/opt/cpanel/ea-wappspector/vendor/phpstan/phpstan
NameSizeModeActions
conf/-0755rm
bootstrap.php56000644editdlrm
composer.json7300644editdlrm
LICENSE10710644editdlrm
phpstan1560755editdlrm
phpstan.phar237980900755editdlrm
phpstan.phar.asc8330644editdlrm
README.md72070644editdlrm
Edit: /opt/cpanel/ea-wappspector/vendor/phpstan/phpstan/phpstan.phar (23798090B)
#!/usr/bin/env php } stubs/typeCheckingFunctions.stub^R~hj^U5 ¤stubs/SplObjectStorage.stubR~hj+qstubs/ReflectionAttribute.stub R~hj qstubs/ext-ds.stubw8R~hjw8 &stubs/mysqli.stubXR~hjX FVstubs/WeakReference.stub`R~hj``stubs/core.stub"R~hj">stubs/ReflectionClass.stubR~hjڤstubs/ibm_db2.stubR~hjcҤstubs/bleedingEdge/Rule.stubR~hjߤ !stubs/bleedingEdge/Countable.stuboR~hjo Ustubs/dom.stubMR~hjMM =stubs/ReflectionMethod.stubR~hjästubs/socket_select.stubR~hjf/stubs/ReflectionParameter.stubR~hj5Τ%stubs/ReflectionFunctionAbstract.stubR~hjVcȤstubs/spl.stub/R~hj/ stubs/PDOStatement.stubR~hjstubs/ImagickPixel.stubpR~hjp+stubs/ArrayObject.stubR~hjjMstubs/socket_select_php8.stubR~hj٤stubs/json_validate.stubR~hjvRstubs/iterable.stub#R~hj#)kstubs/zip.stub4R~hj4#stubs/date.stubR~hjfastubs/ReflectionEnum.stubhR~hjhݠFߤstubs/Countable.stubdR~hjd䞤stubs/ReflectionProperty.stubR~hjXڛڤstubs/Exception.stub- R~hj- Wm,stubs/runtime/ReflectionIntersectionType.phpR~hj;%stubs/runtime/ReflectionAttribute.phpR~hj="/stubs/runtime/Enum/ReflectionEnumBackedCase.phpR~hj;7ystubs/runtime/Enum/UnitEnum.phpR~hj!stubs/runtime/Enum/BackedEnum.php R~hj M-stubs/runtime/Enum/ReflectionEnumUnitCase.phpR~hj%stubs/runtime/Enum/ReflectionEnum.phpR~hjmG%stubs/runtime/ReflectionUnionType.phpR~hjD=stubs/runtime/Attribute.php9R~hj9Qۊstubs/arrayFunctions.stub5R~hj5."stubs/ReflectionClassConstant.stubR~hjDxd bin/phpstanR~hj$resources/functionMap_php74delta.php5R~hj5 resources/functionMap.phpvR~hjvqresources/RegexGrammar.ppR~hj7?y$resources/functionMap_php84delta.phpR~hjb$resources/functionMap_php80delta.phpljR~hjlj1resources/functionMap_php80delta_bleedingEdge.phpR~hjH)resources/functionMetadata.php[R~hj[>I&resources/functionMap_bleedingEdge.phpHLR~hjHL*Y$resources/functionMap_php81delta.phpR~hj@-src/DependencyInjection/Neon/OptionalPath.phpR~hj`GŤTsrc/DependencyInjection/Type/LazyOperatorTypeSpecifyingExtensionRegistryProvider.phpR~hje('Bsrc/DependencyInjection/Type/ParameterOutTypeExtensionProvider.phpR~hjJsrc/DependencyInjection/Type/LazyParameterClosureTypeExtensionProvider.php{R~hj{ äBsrc/DependencyInjection/Type/DynamicThrowTypeExtensionProvider.phpR~hjpդFsrc/DependencyInjection/Type/ParameterClosureTypeExtensionProvider.phpR~hjI{Fsrc/DependencyInjection/Type/LazyDynamicThrowTypeExtensionProvider.php[R~hj[*ǤFsrc/DependencyInjection/Type/LazyParameterOutTypeExtensionProvider.php[R~hj[j4Tsrc/DependencyInjection/Type/LazyExpressionTypeResolverExtensionRegistryProvider.phpR~hjRפOsrc/DependencyInjection/Type/LazyDynamicReturnTypeExtensionRegistryProvider.php!R~hj!;-jPsrc/DependencyInjection/Type/ExpressionTypeResolverExtensionRegistryProvider.phpR~hj楤Psrc/DependencyInjection/Type/OperatorTypeSpecifyingExtensionRegistryProvider.phpR~hjs)Ksrc/DependencyInjection/Type/DynamicReturnTypeExtensionRegistryProvider.phpR~hj;r'src/DependencyInjection/NeonAdapter.phpR~hj]4src/DependencyInjection/ConditionalTagsExtension.phpR~hjɈjI6src/DependencyInjection/ParameterNotFoundException.phpPR~hjP D6src/DependencyInjection/DerivativeContainerFactory.php R~hj 0src/DependencyInjection/Nette/NetteContainer.php R~hj }B)src/DependencyInjection/LoaderFactory.php,R~hj,)FE1;src/DependencyInjection/DuplicateIncludedFilesException.phppR~hjp԰;iOsrc/DependencyInjection/Reflection/ClassReflectionExtensionRegistryProvider.php R~hj rSsrc/DependencyInjection/Reflection/LazyClassReflectionExtensionRegistryProvider.php+ R~hj+ Pyʤ5src/DependencyInjection/ParametersSchemaExtension.phpR~hjW/2,src/DependencyInjection/ContainerFactory.php&<R~hj&<ӎ&src/DependencyInjection/NeonLoader.phpR~hj s/src/DependencyInjection/ProjectConfigHelper.phpR~hj B8src/DependencyInjection/InvalidExcludePathsException.php'R~hj'Ԕ~.src/DependencyInjection/MemoizingContainer.phpR~hjmr(src/DependencyInjection/Configurator.php R~hj cI@src/DependencyInjection/InvalidIgnoredErrorPatternsException.php/R~hj/6:src/DependencyInjection/ValidateIgnoredErrorsExtension.php! R~hj! 1%src/DependencyInjection/Container.phpR~hj؋R.src/DependencyInjection/BleedingEdgeToggle.phpR~hj7a9src/DependencyInjection/ValidateExcludePathsExtension.phpw R~hjw a*src/DependencyInjection/RulesExtension.phpR~hjewGsrc/AnalysedCodeException.phpR~hjiqE^&src/Dependency/ExportedNodeFetcher.phpR~hj*^#src/Dependency/RootExportedNode.phpR~hj]65src/Dependency/ExportedNode.phpaR~hjaVN&src/Dependency/ExportedNodeVisitor.phpR~hj‚Y5src/Dependency/ExportedNode/ExportedInterfaceNode.php R~hj }A1src/Dependency/ExportedNode/ExportedClassNode.phpSR~hjS o9src/Dependency/ExportedNode/ExportedClassConstantNode.phpU R~hjU a%4src/Dependency/ExportedNode/ExportedEnumCaseNode.phpR~hj5src/Dependency/ExportedNode/ExportedParameterNode.php R~hj Ȥ5src/Dependency/ExportedNode/ExportedAttributeNode.phpR~hj071src/Dependency/ExportedNode/ExportedTraitNode.phpR~hj:4src/Dependency/ExportedNode/ExportedFunctionNode.phpR~hj6u:src/Dependency/ExportedNode/ExportedClassConstantsNode.php R~hj )8:src/Dependency/ExportedNode/ExportedTraitUseAdaptation.phpF R~hjF )2src/Dependency/ExportedNode/ExportedPhpDocNode.php)R~hj)2src/Dependency/ExportedNode/ExportedMethodNode.phpR~hjB6src/Dependency/ExportedNode/ExportedPropertiesNode.php$R~hj$2l٤0src/Dependency/ExportedNode/ExportedEnumNode.phpR~hjVt%src/Dependency/DependencyResolver.phpR~hjt#src/Dependency/NodeDependencies.phpR~hjW'src/Dependency/ExportedNodeResolver.php4R~hj4-$src/Testing/PHPStanTestCase.php!%R~hj!%zQsrc/Testing/functions.phpR~hj-c&src/Testing/ErrorFormatterTestCase.php;R~hj;ӏE],src/Testing/TestCaseSourceLocatorFactory.phpiR~hji%src/Testing/TypeInferenceTestCase.php5R~hj5]src/Testing/RuleTestCase.phpOR~hjOIsrc/Testing/LevelsTestCase.phpR~hj&[src/Testing/TestCase.neonR~hj;,!src/Type/IterableType.php=R~hj=e,src/Type/ExpressionTypeResolverExtension.phpIR~hjIC8src/Type/IntegerRangeType.phpc\R~hjc\Y]src/Type/ConditionalType.phpR~hjsrc/Type/VoidType.phpR~hjʃl¤src/Type/StrictMixedType.phpu/R~hju/ֹ.src/Type/FunctionParameterOutTypeExtension.phpR~hj$%¤0src/Type/StaticMethodTypeSpecifyingExtension.phpGR~hjGz;src/Type/ConstantType.php|R~hj|>Gsrc/Type/CallableType.phpgSR~hjgS* 'src/Type/CircularTypeAliasErrorType.phpR~hj[}#src/Type/ObjectWithoutClassType.phpR~hjX@src/Type/ArrayType.phpcR~hjcpsrc/Type/StaticTypeFactory.phpR~hjesrc/Type/NewObjectType.php6 R~hj6 )src/Type/Constant/ConstantIntegerType.php R~hj j)src/Type/Constant/ConstantBooleanType.php R~hj (src/Type/Constant/ConstantStringType.phpKR~hjKD2src/Type/Constant/ConstantScalarToBooleanTrait.phpR~hj&+src/Type/Constant/OversizedArrayBuilder.phpR~hjvj''src/Type/Constant/ConstantFloatType.php R~hj B'src/Type/Constant/ConstantArrayType.phppR~hjpF0src/Type/Constant/ConstantArrayTypeAndMethod.phpR~hj..src/Type/Constant/ConstantArrayTypeBuilder.php0R~hj0Ksrc/Type/VerbosityLevel.phpuR~hjuSsrc/Type/UnionTypeHelper.php~R~hj~"osrc/Type/FileTypeMapper.php4R~hj4:릤src/Type/ClassStringType.phpM R~hjM src/Type/FloatType.phpR~hjj:src/Type/BitwiseFlagHelper.php R~hj *-{src/Type/KeyOfType.php& R~hj& s٤*src/Type/LazyTypeAliasResolverProvider.phpR~hjcksrc/Type/TypeAlias.phpiR~hji9 src/Type/IntegerType.phpR~hjsrc/Type/NullType.phpo)R~hjo),@2src/Type/StaticMethodParameterOutTypeExtension.phpR~hj-src/Type/DynamicMethodReturnTypeExtension.phpR~hjC$$src/Type/Enum/EnumCaseObjectType.phpR~hj Msrc/Type/ExponentiateHelper.phpR~hjM/src/Type/DynamicFunctionReturnTypeExtension.php~R~hj~,src/Type/DirectTypeAliasResolverProvider.phpR~hj),src/Type/FunctionTypeSpecifyingExtension.phpR~hjg\P"src/Type/JustNullableTypeTrait.php2R~hj2OchGsrc/Type/TypeResult.phpR~hj( src/Type/GeneralizePrecision.phpR~hj0"?src/Type/TypeCombinator.phpR~hjERjsrc/Type/BooleanType.phpR~hj D]src/Type/TypeAliasResolver.php4R~hj4Л#src/Type/Regex/RegexGroupParser.phpTR~hjTlդ'src/Type/Regex/RegexGroupWalkResult.php R~hj c)src/Type/Regex/RegexNonCapturingGroup.phpmR~hjm%D%src/Type/Regex/RegexAstWalkResult.php R~hj iڤ(src/Type/Regex/RegexExpressionHelper.phpR~hj(Ϥ#src/Type/Regex/RegexAlternation.phpR~hj^ m&src/Type/Regex/RegexCapturingGroup.phpR~hj+-ڤsrc/Type/ErrorType.phpR~hjXä/src/Type/DynamicReturnTypeExtensionRegistry.phpR~hjn&'src/Type/Helper/GetTemplateTypeType.php R~hj 3src/Type/DynamicStaticMethodReturnTypeExtension.phpR~hjCѤsrc/Type/RecursionGuard.phpR~hj}Osrc/Type/StringType.phpI!R~hjI!G \src/Type/ValueOfType.php R~hj Esrc/Type/TypeWithClassName.php\R~hj\'ܤsrc/Type/TypeUtils.php~2R~hj~2&,src/Type/ClosureType.phpaR~hjaF;$src/Type/UsefulTypeAliasResolver.phpR~hjпsrc/Type/UnionType.php(R~hj([src/Type/ObjectType.phpxR~hjxF282src/Type/FunctionParameterClosureTypeExtension.phpR~hj_(src/Type/ConditionalTypeForParameter.phpR~hjΤ2src/Type/DynamicStaticMethodThrowTypeExtension.phpR~hjsrc/Type/ConstantScalarType.phpR~hj)Y*src/Type/ObjectShapePropertyReflection.phpR~hjc"src/Type/LooseComparisonHelper.php R~hj 9ͤ-src/Type/Accessory/AccessoryArrayListType.php10R~hj104$src/Type/Accessory/HasMethodType.phpR~hjǚ(src/Type/Accessory/NonEmptyArrayType.php+R~hj+դ1src/Type/Accessory/AccessoryLiteralStringType.php$R~hj$dT)src/Type/Accessory/HasOffsetValueType.php5R~hj5fс3src/Type/Accessory/AccessoryUppercaseStringType.phpo$R~hjo$o $src/Type/Accessory/AccessoryType.phpR~hj;ʠ&src/Type/Accessory/HasPropertyType.phpR~hjȨ`2src/Type/Accessory/AccessoryNonFalsyStringType.php'$R~hj'$!f1src/Type/Accessory/AccessoryNumericStringType.php%R~hj%+2src/Type/Accessory/AccessoryNonEmptyStringType.php&R~hj&Ѥ$src/Type/Accessory/HasOffsetType.phpO,R~hjO,)9)src/Type/Accessory/OversizedArrayType.phpk*R~hjk*T%aӤ3src/Type/Accessory/AccessoryLowercaseStringType.phpo$R~hjo$src/Type/StaticType.php^R~hj^ID src/Type/IsSuperTypeOfResult.phpVR~hjV0\src/Type/ObjectShapeType.phpGR~hjGa.src/Type/DynamicFunctionThrowTypeExtension.phplR~hjl+,src/Type/Generic/TemplateStrictMixedType.phpR~hjA&src/Type/Generic/TemplateArrayType.php|R~hj|`&src/Type/Generic/GenericObjectType.php6R~hj6_'Ф&src/Type/Generic/TemplateUnionType.php-R~hj-`mh-src/Type/Generic/TemplateIntersectionType.phpR~hj $src/Type/Generic/TemplateTypeMap.php_R~hj_T)src/Type/Generic/TemplateTypeStrategy.php<R~hj<Uzܤ'src/Type/Generic/TemplateTypeHelper.phpR~hj/%&src/Type/Generic/TemplateKeyOfType.php{R~hj{f1src/Type/Generic/TemplateTypeArgumentStrategy.phpR~hjfy'src/Type/Generic/TemplateObjectType.php R~hj 8&src/Type/Generic/GenericStaticType.php%R~hj%])src/Type/Generic/TypeProjectionHelper.phpsR~hjsH^1)src/Type/Generic/TemplateIterableType.php+R~hj+^2src/Type/Generic/TemplateTypeParameterStrategy.phpR~hj(}'src/Type/Generic/TemplateStringType.phpVR~hjV6yI/3src/Type/Generic/TemplateObjectWithoutClassType.php,R~hj,</src/Type/Generic/TemplateConstantStringType.phpR~hj+T,src/Type/Generic/TemplateObjectShapeType.phpR~hj b&src/Type/Generic/TemplateTypeTrait.php0R~hj0$y(src/Type/Generic/TemplateBooleanType.php[R~hj[.src/Type/Generic/TemplateGenericObjectType.phpR~hj"*src/Type/Generic/TemplateTypeReference.phpR~hjB8(src/Type/Generic/TemplateIntegerType.php[R~hj[˝L+src/Type/Generic/GenericClassStringType.phpR~hj{0src/Type/Generic/TemplateConstantIntegerType.phpR~hjGA8դ.src/Type/Generic/TemplateConstantArrayType.phpR~hj(\&&src/Type/Generic/TemplateFloatType.phpQR~hjQ$Z0src/Type/Generic/TemplateBenevolentUnionType.phpER~hjE֤!src/Type/Generic/TemplateType.php|R~hj|r/)src/Type/Generic/TemplateTypeVariance.phpR~hjK(src/Type/Generic/TemplateTypeFactory.phpTR~hjTiI&src/Type/Generic/TemplateTypeScope.phpR~hjG,src/Type/Generic/TemplateTypeVarianceMap.phpR~hj$.&src/Type/Generic/TemplateMixedType.phphR~hjho,src/Type/OperatorTypeSpecifyingExtension.phpR~hj tFsrc/Type/TypeTraverser.php*R~hj*pIsrc/Type/NeverType.php6R~hj6&"src/Type/NonAcceptingNeverType.phpR~hjE3src/Type/ConstantTypeHelper.php R~hj D㫤src/Type/MixedType.php8R~hj81src/Type/CircularTypeAliasDefinitionException.phpR~hjűä&src/Type/TypeAliasResolverProvider.phpR~hj!nsrc/Type/OffsetAccessType.php R~hj <'src/Type/NonexistentParentClassType.phpR~hjz(src/Type/GenericTypeVariableResolver.phpR~hj0?(src/Type/ParserNodeTypeToPHPStanType.phpR~hj2src/Type/AcceptsResult.php R~hj x|wsrc/Type/SubtractableType.phpR~hj6src/Type/Php/PregFilterFunctionReturnTypeExtension.phpR~hj|7src/Type/Php/IsArrayFunctionTypeSpecifyingExtension.phpR~hj$Ұ4src/Type/Php/PregSplitDynamicReturnTypeExtension.phpsR~hjs1src/Type/Php/RoundFunctionReturnTypeExtension.php R~hj Mcw9src/Type/Php/DateTimeCreateDynamicReturnTypeExtension.php.R~hj.(1[:src/Type/Php/IsIterableFunctionTypeSpecifyingExtension.php.R~hj.R3:src/Type/Php/GetDefinedVarsFunctionReturnTypeExtension.phpR~hj {-src/Type/Php/ThrowableReturnTypeExtension.phpR~hjs@src/Type/Php/ArrayPointerFunctionsDynamicReturnTypeExtension.phpR~hjuC:src/Type/Php/IsCallableFunctionTypeSpecifyingExtension.php R~hj {`֤7src/Type/Php/TriggerErrorDynamicReturnTypeExtension.phpR~hjq=src/Type/Php/ArrayMergeFunctionDynamicReturnTypeExtension.phpR~hjlӤ@src/Type/Php/ReflectionFunctionConstructorThrowTypeExtension.phpjR~hjj23src/Type/Php/DateTimeDynamicReturnTypeExtension.php;R~hj;00*src/Type/Php/IniGetReturnTypeExtension.phpR~hjWN>src/Type/Php/ArrayChangeKeyCaseFunctionReturnTypeExtension.phpR~hjy-l?src/Type/Php/StrWordCountFunctionDynamicReturnTypeExtension.php$R~hj$|45src/Type/Php/ArrayFindFunctionReturnTypeExtension.php3R~hj3S-src/Type/Php/DateFunctionReturnTypeHelper.phpR~hjݠ_@src/Type/Php/MbSubstituteCharacterDynamicReturnTypeExtension.php\R~hj\ )6src/Type/Php/DefineConstantTypeSpecifyingExtension.phpR~hj^/src/Type/Php/PowFunctionReturnTypeExtension.php{R~hj{_ڤ9src/Type/Php/ArgumentBasedFunctionReturnTypeExtension.php R~hj x:src/Type/Php/HighlightStringDynamicReturnTypeExtension.phpR~hjk8Asrc/Type/Php/VersionCompareFunctionDynamicReturnTypeExtension.php R~hj 7src/Type/Php/DefinedConstantTypeSpecifyingExtension.phpR~hjӰ3src/Type/Php/GetClassDynamicReturnTypeExtension.php% R~hj% wϡ:src/Type/Php/DateIntervalConstructorThrowTypeExtension.phpR~hjP476src/Type/Php/ClosureBindDynamicReturnTypeExtension.phpR~hj]9src/Type/Php/GetCalledClassDynamicReturnTypeExtension.phpR~hj*1src/Type/Php/SubstrDynamicReturnTypeExtension.phpoR~hjofڤ>src/Type/Php/ArrayKeyExistsFunctionTypeSpecifyingExtension.phpf R~hjf 3src/Type/Php/PregMatchParameterOutTypeExtension.phphR~hjhH 1src/Type/Php/LtrimFunctionReturnTypeExtension.php[R~hj[ILɤ;src/Type/Php/ParseUrlFunctionDynamicReturnTypeExtension.phpR~hjΉ<src/Type/Php/ArrayKeysFunctionDynamicReturnTypeExtension.php:R~hj:0~8src/Type/Php/ArrayKeyFirstDynamicReturnTypeExtension.phpR~hjyZ9src/Type/Php/DatePeriodConstructorReturnTypeExtension.php$ R~hj$ mFܤ4src/Type/Php/ArrayMapFunctionReturnTypeExtension.phpmR~hjmvaAsrc/Type/Php/GetParentClassDynamicFunctionReturnTypeExtension.php R~hj #hŤ9src/Type/Php/FilterVarArrayDynamicReturnTypeExtension.php R~hj Gv8src/Type/Php/ClosureBindToDynamicReturnTypeExtension.phpR~hj2src/Type/Php/StrlenFunctionReturnTypeExtension.php R~hj S]4src/Type/Php/MethodExistsTypeSpecifyingExtension.phpR~hj̓98src/Type/Php/StrvalFamilyFunctionReturnTypeExtension.phpR~hjа6src/Type/Php/AssertFunctionTypeSpecifyingExtension.phpR~hj&f6src/Type/Php/DateFormatFunctionReturnTypeExtension.phpR~hj¥Cs4src/Type/Php/FilterVarDynamicReturnTypeExtension.phpR~hj7!4src/Type/Php/ArrayPopFunctionReturnTypeExtension.phpR~hjƤ0src/Type/Php/IsAFunctionTypeSpecifyingHelper.php R~hj 2ζ2src/Type/Php/StrPadFunctionReturnTypeExtension.php) R~hj) apAsrc/Type/Php/StrIncrementDecrementFunctionReturnTypeExtension.phpR~hj*Z>src/Type/Php/ArraySearchFunctionDynamicReturnTypeExtension.php&R~hj&O 7src/Type/Php/ArrayReduceFunctionReturnTypeExtension.phpR~hj{uAsrc/Type/Php/ReflectionGetAttributesMethodReturnTypeExtension.phpR~hj-rJ'src/Type/Php/RegexArrayShapeMatcher.phpDR~hjD>src/Type/Php/ReflectionMethodConstructorThrowTypeExtension.php} R~hj} *Τ6src/Type/Php/DateTimeConstructorThrowTypeExtension.phpR~hj4src/Type/Php/ConstantFunctionReturnTypeExtension.phpR~hjԤ>src/Type/Php/ArrayValuesFunctionDynamicReturnTypeExtension.php@R~hj@E"?=src/Type/Php/ReflectionClassConstructorThrowTypeExtension.php&R~hj&9;src/Type/Php/JsonThrowOnErrorDynamicReturnTypeExtension.phpR~hj-ۤ?src/Type/Php/Base64DecodeDynamicFunctionReturnTypeExtension.phpR~hjgR8src/Type/Php/GetDebugTypeFunctionReturnTypeExtension.phpR~hjL5src/Type/Php/StrRepeatFunctionReturnTypeExtension.phpR~hj8 7src/Type/Php/DateTimeModifyMethodThrowTypeExtension.phpR~hj1-3src/Type/Php/CompactFunctionReturnTypeExtension.phpt R~hjt bj2src/Type/Php/DateTimeModifyReturnTypeExtension.php9 R~hj9 w;src/Type/Php/IteratorToArrayFunctionReturnTypeExtension.phpaR~hjamUBɤ8src/Type/Php/ArrayFindKeyFunctionReturnTypeExtension.php+R~hj+*":src/Type/Php/DioStatDynamicFunctionReturnTypeExtension.phpR~hj )src/Type/Php/AssertThrowTypeExtension.php$R~hj$M>src/Type/Php/ClosureFromCallableDynamicReturnTypeExtension.php~R~hj~{s$4src/Type/Php/ArrayNextDynamicReturnTypeExtension.phpR~hj*E8src/Type/Php/OpenSslEncryptParameterOutTypeExtension.php R~hj U3src/Type/Php/GettypeFunctionReturnTypeExtension.phpF R~hjF 1Ŗ6src/Type/Php/ArrayShiftFunctionReturnTypeExtension.phpR~hj5l7src/Type/Php/DateIntervalDynamicReturnTypeExtension.phpR~hjqM>;src/Type/Php/PathinfoFunctionDynamicReturnTypeExtension.php R~hj U8src/Type/Php/ArrayReverseFunctionReturnTypeExtension.phpR~hj"ˤ:src/Type/Php/ExplodeFunctionDynamicReturnTypeExtension.php R~hj f*@src/Type/Php/ReflectionPropertyConstructorThrowTypeExtension.php R~hj 7src/Type/Php/ArraySpliceFunctionReturnTypeExtension.phpR~hjn>src/Type/Php/CurlGetinfoFunctionDynamicReturnTypeExtension.phpR~hjx!5src/Type/Php/StrtotimeFunctionReturnTypeExtension.php R~hj 1)S2src/Type/Php/HrtimeFunctionReturnTypeExtension.phpR~hj>src/Type/Php/SimpleXMLElementConstructorThrowTypeExtension.phpwR~hjwtZˤ6src/Type/Php/ArraySliceFunctionReturnTypeExtension.phpyR~hjyX9src/Type/Php/SscanfFunctionDynamicReturnTypeExtension.phpg R~hjg ns5src/Type/Php/ArrayFillFunctionReturnTypeExtension.php) R~hj) b1src/Type/Php/XMLReaderOpenReturnTypeExtension.phpR~hjh2src/Type/Php/StrrevFunctionReturnTypeExtension.php R~hj -5src/Type/Php/StrContainingTypeSpecifyingExtension.php R~hj s*0src/Type/Php/DsMapDynamicReturnTypeExtension.php:R~hj:̢8src/Type/Php/PregReplaceCallbackClosureTypeExtension.phpR~hj ?src/Type/Php/GettimeofdayDynamicFunctionReturnTypeExtension.phpJR~hjJR>7src/Type/Php/TrimFunctionDynamicReturnTypeExtension.phpR~hjv5src/Type/Php/RandomIntFunctionReturnTypeExtension.php R~hj ߻4+Asrc/Type/Php/SimpleXMLElementClassPropertyReflectionExtension.phpR~hj?@6src/Type/Php/BcMathStringOrNullReturnTypeExtension.phpj(R~hjj(WYB4src/Type/Php/ArrayFilterFunctionReturnTypeHelper.php1R~hj1! K4src/Type/Php/MbStrlenFunctionReturnTypeExtension.phpR~hj^Yܤ6src/Type/Php/PropertyExistsTypeSpecifyingExtension.php R~hj /m5src/Type/Php/MicrotimeFunctionReturnTypeExtension.phpR~hj¤5src/Type/Php/ArrayFlipFunctionReturnTypeExtension.php R~hj VQ6src/Type/Php/AbsFunctionDynamicReturnTypeExtension.phpR~hjD2src/Type/Php/MinMaxFunctionReturnTypeExtension.php R~hj wl?src/Type/Php/SimpleXMLElementXpathMethodReturnTypeExtension.phpR~hjY?/3src/Type/Php/IsAFunctionTypeSpecifyingExtension.phpH R~hjH ΃eCsrc/Type/Php/ReflectionClassIsSubclassOfTypeSpecifyingExtension.phpR~hj,Ф;src/Type/Php/ArraySumFunctionDynamicReturnTypeExtension.phpR~hjVN5src/Type/Php/CountFunctionTypeSpecifyingExtension.phpR~hjbQ/src/Type/Php/MbFunctionsReturnTypeExtension.php R~hj `,0src/Type/Php/DateFunctionReturnTypeExtension.phpR~hjDԤ4src/Type/Php/StrCaseFunctionsReturnTypeExtension.php,R~hj,Bsrc/Type/Php/TypeSpecifyingFunctionsDynamicReturnTypeExtension.php/ R~hj/ ⩏;src/Type/Php/ClassExistsFunctionTypeSpecifyingExtension.phpR~hj j8src/Type/Php/ArrayReplaceFunctionReturnTypeExtension.phpjR~hjjbp:src/Type/Php/CtypeDigitFunctionTypeSpecifyingExtension.php R~hj W4src/Type/Php/MbFunctionsReturnTypeExtensionTrait.phpR~hjo% 9?src/Type/Php/NumberFormatFunctionDynamicReturnTypeExtension.phpR~hj vQ4src/Type/Php/StrSplitFunctionReturnTypeExtension.phpR~hj*4src/Type/Php/DateFormatMethodReturnTypeExtension.php&R~hj&9Ӥ9src/Type/Php/ArrayFillKeysFunctionReturnTypeExtension.phpFR~hjFCl 5src/Type/Php/DsMapDynamicMethodThrowTypeExtension.phpR~hj fS?src/Type/Php/SimpleXMLElementAsXMLMethodReturnTypeExtension.php;R~hj;OX-?src/Type/Php/BackedEnumFromMethodDynamicReturnTypeExtension.phpz R~hjz 5src/Type/Php/ArrayRandFunctionReturnTypeExtension.php!R~hj!`>src/Type/Php/FunctionExistsFunctionTypeSpecifyingExtension.phpAR~hjA /src/Type/Php/StatDynamicReturnTypeExtension.phpnR~hjnڤPD'src/Type/Php/JsonThrowTypeExtension.phpNR~hjND+26src/Type/Php/FilterInputDynamicReturnTypeExtension.phpR~hj^(Ȥ7src/Type/Php/SetTypeFunctionTypeSpecifyingExtension.php; R~hj; G1src/Type/Php/CountFunctionReturnTypeExtension.phpR~hjj.m)src/Type/Php/IntdivThrowTypeExtension.phpgR~hjgC;src/Type/Php/NonEmptyStringFunctionsReturnTypeExtension.phpR~hjcQK;src/Type/Php/ClassImplementsFunctionReturnTypeExtension.php{R~hj{c%w7src/Type/Php/ArrayFilterFunctionReturnTypeExtension.phpR~hjov1src/Type/Php/RangeFunctionReturnTypeExtension.php5R~hj5 3src/Type/Php/ImplodeFunctionReturnTypeExtension.phpR~hjy4src/Type/Php/DateTimeSubMethodThrowTypeExtension.php R~hj դ1src/Type/Php/HashFunctionsReturnTypeExtension.php@R~hj@"D3src/Type/Php/ArrayKeyDynamicReturnTypeExtension.phpR~hj*1==src/Type/Php/MbConvertEncodingFunctionReturnTypeExtension.phpR~hjg#2src/Type/Php/ParseStrParameterOutTypeExtension.phpR~hjǬ7src/Type/Php/ArrayColumnFunctionReturnTypeExtension.phpR~hjI[Ф<src/Type/Php/IsSubclassOfFunctionTypeSpecifyingExtension.php R~hj *٤8src/Type/Php/ArrayCombineFunctionReturnTypeExtension.php^R~hj^¤=src/Type/Php/ArrayIntersectKeyFunctionReturnTypeExtension.phpR~hjmBsrc/Type/Php/ConstantHelper.phpZR~hjZt9;src/Type/Php/ArraySearchFunctionTypeSpecifyingExtension.phpHR~hjHkԤ1src/Type/Php/PregMatchTypeSpecifyingExtension.php4 R~hj4 iKsrc/Type/ThisType.php? R~hj? w- src/Type/BenevolentUnionType.phpR~hjDfr0src/Type/MethodParameterClosureTypeExtension.phpsR~hjsMҌ4src/Type/ExpressionTypeResolverExtensionRegistry.php'R~hj'ynsrc/Type/TypehintHelper.php%R~hj%Z},src/Type/MethodParameterOutTypeExtension.phpR~hj src/Type/ClosureTypeFactory.phplR~hjl?ݤsrc/Type/LateResolvableType.phpR~hj1src/Type/ResourceType.phpw R~hjw ,src/Type/DynamicMethodThrowTypeExtension.phpgR~hjgޭ^8src/Type/StringAlwaysAcceptingObjectWithToStringType.phpR~hjY 9src/Type/CallableTypeHelper.phpR~hj"Tʤsrc/Type/CompoundType.phpR~hjU*src/Type/MethodTypeSpecifyingExtension.php'R~hj'T\0esrc/Type/Type.php0R~hj0$F4src/Type/OperatorTypeSpecifyingExtensionRegistry.php R~hj 46src/Type/StaticMethodParameterClosureTypeExtension.phpR~hjc}B0src/Type/Traits/UndecidedComparisonTypeTrait.phpR~hjn-src/Type/Traits/UndecidedBooleanTypeTrait.phpR~hjȷ*src/Type/Traits/FalseyBooleanTypeTrait.phpR~hj4k1%src/Type/Traits/NonArrayTypeTrait.phpR~hj݄#*src/Type/Traits/TruthyBooleanTypeTrait.phpR~hj &src/Type/Traits/NonObjectTypeTrait.phpu R~hju B'src/Type/Traits/MaybeArrayTypeTrait.phpR~hj{*src/Type/Traits/NonRemoveableTypeTrait.phpR~hj4i8+src/Type/Traits/LateResolvableTypeTrait.php=R~hj=: *src/Type/Traits/MaybeIterableTypeTrait.phpIR~hjI-src/Type/Traits/NonGeneralizableTypeTrait.phpR~hjf7ݤ0src/Type/Traits/NonOffsetAccessibleTypeTrait.phpR~hj*src/Type/Traits/MaybeCallableTypeTrait.phpR~hj+src/Type/Traits/ConstantScalarTypeTrait.php6R~hj6z;r1(src/Type/Traits/NonIterableTypeTrait.phpR~hj. |2src/Type/Traits/MaybeOffsetAccessibleTypeTrait.phpxR~hjx6src/Type/Traits/ConstantNumericComparisonTypeTrait.php) R~hj) 58src/Type/Traits/UndecidedComparisonCompoundTypeTrait.phpR~hj#src/Type/Traits/ObjectTypeTrait.php{R~hj{s>0(src/Type/Traits/MaybeObjectTypeTrait.php R~hj 2{(src/Type/Traits/NonCallableTypeTrait.phpR~hjզ['src/Type/Traits/NonGenericTypeTrait.phpR~hjށsrc/Type/IntersectionType.php\R~hj\Ww&src/Type/SimultaneousTypeTraverser.phpR~hj,դ%src/Broker/ClassNotFoundException.phpR~hj^zߤ'src/Broker/AnonymousClassNameHelper.phpR~hjk0<(src/Broker/ClassAutoloadingException.phpR~hj!uV(src/Broker/ConstantNotFoundException.phpR~hjcH(src/Broker/FunctionNotFoundException.phpR~hjrsrc/Broker/Broker.phpR~hj&src/Broker/BrokerFactory.phpR~hj6QΗ4src/PhpDoc/NameScopeAlreadyBeingCreatedException.phpR~hj//>src/PhpDoc/DirectTypeNodeResolverExtensionRegistryProvider.php&R~hj& Nsrc/PhpDoc/TypeNodeResolver.phpR~hjz/"src/PhpDoc/ResolvedPhpDocBlock.phpҙR~hjҙ8'src/PhpDoc/DefaultStubFilesProvider.php R~hj Pۤsrc/PhpDoc/Tag/PropertyTag.phpR~hj %src/PhpDoc/Tag/TypeAliasImportTag.php8R~hj8Atw src/PhpDoc/Tag/ImplementsTag.php_R~hj_%A;src/PhpDoc/Tag/AssertTag.php R~hj 3src/PhpDoc/Tag/ParamOutTag.phpR~hj~m;src/PhpDoc/Tag/UsesTag.phpYR~hjY{02!src/PhpDoc/Tag/SelfOutTypeTag.php R~hj src/PhpDoc/Tag/TemplateTag.phpbR~hjbasrc/PhpDoc/Tag/TypeAliasTag.php?R~hj?%src/PhpDoc/Tag/MethodTagParameter.phpR~hjP4(src/Process/ProcessCanceledException.phpR~hjw@Xsrc/Process/ProcessHelper.phpY R~hjY }src/Process/ProcessPromise.phpz R~hjz }p'src/Process/ProcessCrashedException.phpR~hj &Ф+src/Classes/ForbiddenClassNameExtension.phpLR~hjL}жsrc/Rules/TipRuleError.phpR~hj|src/Rules/AttributesCheck.phplR~hjlF[)src/Rules/Api/ApiInterfaceExtendsRule.php) R~hj) z6ݤ%src/Rules/Api/ApiClassExtendsRule.php R~hj R4src/Rules/Api/RuntimeReflectionInstantiationRule.php: R~hj: Mh%(src/Rules/Api/ApiClassConstFetchRule.phpf R~hjf _2z!src/Rules/Api/ApiTraitUseRule.phpR~hjL5src/Rules/Api/NodeConnectingVisitorAttributesRule.php R~hj `b7src/Rules/Api/PhpStanNamespaceIn3rdPartyPackageRule.php R~hj Hä#src/Rules/Api/ApiMethodCallRule.php> R~hj> +`|#src/Rules/Api/ApiStaticCallRule.php R~hj (src/Rules/Api/ApiClassImplementsRule.php+ R~hj+ Y/src/Rules/Api/RuntimeReflectionFunctionRule.phpR~hjU src/Rules/Api/ApiRuleHelper.phph R~hjh 1J'src/Rules/Api/ApiInstanceofTypeRule.php<R~hj<&src/Rules/Api/BcUncoveredInterface.phpR~hj ٤&src/Rules/Api/ApiInstantiationRule.php R~hj ױ#src/Rules/Api/ApiInstanceofRule.php[R~hj[jlZ%src/Rules/Api/GetTemplateTypeRule.php R~hj )src/Rules/Ignore/IgnoreParseErrorRule.phpBR~hjBb-src/Rules/DirectRegistry.php%R~hj%u6src/Rules/Properties/TypesAssignedToPropertiesRule.php R~hj >>1src/Rules/Properties/PropertyReflectionFinder.phpR~hj0src/Rules/Properties/FoundPropertyReflection.php0R~hj0_HĤ;src/Rules/Properties/ReadOnlyByPhpDocPropertyAssignRule.phpR~hjzAsrc/Rules/Properties/LazyReadWritePropertiesExtensionProvider.phpR~hjÁ=src/Rules/Properties/ReadWritePropertiesExtensionProvider.php.R~hj._:src/Rules/Properties/MissingReadOnlyPropertyAssignRule.phpO R~hjO my8src/Rules/Properties/ExistingClassesInPropertiesRule.phpR~hjyt2src/Rules/Properties/UninitializedPropertyRule.phpR~hj:UpФ2src/Rules/Properties/NullsafePropertyFetchRule.php R~hj :̑-src/Rules/Properties/AccessPropertiesRule.php6R~hj6٤6src/Rules/Properties/ReadOnlyPropertyAssignRefRule.php<R~hj<Bsrc/Rules/Properties/DefaultValueTypesAssignedToPropertiesRule.php)R~hj)[-src/Rules/Properties/ReadOnlyPropertyRule.phpR~hj84src/Rules/Properties/MissingPropertyTypehintRule.phpB R~hjB H;src/Rules/Properties/AccessStaticPropertiesInAssignRule.phpR~hj.ڤ5src/Rules/Properties/ReadOnlyByPhpDocPropertyRule.phpR~hj۫G3src/Rules/Properties/ReadOnlyPropertyAssignRule.phpR~hjS5src/Rules/Properties/AccessPropertiesInAssignRule.phpR~hj)Bsrc/Rules/Properties/MissingReadOnlyByPhpDocPropertyAssignRule.php R~hj ź/src/Rules/Properties/PropertyAttributesRule.phpR~hjr78src/Rules/Properties/InvalidCallablePropertyTypeRule.phpR~hjh/src/Rules/Properties/OverridingPropertyRule.php R~hj "ؤ+src/Rules/Properties/PropertyDescriptor.phpR~hjOVQ2src/Rules/Properties/PropertiesInInterfaceRule.phpR~hjZ鎤8src/Rules/Properties/WritingToReadOnlyPropertiesRule.phpR~hj8Ġ3src/Rules/Properties/AccessStaticPropertiesRule.phpE"R~hjE"1u7src/Rules/Properties/ReadingWriteOnlyPropertiesRule.phpR~hj@Csrc/Rules/Properties/DirectReadWritePropertiesExtensionProvider.phphR~hjhe*5src/Rules/Properties/ReadWritePropertiesExtension.phpR~hj>src/Rules/Properties/ReadOnlyByPhpDocPropertyAssignRefRule.phpxR~hjx1?src/Rules/Properties/AccessPrivatePropertyThroughStaticRule.php=R~hj=uɤ(src/Rules/PhpDoc/RequireExtendsCheck.phpD R~hjD 5.src/Rules/PhpDoc/InvalidPhpDocTagValueRule.phpR~hj/src/Rules/PhpDoc/IncompatiblePhpDocTypeRule.phpc.R~hjc.)A39src/Rules/PhpDoc/RequireImplementsDefinitionTraitRule.php R~hj qf<src/Rules/PhpDoc/IncompatibleClassConstantPhpDocTypeRule.php R~hj j逘6src/Rules/PhpDoc/FunctionConditionalReturnTypeRule.phpR~hjF9src/Rules/PhpDoc/RequireImplementsDefinitionClassRule.phpR~hj[)src/Rules/PhpDoc/VarTagTypeRuleHelper.phpJ#R~hjJ#]E4src/Rules/PhpDoc/ConditionalReturnTypeRuleHelper.phpR~hjyƐ6src/Rules/PhpDoc/RequireExtendsDefinitionTraitRule.php R~hj FC=.src/Rules/PhpDoc/GenericCallableRuleHelper.phpR~hj -src/Rules/PhpDoc/InvalidPHPStanDocTagRule.phpR~hjaB6src/Rules/PhpDoc/RequireExtendsDefinitionClassRule.php0R~hj0BF1src/Rules/PhpDoc/InvalidThrowsPhpDocValueRule.php R~hj #+src/Rules/PhpDoc/UnresolvableTypeHelper.phpER~hjE u%src/Rules/PhpDoc/PhpDocLineHelper.php:R~hj:6}4src/Rules/PhpDoc/VarTagChangedExpressionTypeRule.phphR~hjhˊ0src/Rules/PhpDoc/IncompatibleSelfOutTypeRule.phpd R~hjd O'src/Rules/PhpDoc/FunctionAssertRule.phpR~hjU֤0src/Rules/PhpDoc/InvalidPhpDocVarTagTypeRule.phpR~hjQգ2src/Rules/PhpDoc/WrongVariableNameInVarTagRule.php6R~hj6laDsrc/Rules/PhpDoc/IncompatibleParamImmediatelyInvokedCallableRule.php R~hj U%src/Rules/PhpDoc/AssertRuleHelper.php%R~hj%vZ%src/Rules/PhpDoc/MethodAssertRule.phpR~hjχ4src/Rules/PhpDoc/MethodConditionalReturnTypeRule.phpR~hj!̷ܤ7src/Rules/PhpDoc/IncompatiblePropertyPhpDocTypeRule.phpR~hjޤ%src/Rules/RuleErrors/RuleError113.phpXR~hjXkOȜ%src/Rules/RuleErrors/RuleError111.php<R~hj<g0!:#src/Rules/RuleErrors/RuleError3.phpR~hj``$src/Rules/RuleErrors/RuleError75.phpR~hj䎀$src/Rules/RuleErrors/RuleError61.phpR~hjyY#src/Rules/RuleErrors/RuleError5.phpR~hjk*$src/Rules/RuleErrors/RuleError27.phpR~hjG:$src/Rules/RuleErrors/RuleError55.phpR~hjti%src/Rules/RuleErrors/RuleError105.php5R~hj5b0$src/Rules/RuleErrors/RuleError41.phpR~hjy{z$src/Rules/RuleErrors/RuleError73.phpQR~hjQUq<$src/Rules/RuleErrors/RuleError29.php<R~hj<F$src/Rules/RuleErrors/RuleError97.phpR~hj B$src/Rules/RuleErrors/RuleError13.phpjR~hjjŤ%src/Rules/RuleErrors/RuleError103.phpR~hj$src/Rules/RuleErrors/RuleError19.phpR~hj.~U#src/Rules/RuleErrors/RuleError7.phphR~hjh%src/Rules/RuleErrors/RuleError115.phpR~hj |%src/Rules/RuleErrors/RuleError123.phpR~hj$src/Rules/RuleErrors/RuleError51.phpR~hj0%src/Rules/RuleErrors/RuleError121.phpR~hj2 ܤ$src/Rules/RuleErrors/RuleError93.php|R~hj|J $src/Rules/RuleErrors/RuleError83.php"R~hj"S$src/Rules/RuleErrors/RuleError45.phpMR~hjM;$src/Rules/RuleErrors/RuleError49.phpR~hj+ݫ`$src/Rules/RuleErrors/RuleError69.phpR~hjR%%src/Rules/RuleErrors/RuleError119.php_R~hj_y%src/Rules/RuleErrors/RuleError125.php`R~hj`+$src/Rules/RuleErrors/RuleError15.phpR~hj$src/Rules/RuleErrors/RuleError85.phpR~hj@9$src/Rules/RuleErrors/RuleError39.phpLR~hjL $src/Rules/RuleErrors/RuleError31.phpR~hjȵ$src/Rules/RuleErrors/RuleError71.phpR~hjⳠ$src/Rules/RuleErrors/RuleError11.phpR~hj3J$src/Rules/RuleErrors/RuleError57.phpR~hjc $src/Rules/RuleErrors/RuleError99.php3R~hj3?$src/Rules/RuleErrors/RuleError25.phpR~hj-$Ť$src/Rules/RuleErrors/RuleError81.phptR~hjtȃe$src/Rules/RuleErrors/RuleError63.phpR~hjiL$src/Rules/RuleErrors/RuleError21.phpR~hjR#x%src/Rules/RuleErrors/RuleError127.phpR~hjV`L$src/Rules/RuleErrors/RuleError37.phpR~hjb $src/Rules/RuleErrors/RuleError91.phpR~hj *$src/Rules/RuleErrors/RuleError87.php{R~hj{oY%src/Rules/RuleErrors/RuleError107.phpR~hjU)$src/Rules/RuleErrors/RuleError65.phpR~hj<$src/Rules/RuleErrors/RuleError53.phppR~hjpJ*$src/Rules/RuleErrors/RuleError23.php;R~hj;[D$src/Rules/RuleErrors/RuleError33.phpER~hjE M$src/Rules/RuleErrors/RuleError59.phptR~hjt#src/Rules/RuleErrors/RuleError9.phpR~hjq&$src/Rules/RuleErrors/RuleError77.phpR~hjFTФ$src/Rules/RuleErrors/RuleError17.php4R~hj4ȹsrc/Rules/Rule.phpR~hjYړ.src/Rules/EnumCases/EnumCaseAttributesRule.phpR~hj8]*)src/Rules/Classes/AllowedSubTypesRule.php R~hj 7D3src/Rules/Classes/DuplicateClassDeclarationRule.php R~hj 1=L;src/Rules/Classes/ExistingClassesInInterfaceExtendsRule.php R~hj '21#src/Rules/Classes/NewStaticRule.phpR~hjO%src/Rules/Classes/PropertyTagRule.phpR~hj?&src/Rules/Classes/PropertyTagCheck.php\'R~hj\' 9$src/Rules/Classes/MixinTraitRule.phpwR~hjw5src/Rules/Classes/UnusedConstructorParametersRule.phpR~hj src/Rules/Classes/MixinCheck.phpR~hj߫.src/Rules/Classes/ImpossibleInstanceOfRule.phpR~hjwO3src/Rules/Classes/ExistingClassInInstanceOfRule.php R~hj @.'src/Rules/Classes/ClassConstantRule.phpR~hj`ä*src/Rules/Classes/PropertyTagTraitRule.phpR~hj'src/Rules/Classes/ReadOnlyClassRule.phpR~hj iB-src/Rules/Classes/PropertyTagTraitUseRule.phpR~hjwbv(src/Rules/Classes/MethodTagTraitRule.phpR~hjjyK2src/Rules/Classes/LocalTypeTraitUseAliasesRule.phpR~hj_v<src/Rules/Classes/AccessPrivateConstantThroughStaticRule.phpR~hj⌵1src/Rules/Classes/ClassConstantAttributesRule.php$R~hj$p0src/Rules/Classes/NonClassAttributeClassRule.phpfR~hjf-Y#src/Rules/Classes/MethodTagRule.phpR~hjF)src/Rules/Classes/ClassAttributesRule.phpRR~hjRcx-src/Rules/Classes/TraitAttributeClassRule.phpPR~hjPE\w$src/Rules/Classes/MethodTagCheck.phpH/R~hjH/}9(src/Rules/Classes/RequireExtendsRule.phpR~hjәi/src/Rules/Classes/InstantiationCallableRule.phpR~hjݦ3src/Rules/Classes/InvalidPromotedPropertiesRule.php R~hj cؕ'src/Rules/Classes/InstantiationRule.php $R~hj $fX:src/Rules/Classes/ExistingClassesInClassImplementsRule.php5 R~hj5 ^.+src/Rules/Classes/RequireImplementsRule.phpR~hjʤ9src/Rules/Classes/ExistingClassesInEnumImplementsRule.php R~hj aV*src/Rules/Classes/LocalTypeAliasesRule.phpR~hjUG}.src/Rules/Classes/DuplicateDeclarationRule.phpR~hj/ 1src/Rules/Classes/ExistingClassInTraitUseRule.php R~hj BկԤ$src/Rules/Classes/EnumSanityRule.php^R~hj^85src/Rules/Classes/ExistingClassInClassExtendsRule.php+R~hj+"Pw-+src/Rules/Classes/MethodTagTraitUseRule.phpR~hj)D'src/Rules/Classes/MixinTraitUseRule.phpR~hj~+src/Rules/Classes/LocalTypeAliasesCheck.php6;R~hj6;(usrc/Rules/Classes/MixinRule.phpR~hjc/src/Rules/Classes/LocalTypeTraitAliasesRule.phpR~hj{ج+src/Rules/Types/InvalidTypesInUnionRule.phpL R~hjL K0src/Rules/FileRuleError.phpR~hj!v*src/Rules/Generators/YieldFromTypeRule.php"R~hj"QҤ&src/Rules/Generators/YieldTypeRule.phpU R~hjU b-src/Rules/Generators/YieldInGeneratorRule.php"R~hj"}! ,src/Rules/Methods/FinalPrivateMethodRule.phpR~hj'ߙ/src/Rules/Methods/AlwaysUsedMethodExtension.phpKR~hjKGe;src/Rules/Methods/LazyAlwaysUsedMethodExtensionProvider.phpR~hjܤ=src/Rules/Methods/DirectAlwaysUsedMethodExtensionProvider.phpR~hjA/src/Rules/Methods/ConstructorReturnTypeRule.phpR~hj:m6src/Rules/Methods/IllegalConstructorMethodCallRule.phpR~hjx</src/Rules/Methods/ConsistentConstructorRule.php6R~hj6>Ф.src/Rules/Methods/StaticMethodCallableRule.php<R~hj<n,src/Rules/Methods/NullsafeMethodCallRule.phppR~hjpu(Ť:src/Rules/Methods/MissingMagicSerializationMethodsRule.php R~hj )Fsrc/Rules/Methods/CallToConstructorStatementWithoutSideEffectsRule.phpR~hjцꑤ8src/Rules/Methods/CallPrivateMethodThroughStaticRule.phpR~hj1y $src/Rules/Methods/ReturnTypeRule.phpR~hjDۊ*src/Rules/Methods/MethodAttributesRule.phpR~hjU95src/Rules/Methods/MissingMethodReturnTypehintRule.php R~hj g7Gsrc/Rules/Methods/CallToStaticMethodStatementWithoutSideEffectsRule.phpI R~hjI +src/Rules/Methods/CallStaticMethodsRule.php R~hj ӆ5src/Rules/Methods/MissingMethodImplementationRule.phpR~hj}Ť7src/Rules/Methods/AlwaysUsedMethodExtensionProvider.php)R~hj)E)src/Rules/Methods/MethodSignatureRule.php.R~hj.)[2src/Rules/Methods/MissingMethodSelfOutTypeRule.phpM R~hjM p~4src/Rules/Methods/ExistingClassesInTypehintsRule.phpR~hjj3 (src/Rules/Methods/MethodCallableRule.phpR~hj^oN5src/Rules/Methods/MethodVisibilityInInterfaceRule.php?R~hj?/src/Rules/Methods/AbstractPrivateMethodRule.phpR~hj~)*src/Rules/Methods/OverridingMethodRule.php?R~hj? %%src/Rules/Methods/MethodCallCheck.phpR~hj:src/Rules/Methods/AbstractMethodInNonAbstractClassRule.phpSR~hjS Asrc/Rules/Methods/CallToMethodStatementWithoutSideEffectsRule.php R~hj >[Ф+src/Rules/Methods/StaticMethodCallCheck.php'R~hj'_P5src/Rules/Methods/MethodParameterComparisonHelper.php8R~hj8?:src/Rules/Methods/IncompatibleDefaultParameterTypeRule.phpR~hj%src/Rules/Methods/CallMethodsRule.php R~hj Wb8src/Rules/Methods/MissingMethodParameterTypehintRule.phpR~hj@b6src/Rules/Methods/IllegalConstructorStaticCallRule.php R~hj %g%src/Rules/FunctionDefinitionCheck.phpfR~hjfUҤsrc/Rules/LazyRegistry.phpR~hjoϒ0src/Rules/Generics/InterfaceTemplateTypeRule.phpR~hja1(src/Rules/Generics/TemplateTypeCheck.php)'R~hj)'j֤,src/Rules/Generics/ClassTemplateTypeRule.phpR~hj訤4src/Rules/Generics/FunctionSignatureVarianceRule.phpR~hjjr2+src/Rules/Generics/PropertyVarianceRule.phpR~hj?,src/Rules/Generics/GenericAncestorsCheck.phpBR~hjBo?/src/Rules/Generics/FunctionTemplateTypeRule.php R~hj faI,1src/Rules/Generics/CrossCheckInterfacesHelper.php R~hj Ԥ-src/Rules/Generics/InterfaceAncestorsRule.php R~hj =ps%src/Rules/Generics/UsedTraitsRule.php R~hj [ ,src/Rules/Generics/TraitTemplateTypeRule.phpZ R~hjZ 3-src/Rules/Generics/MethodTemplateTypeRule.php)R~hj)<;)src/Rules/Generics/ClassAncestorsRule.phpR~hjxM7I-src/Rules/Generics/GenericObjectTypeCheck.phpR~hj-~ˤ$src/Rules/Generics/VarianceCheck.php,R~hj,%61src/Rules/Generics/MethodTagTemplateTypeCheck.php R~hj 0src/Rules/Generics/MethodTagTemplateTypeRule.phptR~hjtӛ:+src/Rules/Generics/EnumTemplateTypeRule.phpR~hj5src/Rules/Generics/MethodTagTemplateTypeTraitRule.php+R~hj++\(src/Rules/Generics/EnumAncestorsRule.phpn R~hjn ۻ2src/Rules/Generics/MethodSignatureVarianceRule.php R~hj  &src/Rules/Debug/DumpPhpDocTypeRule.php*R~hj*zB"src/Rules/Debug/DebugScopeRule.phpHR~hjH  src/Rules/Debug/DumpTypeRule.phpR~hjӤ"src/Rules/Debug/FileAssertRule.phpR~hj~src/Rules/IssetCheck.php/R~hj/c쑤1src/Rules/Regexp/RegularExpressionPatternRule.phpR~hjŜ)1src/Rules/Regexp/RegularExpressionQuotingRule.phpR~hj]pĤ4src/Rules/Namespaces/ExistingNamesInGroupUseRule.phpR~hj6/src/Rules/Namespaces/ExistingNamesInUseRule.phphR~hjhI'src/Rules/Missing/MissingReturnRule.phppR~hjp6src/Rules/MetadataRuleError.phpR~hjh+src/Rules/Whitespace/FileWhitespaceRule.php_ R~hj_ դEsrc/Rules/DeadCode/CallToFunctionStatementWithoutImpurePointsRule.phpR~hj|/src/Rules/DeadCode/UnreachableStatementRule.phpR~hj!0src/Rules/DeadCode/UnusedPrivateConstantRule.phpTR~hjT8KHsrc/Rules/DeadCode/CallToConstructorStatementWithoutImpurePointsRule.phpR~hj Bsrc/Rules/DeadCode/NoopRule.phpR~hj6src/Rules/DeadCode/PossiblyPureStaticCallCollector.phpR~hjj/src/Rules/DeadCode/PossiblyPureNewCollector.php3R~hj3٤0src/Rules/DeadCode/UnusedPrivatePropertyRule.phpC!R~hjC!50.src/Rules/DeadCode/UnusedPrivateMethodRule.phpR~hj2>src/Rules/DeadCode/ConstructorWithoutImpurePointsCollector.phpR~hje;src/Rules/DeadCode/FunctionWithoutImpurePointsCollector.phpR~hjiIsrc/Rules/DeadCode/CallToStaticMethodStatementWithoutImpurePointsRule.phpR~hju9src/Rules/DeadCode/MethodWithoutImpurePointsCollector.phpR~hjCsrc/Rules/DeadCode/CallToMethodStatementWithoutImpurePointsRule.phphR~hjhʩ%src/Rules/DeadCode/BetterNoopRule.phpKR~hjK\6src/Rules/DeadCode/PossiblyPureMethodCallCollector.phpR~hj˒4src/Rules/DeadCode/PossiblyPureFuncCallCollector.phpR~hj+fY@src/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRule.php R~hj Ĕ>src/Rules/TooWideTypehints/TooWideMethodReturnTypehintRule.phpMR~hjMhݤEsrc/Rules/TooWideTypehints/TooWideArrowFunctionReturnTypehintRule.phpR~hj] WBsrc/Rules/TooWideTypehints/TooWideFunctionParameterOutTypeRule.phpR~hjg;src/Rules/TooWideTypehints/TooWideParameterOutTypeCheck.php? R~hj? o|?src/Rules/TooWideTypehints/TooWideClosureReturnTypehintRule.phpR~hji Ф@src/Rules/TooWideTypehints/TooWideMethodParameterOutTypeRule.phpR~hj͉6src/Rules/TooWideTypehints/TooWidePropertyTypeRule.phpR~hj;'6src/Rules/Operators/InvalidComparisonOperationRule.phpR~hj1src/Rules/Operators/InvalidUnaryOperationRule.php R~hj U`,src/Rules/Operators/InvalidAssignVarRule.php R~hj [2src/Rules/Operators/InvalidBinaryOperationRule.php#R~hj#'8P2src/Rules/Operators/InvalidIncDecOperationRule.phpR~hjn)iĤ,src/Rules/ParameterCastableToStringCheck.phpjR~hjjLsrc/Rules/NullsafeCheck.phpR~hjìsrc/Rules/ClassNameCheck.phpR~hjcHsrc/Rules/Registry.php'R~hj'*src/Rules/RuleLevelHelperAcceptsResult.phpR~hjzJ Bsrc/Rules/Exceptions/MissingCheckedExceptionInMethodThrowsRule.phpR~hjg .src/Rules/Exceptions/TooWideThrowTypeCheck.phpR~hjVѤ,src/Rules/Exceptions/ThrowExpressionRule.phpR~hj]5src/Rules/Exceptions/DefaultExceptionTypeResolver.phpR~hj#5src/Rules/Exceptions/CaughtExceptionExistenceRule.php R~hj ~w)=src/Rules/Exceptions/MissingCheckedExceptionInThrowsCheck.phpR~hj~Dsrc/Rules/Exceptions/MissingCheckedExceptionInFunctionThrowsRule.php}R~hj}煤*src/Rules/Exceptions/ThrowExprTypeRule.phpVR~hjVM(K.src/Rules/Exceptions/NoncapturingCatchRule.phpR~hj$5src/Rules/Exceptions/TooWideFunctionThrowTypeRule.phpZR~hjZSڱ7src/Rules/Exceptions/CatchWithUnthrownExceptionRule.phpTR~hjTX:src/Rules/Exceptions/OverwrittenExitPointByFinallyRule.php$R~hj$9}Esrc/Rules/Exceptions/ThrowsVoidFunctionWithExplicitThrowPointRule.php R~hj ӗ.src/Rules/Exceptions/ExceptionTypeResolver.phpR~hjsCsrc/Rules/Exceptions/ThrowsVoidMethodWithExplicitThrowPointRule.php R~hj /zh3src/Rules/Exceptions/TooWideMethodThrowTypeRule.phpR~hj_~,src/Rules/Keywords/RequireFileExistsRule.phpR~hj(.src/Rules/Keywords/ContinueBreakInLoopRule.phpR~hj0r-src/Rules/Keywords/DeclareStrictTypesRule.phpR~hj[B&src/Rules/Playground/NoPhpCodeRule.phpVR~hjV:E Ԥ-src/Rules/Playground/NotAnalysedTraitRule.phpR~hjZʆ*src/Rules/Playground/FunctionNeverRule.phpUR~hjU{٤(src/Rules/Playground/NeverRuleHelper.phpR~hj@.(src/Rules/Playground/MethodNeverRule.phpwR~hjw]r%src/Rules/FunctionReturnTypeCheck.phpP R~hjP Ȯsrc/Rules/RuleError.phpR~hjt@Ф'src/Rules/ClassCaseSensitivityCheck.phpR~hjP%src/Rules/ClassForbiddenNameCheck.php R~hj =s:src/Rules/Arrays/NonexistentOffsetInArrayDimFetchCheck.phpR~hjy.src/Rules/Arrays/InvalidKeyInArrayItemRule.phpR~hj>Zf'src/Rules/Arrays/EmptyArrayItemRule.php:R~hj:Yr:5src/Rules/Arrays/DuplicateKeysInLiteralArraysRule.phpiR~hji P-src/Rules/Arrays/OffsetAccessAssignOpRule.php R~hj ,7($src/Rules/Arrays/DeadForeachRule.phpR~hjAȤ+src/Rules/Arrays/ArrayDestructuringRule.phpZ R~hjZ 1s*src/Rules/Arrays/IterableInForeachRule.phpBR~hjBpz9src/Rules/Arrays/NonexistentOffsetInArrayDimFetchRule.php R~hj r}{o*src/Rules/Arrays/AllowedArrayKeysTypes.php{ R~hj{ ~mB.src/Rules/Arrays/UnpackIterableInArrayRule.phpR~hjr-src/Rules/Arrays/AppendedArrayKeyTypeRule.php R~hj e'src/Rules/Arrays/ArrayUnpackingRule.phpgR~hjg⩤.src/Rules/Arrays/AppendedArrayItemTypeRule.php R~hj ģ4src/Rules/Arrays/OffsetAccessValueAssignmentRule.php R~hj UV/src/Rules/Arrays/OffsetAccessAssignmentRule.php R~hj :9src/Rules/Arrays/OffsetAccessWithoutDimForReadingRule.phpR~hj?2src/Rules/Arrays/InvalidKeyInArrayDimFetchRule.phpR~hjMGsrc/Rules/Comparison/NumberComparisonOperatorsConstantConditionRule.phpp R~hjp , 9src/Rules/Comparison/WhileLoopAlwaysTrueConditionRule.php R~hj x8c=src/Rules/Comparison/TernaryOperatorConstantConditionRule.phpR~hj2< :src/Rules/Comparison/ImpossibleCheckTypeMethodCallRule.phpR~hj{2src/Rules/Comparison/ImpossibleCheckTypeHelper.php"FR~hj"FExǤ:src/Rules/Comparison/WhileLoopAlwaysFalseConditionRule.php2R~hj2P48src/Rules/Comparison/LogicalXorConstantConditionRule.phpR~hjI0src/Rules/Comparison/IfConstantConditionRule.phpR~hjEW@src/Rules/Comparison/ImpossibleCheckTypeStaticMethodCallRule.phpR~hjS=src/Rules/Comparison/StrictComparisonOfDifferentTypesRule.php=R~hj=;&9src/Rules/Comparison/DoWhileLoopConstantConditionRule.php R~hj Eb8src/Rules/Comparison/BooleanAndConstantConditionRule.phpR~hj8src/Rules/Comparison/BooleanNotConstantConditionRule.php R~hj Y]7src/Rules/Comparison/UsageOfVoidMatchExpressionRule.php"R~hj"<src/Rules/Comparison/ImpossibleCheckTypeFunctionCallRule.phpQR~hjQQ4src/Rules/Comparison/ConstantLooseComparisonRule.phpR~hjDu Ӥ2src/Rules/Comparison/UnreachableIfBranchesRule.php R~hj cIK4src/Rules/Comparison/ConstantConditionRuleHelper.php R~hj k7src/Rules/Comparison/BooleanOrConstantConditionRule.phpR~hj kb4src/Rules/Comparison/ElseIfConstantConditionRule.php R~hj 9src/Rules/Comparison/UnreachableTernaryElseBranchRule.php R~hj ^,src/Rules/Comparison/MatchExpressionRule.php>R~hj>Y(@"src/Rules/MissingTypehintCheck.phpR~hjrc'src/Rules/DateTimeInstantiationRule.php/R~hj/+^src/Rules/Cast/PrintRule.phpYR~hjYQf¤ src/Rules/Cast/UnsetCastRule.phpR~hj|Ҥ"src/Rules/Cast/InvalidCastRule.php R~hj (y2src/Rules/Cast/InvalidPartOfEncapsedStringRule.phpR~hj<src/Rules/Cast/EchoRule.phpR~hjv<src/Rules/Functions/ImplodeParameterCastableToStringRule.php R~hj 3src/Rules/Functions/ArrowFunctionAttributesRule.php R~hj m0-src/Rules/Functions/UnusedClosureUsesRule.phpR~hjM<src/Rules/Functions/MissingFunctionParameterTypehintRule.phpR~hj{Esrc/Rules/Functions/CallToFunctionStatementWithoutSideEffectsRule.phpHR~hjH'>5src/Rules/Functions/CallToNonExistentFunctionRule.php'R~hj'.Isrc/Rules/Functions/IncompatibleArrowFunctionDefaultParameterTypeRule.phpR~hjD,src/Rules/Functions/DefineParametersRule.phpR~hjx 6src/Rules/Functions/UselessFunctionReturnValueRule.php R~hj h59src/Rules/Functions/MissingFunctionReturnTypehintRule.php R~hj 8:+src/Rules/Functions/ParamAttributesRule.phpR~hjg$ϤCsrc/Rules/Functions/ExistingClassesInArrowFunctionTypehintsRule.phpR~hjU$$src/Rules/Functions/PrintfHelper.php@ R~hj@ HL5src/Rules/Functions/ParameterCastableToStringRule.php R~hj 鸤)src/Rules/Functions/InnerFunctionRule.phpeR~hjeEl9src/Rules/Functions/SortParameterCastableToStringRule.phpR~hj2%l{&src/Rules/Functions/ReturnTypeRule.php(R~hj(t$7Ϥ?src/Rules/Functions/InvalidLexicalVariablesInClosureUseRule.phpR~hjdu<src/Rules/Functions/ArrowFunctionReturnNullsafeByRefRule.phpR~hj6 4src/Rules/Functions/CallToFunctionParametersRule.php R~hj -l-src/Rules/Functions/ClosureReturnTypeRule.php@R~hj@fn)src/Rules/Functions/CallCallablesRule.phpPR~hjP/src/Rules/Functions/ReturnNullsafeByRefRule.phpZR~hjZן6src/Rules/Functions/ExistingClassesInTypehintsRule.phpR~hjΤ-src/Rules/Functions/ClosureAttributesRule.phpR~hj7f93src/Rules/Functions/ArrowFunctionReturnTypeRule.phpR~hj\MCsrc/Rules/Functions/IncompatibleClosureDefaultParameterTypeRule.phpR~hjW)8src/Rules/Functions/DuplicateFunctionDeclarationRule.phpR~hj7ҭ'src/Rules/Functions/ArrayValuesRule.phpTR~hjT.+src/Rules/Functions/ImplodeFunctionRule.php R~hj CR/src/Rules/Functions/RedefinedParametersRule.phpR~hj4(src/Rules/Functions/CallUserFuncRule.php R~hj K9src/Rules/Functions/VariadicParametersDeclarationRule.php2R~hj2k.src/Rules/Functions/FunctionAttributesRule.phpR~hj'src/Rules/Functions/ArrayFilterRule.phpR~hj;.Ӥ,src/Rules/Functions/FunctionCallableRule.phpR~hj ֤,src/Rules/Functions/PrintfParametersRule.phps R~hjs G=src/Rules/Functions/ExistingClassesInClosureTypehintsRule.php\R~hj\(l1src/Rules/Functions/PrintfArrayParametersRule.phpR~hjۤ<src/Rules/Functions/IncompatibleDefaultParameterTypeRule.phpR~hjƈ/src/Rules/Functions/RandomIntParametersRule.phpR~hjsrc/Rules/ClassNameNodePair.phpR~hj$hͤsrc/Rules/FoundTypeResult.phpR~hjh[gsrc/Rules/RuleErrorBuilder.phpR~hj/)src/Rules/FunctionCallParametersCheck.phpdR~hjde#src/Rules/Pure/PureFunctionRule.phpR~hj=!src/Rules/Pure/PureMethodRule.phpR~hjۅ&src/Rules/Pure/FunctionPurityCheck.phpR~hj4src/Rules/Variables/ParameterOutAssignedTypeRule.php R~hj @%src/Rules/Variables/ThrowTypeRule.phpQR~hjQO,src/Rules/Variables/CompactVariablesRule.php R~hj A!src/Rules/Variables/UnsetRule.phpR~hjSY5+src/Rules/Variables/DefinedVariableRule.phpR~hj^ɤ+src/Rules/Variables/VariableCloningRule.phpR~hj-8src/Rules/Variables/ParameterOutExecutionEndTypeRule.phpR~hjjt(src/Rules/Variables/NullCoalesceRule.phpR~hj1T[!src/Rules/Variables/EmptyRule.phpUR~hjUeR!src/Rules/Variables/IssetRule.phpR~hj⿤!src/Rules/Names/UsedNamesRule.phpR~hjv#src/Rules/NonIgnorableRuleError.phpR~hj6y̤0src/Rules/Constants/ClassAsClassConstantRule.php}R~hj}Esrc/Rules/Constants/LazyAlwaysUsedClassConstantsExtensionProvider.php!R~hj!j0src/Rules/Constants/MagicConstantContextRule.phpvR~hjvɺ5src/Rules/Constants/DynamicClassConstantFetchRule.phpR~hj0a$src/Rules/Constants/ConstantRule.phpR~hjo^ک8src/Rules/Constants/ValueAssignedToClassConstantRule.phpR~hjY4src/Rules/Constants/NativeTypedClassConstantRule.phpR~hjxL.src/Rules/Constants/OverridingConstantRule.phpR~hjZk)src/Rules/Constants/FinalConstantRule.phpR~hja29src/Rules/Constants/AlwaysUsedClassConstantsExtension.phpR~hjޡr8src/Rules/Constants/MissingClassConstantTypehintRule.phpE R~hjE ݤAsrc/Rules/Constants/AlwaysUsedClassConstantsExtensionProvider.phpER~hjER?*src/Rules/Traits/ConstantsInTraitsRule.php*R~hj*٤)src/Rules/Traits/NotAnalysedTraitRule.phpR~hjx^*.src/Rules/Traits/TraitDeclarationCollector.php[R~hj[놤2src/Rules/Traits/ConflictingTraitConstantsRule.php#R~hj#$Pפ&src/Rules/Traits/TraitUseCollector.phpR~hj8+src/Rules/UnusedFunctionParametersCheck.php R~hj ʐԤsrc/Rules/RuleLevelHelper.phpMBR~hjMBxRG!src/Rules/IdentifierRuleError.phpR~hjMT3src/Rules/LineRuleError.phpR~hj[%7"src/Collectors/RegistryFactory.phpR~hjwʤsrc/Collectors/Registry.phpvR~hjv(src/Collectors/Collector.php R~hj ; src/Collectors/CollectedData.phpZR~hjZnasrc/File/FileExcluder.php^R~hj^:UHsrc/File/FileFinderResult.phpZR~hjZ {src/File/FileMonitor.phpSR~hjS>m $src/File/FuzzyRelativePathHelper.phpPR~hjP𜍤#src/File/FileExcluderRawFactory.phpR~hj) f.src/File/ParentDirectoryRelativePathHelper.phpR~hjBhsrc/File/RelativePathHelper.phpR~hj+l3src/File/SystemAgnosticSimpleRelativePathHelper.phpR~hjͤ%src/File/SimpleRelativePathHelper.php.R~hj.cq src/File/FileExcluderFactory.phpKR~hjK[#src/File/NullRelativePathHelper.phpR~hjz'src/File/CouldNotWriteFileException.phpR~hjsrc/File/FileMonitorResult.phpR~hj.src/File/FileWriter.phpR~hjR&src/File/CouldNotReadFileException.phpR~hjx1gsrc/File/FileFinder.phpR~hjiBsrc/File/FileReader.phpR~hjBWͤsrc/File/FileHelper.php R~hj @"src/File/PathNotFoundException.phpR~hjOJ5src/TrinaryLogic.phpR~hj3*src/Parser/CleaningParser.phpR~hjԱDsrc/Parser/SimpleParser.phpR~hjFasrc/Parser/CleaningVisitor.php\ R~hj\ H-src/Parser/TypeTraverserInstanceofVisitor.php(R~hj(QF/src/Parser/ImmediatelyInvokedClosureVisitor.phpR~hjŇo src/Parser/ClosureArgVisitor.phpR~hjgˤ%src/Parser/TraitCollectingVisitor.phpR~hj}4(Ĥ$src/Parser/ParserErrorsException.phpR~hj<)"src/Parser/TryCatchTypeVisitor.phpR~hjK>%src/Parser/ParentStmtTypesVisitor.phpnR~hjn &ܤ$src/Parser/AnonymousClassVisitor.phpfR~hjf,G+src/Parser/NewAssignedToPropertyVisitor.phpR~hjX#src/Parser/CurlSetOptArgVisitor.phpR~hjAc$src/Parser/ClosureBindArgVisitor.phpR~hj`isrc/Parser/CachedParser.php R~hj 64l*src/Parser/FunctionCallStatementFinder.phpR~hjJy%src/Parser/DeclarePositionVisitor.phpR~hjmA"src/Parser/ArrayWalkArgVisitor.phpR~hj+F"src/Parser/ArrayFindArgVisitor.phpR~hj̲?!src/Parser/PhpParserDecorator.phpR~hj#ߤ/src/Parser/MagicConstantParamDefaultVisitor.phpR~hjBä$src/Parser/ArrayFilterArgVisitor.phpR~hjNh5&src/Parser/ArrowFunctionArgVisitor.phpR~hjǤsrc/Parser/Parser.phpR~hj_8#src/Parser/LastConditionVisitor.php R~hj osrc/Parser/RichParser.php4R~hj4dRsrc/Parser/LexerFactory.phpR~hj$B9!src/Parser/ArrayMapArgVisitor.phpR~hj,z츤&src/Parser/ClosureBindToVarVisitor.phpR~hjB4src/Parser/RemoveUnusedCodeByPhpVersionIdVisitor.phpS R~hjS SL src/Parser/PathRoutingParser.php R~hj ҂M src/ShouldNotHappenException.phpR~hjsrc/Command/AnalyseCommand.phpR~hjMC%src/Command/Symfony/SymfonyOutput.phpR~hj1$src/Command/Symfony/SymfonyStyle.phpR~hj%src/Command/IgnoredRegexValidator.phpR~hj9!8 "src/Command/FixerWorkerCommand.php>R~hj>src/Command/AnalyserRunner.php]R~hj]5+src/Command/IgnoredRegexValidatorResult.phpR~hj3?src/Command/OutputStyle.phpR~hj>g"src/Command/ErrorsConsoleStyle.phpR~hj\p src/Command/FixerApplication.phpUR~hjU-TQsrc/Command/AnalysisResult.phpcR~hjc$esrc/Command/WorkerCommand.php,R~hj,PZ"src/Command/AnalyseApplication.php7R~hj7v %src/Command/FixerProcessException.phpR~hjH}%src/Command/DumpParametersCommand.phpFR~hjF"p src/Command/DiagnoseCommand.php?R~hj?N7src/Command/ErrorFormatter/CheckstyleErrorFormatter.phpR~hj=49src/Command/ErrorFormatter/BaselineNeonErrorFormatter.php R~hj 曃3src/Command/ErrorFormatter/GithubErrorFormatter.phph R~hjh VԤ5src/Command/ErrorFormatter/TeamcityErrorFormatter.phpR~hjK.8src/Command/ErrorFormatter/BaselinePhpErrorFormatter.phpP R~hjP W7src/Command/ErrorFormatter/CiDetectedErrorFormatter.phpR~hj,0src/Command/ErrorFormatter/RawErrorFormatter.phpjR~hjj2src/Command/ErrorFormatter/JunitErrorFormatter.php R~hj U+3src/Command/ErrorFormatter/GitlabErrorFormatter.php5R~hj5z\`-src/Command/ErrorFormatter/ErrorFormatter.phpR~hjs̤1src/Command/ErrorFormatter/JsonErrorFormatter.phpRR~hjRʐr2src/Command/ErrorFormatter/TableErrorFormatter.phpPR~hjPt6/src/Command/InceptionNotSuccessfulException.phpR~hj_src/Command/Output.phpR~hj9'src/Command/ClearResultCacheCommand.php R~hj Xdiڤsrc/Command/CommandHelper.php߉R~hj߉xH src/Command/fixer-phar.pubkey R~hj u䪤src/Command/InceptionResult.phpzR~hjzPsrc/Parallel/ProcessPool.phpjR~hjjFsrc/Parallel/Schedule.phpR~hj޻src/Parallel/Scheduler.php R~hj src/Parallel/Process.phpR~hj$~)src/Parallel/ProcessTimedOutException.phpR~hjߤ!src/Parallel/ParallelAnalyser.php!5R~hj!5_#2src/Reflection/SignatureMap/SignatureMapParser.php R~hj Ȥ<src/Reflection/SignatureMap/FunctionSignatureMapProvider.php 'R~hj 'vRp@src/Reflection/SignatureMap/NativeFunctionReflectionProvider.php R~hj 7֥;src/Reflection/SignatureMap/SignatureMapProviderFactory.phpRR~hjR%ڏ4src/Reflection/SignatureMap/SignatureMapProvider.phpR~hjX 72src/Reflection/SignatureMap/ParameterSignature.php?R~hj?ᷤ8src/Reflection/SignatureMap/Php8SignatureMapProvider.phpNR~hjN`Mu1src/Reflection/SignatureMap/FunctionSignature.phpR~hj%src/Reflection/EnumCaseReflection.phpR~hjK"src/Reflection/ClassNameHelper.php R~hj y髤(src/Reflection/ClassMemberReflection.phpdR~hjdY3٤8src/Reflection/Type/IntersectionTypeMethodReflection.phpR~hjDsrc/Reflection/Type/UnionTypeUnresolvedMethodPrototypeReflection.php R~hj 0SФ:src/Reflection/Type/IntersectionTypePropertyReflection.phpnR~hjnT3src/Reflection/Type/UnionTypePropertyReflection.phppR~hjp/~1src/Reflection/Type/UnionTypeMethodReflection.phpTR~hjT?eGsrc/Reflection/Type/CalledOnTypeUnresolvedMethodPrototypeReflection.php?R~hj?cNIsrc/Reflection/Type/CalledOnTypeUnresolvedPropertyPrototypeReflection.phpcR~hjcD耤=src/Reflection/Type/UnresolvedPropertyPrototypeReflection.phpR~hjT`Esrc/Reflection/Type/CallbackUnresolvedPropertyPrototypeReflection.phphR~hjh-3Ksrc/Reflection/Type/IntersectionTypeUnresolvedMethodPrototypeReflection.php R~hj '¤;src/Reflection/Type/UnresolvedMethodPrototypeReflection.phpR~hjC.Msrc/Reflection/Type/IntersectionTypeUnresolvedPropertyPrototypeReflection.php R~hj Cy̤Fsrc/Reflection/Type/UnionTypeUnresolvedPropertyPrototypeReflection.php R~hj ]U_Csrc/Reflection/Type/CallbackUnresolvedMethodPrototypeReflection.php.R~hj.eg0src/Reflection/ParametersAcceptorWithPhpDocs.phpR~hjO$E2src/Reflection/MethodsClassReflectionExtension.php:R~hj:GgN5src/Reflection/CallableFunctionVariantWithPhpDocs.php R~hj 4*Zޤ'src/Reflection/BrokerAwareExtension.phpR~hjJ0src/Reflection/Dummy/DummyPropertyReflection.phpOR~hjOvE3src/Reflection/Dummy/DummyConstructorReflection.php R~hj w.src/Reflection/Dummy/DummyMethodReflection.php R~hj 2gV0src/Reflection/Dummy/DummyConstantReflection.phpuR~hjuA6src/Reflection/Dummy/ChangedTypePropertyReflection.php R~hj m4src/Reflection/Dummy/ChangedTypeMethodReflection.phpR~hj0*-src/Reflection/ResolvedPropertyReflection.phpKR~hjK^p-src/Reflection/ExtendedPropertyReflection.phpR~hjS5src/Reflection/Constant/RuntimeConstantReflection.phpR~hj`@+src/Reflection/PhpVersionStaticAccessor.phpkR~hjkq?5src/Reflection/PropertiesClassReflectionExtension.phpSR~hjS-=[%src/Reflection/PropertyReflection.phpWR~hjWG&src/Reflection/ParameterReflection.phpR~hj`}1Isrc/Reflection/Annotations/AnnotationsMethodsClassReflectionExtension.phpR~hj% 9src/Reflection/Annotations/AnnotationMethodReflection.phpR~hjol㿤;src/Reflection/Annotations/AnnotationPropertyReflection.phpkR~hjkEۡԤLsrc/Reflection/Annotations/AnnotationsPropertiesClassReflectionExtension.phpmR~hjmUaCsrc/Reflection/Annotations/AnnotationsMethodParameterReflection.php.R~hj.3src/Reflection/ClassReflectionExtensionRegistry.php R~hj {#4src/Reflection/WrappedExtendedPropertyReflection.php7R~hj7]Osrc/Reflection/PHPStan/NativeReflectionEnumReturnDynamicReturnTypeExtension.phpR~hjG6src/Reflection/ResolvedFunctionVariantWithCallable.phpR~hjӤ+src/Reflection/ExtendedMethodReflection.phpIR~hjIX\%src/Reflection/InaccessibleMethod.php*R~hj*C؂Dsrc/Reflection/BetterReflection/SourceLocator/FetchedNodesResult.php'R~hj'QOsrc/Reflection/BetterReflection/SourceLocator/OptimizedPsrAutoloaderLocator.phpR~hj[bBVsrc/Reflection/BetterReflection/SourceLocator/OptimizedPsrAutoloaderLocatorFactory.phpsR~hjsǣ/`Qsrc/Reflection/BetterReflection/SourceLocator/OptimizedDirectorySourceLocator.php4R~hj4=Bsrc/Reflection/BetterReflection/SourceLocator/FileNodesFetcher.phpR~hjjn̤Xsrc/Reflection/BetterReflection/SourceLocator/OptimizedDirectorySourceLocatorFactory.phpiR~hjiGsrc/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.phpo6R~hjo6%zTsrc/Reflection/BetterReflection/SourceLocator/NewOptimizedDirectorySourceLocator.php R~hj Rp}=src/Reflection/BetterReflection/SourceLocator/FetchedNode.php R~hj Psrc/Reflection/BetterReflection/SourceLocator/AutoloadFunctionsSourceLocator.phpR~hj[HRsrc/Reflection/BetterReflection/SourceLocator/PhpVersionBlacklistSourceLocator.phpR~hj@src/Reflection/BetterReflection/SourceLocator/CachingVisitor.phpR~hjc$fVMsrc/Reflection/BetterReflection/SourceLocator/SkipClassAliasSourceLocator.phpR~hjsФYsrc/Reflection/BetterReflection/SourceLocator/OptimizedSingleFileSourceLocatorFactory.phpR~hji`src/Reflection/BetterReflection/SourceLocator/ComposerJsonAndInstalledJsonSourceLocatorMaker.php*R~hj*H-[src/Reflection/BetterReflection/SourceLocator/OptimizedDirectorySourceLocatorRepository.phpR~hjbĥ@src/Reflection/BetterReflection/SourceLocator/PhpFileCleaner.php"R~hj"`Nsrc/Reflection/BetterReflection/SourceLocator/ReflectionClassSourceLocator.phpLR~hjL+?\src/Reflection/BetterReflection/SourceLocator/OptimizedSingleFileSourceLocatorRepository.phpR~hj?BPsrc/Reflection/BetterReflection/SourceLocator/RewriteClassAliasSourceLocator.phpR~hj,Ksrc/Reflection/BetterReflection/SourceLocator/FileReadTrapStreamWrapper.php)R~hj)q|Rsrc/Reflection/BetterReflection/SourceLocator/OptimizedSingleFileSourceLocator.php%%R~hj%%K!Hsrc/Reflection/BetterReflection/BetterReflectionSourceLocatorFactory.php!R~hj!"k<src/Reflection/BetterReflection/BetterReflectionProvider.phplTR~hjlT@src/Reflection/BetterReflection/Reflector/MemoizingReflector.phpR~hj'bSsrc/Reflection/BetterReflection/SourceStubber/PhpStormStubsSourceStubberFactory.phpR~hjԊPsrc/Reflection/BetterReflection/SourceStubber/ReflectionSourceStubberFactory.phpR~hjhCsrc/Reflection/BetterReflection/BetterReflectionProviderFactory.php#R~hj#)y9src/Reflection/MissingPropertyFromReflectionException.php}R~hj}D$#src/Reflection/MethodReflection.phpR~hju*6src/Reflection/ResolvedFunctionVariantWithOriginal.php)R~hj)&U,src/Reflection/WrapperPropertyReflection.phpR~hj6@:src/Reflection/AllowedSubTypesClassReflectionExtension.phpR~hjUlb=src/Reflection/Mixin/MixinMethodsClassReflectionExtension.php: R~hj: jVޤ@src/Reflection/Mixin/MixinPropertiesClassReflectionExtension.php R~hj D^פ.src/Reflection/Mixin/MixinMethodReflection.php4R~hj4 #]$src/Reflection/PassedByReference.php%R~hj%B%src/Reflection/ConstantNameHelper.phpR~hjB*src/Reflection/ClassConstantReflection.php\R~hj\\JN%src/Reflection/ConstantReflection.php|R~hj|, = +src/Reflection/ResolvedMethodReflection.php=R~hj=-src/Reflection/ParametersAcceptorSelector.phpR~hjі9src/Reflection/MissingConstantFromReflectionException.php|R~hj|'ʤ3src/Reflection/ReflectionProviderStaticAccessor.phpR~hj2H.src/Reflection/InitializerExprTypeResolver.php,aR~hj,a4ٕ,,src/Reflection/ClassMemberAccessAnswerer.phptR~hjtJ*src/Reflection/ResolvedFunctionVariant.phpR~hjli'Ԥ%src/Reflection/ReflectionProvider.phpR~hjr!4src/Reflection/GenericParametersAcceptorResolver.phpER~hjE =%src/Reflection/ConstructorsHelper.php R~hj (Q2src/Reflection/AdditionalConstructorsExtension.phpR~hj W<"src/Reflection/ClassReflection.php1R~hj1ͤ'%src/Reflection/ParametersAcceptor.phpIR~hjI6UEsrc/Reflection/Php/Soap/SoapClientMethodsClassReflectionExtension.phpR~hj+6src/Reflection/Php/Soap/SoapClientMethodReflection.phpFR~hjFi:src/Reflection/Php/PhpFunctionFromParserNodeReflection.php,R~hj,T"Ȥ2src/Reflection/Php/PhpClassReflectionExtension.php6R~hj6'11src/Reflection/Php/PhpMethodReflectionFactory.phpR~hj8src/Reflection/Php/PhpMethodFromParserNodeReflection.phpR~hj6f2src/Reflection/Php/ClosureCallMethodReflection.phpR~hjYƢ-src/Reflection/Php/PhpParameterReflection.phpzR~hjzf *src/Reflection/Php/PhpMethodReflection.phpxFR~hjxFྤ3src/Reflection/Php/UniversalObjectCrateProperty.phpJR~hjJt?/src/Reflection/Php/SimpleXMLElementProperty.phpR~hj0src/Reflection/Php/EnumCasesMethodReflection.phpS R~hjS Aw)-src/Reflection/Php/ExitFunctionReflection.php R~hj V;src/Reflection/Php/PhpParameterFromParserNodeReflection.phpH R~hjH ^@%src/Reflection/Php/DummyParameter.php R~hj XB@src/Reflection/Php/EnumUnresolvedPropertyPrototypeReflection.phpR~hj'70src/Reflection/Php/DummyParameterWithPhpDocs.phpR~hjj-Dsrc/Reflection/Php/UniversalObjectCratesClassReflectionExtension.php R~hj NN,src/Reflection/Php/PhpFunctionReflection.php.R~hj.-Jդ.src/Reflection/Php/BuiltinMethodReflection.php R~hj l,src/Reflection/Php/PhpPropertyReflection.phpR~hjv4src/Reflection/Php/NativeBuiltinMethodReflection.phpR~hj*KBsrc/Reflection/Php/EnumAllowedSubTypesClassReflectionExtension.php R~hj  Esrc/Reflection/Php/ClosureCallUnresolvedMethodPrototypeReflection.php~R~hj~Kr-src/Reflection/Php/EnumPropertyReflection.phpR~hjT)src/Reflection/InitializerExprContext.phpR~hj"7src/Reflection/MissingMethodFromReflectionException.phpvR~hjvCzb,src/Reflection/FunctionReflectionFactory.phpER~hjEt,src/Reflection/MethodPrototypeReflection.php R~hj # @=src/Reflection/ReflectionProvider/DummyReflectionProvider.phpR~hj1"?src/Reflection/ReflectionProvider/ReflectionProviderFactory.phpSR~hjSG+Fsrc/Reflection/ReflectionProvider/SetterReflectionProviderProvider.phpaR~hja3Asrc/Reflection/ReflectionProvider/MemoizingReflectionProvider.php R~hj T)r@src/Reflection/ReflectionProvider/ReflectionProviderProvider.phpR~hj Dsrc/Reflection/ReflectionProvider/LazyReflectionProviderProvider.php`R~hj`Fsrc/Reflection/ReflectionProvider/DirectReflectionProviderProvider.phpPR~hjPn̪>src/Reflection/Native/NativeParameterWithPhpDocsReflection.php R~hj 52src/Reflection/Native/NativeFunctionReflection.phpR~hjUR3src/Reflection/Native/NativeParameterReflection.phpR~hjatʤ0src/Reflection/Native/NativeMethodReflection.php R~hj A>$src/Reflection/NamespaceAnswerer.phpR~hj\w.src/Reflection/Callables/SimpleImpurePoint.phpR~hjn-src/Reflection/Callables/SimpleThrowPoint.phpR~hjkC4src/Reflection/Callables/FunctionCallableVariant.phptR~hjt,N17src/Reflection/Callables/CallableParametersAcceptor.phpR~hj"R1src/Reflection/ParameterReflectionWithPhpDocs.phpR~hjysrc/Reflection/Assertions.php R~hj kXƤQsrc/Reflection/RequireExtension/RequireExtendsMethodsClassReflectionExtension.phpFR~hjFޤTsrc/Reflection/RequireExtension/RequireExtendsPropertiesClassReflectionExtension.phplR~hjl>-src/Reflection/FunctionVariantWithPhpDocs.phpR~hj src/autoloadFunctions.phpR~hjѤ"src/Diagnose/DiagnoseExtension.phpR~hjפ)src/Diagnose/PHPStanDiagnoseExtension.phpR~hjsrc/dumpType.phpAR~hjA 6src/Analyser/EnsuredNonNullabilityResultExpression.phppR~hjpYCZ%src/Analyser/ProcessClosureResult.phpR~hj 1(src/Analyser/AnalyserResultFinalizer.php%R~hj%p0src/Analyser/Ignore/IgnoredErrorHelperResult.php(R~hj(@q7#src/Analyser/Ignore/IgnoreLexer.phpy R~hjy MZb,src/Analyser/Ignore/IgnoreParseException.phpR~hj툤9src/Analyser/Ignore/IgnoredErrorHelperProcessedResult.php R~hj 48C$src/Analyser/Ignore/IgnoredError.php4 R~hj4 {V%*src/Analyser/Ignore/IgnoredErrorHelper.phpR~hjޓW6src/Analyser/ResultCache/ResultCacheManagerFactory.php R~hj Pk/src/Analyser/ResultCache/ResultCacheManager.phpR~hj8i/src/Analyser/ResultCache/ResultCacheClearer.phpKR~hjKu5src/Analyser/ResultCache/ResultCacheProcessResult.phpwR~hjwv(src/Analyser/ResultCache/ResultCache.phpR~hj}src/Analyser/TypeSpecifier.php2~R~hj2~]#src/Analyser/FileAnalyserResult.phppR~hjpoHN%src/Analyser/TypeSpecifierContext.php R~hj EEsrc/Analyser/ThrowPoint.phpR~hj'#e+src/Analyser/DirectInternalScopeFactory.phpR~hj[1Фsrc/Analyser/FileAnalyser.phpCR~hjC"src/Analyser/NodeScopeResolver.phpx{R~hjx{MUӤ#src/Analyser/StatementExitPoint.phpqR~hjqI%src/Analyser/TypeSpecifierFactory.php=R~hj=yO%src/Analyser/RuleErrorTransformer.php! R~hj! ~&src/Analyser/LocalIgnoresProcessor.php R~hj DWY,src/Analyser/LocalIgnoresProcessorResult.php9R~hj9 n,src/Analyser/ConditionalExpressionHolder.phpR~hjp7src/Analyser/Analyser.phpR~hjL)src/Analyser/RicherScopeGetTypeHelper.php" R~hj" src/Analyser/ScopeContext.php R~hj *src/Analyser/Error.phpR~hj_I%src/Analyser/ExpressionTypeHolder.phpR~hj*-src/Analyser/ScopeFactory.phpR~hjC$src/Analyser/ArgumentsNormalizer.phpR~hj l src/Analyser/StatementResult.phpR~hj.: src/Analyser/FinalizerResult.phpLR~hjLKsrc/Analyser/ImpurePoint.phpR~hjv? src/Analyser/OutOfClassScope.phpR~hj#src/Analyser/Scope.phpR~hj]{src/Analyser/SpecifiedTypes.php^R~hj^Z=src/Analyser/MutatingScope.php\R~hj\8'src/Analyser/NullsafeOperatorHelper.php R~hj src/Analyser/AnalyserResult.php}R~hj}M̤,src/Analyser/EnsuredNonNullabilityResult.phpWR~hjW{=msrc/Analyser/NameScope.phpIR~hjIe=9src/Analyser/InternalError.phpx R~hjx m&x"src/Analyser/ExpressionContext.phpR~hjn,a!src/Analyser/StatementContext.phpR~hj_8(src/Analyser/ConstantResolverFactory.php?R~hj?)&%src/Analyser/InternalScopeFactory.phpR~hjϤƷ)src/Analyser/LazyInternalScopeFactory.phpR~hj9i!src/Analyser/ExpressionResult.phpU R~hjU #src/Analyser/EndStatementResult.phpiR~hji>,src/Analyser/TypeSpecifierAwareExtension.phpR~hjQ+src/Analyser/UndefinedVariableException.php;R~hj;!!src/Analyser/ConstantResolver.php+R~hj+31src/Cache/CacheStorage.php0R~hj0 src/Cache/MemoryCacheStorage.phpOR~hjO kBsrc/Cache/CacheItem.php8R~hj8OIWsrc/Cache/FileCacheStorage.phpO R~hjO ,#ysrc/Cache/Cache.phpgR~hjg`src/debugScope.phpR~hj $src/Php/PhpVersionFactoryFactory.phpR~hj娾src/Php/PhpVersion.php+"R~hj+"P\src/Php/PhpVersionFactory.phpR~hj^ Ф preload.phpR~hj6aդconf/config.neonR~hjDLconf/config.level0.neonp+R~hjp+Uf(conf/config.stubValidator.neon-R~hj-kconf/bleedingEdge.neonR~hjDconf/config.level9.neonHR~hjHuconf/config.level1.neonR~hj?$conf/config.level7.neonYR~hjY^bZconf/config.levelmax.neon!R~hj!hconf/config.level5.neonBR~hjBO'conf/parametersSchema.neonR~hjxconf/config.level3.neonF R~hjF D~conf/config.level4.neon-R~hj-'ϟconf/config.level8.neonDR~hjDsJcconf/config.level2.neonR~hj <conf/config.level6.neonR~hj?~%vendor/ondram/ci-detector/src/Env.phpR~hj1vendor/ondram/ci-detector/src/Ci/AwsCodeBuild.phpR~hj 8/vendor/ondram/ci-detector/src/Ci/AbstractCi.phpR~hjq+vendor/ondram/ci-detector/src/Ci/Circle.phpR~hj+vendor/ondram/ci-detector/src/Ci/GitLab.phpR~hj+vendor/ondram/ci-detector/src/Ci/Travis.phpR~hj# ,vendor/ondram/ci-detector/src/Ci/Wercker.php.R~hj.Yg-vendor/ondram/ci-detector/src/Ci/TeamCity.phpR~hjr-vendor/ondram/ci-detector/src/Ci/AppVeyor.phpR~hjGN*vendor/ondram/ci-detector/src/Ci/Buddy.phpR~hj--vendor/ondram/ci-detector/src/Ci/Codeship.phpR~hjZ2vendor/ondram/ci-detector/src/Ci/GitHubActions.phpR~hjc7vendor/ondram/ci-detector/src/Ci/BitbucketPipelines.phpR~hj+vendor/ondram/ci-detector/src/Ci/Bamboo.php8R~hj8X>0vendor/ondram/ci-detector/src/Ci/CiInterface.phpR~hjU,vendor/ondram/ci-detector/src/Ci/Jenkins.phpR~hj*vendor/ondram/ci-detector/src/Ci/Drone.php2R~hj2}2vendor/ondram/ci-detector/src/Ci/Continuousphp.phpiR~hjil.vendor/ondram/ci-detector/src/TrinaryLogic.php?R~hj? Bvendor/ondram/ci-detector/src/Exception/CiNotDetectedException.phpR~hj=o,vendor/ondram/ci-detector/src/CiDetector.php R~hj VA3vendor/ondrejmirtes/better-reflection/renovate.jsonR~hj{Vvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/ComposerSourceLocator.phpR~hjҤVvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/AbstractSourceLocator.php= R~hj= *|vendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJsonAndInstalledJson.phpo R~hjo :lvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJson.phpR~hjL+mvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Factory/MakeLocatorForInstalledJson.phpR~hj#@pvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Factory/Exception/MissingInstalledJson.phpR~hj"osvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Factory/Exception/InvalidProjectDirectory.phpR~hj!4lovendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Factory/Exception/MissingComposerJson.phpR~hjT_ʤevendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Factory/Exception/Exception.phpR~hjZ\mvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Factory/Exception/FailedToParseJson.phpR~hj'<^vendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/PsrAutoloaderLocator.php R~hj X4mbvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Psr/PsrAutoloaderMapping.phpvR~hjv'֤Yvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Psr/Psr0Mapping.phpGR~hjG'eYvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Psr/Psr4Mapping.php R~hj lvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Psr/Exception/InvalidPrefixMapping.phpsR~hjs󴜤avendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/Composer/Psr/Exception/Exception.phpR~hjZvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/FileIteratorSourceLocator.php R~hj ʑqWYvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/DirectoriesSourceLocator.phpR~hj8QvYTvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/StringSourceLocator.php1R~hj1<>٤Vvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/AutoloadSourceLocator.php.R~hj.ySXvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/SingleFileSourceLocator.phpTR~hjTzE{GWvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/MemoizingSourceLocator.php R~hj _ۤNvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/SourceLocator.php+R~hj+C=Wvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/AggregateSourceLocator.phpR~hjHpvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/AutoloadSourceLocator/FileReadTrapStreamWrapper.php~R~hj~J`Uvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/ClosureSourceLocator.php}R~hj}M$Фbvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/AnonymousClassObjectSourceLocator.phpDR~hjDNwXvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/EvaledCodeSourceLocator.phpR~hjWvYvendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/PhpInternalSourceLocator.php2 R~hj2 Wvendor/ondrejmirtes/better-reflection/src/SourceLocator/Located/EvaledLocatedSource.php4R~hj4{rjVvendor/ondrejmirtes/better-reflection/src/SourceLocator/Located/AliasLocatedSource.phpOR~hjOZvendor/ondrejmirtes/better-reflection/src/SourceLocator/Located/AnonymousLocatedSource.phptR~hjtm Qvendor/ondrejmirtes/better-reflection/src/SourceLocator/Located/LocatedSource.php R~hj SΤYvendor/ondrejmirtes/better-reflection/src/SourceLocator/Located/InternalLocatedSource.php R~hj zavendor/ondrejmirtes/better-reflection/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php(zR~hj(zL5^fvendor/ondrejmirtes/better-reflection/src/SourceLocator/SourceStubber/PhpStormStubs/CachingVisitor.phptR~hjt`vendor/ondrejmirtes/better-reflection/src/SourceLocator/SourceStubber/AggregateSourceStubber.phpR~hj)Wvendor/ondrejmirtes/better-reflection/src/SourceLocator/SourceStubber/SourceStubber.phpR~hjϭRvendor/ondrejmirtes/better-reflection/src/SourceLocator/SourceStubber/StubData.phpR~hj$դmvendor/ondrejmirtes/better-reflection/src/SourceLocator/SourceStubber/Exception/CouldNotFindPhpStormStubs.php0R~hj0~dvendor/ondrejmirtes/better-reflection/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php|R~hj|fE \vendor/ondrejmirtes/better-reflection/src/SourceLocator/Exception/NoAnonymousClassOnLine.phpR~hj\Vvendor/ondrejmirtes/better-reflection/src/SourceLocator/Exception/InvalidDirectory.phpR~hjdTbvendor/ondrejmirtes/better-reflection/src/SourceLocator/Exception/EvaledClosureCannotBeLocated.php$R~hj$dϤUvendor/ondrejmirtes/better-reflection/src/SourceLocator/Exception/InvalidFileInfo.php+R~hj+J"Wvendor/ondrejmirtes/better-reflection/src/SourceLocator/Exception/FunctionUndefined.phpVR~hjVN0ivendor/ondrejmirtes/better-reflection/src/SourceLocator/Exception/EvaledAnonymousClassCannotBeLocated.php3R~hj36ǮUvendor/ondrejmirtes/better-reflection/src/SourceLocator/Exception/NoClosureOnLine.phppR~hjpGcvendor/ondrejmirtes/better-reflection/src/SourceLocator/Exception/TwoAnonymousClassesOnSameLine.phpR~hjM/Yvendor/ondrejmirtes/better-reflection/src/SourceLocator/Exception/InvalidFileLocation.phpR~hjVvendor/ondrejmirtes/better-reflection/src/SourceLocator/Exception/NotInternalClass.phpR~hjzׯ[vendor/ondrejmirtes/better-reflection/src/SourceLocator/Exception/TwoClosuresOnSameLine.phprR~hjrӤUvendor/ondrejmirtes/better-reflection/src/SourceLocator/Ast/FindReflectionsInTree.php0R~hj0d Vvendor/ondrejmirtes/better-reflection/src/SourceLocator/Ast/Parser/MemoizingParser.phpR~hjg ^vendor/ondrejmirtes/better-reflection/src/SourceLocator/Ast/Strategy/AstConversionStrategy.phpR~hjϜYvendor/ondrejmirtes/better-reflection/src/SourceLocator/Ast/Strategy/NodeToReflection.php R~hj |~Gvendor/ondrejmirtes/better-reflection/src/SourceLocator/Ast/Locator.php( R~hj( a[vendor/ondrejmirtes/better-reflection/src/SourceLocator/Ast/Exception/ParseToAstFailure.phpR~hjJ:Gvendor/ondrejmirtes/better-reflection/src/SourceLocator/FileChecker.phpR~hj)MHvendor/ondrejmirtes/better-reflection/src/NodeCompiler/CompiledValue.phpR~hj_Jvendor/ondrejmirtes/better-reflection/src/NodeCompiler/CompilerContext.php_R~hj_ZWMvendor/ondrejmirtes/better-reflection/src/NodeCompiler/CompileNodeToValue.php3R~hj3TXvendor/ondrejmirtes/better-reflection/src/NodeCompiler/Exception/UnableToCompileNode.phpR~hjvNҺKvendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionEnumCase.phpR~hj='Kvendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionProperty.php"KR~hj"K]Svendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionIntersectionType.php R~hj Vvendor/ondrejmirtes/better-reflection/src/Reflection/Support/AlreadyVisitedClasses.php]R~hj]%0Hvendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionClass.phpR~hj ZCvendor/ondrejmirtes/better-reflection/src/Reflection/Reflection.phpR~hjRuKIvendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionObject.php6R~hj6PBeevendor/ondrejmirtes/better-reflection/src/Reflection/StringCast/ReflectionClassConstantStringCast.phpR~hjm4`vendor/ondrejmirtes/better-reflection/src/Reflection/StringCast/ReflectionPropertyStringCast.phpJR~hjJ/avendor/ondrejmirtes/better-reflection/src/Reflection/StringCast/ReflectionAttributeStringCast.phpWR~hjWhW]vendor/ondrejmirtes/better-reflection/src/Reflection/StringCast/ReflectionClassStringCast.php(#R~hj(#U^vendor/ondrejmirtes/better-reflection/src/Reflection/StringCast/ReflectionMethodStringCast.phpyR~hjy+`vendor/ondrejmirtes/better-reflection/src/Reflection/StringCast/ReflectionConstantStringCast.phpR~hjp`vendor/ondrejmirtes/better-reflection/src/Reflection/StringCast/ReflectionFunctionStringCast.php R~hj F[3avendor/ondrejmirtes/better-reflection/src/Reflection/StringCast/ReflectionParameterStringCast.phpeR~hje *`vendor/ondrejmirtes/better-reflection/src/Reflection/StringCast/ReflectionEnumCaseStringCast.phpR~hj2^\vendor/ondrejmirtes/better-reflection/src/Reflection/StringCast/ReflectionTypeStringCast.php:R~hj:l1τLvendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionAttribute.phpR~hjĤLvendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionNamedType.php.R~hj.\ڤLvendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionParameter.php?ER~hj?E ISvendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionFunctionAbstract.phpj<R~hjj<LGvendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionType.phpV R~hjV =aLvendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionUnionType.php R~hj XQvendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionObject.phprGR~hjrGeTvendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionAttribute.phpR~hjC,Tvendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionNamedType.phpR~hjSNTvendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionParameter.phpt#R~hjt#.Ovendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionType.php R~hj Rc/FTvendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionUnionType.phpR~hj|Qvendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionMethod.phpV-R~hjV-S <Xvendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionClassConstant.phphR~hjh̬![vendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionAttributeFactory.php6R~hj6Svendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionFunction.php\"R~hj\"MaWvendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionEnumUnitCase.phpR~hj1?~Xvendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/FakeReflectionAttribute.phpR~hjr Yvendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/Exception/NotImplemented.phpR~hjIReOvendor/ondrejmirtes/better-reflection/src/Reflection/Adapter/ReflectionEnum.phpSKR~hjSKWKvendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionConstant.php'R~hj'Zvendor/ondrejmirtes/better-reflection/src/Reflection/Exception/MethodPrototypeNotFound.phpR~hj27VWvendor/ondrejmirtes/better-reflection/src/Reflection/Exception/PropertyDoesNotExist.php]R~hj]/7i[Zvendor/ondrejmirtes/better-reflection/src/Reflection/Exception/InvalidDefaultValueType.phpR~hjudBNvendor/ondrejmirtes/better-reflection/src/Reflection/Exception/NotAnObject.phpR~hjVvendor/ondrejmirtes/better-reflection/src/Reflection/Exception/CodeLocationMissing.phpR~hjKvendor/ondrejmirtes/better-reflection/src/Reflection/Exception/NoParent.phpR~hjߤ_vendor/ondrejmirtes/better-reflection/src/Reflection/Exception/InvalidArrowFunctionBodyNode.php,R~hj,pJͤVvendor/ondrejmirtes/better-reflection/src/Reflection/Exception/InvalidConstantNode.phpR~hj ՗Wvendor/ondrejmirtes/better-reflection/src/Reflection/Exception/FunctionDoesNotExist.php{R~hj{cTvendor/ondrejmirtes/better-reflection/src/Reflection/Exception/ClassDoesNotExist.phpR~hjnSvendor/ondrejmirtes/better-reflection/src/Reflection/Exception/NoObjectProvided.phpR~hj/Tvendor/ondrejmirtes/better-reflection/src/Reflection/Exception/CircularReference.phpmR~hjm"Vvendor/ondrejmirtes/better-reflection/src/Reflection/Exception/PropertyIsNotStatic.php[R~hj[[vendor/ondrejmirtes/better-reflection/src/Reflection/Exception/ObjectNotInstanceOfClass.phpxR~hjx w\vendor/ondrejmirtes/better-reflection/src/Reflection/Attribute/ReflectionAttributeHelper.php3 R~hj3 KGvendor/ondrejmirtes/better-reflection/src/Reflection/ReflectionEnum.phpjR~hjj 2Ivendor/ondrejmirtes/better-reflection/src/Reflector/ConstantReflector.phpR~hj$EIvendor/ondrejmirtes/better-reflection/src/Reflector/FunctionReflector.phpR~hja8ҤAvendor/ondrejmirtes/better-reflection/src/Reflector/Reflector.phpR~hjbyFvendor/ondrejmirtes/better-reflection/src/Reflector/ClassReflector.phpR~hjEHvendor/ondrejmirtes/better-reflection/src/Reflector/DefaultReflector.phpR~hjTvendor/ondrejmirtes/better-reflection/src/Reflector/Exception/IdentifierNotFound.phpLR~hjLޤ'Gvendor/ondrejmirtes/better-reflection/src/Util/FindReflectionOnLine.phpR~hjP5ˤHvendor/ondrejmirtes/better-reflection/src/Util/ClassExistenceChecker.php{R~hj{JFvendor/ondrejmirtes/better-reflection/src/Util/ConstantNodeChecker.phpR~hj߸CPvendor/ondrejmirtes/better-reflection/src/Util/Exception/InvalidNodePosition.phpVR~hjV>UݤKvendor/ondrejmirtes/better-reflection/src/Util/Exception/NoNodePosition.phpR~hj$Dvendor/ondrejmirtes/better-reflection/src/Util/GetLastDocComment.phpR~hjt=vendor/ondrejmirtes/better-reflection/src/Util/FileHelper.phpf R~hjf AuLLvendor/ondrejmirtes/better-reflection/src/Util/CalculateReflectionColumn.phpR~hj5_>vendor/ondrejmirtes/better-reflection/src/BetterReflection.phpR~hjJSo3Gvendor/ondrejmirtes/better-reflection/src/Identifier/IdentifierType.phpR~hjlޤCvendor/ondrejmirtes/better-reflection/src/Identifier/Identifier.phpR~hjqb!Xvendor/ondrejmirtes/better-reflection/src/Identifier/Exception/InvalidIdentifierName.phpeR~hjeZJ-vendor/ondrejmirtes/better-reflection/LICENSE6R~hj6Wwvendor/autoload.phpR~hjv֤>vendor/jetbrains/phpstorm-stubs/parallel/parallel/Runtime.stubR~hj0ˤNvendor/jetbrains/phpstorm-stubs/parallel/parallel/Sync/Error/IllegalValue.stubeR~hje> wAvendor/jetbrains/phpstorm-stubs/parallel/parallel/Sync/Error.stubHR~hjHb=vendor/jetbrains/phpstorm-stubs/parallel/parallel/Events.stub R~hj ܤNvendor/jetbrains/phpstorm-stubs/parallel/parallel/Channel/Error/Existence.stubhR~hjhyäKvendor/jetbrains/phpstorm-stubs/parallel/parallel/Channel/Error/Closed.stubeR~hjez Qvendor/jetbrains/phpstorm-stubs/parallel/parallel/Channel/Error/IllegalValue.stubkR~hjkDvendor/jetbrains/phpstorm-stubs/parallel/parallel/Channel/Error.stubKR~hjK%Nvendor/jetbrains/phpstorm-stubs/parallel/parallel/Runtime/Error/Bootstrap.stubhR~hjhUR~hj>^Qvendor/jetbrains/phpstorm-stubs/parallel/parallel/Runtime/Object/Unavailable.stub@R~hj@:ǦDvendor/jetbrains/phpstorm-stubs/parallel/parallel/Runtime/Error.stubKR~hjK;vendor/jetbrains/phpstorm-stubs/parallel/parallel/Sync.stubR~hj4R=vendor/jetbrains/phpstorm-stubs/parallel/parallel/Future.stub`R~hj`.?Dä>vendor/jetbrains/phpstorm-stubs/parallel/parallel/Channel.stub(R~hj(&Mvendor/jetbrains/phpstorm-stubs/parallel/parallel/Events/Error/Existence.stubfR~hjfRbKvendor/jetbrains/phpstorm-stubs/parallel/parallel/Events/Error/Timeout.stubdR~hjdJ6Svendor/jetbrains/phpstorm-stubs/parallel/parallel/Events/Input/Error/Existence.stubrR~hjr7oVvendor/jetbrains/phpstorm-stubs/parallel/parallel/Events/Input/Error/IllegalValue.stubuR~hjuiIvendor/jetbrains/phpstorm-stubs/parallel/parallel/Events/Input/Error.stubPR~hjP?Cvendor/jetbrains/phpstorm-stubs/parallel/parallel/Events/Error.stubJR~hjJžCvendor/jetbrains/phpstorm-stubs/parallel/parallel/Events/Input.stub0R~hj0>Cvendor/jetbrains/phpstorm-stubs/parallel/parallel/Events/Event.stubR~hj̀8Hvendor/jetbrains/phpstorm-stubs/parallel/parallel/Events/Event/Type.stub.R~hj.ϞZ>Ivendor/jetbrains/phpstorm-stubs/parallel/parallel/Events/Event/Error.stubPR~hjPRJvendor/jetbrains/phpstorm-stubs/parallel/parallel/Future/Error/Killed.stub\R~hj\< Kvendor/jetbrains/phpstorm-stubs/parallel/parallel/Future/Error/Foreign.stub]R~hj]}Mvendor/jetbrains/phpstorm-stubs/parallel/parallel/Future/Error/Cancelled.stub_R~hj_Cvendor/jetbrains/phpstorm-stubs/parallel/parallel/Future/Error.stubJR~hjJb<vendor/jetbrains/phpstorm-stubs/parallel/parallel/Error.stub:R~hj:{6vendor/jetbrains/phpstorm-stubs/parallel/parallel.stubR~hjz.vendor/jetbrains/phpstorm-stubs/geos/geos.stubAR~hjAU.vendor/jetbrains/phpstorm-stubs/judy/judy.stubF"R~hjF"q32vendor/jetbrains/phpstorm-stubs/random/random.stubR~hj^50vendor/jetbrains/phpstorm-stubs/redis/Redis.stubR~hj*Y5vendor/jetbrains/phpstorm-stubs/redis/RedisArray.stubLR~hjLfL7vendor/jetbrains/phpstorm-stubs/redis/RedisCluster.stub,R~hj,IU8vendor/jetbrains/phpstorm-stubs/redis/RedisSentinel.stubR~hjz A.vendor/jetbrains/phpstorm-stubs/snmp/snmp.stubR~hj.vendor/jetbrains/phpstorm-stubs/grpc/grpc.stubYR~hjYXK٤0vendor/jetbrains/phpstorm-stubs/uuid/uuid_c.stub R~hj }j.vendor/jetbrains/phpstorm-stubs/dom/dom_n.stub R~hj ~,vendor/jetbrains/phpstorm-stubs/dom/dom.stubyR~hjy9.vendor/jetbrains/phpstorm-stubs/dom/dom_c.stub_R~hj_4vendor/jetbrains/phpstorm-stubs/imap/Connection.stubHR~hjHF?.vendor/jetbrains/phpstorm-stubs/imap/imap.stub;R~hj;Е.vendor/jetbrains/phpstorm-stubs/exif/exif.stubR~hj 0 Ѥ.vendor/jetbrains/phpstorm-stubs/amqp/amqp.stub3R~hj3{8vendor/jetbrains/phpstorm-stubs/ZendUtils/ZendUtils.stub8R~hj8܌.vendor/jetbrains/phpstorm-stubs/pcov/pcov.stubR~hj\X,vendor/jetbrains/phpstorm-stubs/svn/svn.stublR~hjl R4vendor/jetbrains/phpstorm-stubs/leveldb/LevelDB.stubR~hj;4vendor/jetbrains/phpstorm-stubs/aerospike/Bytes.stub R~hj ʍ8vendor/jetbrains/phpstorm-stubs/aerospike/aerospike.stub24R~hj24ٸe4vendor/jetbrains/phpstorm-stubs/gearman/gearman.stubR~hjଉ,vendor/jetbrains/phpstorm-stubs/dio/dio.stub%R~hj%'&.vendor/jetbrains/phpstorm-stubs/dio/dio_d.stubR~hjC/vendor/jetbrains/phpstorm-stubs/Inspections.xmlR~hjwl.vendor/jetbrains/phpstorm-stubs/tidy/tidy.stubLR~hjLדN8vendor/jetbrains/phpstorm-stubs/xlswriter/xlswriter.stub'>R~hj'>@2vendor/jetbrains/phpstorm-stubs/xmlrpc/xmlrpc.stubR~hj.vendor/jetbrains/phpstorm-stubs/sync/sync.stubi7R~hji7VB2vendor/jetbrains/phpstorm-stubs/SaxonC/SaxonC.stublR~hjl# ,vendor/jetbrains/phpstorm-stubs/rrd/rrd.stub0R~hj0Τ6vendor/jetbrains/phpstorm-stubs/simdjson/simdjson.stub/R~hj/P^4vendor/jetbrains/phpstorm-stubs/gmagick/gmagick.stubjR~hjjY\ ,vendor/jetbrains/phpstorm-stubs/yar/yar.stubR~hjۤ0vendor/jetbrains/phpstorm-stubs/curl/curl_d.stubNR~hjNr.W?8vendor/jetbrains/phpstorm-stubs/curl/CURLStringFile.stubR~hj@b.vendor/jetbrains/phpstorm-stubs/curl/curl.stubsR~hjs/vendor/jetbrains/phpstorm-stubs/regex/ereg.stubz R~hjz =cP0vendor/jetbrains/phpstorm-stubs/pcntl/pcntl.stubYXR~hjYXۖ<Ȥ2vendor/jetbrains/phpstorm-stubs/pcntl/pcntl_c.stubR~hjzEh.vendor/jetbrains/phpstorm-stubs/yaml/yaml.stubhR~hjh{Ȥ8vendor/jetbrains/phpstorm-stubs/ZendCache/ZendCache.stub R~hj ab;vendor/jetbrains/phpstorm-stubs/couchbase_v2/couchbase.stubR~hjdz :vendor/jetbrains/phpstorm-stubs/couchbase_v2/toplevel.stubWR~hjWa->4vendor/jetbrains/phpstorm-stubs/suhosin/suhosin.stubR~hjQ8vendor/jetbrains/phpstorm-stubs/winbinder/winbinder.stubxR~hjx:0vendor/jetbrains/phpstorm-stubs/stats/stats.stub"HR~hj"He.vendor/jetbrains/phpstorm-stubs/fann/fann.stubhR~hjha*@vendor/jetbrains/phpstorm-stubs/mosquitto-php/mosquitto-php.stubq5R~hjq5H^2vendor/jetbrains/phpstorm-stubs/xhprof/xhprof.stubR~hjg"դ,vendor/jetbrains/phpstorm-stubs/ftp/ftp.stubiR~hjiy("3vendor/jetbrains/phpstorm-stubs/ftp/Connection.stubGR~hjG!2vendor/jetbrains/phpstorm-stubs/docker-compose.ymlZR~hjZzNq.vendor/jetbrains/phpstorm-stubs/ming/ming.stubr"R~hjr"2: 6vendor/jetbrains/phpstorm-stubs/pthreads/pthreads.stubHR~hjH>90vendor/jetbrains/phpstorm-stubs/oci8/oci8v3.stubE9R~hjE9.vendor/jetbrains/phpstorm-stubs/oci8/oci8.stuboR~hjoh!p2vendor/jetbrains/phpstorm-stubs/sodium/sodium.stubR~hj D*vendor/jetbrains/phpstorm-stubs/Ev/Ev.stubR~hjr+vendor/jetbrains/phpstorm-stubs/qodana.yaml R~hj 'JX;8vendor/jetbrains/phpstorm-stubs/memcached/memcached.stubR~hjH@.vendor/jetbrains/phpstorm-stubs/apcu/apcu.stub[nR~hj[nF9vendor/jetbrains/phpstorm-stubs/snappy/snappy/snappy.stubR~hj 0vendor/jetbrains/phpstorm-stubs/mssql/mssql.stub6MR~hj6MW˟8vendor/jetbrains/phpstorm-stubs/xmlreader/xmlreader.stubsDR~hjsD+{ˤ9vendor/jetbrains/phpstorm-stubs/Parle/LexerException.stubwR~hjw^Ut0vendor/jetbrains/phpstorm-stubs/Parle/Token.stubR~hjN1vendor/jetbrains/phpstorm-stubs/Parle/RLexer.stubR~hj w0vendor/jetbrains/phpstorm-stubs/Parle/Lexer.stub*R~hj*; 2vendor/jetbrains/phpstorm-stubs/Parle/RParser.stubR~hjɥФ1vendor/jetbrains/phpstorm-stubs/Parle/Parser.stub,R~hj,0vendor/jetbrains/phpstorm-stubs/Parle/Stack.stubAR~hjA.>o_:vendor/jetbrains/phpstorm-stubs/Parle/ParserException.stubxR~hjxL4vendor/jetbrains/phpstorm-stubs/Parle/ErrorInfo.stubAR~hjA4vendor/jetbrains/phpstorm-stubs/sysvsem/sysvsem.stub R~hj zX@vendor/jetbrains/phpstorm-stubs/mysql_xdevapi/mysql_xdevapi.stubR~hj^6vendor/jetbrains/phpstorm-stubs/mbstring/mbstring.stubR~hjK M2vendor/jetbrains/phpstorm-stubs/libxml/libxml.stub$R~hj$V92vendor/jetbrains/phpstorm-stubs/crypto/crypto.stub1?R~hj1?ګפ0vendor/jetbrains/phpstorm-stubs/date/date_c.stubšR~hjš?Ao0vendor/jetbrains/phpstorm-stubs/date/date_d.stub"R~hj"e.vendor/jetbrains/phpstorm-stubs/date/date.stub+R~hj+s4vendor/jetbrains/phpstorm-stubs/SplType/SplType.stub R~hj o6vendor/jetbrains/phpstorm-stubs/mqseries/mqseries.stubR~hj1%6vendor/jetbrains/phpstorm-stubs/libevent/libevent.stub"YR~hj"Y08vendor/jetbrains/phpstorm-stubs/mailparse/mailparse.stubwR~hjwr4vendor/jetbrains/phpstorm-stubs/session/session.stubiGR~hjiGޤ;vendor/jetbrains/phpstorm-stubs/session/SessionHandler.stub[(R~hj[(mf.vendor/jetbrains/phpstorm-stubs/gd/GdFont.stub3R~hj3`I=*vendor/jetbrains/phpstorm-stubs/gd/gd.stubR~hj*vendor/jetbrains/phpstorm-stubs/ds/ds.stubR~hjREJvendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient.stubR~hj!Bvendor/jetbrains/phpstorm-stubs/simple_kafka_client/functions.stubR~hjBQRvendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/Message.stubR~hjk^vendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/KafkaErrorException.stubR~hji',Svendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/Metadata.stub9R~hj9!aXvendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/Configuration.stubxR~hjxռvYvendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/TopicPartition.stub&R~hj&>~Svendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/Producer.stubR~hjИSvendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/Consumer.stubWR~hjWZvendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/Metadata/Broker.stub9R~hj9uo`Yvendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/Metadata/Topic.stubSR~hjS\]vendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/Metadata/Partition.stubR~hjg^vendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/Metadata/Collection.stub R~hj Pvendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/Topic.stubR~hj Tvendor/jetbrains/phpstorm-stubs/simple_kafka_client/SimpleKafkaClient/Exception.stubdR~hjdYv:vendor/jetbrains/phpstorm-stubs/libsodium/libsodium_d.stub@R~hj@+Ƥ:vendor/jetbrains/phpstorm-stubs/libsodium/libsodium_f.stubR~hjړ+8vendor/jetbrains/phpstorm-stubs/libsodium/libsodium.stube<R~hje<`-8vendor/jetbrains/phpstorm-stubs/couchbase/couchbase.stubR~hjCƤ0vendor/jetbrains/phpstorm-stubs/geoip/geoip.stub$R~hj$66vendor/jetbrains/phpstorm-stubs/standard/password.stub'R~hj'Ou8vendor/jetbrains/phpstorm-stubs/standard/standard_4.stubR~hjgR8vendor/jetbrains/phpstorm-stubs/standard/standard_1.stublR~hjlO8vendor/jetbrains/phpstorm-stubs/standard/standard_0.stub$R~hj$>9vendor/jetbrains/phpstorm-stubs/standard/standard_10.stubR~hj@G8vendor/jetbrains/phpstorm-stubs/standard/standard_3.stubyyR~hjyynN3vendor/jetbrains/phpstorm-stubs/standard/basic.stub,R~hj,ND>vendor/jetbrains/phpstorm-stubs/standard/standard_defines.stub R~hj ~۞4vendor/jetbrains/phpstorm-stubs/standard/_types.stubHR~hjHW8vendor/jetbrains/phpstorm-stubs/standard/standard_8.stubR~hj=N8vendor/jetbrains/phpstorm-stubs/standard/standard_6.stubR~hjbQ8vendor/jetbrains/phpstorm-stubs/standard/standard_2.stub"R~hj"-Qʤ8vendor/jetbrains/phpstorm-stubs/standard/standard_9.stubR~hj/c;/8vendor/jetbrains/phpstorm-stubs/standard/standard_7.stubR~hj.Ť>vendor/jetbrains/phpstorm-stubs/standard/_standard_manual.stub)R~hj)ػD8vendor/jetbrains/phpstorm-stubs/standard/standard_5.stubÄR~hjÄ 4:vendor/jetbrains/phpstorm-stubs/frankenphp/frankenphp.stubR~hjx0vendor/jetbrains/phpstorm-stubs/xdiff/xdiff.stub"(R~hj"(7vendor/jetbrains/phpstorm-stubs/tokenizer/PhpToken.stubR~hj&8vendor/jetbrains/phpstorm-stubs/tokenizer/tokenizer.stubR~hj&>vendor/jetbrains/phpstorm-stubs/ZendDebugger/ZendDebugger.stubR~hjw!6vendor/jetbrains/phpstorm-stubs/wincache/wincache.stubaR~hjaЃ 4vendor/jetbrains/phpstorm-stubs/msgpack/msgpack.stubXR~hjX2d\,vendor/jetbrains/phpstorm-stubs/xsl/xsl.stub;R~hj;$Ȥ.vendor/jetbrains/phpstorm-stubs/v8js/v8js.stubR~hjU90vendor/jetbrains/phpstorm-stubs/pgsql/pgsql.stubsR~hjs Tj2vendor/jetbrains/phpstorm-stubs/pgsql/pgsql_c.stubR~hj޲2vendor/jetbrains/phpstorm-stubs/mysqli/mysqli.stub2R~hj2?4vendor/jetbrains/phpstorm-stubs/sysvmsg/sysvmsg.stub&R~hj&jΤ6vendor/jetbrains/phpstorm-stubs/readline/readline.stubCR~hjCc/vendor/jetbrains/phpstorm-stubs/SPL/SPL_c1.stub ?R~hj ?L,vendor/jetbrains/phpstorm-stubs/SPL/SPL.stubR~hjh .vendor/jetbrains/phpstorm-stubs/SPL/SPL_f.stubmR~hjmO:äFvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionEnumUnitCase.stubR~hjE;Cvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionUnionType.stub R~hj ˜Cvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionAttribute.stubR~hjזCvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionNamedType.stubpR~hjp'Bvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionFunction.stubR~hjbCvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionExtension.stub2R~hj2~?vendor/jetbrains/phpstorm-stubs/Reflection/ReflectionClass.stub\R~hj\ۆ$9vendor/jetbrains/phpstorm-stubs/Reflection/Reflector.stubR~hjT>vendor/jetbrains/phpstorm-stubs/Reflection/ReflectionType.stubR~hjR?vendor/jetbrains/phpstorm-stubs/Reflection/ReflectionFiber.stubR~hj*a@vendor/jetbrains/phpstorm-stubs/Reflection/ReflectionMethod.stubU*R~hjU*@vendor/jetbrains/phpstorm-stubs/Reflection/ReflectionObject.stubR~hj0Hvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionEnumBackedCase.stubPR~hjPgCvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionParameter.stub'R~hj'EOJvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionFunctionAbstract.stubh(R~hjh(#@vendor/jetbrains/phpstorm-stubs/Reflection/PropertyHookType.stub3R~hj3FCvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionException.stubR~hj#5Bvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionConstant.stubR~hj|Gvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionZendExtension.stub R~hj b{`Jvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionIntersectionType.stubR~hj6c8Cvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionReference.stubR~hj؆5>vendor/jetbrains/phpstorm-stubs/Reflection/ReflectionEnum.stubR~hjNBvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionProperty.stuba.R~hja. -:vendor/jetbrains/phpstorm-stubs/Reflection/Reflection.stubR~hjCCvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionGenerator.stubL R~hjL +KGvendor/jetbrains/phpstorm-stubs/Reflection/ReflectionClassConstant.stub4R~hj4|,vendor/jetbrains/phpstorm-stubs/bz2/bz2.stubqR~hjq4 <vendor/jetbrains/phpstorm-stubs/elastic_apm/elastic_apm.stub~R~hj~4vendor/jetbrains/phpstorm-stubs/PhpStormStubsMap.php" R~hj" 1 Ǘ8vendor/jetbrains/phpstorm-stubs/zookeeper/zookeeper.stub")R~hj") ޛ?vendor/jetbrains/phpstorm-stubs/superglobals/_superglobals.stubR~hjFe5vendor/jetbrains/phpstorm-stubs/swoole/constants.stubAR~hjA@y3vendor/jetbrains/phpstorm-stubs/swoole/aliases.stubX R~hjX ᕤ5vendor/jetbrains/phpstorm-stubs/swoole/functions.stub8"R~hj8"6|9vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Server.stubq&R~hjq&EĤ:vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Runtime.stubR~hj9vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Atomic.stubR~hjeKͤ?vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Process/Pool.stubR~hjL4!@vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Server/Packet.stubR~hj+>vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Server/Task.stubR~hjeZvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Server/Port.stubR~hj_{?vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Server/Event.stubR~hj4Evendor/jetbrains/phpstorm-stubs/swoole/Swoole/Server/PipeMessage.stubR~hjvDCvendor/jetbrains/phpstorm-stubs/swoole/Swoole/WebSocket/Server.stubR~hj!AfBvendor/jetbrains/phpstorm-stubs/swoole/Swoole/WebSocket/Frame.stubR~hjDGvendor/jetbrains/phpstorm-stubs/swoole/Swoole/WebSocket/CloseFrame.stubR~hj%<vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine.stubR~hjNˤ7vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Lock.stubR~hj.n8vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Table.stubR~hjƂwդ>vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Atomic/Long.stubR~hjCvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Client/Exception.stubhR~hjh;9vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Client.stub R~hj Ѥ8vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Timer.stub{R~hj{U@vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Http2/Request.stubR~hjH1Avendor/jetbrains/phpstorm-stubs/swoole/Swoole/Http2/Response.stubR~hji8vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Error.stubRR~hjRT@vendor/jetbrains/phpstorm-stubs/swoole/Swoole/ExitException.stub R~hj _Avendor/jetbrains/phpstorm-stubs/swoole/Swoole/Timer/Iterator.stubR~hjg8'?vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Redis/Server.stub R~hj ?Bvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/MySQL.stub<R~hj<& Mvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Socket/Exception.stubrR~hjr-| Bvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Redis.stubmR~hjm%TCvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Socket.stubaR~hjaMCvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Client.stubR~hjpծLvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/MySQL/Statement.stubR~hj5Lvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/MySQL/Exception.stubqR~hjqQïSvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Http2/Client/Exception.stubxR~hjxP Ivendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Http2/Client.stuboR~hjoG>Dvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Channel.stubR~hjOhEvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Iterator.stubR~hj4;Dvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Context.stubR~hjFvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Scheduler.stubR~hj9Kvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Curl/Exception.stubpR~hjp{_ԤHvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Http/Server.stubR~hjy*Rvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Http/Client/Exception.stubwR~hjwHvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/Http/Client.stub)R~hj) g&Cvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Coroutine/System.stub R~hj SAۤFvendor/jetbrains/phpstorm-stubs/swoole/Swoole/Connection/Iterator.stubR~hjfoƤ8vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Event.stubR~hjw<vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Exception.stubZR~hjZ:vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Process.stubR~hj8<ڋ>vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Http/Server.stub`R~hj`Y?vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Http/Request.stubR~hj],@vendor/jetbrains/phpstorm-stubs/swoole/Swoole/Http/Response.stubR~hjc+vendor/jetbrains/phpstorm-stubs/PATCHES.txtER~hjEZΤ0vendor/jetbrains/phpstorm-stubs/ctype/ctype.stubRR~hjRP2vendor/jetbrains/phpstorm-stubs/sqlsrv/sqlsrv.stub~R~hj~i8vendor/jetbrains/phpstorm-stubs/cassandra/cassandra.stub R~hj 3Ԥ.vendor/jetbrains/phpstorm-stubs/Phar/Phar.stub(R~hj(6K,vendor/jetbrains/phpstorm-stubs/zip/zip.stub R~hj C94vendor/jetbrains/phpstorm-stubs/rpminfo/rpminfo.stub-R~hj-8vendor/jetbrains/phpstorm-stubs/blackfire/blackfire.stubHR~hjHZ46vendor/jetbrains/phpstorm-stubs/igbinary/igbinary.stubR~hjo/0vendor/jetbrains/phpstorm-stubs/mysql/mysql.stub|R~hj|0{,vendor/jetbrains/phpstorm-stubs/svm/SVM.stubR~hjg1vendor/jetbrains/phpstorm-stubs/svm/SVMModel.stubR~hj p8vendor/jetbrains/phpstorm-stubs/SimpleXML/SimpleXML.stubQLR~hjQLO4vendor/jetbrains/phpstorm-stubs/enchant/enchant.stub)R~hj)R4vendor/jetbrains/phpstorm-stubs/ibm_db2/ibm_db2.stubR~hj̯6vendor/jetbrains/phpstorm-stubs/newrelic/newrelic.stubR~hjϤ,vendor/jetbrains/phpstorm-stubs/rar/rar.stub_R~hj_EQ`2vendor/jetbrains/phpstorm-stubs/pdflib/PDFlib.stub/TR~hj/T5% K,vendor/jetbrains/phpstorm-stubs/fpm/fpm.stubR~hjB9vendor/jetbrains/phpstorm-stubs/meta/attributes/Pure.stubR~hj;Ś?vendor/jetbrains/phpstorm-stubs/meta/attributes/Deprecated.stubR~hjk^Cvendor/jetbrains/phpstorm-stubs/meta/attributes/ExpectedValues.stubR~hjђ~>vendor/jetbrains/phpstorm-stubs/meta/attributes/Immutable.stubR~hja'[vendor/jetbrains/phpstorm-stubs/meta/attributes/internal/PhpStormStubsElementAvailable.stubR~hje3Kvendor/jetbrains/phpstorm-stubs/meta/attributes/internal/TentativeType.stubR~hj()Pvendor/jetbrains/phpstorm-stubs/meta/attributes/internal/ReturnTypeContract.stubhR~hjh< xTvendor/jetbrains/phpstorm-stubs/meta/attributes/internal/LanguageLevelTypeAware.stuboR~hjo%?vendor/jetbrains/phpstorm-stubs/meta/attributes/ArrayShape.stubVR~hjVO7=vendor/jetbrains/phpstorm-stubs/meta/attributes/NoReturn.stubR~hj4@vendor/jetbrains/phpstorm-stubs/meta/attributes/ObjectShape.stubR~hjk p=vendor/jetbrains/phpstorm-stubs/meta/attributes/Language.stubR~hjMJ.vendor/jetbrains/phpstorm-stubs/json/json.stub4R~hj4tA6vendor/jetbrains/phpstorm-stubs/fileinfo/fileinfo.stubr!R~hjr!WY12vendor/jetbrains/phpstorm-stubs/phpdbg/phpdbg.stubgR~hjgAȾO+vendor/jetbrains/phpstorm-stubs/runTests.sh`R~hj`Rz1,vendor/jetbrains/phpstorm-stubs/FFI/FFI.stubMR~hjMt4vendor/jetbrains/phpstorm-stubs/ncurses/ncurses.stubR~hj*֩,vendor/jetbrains/phpstorm-stubs/zmq/zmq.stubzuR~hjzuZ:vendor/jetbrains/phpstorm-stubs/com_dotnet/com_dotnet.stubf/R~hjf/b,vendor/jetbrains/phpstorm-stubs/xml/xml.stubZR~hjZ]!8vendor/jetbrains/phpstorm-stubs/mapscript/mapscript.stubR~hj{|K'vendor/jetbrains/phpstorm-stubs/LICENSEW,R~hjW,M̤,vendor/jetbrains/phpstorm-stubs/lua/lua.stub< R~hj< €.vendor/jetbrains/phpstorm-stubs/http/http.stubR~hj/vendor/jetbrains/phpstorm-stubs/http/http3.stub]R~hj]<0vendor/jetbrains/phpstorm-stubs/oauth/oauth.stubb R~hjb bp0vendor/jetbrains/phpstorm-stubs/Core/Core_c.stubԋR~hjԋ60vendor/jetbrains/phpstorm-stubs/Core/Core_d.stub $R~hj $Zy.vendor/jetbrains/phpstorm-stubs/Core/Core.stub_R~hj_R.vendor/jetbrains/phpstorm-stubs/zstd/zstd.stubR~hjLV.vendor/jetbrains/phpstorm-stubs/zlib/zlib.stubKR~hjKZԤ4vendor/jetbrains/phpstorm-stubs/pspell/pspell_c.stubR~hjR 2vendor/jetbrains/phpstorm-stubs/pspell/pspell.stubq.R~hjq.0\,vendor/jetbrains/phpstorm-stubs/PDO/PDO.stubcGR~hjcGK&sʤ.vendor/jetbrains/phpstorm-stubs/uopz/uopz.stub&R~hj&-#:vendor/jetbrains/phpstorm-stubs/LuaSandbox/LuaSandbox.stubER~hjE0vendor/jetbrains/phpstorm-stubs/iconv/iconv.stub5R~hj51+G0vendor/jetbrains/phpstorm-stubs/shmop/shmop.stubR~hj2ɤ*vendor/jetbrains/phpstorm-stubs/pq/pq.stub+R~hj+5vendor/jetbrains/phpstorm-stubs/sybase/sybase_ct.stub7R~hj7#!2vendor/jetbrains/phpstorm-stubs/ffmpeg/ffmpeg.stubR~hjg%2vendor/jetbrains/phpstorm-stubs/relay/Cluster.stub?R~hj?_p0vendor/jetbrains/phpstorm-stubs/relay/Table.stubrR~hjrGͤ1vendor/jetbrains/phpstorm-stubs/relay/Events.stubR~hj)3vendor/jetbrains/phpstorm-stubs/relay/Sentinel.stubR~hj&vY2vendor/jetbrains/phpstorm-stubs/relay/KeyType.stubR~hjۼ0vendor/jetbrains/phpstorm-stubs/relay/Event.stubR~hj,7A4vendor/jetbrains/phpstorm-stubs/relay/Exception.stubcR~hjcr!0vendor/jetbrains/phpstorm-stubs/relay/Relay.stub;R~hj;0vendor/jetbrains/phpstorm-stubs/event/event.stubR~hjzI6vendor/jetbrains/phpstorm-stubs/calendar/calendar.stub&R~hj&fxݤ4vendor/jetbrains/phpstorm-stubs/sysvshm/sysvshm.stub>R~hj> 0vendor/jetbrains/phpstorm-stubs/xxtea/xxtea.stubR~hj$nڤ.vendor/jetbrains/phpstorm-stubs/soap/soap.stubGR~hjGZ0vendor/jetbrains/phpstorm-stubs/soap/soap_n.stubR~hju2vendor/jetbrains/phpstorm-stubs/intl/IntlChar.stubL/R~hjL/]tBvendor/jetbrains/phpstorm-stubs/intl/IntlDatePatternGenerator.stubR~hj$J.vendor/jetbrains/phpstorm-stubs/intl/intl.stub.}R~hj.}P,vendor/jetbrains/phpstorm-stubs/lzf/lzf.stubR~hjƤ0vendor/jetbrains/phpstorm-stubs/posix/posix.stubTkR~hjTkd 9vendor/jetbrains/phpstorm-stubs/Zend OPcache/OPcache.stubm R~hjm Im2vendor/jetbrains/phpstorm-stubs/expect/expect.stub R~hj I.Ȥ2vendor/jetbrains/phpstorm-stubs/xdebug/xdebug.stub3R~hj3^Ȥ.vendor/jetbrains/phpstorm-stubs/ssh2/ssh2.stubZR~hjZo.vendor/jetbrains/phpstorm-stubs/odbc/odbc.stubyR~hjyJvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/ServerChangedEvent.stubR~hjpSvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/ServerHeartbeatStartedEvent.stubxR~hjxxKvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/CommandStartedEvent.stubR~hjTLvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/TopologyChangedEvent.stubR~hje4Kvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/TopologyClosedEvent.stubR~hj89Avendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/functions.stubuR~hjuƽgFvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/SDAMSubscriber.stub R~hj ƐLvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/TopologyOpeningEvent.stubR~hjYWuBvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/Subscriber.stubR~hjEvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/LogSubscriber.stubR~hjn̅Mvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/CommandSucceededEvent.stubR~hjuIvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/CommandSubscriber.stubR~hj;OJvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/ServerOpeningEvent.stubvR~hjv62Uvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/ServerHeartbeatSucceededEvent.stubUR~hjU2y{Ivendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/ServerClosedEvent.stubrR~hjr:SRvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/ServerHeartbeatFailedEvent.stub]R~hj]5Jvendor/jetbrains/phpstorm-stubs/mongodb/Monitoring/CommandFailedEvent.stubR~hjc됒3vendor/jetbrains/phpstorm-stubs/mongodb/Server.stub'R~hj';d4vendor/jetbrains/phpstorm-stubs/mongodb/Manager.stub*R~hj*dk>vendor/jetbrains/phpstorm-stubs/mongodb/WriteConcernError.stubR~hjVZ>vendor/jetbrains/phpstorm-stubs/mongodb/ServerDescription.stubR~hj.6vendor/jetbrains/phpstorm-stubs/mongodb/ServerApi.stubR~hj֤;vendor/jetbrains/phpstorm-stubs/mongodb/ReadPreference.stubDR~hjDϣ9vendor/jetbrains/phpstorm-stubs/mongodb/WriteConcern.stubE R~hjE S8vendor/jetbrains/phpstorm-stubs/mongodb/WriteResult.stubd R~hjd ݚ2vendor/jetbrains/phpstorm-stubs/mongodb/Query.stubR~hjԶǤ3vendor/jetbrains/phpstorm-stubs/mongodb/Cursor.stubR~hjH5vendor/jetbrains/phpstorm-stubs/mongodb/CursorId.stubwR~hjw:?8vendor/jetbrains/phpstorm-stubs/mongodb/ReadConcern.stub R~hj w=vendor/jetbrains/phpstorm-stubs/mongodb/ClientEncryption.stubfR~hjf8DZ97vendor/jetbrains/phpstorm-stubs/mongodb/WriteError.stub`R~hj`__K4vendor/jetbrains/phpstorm-stubs/mongodb/Session.stubTR~hjTڸ76vendor/jetbrains/phpstorm-stubs/mongodb/BulkWrite.stub R~hj #Z4vendor/jetbrains/phpstorm-stubs/mongodb/Command.stubR~hj޾d@vendor/jetbrains/phpstorm-stubs/mongodb/TopologyDescription.stubR~hj,Ovendor/jetbrains/phpstorm-stubs/mongodb/Exception/UnexpectedValueException.stubjR~hjjMmQvendor/jetbrains/phpstorm-stubs/mongodb/Exception/ConnectionTimeoutException.stubdR~hjd -;Mvendor/jetbrains/phpstorm-stubs/mongodb/Exception/SSLConnectionException.stub2R~hj2Gvendor/jetbrains/phpstorm-stubs/mongodb/Exception/RuntimeException.stubFR~hjFEIvendor/jetbrains/phpstorm-stubs/mongodb/Exception/BulkWriteException.stubR~hjJvendor/jetbrains/phpstorm-stubs/mongodb/Exception/ConnectionException.stubGR~hjGAlNvendor/jetbrains/phpstorm-stubs/mongodb/Exception/AuthenticationException.stub5R~hj5KPvendor/jetbrains/phpstorm-stubs/mongodb/Exception/ExecutionTimeoutException.stubHR~hjHAEvendor/jetbrains/phpstorm-stubs/mongodb/Exception/LogicException.stubR~hjZŤJvendor/jetbrains/phpstorm-stubs/mongodb/Exception/EncryptionException.stub,R~hj, 5Evendor/jetbrains/phpstorm-stubs/mongodb/Exception/WriteException.stubR~hjGgGvendor/jetbrains/phpstorm-stubs/mongodb/Exception/CommandException.stub R~hj K*Lvendor/jetbrains/phpstorm-stubs/mongodb/Exception/WriteConcernException.stubyR~hjyFvendor/jetbrains/phpstorm-stubs/mongodb/Exception/ServerException.stubR~hj`Ovendor/jetbrains/phpstorm-stubs/mongodb/Exception/InvalidArgumentException.stubSR~hjS5k:@vendor/jetbrains/phpstorm-stubs/mongodb/Exception/Exception.stub:R~hj:M4vendor/jetbrains/phpstorm-stubs/mongodb/mongodb.stubFR~hjF.@vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Unserializable.stubR~hj"t_=vendor/jetbrains/phpstorm-stubs/mongodb/BSON/PackedArray.stubR~hjפAvendor/jetbrains/phpstorm-stubs/mongodb/BSON/MinKeyInterface.stubR~hjGuEvendor/jetbrains/phpstorm-stubs/mongodb/BSON/Decimal128Interface.stub8R~hj8L=p@vendor/jetbrains/phpstorm-stubs/mongodb/BSON/RegexInterface.stubeR~hjemFvendor/jetbrains/phpstorm-stubs/mongodb/BSON/UTCDateTimeInterface.stub+R~hj+2,<vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Decimal128.stubR~hjWϤAvendor/jetbrains/phpstorm-stubs/mongodb/BSON/MaxKeyInterface.stubR~hj#;vendor/jetbrains/phpstorm-stubs/mongodb/BSON/functions.stub^ R~hj^ 9;vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Undefined.stubOR~hjOU6vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Type.stubR~hj'J-8vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Binary.stub R~hj ?8vendor/jetbrains/phpstorm-stubs/mongodb/BSON/MinKey.stubR~hj =vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Persistable.stubR~hj!tDvendor/jetbrains/phpstorm-stubs/mongodb/BSON/TimestampInterface.stubR~hjE p8vendor/jetbrains/phpstorm-stubs/mongodb/BSON/MaxKey.stubR~hjW:vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Iterator.stubR~hj 7vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Int64.stubOR~hjO$>vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Serializable.stubR~hj@}Cvendor/jetbrains/phpstorm-stubs/mongodb/BSON/ObjectIdInterface.stubR~hjC_8vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Symbol.stub/R~hj/RAvendor/jetbrains/phpstorm-stubs/mongodb/BSON/BinaryInterface.stubR~hj0>F7vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Regex.stubVR~hjVuk<vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Javascript.stubR~hj#<Ѥ:vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Document.stubR~hjhbT;vendor/jetbrains/phpstorm-stubs/mongodb/BSON/Timestamp.stubq R~hjq gH=vendor/jetbrains/phpstorm-stubs/mongodb/BSON/UTCDateTime.stubN R~hjN dEvendor/jetbrains/phpstorm-stubs/mongodb/BSON/JavascriptInterface.stubR~hj]O؇;vendor/jetbrains/phpstorm-stubs/mongodb/BSON/DBPointer.stubR~hj7:vendor/jetbrains/phpstorm-stubs/mongodb/BSON/ObjectId.stubR~hjtl?<vendor/jetbrains/phpstorm-stubs/mongodb/CursorInterface.stubR~hj ,vendor/jetbrains/phpstorm-stubs/pam/pam.stubR~hjs]7>vendor/jetbrains/phpstorm-stubs/win32service/win32service.stubEcR~hjEcRۤ.vendor/jetbrains/phpstorm-stubs/wddx/wddx.stub R~hj [L4vendor/jetbrains/phpstorm-stubs/decimal/decimal.stub<<R~hj<<zy4vendor/jetbrains/phpstorm-stubs/inotify/inotify.stubNR~hjNn.vendor/jetbrains/phpstorm-stubs/hash/hash.stubER~hjE̠4vendor/jetbrains/phpstorm-stubs/gettext/gettext.stub\R~hj\f2vendor/jetbrains/phpstorm-stubs/bcmath/bcmath.stub#R~hj#b2vendor/jetbrains/phpstorm-stubs/mcrypt/mcrypt.stub_R~hj_iXV2vendor/jetbrains/phpstorm-stubs/cubrid/cubrid.stubtR~hjt ~4vendor/jetbrains/phpstorm-stubs/sqlite3/sqlite3.stubfR~hjfԽ.vendor/jetbrains/phpstorm-stubs/ldap/ldap.stubR~hj5vendor/jetbrains/phpstorm-stubs/ldap/ResultEntry.stubIR~hjIPx_0vendor/jetbrains/phpstorm-stubs/ldap/Result.stubDR~hjDvZ4vendor/jetbrains/phpstorm-stubs/ldap/Connection.stubHR~hjH4vendor/jetbrains/phpstorm-stubs/uv/uv_functions.stubfR~hjft*vendor/jetbrains/phpstorm-stubs/uv/UV.stub R~hj h<6vendor/jetbrains/phpstorm-stubs/rdkafka/constants.stub#R~hj# 6vendor/jetbrains/phpstorm-stubs/rdkafka/functions.stubR~hj>vendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/TopicConf.stub R~hj x<vendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/Message.stubrR~hjrbWHvendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/KafkaErrorException.stubR~hjQGvendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/KafkaConsumerTopic.stubR~hjC٤=vendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/Metadata.stubR~hjώCvendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/TopicPartition.stub!R~hj!9<9vendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/Conf.stubqR~hjq8Bvendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/ConsumerTopic.stubR~hj>Bvendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/ProducerTopic.stubaR~hja=vendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/Producer.stub9R~hj9߲=vendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/Consumer.stubR~hjTYDvendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/Metadata/Broker.stubR~hjIQuRCvendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/Metadata/Topic.stubR~hjcGvendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/Metadata/Partition.stubR~hjHvendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/Metadata/Collection.stubR~hjLBvendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/KafkaConsumer.stubq R~hjq F!:vendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/Topic.stub{R~hj{t{=>vendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/Exception.stubAR~hjAD/Q:vendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka/Queue.stubR~hjhh4vendor/jetbrains/phpstorm-stubs/rdkafka/RdKafka.stubqR~hjq;Ҥ0vendor/jetbrains/phpstorm-stubs/mongo/mongo.stubR~hj;n.vendor/jetbrains/phpstorm-stubs/zend/zend.stubXR~hjXB 0vendor/jetbrains/phpstorm-stubs/zend/zend_f.stub.R~hj.6x0vendor/jetbrains/phpstorm-stubs/zend/zend_d.stubR~hj-|j2vendor/jetbrains/phpstorm-stubs/recode/recode.stubR~hjO4vendor/jetbrains/phpstorm-stubs/sockets/sockets.stub=R~hj=`p4vendor/jetbrains/phpstorm-stubs/meminfo/meminfo.stubR~hjrbɤ2vendor/jetbrains/phpstorm-stubs/brotli/brotli.stubR~hjp<5ʤ2vendor/jetbrains/phpstorm-stubs/radius/radius.stubGR~hjG4g2vendor/jetbrains/phpstorm-stubs/SQLite/SQLite.stublR~hjl L,vendor/jetbrains/phpstorm-stubs/eio/eio.stubfyR~hjfy2vendor/jetbrains/phpstorm-stubs/apache/apache.stub-R~hj-LBvendor/jetbrains/phpstorm-stubs/uploadprogress/uploadprogress.stub R~hj r݋8vendor/jetbrains/phpstorm-stubs/xmlwriter/xmlwriter.stubR~hjO< 6vendor/jetbrains/phpstorm-stubs/memcache/memcache.stub$RR~hj$RU*4vendor/jetbrains/phpstorm-stubs/imagick/imagick.stubmR~hjm~4vendor/jetbrains/phpstorm-stubs/openssl/openssl.stubR~hjФ0vendor/jetbrains/phpstorm-stubs/gnupg/gnupg.stubZIR~hjZI 3,vendor/jetbrains/phpstorm-stubs/dba/dba.stubE0R~hjE0Nԣ3vendor/jetbrains/phpstorm-stubs/dba/Connection.stubGR~hjGo@33vendor/jetbrains/phpstorm-stubs/solr/constants.stubDR~hjD c9vendor/jetbrains/phpstorm-stubs/solr/Utils/SolrUtils.stub R~hj O:vendor/jetbrains/phpstorm-stubs/solr/Utils/SolrObject.stub R~hj t 3vendor/jetbrains/phpstorm-stubs/solr/functions.stubR~hjAA@vendor/jetbrains/phpstorm-stubs/solr/Documents/SolrDocument.stub/R~hj/F&Evendor/jetbrains/phpstorm-stubs/solr/Documents/SolrInputDocument.stub&R~hj&?J Evendor/jetbrains/phpstorm-stubs/solr/Documents/SolrDocumentField.stubR~hj \Fvendor/jetbrains/phpstorm-stubs/solr/Queries/SolrModifiableParams.stubkR~hjk%Avendor/jetbrains/phpstorm-stubs/solr/Queries/SolrDisMaxQuery.stub-R~hj-I!;vendor/jetbrains/phpstorm-stubs/solr/Queries/SolrQuery.stubs>R~hjs><vendor/jetbrains/phpstorm-stubs/solr/Queries/SolrParams.stubR~hj(DFvendor/jetbrains/phpstorm-stubs/solr/Queries/SolrCollapseFunction.stubR~hjE Bvendor/jetbrains/phpstorm-stubs/solr/Exceptions/SolrException.stubR~hj&[vendor/jetbrains/phpstorm-stubs/solr/Exceptions/SolrMissingMandatoryParameterException.stubR~hjnRvendor/jetbrains/phpstorm-stubs/solr/Exceptions/SolrIllegalOperationException.stubR~hj-N%Qvendor/jetbrains/phpstorm-stubs/solr/Exceptions/SolrIllegalArgumentException.stubR~hj)4Hvendor/jetbrains/phpstorm-stubs/solr/Exceptions/SolrClientException.stubsR~hjsGPHvendor/jetbrains/phpstorm-stubs/solr/Exceptions/SolrServerException.stubyR~hjyC$4vendor/jetbrains/phpstorm-stubs/solr/SolrClient.stubMR~hjMC|@vendor/jetbrains/phpstorm-stubs/solr/Responses/SolrResponse.stubR~hj/I%Dvendor/jetbrains/phpstorm-stubs/solr/Responses/SolrPingResponse.stubR~hjޡޤGvendor/jetbrains/phpstorm-stubs/solr/Responses/SolrGenericResponse.stub+R~hj+Evendor/jetbrains/phpstorm-stubs/solr/Responses/SolrQueryResponse.stubR~hjɤFvendor/jetbrains/phpstorm-stubs/solr/Responses/SolrUpdateResponse.stub%R~hj%>H٤2vendor/jetbrains/phpstorm-stubs/filter/filter.stub;R~hj;v2֬0vendor/jetbrains/phpstorm-stubs/stomp/stomp.stubA"R~hjA"!K2vendor/jetbrains/phpstorm-stubs/xcache/xcache.stubR~hj^).vendor/jetbrains/phpstorm-stubs/pcre/pcre.stubzPR~hjzPY,vendor/jetbrains/phpstorm-stubs/yaf/yaf.stub`R~hj`k6vendor/jetbrains/phpstorm-stubs/yaf/yaf_namespace.stub^[R~hj^[vD,vendor/jetbrains/phpstorm-stubs/ast/ast.stub [R~hj [nΤ8vendor/jetbrains/phpstorm-stubs/interbase/interbase.stubR~hj@vendor/jetbrains/phpstorm-stubs/opentelemetry/opentelemetry.stubPR~hjP<vendor/jetbrains/phpstorm-stubs/libvirt-php/libvirt-php.stub9R~hj9:`,vendor/jetbrains/phpstorm-stubs/gmp/gmp.stubuR~hjuO*vendor/nette/utils/src/Utils/Paginator.phpR~hj&vendor/nette/utils/src/Utils/Image.php`R~hj`s}S(vendor/nette/utils/src/Utils/Strings.phpqQR~hjqQA+vendor/nette/utils/src/Utils/Reflection.php{7R~hj{7,,*vendor/nette/utils/src/Utils/ArrayList.php R~hj ŧ+vendor/nette/utils/src/Utils/Validators.php+R~hj+pqW(vendor/nette/utils/src/Utils/Helpers.php R~hj 5dZ,vendor/nette/utils/src/Utils/ObjectMixin.phpR~hj+vendor/nette/utils/src/Utils/FileSystem.php R~hj H %vendor/nette/utils/src/Utils/Json.phpR~hjC*vendor/nette/utils/src/Utils/ArrayHash.phpNR~hjN(n+vendor/nette/utils/src/Iterators/Mapper.phpR~hj39&4vendor/nette/utils/src/Iterators/CachingIterator.php R~hj <Qw(vendor/nette/utils/src/compatibility.phpR~hj1a%vendor/nette/utils/src/exceptions.phpR~hj )vendor/nette/utils/src/HtmlStringable.phplR~hjlD&vendor/nette/utils/src/SmartObject.phpR~hj@ 4ؤ%vendor/nette/utils/src/Translator.phpR~hj g&vendor/nette/utils/src/StaticClass.phpR~hj8vendor/nette/utils/ncs.php8R~hj85vendor/nette/utils/ncs.xmlR~hj(vendor/nette/finder/src/Utils/Finder.php*R~hj*aFvendor/nette/bootstrap/src/Bootstrap/Extensions/ConstantsExtension.php)R~hj)q@vendor/nette/bootstrap/src/Bootstrap/Extensions/PhpExtension.phpQR~hjQ(o(5vendor/nette/bootstrap/src/Bootstrap/Configurator.php,R~hj,O+vendor/nette/bootstrap/src/Configurator.phpR~hjq?p9vendor/nette/robot-loader/src/RobotLoader/RobotLoader.php@R~hj@Zg<6vendor/nette/php-generator/src/PhpGenerator/Dumper.php8#R~hj8#>Avendor/nette/php-generator/src/PhpGenerator/PromotedParameter.phpR~hj8vendor/nette/php-generator/src/PhpGenerator/Constant.phpR~hjH7vendor/nette/php-generator/src/PhpGenerator/Printer.php[4R~hj[4Mo7vendor/nette/php-generator/src/PhpGenerator/Closure.phpR~hj 7vendor/nette/php-generator/src/PhpGenerator/Literal.php R~hj &P:vendor/nette/php-generator/src/PhpGenerator/PsrPrinter.phpR~hj Ӣ6vendor/nette/php-generator/src/PhpGenerator/Method.php R~hj TV[7vendor/nette/php-generator/src/PhpGenerator/Helpers.phpR~hja8vendor/nette/php-generator/src/PhpGenerator/TraitUse.phpR~hj55>vendor/nette/php-generator/src/PhpGenerator/GlobalFunction.phpR~hj48:vendor/nette/php-generator/src/PhpGenerator/PhpLiteral.phpR~hjO78vendor/nette/php-generator/src/PhpGenerator/EnumCase.phpR~hjG"9vendor/nette/php-generator/src/PhpGenerator/Parameter.php+ R~hj+ + 9vendor/nette/php-generator/src/PhpGenerator/Attribute.php_R~hj_p7vendor/nette/php-generator/src/PhpGenerator/Factory.php3R~hj3Ĥ8vendor/nette/php-generator/src/PhpGenerator/Property.php R~hj 2ޤ<vendor/nette/php-generator/src/PhpGenerator/PhpNamespace.phpC'R~hjC'l7vendor/nette/php-generator/src/PhpGenerator/PhpFile.phpR~hjXwʤ9vendor/nette/php-generator/src/PhpGenerator/ClassType.phpF;R~hjF;{9vendor/nette/php-generator/src/PhpGenerator/Extractor.php >R~hj >4vendor/nette/php-generator/src/PhpGenerator/Type.phpXR~hjXR"eCvendor/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php0R~hj0] 3Fvendor/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php<R~hj<@vendor/nette/php-generator/src/PhpGenerator/Traits/NameAware.phpR~hjPh9Cvendor/nette/php-generator/src/PhpGenerator/Traits/CommentAware.phpR~hj~Evendor/nette/php-generator/src/PhpGenerator/Traits/AttributeAware.phpR~hjZr"vendor/nette/php-generator/ncs.php'R~hj'|&vendor/nette/neon/PATCHES.txtR~hj0Ovendor/nette/neon/bin/neon-lintKR~hjK\b$vendor/nette/neon/src/Neon/Token.php}R~hj}3vendor/nette/neon/src/Neon/Node/EntityChainNode.phpR~hj N2vendor/nette/neon/src/Neon/Node/BlockArrayNode.phpR~hj-ӝ/vendor/nette/neon/src/Neon/Node/LiteralNode.phpE R~hjE :|3vendor/nette/neon/src/Neon/Node/InlineArrayNode.php_R~hj_!^1vendor/nette/neon/src/Neon/Node/ArrayItemNode.phpR~hjm.vendor/nette/neon/src/Neon/Node/StringNode.php R~hj 89".-vendor/nette/neon/src/Neon/Node/ArrayNode.phpR~hj.vendor/nette/neon/src/Neon/Node/EntityNode.phpYR~hjYE+#vendor/nette/neon/src/Neon/Neon.phpR~hj*m*vendor/nette/neon/src/Neon/TokenStream.php.R~hj.f!&vendor/nette/neon/src/Neon/Encoder.phph R~hjh Yդ&vendor/nette/neon/src/Neon/Decoder.phpR~hj?B%vendor/nette/neon/src/Neon/Parser.php!R~hj!$m$vendor/nette/neon/src/Neon/Lexer.php R~hj 7@*%vendor/nette/neon/src/Neon/Entity.phpR~hjBl\#vendor/nette/neon/src/Neon/Node.phpR~hj(vendor/nette/neon/src/Neon/Exception.php7R~hj7r(vendor/nette/neon/src/Neon/Traverser.phpjR~hjjvendor/nette/di/PATCHES.txtR~hj%vendor/nette/di/src/compatibility.phpR~hjm?Fvendor/nette/di/src/Bridges/DITracy/templates/ContainerPanel.tab.phtmlR~hj>F-Hvendor/nette/di/src/Bridges/DITracy/templates/ContainerPanel.panel.phtmlR~hj]띦6vendor/nette/di/src/Bridges/DITracy/ContainerPanel.phpi R~hji +vendor/nette/di/src/DI/ContainerBuilder.php+R~hj+i^9vendor/nette/di/src/DI/Definitions/ImportedDefinition.phpR~hjp0vendor/nette/di/src/DI/Definitions/Reference.phpR~hjwR8vendor/nette/di/src/DI/Definitions/FactoryDefinition.phpG#R~hjG##1vendor/nette/di/src/DI/Definitions/Definition.php'R~hj' #8vendor/nette/di/src/DI/Definitions/LocatorDefinition.phpuR~hjuI$0vendor/nette/di/src/DI/Definitions/Statement.phpR~hjWi9vendor/nette/di/src/DI/Definitions/AccessorDefinition.php$R~hj$S8vendor/nette/di/src/DI/Definitions/ServiceDefinition.phpiR~hji "vendor/nette/di/src/DI/Helpers.php#R~hj#Vq%vendor/nette/di/src/DI/exceptions.php6R~hj6Vݤ6vendor/nette/di/src/DI/Extensions/DefinitionSchema.phpoR~hjo7#H9vendor/nette/di/src/DI/Extensions/ParametersExtension.php{R~hj{ /8vendor/nette/di/src/DI/Extensions/ConstantsExtension.phpR~hj,Lf5vendor/nette/di/src/DI/Extensions/InjectExtension.phpR~hj}2vendor/nette/di/src/DI/Extensions/PhpExtension.phpR~hj8vendor/nette/di/src/DI/Extensions/DecoratorExtension.phpg R~hjg ,Â7vendor/nette/di/src/DI/Extensions/ServicesExtension.phpR~hjI1vendor/nette/di/src/DI/Extensions/DIExtension.php9 R~hj9 X9vendor/nette/di/src/DI/Extensions/ExtensionsExtension.phpR~hj_r]5vendor/nette/di/src/DI/Extensions/SearchExtension.phpR~hjѤ%vendor/nette/di/src/DI/Autowiring.phpcR~hjctc,vendor/nette/di/src/DI/DependencyChecker.phpR~hj7+vendor/nette/di/src/DI/DynamicParameter.phpoR~hjoY%p#vendor/nette/di/src/DI/Compiler.php%R~hj%l=qJ,vendor/nette/di/src/DI/Attributes/Inject.php!R~hj!K)vendor/nette/di/src/DI/Config/Helpers.php%R~hj%څ`t)vendor/nette/di/src/DI/Config/Adapter.phpR~hj>פ(vendor/nette/di/src/DI/Config/Loader.php4R~hj4{a 6vendor/nette/di/src/DI/Config/Adapters/NeonAdapter.phpR~hjŊ)5vendor/nette/di/src/DI/Config/Adapters/PhpAdapter.phpR~hj&Ǥ,vendor/nette/di/src/DI/CompilerExtension.phpR~hj(*vendor/nette/di/src/DI/ContainerLoader.phpLR~hjLɤ#vendor/nette/di/src/DI/Resolver.phpbR~hjb$vendor/nette/di/src/DI/Container.php:,R~hj:,QL'vendor/nette/di/src/DI/PhpGenerator.phpR~hj*vendor/nette/schema/src/Schema/Message.php R~hj 'C;%*vendor/nette/schema/src/Schema/Context.phpR~hjB ,vendor/nette/schema/src/Schema/Processor.php R~hj 5*vendor/nette/schema/src/Schema/Helpers.php R~hj n3vendor/nette/schema/src/Schema/DynamicParameter.phpR~hj; )vendor/nette/schema/src/Schema/Expect.php R~hj Q)vendor/nette/schema/src/Schema/Schema.phpyR~hjyST0vendor/nette/schema/src/Schema/Elements/Base.phpR~hj5u1vendor/nette/schema/src/Schema/Elements/AnyOf.phpVR~hjV}j5vendor/nette/schema/src/Schema/Elements/Structure.phpR~hji?l0vendor/nette/schema/src/Schema/Elements/Type.phpR~hj 4m6vendor/nette/schema/src/Schema/ValidationException.phpR~hjx4vendor/evenement/evenement/src/EventEmitterTrait.phpYR~hjY>d/vendor/evenement/evenement/src/EventEmitter.phprR~hjr!/g8vendor/evenement/evenement/src/EventEmitterInterface.phpR~hjb"vendor/evenement/evenement/LICENSE R~hj {I=#vendor/composer/autoload_static.phpMR~hjM֣q%vendor/composer/ca-bundle/PATCHES.txtR~hjrbmW(vendor/composer/ca-bundle/res/cacert.pemzR~hjz%O*vendor/composer/ca-bundle/src/CaBundle.php+R~hj+ Ǥ!vendor/composer/ca-bundle/LICENSER~hj*!^`%vendor/composer/autoload_classmap.phpR~hjTu-vendor/composer/xdebug-handler/src/Status.phpeR~hjez~[0vendor/composer/xdebug-handler/src/PhpConfig.phpR~hjڤ.vendor/composer/xdebug-handler/src/Process.phpn R~hjn pA4vendor/composer/xdebug-handler/src/XdebugHandler.php}TR~hj}TxӤ&vendor/composer/xdebug-handler/LICENSE)R~hj)#;^vendor/composer/installed.phpR~hjz!vendor/composer/autoload_real.phpR~hjD5'vendor/composer/autoload_namespaces.phpR~hj/t)vendor/composer/semver/src/Comparator.phpb R~hjb hi4vendor/composer/semver/src/Constraint/Constraint.php0R~hj0Mj=vendor/composer/semver/src/Constraint/MatchNoneConstraint.phpR~hj9vendor/composer/semver/src/Constraint/MultiConstraint.php@#R~hj@#t!w/vendor/composer/semver/src/Constraint/Bound.phpE R~hjE Ji =vendor/composer/semver/src/Constraint/ConstraintInterface.phpR~hjhf<vendor/composer/semver/src/Constraint/MatchAllConstraint.phpR~hj's7'vendor/composer/semver/src/Interval.phpR~hj ݤ%vendor/composer/semver/src/Semver.phpT R~hjT dj,vendor/composer/semver/src/VersionParser.phpTR~hjT{$ȳ/vendor/composer/semver/src/CompilingMatcher.php) R~hj) Fz(vendor/composer/semver/src/Intervals.phpNR~hjNvendor/composer/semver/LICENSER~hjBh%vendor/composer/InstalledVersions.phpCR~hjCBbԤ.vendor/react/socket/src/ConnectorInterface.php=R~hj=p,vendor/react/socket/src/StreamEncryption.phpR~hj˛|vendor/react/socket/LICENSEuR~hju{0vendor/react/event-loop/src/StreamSelectLoop.php/R~hj/D@ۤ4vendor/react/event-loop/src/Tick/FutureTickQueue.phpR~hjҩ)vendor/react/event-loop/src/ExtEvLoop.phpR~hj6\-vendor/react/event-loop/src/LoopInterface.phpKR~hjK#N&$vendor/react/event-loop/src/Loop.php9R~hj9?.vendor/react/event-loop/src/SignalsHandler.php+R~hj+^.vendor/react/event-loop/src/TimerInterface.phpR~hjw#B,vendor/react/event-loop/src/ExtLibevLoop.phpR~hjb*L+vendor/react/event-loop/src/Timer/Timer.php6R~hj6&ݤ,vendor/react/event-loop/src/Timer/Timers.php R~hj g'vendor/react/event-loop/src/Factory.php<R~hj</vendor/react/event-loop/src/ExtLibeventLoop.php!R~hj!T,vendor/react/event-loop/src/ExtEventLoop.phpR~hjNz)vendor/react/event-loop/src/ExtUvLoop.php#R~hj#Wvendor/react/event-loop/LICENSEuR~hju{)vendor/react/cache/src/CacheInterface.php0 R~hj0 O%vendor/react/cache/src/ArrayCache.php_R~hj_CbgPvendor/react/cache/LICENSEuR~hju{ vendor/react/stream/src/Util.phpR~hj2vendor/react/stream/src/WritableResourceStream.phpR~hjפ0vendor/react/stream/src/DuplexResourceStream.phpR~hj"{3vendor/react/stream/src/ReadableStreamInterface.php7R~hj7b3vendor/react/stream/src/WritableStreamInterface.php9R~hj92vendor/react/stream/src/ReadableResourceStream.phpR~hj$Ӥ1vendor/react/stream/src/DuplexStreamInterface.phpR~hjXB:)vendor/react/stream/src/ThroughStream.phpR~hj(\+vendor/react/stream/src/CompositeStream.phphR~hjhepvendor/react/stream/LICENSEuR~hju{vendor/react/http/PATCHES.txtR~hj!=y@vendor/react/http/src/Middleware/RequestBodyBufferMiddleware.php3R~hj3f%@vendor/react/http/src/Middleware/RequestBodyParserMiddleware.php^R~hj^/Fvendor/react/http/src/Middleware/LimitConcurrentRequestsMiddleware.phpR~hjm1?vendor/react/http/src/Middleware/StreamingRequestMiddleware.php/ R~hj/ u)vendor/react/http/src/Io/UploadedFile.php R~hj > ̤$vendor/react/http/src/Io/IniUtil.phpsR~hjsIc+vendor/react/http/src/Io/ChunkedEncoder.phpQR~hjQv.vendor/react/http/src/Io/PauseBufferStream.phpR~hj4$vendor/react/http/src/HttpServer.php<R~hj<܅'vendor/react/http/src/Client/Client.phpR~hjfeA vendor/react/http/src/Server.phpFR~hjF8两3vendor/react/http/src/Message/ResponseException.phpR~hj6%vendor/react/http/src/Message/Uri.phpL%R~hjL%GKV)vendor/react/http/src/Message/Request.php" R~hj" @}Ƥ/vendor/react/http/src/Message/ServerRequest.php/R~hj/J=*vendor/react/http/src/Message/Response.php}9R~hj}9hVvendor/react/http/LICENSEuR~hju{$vendor/react/async/src/functions.phpBR~hjB-,vendor/react/async/src/functions_include.phpR~hj~-vendor/react/async/LICENSE^R~hj^yT*vendor/react/child-process/src/Process.php:R~hj:\9"vendor/react/child-process/LICENSEuR~hju{0vendor/react/dns/src/Query/HostsFileExecutor.php R~hj E+vendor/react/dns/src/Query/CoopExecutor.php R~hj .vendor/react/dns/src/Query/CachingExecutor.phpU R~hjU /vendor/react/dns/src/Query/FallbackExecutor.phpR~hjd4vendor/react/dns/src/Query/CancellationException.phpvR~hjv@9vendor/react/dns/src/Query/SelectiveTransportExecutor.php R~hj r0vendor/react/dns/src/Query/ExecutorInterface.phpR~hj4Ƈ3vendor/react/dns/src/Query/UdpTransportExecutor.phph!R~hjh!"$vendor/react/dns/src/Query/Query.phpR~hj{gH/vendor/react/dns/src/Query/TimeoutException.phpjR~hjjk.vendor/react/dns/src/Query/TimeoutExecutor.php R~hj ?_,vendor/react/dns/src/Query/RetryExecutor.phpK R~hjK mܤ3vendor/react/dns/src/Query/TcpTransportExecutor.php6R~hj6E+E0vendor/react/dns/src/RecordNotFoundException.phpkR~hjkT&vendor/react/dns/src/Config/Config.phpKR~hjK4 )vendor/react/dns/src/Config/HostsFile.phpR~hj|i/&vendor/react/dns/src/Model/Message.phpR~hj<%vendor/react/dns/src/Model/Record.phpR~hj.^ .vendor/react/dns/src/Protocol/BinaryDumper.phpQR~hjQǜ(vendor/react/dns/src/Protocol/Parser.php,R~hj,pZ)vendor/react/dns/src/Resolver/Factory.php R~hj *vendor/react/dns/src/Resolver/Resolver.phpR~hjΗ3vendor/react/dns/src/Resolver/ResolverInterface.phpR~hjK+vendor/react/dns/src/BadServerException.phpfR~hjfvendor/react/dns/LICENSEuR~hju{6vendor/phpstan/phpdoc-parser/src/Parser/TypeParser.phpR~hjYդ8vendor/phpstan/phpdoc-parser/src/Parser/PhpDocParser.phpYR~hjY=ߤ;vendor/phpstan/phpdoc-parser/src/Parser/ParserException.phpg R~hjg u/g;vendor/phpstan/phpdoc-parser/src/Parser/ConstExprParser.php<'R~hj<'t;vendor/phpstan/phpdoc-parser/src/Parser/StringUnescaper.php> R~hj> +t99vendor/phpstan/phpdoc-parser/src/Parser/TokenIterator.php#R~hj#G#|0vendor/phpstan/phpdoc-parser/src/Lexer/Lexer.phpR~hj gIvendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayItemNode.phpR~hj4|ͤDvendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprNullNode.php;R~hj;g @vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprNode.phpR~hj0KPvendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/QuoteAwareConstExprStringNode.phpP R~hjP ]Fvendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprStringNode.phpR~hjč Evendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayNode.phpFR~hjFDEvendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprFloatNode.phpR~hj Gvendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprIntegerNode.phpR~hjҳNvendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/DoctrineConstExprStringNode.phpuR~hju,wѤAvendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstFetchNode.phpR~hj[eDvendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprTrueNode.php;R~hj;ĉEEvendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprFalseNode.php=R~hj=P1w1Hvendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayShapeUnsealedTypeNode.php!R~hj!>vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeNode.phpR~hj/,|;vendor/phpstan/phpdoc-parser/src/Ast/Type/ConstTypeNode.phpR~hj!.ߤAvendor/phpstan/phpdoc-parser/src/Ast/Type/ConditionalTypeNode.phpNR~hjN@;vendor/phpstan/phpdoc-parser/src/Ast/Type/UnionTypeNode.php?R~hj?T=vendor/phpstan/phpdoc-parser/src/Ast/Type/GenericTypeNode.phpRR~hjRq`6vendor/phpstan/phpdoc-parser/src/Ast/Type/TypeNode.phpR~hj]ˤMvendor/phpstan/phpdoc-parser/src/Ast/Type/ConditionalTypeForParameterNode.phpAR~hjA>a<vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayShapeNode.php$R~hj$̤Bvendor/phpstan/phpdoc-parser/src/Ast/Type/IntersectionTypeNode.phpFR~hjF76:vendor/phpstan/phpdoc-parser/src/Ast/Type/ThisTypeNode.php(R~hj(+œ;vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayTypeNode.phpR~hjΞ@vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayShapeItemNode.phpR~hjԯBvendor/phpstan/phpdoc-parser/src/Ast/Type/OffsetAccessTypeNode.php_R~hj_HǤ>vendor/phpstan/phpdoc-parser/src/Ast/Type/NullableTypeNode.phpR~hjK6ˤ@vendor/phpstan/phpdoc-parser/src/Ast/Type/IdentifierTypeNode.phpR~hjF=vendor/phpstan/phpdoc-parser/src/Ast/Type/InvalidTypeNode.phpSR~hjSAvendor/phpstan/phpdoc-parser/src/Ast/Type/ObjectShapeItemNode.phpR~hjGvendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeParameterNode.phpR~hj\6=vendor/phpstan/phpdoc-parser/src/Ast/Type/ObjectShapeNode.phpMR~hjMͥRBvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ThrowsTagValueNode.phpR~hj6Kvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TypeAliasImportTagValueNode.phpR~hjpк>vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTextNode.phpR~hjNIvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TypelessParamTagValueNode.phpR~hj<Dvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamOutTagValueNode.php2R~hj2mKvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueParameterNode.php3R~hj3뉤=vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagNode.php(R~hj(XrCvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ExtendsTagValueNode.phpR~hjuE此Bvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagValueNode.phpR~hj9eBvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/AssertTagValueNode.phppR~hjp>䍤Bvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueNode.phpR~hj4>ˤCvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/InvalidTagValueNode.phpR~hj>NFvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/Doctrine/DoctrineArray.phpTR~hjT|mKvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/Doctrine/DoctrineAnnotation.phpR~hj(TͤJvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/Doctrine/DoctrineArrayItem.phpLR~hjL0BIvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/Doctrine/DoctrineArgument.phpR~hjLM*Mvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/Doctrine/DoctrineTagValueNode.phpR~hj^Dvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PropertyTagValueNode.php-R~hj-Y?ŤBvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ReturnTagValueNode.phpR~hjHJvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireExtendsTagValueNode.phpR~hjB'Cvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/GenericTagValueNode.phpR~hj&Avendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MixinTagValueNode.phpR~hjaLvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamClosureThisTagValueNode.php:R~hj:ę:vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocNode.php65R~hj65}nzDvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TemplateTagValueNode.php:R~hj:UFvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ImplementsTagValueNode.phpR~hj??vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocChildNode.phpR~hjFvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/DeprecatedTagValueNode.phpR~hj2w[vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamImmediatelyInvokedCallableTagValueNode.phpR~hj5SUvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamLaterInvokedCallableTagValueNode.phpR~hjOؼJvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/AssertTagPropertyValueNode.phpR~hjPoAvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamTagValueNode.phpR~hjHvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/AssertTagMethodValueNode.phpR~hjĚdEvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TypeAliasTagValueNode.phpwR~hjw6&"!@vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/UsesTagValueNode.phpR~hj?vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/VarTagValueNode.phpBR~hjBkN-Vvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PureUnlessCallableIsImpureTagValueNode.phpR~hjZtCvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/SelfOutTagValueNode.phpR~hj2KMvendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireImplementsTagValueNode.phpR~hj:Eˤ<vendor/phpstan/phpdoc-parser/src/Ast/AbstractNodeVisitor.phpR~hj/6vendor/phpstan/phpdoc-parser/src/Ast/NodeTraverser.php*R~hj*B,2vendor/phpstan/phpdoc-parser/src/Ast/Attribute.php9R~hj94vendor/phpstan/phpdoc-parser/src/Ast/NodeVisitor.php R~hj oCvendor/phpstan/phpdoc-parser/src/Ast/NodeVisitor/CloningVisitor.phpR~hjd-vendor/phpstan/phpdoc-parser/src/Ast/Node.phpwR~hjw?S; 7vendor/phpstan/phpdoc-parser/src/Ast/NodeAttributes.phpR~hjYXT4vendor/phpstan/phpdoc-parser/src/Printer/Printer.phpjR~hjji1M3vendor/phpstan/phpdoc-parser/src/Printer/Differ.phpR~hjRǀ5vendor/phpstan/phpdoc-parser/src/Printer/DiffElem.phpR~hjZ6$vendor/phpstan/phpdoc-parser/LICENSE.R~hj.-+vendor/phpstan/php-8-stubs/Php8StubsMap.phpR~hj*4ڤ;vendor/phpstan/php-8-stubs/stubs/Zend/get_defined_vars.stubER~hjE[m6vendor/phpstan/php-8-stubs/stubs/Zend/strncasecmp.stubTR~hjT*b 7vendor/phpstan/php-8-stubs/stubs/Zend/trait_exists.stubMR~hjMϐ8=vendor/phpstan/php-8-stubs/stubs/Zend/ArgumentCountError.stub7R~hj7f-@vendor/phpstan/php-8-stubs/stubs/Zend/get_defined_constants.stubbR~hjbVɤ7vendor/phpstan/php-8-stubs/stubs/Zend/zend_version.stubMR~hjM吤:vendor/phpstan/php-8-stubs/stubs/Zend/ArithmeticError.stub0R~hj0ڏ:vendor/phpstan/php-8-stubs/stubs/Zend/function_exists.stub<R~hj<$m8vendor/phpstan/php-8-stubs/stubs/Zend/trigger_error.stubR~hj;c5vendor/phpstan/php-8-stubs/stubs/Zend/ValueError.stub+R~hj+&Ȳ9vendor/phpstan/php-8-stubs/stubs/Zend/is_subclass_of.stubR~hj1=vendor/phpstan/php-8-stubs/stubs/Zend/get_included_files.stubGR~hjGT @vendor/phpstan/php-8-stubs/stubs/Zend/set_exception_handler.stubgR~hjg#\%4vendor/phpstan/php-8-stubs/stubs/Zend/TypeError.stub*R~hj*֤/vendor/phpstan/php-8-stubs/stubs/Zend/is_a.stubR~hjߤ5vendor/phpstan/php-8-stubs/stubs/Zend/Deprecated.stub_R~hj_<vendor/phpstan/php-8-stubs/stubs/Zend/get_class_methods.stubdR~hjd]S4vendor/phpstan/php-8-stubs/stubs/Zend/Throwable.stuboR~hjo׍x>vendor/phpstan/php-8-stubs/stubs/Zend/DivisionByZeroError.stub>R~hj>8դ4vendor/phpstan/php-8-stubs/stubs/Zend/get_class.stub@R~hj@Ap9vendor/phpstan/php-8-stubs/stubs/Zend/ErrorException.stub R~hj  m9vendor/phpstan/php-8-stubs/stubs/Zend/zend_thread_id.stubIR~hjI0o8vendor/phpstan/php-8-stubs/stubs/Zend/WeakReference.stubR~hjqq7vendor/phpstan/php-8-stubs/stubs/Zend/func_get_arg.stub7R~hj7<vendor/phpstan/php-8-stubs/stubs/Zend/set_error_handler.stub~R~hj~SQ<vendor/phpstan/php-8-stubs/stubs/Zend/gc_collect_cycles.stub-R~hj-W1vendor/phpstan/php-8-stubs/stubs/Zend/strcmp.stubBR~hjB07vendor/phpstan/php-8-stubs/stubs/Zend/CompileError.stub-R~hj-5vendor/phpstan/php-8-stubs/stubs/Zend/gc_disable.stub'R~hj'@vendor/phpstan/php-8-stubs/stubs/Zend/debug_print_backtrace.stubRR~hjRL:vendor/phpstan/php-8-stubs/stubs/Zend/debug_backtrace.stubR~hjw|z6vendor/phpstan/php-8-stubs/stubs/Zend/Traversable.stubCR~hjCł8vendor/phpstan/php-8-stubs/stubs/Zend/get_resources.stub?R~hj?P2鮤;vendor/phpstan/php-8-stubs/stubs/Zend/extension_loaded.stub>R~hj>2[놤:vendor/phpstan/php-8-stubs/stubs/Zend/property_exists.stub{R~hj{yBvendor/phpstan/php-8-stubs/stubs/Zend/get_declared_interfaces.stubLR~hjLu 56vendor/phpstan/php-8-stubs/stubs/Zend/enum_exists.stub\R~hj\ԩ Bvendor/phpstan/php-8-stubs/stubs/Zend/get_mangled_object_vars.stubCR~hjC2vendor/phpstan/php-8-stubs/stubs/Zend/Closure.stubR~hjɵ(5vendor/phpstan/php-8-stubs/stubs/Zend/Stringable.stubJR~hjJ}ވ?vendor/phpstan/php-8-stubs/stubs/Zend/get_declared_classes.stubIR~hjI\8vendor/phpstan/php-8-stubs/stubs/Zend/func_get_args.stub+R~hj+6Avendor/phpstan/php-8-stubs/stubs/Zend/AllowDynamicProperties.stubR~hj]%5vendor/phpstan/php-8-stubs/stubs/Zend/BackedEnum.stubR~hjH+@vendor/phpstan/php-8-stubs/stubs/Zend/get_defined_functions.stubgR~hjg^&>vendor/phpstan/php-8-stubs/stubs/Zend/get_extension_funcs.stub_R~hj_!S1vendor/phpstan/php-8-stubs/stubs/Zend/define.stubR~hjn>vendor/phpstan/php-8-stubs/stubs/Zend/UnhandledMatchError.stub4R~hj4-A0vendor/phpstan/php-8-stubs/stubs/Zend/Error.stubR~hje;vendor/phpstan/php-8-stubs/stubs/Zend/InternalIterator.stubR~hj }@vendor/phpstan/php-8-stubs/stubs/Zend/restore_error_handler.stubR~hj$P%)8vendor/phpstan/php-8-stubs/stubs/Zend/gc_mem_caches.stub0R~hj0c2vendor/phpstan/php-8-stubs/stubs/Zend/WeakMap.stubDR~hjD-<vendor/phpstan/php-8-stubs/stubs/Zend/get_resource_type.stubZR~hjZ(ˤ4vendor/phpstan/php-8-stubs/stubs/Zend/gc_enable.stub&R~hj&V/4vendor/phpstan/php-8-stubs/stubs/Zend/Attribute.stubR~hj{3vendor/phpstan/php-8-stubs/stubs/Zend/Iterator.stubR~hj]燤2vendor/phpstan/php-8-stubs/stubs/Zend/defined.stub9R~hj9n*b7vendor/phpstan/php-8-stubs/stubs/Zend/class_exists.stubMR~hjM*CF5vendor/phpstan/php-8-stubs/stubs/Zend/user_error.stubR~hjR~hj>0O;vendor/phpstan/php-8-stubs/stubs/Zend/interface_exists.stubUR~hjUy8vendor/phpstan/php-8-stubs/stubs/Zend/func_num_args.stub)R~hj)OPh>vendor/phpstan/php-8-stubs/stubs/Zend/get_declared_traits.stubHR~hjH{8 Cvendor/phpstan/php-8-stubs/stubs/Zend/ClosedGeneratorException.stub=R~hj=kQ:vendor/phpstan/php-8-stubs/stubs/Zend/error_reporting.stubCR~hjCATpDvendor/phpstan/php-8-stubs/stubs/Zend/restore_exception_handler.stubR~hjҤ2vendor/phpstan/php-8-stubs/stubs/Zend/strncmp.stubPR~hjP)6vendor/phpstan/php-8-stubs/stubs/Zend/ArrayAccess.stub5R~hj5&+0vendor/phpstan/php-8-stubs/stubs/Zend/Fiber.stub R~hj m5vendor/phpstan/php-8-stubs/stubs/Zend/FiberError.stubpR~hjpU3<vendor/phpstan/php-8-stubs/stubs/Zend/IteratorAggregate.stubR~hj-E9vendor/phpstan/php-8-stubs/stubs/Zend/get_class_vars.stubPR~hjPu@vendor/phpstan/php-8-stubs/stubs/Zend/get_loaded_extensions.stubgR~hjgO6;vendor/phpstan/php-8-stubs/stubs/Zend/get_called_class.stub/R~hj/歉3vendor/phpstan/php-8-stubs/stubs/Zend/UnitEnum.stubyR~hjywGuפ4vendor/phpstan/php-8-stubs/stubs/Zend/Countable.stub}R~hj}ҿ3vendor/phpstan/php-8-stubs/stubs/Zend/stdClass.stubJR~hjJ" _3vendor/phpstan/php-8-stubs/stubs/Zend/Override.stubR~hj~}Ϥ6vendor/phpstan/php-8-stubs/stubs/Zend/class_alias.stub[R~hj[Ĥ?vendor/phpstan/php-8-stubs/stubs/Zend/ReturnTypeWillChange.stubkR~hjkY:vendor/phpstan/php-8-stubs/stubs/Zend/get_resource_id.stubUR~hjU\ ߤ1vendor/phpstan/php-8-stubs/stubs/Zend/strlen.stub0R~hj0<Bvendor/phpstan/php-8-stubs/stubs/Zend/SensitiveParameterValue.stubR~hjCzO=vendor/phpstan/php-8-stubs/stubs/Zend/SensitiveParameter.stubR~hjQ4vendor/phpstan/php-8-stubs/stubs/Zend/Exception.stubdR~hjd?[i4vendor/phpstan/php-8-stubs/stubs/Zend/Generator.stub:R~hj:5vendor/phpstan/php-8-stubs/stubs/Zend/strcasecmp.stubFR~hjFXDvendor/phpstan/php-8-stubs/stubs/Zend/RequestParseBodyException.stubOR~hjOZ4_;vendor/phpstan/php-8-stubs/stubs/Zend/get_parent_class.stub]R~hj]5vendor/phpstan/php-8-stubs/stubs/Zend/ParseError.stub2R~hj2!(vendor/phpstan/php-8-stubs/stubs/LICENSE R~hj V;vendor/phpstan/php-8-stubs/stubs/ext/random/getrandmax.stubSR~hjS~Rw5vendor/phpstan/php-8-stubs/stubs/ext/random/rand.stubWR~hjW4!8vendor/phpstan/php-8-stubs/stubs/ext/random/mt_rand.stubZR~hjZݐ^6vendor/phpstan/php-8-stubs/stubs/ext/random/srand.stubR~hj6x<>vendor/phpstan/php-8-stubs/stubs/ext/random/mt_getrandmax.stub:R~hj:gCvendor/phpstan/php-8-stubs/stubs/ext/random/Random/RandomError.stubnR~hjnwYGvendor/phpstan/php-8-stubs/stubs/ext/random/Random/RandomException.stubvR~hjva>vendor/phpstan/php-8-stubs/stubs/ext/random/Random/Engine.stubhR~hjh*Hvendor/phpstan/php-8-stubs/stubs/ext/random/Random/CryptoSafeEngine.stubaR~hja?Fvendor/phpstan/php-8-stubs/stubs/ext/random/Random/Engine/Mt19937.stubR~hjRvendor/phpstan/php-8-stubs/stubs/ext/random/Random/Engine/PcgOneseq128XslRr64.stubR~hj|l!Evendor/phpstan/php-8-stubs/stubs/ext/random/Random/Engine/Secure.stubR~hjǥkQvendor/phpstan/php-8-stubs/stubs/ext/random/Random/Engine/Xoshiro256StarStar.stub"R~hj"n !Bvendor/phpstan/php-8-stubs/stubs/ext/random/Random/Randomizer.stubR~hj e]Ovendor/phpstan/php-8-stubs/stubs/ext/random/Random/BrokenRandomEngineError.stubR~hjiHvendor/phpstan/php-8-stubs/stubs/ext/random/Random/IntervalBoundary.stubER~hjEI;vendor/phpstan/php-8-stubs/stubs/ext/random/random_int.stubIR~hjIY:vendor/phpstan/php-8-stubs/stubs/ext/random/lcg_value.stub8R~hj8=vendor/phpstan/php-8-stubs/stubs/ext/random/random_bytes.stubZR~hjZTP9vendor/phpstan/php-8-stubs/stubs/ext/random/mt_srand.stubR~hjdKvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionEnumUnitCase.stub~R~hj~D%Hvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionUnionType.stuboR~hjoHvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionAttribute.stubR~hj:Hvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionNamedType.stubR~hjLQGvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionFunction.stubR~hjDnHvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionExtension.stubR~hjT1Dvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionClass.stubG$R~hjG$Ҹդ>vendor/phpstan/php-8-stubs/stubs/ext/reflection/Reflector.stub3R~hj3Cvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionType.stubR~hj9Dvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionFiber.stubR~hjEvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionMethod.stub R~hj 6Evendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionObject.stubwR~hjwMvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionEnumBackedCase.stubR~hj^hHvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionParameter.stub R~hj Q*6Ovendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionFunctionAbstract.stubR~hj|ҤEvendor/phpstan/php-8-stubs/stubs/ext/reflection/PropertyHookType.stubgR~hjg`פHvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionException.stubZR~hjZ&Gvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionConstant.stubR~hj$KLvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionZendExtension.stubR~hjOvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionIntersectionType.stubR~hjoQHvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionReference.stubbR~hjb^8Cvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionEnum.stub4R~hj4q6ϤGvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionProperty.stub"R~hj"G?vendor/phpstan/php-8-stubs/stubs/ext/reflection/Reflection.stubR~hjHvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionGenerator.stubR~hjQLvendor/phpstan/php-8-stubs/stubs/ext/reflection/ReflectionClassConstant.stub. R~hj. I 3vendor/phpstan/php-8-stubs/stubs/ext/snmp/SNMP.stubR~hj}|$>vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp2_real_walk.stubR~hj}9vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp3_walk.stubR~hj'|M<vendor/phpstan/php-8-stubs/stubs/ext/snmp/SNMPException.stub9R~hj9=w7vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmpwalk.stubR~hjRS:vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmpwalkoid.stubR~hjJA̤9vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp2_walk.stubR~hjuڤ8vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp2_get.stubR~hjKIvendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp_set_oid_numeric_print.stubR~hjjΤCvendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp_set_quick_print.stubR~hj{<vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp2_getnext.stubR~hjD|Bvendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp_set_enum_print.stubR~hjiFvendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp_set_valueretrieval.stubR~hjޤ<vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp3_getnext.stubR~hjZݤIvendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp_set_oid_output_format.stubR~hj:`M;vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmprealwalk.stubR~hjhƤ>vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp3_real_walk.stubR~hjC`Cvendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp_get_quick_print.stub1R~hj1::vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmpgetnext.stubR~hj38vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp3_get.stub R~hj -!LFvendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp_get_valueretrieval.stub3R~hj3K Z6vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmpget.stubR~hjWޤ6vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmpset.stubR~hj8vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp3_set.stub3R~hj3x8vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp2_set.stubR~hj"a<vendor/phpstan/php-8-stubs/stubs/ext/snmp/snmp_read_mib.stub:R~hj:nUBvendor/phpstan/php-8-stubs/stubs/ext/dom/dom_import_simplexml.stubKR~hjKE8vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMElement.stubR~hjs=vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMDocumentType.stubTR~hjToW=6vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMXPath.stubR~hjI@vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMEntityReference.stuboR~hjo*5vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMNode.stub R~hj q':vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMException.stub7R~hj7wH>vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMNameSpaceNode.stubR~hjPHۤ=vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMNamedNodeMap.stubR~hj5vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMAttr.stubR~hjAvendor/phpstan/php-8-stubs/stubs/ext/dom/DOMDocumentFragment.stub7R~hj7 Τ9vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMNotation.stub.R~hj.c9vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMNodeList.stubCR~hjCGQ9vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMDocument.stubR~hj㖑5vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMText.stubR~hj8葰:vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMChildNode.stubIR~hjIheL?vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMImplementation.stub.R~hj. Z=vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMCdataSection.stublR~hjl Fvendor/phpstan/php-8-stubs/stubs/ext/dom/DOMProcessingInstruction.stubR~hjBȤ>vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMCharacterData.stub$R~hj$!28vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMComment.stubuR~hjup=1>vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/CDATASection.stubQR~hjQfƤ=vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/HTMLElement.stubSR~hjSd7z<vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/ParentNode.stubyR~hjycq=vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/XMLDocument.stubR~hjR7vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/XPath.stubR~hj>vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/NamedNodeMap.stub%R~hj%C (@vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/HTMLCollection.stub7R~hj7h+ZGvendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/ProcessingInstruction.stubR~hjMiHAvendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/EntityReference.stubTR~hjTn݁:vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/NodeList.stubR~hj) ;vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/TokenList.stubR~hj͵ȤBvendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/DocumentFragment.stubR~hj\+@m6vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/Text.stubR~hjA􆕤Bvendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/import_simplexml.stubiR~hji*E@vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/Implementation.stubR~hj:vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/Notation.stubR~hjgL>vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/DocumentType.stub(R~hj((y;vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/ChildNode.stubR~hj Ť8vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/Entity.stub<R~hj<}]l6vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/Attr.stub=R~hj=eBvendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/AdjacentPosition.stubR~hjб+?vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/NamespaceInfo.stubCR~hjC\*xAvendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/DtdNamedNodeMap.stubUR~hjUd ?vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/CharacterData.stub+R~hj+:vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/Document.stubR~hj ={9vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/Element.stubR~hj%ܤ9vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/Comment.stubR~hjӜ6vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/Node.stub'R~hj'HRvפ>vendor/phpstan/php-8-stubs/stubs/ext/dom/Dom/HTMLDocument.stubR~hjq;vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMParentNode.stubAR~hjA7vendor/phpstan/php-8-stubs/stubs/ext/dom/DOMEntity.stub,R~hj,vHvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_rfc822_parse_headers.stubpR~hjpóAvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_renamemailbox.stubR~hj8P@vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_getmailboxes.stubR~hjӤ:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_qprint.stub>R~hj>;vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_timeout.stubQR~hjQϔnФ8vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_body.stubR~hj;vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_expunge.stubR~hjΡ@vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_mail_compose.stubTR~hjT0Avendor/phpstan/php-8-stubs/stubs/ext/imap/imap_deletemailbox.stubR~hj*ɧ8vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_8bit.stub<R~hj<W>vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_bodystruct.stubR~hj Z;vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_is_open.stubPR~hjPzAvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_createmailbox.stubR~hj#%Hvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_rfc822_write_address.stubqR~hjqٹ:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_alerts.stub/R~hj/@vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_setflag_full.stubR~hjqhA=vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_fetchtext.stub-R~hj-erAvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_getsubscribed.stubR~hjAvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_utf8_to_mutf7.stub\R~hj\hBvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_fetch_overview.stubR~hj+Bvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_fetchstructure.stub R~hj `=vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_fetchbody.stubR~hj$>vendor/phpstan/php-8-stubs/stubs/ext/imap/IMAP/Connection.stubwR~hjw̑^f8vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_list.stubR~hjREȤ8vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_lsub.stubR~hj ݤ=vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_set_quota.stubR~hj=vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_fetchmime.stubR~hj"?vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_fetchheader.stubR~hj:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_binary.stub>R~hj>s8vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_mail.stubR~hjcp|?vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_utf7_encode.stub=R~hj=N 9vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_close.stub-R~hj-J]7vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_uid.stubR~hj*Bvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_mailboxmsginfo.stubR~hj28Bvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_listsubscribed.stub9R~hj9?9:8vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_scan.stubOR~hjO^BeM=vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_mail_copy.stubR~hjt<vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_listscan.stubR~hj!Iۤ:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_search.stub-R~hj-R-vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_last_error.stub4R~hj48vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_open.stubR~hjD;vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_num_msg.stubR~hjb19vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_msgno.stubR~hj^7.Fvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_mime_header_decode.stubPR~hjPplr:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_setacl.stubR~hj9v:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_errors.stub/R~hj/r8vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_sort.stub}R~hj}-?ܤ:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_delete.stubrR~hjrǖ{>vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_num_recent.stubR~hjE67Avendor/phpstan/php-8-stubs/stubs/ext/imap/imap_mutf7_to_utf8.stubER~hjE:ܤ9vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_check.stubR~hj?8<vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_savebody.stubuR~hjuQp=vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_mail_move.stubR~hj)Ԥ:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_thread.stubR~hjvW8vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_ping.stubR~hjI@@<vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_undelete.stubxR~hjx>$?vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_listmailbox.stub3R~hj3hk:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_create.stubR~hje6Bvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_clearflag_full.stubR~hjcڤ:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_status.stubR~hj(%2:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_append.stubUR~hjU(^:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_base64.stub>R~hj>T'Avendor/phpstan/php-8-stubs/stubs/ext/imap/imap_get_quotaroot.stubR~hjž?vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_scanmailbox.stub]R~hj]?=vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_subscribe.stubR~hj-f=vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_get_quota.stubIR~hjIR<;vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_headers.stubR~hja 8vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_utf8.stubAR~hjA t:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_getacl.stubR~hjk>vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_headerinfo.stubCR~hjC}V@Hvendor/phpstan/php-8-stubs/stubs/ext/imap/imap_rfc822_parse_adrlist.stub_R~hj_c6vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_gc.stubR~hj!װ:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_reopen.stub R~hj 7:o?vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_utf7_decode.stubCR~hjCb5:vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_rename.stubR~hjX֤?vendor/phpstan/php-8-stubs/stubs/ext/imap/imap_unsubscribe.stubR~hj'{J=vendor/phpstan/php-8-stubs/stubs/ext/exif/exif_read_data.stubR~hj~&;vendor/phpstan/php-8-stubs/stubs/ext/exif/exif_tagname.stub]R~hj]J)f=vendor/phpstan/php-8-stubs/stubs/ext/exif/exif_imagetype.stub@R~hj@vY=vendor/phpstan/php-8-stubs/stubs/ext/exif/exif_thumbnail.stubR~hj-)@vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_clean_repair.stub9R~hj9c]<vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_get_head.stub;R~hj;{`<vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_get_body.stub;R~hj;):vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_is_xml.stub3R~hj3դ@vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_parse_string.stubR~hjf*H:vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_getopt.stubNR~hjN\T->vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_get_output.stub9R~hj9J@vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_config_count.stub8R~hj8ŗ?vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_repair_file.stubR~hj絲7vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidyNode.stubR~hjѲޤ@vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_access_count.stub8R~hj8>vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_parse_file.stubR~hj_xN?vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_error_count.stub7R~hj7Å@Avendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_repair_string.stubR~hjc @vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_get_html_ver.stub8R~hj83vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy.stubY R~hjY q?vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_get_release.stub/R~hj/[6G<vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_get_root.stub;R~hj;I<vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_diagnose.stub5R~hj5¤>vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_get_config.stub?R~hj?=Dvendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_get_error_buffer.stubER~hjE&+?vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_get_opt_doc.stubjR~hjj-<vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_is_xhtml.stub5R~hj5>0Avendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_warning_count.stub9R~hj9>vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_get_status.stub6R~hj6731<vendor/phpstan/php-8-stubs/stubs/ext/tidy/tidy_get_html.stub;R~hj;g5;vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_version.stubGR~hjG_F9vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_pause.stubvR~hjv i;9vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_errno.stub9R~hj9?vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_multi_close.stubKR~hjKD$)<vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_strerror.stub<R~hj<óqBvendor/phpstan/php-8-stubs/stubs/ext/curl/curl_share_strerror.stubBR~hjBm2?vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_share_errno.stubJR~hjJu9vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_error.stub<R~hj<>ti@vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_share_setopt.stubgR~hjg?vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_copy_handle.stubMR~hjM 8vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_exec.stubGR~hjGa<vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_unescape.stubUR~hjU:vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_upkeep.stubR~hjj:vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_escape.stubR~hj>vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_multi_exec.stub{R~hj{ IJGvendor/phpstan/php-8-stubs/stubs/ext/curl/curl_multi_remove_handle.stubgR~hjgm?vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_file_create.stub~R~hj~1$jBvendor/phpstan/php-8-stubs/stubs/ext/curl/curl_multi_strerror.stubBR~hjB@vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_setopt_array.stubQR~hjQxgLDvendor/phpstan/php-8-stubs/stubs/ext/curl/curl_multi_getcontent.stubHR~hjH87vendor/phpstan/php-8-stubs/stubs/ext/curl/CURLFile.stubR~hjn7B=vendor/phpstan/php-8-stubs/stubs/ext/curl/CURLStringFile.stubR~hj'V;vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_getinfo.stubRR~hjR3?vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_multi_errno.stubJR~hjJ h9vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_reset.stubAR~hjAuL@vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_multi_setopt.stubgR~hjg}ˤ>vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_multi_init.stub8R~hj85ƤDvendor/phpstan/php-8-stubs/stubs/ext/curl/curl_multi_add_handle.stubdR~hjd8QA:9vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_close.stub:R~hj:09q?vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_share_close.stubKR~hjK>n>vendor/phpstan/php-8-stubs/stubs/ext/curl/CurlMultiHandle.stub'R~hj'`f`@vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_multi_select.stubaR~hja`x>vendor/phpstan/php-8-stubs/stubs/ext/curl/CurlShareHandle.stub'R~hj'4\4Cvendor/phpstan/php-8-stubs/stubs/ext/curl/curl_multi_info_read.stubR~hjԂ:vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_setopt.stubVR~hjVb9vendor/phpstan/php-8-stubs/stubs/ext/curl/CurlHandle.stubDR~hjD8vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_init.stubFR~hjFB4>vendor/phpstan/php-8-stubs/stubs/ext/curl/curl_share_init.stub8R~hj8ZHɤ;vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_alarm.stub3R~hj3u>>vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_strerror.stubCR~hjCfV:vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_fork.stubHR~hjHҤ=vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_unshare.stubHR~hjHk5<vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_waitid.stubR~hjܸ =vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_waitpid.stubR~hjAAvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_sigprocmask.stubR~hjvBvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_getqos_class.stub|R~hj|%<vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_getcpu.stubYR~hjY2;vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_setns.stubR~hjG<vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_signal.stubR~hjAvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_setpriority.stubR~hj9Dvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_getcpuaffinity.stubR~hjIn;vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_errno.stubJR~hjJ6~:vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_wait.stubR~hjtMCvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_async_signals.stubDR~hjD>8>vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_wtermsig.stub;R~hj;LQAvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_wexitstatus.stub>R~hj>Ӑ !Evendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_signal_dispatch.stub2R~hj2:"Hvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_signal_get_handler.stubVR~hjV%>vendor/phpstan/php-8-stubs/stubs/ext/pcntl/Pcntl/QosClass.stubR~hjitVAvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_sigwaitinfo.stubR~hj"OBvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_sigtimedwait.stubR~hji>vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_wstopsig.stub;R~hj; tu;vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_rfork.stublR~hjl :vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_exec.stub[R~hj[ʤ;vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_forkx.stub[R~hj[1ߤ?vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_wifexited.stubER~hjE4 5Bvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_setqos_class.stubtR~hjtDbBvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_wifcontinued.stubQR~hjQhAvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_wifsignaled.stub@R~hj@Dvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_get_last_error.stub0R~hj0h1@vendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_wifstopped.stub8R~hj8pAvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_getpriority.stub|R~hj|Dvendor/phpstan/php-8-stubs/stubs/ext/pcntl/pcntl_setcpuaffinity.stubnR~hjn~=Ƥ8vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_nb_get.stubUR~hjU7vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_chmod.stubR~hjoG6vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_site.stubR~hj<vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_set_option.stub R~hj ^e8vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_append.stub/R~hj/w8vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_rename.stubR~hj^❤6vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_mlsd.stubR~hj٬Ԥ7vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_close.stubR~hjƅV<vendor/phpstan/php-8-stubs/stubs/ext/ftp/FTP/Connection.stubvR~hjv;p6vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_pasv.stubR~hja~6vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_quit.stubR~hj_9vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_nb_fget.stubqR~hjqBE5vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_get.stubKR~hjKŧ6vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_exec.stubR~hjXB`7vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_login.stubR~hjB"9vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_nb_fput.stubqR~hjq6vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_fput.stubmR~hjm3y<vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_get_option.stubR~hjWU!=vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_nb_continue.stubR~hjc Ǥ9vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_systype.stubR~hjn8vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_delete.stubR~hj_96vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_cdup.stubR~hj"=vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_ssl_connect.stub*R~hj*kv7vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_nlist.stub R~hj ]6vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_mdtm.stubR~hj@ԅ5vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_raw.stubR~hj.Z7vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_alloc.stubR~hj*6vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_fget.stubmR~hjm~F8vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_nb_put.stub[R~hj[dC#T5vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_put.stubKR~hjK&ۤ9vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_connect.stubR~hj`q5vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_pwd.stubR~hjvEF6vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_size.stubR~hj'E7vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_mkdir.stubR~hjԵ19vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_rawlist.stub@R~hj@_7vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_rmdir.stubR~hj7vendor/phpstan/php-8-stubs/stubs/ext/ftp/ftp_chdir.stubR~hj0e;vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_rollback.stubWR~hjWUD]7vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocifetch.stubxR~hjxAvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_collection_max.stubNR~hjNpo<vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocibindbyname.stubR~hjܸt7vendor/phpstan/php-8-stubs/stubs/ext/oci8/ociparse.stubR~hjW[Dvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_collection_assign.stubZR~hjZ=vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_append.stubER~hjEҒ<>vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocidefinebyname.stubR~hj:vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicolltrim.stubR~hj;vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocifetchinto.stubR~hj%:vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_connect.stubR~hjb]m=vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocisavelobfile.stubyR~hjySp;vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_save.stubTR~hjTyD*9vendor/phpstan/php-8-stubs/stubs/ext/oci8/ociexecute.stubR~hju7vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocierror.stubR~hj__Avendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_client_version.stub1R~hj1;vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocinewcursor.stubR~hjtգ>vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_fetch_array.stubR~hjQ?vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_set_prefetch.stubdR~hjdק:vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicollsize.stub|R~hj|?vendor/phpstan/php-8-stubs/stubs/ext/oci8/ociserverversion.stubR~hjh:vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_eof.stub4R~hj4D,nBvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_free_descriptor.stub<R~hj<# >vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_new_connect.stubR~hjqHBvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_password_change.stubR~hjP;vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_tell.stub:R~hj:yK@vendor/phpstan/php-8-stubs/stubs/ext/oci8/ociwritelobtofile.stubR~hjѯAvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_field_type_raw.stubtR~hjt+k=vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_export.stubsR~hjsH>=vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_field_name.stubsR~hjs%ɤAvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_new_descriptor.stub|R~hj|C"Bvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_free_collection.stubJR~hjJM|y=vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicollgetelem.stubR~hj"<vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_fetch_all.stubR~hj(?1>vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicolumnisnull.stubR~hjׄ;vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_num_rows.stubZR~hjZ ƤAvendor/phpstan/php-8-stubs/stubs/ext/oci8/ocigetbufferinglob.stub;R~hj;dȤ<vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicolumnname.stubR~hj:?vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_fetch_object.stubR~hjVLWͤAvendor/phpstan/php-8-stubs/stubs/ext/oci8/ocisetbufferinglob.stubGR~hjGPD0Ф>vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_field_scale.stubqR~hjqHvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_set_client_identifier.stubwR~hjws<vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicollappend.stubR~hj158vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocinlogon.stubR~hjd \9vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocinumcols.stub~R~hj~NY9vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocisavelob.stubR~hj%y<>vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_fetch_assoc.stub_R~hj_i@vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocifreecollection.stub}R~hj}~a8vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicancel.stubzR~hjzV_<vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_erase.stubeR~hjeBvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_set_module_name.stublR~hjlog?vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicolumntyperaw.stubR~hjHuä=vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_num_fields.stubVR~hjVTwAvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_define_by_name.stubR~hj^٬Lvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_collection_element_assign.stuboR~hjoAÀ;vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_copy.stubXR~hjXۅњ=vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_import.stubIR~hjI95֤:vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocirollback.stubR~hj8vendor/phpstan/php-8-stubs/stubs/ext/oci8/ociresult.stubR~hjM;:vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocirowcount.stubR~hjԧIvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_collection_element_get.stubpR~hjp 8vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicommit.stub|R~hj|Ҥ<vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_flush.stubER~hjEţ;vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_seek.stub^R~hj^5ݤ9vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_commit.stubUR~hjU&ФCvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_set_call_timeout.stubmR~hjm2=vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_field_size.stubpR~hjpH3Τ?vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_bind_by_name.stubR~hjZ<vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicolumntype.stubR~hjF ?vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocistatementtype.stubR~hjaÅ9vendor/phpstan/php-8-stubs/stubs/ext/oci8/ociloadlob.stubiR~hji#e=8vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_error.stubR~hjYAvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_server_version.stubeR~hje>vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_set_edition.stub;R~hj;?r@vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocifetchstatement.stubR~hj ex9vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicollmax.stubzR~hjz,?vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocinewdescriptor.stubR~hjʆH?vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_is_equal.stubIR~hjISYAvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_statement_type.stubcR~hjci%H:vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocifreedesc.stubiR~hjitD(=vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocisetprefetch.stubR~hj98vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_fetch.stubRR~hjR&դ:vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_execute.stubwR~hjwHj;vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_load.stub=R~hj=?vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocinewcollection.stubR~hjEvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_bind_array_by_name.stubR~hj^$<vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_write.stub^R~hj^8kBvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_collection_trim.stubTR~hjT+S=vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_field_type.stubwR~hjwG8vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_close.stubUR~hjU'^N;vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_pconnect.stubR~hj+v;vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_read.stubJR~hjJBvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_collection_size.stubOR~hjOX=vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicolumnscale.stubR~hjEF=vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_set_action.stubiR~hjiDà֤<vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_fetch_row.stub]R~hj]ҺޤBvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_set_client_info.stubwR~hjwJ8;vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_size.stub:R~hj:!0:9vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_result.stubhR~hjhG%ȤHvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_register_taf_callback.stubyR~hjyN Dvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_collection_append.stub[R~hj[8vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocilogoff.stub|R~hj|Ĭ0y7vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocilogon.stubR~hj{c2Avendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_free_statement.stub[R~hj[+6+@vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocipasswordchange.stubR~hj@vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_field_is_null.stubnR~hjnJ<vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicolumnsize.stubR~hj0Cvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_set_prefetch_lob.stubR~hj <<vendor/phpstan/php-8-stubs/stubs/ext/oci8/OCICollection.stubR~hjqX]9vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_cancel.stubSR~hjSBvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_field_precision.stubuR~hjuڙCvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_set_db_operation.stuboR~hjo,}b>vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_free_cursor.stubyR~hjysQ5vendor/phpstan/php-8-stubs/stubs/ext/oci8/OCILob.stub< R~hj< Ĥ=vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_new_cursor.stubqR~hjq ʤIvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_get_implicit_resultset.stub{R~hj{Avendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_new_collection.stubR~hj4 8vendor/phpstan/php-8-stubs/stubs/ext/oci8/ociplogon.stubR~hj<@vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicollassignelem.stubR~hj KV<vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocifreecursor.stubR~hj`Y'Jvendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_unregister_taf_callback.stubfR~hjfƤ8vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_parse.stubyR~hjyä?vendor/phpstan/php-8-stubs/stubs/ext/oci8/ocifreestatement.stubR~hje Avendor/phpstan/php-8-stubs/stubs/ext/oci8/ocicolumnprecision.stubR~hj/m?vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_truncate.stubJR~hjJ=vendor/phpstan/php-8-stubs/stubs/ext/oci8/oci_lob_rewind.stub7R~hj7T6RDvendor/phpstan/php-8-stubs/stubs/ext/simplexml/SimpleXMLElement.stub R~hj Evendor/phpstan/php-8-stubs/stubs/ext/simplexml/SimpleXMLIterator.stub=R~hj= Ivendor/phpstan/php-8-stubs/stubs/ext/simplexml/simplexml_load_string.stubR~hjs,Gvendor/phpstan/php-8-stubs/stubs/ext/simplexml/simplexml_load_file.stubR~hjHvendor/phpstan/php-8-stubs/stubs/ext/simplexml/simplexml_import_dom.stub#R~hj#u֤Tvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_aead_aegis128l_keygen.stubSR~hjSMUvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_aead_aegis128l_encrypt.stubR~hjځWvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_core_ristretto255_random.stubVR~hjVzLvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_sign_detached.stub]R~hj] UUvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_aead_aes256gcm_encrypt.stubR~hjr;vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_pad.stubHR~hjHZO[Ovendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_generichash_init.stub|R~hj|UD8sOvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_secretbox_keygen.stub=R~hj=oTvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_core_ristretto255_sub.stubgR~hjgo:Mvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_secretbox_open.stuboR~hjo07(Kvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_sign_keypair.stub9R~hj9ۥ?vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_memzero.stub:R~hj:Ivendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_kx_keypair.stub7R~hj7;&Kvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_kx_secretkey.stubIR~hjIgS}Vvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_stream_xchacha20_xor_ic.stubR~hj:8Jvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_auth_verify.stub_R~hj_W#Nvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_scalarmult_base.stubR~hjYL!;vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_add.stubHR~hjHETvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_aead_aes256gcm_keygen.stubBR~hjBTE%avendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_aead_chacha20poly1305_ietf_encrypt.stubR~hjJ>vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_memcmp.stubIR~hjI+H Ovendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_stream_xchacha20.stubR~hjzgvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_secretstream_xchacha20poly1305_init_pull.stubpR~hjp"nMvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_sign_secretkey.stubKR~hjK*Vvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_scalarmult_ristretto255.stubR~hjWhHvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_shorthash.stubYR~hjYxˁ\vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_sign_ed25519_sk_to_curve25519.stub\R~hj\!,Qvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_generichash_keygen.stub?R~hj? a`vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_aead_chacha20poly1305_ietf_keygen.stubNR~hjNu?vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_compare.stubJR~hjJ(gIZvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_pwhash_scryptsalsa208sha256.stubR~hjo^vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_core_ristretto255_scalar_negate.stubfR~hjfUĤIvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_scalarmult.stubRR~hjR+(dvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_secretstream_xchacha20poly1305_keygen.stubR~hjgvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_secretstream_xchacha20poly1305_init_push.stub_R~hj_7$m%?vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_hex2bin.stubPR~hjP$54Cvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_auth.stubTR~hjTVȮbvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_aead_xchacha20poly1305_ietf_decrypt.stubR~hjh\Lhvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_sign_keypair_from_secretkey_and_publickey.stub|R~hj|2ڤPvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_sign_seed_keypair.stubJR~hjJy@Ivendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_stream_xor.stubbR~hjb[Svendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_sign_verify_detached.stubuR~hju"R[vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_core_ristretto255_scalar_add.stubnR~hjn3>m[vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_scalarmult_ristretto255_base.stubcR~hjc-ُ~Hvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_sign_open.stubfR~hjfY\Mvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_sign_publickey.stubKR~hjK|O Pvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_pwhash_str_verify.stubZR~hjZ9Bvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_bin2base64.stubmR~hjmfߤJvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_auth_keygen.stub8R~hj8`@Qbvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_secretstream_xchacha20poly1305_push.stubR~hjauZvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_core_ristretto255_from_hash.stubbR~hjbฤOvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_shorthash_keygen.stub=R~hj=]N̤Zvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_aead_aes256gcm_is_available.stubhR~hjh<Uvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_kx_client_session_keys.stubmR~hjm#,[vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_core_ristretto255_scalar_sub.stubnR~hjnKm@vendor/phpstan/php-8-stubs/stubs/ext/sodium/SodiumException.stub4R~hj4\Svendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_aead_aegis256_keygen.stubRR~hjR'0XLvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_box_publickey.stubJR~hjJВ3Svendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_stream_xchacha20_xor.stub}R~hj}kUIvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_kdf_keygen.stub7R~hj7IǤ^vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_core_ristretto255_scalar_invert.stubfR~hjfwLvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_box_seal_open.stubdR~hjdgVvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_pwhash_str_needs_rehash.stubR~hjq{WDTvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_aead_aegis256_decrypt.stubR~hjcvendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_secretstream_xchacha20poly1305_rekey.stub]R~hj] 9[vendor/phpstan/php-8-stubs/stubs/ext/sodium/sodium_crypto_aead_chacha20poly1305_keygen.stubIR~hjIvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_strripos.stubxR~hjxȴ;vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_eregi.stubsR~hjs>vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_strwidth.stubOR~hjO*Jvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_substitute_character.stubkR~hjk5sϤ=vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_lcfirst.stubbR~hjbUO=vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_ucfirst.stubbR~hjbS~ۤFvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_convert_encoding.stubR~hj)Jv@vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_http_input.stubcR~hjcGBvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_ereg_replace.stubR~hjD>vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_get_info.stub/R~hj/bߗ Gvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_convert_variables.stubR~hj}Z=vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_stripos.stubwR~hjwn?vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_parse_str.stub]R~hj]'&Gvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_regex_set_options.stubJR~hjJRޘ@vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_ereg_match.stubbR~hjb^@vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_strimwidth.stubR~hjcG=vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_strrchr.stubR~hj铤Kvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_ereg_replace_callback.stubR~hj9vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_ord.stubPR~hjP_Bvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_convert_kana.stubkR~hjkyQI~Bvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_convert_case.stubaR~hja7).Evendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_ereg_search_pos.stub}R~hj}AߤHvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_ereg_search_getpos.stub1R~hj1]5>vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_language.stubiR~hjiqCvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_eregi_replace.stubR~hj%7Dvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_output_handler.stubKR~hjKi0Dvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_check_encoding.stubgR~hjgP=vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_stristr.stubR~hj3;vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_ltrim.stub|R~hj|o᪤<vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_substr.stubqR~hjqW@vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_strtoupper.stubTR~hjT;vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_rtrim.stub|R~hj|@Fvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_ereg_search_regs.stub~R~hj~j?vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_send_mail.stubR~hjAHvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_ereg_search_setpos.stub=R~hj=d^;vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_scrub.stubOR~hjO(RR<vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_strstr.stubR~hjB@vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_strtolower.stubTR~hjTnWFvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_encoding_aliases.stubXR~hjXZEvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_detect_encoding.stubR~hjE9vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_chr.stubSR~hjS9,;vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_split.stubsR~hjs Gvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_internal_encoding.stubPR~hjP{Dvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_list_encodings.stub/R~hj/f-=vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_str_pad.stubR~hj 2Jvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_decode_numericentity.stubjR~hjj3䍤Avendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_http_output.stubJR~hjJT.<vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_strlen.stubMR~hjM*j>vendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_strrichr.stubR~hjRBvendor/phpstan/php-8-stubs/stubs/ext/mbstring/mb_substr_count.stubeR~hjeJRvendor/phpstan/php-8-stubs/stubs/ext/libxml/libxml_get_external_entity_loader.stubTR~hjTaARvendor/phpstan/php-8-stubs/stubs/ext/libxml/libxml_set_external_entity_loader.stubZR~hjZfrlKvendor/phpstan/php-8-stubs/stubs/ext/libxml/libxml_use_internal_errors.stubOR~hjOnu8Fvendor/phpstan/php-8-stubs/stubs/ext/libxml/libxml_get_last_error.stub@R~hj@)Mvendor/phpstan/php-8-stubs/stubs/ext/libxml/libxml_disable_entity_loader.stub`R~hj`Kvendor/phpstan/php-8-stubs/stubs/ext/libxml/libxml_set_streams_context.stub_R~hj_pu+Dvendor/phpstan/php-8-stubs/stubs/ext/libxml/libxml_clear_errors.stub0R~hj0'<vendor/phpstan/php-8-stubs/stubs/ext/libxml/LibXMLError.stub?R~hj?Bvendor/phpstan/php-8-stubs/stubs/ext/libxml/libxml_get_errors.stub/R~hj/Gvendor/phpstan/php-8-stubs/stubs/ext/date/timezone_transitions_get.stubR~hj 7vendor/phpstan/php-8-stubs/stubs/ext/date/date_add.stubTR~hjT57fCvendor/phpstan/php-8-stubs/stubs/ext/date/date_interval_format.stubXR~hjXDHvendor/phpstan/php-8-stubs/stubs/ext/date/date_default_timezone_get.stub8R~hj8 H6<vendor/phpstan/php-8-stubs/stubs/ext/date/date_date_set.stubaR~hjai&5vendor/phpstan/php-8-stubs/stubs/ext/date/mktime.stubR~hjqdPvendor/phpstan/php-8-stubs/stubs/ext/date/date_create_immutable_from_format.stubR~hjhBvendor/phpstan/php-8-stubs/stubs/ext/date/timezone_offset_get.stubbR~hjb 8vendor/phpstan/php-8-stubs/stubs/ext/date/checkdate.stubER~hjE&<vendor/phpstan/php-8-stubs/stubs/ext/date/timezone_open.stubIR~hjI.4vendor/phpstan/php-8-stubs/stubs/ext/date/idate.stubMR~hjM18Hvendor/phpstan/php-8-stubs/stubs/ext/date/timezone_identifiers_list.stubR~hj:vendor/phpstan/php-8-stubs/stubs/ext/date/date_modify.stubVR~hjV {U@vendor/phpstan/php-8-stubs/stubs/ext/date/date_timezone_get.stubWR~hjW |Kvendor/phpstan/php-8-stubs/stubs/ext/date/DateInvalidTimeZoneException.stubtR~hjt~M=vendor/phpstan/php-8-stubs/stubs/ext/date/DateRangeError.stubbR~hjb(uTvendor/phpstan/php-8-stubs/stubs/ext/date/date_interval_create_from_date_string.stubaR~hjaa׀ 5vendor/phpstan/php-8-stubs/stubs/ext/date/gmdate.stubKR~hjKeHvendor/phpstan/php-8-stubs/stubs/ext/date/date_default_timezone_set.stubHR~hjH`eKvendor/phpstan/php-8-stubs/stubs/ext/date/DateMalformedStringException.stubtR~hjttkw>vendor/phpstan/php-8-stubs/stubs/ext/date/DateObjectError.stubcR~hjcG\;vendor/phpstan/php-8-stubs/stubs/ext/date/date_sunrise.stubR~hjˠEvendor/phpstan/php-8-stubs/stubs/ext/date/date_parse_from_format.stubkR~hjkMYu;vendor/phpstan/php-8-stubs/stubs/ext/date/DateTimeZone.stubaR~hjaƲ@vendor/phpstan/php-8-stubs/stubs/ext/date/timezone_name_get.stubER~hjEJ<vendor/phpstan/php-8-stubs/stubs/ext/date/DateException.stubaR~hjaf@vendor/phpstan/php-8-stubs/stubs/ext/date/DateTimeInterface.stub R~hj 8vendor/phpstan/php-8-stubs/stubs/ext/date/localtime.stuboR~hjo#v3vendor/phpstan/php-8-stubs/stubs/ext/date/time.stub R~hj e<vendor/phpstan/php-8-stubs/stubs/ext/date/date_sun_info.stubsR~hjs&)Fvendor/phpstan/php-8-stubs/stubs/ext/date/timezone_name_from_abbr.stubnR~hjn7vendor/phpstan/php-8-stubs/stubs/ext/date/gmmktime.stubR~hj˜7vendor/phpstan/php-8-stubs/stubs/ext/date/date_sub.stubTR~hjTq}@vendor/phpstan/php-8-stubs/stubs/ext/date/DateTimeImmutable.stub R~hj _s1:vendor/phpstan/php-8-stubs/stubs/ext/date/date_format.stubTR~hjTq(%ӤAvendor/phpstan/php-8-stubs/stubs/ext/date/date_timestamp_set.stubUR~hjU%=7vendor/phpstan/php-8-stubs/stubs/ext/date/DateTime.stubR~hjҤ<vendor/phpstan/php-8-stubs/stubs/ext/date/date_time_set.stubR~hjr@9vendor/phpstan/php-8-stubs/stubs/ext/date/DatePeriod.stubR~hj@#ZLvendor/phpstan/php-8-stubs/stubs/ext/date/DateInvalidOperationException.stubuR~hju+`Cvendor/phpstan/php-8-stubs/stubs/ext/date/timezone_version_get.stub3R~hj3a1njSvendor/phpstan/php-8-stubs/stubs/ext/date/DateMalformedIntervalStringException.stub|R~hj|oȗAvendor/phpstan/php-8-stubs/stubs/ext/date/date_timestamp_get.stubHR~hjH/a=?vendor/phpstan/php-8-stubs/stubs/ext/date/date_isodate_set.stubmR~hjmwl;vendor/phpstan/php-8-stubs/stubs/ext/date/DateInterval.stubR~hjf8vendor/phpstan/php-8-stubs/stubs/ext/date/date_diff.stubR~hjS~8vendor/phpstan/php-8-stubs/stubs/ext/date/DateError.stubYR~hjYCvendor/phpstan/php-8-stubs/stubs/ext/date/date_get_last_errors.stubOR~hjO֩[9vendor/phpstan/php-8-stubs/stubs/ext/date/gmstrftime.stubUR~hjU~_qFvendor/phpstan/php-8-stubs/stubs/ext/date/date_create_from_format.stubR~hj4:vendor/phpstan/php-8-stubs/stubs/ext/date/date_create.stublR~hjl/8vendor/phpstan/php-8-stubs/stubs/ext/date/strtotime.stubyR~hjyIѤ3vendor/phpstan/php-8-stubs/stubs/ext/date/date.stubIR~hjIY7vendor/phpstan/php-8-stubs/stubs/ext/date/strftime.stubSR~hjStQvendor/phpstan/php-8-stubs/stubs/ext/date/DateMalformedPeriodStringException.stubzR~hjz& TJvendor/phpstan/php-8-stubs/stubs/ext/date/timezone_abbreviations_list.stubPR~hjPP69Dvendor/phpstan/php-8-stubs/stubs/ext/date/timezone_location_get.stubeR~hje:¤Dvendor/phpstan/php-8-stubs/stubs/ext/date/date_create_immutable.stubR~hj:vendor/phpstan/php-8-stubs/stubs/ext/date/date_sunset.stubR~hj`qg6vendor/phpstan/php-8-stubs/stubs/ext/date/getdate.stubRR~hjR]Tp<9vendor/phpstan/php-8-stubs/stubs/ext/date/date_parse.stubOR~hjO%->vendor/phpstan/php-8-stubs/stubs/ext/date/date_offset_get.stubER~hjEZ)@vendor/phpstan/php-8-stubs/stubs/ext/date/date_timezone_set.stub]R~hj](?vendor/phpstan/php-8-stubs/stubs/ext/session/session_abort.stub*R~hj*]ĤJvendor/phpstan/php-8-stubs/stubs/ext/session/session_set_save_handler.stubR~hj_Ӥ>vendor/phpstan/php-8-stubs/stubs/ext/session/session_name.stubgR~hjgC;?vendor/phpstan/php-8-stubs/stubs/ext/session/session_reset.stub*R~hj*l@vendor/phpstan/php-8-stubs/stubs/ext/session/session_commit.stubMR~hjMn =Dvendor/phpstan/php-8-stubs/stubs/ext/session/SessionIdInterface.stubR~hjbᣤKvendor/phpstan/php-8-stubs/stubs/ext/session/session_set_cookie_params.stubR~hj4@vendor/phpstan/php-8-stubs/stubs/ext/session/session_status.stub*R~hj*Qe@vendor/phpstan/php-8-stubs/stubs/ext/session/session_encode.stub3R~hj3 o4Avendor/phpstan/php-8-stubs/stubs/ext/session/session_destroy.stub,R~hj,N@vendor/phpstan/php-8-stubs/stubs/ext/session/SessionHandler.stubR~hj?vendor/phpstan/php-8-stubs/stubs/ext/session/session_start.stub=R~hj=1T<vendor/phpstan/php-8-stubs/stubs/ext/session/session_id.stubAR~hjA󁬤?vendor/phpstan/php-8-stubs/stubs/ext/session/session_unset.stub*R~hj* P%Gvendor/phpstan/php-8-stubs/stubs/ext/session/session_cache_limiter.stubOR~hjOV<vendor/phpstan/php-8-stubs/stubs/ext/session/session_gc.stub,R~hj,Kvendor/phpstan/php-8-stubs/stubs/ext/session/session_get_cookie_params.stubNR~hjN:\aIvendor/phpstan/php-8-stubs/stubs/ext/session/SessionHandlerInterface.stubR~hj&)Cvendor/phpstan/php-8-stubs/stubs/ext/session/session_save_path.stubJR~hjJ.ZXvendor/phpstan/php-8-stubs/stubs/ext/session/SessionUpdateTimestampHandlerInterface.stub+R~hj+BFvendor/phpstan/php-8-stubs/stubs/ext/session/session_cache_expire.stubHR~hjHEvendor/phpstan/php-8-stubs/stubs/ext/session/session_module_name.stubNR~hjNrQKvendor/phpstan/php-8-stubs/stubs/ext/session/session_register_shutdown.stub6R~hj6KSGvendor/phpstan/php-8-stubs/stubs/ext/session/session_regenerate_id.stubRR~hjRMch@vendor/phpstan/php-8-stubs/stubs/ext/session/session_decode.stub7R~hj7쭤Evendor/phpstan/php-8-stubs/stubs/ext/session/session_write_close.stub0R~hj0H8Cvendor/phpstan/php-8-stubs/stubs/ext/session/session_create_id.stubIR~hjI)i8vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreate.stubIR~hjI$>vendor/phpstan/php-8-stubs/stubs/ext/gd/imagegammacorrect.stubfR~hjft<vendor/phpstan/php-8-stubs/stubs/ext/gd/imagegrabscreen.stub6R~hj6cODvendor/phpstan/php-8-stubs/stubs/ext/gd/imagetruecolortopalette.stubbR~hjb?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecopymergegray.stubR~hj0cX4vendor/phpstan/php-8-stubs/stubs/ext/gd/GdImage.stubAR~hjA_n ¤Cvendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefromgd2part.stubvR~hjvH?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefromgif.stubIR~hjIik7<vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolormatch.stubNR~hjN}LǤ?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorallocate.stubdR~hjdպ9vendor/phpstan/php-8-stubs/stubs/ext/gd/imagettftext.stubR~hj*j:vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecropauto.stubR~hj-Avendor/phpstan/php-8-stubs/stubs/ext/gd/imageaffinematrixget.stubR~hj{9;vendor/phpstan/php-8-stubs/stubs/ext/gd/imagefontwidth.stubR~hjd~Ҥ6vendor/phpstan/php-8-stubs/stubs/ext/gd/imageavif.stubR~hjJ(a@vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefromjpeg.stub]R~hj]x<vendor/phpstan/php-8-stubs/stubs/ext/gd/imagegrabwindow.stubmR~hjmp5vendor/phpstan/php-8-stubs/stubs/ext/gd/imagexbm.stubmR~hjm/n5vendor/phpstan/php-8-stubs/stubs/ext/gd/imagegd2.stubR~hjfaDvendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorallocatealpha.stubuR~hjuX3vendor/phpstan/php-8-stubs/stubs/ext/gd/GdFont.stubbR~hjb+<8vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecharup.stubR~hjڤ5vendor/phpstan/php-8-stubs/stubs/ext/gd/imagegif.stubkR~hjk 6vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecopy.stubR~hjo=vendor/phpstan/php-8-stubs/stubs/ext/gd/imageconvolution.stubjR~hjj$ݤ@vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefromwebp.stubeR~hjeY >vendor/phpstan/php-8-stubs/stubs/ext/gd/imagesetthickness.stubMR~hjM݉6vendor/phpstan/php-8-stubs/stubs/ext/gd/imagejpeg.stubR~hjQfDvendor/phpstan/php-8-stubs/stubs/ext/gd/imagepalettetotruecolor.stubCR~hjCI;vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecopymerge.stubR~hj2\>?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecopyresampled.stubR~hju88vendor/phpstan/php-8-stubs/stubs/ext/gd/imageftbbox.stubR~hjM?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagealphablending.stubLR~hjLc=vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecopyresized.stubR~hjbKܤ<vendor/phpstan/php-8-stubs/stubs/ext/gd/imagedashedline.stubkR~hjkV?8vendor/phpstan/php-8-stubs/stubs/ext/gd/imagefttext.stubR~hj^ 8vendor/phpstan/php-8-stubs/stubs/ext/gd/imageaffine.stubeR~hje Avendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatetruecolor.stubRR~hjRޤ;vendor/phpstan/php-8-stubs/stubs/ext/gd/imageinterlace.stubPR~hjP;7vendor/phpstan/php-8-stubs/stubs/ext/gd/imagetypes.stub&R~hj&o JAvendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorclosesthwb.stub`R~hj`-خ9vendor/phpstan/php-8-stubs/stubs/ext/gd/imagepolygon.stubuR~hjuCCvendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorclosestalpha.stubnR~hjnPAvendor/phpstan/php-8-stubs/stubs/ext/gd/imagefilledrectangle.stubpR~hjpVd0Bvendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolortransparent.stubTR~hjTϤ6vendor/phpstan/php-8-stubs/stubs/ext/gd/imagewebp.stubR~hj%b;vendor/phpstan/php-8-stubs/stubs/ext/gd/imagesavealpha.stubHR~hjHF[Bvendor/phpstan/php-8-stubs/stubs/ext/gd/imagegetinterpolation.stub@R~hj@W"u@vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefromavif.stubR~hjK5vendor/phpstan/php-8-stubs/stubs/ext/gd/imagearc.stubR~hj]sF>vendor/phpstan/php-8-stubs/stubs/ext/gd/imagefilltoborder.stublR~hjlyb9vendor/phpstan/php-8-stubs/stubs/ext/gd/imagegetclip.stubPR~hjPrBդ@vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorsforindex.stubcR~hjcO?9vendor/phpstan/php-8-stubs/stubs/ext/gd/imagesettile.stubHR~hjH̤?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefrombmp.stub\R~hj\DE>vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorclosest.stub]R~hj]xp6vendor/phpstan/php-8-stubs/stubs/ext/gd/imagefill.stubQR~hjQdBvendor/phpstan/php-8-stubs/stubs/ext/gd/imagesetinterpolation.stubcR~hjc$mDvendor/phpstan/php-8-stubs/stubs/ext/gd/imageaffinematrixconcat.stubpR~hjpI.4=vendor/phpstan/php-8-stubs/stubs/ext/gd/imageistruecolor.stub<R~hj< @f5vendor/phpstan/php-8-stubs/stubs/ext/gd/imagebmp.stubR~hjx+Cvendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorresolvealpha.stubnR~hjn1hV6vendor/phpstan/php-8-stubs/stubs/ext/gd/imageflip.stub@R~hj@k-Z 8vendor/phpstan/php-8-stubs/stubs/ext/gd/imagerotate.stubUR~hjUNv8vendor/phpstan/php-8-stubs/stubs/ext/gd/imagefilter.stub~R~hj~|&6vendor/phpstan/php-8-stubs/stubs/ext/gd/imagechar.stubR~hjڅ4vendor/phpstan/php-8-stubs/stubs/ext/gd/imagesy.stub2R~hj2iJ䫤=vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorstotal.stub;R~hj;Fp5vendor/phpstan/php-8-stubs/stubs/ext/gd/imagepng.stubR~hjXGC ;vendor/phpstan/php-8-stubs/stubs/ext/gd/imagefilledarc.stubR~hj/?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefrompng.stubcR~hjcBvendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefromstring.stubHR~hjHc6vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecrop.stubQR~hjQ :vendor/phpstan/php-8-stubs/stubs/ext/gd/imagesetpixel.stubUR~hjUBiW 6vendor/phpstan/php-8-stubs/stubs/ext/gd/imagewbmp.stubR~hjU?4vendor/phpstan/php-8-stubs/stubs/ext/gd/imagegd.stubIR~hjI9v9vendor/phpstan/php-8-stubs/stubs/ext/gd/imagedestroy.stub?R~hj? ݪ@vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefromwbmp.stubQR~hjQ ?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefromxpm.stub\R~hj\:q>vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorresolve.stub]R~hj]#ޤ:vendor/phpstan/php-8-stubs/stubs/ext/gd/imagesetbrush.stubJR~hjJs><vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorexact.stub[R~hj[Avendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorexactalpha.stublR~hjl<vendor/phpstan/php-8-stubs/stubs/ext/gd/imagefontheight.stubR~hjPjKK=vendor/phpstan/php-8-stubs/stubs/ext/gd/imagepalettecopy.stubIR~hjI\4?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagefilledpolygon.stub{R~hj{)E:vendor/phpstan/php-8-stubs/stubs/ext/gd/imagesetstyle.stubGR~hjG]=vendor/phpstan/php-8-stubs/stubs/ext/gd/imageopenpolygon.stubyR~hjyޅL;vendor/phpstan/php-8-stubs/stubs/ext/gd/imageantialias.stubHR~hjHYT<vendor/phpstan/php-8-stubs/stubs/ext/gd/imageresolution.stubR~hj)9vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorat.stubMR~hjMF&?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefromtga.stubcR~hjc6>&8vendor/phpstan/php-8-stubs/stubs/ext/gd/imagestring.stubR~hj@>vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefromgd.stubHR~hjH7rAvendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolordeallocate.stubLR~hjLGڤ4vendor/phpstan/php-8-stubs/stubs/ext/gd/gd_info.stub<R~hj<ՙG?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefromgd2.stubIR~hjI.4vendor/phpstan/php-8-stubs/stubs/ext/gd/imagesx.stub2R~hj2(QhŤ?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagefilledellipse.stubR~hj7!ܤ6vendor/phpstan/php-8-stubs/stubs/ext/gd/imageline.stubeR~hjex9vendor/phpstan/php-8-stubs/stubs/ext/gd/imageellipse.stub{R~hj{:=vendor/phpstan/php-8-stubs/stubs/ext/gd/imagelayereffect.stubIR~hjIf^?vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecreatefromxbm.stubPR~hjPW9vendor/phpstan/php-8-stubs/stubs/ext/gd/imagesetclip.stub\R~hj\7vendor/phpstan/php-8-stubs/stubs/ext/gd/imagescale.stub~R~hj~F2|>:vendor/phpstan/php-8-stubs/stubs/ext/gd/imagestringup.stubR~hjE9vendor/phpstan/php-8-stubs/stubs/ext/gd/imagettfbbox.stubR~hjdQ:vendor/phpstan/php-8-stubs/stubs/ext/gd/imagecolorset.stubR~hj\y.;vendor/phpstan/php-8-stubs/stubs/ext/gd/imagerectangle.stubjR~hjj~C7:vendor/phpstan/php-8-stubs/stubs/ext/gd/imageloadfont.stubR~hj"t禤7vendor/phpstan/php-8-stubs/stubs/ext/standard/stat.stubOR~hjO,`Lvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_context_get_params.stubrR~hjrt;vendor/phpstan/php-8-stubs/stubs/ext/standard/ob_start.stubrR~hjr}<9vendor/phpstan/php-8-stubs/stubs/ext/standard/printf.stubBR~hjB(<vendor/phpstan/php-8-stubs/stubs/ext/standard/array_pad.stubNR~hjN{~ ;vendor/phpstan/php-8-stubs/stubs/ext/standard/ob_clean.stub%R~hj%MҤ9vendor/phpstan/php-8-stubs/stubs/ext/standard/putenv.stubHR~hjH+V:vendor/phpstan/php-8-stubs/stubs/ext/standard/implode.stubSR~hjSq?V<vendor/phpstan/php-8-stubs/stubs/ext/standard/inet_ntop.stubUR~hjUYt٤=vendor/phpstan/php-8-stubs/stubs/ext/standard/addslashes.stub7R~hj7PYӛ>vendor/phpstan/php-8-stubs/stubs/ext/standard/get_headers.stubR~hj CC8vendor/phpstan/php-8-stubs/stubs/ext/standard/mkdir.stubR~hj Bvendor/phpstan/php-8-stubs/stubs/ext/standard/array_multisort.stubR~hjnla>vendor/phpstan/php-8-stubs/stubs/ext/standard/str_replace.stubR~hjIvendor/phpstan/php-8-stubs/stubs/ext/standard/array_intersect_uassoc.stubmR~hjm=:|?vendor/phpstan/php-8-stubs/stubs/ext/standard/array_values.stubTR~hjTGvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_socket_sendto.stubR~hjg=vendor/phpstan/php-8-stubs/stubs/ext/standard/dns_get_mx.stubR~hj%<vendor/phpstan/php-8-stubs/stubs/ext/standard/filegroup.stub;R~hj;4Avendor/phpstan/php-8-stubs/stubs/ext/standard/array_key_last.stubBR~hjBs79vendor/phpstan/php-8-stubs/stubs/ext/standard/uksort.stubR~hjDĄCvendor/phpstan/php-8-stubs/stubs/ext/standard/time_sleep_until.stub=R~hj=hEBvendor/phpstan/php-8-stubs/stubs/ext/standard/php_user_filter.stubR~hjb@k<vendor/phpstan/php-8-stubs/stubs/ext/standard/ini_alter.stubR~hjg}٤9vendor/phpstan/php-8-stubs/stubs/ext/standard/intval.stub>R~hj>YAvendor/phpstan/php-8-stubs/stubs/ext/standard/substr_compare.stubR~hjИG?vendor/phpstan/php-8-stubs/stubs/ext/standard/array_column.stubvR~hjv%Lvendor/phpstan/php-8-stubs/stubs/ext/standard/output_reset_rewrite_vars.stub6R~hj6Avendor/phpstan/php-8-stubs/stubs/ext/standard/escapeshellarg.stub8R~hj8 ܤ>vendor/phpstan/php-8-stubs/stubs/ext/standard/array_shift.stub6R~hj60S:vendor/phpstan/php-8-stubs/stubs/ext/standard/settype.stub=R~hj==vendor/phpstan/php-8-stubs/stubs/ext/standard/phpcredits.stubR~hj Lvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_context_set_option.stubR~hjK <vendor/phpstan/php-8-stubs/stubs/ext/standard/is_scalar.stub2R~hj22m8vendor/phpstan/php-8-stubs/stubs/ext/standard/fopen.stubR~hjFvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_set_blocking.stubdR~hjdu<vendor/phpstan/php-8-stubs/stubs/ext/standard/array_sum.stub7R~hj7̮@vendor/phpstan/php-8-stubs/stubs/ext/standard/stripcslashes.stub:R~hj:N_X>vendor/phpstan/php-8-stubs/stubs/ext/standard/is_writable.stub8R~hj8b=vendor/phpstan/php-8-stubs/stubs/ext/standard/strtoupper.stub7R~hj79Z+Kvendor/phpstan/php-8-stubs/stubs/ext/standard/header_register_callback.stubYR~hjYq&Gvendor/phpstan/php-8-stubs/stubs/ext/standard/array_intersect_ukey.stubkR~hjk|<vendor/phpstan/php-8-stubs/stubs/ext/standard/fsockopen.stubR~hj/A7vendor/phpstan/php-8-stubs/stubs/ext/standard/fmod.stub:R~hj:"-Cvendor/phpstan/php-8-stubs/stubs/ext/standard/ob_list_handlers.stubER~hjEDT e?vendor/phpstan/php-8-stubs/stubs/ext/standard/htmlentities.stub]R~hj]Ri~:vendor/phpstan/php-8-stubs/stubs/ext/standard/tmpfile.stub<R~hj<?8vendor/phpstan/php-8-stubs/stubs/ext/standard/chgrp.stubER~hjE* ?vendor/phpstan/php-8-stubs/stubs/ext/standard/array_unique.stubPR~hjP|3J9vendor/phpstan/php-8-stubs/stubs/ext/standard/decbin.stub-R~hj-!K:vendor/phpstan/php-8-stubs/stubs/ext/standard/opendir.stubR~hj#`rHvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_context_create.stubqR~hjqR5R?vendor/phpstan/php-8-stubs/stubs/ext/standard/array_reduce.stubaR~hja AEvendor/phpstan/php-8-stubs/stubs/ext/standard/html_entity_decode.stubR~hjR{Evendor/phpstan/php-8-stubs/stubs/ext/standard/ini_parse_quantity.stubPR~hjP3 Cvendor/phpstan/php-8-stubs/stubs/ext/standard/set_include_path.stubIR~hjI7vendor/phpstan/php-8-stubs/stubs/ext/standard/sort.stubR~hj(vY?vendor/phpstan/php-8-stubs/stubs/ext/standard/ob_end_clean.stub)R~hj)"?E<vendor/phpstan/php-8-stubs/stubs/ext/standard/strnatcmp.stubER~hjEhL<vendor/phpstan/php-8-stubs/stubs/ext/standard/fileinode.stub;R~hj;l6"M8vendor/phpstan/php-8-stubs/stubs/ext/standard/floor.stub1R~hj1opZ9vendor/phpstan/php-8-stubs/stubs/ext/standard/getenv.stubvR~hjvq@vendor/phpstan/php-8-stubs/stubs/ext/standard/array_reverse.stubTR~hjT¼)0:vendor/phpstan/php-8-stubs/stubs/ext/standard/fnmatch.stubiR~hjibDvendor/phpstan/php-8-stubs/stubs/ext/standard/socket_get_status.stubxR~hjxդ=vendor/phpstan/php-8-stubs/stubs/ext/standard/getrandmax.stubBR~hjBlaMvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_context_get_default.stub_R~hj_׬ؤ;vendor/phpstan/php-8-stubs/stubs/ext/standard/filetype.stub=R~hj=L?vendor/phpstan/php-8-stubs/stubs/ext/standard/RoundingMode.stubR~hjtBvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_is_local.stubYR~hjYI(Ѥ;vendor/phpstan/php-8-stubs/stubs/ext/standard/getmypid.stub*R~hj*o4<vendor/phpstan/php-8-stubs/stubs/ext/standard/array_all.stubWR~hjW¤8vendor/phpstan/php-8-stubs/stubs/ext/standard/crc32.stub=R~hj=@<vendor/phpstan/php-8-stubs/stubs/ext/standard/serialize.stub4R~hj4פ:vendor/phpstan/php-8-stubs/stubs/ext/standard/strrchr.stubR~hj vAvendor/phpstan/php-8-stubs/stubs/ext/standard/array_find_key.stub]R~hj]x#8vendor/phpstan/php-8-stubs/stubs/ext/standard/sleep.stub-R~hj-3cLHvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_bucket_prepend.stubR~hjqmEvendor/phpstan/php-8-stubs/stubs/ext/standard/socket_set_timeout.stubR~hjUR<vendor/phpstan/php-8-stubs/stubs/ext/standard/Directory.stubR~hjtw]>vendor/phpstan/php-8-stubs/stubs/ext/standard/addcslashes.stubLR~hjLaq=vendor/phpstan/php-8-stubs/stubs/ext/standard/pfsockopen.stubR~hj{[h=vendor/phpstan/php-8-stubs/stubs/ext/standard/array_flip.stubaR~hja%菤Gvendor/phpstan/php-8-stubs/stubs/ext/standard/php_strip_whitespace.stubCR~hjC%`;vendor/phpstan/php-8-stubs/stubs/ext/standard/realpath.stub9R~hj9/'~>vendor/phpstan/php-8-stubs/stubs/ext/standard/gethostname.stub[R~hj[1);vendor/phpstan/php-8-stubs/stubs/ext/standard/var_dump.stubOR~hjO}>vendor/phpstan/php-8-stubs/stubs/ext/standard/is_infinite.stub2R~hj2ko>vendor/phpstan/php-8-stubs/stubs/ext/standard/count_chars.stubzR~hjz7n>vendor/phpstan/php-8-stubs/stubs/ext/standard/str_shuffle.stub8R~hj87j<vendor/phpstan/php-8-stubs/stubs/ext/standard/urldecode.stub6R~hj6qv8vendor/phpstan/php-8-stubs/stubs/ext/standard/round.stubR~hjp|mqCvendor/phpstan/php-8-stubs/stubs/ext/standard/get_current_user.stub6R~hj6RAvendor/phpstan/php-8-stubs/stubs/ext/standard/password_algos.stub,R~hj,פ6vendor/phpstan/php-8-stubs/stubs/ext/standard/max.stub?R~hj?8vendor/phpstan/php-8-stubs/stubs/ext/standard/ltrim.stubXR~hjX;-?vendor/phpstan/php-8-stubs/stubs/ext/standard/headers_list.stubAR~hjAgŤ9vendor/phpstan/php-8-stubs/stubs/ext/standard/unlink.stubiR~hjiȤ:vendor/phpstan/php-8-stubs/stubs/ext/standard/stristr.stubiR~hjiOzHvendor/phpstan/php-8-stubs/stubs/ext/standard/php_ini_scanned_files.stub:R~hj:WeBvendor/phpstan/php-8-stubs/stubs/ext/standard/password_verify.stubJR~hjJJvendor/phpstan/php-8-stubs/stubs/ext/standard/array_uintersect_uassoc.stubnR~hjnFvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_get_wrappers.stubHR~hjH!Fvendor/phpstan/php-8-stubs/stubs/ext/standard/socket_set_blocking.stubR~hj @~9vendor/phpstan/php-8-stubs/stubs/ext/standard/strrev.stub3R~hj3Jvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_register_wrapper.stubR~hjE8vendor/phpstan/php-8-stubs/stubs/ext/standard/usort.stubR~hj>vendor/phpstan/php-8-stubs/stubs/ext/standard/show_source.stubrR~hjrv6@vendor/phpstan/php-8-stubs/stubs/ext/standard/stream_select.stubOR~hjOݤJvendor/phpstan/php-8-stubs/stubs/ext/standard/array_replace_recursive.stubYR~hjY>Y=vendor/phpstan/php-8-stubs/stubs/ext/standard/proc_close.stubNR~hjNמ<vendor/phpstan/php-8-stubs/stubs/ext/standard/filemtime.stub;R~hj;S;vendor/phpstan/php-8-stubs/stubs/ext/standard/wordwrap.stubzR~hjzcEb<vendor/phpstan/php-8-stubs/stubs/ext/standard/iptcembed.stubmR~hjm/*8vendor/phpstan/php-8-stubs/stubs/ext/standard/fsync.stubYR~hjY+ <vendor/phpstan/php-8-stubs/stubs/ext/standard/is_object.stub2R~hj2*jLvendor/phpstan/php-8-stubs/stubs/ext/standard/forward_static_call_array.stubVR~hjVq;Gvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_socket_server.stub-R~hj-gY;vendor/phpstan/php-8-stubs/stubs/ext/standard/linkinfo.stub6R~hj6ݍ@vendor/phpstan/php-8-stubs/stubs/ext/standard/stream_isatty.stubPR~hjPk;vendor/phpstan/php-8-stubs/stubs/ext/standard/md5_file.stubSR~hjS&ۤ8vendor/phpstan/php-8-stubs/stubs/ext/standard/chdir.stub3R~hj3{RQ=vendor/phpstan/php-8-stubs/stubs/ext/standard/array_fill.stubRR~hjRˤGvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_get_meta_data.stub\R~hj\.>(7vendor/phpstan/php-8-stubs/stubs/ext/standard/sha1.stubTR~hjT ¤Cvendor/phpstan/php-8-stubs/stubs/ext/standard/getprotobynumber.stubcR~hjc<vendor/phpstan/php-8-stubs/stubs/ext/standard/metaphone.stubfR~hjfФ:vendor/phpstan/php-8-stubs/stubs/ext/standard/boolval.stub0R~hj0#AGvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_supports_lock.stubWR~hjWx Ĥ6vendor/phpstan/php-8-stubs/stubs/ext/standard/chr.stub0R~hj04nDvendor/phpstan/php-8-stubs/stubs/ext/standard/ignore_user_abort.stubAR~hjAJvendor/phpstan/php-8-stubs/stubs/ext/standard/quoted_printable_decode.stub^R~hj^n;vendor/phpstan/php-8-stubs/stubs/ext/standard/is_float.stub1R~hj1ʛ:vendor/phpstan/php-8-stubs/stubs/ext/standard/fprintf.stubkR~hjkU8vendor/phpstan/php-8-stubs/stubs/ext/standard/fgets.stubeR~hjeπ28vendor/phpstan/php-8-stubs/stubs/ext/standard/ksort.stubR~hjUf=vendor/phpstan/php-8-stubs/stubs/ext/standard/phpversion.stubHR~hjHL:vendor/phpstan/php-8-stubs/stubs/ext/standard/dirname.stubCR~hjC!jФ=vendor/phpstan/php-8-stubs/stubs/ext/standard/shell_exec.stubCR~hjCWCvendor/phpstan/php-8-stubs/stubs/ext/standard/array_diff_assoc.stubLR~hjLBDvendor/phpstan/php-8-stubs/stubs/ext/standard/password_get_info.stubcR~hjc ?vendor/phpstan/php-8-stubs/stubs/ext/standard/headers_sent.stubR~hjHAvendor/phpstan/php-8-stubs/stubs/ext/standard/parse_ini_file.stubR~hj eJvendor/phpstan/php-8-stubs/stubs/ext/standard/htmlspecialchars_decode.stubR~hj+7vendor/phpstan/php-8-stubs/stubs/ext/standard/sinh.stub,R~hj,+.8vendor/phpstan/php-8-stubs/stubs/ext/standard/rtrim.stubXR~hjXt157vendor/phpstan/php-8-stubs/stubs/ext/standard/chop.stubkR~hjk;vendor/phpstan/php-8-stubs/stubs/ext/standard/getmyuid.stub;R~hj;4G @vendor/phpstan/php-8-stubs/stubs/ext/standard/diskfreespace.stub`R~hj`kK;vendor/phpstan/php-8-stubs/stubs/ext/standard/getmygid.stub*R~hj*59vendor/phpstan/php-8-stubs/stubs/ext/standard/uasort.stubR~hjVnHBvendor/phpstan/php-8-stubs/stubs/ext/standard/str_starts_with.stubLR~hjLY7vendor/phpstan/php-8-stubs/stubs/ext/standard/file.stubR~hjK7vendor/phpstan/php-8-stubs/stubs/ext/standard/rand.stubFR~hjF8vendor/phpstan/php-8-stubs/stubs/ext/standard/count.stubRR~hjRG=vendor/phpstan/php-8-stubs/stubs/ext/standard/is_numeric.stub3R~hj3r9vendor/phpstan/php-8-stubs/stubs/ext/standard/is_dir.stub3R~hj3:vendor/phpstan/php-8-stubs/stubs/ext/standard/is_link.stub4R~hj4@vendor/phpstan/php-8-stubs/stubs/ext/standard/base64_decode.stubVR~hjV5lQ7vendor/phpstan/php-8-stubs/stubs/ext/standard/cosh.stub,R~hj,ge9vendor/phpstan/php-8-stubs/stubs/ext/standard/strval.stub1R~hj18vendor/phpstan/php-8-stubs/stubs/ext/standard/atan2.stub5R~hj5zABvendor/phpstan/php-8-stubs/stubs/ext/standard/ob_get_contents.stub4R~hj4 p>R<vendor/phpstan/php-8-stubs/stubs/ext/standard/fileperms.stub;R~hj;FIvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_socket_recvfrom.stubR~hjUq5$Avendor/phpstan/php-8-stubs/stubs/ext/standard/dns_get_record.stubR~hja[88vendor/phpstan/php-8-stubs/stubs/ext/standard/range.stubR~hjj%>9vendor/phpstan/php-8-stubs/stubs/ext/standard/chroot.stubtR~hjtFvendor/phpstan/php-8-stubs/stubs/ext/standard/array_intersect_key.stubOR~hjO 釤;vendor/phpstan/php-8-stubs/stubs/ext/standard/readfile.stubR~hj8vendor/phpstan/php-8-stubs/stubs/ext/standard/atanh.stub-R~hj-OYHvendor/phpstan/php-8-stubs/stubs/ext/standard/array_merge_recursive.stubCR~hjC<Mvendor/phpstan/php-8-stubs/stubs/ext/standard/get_html_translation_table.stubR~hji@vendor/phpstan/php-8-stubs/stubs/ext/standard/ob_get_length.stub/R~hj/ ם>vendor/phpstan/php-8-stubs/stubs/ext/standard/levenshtein.stubR~hjBvendor/phpstan/php-8-stubs/stubs/ext/standard/proc_get_status.stubhR~hjh_l]9vendor/phpstan/php-8-stubs/stubs/ext/standard/rewind.stubIR~hjIBӐ8vendor/phpstan/php-8-stubs/stubs/ext/standard/rmdir.stubiR~hjipO#?vendor/phpstan/php-8-stubs/stubs/ext/standard/str_ireplace.stubR~hjY9?vendor/phpstan/php-8-stubs/stubs/ext/standard/gettimeofday.stub]R~hj]q;?<vendor/phpstan/php-8-stubs/stubs/ext/standard/microtime.stuboR~hjooĕ:vendor/phpstan/php-8-stubs/stubs/ext/standard/long2ip.stubR~hjQ8vendor/phpstan/php-8-stubs/stubs/ext/standard/fputs.stubR~hj' rDvendor/phpstan/php-8-stubs/stubs/ext/standard/array_udiff_assoc.stubhR~hjhPj>vendor/phpstan/php-8-stubs/stubs/ext/standard/is_callable.stubR~hj(6vendor/phpstan/php-8-stubs/stubs/ext/standard/min.stub?R~hj?Ԥ>vendor/phpstan/php-8-stubs/stubs/ext/standard/utf8_encode.stub8R~hj8_??vendor/phpstan/php-8-stubs/stubs/ext/standard/substr_count.stubnR~hjnH?vendor/phpstan/php-8-stubs/stubs/ext/standard/setrawcookie.stubR~hj$؃Svendor/phpstan/php-8-stubs/stubs/ext/standard/sapi_windows_generate_ctrl_event.stubUR~hjU`?vendor/phpstan/php-8-stubs/stubs/ext/standard/base_convert.stubTR~hjTY!t9vendor/phpstan/php-8-stubs/stubs/ext/standard/hrtime.stubaR~hja2 Evendor/phpstan/php-8-stubs/stubs/ext/standard/move_uploaded_file.stubGR~hjGU*Evendor/phpstan/php-8-stubs/stubs/ext/standard/stream_set_timeout.stubR~hjiه;vendor/phpstan/php-8-stubs/stubs/ext/standard/passthru.stubR~hjO^Cvendor/phpstan/php-8-stubs/stubs/ext/standard/http_build_query.stubR~hj:vendor/phpstan/php-8-stubs/stubs/ext/standard/mt_rand.stubIR~hjI:Cvendor/phpstan/php-8-stubs/stubs/ext/standard/array_key_exists.stub]R~hj]^2Gvendor/phpstan/php-8-stubs/stubs/ext/standard/sapi_windows_cp_conv.stubvR~hjvI]7vendor/phpstan/php-8-stubs/stubs/ext/standard/feof.stubGR~hjG=m>vendor/phpstan/php-8-stubs/stubs/ext/standard/get_cfg_var.stubDR~hjDA:vendor/phpstan/php-8-stubs/stubs/ext/standard/stripos.stubZR~hjZBSAѤ9vendor/phpstan/php-8-stubs/stubs/ext/standard/strspn.stubjR~hjjx7vendor/phpstan/php-8-stubs/stubs/ext/standard/atan.stub,R~hj,ͤ=vendor/phpstan/php-8-stubs/stubs/ext/standard/localeconv.stub?R~hj?{<vendor/phpstan/php-8-stubs/stubs/ext/standard/error_log.stubR~hj-8vendor/phpstan/php-8-stubs/stubs/ext/standard/popen.stubWR~hjWo.9vendor/phpstan/php-8-stubs/stubs/ext/standard/krsort.stubR~hjbK5vendor/phpstan/php-8-stubs/stubs/ext/standard/pi.stub R~hj _loͤ<vendor/phpstan/php-8-stubs/stubs/ext/standard/fileatime.stubLR~hjL|?vendor/phpstan/php-8-stubs/stubs/ext/standard/ob_get_flush.stub1R~hj1x7vendor/phpstan/php-8-stubs/stubs/ext/standard/next.stub6R~hj6UPLvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_wrapper_unregister.stubFR~hjFy@vendor/phpstan/php-8-stubs/stubs/ext/standard/ob_get_status.stub[R~hj[ӁW&9vendor/phpstan/php-8-stubs/stubs/ext/standard/strpos.stubYR~hjYO?:vendor/phpstan/php-8-stubs/stubs/ext/standard/lcfirst.stub4R~hj4 ,9vendor/phpstan/php-8-stubs/stubs/ext/standard/strtok.stubPR~hjPGL9vendor/phpstan/php-8-stubs/stubs/ext/standard/usleep.stub4R~hj4Gvendor/phpstan/php-8-stubs/stubs/ext/standard/array_walk_recursive.stubR~hjc2Evendor/phpstan/php-8-stubs/stubs/ext/standard/stream_get_filters.stubGR~hjG4, `Cvendor/phpstan/php-8-stubs/stubs/ext/standard/convert_uudecode.stubCR~hjC6bEvendor/phpstan/php-8-stubs/stubs/ext/standard/request_parse_body.stubR~hj[+Evendor/phpstan/php-8-stubs/stubs/ext/standard/connection_aborted.stub.R~hj.7Avendor/phpstan/php-8-stubs/stubs/ext/standard/call_user_func.stubNR~hjNEvendor/phpstan/php-8-stubs/stubs/ext/standard/array_udiff_uassoc.stubiR~hjiBJӤ9vendor/phpstan/php-8-stubs/stubs/ext/standard/syslog.stubR~hjx;vendor/phpstan/php-8-stubs/stubs/ext/standard/vsprintf.stubDR~hjD?cIvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_socket_shutdown.stubyR~hjy" Dvendor/phpstan/php-8-stubs/stubs/ext/standard/file_get_contents.stubR~hjј7:vendor/phpstan/php-8-stubs/stubs/ext/standard/is_bool.stub0R~hj0=vendor/phpstan/php-8-stubs/stubs/ext/standard/array_push.stubSR~hjS^;?vendor/phpstan/php-8-stubs/stubs/ext/standard/rawurlencode.stub9R~hj99vendor/phpstan/php-8-stubs/stubs/ext/standard/decoct.stub-R~hj-+@vendor/phpstan/php-8-stubs/stubs/ext/standard/base64_encode.stubIR~hjI:vendor/phpstan/php-8-stubs/stubs/ext/standard/fputcsv.stubR~hj^@"9vendor/phpstan/php-8-stubs/stubs/ext/standard/rename.stubqR~hjq<vendor/phpstan/php-8-stubs/stubs/ext/standard/ftruncate.stubWR~hjWӌӣ<vendor/phpstan/php-8-stubs/stubs/ext/standard/inet_pton.stubUR~hjUɔBvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_get_line.stub|R~hj|9vendor/phpstan/php-8-stubs/stubs/ext/standard/intdiv.stub6R~hj6]aФ>vendor/phpstan/php-8-stubs/stubs/ext/standard/array_slice.stubtR~hjt8vendor/phpstan/php-8-stubs/stubs/ext/standard/chown.stubDR~hjDs8vendor/phpstan/php-8-stubs/stubs/ext/standard/reset.stub7R~hj7?_6vendor/phpstan/php-8-stubs/stubs/ext/standard/abs.stub@R~hj@D_fӤ?vendor/phpstan/php-8-stubs/stubs/ext/standard/str_contains.stubIR~hjIi:3ˤ<vendor/phpstan/php-8-stubs/stubs/ext/standard/fdatasync.stub]R~hj]@9vendor/phpstan/php-8-stubs/stubs/ext/standard/octdec.stub<R~hj<9Cvendor/phpstan/php-8-stubs/stubs/ext/standard/highlight_string.stubR~hjkb>vendor/phpstan/php-8-stubs/stubs/ext/standard/array_chunk.stub_R~hj_ZǤ<vendor/phpstan/php-8-stubs/stubs/ext/standard/proc_open.stubR~hj >vendor/phpstan/php-8-stubs/stubs/ext/standard/array_udiff.stubbR~hjbKBvendor/phpstan/php-8-stubs/stubs/ext/standard/array_diff_ukey.stubfR~hjf7 <vendor/phpstan/php-8-stubs/stubs/ext/standard/getrusage.stubnR~hjn<=vendor/phpstan/php-8-stubs/stubs/ext/standard/getlastmod.stub,R~hj,ӤBvendor/phpstan/php-8-stubs/stubs/ext/standard/array_key_first.stubCR~hjCHrʷ:vendor/phpstan/php-8-stubs/stubs/ext/standard/is_null.stub0R~hj0E87vendor/phpstan/php-8-stubs/stubs/ext/standard/join.stubfR~hjfa)Evendor/phpstan/php-8-stubs/stubs/ext/standard/realpath_cache_get.stubGR~hjG֧7vendor/phpstan/php-8-stubs/stubs/ext/standard/prev.stub6R~hj6l:vendor/phpstan/php-8-stubs/stubs/ext/standard/getmxrr.stubR~hj~ߤ6vendor/phpstan/php-8-stubs/stubs/ext/standard/sin.stub+R~hj+֊Ivendor/phpstan/php-8-stubs/stubs/ext/standard/__PHP_Incomplete_Class.stub^R~hj^LG8HAvendor/phpstan/php-8-stubs/stubs/ext/standard/str_word_count.stubR~hjw}Avendor/phpstan/php-8-stubs/stubs/ext/standard/clearstatcache.stubkR~hjk?Evendor/phpstan/php-8-stubs/stubs/ext/standard/http_response_code.stubIR~hjIyg Bvendor/phpstan/php-8-stubs/stubs/ext/standard/debug_zval_dump.stubJR~hjJd5͉?vendor/phpstan/php-8-stubs/stubs/ext/standard/stripslashes.stub9R~hj9mHvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_copy_to_stream.stubR~hj?K8vendor/phpstan/php-8-stubs/stubs/ext/standard/srand.stubR~hjv N=vendor/phpstan/php-8-stubs/stubs/ext/standard/array_walk.stubR~hjZ8vendor/phpstan/php-8-stubs/stubs/ext/standard/asinh.stub-R~hj-ޤ:vendor/phpstan/php-8-stubs/stubs/ext/standard/sprintf.stub^R~hj^SJvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_set_write_buffer.stubdR~hjd<vendor/phpstan/php-8-stubs/stubs/ext/standard/setcookie.stubR~hjN~:vendor/phpstan/php-8-stubs/stubs/ext/standard/natsort.stub}R~hj}*#<vendor/phpstan/php-8-stubs/stubs/ext/standard/quotemeta.stub6R~hj6V 8vendor/phpstan/php-8-stubs/stubs/ext/standard/rsort.stubR~hj1>\EGvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_filter_remove.stubeR~hje8m%Bvendor/phpstan/php-8-stubs/stubs/ext/standard/set_file_buffer.stubR~hjOKAvendor/phpstan/php-8-stubs/stubs/ext/standard/escapeshellcmd.stub<R~hj<E-_=vendor/phpstan/php-8-stubs/stubs/ext/standard/array_keys.stubR~hj b>vendor/phpstan/php-8-stubs/stubs/ext/standard/natcasesort.stubR~hjAi:vendor/phpstan/php-8-stubs/stubs/ext/standard/current.stub8R~hj8Nr7vendor/phpstan/php-8-stubs/stubs/ext/standard/fpow.stubiR~hji v<vendor/phpstan/php-8-stubs/stubs/ext/standard/proc_nice.stubDR~hjDFvendor/phpstan/php-8-stubs/stubs/ext/standard/sapi_windows_cp_set.stubeR~hjeNv[7vendor/phpstan/php-8-stubs/stubs/ext/standard/copy.stuboR~hjoK=>vendor/phpstan/php-8-stubs/stubs/ext/standard/chunk_split.stubfR~hjf-j:vendor/phpstan/php-8-stubs/stubs/ext/standard/symlink.stub@R~hj@/jHvendor/phpstan/php-8-stubs/stubs/ext/standard/array_change_key_case.stubWR~hjWQIvendor/phpstan/php-8-stubs/stubs/ext/standard/register_tick_function.stub\R~hj\n(Gvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_socket_accept.stubR~hj(_@vendor/phpstan/php-8-stubs/stubs/ext/standard/password_hash.stubhR~hjh4YBvendor/phpstan/php-8-stubs/stubs/ext/standard/version_compare.stubR~hjZ5g8vendor/phpstan/php-8-stubs/stubs/ext/standard/crypt.stubNR~hjN7;vendor/phpstan/php-8-stubs/stubs/ext/standard/closedir.stub_R~hj_DyJSvendor/phpstan/php-8-stubs/stubs/ext/standard/http_clear_last_response_headers.stubNR~hjNA#:vendor/phpstan/php-8-stubs/stubs/ext/standard/shuffle.stub}R~hj}ʓc~:vendor/phpstan/php-8-stubs/stubs/ext/standard/strcspn.stubkR~hjk~:vendor/phpstan/php-8-stubs/stubs/ext/standard/hex2bin.stub:R~hj:@Q\1:vendor/phpstan/php-8-stubs/stubs/ext/standard/compact.stubR~hjzؤ7vendor/phpstan/php-8-stubs/stubs/ext/standard/asin.stub,R~hj,+99vendor/phpstan/php-8-stubs/stubs/ext/standard/lchgrp.stubFR~hjFa;9vendor/phpstan/php-8-stubs/stubs/ext/standard/fflush.stubIR~hjId$_`;vendor/phpstan/php-8-stubs/stubs/ext/standard/basename.stubHR~hjH]aפ9vendor/phpstan/php-8-stubs/stubs/ext/standard/fscanf.stubR~hjt[ <vendor/phpstan/php-8-stubs/stubs/ext/standard/array_pop.stub4R~hj4mߤ@vendor/phpstan/php-8-stubs/stubs/ext/standard/mt_getrandmax.stub)R~hj)ag?vendor/phpstan/php-8-stubs/stubs/ext/standard/getimagesize.stubR~hj:vendor/phpstan/php-8-stubs/stubs/ext/standard/deg2rad.stub/R~hj/C~Jvendor/phpstan/php-8-stubs/stubs/ext/standard/sapi_windows_cp_is_utf8.stub4R~hj4VЋ8vendor/phpstan/php-8-stubs/stubs/ext/standard/lstat.stubPR~hjPBvendor/phpstan/php-8-stubs/stubs/ext/standard/array_intersect.stubKR~hjK]6vendor/phpstan/php-8-stubs/stubs/ext/standard/pow.stubGR~hjG\4ϤDvendor/phpstan/php-8-stubs/stubs/ext/standard/array_diff_uassoc.stubhR~hjh:vendor/phpstan/php-8-stubs/stubs/ext/standard/ip2long.stub3R~hj3Evendor/phpstan/php-8-stubs/stubs/ext/standard/array_count_values.stubiR~hjirZe8vendor/phpstan/php-8-stubs/stubs/ext/standard/acosh.stub-R~hj-3>vendor/phpstan/php-8-stubs/stubs/ext/standard/is_readable.stub8R~hj8[Kz@vendor/phpstan/php-8-stubs/stubs/ext/standard/array_is_list.stubGR~hjG86vendor/phpstan/php-8-stubs/stubs/ext/standard/key.stub>R~hj>{ܠ@vendor/phpstan/php-8-stubs/stubs/ext/standard/get_meta_tags.stubxR~hjxRp@vendor/phpstan/php-8-stubs/stubs/ext/standard/strnatcasecmp.stubIR~hjIA_'Hvendor/phpstan/php-8-stubs/stubs/ext/standard/array_intersect_assoc.stubQR~hjQ³L>vendor/phpstan/php-8-stubs/stubs/ext/standard/unserialize.stubJR~hjJɒ<vendor/phpstan/php-8-stubs/stubs/ext/standard/parse_url.stubR~hjs+Bvendor/phpstan/php-8-stubs/stubs/ext/standard/config_get_hash.stubSR~hjSV+Gvendor/phpstan/php-8-stubs/stubs/ext/standard/call_user_func_array.stubQR~hjQ+wBvendor/phpstan/php-8-stubs/stubs/ext/standard/disk_free_space.stubDR~hjD,TAvendor/phpstan/php-8-stubs/stubs/ext/standard/time_nanosleep.stubyR~hjy08vendor/phpstan/php-8-stubs/stubs/ext/standard/fgetc.stubPR~hjP̳khDvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_bucket_new.stubR~hj6놞6vendor/phpstan/php-8-stubs/stubs/ext/standard/exp.stub+R~hj+ۤ<vendor/phpstan/php-8-stubs/stubs/ext/standard/is_finite.stub0R~hj0Ar7vendor/phpstan/php-8-stubs/stubs/ext/standard/sqrt.stub,R~hj,9vendor/phpstan/php-8-stubs/stubs/ext/standard/is_int.stub/R~hj/^:vendor/phpstan/php-8-stubs/stubs/ext/standard/print_r.stubR~hj"N;vendor/phpstan/php-8-stubs/stubs/ext/standard/strripos.stub[R~hj[ҤBvendor/phpstan/php-8-stubs/stubs/ext/standard/array_fill_keys.stubFR~hjFmIvendor/phpstan/php-8-stubs/stubs/ext/standard/getimagesizefromstring.stubR~hjyCvendor/phpstan/php-8-stubs/stubs/ext/standard/error_clear_last.stub-R~hj-sq8:vendor/phpstan/php-8-stubs/stubs/ext/standard/explode.stubR~hjҤ(M@vendor/phpstan/php-8-stubs/stubs/ext/standard/str_decrement.stubKR~hjKzR>vendor/phpstan/php-8-stubs/stubs/ext/standard/is_iterable.stub4R~hj48ŝ:vendor/phpstan/php-8-stubs/stubs/ext/standard/tempnam.stubMR~hjM>{$Cvendor/phpstan/php-8-stubs/stubs/ext/standard/get_include_path.stub5R~hj5ha;vendor/phpstan/php-8-stubs/stubs/ext/standard/strptime.stubR~hj~Mvendor/phpstan/php-8-stubs/stubs/ext/standard/register_shutdown_function.stubR~hjJKJvendor/phpstan/php-8-stubs/stubs/ext/standard/memory_reset_peak_usage.stubER~hjE4?9vendor/phpstan/php-8-stubs/stubs/ext/standard/hexdec.stub:R~hj:AT9vendor/phpstan/php-8-stubs/stubs/ext/standard/dechex.stub-R~hj-•UCvendor/phpstan/php-8-stubs/stubs/ext/standard/convert_uuencode.stubNR~hjN~<vendor/phpstan/php-8-stubs/stubs/ext/standard/setlocale.stubR~hj Ib9vendor/phpstan/php-8-stubs/stubs/ext/standard/strchr.stub}R~hj}F:vendor/phpstan/php-8-stubs/stubs/ext/standard/fgetcsv.stubR~hj('Avendor/phpstan/php-8-stubs/stubs/ext/standard/proc_terminate.stubeR~hjeuOCvendor/phpstan/php-8-stubs/stubs/ext/standard/memory_get_usage.stubDR~hjDEN>vendor/phpstan/php-8-stubs/stubs/ext/standard/nl_langinfo.stubNR~hjNvendor/phpstan/php-8-stubs/stubs/ext/standard/array_merge.stub9R~hj9d>vendor/phpstan/php-8-stubs/stubs/ext/standard/file_exists.stub8R~hj8^,=vendor/phpstan/php-8-stubs/stubs/ext/standard/strtolower.stub7R~hj7<vendor/phpstan/php-8-stubs/stubs/ext/standard/str_split.stubdR~hjdͤ:vendor/phpstan/php-8-stubs/stubs/ext/standard/soundex.stubDR~hjD+/DAvendor/phpstan/php-8-stubs/stubs/ext/standard/substr_replace.stubR~hj[[>vendor/phpstan/php-8-stubs/stubs/ext/standard/utf8_decode.stub8R~hj8{,6vendor/phpstan/php-8-stubs/stubs/ext/standard/ord.stub0R~hj02a/Evendor/phpstan/php-8-stubs/stubs/ext/standard/stream_socket_pair.stubR~hjXy:vendor/phpstan/php-8-stubs/stubs/ext/standard/ucfirst.stub4R~hj4 ܤ;vendor/phpstan/php-8-stubs/stubs/ext/standard/vfprintf.stubiR~hjiAɤ6vendor/phpstan/php-8-stubs/stubs/ext/standard/log.stub>R~hj>G5vendor/phpstan/php-8-stubs/stubs/ext/standard/dl.stub9R~hj9-U~Gvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_filter_append.stubR~hj;<vendor/phpstan/php-8-stubs/stubs/ext/standard/php_uname.stub:R~hj::vendor/phpstan/php-8-stubs/stubs/ext/standard/strrpos.stubZR~hjZG} 7vendor/phpstan/php-8-stubs/stubs/ext/standard/fdiv.stub:R~hj:];vendor/phpstan/php-8-stubs/stubs/ext/standard/readlink.stubvR~hjvHPMvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_context_get_options.stubxR~hjxໄ=vendor/phpstan/php-8-stubs/stubs/ext/standard/random_int.stub8R~hj8#sJvendor/phpstan/php-8-stubs/stubs/ext/standard/image_type_to_mime_type.stubSR~hjS1{Τ<vendor/phpstan/php-8-stubs/stubs/ext/standard/sha1_file.stubTR~hjTdEW":vendor/phpstan/php-8-stubs/stubs/ext/standard/rad2deg.stub/R~hj/dO-@vendor/phpstan/php-8-stubs/stubs/ext/standard/array_combine.stubER~hjEc`Cvendor/phpstan/php-8-stubs/stubs/ext/standard/parse_ini_string.stubR~hj t9vendor/phpstan/php-8-stubs/stubs/ext/standard/getopt.stubR~hj<vendor/phpstan/php-8-stubs/stubs/ext/standard/lcg_value.stub3R~hj3r*@vendor/phpstan/php-8-stubs/stubs/ext/standard/array_unshift.stubHR~hjHb`?vendor/phpstan/php-8-stubs/stubs/ext/standard/StreamBucket.stub R~hj "i7?vendor/phpstan/php-8-stubs/stubs/ext/standard/random_bytes.stubER~hjEO;vendor/phpstan/php-8-stubs/stubs/ext/standard/in_array.stubYR~hjY(1ä@vendor/phpstan/php-8-stubs/stubs/ext/standard/gethostbyname.stub<R~hj<?N<vendor/phpstan/php-8-stubs/stubs/ext/standard/array_any.stubWR~hjWD9vendor/phpstan/php-8-stubs/stubs/ext/standard/sscanf.stubsR~hjs ]@vendor/phpstan/php-8-stubs/stubs/ext/standard/php_sapi_name.stub2R~hj2Y<vendor/phpstan/php-8-stubs/stubs/ext/standard/filectime.stub;R~hj;3:vendor/phpstan/php-8-stubs/stubs/ext/standard/readdir.stubfR~hjf97Gvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_bucket_append.stubR~hjkKvendor/phpstan/php-8-stubs/stubs/ext/standard/unregister_tick_function.stubGR~hjG{5:vendor/phpstan/php-8-stubs/stubs/ext/standard/phpinfo.stubR~hjߒAvendor/phpstan/php-8-stubs/stubs/ext/standard/getprotobyname.stub_R~hj_q7vendor/phpstan/php-8-stubs/stubs/ext/standard/ftok.stubfR~hjf/':vendor/phpstan/php-8-stubs/stubs/ext/standard/bin2hex.stubCR~hjCFۤ>vendor/phpstan/php-8-stubs/stubs/ext/standard/is_resource.stub4R~hj4U8vendor/phpstan/php-8-stubs/stubs/ext/standard/log10.stub-R~hj-nɤDvendor/phpstan/php-8-stubs/stubs/ext/standard/ob_implicit_flush.stubAR~hjAQvendor/phpstan/php-8-stubs/stubs/ext/standard/http_get_last_response_headers.stubNR~hjN=Ĥ@vendor/phpstan/php-8-stubs/stubs/ext/standard/gethostbyaddr.stubCR~hjC9vendor/phpstan/php-8-stubs/stubs/ext/standard/substr.stubUR~hjUE#Ovendor/phpstan/php-8-stubs/stubs/ext/standard/stream_bucket_make_writeable.stub'R~hj'PΤCvendor/phpstan/php-8-stubs/stubs/ext/standard/htmlspecialchars.stubR~hjW֤:vendor/phpstan/php-8-stubs/stubs/ext/standard/gettype.stubFR~hjF_8vendor/phpstan/php-8-stubs/stubs/ext/standard/expm1.stub-R~hj-Bf:vendor/phpstan/php-8-stubs/stubs/ext/standard/str_pad.stubzR~hjze!>vendor/phpstan/php-8-stubs/stubs/ext/standard/get_browser.stubR~hj/.8vendor/phpstan/php-8-stubs/stubs/ext/standard/umask.stub2R~hj2&M<vendor/phpstan/php-8-stubs/stubs/ext/standard/rewinddir.stub`R~hj`=8vendor/phpstan/php-8-stubs/stubs/ext/standard/fstat.stubbR~hjbh7:vendor/phpstan/php-8-stubs/stubs/ext/standard/is_long.stubER~hjEH;vendor/phpstan/php-8-stubs/stubs/ext/standard/pathinfo.stubkR~hjk6[Ĥ<vendor/phpstan/php-8-stubs/stubs/ext/standard/fileowner.stub;R~hj;OhDvendor/phpstan/php-8-stubs/stubs/ext/standard/connection_status.stub-R~hj-n @vendor/phpstan/php-8-stubs/stubs/ext/standard/number_format.stubR~hj49vendor/phpstan/php-8-stubs/stubs/ext/standard/pclose.stubHR~hjH=t=vendor/phpstan/php-8-stubs/stubs/ext/standard/is_integer.stubHR~hjH =vendor/phpstan/php-8-stubs/stubs/ext/standard/array_diff.stubFR~hjFC@vendor/phpstan/php-8-stubs/stubs/ext/standard/array_replace.stubOR~hjO|7c:vendor/phpstan/php-8-stubs/stubs/ext/standard/ini_set.stubR~hjP<vendor/phpstan/php-8-stubs/stubs/ext/standard/array_map.stubZR~hjZKcܤ:vendor/phpstan/php-8-stubs/stubs/ext/standard/ucwords.stubXR~hjX|ΤIvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_socket_get_name.stuboR~hjo QQJvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_wrapper_register.stubR~hjK$8vendor/phpstan/php-8-stubs/stubs/ext/standard/fseek.stublR~hjl7vendor/phpstan/php-8-stubs/stubs/ext/standard/tanh.stub,R~hj,ש7vendor/phpstan/php-8-stubs/stubs/ext/standard/link.stub=R~hj= Jvendor/phpstan/php-8-stubs/stubs/ext/standard/image_type_to_extension.stubeR~hjecNvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_resolve_include_path.stubPR~hjP'F^Ivendor/phpstan/php-8-stubs/stubs/ext/standard/stream_filter_register.stubUR~hjU-n=vendor/phpstan/php-8-stubs/stubs/ext/standard/var_export.stubLR~hjLk\}Evendor/phpstan/php-8-stubs/stubs/ext/standard/net_get_interfaces.stubR~hjt1Mvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_context_set_default.stubWR~hjWD8vendor/phpstan/php-8-stubs/stubs/ext/standard/chmod.stubKR~hjK8vendor/phpstan/php-8-stubs/stubs/ext/standard/flush.stub"R~hj"E9vendor/phpstan/php-8-stubs/stubs/ext/standard/fclose.stubIR~hjIp|9vendor/phpstan/php-8-stubs/stubs/ext/standard/is_nan.stub-R~hj-#"Ivendor/phpstan/php-8-stubs/stubs/ext/standard/stream_wrapper_restore.stubCR~hjCAe:vendor/phpstan/php-8-stubs/stubs/ext/standard/vprintf.stub@R~hj@^ACvendor/phpstan/php-8-stubs/stubs/ext/standard/is_uploaded_file.stub=R~hj=Էr2Mvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_context_set_options.stub R~hj 'hĤ?vendor/phpstan/php-8-stubs/stubs/ext/standard/rawurldecode.stub9R~hj96<vendor/phpstan/php-8-stubs/stubs/ext/standard/is_string.stub2R~hj2x?vendor/phpstan/php-8-stubs/stubs/ext/standard/array_search.stubiR~hjiaiPvendor/phpstan/php-8-stubs/stubs/ext/standard/sapi_windows_set_ctrl_handler.stub^R~hj^|Lvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_context_set_params.stubR~hj9<Fvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_get_contents.stubR~hj0$7vendor/phpstan/php-8-stubs/stubs/ext/standard/exec.stubR~hj67vendor/phpstan/php-8-stubs/stubs/ext/standard/ceil.stub0R~hj0R>9vendor/phpstan/php-8-stubs/stubs/ext/standard/header.stubpR~hjp7^=vendor/phpstan/php-8-stubs/stubs/ext/standard/getmyinode.stub,R~hj,$h8vendor/phpstan/php-8-stubs/stubs/ext/standard/strtr.stubZR~hjZ<Jvendor/phpstan/php-8-stubs/stubs/ext/standard/quoted_printable_encode.stubDR~hjD0,>vendor/phpstan/php-8-stubs/stubs/ext/standard/ini_restore.stub6R~hj6ik@vendor/phpstan/php-8-stubs/stubs/ext/standard/str_ends_with.stubJR~hjJJO8vendor/phpstan/php-8-stubs/stubs/ext/standard/nl2br.stubJR~hjJ;WtB<vendor/phpstan/php-8-stubs/stubs/ext/standard/is_double.stubIR~hjIFvendor/phpstan/php-8-stubs/stubs/ext/standard/sapi_windows_cp_get.stub@R~hj@9Avendor/phpstan/php-8-stubs/stubs/ext/standard/error_get_last.stubDR~hjDU1̤?vendor/phpstan/php-8-stubs/stubs/ext/standard/ob_get_level.stub(R~hj(y,Avendor/phpstan/php-8-stubs/stubs/ext/standard/sys_getloadavg.stubgR~hjg{dv?vendor/phpstan/php-8-stubs/stubs/ext/standard/ob_get_clean.stub1R~hj1zդ9vendor/phpstan/php-8-stubs/stubs/ext/standard/fwrite.stubqR~hjqAvendor/phpstan/php-8-stubs/stubs/ext/standard/assert_options.stubOR~hjO}dIvendor/phpstan/php-8-stubs/stubs/ext/standard/output_add_rewrite_var.stubNR~hjN]4:vendor/phpstan/php-8-stubs/stubs/ext/standard/strcoll.stubJR~hjJ09vendor/phpstan/php-8-stubs/stubs/ext/standard/unpack.stubR~hjS}T٤<vendor/phpstan/php-8-stubs/stubs/ext/standard/iptcparse.stubVR~hjVה9vendor/phpstan/php-8-stubs/stubs/ext/standard/arsort.stubR~hjD=vendor/phpstan/php-8-stubs/stubs/ext/standard/str_getcsv.stubR~hj:7 Cvendor/phpstan/php-8-stubs/stubs/ext/standard/dns_check_record.stubR~hj@vendor/phpstan/php-8-stubs/stubs/ext/standard/is_executable.stub:R~hj:Hp9vendor/phpstan/php-8-stubs/stubs/ext/standard/getcwd.stub2R~hj288Ǥ;vendor/phpstan/php-8-stubs/stubs/ext/standard/filesize.stub:R~hj:Ivendor/phpstan/php-8-stubs/stubs/ext/standard/stream_set_read_buffer.stubcR~hjcm@vendor/phpstan/php-8-stubs/stubs/ext/standard/header_remove.stub>R~hj>}Hvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_filter_prepend.stubR~hj)8vendor/phpstan/php-8-stubs/stubs/ext/standard/hypot.stub5R~hj5(47vendor/phpstan/php-8-stubs/stubs/ext/standard/acos.stub,R~hj,t׽9vendor/phpstan/php-8-stubs/stubs/ext/standard/assert.stubxR~hjx͢Mo<vendor/phpstan/php-8-stubs/stubs/ext/standard/doubleval.stubJR~hjJg(6vendor/phpstan/php-8-stubs/stubs/ext/standard/md5.stubRR~hjR)<vendor/phpstan/php-8-stubs/stubs/ext/standard/str_rot13.stub6R~hj6谛;Avendor/phpstan/php-8-stubs/stubs/ext/standard/set_time_limit.stubkR~hjk,mz8vendor/phpstan/php-8-stubs/stubs/ext/standard/asort.stubR~hjU!Fvendor/phpstan/php-8-stubs/stubs/ext/standard/forward_static_call.stubSR~hjS;vendor/phpstan/php-8-stubs/stubs/ext/standard/floatval.stub2R~hj229vendor/phpstan/php-8-stubs/stubs/ext/standard/lchown.stubUR~hjUY6vendor/phpstan/php-8-stubs/stubs/ext/standard/tan.stub+R~hj+*>BZ@vendor/phpstan/php-8-stubs/stubs/ext/standard/getservbyname.stubgR~hjg@vendor/phpstan/php-8-stubs/stubs/ext/standard/str_increment.stubKR~hjKtMvendor/phpstan/php-8-stubs/stubs/ext/standard/sapi_windows_vt100_support.stubR~hj?@vendor/phpstan/php-8-stubs/stubs/ext/standard/array_product.stub;R~hj;q-?vendor/phpstan/php-8-stubs/stubs/ext/standard/is_countable.stub5R~hj5s=vendor/phpstan/php-8-stubs/stubs/ext/standard/checkdnsrr.stubkR~hjk:vendor/phpstan/php-8-stubs/stubs/ext/standard/extract.stub|R~hj|f;vendor/phpstan/php-8-stubs/stubs/ext/standard/mt_srand.stubR~hj'=vendor/phpstan/php-8-stubs/stubs/ext/standard/strip_tags.stub_R~hj_fAvendor/phpstan/php-8-stubs/stubs/ext/standard/gethostbynamel.stubYR~hjY{Ivendor/phpstan/php-8-stubs/stubs/ext/standard/array_uintersect_assoc.stubmR~hjmM)wAvendor/phpstan/php-8-stubs/stubs/ext/standard/AssertionError.stub@R~hj@6¤Fvendor/phpstan/php-8-stubs/stubs/ext/standard/realpath_cache_size.stub/R~hj/zl?vendor/phpstan/php-8-stubs/stubs/ext/standard/similar_text.stubwR~hjw<9vendor/phpstan/php-8-stubs/stubs/ext/standard/strstr.stubhR~hjh<:vendor/phpstan/php-8-stubs/stubs/ext/standard/openlog.stubR~hj&r`Cvendor/phpstan/php-8-stubs/stubs/ext/standard/array_uintersect.stubgR~hjgVś;vendor/phpstan/php-8-stubs/stubs/ext/standard/ob_flush.stub%R~hj%$E8vendor/phpstan/php-8-stubs/stubs/ext/standard/ftell.stubMR~hjMT46vendor/phpstan/php-8-stubs/stubs/ext/standard/end.stub5R~hj5e?vendor/phpstan/php-8-stubs/stubs/ext/standard/is_writeable.stubSR~hjS>vendor/phpstan/php-8-stubs/stubs/ext/standard/ini_get_all.stubuR~hjṳ7vendor/phpstan/php-8-stubs/stubs/ext/standard/mail.stubR~hjfc?vendor/phpstan/php-8-stubs/stubs/ext/standard/array_filter.stubaR~hja:vendor/phpstan/php-8-stubs/stubs/ext/standard/is_file.stub4R~hj4J8vendor/phpstan/php-8-stubs/stubs/ext/standard/flock.stubR~hj)-&6vendor/phpstan/php-8-stubs/stubs/ext/standard/cos.stub+R~hj+YF*Avendor/phpstan/php-8-stubs/stubs/ext/standard/get_debug_type.stub9R~hj91&D7vendor/phpstan/php-8-stubs/stubs/ext/standard/glob.stuboR~hjoѤFvendor/phpstan/php-8-stubs/stubs/ext/standard/php_ini_loaded_file.stub8R~hj80 Avendor/phpstan/php-8-stubs/stubs/ext/standard/array_diff_key.stubJR~hjJ=+Nvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_socket_enable_crypto.stubR~hj|j"Gvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_socket_client.stub1R~hj1sx6vendor/phpstan/php-8-stubs/stubs/ext/standard/dir.stubsR~hjs??vendor/phpstan/php-8-stubs/stubs/ext/standard/ob_end_flush.stub)R~hj)Ҥ;vendor/phpstan/php-8-stubs/stubs/ext/standard/closelog.stubeR~hjeI;vendor/phpstan/php-8-stubs/stubs/ext/standard/is_array.stub1R~hj1曤9vendor/phpstan/php-8-stubs/stubs/ext/standard/uniqid.stub|R~hj|=7Cvendor/phpstan/php-8-stubs/stubs/ext/standard/sys_get_temp_dir.stub6R~hj6QqDvendor/phpstan/php-8-stubs/stubs/ext/standard/file_put_contents.stubR~hjAvendor/phpstan/php-8-stubs/stubs/ext/standard/highlight_file.stubXR~hjXH:7vendor/phpstan/php-8-stubs/stubs/ext/standard/trim.stubWR~hjW+8vendor/phpstan/php-8-stubs/stubs/ext/standard/log1p.stub-R~hj-`9:vendor/phpstan/php-8-stubs/stubs/ext/standard/ini_get.stub:R~hj:=vendor/phpstan/php-8-stubs/stubs/ext/standard/array_find.stubYR~hjYn<9vendor/phpstan/php-8-stubs/stubs/ext/standard/hebrev.stubPR~hjPJ=I?vendor/phpstan/php-8-stubs/stubs/ext/standard/array_splice.stubrR~hjrÝ5Hvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_get_transports.stubJR~hjJǤ7vendor/phpstan/php-8-stubs/stubs/ext/standard/pack.stubWR~hjW1ݤCvendor/phpstan/php-8-stubs/stubs/ext/standard/disk_total_space.stubER~hjEBx̤<vendor/phpstan/php-8-stubs/stubs/ext/standard/parse_str.stubZR~hjZȇPIHvendor/phpstan/php-8-stubs/stubs/ext/standard/password_needs_rehash.stubjR~hjj7O9vendor/phpstan/php-8-stubs/stubs/ext/standard/system.stuboR~hjo7қ=vendor/phpstan/php-8-stubs/stubs/ext/standard/key_exists.stubvR~hjv@);;vendor/phpstan/php-8-stubs/stubs/ext/standard/constant.stubJR~hjJk,=vendor/phpstan/php-8-stubs/stubs/ext/standard/array_rand.stubMR~hjMBQ8vendor/phpstan/php-8-stubs/stubs/ext/standard/touch.stubiR~hjiA8vendor/phpstan/php-8-stubs/stubs/ext/standard/fread.stub]R~hj]kO:vendor/phpstan/php-8-stubs/stubs/ext/standard/scandir.stubR~hj:=vendor/phpstan/php-8-stubs/stubs/ext/standard/str_repeat.stubCR~hjC+:vendor/phpstan/php-8-stubs/stubs/ext/standard/strpbrk.stubNR~hjNKݤ6vendor/phpstan/php-8-stubs/stubs/ext/standard/pos.stubJR~hjJ@vendor/phpstan/php-8-stubs/stubs/ext/standard/getservbyport.stubkR~hjkFW9vendor/phpstan/php-8-stubs/stubs/ext/standard/bindec.stub=R~hj=kXa<vendor/phpstan/php-8-stubs/stubs/ext/standard/urlencode.stub6R~hj6zeHvendor/phpstan/php-8-stubs/stubs/ext/standard/memory_get_peak_usage.stubIR~hjI)*<vendor/phpstan/php-8-stubs/stubs/ext/standard/fpassthru.stubKR~hjK9vendor/phpstan/php-8-stubs/stubs/ext/standard/sizeof.stubgR~hjgDHvendor/phpstan/php-8-stubs/stubs/ext/standard/stream_set_chunk_size.stubiR~hji@)>vendor/phpstan/php-8-stubs/stubs/ext/tokenizer/token_name.stub0R~hj0$E<vendor/phpstan/php-8-stubs/stubs/ext/tokenizer/PhpToken.stubR~hj+nAvendor/phpstan/php-8-stubs/stubs/ext/tokenizer/token_get_all.stubiR~hji8L+;vendor/phpstan/php-8-stubs/stubs/ext/xsl/XSLTProcessor.stubR~hj_Y:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_lo_read.stubR~hjdO :vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_untrace.stub/R~hj/>vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_socket_poll.stubR~hj@{;vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_lo_write.stubR~hj u?vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_connect_poll.stubR~hj34>vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_fieldisnull.stubR~hjy =vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_freeresult.stubR~hjע<vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_loreadall.stubR~hje4@vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_field_is_null.stubR~hj6>vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_last_notice.stubR~hjWnXBvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_connection_busy.stubR~hjQEvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_result_memory_size.stubyR~hjyڤAvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_unescape_bytea.stub>R~hj>} T=vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_field_type.stubR~hjD1Cvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_connection_reset.stubR~hjMW<vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_fieldname.stubR~hjt;vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_fieldnum.stubR~hjogǤ=vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_get_result.stubR~hjvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_fieldprtlen.stubR~hj ʤFvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_set_client_encoding.stub)R~hj)H);vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_put_line.stubR~hjƤ?vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_cancel_query.stubR~hj)2T>vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_result_seek.stubR~hjƼI;vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_end_copy.stubR~hjng:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_version.stub R~hj  !:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_connect.stubR~hjEvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_result_error_field.stub R~hj ~Z>vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_lo_read_all.stubR~hjpH@?vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_send_execute.stubR~hjRDvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_send_query_params.stub R~hj 7/:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_copy_to.stubR~hj@>vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_lo_truncate.stubR~hj@I=vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_get_notify.stub:R~hj:%9vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_delete.stub[R~hj[H_%:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_loclose.stubR~hję;vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_lounlink.stubwR~hjw ?vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_query_params.stubR~hjF?vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_errormessage.stub0R~hj0zHvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_set_chunked_rows_size.stubR~hjj/:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_get_pid.stubR~hjgr ?vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_send_prepare.stubR~hj\*;vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_last_oid.stubR~hjSb6vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_jit.stubR~hjf9vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_socket.stubR~hjГOvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_set_error_context_visibility.stubR~hjz뇤:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_lowrite.stub>R~hj>ITe<vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_fieldsize.stubR~hj8bx@vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_consume_input.stubR~hjEe<vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_lo_create.stubhR~hjh8.@vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_affected_rows.stubR~hjh+9vendor/phpstan/php-8-stubs/stubs/ext/pgsql/PgSql/Lob.stubqR~hjq<vendor/phpstan/php-8-stubs/stubs/ext/pgsql/PgSql/Result.stubtR~hjtK}@vendor/phpstan/php-8-stubs/stubs/ext/pgsql/PgSql/Connection.stubxR~hjxZ@ 18vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_query.stubCR~hjC>[@vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_put_copy_data.stubgR~hjgg;vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_num_rows.stubR~hj}h78vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_close.stub)R~hj)jI8vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_trace.stubR~hj%;vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_loimport.stubR~hj` <vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_numfields.stubR~hjX:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_numrows.stubR~hjx?vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_fetch_object.stubiR~hjip,ؤ7vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_host.stubR~hjݤpm=vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_last_error.stubR~hjADAvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_field_type_oid.stubR~hjmRk<vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_lo_export.stubR~hj>vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_field_table.stub R~hj FAvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_clientencoding.stub>R~hj>b<vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_meta_data.stub[R~hj[>vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_fetch_array.stubYR~hjYmyƤ?vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_result_error.stubR~hja&Bvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_client_encoding.stubR~hj9 Dvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_connection_status.stubR~hjy;>vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_fetch_assoc.stub)R~hj)Dl灤9vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_update.stubyR~hjy=vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_getlastoid.stubR~hj{ ?vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_put_copy_end.stubpR~hjpܳפ@vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_escape_string.stub2R~hj2I8vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_flush.stubR~hj'[7vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_port.stubR~hjƤ;vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_loexport.stubR~hjvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_free_result.stubR~hjD<vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_fieldtype.stubR~hjvEvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_transaction_status.stubR~hj3 ;vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_locreate.stubR~hj:"=vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_field_name.stubR~hja<vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_fetch_row.stubSR~hjSVn?vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_field_prtlen.stubR~hj'4:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_lo_seek.stubR~hjW:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_convert.stubeR~hje%˯Cvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_parameter_status.stub@R~hj@ϧݤ9vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_loopen.stubR~hjo<@vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_result_status.stub R~hj 4J=vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_num_fields.stubR~hj <vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_field_num.stubR~hj8,7vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_ping.stubR~hjG<vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_copy_from.stubdR~hjddSf:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_lo_tell.stubR~hjN;vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_pconnect.stubR~hjBĤDvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_setclientencoding.stubR~hj|:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_prepare.stubwR~hjwt7vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_exec.stubXR~hjXRDvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_escape_identifier.stubFR~hjF;l^Avendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_escape_literal.stub@R~hj@yȤ<vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_fetch_all.stubR~hj14?vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_escape_bytea.stub0R~hj0WmI:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_options.stubR~hjwfS<vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_cmdtuples.stubR~hj; 9vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_insert.stubxR~hjx1(9vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_select.stubR~hj]KJ6vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_tty.stubR~hjM ݤ:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_lo_open.stubR~hjHT:vendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_execute.stubR~hj^wDvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_fetch_all_columns.stubR~hjEBvendor/phpstan/php-8-stubs/stubs/ext/pgsql/pg_change_password.stubR~hj-9[<vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_kill.stubGR~hjG/BI<vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_poll.stubR~hjeEvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_affected_rows.stubER~hjECvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_thread_safe.stub/R~hj/GĤDvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_prepare.stubVR~hjV`Cvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_change_user.stubtR~hjtvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_driver.stubGR~hjGAiDvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_more_results.stub>R~hj>yCvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_field_count.stub<R~hj<FGV?vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_connect.stubR~hjpFvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_get_proto_info.stub?R~hj?0!<vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_ping.stub6R~hj6DFvAvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_thread_id.stub:R~hj:YXHvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_free_result.stubKR~hjK,Cvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_free_result.stubER~hjE@@vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_rollback.stub`R~hj`Evendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_num_rows.stubUR~hjUIDvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_fetch_object.stubR~hj'U=vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_errno.stub6R~hj6깤Jvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_real_escape_string.stubVR~hjV<1Evendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_warning_count.stub>R~hj>Y!%<vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_info.stub9R~hj9nmCvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_multi_query.stubLR~hjLRIvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_more_results.stublR~hjl#>vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_result.stub% R~hj% Xo?vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_set_opt.stubR~hj=7vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli.stub2R~hj2aqDvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_fetch_column.stubR~hj^EBvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_error.stubGR~hjG}*Jvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_get_client_version.stub5R~hj5DCEvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_get_host_info.stubAR~hjA`Evendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_fetch_lengths.stubeR~hje{ܧIvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_get_warnings.stubdR~hjd\'<vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt.stub8 R~hj8 rdAvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_savepoint.stubIR~hjIBvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_autocommit.stubJR~hjJ>6Dvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_get_warnings.stubOR~hjO|Bvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_errno.stubDR~hjD2v6Gvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_error_list.stubbR~hjbIgDvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_execute.stubR~hj&2ԤLvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_get_connection_stats.stub~R~hj~vCvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_set_charset.stubNR~hjN='6?vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_execute.stubR~hj=cEvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_connect_error.stub4R~hj4xHvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_get_client_stats.stubLR~hjL Evendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_attr_get.stubWR~hjW}>Gvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_get_result.stubzR~hjzZ}Avendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_select_db.stubMR~hjM[Ivendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_release_savepoint.stubXR~hjX֮Evendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_escape_string.stubyR~hjy0Bvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_field_seek.stubR~hjlJvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_character_set_name.stubFR~hjF6ě>vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_report.stubR~hjpͦIvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_begin_transaction.stubiR~hjiwФCvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_next_result.stub=R~hj=OlCvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_fetch_assoc.stubhR~hjh[kBvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_fetch.stubFR~hjFz?vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_ssl_set.stubYR~hjYOYBvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_num_fields.stubCR~hjCs>Bvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_close.stubR~hjxFvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_data_seek.stubVR~hjVVqTBvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_use_result.stubLR~hjL˞ Evendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_sql_exception.stubR~hj.@vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_sqlstate.stub<R~hj<A4Avendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_data_seek.stubPR~hjP}KBvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_error_list.stubTR~hjT6GQEvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_attr_set.stubdR~hjd[Bvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_real_query.stubKR~hjKl=vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_error.stub9R~hj9H`Hvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_reap_async_query.stubqR~hjqK Jvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_affected_rows.stubSR~hjSM=vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_close.stubR~hjޤHvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_bind_result.stub\R~hj\f[Avendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_fetch_row.stubfR~hjfDg?vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_prepare.stub]R~hj]ڤEvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_connect_errno.stub0R~hj0S>=vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_query.stub}R~hj}vBvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_reset.stubER~hjEoϤCvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_get_charset.stubGR~hjGwޤEvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_sqlstate.stubJR~hjJ}KBvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_field_tell.stubCR~hjC`Dvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_real_connect.stubR~hjo<vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_init.stub1R~hj1xfέGvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_dump_debug_info.stubAR~hjA+UGJvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_fetch_field_direct.stub`R~hj`g`?vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_warning.stubR~hj@`<Lvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_result_metadata.stub_R~hj_퀞٤Jvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_get_server_version.stubCR~hjC"Gvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_get_server_info.stubCR~hjC6Avendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_fetch_all.stubR~hjJD{EKvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_send_long_data.stublR~hjlr?vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_refresh.stubER~hjE٤Hvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_field_count.stubJR~hjJK?vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_options.stubnR~hjn>vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_commit.stub^R~hj^JAvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_insert_id.stubAR~hjAƙs<vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stat.stub>R~hj>ۑDvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_store_result.stub]R~hj]qHvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_next_result.stubKR~hjK'4Cvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_fetch_array.stubR~hj؇Avendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_init.stubIR~hjI-1*Ivendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_store_result.stubLR~hjL繽iGvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_bind_param.stubjR~hjjuX̬Evendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_execute_query.stubR~hj(iۤ=vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_debug.stubR~hj+Hvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_stmt_param_count.stubJR~hjJ܌F@vendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_num_rows.stubHR~hjHPDvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_fetch_fields.stub^R~hj^Gvendor/phpstan/php-8-stubs/stubs/ext/mysqli/mysqli_get_client_info.stubKR~hjK2ܤ?vendor/phpstan/php-8-stubs/stubs/ext/sysvmsg/msg_get_queue.stub^R~hj^+u.=vendor/phpstan/php-8-stubs/stubs/ext/sysvmsg/msg_receive.stub"R~hj"s-Bvendor/phpstan/php-8-stubs/stubs/ext/sysvmsg/SysvMessageQueue.stubJR~hjJ[6M?vendor/phpstan/php-8-stubs/stubs/ext/sysvmsg/msg_set_queue.stubOR~hjOޕ>@vendor/phpstan/php-8-stubs/stubs/ext/sysvmsg/msg_stat_queue.stubJR~hjJ~Bvendor/phpstan/php-8-stubs/stubs/ext/sysvmsg/msg_queue_exists.stub5R~hj5zlBvendor/phpstan/php-8-stubs/stubs/ext/sysvmsg/msg_remove_queue.stubER~hjE:vendor/phpstan/php-8-stubs/stubs/ext/sysvmsg/msg_send.stubR~hj,Svendor/phpstan/php-8-stubs/stubs/ext/readline/readline_callback_handler_remove.stub=R~hj=yOvendor/phpstan/php-8-stubs/stubs/ext/readline/readline_completion_function.stubKR~hjKqRIvendor/phpstan/php-8-stubs/stubs/ext/readline/readline_clear_history.stub3R~hj3$Gvendor/phpstan/php-8-stubs/stubs/ext/readline/readline_on_new_line.stubIR~hjItȸ;vendor/phpstan/php-8-stubs/stubs/ext/readline/readline.stubeR~hje%ؤ@vendor/phpstan/php-8-stubs/stubs/ext/readline/readline_info.stubR~hjGTvendor/phpstan/php-8-stubs/stubs/ext/readline/readline_callback_handler_install.stubR~hj7#Nvendor/phpstan/php-8-stubs/stubs/ext/readline/readline_callback_read_char.stub8R~hj8~qeHvendor/phpstan/php-8-stubs/stubs/ext/readline/readline_read_history.stubQR~hjQ$7ФGvendor/phpstan/php-8-stubs/stubs/ext/readline/readline_add_history.stub?R~hj?fՁIvendor/phpstan/php-8-stubs/stubs/ext/readline/readline_write_history.stubKR~hjK@bRHvendor/phpstan/php-8-stubs/stubs/ext/readline/readline_list_history.stubcR~hjc%Evendor/phpstan/php-8-stubs/stubs/ext/readline/readline_redisplay.stub/R~hj/''8vendor/phpstan/php-8-stubs/stubs/ext/bz2/bzcompress.stubdR~hjd?Qmu5vendor/phpstan/php-8-stubs/stubs/ext/bz2/bzwrite.stubR~hj1]5vendor/phpstan/php-8-stubs/stubs/ext/bz2/bzerror.stubR~hj5vendor/phpstan/php-8-stubs/stubs/ext/bz2/bzflush.stubfR~hjf6vendor/phpstan/php-8-stubs/stubs/ext/bz2/bzerrstr.stubR~hjWǤ:vendor/phpstan/php-8-stubs/stubs/ext/bz2/bzdecompress.stub`R~hj`V4vendor/phpstan/php-8-stubs/stubs/ext/bz2/bzread.stub]R~hj] ѤC4vendor/phpstan/php-8-stubs/stubs/ext/bz2/bzopen.stubR~hjDӤ5vendor/phpstan/php-8-stubs/stubs/ext/bz2/bzclose.stubfR~hjf\m5vendor/phpstan/php-8-stubs/stubs/ext/bz2/bzerrno.stubR~hj-+;vendor/phpstan/php-8-stubs/stubs/ext/ctype/ctype_alnum.stubUR~hjU=4c7;vendor/phpstan/php-8-stubs/stubs/ext/ctype/ctype_space.stub3R~hj36 <vendor/phpstan/php-8-stubs/stubs/ext/ctype/ctype_xdigit.stub4R~hj4u;vendor/phpstan/php-8-stubs/stubs/ext/ctype/ctype_alpha.stub3R~hj3;vendor/phpstan/php-8-stubs/stubs/ext/ctype/ctype_lower.stub3R~hj3̤;vendor/phpstan/php-8-stubs/stubs/ext/ctype/ctype_cntrl.stub3R~hj3Ҥ;vendor/phpstan/php-8-stubs/stubs/ext/ctype/ctype_punct.stub3R~hj3!^;vendor/phpstan/php-8-stubs/stubs/ext/ctype/ctype_print.stub3R~hj3Ë&;vendor/phpstan/php-8-stubs/stubs/ext/ctype/ctype_digit.stub3R~hj3簤;vendor/phpstan/php-8-stubs/stubs/ext/ctype/ctype_upper.stub3R~hj3mM;vendor/phpstan/php-8-stubs/stubs/ext/ctype/ctype_graph.stub3R~hj3_r<vendor/phpstan/php-8-stubs/stubs/ext/zip/zip_entry_read.stubR~hj/Ivendor/phpstan/php-8-stubs/stubs/ext/zip/zip_entry_compressionmethod.stubR~hj|䆤<vendor/phpstan/php-8-stubs/stubs/ext/zip/zip_entry_name.stubrR~hjrESFvendor/phpstan/php-8-stubs/stubs/ext/zip/zip_entry_compressedsize.stubyR~hjyN7vendor/phpstan/php-8-stubs/stubs/ext/zip/zip_close.stubYR~hjYb$6vendor/phpstan/php-8-stubs/stubs/ext/zip/zip_open.stubR~hjC>6vendor/phpstan/php-8-stubs/stubs/ext/zip/zip_read.stublR~hjlJ@vendor/phpstan/php-8-stubs/stubs/ext/zip/zip_entry_filesize.stubsR~hjs yr8vendor/phpstan/php-8-stubs/stubs/ext/zip/ZipArchive.stubR~hj<vendor/phpstan/php-8-stubs/stubs/ext/zip/zip_entry_open.stubR~hjSy=vendor/phpstan/php-8-stubs/stubs/ext/zip/zip_entry_close.stubkR~hjkj5=vendor/phpstan/php-8-stubs/stubs/ext/pdo_pgsql/Pdo/Pgsql.stub[R~hj[}3$Avendor/phpstan/php-8-stubs/stubs/ext/pdo_pgsql/PDO_PGSql_Ext.stubgR~hjg4vendor/phpstan/php-8-stubs/stubs/ext/pdo/PDORow.stubR~hjӪ!2:vendor/phpstan/php-8-stubs/stubs/ext/pdo/PDOException.stubZR~hjZ4:vendor/phpstan/php-8-stubs/stubs/ext/pdo/PDOStatement.stubK R~hjK xҤ9vendor/phpstan/php-8-stubs/stubs/ext/pdo/pdo_drivers.stub@R~hj@C1vendor/phpstan/php-8-stubs/stubs/ext/pdo/PDO.stubbZR~hjbZ-0Cvendor/phpstan/php-8-stubs/stubs/ext/pdo_sqlite/PDO_SQLite_Ext.stubR~hjW?vendor/phpstan/php-8-stubs/stubs/ext/pdo_sqlite/Pdo/Sqlite.stubmR~hjm =vendor/phpstan/php-8-stubs/stubs/ext/pdo_mysql/Pdo/Mysql.stubR~hjLvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_broker_dict_exists.stubZR~hjZG;פFvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_dict_suggest.stubuR~hju4Kvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_broker_list_dicts.stubdR~hjdlSԤCvendor/phpstan/php-8-stubs/stubs/ext/enchant/EnchantDictionary.stub)R~hj)u.=^Gvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_dict_describe.stubhR~hjhj}Nvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_broker_get_dict_path.stubuR~hjux kEvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_broker_init.stub@R~hj@:Pvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_dict_store_replacement.stub~R~hj~EJvUJvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_broker_get_error.stubSR~hjS;ӤMvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_dict_add_to_session.stubdR~hjdYNvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_broker_set_dict_path.stub{R~hj{OQvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_broker_request_pwl_dict.stubxR~hjx{*N7Mvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_broker_set_ordering.stubmR~hjmGvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_dict_is_added.stub^R~hj^8<Dvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_dict_check.stub[R~hj[u?vendor/phpstan/php-8-stubs/stubs/ext/enchant/EnchantBroker.stubGR~hjG!Lvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_dict_is_in_session.stubR~hjTIvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_broker_describe.stubbR~hjbJvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_broker_free_dict.stubfR~hjf Jvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_dict_quick_check.stubR~hjrAEvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_broker_free.stubYR~hjY}Bvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_dict_add.stubYR~hjY'W\Hvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_dict_get_error.stubYR~hjYiJNvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_dict_add_to_personal.stubR~hjʹMvendor/phpstan/php-8-stubs/stubs/ext/enchant/enchant_broker_request_dict.stuboR~hjo$_ Bvendor/phpstan/php-8-stubs/stubs/ext/json/json_last_error_msg.stub2R~hj2 :vendor/phpstan/php-8-stubs/stubs/ext/json/json_decode.stubrR~hjrh)<vendor/phpstan/php-8-stubs/stubs/ext/json/json_validate.stubiR~hji>vendor/phpstan/php-8-stubs/stubs/ext/json/json_last_error.stub+R~hj+ߏ,Ӥ:vendor/phpstan/php-8-stubs/stubs/ext/json/json_encode.stubR~hjx褤?vendor/phpstan/php-8-stubs/stubs/ext/json/JsonSerializable.stubR~hjaH<vendor/phpstan/php-8-stubs/stubs/ext/json/JsonException.stub2R~hj2P'8vendor/phpstan/php-8-stubs/stubs/ext/fileinfo/finfo.stub>R~hj> >vendor/phpstan/php-8-stubs/stubs/ext/fileinfo/finfo_close.stubR~hjޠ8Dvendor/phpstan/php-8-stubs/stubs/ext/fileinfo/mime_content_type.stubkR~hjk}.=vendor/phpstan/php-8-stubs/stubs/ext/fileinfo/finfo_open.stubR~hj<*?vendor/phpstan/php-8-stubs/stubs/ext/fileinfo/finfo_buffer.stubR~hj6 rHBvendor/phpstan/php-8-stubs/stubs/ext/fileinfo/finfo_set_flags.stub R~hj +6%=vendor/phpstan/php-8-stubs/stubs/ext/fileinfo/finfo_file.stubR~hjvz@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_int.stub8R~hj8(?^Hvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/com_safearray_proxy.stubCR~hjCj@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_imp.stubER~hjE26W;vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/dotnet.stubR~hj`*?vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_or.stubDR~hjDS@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_add.stubER~hjE'Z5@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_fix.stub8R~hj8FNvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_date_to_timestamp.stubGR~hjG뾤@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_xor.stubER~hjE؏+@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_eqv.stubER~hjE=@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_mul.stubER~hjE5[Pvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_date_from_timestamp.stubJR~hjJz@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_neg.stub8R~hj8ox@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_not.stub8R~hj8F@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_cat.stubER~hjEjCvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/com_event_sink.stub{R~hj{B0ԅ@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_sub.stubER~hjEAg3Avendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_cast.stubIR~hjI*Avendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_idiv.stubFR~hjFh@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_div.stubER~hjE@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_and.stubER~hjE{wq8vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/com.stubR~hjKϯ@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_cmp.stubxR~hjx?@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_mod.stubER~hjEYEvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/COMPersistHelper.stubR~hj찤Dvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/com_create_guid.stub4R~hj4\B#<vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant.stubR~hj4b@pEvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_set_type.stubIR~hjIkjoJvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/com_get_active_object.stub\R~hj\)ˤEvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/com_load_typelib.stub[R~hj[g@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_pow.stubER~hjEWgBvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_round.stubJR~hjJ.Evendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/com_message_pump.stubJR~hjJ@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_abs.stub8R~hj8<դ@vendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_set.stubiR~hji Gvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/com_print_typeinfo.stubR~hj?oEvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/variant_get_type.stub=R~hj=NDBvendor/phpstan/php-8-stubs/stubs/ext/com_dotnet/com_exception.stub?R~hj?PfLvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_set_character_data_handler.stubR~hjb7vendor/phpstan/php-8-stubs/stubs/ext/xml/XMLParser.stub!R~hj!; A?vendor/phpstan/php-8-stubs/stubs/ext/xml/xml_parser_create.stubnR~hjnkPCvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_parser_get_option.stubR~hj=tKvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_get_current_column_number.stubKR~hjKVJIvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_get_current_line_number.stubIR~hjI< Rvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_set_unparsed_entity_decl_handler.stubR~hj||ߤBvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_parser_create_ns.stubhR~hjh>vendor/phpstan/php-8-stubs/stubs/ext/xml/xml_error_string.stub?R~hj?wKTvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_set_processing_instruction_handler.stubR~hj{NQCvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_parser_set_option.stubR~hjI\xPvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_set_end_namespace_decl_handler.stubR~hjՇ-{Hvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_get_current_byte_index.stubHR~hjHqF@vendor/phpstan/php-8-stubs/stubs/ext/xml/xml_get_error_code.stub@R~hj@m:Kvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_set_notation_decl_handler.stubR~hj7vendor/phpstan/php-8-stubs/stubs/ext/xml/xml_parse.stub]R~hj] NCvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_parse_into_struct.stubeR~hjeG<vendor/phpstan/php-8-stubs/stubs/ext/xml/xml_set_object.stubR~hjjEvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_set_element_handler.stub R~hj ;a=vendor/phpstan/php-8-stubs/stubs/ext/xml/xml_parser_free.stub>R~hj>X9ޤQvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_set_external_entity_ref_handler.stubR~hjqEvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_set_default_handler.stub{R~hj{Rvendor/phpstan/php-8-stubs/stubs/ext/xml/xml_set_start_namespace_decl_handler.stubR~hj "1vendor/phpstan/php-8-stubs/stubs/ext/ffi/FFI.stub R~hj Cg7vendor/phpstan/php-8-stubs/stubs/ext/ffi/FFI/CType.stubF+R~hjF+xAvendor/phpstan/php-8-stubs/stubs/ext/ffi/FFI/ParserException.stubNR~hjN2q 0;vendor/phpstan/php-8-stubs/stubs/ext/ffi/FFI/Exception.stub:R~hj:ڧ7vendor/phpstan/php-8-stubs/stubs/ext/ffi/FFI/CData.stub-R~hj-9vendor/phpstan/php-8-stubs/stubs/ext/zlib/readgzfile.stubWR~hjW1<38vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzdeflate.stubnR~hjn{eq:vendor/phpstan/php-8-stubs/stubs/ext/zlib/zlib_encode.stub\R~hj\dI5vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzseek.stubR~hjF;vendor/phpstan/php-8-stubs/stubs/ext/zlib/ob_gzhandler.stubIR~hjI F08vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzinflate.stubOR~hjO6ޤ6vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzclose.stub_R~hj_c6vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzwrite.stubR~hjD4vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzeof.stub[R~hj[9:l^7vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzdecode.stubNR~hjN]xAvendor/phpstan/php-8-stubs/stubs/ext/zlib/inflate_get_status.stubFR~hjFMsO5vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzgets.stubzR~hjzEl5vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzfile.stublR~hjlۥ;vendor/phpstan/php-8-stubs/stubs/ext/zlib/deflate_init.stub\R~hj\<5vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzgetc.stubeR~hjeZ5vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzputs.stubR~hjd:vendor/phpstan/php-8-stubs/stubs/ext/zlib/zlib_decode.stubQR~hjQB5vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzread.stubrR~hjr:vendor/phpstan/php-8-stubs/stubs/ext/zlib/inflate_add.stubyR~hjyu9vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzcompress.stubsR~hjseֆ=vendor/phpstan/php-8-stubs/stubs/ext/zlib/InflateContext.stubHR~hjHI:vendor/phpstan/php-8-stubs/stubs/ext/zlib/deflate_add.stubyR~hjy9Cvendor/phpstan/php-8-stubs/stubs/ext/zlib/zlib_get_coding_type.stub9R~hj9s);vendor/phpstan/php-8-stubs/stubs/ext/zlib/inflate_init.stub\R~hj\-Ǥ7vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzencode.stubnR~hjnD9~=vendor/phpstan/php-8-stubs/stubs/ext/zlib/DeflateContext.stub&R~hj&Ǭ5vendor/phpstan/php-8-stubs/stubs/ext/zlib/gztell.stubbR~hjb]g5vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzopen.stubtR~hjt6Cvendor/phpstan/php-8-stubs/stubs/ext/zlib/inflate_get_read_len.stubHR~hjH8;vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzuncompress.stubRR~hjR;nx9vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzpassthru.stubdR~hjdjҤ7vendor/phpstan/php-8-stubs/stubs/ext/zlib/gzrewind.stub`R~hj` ~d]Evendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_clear_session.stubR~hjoΤFvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_add_to_session.stubR~hj(Bvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_new_config.stubR~hjCvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_config_mode.stubR~hjA2aEvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_save_wordlist.stubR~hj[WOEvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_config_ignore.stubR~hj`S Gvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_add_to_personal.stubR~hjz&yGvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_config_personal.stubR~hj0 ۤEvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_config_create.stub,R~hj,(Ivendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_store_replacement.stubR~hjGvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_config_data_dir.stubR~hjj<_?vendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_suggest.stubR~hj|Bvendor/phpstan/php-8-stubs/stubs/ext/pspell/PSpell/Dictionary.stubyR~hjyS>vendor/phpstan/php-8-stubs/stubs/ext/pspell/PSpell/Config.stubuR~hjuFF=vendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_check.stubR~hj8ϤGvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_config_dict_dir.stubR~hjtXDvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_new_personal.stub|R~hj|p|Jvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_config_runtogether.stubR~hjwCvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_config_repl.stubR~hj S,;vendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_new.stubhR~hjh?Hvendor/phpstan/php-8-stubs/stubs/ext/pspell/pspell_config_save_repl.stubR~hjFJvendor/phpstan/php-8-stubs/stubs/ext/opcache/opcache_is_script_cached.stubER~hjEd%?vendor/phpstan/php-8-stubs/stubs/ext/opcache/opcache_reset.stubLR~hjLuKvendor/phpstan/php-8-stubs/stubs/ext/opcache/opcache_get_configuration.stubTR~hjTzFvendor/phpstan/php-8-stubs/stubs/ext/opcache/opcache_compile_file.stubAR~hjA:ÑҤDvendor/phpstan/php-8-stubs/stubs/ext/opcache/opcache_invalidate.stubTR~hjT1Gvendor/phpstan/php-8-stubs/stubs/ext/opcache/opcache_jit_blacklist.stubTR~hjTֹDvendor/phpstan/php-8-stubs/stubs/ext/opcache/opcache_get_status.stubiR~hjiZH"<vendor/phpstan/php-8-stubs/stubs/ext/iconv/iconv_strlen.stubxR~hjxBvendor/phpstan/php-8-stubs/stubs/ext/iconv/iconv_get_encoding.stubhR~hjhW=vendor/phpstan/php-8-stubs/stubs/ext/iconv/iconv_strrpos.stubiR~hjia2<vendor/phpstan/php-8-stubs/stubs/ext/iconv/iconv_substr.stub{R~hj{'6Avendor/phpstan/php-8-stubs/stubs/ext/iconv/iconv_mime_encode.stubrR~hjrx Avendor/phpstan/php-8-stubs/stubs/ext/iconv/iconv_mime_decode.stubmR~hjm:<vendor/phpstan/php-8-stubs/stubs/ext/iconv/iconv_strpos.stubyR~hjy2h*Bvendor/phpstan/php-8-stubs/stubs/ext/iconv/iconv_set_encoding.stubMR~hjM۱Ivendor/phpstan/php-8-stubs/stubs/ext/iconv/iconv_mime_decode_headers.stubR~hjz\믤5vendor/phpstan/php-8-stubs/stubs/ext/iconv/iconv.stubdR~hjdzޱCvendor/phpstan/php-8-stubs/stubs/ext/pdo_firebird/Pdo/Firebird.stubR~hjA_g5vendor/phpstan/php-8-stubs/stubs/ext/shmop/Shmop.stub?R~hj?f+<vendor/phpstan/php-8-stubs/stubs/ext/shmop/shmop_delete.stub6R~hj6[;vendor/phpstan/php-8-stubs/stubs/ext/shmop/shmop_write.stubOR~hjOME&;vendor/phpstan/php-8-stubs/stubs/ext/shmop/shmop_close.stubHR~hjH1e%:vendor/phpstan/php-8-stubs/stubs/ext/shmop/shmop_read.stubNR~hjNRΤ:vendor/phpstan/php-8-stubs/stubs/ext/shmop/shmop_size.stub3R~hj3:vendor/phpstan/php-8-stubs/stubs/ext/shmop/shmop_open.stubbR~hjb:=vendor/phpstan/php-8-stubs/stubs/ext/pdo_dblib/Pdo/Dblib.stubQR~hjQM-u>vendor/phpstan/php-8-stubs/stubs/ext/calendar/jddayofweek.stubXR~hjXb=vendor/phpstan/php-8-stubs/stubs/ext/calendar/jdtofrench.stub8R~hj8dV=vendor/phpstan/php-8-stubs/stubs/ext/calendar/juliantojd.stubER~hjE@vendor/phpstan/php-8-stubs/stubs/ext/calendar/gregoriantojd.stubHR~hjH%g^<vendor/phpstan/php-8-stubs/stubs/ext/calendar/cal_to_jd.stubSR~hjSoY@vendor/phpstan/php-8-stubs/stubs/ext/calendar/jdtogregorian.stub;R~hj; >vendor/phpstan/php-8-stubs/stubs/ext/calendar/easter_date.stubXR~hjXM=vendor/phpstan/php-8-stubs/stubs/ext/calendar/frenchtojd.stubER~hjE;vendor/phpstan/php-8-stubs/stubs/ext/calendar/jdtounix.stub3R~hj3)&=vendor/phpstan/php-8-stubs/stubs/ext/calendar/jewishtojd.stubER~hjE>vendor/phpstan/php-8-stubs/stubs/ext/calendar/easter_days.stubXR~hjXTX2=vendor/phpstan/php-8-stubs/stubs/ext/calendar/jdtojulian.stub8R~hj8ݝ>vendor/phpstan/php-8-stubs/stubs/ext/calendar/cal_from_jd.stub^R~hj^xա=vendor/phpstan/php-8-stubs/stubs/ext/calendar/jdtojewish.stub^R~hj^zA>vendor/phpstan/php-8-stubs/stubs/ext/calendar/jdmonthname.stubDR~hjDt;vendor/phpstan/php-8-stubs/stubs/ext/calendar/cal_info.stubOR~hjOVfDvendor/phpstan/php-8-stubs/stubs/ext/calendar/cal_days_in_month.stubsR~hjs V;vendor/phpstan/php-8-stubs/stubs/ext/calendar/unixtojd.stub@R~hj@bv<vendor/phpstan/php-8-stubs/stubs/ext/sysvshm/shm_detach.stub=R~hj=:Pā=vendor/phpstan/php-8-stubs/stubs/ext/sysvshm/shm_has_var.stubHR~hjH9<vendor/phpstan/php-8-stubs/stubs/ext/sysvshm/shm_attach.stubnR~hjn I!=vendor/phpstan/php-8-stubs/stubs/ext/sysvshm/shm_get_var.stubIR~hjIu=vendor/phpstan/php-8-stubs/stubs/ext/sysvshm/shm_put_var.stubVR~hjV¾@vendor/phpstan/php-8-stubs/stubs/ext/sysvshm/shm_remove_var.stubKR~hjK)q<vendor/phpstan/php-8-stubs/stubs/ext/sysvshm/shm_remove.stub=R~hj=BEBvendor/phpstan/php-8-stubs/stubs/ext/sysvshm/SysvSharedMemory.stubJR~hjJI_+7vendor/phpstan/php-8-stubs/stubs/ext/phar/PharData.stub.(R~hj.(2T/<vendor/phpstan/php-8-stubs/stubs/ext/phar/PharException.stubTR~hjTvO3vendor/phpstan/php-8-stubs/stubs/ext/phar/Phar.stube+R~hje+Vפ;vendor/phpstan/php-8-stubs/stubs/ext/phar/PharFileInfo.stubR~hj!yi7vendor/phpstan/php-8-stubs/stubs/ext/soap/Soap/Sdl.stubpR~hjpWͤ7vendor/phpstan/php-8-stubs/stubs/ext/soap/Soap/Url.stubpR~hjpR{Evendor/phpstan/php-8-stubs/stubs/ext/soap/use_soap_error_handler.stubhR~hjhīd9vendor/phpstan/php-8-stubs/stubs/ext/soap/SoapServer.stub&R~hj&}Zn8vendor/phpstan/php-8-stubs/stubs/ext/soap/SoapFault.stubR~hj19vendor/phpstan/php-8-stubs/stubs/ext/soap/SoapHeader.stubR~hjV9vendor/phpstan/php-8-stubs/stubs/ext/soap/SoapClient.stubBR~hjBB<6vendor/phpstan/php-8-stubs/stubs/ext/soap/SoapVar.stubR~hjT|l<vendor/phpstan/php-8-stubs/stubs/ext/soap/is_soap_fault.stub7R~hj7ת*8vendor/phpstan/php-8-stubs/stubs/ext/soap/SoapParam.stubbR~hjbd>Evendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_get_error_code.stubOR~hjO4.Lvendor/phpstan/php-8-stubs/stubs/ext/intl/transliterator/Transliterator.stubR~hjDvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_has_same_rules.stubfR~hjf <vendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_parse.stubR~hj7@vendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_region.stubHR~hjHW_̤Hvendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_set_text_attribute.stubpR~hjpaFvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_display_name.stubR~hjhWDvendor/phpstan/php-8-stubs/stubs/ext/intl/locale_filter_matches.stubrR~hjr?vendor/phpstan/php-8-stubs/stubs/ext/intl/grapheme_stripos.stubcR~hjc Evendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_dst_savings.stubIR~hjICತOvendor/phpstan/php-8-stubs/stubs/ext/intl/intlgregcal_set_gregorian_change.stuboR~hjo<}@vendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_set_symbol.stubeR~hje I٤@vendor/phpstan/php-8-stubs/stubs/ext/intl/locale_get_script.stub?R~hj?Fʿ>vendor/phpstan/php-8-stubs/stubs/ext/intl/intl_is_failure.stub:R~hj:{yHvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_error_message.stubUR~hjU<vendor/phpstan/php-8-stubs/stubs/ext/intl/locale/Locale.stuboR~hjoFvendor/phpstan/php-8-stubs/stubs/ext/intl/collator_get_error_code.stubJR~hjJ.ȤGvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_equivalent_id.stub\R~hj\5=vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_equals.stubXR~hjXeWBvendor/phpstan/php-8-stubs/stubs/ext/intl/common/IntlIterator.stubiR~hjiXAHvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_create_enumeration.stubR~hj5Fvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_create_time_zone.stubPR~hjP{ФDvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_raw_offset.stubHR~hjHDBvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_set_lenient.stub\R~hj\n*wAvendor/phpstan/php-8-stubs/stubs/ext/intl/locale_set_default.stubR~hj=dKvendor/phpstan/php-8-stubs/stubs/ext/intl/collator_sort_with_sort_keys.stubYR~hjY$r_Bvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_maximum.stubXR~hjX{Evendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_error_code.stubOR~hjO,%室=vendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_gmt.stub4R~hj4Hvendor/phpstan/php-8-stubs/stubs/ext/intl/locale_get_display_script.stubkR~hjkdkAvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_is_weekend.stub`R~hj`c)Dvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_error_code.stubNR~hjNU;vendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_parse.stubR~hjҤ<vendor/phpstan/php-8-stubs/stubs/ext/intl/msgfmt_format.stub]R~hj]X/_?vendor/phpstan/php-8-stubs/stubs/ext/intl/grapheme_stristr.stubqR~hjqԺU?vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_set_time.stubVR~hjVsDvendor/phpstan/php-8-stubs/stubs/ext/intl/timezone/IntlTimeZone.stubR~hjWHvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_least_maximum.stub^R~hj^RvLvendor/phpstan/php-8-stubs/stubs/ext/intl/resourcebundle_get_error_code.stubPR~hjP9eHvendor/phpstan/php-8-stubs/stubs/ext/intl/formatter/NumberFormatter.stub\R~hj\Ҥ@vendor/phpstan/php-8-stubs/stubs/ext/intl/collator/Collator.stubF R~hjF CT{Dvendor/phpstan/php-8-stubs/stubs/ext/intl/collator_get_sort_key.stub[R~hj[KHvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_get_error_message.stubUR~hjUDo<vendor/phpstan/php-8-stubs/stubs/ext/intl/msgfmt_create.stubgR~hjgbAvendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_set_pattern.stub[R~hj[$դ@vendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_get_symbol.stub^R~hj^ACvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_set_calendar.stubpR~hjpW)`Ivendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_actual_minimum.stub_R~hj_%B@<vendor/phpstan/php-8-stubs/stubs/ext/intl/collator_sort.stuboR~hjoǍEvendor/phpstan/php-8-stubs/stubs/ext/intl/collator_get_attribute.stubYR~hjY'C $Kvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_id_for_windows_id.stubkR~hjkR-Ivendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_actual_maximum.stub_R~hj_'zyLvendor/phpstan/php-8-stubs/stubs/ext/intl/resourcebundle/ResourceBundle.stubhR~hjh+Gvendor/phpstan/php-8-stubs/stubs/ext/intl/intlgregcal_is_leap_year.stub`R~hj`Kvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_greatest_minimum.stubaR~hja1zBvendor/phpstan/php-8-stubs/stubs/ext/intl/collator_get_locale.stubTR~hjT/<Bvendor/phpstan/php-8-stubs/stubs/ext/intl/locale_canonicalize.stubAR~hjA:Jvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_count_equivalent_ids.stub^R~hj^$'Avendor/phpstan/php-8-stubs/stubs/ext/intl/locale_get_default.stub>R~hj>FPJvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_get_calendar_object.stubiR~hjiV*+}Dvendor/phpstan/php-8-stubs/stubs/ext/intl/resourcebundle_create.stubR~hjkOvendor/phpstan/php-8-stubs/stubs/ext/intl/intlgregcal_get_gregorian_change.stub^R~hj^dƤGvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_is_equivalent_to.stubbR~hjbqrFvendor/phpstan/php-8-stubs/stubs/ext/intl/transliterator_list_ids.stubRR~hjR."9Bvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_set_pattern.stub^R~hj^C-Dvendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_get_error_code.stubLR~hjL$Fvendor/phpstan/php-8-stubs/stubs/ext/intl/locale_get_all_variants.stubDR~hjDlAvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_locale.stubYR~hjY Cvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_get_timezone.stub]R~hj]^=Uvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_set_minimal_days_in_first_week.stubR~hjM=<vendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_create.stubzR~hjz5ڈtOvendor/phpstan/php-8-stubs/stubs/ext/intl/resourcebundle_get_error_message.stubVR~hjV6Avendor/phpstan/php-8-stubs/stubs/ext/intl/grapheme_str_split.stubfR~hjf-sq<vendor/phpstan/php-8-stubs/stubs/ext/intl/locale_lookup.stubR~hjrqCvendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_set_attribute.stubnR~hjn XR;vendor/phpstan/php-8-stubs/stubs/ext/intl/locale_parse.stub9R~hj9p<vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_clear.stubR~hjVʤ@vendor/phpstan/php-8-stubs/stubs/ext/intl/grapheme_strripos.stubdR~hjd='Bvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_get_pattern.stubUR~hjUSX<vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_after.stubWR~hjWUAvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_is_lenient.stubLR~hjLGԤSvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_skipped_wall_time_option.stubWR~hjWyDvendor/phpstan/php-8-stubs/stubs/ext/intl/transliterator_create.stubR~hjw%;vendor/phpstan/php-8-stubs/stubs/ext/intl/msgfmt_parse.stubsR~hjsخ0Dvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_create_default.stub;R~hj;9B:vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_set.stubR~hj&ʵCJvendor/phpstan/php-8-stubs/stubs/ext/intl/intlgregcal_create_instance.stubR~hjioM>vendor/phpstan/php-8-stubs/stubs/ext/intl/grapheme_strstr.stubpR~hjp(5Evendor/phpstan/php-8-stubs/stubs/ext/intl/resourcebundle_locales.stub_R~hj_O_}=vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_is_set.stubNR~hjNi=Gvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_field_difference.stuboR~hjo?Cvendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_get_attribute.stubgR~hjg{Gvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_to_date_time_zone.stub[R~hj[}KIvendor/phpstan/php-8-stubs/stubs/ext/intl/locale_get_display_variant.stublR~hjl2T[Dvendor/phpstan/php-8-stubs/stubs/ext/intl/msgfmt_format_message.stubhR~hjh>vendor/phpstan/php-8-stubs/stubs/ext/intl/grapheme_substr.stubdR~hjdFvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_create_instance.stubR~hj<|?vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_type.stubFR~hjF|Nvendor/phpstan/php-8-stubs/stubs/ext/intl/breakiterator/IntlBreakIterator.stubLR~hjLp WqNvendor/phpstan/php-8-stubs/stubs/ext/intl/breakiterator/IntlPartsIterator.stub@R~hj@m6Wvendor/phpstan/php-8-stubs/stubs/ext/intl/breakiterator/IntlCodePointBreakIterator.stubR~hj?Wvendor/phpstan/php-8-stubs/stubs/ext/intl/breakiterator/IntlRuleBasedBreakIterator.stubR~hjf,Ivendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_from_date_time_zone.stubXR~hjXtEGvendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_get_error_message.stubRR~hjRHvendor/phpstan/php-8-stubs/stubs/ext/intl/spoofchecker/Spoofchecker.stubR~hjda=vendor/phpstan/php-8-stubs/stubs/ext/intl/collator_asort.stubpR~hjp^RUvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_minimal_days_in_first_week.stub_R~hj_F@Mvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_weekend_transition.stubgR~hjgwr=vendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_format.stubR~hj4Cvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_get_timetype.stubSR~hjS`PUvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_create_time_zone_id_enumeration.stubR~hj:Kvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_day_of_week_type.stubeR~hje2Tvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_keyword_values_for_locale.stubR~hjOvendor/phpstan/php-8-stubs/stubs/ext/intl/normalizer_get_raw_decomposition.stubR~hj½Evendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_from_date_time.stuboR~hjoJKCvendor/phpstan/php-8-stubs/stubs/ext/intl/normalizer_normalize.stubxR~hjx'@vendor/phpstan/php-8-stubs/stubs/ext/intl/locale_get_region.stub?R~hj?Dvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_time_zone.stubXR~hjXCLvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_set_first_day_of_week.stubR~hjtGvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_error_message.stubTR~hjTySvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_set_skipped_wall_time_option.stubR~hjJ?vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_time.stubKR~hjK]Evendor/phpstan/php-8-stubs/stubs/ext/intl/intl_get_error_message.stub5R~hj5C;$Hvendor/phpstan/php-8-stubs/stubs/ext/intl/locale_get_display_region.stubkR~hjk+_Lvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_available_locales.stubRR~hjR*e?@vendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_offset.stubR~hjqs(ɤAvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_iana_id.stub|R~hj|`Lvendor/phpstan/php-8-stubs/stubs/ext/intl/transliterator_get_error_code.stub^R~hj^*`;vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_roll.stubrR~hjrFeJvendor/phpstan/php-8-stubs/stubs/ext/intl/locale_get_primary_language.stubIR~hjI@~Cvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_get_calendar.stubSR~hjS{эFvendor/phpstan/php-8-stubs/stubs/ext/intl/locale_get_display_name.stubiR~hji8դ>vendor/phpstan/php-8-stubs/stubs/ext/intl/grapheme_strpos.stubbR~hjb9hⓤJvendor/phpstan/php-8-stubs/stubs/ext/intl/locale_get_display_language.stubmR~hjm׫>vendor/phpstan/php-8-stubs/stubs/ext/intl/intl_error_name.stub<R~hj<vz1Bvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_set_lenient.stubR~hj\Cvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_set_timezone.stubJR~hjJ݆<vendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_format.stubR~hjCZCvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_get_datetype.stubSR~hjSyAvendor/phpstan/php-8-stubs/stubs/ext/intl/resourcebundle_get.stub2R~hj2O>=vendor/phpstan/php-8-stubs/stubs/ext/intl/locale_compose.stubAR~hjA~`Ф<vendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_id.stubIR~hjIATvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_repeated_wall_time_option.stubXR~hjX=vendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_create.stubcR~hjc/u@vendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_localtime.stubR~hjeƤ@vendor/phpstan/php-8-stubs/stubs/ext/intl/msgfmt_get_locale.stubLR~hjL+ Dvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_format_object.stubR~hj2wBvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_minimum.stubXR~hjXB(Ovendor/phpstan/php-8-stubs/stubs/ext/intl/transliterator_get_error_message.stubdR~hjd"KAvendor/phpstan/php-8-stubs/stubs/ext/intl/msgfmt_get_pattern.stubSR~hjSuFvendor/phpstan/php-8-stubs/stubs/ext/intl/locale_accept_from_http.stubJR~hjJg׽Gvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_use_daylight_time.stubLR~hjLҤDvendor/phpstan/php-8-stubs/stubs/ext/intl/calendar/IntlCalendar.stubFR~hjF8+Mvendor/phpstan/php-8-stubs/stubs/ext/intl/calendar/IntlGregorianCalendar.stubR~hj`TAvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_get_locale.stubtR~hjt:LԤAvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_unknown.stub8R~hj8Cvendor/phpstan/php-8-stubs/stubs/ext/intl/msgfmt_parse_message.stubR~hjADvendor/phpstan/php-8-stubs/stubs/ext/intl/normalizer/Normalizer.stub R~hj hDvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_windows_id.stubnR~hjn{$ŋRvendor/phpstan/php-8-stubs/stubs/ext/intl/dateformat/IntlDatePatternGenerator.stubNR~hjNޒ!Kvendor/phpstan/php-8-stubs/stubs/ext/intl/dateformat/IntlDateFormatter.stubR~hj~a4Ivendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_tz_data_version.stub?R~hj?KU^>@vendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_get_locale.stubqR~hjqJ=vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_before.stubXR~hjX3TBvendor/phpstan/php-8-stubs/stubs/ext/intl/intl_get_error_code.stub<R~hj<Q/>vendor/phpstan/php-8-stubs/stubs/ext/intl/grapheme_strlen.stubSR~hjS 4;vendor/phpstan/php-8-stubs/stubs/ext/intl/idn_to_ascii.stubR~hj3HTvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_set_repeated_wall_time_option.stubR~hj^`lDvendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_parse_currency.stubR~hjˤCvendor/phpstan/php-8-stubs/stubs/ext/intl/resourcebundle_count.stubGR~hjGIvendor/phpstan/php-8-stubs/stubs/ext/intl/collator_get_error_message.stubPR~hjP]#Cvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_to_date_time.stubSR~hjS!=rBvendor/phpstan/php-8-stubs/stubs/ext/intl/locale_get_keywords.stubaR~hjaϹn>vendor/phpstan/php-8-stubs/stubs/ext/intl/collator_create.stubOR~hjO `>vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_now.stub-R~hj-Z2Ivendor/phpstan/php-8-stubs/stubs/ext/intl/msgformat/MessageFormatter.stubR~hjL?vendor/phpstan/php-8-stubs/stubs/ext/intl/grapheme_strrpos.stubcR~hjcDҤOvendor/phpstan/php-8-stubs/stubs/ext/intl/transliterator_create_from_rules.stubR~hjw4?vendor/phpstan/php-8-stubs/stubs/ext/intl/collator_compare.stubeR~hje<=RDvendor/phpstan/php-8-stubs/stubs/ext/intl/collator_set_strength.stubR~hjІp=vendor/phpstan/php-8-stubs/stubs/ext/intl/uchar/IntlChar.stubJR~hjJD Kvendor/phpstan/php-8-stubs/stubs/ext/intl/transliterator_transliterate.stubR~hj!nr?vendor/phpstan/php-8-stubs/stubs/ext/intl/grapheme_extract.stubR~hj恤Gvendor/phpstan/php-8-stubs/stubs/ext/intl/normalizer_is_normalized.stubcR~hjc|Fvendor/phpstan/php-8-stubs/stubs/ext/intl/datefmt_get_timezone_id.stubYR~hjYk:vendor/phpstan/php-8-stubs/stubs/ext/intl/idn_to_utf8.stubR~hjJuGvendor/phpstan/php-8-stubs/stubs/ext/intl/msgfmt_get_error_message.stubSR~hjSVYHvendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_get_text_attribute.stubiR~hjiFvendor/phpstan/php-8-stubs/stubs/ext/intl/intltz_get_canonical_id.stubR~hj7Avendor/phpstan/php-8-stubs/stubs/ext/intl/msgfmt_set_pattern.stub\R~hj\Avendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_is_lenient.stubFR~hjFsFLqAvendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_get_pattern.stubRR~hjRKEvendor/phpstan/php-8-stubs/stubs/ext/intl/collator_set_attribute.stub`R~hj`:vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get.stubPR~hjP@D :vendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_add.stubWR~hjWy;zGvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_in_daylight_time.stubLR~hjLLvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_get_first_day_of_week.stubVR~hjVPC̤Cvendor/phpstan/php-8-stubs/stubs/ext/intl/converter/UConverter.stub(1R~hj(1Lvendor/phpstan/php-8-stubs/stubs/ext/intl/transliterator_create_inverse.stubeR~hje~1KDvendor/phpstan/php-8-stubs/stubs/ext/intl/collator_get_strength.stubBR~hjB4[Dvendor/phpstan/php-8-stubs/stubs/ext/intl/intlcal_set_time_zone.stubR~hj Dvendor/phpstan/php-8-stubs/stubs/ext/intl/msgfmt_get_error_code.stubMR~hjMwυ<vendor/phpstan/php-8-stubs/stubs/ext/intl/IntlException.stubTR~hjTcEvendor/phpstan/php-8-stubs/stubs/ext/intl/numfmt_format_currency.stubwR~hjwMd<vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getuid.stub(R~hj(0<vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_isatty.stubeR~hjeN=vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getpgid.stubRR~hjR 4eDvendor/phpstan/php-8-stubs/stubs/ext/posix/posix_get_last_error.stub7R~hj7C7=vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_setpgid.stubWR~hjW%N>vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getlogin.stubOR~hjO^dH@vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_initgroups.stubcR~hjcYW:vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_kill.stubeR~hjen1<vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_setuid.stub5R~hj5><vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_mkfifo.stub^R~hj^y<vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getsid.stubWR~hjWxx<vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_access.stubPR~hjPi?vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_setrlimit.stubxR~hjxhp =vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_setegid.stubKR~hjKrK=vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_eaccess.stuboR~hjoTk'>vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getgrgid.stubVR~hjV)?vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getgroups.stubgR~hjgfK=vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_seteuid.stubJR~hjJwpp=vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_ctermid.stubFR~hjFQoM;vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_errno.stubJR~hjJǤ?vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getrlimit.stubR~hj+=vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getegid.stub)R~hj)&D<vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_setsid.stub;R~hj;:|>vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getgrnam.stubUR~hjU"y>vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_strerror.stub<R~hj<.=vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_geteuid.stub)R~hj)Pޘ%<vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_setgid.stub6R~hj6ht;vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_times.stubFR~hjF_v=vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getpgrp.stub0R~hj0x>vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getpwuid.stubUR~hjU;ߖ=vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getppid.stub)R~hj)֤=vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_ttyname.stubuR~hjuQ<vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getpid.stub(R~hj(!=vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_sysconf.stubMR~hjMX;vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_mknod.stub}R~hj}4?vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_fpathconf.stubR~hj<&<vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getcwd.stub1R~hj1I[;vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_uname.stubMR~hjM"hr<vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getgid.stub/R~hj/fIE>vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_pathconf.stubmR~hjmLb+>vendor/phpstan/php-8-stubs/stubs/ext/posix/posix_getpwnam.stubYR~hjYk8P>vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_result_all.stubR~hjlz>vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_field_name.stubR~hjDvendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_columnprivileges.stub_R~hj_ Q7=vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_field_num.stubR~hjp:vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_result.stubR~hjn|<vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_pconnect.stubhR~hjhSj;vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_connect.stubfR~hjf;vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_prepare.stubR~hj㈤<vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_rollback.stubR~hjN?vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_primarykeys.stub5R~hj5!a<vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_num_rows.stubR~hjPȤ=vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_close_all.stubMR~hjM]j&9vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_error.stubR~hj{ ?vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_next_result.stub R~hj mKKvendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_connection_string_quote.stubWR~hjWA٤?vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_longreadlen.stubR~hjCvendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_field_precision.stubR~hjPؤBvendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_specialcolumns.stubR~hjg`g5?vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_data_source.stubR~hj.;vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_columns.stubR~hjDl=vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_field_len.stubR~hj^e6vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_do.stub R~hj :vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_commit.stubR~hj|OC?vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_gettypeinfo.stubR~hjQ=vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_setoption.stubR~hjp1>vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_fetch_into.stubKR~hjK55?vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_foreignkeys.stubR~hj?>vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_statistics.stubkR~hjkf[=vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_fetch_row.stubR~hj)Ovendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_connection_string_is_quoted.stubsR~hjsPipRvendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_connection_string_should_quote.stub\R~hj\q?vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_field_scale.stubR~hj bV9vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_close.stubR~hjX`N @vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_fetch_object.stubFR~hjF\hCvendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_tableprivileges.stub R~hj H?vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_fetch_array.stubR~hj%\:vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_cursor.stubR~hjl<vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_errormsg.stubR~hjOi};vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_execute.stubR~hj_e;vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_binmode.stubR~hj9V>vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_autocommit.stubbR~hjb(I>vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_procedures.stubiR~hji9G,>vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_field_type.stubR~hjYi:vendor/phpstan/php-8-stubs/stubs/ext/odbc/Odbc/Result.stubmR~hjmܕ>b>vendor/phpstan/php-8-stubs/stubs/ext/odbc/Odbc/Connection.stubqR~hjqWk?vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_free_result.stubR~hjxDDvendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_procedurecolumns.stubCR~hjCѳc:vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_tables.stubR~hj>vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_num_fields.stubR~hj:}f8vendor/phpstan/php-8-stubs/stubs/ext/odbc/odbc_exec.stubR~hjJڮ?vendor/phpstan/php-8-stubs/stubs/ext/hash/mhash_keygen_s2k.stubkR~hjkڣ:vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_equals.stubQR~hjQݍ:vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_update.stubR~hjd89vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_final.stubTR~hjT+i8vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_init.stubR~hjP8=vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_hmac_file.stubtR~hjtm4vendor/phpstan/php-8-stubs/stubs/ext/hash/mhash.stubVR~hjV `8vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_hmac.stubeR~hjeZ饤:vendor/phpstan/php-8-stubs/stubs/ext/hash/mhash_count.stub'R~hj'v 3vendor/phpstan/php-8-stubs/stubs/ext/hash/hash.stub*R~hj*N:vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_pbkdf2.stub_R~hj_DѤ>vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_hmac_algos.stubZR~hjZMU8vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_hkdf.stubxR~hjx:vendor/phpstan/php-8-stubs/stubs/ext/hash/HashContext.stubR~hj Cvendor/phpstan/php-8-stubs/stubs/ext/hash/mhash_get_block_size.stubSR~hjSx?vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_update_file.stubR~hj\Bvendor/phpstan/php-8-stubs/stubs/ext/hash/mhash_get_hash_name.stubAR~hjA3n8vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_copy.stubCR~hjCjAvendor/phpstan/php-8-stubs/stubs/ext/hash/hash_update_stream.stub}R~hj}WZ9vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_algos.stubUR~hjU78vendor/phpstan/php-8-stubs/stubs/ext/hash/hash_file.stubR~hjT53vendor/phpstan/php-8-stubs/stubs/ext/gettext/_.stubER~hjEhﳀIvendor/phpstan/php-8-stubs/stubs/ext/gettext/bind_textdomain_codeset.stubCR~hjCEމ<vendor/phpstan/php-8-stubs/stubs/ext/gettext/textdomain.stubR~hjǕ:vendor/phpstan/php-8-stubs/stubs/ext/gettext/ngettext.stubhR~hjhٵ;vendor/phpstan/php-8-stubs/stubs/ext/gettext/dngettext.stubR~hjO9vendor/phpstan/php-8-stubs/stubs/ext/gettext/gettext.stub5R~hj5R9ג<vendor/phpstan/php-8-stubs/stubs/ext/gettext/dcngettext.stubR~hj:vendor/phpstan/php-8-stubs/stubs/ext/gettext/dgettext.stubFR~hjF;;vendor/phpstan/php-8-stubs/stubs/ext/gettext/dcgettext.stubVR~hjVr-T@vendor/phpstan/php-8-stubs/stubs/ext/gettext/bindtextdomain.stubR~hjh7vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcceil.stubTR~hjT>vendor/phpstan/php-8-stubs/stubs/ext/bcmath/BcMath/Number.stub6R~hj6]8vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcfloor.stubUR~hjU6vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcpow.stubUR~hjUzä8vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcscale.stub5R~hj5<6vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcadd.stubtR~hjt˯9vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcdivmod.stubR~hjc788vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcround.stubR~hj6vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcdiv.stubRR~hjR 6vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcsub.stubRR~hjRrjD6vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcmul.stubRR~hjRf=7vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcsqrt.stubDR~hjD=M9vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcpowmod.stubiR~hji"?57vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bccomp.stubPR~hjPt 6vendor/phpstan/php-8-stubs/stubs/ext/bcmath/bcmod.stubRR~hjR5P?vendor/phpstan/php-8-stubs/stubs/ext/sqlite3/SQLite3Result.stub.R~hj. 9vendor/phpstan/php-8-stubs/stubs/ext/sqlite3/SQLite3.stub9R~hj9=7Bvendor/phpstan/php-8-stubs/stubs/ext/sqlite3/SQLite3Exception.stubkR~hjk*Y=vendor/phpstan/php-8-stubs/stubs/ext/sqlite3/SQLite3Stmt.stubR~hjLȤ:vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_search.stubpR~hjpZ[Hդ9vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_close.stubR~hj6j?vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_free_result.stubR~hjM[Cvendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_set_rebind_proc.stubR~hjf:vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_delete.stubR~hjpQAvendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_count_entries.stubR~hj7DCvendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_parse_reference.stubR~hjHΤ>vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_parse_exop.stub)R~hj)a">vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_set_option.stub1R~hj1h6M>vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_rename_ext.stubR~hj4le>vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_explode_dn.stubfR~hjf&":vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_rename.stubR~hj;?vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_mod_add_ext.stub9R~hj9}?vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_first_entry.stubR~hjS@vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_parse_result.stubR~hjXC?vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_mod_replace.stubR~hj=q㧤@vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_modify_batch.stub/R~hj/g>vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_get_values.stubR~hjD`:vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_escape.stubcR~hjcD[Gt=vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_sasl_bind.stub!R~hj!й8vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_bind.stubR~hjʸ?vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_8859_to_t61.stubBR~hjB-A?vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_exop_passwd.stubR~hj%0Bvendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_next_attribute.stubR~hj75\<Dvendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_count_references.stubR~hjR'Bvendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_connect_wallet.stubR~hj5D>vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_delete_ext.stubR~hj~w>vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_get_option.stub1R~hj1 0;vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_connect.stubR~hjŤBvendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_get_values_len.stubmR~hjm.)ͤ9vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_error.stubR~hjlM;vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_mod_del.stub R~hj 6LBvendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_next_reference.stubR~hjmy8vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_list.stublR~hjle%?vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_mod_del_ext.stub9R~hj9Cvendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_mod_replace_ext.stubAR~hjA/7vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_add.stubR~hjbS;vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_mod_add.stub R~hj oQv?vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_t61_to_8859.stubYR~hjY Bvendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_get_attributes.stub;R~hj;\4yCvendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_first_attribute.stubR~hj6 :vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_dn2ufn.stub:R~hj:bŤ=vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_exop_sync.stubLR~hjL)/ :vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_get_dn.stubR~hj}0?vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_exop_whoami.stubR~hj*8vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_read.stubzR~hjz~3Cvendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_first_reference.stubR~hj3>;vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_err2str.stub5R~hj5:3ސ;vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_compare.stub;R~hj;|?٤;vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_add_ext.stub1R~hj1)f8vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_exop.stubR~hjҝT<vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_bind_ext.stub[R~hj[̖9vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_errno.stubR~hj;:vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_modify.stubGR~hjGҙ8@vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_exop_refresh.stub)R~hj)?vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_get_entries.stub>R~hj> (|=vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_start_tls.stubR~hjg>vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_next_entry.stubR~hj$9:vendor/phpstan/php-8-stubs/stubs/ext/ldap/ldap_unbind.stubR~hjsɤ?vendor/phpstan/php-8-stubs/stubs/ext/ldap/LDAP/ResultEntry.stubxR~hjxoq(:vendor/phpstan/php-8-stubs/stubs/ext/ldap/LDAP/Result.stubsR~hjsA7=>vendor/phpstan/php-8-stubs/stubs/ext/ldap/LDAP/Connection.stubwR~hjw;ըѤ@vendor/phpstan/php-8-stubs/stubs/ext/spl/FilesystemIterator.stubIR~hjI$>vendor/phpstan/php-8-stubs/stubs/ext/spl/IteratorIterator.stub,R~hj,h絤>vendor/phpstan/php-8-stubs/stubs/ext/spl/SplObjectStorage.stubX R~hjX ɤ;vendor/phpstan/php-8-stubs/stubs/ext/spl/OuterIterator.stubR~hj==<vendor/phpstan/php-8-stubs/stubs/ext/spl/RangeException.stubKR~hjK7gͤ5vendor/phpstan/php-8-stubs/stubs/ext/spl/SplHeap.stubZR~hjZ4Y`=vendor/phpstan/php-8-stubs/stubs/ext/spl/CachingIterator.stub R~hj 8vendor/phpstan/php-8-stubs/stubs/ext/spl/class_uses.stubR~hjC=vendor/phpstan/php-8-stubs/stubs/ext/spl/DomainException.stubJR~hjJ|HR;vendor/phpstan/php-8-stubs/stubs/ext/spl/EmptyIterator.stubjR~hjjGځݤ9vendor/phpstan/php-8-stubs/stubs/ext/spl/SplFileInfo.stubR~hjY;vendor/phpstan/php-8-stubs/stubs/ext/spl/SplFixedArray.stubR~hj}1m9vendor/phpstan/php-8-stubs/stubs/ext/spl/SplObserver.stubR~hjMƵ;vendor/phpstan/php-8-stubs/stubs/ext/spl/ArrayIterator.stubR~hjuP>vendor/phpstan/php-8-stubs/stubs/ext/spl/MultipleIterator.stubi R~hji cX䌤;vendor/phpstan/php-8-stubs/stubs/ext/spl/SplFileObject.stubR~hjzFvendor/phpstan/php-8-stubs/stubs/ext/spl/UnexpectedValueException.stubUR~hjUh8vendor/phpstan/php-8-stubs/stubs/ext/spl/SplMaxHeap.stubR~hjC0>vendor/phpstan/php-8-stubs/stubs/ext/spl/NoRewindIterator.stubR~hjKmEvendor/phpstan/php-8-stubs/stubs/ext/spl/RecursiveFilterIterator.stubR~hjAvendor/phpstan/php-8-stubs/stubs/ext/spl/SplDoublyLinkedList.stubrR~hjrCvendor/phpstan/php-8-stubs/stubs/ext/spl/spl_autoload_register.stubwR~hjwn{<vendor/phpstan/php-8-stubs/stubs/ext/spl/AppendIterator.stubR~hjYT>vendor/phpstan/php-8-stubs/stubs/ext/spl/SeekableIterator.stubR~hj֤=vendor/phpstan/php-8-stubs/stubs/ext/spl/LengthException.stubJR~hjJ2?<vendor/phpstan/php-8-stubs/stubs/ext/spl/iterator_apply.stubiR~hji8vendor/phpstan/php-8-stubs/stubs/ext/spl/SplMinHeap.stubR~hj];vendor/phpstan/php-8-stubs/stubs/ext/spl/class_parents.stubR~hjLwHFvendor/phpstan/php-8-stubs/stubs/ext/spl/RecursiveCachingIterator.stubR~hj)>vendor/phpstan/php-8-stubs/stubs/ext/spl/InfiniteIterator.stubR~hj3VH?vendor/phpstan/php-8-stubs/stubs/ext/spl/spl_autoload_call.stub;R~hj;{ń"Hvendor/phpstan/php-8-stubs/stubs/ext/spl/RecursiveDirectoryIterator.stubR~hjt6>vendor/phpstan/php-8-stubs/stubs/ext/spl/RuntimeException.stubFR~hjFG;vendor/phpstan/php-8-stubs/stubs/ext/spl/LimitIterator.stubR~hj9vendor/phpstan/php-8-stubs/stubs/ext/spl/ArrayObject.stub]R~hj]_>vendor/phpstan/php-8-stubs/stubs/ext/spl/class_implements.stubR~hjqNl@;vendor/phpstan/php-8-stubs/stubs/ext/spl/RegexIterator.stub R~hj 1<vendor/phpstan/php-8-stubs/stubs/ext/spl/LogicException.stubcR~hjcU;9vendor/phpstan/php-8-stubs/stubs/ext/spl/spl_classes.stub@R~hj@n;@vendor/phpstan/php-8-stubs/stubs/ext/spl/UnderflowException.stubOR~hjOABvendor/phpstan/php-8-stubs/stubs/ext/spl/OutOfBoundsException.stubQR~hjQ$":vendor/phpstan/php-8-stubs/stubs/ext/spl/spl_autoload.stubWR~hjW5=Evendor/phpstan/php-8-stubs/stubs/ext/spl/spl_autoload_unregister.stubFR~hjFWEvendor/phpstan/php-8-stubs/stubs/ext/spl/spl_autoload_extensions.stubUR~hjUc ?vendor/phpstan/php-8-stubs/stubs/ext/spl/OverflowException.stubNR~hjNƤDvendor/phpstan/php-8-stubs/stubs/ext/spl/RecursiveRegexIterator.stubR~hj6&:vendor/phpstan/php-8-stubs/stubs/ext/spl/GlobIterator.stubcR~hjc 6vendor/phpstan/php-8-stubs/stubs/ext/spl/SplQueue.stubR~hjtVAvendor/phpstan/php-8-stubs/stubs/ext/spl/OutOfRangeException.stubNR~hjN"8<vendor/phpstan/php-8-stubs/stubs/ext/spl/iterator_count.stubR~hjS46vendor/phpstan/php-8-stubs/stubs/ext/spl/SplStack.stub7R~hj7>?vendor/phpstan/php-8-stubs/stubs/ext/spl/DirectoryIterator.stub!R~hj!iECDvendor/phpstan/php-8-stubs/stubs/ext/spl/BadMethodCallException.stub[R~hj[&Gvendor/phpstan/php-8-stubs/stubs/ext/spl/RecursiveIteratorIterator.stub R~hj _Tq<vendor/phpstan/php-8-stubs/stubs/ext/spl/ParentIterator.stub7R~hj7ml=vendor/phpstan/php-8-stubs/stubs/ext/spl/spl_object_hash.stub<R~hj<x~8vendor/phpstan/php-8-stubs/stubs/ext/spl/SplSubject.stubjR~hjjrϤ<vendor/phpstan/php-8-stubs/stubs/ext/spl/FilterIterator.stubR~hjŹ?vendor/phpstan/php-8-stubs/stubs/ext/spl/iterator_to_array.stubR~hj:6Yؤ>vendor/phpstan/php-8-stubs/stubs/ext/spl/SplPriorityQueue.stub R~hj x^;vendor/phpstan/php-8-stubs/stubs/ext/spl/spl_object_id.stub7R~hj7[ 3Dvendor/phpstan/php-8-stubs/stubs/ext/spl/RecursiveArrayIterator.stubqR~hjqZ)#ޤMvendor/phpstan/php-8-stubs/stubs/ext/spl/RecursiveCallbackFilterIterator.stub R~hj :ir&Fvendor/phpstan/php-8-stubs/stubs/ext/spl/InvalidArgumentException.stubSR~hjSWDvendor/phpstan/php-8-stubs/stubs/ext/spl/spl_autoload_functions.stub4R~hj4mpi?vendor/phpstan/php-8-stubs/stubs/ext/spl/RecursiveIterator.stubR~hjۤCvendor/phpstan/php-8-stubs/stubs/ext/spl/RecursiveTreeIterator.stubV R~hjV 41?Dvendor/phpstan/php-8-stubs/stubs/ext/spl/CallbackFilterIterator.stubR~hj Fvendor/phpstan/php-8-stubs/stubs/ext/spl/BadFunctionCallException.stubSR~hjS7}Ҥ?vendor/phpstan/php-8-stubs/stubs/ext/spl/SplTempFileObject.stubR~hjhv?vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_setopt.stubR~hjĉ =vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_recv.stub}R~hj}>Cvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_last_error.stubKR~hjK8vendor/phpstan/php-8-stubs/stubs/ext/sockets/Socket.stub@R~hj@RoCvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_cmsg_space.stubQR~hjQ\դ@vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_connect.stub^R~hj^[`Pvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_wsaprotocol_info_import.stubSR~hjSFvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_addrinfo_bind.stubOR~hjOIDvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_create_pair.stubR~hj l?vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_getopt.stubR~hjtzVFvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_create_listen.stubR~hj7@vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_recvmsg.stub`R~hj`ۓ?vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_accept.stubBR~hjBjդEvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_set_nonblock.stub?R~hj?ܟ0HDvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_clear_error.stubFR~hjF_{ZQvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_wsaprotocol_info_release.stubKR~hjK攘?vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_select.stubR~hjZOޤ?vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_atmark.stubhR~hjh%|@vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_sendmsg.stub_R~hj_qp Cvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_set_option.stubR~hjCvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_get_option.stubxR~hjx]IIvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_addrinfo_explain.stubaR~hjaJ NHvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_addrinfo_lookup.stubR~hj\urFvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_export_stream.stubXR~hjXhPAvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_recvfrom.stubR~hj4!ˤBvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_set_block.stub<R~hj<vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_close.stub8R~hj8?vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_sendto.stubR~hj6qPvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_wsaprotocol_info_export.stubtR~hjtPv=vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_send.stubcR~hjcN.[4=vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_read.stubiR~hjiqb?vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_listen.stubKR~hjK%lIvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_addrinfo_connect.stubRR~hjR~HGAvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_shutdown.stubfR~hjfFvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_import_stream.stub`R~hj`R7Ť=vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_bind.stubWR~hjW%Dvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_getsockname.stubR~hjPI2>vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_write.stub`R~hj`)?vendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_create.stubXR~hjXRODvendor/phpstan/php-8-stubs/stubs/ext/sockets/socket_getpeername.stubR~hjxNvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_write_dtd_entity.stubR~hjtd+ʤIvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_open_memory.stub>R~hj>۽Lvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_start_document.stubR~hj.wӤNvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_write_element_ns.stubR~hj#=vendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/XMLWriter.stub:R~hj:TX Gvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_write_dtd.stubR~hjoGvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_start_dtd.stubR~hjxN`Ivendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_end_comment.stubDR~hjDVPvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_write_attribute_ns.stubR~hjVMvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_write_attribute.stubeR~hjeϤHvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_set_indent.stubQR~hjQ bHIvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_end_element.stubDR~hjD򉯤Gvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_write_raw.stubSR~hjSkˤPvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_start_attribute_ns.stub~R~hj~zIvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_write_cdata.stubUR~hjUEvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_end_dtd.stub@R~hj@U|Lvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_end_dtd_entity.stubGR~hjG&m%Nvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_full_end_element.stubIR~hjI `\Kvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_write_comment.stubWR~hjWdOvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_start_dtd_element.stubaR~hja&htNvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_start_element_ns.stub|R~hj|ǚ>Bvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_text.stubNR~hjNR=kޤKvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_write_element.stubmR~hjmOvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_write_dtd_element.stubiR~hji Gvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_end_cdata.stubBR~hjBW@Ovendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_set_indent_string.stub_R~hj__pMvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_end_dtd_element.stubHR~hjH JHzJvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_end_document.stubER~hjEFkuCvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_flush.stubXR~hjXnŤMvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_end_dtd_attlist.stubHR~hjHYJ.Ovendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_write_dtd_attlist.stubiR~hji"hKvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_start_comment.stubFR~hjFb~oMvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_start_attribute.stubVR~hjV+$UFvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_open_uri.stubhR~hjhsOvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_start_dtd_attlist.stubXR~hjXKvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_end_attribute.stubFR~hjF Dvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_end_pi.stub?R~hj?C0Kvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_output_memory.stub\R~hj\<-5Fvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_start_pi.stubQR~hjQCNvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_start_dtd_entity.stubfR~hjfdIvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_start_cdata.stubDR~hjDQ܋2Fvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_write_pi.stubbR~hjbVKvendor/phpstan/php-8-stubs/stubs/ext/xmlwriter/xmlwriter_start_element.stubTR~hjT,dDvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_cms_verify.stub(R~hj(ۤFvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_error_string.stub9R~hj97G1Fvendor/phpstan/php-8-stubs/stubs/ext/openssl/OpenSSLAsymmetricKey.stub,R~hj,{ՔLvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_get_cipher_methods.stubdR~hjd$Evendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkey_derive.stubR~hjIGEvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_cms_decrypt.stub4R~hj4CzHvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_dh_compute_key.stubqR~hjq 6Dvendor/phpstan/php-8-stubs/stubs/ext/openssl/OpenSSLCertificate.stubLR~hjLLYZBvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_cms_sign.stub]R~hj]Yh8Evendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkey_export.stubR~hjOky>vendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_seal.stubR~hjKAvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_encrypt.stubR~hjlS8Evendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_x509_export.stubR~hj[Lvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_get_cert_locations.stubOR~hjO?Lvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_csr_get_public_key.stubR~hjOXϤHvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_public_decrypt.stubR~hjKvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_cipher_key_length.stub_R~hj_HIvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_password_verify.stubR~hjB;(Dvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_csr_export.stubR~hjiAvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_csr_new.stubR~hja^AEvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_spki_export.stubDR~hjD]ȤBvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_csr_sign.stubR~hjäGvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_get_publickey.stubR~hjUHvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_public_encrypt.stubR~hj'>vendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_open.stubR~hj1̽tGvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkcs7_encrypt.stub R~hj h+ !Cvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_x509_free.stubaR~hja.MIԤDvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkcs7_read.stubmR~hjmzDvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkcs7_sign.stubDR~hjD%Hvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_get_privatekey.stubR~hjNdLvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_csr_export_to_file.stubR~hj;!sGvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkcs7_decrypt.stubR~hj.ͤEvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_x509_verify.stubR~hjkMMvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkey_export_to_file.stubR~hjw#Ivendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkey_get_public.stubR~hj`Evendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkcs12_read.stubR~hjJvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkey_get_private.stubR~hj*oAvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_decrypt.stub~R~hj~8Cvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkey_free.stub[R~hj[[j@vendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_digest.stubqR~hjq~ՒHvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_get_md_methods.stub`R~hj` IFvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkcs7_verify.stubR~hjդMvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_random_pseudo_bytes.stubR~hj%Kp%Gvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_password_hash.stubR~hjlz3Cvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_x509_read.stubjR~hjjb({eIvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_private_decrypt.stubR~hj{Dvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_x509_parse.stubR~hj%Evendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_spki_verify.stub<R~hj<NKvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_x509_checkpurpose.stubR~hjJvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_cipher_iv_length.stubMR~hjM~Jvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_x509_fingerprint.stubR~hjABvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkey_new.stubZR~hjZN>vendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_sign.stubR~hjȤIvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_private_encrypt.stubR~hj ZIvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_csr_get_subject.stubR~hj+sBvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_cms_read.stubuR~hju(oBvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_free_key.stubzR~hjz\҅Gvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkcs12_export.stubR~hj=IWIvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_get_curve_names.stubjR~hjj⡤Ovendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkcs12_export_to_file.stubR~hj4bBvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_spki_new.stubR~hj].@vendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_verify.stubR~hj8o@vendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pbkdf2.stubR~hjsPvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_x509_check_private_key.stubR~hj LOvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_spki_export_challenge.stubNR~hjNJvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_pkey_get_details.stubmR~hjmDEvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_cms_encrypt.stubVR~hjV0ΤRvendor/phpstan/php-8-stubs/stubs/ext/openssl/OpenSSLCertificateSigningRequest.stub8R~hj8wmWMvendor/phpstan/php-8-stubs/stubs/ext/openssl/openssl_x509_export_to_file.stubR~hjC m:vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_handlers.stubXR~hjXN+b8vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_delete.stubKR~hjKmj,7vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_close.stubR~hjٻ6vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_list.stub&R~hj&8vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_exists.stubKR~hjKl;vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_key_split.stubGR~hjGP:vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_firstkey.stubR~hj<vendor/phpstan/php-8-stubs/stubs/ext/dba/Dba/Connection.stubvR~hjvh+7vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_popen.stubR~hj% ޤ6vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_sync.stubR~hj[:vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_optimize.stubR~hjR9vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_replace.stub{R~hj{B9vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_nextkey.stubR~hjT̤7vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_fetch.stubR~hjIؤ8vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_insert.stubxR~hjx9#$6vendor/phpstan/php-8-stubs/stubs/ext/dba/dba_open.stubkR~hjkf?vendor/phpstan/php-8-stubs/stubs/ext/filter/filter_has_var.stubnR~hjnu`Cvendor/phpstan/php-8-stubs/stubs/ext/filter/filter_input_array.stubR~hjKx;vendor/phpstan/php-8-stubs/stubs/ext/filter/filter_var.stubjR~hjjc=vendor/phpstan/php-8-stubs/stubs/ext/filter/filter_input.stub{R~hj{`@8<vendor/phpstan/php-8-stubs/stubs/ext/filter/filter_list.stub@R~hj@V:vendor/phpstan/php-8-stubs/stubs/ext/filter/filter_id.stub7R~hj7Avendor/phpstan/php-8-stubs/stubs/ext/filter/filter_var_array.stubR~hj+{KJvendor/phpstan/php-8-stubs/stubs/ext/pcre/preg_replace_callback_array.stubR~hj?3:vendor/phpstan/php-8-stubs/stubs/ext/pcre/preg_filter.stubR~hj`FH>vendor/phpstan/php-8-stubs/stubs/ext/pcre/preg_last_error.stub+R~hj+9{j ;vendor/phpstan/php-8-stubs/stubs/ext/pcre/preg_replace.stubR~hj<=vendor/phpstan/php-8-stubs/stubs/ext/pcre/preg_match_all.stubR~hjx^Dvendor/phpstan/php-8-stubs/stubs/ext/pcre/preg_replace_callback.stubR~hjόѤ9vendor/phpstan/php-8-stubs/stubs/ext/pcre/preg_quote.stubOR~hjO-Bvendor/phpstan/php-8-stubs/stubs/ext/pcre/preg_last_error_msg.stub2R~hj2tK8vendor/phpstan/php-8-stubs/stubs/ext/pcre/preg_grep.stubZR~hjZ9vendor/phpstan/php-8-stubs/stubs/ext/pcre/preg_split.stubR~hj}X9vendor/phpstan/php-8-stubs/stubs/ext/pcre/preg_match.stubR~hj +=vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_random_bits.stub5R~hj5:vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_popcount.stub<R~hj<=56vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_sign.stub8R~hj8}6vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_fact.stub9R~hj9B烤7vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_div_r.stubwR~hjwlo9?5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_lcm.stubPR~hjPZ%8vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_clrbit.stub<R~hj<-ؤ9vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_sqrtrem.stubTR~hjT^8vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_invert.stubYR~hjY^ 5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_add.stubPR~hjP<6vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_root.stubCR~hjCF1vendor/phpstan/php-8-stubs/stubs/ext/gmp/GMP.stub<R~hj<(8vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_jacobi.stubRR~hjRj5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_neg.stub8R~hj88vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_setbit.stubPR~hjP +5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_abs.stub8R~hj8ܕp8vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_strval.stubMR~hjMO-5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_com.stub8R~hj8SԴ9vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_hamdist.stubSR~hjS0)";vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_nextprime.stub>R~hj>:vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_divexact.stubUR~hjUj<vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_prob_prime.stubUR~hjUY6vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_sqrt.stub9R~hj92H@vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_perfect_square.stubCR~hjCeE*05vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_pow.stubGR~hjG7vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_scan1.stubFR~hjF6:vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_legendre.stubTR~hjTN6vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_powm.stubnR~hjnzR9vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_rootrem.stub^R~hj^se`>vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_random_range.stubWR~hjW-?vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_perfect_power.stubBR~hjBIqΤ9vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_testbit.stubHR~hjHaOX6vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_init.stubCR~hjC'¿J8vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_gcdext.stubkR~hjk~?08vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_div_qr.stubR~hj *7vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_div_q.stubwR~hjww:vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_binomial.stubCR~hjC 7vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_scan0.stubFR~hjFHV8vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_export.stubR~hjt8vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_intval.stub:R~hj:Z5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_gcd.stubPR~hjP64vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_or.stubOR~hjON4;vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_kronecker.stubUR~hjU#¤5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_mul.stubPR~hjPFF5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_and.stubPR~hjPcmΒ5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_cmp.stubOR~hjOЃ5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_sub.stubPR~hjPAi5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_xor.stubPR~hjPɐm5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_mod.stubPR~hjPPZ5vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_div.stubR~hj>}8vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_import.stubwR~hjw[Y=vendor/phpstan/php-8-stubs/stubs/ext/gmp/gmp_random_seed.stubAR~hjA8Dvendor/phpstan/php-8-stubs/stubs/sapi/cli/cli_get_process_title.stub5R~hj5|}p<vendor/phpstan/php-8-stubs/stubs/sapi/cli/getallheaders.stub+R~hj+BEvendor/phpstan/php-8-stubs/stubs/sapi/cli/apache_request_headers.stub4R~hj4DhH:Fvendor/phpstan/php-8-stubs/stubs/sapi/cli/apache_response_headers.stub5R~hj5Dvendor/phpstan/php-8-stubs/stubs/sapi/cli/cli_set_process_title.stub?R~hj?R~hj>jKvendor/phpstan/php-8-stubs/stubs/sapi/litespeed/apache_request_headers.stub\R~hj\8Lvendor/phpstan/php-8-stubs/stubs/sapi/litespeed/apache_response_headers.stubdR~hjdcLNvendor/phpstan/php-8-stubs/stubs/sapi/litespeed/litespeed_request_headers.stubYR~hjY4S@vendor/phpstan/php-8-stubs/stubs/sapi/fpm/fpm/getallheaders.stubPR~hjP(Ivendor/phpstan/php-8-stubs/stubs/sapi/fpm/fpm/fastcgi_finish_request.stubUR~hjURrIvendor/phpstan/php-8-stubs/stubs/sapi/fpm/fpm/apache_request_headers.stub4R~hj4DhH:Avendor/phpstan/php-8-stubs/stubs/sapi/fpm/fpm/fpm_get_status.stub2R~hj2 Lvendor/phpstan/php-8-stubs/stubs/sapi/apache2handler/apache_get_modules.stub0R~hj07ҤAvendor/phpstan/php-8-stubs/stubs/sapi/apache2handler/virtual.stub/R~hj/{XӤGvendor/phpstan/php-8-stubs/stubs/sapi/apache2handler/getallheaders.stubPR~hjP(Pvendor/phpstan/php-8-stubs/stubs/sapi/apache2handler/apache_request_headers.stub4R~hj4DhH:Lvendor/phpstan/php-8-stubs/stubs/sapi/apache2handler/apache_get_version.stub7R~hj7>֤Gvendor/phpstan/php-8-stubs/stubs/sapi/apache2handler/apache_setenv.stubdR~hjdKݤGvendor/phpstan/php-8-stubs/stubs/sapi/apache2handler/apache_getenv.stub]R~hj]]3Evendor/phpstan/php-8-stubs/stubs/sapi/apache2handler/apache_note.stub]R~hj]7dQvendor/phpstan/php-8-stubs/stubs/sapi/apache2handler/apache_response_headers.stub5R~hj5Kvendor/phpstan/php-8-stubs/stubs/sapi/apache2handler/apache_lookup_uri.stubhR~hjhkz->vendor/phpstan/php-8-stubs/stubs/sapi/phpdbg/phpdbg_color.stubDR~hjDψ?vendor/phpstan/php-8-stubs/stubs/sapi/phpdbg/phpdbg_prompt.stub8R~hj85SGvendor/phpstan/php-8-stubs/stubs/sapi/phpdbg/phpdbg_get_executable.stubFR~hjF)FGvendor/phpstan/php-8-stubs/stubs/sapi/phpdbg/phpdbg_break_function.stubBR~hjB{&=vendor/phpstan/php-8-stubs/stubs/sapi/phpdbg/phpdbg_exec.stub>R~hj>e>vendor/phpstan/php-8-stubs/stubs/sapi/phpdbg/phpdbg_clear.stub)R~hj)jwCvendor/phpstan/php-8-stubs/stubs/sapi/phpdbg/phpdbg_break_next.stubPR~hjPdL,Bvendor/phpstan/php-8-stubs/stubs/sapi/phpdbg/phpdbg_end_oplog.stubBR~hjBoqEvendor/phpstan/php-8-stubs/stubs/sapi/phpdbg/phpdbg_break_method.stubMR~hjMJDvendor/phpstan/php-8-stubs/stubs/sapi/phpdbg/phpdbg_start_oplog.stub/R~hj/)NCvendor/phpstan/php-8-stubs/stubs/sapi/phpdbg/phpdbg_break_file.stubER~hjEr;cEvendor/phpstan/php-8-stubs/stubs/sapi/cgi/apache_child_terminate.stubUR~hjU Ϥ<vendor/phpstan/php-8-stubs/stubs/sapi/cgi/getallheaders.stubPR~hjP(Evendor/phpstan/php-8-stubs/stubs/sapi/cgi/apache_request_headers.stub4R~hj4DhH:Fvendor/phpstan/php-8-stubs/stubs/sapi/cgi/apache_response_headers.stub5R~hj5"vendor/phpstan/php-8-stubs/LICENSE/R~hj/#Ȥ&vendor/hoa/consistency/Consistency.php~ R~hj~ bT$vendor/hoa/consistency/Xcallable.phpt R~hjt t"vendor/hoa/consistency/PATCHES.txtR~hjoV?"vendor/hoa/consistency/Prelude.phpR~hjY`i%vendor/hoa/consistency/Autoloader.phpaR~hja$vendor/hoa/consistency/Exception.phpR~hjmXvendor/hoa/visitor/Element.phpR~hjebvendor/hoa/visitor/Visit.phpR~hj5vendor/hoa/regex/Grammar.pp R~hj AL&vendor/hoa/regex/Visitor/Isotropic.php>$R~hj>$CId;vendor/hoa/regex/Exception.phpR~hj  vendor/hoa/zformat/Parameter.phpGR~hjG? vendor/hoa/zformat/Exception.phpR~hjNf&vendor/hoa/zformat/Parameterizable.phpR~hjKn.vendor/hoa/compiler/Documentation/En/Index.xylR~hjd/.vendor/hoa/compiler/Documentation/Fr/Index.xyltR~hjtEvendor/hoa/compiler/PATCHES.txt;R~hj;Tsvendor/hoa/compiler/Bin/Pp.phpR~hj%$vendor/hoa/compiler/Visitor/Dump.php? R~hj? L护&vendor/hoa/compiler/Exception/Rule.phpR~hj5<@.vendor/hoa/compiler/Exception/IllegalToken.php R~hj EW 'vendor/hoa/compiler/Exception/Lexer.phpR~hj1vendor/hoa/compiler/Exception/UnexpectedToken.phpR~hj/+vendor/hoa/compiler/Exception/Exception.php R~hj ?3vendor/hoa/compiler/Exception/UnrecognizedToken.php R~hj wؤ=vendor/hoa/compiler/Exception/FinalStateHasNotBeenReached.phpR~hjbsϤvendor/hoa/compiler/Ll1.php`kR~hj`k[&vendor/hoa/compiler/Llk/Rule/Token.php=R~hj=i/'vendor/hoa/compiler/Llk/Rule/Choice.phpeR~hjeOᙤ%vendor/hoa/compiler/Llk/Rule/Rule.php"R~hj"hg7+vendor/hoa/compiler/Llk/Rule/Invocation.phpLR~hjLᙤ+vendor/hoa/compiler/Llk/Rule/Repetition.php R~hj T1&&vendor/hoa/compiler/Llk/Rule/Entry.phphR~hjh+ͤ)vendor/hoa/compiler/Llk/Rule/Analyzer.php"4R~hj"4xF.vendor/hoa/compiler/Llk/Rule/Concatenation.phpzR~hjz_oP&vendor/hoa/compiler/Llk/Rule/Ekzit.phpoR~hjoV|vendor/hoa/compiler/Llk/Llk.pp R~hj Gr5vendor/hoa/compiler/Llk/Sampler/BoundedExhaustive.php&R~hj&Uo+vendor/hoa/compiler/Llk/Sampler/Uniform.php"R~hj",vendor/hoa/compiler/Llk/Sampler/Coverage.php{FR~hj{FCC+vendor/hoa/compiler/Llk/Sampler/Sampler.phpR~hjk<*-vendor/hoa/compiler/Llk/Sampler/Exception.phpR~hjk"vendor/hoa/compiler/Llk/Parser.php QR~hj QJ(!vendor/hoa/compiler/Llk/Lexer.phpR~hj|O$vendor/hoa/compiler/Llk/TreeNode.phpR~hjIC\ۤvendor/hoa/compiler/Llk/Llk.php.R~hj.&vendor/hoa/math/Context.php R~hj J/vendor/hoa/math/Util.phpYR~hjYc] -vendor/hoa/math/Combinatorics/Permutation.phpR~hjsY7*vendor/hoa/math/Combinatorics/Counting.phpR~hjsY7+vendor/hoa/math/Combinatorics/FiniteSet.phpR~hjsY7>vendor/hoa/math/Combinatorics/Combination/CartesianProduct.phpR~hj3vendor/hoa/math/Combinatorics/Combination/Gamma.php?R~hj?ʤ9vendor/hoa/math/Combinatorics/Combination/Combination.php R~hj  K-vendor/hoa/math/Combinatorics/Arrangement.phpR~hjsY7vendor/hoa/math/Bin/Calc.phpR~hj&~"vendor/hoa/math/Sampler/Random.php R~hj P%#vendor/hoa/math/Sampler/Sampler.php!R~hj!M&vendor/hoa/math/Visitor/Arithmetic.phpG'R~hjG'-}ڤ-vendor/hoa/math/Exception/UnknownFunction.phpR~hj䒤-vendor/hoa/math/Exception/UnknownVariable.phpR~hj*-vendor/hoa/math/Exception/UnknownConstant.phpR~hjq4vendor/hoa/math/Exception/AlreadyDefinedConstant.phpR~hj='vendor/hoa/math/Exception/Exception.phpR~hj vendor/hoa/math/Arithmetic.pp R~hj ٤vendor/hoa/file/File.php%R~hj%W vendor/hoa/file/Link/Link.phpRR~hjRM"vendor/hoa/file/Link/ReadWrite.php"R~hj"ͤvendor/hoa/file/Link/Read.phpPR~hjPX<6vendor/hoa/file/Link/Write.phpR~hjGvendor/hoa/file/Finder.php%DR~hj%Dސvendor/hoa/file/Watcher.phpR~hjċvvendor/hoa/file/PATCHES.txtR~hj)'vendor/hoa/file/Temporary/ReadWrite.php"R~hj"'vendor/hoa/file/Temporary/Temporary.phpR~hj09"vendor/hoa/file/Temporary/Read.phpmR~hjm3#vendor/hoa/file/Temporary/Write.phpR~hjF6vendor/hoa/file/SplFileInfo.php R~hj RKvendor/hoa/file/Directory.phpR~hjVvendor/hoa/file/ReadWrite.php"R~hj".vendor/hoa/file/Exception/FileDoesNotExist.phpR~hjKi'vendor/hoa/file/Exception/Exception.phpR~hjU墕vendor/hoa/file/Read.phpAR~hjA$vendor/hoa/file/Generic.php44R~hj44W\/vendor/hoa/file/Write.phpR~hj0M vendor/hoa/iterator/Iterator.phpR~hj"%vendor/hoa/iterator/Demultiplexer.phpR~hj: + vendor/hoa/iterator/Seekable.phpqR~hjqפ&vendor/hoa/iterator/CallbackFilter.php~R~hj~L vendor/hoa/iterator/Multiple.php R~hj  !vendor/hoa/iterator/Lookahead.phpqR~hjq_"vendor/hoa/iterator/Lookbehind.php4R~hj4*4vendor/hoa/iterator/Filter.phpgR~hjgiһ vendor/hoa/iterator/Infinite.phpfR~hjf*vendor/hoa/iterator/Limit.phpZR~hjZ!x#vendor/hoa/iterator/PATCHES.txtR~hj2vendor/hoa/iterator/Map.phpVR~hjVw#vendor/hoa/iterator/SplFileInfo.phphR~hjholvendor/hoa/iterator/Counter.phpR~hj6՟)vendor/hoa/iterator/CallbackGenerator.php R~hj 6H9vendor/hoa/iterator/Buffer.phpR~hjMtʤ!vendor/hoa/iterator/Directory.phpR~hj~!vendor/hoa/iterator/Aggregate.phpvR~hjvˤ vendor/hoa/iterator/NoRewind.phpfR~hjf7Z/}*vendor/hoa/iterator/Recursive/Iterator.phpR~hjs0vendor/hoa/iterator/Recursive/CallbackFilter.phpR~hj(vendor/hoa/iterator/Recursive/Filter.phpR~hj҅%vendor/hoa/iterator/Recursive/Map.php|R~hj|PX:+vendor/hoa/iterator/Recursive/Directory.phpR~hj6FY+vendor/hoa/iterator/Recursive/Recursive.phpR~hjZr 3vendor/hoa/iterator/Recursive/RegularExpression.phpR~hjlֲ&vendor/hoa/iterator/Recursive/Mock.phpoR~hjow!vendor/hoa/iterator/Exception.phpR~hj>Tvendor/hoa/iterator/Glob.phpVR~hjVǻ vendor/hoa/iterator/Repeater.php5R~hj5qvendor/hoa/iterator/Append.php^R~hj^{F)vendor/hoa/iterator/RegularExpression.php!R~hj!^Iuvendor/hoa/iterator/Mock.phpXR~hjX|!"vendor/hoa/iterator/FileSystem.php R~hj vendor/hoa/iterator/Outer.phpfR~hjf񽲤(vendor/hoa/iterator/IteratorIterator.phpvR~hjviÃ#vendor/hoa/stream/Context.phpeR~hjelp)vendor/hoa/stream/Filter/LateComputed.phpcR~hjc4G#vendor/hoa/stream/Filter/Filter.phpR~hjY&:&vendor/hoa/stream/Filter/Exception.phpR~hj"vendor/hoa/stream/Filter/Basic.phpR~hjxvendor/hoa/stream/Bucket.phpR~hjevendor/hoa/stream/PATCHES.txtR~hjaQvendor/hoa/stream/Composite.php R~hj ¯~vendor/hoa/stream/Exception.phpR~hje3vendor/hoa/stream/Stream.phpAR~hjA](vendor/hoa/stream/IStream/Structural.phpR~hjq~'vendor/hoa/stream/IStream/Pointable.php R~hj gq!vendor/hoa/stream/IStream/Out.php R~hj ǟΤ'vendor/hoa/stream/IStream/Touchable.phpR~hj-6&vendor/hoa/stream/IStream/Pathable.phpsR~hjsI7 vendor/hoa/stream/IStream/In.phpnR~hjnT (vendor/hoa/stream/IStream/Bufferable.php R~hj Yq&vendor/hoa/stream/IStream/Lockable.phph R~hjh $vendor/hoa/stream/IStream/Stream.phpR~hjg&vendor/hoa/stream/IStream/Statable.php R~hj i%vendor/hoa/stream/Wrapper/Wrapper.phpR~hjLQ+vendor/hoa/stream/Wrapper/IWrapper/File.phpR~hj݉=/vendor/hoa/stream/Wrapper/IWrapper/IWrapper.phpR~hj?-vendor/hoa/stream/Wrapper/IWrapper/Stream.php0(R~hj0(_S'vendor/hoa/stream/Wrapper/Exception.phpR~hjXevendor/hoa/protocol/Wrapper.php&FR~hj&F[ ZC$vendor/hoa/protocol/Node/Library.php R~hj 7!vendor/hoa/protocol/Node/Node.php&R~hj&zvendor/hoa/protocol/PATCHES.txtR~hjP#vendor/hoa/protocol/Bin/Resolve.phpR~hjAM vendor/hoa/protocol/Protocol.phpR~hjH!vendor/hoa/protocol/Exception.phpR~hj6\vendor/hoa/event/Event.phpR~hjGṳvendor/hoa/event/Listener.phpR~hjݤvendor/hoa/event/Bucket.phpD R~hjD 4u*vendor/hoa/event/Listens.php R~hj #vvendor/hoa/event/Listenable.phpR~hjGOvendor/hoa/event/Exception.phpR~hj=vendor/hoa/event/Source.php_R~hj_vendor/hoa/ustring/Ustring.phpeR~hje -vendor/hoa/ustring/Documentation/En/Index.xylhR~hjhv-vendor/hoa/ustring/Documentation/Fr/Index.xylEnR~hjEnFp!vendor/hoa/ustring/Bin/Tocode.php R~hj #vendor/hoa/ustring/Bin/Fromcode.php R~hj ;m vendor/hoa/ustring/Exception.phpR~hjPRvendor/hoa/ustring/Search.php R~hj  vendor/hoa/exception/Error.phpH R~hjH *b&vendor/hoa/exception/Idle.phpR~hj= vendor/hoa/exception/PATCHES.txtR~hj`on"vendor/hoa/exception/Exception.phpO R~hjO vendor/hoa/exception/Group.phpZR~hjZf$6vendor/psr/http-message/src/ServerRequestInterface.php'R~hj' (/vendor/psr/http-message/src/StreamInterface.phpR~hj<1vendor/psr/http-message/src/ResponseInterface.phpU R~hjU FSj5vendor/psr/http-message/src/UploadedFileInterface.phppR~hjp+0vendor/psr/http-message/src/MessageInterface.phpRR~hjR"10vendor/psr/http-message/src/RequestInterface.php R~hj ;B",vendor/psr/http-message/src/UriInterface.php1R~hj1?mvendor/psr/http-message/LICENSE=R~hj=/vendor/psr/container/src/ContainerInterface.php"R~hj"@'7vendor/psr/container/src/NotFoundExceptionInterface.phpR~hj8vendor/psr/container/src/ContainerExceptionInterface.phpR~hj+Ivendor/psr/container/LICENSEyR~hjyOp/vendor/psr/log/src/InvalidArgumentException.phpsR~hjs&^M+vendor/psr/log/src/LoggerAwareInterface.php<R~hj<+4L"vendor/psr/log/src/LoggerTrait.phpLR~hjL.L'vendor/psr/log/src/LoggerAwareTrait.phpR~hjtvendor/psr/log/src/LogLevel.phpLR~hjLX%vendor/psr/log/src/AbstractLogger.phpR~hj1.&vendor/psr/log/src/LoggerInterface.php R~hj !vendor/psr/log/src/NullLogger.phpR~hjۤvendor/psr/log/LICENSE=R~hj=pO7vendor/nikic/php-parser/lib/PhpParser/Builder/Enum_.phpg R~hjg koä>vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.phpR~hj8vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php{R~hj{a,;#:vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php/R~hj/G6vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.phpR~hjixL<vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php R~hj w8vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.phpR~hj6ۤ<vendor/nikic/php-parser/lib/PhpParser/Builder/ClassConst.phpR~hjż0Dvendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.phpbR~hjba:vendor/nikic/php-parser/lib/PhpParser/Builder/EnumCase.php.R~hj.(=vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.phpR~hj?{;vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php1R~hj1(jL:vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php<R~hj<L8vendor/nikic/php-parser/lib/PhpParser/Builder/Class_.phpR~hj<vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php%R~hj%7vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php[R~hj[\P58vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.phpR~hj ?vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.phpR~hj 6vendor/nikic/php-parser/lib/PhpParser/NodeAbstract.php~R~hj~[W{>vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php#R~hj#*tY 9vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.phpR~hj'>;;vendor/nikic/php-parser/lib/PhpParser/Internal/DiffElem.php/R~hj/Lvendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.phpzR~hjz56Z7vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php'R~hj'kBvendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.phpR~hj!<vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.phpR~hjħJ7vendor/nikic/php-parser/lib/PhpParser/Node/MatchArm.phpR~hjj,q;vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.phpR~hj,O3vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.phpR~hjEt13vendor/nikic/php-parser/lib/PhpParser/Node/Expr.phpR~hj:=vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.phpYR~hjY28Evendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/File.php@R~hj@g¤Gvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Method.phpFR~hjF3Gvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Trait_.phpDR~hjDCJvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Function_.phpMR~hjMfAEvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Line.php@R~hj@&Q&Gvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Class_.phpDR~hjD+0 Dvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Dir.php=R~hj=)GKvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Namespace_.phpPR~hjPt@vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.phpSR~hjSix=vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/DNumber.phpR~hj^T=vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.phpi R~hji 1Hvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.phpR~hj՝>vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.phpR~hjd3vendor/nikic/php-parser/lib/PhpParser/Node/Name.phpR~hjV5Bvendor/nikic/php-parser/lib/PhpParser/Node/VariadicPlaceholder.phpR~hjE 5vendor/nikic/php-parser/lib/PhpParser/Node/Const_.phpR~hj<Ѥ9vendor/nikic/php-parser/lib/PhpParser/Node/Identifier.phpR~hjm{8vendor/nikic/php-parser/lib/PhpParser/Node/UnionType.phpR~hj8vendor/nikic/php-parser/lib/PhpParser/Node/Attribute.php@R~hj@`@vendor/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php R~hj T.:vendor/nikic/php-parser/lib/PhpParser/Node/ComplexType.phpCR~hjC y=vendor/nikic/php-parser/lib/PhpParser/Node/AttributeGroup.phpR~hjUPR9vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Enum_.phpBR~hjB~Ȥ;vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.phpR~hj¤<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php*R~hj* >vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.phpR~hji=vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.phpR~hj$Uq?vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.phpxR~hjx59vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.phpR~hjyh>vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.phpR~hj+[:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.phpeR~hje#><vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.phpR~hjQM8vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php\R~hj\,:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.phpR~hjc%=vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.phpR~hjU:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.phpR~hj7vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php0R~hj0cL >vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.phpR~hjxRBvendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.phpR~hjץ1:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.phpR~hjp/>vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php R~hj GU7vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php2R~hj2?9vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.phpR~hj+9vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.phpR~hjwC<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.phpR~hj!9vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php\R~hj\XEuFvendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php R~hj !<Qvendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.phpJR~hjJ:`Lvendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php1R~hj1Q9:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.phpR~hjF=eL<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/EnumCase.phpR~hj_:Ǥ:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.phpaR~hja957vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php*R~hj*<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.phpR~hjYƤ9vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.phpR~hjci:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php5R~hj5^?<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.phpwR~hjw ,;vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php9R~hj9t=vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php R~hj ܄h<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php_R~hj_h<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Property.php R~hj / :vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.phprR~hjrŠ;vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.phpR~hjJ}@vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.phpR~hj )=vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php R~hj >7;vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php%R~hj%ߩ'8vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php.R~hj.cW>vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.phpR~hjFHod:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.phpR~hj Dvendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.phpR~hjn;vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.phpR~hj:;vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.phpR~hj{Avendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.phpR~hjDG;vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php~R~hj~4Q:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php(R~hj(93'>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.phpR~hj l Avendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayDimFetch.php>R~hj>08vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php1R~hj1k;vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php R~hj lפ:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php{R~hj{Y=vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.phpiR~hjinTGvendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.phpR~hjM Avendor/nikic/php-parser/lib/PhpParser/Node/Expr/ErrorSuppress.phpR~hjj77:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Match_.phpR~hjx ,9vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.phpR~hj2:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php{R~hj{Gvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanAnd.phpAR~hjA(@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Div.php2R~hj2̒_@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Pow.php3R~hj39VFvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php@R~hj@.?Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftLeft.php?R~hj?эFvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanOr.php?R~hj? 72Dvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Greater.php:R~hj:Ivendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotIdentical.phpFR~hjF1Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Spaceship.php@R~hj@Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalOr.php?R~hj?d;xBvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Minus.php6R~hj6߉Dvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php:R~hj:KEvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Coalesce.php=R~hj=:Gvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftRight.phpAR~hjArL0Avendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Plus.php4R~hj4~i1Bvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Equal.php7R~hj7(Kvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.phpIR~hjIKCvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Concat.php8R~hj8"ɼGvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalAnd.phpBR~hjBاGvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalXor.phpBR~hjBGp@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mod.php2R~hj21Evendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotEqual.php=R~hj=5p6Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseOr.php>R~hj>Η0Kvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.phpIR~hjI#tGvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseXor.php@R~hj@ݞ@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mul.php2R~hj2iaGvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php@R~hj@LK >vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.phpR~hj+28:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Throw_.phpR~hjճŤAvendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.phph R~hjh Ll^Ť:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.phpR~hjix<vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.phpR~hj@ˤ8vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.phpxR~hjxP9vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.phpR~hj<vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.phpR~hj%6`;vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php~R~hj~J@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Div.phpR~hjc@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Pow.phpR~hj|Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftLeft.phpR~hjwúBvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Minus.phpR~hjUEvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Coalesce.phpR~hjQGvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftRight.phpR~hj7FAvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Plus.phpR~hj BCvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Concat.phpR~hj@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mod.phpR~hjǒ߿Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseOr.phpR~hj.Gvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseXor.phpR~hj( f@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mul.phpR~hjU#`ɤGvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.phpR~hjx>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.phpJR~hjJIvendor/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafePropertyFetch.phpR~hjĤ<vendor/nikic/php-parser/lib/PhpParser/Node/Expr/CallLike.phpR~hjp Ф:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.phpR~hj =:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php{R~hj{Ly0:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.phpNR~hjNoP?vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.phpR~hj8)J]>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Bool_.phpR~hjd?vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Unset_.phpR~hj@@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Object_.phpR~hj`̤=vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Int_.phpR~hjo=@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/String_.phpR~hjm3?vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Double.phpR~hjkO#ͤ9vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.phpR~hj*I<vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php_R~hj_4A=vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.phpR~hji$>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.phpR~hj$>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.phpR~hj9Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafeMethodCall.phpSR~hjS3ͤ>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php<R~hj<89vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php{R~hj{~=vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignRef.php8R~hj8)=vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.phpR~hj'(=vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.phpR~hjg;vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.phpR~hjH:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php~R~hj~۵Cvendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClassConstFetch.phpR~hjAʤ<vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php0R~hj0,fS>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.phpwR~hjwp5vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.phpsR~hjsuQ4vendor/nikic/php-parser/lib/PhpParser/Node/Param.phpsR~hjsbN2vendor/nikic/php-parser/lib/PhpParser/Node/Arg.php9R~hj9[?vendor/nikic/php-parser/lib/PhpParser/Node/IntersectionType.phpR~hjaD5vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.phphR~hjhy6vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php2R~hj2L/vendor/nikic/php-parser/lib/PhpParser/Error.phpR~hj%b&7vendor/nikic/php-parser/lib/PhpParser/Parser/Tokens.phpR~hjy\9vendor/nikic/php-parser/lib/PhpParser/Parser/Multiple.phpR~hjFR5vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.phpTR~hjTH5vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php+R~hj+PĤFvendor/nikic/php-parser/lib/PhpParser/ConstExprEvaluationException.phpWR~hjW "?vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.phpnR~hjnZAMAvendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Collecting.php|R~hj|8vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php,R~hj,O@vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.phpR~hjJ5vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.phpD R~hjD CD8vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php%R~hj%M͔=vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.phpR~hj8@vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.phpӤR~hjӤw5vendor/nikic/php-parser/lib/PhpParser/NodeVisitor.phpR~hjY0vendor/nikic/php-parser/lib/PhpParser/Parser.phpR~hjC2Ӥ4vendor/nikic/php-parser/lib/PhpParser/NodeFinder.php R~hj v/vendor/nikic/php-parser/lib/PhpParser/Lexer.php&[R~hj&[N<Dvendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CloningVisitor.phpR~hj!FMvendor/nikic/php-parser/lib/PhpParser/NodeVisitor/ParentConnectingVisitor.php]R~hj] Ivendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.phpR~hj+Bvendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php&R~hj&6Dvendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.phplR~hjl=*Kvendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NodeConnectingVisitor.phptR~hjtkڤ<vendor/nikic/php-parser/lib/PhpParser/ConstExprEvaluator.phpv%R~hjv%Svendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.phpR~hjx,[vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.phpR~hjpXSvendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.phpR~hjvendor/fidry/cpu-core-counter/src/Executor/ProcessExecutor.phpR~hjbWW>vendor/fidry/cpu-core-counter/src/Finder/NullCpuCoreFinder.phpR~hj'b~M?vendor/fidry/cpu-core-counter/src/Finder/WmicPhysicalFinder.phpR~hj`T|>vendor/fidry/cpu-core-counter/src/Finder/_NProcessorFinder.phpR~hj&oIvendor/fidry/cpu-core-counter/src/Finder/WindowsRegistryLogicalFinder.phpxR~hjx:2<vendor/fidry/cpu-core-counter/src/Finder/HwLogicalFinder.phpvR~hjv@vendor/fidry/cpu-core-counter/src/Finder/ProcOpenBasedFinder.php R~hj q1Dvendor/fidry/cpu-core-counter/src/Finder/CmiCmdletPhysicalFinder.phpR~hjAvendor/fidry/cpu-core-counter/src/Finder/SkipOnOSFamilyFinder.phpR~hjCvendor/fidry/cpu-core-counter/src/Finder/CmiCmdletLogicalFinder.phpR~hjz>vendor/fidry/cpu-core-counter/src/Finder/WmicLogicalFinder.phpR~hjr :vendor/fidry/cpu-core-counter/src/Finder/CpuCoreFinder.php R~hj 셋@vendor/fidry/cpu-core-counter/src/Finder/LscpuPhysicalFinder.phpxR~hjxL>vendor/fidry/cpu-core-counter/src/Finder/EnvVariableFinder.phpR~hj:/jCvendor/fidry/cpu-core-counter/src/Finder/OnlyInPowerShellFinder.phpR~hjJuWAvendor/fidry/cpu-core-counter/src/Finder/OnlyOnOSFamilyFinder.phpR~hj#P(;vendor/fidry/cpu-core-counter/src/Finder/FinderRegistry.phpR~hji]?vendor/fidry/cpu-core-counter/src/Finder/DummyCpuCoreFinder.phpAR~hjAJ[?H=vendor/fidry/cpu-core-counter/src/Finder/NProcessorFinder.phpR~hj29:vendor/fidry/cpu-core-counter/src/Finder/CpuInfoFinder.php R~hj Vv=vendor/fidry/cpu-core-counter/src/Finder/HwPhysicalFinder.phpzR~hjzgФ?vendor/fidry/cpu-core-counter/src/Finder/LscpuLogicalFinder.phpMR~hjM8vendor/fidry/cpu-core-counter/src/Finder/NProcFinder.phpR~hjS=vendor/fidry/cpu-core-counter/src/NumberOfCpuCoreNotFound.php$R~hj$sX;vendor/fidry/cpu-core-counter/src/ParallelisationResult.phpR~hj./vendor/fidry/cpu-core-counter/src/Diagnoser.php{R~hj{RC;vendor/fig/http-message-util/src/RequestMethodInterface.phpR~hjTw8vendor/fig/http-message-util/src/StatusCodeInterface.phpyR~hjyY;$vendor/fig/http-message-util/LICENSE=R~hj=? vendor/symfony/finder/Finder.phpXR~hjX{&#vendor/symfony/finder/Gitignore.php% R~hj% @_%vendor/symfony/finder/SplFileInfo.php,R~hj,vendor/symfony/finder/LICENSE,R~hj,U9vendor/symfony/finder/Exception/AccessDeniedException.phpR~hj|yy>vendor/symfony/finder/Exception/DirectoryNotFoundException.phpR~hjTܤvendor/symfony/finder/Glob.phpJR~hjJ螤;vendor/symfony/finder/Iterator/DepthRangeFilterIterator.phpR~hj7<vendor/symfony/finder/Iterator/FilecontentFilterIterator.phpR~hjJ:vendor/symfony/finder/Iterator/SizeRangeFilterIterator.phpR~hjFA=vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.phpR~hj)5Avendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php R~hj Q:vendor/symfony/finder/Iterator/DateRangeFilterIterator.phpR~hjz9vendor/symfony/finder/Iterator/FileTypeFilterIterator.phpR~hj@=vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php R~hj "5vendor/symfony/finder/Iterator/PathFilterIterator.phpR~hj63vendor/symfony/finder/Iterator/SortableIterator.phpjR~hjj8;vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.phpR~hjU/vendor/symfony/finder/Iterator/LazyIterator.phpR~hj79vendor/symfony/finder/Iterator/FilenameFilterIterator.phpR~hjP)7vendor/symfony/finder/Iterator/CustomFilterIterator.php3R~hj3uq5vendor/symfony/finder/Comparator/NumberComparator.php R~hj vk/vendor/symfony/finder/Comparator/Comparator.php R~hj o{3vendor/symfony/finder/Comparator/DateComparator.phpR~hjӇɤ'vendor/symfony/polyfill-php81/Php81.phpR~hj$%vendor/symfony/polyfill-php81/LICENSE,R~hj,0+vendor/symfony/polyfill-php81/bootstrap.phpR~hj<P@vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.phpR~hjJTFvendor/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.phpR~hj5+=vendor/symfony/service-contracts/ServiceProviderInterface.phpR~hj.8vendor/symfony/service-contracts/ServiceLocatorTrait.php R~hj ޤ;vendor/symfony/service-contracts/ServiceSubscriberTrait.phpR~hj4<?vendor/symfony/service-contracts/ServiceSubscriberInterface.phpR~hjyʤ3vendor/symfony/service-contracts/ResetInterface.phpR~hj^6(vendor/symfony/service-contracts/LICENSE,R~hj,@vendor/symfony/service-contracts/Attribute/SubscribedService.php:R~hj:57vendor/symfony/service-contracts/Attribute/Required.phpR~hj\D'vendor/symfony/polyfill-php73/Php73.phpbR~hjbJ<%vendor/symfony/polyfill-php73/LICENSE,R~hj,+vendor/symfony/polyfill-php73/bootstrap.phpR~hj|?vendor/symfony/polyfill-php73/Resources/stubs/JsonException.phpER~hjE8S-vendor/symfony/polyfill-ctype/bootstrap80.phphR~hjhˤ'vendor/symfony/polyfill-ctype/Ctype.phpR~hj{5%vendor/symfony/polyfill-ctype/LICENSE,R~hj,+vendor/symfony/polyfill-ctype/bootstrap.php,R~hj,i'ޤ(vendor/symfony/string/AbstractString.phpOR~hjOR$'vendor/symfony/string/UnicodeString.php2R~hj2 $vendor/symfony/string/LazyString.phprR~hjr6I)vendor/symfony/string/CodePointString.phpR~hj/nɤ/vendor/symfony/string/AbstractUnicodeString.phpaiR~hjaiuAǤvendor/symfony/string/LICENSE,R~hj,զ_Ϥ3vendor/symfony/string/Inflector/FrenchInflector.php$R~hj$-{4vendor/symfony/string/Inflector/EnglishInflector.phpBR~hjBzIݤ6vendor/symfony/string/Inflector/InflectorInterface.phpVR~hjV2vendor/symfony/string/Slugger/SluggerInterface.phpR~hjev.vendor/symfony/string/Slugger/AsciiSlugger.php3R~hj3EN#$vendor/symfony/string/ByteString.php<R~hj< <vendor/symfony/string/Exception/InvalidArgumentException.phpR~hjH&6vendor/symfony/string/Exception/ExceptionInterface.phpcR~hjcm4vendor/symfony/string/Exception/RuntimeException.phpR~hj-n-vendor/symfony/string/Resources/functions.phppR~hjp=<vendor/symfony/string/Resources/data/wcswidth_table_wide.phpR~hje<vendor/symfony/string/Resources/data/wcswidth_table_zero.phpR~hjKĭ%vendor/symfony/process/PhpProcess.php R~hj EѤ'vendor/symfony/process/ProcessUtils.php\R~hj\N1 &vendor/symfony/process/InputStream.php R~hj u-+vendor/symfony/process/ExecutableFinder.php R~hj ^"vendor/symfony/process/Process.phpR~hj)Dvendor/symfony/process/LICENSE,R~hj,U.vendor/symfony/process/PhpExecutableFinder.phpa R~hja )-vendor/symfony/process/Pipes/WindowsPipes.phpoR~hjodgؤ.vendor/symfony/process/Pipes/AbstractPipes.phpR~hjr^/vendor/symfony/process/Pipes/PipesInterface.phpR~hjyH,*vendor/symfony/process/Pipes/UnixPipes.phpR~hjh=vendor/symfony/process/Exception/InvalidArgumentException.phpR~hjP13vendor/symfony/process/Exception/LogicException.phpR~hjw-7vendor/symfony/process/Exception/ExceptionInterface.phpR~hj}i=vendor/symfony/process/Exception/ProcessSignaledException.phpR~hjx ;vendor/symfony/process/Exception/ProcessFailedException.phpIR~hjI:=vendor/symfony/process/Exception/ProcessTimedOutException.php|R~hj|V5vendor/symfony/process/Exception/RuntimeException.phpR~hj',~'vendor/symfony/polyfill-php74/Php74.php R~hj AV܀%vendor/symfony/polyfill-php74/LICENSE,R~hj,զ_Ϥ+vendor/symfony/polyfill-php74/bootstrap.php%R~hj% 1vendor/symfony/deprecation-contracts/function.php2R~hj2p<,vendor/symfony/deprecation-contracts/LICENSE,R~hj, K*vendor/symfony/polyfill-php80/PhpToken.phpR~hj]f'vendor/symfony/polyfill-php80/Php80.php R~hj cH%vendor/symfony/polyfill-php80/LICENSE,R~hj, K+vendor/symfony/polyfill-php80/bootstrap.phpR~hj.Ĥ:vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.phpwR~hjw=7T8<vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php>R~hj>gEvendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.phpGR~hjGֈ+;vendor/symfony/polyfill-php80/Resources/stubs/Attribute.phpR~hjMK<<vendor/symfony/polyfill-php80/Resources/stubs/Stringable.phpR~hjt]\ڤ-vendor/symfony/polyfill-mbstring/Mbstring.phpJR~hjJŮ0vendor/symfony/polyfill-mbstring/bootstrap80.php'R~hj'L#\M(vendor/symfony/polyfill-mbstring/LICENSE,R~hj,H.vendor/symfony/polyfill-mbstring/bootstrap.php!R~hj!dFvendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php9R~hj9>|zKBvendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.phpa R~hja |ⳤ@vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php_R~hj_d@vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.phpfR~hjfP7vendor/symfony/polyfill-intl-normalizer/bootstrap80.phpR~hj,/vendor/symfony/polyfill-intl-normalizer/LICENSE,R~hj,H5vendor/symfony/polyfill-intl-normalizer/bootstrap.phpR~hj#p 6vendor/symfony/polyfill-intl-normalizer/Normalizer.phpd%R~hjd%uFvendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.phpR~hj%Rvendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalComposition.phpDR~hjD'CԤTvendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php{R~hj{jeXvendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.phpoR~hjoc,Lvendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.phpD5R~hjD5 8vendor/symfony/console/Formatter/NullOutputFormatter.phpoR~hjoOq*Fvendor/symfony/console/Formatter/WrappableOutputFormatterInterface.phpR~hjь=vendor/symfony/console/Formatter/NullOutputFormatterStyle.phpR~hjF ֤=vendor/symfony/console/Formatter/OutputFormatterInterface.phpDR~hjD\jBvendor/symfony/console/Formatter/OutputFormatterStyleInterface.phpiR~hjiy>vendor/symfony/console/Formatter/OutputFormatterStyleStack.php+ R~hj+ $٤9vendor/symfony/console/Formatter/OutputFormatterStyle.php R~hj nĤ4vendor/symfony/console/Formatter/OutputFormatter.php R~hj πäDvendor/symfony/console/DependencyInjection/AddConsoleCommandPass.phpR~hj3%/vendor/symfony/console/Logger/ConsoleLogger.phpR~hj2vendor/symfony/console/Question/ChoiceQuestion.phpR~hj)̤8vendor/symfony/console/Question/ConfirmationQuestion.php)R~hj)@ m,vendor/symfony/console/Question/Question.php~R~hj~Ĥ(vendor/symfony/console/ConsoleEvents.phpR~hj覤2vendor/symfony/console/CI/GithubActionReporter.php# R~hj# &ڴm=vendor/symfony/console/CommandLoader/FactoryCommandLoader.phpeR~hje.?vendor/symfony/console/CommandLoader/CommandLoaderInterface.phpR~hj7?vendor/symfony/console/CommandLoader/ContainerCommandLoader.phpR~hj,,vendor/symfony/console/Input/StringInput.php R~hj .k9vendor/symfony/console/Input/StreamableInputInterface.phpzR~hjz0vendor/symfony/console/Input/InputDefinition.phpT.R~hjT.~,vendor/symfony/console/Input/InputOption.php`R~hj`,hw+vendor/symfony/console/Input/ArrayInput.phpR~hj@Ť/vendor/symfony/console/Input/InputInterface.phpR~hjZ.vendor/symfony/console/Input/InputArgument.php R~hj U 4vendor/symfony/console/Input/InputAwareInterface.phpLR~hjLI &vendor/symfony/console/Input/Input.php=R~hj=H*vendor/symfony/console/Input/ArgvInput.php0R~hj0XV vendor/symfony/console/Color.phpZR~hjZ}8vendor/symfony/console/SignalRegistry/SignalRegistry.phpDR~hjD* Ĥ=vendor/symfony/console/Command/SignalableCommandInterface.phpR~hjA{8vendor/symfony/console/Command/DumpCompletionCommand.phpR~hjmb+2vendor/symfony/console/Command/CompleteCommand.php R~hj e^*vendor/symfony/console/Command/Command.phpPR~hjPrﮤ.vendor/symfony/console/Command/LazyCommand.phpFR~hjF0vendor/symfony/console/Command/LockableTrait.php$R~hj$L%l.vendor/symfony/console/Command/ListCommand.php R~hj .vendor/symfony/console/Command/HelpCommand.php R~hj |̜V&vendor/symfony/console/Application.phpR~hj{<3vendor/symfony/console/SingleCommandApplication.php9R~hj91 6vendor/symfony/console/EventListener/ErrorListener.php^ R~hj^ f(vendor/symfony/console/Helper/Dumper.phpXR~hjX o 1vendor/symfony/console/Helper/HelperInterface.php^R~hj^?oa'vendor/symfony/console/Helper/Table.phpsR~hjsZ_0vendor/symfony/console/Helper/QuestionHelper.phpLR~hjL0vendor/symfony/console/Helper/TableSeparator.php%R~hj%΍657vendor/symfony/console/Helper/SymfonyQuestionHelper.phpG R~hjG ֤+vendor/symfony/console/Helper/TableCell.phpR~hjmƕ6vendor/symfony/console/Helper/DebugFormatterHelper.php\ R~hj\ $Ȥ/vendor/symfony/console/Helper/ProcessHelper.phpR~hj3vendor/symfony/console/Helper/ProgressIndicator.phpR~hjB+vendor/symfony/console/Helper/HelperSet.phpE R~hjE kV,vendor/symfony/console/Helper/TableStyle.php0R~hj0ﯤ(vendor/symfony/console/Helper/Helper.phpR~hjK$ߤ-vendor/symfony/console/Helper/ProgressBar.phpOHR~hjOHRm2vendor/symfony/console/Helper/InputAwareHelper.php!R~hj!+vendor/symfony/console/Helper/TableRows.phpVR~hjV|1vendor/symfony/console/Helper/FormatterHelper.php R~hj ˿c2vendor/symfony/console/Helper/DescriptorHelper.php R~hj >I|0vendor/symfony/console/Helper/TableCellStyle.phpdR~hjdV5vendor/symfony/console/Completion/CompletionInput.php[ R~hj[ 360vendor/symfony/console/Completion/Suggestion.phpR~hjEh@;vendor/symfony/console/Completion/CompletionSuggestions.phpnR~hjn9Avendor/symfony/console/Completion/Output/BashCompletionOutput.phpR~hj,ͤFvendor/symfony/console/Completion/Output/CompletionOutputInterface.phpR~hj&Wk09vendor/symfony/console/Descriptor/DescriptorInterface.phpQR~hjQ+Ф3vendor/symfony/console/Descriptor/XmlDescriptor.php.'R~hj.'(8vendor/symfony/console/Descriptor/MarkdownDescriptor.phpkR~hjkr4vendor/symfony/console/Descriptor/JsonDescriptor.phpR~hjP<vendor/symfony/console/Descriptor/ApplicationDescription.php%R~hj%P)0vendor/symfony/console/Descriptor/Descriptor.php R~hj  4vendor/symfony/console/Descriptor/TextDescriptor.php2R~hj29^)vendor/symfony/console/LICENSE,R~hj,U!vendor/symfony/console/Cursor.php?R~hj?:w=vendor/symfony/console/Exception/InvalidArgumentException.phpR~hjTؤ=vendor/symfony/console/Exception/CommandNotFoundException.phpR~hjפ?vendor/symfony/console/Exception/NamespaceNotFoundException.phpR~hjh:vendor/symfony/console/Exception/MissingInputException.phpR~hj"=3vendor/symfony/console/Exception/LogicException.phpR~hj?uƤ7vendor/symfony/console/Exception/ExceptionInterface.phpR~hj;vendor/symfony/console/Exception/InvalidOptionException.phpR~hj}a*#5vendor/symfony/console/Exception/RuntimeException.phpR~hjȨm@vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.phpR~hj T9vendor/symfony/console/Tester/CommandCompletionTester.phpLR~hjLͪ3vendor/symfony/console/Tester/ApplicationTester.php R~hj "-vendor/symfony/console/Tester/TesterTrait.phpR~hjTҤ/vendor/symfony/console/Tester/CommandTester.phpJ R~hjJ 5vendor/symfony/console/Output/TrimmedBufferOutput.phpoR~hjoi/vendor/symfony/console/Output/ConsoleOutput.php)R~hj)40vendor/symfony/console/Output/BufferedOutput.phpcR~hjc+,vendor/symfony/console/Output/NullOutput.php8 R~hj8 r1vendor/symfony/console/Output/OutputInterface.phpt R~hjt (-8vendor/symfony/console/Output/ConsoleOutputInterface.php1R~hj1DGߤ(vendor/symfony/console/Output/Output.phpgR~hjgh6vendor/symfony/console/Output/ConsoleSectionOutput.phpR~hj=].vendor/symfony/console/Output/StreamOutput.phpR~hjSw".vendor/symfony/console/Attribute/AsCommand.phpNR~hjN6@#vendor/symfony/console/Terminal.phpmR~hjmHlu4vendor/symfony/console/Resources/bin/hiddeninput.exe$R~hj$v0vendor/symfony/console/Resources/completion.bash R~hj z(3vendor/symfony/console/Event/ConsoleSignalEvent.phpR~hj*4ؤ6vendor/symfony/console/Event/ConsoleTerminateEvent.phpjR~hjjÒ}-vendor/symfony/console/Event/ConsoleEvent.phpR~hjV!2vendor/symfony/console/Event/ConsoleErrorEvent.php"R~hj"M%4vendor/symfony/console/Event/ConsoleCommandEvent.php=R~hj=k},vendor/symfony/console/Style/OutputStyle.phpL R~hjL >-vendor/symfony/console/Style/SymfonyStyle.php9R~hj9˩Ӥ/vendor/symfony/console/Style/StyleInterface.phpR R~hjR :r5vendor/symfony/polyfill-intl-grapheme/bootstrap80.phpg R~hjg E{2vendor/symfony/polyfill-intl-grapheme/Grapheme.php8&R~hj8&I-vendor/symfony/polyfill-intl-grapheme/LICENSE,R~hj,H3vendor/symfony/polyfill-intl-grapheme/bootstrap.phpR~hj|\Countable ? true : false) */ function is_countable(mixed $value): bool { } /** * @return ($value is object ? true : false) */ function is_object(mixed $value): bool { } /** * @return ($value is scalar ? true : false) */ function is_scalar(mixed $value): bool { } /** * @return ($value is int ? true : false) */ function is_int(mixed $value): bool { } /** * @return ($value is int ? true : false) */ function is_integer(mixed $value): bool { } /** * @return ($value is int ? true : false) */ function is_long(mixed $value): bool { } /** * @phpstan-assert-if-true =resource $value * @return bool */ function is_resource(mixed $value): bool { } /** * @return ($value is array ? true : false) */ function is_array(mixed $value): bool { } /** * @return ($value is iterable ? true : false) */ function is_iterable(mixed $value): bool { } * @template-implements SeekableIterator * @template-implements ArrayAccess */ class SplObjectStorage implements Countable, Iterator, SeekableIterator, Serializable, ArrayAccess { /** * @param \SplObjectStorage $storage */ public function addAll(SplObjectStorage $storage): void { } /** * @param TObject $object * @param TData $data */ public function attach(object $object, $data = null): void { } /** * @param TObject $object */ public function contains(object $object): bool { } /** * @param TObject $object */ public function detach(object $object): void { } /** * @param TObject $object */ public function getHash(object $object): string { } /** * @return TData */ public function getInfo() { } /** * @param \SplObjectStorage<*, *> $storage */ public function removeAll(SplObjectStorage $storage): void { } /** * @param \SplObjectStorage<*, *> $storage */ public function removeAllExcept(SplObjectStorage $storage): void { } /** * @param TData $data */ public function setInfo($data): void { } /** * @param TObject $offset * @return TData */ public function offsetGet($offset); } */ public function getName() : string { } /** * @return T */ public function newInstance() : object { } } */ interface Collection extends IteratorAggregate, Countable, JsonSerializable { /** * @return static */ public function copy(); /** * @return array */ public function toArray(): array; } /** * @template TValue * @implements Sequence */ final class Deque implements Sequence { /** * @param iterable $values */ public function __construct(iterable $values = []) { } /** * @return Deque */ public function copy() { } /** * @template TValue2 * @param iterable $values * @return Deque */ public function merge(iterable $values): Deque { } /** * @param (callable(TValue): bool)|null $callback * @return Deque */ public function filter(?callable $callback = null): Deque { } /** * @template TNewValue * @param callable(TValue): TNewValue $callback * @return Deque */ public function map(callable $callback): Deque { } /** * @return Deque */ public function reversed(): Deque { } /** * @return Deque */ public function slice(int $offset, ?int $length = null): Deque { } } /** * @template TKey * @template TValue * @implements Collection * @implements ArrayAccess */ final class Map implements Collection, ArrayAccess { /** * @param iterable $values */ public function __construct(iterable $values = []) { } /** * @return Map */ public function copy(): Map { } /** * @param callable(TKey, TValue): TValue $callback * @return void */ public function apply(callable $callback) { } /** * @return Pair * @throws UnderflowException */ public function first(): Pair { } /** * @return Pair * @throws UnderflowException */ public function last(): Pair { } /** * @return Pair * @throws OutOfRangeException */ public function skip(int $position): Pair { } /** * @template TKey2 * @template TValue2 * @param iterable $values * @return Map */ public function merge(iterable $values): Map { } /** * @template TKey2 * @template TValue2 * @param Map $map * @return Map */ public function intersect(Map $map): Map { } /** * @template TValue2 * @param Map $map * @return Map */ public function diff(Map $map): Map { } /** * @param TKey $key */ public function hasKey($key): bool { } /** * @param TValue $value */ public function hasValue($value): bool { } /** * @param (callable(TKey, TValue): bool)|null $callback * @return Map */ public function filter(?callable $callback = null): Map { } /** * @template TDefault * @param TKey $key * @param TDefault $default * @return TValue|TDefault * @throws OutOfBoundsException */ public function get($key, $default = null) { } /** * @return Set */ public function keys(): Set { } /** * @template TNewValue * @param callable(TKey, TValue): TNewValue $callback * @return Map */ public function map(callable $callback): Map { } /** * @return Sequence> */ public function pairs(): Sequence { } /** * @param TKey $key * @param TValue $value * @return void */ public function put($key, $value) { } /** * @param iterable $values * @return void */ public function putAll(iterable $values) { } /** * @template TCarry * @param callable(TCarry, TKey, TValue): TCarry $callback * @param TCarry $initial * @return TCarry */ public function reduce(callable $callback, $initial = null) { } /** * @template TDefault * @param TKey $key * @param TDefault $default * @return TValue|TDefault * @throws \OutOfBoundsException */ public function remove($key, $default = null) { } /** * @return Map */ public function reversed(): Map { } /** * @return Map */ public function slice(int $offset, ?int $length = null): Map { } /** * @param (callable(TValue, TValue): int)|null $comparator * @return void */ public function sort(?callable $comparator = null) { } /** * @param (callable(TValue, TValue): int)|null $comparator * @return Map */ public function sorted(?callable $comparator = null): Map { } /** * @param (callable(TKey, TKey): int)|null $comparator * @return void */ public function ksort(?callable $comparator = null) { } /** * @param (callable(TKey, TKey): int)|null $comparator * @return Map */ public function ksorted(?callable $comparator = null): Map { } /** * @return array */ public function toArray(): array { } /** * @return Sequence */ public function values(): Sequence { } /** * @template TKey2 * @template TValue2 * @param Map $map * @return Map */ public function union(Map $map): Map { } /** * @template TKey2 * @template TValue2 * @param Map $map * @return Map */ public function xor(Map $map): Map { } } /** * @template-covariant TKey * @template-covariant TValue */ final class Pair implements JsonSerializable { /** * @var TKey */ public $key; /** * @var TValue */ public $value; /** * @param TKey $key * @param TValue $value */ public function __construct($key = null, $value = null) { } /** * @return Pair */ public function copy(): Pair { } } /** * @template TValue * @extends Collection * @extends ArrayAccess */ interface Sequence extends Collection, ArrayAccess { /** * @param callable(TValue): TValue $callback * @return void */ public function apply(callable $callback); /** * @param TValue ...$values */ public function contains(...$values): bool; /** * @param (callable(TValue): bool)|null $callback * @return Sequence */ public function filter(?callable $callback = null); /** * @param TValue $value * @return int|false */ public function find($value); /** * @return TValue * @throws \UnderflowException */ public function first(); /** * @return TValue * @throws \OutOfRangeException */ public function get(int $index); /** * @param TValue ...$values * @throws \OutOfRangeException * @return void */ public function insert(int $index, ...$values); /** * @param string $glue * @return string */ public function join(?string $glue = null): string; /** * @return TValue * @throws \UnderflowException */ public function last(); /** * @template TNewValue * @param callable(TValue): TNewValue $callback * @return Sequence */ public function map(callable $callback); /** * @template TValue2 * @param iterable $values * @return Sequence */ public function merge(iterable $values); /** * @return TValue * @throws \UnderflowException * @phpstan-impure */ public function pop(); /** * @param TValue ...$values * @return void */ public function push(...$values); /** * @template TCarry * @param callable(TCarry, TValue): TCarry $callback * @param TCarry $initial * @return TCarry */ public function reduce(callable $callback, $initial = null); /** * @return TValue * @throws \OutOfRangeException */ public function remove(int $index); /** * @return Sequence */ public function reversed(); /** * @param TValue $value * @throws \OutOfRangeException * @return void */ public function set(int $index, $value); /** * @return TValue * @throws \UnderflowException * @phpstan-impure */ public function shift(); /** * @return Sequence */ public function slice(int $index, ?int $length = null); /** * @param (callable(TValue, TValue): int)|null $comparator * @return void */ public function sort(?callable $comparator = null); /** * @param (callable(TValue, TValue): int)|null $comparator * @return Sequence */ public function sorted(?callable $comparator = null); /** * @param TValue ...$values * @return void */ public function unshift(...$values); } /** * @template TValue * @implements Sequence */ final class Vector implements Sequence { /** * @param iterable $values */ public function __construct(iterable $values = []) { } /** * @return Vector */ public function copy() { } /** * @return Vector */ public function reversed(): Vector { } /** * @return Vector */ public function slice(int $offset, ?int $length = null): Vector { } /** * @param (callable(TValue, TValue): int)|null $comparator * @return Vector */ public function sorted(?callable $comparator = null): Vector { } /** * @param (callable(TValue): bool)|null $callback * @return Vector */ public function filter(?callable $callback = null): Vector { } /** * @template TNewValue * @param callable(TValue): TNewValue $callback * @return Vector */ public function map(callable $callback): Vector { } /** * @template TValue2 * @param iterable $values * @return Vector */ public function merge(iterable $values): Vector { } } /** * @template TValue * @implements Collection * @implements ArrayAccess */ final class Set implements Collection, ArrayAccess { /** * @param iterable $values */ public function __construct(iterable $values = []) { } /** * @param TValue ...$values */ public function add(...$values): void { } /** * @param TValue ...$values */ public function contains(...$values): bool { } /** * @return Set */ public function copy(): Set { } /** * @template TValue2 * @param Set $set * @return Set */ public function diff(Set $set): Set { } /** * @param (callable(TValue): bool)|null $callback * @return Set */ public function filter(?callable $callback = null): Set { } /** * @return TValue * @throws \UnderflowException */ public function first() { } /** * @return TValue * @throws \OutOfRangeException */ public function get(int $index) { } /** * @template TValue2 * @param Set $set * @return Set */ public function intersect(Set $set): Set { } /** * @return TValue * @throws \UnderflowException */ public function last() { } /** * @template TNewValue * @param callable(TValue): TNewValue $callback * @return Set */ public function map(callable $callback): Set { } /** * @template TValue2 * @param iterable $values * @return Set */ public function merge(iterable $values): Set { } /** * @template TCarry * @param callable(TCarry, TValue): TCarry $callback * @param TCarry $initial * @return TCarry */ public function reduce(callable $callback, $initial = null) { } /** * @param TValue ...$values */ public function remove(...$values): void { } /** * @return Set */ public function reversed(): Set { } /** * @return Set */ public function slice(int $index, ?int $length = null): Set { } /** * @param (callable(TValue, TValue): int)|null $comparator */ public function sort(?callable $comparator = null): void { } /** * @param (callable(TValue, TValue): int)|null $comparator * @return Set */ public function sorted(?callable $comparator = null): Set { } /** * @return list */ public function toArray(): array { } /** * @template TValue2 * @param Set $set * @return Set */ public function union(Set $set): Set { } /** * @template TValue2 * @param Set $set * @return Set */ public function xor(Set $set): Set { } } /** * @template TValue * @implements Collection * @implements ArrayAccess */ final class Stack implements Collection, ArrayAccess { /** * @param iterable $values */ public function __construct(iterable $values = []) { } /** * @return Stack */ public function copy(): Stack { } /** * @return TValue * @throws UnderflowException */ public function peek() { } /** * @return TValue * @throws UnderflowException * @phpstan-impure */ public function pop() { } /** * @param TValue ...$values * @return void */ public function push(...$values): void { } /** * @return list */ public function toArray(): array { } } /** * @template TValue * @implements Collection * @implements ArrayAccess */ final class Queue implements Collection, ArrayAccess { /** * @param iterable $values */ public function __construct(iterable $values = []) { } /** * @return Queue */ public function copy(): Queue { } /** * @return TValue * @throws UnderflowException */ public function peek() { } /** * @return TValue * @throws UnderflowException * @phpstan-impure */ public function pop() { } /** * @param TValue ...$values */ public function push(...$values): void { } /** * @return list */ public function toArray(): array { } } /** * @template TValue * @implements Collection */ final class PriorityQueue implements Collection { /** * @return PriorityQueue */ public function copy(): PriorityQueue { } /** * @return TValue * @throws UnderflowException */ public function peek() { } /** * @return TValue * @throws UnderflowException * @phpstan-impure */ public function pop() { } /** * @param TValue $value */ public function push($value, int $priority): void { } /** * @return list */ public function toArray(): array { } } |numeric-string */ public $affected_rows; } class mysqli_result { /** * @var int<0,max>|numeric-string */ public $num_rows; /** * @template T of object * @param class-string $class * @param array $constructor_args * @return T|null|false */ function fetch_object(string $class = 'stdClass', array $constructor_args = []) {} } /** * @template T of object * * @param class-string $class * @param array $constructor_args * @return T|null|false */ function mysqli_fetch_object(mysqli_result $result, string $class = 'stdClass', array $constructor_args = []) {} class mysqli_stmt { /** * @var int<-1,max>|numeric-string */ public $affected_rows; /** * @var int */ public $errno; /** * @var list */ public $error_list; /** * @var string */ public $error; /** * @var 0|positive-int */ public $field_count; /** * @var int|string */ public $insert_id; /** * @var int<0,max>|numeric-string */ public $num_rows; /** * @var 0|positive-int */ public $param_count; /** * @var non-empty-string */ public $sqlstate; } */ public static function create(object $referent): WeakReference {} /** @return ?T */ public function get() {} } /** * @template TKey of object * @template TValue * @implements \ArrayAccess * @implements \IteratorAggregate */ final class WeakMap implements \ArrayAccess, \Countable, \IteratorAggregate { /** * @param TKey $offset * @return TValue */ public function offsetGet($offset) {} } $result * @param-out array|string> $result */ function parse_str(string $string, array &$result): void {} /** * @param array $result * @param-out array|string> $result */ function mb_parse_str(string $string, array &$result): bool {} /** @param-out float $percent */ function similar_text(string $string1, string $string2, ?float &$percent = null) : int {} /** * @param mixed $output * @param mixed $result_code * * @param-out list $output * @param-out int $result_code * * @return string|false */ function exec(string $command, &$output, &$result_code) {} /** * @param mixed $result_code * @param-out int $result_code * * @return string|false */ function system(string $command, &$result_code) {} /** * @param mixed $result_code * @param-out int $result_code */ function passthru(string $command, &$result_code): ?bool {} /** * @template T * @template TArray as array * * @param TArray $array */ function shuffle(array &$array): bool { } /** * @template T * @template TArray as array * * @param TArray $array */ function sort(array &$array, int $flags = SORT_REGULAR): bool { } /** * @template T * @template TArray as array * * @param TArray $array */ function rsort(array &$array, int $flags = SORT_REGULAR): bool { } /** * @param string $string * @param-out null $string */ function sodium_memzero(string &$string): void { } /** * @param resource $stream * @param mixed $vars * @param-out string|int|float|null $vars * * @return list|int|false */ function fscanf($stream, string $format, &...$vars) {} /** * @param mixed $war * @param mixed $vars * @param-out string|int|float|null $war * @param-out string|int|float|null $vars * * @return int|array|null */ function sscanf(string $string, string $format, &$war, &...$vars) {} /** * @template TFlags as int * * @param string $pattern * @param string $subject * @param mixed $matches * @param TFlags $flags * @param-out ( * TFlags is 1 * ? array> * : (TFlags is 2 * ? list> * : (TFlags is 256|257 * ? array> * : (TFlags is 258 * ? list> * : (TFlags is 512|513 * ? array> * : (TFlags is 514 * ? list> * : (TFlags is 770 * ? list> * : (TFlags is 0 ? array> : array) * ) * ) * ) * ) * ) * ) * ) $matches * @return int|false */ function preg_match_all($pattern, $subject, &$matches = [], int $flags = 1, int $offset = 0) {} /** * @template TFlags as int-mask<0, 256, 512> * * @param string $pattern * @param string $subject * @param mixed $matches * @param TFlags $flags * @param-out ( * TFlags is 256 * ? array * : (TFlags is 512 * ? array * : (TFlags is 768 * ? array * : array * ) * ) * ) $matches * @return 1|0|false */ function preg_match($pattern, $subject, &$matches = [], int $flags = 0, int $offset = 0) {} /** * @param string|array $pattern * @param callable(array):string $callback * @param string|array $subject * @param int $count * @param-out 0|positive-int $count * @return ($subject is array ? list|null : string|null) */ function preg_replace_callback($pattern, $callback, $subject, int $limit = -1, &$count = null, int $flags = 0) {} /** * @param string|array $pattern * @param string|array $replacement * @param string|array $subject * @param int $count * @param-out 0|positive-int $count * @return ($subject is array ? list|null : string|null) */ function preg_replace($pattern, $replacement, $subject, int $limit = -1, &$count = null) {} /** * @param string|array $pattern * @param string|array $replacement * @param string|array $subject * @param int $count * @param-out 0|positive-int $count * @return ($subject is array ? list : string|null) */ function preg_filter($pattern, $replacement, $subject, int $limit = -1, &$count = null) {} /** * @param array|string $search * @param array|string $replace * @param array|string $subject * @param-out int $count * @return list|string */ function str_replace($search, $replace, $subject, ?int &$count = null) {} /** * @param array|string $search * @param array|string $replace * @param array|string $subject * @param-out int $count * @return list|string */ function str_ireplace($search, $replace, $subject, ?int &$count = null) {} /** * @template TRead of null|array * @template TWrite of null|array * @template TExcept of null|array * @param TRead $read * @param TWrite $write * @param TExcept $except * @return false|0|positive-int * @param-out (TRead is null ? null : array) $read * @param-out (TWrite is null ? null : array) $write * @param-out (TExcept is null ? null : array) $except */ function stream_select(?array &$read, ?array &$write, ?array &$except, ?int $seconds, ?int $microseconds = null) {} /** * @param resource $stream * @param-out 0|1 $would_block */ function flock($stream, int $operation, mixed &$would_block = null): bool {} /** * @param-out int $error_code * @param-out string $error_message * @return resource|false */ function fsockopen(string $hostname, int $port = -1, ?int &$error_code = null, ?string &$error_message = null, ?float $timeout = null) {} /** * @param-out string $filename * @param-out int $line */ function headers_sent(?string &$filename = null, ?int &$line = null): bool {} /** * @param-out callable-string $callable_name * @return ($value is callable ? true : false) */ function is_callable(mixed $value, bool $syntax_only = false, ?string &$callable_name = null): bool {} /** * @param float|int $num * @return ($num is float ? float : $num is int ? non-negative-int : float|non-negative-int) */ function abs($num) {} /** * @return ($categorize is true ? array> : array) */ function get_defined_constants(bool $categorize = false): array {} */ public $name; /** * @param T|class-string $argument * @throws ReflectionException */ public function __construct($argument) {} /** * @return class-string */ public function getName() : string; /** * @param mixed ...$args * * @return T */ public function newInstance(...$args) {} /** * @param array $args * * @return T */ public function newInstanceArgs(array $args) {} /** * @return T */ public function newInstanceWithoutConstructor(); /** * @return list> */ public function getAttributes(?string $name = null, int $flags = 0) { } } */ public function getNodeType(): string; /** * @param TNodeType $node * @return list */ public function processNode(Node $node, Scope $scope): array; } */ public function getElementsByTagName ($name) {} /** * @param string $namespaceURI * @param string $localName * @return DOMNodeList */ public function getElementsByTagNameNS ($namespaceURI, $localName) {} } class DOMNode { } class DOMElement extends DOMNode { /** @var DOMDocument */ public $ownerDocument; /** * @param string $name * @return DOMNodeList */ public function getElementsByTagName ($name) {} /** * @param string $namespaceURI * @param string $localName * @return DOMNodeList */ public function getElementsByTagNameNS ($namespaceURI, $localName) {} } /** * @template-covariant TNode as DOMNode * @implements Traversable * @implements IteratorAggregate */ class DOMNodeList implements Traversable, IteratorAggregate, Countable { /** * @param int $index * @return TNode|null */ public function item ($index) {} } class DOMXPath { /** * @param string $expression * @param DOMNode|null $contextNode * @param boolean $registerNodeNS * @return DOMNodeList|false */ public function query($expression, $contextNode, $registerNodeNS) {} } class DOMAttr { /** @var DOMDocument */ public $ownerDocument; } class DOMCharacterData { /** @var DOMDocument */ public $ownerDocument; } class DOMDocumentType { /** @var DOMDocument */ public $ownerDocument; } class DOMEntity { /** @var DOMDocument */ public $ownerDocument; } class DOMNotation { /** @var DOMDocument */ public $ownerDocument; } class DOMProcessingInstruction { /** @var DOMDocument */ public $ownerDocument; /** * @var string */ public $target; /** * @var string */ public $data; } /** * @property-read int $length */ class DOMNamedNodeMap { } class DOMText { /** @var string */ public $wholeText; } |null &$read * @param array|null &$write * @param array|null &$except * @param-out ($read is not null ? array : null) $read * @param-out ($write is not null ? array : null) $write * @param-out ($except is not null ? array : null) $except * @return int|false */ function socket_select(?array &$read, ?array &$write, ?array &$except, ?int $seconds, int $microseconds = 0) {} > */ public function getAttributes(?string $name = null, int $flags = 0) { } } > */ public function getAttributes(?string $name = null, int $flags = 0) { } } * @implements \ArrayAccess */ class SplDoublyLinkedList implements \Iterator, \ArrayAccess { /** * @param int $index * @param TValue $newval * @return void */ public function add($index, $newval) {} /** * @return TValue */ public function pop () {} /** * @return TValue */ public function shift () {} /** * @param TValue $value * @return void */ public function push ($value) {} /** * @param TValue $value * @return void */ public function unshift ($value) {} /** * @return TValue */ public function top () {} /** * @return TValue */ public function bottom () {} /** * @param int $offset * @return TValue */ public function offsetGet ($offset) {} } /** * @template TValue * @extends \SplDoublyLinkedList */ class SplQueue extends \SplDoublyLinkedList { /** * @param TValue $value * @return void */ public function enqueue ($value) {} /** * @return TValue */ public function dequeue () {} } /** * @template TPriority * @template TValue * * @implements \Iterator */ class SplPriorityQueue implements \Iterator { /** * @param TPriority $priority1 * @param TPriority $priority2 * @return int */ public function compare ($priority1, $priority2) {} /** * @param TValue $value * @param TPriority $priority * @return true */ public function insert ($value, $priority) {} /** * @return TPriority|TValue|array{priority: TPriority, data: TValue} */ public function top () {} /** * @return TPriority|TValue|array{priority: TPriority, data: TValue} */ public function extract () {} /** * @return TPriority|TValue|array{priority: TPriority, data: TValue} */ public function current () {} } > * @implements IteratorAggregate> * @link https://php.net/manual/en/class.pdostatement.php */ class PDOStatement implements Traversable, IteratorAggregate { /** * @template T of object * @param class-string $class * @param array $ctorArgs * @return false|T */ public function fetchObject($class = \stdClass::class, array $ctorArgs = array()) {} /** * @return array{name: string, table?: string, native_type?: string, len: int, flags: array, precision: int<0, max>, pdo_type: PDO::PARAM_* }|false */ public function getColumnMeta(int $column) {} } , g: int<0, 255>, b: int<0, 255>, a: int<0, 1>} : ($normalized is 1 ? array{r: float, g: float, b: float, a: float} : ($normalized is 2 ? array{r: int<0, 255>, g: int<0, 255>, b: int<0, 255>, a: int<0, 255>} : array{}))) */ public function getColor(int $normalized = 0): array; } * @implements ArrayAccess */ class ArrayObject implements IteratorAggregate, ArrayAccess { /** * @param array|object $input * @param int $flags * @param class-string $iterator_class */ public function __construct($input = null, $flags = 0, $iterator_class = "ArrayIterator") { } /** * @param TValue $value * @return void */ public function append($value) { } /** * @return array */ public function getArrayCopy() { } /** * @param callable(TValue, TValue): int $cmp_function * @return void */ public function uasort($cmp_function) { } /** * @param callable(TKey, TKey): int $cmp_function * @return void */ public function uksort($cmp_function) { } /** * @return ArrayIterator */ public function getIterator() { } /** * @param class-string $iterator_class * @return void */ public function setIteratorClass($iterator_class) { } } /** * @template TValue * @implements Iterator * @implements IteratorAggregate * @implements ArrayAccess */ class SplFixedArray implements Iterator, IteratorAggregate, ArrayAccess, Countable { /** * @template TInput * @param array $array * @return SplFixedArray */ public static function fromArray(array $array, bool $save_indexes = true): SplFixedArray { } /** * @return array */ public function toArray(): array { } } |null &$read * @param array|null &$write * @param array|null &$except * @param-out ($read is not null ? array : null) $read * @param-out ($write is not null ? array : null) $write * @param-out ($except is not null ? array : null) $except */ function socket_select(?array &$read, ?array &$write, ?array &$except, ?int $seconds, int $microseconds = 0): int|false {} $flags * @phpstan-assert-if-true =non-empty-string $json */ function json_validate(string $json, int $depth = 512, int $flags = 0): bool { } */ interface IteratorAggregate extends Traversable { /** * @return Traversable */ public function getIterator(); } /** * @template-covariant TKey * @template-covariant TValue * * @extends Traversable */ interface Iterator extends Traversable { /** * @return TValue */ public function current(); /** * @return TKey */ public function key(); } /** * @template-covariant TKey * @template-covariant TValue * * @extends Iterator */ interface RecursiveIterator extends Iterator { } /** * @template-covariant TKey * @template-covariant TValue * @template TSend * @template-covariant TReturn * * @implements Iterator */ class Generator implements Iterator { /** * @return TReturn */ public function getReturn() {} /** * @param TSend $value * @return TValue */ public function send($value) {} } /** * @implements Traversable * @implements ArrayAccess * @implements Iterator * @implements RecursiveIterator */ class SimpleXMLElement implements Traversable, ArrayAccess, Iterator, RecursiveIterator { /** * @return ($filename is null ? string|false : bool) */ public function asXML(?string $filename = null) { } /** * @return ($filename is null ? string|false : bool) */ public function saveXML(?string $filename = null) { } } /** * @template-covariant TKey * @template-covariant TValue * @extends Iterator */ interface SeekableIterator extends Iterator { } /** * @template TKey of array-key * @template TValue * @implements SeekableIterator * @implements ArrayAccess */ class ArrayIterator implements SeekableIterator, ArrayAccess, Countable { /** * @param array $array * @param int $flags */ public function __construct($array = array(), $flags = 0) { } /** * @param TValue $value * @return void */ public function append($value) { } /** * @return array */ public function getArrayCopy() { } /** * @param callable(TValue, TValue): int $cmp_function * @return void */ public function uasort($cmp_function) { } /** * @param callable(TKey, TKey): int $cmp_function * @return void */ public function uksort($cmp_function) { } } /** * @template T of \RecursiveIterator|\IteratorAggregate * @mixin T */ class RecursiveIteratorIterator { /** * @param T $iterator */ public function __construct( $iterator, int $mode = RecursiveIteratorIterator::LEAVES_ONLY, int $flags = 0 ) { } } /** * @template-covariant TKey * @template-covariant TValue * * @template-extends Iterator */ interface OuterIterator extends Iterator { /** * @return Iterator */ public function getInnerIterator(); } /** * @template-covariant TKey * @template-covariant TValue * @template TIterator as Traversable * * @template-implements OuterIterator * * @mixin TIterator */ class IteratorIterator implements OuterIterator { /** * @param TIterator $iterator */ public function __construct(Traversable $iterator) {} } /** * @template-covariant TKey * @template-covariant TValue * @template TIterator as Traversable * * @template-extends IteratorIterator */ class FilterIterator extends IteratorIterator { } /** * @template-covariant TKey * @template-covariant TValue * @template TIterator as Traversable * * @extends FilterIterator */ class CallbackFilterIterator extends FilterIterator { } /** * @template-covariant TKey * @template-covariant TValue * @template TIterator as Traversable * * @extends CallbackFilterIterator * @implements RecursiveIterator */ class RecursiveCallbackFilterIterator extends CallbackFilterIterator implements RecursiveIterator { /** * @return bool */ public function hasChildren() {} /** * @return RecursiveCallbackFilterIterator */ public function getChildren() {} } /** * @template TKey of array-key * @template TValue * * @template-implements RecursiveIterator * @template-extends ArrayIterator */ class RecursiveArrayIterator extends ArrayIterator implements RecursiveIterator { /** * @return RecursiveArrayIterator */ public function getChildren() {} /** * @return bool */ public function hasChildren() {} /** * @return TValue */ public function current() {} /** * @return TKey */ public function key() {} /** * @param callable(TKey, TKey): int $cmp_function * @return void */ public function uksort($cmp_function) { } } /** * @template TKey * @template TValue * @template TIterator as Iterator * * @template-extends IteratorIterator */ class AppendIterator extends IteratorIterator { /** * @param TIterator $iterator * @return void */ public function append(Iterator $iterator) {} /** * @return ArrayIterator */ public function getArrayIterator() {} } /** * @template-covariant TKey * @template-covariant TValue * @template TIterator as Iterator * * @template-extends IteratorIterator */ class NoRewindIterator extends IteratorIterator { /** * @param TIterator $iterator */ public function __construct(Iterator $iterator) {} /** * @return TValue */ public function current() {} /** * @return TKey */ public function key() {} } /** * @template-covariant TKey * @template-covariant TValue * @template TIterator as Iterator * * @template-implements OuterIterator * @template-extends IteratorIterator */ class LimitIterator extends IteratorIterator implements OuterIterator { /** * @param TIterator $iterator */ public function __construct(Iterator $iterator, int $offset = 0, int $count = -1) {} /** * @return TValue */ public function current() {} /** * @return TKey */ public function key() {} } /** * @template-covariant TKey * @template-covariant TValue * @template TIterator as Iterator * * @template-extends IteratorIterator */ class InfiniteIterator extends IteratorIterator { /** * @param TIterator $iterator */ public function __construct(Iterator $iterator) {} /** * @return TValue */ public function current() {} /** * @return TKey */ public function key() {} } /** * @template TKey * @template TValue * @template TIterator as Iterator * * @template-implements OuterIterator * @template-implements ArrayAccess * * @template-extends IteratorIterator */ class CachingIterator extends IteratorIterator implements OuterIterator, ArrayAccess, Countable { const CALL_TOSTRING = 1 ; const CATCH_GET_CHILD = 16 ; const TOSTRING_USE_KEY = 2 ; const TOSTRING_USE_CURRENT = 4 ; const TOSTRING_USE_INNER = 8 ; const FULL_CACHE = 256 ; /** * @param TIterator $iterator * @param int-mask-of $flags */ public function __construct(Iterator $iterator, int $flags = self::CALL_TOSTRING) {} /** * @return TValue */ public function current() {} /** * @return TKey */ public function key() {} /** * @return array */ public function getCache() {} } /** * @template TKey * @template TValue * @template TIterator of Traversable * * @template-extends FilterIterator */ class RegexIterator extends FilterIterator { const MATCH = 0 ; const GET_MATCH = 1 ; const ALL_MATCHES = 2 ; const SPLIT = 3 ; const REPLACE = 4 ; const USE_KEY = 1 ; /** * @param Iterator $iterator * @param self::MATCH|self::GET_MATCH|self::ALL_MATCHES|self::SPLIT|self::REPLACE $mode */ public function __construct(Iterator $iterator, string $regex, int $mode = self::MATCH, int $flags = 0, int $preg_flags = 0) {} /** * @return TValue */ public function current() {} /** * @return TKey */ public function key() {} } /** * @template-implements Iterator */ class EmptyIterator implements Iterator { /** * @return never */ public function current() {} /** * @return never */ public function key() {} /** * @return false */ public function valid() {} } * @implements \Traversable */ class DatePeriod implements \IteratorAggregate, \Traversable { /** * @return TEnd */ public function getEndDate() { } /** * @return TRecurrences */ public function getRecurrences() { } /** * @return TDate */ public function getStartDate(): DateTimeInterface { } } */ class ReflectionEnum extends ReflectionClass { /** * @return (T is BackedEnum ? ReflectionEnumBackedCase[] : ReflectionEnumUnitCase[]) */ public function getCases(): array {} /** * @return (T is BackedEnum ? ReflectionEnumBackedCase : ReflectionEnumUnitCase) * @throws ReflectionException */ public function getCase(string $name): ReflectionEnumUnitCase {} /** * @phpstan-assert-if-true self $this * @phpstan-assert-if-true !null $this->getBackingType() */ public function isBacked(): bool {} } > */ public function getAttributes(?string $name = null, int $flags = 0) { } } ',args?:mixed[],object?:object}> * @throws void */ public function getTrace(); /** * @return string * @throws void */ public function getTraceAsString(); /** * @return null|Throwable * @throws void */ public function getPrevious(); /** * @return string */ public function __toString(); } class Exception implements Throwable { /** * @return string * @throws void */ final public function getMessage(): string {} /** * @return mixed * @throws void */ final public function getCode() {} /** * @return string * @throws void */ final public function getFile(): string {} /** * @return int * @throws void */ final public function getLine(): int {} /** * @return list',args?:mixed[],object?:object}> * @throws void */ final public function getTrace(): array {} /** * @return null|Throwable * @throws void */ final public function getPrevious(): ?Throwable {} /** * @return string * @throws void */ final public function getTraceAsString(): string {} } class Error implements Throwable { /** * @return string * @throws void */ final public function getMessage(): string {} /** * @return mixed * @throws void */ final public function getCode() {} /** * @return string * @throws void */ final public function getFile(): string {} /** * @return int * @throws void */ final public function getLine(): int {} /** * @return list',args?:mixed[],object?:object}> * @throws void */ final public function getTrace(): array {} /** * @return null|Throwable * @throws void */ final public function getPrevious(): ?Throwable {} /** * @return string * @throws void */ final public function getTraceAsString(): string {} } */ public static function cases(): array; } } flags = $flags; } } } if (\PHP_VERSION_ID < 80100 && !class_exists('ReturnTypeWillChange', false)) { #[Attribute(Attribute::TARGET_METHOD)] final class ReturnTypeWillChange { } } if (\PHP_VERSION_ID < 80200 && !class_exists('AllowDynamicProperties', false)) { #[Attribute(Attribute::TARGET_CLASS)] final class AllowDynamicProperties { } } if (\PHP_VERSION_ID < 80200 && !class_exists('SensitiveParameter', false)) { #[Attribute(Attribute::TARGET_PARAMETER)] final class SensitiveParameter { } } $one * @param callable(TReturn, TIn): TReturn $two * @param TReturn $three * * @return TReturn */ function array_reduce( array $one, callable $two, $three = null ) {} /** * @template T of mixed * * @param array $array * @return ($array is non-empty-array ? non-empty-list : list) */ function array_values(array $array): array {} /** * @template TKey as (int|string) * @template T * @template TArray as array * * @param TArray $array * @param callable(T,T):int $callback */ function uasort(array &$array, callable $callback): bool {} /** * @template T * @template TArray as array * * @param TArray $array * @param callable(T,T):int $callback */ function usort(array &$array, callable $callback): bool {} /** * @template TKey as (int|string) * @template T * @template TArray as array * * @param TArray $array * @param callable(TKey,TKey):int $callback */ function uksort(array &$array, callable $callback): bool { } /** * @template TV of mixed * @template TK of mixed * * @param array $one * @param array $two * @param callable(TV, TV): int $three * @return array */ function array_udiff( array $one, array $two, callable $three ): array {} /** * @param array $value * @return ($value is __always-list ? true : false) */ function array_is_list(array $value): bool {} /** * @template TK of array-key * @template TV of mixed * * @param array $one * @param array $two * @param callable(TK, TK): int $three * @return array */ function array_diff_uassoc( array $one, array $two, callable $three ): array {} /** * @template TK of array-key * @template TV of mixed * * @param array $one * @param array $two * @param callable(TK, TK): int $three * @return array */ function array_diff_ukey( array $one, array $two, callable $three ): array {} /** * @template TK of array-key * @template TV of mixed * * @param array $one * @param array $two * @param callable(TK, TK): int $three * @return array */ function array_intersect_uassoc( array $one, array $two, callable $three ): array {} /** * @template TK of array-key * @template TV of mixed * * @param array $one * @param array $two * @param callable(TK, TK): int $three * * @return array */ function array_intersect_ukey( array $one, array $two, callable $three ): array {} /** * @template TK of array-key * @template TV of mixed * * @param array $one * @param array $two * @param callable(TV, TV): int $three * * @return array */ function array_udiff_assoc( array $one, array $two, callable $three ): array {} /** * @template TK of array-key * @template TV of mixed * * @param array $one * @param array $two * @param callable(TV, TV): int $three * @param callable(TK, TK): int $four * @return array */ function array_udiff_uassoc( array $one, array $two, callable $three, callable $four ): array {} /** * @template TK of array-key * @template TV of mixed * * @param array $one * @param array $two * @param callable(TV, TV): int $three * @return array */ function array_uintersect_assoc( array $one, array $two, callable $three, ): array {} /** * @template TK of array-key * @template TV of mixed * * @param array $one * @param array $two * @param callable(TV, TV): int $three * @param callable(TK, TK): int $four * @return array */ function array_uintersect_uassoc( array $one, array $two, callable $three, callable $four ): array {} /** * @template TK of array-key * @template TV of mixed * * @param array $one * @param array $two * @param callable(TV, TV): int $three * @return array */ function array_uintersect( array $one, array $two, callable $three, ): array {} > */ public function getAttributes(?string $name = null, int $flags = 0) { } } unregister(); $composerAutoloadFiles = $GLOBALS['__composer_autoload_files']; if (!\array_key_exists('e88992873b7765f9b5710cab95ba5dd7', $composerAutoloadFiles) || !\array_key_exists('3e76f7f02b41af8cea96018933f6b7e3', $composerAutoloadFiles) || !\array_key_exists('a4a119a56e50fbb293281d9a48007e0e', $composerAutoloadFiles) || !\array_key_exists('0e6d7bf4a5811bfa5cf40c5ccd6fae6a', $composerAutoloadFiles) || !\array_key_exists('e69f7f6ee287b969198c3c9d6777bd38', $composerAutoloadFiles) || !\array_key_exists('0d59ee240a4cd96ddbb4ff164fccea4d', $composerAutoloadFiles) || !\array_key_exists('b686b8e46447868025a15ce5d0cb2634', $composerAutoloadFiles) || !\array_key_exists('8825ede83f2f289127722d4e842cf7e8', $composerAutoloadFiles) || !\array_key_exists('23c18046f52bef3eea034657bafda50f', $composerAutoloadFiles)) { echo "Composer autoloader changed\n"; exit(1); } // empty the global variable so that unprefixed functions from user-space can be loaded $GLOBALS['__composer_autoload_files'] = [ // fix unprefixed Hoa namespace - files already loaded 'e88992873b7765f9b5710cab95ba5dd7' => \true, '3e76f7f02b41af8cea96018933f6b7e3' => \true, // vendor/symfony/polyfill-php80/bootstrap.php 'a4a119a56e50fbb293281d9a48007e0e' => \true, // vendor/symfony/polyfill-mbstring/bootstrap.php '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => \true, // vendor/symfony/polyfill-intl-normalizer/bootstrap.php 'e69f7f6ee287b969198c3c9d6777bd38' => \true, // vendor/symfony/polyfill-php73/bootstrap.php '0d59ee240a4cd96ddbb4ff164fccea4d' => \true, // vendor/symfony/polyfill-php74/bootstrap.php 'b686b8e46447868025a15ce5d0cb2634' => \true, // vendor/symfony/polyfill-intl-grapheme/bootstrap.php '8825ede83f2f289127722d4e842cf7e8' => \true, // vendor/symfony/polyfill-php81/bootstrap.php '23c18046f52bef3eea034657bafda50f' => \true, ]; $autoloaderInWorkingDirectory = $vendorDirectory . '/autoload.php'; $composerAutoloaderProjectPaths = []; /** @var array|false $autoloadFunctionsBefore */ $autoloadFunctionsBefore = \spl_autoload_functions(); if (@\is_file($autoloaderInWorkingDirectory)) { $composerAutoloaderProjectPaths[] = \dirname($autoloaderInWorkingDirectory, 2); require_once $autoloaderInWorkingDirectory; } $path = \dirname(__DIR__, 3) . '/autoload.php'; if (!\extension_loaded('phar')) { if (@\is_file($path)) { $composerAutoloaderProjectPaths[] = \dirname($path, 2); require_once $path; } } else { $pharPath = \Phar::running(\false); if ($pharPath === '') { if (@\is_file($path)) { $composerAutoloaderProjectPaths[] = \dirname($path, 2); require_once $path; } } else { $path = \dirname($pharPath, 3) . '/autoload.php'; if (@\is_file($path)) { $composerAutoloaderProjectPaths[] = \dirname($path, 2); require_once $path; } } } /** @var array|false $autoloadFunctionsAfter */ $autoloadFunctionsAfter = \spl_autoload_functions(); if ($autoloadFunctionsBefore !== \false && $autoloadFunctionsAfter !== \false) { $newAutoloadFunctions = []; foreach ($autoloadFunctionsAfter as $after) { if (\is_array($after) && \count($after) > 0) { if (\is_object($after[0]) && \get_class($after[0]) === \Composer\Autoload\ClassLoader::class) { continue; } if ($after[0] === 'PHPStan\\PharAutoloader') { continue; } } foreach ($autoloadFunctionsBefore as $before) { if ($after === $before) { continue 2; } } $newAutoloadFunctions[] = $after; } $GLOBALS['__phpstanAutoloadFunctions'] = $newAutoloadFunctions; } $devOrPharLoader->register(\true); $application = new \_PHPStan_c2fbb2235\Symfony\Component\Console\Application('PHPStan - PHP Static Analysis Tool', ComposerHelper::getPhpStanVersion()); $application->setDefaultCommand('analyse'); ProgressBar::setFormatDefinition('file_download', ' [%bar%] %percent:3s%% %fileSize%'); $composerAutoloaderProjectPaths = \array_map(function (string $s) : string { return \str_replace(\DIRECTORY_SEPARATOR, '/', $s); }, $composerAutoloaderProjectPaths); $reversedComposerAutoloaderProjectPaths = \array_values(\array_unique(\array_reverse($composerAutoloaderProjectPaths))); $application->add(new AnalyseCommand($reversedComposerAutoloaderProjectPaths, $analysisStartTime)); $application->add(new WorkerCommand($reversedComposerAutoloaderProjectPaths)); $application->add(new ClearResultCacheCommand($reversedComposerAutoloaderProjectPaths)); $application->add(new FixerWorkerCommand($reversedComposerAutoloaderProjectPaths)); $application->add(new DumpParametersCommand($reversedComposerAutoloaderProjectPaths)); $application->add(new DiagnoseCommand($reversedComposerAutoloaderProjectPaths)); $application->run(); })(); [ 'FFI::addr' => ['FFI\CData', 'ptr'=>'FFI\CData'], 'FFI::alignof' => ['int', 'ptr'=>'mixed'], 'FFI::arrayType' => ['FFI\CType', 'type'=>'string|FFI\CType', 'dims'=>'array'], 'FFI::cast' => ['FFI\CData', 'type'=>'string|FFI\CType', 'ptr'=>''], 'FFI::cdef' => ['FFI', 'code='=>'string', 'lib='=>'?string'], 'FFI::free' => ['void', 'ptr'=>'FFI\CData'], 'FFI::load' => ['FFI', 'filename'=>'string'], 'FFI::memcmp' => ['int', 'ptr1'=>'FFI\CData|string', 'ptr2'=>'FFI\CData|string', 'size'=>'int'], 'FFI::memcpy' => ['void', 'dst'=>'FFI\CData', 'src'=>'string|FFI\CData', 'size'=>'int'], 'FFI::memset' => ['void', 'ptr'=>'FFI\CData', 'ch'=>'int', 'size'=>'int'], 'FFI::new' => ['FFI\CData', 'type'=>'string|FFI\CType', 'owned='=>'bool', 'persistent='=>'bool'], 'FFI::scope' => ['FFI', 'scope_name'=>'string'], 'FFI::sizeof' => ['int', 'ptr'=>'FFI\CData|FFI\CType'], 'FFI::string' => ['string', 'ptr'=>'FFI\CData', 'size='=>'int'], 'FFI::typeof' => ['FFI\CType', 'ptr'=>'FFI\CData'], 'FFI::type' => ['FFI\CType', 'type'=>'string'], 'fread' => ['string|false', 'fp'=>'resource', 'length'=>'positive-int'], 'get_mangled_object_vars' => ['array', 'obj'=>'object'], 'mb_str_split' => ['list|false', 'str'=>'string', 'split_length='=>'int', 'encoding='=>'string'], 'password_algos' => ['list'], 'password_needs_rehash' => ['bool', 'hash'=>'string', 'algo'=>'string|null', 'options='=>'array'], 'preg_replace_callback' => ['string|array|null', 'regex'=>'string|array', 'callback'=>'callable(array):string', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int', 'flags='=>'int'], 'preg_replace_callback_array' => ['string|array|null', 'pattern'=>'array', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int', 'flags='=>'int'], 'sapi_windows_set_ctrl_handler' => ['bool', 'callable'=>'callable(int):void', 'add='=>'bool'], 'ReflectionProperty::getType' => ['?ReflectionType'], 'ReflectionProperty::hasType' => ['bool'], 'ReflectionProperty::isInitialized' => ['bool', 'object='=>'?object'], 'ReflectionReference::fromArrayElement' => ['?ReflectionReference', 'array'=>'array', 'key'=>'int|string'], 'ReflectionReference::getId' => ['string'], 'SQLite3Stmt::getSQL' => ['string', 'expanded='=>'bool'], 'strip_tags' => ['string', 'str'=>'string', 'allowable_tags='=>'string|array'], 'WeakReference::create' => ['WeakReference', 'referent'=>'object'], 'WeakReference::get' => ['?object'], 'proc_open' => ['resource|false', 'command'=>'string|list', 'descriptorspec'=>'array', '&w_pipes'=>'resource[]', 'cwd='=>'?string', 'env='=>'?array', 'other_options='=>'array'], ], 'old' => [ 'implode\'2' => ['string', 'pieces'=>'array', 'glue'=>'string'], ], ]; ' => [', ''=>''] * alternative signature for the same function * '' => [', ''=>''] * * A '&' in front of the means the arg is always passed by reference. * (i.e. ReflectionParameter->isPassedByReference()) * This was previously only used in cases where the function actually created the * variable in the local scope. * Some reference arguments will have prefixes in to indicate the way the argument is used. * Currently, the only prefixes with meaning are 'rw_' (read-write) and 'w_' (write). * Those prefixes don't mean anything for non-references. * Code using these signatures should remove those prefixes from messages rendered to the user. * 1. '&rw_' indicates that a parameter with a value is expected to be passed in, and may be modified. * Phan will warn if the variable has an incompatible type, or is undefined. * 2. '&w_' indicates that a parameter is expected to be passed in, and the value will be ignored, and may be overwritten. * 3. The absence of a prefix is treated by Phan the same way as having the prefix 'w_' (Some may be changed to 'rw_name'). These will have prefixes added later. * * So, for functions like sort() where technically the arg is by-ref, * indicate the reference param's signature by-ref and read-write, * as `'&rw_array'=>'array'` * so that Phan won't create it in the local scope * * However, for a function like preg_match() where the 3rd arg is an array of sub-pattern matches (and optional), * this arg needs to be marked as by-ref and write-only, as `'&w_matches='=>'array'`. * * A '=' following the indicates this arg is optional. * * The can begin with '...' to indicate the arg is variadic. * '...args=' indicates it is both variadic and optional. * * Some reference arguments will have prefixes in to indicate the way the argument is used. * Currently, the only prefixes with meaning are 'rw_' and 'w_'. * Code using these signatures should remove those prefixes from messages rendered to the user. * 1. '&rw_name' indicates that a parameter with a value is expected to be passed in, and may be modified. * 2. '&w_name' indicates that a parameter is expected to be passed in, and the value will be ignored, and may be overwritten. * * Sources of stub info: * * 1. Reflection * 2. docs.php.net's SVN repo or website, and examples (See internal/internalsignatures.php) * 3. Various websites documenting individual extensions * 4. PHPStorm stubs (For anything missing from the above sources) * See internal/internalsignatures.php */ return [ '_' => ['string', 'message'=>'string'], 'abs' => ['float|0|positive-int', 'num'=>'int|float'], 'accelerator_get_configuration' => ['array'], 'accelerator_get_scripts' => ['array'], 'accelerator_get_status' => ['array', 'fetch_scripts'=>'bool'], 'accelerator_reset' => [''], 'accelerator_set_status' => ['void', 'status'=>''], 'acos' => ['float', 'number'=>'float'], 'acosh' => ['float', 'number'=>'float'], 'addcslashes' => ['string', 'str'=>'string', 'charlist'=>'string'], 'addslashes' => ['string', 'str'=>'string'], 'AMQPChannel::__construct' => ['void', 'connection'=>'AMQPConnection'], 'AMQPChannel::basicRecover' => ['void', 'requeue='=>'bool'], 'AMQPChannel::commitTransaction' => ['void'], 'AMQPChannel::getChannelId' => ['int<1, 65535>'], 'AMQPChannel::getConnection' => ['AMQPConnection'], 'AMQPChannel::getPrefetchCount' => ['int<0, 65535>'], 'AMQPChannel::getPrefetchSize' => ['int<0, max>'], 'AMQPChannel::isConnected' => ['bool'], 'AMQPChannel::qos' => ['void', 'size'=>'int', 'count'=>'int', 'global='=>'bool'], 'AMQPChannel::rollbackTransaction' => ['void'], 'AMQPChannel::setPrefetchCount' => ['void', 'count'=>'int'], 'AMQPChannel::setPrefetchSize' => ['void', 'size'=>'int'], 'AMQPChannel::startTransaction' => ['void'], 'AMQPConnection::__construct' => ['void', 'credentials='=>'array'], 'AMQPConnection::connect' => ['void'], 'AMQPConnection::disconnect' => ['void'], 'AMQPConnection::getHost' => ['string'], 'AMQPConnection::getLogin' => ['string'], 'AMQPConnection::getMaxChannels' => ['int<1, 65535>'], 'AMQPConnection::getPassword' => ['string'], 'AMQPConnection::getPort' => ['int<1, 65535>'], 'AMQPConnection::getReadTimeout' => ['float'], 'AMQPConnection::getTimeout' => ['float'], 'AMQPConnection::getUsedChannels' => ['int<1, 65535>'], 'AMQPConnection::getVhost' => ['string'], 'AMQPConnection::getWriteTimeout' => ['float'], 'AMQPConnection::isConnected' => ['bool'], 'AMQPConnection::isPersistent' => ['bool'], 'AMQPConnection::pconnect' => ['void'], 'AMQPConnection::pdisconnect' => ['void'], 'AMQPConnection::preconnect' => ['void'], 'AMQPConnection::reconnect' => ['void'], 'AMQPConnection::setHost' => ['void', 'host'=>'string'], 'AMQPConnection::setLogin' => ['void', 'login'=>'string'], 'AMQPConnection::setPassword' => ['void', 'password'=>'string'], 'AMQPConnection::setPort' => ['void', 'port'=>'int'], 'AMQPConnection::setReadTimeout' => ['void', 'timeout'=>'int'], 'AMQPConnection::setTimeout' => ['void', 'timeout'=>'int'], 'AMQPConnection::setVhost' => ['void', 'vhost'=>'string'], 'AMQPConnection::setWriteTimeout' => ['void', 'timeout'=>'int'], 'AMQPEnvelope::getAppId' => ['string|null'], 'AMQPEnvelope::getBody' => ['string'], 'AMQPEnvelope::getContentEncoding' => ['string|null'], 'AMQPEnvelope::getContentType' => ['string|null'], 'AMQPEnvelope::getCorrelationId' => ['string|null'], 'AMQPEnvelope::getDeliveryMode' => ['int'], 'AMQPEnvelope::getDeliveryTag' => ['int|null'], 'AMQPEnvelope::getExchangeName' => ['string|null'], 'AMQPEnvelope::getExpiration' => ['string|null'], 'AMQPEnvelope::getHeader' => ['mixed', 'headerName'=>'string'], 'AMQPEnvelope::getHeaders' => ['array'], 'AMQPEnvelope::getMessageId' => ['string|null'], 'AMQPEnvelope::getPriority' => ['int<0, max>'], 'AMQPEnvelope::getReplyTo' => ['string|null'], 'AMQPEnvelope::getRoutingKey' => ['string'], 'AMQPEnvelope::getTimestamp' => ['int|null'], 'AMQPEnvelope::getType' => ['string|null'], 'AMQPEnvelope::getUserId' => ['string|null'], 'AMQPEnvelope::isRedelivery' => ['bool'], 'AMQPExchange::__construct' => ['void', 'channel'=>'AMQPChannel'], 'AMQPExchange::bind' => ['void', 'exchangeName'=>'string', 'routingKey='=>'string|null', 'arguments='=>'array'], 'AMQPExchange::declareExchange' => ['void'], 'AMQPExchange::delete' => ['void', 'exchangeName='=>'string', 'flags='=>'int'], 'AMQPExchange::getArgument' => ['scalar|null', 'argumentName'=>'string'], 'AMQPExchange::getArguments' => ['array'], 'AMQPExchange::getChannel' => ['AMQPChannel'], 'AMQPExchange::getConnection' => ['AMQPConnection'], 'AMQPExchange::getFlags' => ['int'], 'AMQPExchange::getName' => ['string|null'], 'AMQPExchange::getType' => ['string|null'], 'AMQPExchange::publish' => ['void', 'message'=>'string', 'routingKey='=>'string|null', 'flags='=>'int|null', 'header='=>'array'], 'AMQPExchange::setArgument' => ['void', 'argumentName'=>'string', 'argumentValue'=>'scalar|null'], 'AMQPExchange::setArguments' => ['void', 'arguments'=>'array'], 'AMQPExchange::setFlags' => ['void', 'flags'=>'int|null'], 'AMQPExchange::setName' => ['void', 'exchangeName'=>'string|null'], 'AMQPExchange::setType' => ['void', 'exchangeType'=>'string|null'], 'AMQPExchange::unbind' => ['void', 'exchangeName'=>'string', 'routingKey='=>'string|null', 'arguments='=>'array'], 'AMQPQueue::__construct' => ['void', 'channel'=>'AMQPChannel'], 'AMQPQueue::ack' => ['void', 'deliveryTag'=>'int', 'flags='=>'int|null'], 'AMQPQueue::bind' => ['void', 'exchangeName'=>'string', 'routingKey='=>'string|null', 'arguments='=>'array'], 'AMQPQueue::cancel' => ['void', 'consumerTag='=>'string'], 'AMQPQueue::consume' => ['void', 'callback='=>'null|callable(AMQPEnvelope, AMQPQueue): mixed', 'flags='=>'int|null', 'consumerTag='=>'string|null'], 'AMQPQueue::declareQueue' => ['int'], 'AMQPQueue::delete' => ['int', 'flags='=>'int|null'], 'AMQPQueue::get' => ['AMQPEnvelope|null', 'flags='=>'int|null'], 'AMQPQueue::getArgument' => ['scalar|null|array|AMQPValue|AMQPDecimal|AMQPTimestamp', 'argumentName'=>'string'], 'AMQPQueue::getArguments' => ['array'], 'AMQPQueue::getChannel' => ['AMQPChannel'], 'AMQPQueue::getConnection' => ['AMQPConnection'], 'AMQPQueue::getFlags' => ['int'], 'AMQPQueue::getName' => ['string|null'], 'AMQPQueue::nack' => ['void', 'deliveryTag'=>'int', 'flags='=>'int|null'], 'AMQPQueue::purge' => ['int'], 'AMQPQueue::reject' => ['void', 'deliveryTag'=>'int', 'flags='=>'int|null'], 'AMQPQueue::setArgument' => ['void', 'argumentName'=>'string', 'argumentValue'=>'scalar|null|array|AMQPValue|AMQPDecimal|AMQPTimestamp'], 'AMQPQueue::setArguments' => ['void', 'arguments'=>'array'], 'AMQPQueue::setFlags' => ['void', 'flags'=>'int|null'], 'AMQPQueue::setName' => ['void', 'name'=>'string'], 'AMQPQueue::unbind' => ['void', 'exchangeName'=>'string', 'routingKey='=>'string|null', 'arguments='=>'array'], 'apache_child_terminate' => ['bool'], 'apache_get_modules' => ['array'], 'apache_get_version' => ['string|false'], 'apache_getenv' => ['string|false', 'variable'=>'string', 'walk_to_top='=>'bool'], 'apache_lookup_uri' => ['object|false', 'filename'=>'string'], 'apache_note' => ['string|false', 'note_name'=>'string', 'note_value='=>'string'], 'apache_request_headers' => ['array|false'], 'apache_reset_timeout' => ['bool'], 'apache_response_headers' => ['array|false'], 'apache_setenv' => ['bool', 'variable'=>'string', 'value'=>'string', 'walk_to_top='=>'bool'], 'apc_add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'ttl='=>'int'], 'apc_add\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'], 'apc_bin_dump' => ['string', 'files='=>'array', 'user_vars='=>'array'], 'apc_bin_dumpfile' => ['int', 'files'=>'array', 'user_vars'=>'array', 'filename'=>'string', 'flags='=>'int', 'context='=>'resource'], 'apc_bin_load' => ['bool', 'data'=>'string', 'flags='=>'int'], 'apc_bin_loadfile' => ['bool', 'filename'=>'string', 'context='=>'resource', 'flags='=>'int'], 'apc_cache_info' => ['array', 'cache_type='=>'string', 'limited='=>'bool'], 'apc_cas' => ['bool', 'key'=>'string', 'old'=>'int', 'new'=>'int'], 'apc_clear_cache' => ['bool', 'cache_type='=>'string'], 'apc_compile_file' => ['mixed', 'filename'=>'string', 'atomic='=>'bool'], 'apc_dec' => ['int', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool'], 'apc_define_constants' => ['bool', 'key'=>'string', 'constants'=>'array', 'case_sensitive='=>'bool'], 'apc_delete' => ['bool', 'key'=>'string|string[]|APCIterator'], 'apc_delete_file' => ['mixed', 'keys'=>'mixed'], 'apc_exists' => ['bool', 'keys'=>'string'], 'apc_exists\'1' => ['array', 'keys'=>'string[]'], 'apc_fetch' => ['mixed', 'key'=>'mixed', '&w_success='=>'bool'], 'apc_inc' => ['int', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool'], 'apc_load_constants' => ['bool', 'key'=>'string', 'case_sensitive='=>'bool'], 'apc_sma_info' => ['array', 'limited='=>'bool'], 'apc_store' => ['bool', 'key'=>'string', 'var'=>'', 'ttl='=>'int'], 'apc_store\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'], 'APCIterator::__construct' => ['void', 'cache'=>'string', 'search='=>'', 'format='=>'int', 'chunk_size='=>'int', 'list='=>'int'], 'APCIterator::current' => ['mixed'], 'APCIterator::getTotalCount' => ['int'], 'APCIterator::getTotalHits' => ['int'], 'APCIterator::getTotalSize' => ['int'], 'APCIterator::key' => ['string'], 'APCIterator::next' => ['void'], 'APCIterator::rewind' => ['void'], 'APCIterator::valid' => ['bool'], 'apcu_add' => ['bool', 'key'=>'string', 'var'=>'', 'ttl='=>'int'], 'apcu_add\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'], 'apcu_cache_info' => ['array', 'limited='=>'bool'], 'apcu_cas' => ['bool', 'key'=>'string', 'old'=>'int', 'new'=>'int'], 'apcu_clear_cache' => ['bool'], 'apcu_dec' => ['int', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool', 'ttl='=>'int'], 'apcu_delete' => ['bool', 'key'=>'string|APCuIterator'], 'apcu_delete\'1' => ['list', 'key'=>'string[]'], 'apcu_entry' => ['mixed', 'key'=>'string', 'generator'=>'callable', 'ttl='=>'int'], 'apcu_exists' => ['bool', 'keys'=>'string'], 'apcu_exists\'1' => ['array', 'keys'=>'string[]'], 'apcu_fetch' => ['mixed', 'key'=>'string|string[]', '&w_success='=>'bool'], 'apcu_inc' => ['int', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool', 'ttl='=>'int'], 'apcu_sma_info' => ['array', 'limited='=>'bool'], 'apcu_store' => ['bool', 'key'=>'string', 'var='=>'', 'ttl='=>'int'], 'apcu_store\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'], 'APCuIterator::__construct' => ['void', 'search='=>'string|string[]|null', 'format='=>'int', 'chunk_size='=>'int', 'list='=>'int'], 'APCuIterator::current' => ['mixed'], 'APCuIterator::getTotalCount' => ['int'], 'APCuIterator::getTotalHits' => ['int'], 'APCuIterator::getTotalSize' => ['int'], 'APCuIterator::key' => ['string'], 'APCuIterator::next' => ['void'], 'APCuIterator::rewind' => ['void'], 'APCuIterator::valid' => ['bool'], 'apd_breakpoint' => ['bool', 'debug_level'=>'int'], 'apd_callstack' => ['array'], 'apd_clunk' => ['void', 'warning'=>'string', 'delimiter='=>'string'], 'apd_continue' => ['bool', 'debug_level'=>'int'], 'apd_croak' => ['void', 'warning'=>'string', 'delimiter='=>'string'], 'apd_dump_function_table' => ['void'], 'apd_dump_persistent_resources' => ['array'], 'apd_dump_regular_resources' => ['array'], 'apd_echo' => ['bool', 'output'=>'string'], 'apd_get_active_symbols' => ['array'], 'apd_set_pprof_trace' => ['string', 'dump_directory='=>'string', 'fragment='=>'string'], 'apd_set_session' => ['void', 'debug_level'=>'int'], 'apd_set_session_trace' => ['void', 'debug_level'=>'int', 'dump_directory='=>'string'], 'apd_set_session_trace_socket' => ['bool', 'tcp_server'=>'string', 'socket_type'=>'int', 'port'=>'int', 'debug_level'=>'int'], 'AppendIterator::__construct' => ['void'], 'AppendIterator::append' => ['void', 'iterator'=>'Iterator'], 'AppendIterator::current' => ['mixed'], 'AppendIterator::getArrayIterator' => ['ArrayIterator'], 'AppendIterator::getInnerIterator' => ['iterator'], 'AppendIterator::getIteratorIndex' => ['int'], 'AppendIterator::key' => ['mixed'], 'AppendIterator::next' => ['void'], 'AppendIterator::rewind' => ['void'], 'AppendIterator::valid' => ['bool'], 'array_change_key_case' => ['array', 'input'=>'array', 'case='=>'int'], 'array_chunk' => ['list', 'input'=>'array', 'size'=>'positive-int', 'preserve_keys='=>'bool'], 'array_column' => ['array', 'array'=>'array', 'column_key'=>'mixed', 'index_key='=>'mixed'], 'array_combine' => ['array|false', 'keys'=>'array', 'values'=>'array'], 'array_count_values' => ['array', 'input'=>'array'], 'array_diff' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], 'array_diff_assoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], 'array_diff_key' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], 'array_diff_uassoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'data_comp_func'=>'callable(mixed,mixed):int'], 'array_diff_uassoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable'], 'array_diff_ukey' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'key_comp_func'=>'callable(mixed,mixed):int'], 'array_diff_ukey\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'], 'array_fill' => ['array', 'start_key'=>'int', 'num'=>'int', 'val'=>'mixed'], 'array_fill_keys' => ['array', 'keys'=>'array', 'val'=>'mixed'], 'array_filter' => ['array', 'input'=>'array', 'callback='=>'callable(mixed,mixed):bool|callable(mixed):bool', 'flag='=>'int'], 'array_flip' => ['array', 'input'=>'array'], 'array_intersect' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], 'array_intersect_assoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], 'array_intersect_key' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], 'array_intersect_uassoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'key_compare_func'=>'callable(mixed,mixed):int'], 'array_intersect_uassoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest'=>'array|callable'], 'array_intersect_ukey' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'key_compare_func'=>'callable(mixed,mixed):int'], 'array_intersect_ukey\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest'=>'array|callable(mixed,mixed):int'], 'array_key_exists' => ['bool', 'key'=>'string|int', 'search'=>'array'], 'array_key_first' => ['int|string|null', 'array'=>'array'], 'array_key_last' => ['int|string|null', 'array'=>'array'], 'array_keys' => ['list', 'input'=>'array', 'search_value='=>'mixed', 'strict='=>'bool'], 'array_map' => ['array', 'callback'=>'?callable', 'array'=>'array', '...args='=>'array'], 'array_merge' => ['array', 'arr1'=>'array', '...args='=>'array'], 'array_merge_recursive' => ['array', 'arr1'=>'array', '...args='=>'array'], 'array_multisort' => ['bool', 'array1'=>'array', 'array1_sort_order='=>'array|int', 'array1_sort_flags='=>'array|int', '...args='=>'array|int'], 'array_pad' => ['array', 'input'=>'array', 'pad_size'=>'int', 'pad_value'=>'mixed'], 'array_pop' => ['mixed', '&rw_stack'=>'array'], 'array_product' => ['int|float', 'input'=>'array'], 'array_push' => ['int', '&rw_stack'=>'array', 'var'=>'mixed', '...vars='=>'mixed'], 'array_rand' => ['int|string|array|array', 'input'=>'array', 'num_req'=>'int'], 'array_rand\'1' => ['int|string', 'input'=>'array'], 'array_reduce' => ['mixed', 'input'=>'array', 'callback'=>'callable(mixed,mixed):mixed', 'initial='=>'mixed'], 'array_replace' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], 'array_replace_recursive' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], 'array_reverse' => ['array', 'input'=>'array', 'preserve='=>'bool'], 'array_search' => ['int|string|false', 'needle'=>'mixed', 'haystack'=>'array', 'strict='=>'bool'], 'array_shift' => ['mixed', '&rw_stack'=>'array'], 'array_slice' => ['array', 'input'=>'array', 'offset'=>'int', 'length='=>'?int', 'preserve_keys='=>'bool'], 'array_splice' => ['array', '&rw_input'=>'array', 'offset'=>'int', 'length='=>'int', 'replacement='=>'mixed'], 'array_sum' => ['int|float', 'input'=>'array'], 'array_udiff' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'data_comp_func'=>'callable(mixed,mixed):int'], 'array_udiff\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'], 'array_udiff_assoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'key_comp_func'=>'callable(mixed,mixed):int'], 'array_udiff_assoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'], 'array_udiff_uassoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'data_comp_func'=>'callable', 'key_comp_func'=>'callable(mixed,mixed):int'], 'array_udiff_uassoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', 'arg5'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'], 'array_uintersect' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'data_compare_func'=>'callable(mixed,mixed):int'], 'array_uintersect\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'], 'array_uintersect_assoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'data_compare_func'=>'callable(mixed,mixed):int'], 'array_uintersect_assoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'], 'array_uintersect_uassoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'data_compare_func'=>'callable(mixed,mixed):int', 'key_compare_func'=>'callable(mixed,mixed):int'], 'array_uintersect_uassoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', 'arg5'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'], 'array_unique' => ['array', 'array'=>'array', 'flags='=>'int'], 'array_unshift' => ['positive-int', '&rw_stack'=>'array', 'var'=>'mixed', '...vars='=>'mixed'], 'array_values' => ['list', 'input'=>'array'], 'array_walk' => ['bool', '&rw_input'=>'array|object', 'callback'=>'callable', 'userdata='=>'mixed'], 'array_walk_recursive' => ['bool', '&rw_input'=>'array|object', 'callback'=>'callable', 'userdata='=>'mixed'], 'ArrayAccess::offsetExists' => ['bool', 'offset'=>'mixed'], 'ArrayAccess::offsetGet' => ['mixed', 'offset'=>'mixed'], 'ArrayAccess::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], 'ArrayAccess::offsetUnset' => ['void', 'offset'=>'mixed'], 'ArrayIterator::__construct' => ['void', 'array='=>'array|object', 'flags='=>'int'], 'ArrayIterator::append' => ['void', 'value'=>'mixed'], 'ArrayIterator::asort' => ['void'], 'ArrayIterator::count' => ['0|positive-int'], 'ArrayIterator::current' => ['mixed'], 'ArrayIterator::getArrayCopy' => ['array'], 'ArrayIterator::getFlags' => ['int'], 'ArrayIterator::key' => ['int|string|false'], 'ArrayIterator::ksort' => ['void'], 'ArrayIterator::natcasesort' => ['void'], 'ArrayIterator::natsort' => ['void'], 'ArrayIterator::next' => ['void'], 'ArrayIterator::offsetExists' => ['bool', 'index'=>'string|int|bool|null'], 'ArrayIterator::offsetGet' => ['mixed', 'index'=>'string|int|bool|null'], 'ArrayIterator::offsetSet' => ['void', 'index'=>'string|int|bool|null', 'newval'=>'mixed'], 'ArrayIterator::offsetUnset' => ['void', 'index'=>'string|int|bool|null'], 'ArrayIterator::rewind' => ['void'], 'ArrayIterator::seek' => ['void', 'position'=>'int'], 'ArrayIterator::serialize' => ['string'], 'ArrayIterator::setFlags' => ['void', 'flags'=>'string'], 'ArrayIterator::uasort' => ['void', 'callback'=>'callable(mixed,mixed):int'], 'ArrayIterator::uksort' => ['void', 'callback'=>'callable(array-key,array-key):int'], 'ArrayIterator::unserialize' => ['void', 'serialized'=>'string'], 'ArrayIterator::valid' => ['bool'], 'ArrayObject::__construct' => ['void', 'input='=>'array|object', 'flags='=>'int', 'iterator_class='=>'class-string'], 'ArrayObject::append' => ['void', 'value'=>'mixed'], 'ArrayObject::asort' => ['void'], 'ArrayObject::count' => ['0|positive-int'], 'ArrayObject::exchangeArray' => ['array', 'ar'=>'mixed'], 'ArrayObject::getArrayCopy' => ['array'], 'ArrayObject::getFlags' => ['int'], 'ArrayObject::getIterator' => ['ArrayIterator'], 'ArrayObject::getIteratorClass' => ['string'], 'ArrayObject::ksort' => ['void'], 'ArrayObject::natcasesort' => ['void'], 'ArrayObject::natsort' => ['void'], 'ArrayObject::offsetExists' => ['bool', 'index'=>'mixed'], 'ArrayObject::offsetGet' => ['mixed', 'index'=>'mixed'], 'ArrayObject::offsetSet' => ['void', 'index'=>'mixed', 'newval'=>'mixed'], 'ArrayObject::offsetUnset' => ['void', 'index'=>'mixed'], 'ArrayObject::serialize' => ['string'], 'ArrayObject::setFlags' => ['void', 'flags'=>'int'], 'ArrayObject::setIteratorClass' => ['void', 'iterator_class'=>'string'], 'ArrayObject::uasort' => ['void', 'callback'=>'callable'], 'ArrayObject::uksort' => ['void', 'callback'=>'callable(array-key,array-key):int'], 'ArrayObject::unserialize' => ['void', 'serialized'=>'string'], 'arsort' => ['bool', '&rw_array_arg'=>'array', 'sort_flags='=>'int'], 'asin' => ['float', 'number'=>'float'], 'asinh' => ['float', 'number'=>'float'], 'asort' => ['bool', '&rw_array_arg'=>'array', 'sort_flags='=>'int'], 'assert' => ['bool', 'assertion'=>'string|bool', 'description='=>'string|Throwable|null'], 'assert_options' => ['mixed', 'what'=>'int', 'value='=>'mixed'], 'ast\get_kind_name' => ['string', 'kind'=>'int'], 'ast\get_metadata' => ['array'], 'ast\get_supported_versions' => ['array', 'exclude_deprecated='=>'bool'], 'ast\kind_uses_flags' => ['bool', 'kind'=>'int'], 'ast\Node::__construct' => ['void', 'kind='=>'int', 'flags='=>'int', 'children='=>'ast\Node\Decl[]|ast\Node[]|array[]|int[]|string[]|float[]|bool[]|null[]', 'start_line='=>'int'], 'ast\parse_code' => ['ast\Node', 'code'=>'string', 'version'=>'int', 'filename='=>'string'], 'ast\parse_file' => ['ast\Node', 'filename'=>'string', 'version'=>'int'], 'atan' => ['float', 'number'=>'float'], 'atan2' => ['float', 'y'=>'float', 'x'=>'float'], 'atanh' => ['float', 'number'=>'float'], 'BadFunctionCallException::__clone' => ['void'], 'BadFunctionCallException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?BadFunctionCallException)'], 'BadFunctionCallException::__toString' => ['string'], 'BadFunctionCallException::getCode' => ['int'], 'BadFunctionCallException::getFile' => ['string'], 'BadFunctionCallException::getLine' => ['int'], 'BadFunctionCallException::getMessage' => ['string'], 'BadFunctionCallException::getPrevious' => ['(?Throwable)|(?BadFunctionCallException)'], 'BadFunctionCallException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'BadFunctionCallException::getTraceAsString' => ['string'], 'BadMethodCallException::__clone' => ['void'], 'BadMethodCallException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?BadMethodCallException)'], 'BadMethodCallException::__toString' => ['string'], 'BadMethodCallException::getCode' => ['int'], 'BadMethodCallException::getFile' => ['string'], 'BadMethodCallException::getLine' => ['int'], 'BadMethodCallException::getMessage' => ['string'], 'BadMethodCallException::getPrevious' => ['(?Throwable)|(?BadMethodCallException)'], 'BadMethodCallException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'BadMethodCallException::getTraceAsString' => ['string'], 'base64_decode' => ['string', 'str'=>'string', 'strict='=>'false'], 'base64_decode\'1' => ['string|false', 'str'=>'string', 'strict='=>'true'], 'base64_encode' => ['string', 'str'=>'string'], 'base_convert' => ['string', 'number'=>'string', 'frombase'=>'int', 'tobase'=>'int'], 'basename' => ['string', 'path'=>'string', 'suffix='=>'string'], 'bbcode_add_element' => ['bool', 'bbcode_container'=>'resource', 'tag_name'=>'string', 'tag_rules'=>'array'], 'bbcode_add_smiley' => ['bool', 'bbcode_container'=>'resource', 'smiley'=>'string', 'replace_by'=>'string'], 'bbcode_create' => ['resource', 'bbcode_initial_tags='=>'array'], 'bbcode_destroy' => ['bool', 'bbcode_container'=>'resource'], 'bbcode_parse' => ['string', 'bbcode_container'=>'resource', 'to_parse'=>'string'], 'bbcode_set_arg_parser' => ['bool', 'bbcode_container'=>'resource', 'bbcode_arg_parser'=>'resource'], 'bbcode_set_flags' => ['bool', 'bbcode_container'=>'resource', 'flags'=>'int', 'mode='=>'int'], 'bcadd' => ['numeric-string', 'left_operand'=>'string', 'right_operand'=>'string', 'scale='=>'int'], 'bccomp' => ['int', 'left_operand'=>'string', 'right_operand'=>'string', 'scale='=>'int'], 'bcdiv' => ['numeric-string|null', 'left_operand'=>'string', 'right_operand'=>'string', 'scale='=>'int'], 'bcmod' => ['numeric-string|null', 'left_operand'=>'string', 'right_operand'=>'string', 'scale='=>'int'], 'bcmul' => ['numeric-string', 'left_operand'=>'string', 'right_operand'=>'string', 'scale='=>'int'], 'bcompiler_load' => ['bool', 'filename'=>'string'], 'bcompiler_load_exe' => ['bool', 'filename'=>'string'], 'bcompiler_parse_class' => ['bool', 'class'=>'string', 'callback'=>'string'], 'bcompiler_read' => ['bool', 'filehandle'=>'resource'], 'bcompiler_write_class' => ['bool', 'filehandle'=>'resource', 'classname'=>'string', 'extends='=>'string'], 'bcompiler_write_constant' => ['bool', 'filehandle'=>'resource', 'constantname'=>'string'], 'bcompiler_write_exe_footer' => ['bool', 'filehandle'=>'resource', 'startpos'=>'int'], 'bcompiler_write_file' => ['bool', 'filehandle'=>'resource', 'filename'=>'string'], 'bcompiler_write_footer' => ['bool', 'filehandle'=>'resource'], 'bcompiler_write_function' => ['bool', 'filehandle'=>'resource', 'functionname'=>'string'], 'bcompiler_write_functions_from_file' => ['bool', 'filehandle'=>'resource', 'filename'=>'string'], 'bcompiler_write_header' => ['bool', 'filehandle'=>'resource', 'write_ver='=>'string'], 'bcompiler_write_included_filename' => ['bool', 'filehandle'=>'resource', 'filename'=>'string'], 'bcpow' => ['numeric-string', 'base'=>'string', 'exponent'=>'string', 'scale='=>'int'], 'bcpowmod' => ['numeric-string|null', 'base'=>'string', 'exponent'=>'string', 'modulus'=>'string', 'scale='=>'int'], 'bcscale' => ['int', 'scale='=>'int'], 'bcsqrt' => ['numeric-string', 'operand'=>'string', 'scale='=>'int'], 'bcsub' => ['numeric-string', 'left_operand'=>'string', 'right_operand'=>'string', 'scale='=>'int'], 'bin2hex' => ['string', 'data'=>'string'], 'bind_textdomain_codeset' => ['string|false', 'domain'=>'string', 'codeset'=>'string'], 'bindec' => ['float|int', 'binary_number'=>'string'], 'bindtextdomain' => ['string|false', 'domain_name'=>'string', 'dir'=>'string'], 'birdstep_autocommit' => ['bool', 'index'=>'int'], 'birdstep_close' => ['bool', 'id'=>'int'], 'birdstep_commit' => ['bool', 'index'=>'int'], 'birdstep_connect' => ['int', 'server'=>'string', 'user'=>'string', 'pass'=>'string'], 'birdstep_exec' => ['int', 'index'=>'int', 'exec_str'=>'string'], 'birdstep_fetch' => ['bool', 'index'=>'int'], 'birdstep_fieldname' => ['string', 'index'=>'int', 'col'=>'int'], 'birdstep_fieldnum' => ['int', 'index'=>'int'], 'birdstep_freeresult' => ['bool', 'index'=>'int'], 'birdstep_off_autocommit' => ['bool', 'index'=>'int'], 'birdstep_result' => ['', 'index'=>'int', 'col'=>''], 'birdstep_rollback' => ['bool', 'index'=>'int'], 'blenc_encrypt' => ['string', 'plaintext'=>'string', 'encodedfile'=>'string', 'encryption_key='=>'string'], 'boolval' => ['bool', 'var'=>'mixed'], 'BSON\Binary::__construct' => ['void', 'data'=>'string', 'subtype'=>'string'], 'BSON\Binary::getSubType' => [''], 'BSON\fromArray' => ['string', 'array'=>'string'], 'BSON\fromJSON' => ['string', 'json'=>'string'], 'BSON\Javascript::__construct' => ['void', 'javascript'=>'string', 'scope='=>'string'], 'BSON\ObjectID::__construct' => ['void', 'id='=>'string'], 'BSON\ObjectID::__toString' => ['string'], 'BSON\Regex::__construct' => ['void', 'pattern'=>'string', 'flags'=>'string'], 'BSON\Regex::__toString' => ['string'], 'BSON\Regex::getFlags' => [''], 'BSON\Regex::getPattern' => [''], 'BSON\Serializable::bsonSerialize' => ['string'], 'BSON\Timestamp::__construct' => ['void', 'increment'=>'string', 'timestamp'=>'string'], 'BSON\Timestamp::__toString' => ['string'], 'BSON\toArray' => ['array', 'bson'=>'string'], 'BSON\toJSON' => ['string', 'bson'=>'string'], 'BSON\Unserializable::bsonUnserialize' => ['', 'data'=>'array'], 'BSON\UTCDatetime::__construct' => ['void', 'milliseconds'=>'string'], 'BSON\UTCDatetime::__toString' => ['string'], 'BSON\UTCDatetime::toDateTime' => [''], 'bson_decode' => ['array', 'bson'=>'string'], 'bson_encode' => ['string', 'anything'=>'mixed'], 'bzclose' => ['bool', 'bz'=>'resource'], 'bzcompress' => ['string|int', 'source'=>'string', 'blocksize100k='=>'int', 'workfactor='=>'int'], 'bzdecompress' => ['string|int|false', 'source'=>'string', 'small='=>'int'], 'bzerrno' => ['int', 'bz'=>'resource'], 'bzerror' => ['array', 'bz'=>'resource'], 'bzerrstr' => ['string', 'bz'=>'resource'], 'bzflush' => ['bool', 'bz'=>'resource'], 'bzopen' => ['resource|false', 'file'=>'string|resource', 'mode'=>'string'], 'bzread' => ['string|false', 'bz'=>'resource', 'length='=>'int'], 'bzwrite' => ['int|false', 'bz'=>'resource', 'data'=>'string', 'length='=>'int'], 'CachingIterator::__construct' => ['void', 'iterator'=>'Iterator', 'flags='=>''], 'CachingIterator::__toString' => ['string'], 'CachingIterator::count' => ['0|positive-int'], 'CachingIterator::current' => ['mixed'], 'CachingIterator::getCache' => ['array'], 'CachingIterator::getFlags' => ['int'], 'CachingIterator::getInnerIterator' => ['Iterator'], 'CachingIterator::hasNext' => ['bool'], 'CachingIterator::key' => ['mixed'], 'CachingIterator::next' => ['void'], 'CachingIterator::offsetExists' => ['bool', 'index'=>'string'], 'CachingIterator::offsetGet' => ['mixed', 'index'=>'string'], 'CachingIterator::offsetSet' => ['void', 'index'=>'string', 'newval'=>'mixed'], 'CachingIterator::offsetUnset' => ['void', 'index'=>'string'], 'CachingIterator::rewind' => ['void'], 'CachingIterator::setFlags' => ['void', 'flags'=>'int'], 'CachingIterator::valid' => ['bool'], 'Cairo::availableFonts' => ['array'], 'Cairo::availableSurfaces' => ['array'], 'Cairo::statusToString' => ['string', 'status'=>'int'], 'Cairo::version' => ['int'], 'Cairo::versionString' => ['string'], 'cairo_append_path' => ['', 'path'=>'cairopath', 'context'=>'cairocontext'], 'cairo_arc' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'], 'cairo_arc_negative' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'], 'cairo_available_fonts' => ['array'], 'cairo_available_surfaces' => ['array'], 'cairo_clip' => ['', 'context'=>'cairocontext'], 'cairo_clip_extents' => ['array', 'context'=>'cairocontext'], 'cairo_clip_preserve' => ['', 'context'=>'cairocontext'], 'cairo_clip_rectangle_list' => ['array', 'context'=>'cairocontext'], 'cairo_close_path' => ['', 'context'=>'cairocontext'], 'cairo_copy_page' => ['', 'context'=>'cairocontext'], 'cairo_copy_path' => ['CairoPath', 'context'=>'cairocontext'], 'cairo_copy_path_flat' => ['CairoPath', 'context'=>'cairocontext'], 'cairo_create' => ['CairoContext', 'surface'=>'cairosurface'], 'cairo_curve_to' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float', 'context'=>'cairocontext'], 'cairo_device_to_user' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'], 'cairo_device_to_user_distance' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'], 'cairo_fill' => ['', 'context'=>'cairocontext'], 'cairo_fill_extents' => ['array', 'context'=>'cairocontext'], 'cairo_fill_preserve' => ['', 'context'=>'cairocontext'], 'cairo_font_extents' => ['array', 'context'=>'cairocontext'], 'cairo_font_face_get_type' => ['int', 'fontface'=>'cairofontface'], 'cairo_font_face_status' => ['int', 'fontface'=>'cairofontface'], 'cairo_font_options_create' => ['CairoFontOptions'], 'cairo_font_options_equal' => ['bool', 'options'=>'cairofontoptions', 'other'=>'cairofontoptions'], 'cairo_font_options_get_antialias' => ['int', 'options'=>'cairofontoptions'], 'cairo_font_options_get_hint_metrics' => ['int', 'options'=>'cairofontoptions'], 'cairo_font_options_get_hint_style' => ['int', 'options'=>'cairofontoptions'], 'cairo_font_options_get_subpixel_order' => ['int', 'options'=>'cairofontoptions'], 'cairo_font_options_hash' => ['int', 'options'=>'cairofontoptions'], 'cairo_font_options_merge' => ['void', 'options'=>'cairofontoptions', 'other'=>'cairofontoptions'], 'cairo_font_options_set_antialias' => ['void', 'options'=>'cairofontoptions', 'antialias'=>'int'], 'cairo_font_options_set_hint_metrics' => ['void', 'options'=>'cairofontoptions', 'hint_metrics'=>'int'], 'cairo_font_options_set_hint_style' => ['void', 'options'=>'cairofontoptions', 'hint_style'=>'int'], 'cairo_font_options_set_subpixel_order' => ['void', 'options'=>'cairofontoptions', 'subpixel_order'=>'int'], 'cairo_font_options_status' => ['int', 'options'=>'cairofontoptions'], 'cairo_format_stride_for_width' => ['int', 'format'=>'int', 'width'=>'int'], 'cairo_get_antialias' => ['int', 'context'=>'cairocontext'], 'cairo_get_current_point' => ['array', 'context'=>'cairocontext'], 'cairo_get_dash' => ['array', 'context'=>'cairocontext'], 'cairo_get_dash_count' => ['int', 'context'=>'cairocontext'], 'cairo_get_fill_rule' => ['int', 'context'=>'cairocontext'], 'cairo_get_font_face' => ['', 'context'=>'cairocontext'], 'cairo_get_font_matrix' => ['', 'context'=>'cairocontext'], 'cairo_get_font_options' => ['', 'context'=>'cairocontext'], 'cairo_get_group_target' => ['', 'context'=>'cairocontext'], 'cairo_get_line_cap' => ['int', 'context'=>'cairocontext'], 'cairo_get_line_join' => ['int', 'context'=>'cairocontext'], 'cairo_get_line_width' => ['float', 'context'=>'cairocontext'], 'cairo_get_matrix' => ['', 'context'=>'cairocontext'], 'cairo_get_miter_limit' => ['float', 'context'=>'cairocontext'], 'cairo_get_operator' => ['int', 'context'=>'cairocontext'], 'cairo_get_scaled_font' => ['', 'context'=>'cairocontext'], 'cairo_get_source' => ['', 'context'=>'cairocontext'], 'cairo_get_target' => ['', 'context'=>'cairocontext'], 'cairo_get_tolerance' => ['float', 'context'=>'cairocontext'], 'cairo_glyph_path' => ['', 'glyphs'=>'array', 'context'=>'cairocontext'], 'cairo_has_current_point' => ['bool', 'context'=>'cairocontext'], 'cairo_identity_matrix' => ['', 'context'=>'cairocontext'], 'cairo_image_surface_create' => ['CairoImageSurface', 'format'=>'int', 'width'=>'int', 'height'=>'int'], 'cairo_image_surface_create_for_data' => ['CairoImageSurface', 'data'=>'string', 'format'=>'int', 'width'=>'int', 'height'=>'int', 'stride='=>'int'], 'cairo_image_surface_create_from_png' => ['CairoImageSurface', 'file'=>'string'], 'cairo_image_surface_get_data' => ['string', 'surface'=>'cairoimagesurface'], 'cairo_image_surface_get_format' => ['int', 'surface'=>'cairoimagesurface'], 'cairo_image_surface_get_height' => ['int', 'surface'=>'cairoimagesurface'], 'cairo_image_surface_get_stride' => ['int', 'surface'=>'cairoimagesurface'], 'cairo_image_surface_get_width' => ['int', 'surface'=>'cairoimagesurface'], 'cairo_in_fill' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'cairo_in_stroke' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'cairo_line_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'cairo_mask' => ['', 'pattern'=>'cairopattern', 'context'=>'cairocontext'], 'cairo_mask_surface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'], 'cairo_matrix_create_scale' => ['object', 'sx'=>'float', 'sy'=>'float'], 'cairo_matrix_init' => ['object', 'xx='=>'float', 'yx='=>'float', 'xy='=>'float', 'yy='=>'float', 'x0='=>'float', 'y0='=>'float'], 'cairo_matrix_init_identity' => ['object'], 'cairo_matrix_init_rotate' => ['object', 'radians'=>'float'], 'cairo_matrix_init_scale' => ['object', 'sx'=>'float', 'sy'=>'float'], 'cairo_matrix_init_translate' => ['object', 'tx'=>'float', 'ty'=>'float'], 'cairo_matrix_invert' => ['void', 'matrix'=>'cairomatrix'], 'cairo_matrix_multiply' => ['CairoMatrix', 'matrix1'=>'cairomatrix', 'matrix2'=>'cairomatrix'], 'cairo_matrix_rotate' => ['', 'matrix'=>'cairomatrix', 'radians'=>'float'], 'cairo_matrix_scale' => ['', 'sx'=>'float', 'sy'=>'float', 'context'=>'cairocontext'], 'cairo_matrix_transform_distance' => ['array', 'matrix'=>'cairomatrix', 'dx'=>'float', 'dy'=>'float'], 'cairo_matrix_transform_point' => ['array', 'matrix'=>'cairomatrix', 'dx'=>'float', 'dy'=>'float'], 'cairo_matrix_translate' => ['void', 'matrix'=>'cairomatrix', 'tx'=>'float', 'ty'=>'float'], 'cairo_move_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'cairo_new_path' => ['', 'context'=>'cairocontext'], 'cairo_new_sub_path' => ['', 'context'=>'cairocontext'], 'cairo_paint' => ['', 'context'=>'cairocontext'], 'cairo_paint_with_alpha' => ['', 'alpha'=>'string', 'context'=>'cairocontext'], 'cairo_path_extents' => ['array', 'context'=>'cairocontext'], 'cairo_pattern_add_color_stop_rgb' => ['void', 'pattern'=>'cairogradientpattern', 'offset'=>'float', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], 'cairo_pattern_add_color_stop_rgba' => ['void', 'pattern'=>'cairogradientpattern', 'offset'=>'float', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'alpha'=>'float'], 'cairo_pattern_create_for_surface' => ['CairoPattern', 'surface'=>'cairosurface'], 'cairo_pattern_create_linear' => ['CairoPattern', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float'], 'cairo_pattern_create_radial' => ['CairoPattern', 'x0'=>'float', 'y0'=>'float', 'r0'=>'float', 'x1'=>'float', 'y1'=>'float', 'r1'=>'float'], 'cairo_pattern_create_rgb' => ['CairoPattern', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], 'cairo_pattern_create_rgba' => ['CairoPattern', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'alpha'=>'float'], 'cairo_pattern_get_color_stop_count' => ['int', 'pattern'=>'cairogradientpattern'], 'cairo_pattern_get_color_stop_rgba' => ['array', 'pattern'=>'cairogradientpattern', 'index'=>'int'], 'cairo_pattern_get_extend' => ['int', 'pattern'=>'string'], 'cairo_pattern_get_filter' => ['int', 'pattern'=>'cairosurfacepattern'], 'cairo_pattern_get_linear_points' => ['array', 'pattern'=>'cairolineargradient'], 'cairo_pattern_get_matrix' => ['CairoMatrix', 'pattern'=>'cairopattern'], 'cairo_pattern_get_radial_circles' => ['array', 'pattern'=>'cairoradialgradient'], 'cairo_pattern_get_rgba' => ['array', 'pattern'=>'cairosolidpattern'], 'cairo_pattern_get_surface' => ['CairoSurface', 'pattern'=>'cairosurfacepattern'], 'cairo_pattern_get_type' => ['int', 'pattern'=>'cairopattern'], 'cairo_pattern_set_extend' => ['void', 'pattern'=>'string', 'extend'=>'string'], 'cairo_pattern_set_filter' => ['void', 'pattern'=>'cairosurfacepattern', 'filter'=>'int'], 'cairo_pattern_set_matrix' => ['void', 'pattern'=>'cairopattern', 'matrix'=>'cairomatrix'], 'cairo_pattern_status' => ['int', 'pattern'=>'cairopattern'], 'cairo_pdf_surface_create' => ['CairoPdfSurface', 'file'=>'string', 'width'=>'float', 'height'=>'float'], 'cairo_pdf_surface_set_size' => ['void', 'surface'=>'cairopdfsurface', 'width'=>'float', 'height'=>'float'], 'cairo_pop_group' => ['', 'context'=>'cairocontext'], 'cairo_pop_group_to_source' => ['', 'context'=>'cairocontext'], 'cairo_ps_get_levels' => ['array'], 'cairo_ps_level_to_string' => ['string', 'level'=>'int'], 'cairo_ps_surface_create' => ['CairoPsSurface', 'file'=>'string', 'width'=>'float', 'height'=>'float'], 'cairo_ps_surface_dsc_begin_page_setup' => ['void', 'surface'=>'cairopssurface'], 'cairo_ps_surface_dsc_begin_setup' => ['void', 'surface'=>'cairopssurface'], 'cairo_ps_surface_dsc_comment' => ['void', 'surface'=>'cairopssurface', 'comment'=>'string'], 'cairo_ps_surface_get_eps' => ['bool', 'surface'=>'cairopssurface'], 'cairo_ps_surface_restrict_to_level' => ['void', 'surface'=>'cairopssurface', 'level'=>'int'], 'cairo_ps_surface_set_eps' => ['void', 'surface'=>'cairopssurface', 'level'=>'bool'], 'cairo_ps_surface_set_size' => ['void', 'surface'=>'cairopssurface', 'width'=>'float', 'height'=>'float'], 'cairo_push_group' => ['', 'context'=>'cairocontext'], 'cairo_push_group_with_content' => ['', 'content'=>'string', 'context'=>'cairocontext'], 'cairo_rectangle' => ['', 'x'=>'string', 'y'=>'string', 'width'=>'string', 'height'=>'string', 'context'=>'cairocontext'], 'cairo_rel_curve_to' => ['', 'x1'=>'string', 'y1'=>'string', 'x2'=>'string', 'y2'=>'string', 'x3'=>'string', 'y3'=>'string', 'context'=>'cairocontext'], 'cairo_rel_line_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'cairo_rel_move_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'cairo_reset_clip' => ['', 'context'=>'cairocontext'], 'cairo_restore' => ['', 'context'=>'cairocontext'], 'cairo_rotate' => ['', 'sx'=>'string', 'sy'=>'string', 'context'=>'cairocontext', 'angle'=>'string'], 'cairo_save' => ['', 'context'=>'cairocontext'], 'cairo_scale' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'cairo_scaled_font_create' => ['CairoScaledFont', 'fontface'=>'cairofontface', 'matrix'=>'cairomatrix', 'ctm'=>'cairomatrix', 'fontoptions'=>'cairofontoptions'], 'cairo_scaled_font_extents' => ['array', 'scaledfont'=>'cairoscaledfont'], 'cairo_scaled_font_get_ctm' => ['CairoMatrix', 'scaledfont'=>'cairoscaledfont'], 'cairo_scaled_font_get_font_face' => ['CairoFontFace', 'scaledfont'=>'cairoscaledfont'], 'cairo_scaled_font_get_font_matrix' => ['CairoFontOptions', 'scaledfont'=>'cairoscaledfont'], 'cairo_scaled_font_get_font_options' => ['CairoFontOptions', 'scaledfont'=>'cairoscaledfont'], 'cairo_scaled_font_get_scale_matrix' => ['CairoMatrix', 'scaledfont'=>'cairoscaledfont'], 'cairo_scaled_font_get_type' => ['int', 'scaledfont'=>'cairoscaledfont'], 'cairo_scaled_font_glyph_extents' => ['array', 'scaledfont'=>'cairoscaledfont', 'glyphs'=>'array'], 'cairo_scaled_font_status' => ['int', 'scaledfont'=>'cairoscaledfont'], 'cairo_scaled_font_text_extents' => ['array', 'scaledfont'=>'cairoscaledfont', 'text'=>'string'], 'cairo_select_font_face' => ['', 'family'=>'string', 'slant='=>'string', 'weight='=>'string', 'context='=>'cairocontext'], 'cairo_set_antialias' => ['', 'antialias='=>'string', 'context='=>'cairocontext'], 'cairo_set_dash' => ['', 'dashes'=>'array', 'offset='=>'string', 'context='=>'cairocontext'], 'cairo_set_fill_rule' => ['', 'setting'=>'string', 'context'=>'cairocontext'], 'cairo_set_font_face' => ['', 'fontface'=>'cairofontface', 'context'=>'cairocontext'], 'cairo_set_font_matrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], 'cairo_set_font_options' => ['', 'fontoptions'=>'cairofontoptions', 'context'=>'cairocontext'], 'cairo_set_font_size' => ['', 'size'=>'string', 'context'=>'cairocontext'], 'cairo_set_line_cap' => ['', 'setting'=>'string', 'context'=>'cairocontext'], 'cairo_set_line_join' => ['', 'setting'=>'string', 'context'=>'cairocontext'], 'cairo_set_line_width' => ['', 'width'=>'string', 'context'=>'cairocontext'], 'cairo_set_matrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], 'cairo_set_miter_limit' => ['', 'limit'=>'string', 'context'=>'cairocontext'], 'cairo_set_operator' => ['', 'setting'=>'string', 'context'=>'cairocontext'], 'cairo_set_scaled_font' => ['', 'scaledfont'=>'cairoscaledfont', 'context'=>'cairocontext'], 'cairo_set_source' => ['', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'alpha'=>'string', 'context'=>'cairocontext', 'pattern'=>'cairopattern'], 'cairo_set_source_surface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'], 'cairo_set_tolerance' => ['', 'tolerance'=>'string', 'context'=>'cairocontext'], 'cairo_show_page' => ['', 'context'=>'cairocontext'], 'cairo_show_text' => ['', 'text'=>'string', 'context'=>'cairocontext'], 'cairo_status' => ['int', 'context'=>'cairocontext'], 'cairo_status_to_string' => ['string', 'status'=>'int'], 'cairo_stroke' => ['', 'context'=>'cairocontext'], 'cairo_stroke_extents' => ['array', 'context'=>'cairocontext'], 'cairo_stroke_preserve' => ['', 'context'=>'cairocontext'], 'cairo_surface_copy_page' => ['void', 'surface'=>'cairosurface'], 'cairo_surface_create_similar' => ['CairoSurface', 'surface'=>'cairosurface', 'content'=>'int', 'width'=>'float', 'height'=>'float'], 'cairo_surface_finish' => ['void', 'surface'=>'cairosurface'], 'cairo_surface_flush' => ['void', 'surface'=>'cairosurface'], 'cairo_surface_get_content' => ['int', 'surface'=>'cairosurface'], 'cairo_surface_get_device_offset' => ['array', 'surface'=>'cairosurface'], 'cairo_surface_get_font_options' => ['CairoFontOptions', 'surface'=>'cairosurface'], 'cairo_surface_get_type' => ['int', 'surface'=>'cairosurface'], 'cairo_surface_mark_dirty' => ['void', 'surface'=>'cairosurface'], 'cairo_surface_mark_dirty_rectangle' => ['void', 'surface'=>'cairosurface', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'], 'cairo_surface_set_device_offset' => ['void', 'surface'=>'cairosurface', 'x'=>'float', 'y'=>'float'], 'cairo_surface_set_fallback_resolution' => ['void', 'surface'=>'cairosurface', 'x'=>'float', 'y'=>'float'], 'cairo_surface_show_page' => ['void', 'surface'=>'cairosurface'], 'cairo_surface_status' => ['int', 'surface'=>'cairosurface'], 'cairo_surface_write_to_png' => ['void', 'surface'=>'cairosurface', 'stream'=>'resource'], 'cairo_svg_get_versions' => ['array'], 'cairo_svg_surface_create' => ['CairoSvgSurface', 'file'=>'string', 'width'=>'float', 'height'=>'float'], 'cairo_svg_surface_get_versions' => ['array'], 'cairo_svg_surface_restrict_to_version' => ['void', 'surface'=>'cairosvgsurface', 'version'=>'int'], 'cairo_svg_version_to_string' => ['string', 'version'=>'int'], 'cairo_text_extents' => ['array', 'text'=>'string', 'context'=>'cairocontext'], 'cairo_text_path' => ['', 'string'=>'string', 'context'=>'cairocontext', 'text'=>'string'], 'cairo_transform' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], 'cairo_translate' => ['', 'tx'=>'string', 'ty'=>'string', 'context'=>'cairocontext', 'x'=>'string', 'y'=>'string'], 'cairo_user_to_device' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'cairo_user_to_device_distance' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'cairo_version' => ['int'], 'cairo_version_string' => ['string'], 'CairoContext::__construct' => ['void', 'surface'=>'CairoSurface'], 'CairoContext::appendPath' => ['', 'path'=>'cairopath', 'context'=>'cairocontext'], 'CairoContext::arc' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'], 'CairoContext::arcNegative' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'], 'CairoContext::clip' => ['', 'context'=>'cairocontext'], 'CairoContext::clipExtents' => ['array', 'context'=>'cairocontext'], 'CairoContext::clipPreserve' => ['', 'context'=>'cairocontext'], 'CairoContext::clipRectangleList' => ['array', 'context'=>'cairocontext'], 'CairoContext::closePath' => ['', 'context'=>'cairocontext'], 'CairoContext::copyPage' => ['', 'context'=>'cairocontext'], 'CairoContext::copyPath' => ['CairoPath', 'context'=>'cairocontext'], 'CairoContext::copyPathFlat' => ['CairoPath', 'context'=>'cairocontext'], 'CairoContext::curveTo' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float', 'context'=>'cairocontext'], 'CairoContext::deviceToUser' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'], 'CairoContext::deviceToUserDistance' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'], 'CairoContext::fill' => ['', 'context'=>'cairocontext'], 'CairoContext::fillExtents' => ['array', 'context'=>'cairocontext'], 'CairoContext::fillPreserve' => ['', 'context'=>'cairocontext'], 'CairoContext::fontExtents' => ['array', 'context'=>'cairocontext'], 'CairoContext::getAntialias' => ['int', 'context'=>'cairocontext'], 'CairoContext::getCurrentPoint' => ['array', 'context'=>'cairocontext'], 'CairoContext::getDash' => ['array', 'context'=>'cairocontext'], 'CairoContext::getDashCount' => ['int', 'context'=>'cairocontext'], 'CairoContext::getFillRule' => ['int', 'context'=>'cairocontext'], 'CairoContext::getFontFace' => ['', 'context'=>'cairocontext'], 'CairoContext::getFontMatrix' => ['', 'context'=>'cairocontext'], 'CairoContext::getFontOptions' => ['', 'context'=>'cairocontext'], 'CairoContext::getGroupTarget' => ['', 'context'=>'cairocontext'], 'CairoContext::getLineCap' => ['int', 'context'=>'cairocontext'], 'CairoContext::getLineJoin' => ['int', 'context'=>'cairocontext'], 'CairoContext::getLineWidth' => ['float', 'context'=>'cairocontext'], 'CairoContext::getMatrix' => ['', 'context'=>'cairocontext'], 'CairoContext::getMiterLimit' => ['float', 'context'=>'cairocontext'], 'CairoContext::getOperator' => ['int', 'context'=>'cairocontext'], 'CairoContext::getScaledFont' => ['', 'context'=>'cairocontext'], 'CairoContext::getSource' => ['', 'context'=>'cairocontext'], 'CairoContext::getTarget' => ['', 'context'=>'cairocontext'], 'CairoContext::getTolerance' => ['float', 'context'=>'cairocontext'], 'CairoContext::glyphPath' => ['', 'glyphs'=>'array', 'context'=>'cairocontext'], 'CairoContext::hasCurrentPoint' => ['bool', 'context'=>'cairocontext'], 'CairoContext::identityMatrix' => ['', 'context'=>'cairocontext'], 'CairoContext::inFill' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'CairoContext::inStroke' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'CairoContext::lineTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'CairoContext::mask' => ['', 'pattern'=>'cairopattern', 'context'=>'cairocontext'], 'CairoContext::maskSurface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'], 'CairoContext::moveTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'CairoContext::newPath' => ['', 'context'=>'cairocontext'], 'CairoContext::newSubPath' => ['', 'context'=>'cairocontext'], 'CairoContext::paint' => ['', 'context'=>'cairocontext'], 'CairoContext::paintWithAlpha' => ['', 'alpha'=>'string', 'context'=>'cairocontext'], 'CairoContext::pathExtents' => ['array', 'context'=>'cairocontext'], 'CairoContext::popGroup' => ['', 'context'=>'cairocontext'], 'CairoContext::popGroupToSource' => ['', 'context'=>'cairocontext'], 'CairoContext::pushGroup' => ['', 'context'=>'cairocontext'], 'CairoContext::pushGroupWithContent' => ['', 'content'=>'string', 'context'=>'cairocontext'], 'CairoContext::rectangle' => ['', 'x'=>'string', 'y'=>'string', 'width'=>'string', 'height'=>'string', 'context'=>'cairocontext'], 'CairoContext::relCurveTo' => ['', 'x1'=>'string', 'y1'=>'string', 'x2'=>'string', 'y2'=>'string', 'x3'=>'string', 'y3'=>'string', 'context'=>'cairocontext'], 'CairoContext::relLineTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'CairoContext::relMoveTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'CairoContext::resetClip' => ['', 'context'=>'cairocontext'], 'CairoContext::restore' => ['', 'context'=>'cairocontext'], 'CairoContext::rotate' => ['', 'angle'=>'string', 'context'=>'cairocontext'], 'CairoContext::save' => ['', 'context'=>'cairocontext'], 'CairoContext::scale' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'CairoContext::selectFontFace' => ['', 'family'=>'string', 'slant='=>'string', 'weight='=>'string', 'context='=>'cairocontext'], 'CairoContext::setAntialias' => ['', 'antialias='=>'string', 'context='=>'cairocontext'], 'CairoContext::setDash' => ['', 'dashes'=>'array', 'offset='=>'string', 'context='=>'cairocontext'], 'CairoContext::setFillRule' => ['', 'setting'=>'string', 'context'=>'cairocontext'], 'CairoContext::setFontFace' => ['', 'fontface'=>'cairofontface', 'context'=>'cairocontext'], 'CairoContext::setFontMatrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], 'CairoContext::setFontOptions' => ['', 'fontoptions'=>'cairofontoptions', 'context'=>'cairocontext'], 'CairoContext::setFontSize' => ['', 'size'=>'string', 'context'=>'cairocontext'], 'CairoContext::setLineCap' => ['', 'setting'=>'string', 'context'=>'cairocontext'], 'CairoContext::setLineJoin' => ['', 'setting'=>'string', 'context'=>'cairocontext'], 'CairoContext::setLineWidth' => ['', 'width'=>'string', 'context'=>'cairocontext'], 'CairoContext::setMatrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], 'CairoContext::setMiterLimit' => ['', 'limit'=>'string', 'context'=>'cairocontext'], 'CairoContext::setOperator' => ['', 'setting'=>'string', 'context'=>'cairocontext'], 'CairoContext::setScaledFont' => ['', 'scaledfont'=>'cairoscaledfont', 'context'=>'cairocontext'], 'CairoContext::setSource' => ['', 'pattern'=>'cairopattern', 'context'=>'cairocontext'], 'CairoContext::setSourceRGB' => ['', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'context'=>'cairocontext', 'pattern'=>'cairopattern'], 'CairoContext::setSourceRGBA' => ['', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'alpha'=>'string', 'context'=>'cairocontext', 'pattern'=>'cairopattern'], 'CairoContext::setSourceSurface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'], 'CairoContext::setTolerance' => ['', 'tolerance'=>'string', 'context'=>'cairocontext'], 'CairoContext::showPage' => ['', 'context'=>'cairocontext'], 'CairoContext::showText' => ['', 'text'=>'string', 'context'=>'cairocontext'], 'CairoContext::status' => ['int', 'context'=>'cairocontext'], 'CairoContext::stroke' => ['', 'context'=>'cairocontext'], 'CairoContext::strokeExtents' => ['array', 'context'=>'cairocontext'], 'CairoContext::strokePreserve' => ['', 'context'=>'cairocontext'], 'CairoContext::textExtents' => ['array', 'text'=>'string', 'context'=>'cairocontext'], 'CairoContext::textPath' => ['', 'string'=>'string', 'context'=>'cairocontext', 'text'=>'string'], 'CairoContext::transform' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], 'CairoContext::translate' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'CairoContext::userToDevice' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'CairoContext::userToDeviceDistance' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], 'CairoFontFace::__construct' => ['void'], 'CairoFontFace::getType' => ['int'], 'CairoFontFace::status' => ['int', 'fontface'=>'cairofontface'], 'CairoFontOptions::__construct' => ['void'], 'CairoFontOptions::equal' => ['bool', 'other'=>'string'], 'CairoFontOptions::getAntialias' => ['int', 'context'=>'cairocontext'], 'CairoFontOptions::getHintMetrics' => ['int'], 'CairoFontOptions::getHintStyle' => ['int'], 'CairoFontOptions::getSubpixelOrder' => ['int'], 'CairoFontOptions::hash' => ['int'], 'CairoFontOptions::merge' => ['void', 'other'=>'string'], 'CairoFontOptions::setAntialias' => ['', 'antialias='=>'string', 'context='=>'cairocontext'], 'CairoFontOptions::setHintMetrics' => ['void', 'hint_metrics'=>'string'], 'CairoFontOptions::setHintStyle' => ['void', 'hint_style'=>'string'], 'CairoFontOptions::setSubpixelOrder' => ['void', 'subpixel_order'=>'string'], 'CairoFontOptions::status' => ['int', 'context'=>'cairocontext'], 'CairoFormat::strideForWidth' => ['int', 'format'=>'int', 'width'=>'int'], 'CairoGradientPattern::addColorStopRgb' => ['void', 'offset'=>'string', 'red'=>'string', 'green'=>'string', 'blue'=>'string'], 'CairoGradientPattern::addColorStopRgba' => ['void', 'offset'=>'string', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'alpha'=>'string'], 'CairoGradientPattern::getColorStopCount' => ['int'], 'CairoGradientPattern::getColorStopRgba' => ['array', 'index'=>'string'], 'CairoGradientPattern::getExtend' => ['int'], 'CairoGradientPattern::setExtend' => ['void', 'extend'=>'int'], 'CairoImageSurface::__construct' => ['void', 'format'=>'int', 'width'=>'int', 'height'=>'int'], 'CairoImageSurface::createForData' => ['void', 'data'=>'string', 'format'=>'int', 'width'=>'int', 'height'=>'int', 'stride='=>'int'], 'CairoImageSurface::createFromPng' => ['CairoImageSurface', 'file'=>'string'], 'CairoImageSurface::getData' => ['string'], 'CairoImageSurface::getFormat' => ['int'], 'CairoImageSurface::getHeight' => ['int'], 'CairoImageSurface::getStride' => ['int'], 'CairoImageSurface::getWidth' => ['int'], 'CairoLinearGradient::__construct' => ['void', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float'], 'CairoLinearGradient::getPoints' => ['array'], 'CairoMatrix::__construct' => ['void', 'xx='=>'float', 'yx='=>'float', 'xy='=>'float', 'yy='=>'float', 'x0='=>'float', 'y0='=>'float'], 'CairoMatrix::initIdentity' => ['object'], 'CairoMatrix::initRotate' => ['object', 'radians'=>'float'], 'CairoMatrix::initScale' => ['object', 'sx'=>'float', 'sy'=>'float'], 'CairoMatrix::initTranslate' => ['object', 'tx'=>'float', 'ty'=>'float'], 'CairoMatrix::invert' => ['void'], 'CairoMatrix::multiply' => ['CairoMatrix', 'matrix1'=>'cairomatrix', 'matrix2'=>'cairomatrix'], 'CairoMatrix::rotate' => ['', 'sx'=>'string', 'sy'=>'string', 'context'=>'cairocontext', 'angle'=>'string'], 'CairoMatrix::scale' => ['', 'sx'=>'float', 'sy'=>'float', 'context'=>'cairocontext'], 'CairoMatrix::transformDistance' => ['array', 'dx'=>'string', 'dy'=>'string'], 'CairoMatrix::transformPoint' => ['array', 'dx'=>'string', 'dy'=>'string'], 'CairoMatrix::translate' => ['', 'tx'=>'string', 'ty'=>'string', 'context'=>'cairocontext', 'x'=>'string', 'y'=>'string'], 'CairoPattern::__construct' => ['void'], 'CairoPattern::getMatrix' => ['', 'context'=>'cairocontext'], 'CairoPattern::getType' => ['int'], 'CairoPattern::setMatrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], 'CairoPattern::status' => ['int', 'context'=>'cairocontext'], 'CairoPdfSurface::__construct' => ['void', 'file'=>'string', 'width'=>'float', 'height'=>'float'], 'CairoPdfSurface::setSize' => ['void', 'width'=>'string', 'height'=>'string'], 'CairoPsSurface::__construct' => ['void', 'file'=>'string', 'width'=>'float', 'height'=>'float'], 'CairoPsSurface::dscBeginPageSetup' => ['void'], 'CairoPsSurface::dscBeginSetup' => ['void'], 'CairoPsSurface::dscComment' => ['void', 'comment'=>'string'], 'CairoPsSurface::getEps' => ['bool'], 'CairoPsSurface::getLevels' => ['array'], 'CairoPsSurface::levelToString' => ['string', 'level'=>'int'], 'CairoPsSurface::restrictToLevel' => ['void', 'level'=>'string'], 'CairoPsSurface::setEps' => ['void', 'level'=>'string'], 'CairoPsSurface::setSize' => ['void', 'width'=>'string', 'height'=>'string'], 'CairoRadialGradient::__construct' => ['void', 'x0'=>'float', 'y0'=>'float', 'r0'=>'float', 'x1'=>'float', 'y1'=>'float', 'r1'=>'float'], 'CairoRadialGradient::getCircles' => ['array'], 'CairoScaledFont::__construct' => ['void', 'font_face'=>'CairoFontFace', 'matrix'=>'CairoMatrix', 'ctm'=>'CairoMatrix', 'options'=>'CairoFontOptions'], 'CairoScaledFont::extents' => ['array'], 'CairoScaledFont::getCtm' => ['CairoMatrix'], 'CairoScaledFont::getFontFace' => ['', 'context'=>'cairocontext'], 'CairoScaledFont::getFontMatrix' => ['', 'context'=>'cairocontext'], 'CairoScaledFont::getFontOptions' => ['', 'context'=>'cairocontext'], 'CairoScaledFont::getScaleMatrix' => ['void'], 'CairoScaledFont::getType' => ['int'], 'CairoScaledFont::glyphExtents' => ['array', 'glyphs'=>'string'], 'CairoScaledFont::status' => ['int', 'context'=>'cairocontext'], 'CairoScaledFont::textExtents' => ['array', 'text'=>'string', 'context'=>'cairocontext'], 'CairoSolidPattern::__construct' => ['void', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'alpha='=>'float'], 'CairoSolidPattern::getRgba' => ['array'], 'CairoSurface::__construct' => ['void'], 'CairoSurface::copyPage' => ['', 'context'=>'cairocontext'], 'CairoSurface::createSimilar' => ['void', 'other'=>'cairosurface', 'content'=>'int', 'width'=>'string', 'height'=>'string'], 'CairoSurface::finish' => ['void'], 'CairoSurface::flush' => ['void'], 'CairoSurface::getContent' => ['int'], 'CairoSurface::getDeviceOffset' => ['array'], 'CairoSurface::getFontOptions' => ['', 'context'=>'cairocontext'], 'CairoSurface::getType' => ['int'], 'CairoSurface::markDirty' => ['void'], 'CairoSurface::markDirtyRectangle' => ['void', 'x'=>'string', 'y'=>'string', 'width'=>'string', 'height'=>'string'], 'CairoSurface::setDeviceOffset' => ['void', 'x'=>'string', 'y'=>'string'], 'CairoSurface::setFallbackResolution' => ['void', 'x'=>'string', 'y'=>'string'], 'CairoSurface::showPage' => ['', 'context'=>'cairocontext'], 'CairoSurface::status' => ['int', 'context'=>'cairocontext'], 'CairoSurface::writeToPng' => ['void', 'file'=>'string'], 'CairoSurfacePattern::__construct' => ['void', 'surface'=>'CairoSurface'], 'CairoSurfacePattern::getExtend' => ['int'], 'CairoSurfacePattern::getFilter' => ['int'], 'CairoSurfacePattern::getSurface' => ['void'], 'CairoSurfacePattern::setExtend' => ['void', 'extend'=>'int'], 'CairoSurfacePattern::setFilter' => ['void', 'filter'=>'string'], 'CairoSvgSurface::__construct' => ['void', 'file'=>'string', 'width'=>'float', 'height'=>'float'], 'CairoSvgSurface::getVersions' => ['array'], 'CairoSvgSurface::restrictToVersion' => ['void', 'version'=>'string'], 'CairoSvgSurface::versionToString' => ['string', 'version'=>'int'], 'cal_days_in_month' => ['int', 'calendar'=>'int', 'month'=>'int', 'year'=>'int'], 'cal_from_jd' => ['array', 'jd'=>'int', 'calendar'=>'int'], 'cal_info' => ['array', 'calendar='=>'int'], 'cal_to_jd' => ['int', 'calendar'=>'int', 'month'=>'int', 'day'=>'int', 'year'=>'int'], 'calcul_hmac' => ['string', 'clent'=>'string', 'siretcode'=>'string', 'price'=>'string', 'reference'=>'string', 'validity'=>'string', 'taxation'=>'string', 'devise'=>'string', 'language'=>'string'], 'calculhmac' => ['string', 'clent'=>'string', 'data'=>'string'], 'call_user_func' => ['mixed', 'function'=>'callable', '...parameters='=>'mixed'], 'call_user_func_array' => ['mixed', 'function'=>'callable', 'parameters'=>'array'], 'call_user_method' => ['mixed', 'method_name'=>'string', 'obj'=>'object', 'parameter='=>'mixed', '...args='=>'mixed'], 'call_user_method_array' => ['mixed', 'method_name'=>'string', 'obj'=>'object', 'params'=>'array'], 'CallbackFilterIterator::__construct' => ['void', 'iterator'=>'Iterator', 'func'=>'callable'], 'CallbackFilterIterator::accept' => ['bool'], 'CallbackFilterIterator::current' => ['mixed'], 'CallbackFilterIterator::getInnerIterator' => ['Iterator'], 'CallbackFilterIterator::key' => ['mixed'], 'CallbackFilterIterator::next' => ['void'], 'CallbackFilterIterator::rewind' => ['void'], 'CallbackFilterIterator::valid' => ['bool'], 'ceil' => ['__benevolent', 'number'=>'float'], 'chdb::__construct' => ['void', 'pathname'=>'string'], 'chdb::get' => ['string', 'key'=>'string'], 'chdb_create' => ['bool', 'pathname'=>'string', 'data'=>'array'], 'chdir' => ['bool', 'directory'=>'string'], 'checkdate' => ['bool', 'month'=>'int', 'day'=>'int', 'year'=>'int'], 'checkdnsrr' => ['bool', 'host'=>'string', 'type='=>'string'], 'chgrp' => ['bool', 'filename'=>'string', 'group'=>'string|int'], 'chmod' => ['bool', 'filename'=>'string', 'mode'=>'int'], 'chop' => ['string', 'str'=>'string', 'character_mask='=>'string'], 'chown' => ['bool', 'filename'=>'string', 'user'=>'string|int'], 'chr' => ['non-empty-string', 'ascii'=>'int'], 'chroot' => ['bool', 'directory'=>'string'], 'chunk_split' => ['string', 'str'=>'string', 'chunklen='=>'positive-int', 'ending='=>'string'], 'class_alias' => ['bool', 'user_class_name'=>'string', 'alias_name'=>'string', 'autoload='=>'bool'], 'class_exists' => ['bool', 'classname'=>'string', 'autoload='=>'bool'], 'class_implements' => ['array|false', 'what'=>'object|string', 'autoload='=>'bool'], 'class_parents' => ['array|false', 'instance'=>'object|string', 'autoload='=>'bool'], 'class_uses' => ['array|false', 'what'=>'object|string', 'autoload='=>'bool'], 'classkit_import' => ['array', 'filename'=>'string'], 'classkit_method_add' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int'], 'classkit_method_copy' => ['bool', 'dclass'=>'string', 'dmethod'=>'string', 'sclass'=>'string', 'smethod='=>'string'], 'classkit_method_redefine' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int'], 'classkit_method_remove' => ['bool', 'classname'=>'string', 'methodname'=>'string'], 'classkit_method_rename' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'newname'=>'string'], 'classObj::__construct' => ['void', 'layer'=>'layerObj', 'class'=>'classObj'], 'classObj::addLabel' => ['int', 'label'=>'labelObj'], 'classObj::convertToString' => ['string'], 'classObj::createLegendIcon' => ['imageObj', 'width'=>'int', 'height'=>'int'], 'classObj::deletestyle' => ['int', 'index'=>'int'], 'classObj::drawLegendIcon' => ['int', 'width'=>'int', 'height'=>'int', 'im'=>'imageObj', 'dstX'=>'int', 'dstY'=>'int'], 'classObj::free' => ['void'], 'classObj::getExpressionString' => ['string'], 'classObj::getLabel' => ['labelObj', 'index'=>'int'], 'classObj::getMetaData' => ['int', 'name'=>'string'], 'classObj::getStyle' => ['styleObj', 'index'=>'int'], 'classObj::getTextString' => ['string'], 'classObj::movestyledown' => ['int', 'index'=>'int'], 'classObj::movestyleup' => ['int', 'index'=>'int'], 'classObj::ms_newClassObj' => ['classObj', 'layer'=>'layerObj', 'class'=>'classObj'], 'classObj::removeLabel' => ['labelObj', 'index'=>'int'], 'classObj::removeMetaData' => ['int', 'name'=>'string'], 'classObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], 'classObj::setExpression' => ['int', 'expression'=>'string'], 'classObj::setMetaData' => ['int', 'name'=>'string', 'value'=>'string'], 'classObj::settext' => ['int', 'text'=>'string'], 'classObj::updateFromString' => ['int', 'snippet'=>'string'], 'clearstatcache' => ['void', 'clear_realpath_cache='=>'bool', 'filename='=>'string'], 'cli_get_process_title' => ['string'], 'cli_set_process_title' => ['bool', 'arg'=>'string'], 'ClosedGeneratorException::__clone' => ['void'], 'ClosedGeneratorException::__toString' => ['string'], 'ClosedGeneratorException::getCode' => ['int'], 'ClosedGeneratorException::getFile' => ['string'], 'ClosedGeneratorException::getLine' => ['int'], 'ClosedGeneratorException::getMessage' => ['string'], 'ClosedGeneratorException::getPrevious' => ['Throwable|ClosedGeneratorException|null'], 'ClosedGeneratorException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'ClosedGeneratorException::getTraceAsString' => ['string'], 'closedir' => ['void', 'dir_handle='=>'resource'], 'closelog' => ['bool'], 'Closure::__construct' => ['void'], 'Closure::__invoke' => ['', '...args='=>''], 'Closure::bind' => ['__benevolent', 'old'=>'Closure', 'to'=>'?object', 'scope='=>'object|string|null'], 'Closure::bindTo' => ['__benevolent', 'new'=>'?object', 'newscope='=>'object|string|null'], 'Closure::call' => ['', 'to'=>'object', '...parameters='=>''], 'Closure::fromCallable' => ['Closure', 'callable'=>'callable'], 'clusterObj::convertToString' => ['string'], 'clusterObj::getFilterString' => ['string'], 'clusterObj::getGroupString' => ['string'], 'clusterObj::setFilter' => ['int', 'expression'=>'string'], 'clusterObj::setGroup' => ['int', 'expression'=>'string'], 'Collator::__construct' => ['void', 'locale'=>'string'], 'Collator::asort' => ['bool', '&rw_arr'=>'array', 'sort_flag='=>'int'], 'Collator::compare' => ['int|false', 'str1'=>'string', 'str2'=>'string'], 'Collator::create' => ['?Collator', 'locale'=>'string'], 'Collator::getAttribute' => ['int', 'attr'=>'int'], 'Collator::getErrorCode' => ['int'], 'Collator::getErrorMessage' => ['string'], 'Collator::getLocale' => ['string', 'type'=>'int'], 'Collator::getSortKey' => ['string', 'str'=>'string'], 'Collator::getStrength' => ['int'], 'Collator::setAttribute' => ['bool', 'attr'=>'int', 'val'=>'int'], 'Collator::setStrength' => ['bool', 'strength'=>'int'], 'Collator::sort' => ['bool', '&rw_arr'=>'array', 'sort_flags='=>'int'], 'Collator::sortWithSortKeys' => ['bool', '&rw_arr'=>'array'], 'collator_asort' => ['bool', 'coll'=>'collator', '&rw_arr'=>'array', 'sort_flag='=>'int'], 'collator_compare' => ['int|false', 'coll'=>'collator', 'str1'=>'string', 'str2'=>'string'], 'collator_create' => ['?Collator', 'locale'=>'string'], 'collator_get_attribute' => ['int|false', 'coll'=>'collator', 'attr'=>'int'], 'collator_get_error_code' => ['int|false', 'coll'=>'collator'], 'collator_get_error_message' => ['string|false', 'coll'=>'collator'], 'collator_get_locale' => ['string|false', 'coll'=>'collator', 'type'=>'int'], 'collator_get_sort_key' => ['string|false', 'coll'=>'collator', 'str'=>'string'], 'collator_get_strength' => ['int', 'coll'=>'collator'], 'collator_set_attribute' => ['bool', 'coll'=>'collator', 'attr'=>'int', 'val'=>'int'], 'collator_set_strength' => ['bool', 'coll'=>'collator', 'strength'=>'int'], 'collator_sort' => ['bool', 'coll'=>'collator', '&rw_arr'=>'array', 'sort_flag='=>'int'], 'collator_sort_with_sort_keys' => ['bool', 'coll'=>'collator', '&rw_arr'=>'array'], 'Collectable::isGarbage' => ['bool'], 'colorObj::setHex' => ['int', 'hex'=>'string'], 'colorObj::toHex' => ['string'], 'COM::__call' => ['', 'name'=>'', 'args'=>''], 'COM::__construct' => ['void', 'module_name'=>'string', 'server_name='=>'mixed', 'codepage='=>'int', 'typelib='=>'string'], 'COM::__get' => ['', 'name'=>''], 'COM::__set' => ['', 'name'=>'', 'value'=>''], 'com_addref' => [''], 'com_create_guid' => ['string|false'], 'com_event_sink' => ['bool', 'comobject'=>'object', 'sinkobject'=>'object', 'sinkinterface='=>'mixed'], 'com_get_active_object' => ['object', 'progid'=>'string', 'code_page='=>'int'], 'com_isenum' => ['bool', 'com_module'=>'variant'], 'com_load_typelib' => ['bool', 'typelib_name'=>'string', 'case_insensitive='=>'int'], 'com_message_pump' => ['bool', 'timeoutms='=>'int'], 'com_print_typeinfo' => ['bool', 'comobject_or_typelib'=>'object', 'dispinterface='=>'string', 'wantsink='=>'bool'], 'com_release' => [''], 'compact' => ['array', '...var_names='=>'string|array'], 'COMPersistHelper::__construct' => ['void', 'com_object'=>'object'], 'COMPersistHelper::GetCurFile' => ['string'], 'COMPersistHelper::GetMaxStreamSize' => ['int'], 'COMPersistHelper::InitNew' => ['int'], 'COMPersistHelper::LoadFromFile' => ['bool', 'filename'=>'string', 'flags'=>'int'], 'COMPersistHelper::LoadFromStream' => ['', 'stream'=>''], 'COMPersistHelper::SaveToFile' => ['bool', 'filename'=>'string', 'remember'=>'bool'], 'COMPersistHelper::SaveToStream' => ['int', 'stream'=>''], 'componere\cast' => ['Type', 'arg1'=>'', 'object'=>''], 'componere\cast_by_ref' => ['Type', 'arg1'=>'', 'object'=>''], 'confirm_pdo_ibm_compiled' => [''], 'connection_aborted' => ['0|1'], 'connection_status' => ['int-mask'], 'connection_timeout' => ['int'], 'constant' => ['mixed', 'const_name'=>'string'], 'convert_cyr_string' => ['string', 'str'=>'string', 'from'=>'string', 'to'=>'string'], 'convert_uudecode' => ['string|false', 'data'=>'string'], 'convert_uuencode' => ['string', 'data'=>'string'], 'copy' => ['bool', 'source_file'=>'string', 'destination_file'=>'string', 'context='=>'resource'], 'cos' => ['float', 'number'=>'float'], 'cosh' => ['float', 'number'=>'float'], 'Couchbase\AnalyticsQuery::__construct' => ['void'], 'Couchbase\AnalyticsQuery::fromString' => ['Couchbase\AnalyticsQuery', 'statement'=>'string'], 'Couchbase\basicDecoderV1' => ['mixed', 'bytes'=>'string', 'flags'=>'int', 'datatype'=>'int', 'options'=>'array'], 'Couchbase\basicEncoderV1' => ['array', 'value'=>'mixed', 'options'=>'array'], 'Couchbase\BooleanFieldSearchQuery::__construct' => ['void'], 'Couchbase\BooleanFieldSearchQuery::boost' => ['Couchbase\BooleanFieldSearchQuery', 'boost'=>'float'], 'Couchbase\BooleanFieldSearchQuery::field' => ['Couchbase\BooleanFieldSearchQuery', 'field'=>'string'], 'Couchbase\BooleanFieldSearchQuery::jsonSerialize' => ['array'], 'Couchbase\BooleanSearchQuery::__construct' => ['void'], 'Couchbase\BooleanSearchQuery::boost' => ['Couchbase\BooleanSearchQuery', 'boost'=>'float'], 'Couchbase\BooleanSearchQuery::jsonSerialize' => ['array'], 'Couchbase\BooleanSearchQuery::must' => ['Couchbase\BooleanSearchQuery', '...queries='=>'array'], 'Couchbase\BooleanSearchQuery::mustNot' => ['Couchbase\BooleanSearchQuery', '...queries='=>'array'], 'Couchbase\BooleanSearchQuery::should' => ['Couchbase\BooleanSearchQuery', '...queries='=>'array'], 'Couchbase\Bucket::__construct' => ['void'], 'Couchbase\Bucket::__get' => ['int', 'name'=>'string'], 'Couchbase\Bucket::__set' => ['int', 'name'=>'string', 'value'=>'int'], 'Couchbase\Bucket::append' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'], 'Couchbase\Bucket::counter' => ['Couchbase\Document|array', 'ids'=>'array|string', 'delta='=>'int', 'options='=>'array'], 'Couchbase\Bucket::diag' => ['array', 'reportId='=>'string'], 'Couchbase\Bucket::get' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'], 'Couchbase\Bucket::getAndLock' => ['Couchbase\Document|array', 'ids'=>'array|string', 'lockTime'=>'int', 'options='=>'array'], 'Couchbase\Bucket::getAndTouch' => ['Couchbase\Document|array', 'ids'=>'array|string', 'expiry'=>'int', 'options='=>'array'], 'Couchbase\Bucket::getFromReplica' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'], 'Couchbase\Bucket::insert' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'], 'Couchbase\Bucket::listExists' => ['bool', 'id'=>'string', 'value'=>'mixed'], 'Couchbase\Bucket::listGet' => ['mixed', 'id'=>'string', 'index'=>'int'], 'Couchbase\Bucket::listPush' => ['', 'id'=>'string', 'value'=>'mixed'], 'Couchbase\Bucket::listRemove' => ['', 'id'=>'string', 'index'=>'int'], 'Couchbase\Bucket::listSet' => ['', 'id'=>'string', 'index'=>'int', 'value'=>'mixed'], 'Couchbase\Bucket::listShift' => ['', 'id'=>'string', 'value'=>'mixed'], 'Couchbase\Bucket::listSize' => ['int', 'id'=>'string'], 'Couchbase\Bucket::lookupIn' => ['Couchbase\LookupInBuilder', 'id'=>'string'], 'Couchbase\Bucket::manager' => ['Couchbase\BucketManager'], 'Couchbase\Bucket::mapAdd' => ['', 'id'=>'string', 'key'=>'string', 'value'=>'mixed'], 'Couchbase\Bucket::mapGet' => ['mixed', 'id'=>'string', 'key'=>'string'], 'Couchbase\Bucket::mapRemove' => ['', 'id'=>'string', 'key'=>'string'], 'Couchbase\Bucket::mapSize' => ['int', 'id'=>'string'], 'Couchbase\Bucket::mutateIn' => ['Couchbase\MutateInBuilder', 'id'=>'string', 'cas'=>'string'], 'Couchbase\Bucket::ping' => ['array', 'services='=>'int', 'reportId='=>'string'], 'Couchbase\Bucket::prepend' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'], 'Couchbase\Bucket::query' => ['object', 'query'=>'Couchbase\AnalyticsQuery|Couchbase\N1qlQuery|Couchbase\SearchQuery|Couchbase\SpatialViewQuery|Couchbase\ViewQuery', 'jsonAsArray='=>'bool|false'], 'Couchbase\Bucket::queueAdd' => ['', 'id'=>'string', 'value'=>'mixed'], 'Couchbase\Bucket::queueExists' => ['bool', 'id'=>'string', 'value'=>'mixed'], 'Couchbase\Bucket::queueRemove' => ['mixed', 'id'=>'string'], 'Couchbase\Bucket::queueSize' => ['int', 'id'=>'string'], 'Couchbase\Bucket::remove' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'], 'Couchbase\Bucket::replace' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'], 'Couchbase\Bucket::retrieveIn' => ['Couchbase\DocumentFragment', 'id'=>'string', '...paths='=>'array'], 'Couchbase\Bucket::setAdd' => ['', 'id'=>'string', 'value'=>'bool|float|int|string'], 'Couchbase\Bucket::setExists' => ['bool', 'id'=>'string', 'value'=>'bool|float|int|string'], 'Couchbase\Bucket::setRemove' => ['', 'id'=>'string', 'value'=>'bool|float|int|string'], 'Couchbase\Bucket::setSize' => ['int', 'id'=>'string'], 'Couchbase\Bucket::setTranscoder' => ['', 'encoder'=>'callable', 'decoder'=>'callable'], 'Couchbase\Bucket::touch' => ['Couchbase\Document|array', 'ids'=>'array|string', 'expiry'=>'int', 'options='=>'array'], 'Couchbase\Bucket::unlock' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'], 'Couchbase\Bucket::upsert' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'], 'Couchbase\BucketManager::__construct' => ['void'], 'Couchbase\BucketManager::createN1qlIndex' => ['', 'name'=>'string', 'fields'=>'array', 'whereClause='=>'string', 'ignoreIfExist='=>'bool|false', 'defer='=>'bool|false'], 'Couchbase\BucketManager::createN1qlPrimaryIndex' => ['', 'customName='=>'string', 'ignoreIfExist='=>'bool|false', 'defer='=>'bool|false'], 'Couchbase\BucketManager::dropN1qlIndex' => ['', 'name'=>'string', 'ignoreIfNotExist='=>'bool|false'], 'Couchbase\BucketManager::dropN1qlPrimaryIndex' => ['', 'customName='=>'string', 'ignoreIfNotExist='=>'bool|false'], 'Couchbase\BucketManager::flush' => [''], 'Couchbase\BucketManager::getDesignDocument' => ['array', 'name'=>'string'], 'Couchbase\BucketManager::info' => ['array'], 'Couchbase\BucketManager::insertDesignDocument' => ['', 'name'=>'string', 'document'=>'array'], 'Couchbase\BucketManager::listDesignDocuments' => ['array'], 'Couchbase\BucketManager::listN1qlIndexes' => ['array'], 'Couchbase\BucketManager::removeDesignDocument' => ['', 'name'=>'string'], 'Couchbase\BucketManager::upsertDesignDocument' => ['', 'name'=>'string', 'document'=>'array'], 'Couchbase\ClassicAuthenticator::bucket' => ['', 'name'=>'string', 'password'=>'string'], 'Couchbase\ClassicAuthenticator::cluster' => ['', 'username'=>'string', 'password'=>'string'], 'Couchbase\Cluster::__construct' => ['void', 'connstr'=>'string'], 'Couchbase\Cluster::authenticate' => ['null', 'authenticator'=>'Couchbase\Authenticator'], 'Couchbase\Cluster::authenticateAs' => ['null', 'username'=>'string', 'password'=>'string'], 'Couchbase\Cluster::manager' => ['Couchbase\ClusterManager', 'username='=>'string', 'password='=>'string'], 'Couchbase\Cluster::openBucket' => ['Couchbase\Bucket', 'name='=>'string', 'password='=>'string'], 'Couchbase\ClusterManager::__construct' => ['void'], 'Couchbase\ClusterManager::createBucket' => ['', 'name'=>'string', 'options='=>'array'], 'Couchbase\ClusterManager::getUser' => ['array', 'username'=>'string', 'domain='=>'int'], 'Couchbase\ClusterManager::info' => ['array'], 'Couchbase\ClusterManager::listBuckets' => ['array'], 'Couchbase\ClusterManager::listUsers' => ['array', 'domain='=>'int'], 'Couchbase\ClusterManager::removeBucket' => ['', 'name'=>'string'], 'Couchbase\ClusterManager::removeUser' => ['', 'name'=>'string', 'domain='=>'int'], 'Couchbase\ClusterManager::upsertUser' => ['', 'name'=>'string', 'settings'=>'Couchbase\UserSettings', 'domain='=>'int'], 'Couchbase\ConjunctionSearchQuery::__construct' => ['void'], 'Couchbase\ConjunctionSearchQuery::boost' => ['Couchbase\ConjunctionSearchQuery', 'boost'=>'float'], 'Couchbase\ConjunctionSearchQuery::every' => ['Couchbase\ConjunctionSearchQuery', '...queries='=>'array'], 'Couchbase\ConjunctionSearchQuery::jsonSerialize' => ['array'], 'Couchbase\DateRangeSearchFacet::__construct' => ['void'], 'Couchbase\DateRangeSearchFacet::addRange' => ['Couchbase\DateSearchFacet', 'name'=>'string', 'start'=>'int|string', 'end'=>'int|string'], 'Couchbase\DateRangeSearchFacet::jsonSerialize' => ['array'], 'Couchbase\DateRangeSearchQuery::__construct' => ['void'], 'Couchbase\DateRangeSearchQuery::boost' => ['Couchbase\DateRangeSearchQuery', 'boost'=>'float'], 'Couchbase\DateRangeSearchQuery::dateTimeParser' => ['Couchbase\DateRangeSearchQuery', 'dateTimeParser'=>'string'], 'Couchbase\DateRangeSearchQuery::end' => ['Couchbase\DateRangeSearchQuery', 'end'=>'int|string', 'inclusive='=>'bool|false'], 'Couchbase\DateRangeSearchQuery::field' => ['Couchbase\DateRangeSearchQuery', 'field'=>'string'], 'Couchbase\DateRangeSearchQuery::jsonSerialize' => ['array'], 'Couchbase\DateRangeSearchQuery::start' => ['Couchbase\DateRangeSearchQuery', 'start'=>'int|string', 'inclusive='=>'bool|true'], 'Couchbase\defaultDecoder' => ['mixed', 'bytes'=>'string', 'flags'=>'int', 'datatype'=>'int'], 'Couchbase\defaultEncoder' => ['array', 'value'=>'mixed'], 'Couchbase\DisjunctionSearchQuery::__construct' => ['void'], 'Couchbase\DisjunctionSearchQuery::boost' => ['Couchbase\DisjunctionSearchQuery', 'boost'=>'float'], 'Couchbase\DisjunctionSearchQuery::either' => ['Couchbase\DisjunctionSearchQuery', '...queries='=>'array'], 'Couchbase\DisjunctionSearchQuery::jsonSerialize' => ['array'], 'Couchbase\DisjunctionSearchQuery::min' => ['Couchbase\DisjunctionSearchQuery', 'min'=>'int'], 'Couchbase\DocIdSearchQuery::__construct' => ['void'], 'Couchbase\DocIdSearchQuery::boost' => ['Couchbase\DocIdSearchQuery', 'boost'=>'float'], 'Couchbase\DocIdSearchQuery::docIds' => ['Couchbase\DocIdSearchQuery', '...documentIds='=>'array'], 'Couchbase\DocIdSearchQuery::field' => ['Couchbase\DocIdSearchQuery', 'field'=>'string'], 'Couchbase\DocIdSearchQuery::jsonSerialize' => ['array'], 'Couchbase\fastlzCompress' => ['string', 'data'=>'string'], 'Couchbase\fastlzDecompress' => ['string', 'data'=>'string'], 'Couchbase\GeoBoundingBoxSearchQuery::__construct' => ['void'], 'Couchbase\GeoBoundingBoxSearchQuery::boost' => ['Couchbase\GeoBoundingBoxSearchQuery', 'boost'=>'float'], 'Couchbase\GeoBoundingBoxSearchQuery::field' => ['Couchbase\GeoBoundingBoxSearchQuery', 'field'=>'string'], 'Couchbase\GeoBoundingBoxSearchQuery::jsonSerialize' => ['array'], 'Couchbase\GeoDistanceSearchQuery::__construct' => ['void'], 'Couchbase\GeoDistanceSearchQuery::boost' => ['Couchbase\GeoDistanceSearchQuery', 'boost'=>'float'], 'Couchbase\GeoDistanceSearchQuery::field' => ['Couchbase\GeoDistanceSearchQuery', 'field'=>'string'], 'Couchbase\GeoDistanceSearchQuery::jsonSerialize' => ['array'], 'Couchbase\LookupInBuilder::__construct' => ['void'], 'Couchbase\LookupInBuilder::execute' => ['Couchbase\DocumentFragment'], 'Couchbase\LookupInBuilder::exists' => ['Couchbase\LookupInBuilder', 'path'=>'string', 'options='=>'array'], 'Couchbase\LookupInBuilder::get' => ['Couchbase\LookupInBuilder', 'path'=>'string', 'options='=>'array'], 'Couchbase\LookupInBuilder::getCount' => ['Couchbase\LookupInBuilder', 'path'=>'string', 'options='=>'array'], 'Couchbase\MatchAllSearchQuery::__construct' => ['void'], 'Couchbase\MatchAllSearchQuery::boost' => ['Couchbase\MatchAllSearchQuery', 'boost'=>'float'], 'Couchbase\MatchAllSearchQuery::jsonSerialize' => ['array'], 'Couchbase\MatchNoneSearchQuery::__construct' => ['void'], 'Couchbase\MatchNoneSearchQuery::boost' => ['Couchbase\MatchNoneSearchQuery', 'boost'=>'float'], 'Couchbase\MatchNoneSearchQuery::jsonSerialize' => ['array'], 'Couchbase\MatchPhraseSearchQuery::__construct' => ['void'], 'Couchbase\MatchPhraseSearchQuery::analyzer' => ['Couchbase\MatchPhraseSearchQuery', 'analyzer'=>'string'], 'Couchbase\MatchPhraseSearchQuery::boost' => ['Couchbase\MatchPhraseSearchQuery', 'boost'=>'float'], 'Couchbase\MatchPhraseSearchQuery::field' => ['Couchbase\MatchPhraseSearchQuery', 'field'=>'string'], 'Couchbase\MatchPhraseSearchQuery::jsonSerialize' => ['array'], 'Couchbase\MatchSearchQuery::__construct' => ['void'], 'Couchbase\MatchSearchQuery::analyzer' => ['Couchbase\MatchSearchQuery', 'analyzer'=>'string'], 'Couchbase\MatchSearchQuery::boost' => ['Couchbase\MatchSearchQuery', 'boost'=>'float'], 'Couchbase\MatchSearchQuery::field' => ['Couchbase\MatchSearchQuery', 'field'=>'string'], 'Couchbase\MatchSearchQuery::fuzziness' => ['Couchbase\MatchSearchQuery', 'fuzziness'=>'int'], 'Couchbase\MatchSearchQuery::jsonSerialize' => ['array'], 'Couchbase\MatchSearchQuery::prefixLength' => ['Couchbase\MatchSearchQuery', 'prefixLength'=>'int'], 'Couchbase\MutateInBuilder::__construct' => ['void'], 'Couchbase\MutateInBuilder::arrayAddUnique' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'], 'Couchbase\MutateInBuilder::arrayAppend' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'], 'Couchbase\MutateInBuilder::arrayAppendAll' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'values'=>'array', 'options='=>'array|bool'], 'Couchbase\MutateInBuilder::arrayInsert' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array'], 'Couchbase\MutateInBuilder::arrayInsertAll' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'values'=>'array', 'options='=>'array'], 'Couchbase\MutateInBuilder::arrayPrepend' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'], 'Couchbase\MutateInBuilder::arrayPrependAll' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'values'=>'array', 'options='=>'array|bool'], 'Couchbase\MutateInBuilder::counter' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'delta'=>'int', 'options='=>'array|bool'], 'Couchbase\MutateInBuilder::execute' => ['Couchbase\DocumentFragment'], 'Couchbase\MutateInBuilder::insert' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'], 'Couchbase\MutateInBuilder::modeDocument' => ['', 'mode'=>'int'], 'Couchbase\MutateInBuilder::remove' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'options='=>'array'], 'Couchbase\MutateInBuilder::replace' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array'], 'Couchbase\MutateInBuilder::upsert' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'], 'Couchbase\MutateInBuilder::withExpiry' => ['Couchbase\MutateInBuilder', 'expiry'=>'Couchbase\expiry'], 'Couchbase\MutationState::__construct' => ['void'], 'Couchbase\MutationState::add' => ['', 'source'=>'Couchbase\Document|Couchbase\DocumentFragment|array'], 'Couchbase\MutationState::from' => ['Couchbase\MutationState', 'source'=>'Couchbase\Document|Couchbase\DocumentFragment|array'], 'Couchbase\MutationToken::__construct' => ['void'], 'Couchbase\MutationToken::bucketName' => ['string'], 'Couchbase\MutationToken::from' => ['', 'bucketName'=>'string', 'vbucketId'=>'int', 'vbucketUuid'=>'string', 'sequenceNumber'=>'string'], 'Couchbase\MutationToken::sequenceNumber' => ['string'], 'Couchbase\MutationToken::vbucketId' => ['int'], 'Couchbase\MutationToken::vbucketUuid' => ['string'], 'Couchbase\N1qlIndex::__construct' => ['void'], 'Couchbase\N1qlQuery::__construct' => ['void'], 'Couchbase\N1qlQuery::adhoc' => ['Couchbase\N1qlQuery', 'adhoc'=>'bool'], 'Couchbase\N1qlQuery::consistency' => ['Couchbase\N1qlQuery', 'consistency'=>'int'], 'Couchbase\N1qlQuery::consistentWith' => ['Couchbase\N1qlQuery', 'state'=>'Couchbase\MutationState'], 'Couchbase\N1qlQuery::crossBucket' => ['Couchbase\N1qlQuery', 'crossBucket'=>'bool'], 'Couchbase\N1qlQuery::fromString' => ['Couchbase\N1qlQuery', 'statement'=>'string'], 'Couchbase\N1qlQuery::maxParallelism' => ['Couchbase\N1qlQuery', 'maxParallelism'=>'int'], 'Couchbase\N1qlQuery::namedParams' => ['Couchbase\N1qlQuery', 'params'=>'array'], 'Couchbase\N1qlQuery::pipelineBatch' => ['Couchbase\N1qlQuery', 'pipelineBatch'=>'int'], 'Couchbase\N1qlQuery::pipelineCap' => ['Couchbase\N1qlQuery', 'pipelineCap'=>'int'], 'Couchbase\N1qlQuery::positionalParams' => ['Couchbase\N1qlQuery', 'params'=>'array'], 'Couchbase\N1qlQuery::readonly' => ['Couchbase\N1qlQuery', 'readonly'=>'bool'], 'Couchbase\N1qlQuery::scanCap' => ['Couchbase\N1qlQuery', 'scanCap'=>'int'], 'Couchbase\NumericRangeSearchFacet::__construct' => ['void'], 'Couchbase\NumericRangeSearchFacet::addRange' => ['Couchbase\NumericSearchFacet', 'name'=>'string', 'min'=>'float', 'max'=>'float'], 'Couchbase\NumericRangeSearchFacet::jsonSerialize' => ['array'], 'Couchbase\NumericRangeSearchQuery::__construct' => ['void'], 'Couchbase\NumericRangeSearchQuery::boost' => ['Couchbase\NumericRangeSearchQuery', 'boost'=>'float'], 'Couchbase\NumericRangeSearchQuery::field' => ['Couchbase\NumericRangeSearchQuery', 'field'=>'string'], 'Couchbase\NumericRangeSearchQuery::jsonSerialize' => ['array'], 'Couchbase\NumericRangeSearchQuery::max' => ['Couchbase\NumericRangeSearchQuery', 'max'=>'float', 'inclusive='=>'bool|false'], 'Couchbase\NumericRangeSearchQuery::min' => ['Couchbase\NumericRangeSearchQuery', 'min'=>'float', 'inclusive='=>'bool|true'], 'Couchbase\passthruDecoder' => ['string', 'bytes'=>'string', 'flags'=>'int', 'datatype'=>'int'], 'Couchbase\passthruEncoder' => ['array', 'value'=>'string'], 'Couchbase\PasswordAuthenticator::password' => ['Couchbase\PasswordAuthenticator', 'password'=>'string'], 'Couchbase\PasswordAuthenticator::username' => ['Couchbase\PasswordAuthenticator', 'username'=>'string'], 'Couchbase\PhraseSearchQuery::__construct' => ['void'], 'Couchbase\PhraseSearchQuery::boost' => ['Couchbase\PhraseSearchQuery', 'boost'=>'float'], 'Couchbase\PhraseSearchQuery::field' => ['Couchbase\PhraseSearchQuery', 'field'=>'string'], 'Couchbase\PhraseSearchQuery::jsonSerialize' => ['array'], 'Couchbase\PrefixSearchQuery::__construct' => ['void'], 'Couchbase\PrefixSearchQuery::boost' => ['Couchbase\PrefixSearchQuery', 'boost'=>'float'], 'Couchbase\PrefixSearchQuery::field' => ['Couchbase\PrefixSearchQuery', 'field'=>'string'], 'Couchbase\PrefixSearchQuery::jsonSerialize' => ['array'], 'Couchbase\QueryStringSearchQuery::__construct' => ['void'], 'Couchbase\QueryStringSearchQuery::boost' => ['Couchbase\QueryStringSearchQuery', 'boost'=>'float'], 'Couchbase\QueryStringSearchQuery::jsonSerialize' => ['array'], 'Couchbase\RegexpSearchQuery::__construct' => ['void'], 'Couchbase\RegexpSearchQuery::boost' => ['Couchbase\RegexpSearchQuery', 'boost'=>'float'], 'Couchbase\RegexpSearchQuery::field' => ['Couchbase\RegexpSearchQuery', 'field'=>'string'], 'Couchbase\RegexpSearchQuery::jsonSerialize' => ['array'], 'Couchbase\SearchQuery::__construct' => ['void', 'indexName'=>'string', 'queryPart'=>'Couchbase\SearchQueryPart'], 'Couchbase\SearchQuery::addFacet' => ['Couchbase\SearchQuery', 'name'=>'string', 'facet'=>'Couchbase\SearchFacet'], 'Couchbase\SearchQuery::boolean' => ['Couchbase\BooleanSearchQuery'], 'Couchbase\SearchQuery::booleanField' => ['Couchbase\BooleanFieldSearchQuery', 'value'=>'bool'], 'Couchbase\SearchQuery::conjuncts' => ['Couchbase\ConjunctionSearchQuery', '...queries='=>'array'], 'Couchbase\SearchQuery::consistentWith' => ['Couchbase\SearchQuery', 'state'=>'Couchbase\MutationState'], 'Couchbase\SearchQuery::dateRange' => ['Couchbase\DateRangeSearchQuery'], 'Couchbase\SearchQuery::dateRangeFacet' => ['Couchbase\DateRangeSearchFacet', 'field'=>'string', 'limit'=>'int'], 'Couchbase\SearchQuery::disjuncts' => ['Couchbase\DisjunctionSearchQuery', '...queries='=>'array'], 'Couchbase\SearchQuery::docId' => ['Couchbase\DocIdSearchQuery', '...documentIds='=>'array'], 'Couchbase\SearchQuery::explain' => ['Couchbase\SearchQuery', 'explain'=>'bool'], 'Couchbase\SearchQuery::fields' => ['Couchbase\SearchQuery', '...fields='=>'array'], 'Couchbase\SearchQuery::geoBoundingBox' => ['Couchbase\GeoBoundingBoxSearchQuery', 'topLeftLongitude'=>'float', 'topLeftLatitude'=>'float', 'bottomRightLongitude'=>'float', 'bottomRightLatitude'=>'float'], 'Couchbase\SearchQuery::geoDistance' => ['Couchbase\GeoDistanceSearchQuery', 'longitude'=>'float', 'latitude'=>'float', 'distance'=>'string'], 'Couchbase\SearchQuery::highlight' => ['Couchbase\SearchQuery', 'style'=>'string', '...fields='=>'array'], 'Couchbase\SearchQuery::jsonSerialize' => ['array'], 'Couchbase\SearchQuery::limit' => ['Couchbase\SearchQuery', 'limit'=>'int'], 'Couchbase\SearchQuery::match' => ['Couchbase\MatchSearchQuery', 'match'=>'string'], 'Couchbase\SearchQuery::matchAll' => ['Couchbase\MatchAllSearchQuery'], 'Couchbase\SearchQuery::matchNone' => ['Couchbase\MatchNoneSearchQuery'], 'Couchbase\SearchQuery::matchPhrase' => ['Couchbase\MatchPhraseSearchQuery', '...terms='=>'array'], 'Couchbase\SearchQuery::numericRange' => ['Couchbase\NumericRangeSearchQuery'], 'Couchbase\SearchQuery::numericRangeFacet' => ['Couchbase\NumericRangeSearchFacet', 'field'=>'string', 'limit'=>'int'], 'Couchbase\SearchQuery::prefix' => ['Couchbase\PrefixSearchQuery', 'prefix'=>'string'], 'Couchbase\SearchQuery::queryString' => ['Couchbase\QueryStringSearchQuery', 'queryString'=>'string'], 'Couchbase\SearchQuery::regexp' => ['Couchbase\RegexpSearchQuery', 'regexp'=>'string'], 'Couchbase\SearchQuery::serverSideTimeout' => ['Couchbase\SearchQuery', 'serverSideTimeout'=>'int'], 'Couchbase\SearchQuery::skip' => ['Couchbase\SearchQuery', 'skip'=>'int'], 'Couchbase\SearchQuery::sort' => ['Couchbase\SearchQuery', '...sort='=>'array'], 'Couchbase\SearchQuery::term' => ['Couchbase\TermSearchQuery', 'term'=>'string'], 'Couchbase\SearchQuery::termFacet' => ['Couchbase\TermSearchFacet', 'field'=>'string', 'limit'=>'int'], 'Couchbase\SearchQuery::termRange' => ['Couchbase\TermRangeSearchQuery'], 'Couchbase\SearchQuery::wildcard' => ['Couchbase\WildcardSearchQuery', 'wildcard'=>'string'], 'Couchbase\SpatialViewQuery::__construct' => ['void'], 'Couchbase\SpatialViewQuery::bbox' => ['Couchbase\SpatialViewQuery', 'bbox'=>'array'], 'Couchbase\SpatialViewQuery::consistency' => ['Couchbase\SpatialViewQuery', 'consistency'=>'int'], 'Couchbase\SpatialViewQuery::custom' => ['', 'customParameters'=>'array'], 'Couchbase\SpatialViewQuery::encode' => ['array'], 'Couchbase\SpatialViewQuery::endRange' => ['Couchbase\SpatialViewQuery', 'range'=>'array'], 'Couchbase\SpatialViewQuery::limit' => ['Couchbase\SpatialViewQuery', 'limit'=>'int'], 'Couchbase\SpatialViewQuery::order' => ['Couchbase\SpatialViewQuery', 'order'=>'int'], 'Couchbase\SpatialViewQuery::skip' => ['Couchbase\SpatialViewQuery', 'skip'=>'int'], 'Couchbase\SpatialViewQuery::startRange' => ['Couchbase\SpatialViewQuery', 'range'=>'array'], 'Couchbase\TermRangeSearchQuery::__construct' => ['void'], 'Couchbase\TermRangeSearchQuery::boost' => ['Couchbase\TermRangeSearchQuery', 'boost'=>'float'], 'Couchbase\TermRangeSearchQuery::field' => ['Couchbase\TermRangeSearchQuery', 'field'=>'string'], 'Couchbase\TermRangeSearchQuery::jsonSerialize' => ['array'], 'Couchbase\TermRangeSearchQuery::max' => ['Couchbase\TermRangeSearchQuery', 'max'=>'string', 'inclusive='=>'bool|false'], 'Couchbase\TermRangeSearchQuery::min' => ['Couchbase\TermRangeSearchQuery', 'min'=>'string', 'inclusive='=>'bool|true'], 'Couchbase\TermSearchFacet::__construct' => ['void'], 'Couchbase\TermSearchFacet::jsonSerialize' => ['array'], 'Couchbase\TermSearchQuery::__construct' => ['void'], 'Couchbase\TermSearchQuery::boost' => ['Couchbase\TermSearchQuery', 'boost'=>'float'], 'Couchbase\TermSearchQuery::field' => ['Couchbase\TermSearchQuery', 'field'=>'string'], 'Couchbase\TermSearchQuery::fuzziness' => ['Couchbase\TermSearchQuery', 'fuzziness'=>'int'], 'Couchbase\TermSearchQuery::jsonSerialize' => ['array'], 'Couchbase\TermSearchQuery::prefixLength' => ['Couchbase\TermSearchQuery', 'prefixLength'=>'int'], 'Couchbase\UserSettings::fullName' => ['Couchbase\UserSettings', 'fullName'=>'string'], 'Couchbase\UserSettings::password' => ['Couchbase\UserSettings', 'password'=>'string'], 'Couchbase\UserSettings::role' => ['Couchbase\UserSettings', 'role'=>'string', 'bucket='=>'string'], 'Couchbase\ViewQuery::__construct' => ['void'], 'Couchbase\ViewQuery::consistency' => ['Couchbase\ViewQuery', 'consistency'=>'int'], 'Couchbase\ViewQuery::custom' => ['Couchbase\ViewQuery', 'customParameters'=>'array'], 'Couchbase\ViewQuery::encode' => ['array'], 'Couchbase\ViewQuery::from' => ['Couchbase\ViewQuery', 'designDocumentName'=>'string', 'viewName'=>'string'], 'Couchbase\ViewQuery::fromSpatial' => ['Couchbase\SpatialViewQuery', 'designDocumentName'=>'string', 'viewName'=>'string'], 'Couchbase\ViewQuery::group' => ['Couchbase\ViewQuery', 'group'=>'bool'], 'Couchbase\ViewQuery::groupLevel' => ['Couchbase\ViewQuery', 'groupLevel'=>'int'], 'Couchbase\ViewQuery::idRange' => ['Couchbase\ViewQuery', 'startKeyDocumentId'=>'string', 'endKeyDocumentId'=>'string'], 'Couchbase\ViewQuery::key' => ['Couchbase\ViewQuery', 'key'=>'mixed'], 'Couchbase\ViewQuery::keys' => ['Couchbase\ViewQuery', 'keys'=>'array'], 'Couchbase\ViewQuery::limit' => ['Couchbase\ViewQuery', 'limit'=>'int'], 'Couchbase\ViewQuery::order' => ['Couchbase\ViewQuery', 'order'=>'int'], 'Couchbase\ViewQuery::range' => ['Couchbase\ViewQuery', 'startKey'=>'mixed', 'endKey'=>'mixed', 'inclusiveEnd='=>'bool|false'], 'Couchbase\ViewQuery::reduce' => ['Couchbase\ViewQuery', 'reduce'=>'bool'], 'Couchbase\ViewQuery::skip' => ['Couchbase\ViewQuery', 'skip'=>'int'], 'Couchbase\ViewQueryEncodable::encode' => ['array'], 'Couchbase\WildcardSearchQuery::__construct' => ['void'], 'Couchbase\WildcardSearchQuery::boost' => ['Couchbase\WildcardSearchQuery', 'boost'=>'float'], 'Couchbase\WildcardSearchQuery::field' => ['Couchbase\WildcardSearchQuery', 'field'=>'string'], 'Couchbase\WildcardSearchQuery::jsonSerialize' => ['array'], 'Couchbase\zlibCompress' => ['string', 'data'=>'string'], 'Couchbase\zlibDecompress' => ['string', 'data'=>'string'], 'count' => ['0|positive-int', 'var'=>'Countable|array', 'mode='=>'int'], 'count_chars' => ['mixed', 'input'=>'string', 'mode='=>'0|1|2|3|4'], 'Countable::count' => ['0|positive-int'], 'crack_check' => ['bool', 'dictionary'=>'', 'password'=>'string'], 'crack_closedict' => ['bool', 'dictionary='=>'resource'], 'crack_getlastmessage' => ['string'], 'crack_opendict' => ['resource', 'dictionary'=>'string'], 'crash' => [''], 'crc32' => ['int', 'str'=>'string'], 'create_function' => ['string', 'args'=>'string', 'code'=>'string'], 'crypt' => ['non-empty-string', 'str'=>'string', 'salt='=>'string'], 'ctype_alnum' => ['bool', 'c'=>'mixed'], 'ctype_alpha' => ['bool', 'c'=>'mixed'], 'ctype_cntrl' => ['bool', 'c'=>'mixed'], 'ctype_digit' => ['bool', 'c'=>'mixed'], 'ctype_graph' => ['bool', 'c'=>'mixed'], 'ctype_lower' => ['bool', 'c'=>'mixed'], 'ctype_print' => ['bool', 'c'=>'mixed'], 'ctype_punct' => ['bool', 'c'=>'mixed'], 'ctype_space' => ['bool', 'c'=>'mixed'], 'ctype_upper' => ['bool', 'c'=>'mixed'], 'ctype_xdigit' => ['bool', 'c'=>'mixed'], 'cubrid_affected_rows' => ['int', 'req_identifier='=>''], 'cubrid_bind' => ['bool', 'req_identifier'=>'resource', 'bind_param'=>'int', 'bind_value'=>'mixed', 'bind_value_type='=>'string'], 'cubrid_client_encoding' => ['string', 'conn_identifier='=>''], 'cubrid_close' => ['bool', 'conn_identifier='=>''], 'cubrid_close_prepare' => ['bool', 'req_identifier'=>'resource'], 'cubrid_close_request' => ['bool', 'req_identifier'=>'resource'], 'cubrid_col_get' => ['array', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string'], 'cubrid_col_size' => ['int', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string'], 'cubrid_column_names' => ['array', 'req_identifier'=>'resource'], 'cubrid_column_types' => ['array', 'req_identifier'=>'resource'], 'cubrid_commit' => ['bool', 'conn_identifier'=>'resource'], 'cubrid_connect' => ['resource', 'host'=>'string', 'port'=>'int', 'dbname'=>'string', 'userid='=>'string', 'passwd='=>'string'], 'cubrid_connect_with_url' => ['resource', 'conn_url'=>'string', 'userid='=>'string', 'passwd='=>'string'], 'cubrid_current_oid' => ['string', 'req_identifier'=>'resource'], 'cubrid_data_seek' => ['bool', 'req_identifier'=>'', 'row_number'=>'int'], 'cubrid_db_name' => ['string', 'result'=>'array', 'index'=>'int'], 'cubrid_db_parameter' => ['array', 'conn_identifier'=>'resource'], 'cubrid_disconnect' => ['bool', 'conn_identifier'=>'resource'], 'cubrid_drop' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string'], 'cubrid_errno' => ['int', 'conn_identifier='=>''], 'cubrid_error' => ['string', 'connection='=>''], 'cubrid_error_code' => ['int'], 'cubrid_error_code_facility' => ['int'], 'cubrid_error_msg' => ['string'], 'cubrid_execute' => ['bool', 'conn_identifier'=>'', 'sql'=>'string', 'option='=>'int', 'request_identifier='=>''], 'cubrid_fetch' => ['mixed', 'result'=>'resource', 'type='=>'int'], 'cubrid_fetch_array' => ['array', 'result'=>'', 'type='=>'int'], 'cubrid_fetch_assoc' => ['array', 'result'=>''], 'cubrid_fetch_field' => ['object', 'result'=>'', 'field_offset='=>'int'], 'cubrid_fetch_lengths' => ['array', 'result'=>''], 'cubrid_fetch_object' => ['object', 'result'=>'', 'class_name='=>'string', 'params='=>'array'], 'cubrid_fetch_row' => ['array', 'result'=>''], 'cubrid_field_flags' => ['string', 'result'=>'', 'field_offset'=>'int'], 'cubrid_field_len' => ['int', 'result'=>'', 'field_offset'=>'int'], 'cubrid_field_name' => ['string', 'result'=>'', 'field_offset'=>'int'], 'cubrid_field_seek' => ['bool', 'result'=>'', 'field_offset='=>'int'], 'cubrid_field_table' => ['string', 'result'=>'', 'field_offset'=>'int'], 'cubrid_field_type' => ['string', 'result'=>'', 'field_offset'=>'int'], 'cubrid_free_result' => ['bool', 'req_identifier'=>'resource'], 'cubrid_get' => ['mixed', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr='=>'mixed'], 'cubrid_get_autocommit' => ['bool', 'conn_identifier'=>'resource'], 'cubrid_get_charset' => ['string', 'conn_identifier'=>'resource'], 'cubrid_get_class_name' => ['string', 'conn_identifier'=>'resource', 'oid'=>'string'], 'cubrid_get_client_info' => ['string'], 'cubrid_get_db_parameter' => ['array', 'conn_identifier'=>'resource'], 'cubrid_get_query_timeout' => ['int', 'req_identifier'=>'resource'], 'cubrid_get_server_info' => ['string', 'conn_identifier'=>'resource'], 'cubrid_insert_id' => ['string', 'conn_identifier='=>'resource'], 'cubrid_is_instance' => ['int', 'conn_identifier'=>'resource', 'oid'=>'string'], 'cubrid_list_dbs' => ['array', 'conn_identifier'=>''], 'cubrid_load_from_glo' => ['int', 'conn_identifier'=>'', 'oid'=>'string', 'file_name'=>'string'], 'cubrid_lob2_bind' => ['bool', 'req_identifier'=>'resource', 'bind_index'=>'int', 'bind_value'=>'mixed', 'bind_value_type='=>'string'], 'cubrid_lob2_close' => ['bool', 'lob_identifier'=>'resource'], 'cubrid_lob2_export' => ['bool', 'lob_identifier'=>'resource', 'file_name'=>'string'], 'cubrid_lob2_import' => ['bool', 'lob_identifier'=>'resource', 'file_name'=>'string'], 'cubrid_lob2_new' => ['resource', 'conn_identifier='=>'resource', 'type='=>'string'], 'cubrid_lob2_read' => ['string', 'lob_identifier'=>'resource', 'len'=>'int'], 'cubrid_lob2_seek' => ['bool', 'lob_identifier'=>'resource', 'offset'=>'int', 'origin='=>'int'], 'cubrid_lob2_seek64' => ['bool', 'lob_identifier'=>'resource', 'offset'=>'string', 'origin='=>'int'], 'cubrid_lob2_size' => ['int', 'lob_identifier'=>'resource'], 'cubrid_lob2_size64' => ['string', 'lob_identifier'=>'resource'], 'cubrid_lob2_tell' => ['int', 'lob_identifier'=>'resource'], 'cubrid_lob2_tell64' => ['string', 'lob_identifier'=>'resource'], 'cubrid_lob2_write' => ['bool', 'lob_identifier'=>'resource', 'buf'=>'string'], 'cubrid_lob_close' => ['bool', 'lob_identifier_array'=>'array'], 'cubrid_lob_export' => ['bool', 'conn_identifier'=>'resource', 'lob_identifier'=>'resource', 'path_name'=>'string'], 'cubrid_lob_get' => ['array', 'conn_identifier'=>'resource', 'sql'=>'string'], 'cubrid_lob_send' => ['bool', 'conn_identifier'=>'resource', 'lob_identifier'=>'resource'], 'cubrid_lob_size' => ['string', 'lob_identifier'=>'resource'], 'cubrid_lock_read' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string'], 'cubrid_lock_write' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string'], 'cubrid_move_cursor' => ['int', 'req_identifier'=>'resource', 'offset'=>'int', 'origin='=>'int'], 'cubrid_new_glo' => ['string', 'conn_identifier'=>'', 'class_name'=>'string', 'file_name'=>'string'], 'cubrid_next_result' => ['bool', 'result'=>'resource'], 'cubrid_num_cols' => ['int', 'req_identifier'=>'resource'], 'cubrid_num_fields' => ['int', 'result'=>''], 'cubrid_num_rows' => ['int', 'req_identifier'=>'resource'], 'cubrid_pconnect' => ['resource', 'host'=>'string', 'port'=>'int', 'dbname'=>'string', 'userid='=>'string', 'passwd='=>'string'], 'cubrid_pconnect_with_url' => ['resource', 'conn_url'=>'string', 'userid='=>'string', 'passwd='=>'string'], 'cubrid_ping' => ['bool', 'conn_identifier='=>''], 'cubrid_prepare' => ['resource', 'conn_identifier'=>'resource', 'prepare_stmt'=>'string', 'option='=>'int'], 'cubrid_put' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr='=>'string', 'value='=>'mixed'], 'cubrid_query' => ['resource', 'query'=>'string', 'conn_identifier='=>''], 'cubrid_real_escape_string' => ['string', 'unescaped_string'=>'string', 'conn_identifier='=>''], 'cubrid_result' => ['string', 'result'=>'', 'row'=>'int', 'field='=>''], 'cubrid_rollback' => ['bool', 'conn_identifier'=>'resource'], 'cubrid_save_to_glo' => ['int', 'conn_identifier'=>'', 'oid'=>'string', 'file_name'=>'string'], 'cubrid_schema' => ['array', 'conn_identifier'=>'resource', 'schema_type'=>'int', 'class_name='=>'string', 'attr_name='=>'string'], 'cubrid_send_glo' => ['int', 'conn_identifier'=>'', 'oid'=>'string'], 'cubrid_seq_drop' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'index'=>'int'], 'cubrid_seq_insert' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'index'=>'int', 'seq_element'=>'string'], 'cubrid_seq_put' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'index'=>'int', 'seq_element'=>'string'], 'cubrid_set_add' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'set_element'=>'string'], 'cubrid_set_autocommit' => ['bool', 'conn_identifier'=>'resource', 'mode'=>'bool'], 'cubrid_set_db_parameter' => ['bool', 'conn_identifier'=>'resource', 'param_type'=>'int', 'param_value'=>'int'], 'cubrid_set_drop' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'set_element'=>'string'], 'cubrid_set_query_timeout' => ['bool', 'req_identifier'=>'resource', 'timeout'=>'int'], 'cubrid_unbuffered_query' => ['resource', 'query'=>'string', 'conn_identifier='=>''], 'cubrid_version' => ['string'], 'curl_close' => ['void', 'ch'=>'resource'], 'curl_copy_handle' => ['resource|false', 'ch'=>'resource'], 'curl_errno' => ['int', 'ch'=>'resource'], 'curl_error' => ['string', 'ch'=>'resource'], 'curl_escape' => ['string|false', 'ch'=>'resource', 'str'=>'string'], 'curl_exec' => ['bool|string', 'ch'=>'resource'], 'curl_file_create' => ['CURLFile', 'filename'=>'string', 'mimetype='=>'string', 'postfilename='=>'string'], 'curl_getinfo' => ['mixed', 'ch'=>'resource', 'option='=>'int'], 'curl_init' => ['__benevolent', 'url='=>'string'], 'curl_multi_add_handle' => ['int', 'mh'=>'resource', 'ch'=>'resource'], 'curl_multi_close' => ['void', 'mh'=>'resource'], 'curl_multi_errno' => ['int', 'mh'=>'resource'], 'curl_multi_exec' => ['int', 'mh'=>'resource', '&w_still_running'=>'int'], 'curl_multi_getcontent' => ['string|null', 'ch'=>'resource'], 'curl_multi_info_read' => ['array|false', 'mh'=>'resource', '&w_msgs_in_queue='=>'int'], 'curl_multi_init' => ['resource'], 'curl_multi_remove_handle' => ['int', 'mh'=>'resource', 'ch'=>'resource'], 'curl_multi_select' => ['int', 'mh'=>'resource', 'timeout='=>'float'], 'curl_multi_setopt' => ['bool', 'mh'=>'resource', 'option'=>'int', 'value'=>'mixed'], 'curl_multi_strerror' => ['string', 'code'=>'int'], 'curl_pause' => ['int', 'ch'=>'resource', 'bitmask'=>'int'], 'curl_reset' => ['void', 'ch'=>'resource'], 'curl_setopt' => ['bool', 'ch'=>'resource', 'option'=>'int', 'value'=>'mixed'], 'curl_setopt_array' => ['bool', 'ch'=>'resource', 'options'=>'array'], 'curl_share_close' => ['void', 'sh'=>'resource'], 'curl_share_errno' => ['int', 'sh'=>'resource'], 'curl_share_init' => ['resource'], 'curl_share_setopt' => ['bool', 'sh'=>'resource', 'option'=>'int', 'value'=>'mixed'], 'curl_share_strerror' => ['string', 'code'=>'int'], 'curl_strerror' => ['string', 'code'=>'int'], 'curl_unescape' => ['string|false', 'ch'=>'resource', 'str'=>'string'], 'curl_version' => ['array|false', 'version='=>'int'], 'CURLFile::__construct' => ['void', 'filename'=>'string', 'mimetype='=>'string', 'postfilename='=>'string'], 'CURLFile::__wakeup' => ['void'], 'CURLFile::getFilename' => ['string'], 'CURLFile::getMimeType' => ['string'], 'CURLFile::getPostFilename' => ['string'], 'CURLFile::setMimeType' => ['void', 'mime'=>'string'], 'CURLFile::setPostFilename' => ['void', 'name'=>'string'], 'current' => ['mixed', 'array_arg'=>'array|object'], 'cyrus_authenticate' => ['void', 'connection'=>'resource', 'mechlist='=>'string', 'service='=>'string', 'user='=>'string', 'minssf='=>'int', 'maxssf='=>'int', 'authname='=>'string', 'password='=>'string'], 'cyrus_bind' => ['bool', 'connection'=>'resource', 'callbacks'=>'array'], 'cyrus_close' => ['bool', 'connection'=>'resource'], 'cyrus_connect' => ['resource', 'host='=>'string', 'port='=>'string', 'flags='=>'int'], 'cyrus_query' => ['array', 'connection'=>'resource', 'query'=>'string'], 'cyrus_unbind' => ['bool', 'connection'=>'resource', 'trigger_name'=>'string'], 'date' => ['string', 'format'=>'string', 'timestamp='=>'int'], 'date_add' => ['DateTime|false', 'object'=>'', 'interval'=>''], 'date_create' => ['DateTime|false', 'time='=>'string|null', 'timezone='=>'?DateTimeZone'], 'date_create_from_format' => ['DateTime|false', 'format'=>'string', 'time'=>'string', 'timezone='=>'?DateTimeZone'], 'date_create_immutable' => ['DateTimeImmutable|false', 'time='=>'string', 'timezone='=>'?DateTimeZone'], 'date_create_immutable_from_format' => ['DateTimeImmutable|false', 'format'=>'string', 'time'=>'string', 'timezone='=>'?DateTimeZone'], 'date_date_set' => ['DateTime|false', 'object'=>'', 'year'=>'', 'month'=>'', 'day'=>''], 'date_default_timezone_get' => ['string'], 'date_default_timezone_set' => ['bool', 'timezone_identifier'=>'string'], 'date_diff' => ['DateInterval', 'obj1'=>'DateTimeInterface', 'obj2'=>'DateTimeInterface', 'absolute='=>'bool'], 'date_format' => ['string', 'obj'=>'DateTimeInterface', 'format'=>'string'], 'date_get_last_errors' => ['array{warning_count: 0|positive-int, warnings: list, error_count: 0|positive-int, errors: list}|false'], 'date_interval_create_from_date_string' => ['DateInterval|false', 'time'=>'string'], 'date_interval_format' => ['string', 'object'=>'DateInterval', 'format'=>'string'], 'date_isodate_set' => ['DateTime|false', 'object'=>'DateTime', 'year'=>'int', 'week'=>'int', 'day='=>'int|mixed'], 'date_modify' => ['DateTime|false', 'object'=>'DateTime', 'modify'=>'string'], 'date_offset_get' => ['int', 'obj'=>'DateTimeInterface'], 'date_parse' => ['array{year: int|false, month: int|false, day: int|false, hour: int|false, minute: int|false, second: int|false, fraction: float|false, warning_count: int, warnings: string[], error_count: int, errors: string[], is_localtime: bool, zone_type?: int|bool, zone?: int|bool, is_dst?: bool, tz_abbr?: string, tz_id?: string, relative?: array{year: int, month: int, day: int, hour: int, minute: int, second: int, weekday?: int, weekdays?: int, first_day_of_month?: bool, last_day_of_month?: bool}}', 'date'=>'string'], 'date_parse_from_format' => ['array{year: int|false, month: int|false, day: int|false, hour: int|false, minute: int|false, second: int|false, fraction: float|false, warning_count: int, warnings: string[], error_count: int, errors: string[], is_localtime: bool, zone_type?: int|bool, zone?: int|bool, is_dst?: bool, tz_abbr?: string, tz_id?: string, relative?: array{year: int, month: int, day: int, hour: int, minute: int, second: int, weekday?: int, weekdays?: int, first_day_of_month?: bool, last_day_of_month?: bool}}', 'format'=>'string', 'date'=>'string'], 'date_sub' => ['DateTime|false', 'object'=>'DateTime', 'interval'=>'DateInterval'], 'date_sun_info' => ['__benevolent', 'time'=>'int', 'latitude'=>'float', 'longitude'=>'float'], 'date_sunrise' => ['mixed', 'time'=>'int', 'format='=>'int', 'latitude='=>'float', 'longitude='=>'float', 'zenith='=>'float', 'gmt_offset='=>'float'], 'date_sunset' => ['mixed', 'time'=>'int', 'format='=>'int', 'latitude='=>'float', 'longitude='=>'float', 'zenith='=>'float', 'gmt_offset='=>'float'], 'date_time_set' => ['DateTime|false', 'object'=>'', 'hour'=>'', 'minute'=>'', 'second='=>'', 'microseconds='=>''], 'date_timestamp_get' => ['int', 'obj'=>'DateTimeInterface'], 'date_timestamp_set' => ['DateTime|false', 'object'=>'DateTime', 'unixtimestamp'=>'int'], 'date_timezone_get' => ['DateTimeZone|false', 'obj'=>'DateTimeInterface'], 'date_timezone_set' => ['DateTime|false', 'object'=>'DateTime', 'timezone'=>'DateTimeZone'], 'datefmt_create' => ['IntlDateFormatter|false', 'locale'=>'?string', 'datetype'=>'?int', 'timetype'=>'?int', 'timezone='=>'string|DateTimeZone|IntlTimeZone|null', 'calendar='=>'int|IntlCalendar|null', 'pattern='=>'string'], 'datefmt_format' => ['string|false', 'fmt'=>'IntlDateFormatter', 'value'=>'DateTime|IntlCalendar|array|int'], 'datefmt_format_object' => ['string|false', 'object'=>'object', 'format='=>'mixed', 'locale='=>'string'], 'datefmt_get_calendar' => ['int|false', 'fmt'=>'IntlDateFormatter'], 'datefmt_get_calendar_object' => ['IntlCalendar|false|null', 'fmt'=>'IntlDateFormatter'], 'datefmt_get_datetype' => ['int|false', 'fmt'=>'IntlDateFormatter'], 'datefmt_get_error_code' => ['int', 'fmt'=>'IntlDateFormatter'], 'datefmt_get_error_message' => ['string', 'fmt'=>'IntlDateFormatter'], 'datefmt_get_locale' => ['string|false', 'fmt'=>'IntlDateFormatter', 'which='=>'int'], 'datefmt_get_pattern' => ['string|false', 'fmt'=>'IntlDateFormatter'], 'datefmt_get_timetype' => ['int|false', 'fmt'=>'IntlDateFormatter'], 'datefmt_get_timezone' => ['IntlTimeZone|false'], 'datefmt_get_timezone_id' => ['string|false', 'fmt'=>'IntlDateFormatter'], 'datefmt_is_lenient' => ['bool', 'fmt'=>'IntlDateFormatter'], 'datefmt_localtime' => ['array|false', 'fmt'=>'IntlDateFormatter', 'text_to_parse='=>'string', '&rw_parse_pos='=>'int'], 'datefmt_parse' => ['int|float|false', 'fmt'=>'IntlDateFormatter', 'text_to_parse='=>'string', '&rw_parse_pos='=>'int'], 'datefmt_set_calendar' => ['bool', 'fmt'=>'IntlDateFormatter', 'which'=>'int'], 'datefmt_set_lenient' => ['void', 'fmt'=>'IntlDateFormatter', 'lenient'=>'bool'], 'datefmt_set_pattern' => ['bool', 'fmt'=>'IntlDateFormatter', 'pattern'=>'string'], 'datefmt_set_timezone' => ['bool', 'zone'=>'mixed'], 'datefmt_set_timezone_id' => ['bool', 'fmt'=>'IntlDateFormatter', 'zone'=>'string'], 'DateInterval::__construct' => ['void', 'spec'=>'string'], 'DateInterval::__set_state' => ['DateInterval', 'array'=>'array'], 'DateInterval::__wakeup' => ['void'], 'DateInterval::createFromDateString' => ['DateInterval|false', 'time'=>'string'], 'DateInterval::format' => ['string', 'format'=>'string'], 'DatePeriod::__construct' => ['void', 'start'=>'DateTimeInterface', 'interval'=>'DateInterval', 'recur'=>'int', 'options='=>'int'], 'DatePeriod::__construct\'1' => ['void', 'start'=>'DateTimeInterface', 'interval'=>'DateInterval', 'end'=>'DateTimeInterface', 'options='=>'int'], 'DatePeriod::__construct\'2' => ['void', 'iso'=>'string', 'options='=>'int'], 'DatePeriod::__wakeup' => ['void'], 'DatePeriod::getDateInterval' => ['DateInterval'], 'DatePeriod::getEndDate' => ['?DateTimeInterface'], 'DatePeriod::getStartDate' => ['DateTimeInterface'], 'DateTime::__construct' => ['void', 'time='=>'string', 'timezone='=>'?DateTimeZone'], 'DateTime::__set_state' => ['static', 'array'=>'array'], 'DateTime::__wakeup' => ['void'], 'DateTime::add' => ['static', 'interval'=>'DateInterval'], 'DateTime::createFromFormat' => ['static|false', 'format'=>'string', 'time'=>'string', 'timezone='=>'DateTimeZone|null'], 'DateTime::createFromImmutable' => ['static', 'object'=>'DateTimeImmutable'], 'DateTime::diff' => ['DateInterval', 'datetime2'=>'DateTimeInterface', 'absolute='=>'bool'], 'DateTime::format' => ['string', 'format'=>'string'], 'DateTime::getLastErrors' => ['array{warning_count: 0|positive-int, warnings: list, error_count: 0|positive-int, errors: list}|false'], 'DateTime::getOffset' => ['int'], 'DateTime::getTimestamp' => ['int'], 'DateTime::getTimezone' => ['DateTimeZone'], 'DateTime::modify' => ['__benevolent', 'modify'=>'string'], 'DateTime::setDate' => ['static', 'year'=>'int', 'month'=>'int', 'day'=>'int'], 'DateTime::setISODate' => ['static', 'year'=>'int', 'week'=>'int', 'day='=>'int'], 'DateTime::setTime' => ['static', 'hour'=>'int', 'minute'=>'int', 'second='=>'int', 'microseconds='=>'int'], 'DateTime::setTimestamp' => ['static', 'unixtimestamp'=>'int'], 'DateTime::setTimezone' => ['static', 'timezone'=>'DateTimeZone'], 'DateTime::sub' => ['static', 'interval'=>'DateInterval'], 'DateTimeImmutable::__construct' => ['void', 'time='=>'string', 'timezone='=>'?DateTimeZone'], 'DateTimeImmutable::__set_state' => ['static', 'array'=>'array'], 'DateTimeImmutable::__wakeup' => ['void'], 'DateTimeImmutable::add' => ['static', 'interval'=>'DateInterval'], 'DateTimeImmutable::createFromFormat' => ['static|false', 'format'=>'string', 'time'=>'string', 'timezone='=>'DateTimeZone|null'], 'DateTimeImmutable::createFromMutable' => ['static', 'datetime'=>'DateTime'], 'DateTimeImmutable::diff' => ['DateInterval', 'datetime2'=>'DateTimeInterface', 'absolute='=>'bool'], 'DateTimeImmutable::format' => ['string', 'format'=>'string'], 'DateTimeImmutable::getLastErrors' => ['array{warning_count: 0|positive-int, warnings: list, error_count: 0|positive-int, errors: list}|false'], 'DateTimeImmutable::getOffset' => ['int'], 'DateTimeImmutable::getTimestamp' => ['int'], 'DateTimeImmutable::getTimezone' => ['DateTimeZone'], 'DateTimeImmutable::modify' => ['__benevolent', 'modify'=>'string'], 'DateTimeImmutable::setDate' => ['static', 'year'=>'int', 'month'=>'int', 'day'=>'int'], 'DateTimeImmutable::setISODate' => ['static', 'year'=>'int', 'week'=>'int', 'day='=>'int'], 'DateTimeImmutable::setTime' => ['static', 'hour'=>'int', 'minute'=>'int', 'second='=>'int', 'microseconds='=>'int'], 'DateTimeImmutable::setTimestamp' => ['static', 'unixtimestamp'=>'int'], 'DateTimeImmutable::setTimezone' => ['static', 'timezone'=>'DateTimeZone'], 'DateTimeImmutable::sub' => ['static', 'interval'=>'DateInterval'], 'DateTimeInterface::diff' => ['DateInterval', 'datetime2'=>'DateTimeInterface', 'absolute='=>'bool'], 'DateTimeInterface::format' => ['string', 'format'=>'string'], 'DateTimeInterface::getOffset' => ['int'], 'DateTimeInterface::getTimestamp' => ['int'], 'DateTimeInterface::getTimezone' => ['DateTimeZone'], 'DateTimeZone::__construct' => ['void', 'timezone'=>'string'], 'DateTimeZone::__set_state' => ['DateTimeZone', 'array'=>'array'], 'DateTimeZone::__wakeup' => ['void'], 'DateTimeZone::getLocation' => ['array{country_code: string, latitude: float, longitude: float, comments: string}|false'], 'DateTimeZone::getName' => ['string'], 'DateTimeZone::getOffset' => ['int', 'datetime'=>'DateTimeInterface'], 'DateTimeZone::getTransitions' => ['list', 'timestamp_begin='=>'int', 'timestamp_end='=>'int'], 'DateTimeZone::listAbbreviations' => ['array>'], 'DateTimeZone::listIdentifiers' => ['list', 'what='=>'int', 'country='=>'string'], 'db2_autocommit' => ['DB2_AUTOCOMMIT_OFF|DB2_AUTOCOMMIT_ON|bool', 'connection'=>'resource', 'value='=>'DB2_AUTOCOMMIT_OFF|DB2_AUTOCOMMIT_ON'], 'db2_bind_param' => ['bool', 'stmt'=>'resource', 'parameter_number'=>'int', 'variable_name'=>'string', 'parameter_type='=>'int', 'data_type='=>'int', 'precision='=>'int', 'scale='=>'int'], 'db2_client_info' => ['stdClass|false', 'connection'=>'resource'], 'db2_close' => ['bool', 'connection'=>'resource'], 'db2_column_privileges' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string', 'column_name='=>'string'], 'db2_columns' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string', 'column_name='=>'string'], 'db2_commit' => ['bool', 'connection'=>'resource'], 'db2_conn_error' => ['string', 'connection='=>'resource'], 'db2_conn_errormsg' => ['string', 'connection='=>'resource'], 'db2_connect' => ['resource|false', 'database'=>'string', 'username'=>'string', 'password'=>'string', 'options='=>'array'], 'db2_cursor_type' => ['int', 'stmt'=>'resource'], 'db2_escape_string' => ['string', 'string_literal'=>'string'], 'db2_exec' => ['resource|false', 'connection'=>'resource', 'statement'=>'string', 'options='=>'array'], 'db2_execute' => ['bool', 'stmt'=>'resource', 'parameters='=>'array'], 'db2_fetch_array' => ['non-empty-list|false', 'stmt'=>'resource', 'row_number='=>'int'], 'db2_fetch_assoc' => ['non-empty-array|false', 'stmt'=>'resource', 'row_number='=>'int'], 'db2_fetch_both' => ['array|false', 'stmt'=>'resource', 'row_number='=>'int'], 'db2_fetch_object' => ['stdClass|false', 'stmt'=>'resource', 'row_number='=>'int'], 'db2_fetch_row' => ['bool', 'stmt'=>'resource', 'row_number='=>'int'], 'db2_field_display_size' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'], 'db2_field_name' => ['string|false', 'stmt'=>'resource', 'column'=>'mixed'], 'db2_field_num' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'], 'db2_field_precision' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'], 'db2_field_scale' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'], 'db2_field_type' => ['string|false', 'stmt'=>'resource', 'column'=>'mixed'], 'db2_field_width' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'], 'db2_foreign_keys' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string'], 'db2_free_result' => ['bool', 'stmt'=>'resource'], 'db2_free_stmt' => ['bool', 'stmt'=>'resource'], 'db2_get_option' => ['string|false', 'resource'=>'resource', 'option'=>'string'], 'db2_last_insert_id' => ['string|null', 'resource'=>'resource'], 'db2_lob_read' => ['string|false', 'stmt'=>'resource', 'colnum'=>'int', 'length'=>'int'], 'db2_next_result' => ['resource|false', 'stmt'=>'resource'], 'db2_num_fields' => ['0|positive-int|false', 'stmt'=>'resource'], 'db2_num_rows' => ['0|positive-int|false', 'stmt'=>'resource'], 'db2_pclose' => ['bool', 'resource'=>'resource'], 'db2_pconnect' => ['resource|false', 'database'=>'string', 'username'=>'string', 'password'=>'string', 'options='=>'array'], 'db2_prepare' => ['resource|false', 'connection'=>'resource', 'statement'=>'string', 'options='=>'array'], 'db2_primary_keys' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string'], 'db2_primarykeys' => [''], 'db2_procedure_columns' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'procedure'=>'string', 'parameter'=>'string'], 'db2_procedurecolumns' => [''], 'db2_procedures' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'procedure'=>'string'], 'db2_result' => ['mixed', 'stmt'=>'resource', 'column'=>'mixed'], 'db2_rollback' => ['bool', 'connection'=>'resource'], 'db2_server_info' => ['stdClass|false', 'connection'=>'resource'], 'db2_set_option' => ['bool', 'resource'=>'resource', 'options'=>'array', 'type'=>'int'], 'db2_setoption' => [''], 'db2_special_columns' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string', 'scope'=>'int'], 'db2_specialcolumns' => [''], 'db2_statistics' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string', 'unique'=>'bool'], 'db2_stmt_error' => ['string', 'stmt='=>'resource'], 'db2_stmt_errormsg' => ['string', 'stmt='=>'resource'], 'db2_table_privileges' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string'], 'db2_tableprivileges' => [''], 'db2_tables' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string', 'table_type='=>'string'], 'dba_close' => ['void', 'handle'=>'resource'], 'dba_delete' => ['bool', 'key'=>'string', 'handle'=>'resource'], 'dba_exists' => ['bool', 'key'=>'string', 'handle'=>'resource'], 'dba_fetch' => ['string|false', 'key'=>'string', 'skip'=>'int', 'handle'=>'resource'], 'dba_fetch\'1' => ['string|false', 'key'=>'string', 'handle'=>'resource'], 'dba_firstkey' => ['string|false', 'handle'=>'resource'], 'dba_handlers' => ['array', 'full_info='=>'bool'], 'dba_insert' => ['bool', 'key'=>'string', 'value'=>'string', 'handle'=>'resource'], 'dba_key_split' => ['array|false', 'key'=>'string'], 'dba_list' => ['array'], 'dba_nextkey' => ['string|false', 'handle'=>'resource'], 'dba_open' => ['resource|false', 'path'=>'string', 'mode'=>'string', 'handlername='=>'string', '...args='=>'string'], 'dba_optimize' => ['bool', 'handle'=>'resource'], 'dba_popen' => ['resource|false', 'path'=>'string', 'mode'=>'string', 'handlername='=>'string', '...args='=>'string'], 'dba_replace' => ['bool', 'key'=>'string', 'value'=>'string', 'handle'=>'resource'], 'dba_sync' => ['bool', 'handle'=>'resource'], 'dbase_add_record' => ['bool', 'dbase_identifier'=>'resource', 'record'=>'array'], 'dbase_close' => ['bool', 'dbase_identifier'=>'resource'], 'dbase_create' => ['resource|false', 'filename'=>'string', 'fields'=>'array'], 'dbase_delete_record' => ['bool', 'dbase_identifier'=>'resource', 'record_number'=>'int'], 'dbase_get_header_info' => ['array', 'dbase_identifier'=>'resource'], 'dbase_get_record' => ['array', 'dbase_identifier'=>'resource', 'record_number'=>'int'], 'dbase_get_record_with_names' => ['array', 'dbase_identifier'=>'resource', 'record_number'=>'int'], 'dbase_numfields' => ['int', 'dbase_identifier'=>'resource'], 'dbase_numrecords' => ['int', 'dbase_identifier'=>'resource'], 'dbase_open' => ['resource|false', 'filename'=>'string', 'mode'=>'int'], 'dbase_pack' => ['bool', 'dbase_identifier'=>'resource'], 'dbase_replace_record' => ['bool', 'dbase_identifier'=>'resource', 'record'=>'array', 'record_number'=>'int'], 'dbplus_add' => ['int', 'relation'=>'resource', 'tuple'=>'array'], 'dbplus_aql' => ['resource', 'query'=>'string', 'server='=>'string', 'dbpath='=>'string'], 'dbplus_chdir' => ['string', 'newdir='=>'string'], 'dbplus_close' => ['mixed', 'relation'=>'resource'], 'dbplus_curr' => ['int', 'relation'=>'resource', 'tuple'=>'array'], 'dbplus_errcode' => ['string', 'errno='=>'int'], 'dbplus_errno' => ['int'], 'dbplus_find' => ['int', 'relation'=>'resource', 'constraints'=>'array', 'tuple'=>'mixed'], 'dbplus_first' => ['int', 'relation'=>'resource', 'tuple'=>'array'], 'dbplus_flush' => ['int', 'relation'=>'resource'], 'dbplus_freealllocks' => ['int'], 'dbplus_freelock' => ['int', 'relation'=>'resource', 'tuple'=>'string'], 'dbplus_freerlocks' => ['int', 'relation'=>'resource'], 'dbplus_getlock' => ['int', 'relation'=>'resource', 'tuple'=>'string'], 'dbplus_getunique' => ['int', 'relation'=>'resource', 'uniqueid'=>'int'], 'dbplus_info' => ['int', 'relation'=>'resource', 'key'=>'string', 'result'=>'array'], 'dbplus_last' => ['int', 'relation'=>'resource', 'tuple'=>'array'], 'dbplus_lockrel' => ['int', 'relation'=>'resource'], 'dbplus_next' => ['int', 'relation'=>'resource', 'tuple'=>'array'], 'dbplus_open' => ['resource', 'name'=>'string'], 'dbplus_prev' => ['int', 'relation'=>'resource', 'tuple'=>'array'], 'dbplus_rchperm' => ['int', 'relation'=>'resource', 'mask'=>'int', 'user'=>'string', 'group'=>'string'], 'dbplus_rcreate' => ['resource', 'name'=>'string', 'domlist'=>'mixed', 'overwrite='=>'bool'], 'dbplus_rcrtexact' => ['mixed', 'name'=>'string', 'relation'=>'resource', 'overwrite='=>'bool'], 'dbplus_rcrtlike' => ['mixed', 'name'=>'string', 'relation'=>'resource', 'overwrite='=>'int'], 'dbplus_resolve' => ['array', 'relation_name'=>'string'], 'dbplus_restorepos' => ['int', 'relation'=>'resource', 'tuple'=>'array'], 'dbplus_rkeys' => ['mixed', 'relation'=>'resource', 'domlist'=>'mixed'], 'dbplus_ropen' => ['resource', 'name'=>'string'], 'dbplus_rquery' => ['resource', 'query'=>'string', 'dbpath='=>'string'], 'dbplus_rrename' => ['int', 'relation'=>'resource', 'name'=>'string'], 'dbplus_rsecindex' => ['mixed', 'relation'=>'resource', 'domlist'=>'mixed', 'type'=>'int'], 'dbplus_runlink' => ['int', 'relation'=>'resource'], 'dbplus_rzap' => ['int', 'relation'=>'resource'], 'dbplus_savepos' => ['int', 'relation'=>'resource'], 'dbplus_setindex' => ['int', 'relation'=>'resource', 'idx_name'=>'string'], 'dbplus_setindexbynumber' => ['int', 'relation'=>'resource', 'idx_number'=>'int'], 'dbplus_sql' => ['resource', 'query'=>'string', 'server='=>'string', 'dbpath='=>'string'], 'dbplus_tcl' => ['string', 'sid'=>'int', 'script'=>'string'], 'dbplus_tremove' => ['int', 'relation'=>'resource', 'tuple'=>'array', 'current='=>'array'], 'dbplus_undo' => ['int', 'relation'=>'resource'], 'dbplus_undoprepare' => ['int', 'relation'=>'resource'], 'dbplus_unlockrel' => ['int', 'relation'=>'resource'], 'dbplus_unselect' => ['int', 'relation'=>'resource'], 'dbplus_update' => ['int', 'relation'=>'resource', 'old'=>'array', 'new'=>'array'], 'dbplus_xlockrel' => ['int', 'relation'=>'resource'], 'dbplus_xunlockrel' => ['int', 'relation'=>'resource'], 'dbx_close' => ['int', 'link_identifier'=>'object'], 'dbx_compare' => ['int', 'row_a'=>'array', 'row_b'=>'array', 'column_key'=>'string', 'flags='=>'int'], 'dbx_connect' => ['object', 'module'=>'mixed', 'host'=>'string', 'database'=>'string', 'username'=>'string', 'password'=>'string', 'persistent='=>'int'], 'dbx_error' => ['string', 'link_identifier'=>'object'], 'dbx_escape_string' => ['string', 'link_identifier'=>'object', 'text'=>'string'], 'dbx_fetch_row' => ['mixed', 'result_identifier'=>'object'], 'dbx_query' => ['mixed', 'link_identifier'=>'object', 'sql_statement'=>'string', 'flags='=>'int'], 'dbx_sort' => ['bool', 'result'=>'object', 'user_compare_function'=>'string'], 'dcgettext' => ['string', 'domain_name'=>'string', 'msgid'=>'string', 'category'=>'int'], 'dcngettext' => ['string', 'domain'=>'string', 'msgid1'=>'string', 'msgid2'=>'string', 'n'=>'int', 'category'=>'int'], 'deaggregate' => ['', 'object'=>'object', 'class_name='=>'string'], 'debug_backtrace' => ['list\',args?:mixed[],object?:object}>', 'options='=>'int|bool', 'limit='=>'int'], 'debug_print_backtrace' => ['void', 'options='=>'int|bool', 'limit='=>'int'], 'debug_zval_dump' => ['void', '...var'=>'mixed'], 'debugger_connect' => [''], 'debugger_connector_pid' => [''], 'debugger_get_server_start_time' => [''], 'debugger_print' => [''], 'debugger_start_debug' => [''], 'decbin' => ['string', 'decimal_number'=>'int'], 'dechex' => ['string', 'num'=>'int'], 'decoct' => ['string', 'decimal_number'=>'int'], 'define' => ['bool', 'constant_name'=>'string', 'value'=>'mixed', 'case_insensitive='=>'bool'], 'define_syslog_variables' => ['void'], 'defined' => ['bool', 'name'=>'string'], 'deflate_add' => ['string|false', 'context'=>'resource', 'data'=>'string', 'flush_mode='=>'int'], 'deflate_init' => ['resource|false', 'encoding'=>'int', 'options='=>'array'], 'deg2rad' => ['float', 'number'=>'float'], 'dgettext' => ['string', 'domain_name'=>'string', 'msgid'=>'string'], 'dio_close' => ['void', 'fd'=>'resource'], 'dio_fcntl' => ['mixed', 'fd'=>'resource', 'cmd'=>'int', 'args='=>'mixed'], 'dio_open' => ['resource|false', 'filename'=>'string', 'flags'=>'int', 'mode='=>'int'], 'dio_read' => ['string', 'fd'=>'resource', 'len='=>'int'], 'dio_seek' => ['int', 'fd'=>'resource', 'pos'=>'int', 'whence='=>'int'], 'dio_stat' => ['array|null', 'fd'=>'resource'], 'dio_tcsetattr' => ['bool', 'fd'=>'resource', 'options'=>'array'], 'dio_truncate' => ['bool', 'fd'=>'resource', 'offset'=>'int'], 'dio_write' => ['int', 'fd'=>'resource', 'data'=>'string', 'len='=>'int'], 'dir' => ['Directory|false', 'directory'=>'string', 'context='=>'resource'], 'Directory::close' => ['void', 'dir_handle='=>'resource'], 'Directory::read' => ['string|false', 'dir_handle='=>'resource'], 'Directory::rewind' => ['void', 'dir_handle='=>'resource'], 'DirectoryIterator::__construct' => ['void', 'path'=>'string'], 'DirectoryIterator::__toString' => ['string'], 'DirectoryIterator::current' => ['DirectoryIterator'], 'DirectoryIterator::getATime' => ['int'], 'DirectoryIterator::getBasename' => ['string', 'suffix='=>'string'], 'DirectoryIterator::getChildren' => ['RecursiveDirectoryIterator'], 'DirectoryIterator::getCTime' => ['int'], 'DirectoryIterator::getExtension' => ['string'], 'DirectoryIterator::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'], 'DirectoryIterator::getFilename' => ['string'], 'DirectoryIterator::getGroup' => ['int'], 'DirectoryIterator::getInode' => ['int'], 'DirectoryIterator::getLinkTarget' => ['string'], 'DirectoryIterator::getMTime' => ['int'], 'DirectoryIterator::getOwner' => ['int'], 'DirectoryIterator::getPath' => ['string'], 'DirectoryIterator::getPathInfo' => ['SplFileInfo', 'class_name='=>'string'], 'DirectoryIterator::getPathname' => ['string'], 'DirectoryIterator::getPerms' => ['int'], 'DirectoryIterator::getRealPath' => ['string'], 'DirectoryIterator::getSize' => ['int'], 'DirectoryIterator::getType' => ['string'], 'DirectoryIterator::isDir' => ['bool'], 'DirectoryIterator::isDot' => ['bool'], 'DirectoryIterator::isExecutable' => ['bool'], 'DirectoryIterator::isFile' => ['bool'], 'DirectoryIterator::isLink' => ['bool'], 'DirectoryIterator::isReadable' => ['bool'], 'DirectoryIterator::isWritable' => ['bool'], 'DirectoryIterator::key' => ['string'], 'DirectoryIterator::next' => ['void'], 'DirectoryIterator::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'], 'DirectoryIterator::rewind' => ['void'], 'DirectoryIterator::seek' => ['void', 'position'=>'int'], 'DirectoryIterator::setFileClass' => ['void', 'class_name='=>'string'], 'DirectoryIterator::setInfoClass' => ['void', 'class_name='=>'string'], 'DirectoryIterator::valid' => ['bool'], 'dirname' => ['string', 'path'=>'string', 'levels='=>'positive-int'], 'disk_free_space' => ['float|false', 'path'=>'string'], 'disk_total_space' => ['float|false', 'path'=>'string'], 'diskfreespace' => ['float|false', 'path'=>'string'], 'display_disabled_function' => [''], 'dl' => ['bool', 'extension_filename'=>'string'], 'dngettext' => ['string', 'domain'=>'string', 'msgid1'=>'string', 'msgid2'=>'string', 'count'=>'int'], 'dns_check_record' => ['bool', 'host'=>'string', 'type='=>'string'], 'dns_get_mx' => ['bool', 'hostname'=>'string', '&w_mxhosts'=>'array', '&w_weight'=>'array'], 'dns_get_record' => ['list|false', 'hostname'=>'string', 'type='=>'int', '&w_authns='=>'array', '&w_addtl='=>'array', 'raw='=>'bool'], 'dom_document_relaxNG_validate_file' => ['bool', 'filename'=>'string'], 'dom_document_relaxNG_validate_xml' => ['bool', 'source'=>'string'], 'dom_document_schema_validate' => ['bool', 'source'=>'string', 'flags'=>'int'], 'dom_document_schema_validate_file' => ['bool', 'filename'=>'string', 'flags'=>'int'], 'dom_document_xinclude' => ['int', 'options'=>'int'], 'dom_import_simplexml' => ['DOMElement|false', 'node'=>'SimpleXMLElement'], 'dom_xpath_evaluate' => ['', 'expr'=>'string', 'context'=>'DOMNode', 'registernodens'=>'bool'], 'dom_xpath_query' => ['DOMNodeList', 'expr'=>'string', 'context'=>'DOMNode', 'registernodens'=>'bool'], 'dom_xpath_register_ns' => ['bool', 'prefix'=>'string', 'uri'=>'string'], 'dom_xpath_register_php_functions' => [''], 'DomainException::__clone' => ['void'], 'DomainException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?DomainException)'], 'DomainException::__toString' => ['string'], 'DomainException::__wakeup' => ['void'], 'DomainException::getCode' => ['int'], 'DomainException::getFile' => ['string'], 'DomainException::getLine' => ['int'], 'DomainException::getMessage' => ['string'], 'DomainException::getPrevious' => ['Throwable|DomainException|null'], 'DomainException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'DomainException::getTraceAsString' => ['string'], 'DOMAttr::__construct' => ['void', 'name'=>'string', 'value='=>'string'], 'DOMAttr::isId' => ['bool'], 'DomAttribute::name' => ['string'], 'DomAttribute::set_value' => ['bool', 'content'=>'string'], 'DomAttribute::specified' => ['bool'], 'DomAttribute::value' => ['string'], 'DOMCdataSection::__construct' => ['void', 'value'=>'string'], 'DOMCharacterData::appendData' => ['void', 'data'=>'string'], 'DOMCharacterData::deleteData' => ['void', 'offset'=>'int', 'count'=>'int'], 'DOMCharacterData::insertData' => ['void', 'offset'=>'int', 'data'=>'string'], 'DOMCharacterData::replaceData' => ['void', 'offset'=>'int', 'count'=>'int', 'data'=>'string'], 'DOMCharacterData::substringData' => ['string', 'offset'=>'int', 'count'=>'int'], 'DOMComment::__construct' => ['void', 'value='=>'string'], 'DOMDocument::__construct' => ['void', 'version='=>'string', 'encoding='=>'string'], 'DOMDocument::createAttribute' => ['__benevolent', 'name'=>'string'], 'DOMDocument::createAttributeNS' => ['__benevolent', 'namespaceuri'=>'string', 'qualifiedname'=>'string'], 'DOMDocument::createCDATASection' => ['__benevolent', 'data'=>'string'], 'DOMDocument::createComment' => ['DOMComment', 'data'=>'string'], 'DOMDocument::createDocumentFragment' => ['DOMDocumentFragment'], 'DOMDocument::createElement' => ['__benevolent', 'name'=>'string', 'value='=>'string'], 'DOMDocument::createElementNS' => ['__benevolent', 'namespaceuri'=>'string', 'qualifiedname'=>'string', 'value='=>'string'], 'DOMDocument::createEntityReference' => ['__benevolent', 'name'=>'string'], 'DOMDocument::createProcessingInstruction' => ['__benevolent', 'target'=>'string', 'data='=>'string'], 'DOMDocument::createTextNode' => ['DOMText', 'content'=>'string'], 'DOMDocument::getElementById' => ['DOMElement|null', 'elementid'=>'string'], 'DOMDocument::getElementsByTagName' => ['DOMNodeList', 'name'=>'string'], 'DOMDocument::getElementsByTagNameNS' => ['DOMNodeList', 'namespaceuri'=>'string', 'localname'=>'string'], 'DOMDocument::importNode' => ['DOMNode', 'importednode'=>'DOMNode', 'deep='=>'bool'], 'DOMDocument::load' => ['bool', 'filename'=>'string', 'options='=>'int'], 'DOMDocument::loadHTML' => ['bool', 'source'=>'string', 'options='=>'int'], 'DOMDocument::loadHTMLFile' => ['bool', 'filename'=>'string', 'options='=>'int'], 'DOMDocument::loadXML' => ['bool', 'source'=>'string', 'options='=>'int'], 'DOMDocument::normalizeDocument' => ['void'], 'DOMDocument::registerNodeClass' => ['bool', 'baseclass'=>'string', 'extendedclass'=>'string'], 'DOMDocument::relaxNGValidate' => ['bool', 'filename'=>'string'], 'DOMDocument::relaxNGValidateSource' => ['bool', 'source'=>'string'], 'DOMDocument::save' => ['int|false', 'filename'=>'string', 'options='=>'int'], 'DOMDocument::saveHTML' => ['string|false', 'node='=>'?DOMNode'], 'DOMDocument::saveHTMLFile' => ['int|false', 'filename'=>'string'], 'DOMDocument::saveXML' => ['string|false', 'node='=>'?DOMNode', 'options='=>'int'], 'DOMDocument::schemaValidate' => ['bool', 'filename'=>'string', 'flags='=>'int'], 'DOMDocument::schemaValidateSource' => ['bool', 'source'=>'string', 'flags='=>'int'], 'DOMDocument::validate' => ['bool'], 'DOMDocument::xinclude' => ['int', 'options='=>'int'], 'DOMDocumentFragment::__construct' => ['void'], 'DOMDocumentFragment::appendXML' => ['bool', 'data'=>'string'], 'DomDocumentType::entities' => ['array'], 'DomDocumentType::internal_subset' => ['bool'], 'DomDocumentType::name' => ['string'], 'DomDocumentType::notations' => ['array'], 'DomDocumentType::public_id' => ['string'], 'DomDocumentType::system_id' => ['string'], 'DOMElement::__construct' => ['void', 'name'=>'string', 'value='=>'string', 'uri='=>'string'], 'DOMElement::get_attribute' => ['string', 'name'=>'string'], 'DOMElement::get_attribute_node' => ['DomAttribute', 'name'=>'string'], 'DOMElement::get_elements_by_tagname' => ['array', 'name'=>'string'], 'DOMElement::getAttribute' => ['string', 'name'=>'string'], 'DOMElement::getAttributeNode' => ['DOMAttr', 'name'=>'string'], 'DOMElement::getAttributeNodeNS' => ['DOMAttr', 'namespaceuri'=>'string', 'localname'=>'string'], 'DOMElement::getAttributeNS' => ['string', 'namespaceuri'=>'string', 'localname'=>'string'], 'DOMElement::getElementsByTagName' => ['DOMNodeList', 'name'=>'string'], 'DOMElement::getElementsByTagNameNS' => ['DOMNodeList', 'namespaceuri'=>'string', 'localname'=>'string'], 'DOMElement::has_attribute' => ['bool', 'name'=>'string'], 'DOMElement::hasAttribute' => ['bool', 'name'=>'string'], 'DOMElement::hasAttributeNS' => ['bool', 'namespaceuri'=>'string', 'localname'=>'string'], 'DOMElement::remove_attribute' => ['bool', 'name'=>'string'], 'DOMElement::removeAttribute' => ['bool', 'name'=>'string'], 'DOMElement::removeAttributeNode' => ['bool', 'oldnode'=>'DOMAttr'], 'DOMElement::removeAttributeNS' => ['bool', 'namespaceuri'=>'string', 'localname'=>'string'], 'DOMElement::set_attribute' => ['DomAttribute', 'name'=>'string', 'value'=>'string'], 'DOMElement::set_attribute_node' => ['DomNode', 'attr'=>'DOMNode'], 'DOMElement::setAttribute' => ['DOMAttr', 'name'=>'string', 'value'=>'string'], 'DOMElement::setAttributeNode' => ['DOMAttr', 'attr'=>'DOMAttr'], 'DOMElement::setAttributeNodeNS' => ['DOMAttr', 'attr'=>'DOMAttr'], 'DOMElement::setAttributeNS' => ['void', 'namespaceuri'=>'string', 'qualifiedname'=>'string', 'value'=>'string'], 'DOMElement::setIdAttribute' => ['void', 'name'=>'string', 'isid'=>'bool'], 'DOMElement::setIdAttributeNode' => ['void', 'attr'=>'DOMAttr', 'isid'=>'bool'], 'DOMElement::setIdAttributeNS' => ['void', 'namespaceuri'=>'string', 'localname'=>'string', 'isid'=>'bool'], 'DOMElement::tagname' => ['string'], 'DOMEntityReference::__construct' => ['void', 'name'=>'string'], 'DOMImplementation::__construct' => ['void'], 'DOMImplementation::createDocument' => ['DOMDocument', 'namespaceuri='=>'string', 'qualifiedname='=>'string', 'doctype='=>'DOMDocumentType'], 'DOMImplementation::createDocumentType' => ['DOMDocumentType', 'qualifiedname='=>'string', 'publicid='=>'string', 'systemid='=>'string'], 'DOMImplementation::hasFeature' => ['bool', 'feature'=>'string', 'version'=>'string'], 'DOMNamedNodeMap::count' => ['0|positive-int'], 'DOMNamedNodeMap::getNamedItem' => ['?DOMNode', 'name'=>'string'], 'DOMNamedNodeMap::getNamedItemNS' => ['?DOMNode', 'namespaceuri'=>'string', 'localname'=>'string'], 'DOMNamedNodeMap::item' => ['?DOMNode', 'index'=>'int'], 'DomNode::add_namespace' => ['bool', 'uri'=>'string', 'prefix'=>'string'], 'DomNode::append_child' => ['DOMNode', 'newnode'=>'DOMNode'], 'DOMNode::appendChild' => ['DOMNode', 'newnode'=>'DOMNode'], 'DOMNode::C14N' => ['string', 'exclusive='=>'bool', 'with_comments='=>'bool', 'xpath='=>'array', 'ns_prefixes='=>'array'], 'DOMNode::C14NFile' => ['int', 'uri='=>'string', 'exclusive='=>'bool', 'with_comments='=>'bool', 'xpath='=>'array', 'ns_prefixes='=>'array'], 'DOMNode::cloneNode' => ['DOMNode', 'deep='=>'bool'], 'DOMNode::getLineNo' => ['int'], 'DOMNode::getNodePath' => ['?string'], 'DOMNode::hasAttributes' => ['bool'], 'DOMNode::hasChildNodes' => ['bool'], 'DOMNode::insertBefore' => ['DOMNode', 'newnode'=>'DOMNode', 'refnode='=>'DOMNode'], 'DOMNode::isDefaultNamespace' => ['bool', 'namespaceuri'=>'string'], 'DOMNode::isSameNode' => ['bool', 'node'=>'DOMNode'], 'DOMNode::isSupported' => ['bool', 'feature'=>'string', 'version'=>'string'], 'DOMNode::lookupNamespaceURI' => ['?string', 'prefix'=>'?string'], 'DOMNode::lookupPrefix' => ['string', 'namespaceuri'=>'string'], 'DOMNode::normalize' => ['void'], 'DOMNode::removeChild' => ['DOMNode', 'oldnode'=>'DOMNode'], 'DOMNode::replaceChild' => ['DOMNode', 'newnode'=>'DOMNode', 'oldnode'=>'DOMNode'], 'DOMNodeList::count' => ['0|positive-int'], 'DOMNodeList::item' => ['?DOMNode', 'index'=>'int'], 'DOMProcessingInstruction::__construct' => ['void', 'name'=>'string', 'value'=>'string'], 'DomProcessingInstruction::data' => ['string'], 'DomProcessingInstruction::target' => ['string'], 'DOMText::__construct' => ['void', 'value='=>'string'], 'DOMText::isElementContentWhitespace' => ['bool'], 'DOMText::isWhitespaceInElementContent' => ['bool'], 'DOMText::splitText' => ['DOMText|false', 'offset'=>'int'], 'domxml_new_doc' => ['DomDocument', 'version'=>'string'], 'domxml_open_file' => ['DomDocument', 'filename'=>'string', 'mode='=>'int', 'error='=>'array'], 'domxml_open_mem' => ['DomDocument', 'str'=>'string', 'mode='=>'int', 'error='=>'array'], 'domxml_version' => ['string'], 'domxml_xmltree' => ['DomDocument', 'str'=>'string'], 'domxml_xslt_stylesheet' => ['DomXsltStylesheet', 'xsl_buf'=>'string'], 'domxml_xslt_stylesheet_doc' => ['DomXsltStylesheet', 'xsl_doc'=>'DOMDocument'], 'domxml_xslt_stylesheet_file' => ['DomXsltStylesheet', 'xsl_file'=>'string'], 'domxml_xslt_version' => ['int'], 'DOMXPath::__construct' => ['void', 'doc'=>'DOMDocument'], 'DOMXPath::evaluate' => ['mixed', 'expression'=>'string', 'contextnode='=>'?DOMNode', 'registernodens='=>'bool'], 'DOMXPath::query' => ['DOMNodeList|false', 'expression'=>'string', 'contextnode='=>'?DOMNode', 'registernodens='=>'bool'], 'DOMXPath::registerNamespace' => ['bool', 'prefix'=>'string', 'namespaceuri'=>'string'], 'DOMXPath::registerPhpFunctions' => ['void', 'restrict='=>'mixed'], 'DomXsltStylesheet::process' => ['DomDocument', 'xml_doc'=>'DOMDocument', 'xslt_params='=>'array', 'is_xpath_param='=>'bool', 'profile_filename='=>'string'], 'DomXsltStylesheet::result_dump_file' => ['string', 'xmldoc'=>'DOMDocument', 'filename'=>'string'], 'DomXsltStylesheet::result_dump_mem' => ['string', 'xmldoc'=>'DOMDocument'], 'DOTNET::__construct' => ['void', 'assembly_name'=>'string', 'class_name'=>'string', 'codepage='=>'int'], 'dotnet_load' => ['int', 'assembly_name'=>'string', 'datatype_name='=>'string', 'codepage='=>'int'], 'doubleval' => ['float', 'var'=>'scalar|array|resource|null'], 'Ds\Collection::clear' => ['void'], 'Ds\Collection::copy' => ['Ds\Collection'], 'Ds\Collection::isEmpty' => ['bool'], 'Ds\Collection::toArray' => ['array'], 'Ds\Deque::__construct' => ['void', 'values='=>'mixed'], 'Ds\Deque::allocate' => ['void', 'capacity'=>'int'], 'Ds\Deque::apply' => ['void', 'callback'=>'callable'], 'Ds\Deque::capacity' => ['int'], 'Ds\Deque::clear' => ['void'], 'Ds\Deque::contains' => ['bool', '...values='=>'mixed'], 'Ds\Deque::copy' => ['Ds\Deque'], 'Ds\Deque::count' => ['0|positive-int'], 'Ds\Deque::filter' => ['Ds\Deque', 'callback='=>'callable'], 'Ds\Deque::find' => ['mixed', 'value'=>'mixed'], 'Ds\Deque::first' => ['mixed'], 'Ds\Deque::get' => ['void', 'index'=>'int'], 'Ds\Deque::insert' => ['void', 'index'=>'int', '...values='=>'mixed'], 'Ds\Deque::isEmpty' => ['bool'], 'Ds\Deque::join' => ['string', 'glue='=>'string'], 'Ds\Deque::jsonSerialize' => ['array'], 'Ds\Deque::last' => ['mixed'], 'Ds\Deque::map' => ['Ds\Deque', 'callback'=>'callable'], 'Ds\Deque::merge' => ['Ds\Deque', 'values'=>'mixed'], 'Ds\Deque::pop' => ['mixed'], 'Ds\Deque::push' => ['void', '...values='=>'mixed'], 'Ds\Deque::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'], 'Ds\Deque::remove' => ['mixed', 'index'=>'int'], 'Ds\Deque::reverse' => ['void'], 'Ds\Deque::reversed' => ['Ds\Deque'], 'Ds\Deque::rotate' => ['void', 'rotations'=>'int'], 'Ds\Deque::set' => ['void', 'index'=>'int', 'value'=>'mixed'], 'Ds\Deque::shift' => ['mixed'], 'Ds\Deque::slice' => ['Ds\Deque', 'index'=>'int', 'length='=>'?int'], 'Ds\Deque::sort' => ['void', 'comparator='=>'callable'], 'Ds\Deque::sorted' => ['Ds\Deque', 'comparator='=>'callable'], 'Ds\Deque::sum' => ['int|float'], 'Ds\Deque::toArray' => ['array'], 'Ds\Deque::unshift' => ['void', '...values='=>'mixed'], 'Ds\Hashable::equals' => ['bool', 'obj'=>'mixed'], 'Ds\Hashable::hash' => ['mixed'], 'Ds\Map::__construct' => ['void', 'values='=>'mixed'], 'Ds\Map::allocate' => ['void', 'capacity'=>'int'], 'Ds\Map::apply' => ['void', 'callback'=>'callable'], 'Ds\Map::capacity' => ['int'], 'Ds\Map::clear' => ['void'], 'Ds\Map::copy' => ['Ds\Map'], 'Ds\Map::count' => ['0|positive-int'], 'Ds\Map::diff' => ['Ds\Map', 'map'=>'Ds\Map'], 'Ds\Map::filter' => ['Ds\Map', 'callback='=>'callable'], 'Ds\Map::first' => ['Ds\Pair'], 'Ds\Map::get' => ['mixed', 'key'=>'mixed', 'default='=>'mixed'], 'Ds\Map::hasKey' => ['bool', 'key'=>'mixed'], 'Ds\Map::hasValue' => ['bool', 'value'=>'mixed'], 'Ds\Map::intersect' => ['Ds\Map', 'map'=>'Ds\Map'], 'Ds\Map::isEmpty' => ['bool'], 'Ds\Map::jsonSerialize' => ['array'], 'Ds\Map::keys' => ['Ds\Set'], 'Ds\Map::ksort' => ['void', 'comparator='=>'callable'], 'Ds\Map::ksorted' => ['Ds\Map', 'comparator='=>'callable'], 'Ds\Map::last' => ['Ds\Pair'], 'Ds\Map::map' => ['Ds\Map', 'callback'=>'callable'], 'Ds\Map::merge' => ['Ds\Map', 'values'=>'mixed'], 'Ds\Map::pairs' => ['Ds\Sequence'], 'Ds\Map::put' => ['void', 'key'=>'mixed', 'value'=>'mixed'], 'Ds\Map::putAll' => ['void', 'values'=>'mixed'], 'Ds\Map::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'], 'Ds\Map::remove' => ['mixed', 'key'=>'mixed', 'default='=>'mixed'], 'Ds\Map::reverse' => ['void'], 'Ds\Map::reversed' => ['Ds\Map'], 'Ds\Map::skip' => ['Ds\Pair', 'position'=>'int'], 'Ds\Map::slice' => ['Ds\Map', 'index'=>'int', 'length='=>'?int'], 'Ds\Map::sort' => ['void', 'comparator='=>'callable'], 'Ds\Map::sorted' => ['Ds\Map', 'comparator='=>'callable'], 'Ds\Map::sum' => ['int|float'], 'Ds\Map::toArray' => ['array'], 'Ds\Map::union' => ['Ds\Map', 'map'=>'Ds\Map'], 'Ds\Map::values' => ['Ds\Sequence'], 'Ds\Map::xor' => ['Ds\Map', 'map'=>'Ds\Map'], 'Ds\Pair::__construct' => ['void', 'key='=>'mixed', 'value='=>'mixed'], 'Ds\Pair::copy' => ['Ds\Pair'], 'Ds\Pair::jsonSerialize' => ['array'], 'Ds\Pair::toArray' => ['array'], 'Ds\PriorityQueue::__construct' => ['void'], 'Ds\PriorityQueue::allocate' => ['void', 'capacity'=>'int'], 'Ds\PriorityQueue::capacity' => ['int'], 'Ds\PriorityQueue::clear' => ['void'], 'Ds\PriorityQueue::copy' => ['Ds\PriorityQueue'], 'Ds\PriorityQueue::count' => ['0|positive-int'], 'Ds\PriorityQueue::isEmpty' => ['bool'], 'Ds\PriorityQueue::jsonSerialize' => ['array'], 'Ds\PriorityQueue::peek' => ['mixed'], 'Ds\PriorityQueue::pop' => ['mixed'], 'Ds\PriorityQueue::push' => ['void', 'value'=>'mixed', 'priority'=>'int'], 'Ds\PriorityQueue::toArray' => ['array'], 'Ds\Queue::__construct' => ['void', 'values='=>'mixed'], 'Ds\Queue::allocate' => ['void', 'capacity'=>'int'], 'Ds\Queue::capacity' => ['int'], 'Ds\Queue::clear' => ['void'], 'Ds\Queue::copy' => ['Ds\Queue'], 'Ds\Queue::count' => ['0|positive-int'], 'Ds\Queue::isEmpty' => ['bool'], 'Ds\Queue::jsonSerialize' => ['array'], 'Ds\Queue::peek' => ['mixed'], 'Ds\Queue::pop' => ['mixed'], 'Ds\Queue::push' => ['void', '...values='=>'mixed'], 'Ds\Queue::toArray' => ['array'], 'Ds\Sequence::allocate' => ['void', 'capacity'=>'int'], 'Ds\Sequence::apply' => ['void', 'callback'=>'callable'], 'Ds\Sequence::capacity' => ['int'], 'Ds\Sequence::contains' => ['bool', '...values='=>'mixed'], 'Ds\Sequence::filter' => ['Ds\Sequence', 'callback='=>'callable'], 'Ds\Sequence::find' => ['mixed', 'value'=>'mixed'], 'Ds\Sequence::first' => ['mixed'], 'Ds\Sequence::get' => ['mixed', 'index'=>'int'], 'Ds\Sequence::insert' => ['void', 'index'=>'int', '...values='=>'mixed'], 'Ds\Sequence::join' => ['string', 'glue='=>'string'], 'Ds\Sequence::last' => ['void'], 'Ds\Sequence::map' => ['Ds\Sequence', 'callback'=>'callable'], 'Ds\Sequence::merge' => ['Ds\Sequence', 'values'=>'mixed'], 'Ds\Sequence::pop' => ['mixed'], 'Ds\Sequence::push' => ['void', '...values='=>'mixed'], 'Ds\Sequence::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'], 'Ds\Sequence::remove' => ['mixed', 'index'=>'int'], 'Ds\Sequence::reverse' => ['void'], 'Ds\Sequence::reversed' => ['Ds\Sequence'], 'Ds\Sequence::rotate' => ['void', 'rotations'=>'int'], 'Ds\Sequence::set' => ['void', 'index'=>'int', 'value'=>'mixed'], 'Ds\Sequence::shift' => ['mixed'], 'Ds\Sequence::slice' => ['Ds\Sequence', 'index'=>'int', 'length='=>'?int'], 'Ds\Sequence::sort' => ['void', 'comparator='=>'callable'], 'Ds\Sequence::sorted' => ['Ds\Sequence', 'comparator='=>'callable'], 'Ds\Sequence::sum' => ['int|float'], 'Ds\Sequence::unshift' => ['void', '...values='=>'mixed'], 'Ds\Set::__construct' => ['void', 'values='=>'mixed'], 'Ds\Set::add' => ['void', '...values='=>'mixed'], 'Ds\Set::allocate' => ['void', 'capacity'=>'int'], 'Ds\Set::capacity' => ['int'], 'Ds\Set::clear' => ['void'], 'Ds\Set::contains' => ['bool', '...values='=>'mixed'], 'Ds\Set::copy' => ['Ds\Set'], 'Ds\Set::count' => ['0|positive-int'], 'Ds\Set::diff' => ['Ds\Set', 'set'=>'Ds\Set'], 'Ds\Set::filter' => ['Ds\Set', 'callback='=>'callable'], 'Ds\Set::first' => ['mixed'], 'Ds\Set::get' => ['mixed', 'index'=>'int'], 'Ds\Set::intersect' => ['Ds\Set', 'set'=>'Ds\Set'], 'Ds\Set::isEmpty' => ['bool'], 'Ds\Set::join' => ['string', 'glue='=>'string'], 'Ds\Set::jsonSerialize' => ['array'], 'Ds\Set::last' => ['mixed'], 'Ds\Set::map' => ['Ds\Set', 'callback='=>'callable'], 'Ds\Set::merge' => ['Ds\Set', 'values'=>'mixed'], 'Ds\Set::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'], 'Ds\Set::remove' => ['void', '...values='=>'mixed'], 'Ds\Set::reverse' => ['void'], 'Ds\Set::reversed' => ['Ds\Set'], 'Ds\Set::slice' => ['Ds\Set', 'index'=>'int', 'length='=>'?int'], 'Ds\Set::sort' => ['void', 'comparator='=>'callable'], 'Ds\Set::sorted' => ['Ds\Set', 'comparator='=>'callable'], 'Ds\Set::sum' => ['int|float'], 'Ds\Set::toArray' => ['array'], 'Ds\Set::union' => ['Ds\Set', 'set'=>'Ds\Set'], 'Ds\Set::xor' => ['Ds\Set', 'set'=>'Ds\Set'], 'Ds\Stack::__construct' => ['void', 'values='=>'mixed'], 'Ds\Stack::allocate' => ['void', 'capacity'=>'int'], 'Ds\Stack::capacity' => ['int'], 'Ds\Stack::clear' => ['void'], 'Ds\Stack::copy' => ['Ds\Stack'], 'Ds\Stack::count' => ['0|positive-int'], 'Ds\Stack::isEmpty' => ['bool'], 'Ds\Stack::jsonSerialize' => ['array'], 'Ds\Stack::peek' => ['mixed'], 'Ds\Stack::pop' => ['mixed'], 'Ds\Stack::push' => ['void', '...values='=>'mixed'], 'Ds\Stack::toArray' => ['array'], 'Ds\Vector::__construct' => ['void', 'values='=>'mixed'], 'Ds\Vector::allocate' => ['void', 'capacity'=>'int'], 'Ds\Vector::apply' => ['void', 'callback'=>'callable'], 'Ds\Vector::capacity' => ['int'], 'Ds\Vector::clear' => ['void'], 'Ds\Vector::contains' => ['bool', '...values='=>'mixed'], 'Ds\Vector::copy' => ['Ds\Vector'], 'Ds\Vector::count' => ['0|positive-int'], 'Ds\Vector::filter' => ['Ds\Vector', 'callback='=>'callable'], 'Ds\Vector::find' => ['mixed', 'value'=>'mixed'], 'Ds\Vector::first' => ['mixed'], 'Ds\Vector::get' => ['mixed', 'index'=>'int'], 'Ds\Vector::insert' => ['void', 'index'=>'int', '...values='=>'mixed'], 'Ds\Vector::isEmpty' => ['bool'], 'Ds\Vector::join' => ['string', 'glue='=>'string'], 'Ds\Vector::jsonSerialize' => ['array'], 'Ds\Vector::last' => ['mixed'], 'Ds\Vector::map' => ['Ds\Vector', 'callback'=>'callable'], 'Ds\Vector::merge' => ['Ds\Vector', 'values'=>'mixed'], 'Ds\Vector::pop' => ['mixed'], 'Ds\Vector::push' => ['void', '...values='=>'mixed'], 'Ds\Vector::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'], 'Ds\Vector::remove' => ['mixed', 'index'=>'int'], 'Ds\Vector::reverse' => ['void'], 'Ds\Vector::reversed' => ['Ds\Vector'], 'Ds\Vector::rotate' => ['void', 'rotations'=>'int'], 'Ds\Vector::set' => ['void', 'index'=>'int', 'value'=>'mixed'], 'Ds\Vector::shift' => ['mixed'], 'Ds\Vector::slice' => ['Ds\Vector', 'index'=>'int', 'length='=>'?int'], 'Ds\Vector::sort' => ['void', 'comparator='=>'callable'], 'Ds\Vector::sorted' => ['Ds\Vector', 'comparator='=>'callable'], 'Ds\Vector::sum' => ['int|float'], 'Ds\Vector::toArray' => ['array'], 'Ds\Vector::unshift' => ['void', '...values='=>'mixed'], 'each' => ['array', '&rw_arr'=>'array'], 'easter_date' => ['int', 'year='=>'int'], 'easter_days' => ['int', 'year='=>'int', 'method='=>'int'], 'eio_busy' => ['resource', 'delay'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_cancel' => ['void', 'req'=>'resource'], 'eio_chmod' => ['resource', 'path'=>'string', 'mode'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_chown' => ['resource', 'path'=>'string', 'uid'=>'int', 'gid='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_close' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_custom' => ['resource', 'execute'=>'callable', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], 'eio_dup2' => ['resource', 'fd'=>'mixed', 'fd2'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_event_loop' => ['bool'], 'eio_fallocate' => ['resource', 'fd'=>'mixed', 'mode'=>'int', 'offset'=>'int', 'length'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_fchmod' => ['resource', 'fd'=>'mixed', 'mode'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_fchown' => ['resource', 'fd'=>'mixed', 'uid'=>'int', 'gid='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_fdatasync' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_fstat' => ['resource', 'fd'=>'mixed', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], 'eio_fstatvfs' => ['resource', 'fd'=>'mixed', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], 'eio_fsync' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_ftruncate' => ['resource', 'fd'=>'mixed', 'offset='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_futime' => ['resource', 'fd'=>'mixed', 'atime'=>'float', 'mtime'=>'float', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_get_event_stream' => ['mixed'], 'eio_get_last_error' => ['string', 'req'=>'resource'], 'eio_grp' => ['resource', 'callback'=>'callable', 'data='=>'string'], 'eio_grp_add' => ['void', 'grp'=>'resource', 'req'=>'resource'], 'eio_grp_cancel' => ['void', 'grp'=>'resource'], 'eio_grp_limit' => ['void', 'grp'=>'resource', 'limit'=>'int'], 'eio_init' => ['void'], 'eio_link' => ['resource', 'path'=>'string', 'new_path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_lstat' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], 'eio_mkdir' => ['resource', 'path'=>'string', 'mode'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_mknod' => ['resource', 'path'=>'string', 'mode'=>'int', 'dev'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_nop' => ['resource', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_npending' => ['int'], 'eio_nready' => ['int'], 'eio_nreqs' => ['int'], 'eio_nthreads' => ['int'], 'eio_open' => ['resource', 'path'=>'string', 'flags'=>'int', 'mode'=>'int', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], 'eio_poll' => ['int'], 'eio_read' => ['resource', 'fd'=>'mixed', 'length'=>'int', 'offset'=>'int', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], 'eio_readahead' => ['resource', 'fd'=>'mixed', 'offset'=>'int', 'length'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_readdir' => ['resource', 'path'=>'string', 'flags'=>'int', 'pri'=>'int', 'callback'=>'callable', 'data='=>'string'], 'eio_readlink' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'string'], 'eio_realpath' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'string'], 'eio_rename' => ['resource', 'path'=>'string', 'new_path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_rmdir' => ['resource', 'path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_seek' => ['resource', 'fd'=>'mixed', 'offset'=>'int', 'whence'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_sendfile' => ['resource', 'out_fd'=>'mixed', 'in_fd'=>'mixed', 'offset'=>'int', 'length'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'string'], 'eio_set_max_idle' => ['void', 'nthreads'=>'int'], 'eio_set_max_parallel' => ['void', 'nthreads'=>'int'], 'eio_set_max_poll_reqs' => ['void', 'nreqs'=>'int'], 'eio_set_max_poll_time' => ['void', 'nseconds'=>'float'], 'eio_set_min_parallel' => ['void', 'nthreads'=>'string'], 'eio_stat' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], 'eio_statvfs' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], 'eio_symlink' => ['resource', 'path'=>'string', 'new_path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_sync' => ['resource', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_sync_file_range' => ['resource', 'fd'=>'mixed', 'offset'=>'int', 'nbytes'=>'int', 'flags'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_syncfs' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_truncate' => ['resource', 'path'=>'string', 'offset='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_unlink' => ['resource', 'path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_utime' => ['resource', 'path'=>'string', 'atime'=>'float', 'mtime'=>'float', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'eio_write' => ['resource', 'fd'=>'mixed', 'str'=>'string', 'length='=>'int', 'offset='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], 'EmptyIterator::current' => ['mixed'], 'EmptyIterator::key' => ['mixed'], 'EmptyIterator::next' => ['void'], 'EmptyIterator::rewind' => ['void'], 'EmptyIterator::valid' => ['bool'], 'enchant_broker_describe' => ['array', 'broker'=>'resource'], 'enchant_broker_dict_exists' => ['bool', 'broker'=>'resource', 'tag'=>'string'], 'enchant_broker_free' => ['bool', 'broker'=>'resource'], 'enchant_broker_free_dict' => ['bool', 'dict'=>'resource'], 'enchant_broker_get_dict_path' => ['string|false', 'broker'=>'resource', 'dict_type'=>'int'], 'enchant_broker_get_error' => ['string|false', 'broker'=>'resource'], 'enchant_broker_init' => ['resource|false'], 'enchant_broker_list_dicts' => ['array|false', 'broker'=>'resource'], 'enchant_broker_request_dict' => ['resource|false', 'broker'=>'resource', 'tag'=>'string'], 'enchant_broker_request_pwl_dict' => ['resource|false', 'broker'=>'resource', 'filename'=>'string'], 'enchant_broker_set_dict_path' => ['bool', 'broker'=>'resource', 'dict_type'=>'int', 'value'=>'string'], 'enchant_broker_set_ordering' => ['bool', 'broker'=>'resource', 'tag'=>'string', 'ordering'=>'string'], 'enchant_dict_add_to_personal' => ['void', 'dict'=>'resource', 'word'=>'string'], 'enchant_dict_add_to_session' => ['void', 'dict'=>'resource', 'word'=>'string'], 'enchant_dict_check' => ['bool', 'dict'=>'resource', 'word'=>'string'], 'enchant_dict_describe' => ['array', 'dict'=>'resource'], 'enchant_dict_get_error' => ['string|false', 'dict'=>'resource'], 'enchant_dict_is_in_session' => ['bool', 'dict'=>'resource', 'word'=>'string'], 'enchant_dict_quick_check' => ['bool', 'dict'=>'resource', 'word'=>'string', 'suggestions='=>'array'], 'enchant_dict_store_replacement' => ['void', 'dict'=>'resource', 'mis'=>'string', 'cor'=>'string'], 'enchant_dict_suggest' => ['array', 'dict'=>'resource', 'word'=>'string'], 'end' => ['mixed', '&rw_array_arg'=>'array|object'], 'ereg' => ['int', 'pattern'=>'string', 'string'=>'string', 'regs='=>'array'], 'ereg_replace' => ['string', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string'], 'eregi' => ['int', 'pattern'=>'string', 'string'=>'string', 'regs='=>'array'], 'eregi_replace' => ['string', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string'], 'Error::__clone' => ['void'], 'Error::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?Error)'], 'Error::__toString' => ['string'], 'Error::getCode' => ['int'], 'Error::getFile' => ['string'], 'Error::getLine' => ['int'], 'Error::getMessage' => ['string'], 'Error::getPrevious' => ['Throwable|Error|null'], 'Error::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'Error::getTraceAsString' => ['string'], 'error_clear_last' => ['void'], 'error_get_last' => ['?array{type:int,message:string,file:string,line:int}'], 'error_log' => ['bool', 'message'=>'string', 'message_type='=>'int', 'destination='=>'string', 'extra_headers='=>'string'], 'error_reporting' => ['int', 'new_error_level='=>'int'], 'ErrorException::__clone' => ['void'], 'ErrorException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'severity='=>'int', 'filename='=>'string', 'lineno='=>'int', 'previous='=>'(?Throwable)|(?ErrorException)'], 'ErrorException::__toString' => ['string'], 'ErrorException::getCode' => ['int'], 'ErrorException::getFile' => ['string'], 'ErrorException::getLine' => ['int'], 'ErrorException::getMessage' => ['string'], 'ErrorException::getPrevious' => ['Throwable|ErrorException|null'], 'ErrorException::getSeverity' => ['int'], 'ErrorException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'ErrorException::getTraceAsString' => ['string'], 'escapeshellarg' => ['string', 'arg'=>'string'], 'escapeshellcmd' => ['string', 'command'=>'string'], 'Ev::backend' => ['int'], 'Ev::depth' => ['int'], 'Ev::embeddableBackends' => ['int'], 'Ev::feedSignal' => ['void', 'signum'=>'int'], 'Ev::feedSignalEvent' => ['void', 'signum'=>'int'], 'Ev::iteration' => ['int'], 'Ev::now' => ['float'], 'Ev::nowUpdate' => ['void'], 'Ev::recommendedBackends' => ['int'], 'Ev::resume' => ['void'], 'Ev::run' => ['void', 'flags='=>'int'], 'Ev::sleep' => ['void', 'seconds'=>'float'], 'Ev::stop' => ['void', 'how='=>'int'], 'Ev::supportedBackends' => ['int'], 'Ev::suspend' => ['void'], 'Ev::time' => ['float'], 'Ev::verify' => ['void'], 'EvCheck::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvCheck::createStopped' => ['object', 'callback'=>'string', 'data='=>'string', 'priority='=>'string'], 'EvChild::__construct' => ['void', 'pid'=>'int', 'trace'=>'bool', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvChild::createStopped' => ['object', 'pid'=>'int', 'trace'=>'bool', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvChild::set' => ['void', 'pid'=>'int', 'trace'=>'bool'], 'EvEmbed::__construct' => ['void', 'other'=>'object', 'callback='=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvEmbed::createStopped' => ['void', 'other'=>'object', 'callback='=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvEmbed::set' => ['void', 'other'=>'object'], 'EvEmbed::sweep' => ['void'], 'Event::__construct' => ['void', 'base'=>'EventBase', 'fd'=>'mixed', 'what'=>'int', 'cb'=>'callable', 'arg='=>'mixed'], 'Event::add' => ['bool', 'timeout='=>'float'], 'Event::addSignal' => ['bool', 'timeout='=>'float'], 'Event::addTimer' => ['bool', 'timeout='=>'float'], 'Event::del' => ['bool'], 'Event::delSignal' => ['bool'], 'Event::delTimer' => ['bool'], 'Event::free' => ['void'], 'Event::getSupportedMethods' => ['array'], 'Event::pending' => ['bool', 'flags'=>'int'], 'Event::set' => ['bool', 'base'=>'EventBase', 'fd'=>'mixed', 'what='=>'int', 'cb='=>'callable', 'arg='=>'mixed'], 'Event::setPriority' => ['bool', 'priority'=>'int'], 'Event::setTimer' => ['bool', 'base'=>'EventBase', 'cb'=>'callable', 'arg='=>'mixed'], 'Event::signal' => ['Event', 'base'=>'EventBase', 'signum'=>'int', 'cb'=>'callable', 'arg='=>'mixed'], 'Event::timer' => ['Event', 'base'=>'EventBase', 'cb'=>'callable', 'arg='=>'mixed'], 'event_add' => ['bool', 'event'=>'resource', 'timeout='=>'int'], 'event_base_free' => ['void', 'event_base'=>'resource'], 'event_base_loop' => ['int', 'event_base'=>'resource', 'flags='=>'int'], 'event_base_loopbreak' => ['bool', 'event_base'=>'resource'], 'event_base_loopexit' => ['bool', 'event_base'=>'resource', 'timeout='=>'int'], 'event_base_new' => ['resource'], 'event_base_priority_init' => ['bool', 'event_base'=>'resource', 'npriorities'=>'int'], 'event_base_reinit' => ['bool', 'event_base'=>'resource'], 'event_base_set' => ['bool', 'event'=>'resource', 'event_base'=>'resource'], 'event_buffer_base_set' => ['bool', 'bevent'=>'resource', 'event_base'=>'resource'], 'event_buffer_disable' => ['bool', 'bevent'=>'resource', 'events'=>'int'], 'event_buffer_enable' => ['bool', 'bevent'=>'resource', 'events'=>'int'], 'event_buffer_fd_set' => ['void', 'bevent'=>'resource', 'fd'=>'resource'], 'event_buffer_free' => ['void', 'bevent'=>'resource'], 'event_buffer_new' => ['resource', 'stream'=>'resource', 'readcb'=>'mixed', 'writecb'=>'mixed', 'errorcb'=>'mixed', 'arg='=>'mixed'], 'event_buffer_priority_set' => ['bool', 'bevent'=>'resource', 'priority'=>'int'], 'event_buffer_read' => ['string', 'bevent'=>'resource', 'data_size'=>'int'], 'event_buffer_set_callback' => ['bool', 'event'=>'resource', 'readcb'=>'mixed', 'writecb'=>'mixed', 'errorcb'=>'mixed', 'arg='=>'mixed'], 'event_buffer_timeout_set' => ['void', 'bevent'=>'resource', 'read_timeout'=>'int', 'write_timeout'=>'int'], 'event_buffer_watermark_set' => ['void', 'bevent'=>'resource', 'events'=>'int', 'lowmark'=>'int', 'highmark'=>'int'], 'event_buffer_write' => ['bool', 'bevent'=>'resource', 'data'=>'string', 'data_size='=>'int'], 'event_del' => ['bool', 'event'=>'resource'], 'event_free' => ['void', 'event'=>'resource'], 'event_new' => ['resource'], 'event_priority_set' => ['bool', 'event'=>'resource', 'priority'=>'int'], 'event_set' => ['bool', 'event'=>'resource', 'fd'=>'mixed', 'events'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'], 'event_timer_add' => ['bool', 'event'=>'resource', 'timeout='=>'int'], 'event_timer_del' => ['bool', 'event'=>'resource'], 'event_timer_new' => ['bool|resource'], 'event_timer_pending' => ['bool', 'event'=>'resource', 'timeout='=>'int'], 'event_timer_set' => ['bool', 'event'=>'resource', 'callback'=>'callable', 'arg='=>'mixed'], 'EventBase::__construct' => ['void', 'cfg='=>'EventConfig'], 'EventBase::dispatch' => ['void'], 'EventBase::exit' => ['bool', 'timeout='=>'float'], 'EventBase::free' => ['void'], 'EventBase::getFeatures' => ['int'], 'EventBase::getMethod' => ['string', 'cfg='=>'EventConfig'], 'EventBase::getTimeOfDayCached' => ['float'], 'EventBase::gotExit' => ['bool'], 'EventBase::gotStop' => ['bool'], 'EventBase::loop' => ['bool', 'flags='=>'int'], 'EventBase::priorityInit' => ['bool', 'n_priorities'=>'int'], 'EventBase::reInit' => ['bool'], 'EventBase::stop' => ['bool'], 'EventBuffer::__construct' => ['void'], 'EventBuffer::add' => ['bool', 'data'=>'string'], 'EventBuffer::addBuffer' => ['bool', 'buf'=>'EventBuffer'], 'EventBuffer::appendFrom' => ['int', 'buf'=>'EventBuffer', 'len'=>'int'], 'EventBuffer::copyout' => ['int', '&w_data'=>'string', 'max_bytes'=>'int'], 'EventBuffer::drain' => ['bool', 'len'=>'int'], 'EventBuffer::enableLocking' => ['void'], 'EventBuffer::expand' => ['bool', 'len'=>'int'], 'EventBuffer::freeze' => ['bool', 'at_front'=>'bool'], 'EventBuffer::lock' => ['void'], 'EventBuffer::prepend' => ['bool', 'data'=>'string'], 'EventBuffer::prependBuffer' => ['bool', 'buf'=>'EventBuffer'], 'EventBuffer::pullup' => ['string', 'size'=>'int'], 'EventBuffer::read' => ['string', 'max_bytes'=>'int'], 'EventBuffer::readFrom' => ['int', 'fd'=>'mixed', 'howmuch'=>'int'], 'EventBuffer::readLine' => ['string', 'eol_style'=>'int'], 'EventBuffer::search' => ['mixed', 'what'=>'string', 'start='=>'int', 'end='=>'int'], 'EventBuffer::searchEol' => ['mixed', 'start='=>'int', 'eol_style='=>'int'], 'EventBuffer::substr' => ['string', 'start'=>'int', 'length='=>'int'], 'EventBuffer::unfreeze' => ['bool', 'at_front'=>'bool'], 'EventBuffer::unlock' => ['bool'], 'EventBuffer::write' => ['int', 'fd'=>'mixed', 'howmuch='=>'int'], 'EventBufferEvent::__construct' => ['void', 'base'=>'EventBase', 'socket='=>'mixed', 'options='=>'int', 'readcb='=>'callable', 'writecb='=>'callable', 'eventcb='=>'callable'], 'EventBufferEvent::close' => ['void'], 'EventBufferEvent::connect' => ['bool', 'addr'=>'string'], 'EventBufferEvent::connectHost' => ['bool', 'dns_base'=>'EventDnsBase', 'hostname'=>'string', 'port'=>'int', 'family='=>'int'], 'EventBufferEvent::createPair' => ['array', 'base'=>'EventBase', 'options='=>'int'], 'EventBufferEvent::disable' => ['bool', 'events'=>'int'], 'EventBufferEvent::enable' => ['bool', 'events'=>'int'], 'EventBufferEvent::free' => ['void'], 'EventBufferEvent::getDnsErrorString' => ['string'], 'EventBufferEvent::getEnabled' => ['int'], 'EventBufferEvent::getInput' => ['EventBuffer'], 'EventBufferEvent::getOutput' => ['EventBuffer'], 'EventBufferEvent::read' => ['string', 'size'=>'int'], 'EventBufferEvent::readBuffer' => ['bool', 'buf'=>'EventBuffer'], 'EventBufferEvent::setCallbacks' => ['void', 'readcb'=>'callable', 'writecb'=>'callable', 'eventcb'=>'callable', 'arg='=>'string'], 'EventBufferEvent::setPriority' => ['bool', 'priority'=>'int'], 'EventBufferEvent::setTimeouts' => ['bool', 'timeout_read'=>'float', 'timeout_write'=>'float'], 'EventBufferEvent::setWatermark' => ['void', 'events'=>'int', 'lowmark'=>'int', 'highmark'=>'int'], 'EventBufferEvent::sslError' => ['string'], 'EventBufferEvent::sslFilter' => ['EventBufferEvent', 'base'=>'EventBase', 'underlying'=>'EventBufferEvent', 'ctx'=>'EventSslContext', 'state'=>'int', 'options='=>'int'], 'EventBufferEvent::sslGetCipherInfo' => ['string'], 'EventBufferEvent::sslGetCipherName' => ['string'], 'EventBufferEvent::sslGetCipherVersion' => ['string'], 'EventBufferEvent::sslGetProtocol' => ['string'], 'EventBufferEvent::sslRenegotiate' => ['void'], 'EventBufferEvent::sslSocket' => ['EventBufferEvent', 'base'=>'EventBase', 'socket'=>'mixed', 'ctx'=>'EventSslContext', 'state'=>'int', 'options='=>'int'], 'EventBufferEvent::write' => ['bool', 'data'=>'string'], 'EventBufferEvent::writeBuffer' => ['bool', 'buf'=>'EventBuffer'], 'EventConfig::__construct' => ['void'], 'EventConfig::avoidMethod' => ['bool', 'method'=>'string'], 'EventConfig::requireFeatures' => ['bool', 'feature'=>'int'], 'EventConfig::setMaxDispatchInterval' => ['void', 'max_interval'=>'int', 'max_callbacks'=>'int', 'min_priority'=>'int'], 'EventDnsBase::__construct' => ['void', 'base'=>'EventBase', 'initialize'=>'bool'], 'EventDnsBase::addNameserverIp' => ['bool', 'ip'=>'string'], 'EventDnsBase::addSearch' => ['void', 'domain'=>'string'], 'EventDnsBase::clearSearch' => ['void'], 'EventDnsBase::countNameservers' => ['int'], 'EventDnsBase::loadHosts' => ['bool', 'hosts'=>'string'], 'EventDnsBase::parseResolvConf' => ['bool', 'flags'=>'int', 'filename'=>'string'], 'EventDnsBase::setOption' => ['bool', 'option'=>'string', 'value'=>'string'], 'EventDnsBase::setSearchNdots' => ['bool', 'ndots'=>'int'], 'EventHttp::__construct' => ['void', 'base'=>'EventBase', 'ctx='=>'EventSslContext'], 'EventHttp::accept' => ['bool', 'socket'=>'mixed'], 'EventHttp::addServerAlias' => ['bool', 'alias'=>'string'], 'EventHttp::bind' => ['void', 'address'=>'string', 'port'=>'int'], 'EventHttp::removeServerAlias' => ['bool', 'alias'=>'string'], 'EventHttp::setAllowedMethods' => ['void', 'methods'=>'int'], 'EventHttp::setCallback' => ['void', 'path'=>'string', 'cb'=>'string', 'arg='=>'string'], 'EventHttp::setDefaultCallback' => ['void', 'cb'=>'string', 'arg='=>'string'], 'EventHttp::setMaxBodySize' => ['void', 'value'=>'int'], 'EventHttp::setMaxHeadersSize' => ['void', 'value'=>'int'], 'EventHttp::setTimeout' => ['void', 'value'=>'int'], 'EventHttpConnection::__construct' => ['void', 'base'=>'EventBase', 'dns_base'=>'EventDnsBase', 'address'=>'string', 'port'=>'int', 'ctx='=>'EventSslContext'], 'EventHttpConnection::getBase' => ['EventBase'], 'EventHttpConnection::getPeer' => ['void', '&w_address'=>'string', '&w_port'=>'int'], 'EventHttpConnection::makeRequest' => ['bool', 'req'=>'EventHttpRequest', 'type'=>'int', 'uri'=>'string'], 'EventHttpConnection::setCloseCallback' => ['void', 'callback'=>'callable', 'data='=>'mixed'], 'EventHttpConnection::setLocalAddress' => ['void', 'address'=>'string'], 'EventHttpConnection::setLocalPort' => ['void', 'port'=>'int'], 'EventHttpConnection::setMaxBodySize' => ['void', 'max_size'=>'string'], 'EventHttpConnection::setMaxHeadersSize' => ['void', 'max_size'=>'string'], 'EventHttpConnection::setRetries' => ['void', 'retries'=>'int'], 'EventHttpConnection::setTimeout' => ['void', 'timeout'=>'int'], 'EventHttpRequest::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed'], 'EventHttpRequest::addHeader' => ['bool', 'key'=>'string', 'value'=>'string', 'type'=>'int'], 'EventHttpRequest::cancel' => ['void'], 'EventHttpRequest::clearHeaders' => ['void'], 'EventHttpRequest::closeConnection' => ['void'], 'EventHttpRequest::findHeader' => ['void', 'key'=>'string', 'type'=>'string'], 'EventHttpRequest::free' => ['void'], 'EventHttpRequest::getBufferEvent' => ['EventBufferEvent'], 'EventHttpRequest::getCommand' => ['void'], 'EventHttpRequest::getConnection' => ['EventHttpConnection'], 'EventHttpRequest::getHost' => ['string'], 'EventHttpRequest::getInputBuffer' => ['EventBuffer'], 'EventHttpRequest::getInputHeaders' => ['array'], 'EventHttpRequest::getOutputBuffer' => ['EventBuffer'], 'EventHttpRequest::getOutputHeaders' => ['void'], 'EventHttpRequest::getResponseCode' => ['int'], 'EventHttpRequest::getUri' => ['string'], 'EventHttpRequest::removeHeader' => ['void', 'key'=>'string', 'type'=>'string'], 'EventHttpRequest::sendError' => ['void', 'error'=>'int', 'reason='=>'string'], 'EventHttpRequest::sendReply' => ['void', 'code'=>'int', 'reason'=>'string', 'buf='=>'EventBuffer'], 'EventHttpRequest::sendReplyChunk' => ['void', 'buf'=>'EventBuffer'], 'EventHttpRequest::sendReplyEnd' => ['void'], 'EventHttpRequest::sendReplyStart' => ['void', 'code'=>'int', 'reason'=>'string'], 'EventListener::__construct' => ['void', 'base'=>'EventBase', 'cb'=>'callable', 'data'=>'mixed', 'flags'=>'int', 'backlog'=>'int', 'target'=>'mixed'], 'EventListener::disable' => ['bool'], 'EventListener::enable' => ['bool'], 'EventListener::getBase' => ['void'], 'EventListener::getSocketName' => ['bool', '&w_address'=>'string', '&w_port='=>'mixed'], 'EventListener::setCallback' => ['void', 'cb'=>'callable', 'arg='=>'mixed'], 'EventListener::setErrorCallback' => ['void', 'cb'=>'string'], 'EventSslContext::__construct' => ['void', 'method'=>'string', 'options'=>'string'], 'EventUtil::__construct' => ['void'], 'EventUtil::getLastSocketErrno' => ['int', 'socket='=>'mixed'], 'EventUtil::getLastSocketError' => ['string', 'socket='=>'mixed'], 'EventUtil::getSocketFd' => ['int', 'socket'=>'mixed'], 'EventUtil::getSocketName' => ['bool', 'socket'=>'mixed', '&w_address'=>'string', '&w_port='=>'mixed'], 'EventUtil::setSocketOption' => ['bool', 'socket'=>'mixed', 'level'=>'int', 'optname'=>'int', 'optval'=>'mixed'], 'EventUtil::sslRandPoll' => ['void'], 'EvFork::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvFork::createStopped' => ['object', 'callback'=>'string', 'data='=>'string', 'priority='=>'string'], 'EvIdle::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvIdle::createStopped' => ['object', 'callback'=>'string', 'data='=>'mixed', 'priority='=>'int'], 'EvIo::__construct' => ['void', 'fd'=>'mixed', 'events'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvIo::createStopped' => ['EvIo', 'fd'=>'mixed', 'events'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvIo::set' => ['void', 'fd'=>'mixed', 'events'=>'int'], 'EvLoop::__construct' => ['void', 'flags='=>'int', 'data='=>'mixed', 'io_interval='=>'float', 'timeout_interval='=>'float'], 'EvLoop::backend' => ['int'], 'EvLoop::check' => ['EvCheck', 'callback'=>'string', 'data='=>'string', 'priority='=>'string'], 'EvLoop::child' => ['EvChild', 'pid'=>'string', 'trace'=>'string', 'callback'=>'string', 'data='=>'string', 'priority='=>'string'], 'EvLoop::defaultLoop' => ['EvLoop', 'flags='=>'int', 'data='=>'mixed', 'io_interval='=>'float', 'timeout_interval='=>'float'], 'EvLoop::embed' => ['EvEmbed', 'other'=>'string', 'callback='=>'string', 'data='=>'string', 'priority='=>'string'], 'EvLoop::fork' => ['EvFork', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvLoop::idle' => ['EvIdle', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvLoop::invokePending' => ['void'], 'EvLoop::io' => ['EvIo', 'fd'=>'mixed', 'events'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvLoop::loopFork' => ['void'], 'EvLoop::now' => ['float'], 'EvLoop::nowUpdate' => ['void'], 'EvLoop::periodic' => ['EvPeriodic', 'offset'=>'float', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvLoop::prepare' => ['EvPrepare', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvLoop::resume' => ['void'], 'EvLoop::run' => ['void', 'flags='=>'int'], 'EvLoop::signal' => ['EvSignal', 'signum'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvLoop::stat' => ['EvStat', 'path'=>'string', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvLoop::stop' => ['void', 'how='=>'int'], 'EvLoop::suspend' => ['void'], 'EvLoop::timer' => ['EvTimer', 'after'=>'float', 'repeat'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvLoop::verify' => ['void'], 'EvPeriodic::__construct' => ['void', 'offset'=>'float', 'interval'=>'string', 'reschedule_cb'=>'callable', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvPeriodic::again' => ['void'], 'EvPeriodic::at' => ['float'], 'EvPeriodic::createStopped' => ['EvPeriodic', 'offset'=>'float', 'interval'=>'float', 'reschedule_cb'=>'callable', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvPeriodic::set' => ['void', 'offset'=>'float', 'interval'=>'float'], 'EvPrepare::__construct' => ['void', 'callback'=>'string', 'data='=>'string', 'priority='=>'string'], 'EvPrepare::createStopped' => ['EvPrepare', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvSignal::__construct' => ['void', 'signum'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvSignal::createStopped' => ['EvSignal', 'signum'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvSignal::set' => ['void', 'signum'=>'int'], 'EvStat::__construct' => ['void', 'path'=>'string', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvStat::attr' => ['array'], 'EvStat::createStopped' => ['void', 'path'=>'string', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvStat::prev' => ['void'], 'EvStat::set' => ['void', 'path'=>'string', 'interval'=>'float'], 'EvStat::stat' => ['bool'], 'EvTimer::__construct' => ['void', 'after'=>'float', 'repeat'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvTimer::again' => ['void'], 'EvTimer::createStopped' => ['EvTimer', 'after'=>'float', 'repeat'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], 'EvTimer::set' => ['void', 'after'=>'float', 'repeat'=>'float'], 'EvWatcher::__construct' => ['void'], 'EvWatcher::clear' => ['int'], 'EvWatcher::feed' => ['void', 'revents'=>'int'], 'EvWatcher::getLoop' => ['EvLoop'], 'EvWatcher::invoke' => ['void', 'revents'=>'int'], 'EvWatcher::keepalive' => ['bool', 'value='=>'bool'], 'EvWatcher::setCallback' => ['void', 'callback'=>'callable'], 'EvWatcher::start' => ['void'], 'EvWatcher::stop' => ['void'], 'Exception::__clone' => ['void'], 'Exception::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?Exception)'], 'Exception::__toString' => ['string'], 'Exception::getCode' => ['mixed'], 'Exception::getFile' => ['string'], 'Exception::getLine' => ['int'], 'Exception::getMessage' => ['string'], 'Exception::getPrevious' => ['(?Throwable)|(?Exception)'], 'Exception::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'Exception::getTraceAsString' => ['string'], 'exec' => ['string|false', 'command'=>'string', '&w_output='=>'array', '&w_return_value='=>'int'], 'exif_imagetype' => ['int|false', 'imagefile'=>'string'], 'exif_read_data' => ['array|false', 'filename'=>'string|resource', 'sections_needed='=>'string', 'sub_arrays='=>'bool', 'read_thumbnail='=>'bool'], 'exif_tagname' => ['string|false', 'index'=>'int'], 'exif_thumbnail' => ['string|false', 'filename'=>'string', '&w_width='=>'int', '&w_height='=>'int', '&w_imagetype='=>'int'], 'exp' => ['float', 'number'=>'float'], 'expect_expectl' => ['int', 'expect'=>'resource', 'cases'=>'array', 'match='=>'array'], 'expect_popen' => ['resource|false', 'command'=>'string'], 'explode' => ['list|false', 'separator'=>'string', 'str'=>'string', 'limit='=>'int'], 'expm1' => ['float', 'number'=>'float'], 'extension_loaded' => ['bool', 'extension_name'=>'string'], 'extract' => ['0|positive-int', 'array'=>'array', 'flags='=>'int', 'prefix='=>'string|null'], 'ezmlm_hash' => ['int', 'addr'=>'string'], 'fam_cancel_monitor' => ['bool', 'fam'=>'resource', 'fam_monitor'=>'resource'], 'fam_close' => ['void', 'fam'=>'resource'], 'fam_monitor_collection' => ['resource', 'fam'=>'resource', 'dirname'=>'string', 'depth'=>'int', 'mask'=>'string'], 'fam_monitor_directory' => ['resource', 'fam'=>'resource', 'dirname'=>'string'], 'fam_monitor_file' => ['resource', 'fam'=>'resource', 'filename'=>'string'], 'fam_next_event' => ['array', 'fam'=>'resource'], 'fam_open' => ['resource|false', 'appname='=>'string'], 'fam_pending' => ['int', 'fam'=>'resource'], 'fam_resume_monitor' => ['bool', 'fam'=>'resource', 'fam_monitor'=>'resource'], 'fam_suspend_monitor' => ['bool', 'fam'=>'resource', 'fam_monitor'=>'resource'], 'fann_cascadetrain_on_data' => ['bool', 'ann'=>'resource', 'data'=>'resource', 'max_neurons'=>'int', 'neurons_between_reports'=>'int', 'desired_error'=>'float'], 'fann_cascadetrain_on_file' => ['bool', 'ann'=>'resource', 'filename'=>'string', 'max_neurons'=>'int', 'neurons_between_reports'=>'int', 'desired_error'=>'float'], 'fann_clear_scaling_params' => ['bool', 'ann'=>'resource'], 'fann_copy' => ['resource', 'ann'=>'resource'], 'fann_create_from_file' => ['resource', 'configuration_file'=>'string'], 'fann_create_shortcut' => ['reference', 'num_layers'=>'int', 'num_neurons1'=>'int', 'num_neurons2'=>'int', '...args='=>'int'], 'fann_create_shortcut_array' => ['resource', 'num_layers'=>'int', 'layers'=>'array'], 'fann_create_sparse' => ['resource|false', 'connection_rate'=>'float', 'num_layers'=>'int', 'num_neurons1'=>'int', 'num_neurons2'=>'int', '...args='=>'int'], 'fann_create_sparse_array' => ['resource|false', 'connection_rate'=>'float', 'num_layers'=>'int', 'layers'=>'array'], 'fann_create_standard' => ['resource', 'num_layers'=>'int', 'num_neurons1'=>'int', 'num_neurons2'=>'int', '...args='=>'int'], 'fann_create_standard_array' => ['resource', 'num_layers'=>'int', 'layers'=>'array'], 'fann_create_train' => ['resource', 'num_data'=>'int', 'num_input'=>'int', 'num_output'=>'int'], 'fann_create_train_from_callback' => ['resource', 'num_data'=>'int', 'num_input'=>'int', 'num_output'=>'int', 'user_function'=>'callable'], 'fann_descale_input' => ['bool', 'ann'=>'resource', 'input_vector'=>'array'], 'fann_descale_output' => ['bool', 'ann'=>'resource', 'output_vector'=>'array'], 'fann_descale_train' => ['bool', 'ann'=>'resource', 'train_data'=>'resource'], 'fann_destroy' => ['bool', 'ann'=>'resource'], 'fann_destroy_train' => ['bool', 'train_data'=>'resource'], 'fann_duplicate_train_data' => ['resource', 'data'=>'resource'], 'fann_get_activation_function' => ['int', 'ann'=>'resource', 'layer'=>'int', 'neuron'=>'int'], 'fann_get_activation_steepness' => ['float', 'ann'=>'resource', 'layer'=>'int', 'neuron'=>'int'], 'fann_get_bias_array' => ['array', 'ann'=>'resource'], 'fann_get_bit_fail' => ['int', 'ann'=>'resource'], 'fann_get_bit_fail_limit' => ['float', 'ann'=>'resource'], 'fann_get_cascade_activation_functions' => ['array', 'ann'=>'resource'], 'fann_get_cascade_activation_functions_count' => ['int', 'ann'=>'resource'], 'fann_get_cascade_activation_steepnesses' => ['array', 'ann'=>'resource'], 'fann_get_cascade_activation_steepnesses_count' => ['int', 'ann'=>'resource'], 'fann_get_cascade_candidate_change_fraction' => ['float', 'ann'=>'resource'], 'fann_get_cascade_candidate_limit' => ['float', 'ann'=>'resource'], 'fann_get_cascade_candidate_stagnation_epochs' => ['float', 'ann'=>'resource'], 'fann_get_cascade_max_cand_epochs' => ['int', 'ann'=>'resource'], 'fann_get_cascade_max_out_epochs' => ['int', 'ann'=>'resource'], 'fann_get_cascade_min_cand_epochs' => ['int', 'ann'=>'resource'], 'fann_get_cascade_min_out_epochs' => ['int', 'ann'=>'resource'], 'fann_get_cascade_num_candidate_groups' => ['int', 'ann'=>'resource'], 'fann_get_cascade_num_candidates' => ['int', 'ann'=>'resource'], 'fann_get_cascade_output_change_fraction' => ['float', 'ann'=>'resource'], 'fann_get_cascade_output_stagnation_epochs' => ['int', 'ann'=>'resource'], 'fann_get_cascade_weight_multiplier' => ['float', 'ann'=>'resource'], 'fann_get_connection_array' => ['array', 'ann'=>'resource'], 'fann_get_connection_rate' => ['float', 'ann'=>'resource'], 'fann_get_errno' => ['int', 'errdat'=>'resource'], 'fann_get_errstr' => ['string', 'errdat'=>'resource'], 'fann_get_layer_array' => ['array', 'ann'=>'resource'], 'fann_get_learning_momentum' => ['float', 'ann'=>'resource'], 'fann_get_learning_rate' => ['float', 'ann'=>'resource'], 'fann_get_MSE' => ['float', 'ann'=>'resource'], 'fann_get_network_type' => ['int', 'ann'=>'resource'], 'fann_get_num_input' => ['int', 'ann'=>'resource'], 'fann_get_num_layers' => ['int', 'ann'=>'resource'], 'fann_get_num_output' => ['int', 'ann'=>'resource'], 'fann_get_quickprop_decay' => ['float', 'ann'=>'resource'], 'fann_get_quickprop_mu' => ['float', 'ann'=>'resource'], 'fann_get_rprop_decrease_factor' => ['float', 'ann'=>'resource'], 'fann_get_rprop_delta_max' => ['float', 'ann'=>'resource'], 'fann_get_rprop_delta_min' => ['float', 'ann'=>'resource'], 'fann_get_rprop_delta_zero' => ['float|false', 'ann'=>'resource'], 'fann_get_rprop_increase_factor' => ['float', 'ann'=>'resource'], 'fann_get_sarprop_step_error_shift' => ['float', 'ann'=>'resource'], 'fann_get_sarprop_step_error_threshold_factor' => ['float', 'ann'=>'resource'], 'fann_get_sarprop_temperature' => ['float', 'ann'=>'resource'], 'fann_get_sarprop_weight_decay_shift' => ['float', 'ann'=>'resource'], 'fann_get_total_connections' => ['int', 'ann'=>'resource'], 'fann_get_total_neurons' => ['int', 'ann'=>'resource'], 'fann_get_train_error_function' => ['int', 'ann'=>'resource'], 'fann_get_train_stop_function' => ['int', 'ann'=>'resource'], 'fann_get_training_algorithm' => ['int', 'ann'=>'resource'], 'fann_init_weights' => ['bool', 'ann'=>'resource', 'train_data'=>'resource'], 'fann_length_train_data' => ['int', 'data'=>'resource'], 'fann_merge_train_data' => ['resource', 'data1'=>'resource', 'data2'=>'resource'], 'fann_num_input_train_data' => ['int', 'data'=>'resource'], 'fann_num_output_train_data' => ['int', 'data'=>'resource'], 'fann_print_error' => ['void', 'errdat'=>'string'], 'fann_randomize_weights' => ['bool', 'ann'=>'resource', 'min_weight'=>'float', 'max_weight'=>'float'], 'fann_read_train_from_file' => ['resource', 'filename'=>'string'], 'fann_reset_errno' => ['void', 'errdat'=>'resource'], 'fann_reset_errstr' => ['void', 'errdat'=>'resource'], 'fann_reset_MSE' => ['bool', 'ann'=>'string'], 'fann_run' => ['array', 'ann'=>'resource', 'input'=>'array'], 'fann_save' => ['bool', 'ann'=>'resource', 'configuration_file'=>'string'], 'fann_save_train' => ['bool', 'data'=>'resource', 'file_name'=>'string'], 'fann_scale_input' => ['bool', 'ann'=>'resource', 'input_vector'=>'array'], 'fann_scale_input_train_data' => ['bool', 'train_data'=>'resource', 'new_min'=>'float', 'new_max'=>'float'], 'fann_scale_output' => ['bool', 'ann'=>'resource', 'output_vector'=>'array'], 'fann_scale_output_train_data' => ['bool', 'train_data'=>'resource', 'new_min'=>'float', 'new_max'=>'float'], 'fann_scale_train' => ['bool', 'ann'=>'resource', 'train_data'=>'resource'], 'fann_scale_train_data' => ['bool', 'train_data'=>'resource', 'new_min'=>'float', 'new_max'=>'float'], 'fann_set_activation_function' => ['bool', 'ann'=>'resource', 'activation_function'=>'int', 'layer'=>'int', 'neuron'=>'int'], 'fann_set_activation_function_hidden' => ['bool', 'ann'=>'resource', 'activation_function'=>'int'], 'fann_set_activation_function_layer' => ['bool', 'ann'=>'resource', 'activation_function'=>'int', 'layer'=>'int'], 'fann_set_activation_function_output' => ['bool', 'ann'=>'resource', 'activation_function'=>'int'], 'fann_set_activation_steepness' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float', 'layer'=>'int', 'neuron'=>'int'], 'fann_set_activation_steepness_hidden' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float'], 'fann_set_activation_steepness_layer' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float', 'layer'=>'int'], 'fann_set_activation_steepness_output' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float'], 'fann_set_bit_fail_limit' => ['bool', 'ann'=>'resource', 'bit_fail_limit'=>'float'], 'fann_set_callback' => ['bool', 'ann'=>'resource', 'callback'=>'callable'], 'fann_set_cascade_activation_functions' => ['bool', 'ann'=>'resource', 'cascade_activation_functions'=>'array'], 'fann_set_cascade_activation_steepnesses' => ['bool', 'ann'=>'resource', 'cascade_activation_steepnesses_count'=>'array'], 'fann_set_cascade_candidate_change_fraction' => ['bool', 'ann'=>'resource', 'cascade_candidate_change_fraction'=>'float'], 'fann_set_cascade_candidate_limit' => ['bool', 'ann'=>'resource', 'cascade_candidate_limit'=>'float'], 'fann_set_cascade_candidate_stagnation_epochs' => ['bool', 'ann'=>'resource', 'cascade_candidate_stagnation_epochs'=>'int'], 'fann_set_cascade_max_cand_epochs' => ['bool', 'ann'=>'resource', 'cascade_max_cand_epochs'=>'int'], 'fann_set_cascade_max_out_epochs' => ['bool', 'ann'=>'resource', 'cascade_max_out_epochs'=>'int'], 'fann_set_cascade_min_cand_epochs' => ['bool', 'ann'=>'resource', 'cascade_min_cand_epochs'=>'int'], 'fann_set_cascade_min_out_epochs' => ['bool', 'ann'=>'resource', 'cascade_min_out_epochs'=>'int'], 'fann_set_cascade_num_candidate_groups' => ['bool', 'ann'=>'resource', 'cascade_num_candidate_groups'=>'int'], 'fann_set_cascade_output_change_fraction' => ['bool', 'ann'=>'resource', 'cascade_output_change_fraction'=>'float'], 'fann_set_cascade_output_stagnation_epochs' => ['bool', 'ann'=>'resource', 'cascade_output_stagnation_epochs'=>'int'], 'fann_set_cascade_weight_multiplier' => ['bool', 'ann'=>'resource', 'cascade_weight_multiplier'=>'float'], 'fann_set_error_log' => ['void', 'errdat'=>'resource', 'log_file'=>'string'], 'fann_set_input_scaling_params' => ['bool', 'ann'=>'resource', 'train_data'=>'resource', 'new_input_min'=>'float', 'new_input_max'=>'float'], 'fann_set_learning_momentum' => ['bool', 'ann'=>'resource', 'learning_momentum'=>'float'], 'fann_set_learning_rate' => ['bool', 'ann'=>'resource', 'learning_rate'=>'float'], 'fann_set_output_scaling_params' => ['bool', 'ann'=>'resource', 'train_data'=>'resource', 'new_output_min'=>'float', 'new_output_max'=>'float'], 'fann_set_quickprop_decay' => ['bool', 'ann'=>'resource', 'quickprop_decay'=>'float'], 'fann_set_quickprop_mu' => ['bool', 'ann'=>'resource', 'quickprop_mu'=>'float'], 'fann_set_rprop_decrease_factor' => ['bool', 'ann'=>'resource', 'rprop_decrease_factor'=>'float'], 'fann_set_rprop_delta_max' => ['bool', 'ann'=>'resource', 'rprop_delta_max'=>'float'], 'fann_set_rprop_delta_min' => ['bool', 'ann'=>'resource', 'rprop_delta_min'=>'float'], 'fann_set_rprop_delta_zero' => ['bool', 'ann'=>'resource', 'rprop_delta_zero'=>'float'], 'fann_set_rprop_increase_factor' => ['bool', 'ann'=>'resource', 'rprop_increase_factor'=>'float'], 'fann_set_sarprop_step_error_shift' => ['bool', 'ann'=>'resource', 'sarprop_step_error_shift'=>'float'], 'fann_set_sarprop_step_error_threshold_factor' => ['bool', 'ann'=>'resource', 'sarprop_step_error_threshold_factor'=>'float'], 'fann_set_sarprop_temperature' => ['bool', 'ann'=>'resource', 'sarprop_temperature'=>'float'], 'fann_set_sarprop_weight_decay_shift' => ['bool', 'ann'=>'resource', 'sarprop_weight_decay_shift'=>'float'], 'fann_set_scaling_params' => ['bool', 'ann'=>'resource', 'train_data'=>'resource', 'new_input_min'=>'float', 'new_input_max'=>'float', 'new_output_min'=>'float', 'new_output_max'=>'float'], 'fann_set_train_error_function' => ['bool', 'ann'=>'resource', 'error_function'=>'int'], 'fann_set_train_stop_function' => ['bool', 'ann'=>'resource', 'stop_function'=>'int'], 'fann_set_training_algorithm' => ['bool', 'ann'=>'resource', 'training_algorithm'=>'int'], 'fann_set_weight' => ['bool', 'ann'=>'resource', 'from_neuron'=>'int', 'to_neuron'=>'int', 'weight'=>'float'], 'fann_set_weight_array' => ['bool', 'ann'=>'resource', 'connections'=>'array'], 'fann_shuffle_train_data' => ['bool', 'train_data'=>'resource'], 'fann_subset_train_data' => ['resource', 'data'=>'resource', 'pos'=>'int', 'length'=>'int'], 'fann_test' => ['bool', 'ann'=>'resource', 'input'=>'array', 'desired_output'=>'array'], 'fann_test_data' => ['float', 'ann'=>'resource', 'data'=>'resource'], 'fann_train' => ['bool', 'ann'=>'resource', 'input'=>'array', 'desired_output'=>'array'], 'fann_train_epoch' => ['float', 'ann'=>'resource', 'data'=>'resource'], 'fann_train_on_data' => ['bool', 'ann'=>'resource', 'data'=>'resource', 'max_epochs'=>'int', 'epochs_between_reports'=>'int', 'desired_error'=>'float'], 'fann_train_on_file' => ['bool', 'ann'=>'resource', 'filename'=>'string', 'max_epochs'=>'int', 'epochs_between_reports'=>'int', 'desired_error'=>'float'], 'FANNConnection::__construct' => ['void', 'from_neuron'=>'int', 'to_neuron'=>'int', 'weight'=>'float'], 'FANNConnection::getFromNeuron' => ['int'], 'FANNConnection::getToNeuron' => ['int'], 'FANNConnection::getWeight' => ['void'], 'FANNConnection::setWeight' => ['bool', 'weight'=>'float'], 'fastcgi_finish_request' => ['bool'], 'fbsql_affected_rows' => ['int', 'link_identifier='=>'?resource'], 'fbsql_autocommit' => ['bool', 'link_identifier'=>'resource', 'onoff='=>'bool'], 'fbsql_blob_size' => ['int', 'blob_handle'=>'string', 'link_identifier='=>'?resource'], 'fbsql_change_user' => ['bool', 'user'=>'string', 'password'=>'string', 'database='=>'string', 'link_identifier='=>'?resource'], 'fbsql_clob_size' => ['int', 'clob_handle'=>'string', 'link_identifier='=>'?resource'], 'fbsql_close' => ['bool', 'link_identifier='=>'?resource'], 'fbsql_commit' => ['bool', 'link_identifier='=>'?resource'], 'fbsql_connect' => ['resource', 'hostname='=>'string', 'username='=>'string', 'password='=>'string'], 'fbsql_create_blob' => ['string', 'blob_data'=>'string', 'link_identifier='=>'?resource'], 'fbsql_create_clob' => ['string', 'clob_data'=>'string', 'link_identifier='=>'?resource'], 'fbsql_create_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource', 'database_options='=>'string'], 'fbsql_data_seek' => ['bool', 'result'=>'resource', 'row_number'=>'int'], 'fbsql_database' => ['string', 'link_identifier'=>'resource', 'database='=>'string'], 'fbsql_database_password' => ['string', 'link_identifier'=>'resource', 'database_password='=>'string'], 'fbsql_db_query' => ['resource', 'database'=>'string', 'query'=>'string', 'link_identifier='=>'?resource'], 'fbsql_db_status' => ['int', 'database_name'=>'string', 'link_identifier='=>'?resource'], 'fbsql_drop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'], 'fbsql_errno' => ['int', 'link_identifier='=>'?resource'], 'fbsql_error' => ['string', 'link_identifier='=>'?resource'], 'fbsql_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'], 'fbsql_fetch_assoc' => ['array', 'result'=>'resource'], 'fbsql_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'], 'fbsql_fetch_lengths' => ['array', 'result'=>'resource'], 'fbsql_fetch_object' => ['object', 'result'=>'resource'], 'fbsql_fetch_row' => ['array', 'result'=>'resource'], 'fbsql_field_flags' => ['string', 'result'=>'resource', 'field_offset='=>'int'], 'fbsql_field_len' => ['int', 'result'=>'resource', 'field_offset='=>'int'], 'fbsql_field_name' => ['string', 'result'=>'resource', 'field_index='=>'int'], 'fbsql_field_seek' => ['bool', 'result'=>'resource', 'field_offset='=>'int'], 'fbsql_field_table' => ['string', 'result'=>'resource', 'field_offset='=>'int'], 'fbsql_field_type' => ['string', 'result'=>'resource', 'field_offset='=>'int'], 'fbsql_free_result' => ['bool', 'result'=>'resource'], 'fbsql_get_autostart_info' => ['array', 'link_identifier='=>'?resource'], 'fbsql_hostname' => ['string', 'link_identifier'=>'resource', 'host_name='=>'string'], 'fbsql_insert_id' => ['int', 'link_identifier='=>'?resource'], 'fbsql_list_dbs' => ['resource', 'link_identifier='=>'?resource'], 'fbsql_list_fields' => ['resource', 'database_name'=>'string', 'table_name'=>'string', 'link_identifier='=>'?resource'], 'fbsql_list_tables' => ['resource', 'database'=>'string', 'link_identifier='=>'?resource'], 'fbsql_next_result' => ['bool', 'result'=>'resource'], 'fbsql_num_fields' => ['int', 'result'=>'resource'], 'fbsql_num_rows' => ['int', 'result'=>'resource'], 'fbsql_password' => ['string', 'link_identifier'=>'resource', 'password='=>'string'], 'fbsql_pconnect' => ['resource', 'hostname='=>'string', 'username='=>'string', 'password='=>'string'], 'fbsql_query' => ['resource', 'query'=>'string', 'link_identifier='=>'?resource', 'batch_size='=>'int'], 'fbsql_read_blob' => ['string', 'blob_handle'=>'string', 'link_identifier='=>'?resource'], 'fbsql_read_clob' => ['string', 'clob_handle'=>'string', 'link_identifier='=>'?resource'], 'fbsql_result' => ['mixed', 'result'=>'resource', 'row='=>'int', 'field='=>'mixed'], 'fbsql_rollback' => ['bool', 'link_identifier='=>'?resource'], 'fbsql_rows_fetched' => ['int', 'result'=>'resource'], 'fbsql_select_db' => ['bool', 'database_name='=>'string', 'link_identifier='=>'?resource'], 'fbsql_set_characterset' => ['void', 'link_identifier'=>'resource', 'characterset'=>'int', 'in_out_both='=>'int'], 'fbsql_set_lob_mode' => ['bool', 'result'=>'resource', 'lob_mode'=>'int'], 'fbsql_set_password' => ['bool', 'link_identifier'=>'resource', 'user'=>'string', 'password'=>'string', 'old_password'=>'string'], 'fbsql_set_transaction' => ['void', 'link_identifier'=>'resource', 'locking'=>'int', 'isolation'=>'int'], 'fbsql_start_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource', 'database_options='=>'string'], 'fbsql_stop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'], 'fbsql_table_name' => ['string', 'result'=>'resource', 'index'=>'int'], 'fbsql_username' => ['string', 'link_identifier'=>'resource', 'username='=>'string'], 'fbsql_warnings' => ['bool', 'onoff='=>'bool'], 'fclose' => ['bool', 'fp'=>'resource'], 'fdf_add_doc_javascript' => ['bool', 'fdf_document'=>'resource', 'script_name'=>'string', 'script_code'=>'string'], 'fdf_add_template' => ['bool', 'fdf_document'=>'resource', 'newpage'=>'int', 'filename'=>'string', 'template'=>'string', 'rename'=>'int'], 'fdf_close' => ['void', 'fdf_document'=>'resource'], 'fdf_create' => ['resource'], 'fdf_enum_values' => ['bool', 'fdf_document'=>'resource', 'function'=>'callable', 'userdata='=>'mixed'], 'fdf_errno' => ['int'], 'fdf_error' => ['string', 'error_code='=>'int'], 'fdf_get_ap' => ['bool', 'fdf_document'=>'resource', 'field'=>'string', 'face'=>'int', 'filename'=>'string'], 'fdf_get_attachment' => ['array', 'fdf_document'=>'resource', 'fieldname'=>'string', 'savepath'=>'string'], 'fdf_get_encoding' => ['string', 'fdf_document'=>'resource'], 'fdf_get_file' => ['string', 'fdf_document'=>'resource'], 'fdf_get_flags' => ['int', 'fdf_document'=>'resource', 'fieldname'=>'string', 'whichflags'=>'int'], 'fdf_get_opt' => ['mixed', 'fdf_document'=>'resource', 'fieldname'=>'string', 'element='=>'int'], 'fdf_get_status' => ['string', 'fdf_document'=>'resource'], 'fdf_get_value' => ['mixed', 'fdf_document'=>'resource', 'fieldname'=>'string', 'which='=>'int'], 'fdf_get_version' => ['string', 'fdf_document='=>'resource'], 'fdf_header' => ['void'], 'fdf_next_field_name' => ['string', 'fdf_document'=>'resource', 'fieldname='=>'string'], 'fdf_open' => ['resource|false', 'filename'=>'string'], 'fdf_open_string' => ['resource', 'fdf_data'=>'string'], 'fdf_remove_item' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'item'=>'int'], 'fdf_save' => ['bool', 'fdf_document'=>'resource', 'filename='=>'string'], 'fdf_save_string' => ['string', 'fdf_document'=>'resource'], 'fdf_set_ap' => ['bool', 'fdf_document'=>'resource', 'field_name'=>'string', 'face'=>'int', 'filename'=>'string', 'page_number'=>'int'], 'fdf_set_encoding' => ['bool', 'fdf_document'=>'resource', 'encoding'=>'string'], 'fdf_set_file' => ['bool', 'fdf_document'=>'resource', 'url'=>'string', 'target_frame='=>'string'], 'fdf_set_flags' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'whichflags'=>'int', 'newflags'=>'int'], 'fdf_set_javascript_action' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'trigger'=>'int', 'script'=>'string'], 'fdf_set_on_import_javascript' => ['bool', 'fdf_document'=>'resource', 'script'=>'string', 'before_data_import'=>'bool'], 'fdf_set_opt' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'element'=>'int', 'str1'=>'string', 'str2'=>'string'], 'fdf_set_status' => ['bool', 'fdf_document'=>'resource', 'status'=>'string'], 'fdf_set_submit_form_action' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'trigger'=>'int', 'script'=>'string', 'flags'=>'int'], 'fdf_set_target_frame' => ['bool', 'fdf_document'=>'resource', 'frame_name'=>'string'], 'fdf_set_value' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'value'=>'mixed', 'isname='=>'int'], 'fdf_set_version' => ['bool', 'fdf_document'=>'resource', 'version'=>'string'], 'feof' => ['bool', 'fp'=>'resource'], 'fflush' => ['bool', 'fp'=>'resource'], 'ffmpeg_animated_gif::__construct' => ['void', 'output_file_path'=>'string', 'width'=>'int', 'height'=>'int', 'frame_rate'=>'int', 'loop_count='=>'int'], 'ffmpeg_animated_gif::addFrame' => ['', 'frame_to_add'=>'ffmpeg_frame'], 'ffmpeg_frame::__construct' => ['void', 'gd_image'=>'resource'], 'ffmpeg_frame::crop' => ['', 'crop_top'=>'int', 'crop_bottom='=>'int', 'crop_left='=>'int', 'crop_right='=>'int'], 'ffmpeg_frame::getHeight' => ['int'], 'ffmpeg_frame::getPresentationTimestamp' => ['int'], 'ffmpeg_frame::getPTS' => ['int'], 'ffmpeg_frame::getWidth' => ['int'], 'ffmpeg_frame::resize' => ['', 'width'=>'int', 'height'=>'int', 'crop_top='=>'int', 'crop_bottom='=>'int', 'crop_left='=>'int', 'crop_right='=>'int'], 'ffmpeg_frame::toGDImage' => ['resource'], 'ffmpeg_movie::__construct' => ['void', 'path_to_media'=>'string', 'persistent'=>'bool'], 'ffmpeg_movie::getArtist' => ['string'], 'ffmpeg_movie::getAudioBitRate' => ['int'], 'ffmpeg_movie::getAudioChannels' => ['int'], 'ffmpeg_movie::getAudioCodec' => ['string'], 'ffmpeg_movie::getAudioSampleRate' => ['int'], 'ffmpeg_movie::getAuthor' => ['string'], 'ffmpeg_movie::getBitRate' => ['int'], 'ffmpeg_movie::getComment' => ['string'], 'ffmpeg_movie::getCopyright' => ['string'], 'ffmpeg_movie::getDuration' => ['int'], 'ffmpeg_movie::getFilename' => ['string'], 'ffmpeg_movie::getFrame' => ['ffmpeg_frame', 'framenumber'=>'int'], 'ffmpeg_movie::getFrameCount' => ['int'], 'ffmpeg_movie::getFrameHeight' => ['int'], 'ffmpeg_movie::getFrameNumber' => ['int'], 'ffmpeg_movie::getFrameRate' => ['int'], 'ffmpeg_movie::getFrameWidth' => ['int'], 'ffmpeg_movie::getGenre' => ['string'], 'ffmpeg_movie::getNextKeyFrame' => ['ffmpeg_frame'], 'ffmpeg_movie::getPixelFormat' => [''], 'ffmpeg_movie::getTitle' => ['string'], 'ffmpeg_movie::getTrackNumber' => ['int|string'], 'ffmpeg_movie::getVideoBitRate' => ['int'], 'ffmpeg_movie::getVideoCodec' => ['string'], 'ffmpeg_movie::getYear' => ['int|string'], 'ffmpeg_movie::hasAudio' => ['bool'], 'ffmpeg_movie::hasVideo' => ['bool'], 'fgetc' => ['string|false', 'fp'=>'resource'], 'fgetcsv' => ['list|array{0: null}|false|null', 'fp'=>'resource', 'length='=>'0|positive-int|null', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'], 'fgets' => ['string|false', 'fp'=>'resource', 'length='=>'0|positive-int'], 'fgetss' => ['string|false', 'fp'=>'resource', 'length='=>'0|positive-int', 'allowable_tags='=>'string'], 'file' => ['list|false', 'filename'=>'string', 'flags='=>'int', 'context='=>'resource'], 'file_exists' => ['bool', 'filename'=>'string'], 'file_get_contents' => ['string|false', 'filename'=>'string', 'use_include_path='=>'bool', 'context='=>'?resource', 'offset='=>'int', 'maxlen='=>'0|positive-int'], 'file_put_contents' => ['0|positive-int|false', 'file'=>'string', 'data'=>'mixed', 'flags='=>'int', 'context='=>'?resource'], 'fileatime' => ['int|false', 'filename'=>'string'], 'filectime' => ['int|false', 'filename'=>'string'], 'filegroup' => ['int|false', 'filename'=>'string'], 'fileinode' => ['int|false', 'filename'=>'string'], 'filemtime' => ['int|false', 'filename'=>'string'], 'fileowner' => ['int|false', 'filename'=>'string'], 'fileperms' => ['int|false', 'filename'=>'string'], 'filepro' => ['bool', 'directory'=>'string'], 'filepro_fieldcount' => ['int'], 'filepro_fieldname' => ['string', 'field_number'=>'int'], 'filepro_fieldtype' => ['string', 'field_number'=>'int'], 'filepro_fieldwidth' => ['int', 'field_number'=>'int'], 'filepro_retrieve' => ['string', 'row_number'=>'int', 'field_number'=>'int'], 'filepro_rowcount' => ['int'], 'filesize' => ['0|positive-int|false', 'filename'=>'string'], 'FilesystemIterator::__construct' => ['void', 'path'=>'string', 'flags='=>'int'], 'FilesystemIterator::current' => ['string|SplFileInfo'], 'FilesystemIterator::getFlags' => ['int'], 'FilesystemIterator::key' => ['string'], 'FilesystemIterator::next' => ['void'], 'FilesystemIterator::rewind' => ['void'], 'FilesystemIterator::setFlags' => ['void', 'flags='=>'int'], 'filetype' => ['string|false', 'filename'=>'string'], 'filter_has_var' => ['bool', 'type'=>'int', 'variable_name'=>'string'], 'filter_id' => ['int|false', 'filtername'=>'string'], 'filter_input' => ['mixed', 'type'=>'int', 'variable_name'=>'string', 'filter='=>'int', 'options='=>'array|int'], 'filter_input_array' => ['array|false|null', 'type'=>'int', 'definition='=>'int|array', 'add_empty='=>'bool'], 'filter_list' => ['non-empty-list'], 'filter_var' => ['mixed', 'variable'=>'mixed', 'filter='=>'int', 'options='=>'mixed'], 'filter_var_array' => ['array|false|null', 'data'=>'array', 'definition='=>'mixed', 'add_empty='=>'bool'], 'FilterIterator::__construct' => ['void', 'iterator'=>'Iterator'], 'FilterIterator::accept' => ['bool'], 'FilterIterator::current' => ['mixed'], 'FilterIterator::getInnerIterator' => ['Iterator'], 'FilterIterator::key' => ['mixed'], 'FilterIterator::next' => ['void'], 'FilterIterator::rewind' => ['void'], 'FilterIterator::valid' => ['bool'], 'finfo::__construct' => ['void', 'options='=>'int', 'magic_file='=>'string'], 'finfo::finfo' => ['void', 'options='=>'int', 'magic_file='=>'string'], 'finfo::buffer' => ['string|false', 'string'=>'string', 'options='=>'int', 'context='=>'resource'], 'finfo::file' => ['string|false', 'file_name'=>'string', 'options='=>'int', 'context='=>'resource'], 'finfo::set_flags' => ['bool', 'options'=>'int'], 'finfo_buffer' => ['string|false', 'finfo'=>'resource', 'string'=>'string', 'options='=>'int', 'context='=>'resource'], 'finfo_close' => ['bool', 'finfo'=>'resource'], 'finfo_file' => ['string|false', 'finfo'=>'resource', 'file_name'=>'string', 'options='=>'int', 'context='=>'resource'], 'finfo_open' => ['resource|false', 'options='=>'int', 'arg='=>'string'], 'finfo_set_flags' => ['bool', 'finfo'=>'resource', 'options'=>'int'], 'floatval' => ['float', 'var'=>'scalar|array|resource|null'], 'flock' => ['bool', 'fp'=>'resource', 'operation'=>'int', '&w_wouldblock='=>'int'], 'floor' => ['__benevolent', 'number'=>'float'], 'flush' => ['void'], 'fmod' => ['float', 'x'=>'float', 'y'=>'float'], 'fnmatch' => ['bool', 'pattern'=>'string', 'filename'=>'string', 'flags='=>'int'], 'fopen' => ['resource|false', 'filename'=>'string', 'mode'=>'string', 'use_include_path='=>'bool', 'context='=>'resource|null'], 'forward_static_call' => ['mixed', 'function'=>'callable', '...parameters='=>'mixed'], 'forward_static_call_array' => ['mixed', 'function'=>'callable', 'parameters'=>'array'], 'fpassthru' => ['0|positive-int|false', 'fp'=>'resource'], 'fpm_get_status' => ['array{pool: string, process-manager: \'dynamic\'|\'ondemand\'|\'static\', start-time: int<0, max>, start-since: int<0, max>, accepted-conn: int<0, max>, listen-queue: int<0, max>, max-listen-queue: int<0, max>, listen-queue-len: int<0, max>, idle-processes: int<0, max>, active-processes: int<1, max>, total-processes: int<1, max>, max-active-processes: int<1, max>, max-children-reached: 0|1, slow-requests: int<0, max>, procs: array, state: \'Idle\'|\'Running\', start-time: int<0, max>, start-since: int<0, max>, requests: int<0, max>, request-duration: int<0, max>, request-method: string, request-uri: string, query-string: string, request-length: int<0, max>, user: string, script: string, last-request-cpu: float, last-request-memory: int<0, max>}>}|false'], 'fprintf' => ['int', 'stream'=>'resource', 'format'=>'string', '...values='=>'__stringAndStringable|int|float|null|bool'], 'fputcsv' => ['0|positive-int|false', 'fp'=>'resource', 'fields'=>'array', 'delimiter='=>'string', 'enclosure='=>'string', 'escape_char='=>'string'], 'fputs' => ['0|positive-int|false', 'fp'=>'resource', 'str'=>'string', 'length='=>'0|positive-int'], 'fread' => ['string', 'fp'=>'resource', 'length'=>'positive-int'], 'frenchtojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'], 'fribidi_log2vis' => ['string', 'str'=>'string', 'direction'=>'string', 'charset'=>'int'], 'fscanf' => ['list|int|false', 'stream'=>'resource', 'format'=>'string', '&...w_vars='=>'string|int|float|null'], 'fseek' => ['0|-1', 'fp'=>'resource', 'offset'=>'int', 'whence='=>'int'], 'fsockopen' => ['resource|false', 'hostname'=>'string', 'port='=>'int', '&w_errno='=>'int', '&w_errstr='=>'string', 'timeout='=>'float'], 'fstat' => ['array|false', 'fp'=>'resource'], 'ftell' => ['int|false', 'fp'=>'resource'], 'ftok' => ['int', 'pathname'=>'string', 'proj'=>'string'], 'ftp_alloc' => ['bool', 'stream'=>'resource', 'size'=>'int', '&w_response='=>'string'], 'ftp_append' => ['bool', 'ftp'=>'resource', 'remote_file'=>'string', 'local_file'=>'string', 'mode='=>'int'], 'ftp_cdup' => ['bool', 'stream'=>'resource'], 'ftp_chdir' => ['bool', 'stream'=>'resource', 'directory'=>'string'], 'ftp_chmod' => ['int|false', 'stream'=>'resource', 'mode'=>'int', 'filename'=>'string'], 'ftp_close' => ['bool', 'stream'=>'resource'], 'ftp_connect' => ['resource|false', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'], 'ftp_delete' => ['bool', 'stream'=>'resource', 'file'=>'string'], 'ftp_exec' => ['bool', 'stream'=>'resource', 'command'=>'string'], 'ftp_fget' => ['bool', 'stream'=>'resource', 'fp'=>'resource', 'remote_file'=>'string', 'mode='=>'int', 'resumepos='=>'int'], 'ftp_fput' => ['bool', 'stream'=>'resource', 'remote_file'=>'string', 'fp'=>'resource', 'mode='=>'int', 'startpos='=>'int'], 'ftp_get' => ['bool', 'stream'=>'resource', 'local_file'=>'string', 'remote_file'=>'string', 'mode='=>'int', 'resume_pos='=>'int'], 'ftp_get_option' => ['mixed', 'stream'=>'resource', 'option'=>'int'], 'ftp_login' => ['bool', 'stream'=>'resource', 'username'=>'string', 'password'=>'string'], 'ftp_mdtm' => ['int', 'stream'=>'resource', 'filename'=>'string'], 'ftp_mkdir' => ['string|false', 'stream'=>'resource', 'directory'=>'string'], 'ftp_mlsd' => ['array|false', 'ftp_stream'=>'resource', 'directory'=>'string'], 'ftp_nb_continue' => ['int', 'stream'=>'resource'], 'ftp_nb_fget' => ['int', 'stream'=>'resource', 'fp'=>'resource', 'remote_file'=>'string', 'mode='=>'int', 'resumepos='=>'int'], 'ftp_nb_fput' => ['int', 'stream'=>'resource', 'remote_file'=>'string', 'fp'=>'resource', 'mode='=>'int', 'startpos='=>'int'], 'ftp_nb_get' => ['int|false', 'stream'=>'resource', 'local_file'=>'string', 'remote_file'=>'string', 'mode='=>'int', 'resume_pos='=>'int'], 'ftp_nb_put' => ['int|false', 'stream'=>'resource', 'remote_file'=>'string', 'local_file'=>'string', 'mode='=>'int', 'startpos='=>'int'], 'ftp_nlist' => ['array|false', 'stream'=>'resource', 'directory'=>'string'], 'ftp_pasv' => ['bool', 'stream'=>'resource', 'pasv'=>'bool'], 'ftp_put' => ['bool', 'stream'=>'resource', 'remote_file'=>'string', 'local_file'=>'string', 'mode='=>'int', 'startpos='=>'int'], 'ftp_pwd' => ['string|false', 'stream'=>'resource'], 'ftp_raw' => ['array', 'stream'=>'resource', 'command'=>'string'], 'ftp_rawlist' => ['array|false', 'stream'=>'resource', 'directory'=>'string', 'recursive='=>'bool'], 'ftp_rename' => ['bool', 'stream'=>'resource', 'src'=>'string', 'dest'=>'string'], 'ftp_rmdir' => ['bool', 'stream'=>'resource', 'directory'=>'string'], 'ftp_set_option' => ['bool', 'stream'=>'resource', 'option'=>'int', 'value'=>'mixed'], 'ftp_site' => ['bool', 'stream'=>'resource', 'cmd'=>'string'], 'ftp_size' => ['int', 'stream'=>'resource', 'filename'=>'string'], 'ftp_ssl_connect' => ['resource|false', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'], 'ftp_systype' => ['string|false', 'stream'=>'resource'], 'ftruncate' => ['bool', 'fp'=>'resource', 'size'=>'0|positive-int'], 'func_get_arg' => ['mixed', 'arg_num'=>'0|positive-int'], 'func_get_args' => ['list'], 'func_num_args' => ['0|positive-int'], 'function_exists' => ['bool', 'function_name'=>'string'], 'fwrite' => ['0|positive-int|false', 'fp'=>'resource', 'str'=>'string', 'length='=>'0|positive-int'], 'gc_collect_cycles' => ['int'], 'gc_disable' => ['void'], 'gc_enable' => ['void'], 'gc_enabled' => ['bool'], 'gc_mem_caches' => ['int'], 'gc_status' => ['array{runs:int,collected:int,threshold:int,roots:int}'], 'gd_info' => ['array'], 'gearman_bugreport' => [''], 'gearman_client_add_options' => ['', 'client_object'=>'', 'option'=>''], 'gearman_client_add_server' => ['', 'client_object'=>'', 'host'=>'', 'port'=>''], 'gearman_client_add_servers' => ['', 'client_object'=>'', 'servers'=>''], 'gearman_client_add_task' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''], 'gearman_client_add_task_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''], 'gearman_client_add_task_high' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''], 'gearman_client_add_task_high_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''], 'gearman_client_add_task_low' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''], 'gearman_client_add_task_low_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''], 'gearman_client_add_task_status' => ['', 'client_object'=>'', 'job_handle'=>'', 'context'=>''], 'gearman_client_clear_fn' => ['', 'client_object'=>''], 'gearman_client_clone' => ['', 'client_object'=>''], 'gearman_client_context' => ['', 'client_object'=>''], 'gearman_client_create' => ['', 'client_object'=>''], 'gearman_client_do' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''], 'gearman_client_do_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''], 'gearman_client_do_high' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''], 'gearman_client_do_high_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''], 'gearman_client_do_job_handle' => ['', 'client_object'=>''], 'gearman_client_do_low' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''], 'gearman_client_do_low_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''], 'gearman_client_do_normal' => ['', 'client_object'=>'', 'function_name'=>'string', 'workload'=>'string', 'unique'=>'string'], 'gearman_client_do_status' => ['', 'client_object'=>''], 'gearman_client_echo' => ['', 'client_object'=>'', 'workload'=>''], 'gearman_client_errno' => ['', 'client_object'=>''], 'gearman_client_error' => ['', 'client_object'=>''], 'gearman_client_job_status' => ['', 'client_object'=>'', 'job_handle'=>''], 'gearman_client_options' => ['', 'client_object'=>''], 'gearman_client_remove_options' => ['', 'client_object'=>'', 'option'=>''], 'gearman_client_return_code' => ['', 'client_object'=>''], 'gearman_client_run_tasks' => ['', 'data'=>''], 'gearman_client_set_complete_fn' => ['', 'client_object'=>'', 'callback'=>''], 'gearman_client_set_context' => ['', 'client_object'=>'', 'context'=>''], 'gearman_client_set_created_fn' => ['', 'client_object'=>'', 'callback'=>''], 'gearman_client_set_data_fn' => ['', 'client_object'=>'', 'callback'=>''], 'gearman_client_set_exception_fn' => ['', 'client_object'=>'', 'callback'=>''], 'gearman_client_set_fail_fn' => ['', 'client_object'=>'', 'callback'=>''], 'gearman_client_set_options' => ['', 'client_object'=>'', 'option'=>''], 'gearman_client_set_status_fn' => ['', 'client_object'=>'', 'callback'=>''], 'gearman_client_set_timeout' => ['', 'client_object'=>'', 'timeout'=>''], 'gearman_client_set_warning_fn' => ['', 'client_object'=>'', 'callback'=>''], 'gearman_client_set_workload_fn' => ['', 'client_object'=>'', 'callback'=>''], 'gearman_client_timeout' => ['', 'client_object'=>''], 'gearman_client_wait' => ['', 'client_object'=>''], 'gearman_job_function_name' => ['', 'job_object'=>''], 'gearman_job_handle' => ['string'], 'gearman_job_return_code' => ['', 'job_object'=>''], 'gearman_job_send_complete' => ['', 'job_object'=>'', 'result'=>''], 'gearman_job_send_data' => ['', 'job_object'=>'', 'data'=>''], 'gearman_job_send_exception' => ['', 'job_object'=>'', 'exception'=>''], 'gearman_job_send_fail' => ['', 'job_object'=>''], 'gearman_job_send_status' => ['', 'job_object'=>'', 'numerator'=>'', 'denominator'=>''], 'gearman_job_send_warning' => ['', 'job_object'=>'', 'warning'=>''], 'gearman_job_status' => ['array', 'job_handle'=>'string'], 'gearman_job_unique' => ['', 'job_object'=>''], 'gearman_job_workload' => ['', 'job_object'=>''], 'gearman_job_workload_size' => ['', 'job_object'=>''], 'gearman_task_data' => ['', 'task_object'=>''], 'gearman_task_data_size' => ['', 'task_object'=>''], 'gearman_task_denominator' => ['', 'task_object'=>''], 'gearman_task_function_name' => ['', 'task_object'=>''], 'gearman_task_is_known' => ['', 'task_object'=>''], 'gearman_task_is_running' => ['', 'task_object'=>''], 'gearman_task_job_handle' => ['', 'task_object'=>''], 'gearman_task_numerator' => ['', 'task_object'=>''], 'gearman_task_recv_data' => ['', 'task_object'=>'', 'data_len'=>''], 'gearman_task_return_code' => ['', 'task_object'=>''], 'gearman_task_send_workload' => ['', 'task_object'=>'', 'data'=>''], 'gearman_task_unique' => ['', 'task_object'=>''], 'gearman_verbose_name' => ['', 'verbose'=>''], 'gearman_version' => [''], 'gearman_worker_add_function' => ['', 'worker_object'=>'', 'function_name'=>'', 'function'=>'', 'data'=>'', 'timeout'=>''], 'gearman_worker_add_options' => ['', 'worker_object'=>'', 'option'=>''], 'gearman_worker_add_server' => ['', 'worker_object'=>'', 'host'=>'', 'port'=>''], 'gearman_worker_add_servers' => ['', 'worker_object'=>'', 'servers'=>''], 'gearman_worker_clone' => ['', 'worker_object'=>''], 'gearman_worker_create' => [''], 'gearman_worker_echo' => ['', 'worker_object'=>'', 'workload'=>''], 'gearman_worker_errno' => ['', 'worker_object'=>''], 'gearman_worker_error' => ['', 'worker_object'=>''], 'gearman_worker_grab_job' => ['', 'worker_object'=>''], 'gearman_worker_options' => ['', 'worker_object'=>''], 'gearman_worker_register' => ['', 'worker_object'=>'', 'function_name'=>'', 'timeout'=>''], 'gearman_worker_remove_options' => ['', 'worker_object'=>'', 'option'=>''], 'gearman_worker_return_code' => ['', 'worker_object'=>''], 'gearman_worker_set_options' => ['', 'worker_object'=>'', 'option'=>''], 'gearman_worker_set_timeout' => ['', 'worker_object'=>'', 'timeout'=>''], 'gearman_worker_timeout' => ['', 'worker_object'=>''], 'gearman_worker_unregister' => ['', 'worker_object'=>'', 'function_name'=>''], 'gearman_worker_unregister_all' => ['', 'worker_object'=>''], 'gearman_worker_wait' => ['', 'worker_object'=>''], 'gearman_worker_work' => ['', 'worker_object'=>''], 'GearmanClient::__construct' => ['void'], 'GearmanClient::addOptions' => ['bool', 'options'=>'int'], 'GearmanClient::addServer' => ['bool', 'host='=>'string', 'port='=>'int'], 'GearmanClient::addServers' => ['bool', 'servers='=>'string'], 'GearmanClient::addTask' => ['GearmanTask', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'], 'GearmanClient::addTaskBackground' => ['GearmanTask', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'], 'GearmanClient::addTaskHigh' => ['GearmanTask', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'], 'GearmanClient::addTaskHighBackground' => ['GearmanTask', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'], 'GearmanClient::addTaskLow' => ['GearmanTask', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'], 'GearmanClient::addTaskLowBackground' => ['GearmanTask', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'], 'GearmanClient::addTaskStatus' => ['GearmanTask', 'job_handle'=>'string', 'context='=>'string'], 'GearmanClient::clearCallbacks' => ['bool'], 'GearmanClient::clone' => ['GearmanClient'], 'GearmanClient::context' => ['string'], 'GearmanClient::data' => ['string'], 'GearmanClient::do' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], 'GearmanClient::doBackground' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], 'GearmanClient::doHigh' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], 'GearmanClient::doHighBackground' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], 'GearmanClient::doJobHandle' => ['string'], 'GearmanClient::doLow' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], 'GearmanClient::doLowBackground' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], 'GearmanClient::doNormal' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], 'GearmanClient::doStatus' => ['array'], 'GearmanClient::echo' => ['bool', 'workload'=>'string'], 'GearmanClient::error' => ['string'], 'GearmanClient::getErrno' => ['int'], 'GearmanClient::jobStatus' => ['array', 'job_handle'=>'string'], 'GearmanClient::options' => [''], 'GearmanClient::ping' => ['bool', 'workload'=>'string'], 'GearmanClient::removeOptions' => ['bool', 'options'=>'int'], 'GearmanClient::returnCode' => ['int'], 'GearmanClient::runTasks' => ['bool'], 'GearmanClient::setClientCallback' => ['void', 'callback'=>'callable'], 'GearmanClient::setCompleteCallback' => ['bool', 'callback'=>'callable'], 'GearmanClient::setContext' => ['bool', 'context'=>'string'], 'GearmanClient::setCreatedCallback' => ['bool', 'callback'=>'string'], 'GearmanClient::setData' => ['bool', 'data'=>'string'], 'GearmanClient::setDataCallback' => ['bool', 'callback'=>'callable'], 'GearmanClient::setExceptionCallback' => ['bool', 'callback'=>'callable'], 'GearmanClient::setFailCallback' => ['bool', 'callback'=>'callable'], 'GearmanClient::setOptions' => ['bool', 'options'=>'int'], 'GearmanClient::setStatusCallback' => ['bool', 'callback'=>'callable'], 'GearmanClient::setTimeout' => ['bool', 'timeout'=>'int'], 'GearmanClient::setWarningCallback' => ['bool', 'callback'=>'callable'], 'GearmanClient::setWorkloadCallback' => ['bool', 'callback'=>'callable'], 'GearmanClient::timeout' => ['int'], 'GearmanClient::wait' => [''], 'GearmanJob::__construct' => ['void'], 'GearmanJob::complete' => ['bool', 'result'=>'string'], 'GearmanJob::data' => ['bool', 'data'=>'string'], 'GearmanJob::exception' => ['bool', 'exception'=>'string'], 'GearmanJob::fail' => ['bool'], 'GearmanJob::functionName' => ['string'], 'GearmanJob::handle' => ['string'], 'GearmanJob::returnCode' => ['int'], 'GearmanJob::sendComplete' => ['bool', 'result'=>'string'], 'GearmanJob::sendData' => ['bool', 'data'=>'string'], 'GearmanJob::sendException' => ['bool', 'exception'=>'string'], 'GearmanJob::sendFail' => ['bool'], 'GearmanJob::sendStatus' => ['bool', 'numerator'=>'int', 'denominator'=>'int'], 'GearmanJob::sendWarning' => ['bool', 'warning'=>'string'], 'GearmanJob::setReturn' => ['bool', 'gearman_return_t'=>'string'], 'GearmanJob::status' => ['bool', 'numerator'=>'int', 'denominator'=>'int'], 'GearmanJob::unique' => ['string'], 'GearmanJob::warning' => ['bool', 'warning'=>'string'], 'GearmanJob::workload' => ['string'], 'GearmanJob::workloadSize' => ['int'], 'GearmanTask::__construct' => ['void'], 'GearmanTask::create' => ['GearmanTask'], 'GearmanTask::data' => ['string'], 'GearmanTask::dataSize' => ['int'], 'GearmanTask::function' => ['string'], 'GearmanTask::functionName' => ['string'], 'GearmanTask::isKnown' => ['bool'], 'GearmanTask::isRunning' => ['bool'], 'GearmanTask::jobHandle' => ['string'], 'GearmanTask::recvData' => ['array', 'data_len'=>'int'], 'GearmanTask::returnCode' => ['int'], 'GearmanTask::sendData' => ['int', 'data'=>'string'], 'GearmanTask::sendWorkload' => ['int', 'data'=>'string'], 'GearmanTask::taskDenominator' => ['int'], 'GearmanTask::taskNumerator' => ['int'], 'GearmanTask::unique' => ['string'], 'GearmanTask::uuid' => ['string'], 'GearmanWorker::__construct' => ['void'], 'GearmanWorker::addFunction' => ['bool', 'function_name'=>'string', 'function'=>'callable', 'context='=>'mixed', 'timeout='=>'int'], 'GearmanWorker::addOptions' => ['bool', 'option'=>'int'], 'GearmanWorker::addServer' => ['bool', 'host='=>'string', 'port='=>'int'], 'GearmanWorker::addServers' => ['bool', 'servers'=>'string'], 'GearmanWorker::clone' => ['void'], 'GearmanWorker::echo' => ['bool', 'workload'=>'string'], 'GearmanWorker::error' => ['string'], 'GearmanWorker::getErrno' => ['int'], 'GearmanWorker::grabJob' => [''], 'GearmanWorker::options' => ['int'], 'GearmanWorker::register' => ['bool', 'function_name'=>'string', 'timeout='=>'int'], 'GearmanWorker::removeOptions' => ['bool', 'option'=>'int'], 'GearmanWorker::returnCode' => ['int'], 'GearmanWorker::setId' => ['bool', 'id'=>'string'], 'GearmanWorker::setOptions' => ['bool', 'option'=>'int'], 'GearmanWorker::setTimeout' => ['bool', 'timeout'=>'int'], 'GearmanWorker::timeout' => ['int'], 'GearmanWorker::unregister' => ['bool', 'function_name'=>'string'], 'GearmanWorker::unregisterAll' => ['bool'], 'GearmanWorker::wait' => ['bool'], 'GearmanWorker::work' => ['bool'], 'Gender\Gender::__construct' => ['void', 'dsn='=>'string'], 'Gender\Gender::connect' => ['bool', 'dsn'=>'string'], 'Gender\Gender::country' => ['array', 'country'=>'int'], 'Gender\Gender::get' => ['int', 'name'=>'string', 'country='=>'int'], 'Gender\Gender::isNick' => ['array', 'name0'=>'string', 'name1'=>'string', 'country='=>'int'], 'Gender\Gender::similarNames' => ['array', 'name'=>'string', 'country='=>'int'], 'Generator::__wakeup' => ['void'], 'Generator::current' => ['mixed'], 'Generator::getReturn' => ['mixed'], 'Generator::key' => ['mixed'], 'Generator::next' => ['void'], 'Generator::rewind' => ['void'], 'Generator::send' => ['mixed', 'value'=>'mixed'], 'Generator::throw' => ['mixed', 'exception'=>'Exception|Throwable'], 'Generator::valid' => ['bool'], 'geoip_asnum_by_name' => ['string', 'hostname'=>'string'], 'geoip_continent_code_by_name' => ['string', 'hostname'=>'string'], 'geoip_country_code3_by_name' => ['string', 'hostname'=>'string'], 'geoip_country_code_by_name' => ['string', 'hostname'=>'string'], 'geoip_country_name_by_name' => ['string', 'hostname'=>'string'], 'geoip_database_info' => ['string', 'database='=>'int'], 'geoip_db_avail' => ['bool', 'database'=>'int'], 'geoip_db_filename' => ['string', 'database'=>'int'], 'geoip_db_get_all_info' => ['array'], 'geoip_domain_by_name' => ['string', 'hostname'=>'string'], 'geoip_id_by_name' => ['int', 'hostname'=>'string'], 'geoip_isp_by_name' => ['string', 'hostname'=>'string'], 'geoip_netspeedcell_by_name' => ['string', 'hostname'=>'string'], 'geoip_org_by_name' => ['string', 'hostname'=>'string'], 'geoip_record_by_name' => ['array', 'hostname'=>'string'], 'geoip_region_by_name' => ['array', 'hostname'=>'string'], 'geoip_region_name_by_code' => ['string', 'country_code'=>'string', 'region_code'=>'string'], 'geoip_setup_custom_directory' => ['void', 'path'=>'string'], 'geoip_time_zone_by_country_and_region' => ['string|false', 'country_code'=>'string', 'region_code='=>'string'], 'get_browser' => ['mixed', 'browser_name='=>'string', 'return_array='=>'bool'], 'get_call_stack' => [''], 'get_called_class' => ['class-string'], 'get_cfg_var' => ['mixed', 'option_name'=>'string'], 'get_class' => ['class-string', 'object='=>'object'], 'get_class_methods' => ['list', 'class'=>'mixed'], 'get_class_vars' => ['array', 'class_name'=>'string'], 'get_current_user' => ['string'], 'get_declared_classes' => ['list'], 'get_declared_interfaces' => ['list'], 'get_declared_traits' => ['list'], 'get_defined_constants' => ['array', 'categorize='=>'bool'], 'get_defined_functions' => ['array{internal:non-empty-list,user:list}', 'exclude_disabled='=>'bool'], 'get_defined_vars' => ['array'], 'get_extension_funcs' => ['list|false', 'extension_name'=>'string'], 'get_headers' => ['array|false', 'url'=>'string', 'format='=>'int', 'context='=>'resource'], 'get_html_translation_table' => ['array', 'table='=>'int', 'flags='=>'int', 'encoding='=>'string'], 'get_include_path' => ['__benevolent'], 'get_included_files' => ['list'], 'get_loaded_extensions' => ['list', 'zend_extensions='=>'bool'], 'get_magic_quotes_gpc' => ['false'], 'get_magic_quotes_runtime' => ['false'], 'get_meta_tags' => ['array|false', 'filename'=>'string', 'use_include_path='=>'bool'], 'get_object_vars' => ['array', 'obj'=>'object'], 'get_parent_class' => ['class-string|false', 'object='=>'mixed'], 'get_required_files' => ['list'], 'get_resource_type' => ['string', 'res'=>'resource'], 'get_resources' => ['array', 'type='=>'string'], 'getallheaders' => ['array'], 'getcwd' => ['non-empty-string|false'], 'getdate' => ['array{seconds: int<0, 59>, minutes: int<0, 59>, hours: int<0, 23>, mday: int<1, 31>, wday: int<0, 6>, mon: int<1, 12>, year: int, yday: int<0, 365>, weekday: "Monday"|"Tuesday"|"Wednesday"|"Thursday"|"Friday"|"Saturday"|"Sunday", month: "January"|"February"|"March"|"April"|"May"|"June"|"July"|"August"|"September"|"October"|"November"|"December", 0: int}', 'timestamp='=>'int'], 'getenv' => ['string|false', 'varname'=>'string', 'local_only='=>'bool'], 'getenv\'1' => ['array'], 'gethostbyaddr' => ['string|false', 'ip_address'=>'string'], 'gethostbyname' => ['string', 'hostname'=>'string'], 'gethostbynamel' => ['list|false', 'hostname'=>'string'], 'gethostname' => ['string|false'], 'getimagesize' => ['array{0: 0|positive-int, 1: 0|positive-int, 2: int, 3: string, mime: string, channels?: int, bits?: int}|false', 'imagefile'=>'string', '&w_info='=>'array'], 'getimagesizefromstring' => ['array{0: 0|positive-int, 1: 0|positive-int, 2: int, 3: string, mime: string, channels?: int, bits?: int}|false', 'data'=>'string', '&w_info='=>'array'], 'getlastmod' => ['int|false'], 'getmxrr' => ['bool', 'hostname'=>'string', '&w_mxhosts'=>'array', '&w_weight='=>'array'], 'getmygid' => ['int|false'], 'getmyinode' => ['int|false'], 'getmypid' => ['int|false'], 'getmyuid' => ['int|false'], 'getopt' => ['__benevolent|array|array>|false>', 'options'=>'string', 'longopts='=>'array', '&w_optind='=>'int'], 'getprotobyname' => ['int|false', 'name'=>'string'], 'getprotobynumber' => ['string|false', 'proto'=>'int'], 'getrandmax' => ['int'], 'getrusage' => ['array|false', 'who='=>'int'], 'getservbyname' => ['int|false', 'service'=>'string', 'protocol'=>'string'], 'getservbyport' => ['string|false', 'port'=>'int', 'protocol'=>'string'], 'gettext' => ['string', 'msgid'=>'string'], 'gettimeofday' => ['array|float', 'get_as_float='=>'bool'], 'gettype' => ['string', 'var'=>'mixed'], 'glob' => ['list|false', 'pattern'=>'string', 'flags='=>'int'], 'GlobIterator::__construct' => ['void', 'path'=>'string', 'flags='=>'int'], 'GlobIterator::cont' => ['int'], 'GlobIterator::count' => ['0|positive-int'], 'Gmagick::__construct' => ['void', 'filename='=>'string'], 'Gmagick::addimage' => ['Gmagick', 'gmagick'=>'gmagick'], 'Gmagick::addnoiseimage' => ['Gmagick', 'noise'=>'int'], 'Gmagick::annotateimage' => ['Gmagick', 'gmagickdraw'=>'gmagickdraw', 'x'=>'float', 'y'=>'float', 'angle'=>'float', 'text'=>'string'], 'Gmagick::blurimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'], 'Gmagick::borderimage' => ['Gmagick', 'color'=>'gmagickpixel', 'width'=>'int', 'height'=>'int'], 'Gmagick::charcoalimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float'], 'Gmagick::chopimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], 'Gmagick::clear' => ['Gmagick'], 'Gmagick::commentimage' => ['Gmagick', 'comment'=>'string'], 'Gmagick::compositeimage' => ['Gmagick', 'source'=>'gmagick', 'compose'=>'int', 'x'=>'int', 'y'=>'int'], 'Gmagick::cropimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], 'Gmagick::cropthumbnailimage' => ['Gmagick', 'width'=>'int', 'height'=>'int'], 'Gmagick::current' => ['Gmagick'], 'Gmagick::cyclecolormapimage' => ['Gmagick', 'displace'=>'int'], 'Gmagick::deconstructimages' => ['Gmagick'], 'Gmagick::despeckleimage' => ['Gmagick'], 'Gmagick::destroy' => ['bool'], 'Gmagick::drawimage' => ['Gmagick', 'gmagickdraw'=>'gmagickdraw'], 'Gmagick::edgeimage' => ['Gmagick', 'radius'=>'float'], 'Gmagick::embossimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float'], 'Gmagick::enhanceimage' => ['Gmagick'], 'Gmagick::equalizeimage' => ['Gmagick'], 'Gmagick::flipimage' => ['Gmagick'], 'Gmagick::flopimage' => ['Gmagick'], 'Gmagick::frameimage' => ['Gmagick', 'color'=>'gmagickpixel', 'width'=>'int', 'height'=>'int', 'inner_bevel'=>'int', 'outer_bevel'=>'int'], 'Gmagick::gammaimage' => ['Gmagick', 'gamma'=>'float'], 'Gmagick::getcopyright' => ['string'], 'Gmagick::getfilename' => ['string'], 'Gmagick::getimagebackgroundcolor' => ['GmagickPixel'], 'Gmagick::getimageblueprimary' => ['array'], 'Gmagick::getimagebordercolor' => ['GmagickPixel'], 'Gmagick::getimagechanneldepth' => ['int', 'channel_type'=>'int'], 'Gmagick::getimagecolors' => ['int'], 'Gmagick::getimagecolorspace' => ['int'], 'Gmagick::getimagecompose' => ['int'], 'Gmagick::getimagedelay' => ['int'], 'Gmagick::getimagedepth' => ['int'], 'Gmagick::getimagedispose' => ['int'], 'Gmagick::getimageextrema' => ['array'], 'Gmagick::getimagefilename' => ['string'], 'Gmagick::getimageformat' => ['string'], 'Gmagick::getimagegamma' => ['float'], 'Gmagick::getimagegreenprimary' => ['array'], 'Gmagick::getimageheight' => ['int'], 'Gmagick::getimagehistogram' => ['array'], 'Gmagick::getimageindex' => ['int'], 'Gmagick::getimageinterlacescheme' => ['int'], 'Gmagick::getimageiterations' => ['int'], 'Gmagick::getimagematte' => ['int'], 'Gmagick::getimagemattecolor' => ['GmagickPixel'], 'Gmagick::getimageprofile' => ['string', 'name'=>'string'], 'Gmagick::getimageredprimary' => ['array'], 'Gmagick::getimagerenderingintent' => ['int'], 'Gmagick::getimageresolution' => ['array'], 'Gmagick::getimagescene' => ['int'], 'Gmagick::getimagesignature' => ['string'], 'Gmagick::getimagetype' => ['int'], 'Gmagick::getimageunits' => ['int'], 'Gmagick::getimagewhitepoint' => ['array'], 'Gmagick::getimagewidth' => ['int'], 'Gmagick::getpackagename' => ['string'], 'Gmagick::getquantumdepth' => ['array'], 'Gmagick::getreleasedate' => ['string'], 'Gmagick::getsamplingfactors' => ['array'], 'Gmagick::getsize' => ['array'], 'Gmagick::getversion' => ['array'], 'Gmagick::hasnextimage' => ['bool'], 'Gmagick::haspreviousimage' => ['bool'], 'Gmagick::implodeimage' => ['mixed', 'radius'=>'float'], 'Gmagick::labelimage' => ['mixed', 'label'=>'string'], 'Gmagick::levelimage' => ['mixed', 'blackpoint'=>'float', 'gamma'=>'float', 'whitepoint'=>'float', 'channel='=>'int'], 'Gmagick::magnifyimage' => ['mixed'], 'Gmagick::mapimage' => ['Gmagick', 'gmagick'=>'gmagick', 'dither'=>'bool'], 'Gmagick::medianfilterimage' => ['void', 'radius'=>'float'], 'Gmagick::minifyimage' => ['Gmagick'], 'Gmagick::modulateimage' => ['Gmagick', 'brightness'=>'float', 'saturation'=>'float', 'hue'=>'float'], 'Gmagick::motionblurimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float', 'angle'=>'float'], 'Gmagick::newimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'background'=>'string', 'format='=>'string'], 'Gmagick::nextimage' => ['bool'], 'Gmagick::normalizeimage' => ['Gmagick', 'channel='=>'int'], 'Gmagick::oilpaintimage' => ['Gmagick', 'radius'=>'float'], 'Gmagick::previousimage' => ['bool'], 'Gmagick::profileimage' => ['Gmagick', 'name'=>'string', 'profile'=>'string'], 'Gmagick::quantizeimage' => ['Gmagick', 'numcolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'], 'Gmagick::quantizeimages' => ['Gmagick', 'numcolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'], 'Gmagick::queryfontmetrics' => ['array', 'draw'=>'gmagickdraw', 'text'=>'string'], 'Gmagick::queryfonts' => ['array', 'pattern='=>'string'], 'Gmagick::queryformats' => ['array', 'pattern='=>'string'], 'Gmagick::radialblurimage' => ['Gmagick', 'angle'=>'float', 'channel='=>'int'], 'Gmagick::raiseimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int', 'raise'=>'bool'], 'Gmagick::read' => ['Gmagick', 'filename'=>'string'], 'Gmagick::readimage' => ['Gmagick', 'filename'=>'string'], 'Gmagick::readimageblob' => ['Gmagick', 'imagecontents'=>'string', 'filename='=>'string'], 'Gmagick::readimagefile' => ['Gmagick', 'fp'=>'resource', 'filename='=>'string'], 'Gmagick::reducenoiseimage' => ['Gmagick', 'radius'=>'float'], 'Gmagick::removeimage' => ['Gmagick'], 'Gmagick::removeimageprofile' => ['string', 'name'=>'string'], 'Gmagick::resampleimage' => ['Gmagick', 'xresolution'=>'float', 'yresolution'=>'float', 'filter'=>'int', 'blur'=>'float'], 'Gmagick::resizeimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'filter'=>'int', 'blur'=>'float', 'fit='=>'bool'], 'Gmagick::rollimage' => ['Gmagick', 'x'=>'int', 'y'=>'int'], 'Gmagick::rotateimage' => ['Gmagick', 'color'=>'mixed', 'degrees'=>'float'], 'Gmagick::scaleimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'fit='=>'bool'], 'Gmagick::separateimagechannel' => ['Gmagick', 'channel'=>'int'], 'Gmagick::setCompressionQuality' => ['Gmagick', 'quality'=>'int'], 'Gmagick::setfilename' => ['Gmagick', 'filename'=>'string'], 'Gmagick::setimagebackgroundcolor' => ['Gmagick', 'color'=>'gmagickpixel'], 'Gmagick::setimageblueprimary' => ['Gmagick', 'x'=>'float', 'y'=>'float'], 'Gmagick::setimagebordercolor' => ['Gmagick', 'color'=>'gmagickpixel'], 'Gmagick::setimagechanneldepth' => ['Gmagick', 'channel'=>'int', 'depth'=>'int'], 'Gmagick::setimagecolorspace' => ['Gmagick', 'colorspace'=>'int'], 'Gmagick::setimagecompose' => ['Gmagick', 'composite'=>'int'], 'Gmagick::setimagedelay' => ['Gmagick', 'delay'=>'int'], 'Gmagick::setimagedepth' => ['Gmagick', 'depth'=>'int'], 'Gmagick::setimagedispose' => ['Gmagick', 'disposetype'=>'int'], 'Gmagick::setimagefilename' => ['Gmagick', 'filename'=>'string'], 'Gmagick::setimageformat' => ['Gmagick', 'imageformat'=>'string'], 'Gmagick::setimagegamma' => ['Gmagick', 'gamma'=>'float'], 'Gmagick::setimagegreenprimary' => ['Gmagick', 'x'=>'float', 'y'=>'float'], 'Gmagick::setimageindex' => ['Gmagick', 'index'=>'int'], 'Gmagick::setimageinterlacescheme' => ['Gmagick', 'interlace'=>'int'], 'Gmagick::setimageiterations' => ['Gmagick', 'iterations'=>'int'], 'Gmagick::setimageprofile' => ['Gmagick', 'name'=>'string', 'profile'=>'string'], 'Gmagick::setimageredprimary' => ['Gmagick', 'x'=>'float', 'y'=>'float'], 'Gmagick::setimagerenderingintent' => ['Gmagick', 'rendering_intent'=>'int'], 'Gmagick::setimageresolution' => ['Gmagick', 'xresolution'=>'float', 'yresolution'=>'float'], 'Gmagick::setimagescene' => ['Gmagick', 'scene'=>'int'], 'Gmagick::setimagetype' => ['Gmagick', 'imgtype'=>'int'], 'Gmagick::setimageunits' => ['Gmagick', 'resolution'=>'int'], 'Gmagick::setimagewhitepoint' => ['Gmagick', 'x'=>'float', 'y'=>'float'], 'Gmagick::setsamplingfactors' => ['Gmagick', 'factors'=>'array'], 'Gmagick::setsize' => ['Gmagick', 'columns'=>'int', 'rows'=>'int'], 'Gmagick::shearimage' => ['Gmagick', 'color'=>'mixed', 'xshear'=>'float', 'yshear'=>'float'], 'Gmagick::solarizeimage' => ['Gmagick', 'threshold'=>'int'], 'Gmagick::spreadimage' => ['Gmagick', 'radius'=>'float'], 'Gmagick::stripimage' => ['Gmagick'], 'Gmagick::swirlimage' => ['Gmagick', 'degrees'=>'float'], 'Gmagick::thumbnailimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'fit='=>'bool'], 'Gmagick::trimimage' => ['Gmagick', 'fuzz'=>'float'], 'Gmagick::write' => ['', 'filename'=>'string'], 'Gmagick::writeimage' => ['Gmagick', 'filename'=>'string', 'all_frames='=>'bool'], 'GmagickDraw::annotate' => ['GmagickDraw', 'x'=>'float', 'y'=>'float', 'text'=>'string'], 'GmagickDraw::arc' => ['GmagickDraw', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float', 'sd'=>'float', 'ed'=>'float'], 'GmagickDraw::bezier' => ['GmagickDraw', 'coordinate_array'=>'array'], 'GmagickDraw::ellipse' => ['GmagickDraw', 'ox'=>'float', 'oy'=>'float', 'rx'=>'float', 'ry'=>'float', 'start'=>'float', 'end'=>'float'], 'GmagickDraw::getfillcolor' => ['GmagickPixel'], 'GmagickDraw::getfillopacity' => ['float'], 'GmagickDraw::getfont' => ['string'], 'GmagickDraw::getfontsize' => ['float'], 'GmagickDraw::getfontstyle' => ['int'], 'GmagickDraw::getfontweight' => ['int'], 'GmagickDraw::getstrokecolor' => ['GmagickPixel'], 'GmagickDraw::getstrokeopacity' => ['float'], 'GmagickDraw::getstrokewidth' => ['float'], 'GmagickDraw::gettextdecoration' => ['int'], 'GmagickDraw::gettextencoding' => ['string'], 'GmagickDraw::line' => ['GmagickDraw', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float'], 'GmagickDraw::point' => ['GmagickDraw', 'x'=>'float', 'y'=>'float'], 'GmagickDraw::polygon' => ['GmagickDraw', 'coordinates'=>'array'], 'GmagickDraw::polyline' => ['GmagickDraw', 'coordinate_array'=>'array'], 'GmagickDraw::rectangle' => ['GmagickDraw', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float'], 'GmagickDraw::rotate' => ['GmagickDraw', 'degrees'=>'float'], 'GmagickDraw::roundrectangle' => ['GmagickDraw', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'rx'=>'float', 'ry'=>'float'], 'GmagickDraw::scale' => ['GmagickDraw', 'x'=>'float', 'y'=>'float'], 'GmagickDraw::setfillcolor' => ['GmagickDraw', 'color'=>'string'], 'GmagickDraw::setfillopacity' => ['GmagickDraw', 'fill_opacity'=>'float'], 'GmagickDraw::setfont' => ['GmagickDraw', 'font'=>'string'], 'GmagickDraw::setfontsize' => ['GmagickDraw', 'pointsize'=>'float'], 'GmagickDraw::setfontstyle' => ['GmagickDraw', 'style'=>'int'], 'GmagickDraw::setfontweight' => ['GmagickDraw', 'weight'=>'int'], 'GmagickDraw::setstrokecolor' => ['GmagickDraw', 'color'=>'gmagickpixel'], 'GmagickDraw::setstrokeopacity' => ['GmagickDraw', 'stroke_opacity'=>'float'], 'GmagickDraw::setstrokewidth' => ['GmagickDraw', 'width'=>'float'], 'GmagickDraw::settextdecoration' => ['GmagickDraw', 'decoration'=>'int'], 'GmagickDraw::settextencoding' => ['GmagickDraw', 'encoding'=>'string'], 'GmagickPixel::__construct' => ['void', 'color='=>'string'], 'GmagickPixel::getcolor' => ['mixed', 'as_array='=>'bool', 'normalize_array='=>'bool'], 'GmagickPixel::getcolorcount' => ['int'], 'GmagickPixel::getcolorvalue' => ['float', 'color'=>'int'], 'GmagickPixel::setcolor' => ['GmagickPixel', 'color'=>'string'], 'GmagickPixel::setcolorvalue' => ['GmagickPixel', 'color'=>'int', 'value'=>'float'], 'gmdate' => ['string', 'format'=>'string', 'timestamp='=>'int'], 'gmmktime' => ['int|false', 'hour='=>'int', 'min='=>'int', 'sec='=>'int', 'mon='=>'int', 'day='=>'int', 'year='=>'int'], 'GMP::__construct' => ['void'], 'GMP::__toString' => ['string'], 'GMP::serialize' => ['string'], 'GMP::unserialize' => ['void', 'serialized'=>'string'], 'gmp_abs' => ['GMP', 'a'=>'GMP|string|int'], 'gmp_add' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_and' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_binomial' => ['GMP|false', 'n'=>'GMP|string|int', 'k'=>'int'], 'gmp_clrbit' => ['void', 'a'=>'GMP|string|int', 'index'=>'int'], 'gmp_cmp' => ['int', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_com' => ['GMP', 'a'=>'GMP|string|int'], 'gmp_div' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int', 'round='=>'int'], 'gmp_div_q' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int', 'round='=>'int'], 'gmp_div_qr' => ['array', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int', 'round='=>'int'], 'gmp_div_r' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int', 'round='=>'int'], 'gmp_divexact' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_export' => ['string', 'gmpnumber'=>'GMP|string|int', 'word_size='=>'int', 'options='=>'int'], 'gmp_fact' => ['GMP', 'a'=>'int'], 'gmp_gcd' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_gcdext' => ['array', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_hamdist' => ['int', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_import' => ['GMP', 'data'=>'string', 'word_size='=>'int', 'options='=>'int'], 'gmp_init' => ['GMP', 'number'=>'int|string', 'base='=>'int'], 'gmp_intval' => ['int', 'gmpnumber'=>'GMP|string|int'], 'gmp_invert' => ['GMP|false', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_jacobi' => ['int', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_kronecker' => ['int', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_lcm' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_legendre' => ['int', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_mod' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_mul' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_neg' => ['GMP', 'a'=>'GMP|string|int'], 'gmp_nextprime' => ['GMP', 'a'=>'GMP|string|int'], 'gmp_or' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_perfect_power' => ['bool', 'a'=>'GMP|string|int'], 'gmp_perfect_square' => ['bool', 'a'=>'GMP|string|int'], 'gmp_popcount' => ['int', 'a'=>'GMP|string|int'], 'gmp_pow' => ['GMP', 'base'=>'GMP|string|int', 'exp'=>'int'], 'gmp_powm' => ['GMP', 'base'=>'GMP|string|int', 'exp'=>'GMP|string|int', 'mod'=>'GMP|string|int'], 'gmp_prob_prime' => ['int', 'a'=>'GMP|string|int', 'reps='=>'int'], 'gmp_random' => ['GMP', 'limiter='=>'int'], 'gmp_random_bits' => ['GMP', 'bits'=>'int'], 'gmp_random_range' => ['GMP', 'min'=>'GMP|string|int', 'max'=>'GMP|string|int'], 'gmp_random_seed' => ['void', 'seed'=>'GMP|string|int'], 'gmp_root' => ['GMP', 'a'=>'GMP|string|int', 'nth'=>'int'], 'gmp_rootrem' => ['array', 'a'=>'GMP|string|int', 'nth'=>'int'], 'gmp_scan0' => ['int', 'a'=>'GMP|string|int', 'start'=>'int'], 'gmp_scan1' => ['int', 'a'=>'GMP|string|int', 'start'=>'int'], 'gmp_setbit' => ['void', 'a'=>'GMP|string|int', 'index'=>'int', 'set_clear='=>'bool'], 'gmp_sign' => ['int', 'a'=>'GMP|string|int'], 'gmp_sqrt' => ['GMP', 'a'=>'GMP|string|int'], 'gmp_sqrtrem' => ['array', 'a'=>'GMP|string|int'], 'gmp_strval' => ['string', 'gmpnumber'=>'GMP|string|int', 'base='=>'int'], 'gmp_sub' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmp_testbit' => ['bool', 'a'=>'GMP|string|int', 'index'=>'int'], 'gmp_xor' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], 'gmstrftime' => ['string|false', 'format'=>'string', 'timestamp='=>'int'], 'gnupg::adddecryptkey' => ['bool', 'fingerprint'=>'string', 'passphrase'=>'string'], 'gnupg::addencryptkey' => ['bool', 'fingerprint'=>'string'], 'gnupg::addsignkey' => ['bool', 'fingerprint'=>'string', 'passphrase='=>'string'], 'gnupg::cleardecryptkeys' => ['bool'], 'gnupg::clearencryptkeys' => ['bool'], 'gnupg::clearsignkeys' => ['bool'], 'gnupg::decrypt' => ['string|false', 'text'=>'string'], 'gnupg::deletekey' => ['bool', 'key'=>'string', 'allow_secret'=>'bool'], 'gnupg::decryptverify' => ['array|false', 'text'=>'string', '&plaintext'=>'string'], 'gnupg::encrypt' => ['string|false', 'plaintext'=>'string'], 'gnupg::encryptsign' => ['string|false', 'plaintext'=>'string'], 'gnupg::export' => ['string|false', 'fingerprint'=>'string'], 'gnupg::getengineinfo' => ['array'], 'gnupg::geterror' => ['string|false'], 'gnupg::getprotocol' => ['int'], 'gnupg::gettrustlist' => ['array', 'pattern'=>'string'], 'gnupg::import' => ['array|false', 'keydata'=>'string'], 'gnupg::init' => ['resource', 'options'=>'?array{file_name?:string,home_dir?:string}'], 'gnupg::keyinfo' => ['array|false', 'pattern'=>'string'], 'gnupg::listsignatures' => ['?array', 'keyid'=>'string'], 'gnupg::setarmor' => ['bool', 'armor'=>'int'], 'gnupg::seterrormode' => ['void', 'errormode'=>'int'], 'gnupg::setsignmode' => ['bool', 'signmode'=>'int'], 'gnupg::sign' => ['string|false', 'plaintext'=>'string'], 'gnupg::verify' => ['array|false', 'signed_text'=>'string', 'signature'=>'string|false', '&plaintext='=>'string'], 'gnupg_adddecryptkey' => ['bool', 'identifier'=>'resource', 'fingerprint'=>'string', 'passphrase'=>'string'], 'gnupg_addencryptkey' => ['bool', 'identifier'=>'resource', 'fingerprint'=>'string'], 'gnupg_addsignkey' => ['bool', 'identifier'=>'resource', 'fingerprint'=>'string', 'passphrase='=>'string'], 'gnupg_cleardecryptkeys' => ['bool', 'identifier'=>'resource'], 'gnupg_clearencryptkeys' => ['bool', 'identifier'=>'resource'], 'gnupg_clearsignkeys' => ['bool', 'identifier'=>'resource'], 'gnupg_decrypt' => ['string|false', 'identifier'=>'resource', 'text'=>'string'], 'gnupg_decryptverify' => ['array', 'identifier'=>'resource', 'text'=>'string', 'plaintext'=>'string'], 'gnupg_deletekey' => ['bool', 'identifier'=>'resource', 'key'=>'string', 'allow_secret'=>'bool'], 'gnupg_encrypt' => ['string|false', 'identifier'=>'resource', 'plaintext'=>'string'], 'gnupg_encryptsign' => ['string|false', 'identifier'=>'resource', 'plaintext'=>'string'], 'gnupg_export' => ['string|false', 'identifier'=>'resource', 'fingerprint'=>'string'], 'gnupg_getengineinfo' => ['array', 'identifier'=>'resource'], 'gnupg_geterror' => ['string|false', 'identifier'=>'resource'], 'gnupg_getprotocol' => ['int', 'identifier'=>'resource'], 'gnupg_gettrustlist' => ['array', 'identifier'=>'resource', 'pattern'=>'string'], 'gnupg_import' => ['array|false', 'identifier'=>'resource', 'keydata'=>'string'], 'gnupg_init' => ['resource', 'options='=>'?array{file_name?:string,home_dir?:string}'], 'gnupg_keyinfo' => ['array|false', 'identifier'=>'resource', 'pattern'=>'string'], 'gnupg_listsignatures' => ['?array', 'identifier'=>'resource', 'keyid'=>'string'], 'gnupg_setarmor' => ['bool', 'identifier'=>'resource', 'armor'=>'int'], 'gnupg_seterrormode' => ['void', 'identifier'=>'resource', 'errormode'=>'int'], 'gnupg_setsignmode' => ['bool', 'identifier'=>'resource', 'signmode'=>'int'], 'gnupg_sign' => ['string|false', 'identifier'=>'resource', 'plaintext'=>'string'], 'gnupg_verify' => ['array|false', 'identifier'=>'resource', 'signed_text'=>'string', 'signature'=>'string|false', '&plaintext='=>'string'], 'gopher_parsedir' => ['array', 'dirent'=>'string'], 'grapheme_extract' => ['string|false', 'str'=>'string', 'size'=>'int', 'extract_type='=>'int', 'start='=>'int', '&w_next='=>'int'], 'grapheme_stripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'], 'grapheme_stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool'], 'grapheme_strlen' => ['0|positive-int|false', 'str'=>'string'], 'grapheme_strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'], 'grapheme_strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'], 'grapheme_strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'], 'grapheme_strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool'], 'grapheme_substr' => ['string|false', 'str'=>'string', 'start'=>'int', 'length='=>'int'], 'gregoriantojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'], 'gridObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], 'Grpc\Call::__construct' => ['void', 'channel'=>'Grpc\Channel', 'method'=>'string', 'absolute_deadline'=>'Grpc\Timeval', 'host_override='=>'mixed'], 'Grpc\Call::cancel' => [''], 'Grpc\Call::getPeer' => ['string'], 'Grpc\Call::setCredentials' => ['int', 'creds_obj'=>'Grpc\CallCredentials'], 'Grpc\Call::startBatch' => ['object', 'batch'=>'array'], 'Grpc\CallCredentials::createComposite' => ['Grpc\CallCredentials', 'cred1'=>'Grpc\CallCredentials', 'cred2'=>'Grpc\CallCredentials'], 'Grpc\CallCredentials::createFromPlugin' => ['Grpc\CallCredentials', 'callback'=>'Closure'], 'Grpc\Channel::__construct' => ['void', 'target'=>'string', 'args='=>'array'], 'Grpc\Channel::close' => [''], 'Grpc\Channel::getConnectivityState' => ['int', 'try_to_connect='=>'bool|false'], 'Grpc\Channel::getTarget' => ['string'], 'Grpc\Channel::watchConnectivityState' => ['bool', 'last_state'=>'int', 'deadline_obj'=>'Grpc\Timeval'], 'Grpc\ChannelCredentials::createComposite' => ['Grpc\ChannelCredentials', 'cred1'=>'Grpc\ChannelCredentials', 'cred2'=>'Grpc\CallCredentials'], 'Grpc\ChannelCredentials::createDefault' => ['Grpc\ChannelCredentials'], 'Grpc\ChannelCredentials::createInsecure' => ['null'], 'Grpc\ChannelCredentials::createSsl' => ['Grpc\ChannelCredentials', 'pem_root_certs='=>'string|null', 'pem_private_key='=>'string|null', 'pem_cert_chain='=>'string|null'], 'Grpc\ChannelCredentials::setDefaultRootsPem' => ['', 'pem_roots'=>'string'], 'Grpc\Server::__construct' => ['void', 'args'=>'array'], 'Grpc\Server::addHttp2Port' => ['bool', 'addr'=>'string'], 'Grpc\Server::addSecureHttp2Port' => ['bool', 'addr'=>'string', 'creds_obj'=>'Grpc\ServerCredentials'], 'Grpc\Server::requestCall' => ['', 'tag_new'=>'int', 'tag_cancel'=>'int'], 'Grpc\Server::start' => [''], 'Grpc\ServerCredentials::createSsl' => ['object', 'pem_root_certs'=>'string', 'pem_private_key'=>'string', 'pem_cert_chain'=>'string'], 'Grpc\Timeval::__construct' => ['void', 'usec'=>'int'], 'Grpc\Timeval::add' => ['Grpc\Timeval', 'other'=>'Grpc\Timeval'], 'Grpc\Timeval::compare' => ['int', 'a'=>'Grpc\Timeval', 'b'=>'Grpc\Timeval'], 'Grpc\Timeval::infFuture' => ['Grpc\Timeval'], 'Grpc\Timeval::infPast' => ['Grpc\Timeval'], 'Grpc\Timeval::now' => ['Grpc\Timeval'], 'Grpc\Timeval::similar' => ['bool', 'a'=>'Grpc\Timeval', 'b'=>'Grpc\Timeval', 'threshold'=>'Grpc\Timeval'], 'Grpc\Timeval::sleepUntil' => [''], 'Grpc\Timeval::subtract' => ['Grpc\Timeval', 'other'=>'Grpc\Timeval'], 'Grpc\Timeval::zero' => ['Grpc\Timeval'], 'gupnp_context_get_host_ip' => ['string', 'context'=>'resource'], 'gupnp_context_get_port' => ['int', 'context'=>'resource'], 'gupnp_context_get_subscription_timeout' => ['int', 'context'=>'resource'], 'gupnp_context_host_path' => ['bool', 'context'=>'resource', 'local_path'=>'string', 'server_path'=>'string'], 'gupnp_context_new' => ['resource', 'host_ip='=>'string', 'port='=>'int'], 'gupnp_context_set_subscription_timeout' => ['void', 'context'=>'resource', 'timeout'=>'int'], 'gupnp_context_timeout_add' => ['bool', 'context'=>'resource', 'timeout'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'], 'gupnp_context_unhost_path' => ['bool', 'context'=>'resource', 'server_path'=>'string'], 'gupnp_control_point_browse_start' => ['bool', 'cpoint'=>'resource'], 'gupnp_control_point_browse_stop' => ['bool', 'cpoint'=>'resource'], 'gupnp_control_point_callback_set' => ['bool', 'cpoint'=>'resource', 'signal'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'], 'gupnp_control_point_new' => ['resource', 'context'=>'resource', 'target'=>'string'], 'gupnp_device_action_callback_set' => ['bool', 'root_device'=>'resource', 'signal'=>'int', 'action_name'=>'string', 'callback'=>'mixed', 'arg='=>'mixed'], 'gupnp_device_info_get' => ['array', 'root_device'=>'resource'], 'gupnp_device_info_get_service' => ['resource', 'root_device'=>'resource', 'type'=>'string'], 'gupnp_root_device_get_available' => ['bool', 'root_device'=>'resource'], 'gupnp_root_device_get_relative_location' => ['string', 'root_device'=>'resource'], 'gupnp_root_device_new' => ['resource', 'context'=>'resource', 'location'=>'string', 'description_dir'=>'string'], 'gupnp_root_device_set_available' => ['bool', 'root_device'=>'resource', 'available'=>'bool'], 'gupnp_root_device_start' => ['bool', 'root_device'=>'resource'], 'gupnp_root_device_stop' => ['bool', 'root_device'=>'resource'], 'gupnp_service_action_get' => ['mixed', 'action'=>'resource', 'name'=>'string', 'type'=>'int'], 'gupnp_service_action_return' => ['bool', 'action'=>'resource'], 'gupnp_service_action_return_error' => ['bool', 'action'=>'resource', 'error_code'=>'int', 'error_description='=>'string'], 'gupnp_service_action_set' => ['bool', 'action'=>'resource', 'name'=>'string', 'type'=>'int', 'value'=>'mixed'], 'gupnp_service_freeze_notify' => ['bool', 'service'=>'resource'], 'gupnp_service_info_get' => ['array', 'proxy'=>'resource'], 'gupnp_service_info_get_introspection' => ['mixed', 'proxy'=>'resource', 'callback='=>'mixed', 'arg='=>'mixed'], 'gupnp_service_introspection_get_state_variable' => ['array', 'introspection'=>'resource', 'variable_name'=>'string'], 'gupnp_service_notify' => ['bool', 'service'=>'resource', 'name'=>'string', 'type'=>'int', 'value'=>'mixed'], 'gupnp_service_proxy_action_get' => ['mixed', 'proxy'=>'resource', 'action'=>'string', 'name'=>'string', 'type'=>'int'], 'gupnp_service_proxy_action_set' => ['bool', 'proxy'=>'resource', 'action'=>'string', 'name'=>'string', 'value'=>'mixed', 'type'=>'int'], 'gupnp_service_proxy_add_notify' => ['bool', 'proxy'=>'resource', 'value'=>'string', 'type'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'], 'gupnp_service_proxy_callback_set' => ['bool', 'proxy'=>'resource', 'signal'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'], 'gupnp_service_proxy_get_subscribed' => ['bool', 'proxy'=>'resource'], 'gupnp_service_proxy_remove_notify' => ['bool', 'proxy'=>'resource', 'value'=>'string'], 'gupnp_service_proxy_send_action' => ['array', 'proxy'=>'resource', 'action'=>'string', 'in_params'=>'array', 'out_params'=>'array'], 'gupnp_service_proxy_set_subscribed' => ['bool', 'proxy'=>'resource', 'subscribed'=>'bool'], 'gupnp_service_thaw_notify' => ['bool', 'service'=>'resource'], 'gzclose' => ['bool', 'zp'=>'resource'], 'gzcompress' => ['string|false', 'data'=>'string', 'level='=>'int', 'encoding='=>'int'], 'gzdecode' => ['string|false', 'data'=>'string', 'length='=>'int'], 'gzdeflate' => ['string|false', 'data'=>'string', 'level='=>'int', 'encoding='=>'int'], 'gzencode' => ['string|false', 'data'=>'string', 'level='=>'int', 'encoding_mode='=>'int'], 'gzeof' => ['bool', 'zp'=>'resource'], 'gzfile' => ['list|false', 'filename'=>'string', 'use_include_path='=>'int'], 'gzgetc' => ['string|false', 'zp'=>'resource'], 'gzgets' => ['string|false', 'zp'=>'resource', 'length='=>'int'], 'gzgetss' => ['string|false', 'zp'=>'resource', 'length'=>'int', 'allowable_tags='=>'string'], 'gzinflate' => ['string|false', 'data'=>'string', 'length='=>'int'], 'gzopen' => ['resource|false', 'filename'=>'string', 'mode'=>'string', 'use_include_path='=>'int'], 'gzpassthru' => ['int|false', 'zp'=>'resource'], 'gzputs' => ['int|false', 'zp'=>'resource', 'string'=>'string', 'length='=>'int'], 'gzread' => ['string|false', 'zp'=>'resource', 'length'=>'int'], 'gzrewind' => ['bool', 'zp'=>'resource'], 'gzseek' => ['int', 'zp'=>'resource', 'offset'=>'int', 'whence='=>'int'], 'gztell' => ['int|false', 'zp'=>'resource'], 'gzuncompress' => ['string|false', 'data'=>'string', 'length='=>'int'], 'gzwrite' => ['int|false', 'zp'=>'resource', 'string'=>'string', 'length='=>'int'], 'HaruAnnotation::setBorderStyle' => ['bool', 'width'=>'float', 'dash_on'=>'int', 'dash_off'=>'int'], 'HaruAnnotation::setHighlightMode' => ['bool', 'mode'=>'int'], 'HaruAnnotation::setIcon' => ['bool', 'icon'=>'int'], 'HaruAnnotation::setOpened' => ['bool', 'opened'=>'bool'], 'HaruDestination::setFit' => ['bool'], 'HaruDestination::setFitB' => ['bool'], 'HaruDestination::setFitBH' => ['bool', 'top'=>'float'], 'HaruDestination::setFitBV' => ['bool', 'left'=>'float'], 'HaruDestination::setFitH' => ['bool', 'top'=>'float'], 'HaruDestination::setFitR' => ['bool', 'left'=>'float', 'bottom'=>'float', 'right'=>'float', 'top'=>'float'], 'HaruDestination::setFitV' => ['bool', 'left'=>'float'], 'HaruDestination::setXYZ' => ['bool', 'left'=>'float', 'top'=>'float', 'zoom'=>'float'], 'HaruDoc::__construct' => ['void'], 'HaruDoc::addPage' => ['object'], 'HaruDoc::addPageLabel' => ['bool', 'first_page'=>'int', 'style'=>'int', 'first_num'=>'int', 'prefix='=>'string'], 'HaruDoc::createOutline' => ['object', 'title'=>'string', 'parent_outline='=>'object', 'encoder='=>'object'], 'HaruDoc::getCurrentEncoder' => ['object'], 'HaruDoc::getCurrentPage' => ['object'], 'HaruDoc::getEncoder' => ['object', 'encoding'=>'string'], 'HaruDoc::getFont' => ['object', 'fontname'=>'string', 'encoding='=>'string'], 'HaruDoc::getInfoAttr' => ['string', 'type'=>'int'], 'HaruDoc::getPageLayout' => ['int'], 'HaruDoc::getPageMode' => ['int'], 'HaruDoc::getStreamSize' => ['int'], 'HaruDoc::insertPage' => ['object', 'page'=>'object'], 'HaruDoc::loadJPEG' => ['object', 'filename'=>'string'], 'HaruDoc::loadPNG' => ['object', 'filename'=>'string', 'deferred='=>'bool'], 'HaruDoc::loadRaw' => ['object', 'filename'=>'string', 'width'=>'int', 'height'=>'int', 'color_space'=>'int'], 'HaruDoc::loadTTC' => ['string', 'fontfile'=>'string', 'index'=>'int', 'embed='=>'bool'], 'HaruDoc::loadTTF' => ['string', 'fontfile'=>'string', 'embed='=>'bool'], 'HaruDoc::loadType1' => ['string', 'afmfile'=>'string', 'pfmfile='=>'string'], 'HaruDoc::output' => ['bool'], 'HaruDoc::readFromStream' => ['string', 'bytes'=>'int'], 'HaruDoc::resetError' => ['bool'], 'HaruDoc::resetStream' => ['bool'], 'HaruDoc::save' => ['bool', 'file'=>'string'], 'HaruDoc::saveToStream' => ['bool'], 'HaruDoc::setCompressionMode' => ['bool', 'mode'=>'int'], 'HaruDoc::setCurrentEncoder' => ['bool', 'encoding'=>'string'], 'HaruDoc::setEncryptionMode' => ['bool', 'mode'=>'int', 'key_len='=>'int'], 'HaruDoc::setInfoAttr' => ['bool', 'type'=>'int', 'info'=>'string'], 'HaruDoc::setInfoDateAttr' => ['bool', 'type'=>'int', 'year'=>'int', 'month'=>'int', 'day'=>'int', 'hour'=>'int', 'min'=>'int', 'sec'=>'int', 'ind'=>'string', 'off_hour'=>'int', 'off_min'=>'int'], 'HaruDoc::setOpenAction' => ['bool', 'destination'=>'object'], 'HaruDoc::setPageLayout' => ['bool', 'layout'=>'int'], 'HaruDoc::setPageMode' => ['bool', 'mode'=>'int'], 'HaruDoc::setPagesConfiguration' => ['bool', 'page_per_pages'=>'int'], 'HaruDoc::setPassword' => ['bool', 'owner_password'=>'string', 'user_password'=>'string'], 'HaruDoc::setPermission' => ['bool', 'permission'=>'int'], 'HaruDoc::useCNSEncodings' => ['bool'], 'HaruDoc::useCNSFonts' => ['bool'], 'HaruDoc::useCNTEncodings' => ['bool'], 'HaruDoc::useCNTFonts' => ['bool'], 'HaruDoc::useJPEncodings' => ['bool'], 'HaruDoc::useJPFonts' => ['bool'], 'HaruDoc::useKREncodings' => ['bool'], 'HaruDoc::useKRFonts' => ['bool'], 'HaruEncoder::getByteType' => ['int', 'text'=>'string', 'index'=>'int'], 'HaruEncoder::getType' => ['int'], 'HaruEncoder::getUnicode' => ['int', 'character'=>'int'], 'HaruEncoder::getWritingMode' => ['int'], 'HaruFont::getAscent' => ['int'], 'HaruFont::getCapHeight' => ['int'], 'HaruFont::getDescent' => ['int'], 'HaruFont::getEncodingName' => ['string'], 'HaruFont::getFontName' => ['string'], 'HaruFont::getTextWidth' => ['array', 'text'=>'string'], 'HaruFont::getUnicodeWidth' => ['int', 'character'=>'int'], 'HaruFont::getXHeight' => ['int'], 'HaruFont::measureText' => ['int', 'text'=>'string', 'width'=>'float', 'font_size'=>'float', 'char_space'=>'float', 'word_space'=>'float', 'word_wrap='=>'bool'], 'HaruImage::getBitsPerComponent' => ['int'], 'HaruImage::getColorSpace' => ['string'], 'HaruImage::getHeight' => ['int'], 'HaruImage::getSize' => ['array'], 'HaruImage::getWidth' => ['int'], 'HaruImage::setColorMask' => ['bool', 'rmin'=>'int', 'rmax'=>'int', 'gmin'=>'int', 'gmax'=>'int', 'bmin'=>'int', 'bmax'=>'int'], 'HaruImage::setMaskImage' => ['bool', 'mask_image'=>'object'], 'HaruOutline::setDestination' => ['bool', 'destination'=>'object'], 'HaruOutline::setOpened' => ['bool', 'opened'=>'bool'], 'HaruPage::arc' => ['bool', 'x'=>'float', 'y'=>'float', 'ray'=>'float', 'ang1'=>'float', 'ang2'=>'float'], 'HaruPage::beginText' => ['bool'], 'HaruPage::circle' => ['bool', 'x'=>'float', 'y'=>'float', 'ray'=>'float'], 'HaruPage::closePath' => ['bool'], 'HaruPage::concat' => ['bool', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'x'=>'float', 'y'=>'float'], 'HaruPage::createDestination' => ['object'], 'HaruPage::createLinkAnnotation' => ['object', 'rectangle'=>'array', 'destination'=>'object'], 'HaruPage::createTextAnnotation' => ['object', 'rectangle'=>'array', 'text'=>'string', 'encoder='=>'object'], 'HaruPage::createURLAnnotation' => ['object', 'rectangle'=>'array', 'url'=>'string'], 'HaruPage::curveTo' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'], 'HaruPage::curveTo2' => ['bool', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'], 'HaruPage::curveTo3' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x3'=>'float', 'y3'=>'float'], 'HaruPage::drawImage' => ['bool', 'image'=>'object', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'], 'HaruPage::ellipse' => ['bool', 'x'=>'float', 'y'=>'float', 'xray'=>'float', 'yray'=>'float'], 'HaruPage::endPath' => ['bool'], 'HaruPage::endText' => ['bool'], 'HaruPage::eofill' => ['bool'], 'HaruPage::eoFillStroke' => ['bool', 'close_path='=>'bool'], 'HaruPage::fill' => ['bool'], 'HaruPage::fillStroke' => ['bool', 'close_path='=>'bool'], 'HaruPage::getCharSpace' => ['float'], 'HaruPage::getCMYKFill' => ['array'], 'HaruPage::getCMYKStroke' => ['array'], 'HaruPage::getCurrentFont' => ['object'], 'HaruPage::getCurrentFontSize' => ['float'], 'HaruPage::getCurrentPos' => ['array'], 'HaruPage::getCurrentTextPos' => ['array'], 'HaruPage::getDash' => ['array'], 'HaruPage::getFillingColorSpace' => ['int'], 'HaruPage::getFlatness' => ['float'], 'HaruPage::getGMode' => ['int'], 'HaruPage::getGrayFill' => ['float'], 'HaruPage::getGrayStroke' => ['float'], 'HaruPage::getHeight' => ['float'], 'HaruPage::getHorizontalScaling' => ['float'], 'HaruPage::getLineCap' => ['int'], 'HaruPage::getLineJoin' => ['int'], 'HaruPage::getLineWidth' => ['float'], 'HaruPage::getMiterLimit' => ['float'], 'HaruPage::getRGBFill' => ['array'], 'HaruPage::getRGBStroke' => ['array'], 'HaruPage::getStrokingColorSpace' => ['int'], 'HaruPage::getTextLeading' => ['float'], 'HaruPage::getTextMatrix' => ['array'], 'HaruPage::getTextRenderingMode' => ['int'], 'HaruPage::getTextRise' => ['float'], 'HaruPage::getTextWidth' => ['float', 'text'=>'string'], 'HaruPage::getTransMatrix' => ['array'], 'HaruPage::getWidth' => ['float'], 'HaruPage::getWordSpace' => ['float'], 'HaruPage::lineTo' => ['bool', 'x'=>'float', 'y'=>'float'], 'HaruPage::measureText' => ['int', 'text'=>'string', 'width'=>'float', 'wordwrap='=>'bool'], 'HaruPage::moveTextPos' => ['bool', 'x'=>'float', 'y'=>'float', 'set_leading='=>'bool'], 'HaruPage::moveTo' => ['bool', 'x'=>'float', 'y'=>'float'], 'HaruPage::moveToNextLine' => ['bool'], 'HaruPage::rectangle' => ['bool', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'], 'HaruPage::setCharSpace' => ['bool', 'char_space'=>'float'], 'HaruPage::setCMYKFill' => ['bool', 'c'=>'float', 'm'=>'float', 'y'=>'float', 'k'=>'float'], 'HaruPage::setCMYKStroke' => ['bool', 'c'=>'float', 'm'=>'float', 'y'=>'float', 'k'=>'float'], 'HaruPage::setDash' => ['bool', 'pattern'=>'array', 'phase'=>'int'], 'HaruPage::setFlatness' => ['bool', 'flatness'=>'float'], 'HaruPage::setFontAndSize' => ['bool', 'font'=>'object', 'size'=>'float'], 'HaruPage::setGrayFill' => ['bool', 'value'=>'float'], 'HaruPage::setGrayStroke' => ['bool', 'value'=>'float'], 'HaruPage::setHeight' => ['bool', 'height'=>'float'], 'HaruPage::setHorizontalScaling' => ['bool', 'scaling'=>'float'], 'HaruPage::setLineCap' => ['bool', 'cap'=>'int'], 'HaruPage::setLineJoin' => ['bool', 'join'=>'int'], 'HaruPage::setLineWidth' => ['bool', 'width'=>'float'], 'HaruPage::setMiterLimit' => ['bool', 'limit'=>'float'], 'HaruPage::setRGBFill' => ['bool', 'r'=>'float', 'g'=>'float', 'b'=>'float'], 'HaruPage::setRGBStroke' => ['bool', 'r'=>'float', 'g'=>'float', 'b'=>'float'], 'HaruPage::setRotate' => ['bool', 'angle'=>'int'], 'HaruPage::setSize' => ['bool', 'size'=>'int', 'direction'=>'int'], 'HaruPage::setSlideShow' => ['bool', 'type'=>'int', 'disp_time'=>'float', 'trans_time'=>'float'], 'HaruPage::setTextLeading' => ['bool', 'text_leading'=>'float'], 'HaruPage::setTextMatrix' => ['bool', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'x'=>'float', 'y'=>'float'], 'HaruPage::setTextRenderingMode' => ['bool', 'mode'=>'int'], 'HaruPage::setTextRise' => ['bool', 'rise'=>'float'], 'HaruPage::setWidth' => ['bool', 'width'=>'float'], 'HaruPage::setWordSpace' => ['bool', 'word_space'=>'float'], 'HaruPage::showText' => ['bool', 'text'=>'string'], 'HaruPage::showTextNextLine' => ['bool', 'text'=>'string', 'word_space='=>'float', 'char_space='=>'float'], 'HaruPage::stroke' => ['bool', 'close_path='=>'bool'], 'HaruPage::textOut' => ['bool', 'x'=>'float', 'y'=>'float', 'text'=>'string'], 'HaruPage::textRect' => ['bool', 'left'=>'float', 'top'=>'float', 'right'=>'float', 'bottom'=>'float', 'text'=>'string', 'align='=>'int'], 'hash' => ['non-falsy-string|false', 'algo'=>'string', 'data'=>'string', 'raw_output='=>'bool'], 'hash_algos' => ['non-empty-list'], 'hash_copy' => ['HashContext', 'context'=>'HashContext'], 'hash_equals' => ['bool', 'known_string'=>'string', 'user_string'=>'string'], 'hash_file' => ['non-falsy-string|false', 'algo'=>'string', 'filename'=>'string', 'raw_output='=>'bool'], 'hash_final' => ['non-falsy-string', 'context'=>'HashContext', 'raw_output='=>'bool'], 'hash_hkdf' => ['non-falsy-string|false', 'algo'=>'string', 'key'=>'string', 'length='=>'int', 'info='=>'string', 'salt='=>'string'], 'hash_hmac' => ['non-falsy-string|false', 'algo'=>'string', 'data'=>'string', 'key'=>'string', 'raw_output='=>'bool'], 'hash_hmac_algos' => ['non-empty-list'], 'hash_hmac_file' => ['non-falsy-string|false', 'algo'=>'string', 'filename'=>'string', 'key'=>'string', 'raw_output='=>'bool'], 'hash_init' => ['HashContext', 'algo'=>'string', 'options='=>'int', 'key='=>'string'], 'hash_pbkdf2' => ['(non-falsy-string&lowercase-string)|false', 'algo'=>'string', 'password'=>'string', 'salt'=>'string', 'iterations'=>'int', 'length='=>'int', 'raw_output='=>'bool'], 'hash_update' => ['bool', 'context'=>'HashContext', 'data'=>'string'], 'hash_update_file' => ['bool', 'context'=>'HashContext', 'filename'=>'string', 'scontext='=>'?HashContext'], 'hash_update_stream' => ['int', 'context'=>'HashContext', 'handle'=>'resource', 'length='=>'int'], 'hashTableObj::clear' => ['void'], 'hashTableObj::get' => ['string', 'key'=>'string'], 'hashTableObj::nextkey' => ['string', 'previousKey'=>'string'], 'hashTableObj::remove' => ['int', 'key'=>'string'], 'hashTableObj::set' => ['int', 'key'=>'string', 'value'=>'string'], 'header' => ['void', 'header'=>'string', 'replace='=>'bool', 'http_response_code='=>'int'], 'header_register_callback' => ['bool', 'callback'=>'callable'], 'header_remove' => ['void', 'name='=>'string'], 'headers_list' => ['list'], 'headers_sent' => ['bool', '&w_file='=>'string', '&w_line='=>'int'], 'hebrev' => ['string', 'str'=>'string', 'max_chars_per_line='=>'int'], 'hebrevc' => ['string', 'str'=>'string', 'max_chars_per_line='=>'int'], 'hex2bin' => ['string|false', 'data'=>'string'], 'hexdec' => ['int|float', 'hexadecimal_number'=>'string'], 'highlight_file' => ['string|bool', 'file_name'=>'string', 'return='=>'bool'], 'highlight_string' => ['string|bool', 'string'=>'string', 'return='=>'bool'], 'hrtime' => ['array{0:int,1:int}|int|float|false', 'get_as_number='=>'bool'], 'HRTime\PerformanceCounter::getElapsedTicks' => ['int'], 'HRTime\PerformanceCounter::getFrequency' => ['int'], 'HRTime\PerformanceCounter::getLastElapsedTicks' => ['int'], 'HRTime\PerformanceCounter::getTicks' => ['int'], 'HRTime\PerformanceCounter::getTicksSince' => ['int', 'start'=>'int'], 'HRTime\PerformanceCounter::isRunning' => ['bool'], 'HRTime\PerformanceCounter::start' => ['void'], 'HRTime\PerformanceCounter::stop' => ['void'], 'HRTime\StopWatch::getElapsedTicks' => ['int'], 'HRTime\StopWatch::getElapsedTime' => ['float', 'unit='=>'int'], 'HRTime\StopWatch::getLastElapsedTicks' => ['int'], 'HRTime\StopWatch::getLastElapsedTime' => ['float', 'unit='=>'int'], 'HRTime\StopWatch::isRunning' => ['bool'], 'HRTime\StopWatch::start' => ['void'], 'HRTime\StopWatch::stop' => ['void'], 'html_entity_decode' => ['string', 'string'=>'string', 'quote_style='=>'int', 'encoding='=>'string'], 'htmlentities' => ['string', 'string'=>'string', 'quote_style='=>'int', 'encoding='=>'string', 'double_encode='=>'bool'], 'htmlspecialchars' => ['string', 'string'=>'string', 'quote_style='=>'int', 'encoding='=>'string', 'double_encode='=>'bool'], 'htmlspecialchars_decode' => ['string', 'string'=>'string', 'quote_style='=>'int'], 'http\Env\Request::__construct' => ['void'], 'http\Env\Request::getCookie' => ['mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool|false'], 'http\Env\Request::getFiles' => ['array'], 'http\Env\Request::getForm' => ['mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool|false'], 'http\Env\Request::getQuery' => ['mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool|false'], 'http\Env\Response::__construct' => ['void'], 'http\Env\Response::__invoke' => ['bool', 'data'=>'string', 'ob_flags='=>'int'], 'http\Env\Response::isCachedByETag' => ['int', 'header_name='=>'string'], 'http\Env\Response::isCachedByLastModified' => ['int', 'header_name='=>'string'], 'http\Env\Response::send' => ['bool', 'stream='=>'resource'], 'http\Env\Response::setCacheControl' => ['http\Env\Response', 'cache_control'=>'string'], 'http\Env\Response::setContentDisposition' => ['http\Env\Response', 'disposition_params'=>'array'], 'http\Env\Response::setContentEncoding' => ['http\Env\Response', 'content_encoding'=>'int'], 'http\Env\Response::setContentType' => ['http\Env\Response', 'content_type'=>'string'], 'http\Env\Response::setCookie' => ['http\Env\Response', 'cookie'=>'mixed'], 'http\Env\Response::setEnvRequest' => ['http\Env\Response', 'env_request'=>'http\Message'], 'http\Env\Response::setEtag' => ['http\Env\Response', 'etag'=>'string'], 'http\Env\Response::setLastModified' => ['http\Env\Response', 'last_modified'=>'int'], 'http\Env\Response::setThrottleRate' => ['http\Env\Response', 'chunk_size'=>'int', 'delay='=>'float|int'], 'http\QueryString::__construct' => ['void', 'querystring'=>'string'], 'http\QueryString::__toString' => ['string'], 'http\QueryString::get' => ['', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool|false'], 'http\QueryString::getArray' => ['array', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'], 'http\QueryString::getBool' => ['bool', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'], 'http\QueryString::getFloat' => ['float', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'], 'http\QueryString::getGlobalInstance' => ['http\QueryString'], 'http\QueryString::getInt' => ['int', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'], 'http\QueryString::getIterator' => ['IteratorAggregate'], 'http\QueryString::getObject' => ['', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'], 'http\QueryString::getString' => ['string', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'], 'http\QueryString::mod' => ['http\QueryString', 'params='=>'mixed'], 'http\QueryString::offsetExists' => ['bool', 'offset'=>'mixed'], 'http\QueryString::offsetGet' => ['mixed', 'offset'=>'mixed'], 'http\QueryString::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], 'http\QueryString::offsetUnset' => ['void', 'offset'=>'mixed'], 'http\QueryString::serialize' => ['string'], 'http\QueryString::set' => ['http\QueryString', 'params'=>'mixed'], 'http\QueryString::toArray' => ['mixed[]'], 'http\QueryString::toString' => ['string'], 'http\QueryString::unserialize' => ['void', 'serialized'=>''], 'http\QueryString::xlate' => ['http\QueryString'], 'http\Url::__construct' => ['void', 'old_url='=>'mixed', 'new_url='=>'mixed', 'flags='=>'int'], 'http\Url::__toString' => [''], 'http\Url::mod' => ['http\Url', 'parts'=>'mixed', 'flags='=>'float|int|mixed'], 'http\Url::toArray' => ['string[]'], 'http\Url::toString' => ['string'], 'http_build_cookie' => ['string', 'cookie'=>'array'], 'http_build_query' => ['string', 'querydata'=>'array|object', 'prefix='=>'string', 'arg_separator='=>'string', 'enc_type='=>'int'], 'http_build_str' => ['string', 'query'=>'array', 'prefix='=>'?string', 'arg_separator='=>'string'], 'http_build_url' => ['string', 'url='=>'string|array', 'parts='=>'string|array', 'flags='=>'int', 'new_url='=>'array'], 'http_cache_etag' => ['bool', 'etag='=>'string'], 'http_cache_last_modified' => ['bool', 'timestamp_or_expires='=>'int'], 'http_chunked_decode' => ['string', 'encoded'=>'string'], 'http_date' => ['string', 'timestamp='=>'int'], 'http_deflate' => ['string', 'data'=>'string', 'flags='=>'int'], 'http_get' => ['string', 'url'=>'string', 'options='=>'array', 'info='=>'array'], 'http_get_request_body' => ['string'], 'http_get_request_body_stream' => ['resource'], 'http_get_request_headers' => ['array'], 'http_head' => ['string', 'url'=>'string', 'options='=>'array', 'info='=>'array'], 'http_inflate' => ['string', 'data'=>'string'], 'http_match_etag' => ['bool', 'etag'=>'string', 'for_range='=>'bool'], 'http_match_modified' => ['bool', 'timestamp='=>'int', 'for_range='=>'bool'], 'http_match_request_header' => ['bool', 'header'=>'string', 'value'=>'string', 'match_case='=>'bool'], 'http_negotiate_charset' => ['string', 'supported'=>'array', 'result='=>'array'], 'http_negotiate_content_type' => ['string', 'supported'=>'array', 'result='=>'array'], 'http_negotiate_language' => ['string', 'supported'=>'array', 'result='=>'array'], 'http_parse_cookie' => ['object', 'cookie'=>'string', 'flags='=>'int', 'allowed_extras='=>'array'], 'http_parse_headers' => ['array', 'header'=>'string'], 'http_parse_message' => ['object', 'message'=>'string'], 'http_parse_params' => ['object', 'param'=>'string', 'flags='=>'int'], 'http_persistent_handles_clean' => ['string', 'ident='=>'string'], 'http_persistent_handles_count' => ['object'], 'http_persistent_handles_ident' => ['string', 'ident='=>'string'], 'http_post_data' => ['string', 'url'=>'string', 'data'=>'string', 'options='=>'array', 'info='=>'array'], 'http_post_fields' => ['string', 'url'=>'string', 'data'=>'array', 'files='=>'array', 'options='=>'array', 'info='=>'array'], 'http_put_data' => ['string', 'url'=>'string', 'data'=>'string', 'options='=>'array', 'info='=>'array'], 'http_put_file' => ['string', 'url'=>'string', 'file'=>'string', 'options='=>'array', 'info='=>'array'], 'http_put_stream' => ['string', 'url'=>'string', 'stream'=>'', 'options='=>'array', 'info='=>'array'], 'http_redirect' => ['bool', 'url='=>'string', 'params='=>'array', 'session='=>'bool', 'status='=>'int'], 'http_request' => ['string', 'method'=>'int', 'url'=>'string', 'body='=>'string', 'options='=>'array', 'info='=>'array'], 'http_request_body_encode' => ['string', 'fields'=>'array', 'files'=>'array'], 'http_request_method_exists' => ['int', 'method'=>''], 'http_request_method_name' => ['string', 'method'=>'int'], 'http_request_method_register' => ['int', 'method'=>'string'], 'http_request_method_unregister' => ['bool', 'method'=>''], 'http_response_code' => ['int|bool', 'response_code='=>'int'], 'http_send_content_disposition' => ['bool', 'filename'=>'string', 'inline='=>'bool'], 'http_send_content_type' => ['bool', 'content_type='=>'string'], 'http_send_data' => ['bool', 'data'=>'string'], 'http_send_file' => ['bool', 'file'=>'string'], 'http_send_last_modified' => ['bool', 'timestamp='=>'int'], 'http_send_status' => ['bool', 'status'=>'int'], 'http_send_stream' => ['bool', 'stream'=>''], 'http_support' => ['int', 'feature='=>'int'], 'http_throttle' => ['', 'sec'=>'float', 'bytes='=>'int'], 'HttpDeflateStream::__construct' => ['void', 'flags='=>'int'], 'HttpDeflateStream::factory' => ['HttpDeflateStream', 'flags='=>'int', 'class_name='=>'string'], 'HttpDeflateStream::finish' => ['string', 'data='=>'string'], 'HttpDeflateStream::flush' => ['string', 'data='=>'string'], 'HttpDeflateStream::update' => ['string', 'data'=>'string'], 'HttpInflateStream::__construct' => ['void', 'flags='=>'int'], 'HttpInflateStream::factory' => ['HttpInflateStream', 'flags='=>'int', 'class_name='=>'string'], 'HttpInflateStream::finish' => ['string', 'data='=>'string'], 'HttpInflateStream::flush' => ['string', 'data='=>'string'], 'HttpInflateStream::update' => ['string', 'data'=>'string'], 'HttpMessage::__construct' => ['void', 'message='=>'string'], 'HttpMessage::__toString' => ['string'], 'HttpMessage::addHeaders' => ['', 'headers'=>'array', 'append='=>'bool'], 'HttpMessage::count' => ['0|positive-int'], 'HttpMessage::current' => ['mixed'], 'HttpMessage::detach' => ['HttpMessage'], 'HttpMessage::factory' => ['HttpMessage', 'raw_message='=>'string', 'class_name='=>'string'], 'HttpMessage::fromEnv' => ['HttpMessage', 'message_type'=>'int', 'class_name='=>'string'], 'HttpMessage::fromString' => ['HttpMessage', 'raw_message='=>'string', 'class_name='=>'string'], 'HttpMessage::getBody' => ['string'], 'HttpMessage::getHeader' => ['string', 'header'=>'string'], 'HttpMessage::getHeaders' => ['array'], 'HttpMessage::getHttpVersion' => ['string'], 'HttpMessage::getInfo' => [''], 'HttpMessage::getParentMessage' => ['HttpMessage'], 'HttpMessage::getRequestMethod' => ['string'], 'HttpMessage::getRequestUrl' => ['string'], 'HttpMessage::getResponseCode' => ['int'], 'HttpMessage::getResponseStatus' => ['string'], 'HttpMessage::getType' => ['int'], 'HttpMessage::guessContentType' => ['string', 'magic_file'=>'string', 'magic_mode='=>'int'], 'HttpMessage::key' => ['int|string'], 'HttpMessage::next' => ['void'], 'HttpMessage::prepend' => ['', 'message'=>'httpmessage', 'top='=>'bool'], 'HttpMessage::reverse' => ['HttpMessage'], 'HttpMessage::rewind' => ['void'], 'HttpMessage::send' => ['bool'], 'HttpMessage::serialize' => ['string'], 'HttpMessage::setBody' => ['', 'body'=>'string'], 'HttpMessage::setHeaders' => ['', 'headers'=>'array'], 'HttpMessage::setHttpVersion' => ['bool', 'version'=>'string'], 'HttpMessage::setInfo' => ['', 'http_info'=>''], 'HttpMessage::setRequestMethod' => ['bool', 'method'=>'string'], 'HttpMessage::setRequestUrl' => ['bool', 'url'=>'string'], 'HttpMessage::setResponseCode' => ['bool', 'code'=>'int'], 'HttpMessage::setResponseStatus' => ['bool', 'status'=>'string'], 'HttpMessage::setType' => ['', 'type'=>'int'], 'HttpMessage::toMessageTypeObject' => ['HttpRequest|HttpResponse'], 'HttpMessage::toString' => ['string', 'include_parent='=>'bool'], 'HttpMessage::unserialize' => ['void', 'serialized'=>''], 'HttpMessage::valid' => ['bool'], 'HttpQueryString::__construct' => ['void', 'global='=>'bool', 'add='=>''], 'HttpQueryString::__toString' => ['string'], 'HttpQueryString::factory' => ['', 'global'=>'', 'params'=>'', 'class_name'=>''], 'HttpQueryString::get' => ['', 'key='=>'string', 'type='=>'', 'defval='=>'', 'delete='=>'bool'], 'HttpQueryString::getArray' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''], 'HttpQueryString::getBool' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''], 'HttpQueryString::getFloat' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''], 'HttpQueryString::getInt' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''], 'HttpQueryString::getObject' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''], 'HttpQueryString::getString' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''], 'HttpQueryString::mod' => ['HttpQueryString', 'params'=>''], 'HttpQueryString::offsetExists' => ['bool', 'offset'=>'mixed'], 'HttpQueryString::offsetGet' => ['mixed', 'offset'=>'mixed'], 'HttpQueryString::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], 'HttpQueryString::offsetUnset' => ['void', 'offset'=>'mixed'], 'HttpQueryString::serialize' => ['string'], 'HttpQueryString::set' => ['string', 'params'=>''], 'HttpQueryString::singleton' => ['HttpQueryString', 'global='=>'bool'], 'HttpQueryString::toArray' => ['array'], 'HttpQueryString::toString' => ['string'], 'HttpQueryString::unserialize' => ['void', 'serialized'=>'string'], 'HttpQueryString::xlate' => ['bool', 'ie'=>'string', 'oe'=>'string'], 'HttpRequest::__construct' => ['void', 'url='=>'string', 'request_method='=>'int', 'options='=>'array'], 'HttpRequest::addBody' => ['', 'request_body_data'=>''], 'HttpRequest::addCookies' => ['bool', 'cookies'=>'array'], 'HttpRequest::addHeaders' => ['bool', 'headers'=>'array'], 'HttpRequest::addPostFields' => ['bool', 'post_data'=>'array'], 'HttpRequest::addPostFile' => ['bool', 'name'=>'string', 'file'=>'string', 'content_type='=>'string'], 'HttpRequest::addPutData' => ['bool', 'put_data'=>'string'], 'HttpRequest::addQueryData' => ['bool', 'query_params'=>'array'], 'HttpRequest::addRawPostData' => ['bool', 'raw_post_data'=>'string'], 'HttpRequest::addSslOptions' => ['bool', 'options'=>'array'], 'HttpRequest::clearHistory' => [''], 'HttpRequest::enableCookies' => ['bool'], 'HttpRequest::encodeBody' => ['', 'fields'=>'', 'files'=>''], 'HttpRequest::factory' => ['', 'url'=>'', 'method'=>'', 'options'=>'', 'class_name'=>''], 'HttpRequest::flushCookies' => [''], 'HttpRequest::get' => ['', 'url'=>'', 'options'=>'', '&info'=>''], 'HttpRequest::getBody' => [''], 'HttpRequest::getContentType' => ['string'], 'HttpRequest::getCookies' => ['array'], 'HttpRequest::getHeaders' => ['array'], 'HttpRequest::getHistory' => ['HttpMessage'], 'HttpRequest::getMethod' => ['int'], 'HttpRequest::getOptions' => ['array'], 'HttpRequest::getPostFields' => ['array'], 'HttpRequest::getPostFiles' => ['array'], 'HttpRequest::getPutData' => ['string'], 'HttpRequest::getPutFile' => ['string'], 'HttpRequest::getQueryData' => ['string'], 'HttpRequest::getRawPostData' => ['string'], 'HttpRequest::getRawRequestMessage' => ['string'], 'HttpRequest::getRawResponseMessage' => ['string'], 'HttpRequest::getRequestMessage' => ['HttpMessage'], 'HttpRequest::getResponseBody' => ['string'], 'HttpRequest::getResponseCode' => ['int'], 'HttpRequest::getResponseCookies' => ['array', 'flags='=>'int', 'allowed_extras='=>'array'], 'HttpRequest::getResponseData' => ['array'], 'HttpRequest::getResponseHeader' => ['', 'name='=>'string'], 'HttpRequest::getResponseInfo' => ['', 'name='=>'string'], 'HttpRequest::getResponseMessage' => ['HttpMessage'], 'HttpRequest::getResponseStatus' => ['string'], 'HttpRequest::getSslOptions' => ['array'], 'HttpRequest::getUrl' => ['string'], 'HttpRequest::head' => ['', 'url'=>'', 'options'=>'', '&info'=>''], 'HttpRequest::methodExists' => ['', 'method'=>''], 'HttpRequest::methodName' => ['', 'method_id'=>''], 'HttpRequest::methodRegister' => ['', 'method_name'=>''], 'HttpRequest::methodUnregister' => ['', 'method'=>''], 'HttpRequest::postData' => ['', 'url'=>'', 'data'=>'', 'options'=>'', '&info'=>''], 'HttpRequest::postFields' => ['', 'url'=>'', 'data'=>'', 'options'=>'', '&info'=>''], 'HttpRequest::putData' => ['', 'url'=>'', 'data'=>'', 'options'=>'', '&info'=>''], 'HttpRequest::putFile' => ['', 'url'=>'', 'file'=>'', 'options'=>'', '&info'=>''], 'HttpRequest::putStream' => ['', 'url'=>'', 'stream'=>'', 'options'=>'', '&info'=>''], 'HttpRequest::resetCookies' => ['bool', 'session_only='=>'bool'], 'HttpRequest::send' => ['HttpMessage'], 'HttpRequest::setBody' => ['bool', 'request_body_data='=>'string'], 'HttpRequest::setContentType' => ['bool', 'content_type'=>'string'], 'HttpRequest::setCookies' => ['bool', 'cookies='=>'array'], 'HttpRequest::setHeaders' => ['bool', 'headers='=>'array'], 'HttpRequest::setMethod' => ['bool', 'request_method'=>'int'], 'HttpRequest::setOptions' => ['bool', 'options='=>'array'], 'HttpRequest::setPostFields' => ['bool', 'post_data'=>'array'], 'HttpRequest::setPostFiles' => ['bool', 'post_files'=>'array'], 'HttpRequest::setPutData' => ['bool', 'put_data='=>'string'], 'HttpRequest::setPutFile' => ['bool', 'file='=>'string'], 'HttpRequest::setQueryData' => ['bool', 'query_data'=>''], 'HttpRequest::setRawPostData' => ['bool', 'raw_post_data='=>'string'], 'HttpRequest::setSslOptions' => ['bool', 'options='=>'array'], 'HttpRequest::setUrl' => ['bool', 'url'=>'string'], 'HttpRequestDataShare::__construct' => ['void'], 'HttpRequestDataShare::__destruct' => [''], 'HttpRequestDataShare::attach' => ['', 'request'=>'HttpRequest'], 'HttpRequestDataShare::count' => ['0|positive-int'], 'HttpRequestDataShare::detach' => ['', 'request'=>'HttpRequest'], 'HttpRequestDataShare::factory' => ['', 'global'=>'', 'class_name'=>''], 'HttpRequestDataShare::reset' => [''], 'HttpRequestDataShare::singleton' => ['', 'global'=>''], 'HttpRequestPool::__construct' => ['void', 'request='=>'httprequest'], 'HttpRequestPool::__destruct' => [''], 'HttpRequestPool::attach' => ['bool', 'request'=>'httprequest'], 'HttpRequestPool::count' => ['0|positive-int'], 'HttpRequestPool::current' => ['mixed'], 'HttpRequestPool::detach' => ['bool', 'request'=>'httprequest'], 'HttpRequestPool::enableEvents' => ['', 'enable'=>''], 'HttpRequestPool::enablePipelining' => ['', 'enable'=>''], 'HttpRequestPool::getAttachedRequests' => ['array'], 'HttpRequestPool::getFinishedRequests' => ['array'], 'HttpRequestPool::key' => ['int|string'], 'HttpRequestPool::next' => ['void'], 'HttpRequestPool::reset' => [''], 'HttpRequestPool::rewind' => ['void'], 'HttpRequestPool::send' => ['bool'], 'HttpRequestPool::socketPerform' => ['bool'], 'HttpRequestPool::socketSelect' => ['bool', 'timeout='=>'float'], 'HttpRequestPool::valid' => ['bool'], 'HttpResponse::capture' => [''], 'HttpResponse::getBufferSize' => ['int'], 'HttpResponse::getCache' => ['bool'], 'HttpResponse::getCacheControl' => ['string'], 'HttpResponse::getContentDisposition' => ['string'], 'HttpResponse::getContentType' => ['string'], 'HttpResponse::getData' => ['string'], 'HttpResponse::getETag' => ['string'], 'HttpResponse::getFile' => ['string'], 'HttpResponse::getGzip' => ['bool'], 'HttpResponse::getHeader' => ['', 'name='=>'string'], 'HttpResponse::getLastModified' => ['int'], 'HttpResponse::getRequestBody' => ['string'], 'HttpResponse::getRequestBodyStream' => ['resource'], 'HttpResponse::getRequestHeaders' => ['array'], 'HttpResponse::getStream' => ['resource'], 'HttpResponse::getThrottleDelay' => ['float'], 'HttpResponse::guessContentType' => ['string', 'magic_file'=>'string', 'magic_mode='=>'int'], 'HttpResponse::redirect' => ['', 'url='=>'string', 'params='=>'array', 'session='=>'bool', 'status='=>'int'], 'HttpResponse::send' => ['bool', 'clean_ob='=>'bool'], 'HttpResponse::setBufferSize' => ['bool', 'bytes'=>'int'], 'HttpResponse::setCache' => ['bool', 'cache'=>'bool'], 'HttpResponse::setCacheControl' => ['bool', 'control'=>'string', 'max_age='=>'int', 'must_revalidate='=>'bool'], 'HttpResponse::setContentDisposition' => ['bool', 'filename'=>'string', 'inline='=>'bool'], 'HttpResponse::setContentType' => ['bool', 'content_type'=>'string'], 'HttpResponse::setData' => ['bool', 'data'=>''], 'HttpResponse::setETag' => ['bool', 'etag'=>'string'], 'HttpResponse::setFile' => ['bool', 'file'=>'string'], 'HttpResponse::setGzip' => ['bool', 'gzip'=>'bool'], 'HttpResponse::setHeader' => ['bool', 'name'=>'string', 'value='=>'', 'replace='=>'bool'], 'HttpResponse::setLastModified' => ['bool', 'timestamp'=>'int'], 'HttpResponse::setStream' => ['bool', 'stream'=>''], 'HttpResponse::setThrottleDelay' => ['bool', 'seconds'=>'float'], 'HttpResponse::status' => ['bool', 'status'=>'int'], 'HttpUtil::buildCookie' => ['', 'cookie_array'=>''], 'HttpUtil::buildStr' => ['', 'query'=>'', 'prefix'=>'', 'arg_sep'=>''], 'HttpUtil::buildUrl' => ['', 'url'=>'', 'parts'=>'', 'flags'=>'', '&composed'=>''], 'HttpUtil::chunkedDecode' => ['', 'encoded_string'=>''], 'HttpUtil::date' => ['', 'timestamp'=>''], 'HttpUtil::deflate' => ['', 'plain'=>'', 'flags'=>''], 'HttpUtil::inflate' => ['', 'encoded'=>''], 'HttpUtil::matchEtag' => ['', 'plain_etag'=>'', 'for_range'=>''], 'HttpUtil::matchModified' => ['', 'last_modified'=>'', 'for_range'=>''], 'HttpUtil::matchRequestHeader' => ['', 'header_name'=>'', 'header_value'=>'', 'case_sensitive'=>''], 'HttpUtil::negotiateCharset' => ['', 'supported'=>'', '&result'=>''], 'HttpUtil::negotiateContentType' => ['', 'supported'=>'', '&result'=>''], 'HttpUtil::negotiateLanguage' => ['', 'supported'=>'', '&result'=>''], 'HttpUtil::parseCookie' => ['', 'cookie_string'=>''], 'HttpUtil::parseHeaders' => ['', 'headers_string'=>''], 'HttpUtil::parseMessage' => ['', 'message_string'=>''], 'HttpUtil::parseParams' => ['', 'param_string'=>'', 'flags'=>''], 'HttpUtil::support' => ['', 'feature'=>''], 'hw_api::checkin' => ['bool', 'parameter'=>'array'], 'hw_api::checkout' => ['bool', 'parameter'=>'array'], 'hw_api::children' => ['array', 'parameter'=>'array'], 'hw_api::content' => ['HW_API_Content', 'parameter'=>'array'], 'hw_api::copy' => ['hw_api_content', 'parameter'=>'array'], 'hw_api::dbstat' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::dcstat' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::dstanchors' => ['array', 'parameter'=>'array'], 'hw_api::dstofsrcanchor' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::find' => ['array', 'parameter'=>'array'], 'hw_api::ftstat' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::hwstat' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::identify' => ['bool', 'parameter'=>'array'], 'hw_api::info' => ['array', 'parameter'=>'array'], 'hw_api::insert' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::insertanchor' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::insertcollection' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::insertdocument' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::link' => ['bool', 'parameter'=>'array'], 'hw_api::lock' => ['bool', 'parameter'=>'array'], 'hw_api::move' => ['bool', 'parameter'=>'array'], 'hw_api::object' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::objectbyanchor' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::parents' => ['array', 'parameter'=>'array'], 'hw_api::remove' => ['bool', 'parameter'=>'array'], 'hw_api::replace' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::setcommittedversion' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::srcanchors' => ['array', 'parameter'=>'array'], 'hw_api::srcsofdst' => ['array', 'parameter'=>'array'], 'hw_api::unlock' => ['bool', 'parameter'=>'array'], 'hw_api::user' => ['hw_api_object', 'parameter'=>'array'], 'hw_api::userlist' => ['array', 'parameter'=>'array'], 'hw_api_attribute' => ['HW_API_Attribute', 'name='=>'string', 'value='=>'string'], 'hw_api_attribute::key' => ['string'], 'hw_api_attribute::langdepvalue' => ['string', 'language'=>'string'], 'hw_api_attribute::value' => ['string'], 'hw_api_attribute::values' => ['array'], 'hw_api_content' => ['HW_API_Content', 'content'=>'string', 'mimetype'=>'string'], 'hw_api_content::mimetype' => ['string'], 'hw_api_content::read' => ['string', 'buffer'=>'string', 'len'=>'int'], 'hw_api_error::count' => ['0|positive-int'], 'hw_api_error::reason' => ['HW_API_Reason'], 'hw_api_object' => ['hw_api_object', 'parameter'=>'array'], 'hw_api_object::assign' => ['bool', 'parameter'=>'array'], 'hw_api_object::attreditable' => ['bool', 'parameter'=>'array'], 'hw_api_object::count' => ['0|positive-int', 'parameter'=>'array'], 'hw_api_object::insert' => ['bool', 'attribute'=>'hw_api_attribute'], 'hw_api_object::remove' => ['bool', 'name'=>'string'], 'hw_api_object::title' => ['string', 'parameter'=>'array'], 'hw_api_object::value' => ['string', 'name'=>'string'], 'hw_api_reason::description' => ['string'], 'hw_api_reason::type' => ['HW_API_Reason'], 'hw_Array2Objrec' => ['string', 'object_array'=>'array'], 'hw_changeobject' => ['bool', 'link'=>'int', 'objid'=>'int', 'attributes'=>'array'], 'hw_Children' => ['array', 'connection'=>'int', 'objectid'=>'int'], 'hw_ChildrenObj' => ['array', 'connection'=>'int', 'objectid'=>'int'], 'hw_Close' => ['bool', 'connection'=>'int'], 'hw_Connect' => ['int', 'host'=>'string', 'port'=>'int', 'username='=>'string', 'password='=>'string'], 'hw_connection_info' => ['', 'link'=>'int'], 'hw_cp' => ['int', 'connection'=>'int', 'object_id_array'=>'array', 'destination_id'=>'int'], 'hw_Deleteobject' => ['bool', 'connection'=>'int', 'object_to_delete'=>'int'], 'hw_DocByAnchor' => ['int', 'connection'=>'int', 'anchorid'=>'int'], 'hw_DocByAnchorObj' => ['string', 'connection'=>'int', 'anchorid'=>'int'], 'hw_Document_Attributes' => ['string', 'hw_document'=>'int'], 'hw_Document_BodyTag' => ['string', 'hw_document'=>'int', 'prefix='=>'string'], 'hw_Document_Content' => ['string', 'hw_document'=>'int'], 'hw_Document_SetContent' => ['bool', 'hw_document'=>'int', 'content'=>'string'], 'hw_Document_Size' => ['int', 'hw_document'=>'int'], 'hw_dummy' => ['string', 'link'=>'int', 'id'=>'int', 'msgid'=>'int'], 'hw_EditText' => ['bool', 'connection'=>'int', 'hw_document'=>'int'], 'hw_Error' => ['int', 'connection'=>'int'], 'hw_ErrorMsg' => ['string', 'connection'=>'int'], 'hw_Free_Document' => ['bool', 'hw_document'=>'int'], 'hw_GetAnchors' => ['array', 'connection'=>'int', 'objectid'=>'int'], 'hw_GetAnchorsObj' => ['array', 'connection'=>'int', 'objectid'=>'int'], 'hw_GetAndLock' => ['string', 'connection'=>'int', 'objectid'=>'int'], 'hw_GetChildColl' => ['array', 'connection'=>'int', 'objectid'=>'int'], 'hw_GetChildCollObj' => ['array', 'connection'=>'int', 'objectid'=>'int'], 'hw_GetChildDocColl' => ['array', 'connection'=>'int', 'objectid'=>'int'], 'hw_GetChildDocCollObj' => ['array', 'connection'=>'int', 'objectid'=>'int'], 'hw_GetObject' => ['', 'connection'=>'int', 'objectid'=>'', 'query='=>'string'], 'hw_GetObjectByQuery' => ['array', 'connection'=>'int', 'query'=>'string', 'max_hits'=>'int'], 'hw_GetObjectByQueryColl' => ['array', 'connection'=>'int', 'objectid'=>'int', 'query'=>'string', 'max_hits'=>'int'], 'hw_GetObjectByQueryCollObj' => ['array', 'connection'=>'int', 'objectid'=>'int', 'query'=>'string', 'max_hits'=>'int'], 'hw_GetObjectByQueryObj' => ['array', 'connection'=>'int', 'query'=>'string', 'max_hits'=>'int'], 'hw_GetParents' => ['array', 'connection'=>'int', 'objectid'=>'int'], 'hw_GetParentsObj' => ['array', 'connection'=>'int', 'objectid'=>'int'], 'hw_getrellink' => ['string', 'link'=>'int', 'rootid'=>'int', 'sourceid'=>'int', 'destid'=>'int'], 'hw_GetRemote' => ['int', 'connection'=>'int', 'objectid'=>'int'], 'hw_getremotechildren' => ['', 'connection'=>'int', 'object_record'=>'string'], 'hw_GetSrcByDestObj' => ['array', 'connection'=>'int', 'objectid'=>'int'], 'hw_GetText' => ['int', 'connection'=>'int', 'objectid'=>'int', 'prefix='=>''], 'hw_getusername' => ['string', 'connection'=>'int'], 'hw_Identify' => ['string', 'link'=>'int', 'username'=>'string', 'password'=>'string'], 'hw_InCollections' => ['array', 'connection'=>'int', 'object_id_array'=>'array', 'collection_id_array'=>'array', 'return_collections'=>'int'], 'hw_Info' => ['string', 'connection'=>'int'], 'hw_InsColl' => ['int', 'connection'=>'int', 'objectid'=>'int', 'object_array'=>'array'], 'hw_InsDoc' => ['int', 'connection'=>'', 'parentid'=>'int', 'object_record'=>'string', 'text='=>'string'], 'hw_insertanchors' => ['bool', 'hwdoc'=>'int', 'anchorecs'=>'array', 'dest'=>'array', 'urlprefixes='=>'array'], 'hw_InsertDocument' => ['int', 'connection'=>'int', 'parent_id'=>'int', 'hw_document'=>'int'], 'hw_InsertObject' => ['int', 'connection'=>'int', 'object_rec'=>'string', 'parameter'=>'string'], 'hw_mapid' => ['int', 'connection'=>'int', 'server_id'=>'int', 'object_id'=>'int'], 'hw_Modifyobject' => ['bool', 'connection'=>'int', 'object_to_change'=>'int', 'remove'=>'array', 'add'=>'array', 'mode='=>'int'], 'hw_mv' => ['int', 'connection'=>'int', 'object_id_array'=>'array', 'source_id'=>'int', 'destination_id'=>'int'], 'hw_New_Document' => ['int', 'object_record'=>'string', 'document_data'=>'string', 'document_size'=>'int'], 'hw_objrec2array' => ['array', 'object_record'=>'string', 'format='=>'array'], 'hw_Output_Document' => ['bool', 'hw_document'=>'int'], 'hw_pConnect' => ['int', 'host'=>'string', 'port'=>'int', 'username='=>'string', 'password='=>'string'], 'hw_PipeDocument' => ['int', 'connection'=>'int', 'objectid'=>'int', 'url_prefixes='=>'array'], 'hw_Root' => ['int'], 'hw_setlinkroot' => ['int', 'link'=>'int', 'rootid'=>'int'], 'hw_stat' => ['string', 'link'=>'int'], 'hw_Unlock' => ['bool', 'connection'=>'int', 'objectid'=>'int'], 'hw_Who' => ['array', 'connection'=>'int'], 'hwapi_attribute_new' => ['HW_API_Attribute', 'name='=>'string', 'value='=>'string'], 'hwapi_content_new' => ['HW_API_Content', 'content'=>'string', 'mimetype'=>'string'], 'hwapi_hgcsp' => ['HW_API', 'hostname'=>'string', 'port='=>'int'], 'hwapi_object_new' => ['hw_api_object', 'parameter'=>'array'], 'hypot' => ['float', 'num1'=>'float', 'num2'=>'float'], 'ibase_add_user' => ['bool', 'service_handle'=>'resource', 'user_name'=>'string', 'password'=>'string', 'first_name='=>'string', 'middle_name='=>'string', 'last_name='=>'string'], 'ibase_affected_rows' => ['int', 'link_identifier='=>'resource'], 'ibase_backup' => ['mixed', 'service_handle'=>'resource', 'source_db'=>'string', 'dest_file'=>'string', 'options='=>'int', 'verbose='=>'bool'], 'ibase_blob_add' => ['void', 'blob_handle'=>'resource', 'data'=>'string'], 'ibase_blob_cancel' => ['bool', 'blob_handle'=>'resource'], 'ibase_blob_close' => ['string', 'blob_handle'=>'resource'], 'ibase_blob_create' => ['resource', 'link_identifier='=>'resource'], 'ibase_blob_echo' => ['bool', 'link_identifier'=>'', 'blob_id'=>'string'], 'ibase_blob_echo\'1' => ['bool', 'blob_id'=>'string'], 'ibase_blob_get' => ['string', 'blob_handle'=>'resource', 'len'=>'int'], 'ibase_blob_import' => ['string', 'link_identifier'=>'', 'file_handle'=>''], 'ibase_blob_info' => ['array', 'link_identifier'=>'', 'blob_id'=>'string'], 'ibase_blob_info\'1' => ['array', 'blob_id'=>'string'], 'ibase_blob_open' => ['resource|false', 'link_identifier'=>'', 'blob_id'=>'string'], 'ibase_blob_open\'1' => ['resource', 'blob_id'=>'string'], 'ibase_close' => ['bool', 'link_identifier='=>'resource'], 'ibase_commit' => ['bool', 'link_identifier='=>'resource'], 'ibase_commit_ret' => ['bool', 'link_identifier='=>'resource'], 'ibase_connect' => ['resource', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'charset='=>'string', 'buffers='=>'int', 'dialect='=>'int', 'role='=>'string'], 'ibase_db_info' => ['string', 'service_handle'=>'resource', 'db'=>'string', 'action'=>'int', 'argument='=>'int'], 'ibase_delete_user' => ['bool', 'service_handle'=>'resource', 'user_name'=>'string', 'password='=>'string', 'first_name='=>'string', 'middle_name='=>'string', 'last_name='=>'string'], 'ibase_drop_db' => ['bool', 'link_identifier='=>'resource'], 'ibase_errcode' => ['int'], 'ibase_errmsg' => ['string'], 'ibase_execute' => ['resource', 'query'=>'resource', 'bind_arg='=>'mixed', '...args='=>'mixed'], 'ibase_fetch_assoc' => ['array', 'result'=>'resource', 'fetch_flags='=>'int'], 'ibase_fetch_object' => ['object', 'result'=>'resource', 'fetch_flags='=>'int'], 'ibase_fetch_row' => ['array', 'result'=>'resource', 'fetch_flags='=>'int'], 'ibase_field_info' => ['array', 'query_result'=>'resource', 'field_number'=>'int'], 'ibase_free_event_handler' => ['bool', 'event'=>'resource'], 'ibase_free_query' => ['bool', 'query'=>'resource'], 'ibase_free_result' => ['bool', 'result'=>'resource'], 'ibase_gen_id' => ['int', 'generator'=>'string', 'increment='=>'int', 'link_identifier='=>'resource'], 'ibase_maintain_db' => ['bool', 'service_handle'=>'resource', 'db'=>'string', 'action'=>'int', 'argument='=>'int'], 'ibase_modify_user' => ['bool', 'service_handle'=>'resource', 'user_name'=>'string', 'password'=>'string', 'first_name='=>'string', 'middle_name='=>'string', 'last_name='=>'string'], 'ibase_name_result' => ['bool', 'result'=>'resource', 'name'=>'string'], 'ibase_num_fields' => ['int', 'query_result'=>'resource'], 'ibase_num_params' => ['int', 'query'=>'resource'], 'ibase_num_rows' => ['int', 'result_identifier'=>''], 'ibase_param_info' => ['array', 'query'=>'resource', 'field_number'=>'int'], 'ibase_pconnect' => ['resource', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'charset='=>'string', 'buffers='=>'int', 'dialect='=>'int', 'role='=>'string'], 'ibase_prepare' => ['resource', 'link_identifier'=>'', 'query'=>'string', 'trans_identifier'=>''], 'ibase_query' => ['resource', 'link_identifier='=>'resource', 'string='=>'string', 'bind_arg='=>'int', '...args='=>''], 'ibase_restore' => ['mixed', 'service_handle'=>'resource', 'source_file'=>'string', 'dest_db'=>'string', 'options='=>'int', 'verbose='=>'bool'], 'ibase_rollback' => ['bool', 'link_identifier='=>'resource'], 'ibase_rollback_ret' => ['bool', 'link_identifier='=>'resource'], 'ibase_server_info' => ['string', 'service_handle'=>'resource', 'action'=>'int'], 'ibase_service_attach' => ['resource', 'host'=>'string', 'dba_username'=>'string', 'dba_password'=>'string'], 'ibase_service_detach' => ['bool', 'service_handle'=>'resource'], 'ibase_set_event_handler' => ['resource', 'link_identifier'=>'', 'callback'=>'callable', 'event='=>'string', '...args='=>''], 'ibase_set_event_handler\'1' => ['resource', 'callback'=>'callable', 'event'=>'string', '...args'=>''], 'ibase_timefmt' => ['bool', 'format'=>'string', 'columntype='=>'int'], 'ibase_trans' => ['resource', 'trans_args='=>'int', 'link_identifier='=>'', '...args='=>''], 'ibase_wait_event' => ['string', 'link_identifier'=>'', 'event='=>'string', '...args='=>''], 'ibase_wait_event\'1' => ['string', 'event'=>'string', '...args'=>''], 'iconv' => ['string|false', 'in_charset'=>'string', 'out_charset'=>'string', 'str'=>'string'], 'iconv_get_encoding' => ['mixed', 'type='=>'string'], 'iconv_mime_decode' => ['string|false', 'encoded_string'=>'string', 'mode='=>'int', 'charset='=>'string'], 'iconv_mime_decode_headers' => ['array|false', 'headers'=>'string', 'mode='=>'int', 'charset='=>'string'], 'iconv_mime_encode' => ['string|false', 'field_name'=>'string', 'field_value'=>'string', 'preference='=>'array'], 'iconv_set_encoding' => ['bool', 'type'=>'string', 'charset'=>'string'], 'iconv_strlen' => ['0|positive-int|false', 'str'=>'string', 'charset='=>'string'], 'iconv_strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'charset='=>'string'], 'iconv_strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'charset='=>'string'], 'iconv_substr' => ['string|false', 'str'=>'string', 'offset'=>'int', 'length='=>'int', 'charset='=>'string'], 'id3_get_frame_long_name' => ['string', 'frameid'=>'string'], 'id3_get_frame_short_name' => ['string', 'frameid'=>'string'], 'id3_get_genre_id' => ['int', 'genre'=>'string'], 'id3_get_genre_list' => ['array'], 'id3_get_genre_name' => ['string', 'genre_id'=>'int'], 'id3_get_tag' => ['array', 'filename'=>'string', 'version='=>'int'], 'id3_get_version' => ['int', 'filename'=>'string'], 'id3_remove_tag' => ['bool', 'filename'=>'string', 'version='=>'int'], 'id3_set_tag' => ['bool', 'filename'=>'string', 'tag'=>'array', 'version='=>'int'], 'idate' => ['int|false', 'format'=>'string', 'timestamp='=>'int'], 'idn_strerror' => ['string', 'errorcode'=>'int'], 'idn_to_ascii' => ['string|false', 'domain'=>'string', 'options='=>'int', 'variant='=>'int', '&w_idna_info='=>'array'], 'idn_to_utf8' => ['string|false', 'domain'=>'string', 'options='=>'int', 'variant='=>'int', '&w_idna_info='=>'array'], 'ifx_affected_rows' => ['int', 'result_id'=>'resource'], 'ifx_blobinfile_mode' => ['bool', 'mode'=>'int'], 'ifx_byteasvarchar' => ['bool', 'mode'=>'int'], 'ifx_close' => ['bool', 'link_identifier='=>'resource'], 'ifx_connect' => ['resource', 'database='=>'string', 'userid='=>'string', 'password='=>'string'], 'ifx_copy_blob' => ['int', 'bid'=>'int'], 'ifx_create_blob' => ['int', 'type'=>'int', 'mode'=>'int', 'param'=>'string'], 'ifx_create_char' => ['int', 'param'=>'string'], 'ifx_do' => ['bool', 'result_id'=>'resource'], 'ifx_error' => ['string', 'link_identifier='=>'resource'], 'ifx_errormsg' => ['string', 'errorcode='=>'int'], 'ifx_fetch_row' => ['array', 'result_id'=>'resource', 'position='=>'mixed'], 'ifx_fieldproperties' => ['array', 'result_id'=>'resource'], 'ifx_fieldtypes' => ['array', 'result_id'=>'resource'], 'ifx_free_blob' => ['bool', 'bid'=>'int'], 'ifx_free_char' => ['bool', 'bid'=>'int'], 'ifx_free_result' => ['bool', 'result_id'=>'resource'], 'ifx_get_blob' => ['string', 'bid'=>'int'], 'ifx_get_char' => ['string', 'bid'=>'int'], 'ifx_getsqlca' => ['array', 'result_id'=>'resource'], 'ifx_htmltbl_result' => ['int', 'result_id'=>'resource', 'html_table_options='=>'string'], 'ifx_nullformat' => ['bool', 'mode'=>'int'], 'ifx_num_fields' => ['int', 'result_id'=>'resource'], 'ifx_num_rows' => ['int', 'result_id'=>'resource'], 'ifx_pconnect' => ['resource', 'database='=>'string', 'userid='=>'string', 'password='=>'string'], 'ifx_prepare' => ['resource', 'query'=>'string', 'link_identifier'=>'resource', 'cursor_def='=>'int', 'blobidarray='=>'mixed'], 'ifx_query' => ['resource', 'query'=>'string', 'link_identifier'=>'resource', 'cursor_type='=>'int', 'blobidarray='=>'mixed'], 'ifx_textasvarchar' => ['bool', 'mode'=>'int'], 'ifx_update_blob' => ['bool', 'bid'=>'int', 'content'=>'string'], 'ifx_update_char' => ['bool', 'bid'=>'int', 'content'=>'string'], 'ifxus_close_slob' => ['bool', 'bid'=>'int'], 'ifxus_create_slob' => ['int', 'mode'=>'int'], 'ifxus_free_slob' => ['bool', 'bid'=>'int'], 'ifxus_open_slob' => ['int', 'bid'=>'int', 'mode'=>'int'], 'ifxus_read_slob' => ['string', 'bid'=>'int', 'nbytes'=>'int'], 'ifxus_seek_slob' => ['int', 'bid'=>'int', 'mode'=>'int', 'offset'=>'int'], 'ifxus_tell_slob' => ['int', 'bid'=>'int'], 'ifxus_write_slob' => ['int', 'bid'=>'int', 'content'=>'string'], 'igbinary_serialize' => ['string|null', 'value'=>'mixed'], 'igbinary_unserialize' => ['mixed', 'str'=>'string'], 'ignore_user_abort' => ['0|1', 'value='=>'bool'], 'iis_add_server' => ['int', 'path'=>'string', 'comment'=>'string', 'server_ip'=>'string', 'port'=>'int', 'host_name'=>'string', 'rights'=>'int', 'start_server'=>'int'], 'iis_get_dir_security' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string'], 'iis_get_script_map' => ['string', 'server_instance'=>'int', 'virtual_path'=>'string', 'script_extension'=>'string'], 'iis_get_server_by_comment' => ['int', 'comment'=>'string'], 'iis_get_server_by_path' => ['int', 'path'=>'string'], 'iis_get_server_rights' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string'], 'iis_get_service_state' => ['int', 'service_id'=>'string'], 'iis_remove_server' => ['int', 'server_instance'=>'int'], 'iis_set_app_settings' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'application_scope'=>'string'], 'iis_set_dir_security' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'directory_flags'=>'int'], 'iis_set_script_map' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'script_extension'=>'string', 'engine_path'=>'string', 'allow_scripting'=>'int'], 'iis_set_server_rights' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'directory_flags'=>'int'], 'iis_start_server' => ['int', 'server_instance'=>'int'], 'iis_start_service' => ['int', 'service_id'=>'string'], 'iis_stop_server' => ['int', 'server_instance'=>'int'], 'iis_stop_service' => ['int', 'service_id'=>'string'], 'image2wbmp' => ['bool', 'im'=>'resource', 'filename='=>'?string', 'threshold='=>'int'], 'image_type_to_extension' => ['string|false', 'imagetype'=>'int', 'include_dot='=>'bool'], 'image_type_to_mime_type' => ['string', 'imagetype'=>'int'], 'imageaffine' => ['resource|false', 'src'=>'resource', 'affine'=>'array', 'clip='=>'array'], 'imageaffineconcat' => ['array', 'm1'=>'array', 'm2'=>'array'], 'imageaffinematrixconcat' => ['array{0:float,1:float,2:float,3:float,4:float,5:float}|false', 'm1'=>'array', 'm2'=>'array'], 'imageaffinematrixget' => ['array{0:float,1:float,2:float,3:float,4:float,5:float}|false', 'type'=>'int', 'options'=>'array|float'], 'imagealphablending' => ['bool', 'im'=>'resource', 'on'=>'bool'], 'imageantialias' => ['bool', 'im'=>'resource', 'on'=>'bool'], 'imagearc' => ['bool', 'im'=>'resource', 'cx'=>'int', 'cy'=>'int', 'w'=>'int', 'h'=>'int', 's'=>'int', 'e'=>'int', 'col'=>'int'], 'imagebmp' => ['bool', 'image'=>'resource', 'to='=>'string|resource|null', 'compressed='=>'bool'], 'imagechar' => ['bool', 'im'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'c'=>'string', 'col'=>'int'], 'imagecharup' => ['bool', 'im'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'c'=>'string', 'col'=>'int'], 'imagecolorallocate' => ['int<0, max>|false', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], 'imagecolorallocatealpha' => ['int<0, max>|false', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'], 'imagecolorat' => ['int<0, max>|false', 'im'=>'resource', 'x'=>'int', 'y'=>'int'], 'imagecolorclosest' => ['int<0, max>', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], 'imagecolorclosestalpha' => ['int<0, max>', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'], 'imagecolorclosesthwb' => ['int<0, max>', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], 'imagecolordeallocate' => ['bool', 'im'=>'resource', 'index'=>'int'], 'imagecolorexact' => ['int<0, max>|false', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], 'imagecolorexactalpha' => ['int<0, max>|false', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'], 'imagecolormatch' => ['bool', 'im1'=>'resource', 'im2'=>'resource'], 'imagecolorresolve' => ['int<0, max>', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], 'imagecolorresolvealpha' => ['int<0, max>', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'], 'imagecolorset' => ['void', 'im'=>'resource', 'col'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int'], 'imagecolorsforindex' => ['array{red: int<0, 255>, green: int<0, 255>, blue: int<0, 255>, alpha: int<0, 127>}', 'im'=>'resource', 'col'=>'int'], 'imagecolorstotal' => ['int<0, 256>', 'im'=>'resource'], 'imagecolortransparent' => ['int', 'im'=>'resource', 'col='=>'int'], 'imageconvolution' => ['bool', 'src_im'=>'resource', 'matrix3x3'=>'array', 'div'=>'float', 'offset'=>'float'], 'imagecopy' => ['bool', 'dst_im'=>'resource', 'src_im'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_w'=>'int', 'src_h'=>'int'], 'imagecopymerge' => ['bool', 'src_im'=>'resource', 'dst_im'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_w'=>'int', 'src_h'=>'int', 'pct'=>'int'], 'imagecopymergegray' => ['bool', 'src_im'=>'resource', 'dst_im'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_w'=>'int', 'src_h'=>'int', 'pct'=>'int'], 'imagecopyresampled' => ['bool', 'dst_im'=>'resource', 'src_im'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'dst_w'=>'int', 'dst_h'=>'int', 'src_w'=>'int', 'src_h'=>'int'], 'imagecopyresized' => ['bool', 'dst_im'=>'resource', 'src_im'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'dst_w'=>'int', 'dst_h'=>'int', 'src_w'=>'int', 'src_h'=>'int'], 'imagecreate' => ['__benevolent', 'x_size'=>'int', 'y_size'=>'int'], 'imagecreatefrombmp' => ['resource|false', 'filename'=>'string'], 'imagecreatefromgd' => ['resource|false', 'filename'=>'string'], 'imagecreatefromgd2' => ['resource|false', 'filename'=>'string'], 'imagecreatefromgd2part' => ['resource|false', 'filename'=>'string', 'srcx'=>'int', 'srcy'=>'int', 'width'=>'int', 'height'=>'int'], 'imagecreatefromgif' => ['resource|false', 'filename'=>'string'], 'imagecreatefromjpeg' => ['resource|false', 'filename'=>'string'], 'imagecreatefrompng' => ['resource|false', 'filename'=>'string'], 'imagecreatefromstring' => ['resource|false', 'image'=>'string'], 'imagecreatefromwbmp' => ['resource|false', 'filename'=>'string'], 'imagecreatefromwebp' => ['resource|false', 'filename'=>'string'], 'imagecreatefromxbm' => ['resource|false', 'filename'=>'string'], 'imagecreatefromxpm' => ['resource|false', 'filename'=>'string'], 'imagecreatetruecolor' => ['__benevolent', 'x_size'=>'int', 'y_size'=>'int'], 'imagecrop' => ['resource|false', 'im'=>'resource', 'rect'=>'array'], 'imagecropauto' => ['resource|false', 'im'=>'resource', 'mode='=>'int', 'threshold='=>'float', 'color='=>'int'], 'imagedashedline' => ['bool', 'im'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'col'=>'int'], 'imagedestroy' => ['bool', 'im'=>'resource'], 'imageellipse' => ['bool', 'im'=>'resource', 'cx'=>'int', 'cy'=>'int', 'w'=>'int', 'h'=>'int', 'color'=>'int'], 'imagefill' => ['bool', 'im'=>'resource', 'x'=>'int', 'y'=>'int', 'col'=>'int'], 'imagefilledarc' => ['bool', 'im'=>'resource', 'cx'=>'int', 'cy'=>'int', 'w'=>'int', 'h'=>'int', 's'=>'int', 'e'=>'int', 'col'=>'int', 'style'=>'int'], 'imagefilledellipse' => ['bool', 'im'=>'resource', 'cx'=>'int', 'cy'=>'int', 'w'=>'int', 'h'=>'int', 'color'=>'int'], 'imagefilledpolygon' => ['bool', 'im'=>'resource', 'point'=>'array', 'num_points'=>'int', 'col'=>'int'], 'imagefilledrectangle' => ['bool', 'im'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'col'=>'int'], 'imagefilltoborder' => ['bool', 'im'=>'resource', 'x'=>'int', 'y'=>'int', 'border'=>'int', 'col'=>'int'], 'imagefilter' => ['bool', 'src_im'=>'resource', 'filtertype'=>'int', 'arg1='=>'int', 'arg2='=>'int', 'arg3='=>'int', 'arg4='=>'int'], 'imageflip' => ['bool', 'im'=>'resource', 'mode'=>'int'], 'imagefontheight' => ['int', 'font'=>'int'], 'imagefontwidth' => ['int', 'font'=>'int'], 'imageftbbox' => ['array|false', 'size'=>'float', 'angle'=>'float', 'font_file'=>'string', 'text'=>'string', 'extrainfo='=>'array'], 'imagefttext' => ['array|false', 'im'=>'resource', 'size'=>'float', 'angle'=>'float', 'x'=>'int', 'y'=>'int', 'col'=>'int', 'font_file'=>'string', 'text'=>'string', 'extrainfo='=>'array'], 'imagegammacorrect' => ['bool', 'im'=>'resource', 'inputgamma'=>'float', 'outputgamma'=>'float'], 'imagegd' => ['bool', 'im'=>'resource', 'filename='=>'string|resource|null'], 'imagegd2' => ['bool', 'im'=>'resource', 'filename='=>'string|resource|null', 'chunk_size='=>'int', 'type='=>'int'], 'imagegetclip' => ['array', 'im'=>'resource'], 'imagegif' => ['bool', 'im'=>'resource', 'filename='=>'string|resource|null'], 'imagegrabscreen' => ['resource|false'], 'imagegrabwindow' => ['resource|false', 'window_handle'=>'int', 'client_area='=>'int'], 'imageinterlace' => ['int', 'im'=>'resource', 'interlace='=>'int'], 'imageistruecolor' => ['bool', 'im'=>'resource'], 'imagejpeg' => ['bool', 'im'=>'resource', 'filename='=>'string|resource|null', 'quality='=>'int'], 'imagelayereffect' => ['bool', 'im'=>'resource', 'effect'=>'int'], 'imageline' => ['bool', 'im'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'col'=>'int'], 'imageloadfont' => ['int|false', 'filename'=>'string'], 'imageObj::pasteImage' => ['void', 'srcImg'=>'imageObj', 'transparentColorHex'=>'int', 'dstX'=>'int', 'dstY'=>'int', 'angle'=>'int'], 'imageObj::saveImage' => ['int', 'filename'=>'string', 'oMap'=>'mapObj'], 'imageObj::saveWebImage' => ['string'], 'imageopenpolygon' => ['bool', 'image'=>'resource', 'points'=>'array', 'num_points'=>'int', 'color'=>'int'], 'imagepalettecopy' => ['void', 'dst'=>'resource', 'src'=>'resource'], 'imagepalettetotruecolor' => ['bool', 'src'=>'resource'], 'imagepng' => ['bool', 'im'=>'resource', 'filename='=>'string|resource|null', 'quality='=>'int', 'filters='=>'int'], 'imagepolygon' => ['bool', 'im'=>'resource', 'point'=>'array', 'num_points'=>'int', 'col'=>'int'], 'imagepsbbox' => ['array', 'text'=>'string', 'font'=>'', 'size'=>'int', 'space'=>'int', 'tightness'=>'int', 'angle'=>'float'], 'imagepsencodefont' => ['bool', 'font_index'=>'resource', 'encodingfile'=>'string'], 'imagepsextendfont' => ['bool', 'font_index'=>'resource', 'extend'=>'float'], 'imagepsfreefont' => ['bool', 'font_index'=>'resource'], 'imagepsloadfont' => ['resource', 'filename'=>'string'], 'imagepsslantfont' => ['bool', 'font_index'=>'resource', 'slant'=>'float'], 'imagepstext' => ['array', 'image'=>'resource', 'text'=>'string', 'font_index'=>'resource', 'size'=>'int', 'foreground'=>'int', 'background'=>'int', 'x'=>'int', 'y'=>'int', 'space='=>'int', 'tightness='=>'int', 'angle='=>'float', 'antialias_steps='=>'int'], 'imagerectangle' => ['bool', 'im'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'col'=>'int'], 'imageresolution' => ['mixed', 'image'=>'resource', 'res_x='=>'int', 'res_y='=>'int'], 'imagerotate' => ['resource|false', 'src_im'=>'resource', 'angle'=>'float', 'bgdcolor'=>'int', 'ignoretransparent='=>'int'], 'imagesavealpha' => ['bool', 'im'=>'resource', 'on'=>'bool'], 'imagescale' => ['resource|false', 'im'=>'resource', 'new_width'=>'int', 'new_height='=>'int', 'method='=>'int'], 'imagesetbrush' => ['bool', 'image'=>'resource', 'brush'=>'resource'], 'imagesetclip' => ['bool', 'im'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int'], 'imagesetinterpolation' => ['bool', 'im'=>'resource', 'method'=>'int'], 'imagesetpixel' => ['bool', 'im'=>'resource', 'x'=>'int', 'y'=>'int', 'col'=>'int'], 'imagesetstyle' => ['bool', 'im'=>'resource', 'styles'=>'array'], 'imagesetthickness' => ['bool', 'im'=>'resource', 'thickness'=>'int'], 'imagesettile' => ['bool', 'image'=>'resource', 'tile'=>'resource'], 'imagestring' => ['bool', 'im'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'str'=>'string', 'col'=>'int'], 'imagestringup' => ['bool', 'im'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'str'=>'string', 'col'=>'int'], 'imagesx' => ['int<1, max>', 'im'=>'resource'], 'imagesy' => ['int<1, max>', 'im'=>'resource'], 'imagetruecolortopalette' => ['bool', 'im'=>'resource', 'ditherflag'=>'bool', 'colorswanted'=>'int'], 'imagettfbbox' => ['array|false', 'size'=>'float', 'angle'=>'float', 'font_file'=>'string', 'text'=>'string'], 'imagettftext' => ['array|false', 'im'=>'resource', 'size'=>'float', 'angle'=>'float', 'x'=>'int', 'y'=>'int', 'col'=>'int', 'font_file'=>'string', 'text'=>'string'], 'imagetypes' => ['int'], 'imagewbmp' => ['bool', 'im'=>'resource', 'filename='=>'string|resource|null', 'foreground='=>'int'], 'imagewebp' => ['bool', 'im'=>'resource', 'filename='=>'string|resource|null', 'quality='=>'int'], 'imagexbm' => ['bool', 'im'=>'resource', 'filename='=>'string|resource|null', 'foreground='=>'int'], 'Imagick::__construct' => ['void', 'files='=>''], 'Imagick::__toString' => ['string'], 'Imagick::adaptiveBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'], 'Imagick::adaptiveResizeImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'bestfit='=>'bool'], 'Imagick::adaptiveSharpenImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'], 'Imagick::adaptiveThresholdImage' => ['bool', 'width'=>'int', 'height'=>'int', 'offset'=>'int'], 'Imagick::addImage' => ['bool', 'source'=>'imagick'], 'Imagick::addNoiseImage' => ['bool', 'noise_type'=>'int', 'channel='=>'int'], 'Imagick::affineTransformImage' => ['bool', 'matrix'=>'imagickdraw'], 'Imagick::animateImages' => ['bool', 'x_server'=>'string'], 'Imagick::annotateImage' => ['bool', 'draw_settings'=>'imagickdraw', 'x'=>'float', 'y'=>'float', 'angle'=>'float', 'text'=>'string'], 'Imagick::appendImages' => ['Imagick', 'stack'=>'bool'], 'Imagick::autoGammaImage' => ['bool', 'channel='=>'int'], 'Imagick::autoLevelImage' => ['bool', 'channel='=>'int'], 'Imagick::autoOrient' => ['bool'], 'Imagick::averageImages' => ['Imagick'], 'Imagick::blackThresholdImage' => ['bool', 'threshold'=>'mixed'], 'Imagick::blueShiftImage' => ['bool', 'factor='=>'float'], 'Imagick::blurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'], 'Imagick::borderImage' => ['bool', 'bordercolor'=>'mixed', 'width'=>'int', 'height'=>'int'], 'Imagick::brightnessContrastImage' => ['bool', 'brightness'=>'float', 'contrast'=>'float', 'channel='=>'int'], 'Imagick::charcoalImage' => ['bool', 'radius'=>'float', 'sigma'=>'float'], 'Imagick::chopImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], 'Imagick::clampImage' => ['bool', 'channel='=>'int'], 'Imagick::clear' => ['bool'], 'Imagick::clipImage' => ['bool'], 'Imagick::clipImagePath' => ['void', 'pathname'=>'string', 'inside'=>'string'], 'Imagick::clipPathImage' => ['bool', 'pathname'=>'string', 'inside'=>'bool'], 'Imagick::clone' => ['Imagick'], 'Imagick::clutImage' => ['bool', 'lookup_table'=>'imagick', 'int='=>'float'], 'Imagick::coalesceImages' => ['Imagick'], 'Imagick::colorFloodfillImage' => ['bool', 'fill'=>'mixed', 'fuzz'=>'float', 'bordercolor'=>'mixed', 'x'=>'int', 'y'=>'int'], 'Imagick::colorizeImage' => ['bool', 'colorize'=>'mixed', 'opacity'=>'mixed'], 'Imagick::colorMatrixImage' => ['bool', 'color_matrix'=>'array'], 'Imagick::combineImages' => ['Imagick', 'channeltype'=>'int'], 'Imagick::commentImage' => ['bool', 'comment'=>'string'], 'Imagick::compareImageChannels' => ['array{Imagick,float}', 'image'=>'imagick', 'channeltype'=>'int', 'metrictype'=>'int'], 'Imagick::compareImageLayers' => ['Imagick', 'method'=>'int'], 'Imagick::compareImages' => ['array{Imagick,float}', 'compare'=>'imagick', 'metric'=>'int'], 'Imagick::compositeImage' => ['bool', 'composite_object'=>'imagick', 'composite'=>'int', 'x'=>'int', 'y'=>'int', 'channel='=>'int'], 'Imagick::compositeImageGravity' => ['bool', 'imagick'=>'Imagick', 'COMPOSITE_CONSTANT'=>'int', 'GRAVITY_CONSTANT'=>'int'], 'Imagick::contrastImage' => ['bool', 'sharpen'=>'bool'], 'Imagick::contrastStretchImage' => ['bool', 'black_point'=>'float', 'white_point'=>'float', 'channel='=>'int'], 'Imagick::convolveImage' => ['bool', 'kernel'=>'array', 'channel='=>'int'], 'Imagick::count' => ['0|positive-int', 'mode='=>'int'], 'Imagick::cropImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], 'Imagick::cropThumbnailImage' => ['bool', 'width'=>'int', 'height'=>'int', 'legacy='=>'bool'], 'Imagick::current' => ['Imagick'], 'Imagick::cycleColormapImage' => ['bool', 'displace'=>'int'], 'Imagick::decipherImage' => ['bool', 'passphrase'=>'string'], 'Imagick::deconstructImages' => ['Imagick'], 'Imagick::deleteImageArtifact' => ['bool', 'artifact'=>'string'], 'Imagick::deleteImageProperty' => ['void', 'name'=>'string'], 'Imagick::deskewImage' => ['bool', 'threshold'=>'float'], 'Imagick::despeckleImage' => ['bool'], 'Imagick::destroy' => ['bool'], 'Imagick::displayImage' => ['bool', 'servername'=>'string'], 'Imagick::displayImages' => ['bool', 'servername'=>'string'], 'Imagick::distortImage' => ['bool', 'method'=>'int', 'arguments'=>'array', 'bestfit'=>'bool'], 'Imagick::drawImage' => ['bool', 'draw'=>'imagickdraw'], 'Imagick::edgeImage' => ['bool', 'radius'=>'float'], 'Imagick::embossImage' => ['bool', 'radius'=>'float', 'sigma'=>'float'], 'Imagick::encipherImage' => ['bool', 'passphrase'=>'string'], 'Imagick::enhanceImage' => ['bool'], 'Imagick::equalizeImage' => ['bool'], 'Imagick::evaluateImage' => ['bool', 'op'=>'int', 'constant'=>'float', 'channel='=>'int'], 'Imagick::evaluateImages' => ['bool', 'EVALUATE_CONSTANT'=>'int'], 'Imagick::exportImagePixels' => ['list', 'x'=>'int', 'y'=>'int', 'width'=>'int', 'height'=>'int', 'map'=>'string', 'storage'=>'int'], 'Imagick::extentImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], 'Imagick::filter' => ['bool', 'ImagickKernel'=>'ImagickKernel', 'CHANNEL='=>'int'], 'Imagick::flattenImages' => ['Imagick'], 'Imagick::flipImage' => ['bool'], 'Imagick::floodFillPaintImage' => ['bool', 'fill'=>'mixed', 'fuzz'=>'float', 'target'=>'mixed', 'x'=>'int', 'y'=>'int', 'invert'=>'bool', 'channel='=>'int'], 'Imagick::flopImage' => ['bool'], 'Imagick::forwardFourierTransformimage' => ['bool', 'magnitude'=>'bool'], 'Imagick::frameImage' => ['bool', 'matte_color'=>'mixed', 'width'=>'int', 'height'=>'int', 'inner_bevel'=>'int', 'outer_bevel'=>'int'], 'Imagick::functionImage' => ['bool', 'function'=>'int', 'arguments'=>'array', 'channel='=>'int'], 'Imagick::fxImage' => ['Imagick', 'expression'=>'string', 'channel='=>'int'], 'Imagick::gammaImage' => ['bool', 'gamma'=>'float', 'channel='=>'int'], 'Imagick::gaussianBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'], 'Imagick::getColorspace' => ['Imagick::COLORSPACE_*'], 'Imagick::getCompression' => ['Imagick::COMPRESSION_*'], 'Imagick::getCompressionQuality' => ['int'], 'Imagick::getConfigureOptions' => ['string'], 'Imagick::getCopyright' => ['string'], 'Imagick::getFeatures' => ['string'], 'Imagick::getFilename' => ['string'], 'Imagick::getFont' => ['string'], 'Imagick::getFormat' => ['string'], 'Imagick::getGravity' => ['Imagick::GRAVITY_*'], 'Imagick::getHDRIEnabled' => ['int'], 'Imagick::getHomeURL' => ['string'], 'Imagick::getImage' => ['Imagick'], 'Imagick::getImageAlphaChannel' => ['bool'], 'Imagick::getImageArtifact' => ['string', 'artifact'=>'string'], 'Imagick::getImageAttribute' => ['string', 'key'=>'string'], 'Imagick::getImageBackgroundColor' => ['ImagickPixel'], 'Imagick::getImageBlob' => ['string'], 'Imagick::getImageBluePrimary' => ['array{x:float,y:float}'], 'Imagick::getImageBorderColor' => ['ImagickPixel'], 'Imagick::getImageChannelDepth' => ['int', 'channel'=>'int'], 'Imagick::getImageChannelDistortion' => ['float', 'reference'=>'imagick', 'channel'=>'int', 'metric'=>'int'], 'Imagick::getImageChannelDistortions' => ['float', 'reference'=>'imagick', 'metric'=>'int', 'channel='=>'int'], 'Imagick::getImageChannelExtrema' => ['array{minima:0|positive-int,maxima:0|positive-int}', 'channel'=>'int'], 'Imagick::getImageChannelKurtosis' => ['array{kurtosis:float,skewness:float}', 'channel='=>'int'], 'Imagick::getImageChannelMean' => ['array{mean:float,standardDeviation:float}', 'channel'=>'int'], 'Imagick::getImageChannelRange' => ['array{minima:float,maxima:float}', 'channel'=>'int'], 'Imagick::getImageChannelStatistics' => ['array{mean:float,minima:float,maxima:float,standardDeviation:float,depth:int}'], 'Imagick::getImageClipMask' => ['Imagick'], 'Imagick::getImageColormapColor' => ['ImagickPixel', 'index'=>'int'], 'Imagick::getImageColors' => ['int'], 'Imagick::getImageColorspace' => ['Imagick::COLORSPACE_*'], 'Imagick::getImageCompose' => ['Imagick::COMPOSITE_*'], 'Imagick::getImageCompression' => ['Imagick::COMPRESSION_*'], 'Imagick::getImageCompressionQuality' => ['int'], 'Imagick::getImageDelay' => ['int'], 'Imagick::getImageDepth' => ['int'], 'Imagick::getImageDispose' => ['Imagick::DISPOSE_*'], 'Imagick::getImageDistortion' => ['float', 'reference'=>'magickwand', 'metric'=>'int'], 'Imagick::getImageExtrema' => ['array{min:0|positive-int,max:0|positive-int}'], 'Imagick::getImageFilename' => ['string'], 'Imagick::getImageFormat' => ['string'], 'Imagick::getImageGamma' => ['float'], 'Imagick::getImageGeometry' => ['array{width:int,height:int}'], 'Imagick::getImageGravity' => ['Imagick::GRAVITY_*'], 'Imagick::getImageGreenPrimary' => ['array{x:float,y:float}'], 'Imagick::getImageHeight' => ['int'], 'Imagick::getImageHistogram' => ['list'], 'Imagick::getImageIndex' => ['int'], 'Imagick::getImageInterlaceScheme' => ['Imagick::INTERLACE_*'], 'Imagick::getImageInterpolateMethod' => ['Imagick::INTERPOLATE_*'], 'Imagick::getImageIterations' => ['int'], 'Imagick::getImageLength' => ['0|positive-int'], 'Imagick::getImageMagickLicense' => ['string'], 'Imagick::getImageMatte' => ['bool'], 'Imagick::getImageMatteColor' => ['ImagickPixel'], 'Imagick::getImageMimeType' => ['non-empty-string'], 'Imagick::getImageOrientation' => ['Imagick::ORIENTATION_*'], 'Imagick::getImagePage' => ['array{width:int,height:int,x:int,y:int}'], 'Imagick::getImagePixelColor' => ['ImagickPixel', 'x'=>'int', 'y'=>'int'], 'Imagick::getImageProfile' => ['string', 'name'=>'string'], 'Imagick::getImageProfiles' => ['array', 'pattern='=>'string', 'only_names='=>'bool'], 'Imagick::getImageProperties' => ['array', 'pattern='=>'string', 'only_names='=>'bool'], 'Imagick::getImageProperty' => ['string', 'name'=>'string'], 'Imagick::getImageRedPrimary' => ['array{x:float,y:float}'], 'Imagick::getImageRegion' => ['Imagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], 'Imagick::getImageRenderingIntent' => ['Imagick::RENDERINGINTENT_*'], 'Imagick::getImageResolution' => ['array{x:float,y:float}'], 'Imagick::getImagesBlob' => ['string'], 'Imagick::getImageScene' => ['0|positive-int'], 'Imagick::getImageSignature' => ['string'], 'Imagick::getImageSize' => ['0|positive-int'], 'Imagick::getImageTicksPerSecond' => ['0|positive-int'], 'Imagick::getImageTotalInkDensity' => ['float'], 'Imagick::getImageType' => ['Imagick::IMGTYPE_*'], 'Imagick::getImageUnits' => ['int'], 'Imagick::getImageVirtualPixelMethod' => ['int'], 'Imagick::getImageWhitePoint' => ['array{x:float,y:float}'], 'Imagick::getImageWidth' => ['0|positive-int'], 'Imagick::getInterlaceScheme' => ['Imagick::INTERLACE_*'], 'Imagick::getIteratorIndex' => ['int'], 'Imagick::getNumberImages' => ['0|positive-int'], 'Imagick::getOption' => ['string', 'key'=>'string'], 'Imagick::getPackageName' => ['string'], 'Imagick::getPage' => ['array{width:int,height:int,x:int,y:int}'], 'Imagick::getPixelIterator' => ['ImagickPixelIterator'], 'Imagick::getPixelRegionIterator' => ['ImagickPixelIterator', 'x'=>'int', 'y'=>'int', 'columns'=>'int', 'rows'=>'int'], 'Imagick::getPointSize' => ['float'], 'Imagick::getQuantum' => ['0|positive-int'], 'Imagick::getQuantumDepth' => ['array{quantumDepthLong:0|positive-int,quantumDepthString:numeric-string}'], 'Imagick::getQuantumRange' => ['array{quantumRangeLong:0|positive-int,quantumRangeString:numeric-string}'], 'Imagick::getRegistry' => ['string', 'key'=>'string'], 'Imagick::getReleaseDate' => ['string'], 'Imagick::getResource' => ['int', 'type'=>'int'], 'Imagick::getResourceLimit' => ['int', 'type'=>'int'], 'Imagick::getSamplingFactors' => ['list'], 'Imagick::getSize' => ['array{columns:0|positive-int,rows:0|positive-int}'], 'Imagick::getSizeOffset' => ['int'], 'Imagick::getVersion' => ['array{versionNumber:0|positive-int,versionString:non-falsy-string}'], 'Imagick::haldClutImage' => ['bool', 'clut'=>'imagick', 'channel='=>'int'], 'Imagick::hasNextImage' => ['bool'], 'Imagick::hasPreviousImage' => ['bool'], 'Imagick::identifyFormat' => ['string|false', 'embedText'=>'string'], 'Imagick::identifyImage' => ['array{imageName:string,mimetype:string,format:string,units:string,colorSpace:string,type:string,compression:string,fileSize:string,geometry:array{width:0|positive-int,height:0|positive-int},resolution:array{x:float,y:float},signature:string}', 'appendrawoutput='=>'bool'], 'Imagick::identifyImageType' => ['int'], 'Imagick::implodeImage' => ['bool', 'radius'=>'float'], 'Imagick::importImagePixels' => ['bool', 'x'=>'int', 'y'=>'int', 'width'=>'int', 'height'=>'int', 'map'=>'string', 'storage'=>'int', 'pixels'=>'array'], 'Imagick::inverseFourierTransformImage' => ['bool', 'complement'=>'Imagick', 'magnitude'=>'bool'], 'Imagick::key' => ['int|string'], 'Imagick::labelImage' => ['bool', 'label'=>'string'], 'Imagick::levelImage' => ['bool', 'blackpoint'=>'float', 'gamma'=>'float', 'whitepoint'=>'float', 'channel='=>'int'], 'Imagick::linearStretchImage' => ['bool', 'blackpoint'=>'float', 'whitepoint'=>'float'], 'Imagick::liquidRescaleImage' => ['bool', 'width'=>'int', 'height'=>'int', 'delta_x'=>'float', 'rigidity'=>'float'], 'Imagick::listRegistry' => ['array'], 'Imagick::localContrastImage' => ['bool', 'radius'=>'float', 'strength'=>'float'], 'Imagick::magnifyImage' => ['bool'], 'Imagick::mapImage' => ['bool', 'map'=>'imagick', 'dither'=>'bool'], 'Imagick::matteFloodfillImage' => ['bool', 'alpha'=>'float', 'fuzz'=>'float', 'bordercolor'=>'mixed', 'x'=>'int', 'y'=>'int'], 'Imagick::medianFilterImage' => ['bool', 'radius'=>'float'], 'Imagick::mergeImageLayers' => ['Imagick', 'layer_method'=>'int'], 'Imagick::minifyImage' => ['bool'], 'Imagick::modulateImage' => ['bool', 'brightness'=>'float', 'saturation'=>'float', 'hue'=>'float'], 'Imagick::montageImage' => ['Imagick', 'draw'=>'imagickdraw', 'tile_geometry'=>'string', 'thumbnail_geometry'=>'string', 'mode'=>'int', 'frame'=>'string'], 'Imagick::morphImages' => ['Imagick', 'number_frames'=>'int'], 'Imagick::morphology' => ['bool', 'morphologyMethod'=>'int', 'iterations'=>'int', 'ImagickKernel'=>'ImagickKernel', 'channel='=>'int'], 'Imagick::mosaicImages' => ['Imagick'], 'Imagick::motionBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'angle'=>'float', 'channel='=>'int'], 'Imagick::negateImage' => ['bool', 'gray'=>'bool', 'channel='=>'int'], 'Imagick::newImage' => ['bool', 'cols'=>'int', 'rows'=>'int', 'background'=>'mixed', 'format='=>'string'], 'Imagick::newPseudoImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'pseudostring'=>'string'], 'Imagick::next' => ['void'], 'Imagick::nextImage' => ['bool'], 'Imagick::normalizeImage' => ['bool', 'channel='=>'int'], 'Imagick::oilPaintImage' => ['bool', 'radius'=>'float'], 'Imagick::opaquePaintImage' => ['bool', 'target'=>'mixed', 'fill'=>'mixed', 'fuzz'=>'float', 'invert'=>'bool', 'channel='=>'int'], 'Imagick::optimizeImageLayers' => ['bool'], 'Imagick::orderedPosterizeImage' => ['bool', 'threshold_map'=>'string', 'channel='=>'int'], 'Imagick::paintFloodfillImage' => ['bool', 'fill'=>'mixed', 'fuzz'=>'float', 'bordercolor'=>'mixed', 'x'=>'int', 'y'=>'int', 'channel='=>'int'], 'Imagick::paintOpaqueImage' => ['bool', 'target'=>'mixed', 'fill'=>'mixed', 'fuzz'=>'float', 'channel='=>'int'], 'Imagick::paintTransparentImage' => ['bool', 'target'=>'mixed', 'alpha'=>'float', 'fuzz'=>'float'], 'Imagick::pingImage' => ['bool', 'filename'=>'string'], 'Imagick::pingImageBlob' => ['bool', 'image'=>'string'], 'Imagick::pingImageFile' => ['bool', 'filehandle'=>'resource', 'filename='=>'string'], 'Imagick::polaroidImage' => ['bool', 'properties'=>'imagickdraw', 'angle'=>'float'], 'Imagick::posterizeImage' => ['bool', 'levels'=>'int', 'dither'=>'bool'], 'Imagick::previewImages' => ['bool', 'preview'=>'int'], 'Imagick::previousImage' => ['bool'], 'Imagick::profileImage' => ['bool', 'name'=>'string', 'profile'=>'?string'], 'Imagick::quantizeImage' => ['bool', 'numbercolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'], 'Imagick::quantizeImages' => ['bool', 'numbercolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'], 'Imagick::queryFontMetrics' => ['array{characterWidth:float,characterHeight:float,ascender:float,descender:float,textWidth:float,textHeight:float,maxHorizontalAdvance:float,boundingBox:array{x1:float,x2:float,y1:float,y2:float},originX:float,originY:float}', 'properties'=>'imagickdraw', 'text'=>'string', 'multiline='=>'bool'], 'Imagick::queryFonts' => ['list', 'pattern='=>'string'], 'Imagick::queryFormats' => ['list', 'pattern='=>'string'], 'Imagick::radialBlurImage' => ['bool', 'angle'=>'float', 'channel='=>'int'], 'Imagick::raiseImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int', 'raise'=>'bool'], 'Imagick::randomThresholdImage' => ['bool', 'low'=>'float', 'high'=>'float', 'channel='=>'int'], 'Imagick::readImage' => ['bool', 'filename'=>'string'], 'Imagick::readImageBlob' => ['bool', 'image'=>'string', 'filename='=>'string'], 'Imagick::readImageFile' => ['bool', 'filehandle'=>'resource', 'filename='=>'string'], 'Imagick::readImages' => ['Imagick', 'filenames'=>'string'], 'Imagick::recolorImage' => ['bool', 'matrix'=>'array'], 'Imagick::reduceNoiseImage' => ['bool', 'radius'=>'float'], 'Imagick::remapImage' => ['bool', 'replacement'=>'imagick', 'dither'=>'int'], 'Imagick::removeImage' => ['bool'], 'Imagick::removeImageProfile' => ['string', 'name'=>'string'], 'Imagick::render' => ['bool'], 'Imagick::resampleImage' => ['bool', 'x_resolution'=>'float', 'y_resolution'=>'float', 'filter'=>'int', 'blur'=>'float'], 'Imagick::resetImagePage' => ['bool', 'page'=>'string'], 'Imagick::resetIterator' => [''], 'Imagick::resizeImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'filter'=>'int', 'blur'=>'float', 'bestfit='=>'bool'], 'Imagick::rewind' => ['void'], 'Imagick::rollImage' => ['bool', 'x'=>'int', 'y'=>'int'], 'Imagick::rotateImage' => ['bool', 'background'=>'mixed', 'degrees'=>'float'], 'Imagick::rotationalBlurImage' => ['bool', 'float'=>'string', 'channel='=>'int'], 'Imagick::roundCorners' => ['bool', 'x_rounding'=>'float', 'y_rounding'=>'float', 'stroke_width='=>'float', 'displace='=>'float', 'size_correction='=>'float'], 'Imagick::roundCornersImage' => ['bool', 'x_rounding'=>'', 'y_rounding'=>'', 'stroke_width='=>'', 'displace='=>'', 'size_correction='=>''], 'Imagick::sampleImage' => ['bool', 'columns'=>'int', 'rows'=>'int'], 'Imagick::scaleImage' => ['bool', 'cols'=>'int', 'rows'=>'int', 'bestfit='=>'bool', 'legacy='=>'bool'], 'Imagick::segmentImage' => ['bool', 'colorspace'=>'int', 'cluster_threshold'=>'float', 'smooth_threshold'=>'float', 'verbose='=>'bool'], 'Imagick::selectiveBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'threshold'=>'float', 'channel='=>'int'], 'Imagick::separateImageChannel' => ['bool', 'channel'=>'int'], 'Imagick::sepiaToneImage' => ['bool', 'threshold'=>'float'], 'Imagick::setAntiAlias' => ['int', 'antialias'=>'bool'], 'Imagick::setBackgroundColor' => ['bool', 'background'=>'mixed'], 'Imagick::setColorspace' => ['bool', 'colorspace'=>'int'], 'Imagick::setCompression' => ['bool', 'compression'=>'int'], 'Imagick::setCompressionQuality' => ['bool', 'quality'=>'int'], 'Imagick::setFilename' => ['bool', 'filename'=>'string'], 'Imagick::setFirstIterator' => ['bool'], 'Imagick::setFont' => ['bool', 'font'=>'string'], 'Imagick::setFormat' => ['bool', 'format'=>'string'], 'Imagick::setGravity' => ['bool', 'gravity'=>'int'], 'Imagick::setImage' => ['bool', 'replace'=>'imagick'], 'Imagick::setImageAlpha' => ['bool', 'alpha'=>'float'], 'Imagick::setImageAlphaChannel' => ['bool', 'mode'=>'int'], 'Imagick::setImageArtifact' => ['bool', 'artifact'=>'string', 'value'=>'string'], 'Imagick::setImageAttribute' => ['bool', 'key'=>'string', 'value'=>'string'], 'Imagick::setImageBackgroundColor' => ['bool', 'background'=>'mixed'], 'Imagick::setImageBias' => ['bool', 'bias'=>'float'], 'Imagick::setImageBiasQuantum' => ['void', 'bias'=>'string'], 'Imagick::setImageBluePrimary' => ['bool', 'x'=>'float', 'y'=>'float'], 'Imagick::setImageBorderColor' => ['bool', 'border'=>'mixed'], 'Imagick::setImageChannelDepth' => ['bool', 'channel'=>'int', 'depth'=>'int'], 'Imagick::setImageChannelMask' => ['', 'channel'=>'int'], 'Imagick::setImageClipMask' => ['bool', 'clip_mask'=>'imagick'], 'Imagick::setImageColormapColor' => ['bool', 'index'=>'int', 'color'=>'imagickpixel'], 'Imagick::setImageColorspace' => ['bool', 'colorspace'=>'int'], 'Imagick::setImageCompose' => ['bool', 'compose'=>'int'], 'Imagick::setImageCompression' => ['bool', 'compression'=>'int'], 'Imagick::setImageCompressionQuality' => ['bool', 'quality'=>'int'], 'Imagick::setImageDelay' => ['bool', 'delay'=>'int'], 'Imagick::setImageDepth' => ['bool', 'depth'=>'int'], 'Imagick::setImageDispose' => ['bool', 'dispose'=>'int'], 'Imagick::setImageExtent' => ['bool', 'columns'=>'int', 'rows'=>'int'], 'Imagick::setImageFilename' => ['bool', 'filename'=>'string'], 'Imagick::setImageFormat' => ['bool', 'format'=>'string'], 'Imagick::setImageGamma' => ['bool', 'gamma'=>'float'], 'Imagick::setImageGravity' => ['bool', 'gravity'=>'int'], 'Imagick::setImageGreenPrimary' => ['bool', 'x'=>'float', 'y'=>'float'], 'Imagick::setImageIndex' => ['bool', 'index'=>'int'], 'Imagick::setImageInterlaceScheme' => ['bool', 'interlace_scheme'=>'int'], 'Imagick::setImageInterpolateMethod' => ['bool', 'method'=>'int'], 'Imagick::setImageIterations' => ['bool', 'iterations'=>'int'], 'Imagick::setImageMatte' => ['bool', 'matte'=>'bool'], 'Imagick::setImageMatteColor' => ['bool', 'matte'=>'mixed'], 'Imagick::setImageOpacity' => ['bool', 'opacity'=>'float'], 'Imagick::setImageOrientation' => ['bool', 'orientation'=>'int'], 'Imagick::setImagePage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], 'Imagick::setImageProfile' => ['bool', 'name'=>'string', 'profile'=>'string'], 'Imagick::setImageProgressMonitor' => ['', 'filename'=>''], 'Imagick::setImageProperty' => ['bool', 'name'=>'string', 'value'=>'string'], 'Imagick::setImageRedPrimary' => ['bool', 'x'=>'float', 'y'=>'float'], 'Imagick::setImageRenderingIntent' => ['bool', 'rendering_intent'=>'int'], 'Imagick::setImageResolution' => ['bool', 'x_resolution'=>'float', 'y_resolution'=>'float'], 'Imagick::setImageScene' => ['bool', 'scene'=>'int'], 'Imagick::setImageTicksPerSecond' => ['bool', 'ticks_per_second'=>'int'], 'Imagick::setImageType' => ['bool', 'image_type'=>'int'], 'Imagick::setImageUnits' => ['bool', 'units'=>'int'], 'Imagick::setImageVirtualPixelMethod' => ['bool', 'method'=>'int'], 'Imagick::setImageWhitePoint' => ['bool', 'x'=>'float', 'y'=>'float'], 'Imagick::setInterlaceScheme' => ['bool', 'interlace_scheme'=>'int'], 'Imagick::setIteratorIndex' => ['bool', 'index'=>'int'], 'Imagick::setLastIterator' => ['bool'], 'Imagick::setOption' => ['bool', 'key'=>'string', 'value'=>'string'], 'Imagick::setPage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], 'Imagick::setPointSize' => ['bool', 'point_size'=>'float'], 'Imagick::setProgressMonitor' => ['bool', 'callback'=>'callable'], 'Imagick::setRegistry' => ['bool', 'key'=>'string', 'value'=>'string'], 'Imagick::setResolution' => ['bool', 'x_resolution'=>'float', 'y_resolution'=>'float'], 'Imagick::setResourceLimit' => ['bool', 'type'=>'int', 'limit'=>'int'], 'Imagick::setSamplingFactors' => ['bool', 'factors'=>'array'], 'Imagick::setSize' => ['bool', 'columns'=>'int', 'rows'=>'int'], 'Imagick::setSizeOffset' => ['bool', 'columns'=>'int', 'rows'=>'int', 'offset'=>'int'], 'Imagick::setType' => ['bool', 'image_type'=>'int'], 'Imagick::shadeImage' => ['bool', 'gray'=>'bool', 'azimuth'=>'float', 'elevation'=>'float'], 'Imagick::shadowImage' => ['bool', 'opacity'=>'float', 'sigma'=>'float', 'x'=>'int', 'y'=>'int'], 'Imagick::sharpenImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'], 'Imagick::shaveImage' => ['bool', 'columns'=>'int', 'rows'=>'int'], 'Imagick::shearImage' => ['bool', 'background'=>'mixed', 'x_shear'=>'float', 'y_shear'=>'float'], 'Imagick::sigmoidalContrastImage' => ['bool', 'sharpen'=>'bool', 'alpha'=>'float', 'beta'=>'float', 'channel='=>'int'], 'Imagick::similarityImage' => ['Imagick', 'imagick'=>'Imagick', '&bestMatch'=>'array', '&similarity'=>'float', 'similarity_threshold'=>'float', 'metric'=>'int'], 'Imagick::sketchImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'angle'=>'float'], 'Imagick::smushImages' => ['Imagick', 'stack'=>'bool', 'offset'=>'int'], 'Imagick::solarizeImage' => ['bool', 'threshold'=>'0|positive-int'], 'Imagick::sparseColorImage' => ['bool', 'sparse_method'=>'int', 'arguments'=>'array', 'channel='=>'int'], 'Imagick::spliceImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], 'Imagick::spreadImage' => ['bool', 'radius'=>'float'], 'Imagick::statisticImage' => ['bool', 'type'=>'int', 'width'=>'int', 'height'=>'int', 'channel='=>'int'], 'Imagick::steganoImage' => ['Imagick', 'watermark_wand'=>'imagick', 'offset'=>'int'], 'Imagick::stereoImage' => ['bool', 'offset_wand'=>'imagick'], 'Imagick::stripImage' => ['bool'], 'Imagick::subImageMatch' => ['Imagick', 'Imagick'=>'Imagick', '&w_offset='=>'array', '&w_similarity='=>'float'], 'Imagick::swirlImage' => ['bool', 'degrees'=>'float'], 'Imagick::textureImage' => ['Imagick', 'texture_wand'=>'imagick'], 'Imagick::thresholdImage' => ['bool', 'threshold'=>'float', 'channel='=>'int'], 'Imagick::thumbnailImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'bestfit='=>'bool', 'fill='=>'bool', 'legacy='=>'bool'], 'Imagick::tintImage' => ['bool', 'tint'=>'mixed', 'opacity'=>'mixed'], 'Imagick::transformImage' => ['Imagick', 'crop'=>'string', 'geometry'=>'string'], 'Imagick::transformImageColorspace' => ['bool', 'colorspace'=>'int'], 'Imagick::transparentPaintImage' => ['bool', 'target'=>'mixed', 'alpha'=>'float', 'fuzz'=>'float', 'invert'=>'bool'], 'Imagick::transposeImage' => ['bool'], 'Imagick::transverseImage' => ['bool'], 'Imagick::trimImage' => ['bool', 'fuzz'=>'float'], 'Imagick::uniqueImageColors' => ['bool'], 'Imagick::unsharpMaskImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'amount'=>'float', 'threshold'=>'float', 'channel='=>'int'], 'Imagick::valid' => ['bool'], 'Imagick::vignetteImage' => ['bool', 'blackpoint'=>'float', 'whitepoint'=>'float', 'x'=>'int', 'y'=>'int'], 'Imagick::waveImage' => ['bool', 'amplitude'=>'float', 'length'=>'float'], 'Imagick::whiteThresholdImage' => ['bool', 'threshold'=>'mixed'], 'Imagick::writeImage' => ['bool', 'filename='=>'string'], 'Imagick::writeImageFile' => ['bool', 'filehandle'=>'resource', 'format='=>'?string'], 'Imagick::writeImages' => ['bool', 'filename'=>'string', 'adjoin'=>'bool'], 'Imagick::writeImagesFile' => ['bool', 'filehandle'=>'resource', 'format='=>'?string'], 'ImagickDraw::__construct' => ['void'], 'ImagickDraw::affine' => ['bool', 'affine'=>'array'], 'ImagickDraw::annotation' => ['bool', 'x'=>'float', 'y'=>'float', 'text'=>'string'], 'ImagickDraw::arc' => ['bool', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float', 'sd'=>'float', 'ed'=>'float'], 'ImagickDraw::bezier' => ['bool', 'coordinates'=>'array'], 'ImagickDraw::circle' => ['bool', 'ox'=>'float', 'oy'=>'float', 'px'=>'float', 'py'=>'float'], 'ImagickDraw::clear' => ['bool'], 'ImagickDraw::clone' => ['ImagickDraw'], 'ImagickDraw::color' => ['bool', 'x'=>'float', 'y'=>'float', 'paintmethod'=>'int'], 'ImagickDraw::comment' => ['bool', 'comment'=>'string'], 'ImagickDraw::composite' => ['bool', 'compose'=>'int', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float', 'compositewand'=>'imagick'], 'ImagickDraw::destroy' => ['bool'], 'ImagickDraw::ellipse' => ['bool', 'ox'=>'float', 'oy'=>'float', 'rx'=>'float', 'ry'=>'float', 'start'=>'float', 'end'=>'float'], 'ImagickDraw::getBorderColor' => ['ImagickPixel'], 'ImagickDraw::getClipPath' => ['string'], 'ImagickDraw::getClipRule' => ['int'], 'ImagickDraw::getClipUnits' => ['int'], 'ImagickDraw::getDensity' => ['null|string'], 'ImagickDraw::getFillColor' => ['ImagickPixel'], 'ImagickDraw::getFillOpacity' => ['float'], 'ImagickDraw::getFillRule' => ['Imagick::FILLRULE_*'], 'ImagickDraw::getFont' => ['string'], 'ImagickDraw::getFontFamily' => ['string'], 'ImagickDraw::getFontResolution' => ['array'], 'ImagickDraw::getFontSize' => ['float'], 'ImagickDraw::getFontStretch' => ['Imagick::STRETCH_*'], 'ImagickDraw::getFontStyle' => ['Imagick::STYLE_*'], 'ImagickDraw::getFontWeight' => ['int'], 'ImagickDraw::getGravity' => ['Imagick::GRAVITY_*'], 'ImagickDraw::getOpacity' => ['float'], 'ImagickDraw::getStrokeAntialias' => ['bool'], 'ImagickDraw::getStrokeColor' => ['ImagickPixel'], 'ImagickDraw::getStrokeDashArray' => ['array'], 'ImagickDraw::getStrokeDashOffset' => ['float'], 'ImagickDraw::getStrokeLineCap' => ['Imagick::LINECAP_*'], 'ImagickDraw::getStrokeLineJoin' => ['Imagick::LINEJOIN_*'], 'ImagickDraw::getStrokeMiterLimit' => ['int'], 'ImagickDraw::getStrokeOpacity' => ['float'], 'ImagickDraw::getStrokeWidth' => ['float'], 'ImagickDraw::getTextAlignment' => ['Imagick::ALIGN_*'], 'ImagickDraw::getTextAntialias' => ['bool'], 'ImagickDraw::getTextDecoration' => ['Imagick::DECORATION_*'], 'ImagickDraw::getTextDirection' => ['bool'], 'ImagickDraw::getTextEncoding' => ['string'], 'ImagickDraw::getTextInterlineSpacing' => ['float'], 'ImagickDraw::getTextInterwordSpacing' => ['float'], 'ImagickDraw::getTextKerning' => ['float'], 'ImagickDraw::getTextUnderColor' => ['ImagickPixel'], 'ImagickDraw::getVectorGraphics' => ['string'], 'ImagickDraw::line' => ['bool', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float'], 'ImagickDraw::matte' => ['bool', 'x'=>'float', 'y'=>'float', 'paintmethod'=>'int'], 'ImagickDraw::pathClose' => ['bool'], 'ImagickDraw::pathCurveToAbsolute' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathCurveToQuadraticBezierAbsolute' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathCurveToQuadraticBezierRelative' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathCurveToQuadraticBezierSmoothAbsolute' => ['bool', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathCurveToQuadraticBezierSmoothRelative' => ['bool', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathCurveToRelative' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathCurveToSmoothAbsolute' => ['bool', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathCurveToSmoothRelative' => ['bool', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathEllipticArcAbsolute' => ['bool', 'rx'=>'float', 'ry'=>'float', 'x_axis_rotation'=>'float', 'large_arc_flag'=>'bool', 'sweep_flag'=>'bool', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathEllipticArcRelative' => ['bool', 'rx'=>'float', 'ry'=>'float', 'x_axis_rotation'=>'float', 'large_arc_flag'=>'bool', 'sweep_flag'=>'bool', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathFinish' => ['bool'], 'ImagickDraw::pathLineToAbsolute' => ['bool', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathLineToHorizontalAbsolute' => ['bool', 'x'=>'float'], 'ImagickDraw::pathLineToHorizontalRelative' => ['bool', 'x'=>'float'], 'ImagickDraw::pathLineToRelative' => ['bool', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathLineToVerticalAbsolute' => ['bool', 'y'=>'float'], 'ImagickDraw::pathLineToVerticalRelative' => ['bool', 'y'=>'float'], 'ImagickDraw::pathMoveToAbsolute' => ['bool', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathMoveToRelative' => ['bool', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::pathStart' => ['bool'], 'ImagickDraw::point' => ['bool', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::polygon' => ['bool', 'coordinates'=>'array'], 'ImagickDraw::polyline' => ['bool', 'coordinates'=>'array'], 'ImagickDraw::pop' => ['bool'], 'ImagickDraw::popClipPath' => ['bool'], 'ImagickDraw::popDefs' => ['bool'], 'ImagickDraw::popPattern' => ['bool'], 'ImagickDraw::push' => ['bool'], 'ImagickDraw::pushClipPath' => ['bool', 'clip_mask_id'=>'string'], 'ImagickDraw::pushDefs' => ['bool'], 'ImagickDraw::pushPattern' => ['bool', 'pattern_id'=>'string', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'], 'ImagickDraw::rectangle' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float'], 'ImagickDraw::render' => ['bool'], 'ImagickDraw::resetVectorGraphics' => ['void'], 'ImagickDraw::rotate' => ['bool', 'degrees'=>'float'], 'ImagickDraw::roundRectangle' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'rx'=>'float', 'ry'=>'float'], 'ImagickDraw::scale' => ['bool', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::setBorderColor' => ['bool', 'color'=>'ImagickPixel|string'], 'ImagickDraw::setClipPath' => ['bool', 'clip_mask'=>'string'], 'ImagickDraw::setClipRule' => ['bool', 'fill_rule'=>'int'], 'ImagickDraw::setClipUnits' => ['bool', 'clip_units'=>'int'], 'ImagickDraw::setDensity' => ['bool', 'density_string'=>'string'], 'ImagickDraw::setFillAlpha' => ['bool', 'opacity'=>'float'], 'ImagickDraw::setFillColor' => ['bool', 'fill_pixel'=>'ImagickPixel|string'], 'ImagickDraw::setFillOpacity' => ['bool', 'fillopacity'=>'float'], 'ImagickDraw::setFillPatternURL' => ['bool', 'fill_url'=>'string'], 'ImagickDraw::setFillRule' => ['bool', 'fill_rule'=>'int'], 'ImagickDraw::setFont' => ['bool', 'font_name'=>'string'], 'ImagickDraw::setFontFamily' => ['bool', 'font_family'=>'string'], 'ImagickDraw::setFontResolution' => ['bool', 'x'=>'float', 'y'=>'float'], 'ImagickDraw::setFontSize' => ['bool', 'pointsize'=>'float'], 'ImagickDraw::setFontStretch' => ['bool', 'fontstretch'=>'int'], 'ImagickDraw::setFontStyle' => ['bool', 'style'=>'int'], 'ImagickDraw::setFontWeight' => ['bool', 'font_weight'=>'int'], 'ImagickDraw::setGravity' => ['bool', 'gravity'=>'int'], 'ImagickDraw::setOpacity' => ['void', 'opacity'=>'float'], 'ImagickDraw::setResolution' => ['void', 'x_resolution'=>'float', 'y_resolution'=>'float'], 'ImagickDraw::setStrokeAlpha' => ['bool', 'opacity'=>'float'], 'ImagickDraw::setStrokeAntialias' => ['bool', 'stroke_antialias'=>'bool'], 'ImagickDraw::setStrokeColor' => ['bool', 'stroke_pixel'=>'ImagickPixel|string'], 'ImagickDraw::setStrokeDashArray' => ['bool', 'dasharray'=>'array'], 'ImagickDraw::setStrokeDashOffset' => ['bool', 'dash_offset'=>'float'], 'ImagickDraw::setStrokeLineCap' => ['bool', 'linecap'=>'int'], 'ImagickDraw::setStrokeLineJoin' => ['bool', 'linejoin'=>'int'], 'ImagickDraw::setStrokeMiterLimit' => ['bool', 'miterlimit'=>'int'], 'ImagickDraw::setStrokeOpacity' => ['bool', 'stroke_opacity'=>'float'], 'ImagickDraw::setStrokePatternURL' => ['bool', 'stroke_url'=>'string'], 'ImagickDraw::setStrokeWidth' => ['bool', 'stroke_width'=>'float'], 'ImagickDraw::setTextAlignment' => ['bool', 'alignment'=>'int'], 'ImagickDraw::setTextAntialias' => ['bool', 'antialias'=>'bool'], 'ImagickDraw::setTextDecoration' => ['bool', 'decoration'=>'int'], 'ImagickDraw::setTextDirection' => ['bool', 'direction'=>'int'], 'ImagickDraw::setTextEncoding' => ['bool', 'encoding'=>'string'], 'ImagickDraw::setTextInterlineSpacing' => ['void', 'spacing'=>'float'], 'ImagickDraw::setTextInterwordSpacing' => ['void', 'spacing'=>'float'], 'ImagickDraw::setTextKerning' => ['void', 'kerning'=>'float'], 'ImagickDraw::setTextUnderColor' => ['bool', 'under_color'=>'ImagickPixel|string'], 'ImagickDraw::setVectorGraphics' => ['bool', 'xml'=>'string'], 'ImagickDraw::setViewbox' => ['bool', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int'], 'ImagickDraw::skewX' => ['bool', 'degrees'=>'float'], 'ImagickDraw::skewY' => ['bool', 'degrees'=>'float'], 'ImagickDraw::translate' => ['bool', 'x'=>'float', 'y'=>'float'], 'ImagickKernel::addKernel' => ['void', 'ImagickKernel'=>'ImagickKernel'], 'ImagickKernel::addUnityKernel' => ['void'], 'ImagickKernel::fromBuiltin' => ['ImagickKernel', 'kernelType'=>'int', 'kernelString'=>'string'], 'ImagickKernel::fromMatrix' => ['ImagickKernel', 'matrix'=>'array', 'origin='=>'array'], 'ImagickKernel::getMatrix' => ['list>'], 'ImagickKernel::scale' => ['void', 'scale'=>'float', 'normalizeFlag'=>'int'], 'ImagickKernel::separate' => ['array'], 'ImagickPixel::__construct' => ['void', 'color='=>'string'], 'ImagickPixel::clear' => ['bool'], 'ImagickPixel::clone' => ['void'], 'ImagickPixel::destroy' => ['bool'], 'ImagickPixel::getColor' => ['array{r: int|float, g: int|float, b: int|float, a: int|float}', 'normalized='=>'0|1|2'], 'ImagickPixel::getColorAsString' => ['string'], 'ImagickPixel::getColorCount' => ['int'], 'ImagickPixel::getColorQuantum' => ['mixed'], 'ImagickPixel::getColorValue' => ['float', 'color'=>'int'], 'ImagickPixel::getColorValueQuantum' => ['mixed'], 'ImagickPixel::getHSL' => ['array'], 'ImagickPixel::getIndex' => ['int'], 'ImagickPixel::isPixelSimilar' => ['bool', 'color'=>'ImagickPixel', 'fuzz'=>'float'], 'ImagickPixel::isPixelSimilarQuantum' => ['bool', 'color'=>'string', 'fuzz='=>'string'], 'ImagickPixel::isSimilar' => ['bool', 'color'=>'imagickpixel', 'fuzz'=>'float'], 'ImagickPixel::setColor' => ['bool', 'color'=>'string'], 'ImagickPixel::setcolorcount' => ['void', 'colorCount'=>'string'], 'ImagickPixel::setColorFromPixel' => ['bool', 'srcPixel'=>'ImagickPixel'], 'ImagickPixel::setColorValue' => ['bool', 'color'=>'int', 'value'=>'float'], 'ImagickPixel::setColorValueQuantum' => ['void', 'color'=>'int', 'value'=>'mixed'], 'ImagickPixel::setHSL' => ['bool', 'hue'=>'float', 'saturation'=>'float', 'luminosity'=>'float'], 'ImagickPixel::setIndex' => ['void', 'index'=>'int'], 'ImagickPixelIterator::__construct' => ['void', 'wand'=>'imagick'], 'ImagickPixelIterator::clear' => ['bool'], 'ImagickPixelIterator::current' => ['mixed'], 'ImagickPixelIterator::destroy' => ['bool'], 'ImagickPixelIterator::getCurrentIteratorRow' => ['array'], 'ImagickPixelIterator::getIteratorRow' => ['int'], 'ImagickPixelIterator::getNextIteratorRow' => ['array'], 'ImagickPixelIterator::getpixeliterator' => ['', 'Imagick'=>'Imagick'], 'ImagickPixelIterator::getpixelregioniterator' => ['', 'Imagick'=>'Imagick', 'x'=>'', 'y'=>'', 'columns'=>'', 'rows'=>''], 'ImagickPixelIterator::getPreviousIteratorRow' => ['array'], 'ImagickPixelIterator::key' => ['int|string'], 'ImagickPixelIterator::newPixelIterator' => ['bool', 'wand'=>'imagick'], 'ImagickPixelIterator::newPixelRegionIterator' => ['bool', 'wand'=>'imagick', 'x'=>'int', 'y'=>'int', 'columns'=>'int', 'rows'=>'int'], 'ImagickPixelIterator::next' => ['void'], 'ImagickPixelIterator::resetIterator' => ['bool'], 'ImagickPixelIterator::rewind' => ['void'], 'ImagickPixelIterator::setIteratorFirstRow' => ['bool'], 'ImagickPixelIterator::setIteratorLastRow' => ['bool'], 'ImagickPixelIterator::setIteratorRow' => ['bool', 'row'=>'int'], 'ImagickPixelIterator::syncIterator' => ['bool'], 'ImagickPixelIterator::valid' => ['bool'], 'imap_8bit' => ['string|false', 'text'=>'string'], 'imap_alerts' => ['array|false'], 'imap_append' => ['bool', 'stream_id'=>'resource', 'folder'=>'string', 'message'=>'string', 'options='=>'string', 'internal_date='=>'string'], 'imap_base64' => ['string|false', 'text'=>'string'], 'imap_binary' => ['string|false', 'text'=>'string'], 'imap_body' => ['string|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'options='=>'int'], 'imap_bodystruct' => ['stdClass|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'section'=>'string'], 'imap_check' => ['stdClass|false', 'stream_id'=>'resource'], 'imap_clearflag_full' => ['bool', 'stream_id'=>'resource', 'sequence'=>'string', 'flag'=>'string', 'options='=>'int'], 'imap_close' => ['bool', 'stream_id'=>'resource', 'options='=>'int'], 'imap_create' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string'], 'imap_createmailbox' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string'], 'imap_delete' => ['bool', 'stream_id'=>'resource', 'msg_no'=>'string', 'options='=>'int'], 'imap_deletemailbox' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string'], 'imap_errors' => ['array|false'], 'imap_expunge' => ['bool', 'stream_id'=>'resource'], 'imap_fetch_overview' => ['array|false', 'stream_id'=>'resource', 'sequence'=>'string', 'options='=>'int'], 'imap_fetchbody' => ['string|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'section'=>'string', 'options='=>'int'], 'imap_fetchheader' => ['string|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'options='=>'int'], 'imap_fetchmime' => ['string|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'section'=>'string', 'options='=>'int'], 'imap_fetchstructure' => ['stdClass|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'options='=>'int'], 'imap_fetchtext' => ['string|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'options='=>'int'], 'imap_gc' => ['bool', 'stream_id'=>'resource', 'flags'=>'int'], 'imap_get_quota' => ['array|false', 'stream_id'=>'resource', 'qroot'=>'string'], 'imap_get_quotaroot' => ['array|false', 'stream_id'=>'resource', 'mbox'=>'string'], 'imap_getacl' => ['array|false', 'stream_id'=>'resource', 'mailbox'=>'string'], 'imap_getmailboxes' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string'], 'imap_getsubscribed' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string'], 'imap_header' => ['stdClass|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'from_length='=>'int', 'subject_length='=>'int', 'default_host='=>'string'], 'imap_headerinfo' => ['stdClass|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'from_length='=>'int', 'subject_length='=>'int', 'default_host='=>'string|null'], 'imap_headers' => ['array|false', 'stream_id'=>'resource'], 'imap_last_error' => ['string|false'], 'imap_list' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string'], 'imap_listmailbox' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string'], 'imap_listscan' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string', 'content'=>'string'], 'imap_listsubscribed' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string'], 'imap_lsub' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string'], 'imap_mail' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string', 'cc='=>'string', 'bcc='=>'string', 'rpath='=>'string'], 'imap_mail_compose' => ['string|false', 'envelope'=>'array', 'body'=>'array'], 'imap_mail_copy' => ['bool', 'stream_id'=>'resource', 'msglist'=>'string', 'mailbox'=>'string', 'options='=>'int'], 'imap_mail_move' => ['bool', 'stream_id'=>'resource', 'sequence'=>'string', 'mailbox'=>'string', 'options='=>'int'], 'imap_mailboxmsginfo' => ['stdClass|false', 'stream_id'=>'resource'], 'imap_mime_header_decode' => ['array|false', 'str'=>'string'], 'imap_msgno' => ['int|false', 'stream_id'=>'resource', 'unique_msg_id'=>'int'], 'imap_mutf7_to_utf8' => ['string|false', 'in'=>'string'], 'imap_num_msg' => ['int|false', 'stream_id'=>'resource'], 'imap_num_recent' => ['int|false', 'stream_id'=>'resource'], 'imap_open' => ['resource|false', 'mailbox'=>'string', 'user'=>'string', 'password'=>'string', 'options='=>'int', 'n_retries='=>'int', 'params='=>'array|null'], 'imap_ping' => ['bool', 'stream_id'=>'resource'], 'imap_qprint' => ['string|false', 'text'=>'string'], 'imap_rename' => ['bool', 'stream_id'=>'resource', 'old_name'=>'string', 'new_name'=>'string'], 'imap_renamemailbox' => ['bool', 'stream_id'=>'resource', 'old_name'=>'string', 'new_name'=>'string'], 'imap_reopen' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string', 'options='=>'int', 'n_retries='=>'int'], 'imap_rfc822_parse_adrlist' => ['array', 'address_string'=>'string', 'default_host'=>'string'], 'imap_rfc822_parse_headers' => ['stdClass', 'headers'=>'string', 'default_host='=>'string'], 'imap_rfc822_write_address' => ['string|false', 'mailbox'=>'?string', 'host'=>'?string', 'personal'=>'?string'], 'imap_savebody' => ['bool', 'stream_id'=>'resource', 'file'=>'string|resource', 'msg_no'=>'int', 'section='=>'string', 'options='=>'int'], 'imap_scan' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string', 'content'=>'string'], 'imap_scanmailbox' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string', 'content'=>'string'], 'imap_search' => ['array|false', 'stream_id'=>'resource', 'criteria'=>'string', 'options='=>'int', 'charset='=>'string'], 'imap_set_quota' => ['bool', 'stream_id'=>'resource', 'qroot'=>'string', 'mailbox_size'=>'int'], 'imap_setacl' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string', 'id'=>'string', 'rights'=>'string'], 'imap_setflag_full' => ['bool', 'stream_id'=>'resource', 'sequence'=>'string', 'flag'=>'string', 'options='=>'int'], 'imap_sort' => ['array|false', 'stream_id'=>'resource', 'criteria'=>'int', 'reverse'=>'int', 'options='=>'int', 'search_criteria='=>'string', 'charset='=>'string'], 'imap_status' => ['stdClass|false', 'stream_id'=>'resource', 'mailbox'=>'string', 'options'=>'int'], 'imap_subscribe' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string'], 'imap_thread' => ['array|false', 'stream_id'=>'resource', 'options='=>'int'], 'imap_timeout' => ['mixed', 'timeout_type'=>'int', 'timeout='=>'int'], 'imap_uid' => ['int|false', 'stream_id'=>'resource', 'msg_no'=>'int'], 'imap_undelete' => ['bool', 'stream_id'=>'resource', 'msg_no'=>'string', 'flags='=>'int'], 'imap_unsubscribe' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string'], 'imap_utf7_decode' => ['string|false', 'buf'=>'string'], 'imap_utf7_encode' => ['string', 'buf'=>'string'], 'imap_utf8' => ['string', 'mime_encoded_text'=>'string'], 'imap_utf8_to_mutf7' => ['string|false', 'in'=>'string'], 'implode' => ['string', 'glue'=>'string', 'pieces'=>'array'], 'implode\'1' => ['string', 'pieces'=>'array'], 'implode\'2' => ['string', 'pieces'=>'array', 'glue'=>'string'], 'import_request_variables' => ['bool', 'types'=>'string', 'prefix='=>'string'], 'in_array' => ['bool', 'needle'=>'mixed', 'haystack'=>'array', 'strict='=>'bool'], 'inclued_get_data' => ['array'], 'inet_ntop' => ['string|false', 'in_addr'=>'string'], 'inet_pton' => ['string|false', 'ip_address'=>'string'], 'InfiniteIterator::__construct' => ['void', 'iterator'=>'Iterator'], 'InfiniteIterator::next' => ['void'], 'inflate_add' => ['string|false', 'context'=>'resource', 'encoded_data'=>'string', 'flush_mode='=>'int'], 'inflate_get_read_len' => ['int|false', 'resource'=>'resource'], 'inflate_get_status' => ['int|false', 'resource'=>'resource'], 'inflate_init' => ['resource|false', 'encoding'=>'int', 'options='=>'array'], 'ingres_autocommit' => ['bool', 'link'=>'resource'], 'ingres_autocommit_state' => ['bool', 'link'=>'resource'], 'ingres_charset' => ['string', 'link'=>'resource'], 'ingres_close' => ['bool', 'link'=>'resource'], 'ingres_commit' => ['bool', 'link'=>'resource'], 'ingres_connect' => ['resource', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'options='=>'array'], 'ingres_cursor' => ['string', 'result'=>'resource'], 'ingres_errno' => ['int', 'link='=>'resource'], 'ingres_error' => ['string', 'link='=>'resource'], 'ingres_errsqlstate' => ['string', 'link='=>'resource'], 'ingres_escape_string' => ['string', 'link'=>'resource', 'source_string'=>'string'], 'ingres_execute' => ['bool', 'result'=>'resource', 'params='=>'array', 'types='=>'string'], 'ingres_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'], 'ingres_fetch_assoc' => ['array', 'result'=>'resource'], 'ingres_fetch_object' => ['object', 'result'=>'resource', 'result_type='=>'int'], 'ingres_fetch_proc_return' => ['int', 'result'=>'resource'], 'ingres_fetch_row' => ['array', 'result'=>'resource'], 'ingres_field_length' => ['int', 'result'=>'resource', 'index'=>'int'], 'ingres_field_name' => ['string', 'result'=>'resource', 'index'=>'int'], 'ingres_field_nullable' => ['bool', 'result'=>'resource', 'index'=>'int'], 'ingres_field_precision' => ['int', 'result'=>'resource', 'index'=>'int'], 'ingres_field_scale' => ['int', 'result'=>'resource', 'index'=>'int'], 'ingres_field_type' => ['string', 'result'=>'resource', 'index'=>'int'], 'ingres_free_result' => ['bool', 'result'=>'resource'], 'ingres_next_error' => ['bool', 'link='=>'resource'], 'ingres_num_fields' => ['int', 'result'=>'resource'], 'ingres_num_rows' => ['int', 'result'=>'resource'], 'ingres_pconnect' => ['resource', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'options='=>'array'], 'ingres_prepare' => ['mixed', 'link'=>'resource', 'query'=>'string'], 'ingres_query' => ['mixed', 'link'=>'resource', 'query'=>'string', 'params='=>'array', 'types='=>'string'], 'ingres_result_seek' => ['bool', 'result'=>'resource', 'position'=>'int'], 'ingres_rollback' => ['bool', 'link'=>'resource'], 'ingres_set_environment' => ['bool', 'link'=>'resource', 'options'=>'array'], 'ingres_unbuffered_query' => ['mixed', 'link'=>'resource', 'query'=>'string', 'params='=>'array', 'types='=>'string'], 'ini_alter' => ['string|false', 'varname'=>'string', 'newvalue'=>'string'], 'ini_get' => ['string|false', 'varname'=>'string'], 'ini_get_all' => ['array|false', 'extension='=>'?string', 'details='=>'bool'], 'ini_restore' => ['void', 'varname'=>'string'], 'ini_set' => ['string|false', 'varname'=>'string', 'newvalue'=>'string'], 'inotify_add_watch' => ['int<1,max>|false', 'inotify_instance'=>'resource', 'pathname'=>'string', 'mask'=>'int'], 'inotify_init' => ['resource'], 'inotify_queue_len' => ['int<0,max>', 'inotify_instance'=>'resource'], 'inotify_read' => ['list,mask:int<0,max>,cookie:int<0,max>,name:string}>|false', 'inotify_instance'=>'resource'], 'inotify_rm_watch' => ['bool', 'inotify_instance'=>'resource', 'watch_descriptor'=>'int'], 'intdiv' => ['int', 'numerator'=>'int', 'divisor'=>'int'], 'interface_exists' => ['bool', 'classname'=>'string', 'autoload='=>'bool'], 'intl_error_name' => ['string', 'error_code'=>'int'], 'intl_get_error_code' => ['int'], 'intl_get_error_message' => ['string'], 'intl_is_failure' => ['bool', 'error_code'=>'int'], 'IntlBreakIterator::__construct' => ['void'], 'IntlBreakIterator::createCharacterInstance' => ['IntlRuleBasedBreakIterator', 'locale='=>'string'], 'IntlBreakIterator::createCodePointInstance' => ['IntlCodePointBreakIterator'], 'IntlBreakIterator::createLineInstance' => ['IntlRuleBasedBreakIterator', 'locale='=>'string'], 'IntlBreakIterator::createSentenceInstance' => ['IntlRuleBasedBreakIterator', 'locale='=>'string'], 'IntlBreakIterator::createTitleInstance' => ['IntlRuleBasedBreakIterator', 'locale='=>'string'], 'IntlBreakIterator::createWordInstance' => ['IntlRuleBasedBreakIterator', 'locale='=>'string'], 'IntlBreakIterator::current' => ['int'], 'IntlBreakIterator::first' => ['int'], 'IntlBreakIterator::following' => ['int', 'offset'=>'int'], 'IntlBreakIterator::getErrorCode' => ['int'], 'IntlBreakIterator::getErrorMessage' => ['string'], 'IntlBreakIterator::getLocale' => ['string', 'locale_type'=>'string'], 'IntlBreakIterator::getPartsIterator' => ['IntlPartsIterator', 'key_type='=>'IntlPartsIterator::KEY_*'], 'IntlBreakIterator::getText' => ['string'], 'IntlBreakIterator::isBoundary' => ['bool', 'offset'=>'int'], 'IntlBreakIterator::last' => ['int'], 'IntlBreakIterator::next' => ['int', 'offset='=>'int'], 'IntlBreakIterator::preceding' => ['int', 'offset'=>'int'], 'IntlBreakIterator::previous' => ['int'], 'IntlBreakIterator::setText' => ['bool', 'text'=>'string'], 'intlcal_add' => ['bool', 'cal'=>'IntlCalendar', 'field'=>'int', 'amount'=>'int'], 'intlcal_after' => ['bool', 'cal'=>'IntlCalendar', 'other'=>'IntlCalendar'], 'intlcal_before' => ['bool', 'cal'=>'IntlCalendar', 'other'=>'IntlCalendar'], 'intlcal_clear' => ['bool', 'cal'=>'IntlCalendar', 'field='=>'int'], 'intlcal_create_instance' => ['IntlCalendar', 'timeZone='=>'mixed', 'locale='=>'string'], 'intlcal_equals' => ['bool', 'cal'=>'IntlCalendar', 'other'=>'IntlCalendar'], 'intlcal_field_difference' => ['int', 'cal'=>'IntlCalendar', 'when'=>'float', 'field'=>'int'], 'intlcal_from_date_time' => ['IntlCalendar', 'dateTime'=>'DateTime|string'], 'intlcal_get' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], 'intlcal_get_actual_maximum' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], 'intlcal_get_actual_minimum' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], 'intlcal_get_available_locales' => ['array'], 'intlcal_get_day_of_week_type' => ['int', 'cal'=>'IntlCalendar', 'dayOfWeek'=>'int'], 'intlcal_get_first_day_of_week' => ['int', 'cal'=>'IntlCalendar'], 'intlcal_get_greatest_minimum' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], 'intlcal_get_keyword_values_for_locale' => ['Iterator|false', 'key'=>'string', 'locale'=>'string', 'commonlyUsed'=>'bool'], 'intlcal_get_least_maximum' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], 'intlcal_get_locale' => ['string', 'cal'=>'IntlCalendar', 'localeType'=>'int'], 'intlcal_get_maximum' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], 'intlcal_get_minimal_days_in_first_week' => ['int', 'cal'=>'IntlCalendar'], 'intlcal_get_minimum' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], 'intlcal_get_now' => ['float'], 'intlcal_get_repeated_wall_time_option' => ['int', 'cal'=>'IntlCalendar'], 'intlcal_get_skipped_wall_time_option' => ['int', 'cal'=>'IntlCalendar'], 'intlcal_get_time' => ['float', 'cal'=>'IntlCalendar'], 'intlcal_get_time_zone' => ['IntlTimeZone|false', 'cal'=>'IntlCalendar'], 'intlcal_get_type' => ['string', 'cal'=>'IntlCalendar'], 'intlcal_get_weekend_transition' => ['int', 'cal'=>'IntlCalendar', 'dayOfWeek'=>'string'], 'intlcal_in_daylight_time' => ['bool', 'cal'=>'IntlCalendar'], 'intlcal_is_equivalent_to' => ['bool', 'cal'=>'IntlCalendar', 'other'=>'IntlCalendar'], 'intlcal_is_lenient' => ['bool', 'cal'=>'IntlCalendar'], 'intlcal_is_set' => ['bool', 'cal'=>'IntlCalendar', 'field'=>'int'], 'intlcal_is_weekend' => ['bool', 'cal'=>'IntlCalendar', 'date='=>'float'], 'intlcal_roll' => ['bool', 'cal'=>'IntlCalendar', 'field'=>'int', 'amountOrUpOrDown'=>'mixed'], 'intlcal_set' => ['bool', 'cal'=>'IntlCalendar', 'field'=>'int', 'value'=>'int'], 'intlcal_set\'1' => ['bool', 'cal'=>'IntlCalendar', 'year'=>'int', 'month'=>'int', 'dayOfMonth='=>'int', 'hour='=>'int', 'minute='=>'int', 'second='=>'int'], 'intlcal_set_first_day_of_week' => ['bool', 'cal'=>'IntlCalendar', 'dayOfWeek'=>'int'], 'intlcal_set_lenient' => ['bool', 'cal'=>'IntlCalendar', 'isLenient'=>'bool'], 'intlcal_set_repeated_wall_time_option' => ['bool', 'cal'=>'IntlCalendar', 'wallTimeOption'=>'int'], 'intlcal_set_skipped_wall_time_option' => ['bool', 'cal'=>'IntlCalendar', 'wallTimeOption'=>'int'], 'intlcal_set_time' => ['bool', 'cal'=>'IntlCalendar', 'date'=>'float'], 'intlcal_set_time_zone' => ['bool', 'cal'=>'IntlCalendar', 'timeZone'=>'mixed'], 'intlcal_to_date_time' => ['DateTime|false', 'cal'=>'IntlCalendar'], 'IntlCalendar::__construct' => ['void'], 'IntlCalendar::add' => ['bool', 'field'=>'int', 'amount'=>'int'], 'IntlCalendar::after' => ['bool', 'other'=>'IntlCalendar'], 'IntlCalendar::before' => ['bool', 'other'=>'IntlCalendar'], 'IntlCalendar::clear' => ['bool', 'field='=>'int'], 'IntlCalendar::createInstance' => ['IntlCalendar', 'timeZone='=>'mixed', 'locale='=>'string'], 'IntlCalendar::equals' => ['bool', 'other'=>'IntlCalendar'], 'IntlCalendar::fieldDifference' => ['int', 'when'=>'float', 'field'=>'int'], 'IntlCalendar::fromDateTime' => ['IntlCalendar', 'dateTime'=>'DateTime|string'], 'IntlCalendar::get' => ['int', 'field'=>'int'], 'IntlCalendar::getActualMaximum' => ['int', 'field'=>'int'], 'IntlCalendar::getActualMinimum' => ['int', 'field'=>'int'], 'IntlCalendar::getAvailableLocales' => ['array'], 'IntlCalendar::getDayOfWeekType' => ['int', 'dayOfWeek'=>'int'], 'IntlCalendar::getErrorCode' => ['int'], 'IntlCalendar::getErrorMessage' => ['string'], 'IntlCalendar::getFirstDayOfWeek' => ['int'], 'IntlCalendar::getGreatestMinimum' => ['int', 'field'=>'int'], 'IntlCalendar::getKeywordValuesForLocale' => ['Iterator', 'key'=>'string', 'locale'=>'string', 'commonlyUsed'=>'bool'], 'IntlCalendar::getLeastMaximum' => ['int', 'field'=>'int'], 'IntlCalendar::getLocale' => ['string', 'localeType'=>'int'], 'IntlCalendar::getMaximum' => ['int', 'field'=>'int'], 'IntlCalendar::getMinimalDaysInFirstWeek' => ['int'], 'IntlCalendar::getMinimum' => ['int', 'field'=>'int'], 'IntlCalendar::getNow' => ['float'], 'IntlCalendar::getRepeatedWallTimeOption' => ['int'], 'IntlCalendar::getSkippedWallTimeOption' => ['int'], 'IntlCalendar::getTime' => ['float'], 'IntlCalendar::getTimeZone' => ['IntlTimeZone'], 'IntlCalendar::getType' => ['string'], 'IntlCalendar::getWeekendTransition' => ['int', 'dayOfWeek'=>'string'], 'IntlCalendar::inDaylightTime' => ['bool'], 'IntlCalendar::isEquivalentTo' => ['bool', 'other'=>'IntlCalendar'], 'IntlCalendar::isLenient' => ['bool'], 'IntlCalendar::isSet' => ['bool', 'field'=>'int'], 'IntlCalendar::isWeekend' => ['bool', 'date='=>'float'], 'IntlCalendar::roll' => ['bool', 'field'=>'int', 'amountOrUpOrDown'=>'mixed'], 'IntlCalendar::set' => ['bool', 'field'=>'int', 'value'=>'int'], 'IntlCalendar::set\'1' => ['bool', 'year'=>'int', 'month'=>'int', 'dayOfMonth='=>'int', 'hour='=>'int', 'minute='=>'int', 'second='=>'int'], 'IntlCalendar::setFirstDayOfWeek' => ['bool', 'dayOfWeek'=>'int'], 'IntlCalendar::setLenient' => ['bool', 'isLenient'=>'string'], 'IntlCalendar::setMinimalDaysInFirstWeek' => ['bool', 'minimalDays'=>'int'], 'IntlCalendar::setRepeatedWallTimeOption' => ['bool', 'wallTimeOption'=>'int'], 'IntlCalendar::setSkippedWallTimeOption' => ['bool', 'wallTimeOption'=>'int'], 'IntlCalendar::setTime' => ['bool', 'date'=>'float'], 'IntlCalendar::setTimeZone' => ['bool', 'timeZone'=>'mixed'], 'IntlCalendar::toDateTime' => ['DateTime'], 'IntlChar::charAge' => ['array', 'char'=>'int|string'], 'IntlChar::charDigitValue' => ['int', 'codepoint'=>'mixed'], 'IntlChar::charDirection' => ['int', 'codepoint'=>'mixed'], 'IntlChar::charFromName' => ['int', 'name'=>'string', 'namechoice='=>'int'], 'IntlChar::charMirror' => ['mixed', 'codepoint'=>'mixed'], 'IntlChar::charName' => ['string', 'char'=>'int|string', 'namechoice='=>'int'], 'IntlChar::charType' => ['int', 'codepoint'=>'mixed'], 'IntlChar::chr' => ['string', 'codepoint'=>'mixed'], 'IntlChar::digit' => ['int', 'char'=>'int|string', 'radix='=>'int'], 'IntlChar::enumCharNames' => ['void', 'start'=>'mixed', 'limit'=>'mixed', 'callback'=>'callable', 'nameChoice='=>'int'], 'IntlChar::enumCharTypes' => ['void', 'cb='=>'callable'], 'IntlChar::foldCase' => ['int|string', 'char'=>'int|string', 'options='=>'int'], 'IntlChar::forDigit' => ['int', 'digit'=>'int', 'radix'=>'int'], 'IntlChar::getBidiPairedBracket' => ['mixed', 'codepoint'=>'mixed'], 'IntlChar::getBlockCode' => ['int', 'char'=>'int|string'], 'IntlChar::getCombiningClass' => ['int', 'codepoint'=>'mixed'], 'IntlChar::getFC_NFKC_Closure' => ['string', 'char'=>'int|string'], 'IntlChar::getIntPropertyMaxValue' => ['int', 'property'=>'int'], 'IntlChar::getIntPropertyMinValue' => ['int', 'property'=>'int'], 'IntlChar::getIntPropertyMxValue' => ['int', 'property'=>'int'], 'IntlChar::getIntPropertyValue' => ['int', 'char'=>'int|string', 'property'=>'int'], 'IntlChar::getNumericValue' => ['float', 'char'=>'int|string'], 'IntlChar::getPropertyEnum' => ['int', 'alias'=>'string'], 'IntlChar::getPropertyName' => ['string', 'property'=>'int', 'namechoice='=>'int'], 'IntlChar::getPropertyValueEnum' => ['int', 'property'=>'int', 'name'=>'string'], 'IntlChar::getPropertyValueName' => ['string', 'prop'=>'int', 'val'=>'int', 'namechoice='=>'int'], 'IntlChar::getUnicodeVersion' => ['array'], 'IntlChar::hasBinaryProperty' => ['bool', 'char'=>'int|string', 'property'=>'int'], 'IntlChar::isalnum' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isalpha' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isbase' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isblank' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::iscntrl' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isdefined' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isdigit' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isgraph' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isIDIgnorable' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isIDPart' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isIDStart' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isISOControl' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isJavaIDPart' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isJavaIDStart' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isJavaSpaceChar' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::islower' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isMirrored' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isprint' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::ispunct' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isspace' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::istitle' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isUAlphabetic' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isULowercase' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isupper' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isUUppercase' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isUWhiteSpace' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isWhitespace' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::isxdigit' => ['bool', 'codepoint'=>'mixed'], 'IntlChar::ord' => ['int', 'character'=>'mixed'], 'IntlChar::tolower' => ['mixed', 'codepoint'=>'mixed'], 'IntlChar::totitle' => ['mixed', 'codepoint'=>'mixed'], 'IntlChar::toupper' => ['mixed', 'codepoint'=>'mixed'], 'IntlCodePointBreakIterator::getLastCodePoint' => ['int'], 'IntlDateFormatter::__construct' => ['void', 'locale'=>'?string', 'datetype'=>'?int', 'timetype'=>'?int', 'timezone='=>'null|string|IntlTimeZone|DateTimeZone', 'calendar='=>'null|int|IntlCalendar', 'pattern='=>'string'], 'IntlDateFormatter::create' => ['IntlDateFormatter|null', 'locale'=>'?string', 'datetype'=>'?int', 'timetype'=>'?int', 'timezone='=>'null|string|IntlTimeZone|DateTimeZone', 'calendar='=>'int|IntlCalendar', 'pattern='=>'string'], 'IntlDateFormatter::format' => ['string|false', 'args'=>''], 'IntlDateFormatter::formatObject' => ['string|false', 'object'=>'object', 'format='=>'mixed', 'locale='=>'string'], 'IntlDateFormatter::getCalendar' => ['int|false'], 'IntlDateFormatter::getCalendarObject' => ['IntlCalendar|false|null'], 'IntlDateFormatter::getDateType' => ['int|false'], 'IntlDateFormatter::getErrorCode' => ['int'], 'IntlDateFormatter::getErrorMessage' => ['string'], 'IntlDateFormatter::getLocale' => ['string|false'], 'IntlDateFormatter::getPattern' => ['string|false'], 'IntlDateFormatter::getTimeType' => ['int|false'], 'IntlDateFormatter::getTimeZone' => ['IntlTimeZone|false'], 'IntlDateFormatter::getTimeZoneId' => ['string|false'], 'IntlDateFormatter::isLenient' => ['bool'], 'IntlDateFormatter::localtime' => ['array|false', 'text_to_parse'=>'string', '&w_parse_pos='=>'int'], 'IntlDateFormatter::parse' => ['int|float|false', 'text_to_parse'=>'string', '&w_parse_pos='=>'int'], 'IntlDateFormatter::setCalendar' => ['bool', 'calendar'=>''], 'IntlDateFormatter::setLenient' => ['void', 'lenient'=>'bool'], 'IntlDateFormatter::setPattern' => ['bool', 'pattern'=>'string'], 'IntlDateFormatter::setTimeZone' => ['bool', 'timezone'=>''], 'IntlDateFormatter::setTimeZoneId' => ['bool', 'zone'=>'string', 'fmt='=>'IntlDateFormatter'], 'IntlGregorianCalendar::getGregorianChange' => ['float'], 'IntlGregorianCalendar::isLeapYear' => ['bool', 'year'=>'int'], 'IntlGregorianCalendar::setGregorianChange' => ['bool', 'date'=>'float'], 'IntlIterator::current' => ['mixed'], 'IntlIterator::key' => ['string'], 'IntlIterator::next' => ['void'], 'IntlIterator::rewind' => ['void'], 'IntlIterator::valid' => ['bool'], 'IntlPartsIterator::current' => ['non-empty-string'], 'IntlPartsIterator::getBreakIterator' => ['IntlBreakIterator'], 'IntlRuleBasedBreakIterator::__construct' => ['void', 'rules'=>'string', 'areCompiled='=>'string'], 'IntlRuleBasedBreakIterator::createCharacterInstance' => ['IntlRuleBasedBreakIterator', 'locale'=>'string'], 'IntlRuleBasedBreakIterator::createCodePointInstance' => ['IntlCodePointBreakIterator'], 'IntlRuleBasedBreakIterator::createLineInstance' => ['IntlRuleBasedBreakIterator', 'locale'=>'string'], 'IntlRuleBasedBreakIterator::createSentenceInstance' => ['IntlRuleBasedBreakIterator', 'locale'=>'string'], 'IntlRuleBasedBreakIterator::createTitleInstance' => ['IntlRuleBasedBreakIterator', 'locale'=>'string'], 'IntlRuleBasedBreakIterator::createWordInstance' => ['IntlRuleBasedBreakIterator', 'locale'=>'string'], 'IntlRuleBasedBreakIterator::current' => ['int'], 'IntlRuleBasedBreakIterator::first' => ['int'], 'IntlRuleBasedBreakIterator::following' => ['int', 'offset'=>'int'], 'IntlRuleBasedBreakIterator::getBinaryRules' => ['string'], 'IntlRuleBasedBreakIterator::getErrorCode' => ['int'], 'IntlRuleBasedBreakIterator::getErrorMessage' => ['string'], 'IntlRuleBasedBreakIterator::getLocale' => ['string', 'locale_type'=>'string'], 'IntlRuleBasedBreakIterator::getPartsIterator' => ['IntlPartsIterator', 'key_type='=>'int'], 'IntlRuleBasedBreakIterator::getRules' => ['string'], 'IntlRuleBasedBreakIterator::getRuleStatus' => ['int'], 'IntlRuleBasedBreakIterator::getRuleStatusVec' => ['array'], 'IntlRuleBasedBreakIterator::getText' => ['string'], 'IntlRuleBasedBreakIterator::isBoundary' => ['bool', 'offset'=>'int'], 'IntlRuleBasedBreakIterator::last' => ['int'], 'IntlRuleBasedBreakIterator::next' => ['int', 'offset='=>'int'], 'IntlRuleBasedBreakIterator::preceding' => ['int', 'offset'=>'int'], 'IntlRuleBasedBreakIterator::previous' => ['int'], 'IntlRuleBasedBreakIterator::setText' => ['bool', 'text'=>'string'], 'IntlTimeZone::countEquivalentIDs' => ['int', 'zoneId'=>'string'], 'IntlTimeZone::createDefault' => ['IntlTimeZone'], 'IntlTimeZone::createEnumeration' => ['IntlIterator', 'countryOrRawOffset='=>'mixed'], 'IntlTimeZone::createTimeZone' => ['IntlTimeZone', 'zoneId'=>'string'], 'IntlTimeZone::createTimeZoneIDEnumeration' => ['IntlIterator', 'zoneType'=>'int', 'region='=>'string', 'rawOffset='=>'int'], 'IntlTimeZone::fromDateTimeZone' => ['IntlTimeZone', 'zoneId'=>'DateTimeZone'], 'IntlTimeZone::getCanonicalID' => ['string', 'zoneId'=>'string', '&w_isSystemID='=>'bool'], 'IntlTimeZone::getDisplayName' => ['string', 'isDaylight='=>'bool', 'style='=>'int', 'locale='=>'string'], 'IntlTimeZone::getDSTSavings' => ['int'], 'IntlTimeZone::getEquivalentID' => ['string', 'zoneId'=>'string', 'index'=>'int'], 'IntlTimeZone::getErrorCode' => ['int'], 'IntlTimeZone::getErrorMessage' => ['string'], 'IntlTimeZone::getGMT' => ['IntlTimeZone'], 'IntlTimeZone::getID' => ['string'], 'IntlTimeZone::getIDForWindowsID' => ['string', 'timezone'=>'string', 'region='=>'string'], 'IntlTimeZone::getOffset' => ['int', 'date'=>'float', 'local'=>'bool', '&w_rawOffset'=>'int', '&w_dstOffset'=>'int'], 'IntlTimeZone::getRawOffset' => ['int'], 'IntlTimeZone::getRegion' => ['string', 'zoneId'=>'string'], 'IntlTimeZone::getTZDataVersion' => ['string'], 'IntlTimeZone::getUnknown' => ['IntlTimeZone'], 'IntlTimeZone::getWindowsID' => ['string', 'timezone'=>'string'], 'IntlTimeZone::hasSameRules' => ['bool', 'otherTimeZone'=>'IntlTimeZone'], 'IntlTimeZone::toDateTimeZone' => ['DateTimeZone'], 'IntlTimeZone::useDaylightTime' => ['bool'], 'intltz_count_equivalent_ids' => ['int|false', 'zoneId'=>'string'], 'intltz_create_enumeration' => ['IntlIterator', 'countryOrRawOffset'=>'mixed'], 'intltz_create_time_zone' => ['IntlTimeZone', 'zoneId'=>'string'], 'intltz_from_date_time_zone' => ['IntlTimeZone', 'zoneId'=>'DateTimeZone'], 'intltz_get_canonical_id' => ['string|false', 'zoneId'=>'string', '&isSystemID'=>'bool'], 'intltz_get_display_name' => ['string|false', 'obj'=>'IntlTimeZone', 'isDaylight'=>'bool', 'style'=>'int', 'locale'=>'string'], 'intltz_get_dst_savings' => ['int', 'obj'=>'IntlTimeZone'], 'intltz_get_equivalent_id' => ['string|false', 'zoneId'=>'string', 'index'=>'int'], 'intltz_get_error_code' => ['int|false', 'obj'=>'IntlTimeZone'], 'intltz_get_error_message' => ['string|false', 'obj'=>'IntlTimeZone'], 'intltz_get_id' => ['string|false', 'obj'=>'IntlTimeZone'], 'intltz_get_offset' => ['int', 'obj'=>'IntlTimeZone', 'date'=>'float', 'local'=>'bool', '&rawOffset'=>'int', '&dstOffset'=>'int'], 'intltz_get_raw_offset' => ['int', 'obj'=>'IntlTimeZone'], 'intltz_get_tz_data_version' => ['string|false', 'obj'=>'IntlTimeZone'], 'intltz_getGMT' => ['IntlTimeZone'], 'intltz_has_same_rules' => ['bool', 'obj'=>'IntlTimeZone', 'otherTimeZone'=>'IntlTimeZone'], 'intltz_to_date_time_zone' => ['DateTimeZone|false', 'obj'=>''], 'intltz_use_daylight_time' => ['bool', 'obj'=>''], 'intlz_create_default' => ['IntlTimeZone'], 'intval' => ['int', 'var'=>'scalar|array|resource|null', 'base='=>'int'], 'InvalidArgumentException::__clone' => ['void'], 'InvalidArgumentException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?InvalidArgumentException)'], 'InvalidArgumentException::__toString' => ['string'], 'InvalidArgumentException::getCode' => ['int'], 'InvalidArgumentException::getFile' => ['string'], 'InvalidArgumentException::getLine' => ['int'], 'InvalidArgumentException::getMessage' => ['string'], 'InvalidArgumentException::getPrevious' => ['Throwable|InvalidArgumentException|null'], 'InvalidArgumentException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'InvalidArgumentException::getTraceAsString' => ['string'], 'ip2long' => ['int|false', 'ip_address'=>'string'], 'iptcembed' => ['string|bool', 'iptcdata'=>'string', 'jpeg_file_name'=>'string', 'spool='=>'int'], 'iptcparse' => ['array>|false', 'iptcdata'=>'string'], 'is_a' => ['bool', 'object_or_string'=>'object|string', 'class_name'=>'string', 'allow_string='=>'bool'], 'is_array' => ['bool', 'var'=>'mixed'], 'is_bool' => ['bool', 'var'=>'mixed'], 'is_callable' => ['bool', 'var'=>'mixed', 'syntax_only='=>'bool', '&w_callable_name='=>'string'], 'is_countable' => ['bool', 'var'=>'mixed'], 'is_dir' => ['bool', 'filename'=>'string'], 'is_double' => ['bool', 'var'=>''], 'is_executable' => ['bool', 'filename'=>'string'], 'is_file' => ['bool', 'filename'=>'string'], 'is_finite' => ['bool', 'val'=>'float'], 'is_float' => ['bool', 'var'=>'mixed'], 'is_infinite' => ['bool', 'val'=>'float'], 'is_int' => ['bool', 'var'=>'mixed'], 'is_integer' => ['bool', 'var'=>''], 'is_iterable' => ['bool', 'var'=>'mixed'], 'is_link' => ['bool', 'filename'=>'string'], 'is_long' => ['bool', 'var'=>''], 'is_nan' => ['bool', 'val'=>'float'], 'is_null' => ['bool', 'var'=>'mixed'], 'is_numeric' => ['bool', 'value'=>'mixed'], 'is_object' => ['bool', 'var'=>'mixed'], 'is_readable' => ['bool', 'filename'=>'string'], 'is_real' => ['bool', 'var'=>''], 'is_resource' => ['bool', 'var'=>'mixed'], 'is_scalar' => ['bool', 'value'=>'mixed'], 'is_soap_fault' => ['bool', 'object'=>'mixed'], 'is_string' => ['bool', 'var'=>'mixed'], 'is_subclass_of' => ['bool', 'object_or_string'=>'object|string', 'class_name'=>'string', 'allow_string='=>'bool'], 'is_tainted' => ['bool', 'string'=>'string'], 'is_uploaded_file' => ['bool', 'path'=>'string'], 'is_writable' => ['bool', 'filename'=>'string'], 'is_writeable' => ['bool', 'filename'=>'string'], 'Iterator::current' => ['mixed'], 'Iterator::key' => ['mixed'], 'Iterator::next' => ['void'], 'Iterator::rewind' => ['void'], 'Iterator::valid' => ['bool'], 'iterator_apply' => ['0|positive-int', 'iterator'=>'Traversable', 'function'=>'callable', 'params='=>'array'], 'iterator_count' => ['0|positive-int', 'iterator'=>'Traversable'], 'iterator_to_array' => ['array', 'iterator'=>'Traversable', 'use_keys='=>'bool'], 'IteratorAggregate::getIterator' => ['Traversable'], 'IteratorIterator::__construct' => ['void', 'iterator'=>'Traversable'], 'IteratorIterator::current' => ['mixed'], 'IteratorIterator::getInnerIterator' => ['Traversable'], 'IteratorIterator::key' => ['mixed'], 'IteratorIterator::next' => ['void'], 'IteratorIterator::rewind' => ['void'], 'IteratorIterator::valid' => ['bool'], 'java_last_exception_clear' => [''], 'java_last_exception_get' => ['object'], 'java_reload' => ['array', 'new_jarpath'=>'new_jarpath'], 'java_require' => ['array', 'new_classpath'=>'new_classpath'], 'java_set_encoding' => ['array', 'encoding'=>'encoding'], 'java_set_ignore_case' => ['void', 'ignore'=>'ignore'], 'java_throw_exceptions' => ['void', 'throw'=>'throw'], 'JavaException::getCause' => ['object'], 'jddayofweek' => ['mixed', 'juliandaycount'=>'int', 'mode='=>'int'], 'jdmonthname' => ['string', 'juliandaycount'=>'int', 'mode'=>'int'], 'jdtofrench' => ['string', 'juliandaycount'=>'int'], 'jdtogregorian' => ['string', 'juliandaycount'=>'int'], 'jdtojewish' => ['string', 'juliandaycount'=>'int', 'hebrew='=>'bool', 'fl='=>'int'], 'jdtojulian' => ['string', 'juliandaycount'=>'int'], 'jdtounix' => ['int|false', 'jday'=>'int'], 'jewishtojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'], 'jobqueue_license_info' => ['array'], 'join' => ['string', 'glue'=>'string', 'pieces'=>'array'], 'join\'1' => ['string', 'pieces'=>'array'], 'jpeg2wbmp' => ['bool', 'jpegname'=>'string', 'wbmpname'=>'string', 'dest_height'=>'int', 'dest_width'=>'int', 'threshold'=>'int'], 'json_decode' => ['mixed', 'json'=>'string', 'assoc='=>'bool|null', 'depth='=>'positive-int', 'options='=>'int'], 'json_encode' => ['non-empty-string|false', 'data'=>'mixed', 'options='=>'int', 'depth='=>'positive-int'], 'json_last_error' => ['JSON_ERROR_NONE|JSON_ERROR_DEPTH|JSON_ERROR_STATE_MISMATCH|JSON_ERROR_CTRL_CHAR|JSON_ERROR_SYNTAX|JSON_ERROR_UTF8|JSON_ERROR_RECURSION|JSON_ERROR_INF_OR_NAN|JSON_ERROR_UNSUPPORTED_TYPE|JSON_ERROR_INVALID_PROPERTY_NAME|JSON_ERROR_UTF16'], 'json_last_error_msg' => ['string'], 'JsonIncrementalParser::__construct' => ['void', 'depth'=>'', 'options'=>''], 'JsonIncrementalParser::get' => ['', 'options'=>''], 'JsonIncrementalParser::getError' => [''], 'JsonIncrementalParser::parse' => ['', 'json'=>''], 'JsonIncrementalParser::parseFile' => ['', 'filename'=>''], 'JsonIncrementalParser::reset' => [''], 'JsonSerializable::jsonSerialize' => ['mixed'], 'Judy::__construct' => ['void', 'judy_type'=>'int'], 'Judy::__destruct' => [''], 'Judy::byCount' => ['int', 'nth_index'=>'int'], 'Judy::count' => ['0|positive-int', 'index_start='=>'int', 'index_end='=>'int'], 'Judy::first' => ['mixed', 'index='=>'mixed'], 'Judy::firstEmpty' => ['int', 'index='=>'mixed'], 'Judy::free' => ['int'], 'Judy::getType' => ['int'], 'Judy::last' => ['void', 'index='=>'string'], 'Judy::lastEmpty' => ['int', 'index='=>'int'], 'Judy::memoryUsage' => ['int'], 'Judy::next' => ['mixed', 'index'=>'mixed'], 'Judy::nextEmpty' => ['int', 'index'=>'int'], 'Judy::offsetExists' => ['bool', 'offset'=>'mixed'], 'Judy::offsetGet' => ['mixed', 'offset'=>'mixed'], 'Judy::offsetSet' => ['bool', 'offset'=>'mixed', 'value'=>'mixed'], 'Judy::offsetUnset' => ['bool', 'offset'=>'mixed'], 'Judy::prev' => ['mixed', 'index'=>'mixed'], 'Judy::prevEmpty' => ['int', 'index'=>'mixed'], 'Judy::size' => ['void'], 'judy_type' => ['int', 'array'=>'judy'], 'judy_version' => ['string'], 'juliantojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'], 'kadm5_chpass_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'password'=>'string'], 'kadm5_create_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'password='=>'string', 'options='=>'array'], 'kadm5_delete_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string'], 'kadm5_destroy' => ['bool', 'handle'=>'resource'], 'kadm5_flush' => ['bool', 'handle'=>'resource'], 'kadm5_get_policies' => ['array', 'handle'=>'resource'], 'kadm5_get_principal' => ['array', 'handle'=>'resource', 'principal'=>'string'], 'kadm5_get_principals' => ['array', 'handle'=>'resource'], 'kadm5_init_with_password' => ['resource', 'admin_server'=>'string', 'realm'=>'string', 'principal'=>'string', 'password'=>'string'], 'kadm5_modify_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'options'=>'array'], 'key' => ['int|string|null', 'array_arg'=>'array|object'], 'key_exists' => ['bool', 'key'=>'string|int', 'search'=>'array'], 'krsort' => ['bool', '&rw_array_arg'=>'array', 'sort_flags='=>'int'], 'ksort' => ['bool', '&rw_array_arg'=>'array', 'sort_flags='=>'int'], 'KTaglib_ID3v2_AttachedPictureFrame::getDescription' => ['string'], 'KTaglib_ID3v2_AttachedPictureFrame::getMimeType' => ['string'], 'KTaglib_ID3v2_AttachedPictureFrame::getType' => ['int'], 'KTaglib_ID3v2_AttachedPictureFrame::savePicture' => ['bool', 'filename'=>'string'], 'KTaglib_ID3v2_AttachedPictureFrame::setMimeType' => ['string', 'type'=>'string'], 'KTaglib_ID3v2_AttachedPictureFrame::setPicture' => ['', 'filename'=>'string'], 'KTaglib_ID3v2_AttachedPictureFrame::setType' => ['', 'type'=>'int'], 'KTaglib_ID3v2_Frame::__toString' => ['string'], 'KTaglib_ID3v2_Frame::getSize' => ['int'], 'KTaglib_ID3v2_Tag::addFrame' => ['bool', 'frame'=>'ktaglib_id3v2_frame'], 'KTaglib_ID3v2_Tag::getFrameList' => ['array'], 'KTaglib_MPEG_AudioProperties::getBitrate' => ['int'], 'KTaglib_MPEG_AudioProperties::getChannels' => ['int'], 'KTaglib_MPEG_AudioProperties::getLayer' => ['int'], 'KTaglib_MPEG_AudioProperties::getLength' => ['int'], 'KTaglib_MPEG_AudioProperties::getSampleBitrate' => ['int'], 'KTaglib_MPEG_AudioProperties::getVersion' => ['int'], 'KTaglib_MPEG_AudioProperties::isCopyrighted' => ['bool'], 'KTaglib_MPEG_AudioProperties::isOriginal' => ['bool'], 'KTaglib_MPEG_AudioProperties::isProtectionEnabled' => ['bool'], 'KTaglib_MPEG_File::getAudioProperties' => ['KTaglib_MPEG_File'], 'KTaglib_MPEG_File::getID3v1Tag' => ['KTaglib_ID3v1_Tag', 'create='=>'bool'], 'KTaglib_MPEG_File::getID3v2Tag' => ['KTaglib_ID3v2_Tag', 'create='=>'bool'], 'KTaglib_Tag::getAlbum' => ['string'], 'KTaglib_Tag::getArtist' => ['string'], 'KTaglib_Tag::getComment' => ['string'], 'KTaglib_Tag::getGenre' => ['string'], 'KTaglib_Tag::getTitle' => ['string'], 'KTaglib_Tag::getTrack' => ['int'], 'KTaglib_Tag::getYear' => ['int'], 'KTaglib_Tag::isEmpty' => ['bool'], 'labelcacheObj::freeCache' => ['bool'], 'labelObj::__construct' => ['void'], 'labelObj::convertToString' => ['string'], 'labelObj::deleteStyle' => ['int', 'index'=>'int'], 'labelObj::free' => ['void'], 'labelObj::getBinding' => ['string', 'labelbinding'=>'mixed'], 'labelObj::getExpressionString' => ['string'], 'labelObj::getStyle' => ['styleObj', 'index'=>'int'], 'labelObj::getTextString' => ['string'], 'labelObj::moveStyleDown' => ['int', 'index'=>'int'], 'labelObj::moveStyleUp' => ['int', 'index'=>'int'], 'labelObj::removeBinding' => ['int', 'labelbinding'=>'mixed'], 'labelObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], 'labelObj::setBinding' => ['int', 'labelbinding'=>'mixed', 'value'=>'string'], 'labelObj::setExpression' => ['int', 'expression'=>'string'], 'labelObj::setText' => ['int', 'text'=>'string'], 'labelObj::updateFromString' => ['int', 'snippet'=>'string'], 'Lapack::eigenValues' => ['array', 'a'=>'array', 'left='=>'array', 'right='=>'array'], 'Lapack::identity' => ['array', 'n'=>'int'], 'Lapack::leastSquaresByFactorisation' => ['array', 'a'=>'array', 'b'=>'array'], 'Lapack::leastSquaresBySVD' => ['array', 'a'=>'array', 'b'=>'array'], 'Lapack::pseudoInverse' => ['array', 'a'=>'array'], 'Lapack::singularValues' => ['array', 'a'=>'array'], 'Lapack::solveLinearEquation' => ['array', 'a'=>'array', 'b'=>'array'], 'layerObj::addFeature' => ['int', 'shape'=>'shapeObj'], 'layerObj::applySLD' => ['int', 'sldxml'=>'string', 'namedlayer'=>'string'], 'layerObj::applySLDURL' => ['int', 'sldurl'=>'string', 'namedlayer'=>'string'], 'layerObj::clearProcessing' => ['void'], 'layerObj::close' => ['void'], 'layerObj::convertToString' => ['string'], 'layerObj::draw' => ['int', 'image'=>'imageObj'], 'layerObj::drawQuery' => ['int', 'image'=>'imageObj'], 'layerObj::free' => ['void'], 'layerObj::generateSLD' => ['string'], 'layerObj::getClass' => ['classObj', 'classIndex'=>'int'], 'layerObj::getClassIndex' => ['int', 'shape'=>'', 'classgroup'=>'', 'numclasses'=>''], 'layerObj::getExtent' => ['rectObj'], 'layerObj::getFilterString' => ['string'], 'layerObj::getGridIntersectionCoordinates' => ['array'], 'layerObj::getItems' => ['array'], 'layerObj::getMetaData' => ['int', 'name'=>'string'], 'layerObj::getNumResults' => ['int'], 'layerObj::getProcessing' => ['array'], 'layerObj::getProjection' => ['string'], 'layerObj::getResult' => ['resultObj', 'index'=>'int'], 'layerObj::getResultsBounds' => ['rectObj'], 'layerObj::getShape' => ['shapeObj', 'result'=>'resultObj'], 'layerObj::getWMSFeatureInfoURL' => ['string', 'clickX'=>'int', 'clickY'=>'int', 'featureCount'=>'int', 'infoFormat'=>'string'], 'layerObj::isVisible' => ['bool'], 'layerObj::moveclassdown' => ['int', 'index'=>'int'], 'layerObj::moveclassup' => ['int', 'index'=>'int'], 'layerObj::ms_newLayerObj' => ['layerObj', 'map'=>'mapObj', 'layer'=>'layerObj'], 'layerObj::nextShape' => ['shapeObj'], 'layerObj::open' => ['int'], 'layerObj::queryByAttributes' => ['int', 'qitem'=>'string', 'qstring'=>'string', 'mode'=>'int'], 'layerObj::queryByFeatures' => ['int', 'slayer'=>'int'], 'layerObj::queryByPoint' => ['int', 'point'=>'pointObj', 'mode'=>'int', 'buffer'=>'float'], 'layerObj::queryByRect' => ['int', 'rect'=>'rectObj'], 'layerObj::queryByShape' => ['int', 'shape'=>'shapeObj'], 'layerObj::removeClass' => ['classObj', 'index'=>'int'], 'layerObj::removeMetaData' => ['int', 'name'=>'string'], 'layerObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], 'layerObj::setConnectionType' => ['int', 'connectiontype'=>'int', 'plugin_library'=>'string'], 'layerObj::setFilter' => ['int', 'expression'=>'string'], 'layerObj::setMetaData' => ['int', 'name'=>'string', 'value'=>'string'], 'layerObj::setProjection' => ['int', 'proj_params'=>'string'], 'layerObj::setWKTProjection' => ['int', 'proj_params'=>'string'], 'layerObj::updateFromString' => ['int', 'snippet'=>'string'], 'lcfirst' => ['string', 'str'=>'string'], 'lcg_value' => ['float'], 'lchgrp' => ['bool', 'filename'=>'string', 'group'=>'string|int'], 'lchown' => ['bool', 'filename'=>'string', 'user'=>'string|int'], 'ldap_8859_to_t61' => ['string|false', 'value'=>'string'], 'ldap_add' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array', 'servercontrols='=>'array'], 'ldap_add_ext' => ['resource|false', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array', 'servercontrols='=>'array'], 'ldap_bind' => ['bool', 'link_identifier'=>'resource', 'bind_rdn='=>'string|null', 'bind_password='=>'string|null', 'serverctrls='=>'array'], 'ldap_bind_ext' => ['resource|false', 'link_identifier'=>'resource', 'bind_rdn='=>'string|null', 'bind_password='=>'string|null', 'serverctrls='=>'array'], 'ldap_close' => ['bool', 'link_identifier'=>'resource'], 'ldap_compare' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'attr'=>'string', 'value'=>'string', 'servercontrols='=>'array'], 'ldap_connect' => ['resource|false', 'host='=>'string', 'port='=>'int', 'wallet='=>'string', 'wallet_passwd='=>'string', 'authmode='=>'int'], 'ldap_control_paged_result' => ['bool', 'link_identifier'=>'resource', 'pagesize'=>'int', 'iscritical='=>'bool', 'cookie='=>'string'], 'ldap_control_paged_result_response' => ['bool', 'link_identifier'=>'resource', 'result_identifier'=>'resource', '&w_cookie='=>'string', '&w_estimated='=>'int'], 'ldap_count_entries' => ['int', 'link_identifier'=>'resource', 'result'=>'resource'], 'ldap_delete' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'servercontrols='=>'array'], 'ldap_delete_ext' => ['resource|false', 'link_identifier'=>'resource', 'dn'=>'string', 'servercontrols='=>'array'], 'ldap_dn2ufn' => ['string|false', 'dn'=>'string'], 'ldap_err2str' => ['string', 'errno'=>'int'], 'ldap_errno' => ['int', 'link_identifier'=>'resource'], 'ldap_error' => ['string', 'link_identifier'=>'resource'], 'ldap_escape' => ['string', 'value'=>'string', 'ignore='=>'string', 'flags='=>'int'], 'ldap_exop' => ['resource|bool', 'link'=>'resource', 'reqoid'=>'string', 'reqdata='=>'string', 'serverctrls='=>'array|null', '&w_retdata='=>'string', '&w_retoid='=>'string'], 'ldap_exop_passwd' => ['string|bool', 'link'=>'resource', 'user='=>'string', 'oldpw='=>'string', 'newpw='=>'string', 'serverctrls='=>'array'], 'ldap_exop_refresh' => ['int|false', 'link'=>'resource', 'dn'=>'string', 'ttl'=>'int'], 'ldap_exop_whoami' => ['string|bool', 'link'=>'resource'], 'ldap_explode_dn' => ['array|false', 'dn'=>'string', 'with_attrib'=>'int'], 'ldap_first_attribute' => ['string|false', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource'], 'ldap_first_entry' => ['resource|false', 'link_identifier'=>'resource', 'result_identifier'=>'resource'], 'ldap_first_reference' => ['resource|false', 'link_identifier'=>'resource', 'result_identifier'=>'resource'], 'ldap_free_result' => ['bool', 'result_identifier'=>'resource'], 'ldap_get_attributes' => ['array', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource'], 'ldap_get_dn' => ['string|false', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource'], 'ldap_get_entries' => ['array|false', 'link_identifier'=>'resource', 'result_identifier'=>'resource'], 'ldap_get_option' => ['bool', 'link_identifier'=>'resource', 'option'=>'int', '&w_retval'=>'mixed'], 'ldap_get_values' => ['array|false', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource', 'attribute'=>'string'], 'ldap_get_values_len' => ['array|false', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource', 'attribute'=>'string'], 'ldap_list' => ['resource|false', 'link'=>'resource|array', 'base_dn'=>'string', 'filter'=>'string', 'attrs='=>'array', 'attrsonly='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int', 'servercontrols='=>'array'], 'ldap_mod_add' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array', 'servercontrols='=>'array'], 'ldap_mod_add_ext' => ['resource|false', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array', 'servercontrols='=>'array'], 'ldap_mod_del' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array', 'servercontrols='=>'array'], 'ldap_mod_del_ext' => ['resource|false', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array', 'servercontrols='=>'array'], 'ldap_mod_replace' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array', 'servercontrols='=>'array'], 'ldap_mod_replace_ext' => ['resource|false', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array', 'servercontrols='=>'array'], 'ldap_modify' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array'], 'ldap_modify_batch' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'modifs'=>'array', 'servercontrols='=>'array'], 'ldap_next_attribute' => ['string|false', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource'], 'ldap_next_entry' => ['resource|false', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource'], 'ldap_next_reference' => ['resource|false', 'link_identifier'=>'resource', 'reference_entry_identifier'=>'resource'], 'ldap_parse_exop' => ['bool', 'link'=>'resource', 'result'=>'resource', '&w_retdata='=>'string', '&w_retoid='=>'string'], 'ldap_parse_reference' => ['bool', 'link_identifier'=>'resource', 'reference_entry_identifier'=>'resource', 'referrals'=>'array'], 'ldap_parse_result' => ['bool', 'link_identifier'=>'resource', 'result'=>'resource', '&w_errcode'=>'int', '&w_matcheddn='=>'string', '&w_errmsg='=>'string', '&w_referrals='=>'array', '&w_serverctrls='=>'array'], 'ldap_read' => ['resource|false', 'link'=>'resource|array', 'base_dn'=>'string', 'filter'=>'string', 'attrs='=>'array', 'attrsonly='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int', 'servercontrols='=>'array'], 'ldap_rename' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'newrdn'=>'string', 'newparent'=>'string', 'deleteoldrdn'=>'bool', 'servercontrols='=>'array'], 'ldap_rename_ext' => ['resource|false', 'link_identifier'=>'resource', 'dn'=>'string', 'newrdn'=>'string', 'newparent'=>'string', 'deleteoldrdn'=>'bool', 'servercontrols='=>'array'], 'ldap_sasl_bind' => ['bool', 'link_identifier'=>'resource', 'binddn='=>'string', 'password='=>'string', 'sasl_mech='=>'string', 'sasl_realm='=>'string', 'sasl_authc_id='=>'string', 'sasl_authz_id='=>'string', 'props='=>'string'], 'ldap_search' => ['resource|false', 'link_identifier'=>'resource|array', 'base_dn'=>'string', 'filter'=>'string', 'attrs='=>'array', 'attrsonly='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int', 'servercontrols='=>'array'], 'ldap_set_option' => ['bool', 'link_identifier'=>'resource|null', 'option'=>'int', 'newval'=>'mixed'], 'ldap_set_rebind_proc' => ['bool', 'link_identifier'=>'resource', 'callback'=>'callable'], 'ldap_sort' => ['bool', 'link_identifier'=>'resource', 'result_identifier'=>'resource', 'sortfilter'=>'string'], 'ldap_start_tls' => ['bool', 'link_identifier'=>'resource'], 'ldap_t61_to_8859' => ['string|false', 'value'=>'string'], 'ldap_unbind' => ['bool', 'link_identifier'=>'resource'], 'leak' => ['', 'num_bytes'=>'int'], 'leak_variable' => ['', 'variable'=>'', 'leak_data'=>'bool'], 'legendObj::convertToString' => ['string'], 'legendObj::free' => ['void'], 'legendObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], 'legendObj::updateFromString' => ['int', 'snippet'=>'string'], 'LengthException::__clone' => ['void'], 'LengthException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?LengthException)'], 'LengthException::__toString' => ['string'], 'LengthException::getCode' => ['int'], 'LengthException::getFile' => ['string'], 'LengthException::getLine' => ['int'], 'LengthException::getMessage' => ['string'], 'LengthException::getPrevious' => ['Throwable|LengthException|null'], 'LengthException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'LengthException::getTraceAsString' => ['string'], 'levenshtein' => ['int', 'str1'=>'string', 'str2'=>'string'], 'levenshtein\'1' => ['int', 'str1'=>'string', 'str2'=>'string', 'cost_ins'=>'int', 'cost_rep'=>'int', 'cost_del'=>'int'], 'libxml_clear_errors' => ['void'], 'libxml_disable_entity_loader' => ['bool', 'disable='=>'bool'], 'libxml_get_errors' => ['array'], 'libxml_get_last_error' => ['LibXMLError|false'], 'libxml_set_external_entity_loader' => ['bool', 'resolver_function'=>'callable'], 'libxml_set_streams_context' => ['void', 'streams_context'=>'resource'], 'libxml_use_internal_errors' => ['bool', 'use_errors='=>'bool'], 'LimitIterator::__construct' => ['void', 'iterator'=>'Iterator', 'offset='=>'int', 'count='=>'int'], 'LimitIterator::current' => ['mixed'], 'LimitIterator::getInnerIterator' => ['Iterator'], 'LimitIterator::getPosition' => ['int'], 'LimitIterator::key' => ['mixed'], 'LimitIterator::next' => ['void'], 'LimitIterator::rewind' => ['void'], 'LimitIterator::seek' => ['int', 'position'=>'int'], 'LimitIterator::valid' => ['bool'], 'lineObj::__construct' => ['void'], 'lineObj::add' => ['int', 'point'=>'pointObj'], 'lineObj::addXY' => ['int', 'x'=>'float', 'y'=>'float', 'm'=>'float'], 'lineObj::addXYZ' => ['int', 'x'=>'float', 'y'=>'float', 'z'=>'float', 'm'=>'float'], 'lineObj::ms_newLineObj' => ['lineObj'], 'lineObj::point' => ['pointObj', 'i'=>'int'], 'lineObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'], 'link' => ['bool', 'target'=>'string', 'link'=>'string'], 'linkinfo' => ['int|false', 'filename'=>'string'], 'litespeed_request_headers' => ['array'], 'litespeed_response_headers' => ['array|false'], 'Locale::acceptFromHttp' => ['non-empty-string|false', 'header'=>'string'], 'Locale::canonicalize' => ['non-empty-string|null', 'locale'=>'string'], 'Locale::composeLocale' => ['string|false', 'subtags'=>'array'], 'Locale::filterMatches' => ['bool|null', 'langtag'=>'string', 'locale'=>'string', 'canonicalize='=>'bool'], 'Locale::getAllVariants' => ['array|null', 'locale'=>'string'], 'Locale::getDefault' => ['non-empty-string'], 'Locale::getDisplayLanguage' => ['non-empty-string', 'locale'=>'string', 'displayLocale='=>'string'], 'Locale::getDisplayName' => ['non-empty-string', 'locale'=>'string', 'displayLocale='=>'string'], 'Locale::getDisplayRegion' => ['non-empty-string', 'locale'=>'string', 'displayLocale='=>'string'], 'Locale::getDisplayScript' => ['string', 'locale'=>'string', 'displayLocale='=>'string'], 'Locale::getDisplayVariant' => ['string', 'locale'=>'string', 'displayLocale='=>'string'], 'Locale::getKeywords' => ['array|null', 'locale'=>'string'], 'Locale::getPrimaryLanguage' => ['non-empty-string|null', 'locale'=>'string'], 'Locale::getRegion' => ['string|null', 'locale'=>'string'], 'Locale::getScript' => ['string|null', 'locale'=>'string'], 'Locale::lookup' => ['string|null', 'languageTag'=>'array', 'locale'=>'string', 'canonicalize='=>'bool', 'defaultLocale='=>'string'], 'Locale::parseLocale' => ['array|null', 'locale'=>'string'], 'Locale::setDefault' => ['bool', 'locale'=>'string'], 'locale_accept_from_http' => ['non-empty-string|false', 'header'=>'string'], 'locale_canonicalize' => ['non-empty-string|null', 'locale'=>'string'], 'locale_compose' => ['string|false', 'subtags'=>'array'], 'locale_filter_matches' => ['bool|null', 'langtag'=>'string', 'locale'=>'string', 'canonicalize='=>'bool'], 'locale_get_all_variants' => ['array|null', 'locale'=>'string'], 'locale_get_default' => ['non-empty-string'], 'locale_get_display_language' => ['non-empty-string', 'locale'=>'string', 'displayLocale='=>'string'], 'locale_get_display_name' => ['non-empty-string', 'locale'=>'string', 'displayLocale='=>'string'], 'locale_get_display_region' => ['non-empty-string', 'locale'=>'string', 'displayLocale='=>'string'], 'locale_get_display_script' => ['string', 'locale'=>'string', 'displayLocale='=>'string'], 'locale_get_display_variant' => ['string', 'locale'=>'string', 'displayLocale='=>'string'], 'locale_get_keywords' => ['array|null', 'locale'=>'string'], 'locale_get_primary_language' => ['non-empty-string|null', 'locale'=>'string'], 'locale_get_region' => ['string|null', 'locale'=>'string'], 'locale_get_script' => ['string|null', 'locale'=>'string'], 'locale_lookup' => ['string|null', 'langtag'=>'array', 'locale'=>'string', 'canonicalize='=>'bool', 'defaultLocale='=>'string'], 'locale_parse' => ['array|null', 'locale'=>'string'], 'locale_set_default' => ['bool', 'locale'=>'string'], 'localeconv' => ['array'], 'localtime' => ['array', 'timestamp='=>'int', 'associative_array='=>'bool'], 'log' => ['float', 'number'=>'float', 'base='=>'float'], 'log10' => ['float', 'number'=>'float'], 'log1p' => ['float', 'number'=>'float'], 'LogicException::__clone' => ['void'], 'LogicException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?LogicException)'], 'LogicException::__toString' => ['string'], 'LogicException::getCode' => ['int'], 'LogicException::getFile' => ['string'], 'LogicException::getLine' => ['int'], 'LogicException::getMessage' => ['string'], 'LogicException::getPrevious' => ['Throwable|LogicException|null'], 'LogicException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'LogicException::getTraceAsString' => ['string'], 'long2ip' => ['string|false', 'proper_address'=>'int'], 'lstat' => ['array|false', 'filename'=>'string'], 'ltrim' => ['string', 'str'=>'string', 'character_mask='=>'string'], 'Lua::__call' => ['mixed', 'lua_func'=>'callable', 'args='=>'array', 'use_self='=>'int'], 'Lua::__construct' => ['void', 'lua_script_file'=>'string'], 'Lua::assign' => ['mixed', 'name'=>'string', 'value'=>'string'], 'Lua::call' => ['mixed', 'lua_func'=>'callable', 'args='=>'array', 'use_self='=>'int'], 'Lua::eval' => ['mixed', 'statements'=>'string'], 'Lua::getVersion' => ['string'], 'Lua::include' => ['mixed', 'file'=>'string'], 'Lua::registerCallback' => ['mixed', 'name'=>'string', 'function'=>'callable'], 'LuaClosure::__invoke' => ['void', 'arg'=>'mixed', '...args='=>'mixed'], 'lzf_compress' => ['string', 'data'=>'string'], 'lzf_decompress' => ['string', 'data'=>'string'], 'lzf_optimized_for' => ['int'], 'm_checkstatus' => ['int', 'conn'=>'resource', 'identifier'=>'int'], 'm_completeauthorizations' => ['int', 'conn'=>'resource', 'array'=>'int'], 'm_connect' => ['int', 'conn'=>'resource'], 'm_connectionerror' => ['string', 'conn'=>'resource'], 'm_deletetrans' => ['bool', 'conn'=>'resource', 'identifier'=>'int'], 'm_destroyconn' => ['bool', 'conn'=>'resource'], 'm_destroyengine' => ['void'], 'm_getcell' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'column'=>'string', 'row'=>'int'], 'm_getcellbynum' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'column'=>'int', 'row'=>'int'], 'm_getcommadelimited' => ['string', 'conn'=>'resource', 'identifier'=>'int'], 'm_getheader' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'column_num'=>'int'], 'm_initconn' => ['resource'], 'm_initengine' => ['int', 'location'=>'string'], 'm_iscommadelimited' => ['int', 'conn'=>'resource', 'identifier'=>'int'], 'm_maxconntimeout' => ['bool', 'conn'=>'resource', 'secs'=>'int'], 'm_monitor' => ['int', 'conn'=>'resource'], 'm_numcolumns' => ['int', 'conn'=>'resource', 'identifier'=>'int'], 'm_numrows' => ['int', 'conn'=>'resource', 'identifier'=>'int'], 'm_parsecommadelimited' => ['int', 'conn'=>'resource', 'identifier'=>'int'], 'm_responsekeys' => ['array', 'conn'=>'resource', 'identifier'=>'int'], 'm_responseparam' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'key'=>'string'], 'm_returnstatus' => ['int', 'conn'=>'resource', 'identifier'=>'int'], 'm_setblocking' => ['int', 'conn'=>'resource', 'tf'=>'int'], 'm_setdropfile' => ['int', 'conn'=>'resource', 'directory'=>'string'], 'm_setip' => ['int', 'conn'=>'resource', 'host'=>'string', 'port'=>'int'], 'm_setssl' => ['int', 'conn'=>'resource', 'host'=>'string', 'port'=>'int'], 'm_setssl_cafile' => ['int', 'conn'=>'resource', 'cafile'=>'string'], 'm_setssl_files' => ['int', 'conn'=>'resource', 'sslkeyfile'=>'string', 'sslcertfile'=>'string'], 'm_settimeout' => ['int', 'conn'=>'resource', 'seconds'=>'int'], 'm_sslcert_gen_hash' => ['string', 'filename'=>'string'], 'm_transactionssent' => ['int', 'conn'=>'resource'], 'm_transinqueue' => ['int', 'conn'=>'resource'], 'm_transkeyval' => ['int', 'conn'=>'resource', 'identifier'=>'int', 'key'=>'string', 'value'=>'string'], 'm_transnew' => ['int', 'conn'=>'resource'], 'm_transsend' => ['int', 'conn'=>'resource', 'identifier'=>'int'], 'm_uwait' => ['int', 'microsecs'=>'int'], 'm_validateidentifier' => ['int', 'conn'=>'resource', 'tf'=>'int'], 'm_verifyconnection' => ['bool', 'conn'=>'resource', 'tf'=>'int'], 'm_verifysslcert' => ['bool', 'conn'=>'resource', 'tf'=>'int'], 'magic_quotes_runtime' => ['', 'new_setting'=>''], 'mail' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string|array|null', 'additional_parameters='=>'string'], 'mailparse_determine_best_xfer_encoding' => ['string', 'fp'=>'resource'], 'mailparse_msg_create' => ['resource'], 'mailparse_msg_extract_part' => ['void', 'mimemail'=>'resource', 'msgbody'=>'string', 'callbackfunc='=>'callable'], 'mailparse_msg_extract_part_file' => ['string', 'mimemail'=>'resource', 'filename'=>'mixed', 'callbackfunc='=>'callable'], 'mailparse_msg_extract_whole_part_file' => ['string', 'mimemail'=>'resource', 'filename'=>'string', 'callbackfunc='=>'callable'], 'mailparse_msg_free' => ['bool', 'mimemail'=>'resource'], 'mailparse_msg_get_part' => ['resource|false', 'mimemail'=>'resource', 'mimesection'=>'string'], 'mailparse_msg_get_part_data' => ['array', 'mimemail'=>'resource'], 'mailparse_msg_get_structure' => ['array', 'mimemail'=>'resource'], 'mailparse_msg_parse' => ['bool', 'mimemail'=>'resource', 'data'=>'string'], 'mailparse_msg_parse_file' => ['resource', 'filename'=>'string'], 'mailparse_rfc822_parse_addresses' => ['array', 'addresses'=>'string'], 'mailparse_stream_encode' => ['bool', 'sourcefp'=>'resource', 'destfp'=>'resource', 'encoding'=>'string'], 'mailparse_uudecode_all' => ['array', 'fp'=>'resource'], 'mapObj::__construct' => ['void', 'map_file_name'=>'string', 'new_map_path'=>'string'], 'mapObj::appendOutputFormat' => ['int', 'outputFormat'=>'outputformatObj'], 'mapObj::applyconfigoptions' => ['int'], 'mapObj::applySLD' => ['int', 'sldxml'=>'string'], 'mapObj::applySLDURL' => ['int', 'sldurl'=>'string'], 'mapObj::convertToString' => ['string'], 'mapObj::draw' => ['imageObj'], 'mapObj::drawLabelCache' => ['int', 'image'=>'imageObj'], 'mapObj::drawLegend' => ['imageObj'], 'mapObj::drawQuery' => ['imageObj'], 'mapObj::drawReferenceMap' => ['imageObj'], 'mapObj::drawScaleBar' => ['imageObj'], 'mapObj::embedLegend' => ['int', 'image'=>'imageObj'], 'mapObj::embedScalebar' => ['int', 'image'=>'imageObj'], 'mapObj::free' => ['void'], 'mapObj::generateSLD' => ['string'], 'mapObj::getAllGroupNames' => ['array'], 'mapObj::getAllLayerNames' => ['array'], 'mapObj::getColorbyIndex' => ['colorObj', 'iCloIndex'=>'int'], 'mapObj::getConfigOption' => ['string', 'key'=>'string'], 'mapObj::getLabel' => ['labelcacheMemberObj', 'index'=>'int'], 'mapObj::getLayer' => ['layerObj', 'index'=>'int'], 'mapObj::getLayerByName' => ['layerObj', 'layer_name'=>'string'], 'mapObj::getLayersDrawingOrder' => ['array'], 'mapObj::getLayersIndexByGroup' => ['array', 'groupname'=>'string'], 'mapObj::getMetaData' => ['int', 'name'=>'string'], 'mapObj::getNumSymbols' => ['int'], 'mapObj::getOutputFormat' => ['outputformatObj', 'index'=>'int'], 'mapObj::getProjection' => ['string'], 'mapObj::getSymbolByName' => ['int', 'symbol_name'=>'string'], 'mapObj::getSymbolObjectById' => ['symbolObj', 'symbolid'=>'int'], 'mapObj::loadMapContext' => ['int', 'filename'=>'string', 'unique_layer_name'=>'bool'], 'mapObj::loadOWSParameters' => ['int', 'request'=>'OwsrequestObj', 'version'=>'string'], 'mapObj::moveLayerDown' => ['int', 'layerindex'=>'int'], 'mapObj::moveLayerUp' => ['int', 'layerindex'=>'int'], 'mapObj::ms_newMapObjFromString' => ['mapObj', 'map_file_string'=>'string', 'new_map_path'=>'string'], 'mapObj::offsetExtent' => ['int', 'x'=>'float', 'y'=>'float'], 'mapObj::owsDispatch' => ['int', 'request'=>'OwsrequestObj'], 'mapObj::prepareImage' => ['imageObj'], 'mapObj::prepareQuery' => ['void'], 'mapObj::processLegendTemplate' => ['string', 'params'=>'array'], 'mapObj::processQueryTemplate' => ['string', 'params'=>'array', 'generateimages'=>'bool'], 'mapObj::processTemplate' => ['string', 'params'=>'array', 'generateimages'=>'bool'], 'mapObj::queryByFeatures' => ['int', 'slayer'=>'int'], 'mapObj::queryByIndex' => ['int', 'layerindex'=>'', 'tileindex'=>'', 'shapeindex'=>'', 'addtoquery'=>''], 'mapObj::queryByPoint' => ['int', 'point'=>'pointObj', 'mode'=>'int', 'buffer'=>'float'], 'mapObj::queryByRect' => ['int', 'rect'=>'rectObj'], 'mapObj::queryByShape' => ['int', 'shape'=>'shapeObj'], 'mapObj::removeLayer' => ['layerObj', 'nIndex'=>'int'], 'mapObj::removeMetaData' => ['int', 'name'=>'string'], 'mapObj::removeOutputFormat' => ['int', 'name'=>'string'], 'mapObj::save' => ['int', 'filename'=>'string'], 'mapObj::saveMapContext' => ['int', 'filename'=>'string'], 'mapObj::saveQuery' => ['int', 'filename'=>'string', 'results'=>'int'], 'mapObj::scaleExtent' => ['int', 'zoomfactor'=>'float', 'minscaledenom'=>'float', 'maxscaledenom'=>'float'], 'mapObj::selectOutputFormat' => ['int', 'type'=>'string'], 'mapObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], 'mapObj::setCenter' => ['int', 'center'=>'pointObj'], 'mapObj::setConfigOption' => ['int', 'key'=>'string', 'value'=>'string'], 'mapObj::setExtent' => ['void', 'minx'=>'float', 'miny'=>'float', 'maxx'=>'float', 'maxy'=>'float'], 'mapObj::setFontSet' => ['int', 'fileName'=>'string'], 'mapObj::setMetaData' => ['int', 'name'=>'string', 'value'=>'string'], 'mapObj::setProjection' => ['int', 'proj_params'=>'string', 'bSetUnitsAndExtents'=>'bool'], 'mapObj::setRotation' => ['int', 'rotation_angle'=>'float'], 'mapObj::setSize' => ['int', 'width'=>'int', 'height'=>'int'], 'mapObj::setSymbolSet' => ['int', 'fileName'=>'string'], 'mapObj::setWKTProjection' => ['int', 'proj_params'=>'string', 'bSetUnitsAndExtents'=>'bool'], 'mapObj::zoomPoint' => ['int', 'nZoomFactor'=>'int', 'oPixelPos'=>'pointObj', 'nImageWidth'=>'int', 'nImageHeight'=>'int', 'oGeorefExt'=>'rectObj'], 'mapObj::zoomRectangle' => ['int', 'oPixelExt'=>'rectObj', 'nImageWidth'=>'int', 'nImageHeight'=>'int', 'oGeorefExt'=>'rectObj'], 'mapObj::zoomScale' => ['int', 'nScaleDenom'=>'float', 'oPixelPos'=>'pointObj', 'nImageWidth'=>'int', 'nImageHeight'=>'int', 'oGeorefExt'=>'rectObj', 'oMaxGeorefExt'=>'rectObj'], 'max' => ['', '...arg1'=>'array'], 'max\'1' => ['', 'arg1'=>'', 'arg2'=>'', '...args='=>''], 'maxdb::__construct' => ['void', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'], 'maxdb::affected_rows' => ['int', 'link'=>''], 'maxdb::auto_commit' => ['bool', 'link'=>'', 'mode'=>'bool'], 'maxdb::change_user' => ['bool', 'link'=>'', 'user'=>'string', 'password'=>'string', 'database'=>'string'], 'maxdb::character_set_name' => ['string', 'link'=>''], 'maxdb::close' => ['bool', 'link'=>''], 'maxdb::commit' => ['bool', 'link'=>''], 'maxdb::disable_reads_from_master' => ['', 'link'=>''], 'maxdb::errno' => ['int', 'link'=>''], 'maxdb::error' => ['string', 'link'=>''], 'maxdb::field_count' => ['int', 'link'=>''], 'maxdb::get_host_info' => ['string', 'link'=>''], 'maxdb::info' => ['string', 'link'=>''], 'maxdb::insert_id' => ['', 'link'=>''], 'maxdb::kill' => ['bool', 'link'=>'', 'processid'=>'int'], 'maxdb::more_results' => ['bool', 'link'=>''], 'maxdb::multi_query' => ['bool', 'link'=>'', 'query'=>'string'], 'maxdb::next_result' => ['bool', 'link'=>''], 'maxdb::num_rows' => ['int', 'result'=>''], 'maxdb::options' => ['bool', 'link'=>'', 'option'=>'int', 'value'=>''], 'maxdb::ping' => ['bool', 'link'=>''], 'maxdb::prepare' => ['maxdb_stmt', 'link'=>'', 'query'=>'string'], 'maxdb::protocol_version' => ['string', 'link'=>''], 'maxdb::query' => ['', 'link'=>'', 'query'=>'string', 'resultmode='=>'int'], 'maxdb::real_connect' => ['bool', 'link'=>'', 'hostname='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'], 'maxdb::real_escape_string' => ['string', 'link'=>'', 'escapestr'=>'string'], 'maxdb::real_query' => ['bool', 'link'=>'', 'query'=>'string'], 'maxdb::rollback' => ['bool', 'link'=>''], 'maxdb::rpl_query_type' => ['int', 'link'=>''], 'maxdb::select_db' => ['bool', 'link'=>'', 'dbname'=>'string'], 'maxdb::send_query' => ['bool', 'link'=>'', 'query'=>'string'], 'maxdb::server_info' => ['string', 'link'=>''], 'maxdb::server_version' => ['int', 'link'=>''], 'maxdb::sqlstate' => ['string', 'link'=>''], 'maxdb::ssl_set' => ['bool', 'link'=>'', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'], 'maxdb::stat' => ['string', 'link'=>''], 'maxdb::stmt_init' => ['object', 'link'=>''], 'maxdb::store_result' => ['bool', 'link'=>''], 'maxdb::thread_id' => ['int', 'link'=>''], 'maxdb::use_result' => ['resource', 'link'=>''], 'maxdb::warning_count' => ['int', 'link'=>''], 'maxdb_affected_rows' => ['int', 'link'=>'resource'], 'maxdb_autocommit' => ['bool', 'link'=>'', 'mode'=>'bool'], 'maxdb_change_user' => ['bool', 'link'=>'', 'user'=>'string', 'password'=>'string', 'database'=>'string'], 'maxdb_character_set_name' => ['string', 'link'=>''], 'maxdb_close' => ['bool', 'link'=>''], 'maxdb_commit' => ['bool', 'link'=>''], 'maxdb_connect' => ['resource', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'], 'maxdb_connect_errno' => ['int'], 'maxdb_connect_error' => ['string'], 'maxdb_data_seek' => ['bool', 'result'=>'', 'offset'=>'int'], 'maxdb_debug' => ['void', 'debug'=>'string'], 'maxdb_disable_reads_from_master' => ['', 'link'=>''], 'maxdb_disable_rpl_parse' => ['bool', 'link'=>'resource'], 'maxdb_dump_debug_info' => ['bool', 'link'=>'resource'], 'maxdb_embedded_connect' => ['resource', 'dbname='=>'string'], 'maxdb_enable_reads_from_master' => ['bool', 'link'=>'resource'], 'maxdb_enable_rpl_parse' => ['bool', 'link'=>'resource'], 'maxdb_errno' => ['int', 'link'=>'resource'], 'maxdb_error' => ['string', 'link'=>'resource'], 'maxdb_fetch_array' => ['', 'result'=>'', 'resulttype='=>'int'], 'maxdb_fetch_assoc' => ['array', 'result'=>''], 'maxdb_fetch_field' => ['', 'result'=>''], 'maxdb_fetch_field_direct' => ['', 'result'=>'', 'fieldnr'=>'int'], 'maxdb_fetch_fields' => ['', 'result'=>''], 'maxdb_fetch_lengths' => ['array', 'result'=>'resource'], 'maxdb_fetch_object' => ['object', 'result'=>'object'], 'maxdb_fetch_row' => ['', 'result'=>''], 'maxdb_field_count' => ['int', 'link'=>''], 'maxdb_field_seek' => ['bool', 'result'=>'', 'fieldnr'=>'int'], 'maxdb_field_tell' => ['int', 'result'=>'resource'], 'maxdb_free_result' => ['', 'result'=>''], 'maxdb_get_client_info' => ['string'], 'maxdb_get_client_version' => ['int'], 'maxdb_get_host_info' => ['string', 'link'=>'resource'], 'maxdb_get_proto_info' => ['string', 'link'=>'resource'], 'maxdb_get_server_info' => ['string', 'link'=>'resource'], 'maxdb_get_server_version' => ['int', 'link'=>'resource'], 'maxdb_info' => ['string', 'link'=>'resource'], 'maxdb_init' => ['resource'], 'maxdb_insert_id' => ['mixed', 'link'=>'resource'], 'maxdb_kill' => ['bool', 'link'=>'', 'processid'=>'int'], 'maxdb_master_query' => ['bool', 'link'=>'resource', 'query'=>'string'], 'maxdb_more_results' => ['bool', 'link'=>'resource'], 'maxdb_multi_query' => ['bool', 'link'=>'', 'query'=>'string'], 'maxdb_next_result' => ['bool', 'link'=>'resource'], 'maxdb_num_fields' => ['int', 'result'=>'resource'], 'maxdb_num_rows' => ['int', 'result'=>'resource'], 'maxdb_options' => ['bool', 'link'=>'', 'option'=>'int', 'value'=>''], 'maxdb_ping' => ['bool', 'link'=>''], 'maxdb_prepare' => ['maxdb_stmt', 'link'=>'', 'query'=>'string'], 'maxdb_query' => ['', 'link'=>'', 'query'=>'string', 'resultmode='=>'int'], 'maxdb_real_connect' => ['bool', 'link'=>'', 'hostname='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'], 'maxdb_real_escape_string' => ['string', 'link'=>'', 'escapestr'=>'string'], 'maxdb_real_query' => ['bool', 'link'=>'', 'query'=>'string'], 'maxdb_report' => ['bool', 'flags'=>'int'], 'maxdb_result::current_field' => ['int', 'result'=>''], 'maxdb_result::data_seek' => ['bool', 'result'=>'', 'offset'=>'int'], 'maxdb_result::fetch_array' => ['', 'result'=>'', 'resulttype='=>'int'], 'maxdb_result::fetch_assoc' => ['array', 'result'=>''], 'maxdb_result::fetch_field' => ['', 'result'=>''], 'maxdb_result::fetch_field_direct' => ['', 'result'=>'', 'fieldnr'=>'int'], 'maxdb_result::fetch_fields' => ['', 'result'=>''], 'maxdb_result::fetch_object' => ['object', 'result'=>'object'], 'maxdb_result::fetch_row' => ['', 'result'=>''], 'maxdb_result::field_count' => ['int', 'result'=>''], 'maxdb_result::field_seek' => ['bool', 'result'=>'', 'fieldnr'=>'int'], 'maxdb_result::free' => ['', 'result'=>''], 'maxdb_result::lengths' => ['array', 'result'=>''], 'maxdb_rollback' => ['bool', 'link'=>''], 'maxdb_rpl_parse_enabled' => ['int', 'link'=>'resource'], 'maxdb_rpl_probe' => ['bool', 'link'=>'resource'], 'maxdb_rpl_query_type' => ['int', 'link'=>''], 'maxdb_select_db' => ['bool', 'link'=>'resource', 'dbname'=>'string'], 'maxdb_send_query' => ['bool', 'link'=>'', 'query'=>'string'], 'maxdb_server_end' => ['void'], 'maxdb_server_init' => ['bool', 'server='=>'array', 'groups='=>'array'], 'maxdb_sqlstate' => ['string', 'link'=>'resource'], 'maxdb_ssl_set' => ['bool', 'link'=>'', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'], 'maxdb_stat' => ['string', 'link'=>''], 'maxdb_stmt::affected_rows' => ['int', 'stmt'=>''], 'maxdb_stmt::bind_param' => ['bool', 'stmt'=>'', 'types'=>'string', '&...rw_var'=>''], 'maxdb_stmt::bind_param\'1' => ['bool', 'stmt'=>'', 'types'=>'string', '&rw_var'=>'array'], 'maxdb_stmt::bind_result' => ['bool', 'stmt'=>'', '&w_var1'=>'', '&...w_vars='=>''], 'maxdb_stmt::close' => ['bool', 'stmt'=>''], 'maxdb_stmt::close_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int'], 'maxdb_stmt::data_seek' => ['bool', 'statement'=>'', 'offset'=>'int'], 'maxdb_stmt::errno' => ['int', 'stmt'=>''], 'maxdb_stmt::error' => ['string', 'stmt'=>''], 'maxdb_stmt::execute' => ['bool', 'stmt'=>''], 'maxdb_stmt::fetch' => ['bool', 'stmt'=>''], 'maxdb_stmt::free_result' => ['', 'stmt'=>''], 'maxdb_stmt::num_rows' => ['int', 'stmt'=>''], 'maxdb_stmt::param_count' => ['int', 'stmt'=>''], 'maxdb_stmt::prepare' => ['', 'stmt'=>'', 'query'=>'string'], 'maxdb_stmt::reset' => ['bool', 'stmt'=>''], 'maxdb_stmt::result_metadata' => ['resource', 'stmt'=>''], 'maxdb_stmt::send_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int', 'data'=>'string'], 'maxdb_stmt::stmt_send_long_data' => ['bool', 'param_nr'=>'int', 'data'=>'string'], 'maxdb_stmt::store_result' => ['bool'], 'maxdb_stmt_affected_rows' => ['int', 'stmt'=>'resource'], 'maxdb_stmt_bind_param' => ['bool', 'stmt'=>'', 'types'=>'string', 'var1'=>'', '...args='=>'', 'var='=>'array'], 'maxdb_stmt_bind_result' => ['bool', 'stmt'=>'', '&w_var1'=>'', '&...w_vars='=>''], 'maxdb_stmt_close' => ['bool', 'stmt'=>''], 'maxdb_stmt_close_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int'], 'maxdb_stmt_data_seek' => ['bool', 'statement'=>'', 'offset'=>'int'], 'maxdb_stmt_errno' => ['int', 'stmt'=>'resource'], 'maxdb_stmt_error' => ['string', 'stmt'=>'resource'], 'maxdb_stmt_execute' => ['bool', 'stmt'=>''], 'maxdb_stmt_fetch' => ['bool', 'stmt'=>''], 'maxdb_stmt_free_result' => ['', 'stmt'=>''], 'maxdb_stmt_init' => ['object', 'link'=>''], 'maxdb_stmt_num_rows' => ['int', 'stmt'=>'resource'], 'maxdb_stmt_param_count' => ['int', 'stmt'=>'resource'], 'maxdb_stmt_prepare' => ['', 'stmt'=>'', 'query'=>'string'], 'maxdb_stmt_reset' => ['bool', 'stmt'=>''], 'maxdb_stmt_result_metadata' => ['resource', 'stmt'=>''], 'maxdb_stmt_send_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int', 'data'=>'string'], 'maxdb_stmt_sqlstate' => ['string', 'stmt'=>'resource'], 'maxdb_stmt_store_result' => ['bool', 'stmt'=>''], 'maxdb_store_result' => ['bool', 'link'=>''], 'maxdb_thread_id' => ['int', 'link'=>'resource'], 'maxdb_thread_safe' => ['bool'], 'maxdb_use_result' => ['resource', 'link'=>''], 'maxdb_warning_count' => ['int', 'link'=>'resource'], 'mb_check_encoding' => ['bool', 'var='=>'string|array', 'encoding='=>'string'], 'mb_chr' => ['string|false', 'cp'=>'int', 'encoding='=>'string'], 'mb_convert_case' => ['string', 'sourcestring'=>'string', 'mode'=>'int', 'encoding='=>'string'], 'mb_convert_encoding' => ['string|array|false', 'val'=>'string|array', 'to_encoding'=>'string', 'from_encoding='=>'mixed'], 'mb_convert_kana' => ['string', 'str'=>'string', 'option='=>'string', 'encoding='=>'string'], 'mb_convert_variables' => ['string|false', 'to_encoding'=>'string', 'from_encoding'=>'array|string', '&rw_vars'=>'string|array|object', '&...rw_vars='=>'string|array|object'], 'mb_decode_mimeheader' => ['string', 'string'=>'string'], 'mb_decode_numericentity' => ['string', 'string'=>'string', 'convmap'=>'array', 'encoding'=>'string'], 'mb_detect_encoding' => ['string|false', 'str'=>'string', 'encoding_list='=>'mixed', 'strict='=>'bool'], 'mb_detect_order' => ['bool|list', 'encoding_list='=>'mixed'], 'mb_encode_mimeheader' => ['string', 'str'=>'string', 'charset='=>'string', 'transfer_encoding='=>'string', 'linefeed='=>'string', 'indent='=>'int'], 'mb_encode_numericentity' => ['string', 'string'=>'string', 'convmap'=>'array', 'encoding='=>'string', 'is_hex='=>'bool'], 'mb_encoding_aliases' => ['list|false', 'encoding'=>'string'], 'mb_ereg' => ['int|false', 'pattern'=>'string', 'string'=>'string', '&w_registers='=>'array'], 'mb_ereg_match' => ['bool', 'pattern'=>'string', 'string'=>'string', 'option='=>'string'], 'mb_ereg_replace' => ['string|false|null', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string', 'option='=>'string'], 'mb_ereg_replace_callback' => ['string|false|null', 'pattern'=>'string', 'callback'=>'callable(array):string', 'string'=>'string', 'option='=>'string'], 'mb_ereg_search' => ['bool', 'pattern='=>'string', 'option='=>'string'], 'mb_ereg_search_getpos' => ['int'], 'mb_ereg_search_getregs' => ['array|false'], 'mb_ereg_search_init' => ['bool', 'string'=>'string', 'pattern='=>'string', 'option='=>'string'], 'mb_ereg_search_pos' => ['array|false', 'pattern='=>'string', 'option='=>'string'], 'mb_ereg_search_regs' => ['array|false', 'pattern='=>'string', 'option='=>'string'], 'mb_ereg_search_setpos' => ['bool', 'position'=>'int'], 'mb_eregi' => ['int', 'pattern'=>'string', 'string'=>'string', '&w_registers='=>'array'], 'mb_eregi_replace' => ['string|false', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string', 'option='=>'string'], 'mb_get_info' => ['mixed', 'type='=>'string'], 'mb_http_input' => ['mixed', 'type='=>'string'], 'mb_http_output' => ['string|bool', 'encoding='=>'string'], 'mb_internal_encoding' => ['string|bool', 'encoding='=>'string'], 'mb_language' => ['string|bool', 'language='=>'string'], 'mb_list_encodings' => ['non-empty-list'], 'mb_ord' => ['int|false', 'str'=>'string', 'enc='=>'string'], 'mb_output_handler' => ['string', 'contents'=>'string', 'status'=>'int'], 'mb_parse_str' => ['bool', 'encoded_string'=>'string', '&w_result='=>'array'], 'mb_preferred_mime_name' => ['string|false', 'encoding'=>'string'], 'mb_regex_encoding' => ['string|bool', 'encoding='=>'string'], 'mb_regex_set_options' => ['string', 'options='=>'string'], 'mb_scrub' => ['string', 'str'=>'string', 'enc='=>'string'], 'mb_send_mail' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string|array|null', 'additional_parameter='=>'string'], 'mb_split' => ['list|false', 'pattern'=>'string', 'string'=>'string', 'limit='=>'int'], 'mb_strcut' => ['string', 'str'=>'string', 'start'=>'int', 'length='=>'?int', 'encoding='=>'string'], 'mb_strimwidth' => ['string', 'str'=>'string', 'start'=>'int', 'width'=>'int', 'trimmarker='=>'string', 'encoding='=>'string'], 'mb_stripos' => ['0|positive-int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'], 'mb_stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool', 'encoding='=>'string'], 'mb_strlen' => ['0|positive-int|false', 'str'=>'string', 'encoding='=>'string'], 'mb_strpos' => ['0|positive-int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'], 'mb_strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool', 'encoding='=>'string'], 'mb_strrichr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool', 'encoding='=>'string'], 'mb_strripos' => ['0|positive-int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'], 'mb_strrpos' => ['0|positive-int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'], 'mb_strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool', 'encoding='=>'string'], 'mb_strtolower' => ['lowercase-string', 'str'=>'string', 'encoding='=>'string'], 'mb_strtoupper' => ['uppercase-string', 'str'=>'string', 'encoding='=>'string'], 'mb_strwidth' => ['0|positive-int', 'str'=>'string', 'encoding='=>'string'], 'mb_substitute_character' => ['mixed', 'substchar='=>'mixed'], 'mb_substr' => ['string', 'str'=>'string', 'start'=>'int', 'length='=>'?int', 'encoding='=>'string'], 'mb_substr_count' => ['0|positive-int', 'haystack'=>'string', 'needle'=>'string', 'encoding='=>'string'], 'mcrypt_cbc' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], 'mcrypt_cfb' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], 'mcrypt_create_iv' => ['string', 'size'=>'int', 'source='=>'int'], 'mcrypt_decrypt' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'string', 'iv='=>'string'], 'mcrypt_ecb' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], 'mcrypt_enc_get_algorithms_name' => ['string', 'td'=>'resource'], 'mcrypt_enc_get_block_size' => ['int', 'td'=>'resource'], 'mcrypt_enc_get_iv_size' => ['int', 'td'=>'resource'], 'mcrypt_enc_get_key_size' => ['int', 'td'=>'resource'], 'mcrypt_enc_get_modes_name' => ['string', 'td'=>'resource'], 'mcrypt_enc_get_supported_key_sizes' => ['array', 'td'=>'resource'], 'mcrypt_enc_is_block_algorithm' => ['bool', 'td'=>'resource'], 'mcrypt_enc_is_block_algorithm_mode' => ['bool', 'td'=>'resource'], 'mcrypt_enc_is_block_mode' => ['bool', 'td'=>'resource'], 'mcrypt_enc_self_test' => ['int', 'td'=>'resource'], 'mcrypt_encrypt' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'string', 'iv='=>'string'], 'mcrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'], 'mcrypt_generic_deinit' => ['bool', 'td'=>'resource'], 'mcrypt_generic_end' => ['bool', 'td'=>'resource'], 'mcrypt_generic_init' => ['int', 'td'=>'resource', 'key'=>'string', 'iv'=>'string'], 'mcrypt_get_block_size' => ['int', 'cipher'=>'string', 'module'=>'string'], 'mcrypt_get_cipher_name' => ['string', 'cipher'=>'int|string'], 'mcrypt_get_iv_size' => ['int', 'cipher'=>'string', 'module'=>'string'], 'mcrypt_get_key_size' => ['int', 'cipher'=>'string', 'module'=>'string'], 'mcrypt_list_algorithms' => ['array', 'lib_dir='=>'string'], 'mcrypt_list_modes' => ['array', 'lib_dir='=>'string'], 'mcrypt_module_close' => ['bool', 'td'=>'resource'], 'mcrypt_module_get_algo_block_size' => ['int', 'algorithm'=>'string', 'lib_dir='=>'string'], 'mcrypt_module_get_algo_key_size' => ['int', 'algorithm'=>'string', 'lib_dir='=>'string'], 'mcrypt_module_get_supported_key_sizes' => ['array', 'algorithm'=>'string', 'lib_dir='=>'string'], 'mcrypt_module_is_block_algorithm' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'], 'mcrypt_module_is_block_algorithm_mode' => ['bool', 'mode'=>'string', 'lib_dir='=>'string'], 'mcrypt_module_is_block_mode' => ['bool', 'mode'=>'string', 'lib_dir='=>'string'], 'mcrypt_module_open' => ['resource|false', 'cipher'=>'string', 'cipher_directory'=>'string', 'mode'=>'string', 'mode_directory'=>'string'], 'mcrypt_module_self_test' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'], 'mcrypt_ofb' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], 'md5' => ['non-falsy-string&lowercase-string', 'str'=>'string', 'raw_output='=>'bool'], 'md5_file' => ['(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], 'mdecrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'], 'Memcache::add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], 'Memcache::addServer' => ['bool', 'host'=>'string', 'port='=>'int', 'persistent='=>'bool', 'weight='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable', 'timeoutms='=>'int'], 'Memcache::close' => ['bool'], 'Memcache::connect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'], 'Memcache::decrement' => ['int', 'key'=>'string', 'value='=>'int'], 'Memcache::delete' => ['bool', 'key'=>'string', 'timeout='=>'int'], 'Memcache::flush' => ['bool'], 'Memcache::get' => ['mixed', 'key'=>'string', '&flags='=>'int'], 'Memcache::get\'1' => ['mixed[]|false', 'keys'=>'string[]', '&flags='=>'int[]'], 'Memcache::getExtendedStats' => ['array', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'], 'Memcache::getServerStatus' => ['int', 'host'=>'string', 'port='=>'int'], 'Memcache::getStats' => ['array', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'], 'Memcache::getVersion' => ['string'], 'Memcache::increment' => ['int', 'key'=>'string', 'value='=>'int'], 'Memcache::pconnect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'], 'Memcache::replace' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], 'Memcache::set' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], 'Memcache::setCompressThreshold' => ['bool', 'threshold'=>'int', 'min_savings='=>'float'], 'Memcache::setServerParams' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable'], 'memcache_debug' => ['bool', 'on_off'=>'bool'], 'Memcached::add' => ['bool', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], 'Memcached::addByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], 'Memcached::addServer' => ['bool', 'host'=>'string', 'port'=>'int', 'weight='=>'int'], 'Memcached::addServers' => ['bool', 'servers'=>'array'], 'Memcached::append' => ['bool', 'key'=>'string', 'value'=>'string'], 'Memcached::appendByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'string'], 'Memcached::cas' => ['bool', 'cas_token'=>'float', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], 'Memcached::casByKey' => ['bool', 'cas_token'=>'float', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], 'Memcached::decrement' => ['int|false', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'], 'Memcached::decrementByKey' => ['int|false', 'server_key'=>'string', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'], 'Memcached::delete' => ['bool', 'key'=>'string', 'time='=>'int'], 'Memcached::deleteByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'time='=>'int'], 'Memcached::deleteMulti' => ['array', 'keys'=>'array', 'time='=>'int'], 'Memcached::deleteMultiByKey' => ['bool', 'server_key'=>'string', 'keys'=>'array', 'time='=>'int'], 'Memcached::fetch' => ['array'], 'Memcached::fetchAll' => ['array'], 'Memcached::flush' => ['bool', 'delay='=>'int'], 'Memcached::get' => ['mixed', 'key'=>'string', 'cache_cb='=>'?callable', 'flags='=>'int'], 'Memcached::getAllKeys' => ['array|false'], 'Memcached::getByKey' => ['mixed', 'server_key'=>'string', 'key'=>'string', 'value_cb='=>'?callable', 'flags='=>'int'], 'Memcached::getDelayed' => ['bool', 'keys'=>'array', 'with_cas='=>'bool', 'value_cb='=>'callable'], 'Memcached::getDelayedByKey' => ['bool', 'server_key'=>'string', 'keys'=>'array', 'with_cas='=>'bool', 'value_cb='=>'?callable'], 'Memcached::getMulti' => ['array|false', 'keys'=>'array', 'flags='=>'int'], 'Memcached::getMultiByKey' => ['array', 'server_key'=>'string', 'keys'=>'array', 'flags='=>'int'], 'Memcached::getOption' => ['mixed', 'option'=>'int'], 'Memcached::getResultCode' => ['int'], 'Memcached::getResultMessage' => ['string'], 'Memcached::getServerByKey' => ['array', 'server_key'=>'string'], 'Memcached::getServerList' => ['array'], 'Memcached::getStats' => ['array', 'type='=>'?string'], 'Memcached::getVersion' => ['array'], 'Memcached::increment' => ['int|false', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'], 'Memcached::incrementByKey' => ['int|false', 'server_key'=>'string', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'], 'Memcached::isPersistent' => ['bool'], 'Memcached::isPristine' => ['bool'], 'Memcached::prepend' => ['bool', 'key'=>'string', 'value'=>'string'], 'Memcached::prependByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'string'], 'Memcached::quit' => ['bool'], 'Memcached::replace' => ['bool', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], 'Memcached::replaceByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], 'Memcached::resetServerList' => ['bool'], 'Memcached::set' => ['bool', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], 'Memcached::setByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], 'Memcached::setMulti' => ['bool', 'items'=>'array', 'expiration='=>'int'], 'Memcached::setMultiByKey' => ['bool', 'server_key'=>'string', 'items'=>'array', 'expiration='=>'int'], 'Memcached::setOption' => ['bool', 'option'=>'int', 'value'=>'mixed'], 'Memcached::setOptions' => ['bool', 'options'=>'array'], 'Memcached::setSaslAuthData' => ['void', 'username'=>'string', 'password'=>'string'], 'Memcached::touch' => ['bool', 'key'=>'string', 'expiration'=>'int'], 'Memcached::touchByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'expiration'=>'int'], 'MemcachePool::add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], 'MemcachePool::close' => ['bool'], 'MemcachePool::decrement' => ['int', 'key'=>'string', 'value='=>'int'], 'MemcachePool::delete' => ['bool', 'key'=>'string', 'timeout='=>'int'], 'MemcachePool::flush' => ['bool'], 'MemcachePool::get' => ['mixed', 'key'=>'string', '&flags='=>'int'], 'MemcachePool::get\'1' => ['mixed[]|false', 'keys'=>'string[]', '&flags='=>'int[]'], 'MemcachePool::getExtendedStats' => ['array', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'], 'MemcachePool::getServerStatus' => ['int', 'host'=>'string', 'port='=>'int'], 'MemcachePool::getStats' => ['array', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'], 'MemcachePool::getVersion' => ['string'], 'MemcachePool::increment' => ['int', 'key'=>'string', 'value='=>'int'], 'MemcachePool::replace' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], 'MemcachePool::set' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], 'MemcachePool::setCompressThreshold' => ['bool', 'threshold'=>'int', 'min_savings='=>'float'], 'MemcachePool::setServerParams' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable'], 'memory_get_peak_usage' => ['positive-int', 'real_usage='=>'bool'], 'memory_get_usage' => ['positive-int', 'real_usage='=>'bool'], 'MessageFormatter::__construct' => ['void', 'locale'=>'string', 'pattern'=>'string'], 'MessageFormatter::create' => ['MessageFormatter', 'locale'=>'string', 'pattern'=>'string'], 'MessageFormatter::format' => ['false|string', 'args'=>'array'], 'MessageFormatter::formatMessage' => ['false|string', 'locale'=>'string', 'pattern'=>'string', 'args'=>'array'], 'MessageFormatter::getErrorCode' => ['int'], 'MessageFormatter::getErrorMessage' => ['string'], 'MessageFormatter::getLocale' => ['string'], 'MessageFormatter::getPattern' => ['string'], 'MessageFormatter::parse' => ['array', 'value'=>'string'], 'MessageFormatter::parseMessage' => ['array', 'locale'=>'string', 'pattern'=>'string', 'source'=>'string'], 'MessageFormatter::setPattern' => ['bool', 'pattern'=>'string'], 'metaphone' => ['string', 'text'=>'string', 'phones='=>'int'], 'method_exists' => ['bool', 'object'=>'object|string', 'method'=>'string'], 'mhash' => ['string|false', 'hash'=>'int', 'data'=>'string', 'key='=>'string'], 'mhash_count' => ['int'], 'mhash_get_block_size' => ['int|false', 'hash'=>'int'], 'mhash_get_hash_name' => ['string|false', 'hash'=>'int'], 'mhash_keygen_s2k' => ['string|false', 'hash'=>'int', 'input_password'=>'string', 'salt'=>'string', 'bytes'=>'int'], 'microtime' => ['mixed', 'get_as_float='=>'bool'], 'mime_content_type' => ['string|false', 'filename_or_stream'=>'string|resource'], 'min' => ['', '...arg1'=>'array'], 'min\'1' => ['', 'arg1'=>'', 'arg2'=>'', '...args='=>''], 'ming_keypress' => ['int', 'char'=>'string'], 'ming_setcubicthreshold' => ['void', 'threshold'=>'int'], 'ming_setscale' => ['void', 'scale'=>'float'], 'ming_setswfcompression' => ['void', 'level'=>'int'], 'ming_useconstants' => ['void', 'use'=>'int'], 'ming_useswfversion' => ['void', 'version'=>'int'], 'mkdir' => ['bool', 'pathname'=>'string', 'mode='=>'int', 'recursive='=>'bool', 'context='=>'resource'], 'mktime' => ['__benevolent', 'hour='=>'int', 'min='=>'int', 'sec='=>'int', 'mon='=>'int', 'day='=>'int', 'year='=>'int'], 'money_format' => ['string', 'format'=>'string', 'value'=>'float'], 'Mongo::__construct' => ['void', 'server='=>'string', 'options='=>'array', 'driver_options='=>'array'], 'Mongo::__get' => ['MongoDB', 'dbname'=>'string'], 'Mongo::__toString' => ['string'], 'Mongo::close' => ['bool'], 'Mongo::connect' => ['bool'], 'Mongo::connectUtil' => ['bool'], 'Mongo::dropDB' => ['array', 'db'=>''], 'Mongo::forceError' => ['bool'], 'Mongo::getConnections' => ['array'], 'Mongo::getHosts' => ['array'], 'Mongo::getPoolSize' => ['int'], 'Mongo::getReadPreference' => ['array'], 'Mongo::getSlave' => ['string'], 'Mongo::getSlaveOkay' => ['bool'], 'Mongo::getWriteConcern' => ['array'], 'Mongo::killCursor' => ['', 'server_hash'=>'string', 'id'=>'MongoInt64|int'], 'Mongo::lastError' => ['array|null'], 'Mongo::listDBs' => ['array'], 'Mongo::pairConnect' => ['bool'], 'Mongo::pairPersistConnect' => ['bool', 'username='=>'string', 'password='=>'string'], 'Mongo::persistConnect' => ['bool', 'username='=>'string', 'password='=>'string'], 'Mongo::poolDebug' => ['array'], 'Mongo::prevError' => ['array'], 'Mongo::resetError' => ['array'], 'Mongo::selectCollection' => ['MongoCollection', 'db'=>'string', 'collection'=>'string'], 'Mongo::selectDB' => ['MongoDB', 'name'=>'string'], 'Mongo::setPoolSize' => ['bool', 'size'=>'int'], 'Mongo::setReadPreference' => ['bool', 'readPreference'=>'string', 'tags='=>'array'], 'Mongo::setSlaveOkay' => ['bool', 'ok='=>'bool'], 'Mongo::switchSlave' => ['string'], 'MongoBinData::__construct' => ['void', 'data'=>'string', 'type='=>'int'], 'MongoBinData::__toString' => ['string'], 'MongoClient::__construct' => ['void', 'server='=>'string', 'options='=>'array', 'driver_options='=>'array'], 'MongoClient::__get' => ['MongoDB', 'dbname'=>'string'], 'MongoClient::__toString' => ['string'], 'MongoClient::close' => ['bool', 'connection='=>'bool|string'], 'MongoClient::connect' => ['bool'], 'MongoClient::dropDB' => ['array', 'db'=>'mixed'], 'MongoClient::getConnections' => ['array'], 'MongoClient::getHosts' => ['array'], 'MongoClient::getReadPreference' => ['array'], 'MongoClient::getWriteConcern' => ['array'], 'MongoClient::killCursor' => ['bool', 'server_hash'=>'string', 'id'=>'int|MongoInt64'], 'MongoClient::listDBs' => ['array'], 'MongoClient::selectCollection' => ['MongoCollection', 'db'=>'string', 'collection'=>'string'], 'MongoClient::selectDB' => ['MongoDB', 'name'=>'string'], 'MongoClient::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags='=>'array'], 'MongoClient::setWriteConcern' => ['bool', 'w'=>'mixed', 'wtimeout='=>'int'], 'MongoClient::switchSlave' => ['string'], 'MongoCode::__construct' => ['void', 'code'=>'string', 'scope='=>'array'], 'MongoCode::__toString' => ['string'], 'MongoCollection::__construct' => ['void', 'db'=>'MongoDB', 'name'=>'string'], 'MongoCollection::__get' => ['MongoCollection', 'name'=>'string'], 'MongoCollection::__toString' => ['string'], 'MongoCollection::aggregate' => ['array', 'op'=>'array', 'op='=>'array', '...args='=>'array'], 'MongoCollection::aggregate\'1' => ['array', 'pipeline'=>'array', 'options='=>'array'], 'MongoCollection::aggregateCursor' => ['MongoCommandCursor', 'command'=>'array', 'options='=>'array'], 'MongoCollection::batchInsert' => ['mixed', 'a'=>'array', 'options='=>'array'], 'MongoCollection::count' => ['0|positive-int', 'query='=>'array', 'limit='=>'int', 'skip='=>'int'], 'MongoCollection::createDBRef' => ['array', 'a'=>'array'], 'MongoCollection::createIndex' => ['bool', 'keys'=>'array', 'options='=>'array'], 'MongoCollection::deleteIndex' => ['array', 'keys'=>'string|array'], 'MongoCollection::deleteIndexes' => ['array'], 'MongoCollection::distinct' => ['array', 'key'=>'string', 'query='=>'array'], 'MongoCollection::drop' => ['array'], 'MongoCollection::ensureIndex' => ['bool', 'keys'=>'array', 'options='=>'array'], 'MongoCollection::find' => ['MongoCursor', 'query='=>'array', 'fields='=>'array'], 'MongoCollection::findAndModify' => ['array', 'query'=>'array', 'update='=>'array', 'fields='=>'array', 'options='=>'array'], 'MongoCollection::findOne' => ['array|null', 'query='=>'array', 'fields='=>'array'], 'MongoCollection::getDBRef' => ['array', 'ref'=>'array'], 'MongoCollection::getIndexInfo' => ['array'], 'MongoCollection::getName' => ['string'], 'MongoCollection::getReadPreference' => ['array'], 'MongoCollection::getSlaveOkay' => ['bool'], 'MongoCollection::getWriteConcern' => ['array'], 'MongoCollection::group' => ['array', 'keys'=>'mixed', 'initial'=>'array', 'reduce'=>'mongocode', 'options='=>'array'], 'MongoCollection::insert' => ['bool|array', 'a'=>'array', 'options='=>'array'], 'MongoCollection::parallelCollectionScan' => ['MongoCommandCursor[]', 'num_cursors'=>'int'], 'MongoCollection::remove' => ['bool|array', 'criteria='=>'array', 'options='=>'array'], 'MongoCollection::save' => ['mixed', 'a'=>'array|object', 'options='=>'array'], 'MongoCollection::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags='=>'array'], 'MongoCollection::setSlaveOkay' => ['bool', 'ok='=>'bool'], 'MongoCollection::setWriteConcern' => ['bool', 'w'=>'mixed', 'wtimeout='=>'int'], 'MongoCollection::toIndexString' => ['string', 'keys'=>'mixed'], 'MongoCollection::update' => ['bool', 'criteria'=>'array', 'newobj'=>'array', 'options='=>'array'], 'MongoCollection::validate' => ['array', 'scan_data='=>'bool'], 'MongoCommandCursor::__construct' => ['void', 'connection'=>'MongoClient', 'ns'=>'string', 'command'=>'array'], 'MongoCommandCursor::batchSize' => ['MongoCommandCursor', 'batchSize'=>'int'], 'MongoCommandCursor::createFromDocument' => ['MongoCommandCursor', 'connection'=>'MongoClient', 'hash'=>'string', 'document'=>'array'], 'MongoCommandCursor::current' => ['array'], 'MongoCommandCursor::dead' => ['bool'], 'MongoCommandCursor::getReadPreference' => ['array'], 'MongoCommandCursor::info' => ['array'], 'MongoCommandCursor::key' => ['int'], 'MongoCommandCursor::next' => ['void'], 'MongoCommandCursor::rewind' => ['array'], 'MongoCommandCursor::setReadPreference' => ['MongoCommandCursor', 'read_preference'=>'string', 'tags='=>'array'], 'MongoCommandCursor::timeout' => ['MongoCommandCursor', 'ms'=>'int'], 'MongoCommandCursor::valid' => ['bool'], 'MongoCursor::__construct' => ['void', 'connection'=>'MongoClient', 'ns'=>'string', 'query='=>'array', 'fields='=>'array'], 'MongoCursor::addOption' => ['MongoCursor', 'key'=>'string', 'value'=>'mixed'], 'MongoCursor::awaitData' => ['MongoCursor', 'wait='=>'bool'], 'MongoCursor::batchSize' => ['MongoCursor', 'num'=>'int'], 'MongoCursor::count' => ['0|positive-int', 'foundonly='=>'bool'], 'MongoCursor::current' => ['array'], 'MongoCursor::dead' => ['bool'], 'MongoCursor::doQuery' => ['void'], 'MongoCursor::explain' => ['array'], 'MongoCursor::fields' => ['MongoCursor', 'f'=>'array'], 'MongoCursor::getNext' => ['array'], 'MongoCursor::getReadPreference' => ['array'], 'MongoCursor::hasNext' => ['bool'], 'MongoCursor::hint' => ['MongoCursor', 'key_pattern'=>'array'], 'MongoCursor::immortal' => ['MongoCursor', 'liveforever='=>'bool'], 'MongoCursor::info' => ['array'], 'MongoCursor::key' => ['string'], 'MongoCursor::limit' => ['MongoCursor', 'num'=>'int'], 'MongoCursor::maxTimeMS' => ['MongoCursor', 'ms'=>'int'], 'MongoCursor::next' => ['array'], 'MongoCursor::partial' => ['MongoCursor', 'okay='=>'bool'], 'MongoCursor::reset' => ['void'], 'MongoCursor::rewind' => ['void'], 'MongoCursor::setFlag' => ['MongoCursor', 'flag'=>'int', 'set='=>'bool'], 'MongoCursor::setReadPreference' => ['MongoCursor', 'read_preference'=>'string', 'tags='=>'array'], 'MongoCursor::skip' => ['MongoCursor', 'num'=>'int'], 'MongoCursor::slaveOkay' => ['MongoCursor', 'okay='=>'bool'], 'MongoCursor::snapshot' => ['MongoCursor'], 'MongoCursor::sort' => ['MongoCursor', 'fields'=>'array'], 'MongoCursor::tailable' => ['MongoCursor', 'tail='=>'bool'], 'MongoCursor::timeout' => ['MongoCursor', 'ms'=>'int'], 'MongoCursor::valid' => ['bool'], 'MongoCursorException::__clone' => ['void'], 'MongoCursorException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Exception)|(?Throwable)'], 'MongoCursorException::__toString' => ['string'], 'MongoCursorException::__wakeup' => ['void'], 'MongoCursorException::getCode' => ['int'], 'MongoCursorException::getFile' => ['string'], 'MongoCursorException::getHost' => ['string'], 'MongoCursorException::getLine' => ['int'], 'MongoCursorException::getMessage' => ['string'], 'MongoCursorException::getPrevious' => ['Exception|Throwable'], 'MongoCursorException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'MongoCursorException::getTraceAsString' => ['string'], 'MongoCursorInterface::__construct' => ['void'], 'MongoCursorInterface::batchSize' => ['MongoCursorInterface', 'batchSize'=>'int'], 'MongoCursorInterface::current' => ['mixed'], 'MongoCursorInterface::dead' => ['bool'], 'MongoCursorInterface::getReadPreference' => ['array'], 'MongoCursorInterface::info' => ['array'], 'MongoCursorInterface::key' => ['int|string'], 'MongoCursorInterface::next' => ['void'], 'MongoCursorInterface::rewind' => ['void'], 'MongoCursorInterface::setReadPreference' => ['MongoCursorInterface', 'read_preference'=>'string', 'tags='=>'array'], 'MongoCursorInterface::timeout' => ['MongoCursorInterface', 'ms'=>'int'], 'MongoCursorInterface::valid' => ['bool'], 'MongoDate::__construct' => ['void', 'sec='=>'int', 'usec='=>'int'], 'MongoDate::__toString' => ['string'], 'MongoDate::toDateTime' => ['DateTime'], 'MongoDB::__construct' => ['void', 'conn'=>'MongoClient', 'name'=>'string'], 'MongoDB::__get' => ['MongoCollection', 'name'=>'string'], 'MongoDB::__toString' => ['string'], 'MongoDB::authenticate' => ['array', 'username'=>'string', 'password'=>'string'], 'MongoDB::command' => ['array', 'command'=>'array'], 'MongoDB::createCollection' => ['MongoCollection', 'name'=>'string', 'capped='=>'bool', 'size='=>'int', 'max='=>'int'], 'MongoDB::createDBRef' => ['array', 'collection'=>'string', 'a'=>''], 'MongoDB::drop' => ['array'], 'MongoDB::dropCollection' => ['array', 'coll'=>''], 'MongoDB::execute' => ['array', 'code'=>'', 'args='=>'array'], 'MongoDB::forceError' => ['bool'], 'MongoDB::getCollectionInfo' => ['array', 'options='=>'array'], 'MongoDB::getCollectionNames' => ['array', 'options='=>'array'], 'MongoDB::getDBRef' => ['array', 'ref'=>'array'], 'MongoDB::getGridFS' => ['MongoGridFS', 'prefix='=>'string'], 'MongoDB::getProfilingLevel' => ['int'], 'MongoDB::getReadPreference' => ['array'], 'MongoDB::getSlaveOkay' => ['bool'], 'MongoDB::getWriteConcern' => ['array'], 'MongoDB::lastError' => ['array'], 'MongoDB::listCollections' => ['array'], 'MongoDB::prevError' => ['array'], 'MongoDB::repair' => ['array', 'preserve_cloned_files='=>'bool', 'backup_original_files='=>'bool'], 'MongoDB::resetError' => ['array'], 'MongoDB::selectCollection' => ['MongoCollection', 'name'=>'string'], 'MongoDB::setProfilingLevel' => ['int', 'level'=>'int'], 'MongoDB::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags='=>'array'], 'MongoDB::setSlaveOkay' => ['bool', 'ok='=>'bool'], 'MongoDB::setWriteConcern' => ['bool', 'w'=>'mixed', 'wtimeout='=>'int'], 'MongoDB\BSON\fromJSON' => ['string', 'json'=>'string'], 'MongoDB\BSON\fromPHP' => ['string', 'value'=>'object|array'], 'MongoDB\BSON\toCanonicalExtendedJSON' => ['string', 'bson'=>'string'], 'MongoDB\BSON\toJSON' => ['string', 'bson'=>'string'], 'MongoDB\BSON\toPHP' => ['object|array', 'bson'=>'string', 'typemap='=>'?array'], 'MongoDB\BSON\toRelaxedExtendedJSON' => ['string', 'bson'=>'string'], 'MongoDB\Driver\Monitoring\addSubscriber' => ['void', 'subscriber'=>'MongoDB\Driver\Monitoring\Subscriber'], 'MongoDB\Driver\Monitoring\removeSubscriber' => ['void', 'subscriber'=>'MongoDB\Driver\Monitoring\Subscriber'], 'MongoDB\BSON\Binary::__construct' => ['void', 'data'=>'string', 'type='=>'int'], 'MongoDB\BSON\Binary::getData' => ['string'], 'MongoDB\BSON\Binary::getType' => ['int'], 'MongoDB\BSON\Binary::__toString' => ['string'], 'MongoDB\BSON\Binary::serialize' => ['string'], 'MongoDB\BSON\Binary::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\Binary::jsonSerialize' => ['mixed'], 'MongoDB\BSON\BinaryInterface::getData' => ['string'], 'MongoDB\BSON\BinaryInterface::getType' => ['int'], 'MongoDB\BSON\BinaryInterface::__toString' => ['string'], 'MongoDB\BSON\DBPointer::__toString' => ['string'], 'MongoDB\BSON\DBPointer::serialize' => ['string'], 'MongoDB\BSON\DBPointer::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\DBPointer::jsonSerialize' => ['mixed'], 'MongoDB\BSON\Decimal128::__construct' => ['void', 'value'=>'string'], 'MongoDB\BSON\Decimal128::__toString' => ['string'], 'MongoDB\BSON\Decimal128::serialize' => ['string'], 'MongoDB\BSON\Decimal128::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\Decimal128::jsonSerialize' => ['mixed'], 'MongoDB\BSON\Decimal128Interface::__toString' => ['string'], 'MongoDB\BSON\Document::fromBSON' => ['MongoDB\BSON\Document', 'bson'=>'string'], 'MongoDB\BSON\Document::fromJSON' => ['MongoDB\BSON\Document', 'json'=>'string'], 'MongoDB\BSON\Document::fromPHP' => ['MongoDB\BSON\Document', 'value'=>'object|array'], 'MongoDB\BSON\Document::get' => ['mixed', 'key'=>'string'], 'MongoDB\BSON\Document::getIterator' => ['MongoDB\BSON\Iterator'], 'MongoDB\BSON\Document::has' => ['bool', 'key'=>'string'], 'MongoDB\BSON\Document::toPHP' => ['object|array', 'typeMap='=>'?array'], 'MongoDB\BSON\Document::toCanonicalExtendedJSON' => ['string'], 'MongoDB\BSON\Document::toRelaxedExtendedJSON' => ['string'], 'MongoDB\BSON\Document::offsetExists' => ['bool', 'offset'=>'mixed'], 'MongoDB\BSON\Document::offsetGet' => ['mixed', 'offset'=>'mixed'], 'MongoDB\BSON\Document::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], 'MongoDB\BSON\Document::offsetUnset' => ['void', 'offset'=>'mixed'], 'MongoDB\BSON\Document::__toString' => ['string'], 'MongoDB\BSON\Document::serialize' => ['string'], 'MongoDB\BSON\Document::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\Int64::__construct' => ['void', 'value'=>'string|int'], 'MongoDB\BSON\Int64::__toString' => ['string'], 'MongoDB\BSON\Int64::serialize' => ['string'], 'MongoDB\BSON\Int64::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\Int64::jsonSerialize' => ['mixed'], 'MongoDB\BSON\Iterator::current' => ['mixed'], 'MongoDB\BSON\Iterator::key' => ['string|int'], 'MongoDB\BSON\Iterator::next' => ['void'], 'MongoDB\BSON\Iterator::rewind' => ['void'], 'MongoDB\BSON\Iterator::valid' => ['bool'], 'MongoDB\BSON\Javascript::__construct' => ['void', 'code'=>'string', 'scope='=>'object|array|null'], 'MongoDB\BSON\Javascript::getCode' => ['string'], 'MongoDB\BSON\Javascript::getScope' => ['?object'], 'MongoDB\BSON\Javascript::__toString' => ['string'], 'MongoDB\BSON\Javascript::serialize' => ['string'], 'MongoDB\BSON\Javascript::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\Javascript::jsonSerialize' => ['mixed'], 'MongoDB\BSON\JavascriptInterface::getCode' => ['string'], 'MongoDB\BSON\JavascriptInterface::getScope' => ['?object'], 'MongoDB\BSON\JavascriptInterface::__toString' => ['string'], 'MongoDB\BSON\MaxKey::serialize' => ['string'], 'MongoDB\BSON\MaxKey::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\MaxKey::jsonSerialize' => ['mixed'], 'MongoDB\BSON\MinKey::serialize' => ['string'], 'MongoDB\BSON\MinKey::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\MinKey::jsonSerialize' => ['mixed'], 'MongoDB\BSON\ObjectId::__construct' => ['void', 'id='=>'?string'], 'MongoDB\BSON\ObjectId::getTimestamp' => ['int'], 'MongoDB\BSON\ObjectId::__toString' => ['string'], 'MongoDB\BSON\ObjectId::serialize' => ['string'], 'MongoDB\BSON\ObjectId::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\ObjectId::jsonSerialize' => ['mixed'], 'MongoDB\BSON\ObjectIdInterface::getTimestamp' => ['int'], 'MongoDB\BSON\ObjectIdInterface::__toString' => ['string'], 'MongoDB\BSON\PackedArray::fromPHP' => ['MongoDB\BSON\PackedArray', 'value'=>'array'], 'MongoDB\BSON\PackedArray::get' => ['mixed', 'index'=>'int'], 'MongoDB\BSON\PackedArray::getIterator' => ['MongoDB\BSON\Iterator'], 'MongoDB\BSON\PackedArray::has' => ['bool', 'index'=>'int'], 'MongoDB\BSON\PackedArray::toPHP' => ['object|array', 'typeMap='=>'?array'], 'MongoDB\BSON\PackedArray::offsetExists' => ['bool', 'offset'=>'mixed'], 'MongoDB\BSON\PackedArray::offsetGet' => ['mixed', 'offset'=>'mixed'], 'MongoDB\BSON\PackedArray::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], 'MongoDB\BSON\PackedArray::offsetUnset' => ['void', 'offset'=>'mixed'], 'MongoDB\BSON\PackedArray::__toString' => ['string'], 'MongoDB\BSON\PackedArray::serialize' => ['string'], 'MongoDB\BSON\PackedArray::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\Persistable::bsonSerialize' => ['stdClass|MongoDB\BSON\Document|array'], 'MongoDB\BSON\Regex::__construct' => ['void', 'pattern'=>'string', 'flags='=>'string'], 'MongoDB\BSON\Regex::getPattern' => ['string'], 'MongoDB\BSON\Regex::getFlags' => ['string'], 'MongoDB\BSON\Regex::__toString' => ['string'], 'MongoDB\BSON\Regex::serialize' => ['string'], 'MongoDB\BSON\Regex::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\Regex::jsonSerialize' => ['mixed'], 'MongoDB\BSON\RegexInterface::getPattern' => ['string'], 'MongoDB\BSON\RegexInterface::getFlags' => ['string'], 'MongoDB\BSON\RegexInterface::__toString' => ['string'], 'MongoDB\BSON\Serializable::bsonSerialize' => ['stdClass|MongoDB\BSON\Document|MongoDB\BSON\PackedArray|array'], 'MongoDB\BSON\Symbol::__toString' => ['string'], 'MongoDB\BSON\Symbol::serialize' => ['string'], 'MongoDB\BSON\Symbol::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\Symbol::jsonSerialize' => ['mixed'], 'MongoDB\BSON\Timestamp::__construct' => ['void', 'increment'=>'string|int', 'timestamp'=>'string|int'], 'MongoDB\BSON\Timestamp::getTimestamp' => ['int'], 'MongoDB\BSON\Timestamp::getIncrement' => ['int'], 'MongoDB\BSON\Timestamp::__toString' => ['string'], 'MongoDB\BSON\Timestamp::serialize' => ['string'], 'MongoDB\BSON\Timestamp::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\Timestamp::jsonSerialize' => ['mixed'], 'MongoDB\BSON\TimestampInterface::getTimestamp' => ['int'], 'MongoDB\BSON\TimestampInterface::getIncrement' => ['int'], 'MongoDB\BSON\TimestampInterface::__toString' => ['string'], 'MongoDB\BSON\UTCDateTime::__construct' => ['void', 'milliseconds='=>'DateTimeInterface|string|int|float|null'], 'MongoDB\BSON\UTCDateTime::toDateTime' => ['DateTime'], 'MongoDB\BSON\UTCDateTime::__toString' => ['string'], 'MongoDB\BSON\UTCDateTime::serialize' => ['string'], 'MongoDB\BSON\UTCDateTime::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\UTCDateTime::jsonSerialize' => ['mixed'], 'MongoDB\BSON\UTCDateTimeInterface::toDateTime' => ['DateTime'], 'MongoDB\BSON\UTCDateTimeInterface::__toString' => ['string'], 'MongoDB\BSON\Undefined::__toString' => ['string'], 'MongoDB\BSON\Undefined::serialize' => ['string'], 'MongoDB\BSON\Undefined::unserialize' => ['void', 'data'=>'string'], 'MongoDB\BSON\Undefined::jsonSerialize' => ['mixed'], 'MongoDB\BSON\Unserializable::bsonUnserialize' => ['void', 'data'=>'array'], 'MongoDB\Driver\BulkWrite::__construct' => ['void', 'options='=>'?array'], 'MongoDB\Driver\BulkWrite::count' => ['int'], 'MongoDB\Driver\BulkWrite::delete' => ['void', 'filter'=>'object|array', 'deleteOptions='=>'?array'], 'MongoDB\Driver\BulkWrite::insert' => ['mixed', 'document'=>'object|array'], 'MongoDB\Driver\BulkWrite::update' => ['void', 'filter'=>'object|array', 'newObj'=>'object|array', 'updateOptions='=>'?array'], 'MongoDB\Driver\ClientEncryption::__construct' => ['void', 'options'=>'array'], 'MongoDB\Driver\ClientEncryption::addKeyAltName' => ['?object', 'keyId'=>'MongoDB\BSON\Binary', 'keyAltName'=>'string'], 'MongoDB\Driver\ClientEncryption::createDataKey' => ['MongoDB\BSON\Binary', 'kmsProvider'=>'string', 'options='=>'?array'], 'MongoDB\Driver\ClientEncryption::decrypt' => ['mixed', 'value'=>'MongoDB\BSON\Binary'], 'MongoDB\Driver\ClientEncryption::deleteKey' => ['object', 'keyId'=>'MongoDB\BSON\Binary'], 'MongoDB\Driver\ClientEncryption::encrypt' => ['MongoDB\BSON\Binary', 'value'=>'mixed', 'options='=>'?array'], 'MongoDB\Driver\ClientEncryption::encryptExpression' => ['object', 'expr'=>'object|array', 'options='=>'?array'], 'MongoDB\Driver\ClientEncryption::getKey' => ['?object', 'keyId'=>'MongoDB\BSON\Binary'], 'MongoDB\Driver\ClientEncryption::getKeyByAltName' => ['?object', 'keyAltName'=>'string'], 'MongoDB\Driver\ClientEncryption::getKeys' => ['MongoDB\Driver\Cursor'], 'MongoDB\Driver\ClientEncryption::removeKeyAltName' => ['?object', 'keyId'=>'MongoDB\BSON\Binary', 'keyAltName'=>'string'], 'MongoDB\Driver\ClientEncryption::rewrapManyDataKey' => ['object', 'filter'=>'object|array', 'options='=>'?array'], 'MongoDB\Driver\Command::__construct' => ['void', 'document'=>'object|array', 'commandOptions='=>'?array'], 'MongoDB\Driver\Cursor::current' => ['object|array|null'], 'MongoDB\Driver\Cursor::getId' => ['MongoDB\Driver\CursorId'], 'MongoDB\Driver\Cursor::getServer' => ['MongoDB\Driver\Server'], 'MongoDB\Driver\Cursor::isDead' => ['bool'], 'MongoDB\Driver\Cursor::key' => ['?int'], 'MongoDB\Driver\Cursor::next' => ['void'], 'MongoDB\Driver\Cursor::rewind' => ['void'], 'MongoDB\Driver\Cursor::setTypeMap' => ['void', 'typemap'=>'array'], 'MongoDB\Driver\Cursor::toArray' => ['array'], 'MongoDB\Driver\Cursor::valid' => ['bool'], 'MongoDB\Driver\CursorId::__toString' => ['string'], 'MongoDB\Driver\CursorId::serialize' => ['string'], 'MongoDB\Driver\CursorId::unserialize' => ['void', 'data'=>'string'], 'MongoDB\Driver\CursorInterface::getId' => ['MongoDB\Driver\CursorId'], 'MongoDB\Driver\CursorInterface::getServer' => ['MongoDB\Driver\Server'], 'MongoDB\Driver\CursorInterface::isDead' => ['bool'], 'MongoDB\Driver\CursorInterface::setTypeMap' => ['void', 'typemap'=>'array'], 'MongoDB\Driver\CursorInterface::toArray' => ['array'], 'MongoDB\Driver\Exception\AuthenticationException::__toString' => ['string'], 'MongoDB\Driver\Exception\BulkWriteException::__toString' => ['string'], 'MongoDB\Driver\Exception\CommandException::getResultDocument' => ['object'], 'MongoDB\Driver\Exception\CommandException::__toString' => ['string'], 'MongoDB\Driver\Exception\ConnectionException::__toString' => ['string'], 'MongoDB\Driver\Exception\ConnectionTimeoutException::__toString' => ['string'], 'MongoDB\Driver\Exception\EncryptionException::__toString' => ['string'], 'MongoDB\Driver\Exception\Exception::__toString' => ['string'], 'MongoDB\Driver\Exception\ExecutionTimeoutException::__toString' => ['string'], 'MongoDB\Driver\Exception\InvalidArgumentException::__toString' => ['string'], 'MongoDB\Driver\Exception\LogicException::__toString' => ['string'], 'MongoDB\Driver\Exception\RuntimeException::hasErrorLabel' => ['bool', 'errorLabel'=>'string'], 'MongoDB\Driver\Exception\RuntimeException::__toString' => ['string'], 'MongoDB\Driver\Exception\SSLConnectionException::__toString' => ['string'], 'MongoDB\Driver\Exception\ServerException::__toString' => ['string'], 'MongoDB\Driver\Exception\UnexpectedValueException::__toString' => ['string'], 'MongoDB\Driver\Exception\WriteException::getWriteResult' => ['MongoDB\Driver\WriteResult'], 'MongoDB\Driver\Exception\WriteException::__toString' => ['string'], 'MongoDB\Driver\Manager::__construct' => ['void', 'uri='=>'?string', 'uriOptions='=>'?array', 'driverOptions='=>'?array'], 'MongoDB\Driver\Manager::addSubscriber' => ['void', 'subscriber'=>'MongoDB\Driver\Monitoring\Subscriber'], 'MongoDB\Driver\Manager::createClientEncryption' => ['MongoDB\Driver\ClientEncryption', 'options'=>'array'], 'MongoDB\Driver\Manager::executeBulkWrite' => ['MongoDB\Driver\WriteResult', 'namespace'=>'string', 'bulk'=>'MongoDB\Driver\BulkWrite', 'options='=>'MongoDB\Driver\WriteConcern|array|null'], 'MongoDB\Driver\Manager::executeCommand' => ['MongoDB\Driver\Cursor', 'db'=>'string', 'command'=>'MongoDB\Driver\Command', 'options='=>'MongoDB\Driver\ReadPreference|array|null'], 'MongoDB\Driver\Manager::executeQuery' => ['MongoDB\Driver\Cursor', 'namespace'=>'string', 'query'=>'MongoDB\Driver\Query', 'options='=>'MongoDB\Driver\ReadPreference|array|null'], 'MongoDB\Driver\Manager::executeReadCommand' => ['MongoDB\Driver\Cursor', 'db'=>'string', 'command'=>'MongoDB\Driver\Command', 'options='=>'?array'], 'MongoDB\Driver\Manager::executeReadWriteCommand' => ['MongoDB\Driver\Cursor', 'db'=>'string', 'command'=>'MongoDB\Driver\Command', 'options='=>'?array'], 'MongoDB\Driver\Manager::executeWriteCommand' => ['MongoDB\Driver\Cursor', 'db'=>'string', 'command'=>'MongoDB\Driver\Command', 'options='=>'?array'], 'MongoDB\Driver\Manager::getEncryptedFieldsMap' => ['object|array|null'], 'MongoDB\Driver\Manager::getReadConcern' => ['MongoDB\Driver\ReadConcern'], 'MongoDB\Driver\Manager::getReadPreference' => ['MongoDB\Driver\ReadPreference'], 'MongoDB\Driver\Manager::getServers' => ['array'], 'MongoDB\Driver\Manager::getWriteConcern' => ['MongoDB\Driver\WriteConcern'], 'MongoDB\Driver\Manager::removeSubscriber' => ['void', 'subscriber'=>'MongoDB\Driver\Monitoring\Subscriber'], 'MongoDB\Driver\Manager::selectServer' => ['MongoDB\Driver\Server', 'readPreference='=>'?MongoDB\Driver\ReadPreference'], 'MongoDB\Driver\Manager::startSession' => ['MongoDB\Driver\Session', 'options='=>'?array'], 'MongoDB\Driver\Monitoring\CommandFailedEvent::getCommandName' => ['string'], 'MongoDB\Driver\Monitoring\CommandFailedEvent::getDurationMicros' => ['int'], 'MongoDB\Driver\Monitoring\CommandFailedEvent::getError' => ['Exception'], 'MongoDB\Driver\Monitoring\CommandFailedEvent::getOperationId' => ['string'], 'MongoDB\Driver\Monitoring\CommandFailedEvent::getReply' => ['object'], 'MongoDB\Driver\Monitoring\CommandFailedEvent::getRequestId' => ['string'], 'MongoDB\Driver\Monitoring\CommandFailedEvent::getServer' => ['MongoDB\Driver\Server'], 'MongoDB\Driver\Monitoring\CommandFailedEvent::getServiceId' => ['?MongoDB\BSON\ObjectId'], 'MongoDB\Driver\Monitoring\CommandFailedEvent::getServerConnectionId' => ['?int'], 'MongoDB\Driver\Monitoring\CommandStartedEvent::getCommand' => ['object'], 'MongoDB\Driver\Monitoring\CommandStartedEvent::getCommandName' => ['string'], 'MongoDB\Driver\Monitoring\CommandStartedEvent::getDatabaseName' => ['string'], 'MongoDB\Driver\Monitoring\CommandStartedEvent::getOperationId' => ['string'], 'MongoDB\Driver\Monitoring\CommandStartedEvent::getRequestId' => ['string'], 'MongoDB\Driver\Monitoring\CommandStartedEvent::getServer' => ['MongoDB\Driver\Server'], 'MongoDB\Driver\Monitoring\CommandStartedEvent::getServiceId' => ['?MongoDB\BSON\ObjectId'], 'MongoDB\Driver\Monitoring\CommandStartedEvent::getServerConnectionId' => ['?int'], 'MongoDB\Driver\Monitoring\CommandSubscriber::commandStarted' => ['void', 'event'=>'MongoDB\Driver\Monitoring\CommandStartedEvent'], 'MongoDB\Driver\Monitoring\CommandSubscriber::commandSucceeded' => ['void', 'event'=>'MongoDB\Driver\Monitoring\CommandSucceededEvent'], 'MongoDB\Driver\Monitoring\CommandSubscriber::commandFailed' => ['void', 'event'=>'MongoDB\Driver\Monitoring\CommandFailedEvent'], 'MongoDB\Driver\Monitoring\CommandSucceededEvent::getCommandName' => ['string'], 'MongoDB\Driver\Monitoring\CommandSucceededEvent::getDurationMicros' => ['int'], 'MongoDB\Driver\Monitoring\CommandSucceededEvent::getOperationId' => ['string'], 'MongoDB\Driver\Monitoring\CommandSucceededEvent::getReply' => ['object'], 'MongoDB\Driver\Monitoring\CommandSucceededEvent::getRequestId' => ['string'], 'MongoDB\Driver\Monitoring\CommandSucceededEvent::getServer' => ['MongoDB\Driver\Server'], 'MongoDB\Driver\Monitoring\CommandSucceededEvent::getServiceId' => ['?MongoDB\BSON\ObjectId'], 'MongoDB\Driver\Monitoring\CommandSucceededEvent::getServerConnectionId' => ['?int'], 'MongoDB\Driver\Monitoring\LogSubscriber::log' => ['void', 'level'=>'int', 'domain'=>'string', 'message'=>'string'], 'MongoDB\Driver\Monitoring\SDAMSubscriber::serverChanged' => ['void', 'event'=>'MongoDB\Driver\Monitoring\ServerChangedEvent'], 'MongoDB\Driver\Monitoring\SDAMSubscriber::serverClosed' => ['void', 'event'=>'MongoDB\Driver\Monitoring\ServerClosedEvent'], 'MongoDB\Driver\Monitoring\SDAMSubscriber::serverOpening' => ['void', 'event'=>'MongoDB\Driver\Monitoring\ServerOpeningEvent'], 'MongoDB\Driver\Monitoring\SDAMSubscriber::serverHeartbeatFailed' => ['void', 'event'=>'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent'], 'MongoDB\Driver\Monitoring\SDAMSubscriber::serverHeartbeatStarted' => ['void', 'event'=>'MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent'], 'MongoDB\Driver\Monitoring\SDAMSubscriber::serverHeartbeatSucceeded' => ['void', 'event'=>'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent'], 'MongoDB\Driver\Monitoring\SDAMSubscriber::topologyChanged' => ['void', 'event'=>'MongoDB\Driver\Monitoring\TopologyChangedEvent'], 'MongoDB\Driver\Monitoring\SDAMSubscriber::topologyClosed' => ['void', 'event'=>'MongoDB\Driver\Monitoring\TopologyClosedEvent'], 'MongoDB\Driver\Monitoring\SDAMSubscriber::topologyOpening' => ['void', 'event'=>'MongoDB\Driver\Monitoring\TopologyOpeningEvent'], 'MongoDB\Driver\Monitoring\ServerChangedEvent::getPort' => ['int'], 'MongoDB\Driver\Monitoring\ServerChangedEvent::getHost' => ['string'], 'MongoDB\Driver\Monitoring\ServerChangedEvent::getNewDescription' => ['MongoDB\Driver\ServerDescription'], 'MongoDB\Driver\Monitoring\ServerChangedEvent::getPreviousDescription' => ['MongoDB\Driver\ServerDescription'], 'MongoDB\Driver\Monitoring\ServerChangedEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'], 'MongoDB\Driver\Monitoring\ServerClosedEvent::getPort' => ['int'], 'MongoDB\Driver\Monitoring\ServerClosedEvent::getHost' => ['string'], 'MongoDB\Driver\Monitoring\ServerClosedEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'], 'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::getDurationMicros' => ['int'], 'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::getError' => ['Exception'], 'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::getPort' => ['int'], 'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::getHost' => ['string'], 'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::isAwaited' => ['bool'], 'MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent::getPort' => ['int'], 'MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent::getHost' => ['string'], 'MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent::isAwaited' => ['bool'], 'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::getDurationMicros' => ['int'], 'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::getReply' => ['object'], 'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::getPort' => ['int'], 'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::getHost' => ['string'], 'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::isAwaited' => ['bool'], 'MongoDB\Driver\Monitoring\ServerOpeningEvent::getPort' => ['int'], 'MongoDB\Driver\Monitoring\ServerOpeningEvent::getHost' => ['string'], 'MongoDB\Driver\Monitoring\ServerOpeningEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'], 'MongoDB\Driver\Monitoring\TopologyChangedEvent::getNewDescription' => ['MongoDB\Driver\TopologyDescription'], 'MongoDB\Driver\Monitoring\TopologyChangedEvent::getPreviousDescription' => ['MongoDB\Driver\TopologyDescription'], 'MongoDB\Driver\Monitoring\TopologyChangedEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'], 'MongoDB\Driver\Monitoring\TopologyClosedEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'], 'MongoDB\Driver\Monitoring\TopologyOpeningEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'], 'MongoDB\Driver\Query::__construct' => ['void', 'filter'=>'object|array', 'queryOptions='=>'?array'], 'MongoDB\Driver\ReadConcern::__construct' => ['void', 'level='=>'?string'], 'MongoDB\Driver\ReadConcern::getLevel' => ['?string'], 'MongoDB\Driver\ReadConcern::isDefault' => ['bool'], 'MongoDB\Driver\ReadConcern::bsonSerialize' => ['stdClass'], 'MongoDB\Driver\ReadConcern::serialize' => ['string'], 'MongoDB\Driver\ReadConcern::unserialize' => ['void', 'data'=>'string'], 'MongoDB\Driver\ReadPreference::__construct' => ['void', 'mode'=>'string|int', 'tagSets='=>'?array', 'options='=>'?array'], 'MongoDB\Driver\ReadPreference::getHedge' => ['?object'], 'MongoDB\Driver\ReadPreference::getMaxStalenessSeconds' => ['int'], 'MongoDB\Driver\ReadPreference::getMode' => ['int'], 'MongoDB\Driver\ReadPreference::getModeString' => ['string'], 'MongoDB\Driver\ReadPreference::getTagSets' => ['array'], 'MongoDB\Driver\ReadPreference::bsonSerialize' => ['stdClass'], 'MongoDB\Driver\ReadPreference::serialize' => ['string'], 'MongoDB\Driver\ReadPreference::unserialize' => ['void', 'data'=>'string'], 'MongoDB\Driver\Server::executeBulkWrite' => ['MongoDB\Driver\WriteResult', 'namespace'=>'string', 'bulkWrite'=>'MongoDB\Driver\BulkWrite', 'options='=>'MongoDB\Driver\WriteConcern|array|null'], 'MongoDB\Driver\Server::executeCommand' => ['MongoDB\Driver\Cursor', 'db'=>'string', 'command'=>'MongoDB\Driver\Command', 'options='=>'MongoDB\Driver\ReadPreference|array|null'], 'MongoDB\Driver\Server::executeQuery' => ['MongoDB\Driver\Cursor', 'namespace'=>'string', 'query'=>'MongoDB\Driver\Query', 'options='=>'MongoDB\Driver\ReadPreference|array|null'], 'MongoDB\Driver\Server::executeReadCommand' => ['MongoDB\Driver\Cursor', 'db'=>'string', 'command'=>'MongoDB\Driver\Command', 'options='=>'?array'], 'MongoDB\Driver\Server::executeReadWriteCommand' => ['MongoDB\Driver\Cursor', 'db'=>'string', 'command'=>'MongoDB\Driver\Command', 'options='=>'?array'], 'MongoDB\Driver\Server::executeWriteCommand' => ['MongoDB\Driver\Cursor', 'db'=>'string', 'command'=>'MongoDB\Driver\Command', 'options='=>'?array'], 'MongoDB\Driver\Server::getHost' => ['string'], 'MongoDB\Driver\Server::getInfo' => ['array'], 'MongoDB\Driver\Server::getLatency' => ['?int'], 'MongoDB\Driver\Server::getPort' => ['int'], 'MongoDB\Driver\Server::getServerDescription' => ['MongoDB\Driver\ServerDescription'], 'MongoDB\Driver\Server::getTags' => ['array'], 'MongoDB\Driver\Server::getType' => ['int'], 'MongoDB\Driver\Server::isArbiter' => ['bool'], 'MongoDB\Driver\Server::isHidden' => ['bool'], 'MongoDB\Driver\Server::isPassive' => ['bool'], 'MongoDB\Driver\Server::isPrimary' => ['bool'], 'MongoDB\Driver\Server::isSecondary' => ['bool'], 'MongoDB\Driver\ServerApi::__construct' => ['void', 'version'=>'string', 'strict='=>'?bool', 'deprecationErrors='=>'?bool'], 'MongoDB\Driver\ServerApi::bsonSerialize' => ['stdClass'], 'MongoDB\Driver\ServerApi::serialize' => ['string'], 'MongoDB\Driver\ServerApi::unserialize' => ['void', 'data'=>'string'], 'MongoDB\Driver\ServerDescription::getHelloResponse' => ['array'], 'MongoDB\Driver\ServerDescription::getHost' => ['string'], 'MongoDB\Driver\ServerDescription::getLastUpdateTime' => ['int'], 'MongoDB\Driver\ServerDescription::getPort' => ['int'], 'MongoDB\Driver\ServerDescription::getRoundTripTime' => ['?int'], 'MongoDB\Driver\ServerDescription::getType' => ['string'], 'MongoDB\Driver\Session::abortTransaction' => ['void'], 'MongoDB\Driver\Session::advanceClusterTime' => ['void', 'clusterTime'=>'object|array'], 'MongoDB\Driver\Session::advanceOperationTime' => ['void', 'operationTime'=>'MongoDB\BSON\TimestampInterface'], 'MongoDB\Driver\Session::commitTransaction' => ['void'], 'MongoDB\Driver\Session::endSession' => ['void'], 'MongoDB\Driver\Session::getClusterTime' => ['?object'], 'MongoDB\Driver\Session::getLogicalSessionId' => ['object'], 'MongoDB\Driver\Session::getOperationTime' => ['?MongoDB\BSON\Timestamp'], 'MongoDB\Driver\Session::getServer' => ['?MongoDB\Driver\Server'], 'MongoDB\Driver\Session::getTransactionOptions' => ['?array'], 'MongoDB\Driver\Session::getTransactionState' => ['string'], 'MongoDB\Driver\Session::isDirty' => ['bool'], 'MongoDB\Driver\Session::isInTransaction' => ['bool'], 'MongoDB\Driver\Session::startTransaction' => ['void', 'options='=>'?array'], 'MongoDB\Driver\TopologyDescription::getServers' => ['array'], 'MongoDB\Driver\TopologyDescription::getType' => ['string'], 'MongoDB\Driver\TopologyDescription::hasReadableServer' => ['bool', 'readPreference='=>'?MongoDB\Driver\ReadPreference'], 'MongoDB\Driver\TopologyDescription::hasWritableServer' => ['bool'], 'MongoDB\Driver\WriteConcern::__construct' => ['void', 'w'=>'string|int', 'wtimeout='=>'?int', 'journal='=>'?bool'], 'MongoDB\Driver\WriteConcern::getJournal' => ['?bool'], 'MongoDB\Driver\WriteConcern::getW' => ['string|int|null'], 'MongoDB\Driver\WriteConcern::getWtimeout' => ['int'], 'MongoDB\Driver\WriteConcern::isDefault' => ['bool'], 'MongoDB\Driver\WriteConcern::bsonSerialize' => ['stdClass'], 'MongoDB\Driver\WriteConcern::serialize' => ['string'], 'MongoDB\Driver\WriteConcern::unserialize' => ['void', 'data'=>'string'], 'MongoDB\Driver\WriteConcernError::getCode' => ['int'], 'MongoDB\Driver\WriteConcernError::getInfo' => ['?object'], 'MongoDB\Driver\WriteConcernError::getMessage' => ['string'], 'MongoDB\Driver\WriteError::getCode' => ['int'], 'MongoDB\Driver\WriteError::getIndex' => ['int'], 'MongoDB\Driver\WriteError::getInfo' => ['?object'], 'MongoDB\Driver\WriteError::getMessage' => ['string'], 'MongoDB\Driver\WriteResult::getInsertedCount' => ['?int'], 'MongoDB\Driver\WriteResult::getMatchedCount' => ['?int'], 'MongoDB\Driver\WriteResult::getModifiedCount' => ['?int'], 'MongoDB\Driver\WriteResult::getDeletedCount' => ['?int'], 'MongoDB\Driver\WriteResult::getUpsertedCount' => ['?int'], 'MongoDB\Driver\WriteResult::getServer' => ['MongoDB\Driver\Server'], 'MongoDB\Driver\WriteResult::getUpsertedIds' => ['array'], 'MongoDB\Driver\WriteResult::getWriteConcernError' => ['?MongoDB\Driver\WriteConcernError'], 'MongoDB\Driver\WriteResult::getWriteErrors' => ['array'], 'MongoDB\Driver\WriteResult::getErrorReplies' => ['array'], 'MongoDB\Driver\WriteResult::isAcknowledged' => ['bool'], 'MongoDBRef::create' => ['array', 'collection'=>'string', 'id'=>'mixed', 'database='=>'string'], 'MongoDBRef::get' => ['array', 'db'=>'mongodb', 'ref'=>'array'], 'MongoDBRef::isRef' => ['bool', 'ref'=>'mixed'], 'MongoDeleteBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'write_options='=>'array'], 'MongoException::__clone' => ['void'], 'MongoException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Exception)|(?Throwable)'], 'MongoException::__toString' => ['string'], 'MongoException::__wakeup' => ['void'], 'MongoException::getCode' => ['int'], 'MongoException::getFile' => ['string'], 'MongoException::getLine' => ['int'], 'MongoException::getMessage' => ['string'], 'MongoException::getPrevious' => ['Exception|Throwable'], 'MongoException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'MongoException::getTraceAsString' => ['string'], 'MongoGridFS::__construct' => ['void', 'db'=>'MongoDB', 'prefix='=>'string', 'chunks='=>'mixed'], 'MongoGridFS::__get' => ['MongoCollection', 'name'=>'string'], 'MongoGridFS::__toString' => ['string'], 'MongoGridFS::aggregate' => ['array', 'pipeline'=>'array', 'op'=>'array', 'pipelineOperators'=>'array'], 'MongoGridFS::aggregateCursor' => ['MongoCommandCursor', 'pipeline'=>'array', 'options'=>'array'], 'MongoGridFS::batchInsert' => ['mixed', 'a'=>'array', 'options='=>'array'], 'MongoGridFS::count' => ['0|positive-int', 'query='=>'stdClass|array'], 'MongoGridFS::createDBRef' => ['array', 'a'=>'array'], 'MongoGridFS::createIndex' => ['array', 'keys'=>'array', 'options='=>'array'], 'MongoGridFS::delete' => ['bool', 'id'=>'mixed'], 'MongoGridFS::deleteIndex' => ['array', 'keys'=>'array|string'], 'MongoGridFS::deleteIndexes' => ['array'], 'MongoGridFS::distinct' => ['array|bool', 'key'=>'string', 'query='=>'?array'], 'MongoGridFS::drop' => ['array'], 'MongoGridFS::ensureIndex' => ['bool', 'keys'=>'array', 'options='=>'array'], 'MongoGridFS::find' => ['MongoGridFSCursor', 'query='=>'array', 'fields='=>'array'], 'MongoGridFS::findAndModify' => ['array', 'query'=>'array', 'update='=>'?array', 'fields='=>'?array', 'options='=>'?array'], 'MongoGridFS::findOne' => ['MongoGridFSFile', 'query='=>'mixed', 'fields='=>'mixed'], 'MongoGridFS::get' => ['MongoGridFSFile', 'id'=>'mixed'], 'MongoGridFS::getDBRef' => ['array', 'ref'=>'array'], 'MongoGridFS::getIndexInfo' => ['array'], 'MongoGridFS::getName' => ['string'], 'MongoGridFS::getReadPreference' => ['array'], 'MongoGridFS::getSlaveOkay' => ['bool'], 'MongoGridFS::group' => ['array', 'keys'=>'mixed', 'initial'=>'array', 'reduce'=>'MongoCode', 'condition='=>'array'], 'MongoGridFS::insert' => ['array|bool', 'a'=>'array|object', 'options='=>'array'], 'MongoGridFS::put' => ['mixed', 'filename'=>'string', 'extra='=>'array'], 'MongoGridFS::remove' => ['bool', 'criteria='=>'array', 'options='=>'array'], 'MongoGridFS::save' => ['array|bool', 'a'=>'array|object', 'options='=>'array'], 'MongoGridFS::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags'=>'array'], 'MongoGridFS::setSlaveOkay' => ['bool', 'ok='=>'bool|true'], 'MongoGridFS::storeBytes' => ['mixed', 'bytes'=>'string', 'extra='=>'array', 'options='=>'array'], 'MongoGridFS::storeFile' => ['mixed', 'filename'=>'string', 'extra='=>'array', 'options='=>'array'], 'MongoGridFS::storeUpload' => ['mixed', 'name'=>'string', 'filename='=>'string'], 'MongoGridFS::toIndexString' => ['string', 'keys'=>'mixed'], 'MongoGridFS::update' => ['bool', 'criteria'=>'array', 'newobj'=>'array', 'options='=>'array'], 'MongoGridFS::validate' => ['array', 'scan_data='=>'bool|false'], 'MongoGridFSCursor::__construct' => ['void', 'gridfs'=>'MongoGridFS', 'connection'=>'resource', 'ns'=>'string', 'query'=>'array', 'fields'=>'array'], 'MongoGridFSCursor::addOption' => ['MongoCursor', 'key'=>'string', 'value'=>'mixed'], 'MongoGridFSCursor::awaitData' => ['MongoCursor', 'wait='=>'bool|true'], 'MongoGridFSCursor::batchSize' => ['MongoCursor', 'batchSize'=>'int'], 'MongoGridFSCursor::count' => ['0|positive-int', 'all='=>'bool|false'], 'MongoGridFSCursor::current' => ['MongoGridFSFile'], 'MongoGridFSCursor::dead' => ['bool'], 'MongoGridFSCursor::doQuery' => ['void'], 'MongoGridFSCursor::explain' => ['array'], 'MongoGridFSCursor::fields' => ['MongoCursor', 'f'=>'array'], 'MongoGridFSCursor::getNext' => ['MongoGridFSFile'], 'MongoGridFSCursor::getReadPreference' => ['array'], 'MongoGridFSCursor::hasNext' => ['bool'], 'MongoGridFSCursor::hint' => ['MongoCursor', 'key_pattern'=>'mixed'], 'MongoGridFSCursor::immortal' => ['MongoCursor', 'liveForever='=>'bool|true'], 'MongoGridFSCursor::info' => ['array'], 'MongoGridFSCursor::key' => ['string'], 'MongoGridFSCursor::limit' => ['MongoCursor', 'num'=>'int'], 'MongoGridFSCursor::maxTimeMS' => ['MongoCursor', 'ms'=>'int'], 'MongoGridFSCursor::next' => ['void'], 'MongoGridFSCursor::partial' => ['MongoCursor', 'okay='=>'bool|true'], 'MongoGridFSCursor::reset' => ['void'], 'MongoGridFSCursor::rewind' => ['void'], 'MongoGridFSCursor::setFlag' => ['MongoCursor', 'flag'=>'int', 'set='=>'bool|true'], 'MongoGridFSCursor::setReadPreference' => ['MongoCursor', 'read_preference'=>'string', 'tags'=>'array'], 'MongoGridFSCursor::skip' => ['MongoCursor', 'num'=>'int'], 'MongoGridFSCursor::slaveOkay' => ['MongoCursor', 'okay='=>'bool|true'], 'MongoGridFSCursor::snapshot' => ['MongoCursor'], 'MongoGridFSCursor::sort' => ['MongoCursor', 'fields'=>'array'], 'MongoGridFSCursor::tailable' => ['MongoCursor', 'tail='=>'bool|true'], 'MongoGridFSCursor::timeout' => ['MongoCursor', 'ms'=>'int'], 'MongoGridFSCursor::valid' => ['bool'], 'MongoGridfsFile::__construct' => ['void', 'gridfs'=>'MongoGridFS', 'file'=>'array'], 'MongoGridFSFile::getBytes' => ['string'], 'MongoGridFSFile::getFilename' => ['string'], 'MongoGridFSFile::getResource' => ['resource'], 'MongoGridFSFile::getSize' => ['int'], 'MongoGridFSFile::write' => ['int', 'filename='=>'string'], 'MongoId::__construct' => ['void', 'id='=>'string|MongoId'], 'MongoId::__set_state' => ['MongoId', 'props'=>'array'], 'MongoId::__toString' => ['string'], 'MongoId::getHostname' => ['string'], 'MongoId::getInc' => ['int'], 'MongoId::getPID' => ['int'], 'MongoId::getTimestamp' => ['int'], 'MongoId::isValid' => ['bool', 'value'=>'mixed'], 'MongoInsertBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'write_options='=>'array'], 'MongoInt32::__construct' => ['void', 'value'=>'string'], 'MongoInt32::__toString' => ['string'], 'MongoInt64::__construct' => ['void', 'value'=>'string'], 'MongoInt64::__toString' => ['string'], 'MongoLog::getCallback' => ['callable'], 'MongoLog::getLevel' => ['int'], 'MongoLog::getModule' => ['int'], 'MongoLog::setCallback' => ['bool', 'log_function'=>'callable'], 'MongoLog::setLevel' => ['void', 'level'=>'int'], 'MongoLog::setModule' => ['void', 'module'=>'int'], 'MongoPool::getSize' => ['int'], 'MongoPool::info' => ['array'], 'MongoPool::setSize' => ['bool', 'size'=>'int'], 'MongoRegex::__construct' => ['void', 'regex'=>'string'], 'MongoRegex::__toString' => ['string'], 'MongoResultException::__clone' => ['void'], 'MongoResultException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Exception)|(?Throwable)'], 'MongoResultException::__toString' => ['string'], 'MongoResultException::__wakeup' => ['void'], 'MongoResultException::getCode' => ['int'], 'MongoResultException::getDocument' => ['array'], 'MongoResultException::getFile' => ['string'], 'MongoResultException::getLine' => ['int'], 'MongoResultException::getMessage' => ['string'], 'MongoResultException::getPrevious' => ['Exception|Throwable'], 'MongoResultException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'MongoResultException::getTraceAsString' => ['string'], 'MongoTimestamp::__construct' => ['void', 'sec='=>'int', 'inc='=>'int'], 'MongoTimestamp::__toString' => ['string'], 'MongoUpdateBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'write_options='=>'array'], 'MongoUpdateBatch::add' => ['bool', 'item'=>'array'], 'MongoUpdateBatch::execute' => ['array', 'write_options'=>'array'], 'MongoWriteBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'batch_type'=>'string', 'write_options'=>'array'], 'MongoWriteBatch::add' => ['bool', 'item'=>'array'], 'MongoWriteBatch::execute' => ['array', 'write_options'=>'array'], 'MongoWriteConcernException::__clone' => ['void'], 'MongoWriteConcernException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Exception)|(?Throwable)'], 'MongoWriteConcernException::__toString' => ['string'], 'MongoWriteConcernException::__wakeup' => ['void'], 'MongoWriteConcernException::getCode' => ['int'], 'MongoWriteConcernException::getDocument' => ['array'], 'MongoWriteConcernException::getFile' => ['string'], 'MongoWriteConcernException::getLine' => ['int'], 'MongoWriteConcernException::getMessage' => ['string'], 'MongoWriteConcernException::getPrevious' => ['Exception|Throwable'], 'MongoWriteConcernException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'MongoWriteConcernException::getTraceAsString' => ['string'], 'monitor_custom_event' => ['void', 'class'=>'string', 'text'=>'string', 'severe='=>'int', 'user_data='=>'mixed'], 'monitor_httperror_event' => ['void', 'error_code'=>'int', 'url'=>'string', 'severe='=>'int'], 'monitor_license_info' => ['array'], 'monitor_pass_error' => ['void', 'errno'=>'int', 'errstr'=>'string', 'errfile'=>'string', 'errline'=>'int'], 'monitor_set_aggregation_hint' => ['void', 'hint'=>'string'], 'move_uploaded_file' => ['bool', 'path'=>'string', 'new_path'=>'string'], 'mqseries_back' => ['void', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_begin' => ['void', 'hconn'=>'resource', 'beginoptions'=>'array', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_close' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'options'=>'int', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_cmit' => ['void', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_conn' => ['void', 'qmanagername'=>'string', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_connx' => ['void', 'qmanagername'=>'string', 'connoptions'=>'array', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_disc' => ['void', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_get' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'md'=>'array', 'gmo'=>'array', 'bufferlength'=>'int', 'msg'=>'string', 'data_length'=>'int', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_inq' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'selectorcount'=>'int', 'selectors'=>'array', 'intattrcount'=>'int', 'intattr'=>'resource', 'charattrlength'=>'int', 'charattr'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_open' => ['void', 'hconn'=>'resource', 'objdesc'=>'array', 'option'=>'int', 'hobj'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_put' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'md'=>'array', 'pmo'=>'array', 'message'=>'string', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_put1' => ['void', 'hconn'=>'resource', 'objdesc'=>'resource', 'msgdesc'=>'resource', 'pmo'=>'resource', 'buffer'=>'string', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_set' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'selectorcount'=>'int', 'selectors'=>'array', 'intattrcount'=>'int', 'intattrs'=>'array', 'charattrlength'=>'int', 'charattrs'=>'array', 'compcode'=>'resource', 'reason'=>'resource'], 'mqseries_strerror' => ['string', 'reason'=>'int'], 'ms_GetErrorObj' => ['errorObj'], 'ms_GetVersion' => ['string'], 'ms_GetVersionInt' => ['int'], 'ms_iogetStdoutBufferBytes' => ['int'], 'ms_iogetstdoutbufferstring' => ['void'], 'ms_ioinstallstdinfrombuffer' => ['void'], 'ms_ioinstallstdouttobuffer' => ['void'], 'ms_ioresethandlers' => ['void'], 'ms_iostripstdoutbuffercontentheaders' => ['void'], 'ms_iostripstdoutbuffercontenttype' => ['string'], 'ms_ResetErrorList' => ['void'], 'ms_TokenizeMap' => ['array', 'map_file_name'=>'string'], 'msession_connect' => ['bool', 'host'=>'string', 'port'=>'string'], 'msession_count' => ['int'], 'msession_create' => ['bool', 'session'=>'string', 'classname='=>'string', 'data='=>'string'], 'msession_destroy' => ['bool', 'name'=>'string'], 'msession_disconnect' => ['void'], 'msession_find' => ['array', 'name'=>'string', 'value'=>'string'], 'msession_get' => ['string', 'session'=>'string', 'name'=>'string', 'value'=>'string'], 'msession_get_array' => ['array', 'session'=>'string'], 'msession_get_data' => ['string', 'session'=>'string'], 'msession_inc' => ['string', 'session'=>'string', 'name'=>'string'], 'msession_list' => ['array'], 'msession_listvar' => ['array', 'name'=>'string'], 'msession_lock' => ['int', 'name'=>'string'], 'msession_plugin' => ['string', 'session'=>'string', 'val'=>'string', 'param='=>'string'], 'msession_randstr' => ['string', 'param'=>'int'], 'msession_set' => ['bool', 'session'=>'string', 'name'=>'string', 'value'=>'string'], 'msession_set_array' => ['void', 'session'=>'string', 'tuples'=>'array'], 'msession_set_data' => ['bool', 'session'=>'string', 'value'=>'string'], 'msession_timeout' => ['int', 'session'=>'string', 'param='=>'int'], 'msession_uniq' => ['string', 'param'=>'int', 'classname='=>'string', 'data='=>'string'], 'msession_unlock' => ['int', 'session'=>'string', 'key'=>'int'], 'msg_get_queue' => ['resource|false', 'key'=>'int', 'perms='=>'int'], 'msg_queue_exists' => ['bool', 'key'=>'int'], 'msg_receive' => ['bool', 'queue'=>'resource', 'desiredmsgtype'=>'int', '&w_msgtype'=>'int', 'maxsize'=>'int', '&w_message'=>'mixed', 'unserialize='=>'bool', 'flags='=>'int', '&w_errorcode='=>'int'], 'msg_remove_queue' => ['bool', 'queue'=>'resource'], 'msg_send' => ['bool', 'queue'=>'resource', 'msgtype'=>'int', 'message'=>'mixed', 'serialize='=>'bool', 'blocking='=>'bool', '&w_errorcode='=>'int'], 'msg_set_queue' => ['bool', 'queue'=>'resource', 'data'=>'array'], 'msg_stat_queue' => ['array|false', 'queue'=>'resource'], 'msgfmt_create' => ['MessageFormatter', 'locale'=>'string', 'pattern'=>'string'], 'msgfmt_format' => ['string|false', 'fmt'=>'messageformatter', 'args'=>'array'], 'msgfmt_format_message' => ['string|false', 'locale'=>'string', 'pattern'=>'string', 'args'=>'array'], 'msgfmt_get_error_code' => ['int', 'fmt'=>'messageformatter'], 'msgfmt_get_error_message' => ['string', 'fmt'=>'messageformatter'], 'msgfmt_get_locale' => ['string', 'formatter'=>'messageformatter'], 'msgfmt_get_pattern' => ['string|false', 'fmt'=>'messageformatter'], 'msgfmt_parse' => ['array|false', 'fmt'=>'messageformatter', 'value'=>'string'], 'msgfmt_parse_message' => ['array|false', 'locale'=>'string', 'pattern'=>'string', 'source'=>'string'], 'msgfmt_set_pattern' => ['bool', 'fmt'=>'messageformatter', 'pattern'=>'string'], 'msql_affected_rows' => ['int', 'result'=>'resource'], 'msql_close' => ['bool', 'link_identifier='=>'?resource'], 'msql_connect' => ['resource', 'hostname='=>'string'], 'msql_create_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'], 'msql_data_seek' => ['bool', 'result'=>'resource', 'row_number'=>'int'], 'msql_db_query' => ['resource', 'database'=>'string', 'query'=>'string', 'link_identifier='=>'?resource'], 'msql_drop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'], 'msql_error' => ['string'], 'msql_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'], 'msql_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'], 'msql_fetch_object' => ['object', 'result'=>'resource'], 'msql_fetch_row' => ['array', 'result'=>'resource'], 'msql_field_flags' => ['string', 'result'=>'resource', 'field_offset'=>'int'], 'msql_field_len' => ['int', 'result'=>'resource', 'field_offset'=>'int'], 'msql_field_name' => ['string', 'result'=>'resource', 'field_offset'=>'int'], 'msql_field_seek' => ['bool', 'result'=>'resource', 'field_offset'=>'int'], 'msql_field_table' => ['int', 'result'=>'resource', 'field_offset'=>'int'], 'msql_field_type' => ['string', 'result'=>'resource', 'field_offset'=>'int'], 'msql_free_result' => ['bool', 'result'=>'resource'], 'msql_list_dbs' => ['resource', 'link_identifier='=>'?resource'], 'msql_list_fields' => ['resource', 'database'=>'string', 'tablename'=>'string', 'link_identifier='=>'?resource'], 'msql_list_tables' => ['resource', 'database'=>'string', 'link_identifier='=>'?resource'], 'msql_num_fields' => ['int', 'result'=>'resource'], 'msql_num_rows' => ['int', 'query_identifier'=>'resource'], 'msql_pconnect' => ['resource', 'hostname='=>'string'], 'msql_query' => ['resource', 'query'=>'string', 'link_identifier='=>'?resource'], 'msql_result' => ['string', 'result'=>'resource', 'row'=>'int', 'field='=>'mixed'], 'msql_select_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'], 'mssql_bind' => ['bool', 'stmt'=>'resource', 'param_name'=>'string', 'var'=>'mixed', 'type'=>'int', 'is_output='=>'bool', 'is_null='=>'bool', 'maxlen='=>'int'], 'mssql_close' => ['bool', 'link_identifier='=>'resource'], 'mssql_connect' => ['resource', 'servername='=>'string', 'username='=>'string', 'password='=>'string', 'new_link='=>'bool'], 'mssql_data_seek' => ['bool', 'result_identifier'=>'resource', 'row_number'=>'int'], 'mssql_execute' => ['mixed', 'stmt'=>'resource', 'skip_results='=>'bool'], 'mssql_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'], 'mssql_fetch_assoc' => ['array', 'result_id'=>'resource'], 'mssql_fetch_batch' => ['int', 'result'=>'resource'], 'mssql_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'], 'mssql_fetch_object' => ['object', 'result'=>'resource'], 'mssql_fetch_row' => ['array', 'result'=>'resource'], 'mssql_field_length' => ['int', 'result'=>'resource', 'offset='=>'int'], 'mssql_field_name' => ['string', 'result'=>'resource', 'offset='=>'int'], 'mssql_field_seek' => ['bool', 'result'=>'resource', 'field_offset'=>'int'], 'mssql_field_type' => ['string', 'result'=>'resource', 'offset='=>'int'], 'mssql_free_result' => ['bool', 'result'=>'resource'], 'mssql_free_statement' => ['bool', 'stmt'=>'resource'], 'mssql_get_last_message' => ['string'], 'mssql_guid_string' => ['string', 'binary'=>'string', 'short_format='=>'bool'], 'mssql_init' => ['resource', 'sp_name'=>'string', 'link_identifier='=>'resource'], 'mssql_min_error_severity' => ['void', 'severity'=>'int'], 'mssql_min_message_severity' => ['void', 'severity'=>'int'], 'mssql_next_result' => ['bool', 'result_id'=>'resource'], 'mssql_num_fields' => ['int', 'result'=>'resource'], 'mssql_num_rows' => ['int', 'result'=>'resource'], 'mssql_pconnect' => ['resource', 'servername='=>'string', 'username='=>'string', 'password='=>'string', 'new_link='=>'bool'], 'mssql_query' => ['mixed', 'query'=>'string', 'link_identifier='=>'resource', 'batch_size='=>'int'], 'mssql_result' => ['string', 'result'=>'resource', 'row'=>'int', 'field'=>'mixed'], 'mssql_rows_affected' => ['int', 'link_identifier'=>'resource'], 'mssql_select_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'resource'], 'mt_getrandmax' => ['int'], 'mt_rand' => ['int', 'min'=>'int', 'max'=>'int'], 'mt_rand\'1' => ['int'], 'mt_srand' => ['void', 'seed='=>'int', 'mode='=>'int'], 'MultipleIterator::__construct' => ['void', 'flags='=>'int'], 'MultipleIterator::attachIterator' => ['void', 'iterator'=>'Iterator', 'infos='=>'string'], 'MultipleIterator::containsIterator' => ['bool', 'iterator'=>'Iterator'], 'MultipleIterator::countIterators' => ['int'], 'MultipleIterator::current' => ['array'], 'MultipleIterator::detachIterator' => ['void', 'iterator'=>'Iterator'], 'MultipleIterator::getFlags' => ['int'], 'MultipleIterator::key' => ['array'], 'MultipleIterator::next' => ['void'], 'MultipleIterator::rewind' => ['void'], 'MultipleIterator::setFlags' => ['int', 'flags'=>'int'], 'MultipleIterator::valid' => ['bool'], 'mysql_affected_rows' => ['int', 'link_identifier='=>'resource'], 'mysql_client_encoding' => ['string', 'link_identifier='=>'resource'], 'mysql_close' => ['bool', 'link_identifier='=>'resource'], 'mysql_connect' => ['resource|false', 'server='=>'string', 'username='=>'string', 'password='=>'string', 'new_link='=>'bool', 'client_flags='=>'int'], 'mysql_create_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'resource'], 'mysql_data_seek' => ['bool', 'result'=>'resource', 'row_number'=>'int'], 'mysql_db_name' => ['string|false', 'result'=>'resource', 'row'=>'int', 'field='=>'mixed'], 'mysql_db_query' => ['resource|bool', 'database'=>'string', 'query'=>'string', 'link_identifier='=>'resource'], 'mysql_drop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'resource'], 'mysql_errno' => ['int', 'link_identifier='=>'resource'], 'mysql_error' => ['string', 'link_identifier='=>'resource'], 'mysql_escape_string' => ['string', 'unescaped_string'=>'string'], 'mysql_fetch_array' => ['array|false', 'result'=>'resource', 'result_type='=>'int'], 'mysql_fetch_assoc' => ['array|false', 'result'=>'resource'], 'mysql_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'], 'mysql_fetch_lengths' => ['array|false', 'result'=>'resource'], 'mysql_fetch_object' => ['object|false', 'result'=>'resource', 'class_name='=>'string', 'params='=>'array'], 'mysql_fetch_row' => ['array|false', 'result'=>'resource'], 'mysql_field_flags' => ['string|false', 'result'=>'resource', 'field_offset'=>'int'], 'mysql_field_len' => ['int|false', 'result'=>'resource', 'field_offset'=>'int'], 'mysql_field_name' => ['string|false', 'result'=>'resource', 'field_offset'=>'int'], 'mysql_field_seek' => ['bool', 'result'=>'resource', 'field_offset'=>'int'], 'mysql_field_table' => ['string', 'result'=>'resource', 'field_offset'=>'int'], 'mysql_field_type' => ['string', 'result'=>'resource', 'field_offset'=>'int'], 'mysql_free_result' => ['bool', 'result'=>'resource'], 'mysql_get_client_info' => ['string'], 'mysql_get_host_info' => ['string|false', 'link_identifier='=>'resource'], 'mysql_get_proto_info' => ['int|false', 'link_identifier='=>'resource'], 'mysql_get_server_info' => ['string|false', 'link_identifier='=>'resource'], 'mysql_info' => ['string|false', 'link_identifier='=>'resource'], 'mysql_insert_id' => ['int|false', 'link_identifier='=>'resource'], 'mysql_list_dbs' => ['resource|false', 'link_identifier='=>'resource'], 'mysql_list_fields' => ['resource|false', 'database_name'=>'string', 'table_name'=>'string', 'link_identifier='=>'resource'], 'mysql_list_processes' => ['resource|false', 'link_identifier='=>'resource'], 'mysql_list_tables' => ['resource', 'database'=>'string', 'link_identifier='=>'resource'], 'mysql_num_fields' => ['int|false', 'result'=>'resource'], 'mysql_num_rows' => ['int|false', 'result'=>'resource'], 'mysql_pconnect' => ['resource|false', 'server='=>'string', 'username='=>'string', 'password='=>'string', 'client_flags='=>'int'], 'mysql_ping' => ['bool', 'link_identifier='=>'resource'], 'mysql_query' => ['resource|bool', 'query'=>'string', 'link_identifier='=>'resource'], 'mysql_real_escape_string' => ['string|false', 'unescaped_string'=>'string', 'link_identifier='=>'resource'], 'mysql_result' => ['string|false', 'result'=>'resource', 'row'=>'int', 'field='=>'mixed'], 'mysql_select_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'resource'], 'mysql_set_charset' => ['bool', 'charset'=>'string', 'link_identifier='=>'resource'], 'mysql_stat' => ['string|null', 'link_identifier='=>'resource'], 'mysql_tablename' => ['string|false', 'result'=>'resource', 'i'=>'int'], 'mysql_thread_id' => ['int|false', 'link_identifier='=>'resource'], 'mysql_unbuffered_query' => ['resource|bool', 'query'=>'string', 'link_identifier='=>'resource'], 'mysqli::__construct' => ['void', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'], 'mysqli::autocommit' => ['bool', 'mode'=>'bool'], 'mysqli::begin_transaction' => ['bool', 'flags='=>'int', 'name='=>'string'], 'mysqli::change_user' => ['bool', 'user'=>'string', 'password'=>'string', 'database'=>'string'], 'mysqli::character_set_name' => ['string'], 'mysqli::close' => ['bool'], 'mysqli::commit' => ['bool', 'flags='=>'int', 'name='=>'string'], 'mysqli::debug' => ['bool', 'message'=>'string'], 'mysqli::disable_reads_from_master' => ['bool'], 'mysqli::dump_debug_info' => ['bool'], 'mysqli::get_charset' => ['object'], 'mysqli::get_client_info' => ['string'], 'mysqli::get_connection_stats' => ['array|false'], 'mysqli::get_warnings' => ['mysqli_warning|false'], 'mysqli::init' => ['mysqli'], 'mysqli::kill' => ['bool', 'processid'=>'int'], 'mysqli::more_results' => ['bool'], 'mysqli::multi_query' => ['bool', 'query'=>'string'], 'mysqli::next_result' => ['bool'], 'mysqli::options' => ['bool', 'option'=>'int', 'value'=>'mixed'], 'mysqli::ping' => ['bool'], 'mysqli::poll' => ['int|false', '&w_read'=>'array', '&w_error'=>'array', '&w_reject'=>'array', 'sec'=>'int', 'usec='=>'int'], 'mysqli::prepare' => ['mysqli_stmt|false', 'query'=>'string'], 'mysqli::query' => ['bool|mysqli_result', 'query'=>'string', 'resultmode='=>'int'], 'mysqli::real_connect' => ['bool', 'host='=>'?string', 'username='=>'?string', 'passwd='=>'?string', 'dbname='=>'?string', 'port='=>'?int', 'socket='=>'?string', 'flags='=>'int'], 'mysqli::real_escape_string' => ['string', 'escapestr'=>'string'], 'mysqli::real_query' => ['bool', 'query'=>'string'], 'mysqli::reap_async_query' => ['mysqli_result|false'], 'mysqli::refresh' => ['bool', 'options'=>'int'], 'mysqli::release_savepoint' => ['bool', 'name'=>'string'], 'mysqli::rollback' => ['bool', 'flags='=>'int', 'name='=>'string'], 'mysqli::rpl_query_type' => ['int', 'query'=>'string'], 'mysqli::savepoint' => ['bool', 'name'=>'string'], 'mysqli::select_db' => ['bool', 'dbname'=>'string'], 'mysqli::send_query' => ['bool', 'query'=>'string'], 'mysqli::set_charset' => ['bool', 'charset'=>'string'], 'mysqli::set_local_infile_default' => ['void'], 'mysqli::set_local_infile_handler' => ['bool', 'read_func='=>'callable'], 'mysqli::ssl_set' => ['bool', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'], 'mysqli::stat' => ['string|false'], 'mysqli::stmt_init' => ['mysqli_stmt'], 'mysqli::store_result' => ['mysqli_result|false', 'option='=>'int'], 'mysqli::thread_safe' => ['bool'], 'mysqli::use_result' => ['mysqli_result|false'], 'mysqli_affected_rows' => ['int<-1,max>|numeric-string', 'link'=>'mysqli'], 'mysqli_autocommit' => ['bool', 'link'=>'mysqli', 'mode'=>'bool'], 'mysqli_begin_transaction' => ['bool', 'link'=>'mysqli', 'flags='=>'int', 'name='=>'string'], 'mysqli_change_user' => ['bool', 'link'=>'mysqli', 'user'=>'string', 'password'=>'string', 'database'=>'string'], 'mysqli_character_set_name' => ['string', 'link'=>'mysqli'], 'mysqli_close' => ['bool', 'link'=>'mysqli'], 'mysqli_commit' => ['bool', 'link'=>'mysqli', 'flags='=>'int', 'name='=>'string'], 'mysqli_connect' => ['mysqli|false|null', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'], 'mysqli_connect_errno' => ['int'], 'mysqli_connect_error' => ['string|null'], 'mysqli_data_seek' => ['bool', 'result'=>'mysqli_result', 'offset'=>'int'], 'mysqli_debug' => ['bool', 'message'=>'string'], 'mysqli_disable_reads_from_master' => ['bool', 'link'=>'mysqli'], 'mysqli_disable_rpl_parse' => ['bool', 'link'=>'mysqli'], 'mysqli_driver::embedded_server_end' => ['void'], 'mysqli_driver::embedded_server_start' => ['bool', 'start'=>'int', 'arguments'=>'array', 'groups'=>'array'], 'mysqli_dump_debug_info' => ['bool', 'link'=>'mysqli'], 'mysqli_embedded_server_end' => ['void'], 'mysqli_embedded_server_start' => ['bool', 'start'=>'int', 'arguments'=>'array', 'groups'=>'array'], 'mysqli_enable_reads_from_master' => ['bool', 'link'=>'mysqli'], 'mysqli_enable_rpl_parse' => ['bool', 'link'=>'mysqli'], 'mysqli_errno' => ['int', 'link'=>'mysqli'], 'mysqli_error' => ['string|null', 'link'=>'mysqli'], 'mysqli_error_list' => ['array', 'connection'=>'mysqli'], 'mysqli_fetch_all' => ['array', 'result'=>'mysqli_result', 'resulttype='=>'int'], 'mysqli_fetch_array' => ['array|null|false', 'result'=>'mysqli_result', 'resulttype='=>'int'], 'mysqli_fetch_assoc' => ['array|null|false', 'result'=>'mysqli_result'], 'mysqli_fetch_column' => ['null|int|float|string|false', 'result' => 'mysqli_result', 'column'=>'int'], 'mysqli_fetch_field' => ['(stdClass&object{name: string, orgname: string, table: string, orgtable: string, def: string, db: string, catalog: "def", max_length: int, length: int, charsetnr: string, flags: int, type: int, decimals: int})|false', 'result'=>'mysqli_result'], 'mysqli_fetch_field_direct' => ['(stdClass&object{name: string, orgname: string, table: string, orgtable: string, def: string, db: string, catalog: "def", max_length: int, length: int, charsetnr: string, flags: int, type: int, decimals: int})|false', 'result'=>'mysqli_result', 'fieldnr'=>'int'], 'mysqli_fetch_fields' => ['list', 'result'=>'mysqli_result'], 'mysqli_fetch_lengths' => ['array|false', 'result'=>'mysqli_result'], 'mysqli_fetch_object' => ['object|false|null', 'result'=>'mysqli_result', 'class_name='=>'string', 'params='=>'?array'], 'mysqli_fetch_row' => ['array|null', 'result'=>'mysqli_result'], 'mysqli_field_count' => ['int', 'link'=>'mysqli'], 'mysqli_field_seek' => ['bool', 'result'=>'mysqli_result', 'fieldnr'=>'int'], 'mysqli_field_tell' => ['int', 'result'=>'mysqli_result'], 'mysqli_free_result' => ['void', 'link'=>'mysqli_result'], 'mysqli_get_cache_stats' => ['array'], 'mysqli_get_charset' => ['object', 'link'=>'mysqli'], 'mysqli_get_client_info' => ['string', 'link='=>'mysqli'], 'mysqli_get_client_stats' => ['array|false'], 'mysqli_get_client_version' => ['int'], 'mysqli_get_connection_stats' => ['array|false', 'link'=>'mysqli'], 'mysqli_get_host_info' => ['string', 'link'=>'mysqli'], 'mysqli_get_links_stats' => ['array'], 'mysqli_get_proto_info' => ['int', 'link'=>'mysqli'], 'mysqli_get_server_info' => ['string', 'link'=>'mysqli'], 'mysqli_get_server_version' => ['int', 'link'=>'mysqli'], 'mysqli_get_warnings' => ['mysqli_warning|false', 'link'=>'mysqli'], 'mysqli_info' => ['?string', 'link'=>'mysqli'], 'mysqli_init' => ['mysqli|false'], 'mysqli_insert_id' => ['int|string', 'link'=>'mysqli'], 'mysqli_kill' => ['bool', 'link'=>'mysqli', 'processid'=>'int'], 'mysqli_link_construct' => ['object'], 'mysqli_master_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'], 'mysqli_more_results' => ['bool', 'link'=>'mysqli'], 'mysqli_multi_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'], 'mysqli_next_result' => ['bool', 'link'=>'mysqli'], 'mysqli_num_fields' => ['int', 'link'=>'mysqli_result'], 'mysqli_num_rows' => ['int<0,max>|numeric-string', 'link'=>'mysqli_result'], 'mysqli_options' => ['bool', 'link'=>'mysqli', 'option'=>'int', 'value'=>'mixed'], 'mysqli_ping' => ['bool', 'link'=>'mysqli'], 'mysqli_poll' => ['int|false', 'read'=>'array', 'error'=>'array', 'reject'=>'array', 'sec'=>'int', 'usec='=>'int'], 'mysqli_prepare' => ['mysqli_stmt|false', 'link'=>'mysqli', 'query'=>'string'], 'mysqli_query' => ['mysqli_result|bool', 'link'=>'mysqli', 'query'=>'string', 'resultmode='=>'int'], 'mysqli_real_connect' => ['bool', 'link='=>'mysqli', 'host='=>'?string', 'username='=>'?string', 'passwd='=>'?string', 'dbname='=>'?string', 'port='=>'?int', 'socket='=>'?string', 'flags='=>'int'], 'mysqli_real_escape_string' => ['string', 'link'=>'mysqli', 'escapestr'=>'string'], 'mysqli_real_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'], 'mysqli_reap_async_query' => ['mysqli_result|false', 'link'=>'mysqli'], 'mysqli_refresh' => ['bool', 'link'=>'mysqli', 'options'=>'int'], 'mysqli_release_savepoint' => ['bool', 'link'=>'mysqli', 'name'=>'string'], 'mysqli_report' => ['bool', 'flags'=>'int'], 'mysqli_result::__construct' => ['void', 'link'=>'mysqli', 'resultmode='=>'int'], 'mysqli_result::close' => ['void'], 'mysqli_result::data_seek' => ['bool', 'offset'=>'int'], 'mysqli_result::fetch_all' => ['array', 'resulttype='=>'int'], 'mysqli_result::fetch_array' => ['array|null|false', 'resulttype='=>'int'], 'mysqli_result::fetch_assoc' => ['array|null|false'], 'mysqli_result::fetch_column' => ['null|int|float|string|false', 'column'=>'int'], 'mysqli_result::fetch_field' => ['(stdClass&object{name: string, orgname: string, table: string, orgtable: string, def: string, db: string, catalog: "def", max_length: int, length: int, charsetnr: string, flags: int, type: int, decimals: int})|false'], 'mysqli_result::fetch_field_direct' => ['(stdClass&object{name: string, orgname: string, table: string, orgtable: string, def: string, db: string, catalog: "def", max_length: int, length: int, charsetnr: string, flags: int, type: int, decimals: int})|false', 'fieldnr'=>'int'], 'mysqli_result::fetch_fields' => ['list'], 'mysqli_result::fetch_object' => ['object|null', 'class_name='=>'string', 'params='=>'array'], 'mysqli_result::fetch_row' => ['array|null'], 'mysqli_result::field_seek' => ['bool', 'fieldnr'=>'int'], 'mysqli_result::free' => ['void'], 'mysqli_result::free_result' => ['void'], 'mysqli_rollback' => ['bool', 'link'=>'mysqli', 'flags='=>'int', 'name='=>'string'], 'mysqli_rpl_parse_enabled' => ['int', 'link'=>'mysqli'], 'mysqli_rpl_probe' => ['bool', 'link'=>'mysqli'], 'mysqli_rpl_query_type' => ['int', 'link'=>'mysqli', 'query'=>'string'], 'mysqli_savepoint' => ['bool', 'link'=>'mysqli', 'name'=>'string'], 'mysqli_savepoint_libmysql' => ['bool'], 'mysqli_select_db' => ['bool', 'link'=>'mysqli', 'dbname'=>'string'], 'mysqli_send_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'], 'mysqli_set_charset' => ['bool', 'link'=>'mysqli', 'charset'=>'string'], 'mysqli_set_local_infile_default' => ['void', 'link'=>'mysqli'], 'mysqli_set_local_infile_handler' => ['bool', 'link'=>'mysqli', 'read_func'=>'callable'], 'mysqli_slave_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'], 'mysqli_sqlstate' => ['string', 'link'=>'mysqli'], 'mysqli_ssl_set' => ['bool', 'link'=>'mysqli', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'], 'mysqli_stat' => ['string|false', 'link'=>'mysqli'], 'mysqli_stmt::__construct' => ['void', 'link'=>'mysqli', 'query='=>'string'], 'mysqli_stmt::attr_get' => ['false|int', 'attr'=>'int'], 'mysqli_stmt::attr_set' => ['bool', 'attr'=>'int', 'mode'=>'int'], 'mysqli_stmt::bind_param' => ['bool', 'types'=>'string', 'var1'=>'mixed', '...args='=>'mixed'], 'mysqli_stmt::bind_result' => ['bool', '&w_var1'=>'', '&...w_vars='=>''], 'mysqli_stmt::close' => ['bool'], 'mysqli_stmt::data_seek' => ['void', 'offset'=>'int'], 'mysqli_stmt::execute' => ['bool'], 'mysqli_stmt::fetch' => ['bool|null'], 'mysqli_stmt::free_result' => ['void'], 'mysqli_stmt::get_result' => ['mysqli_result|false'], 'mysqli_stmt::get_warnings' => ['mysqli_warning|false'], 'mysqli_stmt::more_results' => ['bool'], 'mysqli_stmt::next_result' => ['bool'], 'mysqli_stmt::num_rows' => ['int<0,max>|numeric-string'], 'mysqli_stmt::prepare' => ['bool', 'query'=>'string'], 'mysqli_stmt::reset' => ['bool'], 'mysqli_stmt::result_metadata' => ['mysqli_result|false'], 'mysqli_stmt::send_long_data' => ['bool', 'param_nr'=>'int', 'data'=>'string'], 'mysqli_stmt::store_result' => ['bool'], 'mysqli_stmt_affected_rows' => ['int<-1,max>|numeric-string', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_attr_get' => ['int|false', 'stmt'=>'mysqli_stmt', 'attr'=>'int'], 'mysqli_stmt_attr_set' => ['bool', 'stmt'=>'mysqli_stmt', 'attr'=>'int', 'mode'=>'int'], 'mysqli_stmt_bind_param' => ['bool', 'stmt'=>'mysqli_stmt', 'types'=>'string', 'var1'=>'mixed', '...args='=>'mixed'], 'mysqli_stmt_bind_result' => ['bool', 'stmt'=>'mysqli_stmt', '&w_var1'=>'', '&...w_vars='=>''], 'mysqli_stmt_close' => ['bool', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_data_seek' => ['void', 'stmt'=>'mysqli_stmt', 'offset'=>'int'], 'mysqli_stmt_errno' => ['int', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_error' => ['string', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_error_list' => ['list', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_execute' => ['bool', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_fetch' => ['bool|null', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_field_count' => ['0|positive-int', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_free_result' => ['void', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_get_result' => ['mysqli_result|false', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_get_warnings' => ['mysqli_warning|false', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_init' => ['mysqli_stmt|false', 'link'=>'mysqli'], 'mysqli_stmt_insert_id' => ['', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_more_results' => ['bool', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_next_result' => ['bool', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_num_rows' => ['0|positive-int', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_param_count' => ['0|positive-int', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_prepare' => ['bool', 'stmt'=>'mysqli_stmt', 'query'=>'string'], 'mysqli_stmt_reset' => ['bool', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_result_metadata' => ['mysqli_result|false', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_send_long_data' => ['bool', 'stmt'=>'mysqli_stmt', 'param_nr'=>'int', 'data'=>'string'], 'mysqli_stmt_sqlstate' => ['non-empty-string', 'stmt'=>'mysqli_stmt'], 'mysqli_stmt_store_result' => ['bool', 'stmt'=>'mysqli_stmt'], 'mysqli_store_result' => ['mysqli_result|false', 'link'=>'mysqli', 'option='=>'int'], 'mysqli_thread_id' => ['int', 'link'=>'mysqli'], 'mysqli_thread_safe' => ['bool'], 'mysqli_use_result' => ['mysqli_result|false', 'link'=>'mysqli'], 'mysqli_warning::__construct' => ['void'], 'mysqli_warning::next' => ['bool'], 'mysqli_warning_count' => ['int', 'link'=>'mysqli'], 'mysqlnd_memcache_get_config' => ['array', 'connection'=>'mixed'], 'mysqlnd_memcache_set' => ['bool', 'mysql_connection'=>'mixed', 'memcache_connection='=>'Memcached', 'pattern='=>'string', 'callback='=>'callable'], 'mysqlnd_ms_dump_servers' => ['array', 'connection'=>'mixed'], 'mysqlnd_ms_fabric_select_global' => ['array', 'connection'=>'mixed', 'table_name'=>'mixed'], 'mysqlnd_ms_fabric_select_shard' => ['array', 'connection'=>'mixed', 'table_name'=>'mixed', 'shard_key'=>'mixed'], 'mysqlnd_ms_get_last_gtid' => ['string', 'connection'=>'mixed'], 'mysqlnd_ms_get_last_used_connection' => ['array', 'connection'=>'mixed'], 'mysqlnd_ms_get_stats' => ['array'], 'mysqlnd_ms_match_wild' => ['bool', 'table_name'=>'string', 'wildcard'=>'string'], 'mysqlnd_ms_query_is_select' => ['int', 'query'=>'string'], 'mysqlnd_ms_set_qos' => ['bool', 'connection'=>'mixed', 'service_level'=>'int', 'service_level_option='=>'int', 'option_value='=>'mixed'], 'mysqlnd_ms_set_user_pick_server' => ['bool', 'function'=>'string'], 'mysqlnd_ms_xa_begin' => ['int', 'connection'=>'mixed', 'gtrid'=>'string', 'timeout='=>'int'], 'mysqlnd_ms_xa_commit' => ['int', 'connection'=>'mixed', 'gtrid'=>'string'], 'mysqlnd_ms_xa_gc' => ['int', 'connection'=>'mixed', 'gtrid='=>'string', 'ignore_max_retries='=>'bool'], 'mysqlnd_ms_xa_rollback' => ['int', 'connection'=>'mixed', 'gtrid'=>'string'], 'mysqlnd_qc_change_handler' => ['bool', 'handler'=>''], 'mysqlnd_qc_clear_cache' => ['bool'], 'mysqlnd_qc_get_available_handlers' => ['array'], 'mysqlnd_qc_get_cache_info' => ['array'], 'mysqlnd_qc_get_core_stats' => ['array'], 'mysqlnd_qc_get_handler' => ['array'], 'mysqlnd_qc_get_normalized_query_trace_log' => ['array'], 'mysqlnd_qc_get_query_trace_log' => ['array'], 'mysqlnd_qc_set_cache_condition' => ['bool', 'condition_type'=>'int', 'condition'=>'mixed', 'condition_option'=>'mixed'], 'mysqlnd_qc_set_is_select' => ['mixed', 'callback'=>'string'], 'mysqlnd_qc_set_storage_handler' => ['bool', 'handler'=>'string'], 'mysqlnd_qc_set_user_handlers' => ['bool', 'get_hash'=>'string', 'find_query_in_cache'=>'string', 'return_to_cache'=>'string', 'add_query_to_cache_if_not_exists'=>'string', 'query_is_select'=>'string', 'update_query_run_time_stats'=>'string', 'get_stats'=>'string', 'clear_cache'=>'string'], 'mysqlnd_uh_convert_to_mysqlnd' => ['resource', '&rw_mysql_connection'=>'mysqli'], 'mysqlnd_uh_set_connection_proxy' => ['bool', '&rw_connection_proxy'=>'MysqlndUhConnection', '&rw_mysqli_connection='=>'mysqli'], 'mysqlnd_uh_set_statement_proxy' => ['bool', '&rw_statement_proxy'=>'MysqlndUhStatement'], 'MysqlndUhConnection::__construct' => ['void'], 'MysqlndUhConnection::changeUser' => ['bool', 'connection'=>'mysqlnd_connection', 'user'=>'string', 'password'=>'string', 'database'=>'string', 'silent'=>'bool', 'passwd_len'=>'int'], 'MysqlndUhConnection::charsetName' => ['string', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::close' => ['bool', 'connection'=>'mysqlnd_connection', 'close_type'=>'int'], 'MysqlndUhConnection::connect' => ['bool', 'connection'=>'mysqlnd_connection', 'host'=>'string', 'use'=>'string', 'password'=>'string', 'database'=>'string', 'port'=>'int', 'socket'=>'string', 'mysql_flags'=>'int'], 'MysqlndUhConnection::endPSession' => ['bool', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::escapeString' => ['string', 'connection'=>'mysqlnd_connection', 'escape_string'=>'string'], 'MysqlndUhConnection::getAffectedRows' => ['int', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getErrorNumber' => ['int', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getErrorString' => ['string', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getFieldCount' => ['int', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getHostInformation' => ['string', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getLastInsertId' => ['int', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getLastMessage' => ['void', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getProtocolInformation' => ['string', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getServerInformation' => ['string', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getServerStatistics' => ['string', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getServerVersion' => ['int', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getSqlstate' => ['string', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getStatistics' => ['array', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getThreadId' => ['int', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::getWarningCount' => ['int', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::init' => ['bool', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::killConnection' => ['bool', 'connection'=>'mysqlnd_connection', 'pid'=>'int'], 'MysqlndUhConnection::listFields' => ['array', 'connection'=>'mysqlnd_connection', 'table'=>'string', 'achtung_wild'=>'string'], 'MysqlndUhConnection::listMethod' => ['void', 'connection'=>'mysqlnd_connection', 'query'=>'string', 'achtung_wild'=>'string', 'par1'=>'string'], 'MysqlndUhConnection::moreResults' => ['bool', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::nextResult' => ['bool', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::ping' => ['bool', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::query' => ['bool', 'connection'=>'mysqlnd_connection', 'query'=>'string'], 'MysqlndUhConnection::queryReadResultsetHeader' => ['bool', 'connection'=>'mysqlnd_connection', 'mysqlnd_stmt'=>'mysqlnd_statement'], 'MysqlndUhConnection::reapQuery' => ['bool', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::refreshServer' => ['bool', 'connection'=>'mysqlnd_connection', 'options'=>'int'], 'MysqlndUhConnection::restartPSession' => ['bool', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::selectDb' => ['bool', 'connection'=>'mysqlnd_connection', 'database'=>'string'], 'MysqlndUhConnection::sendClose' => ['bool', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::sendQuery' => ['bool', 'connection'=>'mysqlnd_connection', 'query'=>'string'], 'MysqlndUhConnection::serverDumpDebugInformation' => ['bool', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::setAutocommit' => ['bool', 'connection'=>'mysqlnd_connection', 'mode'=>'int'], 'MysqlndUhConnection::setCharset' => ['bool', 'connection'=>'mysqlnd_connection', 'charset'=>'string'], 'MysqlndUhConnection::setClientOption' => ['bool', 'connection'=>'mysqlnd_connection', 'option'=>'int', 'value'=>'int'], 'MysqlndUhConnection::setServerOption' => ['void', 'connection'=>'mysqlnd_connection', 'option'=>'int'], 'MysqlndUhConnection::shutdownServer' => ['void', 'MYSQLND_UH_RES_MYSQLND_NAME'=>'string', 'level'=>'string'], 'MysqlndUhConnection::simpleCommand' => ['bool', 'connection'=>'mysqlnd_connection', 'command'=>'int', 'arg'=>'string', 'ok_packet'=>'int', 'silent'=>'bool', 'ignore_upsert_status'=>'bool'], 'MysqlndUhConnection::simpleCommandHandleResponse' => ['bool', 'connection'=>'mysqlnd_connection', 'ok_packet'=>'int', 'silent'=>'bool', 'command'=>'int', 'ignore_upsert_status'=>'bool'], 'MysqlndUhConnection::sslSet' => ['bool', 'connection'=>'mysqlnd_connection', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'], 'MysqlndUhConnection::stmtInit' => ['resource', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::storeResult' => ['resource', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::txCommit' => ['bool', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::txRollback' => ['bool', 'connection'=>'mysqlnd_connection'], 'MysqlndUhConnection::useResult' => ['resource', 'connection'=>'mysqlnd_connection'], 'MysqlndUhPreparedStatement::__construct' => ['void'], 'MysqlndUhPreparedStatement::execute' => ['bool', 'statement'=>'mysqlnd_prepared_statement'], 'MysqlndUhPreparedStatement::prepare' => ['bool', 'statement'=>'mysqlnd_prepared_statement', 'query'=>'string'], 'natcasesort' => ['bool', '&rw_array_arg'=>'array'], 'natsort' => ['bool', '&rw_array_arg'=>'array'], 'ncurses_addch' => ['int', 'ch'=>'int'], 'ncurses_addchnstr' => ['int', 's'=>'string', 'n'=>'int'], 'ncurses_addchstr' => ['int', 's'=>'string'], 'ncurses_addnstr' => ['int', 's'=>'string', 'n'=>'int'], 'ncurses_addstr' => ['int', 'text'=>'string'], 'ncurses_assume_default_colors' => ['int', 'fg'=>'int', 'bg'=>'int'], 'ncurses_attroff' => ['int', 'attributes'=>'int'], 'ncurses_attron' => ['int', 'attributes'=>'int'], 'ncurses_attrset' => ['int', 'attributes'=>'int'], 'ncurses_baudrate' => ['int'], 'ncurses_beep' => ['int'], 'ncurses_bkgd' => ['int', 'attrchar'=>'int'], 'ncurses_bkgdset' => ['void', 'attrchar'=>'int'], 'ncurses_border' => ['int', 'left'=>'int', 'right'=>'int', 'top'=>'int', 'bottom'=>'int', 'tl_corner'=>'int', 'tr_corner'=>'int', 'bl_corner'=>'int', 'br_corner'=>'int'], 'ncurses_bottom_panel' => ['int', 'panel'=>'resource'], 'ncurses_can_change_color' => ['bool'], 'ncurses_cbreak' => ['bool'], 'ncurses_clear' => ['bool'], 'ncurses_clrtobot' => ['bool'], 'ncurses_clrtoeol' => ['bool'], 'ncurses_color_content' => ['int', 'color'=>'int', 'r'=>'int', 'g'=>'int', 'b'=>'int'], 'ncurses_color_set' => ['int', 'pair'=>'int'], 'ncurses_curs_set' => ['int', 'visibility'=>'int'], 'ncurses_def_prog_mode' => ['bool'], 'ncurses_def_shell_mode' => ['bool'], 'ncurses_define_key' => ['int', 'definition'=>'string', 'keycode'=>'int'], 'ncurses_del_panel' => ['bool', 'panel'=>'resource'], 'ncurses_delay_output' => ['int', 'milliseconds'=>'int'], 'ncurses_delch' => ['bool'], 'ncurses_deleteln' => ['bool'], 'ncurses_delwin' => ['bool', 'window'=>'resource'], 'ncurses_doupdate' => ['bool'], 'ncurses_echo' => ['bool'], 'ncurses_echochar' => ['int', 'character'=>'int'], 'ncurses_end' => ['int'], 'ncurses_erase' => ['bool'], 'ncurses_erasechar' => ['string'], 'ncurses_filter' => ['void'], 'ncurses_flash' => ['bool'], 'ncurses_flushinp' => ['bool'], 'ncurses_getch' => ['int'], 'ncurses_getmaxyx' => ['void', 'window'=>'resource', 'y'=>'int', 'x'=>'int'], 'ncurses_getmouse' => ['bool', 'mevent'=>'array'], 'ncurses_getyx' => ['void', 'window'=>'resource', 'y'=>'int', 'x'=>'int'], 'ncurses_halfdelay' => ['int', 'tenth'=>'int'], 'ncurses_has_colors' => ['bool'], 'ncurses_has_ic' => ['bool'], 'ncurses_has_il' => ['bool'], 'ncurses_has_key' => ['int', 'keycode'=>'int'], 'ncurses_hide_panel' => ['int', 'panel'=>'resource'], 'ncurses_hline' => ['int', 'charattr'=>'int', 'n'=>'int'], 'ncurses_inch' => ['string'], 'ncurses_init' => ['void'], 'ncurses_init_color' => ['int', 'color'=>'int', 'r'=>'int', 'g'=>'int', 'b'=>'int'], 'ncurses_init_pair' => ['int', 'pair'=>'int', 'fg'=>'int', 'bg'=>'int'], 'ncurses_insch' => ['int', 'character'=>'int'], 'ncurses_insdelln' => ['int', 'count'=>'int'], 'ncurses_insertln' => ['int'], 'ncurses_insstr' => ['int', 'text'=>'string'], 'ncurses_instr' => ['int', 'buffer'=>'string'], 'ncurses_isendwin' => ['bool'], 'ncurses_keyok' => ['int', 'keycode'=>'int', 'enable'=>'bool'], 'ncurses_keypad' => ['int', 'window'=>'resource', 'bf'=>'bool'], 'ncurses_killchar' => ['string'], 'ncurses_longname' => ['string'], 'ncurses_meta' => ['int', 'window'=>'resource', '_8bit'=>'bool'], 'ncurses_mouse_trafo' => ['bool', 'y'=>'int', 'x'=>'int', 'toscreen'=>'bool'], 'ncurses_mouseinterval' => ['int', 'milliseconds'=>'int'], 'ncurses_mousemask' => ['int', 'newmask'=>'int', 'oldmask'=>'int'], 'ncurses_move' => ['int', 'y'=>'int', 'x'=>'int'], 'ncurses_move_panel' => ['int', 'panel'=>'resource', 'startx'=>'int', 'starty'=>'int'], 'ncurses_mvaddch' => ['int', 'y'=>'int', 'x'=>'int', 'c'=>'int'], 'ncurses_mvaddchnstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string', 'n'=>'int'], 'ncurses_mvaddchstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string'], 'ncurses_mvaddnstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string', 'n'=>'int'], 'ncurses_mvaddstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string'], 'ncurses_mvcur' => ['int', 'old_y'=>'int', 'old_x'=>'int', 'new_y'=>'int', 'new_x'=>'int'], 'ncurses_mvdelch' => ['int', 'y'=>'int', 'x'=>'int'], 'ncurses_mvgetch' => ['int', 'y'=>'int', 'x'=>'int'], 'ncurses_mvhline' => ['int', 'y'=>'int', 'x'=>'int', 'attrchar'=>'int', 'n'=>'int'], 'ncurses_mvinch' => ['int', 'y'=>'int', 'x'=>'int'], 'ncurses_mvvline' => ['int', 'y'=>'int', 'x'=>'int', 'attrchar'=>'int', 'n'=>'int'], 'ncurses_mvwaddstr' => ['int', 'window'=>'resource', 'y'=>'int', 'x'=>'int', 'text'=>'string'], 'ncurses_napms' => ['int', 'milliseconds'=>'int'], 'ncurses_new_panel' => ['resource', 'window'=>'resource'], 'ncurses_newpad' => ['resource', 'rows'=>'int', 'cols'=>'int'], 'ncurses_newwin' => ['resource', 'rows'=>'int', 'cols'=>'int', 'y'=>'int', 'x'=>'int'], 'ncurses_nl' => ['bool'], 'ncurses_nocbreak' => ['bool'], 'ncurses_noecho' => ['bool'], 'ncurses_nonl' => ['bool'], 'ncurses_noqiflush' => ['void'], 'ncurses_noraw' => ['bool'], 'ncurses_pair_content' => ['int', 'pair'=>'int', 'f'=>'int', 'b'=>'int'], 'ncurses_panel_above' => ['resource', 'panel'=>'resource'], 'ncurses_panel_below' => ['resource', 'panel'=>'resource'], 'ncurses_panel_window' => ['resource', 'panel'=>'resource'], 'ncurses_pnoutrefresh' => ['int', 'pad'=>'resource', 'pminrow'=>'int', 'pmincol'=>'int', 'sminrow'=>'int', 'smincol'=>'int', 'smaxrow'=>'int', 'smaxcol'=>'int'], 'ncurses_prefresh' => ['int', 'pad'=>'resource', 'pminrow'=>'int', 'pmincol'=>'int', 'sminrow'=>'int', 'smincol'=>'int', 'smaxrow'=>'int', 'smaxcol'=>'int'], 'ncurses_putp' => ['int', 'text'=>'string'], 'ncurses_qiflush' => ['void'], 'ncurses_raw' => ['bool'], 'ncurses_refresh' => ['int', 'ch'=>'int'], 'ncurses_replace_panel' => ['int', 'panel'=>'resource', 'window'=>'resource'], 'ncurses_reset_prog_mode' => ['int'], 'ncurses_reset_shell_mode' => ['int'], 'ncurses_resetty' => ['bool'], 'ncurses_savetty' => ['bool'], 'ncurses_scr_dump' => ['int', 'filename'=>'string'], 'ncurses_scr_init' => ['int', 'filename'=>'string'], 'ncurses_scr_restore' => ['int', 'filename'=>'string'], 'ncurses_scr_set' => ['int', 'filename'=>'string'], 'ncurses_scrl' => ['int', 'count'=>'int'], 'ncurses_show_panel' => ['int', 'panel'=>'resource'], 'ncurses_slk_attr' => ['int'], 'ncurses_slk_attroff' => ['int', 'intarg'=>'int'], 'ncurses_slk_attron' => ['int', 'intarg'=>'int'], 'ncurses_slk_attrset' => ['int', 'intarg'=>'int'], 'ncurses_slk_clear' => ['bool'], 'ncurses_slk_color' => ['int', 'intarg'=>'int'], 'ncurses_slk_init' => ['bool', 'format'=>'int'], 'ncurses_slk_noutrefresh' => ['bool'], 'ncurses_slk_refresh' => ['int'], 'ncurses_slk_restore' => ['int'], 'ncurses_slk_set' => ['bool', 'labelnr'=>'int', 'label'=>'string', 'format'=>'int'], 'ncurses_slk_touch' => ['int'], 'ncurses_standend' => ['int'], 'ncurses_standout' => ['int'], 'ncurses_start_color' => ['int'], 'ncurses_termattrs' => ['bool'], 'ncurses_termname' => ['string'], 'ncurses_timeout' => ['void', 'millisec'=>'int'], 'ncurses_top_panel' => ['int', 'panel'=>'resource'], 'ncurses_typeahead' => ['int', 'fd'=>'int'], 'ncurses_ungetch' => ['int', 'keycode'=>'int'], 'ncurses_ungetmouse' => ['bool', 'mevent'=>'array'], 'ncurses_update_panels' => ['void'], 'ncurses_use_default_colors' => ['bool'], 'ncurses_use_env' => ['void', 'flag'=>'bool'], 'ncurses_use_extended_names' => ['int', 'flag'=>'bool'], 'ncurses_vidattr' => ['int', 'intarg'=>'int'], 'ncurses_vline' => ['int', 'charattr'=>'int', 'n'=>'int'], 'ncurses_waddch' => ['int', 'window'=>'resource', 'ch'=>'int'], 'ncurses_waddstr' => ['int', 'window'=>'resource', 'str'=>'string', 'n='=>'int'], 'ncurses_wattroff' => ['int', 'window'=>'resource', 'attrs'=>'int'], 'ncurses_wattron' => ['int', 'window'=>'resource', 'attrs'=>'int'], 'ncurses_wattrset' => ['int', 'window'=>'resource', 'attrs'=>'int'], 'ncurses_wborder' => ['int', 'window'=>'resource', 'left'=>'int', 'right'=>'int', 'top'=>'int', 'bottom'=>'int', 'tl_corner'=>'int', 'tr_corner'=>'int', 'bl_corner'=>'int', 'br_corner'=>'int'], 'ncurses_wclear' => ['int', 'window'=>'resource'], 'ncurses_wcolor_set' => ['int', 'window'=>'resource', 'color_pair'=>'int'], 'ncurses_werase' => ['int', 'window'=>'resource'], 'ncurses_wgetch' => ['int', 'window'=>'resource'], 'ncurses_whline' => ['int', 'window'=>'resource', 'charattr'=>'int', 'n'=>'int'], 'ncurses_wmouse_trafo' => ['bool', 'window'=>'resource', 'y'=>'int', 'x'=>'int', 'toscreen'=>'bool'], 'ncurses_wmove' => ['int', 'window'=>'resource', 'y'=>'int', 'x'=>'int'], 'ncurses_wnoutrefresh' => ['int', 'window'=>'resource'], 'ncurses_wrefresh' => ['int', 'window'=>'resource'], 'ncurses_wstandend' => ['int', 'window'=>'resource'], 'ncurses_wstandout' => ['int', 'window'=>'resource'], 'ncurses_wvline' => ['int', 'window'=>'resource', 'charattr'=>'int', 'n'=>'int'], 'net_get_interfaces' => ['array|false'], 'newrelic_add_custom_parameter' => ['bool', 'key'=>'string', 'value'=>''], 'newrelic_add_custom_tracer' => ['bool', 'function_name'=>'string'], 'newrelic_background_job' => ['void', 'flag='=>'bool'], 'newrelic_capture_params' => ['void', 'enable='=>'bool'], 'newrelic_custom_metric' => ['bool', 'metric_name'=>'string', 'value'=>'float'], 'newrelic_disable_autorum' => ['bool'], 'newrelic_end_of_transaction' => ['void'], 'newrelic_end_transaction' => ['bool', 'ignore='=>'bool'], 'newrelic_get_browser_timing_footer' => ['string', 'include_tags='=>'bool'], 'newrelic_get_browser_timing_header' => ['string', 'include_tags='=>'bool'], 'newrelic_ignore_apdex' => ['void'], 'newrelic_ignore_transaction' => ['void'], 'newrelic_name_transaction' => ['bool', 'name'=>'string'], 'newrelic_notice_error' => ['void', 'message'=>'string', 'exception='=>'Exception|Throwable'], 'newrelic_notice_error\'1' => ['void', 'unused_1'=>'string', 'message'=>'string', 'unused_2'=>'string', 'unused_3'=>'int', 'unused_4='=>''], 'newrelic_record_custom_event' => ['void', 'name'=>'string', 'attributes'=>'array'], 'newrelic_record_datastore_segment' => ['mixed', 'func'=>'callable', 'parameters'=>'array'], 'newrelic_set_appname' => ['bool', 'name'=>'string', 'license='=>'string', 'xmit='=>'bool'], 'newrelic_set_user_attributes' => ['bool', 'user'=>'string', 'account'=>'string', 'product'=>'string'], 'newrelic_start_transaction' => ['bool', 'appname'=>'string', 'license='=>'string'], 'newt_bell' => ['void'], 'newt_button' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string'], 'newt_button_bar' => ['resource', 'buttons'=>'array'], 'newt_centered_window' => ['int', 'width'=>'int', 'height'=>'int', 'title='=>'string'], 'newt_checkbox' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string', 'def_value'=>'string', 'seq='=>'string'], 'newt_checkbox_get_value' => ['string', 'checkbox'=>'resource'], 'newt_checkbox_set_flags' => ['void', 'checkbox'=>'resource', 'flags'=>'int', 'sense'=>'int'], 'newt_checkbox_set_value' => ['void', 'checkbox'=>'resource', 'value'=>'string'], 'newt_checkbox_tree' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'flags='=>'int'], 'newt_checkbox_tree_add_item' => ['void', 'checkboxtree'=>'resource', 'text'=>'string', 'data'=>'mixed', 'flags'=>'int', 'index'=>'int', '...args='=>'int'], 'newt_checkbox_tree_find_item' => ['array', 'checkboxtree'=>'resource', 'data'=>'mixed'], 'newt_checkbox_tree_get_current' => ['mixed', 'checkboxtree'=>'resource'], 'newt_checkbox_tree_get_entry_value' => ['string', 'checkboxtree'=>'resource', 'data'=>'mixed'], 'newt_checkbox_tree_get_multi_selection' => ['array', 'checkboxtree'=>'resource', 'seqnum'=>'string'], 'newt_checkbox_tree_get_selection' => ['array', 'checkboxtree'=>'resource'], 'newt_checkbox_tree_multi' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'seq'=>'string', 'flags='=>'int'], 'newt_checkbox_tree_set_current' => ['void', 'checkboxtree'=>'resource', 'data'=>'mixed'], 'newt_checkbox_tree_set_entry' => ['void', 'checkboxtree'=>'resource', 'data'=>'mixed', 'text'=>'string'], 'newt_checkbox_tree_set_entry_value' => ['void', 'checkboxtree'=>'resource', 'data'=>'mixed', 'value'=>'string'], 'newt_checkbox_tree_set_width' => ['void', 'checkbox_tree'=>'resource', 'width'=>'int'], 'newt_clear_key_buffer' => ['void'], 'newt_cls' => ['void'], 'newt_compact_button' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string'], 'newt_component_add_callback' => ['void', 'component'=>'resource', 'func_name'=>'mixed', 'data'=>'mixed'], 'newt_component_takes_focus' => ['void', 'component'=>'resource', 'takes_focus'=>'bool'], 'newt_create_grid' => ['resource', 'cols'=>'int', 'rows'=>'int'], 'newt_cursor_off' => ['void'], 'newt_cursor_on' => ['void'], 'newt_delay' => ['void', 'microseconds'=>'int'], 'newt_draw_form' => ['void', 'form'=>'resource'], 'newt_draw_root_text' => ['void', 'left'=>'int', 'top'=>'int', 'text'=>'string'], 'newt_entry' => ['resource', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'init_value='=>'string', 'flags='=>'int'], 'newt_entry_get_value' => ['string', 'entry'=>'resource'], 'newt_entry_set' => ['void', 'entry'=>'resource', 'value'=>'string', 'cursor_at_end='=>'bool'], 'newt_entry_set_filter' => ['void', 'entry'=>'resource', 'filter'=>'callable', 'data'=>'mixed'], 'newt_entry_set_flags' => ['void', 'entry'=>'resource', 'flags'=>'int', 'sense'=>'int'], 'newt_finished' => ['int'], 'newt_form' => ['resource', 'vert_bar='=>'resource', 'help='=>'string', 'flags='=>'int'], 'newt_form_add_component' => ['void', 'form'=>'resource', 'component'=>'resource'], 'newt_form_add_components' => ['void', 'form'=>'resource', 'components'=>'array'], 'newt_form_add_hot_key' => ['void', 'form'=>'resource', 'key'=>'int'], 'newt_form_destroy' => ['void', 'form'=>'resource'], 'newt_form_get_current' => ['resource', 'form'=>'resource'], 'newt_form_run' => ['void', 'form'=>'resource', 'exit_struct'=>'array'], 'newt_form_set_background' => ['void', 'from'=>'resource', 'background'=>'int'], 'newt_form_set_height' => ['void', 'form'=>'resource', 'height'=>'int'], 'newt_form_set_size' => ['void', 'form'=>'resource'], 'newt_form_set_timer' => ['void', 'form'=>'resource', 'milliseconds'=>'int'], 'newt_form_set_width' => ['void', 'form'=>'resource', 'width'=>'int'], 'newt_form_watch_fd' => ['void', 'form'=>'resource', 'stream'=>'resource', 'flags='=>'int'], 'newt_get_screen_size' => ['void', 'cols'=>'int', 'rows'=>'int'], 'newt_grid_add_components_to_form' => ['void', 'grid'=>'resource', 'form'=>'resource', 'recurse'=>'bool'], 'newt_grid_basic_window' => ['resource', 'text'=>'resource', 'middle'=>'resource', 'buttons'=>'resource'], 'newt_grid_free' => ['void', 'grid'=>'resource', 'recurse'=>'bool'], 'newt_grid_get_size' => ['void', 'grid'=>'resource', 'width'=>'int', 'height'=>'int'], 'newt_grid_h_close_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'], 'newt_grid_h_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'], 'newt_grid_place' => ['void', 'grid'=>'resource', 'left'=>'int', 'top'=>'int'], 'newt_grid_set_field' => ['void', 'grid'=>'resource', 'col'=>'int', 'row'=>'int', 'type'=>'int', 'val'=>'resource', 'pad_left'=>'int', 'pad_top'=>'int', 'pad_right'=>'int', 'pad_bottom'=>'int', 'anchor'=>'int', 'flags='=>'int'], 'newt_grid_simple_window' => ['resource', 'text'=>'resource', 'middle'=>'resource', 'buttons'=>'resource'], 'newt_grid_v_close_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'], 'newt_grid_v_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'], 'newt_grid_wrapped_window' => ['void', 'grid'=>'resource', 'title'=>'string'], 'newt_grid_wrapped_window_at' => ['void', 'grid'=>'resource', 'title'=>'string', 'left'=>'int', 'top'=>'int'], 'newt_init' => ['int'], 'newt_label' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string'], 'newt_label_set_text' => ['void', 'label'=>'resource', 'text'=>'string'], 'newt_listbox' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'flags='=>'int'], 'newt_listbox_append_entry' => ['void', 'listbox'=>'resource', 'text'=>'string', 'data'=>'mixed'], 'newt_listbox_clear' => ['void', 'listobx'=>'resource'], 'newt_listbox_clear_selection' => ['void', 'listbox'=>'resource'], 'newt_listbox_delete_entry' => ['void', 'listbox'=>'resource', 'key'=>'mixed'], 'newt_listbox_get_current' => ['string', 'listbox'=>'resource'], 'newt_listbox_get_selection' => ['array', 'listbox'=>'resource'], 'newt_listbox_insert_entry' => ['void', 'listbox'=>'resource', 'text'=>'string', 'data'=>'mixed', 'key'=>'mixed'], 'newt_listbox_item_count' => ['int', 'listbox'=>'resource'], 'newt_listbox_select_item' => ['void', 'listbox'=>'resource', 'key'=>'mixed', 'sense'=>'int'], 'newt_listbox_set_current' => ['void', 'listbox'=>'resource', 'num'=>'int'], 'newt_listbox_set_current_by_key' => ['void', 'listbox'=>'resource', 'key'=>'mixed'], 'newt_listbox_set_data' => ['void', 'listbox'=>'resource', 'num'=>'int', 'data'=>'mixed'], 'newt_listbox_set_entry' => ['void', 'listbox'=>'resource', 'num'=>'int', 'text'=>'string'], 'newt_listbox_set_width' => ['void', 'listbox'=>'resource', 'width'=>'int'], 'newt_listitem' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string', 'is_default'=>'bool', 'prev_item'=>'resource', 'data'=>'mixed', 'flags='=>'int'], 'newt_listitem_get_data' => ['mixed', 'item'=>'resource'], 'newt_listitem_set' => ['void', 'item'=>'resource', 'text'=>'string'], 'newt_open_window' => ['int', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'height'=>'int', 'title='=>'string'], 'newt_pop_help_line' => ['void'], 'newt_pop_window' => ['void'], 'newt_push_help_line' => ['void', 'text='=>'string'], 'newt_radio_get_current' => ['resource', 'set_member'=>'resource'], 'newt_radiobutton' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string', 'is_default'=>'bool', 'prev_button='=>'resource'], 'newt_redraw_help_line' => ['void'], 'newt_reflow_text' => ['string', 'text'=>'string', 'width'=>'int', 'flex_down'=>'int', 'flex_up'=>'int', 'actual_width'=>'int', 'actual_height'=>'int'], 'newt_refresh' => ['void'], 'newt_resize_screen' => ['void', 'redraw='=>'bool'], 'newt_resume' => ['void'], 'newt_run_form' => ['resource', 'form'=>'resource'], 'newt_scale' => ['resource', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'full_value'=>'int'], 'newt_scale_set' => ['void', 'scale'=>'resource', 'amount'=>'int'], 'newt_scrollbar_set' => ['void', 'scrollbar'=>'resource', 'where'=>'int', 'total'=>'int'], 'newt_set_help_callback' => ['void', 'function'=>'mixed'], 'newt_set_suspend_callback' => ['void', 'function'=>'callable', 'data'=>'mixed'], 'newt_suspend' => ['void'], 'newt_textbox' => ['resource', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'height'=>'int', 'flags='=>'int'], 'newt_textbox_get_num_lines' => ['int', 'textbox'=>'resource'], 'newt_textbox_reflowed' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'char', 'width'=>'int', 'flex_down'=>'int', 'flex_up'=>'int', 'flags='=>'int'], 'newt_textbox_set_height' => ['void', 'textbox'=>'resource', 'height'=>'int'], 'newt_textbox_set_text' => ['void', 'textbox'=>'resource', 'text'=>'string'], 'newt_vertical_scrollbar' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'normal_colorset='=>'int', 'thumb_colorset='=>'int'], 'newt_wait_for_key' => ['void'], 'newt_win_choice' => ['int', 'title'=>'string', 'button1_text'=>'string', 'button2_text'=>'string', 'format'=>'string', 'args='=>'mixed', '...args='=>'mixed'], 'newt_win_entries' => ['int', 'title'=>'string', 'text'=>'string', 'suggested_width'=>'int', 'flex_down'=>'int', 'flex_up'=>'int', 'data_width'=>'int', 'items'=>'array', 'button1'=>'string', '...args='=>'string'], 'newt_win_menu' => ['int', 'title'=>'string', 'text'=>'string', 'suggestedwidth'=>'int', 'flexdown'=>'int', 'flexup'=>'int', 'maxlistheight'=>'int', 'items'=>'array', 'listitem'=>'int', 'button1='=>'string', '...args='=>'string'], 'newt_win_message' => ['void', 'title'=>'string', 'button_text'=>'string', 'format'=>'string', 'args='=>'mixed', '...args='=>'mixed'], 'newt_win_messagev' => ['void', 'title'=>'string', 'button_text'=>'string', 'format'=>'string', 'args'=>'array'], 'newt_win_ternary' => ['int', 'title'=>'string', 'button1_text'=>'string', 'button2_text'=>'string', 'button3_text'=>'string', 'format'=>'string', 'args='=>'mixed', '...args='=>'mixed'], 'next' => ['mixed', '&rw_array_arg'=>'array|object'], 'ngettext' => ['string', 'msgid1'=>'string', 'msgid2'=>'string', 'n'=>'int'], 'nl2br' => ['string', 'str'=>'string', 'is_xhtml='=>'bool'], 'nl_langinfo' => ['string|false', 'item'=>'int'], 'NoRewindIterator::__construct' => ['void', 'iterator'=>'Iterator'], 'NoRewindIterator::current' => ['mixed'], 'NoRewindIterator::getInnerIterator' => ['Iterator'], 'NoRewindIterator::key' => ['mixed'], 'NoRewindIterator::next' => ['void'], 'NoRewindIterator::rewind' => ['void'], 'NoRewindIterator::valid' => ['bool'], 'Normalizer::getRawDecomposition' => ['string|null', 'input'=>'string'], 'Normalizer::isNormalized' => ['bool', 'input'=>'string', 'form='=>'int'], 'Normalizer::normalize' => ['string|false', 'input'=>'string', 'form='=>'int'], 'normalizer_get_raw_decomposition' => ['string|null', 'input'=>'string'], 'normalizer_is_normalized' => ['bool', 'input'=>'string', 'form='=>'int'], 'normalizer_normalize' => ['string|false', 'input'=>'string', 'form='=>'int'], 'notes_body' => ['array', 'server'=>'string', 'mailbox'=>'string', 'msg_number'=>'int'], 'notes_copy_db' => ['bool', 'from_database_name'=>'string', 'to_database_name'=>'string'], 'notes_create_db' => ['bool', 'database_name'=>'string'], 'notes_create_note' => ['bool', 'database_name'=>'string', 'form_name'=>'string'], 'notes_drop_db' => ['bool', 'database_name'=>'string'], 'notes_find_note' => ['int', 'database_name'=>'string', 'name'=>'string', 'type='=>'string'], 'notes_header_info' => ['object', 'server'=>'string', 'mailbox'=>'string', 'msg_number'=>'int'], 'notes_list_msgs' => ['bool', 'db'=>'string'], 'notes_mark_read' => ['bool', 'database_name'=>'string', 'user_name'=>'string', 'note_id'=>'string'], 'notes_mark_unread' => ['bool', 'database_name'=>'string', 'user_name'=>'string', 'note_id'=>'string'], 'notes_nav_create' => ['bool', 'database_name'=>'string', 'name'=>'string'], 'notes_search' => ['array', 'database_name'=>'string', 'keywords'=>'string'], 'notes_unread' => ['array', 'database_name'=>'string', 'user_name'=>'string'], 'notes_version' => ['float', 'database_name'=>'string'], 'nsapi_request_headers' => ['array'], 'nsapi_response_headers' => ['array'], 'nsapi_virtual' => ['bool', 'uri'=>'string'], 'nthmac' => ['string', 'clent'=>'string', 'data'=>'string'], 'number_format' => ['non-empty-string', 'number'=>'float', 'num_decimal_places='=>'int', 'dec_separator='=>'string|null', 'thousands_separator='=>'string|null'], 'NumberFormatter::__construct' => ['void', 'locale'=>'string', 'style'=>'int', 'pattern='=>'string'], 'NumberFormatter::create' => ['NumberFormatter', 'locale'=>'string', 'style'=>'int', 'pattern='=>'string'], 'NumberFormatter::format' => ['string|false', 'num'=>'', 'type='=>'int'], 'NumberFormatter::formatCurrency' => ['string|false', 'num'=>'float', 'currency'=>'string'], 'NumberFormatter::getAttribute' => ['int', 'attr'=>'int'], 'NumberFormatter::getErrorCode' => ['int'], 'NumberFormatter::getErrorMessage' => ['string'], 'NumberFormatter::getLocale' => ['string', 'type='=>'int'], 'NumberFormatter::getPattern' => ['string'], 'NumberFormatter::getSymbol' => ['string', 'attr'=>'int'], 'NumberFormatter::getTextAttribute' => ['string', 'attr'=>'int'], 'NumberFormatter::parse' => ['float|false', 'str'=>'string', 'type='=>'int', '&rw_position='=>'int'], 'NumberFormatter::parseCurrency' => ['float|false', 'str'=>'string', '&w_currency'=>'string', '&rw_position='=>'int'], 'NumberFormatter::setAttribute' => ['bool', 'attr'=>'int', 'value'=>''], 'NumberFormatter::setPattern' => ['bool', 'pattern'=>'string'], 'NumberFormatter::setSymbol' => ['bool', 'attr'=>'int', 'symbol'=>'string'], 'NumberFormatter::setTextAttribute' => ['bool', 'attr'=>'int', 'value'=>'string'], 'numfmt_create' => ['NumberFormatter', 'locale'=>'string', 'style'=>'int', 'pattern='=>'string'], 'numfmt_format' => ['string|false', 'fmt'=>'numberformatter', 'value='=>'float', 'type='=>'int'], 'numfmt_format_currency' => ['string|false', 'fmt'=>'numberformatter', 'value'=>'float', 'currency'=>'string'], 'numfmt_get_attribute' => ['int|false', 'fmt'=>'numberformatter', 'attr'=>'int'], 'numfmt_get_error_code' => ['int', 'fmt'=>'numberformatter'], 'numfmt_get_error_message' => ['string', 'fmt'=>'numberformatter'], 'numfmt_get_locale' => ['string|false', 'fmt'=>'numberformatter', 'type='=>'int'], 'numfmt_get_pattern' => ['string|false', 'fmt'=>'numberformatter'], 'numfmt_get_symbol' => ['string|false', 'fmt'=>'numberformatter', 'attr'=>'int'], 'numfmt_get_text_attribute' => ['string|false', 'fmt'=>'numberformatter', 'attr'=>'int'], 'numfmt_parse' => ['float|false', 'fmt'=>'numberformatter', 'value'=>'string', 'type='=>'int', '&rw_position='=>'int'], 'numfmt_parse_currency' => ['float|false', 'fmt'=>'numberformatter', 'value'=>'string', '&w_currency'=>'string', '&rw_position='=>'int'], 'numfmt_set_attribute' => ['bool', 'fmt'=>'numberformatter', 'attr'=>'int', 'value'=>'int'], 'numfmt_set_pattern' => ['bool', 'fmt'=>'numberformatter', 'pattern'=>'string'], 'numfmt_set_symbol' => ['bool', 'fmt'=>'numberformatter', 'attr'=>'int', 'value'=>'string'], 'numfmt_set_text_attribute' => ['bool', 'fmt'=>'numberformatter', 'attr'=>'int', 'value'=>'string'], 'OAuth::__construct' => ['void', 'consumer_key'=>'string', 'consumer_secret'=>'string', 'signature_method='=>'string', 'auth_type='=>'int'], 'OAuth::__destruct' => [''], 'OAuth::disableDebug' => ['bool'], 'OAuth::disableRedirects' => ['bool'], 'OAuth::disableSSLChecks' => ['bool'], 'OAuth::enableDebug' => ['bool'], 'OAuth::enableRedirects' => ['bool'], 'OAuth::enableSSLChecks' => ['bool'], 'OAuth::fetch' => ['mixed', 'protected_resource_url'=>'string', 'extra_parameters='=>'array', 'http_method='=>'string', 'http_headers='=>'array'], 'OAuth::generateSignature' => ['string', 'http_method'=>'string', 'url'=>'string', 'extra_parameters='=>'mixed'], 'OAuth::getAccessToken' => ['array|false', 'access_token_url'=>'string', 'auth_session_handle='=>'string', 'verifier_token='=>'string'], 'OAuth::getCAPath' => ['array'], 'OAuth::getLastResponse' => ['string'], 'OAuth::getLastResponseHeaders' => ['string|false'], 'OAuth::getLastResponseInfo' => ['array'], 'OAuth::getRequestHeader' => ['string|false', 'http_method'=>'string', 'url'=>'string', 'extra_parameters='=>'mixed'], 'OAuth::getRequestToken' => ['array|false', 'request_token_url'=>'string', 'callback_url='=>'string'], 'OAuth::setAuthType' => ['bool', 'auth_type'=>'int'], 'OAuth::setCAPath' => ['mixed', 'ca_path='=>'string', 'ca_info='=>'string'], 'OAuth::setNonce' => ['mixed', 'nonce'=>'string'], 'OAuth::setRequestEngine' => ['void', 'reqengine'=>'int'], 'OAuth::setRSACertificate' => ['mixed', 'cert'=>'string'], 'OAuth::setSSLChecks' => ['bool', 'sslcheck'=>'int'], 'OAuth::setTimestamp' => ['mixed', 'timestamp'=>'string'], 'OAuth::setToken' => ['bool', 'token'=>'string', 'token_secret'=>'string'], 'OAuth::setVersion' => ['bool', 'version'=>'string'], 'oauth_get_sbs' => ['string', 'http_method'=>'string', 'uri'=>'string', 'request_parameters='=>'array'], 'oauth_urlencode' => ['string', 'uri'=>'string'], 'OAuthProvider::__construct' => ['void', 'params_array='=>'array'], 'OAuthProvider::addRequiredParameter' => ['bool', 'req_params'=>'string'], 'OAuthProvider::callconsumerHandler' => ['void'], 'OAuthProvider::callTimestampNonceHandler' => ['void'], 'OAuthProvider::calltokenHandler' => ['void'], 'OAuthProvider::checkOAuthRequest' => ['void', 'uri='=>'string', 'method='=>'string'], 'OAuthProvider::consumerHandler' => ['void', 'callback_function'=>'callable'], 'OAuthProvider::generateToken' => ['string', 'size'=>'int', 'strong='=>'bool'], 'OAuthProvider::is2LeggedEndpoint' => ['void', 'params_array'=>'mixed'], 'OAuthProvider::isRequestTokenEndpoint' => ['void', 'will_issue_request_token'=>'bool'], 'OAuthProvider::removeRequiredParameter' => ['bool', 'req_params'=>'string'], 'OAuthProvider::reportProblem' => ['string', 'oauthexception'=>'string', 'send_headers='=>'bool'], 'OAuthProvider::setParam' => ['bool', 'param_key'=>'string', 'param_val='=>'mixed'], 'OAuthProvider::setRequestTokenPath' => ['bool', 'path'=>'string'], 'OAuthProvider::timestampNonceHandler' => ['void', 'callback_function'=>'callable'], 'OAuthProvider::tokenHandler' => ['void', 'callback_function'=>'callable'], 'ob_clean' => ['bool'], 'ob_deflatehandler' => ['string', 'data'=>'string', 'mode'=>'int'], 'ob_end_clean' => ['bool'], 'ob_end_flush' => ['bool'], 'ob_etaghandler' => ['string', 'data'=>'string', 'mode'=>'int'], 'ob_flush' => ['bool'], 'ob_get_clean' => ['string|false'], 'ob_get_contents' => ['string|false'], 'ob_get_flush' => ['string|false'], 'ob_get_length' => ['int|false'], 'ob_get_level' => ['int'], 'ob_get_status' => ['array', 'full_status='=>'bool'], 'ob_gzhandler' => ['string|false', 'data'=>'string', 'flags'=>'int'], 'ob_iconv_handler' => ['string', 'contents'=>'string', 'status'=>'int'], 'ob_implicit_flush' => ['void', 'flag='=>'int'], 'ob_inflatehandler' => ['string', 'data'=>'string', 'mode'=>'int'], 'ob_list_handlers' => ['false|list'], 'ob_start' => ['bool', 'user_function='=>'string|array|callable|null', 'chunk_size='=>'int', 'flags='=>'int'], 'ob_tidyhandler' => ['string', 'input'=>'string', 'mode='=>'int'], 'OCI-Collection::append' => ['bool', 'value'=>'mixed'], 'OCI-Collection::assign' => ['bool', 'from'=>'OCI-Collection'], 'OCI-Collection::assignElem' => ['bool', 'index'=>'int', 'value'=>''], 'OCI-Collection::assignelem' => ['bool', 'index'=>'int', 'value'=>'mixed'], 'OCI-Collection::free' => ['bool'], 'OCI-Collection::getElem' => ['', 'index'=>'int'], 'OCI-Collection::getelem' => ['mixed', 'index'=>'int'], 'OCI-Collection::max' => ['int'], 'OCI-Collection::size' => ['int'], 'OCI-Collection::trim' => ['bool', 'num'=>'int'], 'OCI-Lob::append' => ['bool', 'lob_from'=>'OCI-Lob'], 'OCI-Lob::close' => ['bool'], 'OCI-Lob::eof' => ['bool'], 'OCI-Lob::erase' => ['int', 'offset='=>'int', 'length='=>'int'], 'OCI-Lob::export' => ['bool', 'filename'=>'string', 'start='=>'int', 'length='=>'int'], 'OCI-Lob::flush' => ['bool', 'flag='=>'int'], 'OCI-Lob::free' => ['bool'], 'OCI-Lob::getBuffering' => ['bool'], 'OCI-Lob::getbuffering' => ['bool'], 'OCI-Lob::import' => ['bool', 'filename'=>'string'], 'OCI-Lob::load' => ['string'], 'OCI-Lob::read' => ['string', 'length'=>'int'], 'OCI-Lob::rewind' => ['bool'], 'OCI-Lob::save' => ['bool', 'data'=>'string', 'offset='=>'int'], 'OCI-Lob::savefile' => ['bool', 'filename'=>''], 'OCI-Lob::seek' => ['bool', 'offset'=>'int', 'whence='=>'int'], 'OCI-Lob::setBuffering' => ['bool', 'on_off'=>'bool'], 'OCI-Lob::setbuffering' => ['bool', 'on_off'=>'bool'], 'OCI-Lob::size' => ['int'], 'OCI-Lob::tell' => ['int'], 'OCI-Lob::truncate' => ['bool', 'length='=>'int'], 'OCI-Lob::write' => ['int', 'data'=>'string', 'length='=>'int'], 'OCI-Lob::writeTemporary' => ['bool', 'data'=>'string', 'lob_type='=>'int'], 'OCI-Lob::writetofile' => ['bool', 'filename'=>'', 'start'=>'', 'length'=>''], 'oci_bind_array_by_name' => ['bool', 'stmt'=>'resource', 'name'=>'string', '&rw_var'=>'array', 'max_table_length'=>'int', 'max_item_length='=>'int', 'type='=>'int'], 'oci_bind_by_name' => ['bool', 'stmt'=>'resource', 'name'=>'string', '&rw_var'=>'mixed', 'maxlength='=>'int', 'type='=>'int'], 'oci_cancel' => ['bool', 'stmt'=>'resource'], 'oci_client_version' => ['string'], 'oci_close' => ['bool', 'connection'=>'resource'], 'oci_collection_append' => ['bool', 'value'=>'string'], 'oci_collection_assign' => ['bool', 'from'=>'OCI-Collection'], 'oci_collection_element_assign' => ['bool', 'index'=>'int', 'val'=>'string'], 'oci_collection_element_get' => ['string|false', 'ndx'=>'int'], 'oci_collection_max' => ['int|false'], 'oci_collection_size' => ['int|false'], 'oci_collection_trim' => ['bool', 'num'=>'int'], 'oci_commit' => ['bool', 'connection'=>'resource'], 'oci_connect' => ['resource|false', 'user'=>'string', 'pass'=>'string', 'db='=>'string', 'charset='=>'string', 'session_mode='=>'int'], 'oci_define_by_name' => ['bool', 'stmt'=>'resource', 'name'=>'string', '&w_var'=>'mixed', 'type='=>'int'], 'oci_error' => ['array|false', 'resource='=>'resource'], 'oci_execute' => ['bool', 'stmt'=>'resource', 'mode='=>'int'], 'oci_fetch' => ['bool', 'stmt'=>'resource'], 'oci_fetch_all' => ['int|false', 'stmt'=>'resource', '&w_output'=>'array', 'skip='=>'int', 'maxrows='=>'int', 'flags='=>'int'], 'oci_fetch_array' => ['array|false', 'stmt'=>'resource', 'mode='=>'int'], 'oci_fetch_assoc' => ['array|false', 'stmt'=>'resource'], 'oci_fetch_object' => ['object|false', 'stmt'=>'resource'], 'oci_fetch_row' => ['array|false', 'stmt'=>'resource'], 'oci_field_is_null' => ['bool', 'stmt'=>'resource', 'col'=>'mixed'], 'oci_field_name' => ['string|false', 'stmt'=>'resource', 'col'=>'mixed'], 'oci_field_precision' => ['int|false', 'stmt'=>'resource', 'col'=>'mixed'], 'oci_field_scale' => ['int|false', 'stmt'=>'resource', 'col'=>'mixed'], 'oci_field_size' => ['int|false', 'stmt'=>'resource', 'col'=>'mixed'], 'oci_field_type' => ['mixed', 'stmt'=>'resource', 'col'=>'mixed'], 'oci_field_type_raw' => ['int|false', 'stmt'=>'resource', 'col'=>'mixed'], 'oci_free_collection' => ['bool'], 'oci_free_cursor' => ['bool', 'stmt'=>'resource'], 'oci_free_descriptor' => ['bool'], 'oci_free_statement' => ['bool', 'stmt'=>'resource'], 'oci_get_implicit' => ['bool', 'stmt'=>''], 'oci_get_implicit_resultset' => ['resource|false', 'statement'=>'resource'], 'oci_internal_debug' => ['void', 'onoff'=>'bool'], 'oci_lob_append' => ['bool', 'lob'=>'OCI-Lob'], 'oci_lob_close' => ['bool'], 'oci_lob_copy' => ['bool', 'lob_to'=>'OCI-Lob', 'lob_from'=>'OCI-Lob', 'length='=>'int'], 'oci_lob_eof' => ['bool'], 'oci_lob_erase' => ['int|false', 'offset'=>'int', 'length'=>'int'], 'oci_lob_export' => ['bool', 'filename'=>'string', 'start'=>'int', 'length'=>'int'], 'oci_lob_flush' => ['bool', 'flag'=>'int'], 'oci_lob_import' => ['bool', 'filename'=>'string'], 'oci_lob_is_equal' => ['bool', 'lob1'=>'OCI-Lob', 'lob2'=>'OCI-Lob'], 'oci_lob_load' => ['string|false'], 'oci_lob_read' => ['string|false', 'length'=>'int'], 'oci_lob_rewind' => ['bool'], 'oci_lob_save' => ['bool', 'data'=>'string', 'offset'=>'int'], 'oci_lob_seek' => ['bool', 'offset'=>'int', 'whence'=>'int'], 'oci_lob_size' => ['int|false'], 'oci_lob_tell' => ['int|false'], 'oci_lob_truncate' => ['bool', 'length'=>'int'], 'oci_lob_write' => ['int|false', 'string'=>'string', 'length'=>'int'], 'oci_lob_write_temporary' => ['bool', 'var'=>'string', 'lob_type'=>'int'], 'oci_new_collection' => ['OCI-Collection|false', 'connection'=>'resource', 'tdo'=>'string', 'schema='=>'string'], 'oci_new_connect' => ['resource|false', 'user'=>'string', 'pass'=>'string', 'db='=>'string', 'charset='=>'string', 'session_mode='=>'int'], 'oci_new_cursor' => ['resource|false', 'connection'=>'resource'], 'oci_new_descriptor' => ['OCI-Lob|false', 'connection'=>'resource', 'type='=>'int'], 'oci_num_fields' => ['0|positive-int|false', 'stmt'=>'resource'], 'oci_num_rows' => ['0|positive-int|false', 'stmt'=>'resource'], 'oci_parse' => ['resource|false', 'connection'=>'resource', 'statement'=>'string'], 'oci_password_change' => ['bool', 'connection'=>'', 'username'=>'string', 'old_password'=>'string', 'new_password'=>'string'], 'oci_pconnect' => ['resource|false', 'user'=>'string', 'pass'=>'string', 'db='=>'string', 'charset='=>'string', 'session_mode='=>'int'], 'oci_register_taf_callback' => ['bool', 'connection'=>'resource', 'callback='=>'callable'], 'oci_result' => ['string|false', 'stmt'=>'resource', 'column'=>'mixed'], 'oci_rollback' => ['bool', 'connection'=>'resource'], 'oci_server_version' => ['string|false', 'connection'=>'resource'], 'oci_set_action' => ['bool', 'connection'=>'resource', 'value'=>'string'], 'oci_set_client_identifier' => ['bool', 'connection'=>'resource', 'value'=>'string'], 'oci_set_client_info' => ['bool', 'connection'=>'resource', 'value'=>'string'], 'oci_set_db_operation' => ['bool', 'connection'=>'resource', 'value'=>'string'], 'oci_set_edition' => ['bool', 'value'=>'string'], 'oci_set_module_name' => ['bool', 'connection'=>'resource', 'value'=>'string'], 'oci_set_prefetch' => ['bool', 'stmt'=>'resource', 'prefetch_rows'=>'int'], 'oci_statement_type' => ['string|false', 'stmt'=>'resource'], 'oci_unregister_taf_callback' => ['bool', 'connection'=>'resource'], 'ocifetchinto' => ['int|false', 'stmt'=>'', '&w_output'=>'array', 'mode='=>'int'], 'ocigetbufferinglob' => ['bool'], 'ocisetbufferinglob' => ['bool', 'flag'=>'bool'], 'octdec' => ['int|float', 'octal_number'=>'string'], 'odbc_autocommit' => ['mixed', 'connection_id'=>'resource', 'onoff='=>'bool'], 'odbc_binmode' => ['bool', 'result_id'=>'int', 'mode'=>'int'], 'odbc_close' => ['void', 'connection_id'=>'resource'], 'odbc_close_all' => ['void'], 'odbc_columnprivileges' => ['resource', 'connection_id'=>'resource', 'catalog'=>'string', 'schema'=>'string', 'table'=>'string', 'column'=>'string'], 'odbc_columns' => ['resource', 'connection_id'=>'resource', 'qualifier='=>'string', 'owner='=>'string', 'table_name='=>'string', 'column_name='=>'string'], 'odbc_commit' => ['bool', 'connection_id'=>'resource'], 'odbc_connect' => ['resource|false', 'dsn'=>'string', 'user'=>'string', 'password'=>'string', 'cursor_option='=>'int'], 'odbc_cursor' => ['string|false', 'result_id'=>'resource'], 'odbc_data_source' => ['array|false', 'connection_id'=>'resource', 'fetch_type'=>'int'], 'odbc_do' => ['resource', 'connection_id'=>'resource', 'query'=>'string', 'flags='=>'int'], 'odbc_error' => ['string', 'connection_id='=>'resource'], 'odbc_errormsg' => ['string', 'connection_id='=>'resource'], 'odbc_exec' => ['resource|false', 'connection_id'=>'resource', 'query'=>'string', 'flags='=>'int'], 'odbc_execute' => ['bool', 'result_id'=>'resource', 'parameters_array='=>'array'], 'odbc_fetch_array' => ['array|false', 'result'=>'resource', 'rownumber='=>'int'], 'odbc_fetch_into' => ['int|false', 'result_id'=>'resource', '&w_result_array'=>'array', 'rownumber='=>'int'], 'odbc_fetch_object' => ['object|false', 'result'=>'int', 'rownumber='=>'int'], 'odbc_fetch_row' => ['bool', 'result_id'=>'resource', 'row_number='=>'int'], 'odbc_field_len' => ['int|false', 'result_id'=>'resource', 'field_number'=>'int'], 'odbc_field_name' => ['string|false', 'result_id'=>'resource', 'field_number'=>'int'], 'odbc_field_num' => ['int|false', 'result_id'=>'resource', 'field_name'=>'string'], 'odbc_field_precision' => ['int|false', 'result_id'=>'resource', 'field_number'=>'int'], 'odbc_field_scale' => ['int|false', 'result_id'=>'resource', 'field_number'=>'int'], 'odbc_field_type' => ['string|false', 'result_id'=>'resource', 'field_number'=>'int'], 'odbc_foreignkeys' => ['resource', 'connection_id'=>'resource', 'pk_qualifier'=>'string', 'pk_owner'=>'string', 'pk_table'=>'string', 'fk_qualifier'=>'string', 'fk_owner'=>'string', 'fk_table'=>'string'], 'odbc_free_result' => ['bool', 'result_id'=>'resource'], 'odbc_gettypeinfo' => ['resource', 'connection_id'=>'resource', 'data_type='=>'int'], 'odbc_longreadlen' => ['bool', 'result_id'=>'resource', 'length'=>'int'], 'odbc_next_result' => ['bool', 'result_id'=>'resource'], 'odbc_num_fields' => ['int', 'result_id'=>'resource'], 'odbc_num_rows' => ['int', 'result_id'=>'resource'], 'odbc_pconnect' => ['resource', 'dsn'=>'string', 'user'=>'string', 'password'=>'string', 'cursor_option='=>'int'], 'odbc_prepare' => ['resource|false', 'connection_id'=>'resource', 'query'=>'string'], 'odbc_primarykeys' => ['resource', 'connection_id'=>'resource', 'qualifier'=>'string', 'owner'=>'string', 'table'=>'string'], 'odbc_procedurecolumns' => ['resource', 'connection_id'=>'', 'qualifier'=>'string', 'owner'=>'string', 'proc'=>'string', 'column'=>'string'], 'odbc_procedures' => ['resource', 'connection_id'=>'', 'qualifier'=>'string', 'owner'=>'string', 'name'=>'string'], 'odbc_result' => ['mixed', 'result_id'=>'resource', 'field'=>'mixed'], 'odbc_result_all' => ['int|false', 'result_id'=>'resource', 'format='=>'string'], 'odbc_rollback' => ['bool', 'connection_id'=>'resource'], 'odbc_setoption' => ['bool', 'result_id'=>'resource', 'which'=>'int', 'option'=>'int', 'value'=>'int'], 'odbc_specialcolumns' => ['resource', 'connection_id'=>'resource', 'type'=>'int', 'qualifier'=>'string', 'owner'=>'string', 'table'=>'string', 'scope'=>'int', 'nullable'=>'int'], 'odbc_statistics' => ['resource', 'connection_id'=>'resource', 'qualifier'=>'string', 'owner'=>'string', 'name'=>'string', 'unique'=>'int', 'accuracy'=>'int'], 'odbc_tableprivileges' => ['resource', 'connection_id'=>'resource', 'qualifier'=>'string', 'owner'=>'string', 'name'=>'string'], 'odbc_tables' => ['resource', 'connection_id'=>'resource', 'qualifier='=>'string', 'owner='=>'string', 'name='=>'string', 'table_types='=>'string'], 'opcache_compile_file' => ['bool', 'file'=>'string'], 'opcache_get_configuration' => ['array|false'], 'opcache_get_status' => ['array|false', 'get_scripts='=>'bool'], 'opcache_invalidate' => ['bool', 'script'=>'string', 'force='=>'bool'], 'opcache_is_script_cached' => ['bool', 'script'=>'string'], 'opcache_reset' => ['bool'], 'openal_buffer_create' => ['resource'], 'openal_buffer_data' => ['bool', 'buffer'=>'resource', 'format'=>'int', 'data'=>'string', 'freq'=>'int'], 'openal_buffer_destroy' => ['bool', 'buffer'=>'resource'], 'openal_buffer_get' => ['int', 'buffer'=>'resource', 'property'=>'int'], 'openal_buffer_loadwav' => ['bool', 'buffer'=>'resource', 'wavfile'=>'string'], 'openal_context_create' => ['resource', 'device'=>'resource'], 'openal_context_current' => ['bool', 'context'=>'resource'], 'openal_context_destroy' => ['bool', 'context'=>'resource'], 'openal_context_process' => ['bool', 'context'=>'resource'], 'openal_context_suspend' => ['bool', 'context'=>'resource'], 'openal_device_close' => ['bool', 'device'=>'resource'], 'openal_device_open' => ['resource|false', 'device_desc='=>'string'], 'openal_listener_get' => ['mixed', 'property'=>'int'], 'openal_listener_set' => ['bool', 'property'=>'int', 'setting'=>'mixed'], 'openal_source_create' => ['resource'], 'openal_source_destroy' => ['bool', 'source'=>'resource'], 'openal_source_get' => ['mixed', 'source'=>'resource', 'property'=>'int'], 'openal_source_pause' => ['bool', 'source'=>'resource'], 'openal_source_play' => ['bool', 'source'=>'resource'], 'openal_source_rewind' => ['bool', 'source'=>'resource'], 'openal_source_set' => ['bool', 'source'=>'resource', 'property'=>'int', 'setting'=>'mixed'], 'openal_source_stop' => ['bool', 'source'=>'resource'], 'openal_stream' => ['resource', 'source'=>'resource', 'format'=>'int', 'rate'=>'int'], 'opendir' => ['resource|false', 'path'=>'string', 'context='=>'resource'], 'openlog' => ['bool', 'ident'=>'string', 'option'=>'int', 'facility'=>'int'], 'openssl_cipher_iv_length' => ['int|false', 'method'=>'string'], 'openssl_csr_export' => ['bool', 'csr'=>'string|resource', '&w_out'=>'string', 'notext='=>'bool'], 'openssl_csr_export_to_file' => ['bool', 'csr'=>'string|resource', 'outfilename'=>'string', 'notext='=>'bool'], 'openssl_csr_get_public_key' => ['resource|false', 'csr'=>'string|resource', 'use_shortnames='=>'bool'], 'openssl_csr_get_subject' => ['array|false', 'csr'=>'string|resource', 'use_shortnames='=>'bool'], 'openssl_csr_new' => ['resource|false', 'dn'=>'array', '&w_privkey'=>'resource', 'configargs='=>'array', 'extraattribs='=>'array'], 'openssl_csr_sign' => ['resource|false', 'csr'=>'string|resource', 'x509'=>'string|resource|null', 'priv_key'=>'string|resource|array', 'days'=>'int', 'config_args='=>'array', 'serial='=>'int'], 'openssl_decrypt' => ['string|false', 'data'=>'string', 'method'=>'string', 'key'=>'string', 'options='=>'int', 'iv='=>'string', 'tag='=>'string', 'aad='=>'string'], 'openssl_dh_compute_key' => ['string|false', 'pub_key'=>'string', 'dh_key'=>'resource'], 'openssl_digest' => ['string|false', 'data'=>'string', 'method'=>'string', 'raw_output='=>'bool'], 'openssl_encrypt' => ['string|false', 'data'=>'string', 'method'=>'string', 'key'=>'string', 'options='=>'int', 'iv='=>'string', '&w_tag='=>'string', 'aad='=>'string', 'tag_length='=>'int'], 'openssl_error_string' => ['string|false'], 'openssl_free_key' => ['void', 'key_identifier'=>'resource'], 'openssl_get_cert_locations' => ['array'], 'openssl_get_cipher_methods' => ['list', 'aliases='=>'bool'], 'openssl_get_curve_names' => ['list|false'], 'openssl_get_md_methods' => ['list', 'aliases='=>'bool'], 'openssl_get_privatekey' => ['resource|false', 'key'=>'string', 'passphrase='=>'string'], 'openssl_get_publickey' => ['resource|false', 'cert'=>'resource|string'], 'openssl_open' => ['bool', 'sealed_data'=>'string', '&w_open_data'=>'string', 'env_key'=>'string', 'priv_key_id'=>'string|array|resource', 'method='=>'string', 'iv='=>'string'], 'openssl_pbkdf2' => ['string|false', 'password'=>'string', 'salt'=>'string', 'key_length'=>'int', 'iterations'=>'int', 'digest_algorithm'=>'string'], 'openssl_pkcs12_export' => ['bool', 'x509'=>'string|resource', '&w_out'=>'string', 'priv_key'=>'string|array|resource', 'pass'=>'string', 'args='=>'array'], 'openssl_pkcs12_export_to_file' => ['bool', 'x509'=>'string|resource', 'filename'=>'string', 'priv_key'=>'string|array|resource', 'pass'=>'string', 'args='=>'array'], 'openssl_pkcs12_read' => ['bool', 'pkcs12'=>'string', '&w_certs'=>'array', 'pass'=>'string'], 'openssl_pkcs7_decrypt' => ['bool', 'infilename'=>'string', 'outfilename'=>'string', 'recipcert'=>'string|resource', 'recipkey='=>'string|resource|array'], 'openssl_pkcs7_encrypt' => ['bool', 'infile'=>'string', 'outfile'=>'string', 'recipcerts'=>'string|resource|array', 'headers'=>'array', 'flags='=>'int', 'cipherid='=>'int'], 'openssl_pkcs7_read' => ['bool', 'infilename'=>'string', '&w_certs'=>'array'], 'openssl_pkcs7_sign' => ['bool', 'infile'=>'string', 'outfile'=>'string', 'signcert'=>'string|resource', 'privkey'=>'string|resource|array', 'headers'=>'array', 'flags='=>'int', 'extracerts='=>'string'], 'openssl_pkcs7_verify' => ['bool|int', 'filename'=>'string', 'flags'=>'int', 'outfilename='=>'string', 'cainfo='=>'array', 'extracerts='=>'string', 'content='=>'string', 'p7bfilename='=>'string'], 'openssl_pkey_derive' => ['string|false', 'pub_key'=>'resource', 'priv_key'=>'resource', 'keylen='=>'int'], 'openssl_pkey_export' => ['bool', 'key'=>'resource', '&w_out'=>'string', 'passphrase='=>'string|null', 'configargs='=>'array'], 'openssl_pkey_export_to_file' => ['bool', 'key'=>'resource|string|array', 'outfilename'=>'string', 'passphrase='=>'string|null', 'configargs='=>'array'], 'openssl_pkey_free' => ['void', 'key'=>'resource'], 'openssl_pkey_get_details' => ['array|false', 'key'=>'resource'], 'openssl_pkey_get_private' => ['resource|false', 'key'=>'string', 'passphrase='=>'string'], 'openssl_pkey_get_public' => ['resource|false', 'certificate'=>'resource|string'], 'openssl_pkey_new' => ['resource|false', 'configargs='=>'array'], 'openssl_private_decrypt' => ['bool', 'data'=>'string', '&w_decrypted'=>'string', 'key'=>'string|resource|array', 'padding='=>'int'], 'openssl_private_encrypt' => ['bool', 'data'=>'string', '&w_crypted'=>'string', 'key'=>'string|resource|array', 'padding='=>'int'], 'openssl_public_decrypt' => ['bool', 'data'=>'string', '&w_decrypted'=>'string', 'key'=>'string|resource', 'padding='=>'int'], 'openssl_public_encrypt' => ['bool', 'data'=>'string', '&w_crypted'=>'string', 'key'=>'string|resource', 'padding='=>'int'], 'openssl_random_pseudo_bytes' => ['string|false', 'length'=>'int', '&w_crypto_strong='=>'bool'], 'openssl_seal' => ['int|false', 'data'=>'string', '&w_sealed_data'=>'string', '&w_env_keys'=>'array', 'pub_key_ids'=>'array', 'method='=>'string', '&w_iv='=>'string'], 'openssl_sign' => ['bool', 'data'=>'string', '&w_signature'=>'string', 'priv_key_id'=>'resource|string', 'signature_alg='=>'int|string'], 'openssl_spki_export' => ['string|null|false', 'spkac'=>'string'], 'openssl_spki_export_challenge' => ['string|null|false', 'spkac'=>'string'], 'openssl_spki_new' => ['string|null|false', 'privkey'=>'resource', 'challenge'=>'string', 'algorithm='=>'int'], 'openssl_spki_verify' => ['bool', 'spkac'=>'string'], 'openssl_verify' => ['-1|0|1|false', 'data'=>'string', 'signature'=>'string', 'pub_key_id'=>'resource|string', 'signature_alg='=>'int|string'], 'openssl_x509_check_private_key' => ['bool', 'cert'=>'string|resource', 'key'=>'string|resource|array'], 'openssl_x509_checkpurpose' => ['bool|int', 'x509cert'=>'string|resource', 'purpose'=>'int', 'cainfo='=>'array', 'untrustedfile='=>'string'], 'openssl_x509_export' => ['bool', 'x509'=>'string|resource', '&w_output'=>'string', 'notext='=>'bool'], 'openssl_x509_export_to_file' => ['bool', 'x509'=>'string|resource', 'outfilename'=>'string', 'notext='=>'bool'], 'openssl_x509_fingerprint' => ['string|false', 'x509'=>'string|resource', 'hash_algorithm='=>'string', 'raw_output='=>'bool'], 'openssl_x509_free' => ['void', 'x509'=>'resource'], 'openssl_x509_parse' => ['array|false', 'x509cert'=>'string|resource', 'shortnames='=>'bool'], 'openssl_x509_read' => ['resource|false', 'x509certdata'=>'string|resource'], 'ord' => ['int<0, 255>', 'character'=>'string'], 'OuterIterator::getInnerIterator' => ['Iterator'], 'OutOfBoundsException::__clone' => ['void'], 'OutOfBoundsException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?OutOfBoundsException)'], 'OutOfBoundsException::__toString' => ['string'], 'OutOfBoundsException::getCode' => ['int'], 'OutOfBoundsException::getFile' => ['string'], 'OutOfBoundsException::getLine' => ['int'], 'OutOfBoundsException::getMessage' => ['string'], 'OutOfBoundsException::getPrevious' => ['Throwable|OutOfBoundsException|null'], 'OutOfBoundsException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'OutOfBoundsException::getTraceAsString' => ['string'], 'OutOfRangeException::__clone' => ['void'], 'OutOfRangeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?OutOfRangeException)'], 'OutOfRangeException::__toString' => ['string'], 'OutOfRangeException::getCode' => ['int'], 'OutOfRangeException::getFile' => ['string'], 'OutOfRangeException::getLine' => ['int'], 'OutOfRangeException::getMessage' => ['string'], 'OutOfRangeException::getPrevious' => ['Throwable|OutOfRangeException|null'], 'OutOfRangeException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'OutOfRangeException::getTraceAsString' => ['string'], 'output_add_rewrite_var' => ['bool', 'name'=>'string', 'value'=>'string'], 'output_reset_rewrite_vars' => ['bool'], 'OverflowException::__clone' => ['void'], 'OverflowException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?OverflowException)'], 'OverflowException::__toString' => ['string'], 'OverflowException::getCode' => ['int'], 'OverflowException::getFile' => ['string'], 'OverflowException::getLine' => ['int'], 'OverflowException::getMessage' => ['string'], 'OverflowException::getPrevious' => ['Throwable|OverflowException|null'], 'OverflowException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'OverflowException::getTraceAsString' => ['string'], 'overload' => ['', 'class_name'=>'string'], 'override_function' => ['bool', 'function_name'=>'string', 'function_args'=>'string', 'function_code'=>'string'], 'pack' => ['string', 'format'=>'string', '...args='=>'mixed'], 'ParentIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator'], 'ParentIterator::accept' => ['bool'], 'ParentIterator::getChildren' => ['ParentIterator'], 'ParentIterator::hasChildren' => ['bool'], 'ParentIterator::next' => ['void'], 'ParentIterator::rewind' => ['void'], 'ParentIterator::valid' => [''], 'Parle\Lexer::advance' => ['void'], 'Parle\Lexer::build' => ['void'], 'Parle\Lexer::callout' => ['void', 'id'=>'int', 'callback'=>'callable'], 'Parle\Lexer::consume' => ['void', 'data'=>'string'], 'Parle\Lexer::dump' => ['void'], 'Parle\Lexer::getToken' => ['Parle\Token'], 'Parle\Lexer::insertMacro' => ['void', 'name'=>'string', 'regex'=>'string'], 'Parle\Lexer::push' => ['void', 'regex'=>'string', 'id'=>'int'], 'Parle\Lexer::reset' => ['void', 'pos'=>'int'], 'Parle\Parser::advance' => ['void'], 'Parle\Parser::build' => ['void'], 'Parle\Parser::consume' => ['void', 'data'=>'string', 'lexer'=>'Parle\Lexer'], 'Parle\Parser::dump' => ['void'], 'Parle\Parser::errorInfo' => ['Parle\ErrorInfo'], 'Parle\Parser::left' => ['void', 'token'=>'string'], 'Parle\Parser::nonassoc' => ['void', 'token'=>'string'], 'Parle\Parser::precedence' => ['void', 'token'=>'string'], 'Parle\Parser::push' => ['int', 'name'=>'string', 'rule'=>'string'], 'Parle\Parser::reset' => ['void', 'tokenId'=>'int'], 'Parle\Parser::right' => ['void', 'token'=>'string'], 'Parle\Parser::sigil' => ['string', 'idx'=>'array'], 'Parle\Parser::token' => ['void', 'token'=>'string'], 'Parle\Parser::tokenId' => ['int', 'token'=>'string'], 'Parle\Parser::trace' => ['string'], 'Parle\Parser::validate' => ['bool', 'data'=>'string', 'lexer'=>'Parle\Lexer'], 'Parle\RLexer::advance' => ['void'], 'Parle\RLexer::build' => ['void'], 'Parle\RLexer::callout' => ['void', 'id'=>'int', 'callback'=>'callable'], 'Parle\RLexer::consume' => ['void', 'data'=>'string'], 'Parle\RLexer::dump' => ['void'], 'Parle\RLexer::getToken' => ['Parle\Token'], 'Parle\RLexer::push' => ['void', 'state'=>'string', 'regex'=>'string', 'newState'=>'string'], 'Parle\RLexer::pushState' => ['int', 'state'=>'string'], 'Parle\RLexer::reset' => ['void', 'pos'=>'int'], 'Parle\RParser::advance' => ['void'], 'Parle\RParser::build' => ['void'], 'Parle\RParser::consume' => ['void', 'data'=>'string', 'lexer'=>'Parle\Lexer'], 'Parle\RParser::dump' => ['void'], 'Parle\RParser::errorInfo' => ['Parle\ErrorInfo'], 'Parle\RParser::left' => ['void', 'token'=>'string'], 'Parle\RParser::nonassoc' => ['void', 'token'=>'string'], 'Parle\RParser::precedence' => ['void', 'token'=>'string'], 'Parle\RParser::push' => ['int', 'name'=>'string', 'rule'=>'string'], 'Parle\RParser::reset' => ['void', 'tokenId'=>'int'], 'Parle\RParser::right' => ['void', 'token'=>'string'], 'Parle\RParser::sigil' => ['string', 'idx'=>'array'], 'Parle\RParser::token' => ['void', 'token'=>'string'], 'Parle\RParser::tokenId' => ['int', 'token'=>'string'], 'Parle\RParser::trace' => ['string'], 'Parle\RParser::validate' => ['bool', 'data'=>'string', 'lexer'=>'Parle\Lexer'], 'Parle\Stack::pop' => ['void'], 'Parle\Stack::push' => ['void', 'item'=>''], 'parse_ini_file' => ['array|false', 'filename'=>'string', 'process_sections='=>'bool', 'scanner_mode='=>'int'], 'parse_ini_string' => ['array|false', 'ini_string'=>'string', 'process_sections='=>'bool', 'scanner_mode='=>'int'], 'parse_str' => ['void', 'encoded_string'=>'string', '&w_result='=>'array'], 'parse_url' => ['array|int|string|false|null', 'url'=>'string', 'url_component='=>'int'], 'ParseError::__clone' => ['void'], 'ParseError::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?ParseError)'], 'ParseError::__toString' => ['string'], 'ParseError::getCode' => ['int'], 'ParseError::getFile' => ['string'], 'ParseError::getLine' => ['int'], 'ParseError::getMessage' => ['string'], 'ParseError::getPrevious' => ['Throwable|ParseError|null'], 'ParseError::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'ParseError::getTraceAsString' => ['string'], 'parsekit_compile_file' => ['array', 'filename'=>'string', 'errors='=>'array', 'options='=>'int'], 'parsekit_compile_string' => ['array', 'phpcode'=>'string', 'errors='=>'array', 'options='=>'int'], 'parsekit_func_arginfo' => ['array', 'function'=>'mixed'], 'passthru' => ['void', 'command'=>'string', '&w_return_value='=>'int'], 'password_get_info' => ['array', 'hash'=>'string'], 'password_hash' => ['__benevolent', 'password'=>'string', 'algo'=>'string|int', 'options='=>'array'], 'password_make_salt' => ['bool', 'password'=>'string', 'hash'=>'string'], 'password_needs_rehash' => ['bool', 'hash'=>'string', 'algo'=>'int', 'options='=>'array'], 'password_verify' => ['bool', 'password'=>'string', 'hash'=>'string'], 'pathinfo' => ['array|string', 'path'=>'string', 'options='=>'int'], 'pclose' => ['int', 'fp'=>'resource'], 'pcnlt_sigwaitinfo' => ['int', 'set'=>'array', '&w_siginfo'=>'array'], 'pcntl_alarm' => ['int', 'seconds'=>'int'], 'pcntl_async_signals' => ['bool', 'on='=>'bool'], 'pcntl_errno' => ['int'], 'pcntl_exec' => ['bool', 'path'=>'string', 'args='=>'array', 'envs='=>'array'], 'pcntl_fork' => ['int'], 'pcntl_get_last_error' => ['int'], 'pcntl_getpriority' => ['int|false', 'pid='=>'int', 'process_identifier='=>'int'], 'pcntl_setpriority' => ['bool', 'priority'=>'int', 'pid='=>'int', 'process_identifier='=>'int'], 'pcntl_signal' => ['bool', 'signo'=>'int', 'handle'=>'callable|int', 'restart_syscalls='=>'bool'], 'pcntl_signal_dispatch' => ['bool'], 'pcntl_signal_get_handler' => ['int|string', 'signo'=>'int'], 'pcntl_sigprocmask' => ['bool', 'how'=>'int', 'set'=>'array', '&w_oldset='=>'array'], 'pcntl_sigtimedwait' => ['int|false', 'set'=>'array', '&w_siginfo='=>'array', 'seconds='=>'int', 'nanoseconds='=>'int'], 'pcntl_sigwaitinfo' => ['int|false', 'set'=>'array', '&w_siginfo='=>'array'], 'pcntl_strerror' => ['string', 'errno'=>'int'], 'pcntl_wait' => ['int', '&w_status'=>'int', 'options='=>'int', '&w_rusage='=>'array'], 'pcntl_waitpid' => ['int', 'pid'=>'int', '&w_status'=>'int', 'options='=>'int', '&w_rusage='=>'array'], 'pcntl_wexitstatus' => ['int|false', 'status'=>'int'], 'pcntl_wifcontinued' => ['bool', 'status'=>'int'], 'pcntl_wifexited' => ['bool', 'status'=>'int'], 'pcntl_wifsignaled' => ['bool', 'status'=>'int'], 'pcntl_wifstopped' => ['bool', 'status'=>'int'], 'pcntl_wstopsig' => ['int|false', 'status'=>'int'], 'pcntl_wtermsig' => ['int|false', 'status'=>'int'], 'PDF_activate_item' => ['bool', 'pdfdoc'=>'resource', 'id'=>'int'], 'PDF_add_launchlink' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string'], 'PDF_add_locallink' => ['bool', 'pdfdoc'=>'resource', 'lowerleftx'=>'float', 'lowerlefty'=>'float', 'upperrightx'=>'float', 'upperrighty'=>'float', 'page'=>'int', 'dest'=>'string'], 'PDF_add_nameddest' => ['bool', 'pdfdoc'=>'resource', 'name'=>'string', 'optlist'=>'string'], 'PDF_add_note' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'contents'=>'string', 'title'=>'string', 'icon'=>'string', 'open'=>'int'], 'PDF_add_pdflink' => ['bool', 'pdfdoc'=>'resource', 'bottom_left_x'=>'float', 'bottom_left_y'=>'float', 'up_right_x'=>'float', 'up_right_y'=>'float', 'filename'=>'string', 'page'=>'int', 'dest'=>'string'], 'PDF_add_table_cell' => ['int', 'pdfdoc'=>'resource', 'table'=>'int', 'column'=>'int', 'row'=>'int', 'text'=>'string', 'optlist'=>'string'], 'PDF_add_textflow' => ['int', 'pdfdoc'=>'resource', 'textflow'=>'int', 'text'=>'string', 'optlist'=>'string'], 'PDF_add_thumbnail' => ['bool', 'pdfdoc'=>'resource', 'image'=>'int'], 'PDF_add_weblink' => ['bool', 'pdfdoc'=>'resource', 'lowerleftx'=>'float', 'lowerlefty'=>'float', 'upperrightx'=>'float', 'upperrighty'=>'float', 'url'=>'string'], 'PDF_arc' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'alpha'=>'float', 'beta'=>'float'], 'PDF_arcn' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'alpha'=>'float', 'beta'=>'float'], 'PDF_attach_file' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string', 'description'=>'string', 'author'=>'string', 'mimetype'=>'string', 'icon'=>'string'], 'PDF_begin_document' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'optlist'=>'string'], 'PDF_begin_font' => ['bool', 'pdfdoc'=>'resource', 'filename'=>'string', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float', 'optlist'=>'string'], 'PDF_begin_glyph' => ['bool', 'pdfdoc'=>'resource', 'glyphname'=>'string', 'wx'=>'float', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float'], 'PDF_begin_item' => ['int', 'pdfdoc'=>'resource', 'tag'=>'string', 'optlist'=>'string'], 'PDF_begin_layer' => ['bool', 'pdfdoc'=>'resource', 'layer'=>'int'], 'PDF_begin_page' => ['bool', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float'], 'PDF_begin_page_ext' => ['bool', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'optlist'=>'string'], 'PDF_begin_pattern' => ['int', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'xstep'=>'float', 'ystep'=>'float', 'painttype'=>'int'], 'PDF_begin_template' => ['int', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float'], 'PDF_begin_template_ext' => ['int', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'optlist'=>'string'], 'PDF_circle' => ['bool', 'pdfdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'r'=>'float'], 'PDF_clip' => ['bool', 'p'=>'resource'], 'PDF_close' => ['bool', 'p'=>'resource'], 'PDF_close_image' => ['bool', 'p'=>'resource', 'image'=>'int'], 'PDF_close_pdi' => ['bool', 'p'=>'resource', 'doc'=>'int'], 'PDF_close_pdi_page' => ['bool', 'p'=>'resource', 'page'=>'int'], 'PDF_closepath' => ['bool', 'p'=>'resource'], 'PDF_closepath_fill_stroke' => ['bool', 'p'=>'resource'], 'PDF_closepath_stroke' => ['bool', 'p'=>'resource'], 'PDF_concat' => ['bool', 'p'=>'resource', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float'], 'PDF_continue_text' => ['bool', 'p'=>'resource', 'text'=>'string'], 'PDF_create_3dview' => ['int', 'pdfdoc'=>'resource', 'username'=>'string', 'optlist'=>'string'], 'PDF_create_action' => ['int', 'pdfdoc'=>'resource', 'type'=>'string', 'optlist'=>'string'], 'PDF_create_annotation' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'type'=>'string', 'optlist'=>'string'], 'PDF_create_bookmark' => ['int', 'pdfdoc'=>'resource', 'text'=>'string', 'optlist'=>'string'], 'PDF_create_field' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'name'=>'string', 'type'=>'string', 'optlist'=>'string'], 'PDF_create_fieldgroup' => ['bool', 'pdfdoc'=>'resource', 'name'=>'string', 'optlist'=>'string'], 'PDF_create_gstate' => ['int', 'pdfdoc'=>'resource', 'optlist'=>'string'], 'PDF_create_pvf' => ['bool', 'pdfdoc'=>'resource', 'filename'=>'string', 'data'=>'string', 'optlist'=>'string'], 'PDF_create_textflow' => ['int', 'pdfdoc'=>'resource', 'text'=>'string', 'optlist'=>'string'], 'PDF_curveto' => ['bool', 'p'=>'resource', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'], 'PDF_define_layer' => ['int', 'pdfdoc'=>'resource', 'name'=>'string', 'optlist'=>'string'], 'PDF_delete' => ['bool', 'pdfdoc'=>'resource'], 'PDF_delete_pvf' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string'], 'PDF_delete_table' => ['bool', 'pdfdoc'=>'resource', 'table'=>'int', 'optlist'=>'string'], 'PDF_delete_textflow' => ['bool', 'pdfdoc'=>'resource', 'textflow'=>'int'], 'PDF_encoding_set_char' => ['bool', 'pdfdoc'=>'resource', 'encoding'=>'string', 'slot'=>'int', 'glyphname'=>'string', 'uv'=>'int'], 'PDF_end_document' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'], 'PDF_end_font' => ['bool', 'pdfdoc'=>'resource'], 'PDF_end_glyph' => ['bool', 'pdfdoc'=>'resource'], 'PDF_end_item' => ['bool', 'pdfdoc'=>'resource', 'id'=>'int'], 'PDF_end_layer' => ['bool', 'pdfdoc'=>'resource'], 'PDF_end_page' => ['bool', 'p'=>'resource'], 'PDF_end_page_ext' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'], 'PDF_end_pattern' => ['bool', 'p'=>'resource'], 'PDF_end_template' => ['bool', 'p'=>'resource'], 'PDF_endpath' => ['bool', 'p'=>'resource'], 'PDF_fill' => ['bool', 'p'=>'resource'], 'PDF_fill_imageblock' => ['int', 'pdfdoc'=>'resource', 'page'=>'int', 'blockname'=>'string', 'image'=>'int', 'optlist'=>'string'], 'PDF_fill_pdfblock' => ['int', 'pdfdoc'=>'resource', 'page'=>'int', 'blockname'=>'string', 'contents'=>'int', 'optlist'=>'string'], 'PDF_fill_stroke' => ['bool', 'p'=>'resource'], 'PDF_fill_textblock' => ['int', 'pdfdoc'=>'resource', 'page'=>'int', 'blockname'=>'string', 'text'=>'string', 'optlist'=>'string'], 'PDF_findfont' => ['int', 'p'=>'resource', 'fontname'=>'string', 'encoding'=>'string', 'embed'=>'int'], 'PDF_fit_image' => ['bool', 'pdfdoc'=>'resource', 'image'=>'int', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'], 'PDF_fit_pdi_page' => ['bool', 'pdfdoc'=>'resource', 'page'=>'int', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'], 'PDF_fit_table' => ['string', 'pdfdoc'=>'resource', 'table'=>'int', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'optlist'=>'string'], 'PDF_fit_textflow' => ['string', 'pdfdoc'=>'resource', 'textflow'=>'int', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'optlist'=>'string'], 'PDF_fit_textline' => ['bool', 'pdfdoc'=>'resource', 'text'=>'string', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'], 'PDF_get_apiname' => ['string', 'pdfdoc'=>'resource'], 'PDF_get_buffer' => ['string', 'p'=>'resource'], 'PDF_get_errmsg' => ['string', 'pdfdoc'=>'resource'], 'PDF_get_errnum' => ['int', 'pdfdoc'=>'resource'], 'PDF_get_majorversion' => ['int'], 'PDF_get_minorversion' => ['int'], 'PDF_get_parameter' => ['string', 'p'=>'resource', 'key'=>'string', 'modifier'=>'float'], 'PDF_get_pdi_parameter' => ['string', 'p'=>'resource', 'key'=>'string', 'doc'=>'int', 'page'=>'int', 'reserved'=>'int'], 'PDF_get_pdi_value' => ['float', 'p'=>'resource', 'key'=>'string', 'doc'=>'int', 'page'=>'int', 'reserved'=>'int'], 'PDF_get_value' => ['float', 'p'=>'resource', 'key'=>'string', 'modifier'=>'float'], 'PDF_info_font' => ['float', 'pdfdoc'=>'resource', 'font'=>'int', 'keyword'=>'string', 'optlist'=>'string'], 'PDF_info_matchbox' => ['float', 'pdfdoc'=>'resource', 'boxname'=>'string', 'num'=>'int', 'keyword'=>'string'], 'PDF_info_table' => ['float', 'pdfdoc'=>'resource', 'table'=>'int', 'keyword'=>'string'], 'PDF_info_textflow' => ['float', 'pdfdoc'=>'resource', 'textflow'=>'int', 'keyword'=>'string'], 'PDF_info_textline' => ['float', 'pdfdoc'=>'resource', 'text'=>'string', 'keyword'=>'string', 'optlist'=>'string'], 'PDF_initgraphics' => ['bool', 'p'=>'resource'], 'PDF_lineto' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float'], 'PDF_load_3ddata' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'optlist'=>'string'], 'PDF_load_font' => ['int', 'pdfdoc'=>'resource', 'fontname'=>'string', 'encoding'=>'string', 'optlist'=>'string'], 'PDF_load_iccprofile' => ['int', 'pdfdoc'=>'resource', 'profilename'=>'string', 'optlist'=>'string'], 'PDF_load_image' => ['int', 'pdfdoc'=>'resource', 'imagetype'=>'string', 'filename'=>'string', 'optlist'=>'string'], 'PDF_makespotcolor' => ['int', 'p'=>'resource', 'spotname'=>'string'], 'PDF_moveto' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float'], 'PDF_new' => ['resource'], 'PDF_open_ccitt' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'width'=>'int', 'height'=>'int', 'bitreverse'=>'int', 'k'=>'int', 'blackls1'=>'int'], 'PDF_open_file' => ['bool', 'p'=>'resource', 'filename'=>'string'], 'PDF_open_image' => ['int', 'p'=>'resource', 'imagetype'=>'string', 'source'=>'string', 'data'=>'string', 'length'=>'int', 'width'=>'int', 'height'=>'int', 'components'=>'int', 'bpc'=>'int', 'params'=>'string'], 'PDF_open_image_file' => ['int', 'p'=>'resource', 'imagetype'=>'string', 'filename'=>'string', 'stringparam'=>'string', 'intparam'=>'int'], 'PDF_open_memory_image' => ['int', 'p'=>'resource', 'image'=>'resource'], 'PDF_open_pdi' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'optlist'=>'string', 'len'=>'int'], 'PDF_open_pdi_document' => ['int', 'p'=>'resource', 'filename'=>'string', 'optlist'=>'string'], 'PDF_open_pdi_page' => ['int', 'p'=>'resource', 'doc'=>'int', 'pagenumber'=>'int', 'optlist'=>'string'], 'PDF_pcos_get_number' => ['float', 'p'=>'resource', 'doc'=>'int', 'path'=>'string'], 'PDF_pcos_get_stream' => ['string', 'p'=>'resource', 'doc'=>'int', 'optlist'=>'string', 'path'=>'string'], 'PDF_pcos_get_string' => ['string', 'p'=>'resource', 'doc'=>'int', 'path'=>'string'], 'PDF_place_image' => ['bool', 'pdfdoc'=>'resource', 'image'=>'int', 'x'=>'float', 'y'=>'float', 'scale'=>'float'], 'PDF_place_pdi_page' => ['bool', 'pdfdoc'=>'resource', 'page'=>'int', 'x'=>'float', 'y'=>'float', 'sx'=>'float', 'sy'=>'float'], 'PDF_process_pdi' => ['int', 'pdfdoc'=>'resource', 'doc'=>'int', 'page'=>'int', 'optlist'=>'string'], 'PDF_rect' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'], 'PDF_restore' => ['bool', 'p'=>'resource'], 'PDF_resume_page' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'], 'PDF_rotate' => ['bool', 'p'=>'resource', 'phi'=>'float'], 'PDF_save' => ['bool', 'p'=>'resource'], 'PDF_scale' => ['bool', 'p'=>'resource', 'sx'=>'float', 'sy'=>'float'], 'PDF_set_border_color' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], 'PDF_set_border_dash' => ['bool', 'pdfdoc'=>'resource', 'black'=>'float', 'white'=>'float'], 'PDF_set_border_style' => ['bool', 'pdfdoc'=>'resource', 'style'=>'string', 'width'=>'float'], 'PDF_set_gstate' => ['bool', 'pdfdoc'=>'resource', 'gstate'=>'int'], 'PDF_set_info' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'string'], 'PDF_set_layer_dependency' => ['bool', 'pdfdoc'=>'resource', 'type'=>'string', 'optlist'=>'string'], 'PDF_set_parameter' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'string'], 'PDF_set_text_pos' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float'], 'PDF_set_value' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'float'], 'PDF_setcolor' => ['bool', 'p'=>'resource', 'fstype'=>'string', 'colorspace'=>'string', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float'], 'PDF_setdash' => ['bool', 'pdfdoc'=>'resource', 'b'=>'float', 'w'=>'float'], 'PDF_setdashpattern' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'], 'PDF_setflat' => ['bool', 'pdfdoc'=>'resource', 'flatness'=>'float'], 'PDF_setfont' => ['bool', 'pdfdoc'=>'resource', 'font'=>'int', 'fontsize'=>'float'], 'PDF_setgray' => ['bool', 'p'=>'resource', 'g'=>'float'], 'PDF_setgray_fill' => ['bool', 'p'=>'resource', 'g'=>'float'], 'PDF_setgray_stroke' => ['bool', 'p'=>'resource', 'g'=>'float'], 'PDF_setlinecap' => ['bool', 'p'=>'resource', 'linecap'=>'int'], 'PDF_setlinejoin' => ['bool', 'p'=>'resource', 'value'=>'int'], 'PDF_setlinewidth' => ['bool', 'p'=>'resource', 'width'=>'float'], 'PDF_setmatrix' => ['bool', 'p'=>'resource', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float'], 'PDF_setmiterlimit' => ['bool', 'pdfdoc'=>'resource', 'miter'=>'float'], 'PDF_setrgbcolor' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], 'PDF_setrgbcolor_fill' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], 'PDF_setrgbcolor_stroke' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], 'PDF_shading' => ['int', 'pdfdoc'=>'resource', 'shtype'=>'string', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float', 'optlist'=>'string'], 'PDF_shading_pattern' => ['int', 'pdfdoc'=>'resource', 'shading'=>'int', 'optlist'=>'string'], 'PDF_shfill' => ['bool', 'pdfdoc'=>'resource', 'shading'=>'int'], 'PDF_show' => ['bool', 'pdfdoc'=>'resource', 'text'=>'string'], 'PDF_show_boxed' => ['int', 'p'=>'resource', 'text'=>'string', 'left'=>'float', 'top'=>'float', 'width'=>'float', 'height'=>'float', 'mode'=>'string', 'feature'=>'string'], 'PDF_show_xy' => ['bool', 'p'=>'resource', 'text'=>'string', 'x'=>'float', 'y'=>'float'], 'PDF_skew' => ['bool', 'p'=>'resource', 'alpha'=>'float', 'beta'=>'float'], 'PDF_stringwidth' => ['float', 'p'=>'resource', 'text'=>'string', 'font'=>'int', 'fontsize'=>'float'], 'PDF_stroke' => ['bool', 'p'=>'resource'], 'PDF_suspend_page' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'], 'PDF_translate' => ['bool', 'p'=>'resource', 'tx'=>'float', 'ty'=>'float'], 'PDF_utf16_to_utf8' => ['string', 'pdfdoc'=>'resource', 'utf16string'=>'string'], 'PDF_utf32_to_utf16' => ['string', 'pdfdoc'=>'resource', 'utf32string'=>'string', 'ordering'=>'string'], 'PDF_utf8_to_utf16' => ['string', 'pdfdoc'=>'resource', 'utf8string'=>'string', 'ordering'=>'string'], 'PDO::__construct' => ['void', 'dsn'=>'string', 'username='=>'?string', 'passwd='=>'?string', 'options='=>'?array'], 'PDO::__sleep' => ['list'], 'PDO::__wakeup' => ['void'], 'PDO::beginTransaction' => ['bool'], 'PDO::commit' => ['bool'], 'PDO::cubrid_schema' => ['array', 'schema_type'=>'int', 'table_name='=>'string', 'col_name='=>'string'], 'PDO::errorCode' => ['string|null'], 'PDO::errorInfo' => ['array'], 'PDO::exec' => ['int|false', 'query'=>'string'], 'PDO::getAttribute' => ['', 'attribute'=>'int'], 'PDO::getAvailableDrivers' => ['array'], 'PDO::inTransaction' => ['bool'], 'PDO::lastInsertId' => ['string|false', 'seqname='=>'string'], 'PDO::pgsqlCopyFromArray' => ['bool', 'table_name'=>'string', 'rows'=>'array', 'delimiter='=>'string', 'null_as='=>'string', 'fields='=>'string'], 'PDO::pgsqlCopyFromFile' => ['bool', 'table_name'=>'string', 'filename'=>'string', 'delimiter='=>'string', 'null_as='=>'string', 'fields='=>'string'], 'PDO::pgsqlCopyToArray' => ['array', 'table_name'=>'string', 'delimiter='=>'string', 'null_as='=>'string', 'fields='=>'string'], 'PDO::pgsqlCopyToFile' => ['bool', 'table_name'=>'string', 'filename'=>'string', 'delimiter='=>'string', 'null_as='=>'string', 'fields='=>'string'], 'PDO::pgsqlGetNotify' => ['array', 'result_type='=>'int', 'ms_timeout='=>'int'], 'PDO::pgsqlGetPid' => ['int'], 'PDO::pgsqlLOBCreate' => ['string'], 'PDO::pgsqlLOBOpen' => ['resource', 'oid'=>'string', 'mode='=>'string'], 'PDO::pgsqlLOBUnlink' => ['bool', 'oid'=>'string'], 'PDO::prepare' => ['__benevolent', 'statement'=>'string', 'options='=>'array'], 'PDO::query' => ['PDOStatement|false', 'sql'=>'string'], 'PDO::query\'1' => ['PDOStatement|false', 'sql'=>'string', 'fetch_column'=>'int', 'colno'=>'int'], 'PDO::query\'2' => ['PDOStatement|false', 'sql'=>'string', 'fetch_class'=>'int', 'classname'=>'string', 'ctorargs'=>'array'], 'PDO::query\'3' => ['PDOStatement|false', 'sql'=>'string', 'fetch_into'=>'int', 'object'=>'object'], 'PDO::quote' => ['string', 'string'=>'string', 'paramtype='=>'int'], 'PDO::rollBack' => ['bool'], 'PDO::setAttribute' => ['bool', 'attribute'=>'int', 'value'=>''], 'PDO::sqliteCreateAggregate' => ['bool', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'], 'PDO::sqliteCreateCollation' => ['bool', 'name'=>'string', 'callback'=>'callable'], 'PDO::sqliteCreateFunction' => ['bool', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int', 'flags='=>'int'], 'pdo_drivers' => ['array'], 'PDOException::getCode' => [''], 'PDOException::getFile' => [''], 'PDOException::getLine' => [''], 'PDOException::getMessage' => [''], 'PDOException::getPrevious' => [''], 'PDOException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'PDOException::getTraceAsString' => [''], 'PDOStatement::__sleep' => ['list'], 'PDOStatement::__wakeup' => ['void'], 'PDOStatement::bindColumn' => ['bool', 'column'=>'mixed', '&w_param'=>'mixed', 'type='=>'int', 'maxlen='=>'int', 'driverdata='=>'mixed'], 'PDOStatement::bindParam' => ['bool', 'parameter'=>'mixed', '&w_variable'=>'mixed', 'data_type='=>'int', 'length='=>'int', 'driver_options='=>'mixed'], 'PDOStatement::bindValue' => ['bool', 'parameter'=>'mixed', 'value'=>'mixed', 'data_type='=>'int'], 'PDOStatement::closeCursor' => ['bool'], 'PDOStatement::columnCount' => ['0|positive-int'], 'PDOStatement::debugDumpParams' => ['void'], 'PDOStatement::errorCode' => ['string|null'], 'PDOStatement::errorInfo' => ['array'], 'PDOStatement::execute' => ['bool', 'bound_input_params='=>'?array'], 'PDOStatement::fetch' => ['mixed', 'how='=>'int', 'orientation='=>'int', 'offset='=>'int'], 'PDOStatement::fetchAll' => ['array|false', 'how='=>'int', 'fetch_argument='=>'int|string|callable', 'ctor_args='=>'?array'], 'PDOStatement::fetchColumn' => ['string|null|false|int', 'column_number='=>'int'], 'PDOStatement::fetchObject' => ['mixed', 'class_name='=>'string', 'ctor_args='=>'?array'], 'PDOStatement::getAttribute' => ['mixed', 'attribute'=>'int'], 'PDOStatement::getColumnMeta' => ['array|false', 'column'=>'int'], 'PDOStatement::nextRowset' => ['bool'], 'PDOStatement::rowCount' => ['0|positive-int'], 'PDOStatement::setAttribute' => ['bool', 'attribute'=>'int', 'value'=>'mixed'], 'PDOStatement::setFetchMode' => ['bool', 'mode'=>'int'], 'PDOStatement::setFetchMode\'1' => ['bool', 'fetch_column'=>'int', 'colno'=>'int'], 'PDOStatement::setFetchMode\'2' => ['bool', 'fetch_class'=>'int', 'classname'=>'string', 'ctorargs='=>'?array'], 'PDOStatement::setFetchMode\'3' => ['bool', 'fetch_into'=>'int', 'object'=>'object'], 'pfsockopen' => ['resource|false', 'hostname'=>'string', 'port='=>'int', '&w_errno='=>'int', '&w_errstr='=>'string', 'timeout='=>'float'], 'pg_affected_rows' => ['int', 'result'=>'resource'], 'pg_cancel_query' => ['bool', 'connection'=>'resource'], 'pg_client_encoding' => ['string', 'connection='=>'resource'], 'pg_close' => ['bool', 'connection='=>'resource'], 'pg_connect' => ['resource|false', 'connection_string'=>'string', 'connect_type='=>'int'], 'pg_connect_poll' => ['int', 'connection'=>'resource'], 'pg_connection_busy' => ['bool', 'connection'=>'resource'], 'pg_connection_reset' => ['bool', 'connection'=>'resource'], 'pg_connection_status' => ['int', 'connection'=>'resource'], 'pg_consume_input' => ['bool', 'connection'=>'resource'], 'pg_convert' => ['array|false', 'db'=>'resource', 'table'=>'string', 'values'=>'array', 'options='=>'int'], 'pg_copy_from' => ['bool', 'connection'=>'resource', 'table_name'=>'string', 'rows'=>'array', 'delimiter='=>'string', 'null_as='=>'string'], 'pg_copy_to' => ['array|false', 'connection'=>'resource', 'table_name'=>'string', 'delimiter='=>'string', 'null_as='=>'string'], 'pg_dbname' => ['string', 'connection='=>'resource'], 'pg_delete' => ['mixed', 'db'=>'resource', 'table'=>'string', 'ids'=>'array', 'options='=>'int'], 'pg_end_copy' => ['bool', 'connection='=>'resource'], 'pg_escape_bytea' => ['string', 'connection'=>'resource', 'data'=>'string'], 'pg_escape_bytea\'1' => ['string', 'data'=>'string'], 'pg_escape_identifier' => ['string|false', 'connection'=>'resource', 'data'=>'string'], 'pg_escape_identifier\'1' => ['string', 'data'=>'string'], 'pg_escape_literal' => ['string|false', 'connection'=>'resource', 'data'=>'string'], 'pg_escape_literal\'1' => ['string', 'data'=>'string'], 'pg_escape_string' => ['string', 'connection'=>'resource', 'data'=>'string'], 'pg_escape_string\'1' => ['string', 'data'=>'string'], 'pg_execute' => ['resource|false', 'connection'=>'resource', 'stmtname'=>'string', 'params'=>'array'], 'pg_execute\'1' => ['resource|false', 'stmtname'=>'string', 'params'=>'array'], 'pg_fetch_all' => ['array>', 'result'=>'resource', 'result_type='=>'int'], 'pg_fetch_all_columns' => ['array|false', 'result'=>'resource', 'column_number='=>'int'], 'pg_fetch_array' => ['array|false', 'result'=>'resource', 'row='=>'?int', 'result_type='=>'int'], 'pg_fetch_assoc' => ['non-empty-array|false', 'result'=>'resource', 'row='=>'?int'], 'pg_fetch_object' => ['object|false', 'result'=>'', 'row='=>'?int', 'result_type='=>'int'], 'pg_fetch_object\'1' => ['object', 'result'=>'', 'row='=>'?int', 'class_name='=>'string', 'ctor_params='=>'array'], 'pg_fetch_result' => ['', 'result'=>'', 'field_name'=>'string|int'], 'pg_fetch_result\'1' => ['', 'result'=>'', 'row_number'=>'int', 'field_name'=>'string|int'], 'pg_fetch_row' => ['non-empty-list|false', 'result'=>'resource', 'row='=>'?int', 'result_type='=>'int'], 'pg_field_is_null' => ['int|false', 'result'=>'', 'field_name_or_number'=>'string|int'], 'pg_field_is_null\'1' => ['int', 'result'=>'', 'row'=>'int', 'field_name_or_number'=>'string|int'], 'pg_field_name' => ['string|false', 'result'=>'resource', 'field_number'=>'int'], 'pg_field_num' => ['int', 'result'=>'resource', 'field_name'=>'string'], 'pg_field_prtlen' => ['int|false', 'result'=>'', 'field_name_or_number'=>''], 'pg_field_prtlen\'1' => ['int', 'result'=>'', 'row'=>'int', 'field_name_or_number'=>'string|int'], 'pg_field_size' => ['int', 'result'=>'resource', 'field_number'=>'int'], 'pg_field_table' => ['mixed', 'result'=>'resource', 'field_number'=>'int', 'oid_only='=>'bool'], 'pg_field_type' => ['string', 'result'=>'resource', 'field_number'=>'int'], 'pg_field_type_oid' => ['int|false', 'result'=>'resource', 'field_number'=>'int'], 'pg_flush' => ['mixed', 'connection'=>'resource'], 'pg_free_result' => ['bool', 'result'=>'resource'], 'pg_get_notify' => ['array|false', 'connection'=>'resource', 'result_type='=>'int'], 'pg_get_pid' => ['int|false', 'connection'=>'resource'], 'pg_get_result' => ['resource|false', 'connection='=>'resource'], 'pg_host' => ['string', 'connection='=>'resource'], 'pg_insert' => ['mixed', 'db'=>'resource', 'table'=>'string', 'values'=>'array', 'options='=>'int'], 'pg_last_error' => ['string', 'connection='=>'resource', 'operation='=>'int'], 'pg_last_notice' => ['string', 'connection'=>'resource', 'option='=>'int'], 'pg_last_oid' => ['string|false', 'result'=>'resource'], 'pg_lo_close' => ['bool', 'large_object'=>'resource'], 'pg_lo_create' => ['int|false', 'connection='=>'resource', 'large_object_oid='=>''], 'pg_lo_export' => ['bool', 'connection'=>'resource', 'oid'=>'int', 'filename'=>'string'], 'pg_lo_export\'1' => ['bool', 'oid'=>'int', 'pathname'=>'string'], 'pg_lo_import' => ['int|false', 'connection'=>'resource', 'pathname'=>'string', 'oid'=>''], 'pg_lo_import\'1' => ['int', 'pathname'=>'string', 'oid'=>''], 'pg_lo_open' => ['resource|false', 'connection'=>'resource', 'oid'=>'int', 'mode'=>'string'], 'pg_lo_read' => ['string|false', 'large_object'=>'resource', 'len='=>'int'], 'pg_lo_read_all' => ['int', 'large_object'=>'resource'], 'pg_lo_seek' => ['bool', 'large_object'=>'resource', 'offset'=>'int', 'whence='=>'int'], 'pg_lo_tell' => ['int', 'large_object'=>'resource'], 'pg_lo_truncate' => ['bool', 'large_object'=>'resource', 'size'=>'int'], 'pg_lo_unlink' => ['bool', 'connection'=>'resource', 'oid'=>'int'], 'pg_lo_write' => ['int|false', 'large_object'=>'resource', 'data'=>'string', 'len='=>'int'], 'pg_meta_data' => ['array|false', 'db'=>'resource', 'table'=>'string', 'extended='=>'bool'], 'pg_num_fields' => ['int', 'result'=>'resource'], 'pg_num_rows' => ['int', 'result'=>'resource'], 'pg_options' => ['string', 'connection='=>'resource'], 'pg_parameter_status' => ['string|false', 'connection'=>'resource', 'param_name'=>'string'], 'pg_parameter_status\'1' => ['string|false', 'param_name'=>'string'], 'pg_pconnect' => ['resource|false', 'connection_string'=>'string', 'connect_type='=>'int'], 'pg_ping' => ['bool', 'connection='=>'resource'], 'pg_port' => ['int', 'connection='=>'resource'], 'pg_prepare' => ['resource|false', 'connection'=>'resource', 'stmtname'=>'string', 'query'=>'string'], 'pg_prepare\'1' => ['resource|false', 'stmtname'=>'string', 'query'=>'string'], 'pg_put_line' => ['bool', 'connection'=>'resource', 'data'=>'string'], 'pg_put_line\'1' => ['bool', 'data'=>'string'], 'pg_query' => ['resource|false', 'connection'=>'resource', 'query'=>'string'], 'pg_query\'1' => ['resource|false', 'query'=>'string'], 'pg_query_params' => ['resource|false', 'connection'=>'resource', 'query'=>'string', 'params'=>'array'], 'pg_query_params\'1' => ['resource|false', 'query'=>'string', 'params'=>'array'], 'pg_result_error' => ['string|false', 'result'=>'resource'], 'pg_result_error_field' => ['string|false|null', 'result'=>'resource', 'fieldcode'=>'int'], 'pg_result_seek' => ['bool', 'result'=>'resource', 'offset'=>'int'], 'pg_result_status' => ['mixed', 'result'=>'resource', 'result_type='=>'int'], 'pg_select' => ['mixed', 'db'=>'resource', 'table'=>'string', 'ids'=>'array', 'options='=>'int', 'result_type='=>'int'], 'pg_send_execute' => ['bool', 'connection'=>'resource', 'stmtname'=>'string', 'params'=>'array'], 'pg_send_prepare' => ['bool', 'connection'=>'resource', 'stmtname'=>'string', 'query'=>'string'], 'pg_send_query' => ['bool', 'connection'=>'resource', 'query'=>'string'], 'pg_send_query_params' => ['bool', 'connection'=>'resource', 'query'=>'string', 'params'=>'array'], 'pg_set_client_encoding' => ['int', 'connection'=>'resource', 'encoding'=>'string'], 'pg_set_client_encoding\'1' => ['int', 'encoding'=>'string'], 'pg_set_error_verbosity' => ['int|false', 'connection'=>'resource', 'verbosity'=>'int'], 'pg_set_error_verbosity\'1' => ['int', 'verbosity'=>'int'], 'pg_socket' => ['resource|false', 'connection'=>'resource'], 'pg_trace' => ['bool', 'filename'=>'string', 'mode='=>'string', 'connection='=>'resource'], 'pg_transaction_status' => ['int', 'connection'=>'resource'], 'pg_tty' => ['string', 'connection='=>'resource'], 'pg_tty\'1' => ['string'], 'pg_unescape_bytea' => ['string', 'data'=>'string'], 'pg_untrace' => ['bool', 'connection='=>'resource'], 'pg_untrace\'1' => ['bool'], 'pg_update' => ['mixed', 'db'=>'resource', 'table'=>'string', 'fields'=>'array', 'ids'=>'array', 'options='=>'int'], 'pg_version' => ['array', 'connection='=>'resource'], 'Phar::__construct' => ['void', 'fname'=>'string', 'flags='=>'int', 'alias='=>'string'], 'Phar::addEmptyDir' => ['', 'dirname'=>'string'], 'Phar::addFile' => ['', 'file'=>'string', 'localname='=>'string'], 'Phar::addFromString' => ['', 'localname'=>'string', 'contents'=>'string'], 'Phar::apiVersion' => ['string'], 'Phar::buildFromDirectory' => ['array', 'base_dir'=>'string', 'regex='=>'string'], 'Phar::buildFromIterator' => ['array', 'iter'=>'Iterator', 'base_directory='=>'string'], 'Phar::canCompress' => ['bool', 'method='=>'int'], 'Phar::canWrite' => ['bool'], 'Phar::compress' => ['Phar', 'compression'=>'int', 'extension='=>'string'], 'Phar::compressAllFilesBZIP2' => ['bool'], 'Phar::compressAllFilesGZ' => ['bool'], 'Phar::compressFiles' => ['', 'compression'=>'int'], 'Phar::convertToData' => ['PharData', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'], 'Phar::convertToExecutable' => ['Phar', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'], 'Phar::copy' => ['bool', 'oldfile'=>'string', 'newfile'=>'string'], 'Phar::count' => ['0|positive-int'], 'Phar::createDefaultStub' => ['string', 'indexfile='=>'string', 'webindexfile='=>'string'], 'Phar::decompress' => ['Phar', 'extension='=>'string'], 'Phar::decompressFiles' => ['bool'], 'Phar::delete' => ['bool', 'entry'=>'string'], 'Phar::delMetadata' => ['bool'], 'Phar::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string|array|null', 'overwrite='=>'bool'], 'Phar::getAlias' => ['string'], 'Phar::getMetadata' => ['mixed'], 'Phar::getModified' => ['bool'], 'Phar::getPath' => ['string'], 'Phar::getSignature' => ['array{hash:string, hash_type:string}'], 'Phar::getStub' => ['string'], 'Phar::getSupportedCompression' => ['array'], 'Phar::getSupportedSignatures' => ['array'], 'Phar::getVersion' => ['string'], 'Phar::hasMetadata' => ['bool'], 'Phar::interceptFileFuncs' => [''], 'Phar::isBuffering' => ['bool'], 'Phar::isCompressed' => [''], 'Phar::isFileFormat' => ['bool', 'format'=>'int'], 'Phar::isValidPharFilename' => ['bool', 'filename'=>'string', 'executable='=>'bool'], 'Phar::isWritable' => ['bool'], 'Phar::loadPhar' => ['bool', 'filename'=>'string', 'alias='=>'string'], 'Phar::mapPhar' => ['bool', 'alias='=>'string', 'dataoffset='=>'int'], 'Phar::mount' => ['void', 'pharpath'=>'string', 'externalpath'=>'string'], 'Phar::mungServer' => ['', 'munglist'=>'array'], 'Phar::offsetExists' => ['bool', 'offset'=>'string'], 'Phar::offsetGet' => ['PharFileInfo', 'offset'=>'string'], 'Phar::offsetSet' => ['', 'offset'=>'string', 'value'=>'string'], 'Phar::offsetUnset' => ['bool', 'offset'=>'string'], 'Phar::running' => ['string', 'retphar='=>'bool'], 'Phar::setAlias' => ['bool', 'alias'=>'string'], 'Phar::setDefaultStub' => ['bool', 'index='=>'string', 'webindex='=>'string'], 'Phar::setMetadata' => ['', 'metadata'=>''], 'Phar::setSignatureAlgorithm' => ['', 'sigtype'=>'int', 'privatekey='=>'string'], 'Phar::setStub' => ['bool', 'stub'=>'string', 'len='=>'int'], 'Phar::startBuffering' => [''], 'Phar::stopBuffering' => [''], 'Phar::uncompressAllFiles' => ['bool'], 'Phar::unlinkArchive' => ['bool', 'archive'=>'string'], 'Phar::webPhar' => ['', 'alias='=>'string', 'index='=>'string', 'f404='=>'string', 'mimetypes='=>'array', 'rewrites='=>'array'], 'PharData::__construct' => ['void', 'fname'=>'string', 'flags='=>'int', 'alias='=>'string', 'format='=>'int'], 'PharData::addEmptyDir' => ['bool', 'dirname'=>'string'], 'PharData::addFile' => ['', 'file'=>'string', 'localname='=>'string'], 'PharData::addFromString' => ['bool', 'localname'=>'string', 'contents'=>'string'], 'PharData::buildFromDirectory' => ['array', 'base_dir'=>'string', 'regex='=>'string'], 'PharData::buildFromIterator' => ['array', 'iter'=>'Iterator', 'base_directory='=>'string'], 'PharData::compress' => ['PharData', 'compression'=>'int', 'extension='=>'string'], 'PharData::compressFiles' => ['bool', 'compression'=>'int'], 'PharData::convertToData' => ['PharData', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'], 'PharData::convertToExecutable' => ['Phar', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'], 'PharData::copy' => ['bool', 'oldfile'=>'string', 'newfile'=>'string'], 'PharData::decompress' => ['PharData', 'extension='=>'string'], 'PharData::decompressFiles' => ['bool'], 'PharData::delete' => ['bool', 'entry'=>'string'], 'PharData::delMetadata' => ['bool'], 'PharData::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string|array|null', 'overwrite='=>'bool'], 'PharData::isWritable' => ['bool'], 'PharData::offsetGet' => ['PharFileInfo', 'offset'=>'string'], 'PharData::offsetSet' => ['', 'offset'=>'string', 'value'=>'string'], 'PharData::offsetUnset' => ['bool', 'offset'=>'string'], 'PharData::setAlias' => ['bool', 'alias'=>'string'], 'PharData::setDefaultStub' => ['bool', 'index='=>'string', 'webindex='=>'string'], 'PharData::setStub' => ['bool', 'stub'=>'string'], 'PharFileInfo::__construct' => ['void', 'entry'=>'string'], 'PharFileInfo::chmod' => ['void', 'permissions'=>'int'], 'PharFileInfo::compress' => ['bool', 'compression'=>'int'], 'PharFileInfo::decompress' => ['bool'], 'PharFileInfo::delMetadata' => ['bool'], 'PharFileInfo::getCompressedSize' => ['int'], 'PharFileInfo::getContent' => ['string'], 'PharFileInfo::getCRC32' => ['int'], 'PharFileInfo::getMetadata' => ['mixed'], 'PharFileInfo::getPharFlags' => ['int'], 'PharFileInfo::hasMetadata' => ['bool'], 'PharFileInfo::isCompressed' => ['bool', 'compression_type='=>'int'], 'PharFileInfo::isCompressedBZIP2' => ['bool'], 'PharFileInfo::isCompressedGZ' => ['bool'], 'PharFileInfo::isCRCChecked' => ['bool'], 'PharFileInfo::setCompressedBZIP2' => ['bool'], 'PharFileInfo::setCompressedGZ' => ['bool'], 'PharFileInfo::setMetadata' => ['void', 'metadata'=>'mixed'], 'PharFileInfo::setUncompressed' => ['bool'], 'phdfs::__construct' => ['void', 'ip'=>'string', 'port'=>'string'], 'phdfs::__destruct' => [''], 'phdfs::connect' => ['bool'], 'phdfs::copy' => ['bool', 'source_file'=>'string', 'destination_file'=>'string'], 'phdfs::create_directory' => ['bool', 'path'=>'string'], 'phdfs::delete' => ['bool', 'path'=>'string'], 'phdfs::disconnect' => ['bool'], 'phdfs::exists' => ['bool', 'path'=>'string'], 'phdfs::file_info' => ['array', 'path'=>'string'], 'phdfs::list_directory' => ['array', 'path'=>'string'], 'phdfs::read' => ['string', 'path'=>'string', 'length='=>'string'], 'phdfs::rename' => ['bool', 'old_path'=>'string', 'new_path'=>'string'], 'phdfs::tell' => ['int', 'path'=>'string'], 'phdfs::write' => ['bool', 'path'=>'string', 'buffer'=>'string', 'mode='=>'string'], 'php_check_syntax' => ['bool', 'filename'=>'string', 'error_message='=>'string'], 'php_ini_loaded_file' => ['non-empty-string|false'], 'php_ini_scanned_files' => ['string|false'], 'php_logo_guid' => ['string'], 'php_sapi_name' => ['__benevolent'], 'php_strip_whitespace' => ['string', 'file_name'=>'string'], 'php_uname' => ['string', 'mode='=>'string'], 'php_user_filter::filter' => ['int', 'in'=>'resource', 'out'=>'resource', '&rw_consumed'=>'int', 'closing'=>'bool'], 'php_user_filter::onClose' => ['void'], 'php_user_filter::onCreate' => ['bool'], 'phpcredits' => ['bool', 'flag='=>'int'], 'phpdbg_break_file' => ['', 'file'=>'string', 'line'=>'int'], 'phpdbg_break_function' => ['', 'function'=>'string'], 'phpdbg_break_method' => ['', 'class'=>'string', 'method'=>'string'], 'phpdbg_break_next' => [''], 'phpdbg_clear' => [''], 'phpdbg_color' => ['', 'element'=>'int', 'color'=>'string'], 'phpdbg_end_oplog' => ['array', 'options='=>'array'], 'phpdbg_prompt' => ['', 'prompt'=>'string'], 'phpdbg_start_oplog' => [''], 'phpinfo' => ['bool', 'what='=>'int'], 'phpversion' => ['string'], 'phpversion\'1' => ['string|false', 'extension'=>'string'], 'pht\AtomicInteger::__construct' => ['void', 'value='=>'int'], 'pht\AtomicInteger::dec' => ['void'], 'pht\AtomicInteger::get' => ['int'], 'pht\AtomicInteger::inc' => ['void'], 'pht\AtomicInteger::lock' => ['void'], 'pht\AtomicInteger::set' => ['void', 'value'=>'int'], 'pht\AtomicInteger::unlock' => ['void'], 'pht\HashTable::lock' => ['void'], 'pht\HashTable::size' => ['int'], 'pht\HashTable::unlock' => ['void'], 'pht\Queue::front' => ['mixed'], 'pht\Queue::lock' => ['void'], 'pht\Queue::pop' => ['mixed'], 'pht\Queue::push' => ['void', 'value'=>'mixed'], 'pht\Queue::size' => ['int'], 'pht\Queue::unlock' => ['void'], 'pht\Runnable::run' => ['void'], 'pht\Vector::__construct' => ['void', 'size='=>'int', 'value='=>'mixed'], 'pht\Vector::deleteAt' => ['void', 'offset'=>'int'], 'pht\Vector::insertAt' => ['void', 'value'=>'mixed', 'offset'=>'int'], 'pht\Vector::lock' => ['void'], 'pht\Vector::pop' => ['mixed'], 'pht\Vector::push' => ['void', 'value'=>'mixed'], 'pht\Vector::resize' => ['void', 'size'=>'int', 'value='=>'mixed'], 'pht\Vector::shift' => ['mixed'], 'pht\Vector::size' => ['int'], 'pht\Vector::unlock' => ['void'], 'pht\Vector::unshift' => ['void', 'value'=>'mixed'], 'pht\Vector::updateAt' => ['void', 'value'=>'mixed', 'offset'=>'int'], 'pi' => ['float'], 'png2wbmp' => ['bool', 'pngname'=>'string', 'wbmpname'=>'string', 'dest_height'=>'int', 'dest_width'=>'int', 'threshold'=>'int'], 'pointObj::__construct' => ['void'], 'pointObj::distanceToLine' => ['float', 'p1'=>'pointObj', 'p2'=>'pointObj'], 'pointObj::distanceToPoint' => ['float', 'poPoint'=>'pointObj'], 'pointObj::distanceToShape' => ['float', 'shape'=>'shapeObj'], 'pointObj::draw' => ['int', 'map'=>'mapObj', 'layer'=>'layerObj', 'img'=>'imageObj', 'class_index'=>'int', 'text'=>'string'], 'pointObj::ms_newPointObj' => ['pointObj'], 'pointObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'], 'pointObj::setXY' => ['int', 'x'=>'float', 'y'=>'float', 'm'=>'float'], 'pointObj::setXYZ' => ['int', 'x'=>'float', 'y'=>'float', 'z'=>'float', 'm'=>'float'], 'Pool::__construct' => ['void', 'size'=>'int', 'class'=>'string', 'ctor='=>'array'], 'Pool::collect' => ['int', 'collector'=>'Callable'], 'Pool::resize' => ['void', 'size'=>'int'], 'Pool::shutdown' => ['void'], 'Pool::submit' => ['int', 'task'=>'Threaded'], 'Pool::submitTo' => ['int', 'worker'=>'int', 'task'=>'Threaded'], 'popen' => ['resource|false', 'command'=>'string', 'mode'=>'string'], 'pos' => ['mixed', 'array_arg'=>'array'], 'posix_access' => ['bool', 'file'=>'string', 'mode='=>'int'], 'posix_ctermid' => ['string|false'], 'posix_errno' => ['int'], 'posix_get_last_error' => ['int'], 'posix_getcwd' => ['string|false'], 'posix_getegid' => ['int'], 'posix_geteuid' => ['int'], 'posix_getgid' => ['int'], 'posix_getgrgid' => ['array{name: string, passwd: string, gid: int, members: list}|false', 'gid'=>'int'], 'posix_getgrnam' => ['array{name: string, passwd: string, gid: int, members: list}|false', 'groupname'=>'string'], 'posix_getgroups' => ['list|false'], 'posix_getlogin' => ['string|false'], 'posix_getpgid' => ['int|false', 'pid'=>'int'], 'posix_getpgrp' => ['int'], 'posix_getpid' => ['int'], 'posix_getppid' => ['int'], 'posix_getpwnam' => ['array|false', 'groupname'=>'string'], 'posix_getpwuid' => ['array{name: string, passwd: string, uid: int, gid: int, gecos: string, dir: string, shell: string}|false', 'uid'=>'int'], 'posix_getrlimit' => ['array|false'], 'posix_getsid' => ['int|false', 'pid'=>'int'], 'posix_getuid' => ['int'], 'posix_initgroups' => ['bool', 'name'=>'string', 'base_group_id'=>'int'], 'posix_isatty' => ['bool', 'fd'=>'resource|int'], 'posix_kill' => ['bool', 'pid'=>'int', 'sig'=>'int'], 'posix_mkfifo' => ['bool', 'pathname'=>'string', 'mode'=>'int'], 'posix_mknod' => ['bool', 'pathname'=>'string', 'mode'=>'int', 'major='=>'int', 'minor='=>'int'], 'posix_setegid' => ['bool', 'uid'=>'int'], 'posix_seteuid' => ['bool', 'uid'=>'int'], 'posix_setgid' => ['bool', 'uid'=>'int'], 'posix_setpgid' => ['bool', 'pid'=>'int', 'pgid'=>'int'], 'posix_setrlimit' => ['bool', 'resource'=>'int', 'softlimit'=>'int', 'hardlimit'=>'int'], 'posix_setsid' => ['int'], 'posix_setuid' => ['bool', 'uid'=>'int'], 'posix_strerror' => ['string', 'errno'=>'int'], 'posix_times' => ['array|false'], 'posix_ttyname' => ['string|false', 'fd'=>'resource|int'], 'posix_uname' => ['array|false'], 'Postal\Expand::expand_address' => ['string[]', 'address'=>'string', 'options='=>'array'], 'Postal\Parser::parse_address' => ['array', 'address'=>'string', 'options='=>'array'], 'pow' => ['float|int', 'base'=>'int|float', 'exponent'=>'int|float'], 'preg_filter' => ['string|array|null', 'regex'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'], 'preg_grep' => ['array|false', 'regex'=>'string', 'input'=>'array', 'flags='=>'int'], 'preg_last_error' => ['int'], 'preg_match' => ['0|1|false', 'pattern'=>'string', 'subject'=>'string', '&w_subpatterns='=>'string[]', 'flags='=>'int', 'offset='=>'int'], 'preg_match_all' => ['0|positive-int|false|null', 'pattern'=>'string', 'subject'=>'string', '&w_subpatterns='=>'array', 'flags='=>'int', 'offset='=>'int'], 'preg_quote' => ['string', 'str'=>'string', 'delim_char='=>'string'], 'preg_replace' => ['string|array|null', 'regex'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'], 'preg_replace_callback' => ['string|array|null', 'regex'=>'string|array', 'callback'=>'callable(array):string', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'], 'preg_replace_callback_array' => ['string|array|null', 'pattern'=>'array', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'], 'preg_split' => ['list|false', 'pattern'=>'string', 'subject'=>'string', 'limit='=>'?int', 'flags='=>'int'], 'prev' => ['mixed', '&rw_array_arg'=>'array|object'], 'print_r' => ['string|true', 'var'=>'mixed', 'return='=>'bool'], 'printf' => ['int', 'format'=>'string', '...values='=>'__stringAndStringable|int|float|null|bool'], 'proc_close' => ['int', 'process'=>'resource'], 'proc_get_status' => ['array{command: string, pid: int, running: bool, signaled: bool, stopped: bool, exitcode: int, termsig: int, stopsig: int}|false', 'process'=>'resource'], 'proc_nice' => ['bool', 'priority'=>'int'], 'proc_open' => ['resource|false', 'command'=>'string', 'descriptorspec'=>'array', '&w_pipes'=>'resource[]', 'cwd='=>'?string', 'env='=>'?array', 'other_options='=>'array'], 'proc_terminate' => ['bool', 'process'=>'resource', 'signal='=>'int'], 'projectionObj::__construct' => ['void', 'projectionString'=>'string'], 'projectionObj::getUnits' => ['int'], 'projectionObj::ms_newProjectionObj' => ['projectionObj', 'projectionString'=>'string'], 'property_exists' => ['bool', 'object_or_class'=>'object|string', 'property_name'=>'string'], 'ps_add_bookmark' => ['int', 'psdoc'=>'resource', 'text'=>'string', 'parent='=>'int', 'open='=>'int'], 'ps_add_launchlink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string'], 'ps_add_locallink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'page'=>'int', 'dest'=>'string'], 'ps_add_note' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'contents'=>'string', 'title'=>'string', 'icon'=>'string', 'open'=>'int'], 'ps_add_pdflink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string', 'page'=>'int', 'dest'=>'string'], 'ps_add_weblink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'url'=>'string'], 'ps_arc' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'alpha'=>'float', 'beta'=>'float'], 'ps_arcn' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'alpha'=>'float', 'beta'=>'float'], 'ps_begin_page' => ['bool', 'psdoc'=>'resource', 'width'=>'float', 'height'=>'float'], 'ps_begin_pattern' => ['int', 'psdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'xstep'=>'float', 'ystep'=>'float', 'painttype'=>'int'], 'ps_begin_template' => ['int', 'psdoc'=>'resource', 'width'=>'float', 'height'=>'float'], 'ps_circle' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'radius'=>'float'], 'ps_clip' => ['bool', 'psdoc'=>'resource'], 'ps_close' => ['bool', 'psdoc'=>'resource'], 'ps_close_image' => ['void', 'psdoc'=>'resource', 'imageid'=>'int'], 'ps_closepath' => ['bool', 'psdoc'=>'resource'], 'ps_closepath_stroke' => ['bool', 'psdoc'=>'resource'], 'ps_continue_text' => ['bool', 'psdoc'=>'resource', 'text'=>'string'], 'ps_curveto' => ['bool', 'psdoc'=>'resource', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'], 'ps_delete' => ['bool', 'psdoc'=>'resource'], 'ps_end_page' => ['bool', 'psdoc'=>'resource'], 'ps_end_pattern' => ['bool', 'psdoc'=>'resource'], 'ps_end_template' => ['bool', 'psdoc'=>'resource'], 'ps_fill' => ['bool', 'psdoc'=>'resource'], 'ps_fill_stroke' => ['bool', 'psdoc'=>'resource'], 'ps_findfont' => ['int', 'psdoc'=>'resource', 'fontname'=>'string', 'encoding'=>'string', 'embed='=>'bool'], 'ps_get_buffer' => ['string', 'psdoc'=>'resource'], 'ps_get_parameter' => ['string', 'psdoc'=>'resource', 'name'=>'string', 'modifier='=>'float'], 'ps_get_value' => ['float', 'psdoc'=>'resource', 'name'=>'string', 'modifier='=>'float'], 'ps_hyphenate' => ['array', 'psdoc'=>'resource', 'text'=>'string'], 'ps_include_file' => ['bool', 'psdoc'=>'resource', 'file'=>'string'], 'ps_lineto' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'], 'ps_makespotcolor' => ['int', 'psdoc'=>'resource', 'name'=>'string', 'reserved='=>'int'], 'ps_moveto' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'], 'ps_new' => ['resource'], 'ps_open_file' => ['bool', 'psdoc'=>'resource', 'filename='=>'string'], 'ps_open_image' => ['int', 'psdoc'=>'resource', 'type'=>'string', 'source'=>'string', 'data'=>'string', 'length'=>'int', 'width'=>'int', 'height'=>'int', 'components'=>'int', 'bpc'=>'int', 'params'=>'string'], 'ps_open_image_file' => ['int', 'psdoc'=>'resource', 'type'=>'string', 'filename'=>'string', 'stringparam='=>'string', 'intparam='=>'int'], 'ps_open_memory_image' => ['int', 'psdoc'=>'resource', 'gd'=>'int'], 'ps_place_image' => ['bool', 'psdoc'=>'resource', 'imageid'=>'int', 'x'=>'float', 'y'=>'float', 'scale'=>'float'], 'ps_rect' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'], 'ps_restore' => ['bool', 'psdoc'=>'resource'], 'ps_rotate' => ['bool', 'psdoc'=>'resource', 'rot'=>'float'], 'ps_save' => ['bool', 'psdoc'=>'resource'], 'ps_scale' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'], 'ps_set_border_color' => ['bool', 'psdoc'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], 'ps_set_border_dash' => ['bool', 'psdoc'=>'resource', 'black'=>'float', 'white'=>'float'], 'ps_set_border_style' => ['bool', 'psdoc'=>'resource', 'style'=>'string', 'width'=>'float'], 'ps_set_info' => ['bool', 'p'=>'resource', 'key'=>'string', 'val'=>'string'], 'ps_set_parameter' => ['bool', 'psdoc'=>'resource', 'name'=>'string', 'value'=>'string'], 'ps_set_text_pos' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'], 'ps_set_value' => ['bool', 'psdoc'=>'resource', 'name'=>'string', 'value'=>'float'], 'ps_setcolor' => ['bool', 'psdoc'=>'resource', 'type'=>'string', 'colorspace'=>'string', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float'], 'ps_setdash' => ['bool', 'psdoc'=>'resource', 'on'=>'float', 'off'=>'float'], 'ps_setflat' => ['bool', 'psdoc'=>'resource', 'value'=>'float'], 'ps_setfont' => ['bool', 'psdoc'=>'resource', 'fontid'=>'int', 'size'=>'float'], 'ps_setgray' => ['bool', 'psdoc'=>'resource', 'gray'=>'float'], 'ps_setlinecap' => ['bool', 'psdoc'=>'resource', 'type'=>'int'], 'ps_setlinejoin' => ['bool', 'psdoc'=>'resource', 'type'=>'int'], 'ps_setlinewidth' => ['bool', 'psdoc'=>'resource', 'width'=>'float'], 'ps_setmiterlimit' => ['bool', 'psdoc'=>'resource', 'value'=>'float'], 'ps_setoverprintmode' => ['bool', 'psdoc'=>'resource', 'mode'=>'int'], 'ps_setpolydash' => ['bool', 'psdoc'=>'resource', 'arr'=>'float'], 'ps_shading' => ['int', 'psdoc'=>'resource', 'type'=>'string', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float', 'optlist'=>'string'], 'ps_shading_pattern' => ['int', 'psdoc'=>'resource', 'shadingid'=>'int', 'optlist'=>'string'], 'ps_shfill' => ['bool', 'psdoc'=>'resource', 'shadingid'=>'int'], 'ps_show' => ['bool', 'psdoc'=>'resource', 'text'=>'string'], 'ps_show2' => ['bool', 'psdoc'=>'resource', 'text'=>'string', 'len'=>'int'], 'ps_show_boxed' => ['int', 'psdoc'=>'resource', 'text'=>'string', 'left'=>'float', 'bottom'=>'float', 'width'=>'float', 'height'=>'float', 'hmode'=>'string', 'feature='=>'string'], 'ps_show_xy' => ['bool', 'psdoc'=>'resource', 'text'=>'string', 'x'=>'float', 'y'=>'float'], 'ps_show_xy2' => ['bool', 'psdoc'=>'resource', 'text'=>'string', 'len'=>'int', 'xcoor'=>'float', 'ycoor'=>'float'], 'ps_string_geometry' => ['array', 'psdoc'=>'resource', 'text'=>'string', 'fontid='=>'int', 'size='=>'float'], 'ps_stringwidth' => ['float', 'psdoc'=>'resource', 'text'=>'string', 'fontid='=>'int', 'size='=>'float'], 'ps_stroke' => ['bool', 'psdoc'=>'resource'], 'ps_symbol' => ['bool', 'psdoc'=>'resource', 'ord'=>'int'], 'ps_symbol_name' => ['string', 'psdoc'=>'resource', 'ord'=>'int', 'fontid='=>'int'], 'ps_symbol_width' => ['float', 'psdoc'=>'resource', 'ord'=>'int', 'fontid='=>'int', 'size='=>'float'], 'ps_translate' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'], 'pspell_add_to_personal' => ['bool', 'pspell'=>'int', 'word'=>'string'], 'pspell_add_to_session' => ['bool', 'pspell'=>'int', 'word'=>'string'], 'pspell_check' => ['bool', 'pspell'=>'int', 'word'=>'string'], 'pspell_clear_session' => ['bool', 'pspell'=>'int'], 'pspell_config_create' => ['int|false', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string'], 'pspell_config_data_dir' => ['bool', 'conf'=>'int', 'directory'=>'string'], 'pspell_config_dict_dir' => ['bool', 'conf'=>'int', 'directory'=>'string'], 'pspell_config_ignore' => ['bool', 'conf'=>'int', 'ignore'=>'int'], 'pspell_config_mode' => ['bool', 'conf'=>'int', 'mode'=>'int'], 'pspell_config_personal' => ['bool', 'conf'=>'int', 'personal'=>'string'], 'pspell_config_repl' => ['bool', 'conf'=>'int', 'repl'=>'string'], 'pspell_config_runtogether' => ['bool', 'conf'=>'int', 'runtogether'=>'bool'], 'pspell_config_save_repl' => ['bool', 'conf'=>'int', 'save'=>'bool'], 'pspell_new' => ['int|false', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string', 'mode='=>'int'], 'pspell_new_config' => ['int|false', 'config'=>'int'], 'pspell_new_personal' => ['int|false', 'personal'=>'string', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string', 'mode='=>'int'], 'pspell_save_wordlist' => ['bool', 'pspell'=>'int'], 'pspell_store_replacement' => ['bool', 'pspell'=>'int', 'misspell'=>'string', 'correct'=>'string'], 'pspell_suggest' => ['array|false', 'pspell'=>'int', 'word'=>'string'], 'putenv' => ['bool', 'setting'=>'string'], 'px_close' => ['bool', 'pxdoc'=>'resource'], 'px_create_fp' => ['bool', 'pxdoc'=>'resource', 'file'=>'resource', 'fielddesc'=>'array'], 'px_date2string' => ['string', 'pxdoc'=>'resource', 'value'=>'int', 'format'=>'string'], 'px_delete' => ['bool', 'pxdoc'=>'resource'], 'px_delete_record' => ['bool', 'pxdoc'=>'resource', 'num'=>'int'], 'px_get_field' => ['array', 'pxdoc'=>'resource', 'fieldno'=>'int'], 'px_get_info' => ['array', 'pxdoc'=>'resource'], 'px_get_parameter' => ['string', 'pxdoc'=>'resource', 'name'=>'string'], 'px_get_record' => ['array', 'pxdoc'=>'resource', 'num'=>'int', 'mode='=>'int'], 'px_get_schema' => ['array', 'pxdoc'=>'resource', 'mode='=>'int'], 'px_get_value' => ['float', 'pxdoc'=>'resource', 'name'=>'string'], 'px_insert_record' => ['int', 'pxdoc'=>'resource', 'data'=>'array'], 'px_new' => ['resource'], 'px_numfields' => ['int', 'pxdoc'=>'resource'], 'px_numrecords' => ['int', 'pxdoc'=>'resource'], 'px_open_fp' => ['bool', 'pxdoc'=>'resource', 'file'=>'resource'], 'px_put_record' => ['bool', 'pxdoc'=>'resource', 'record'=>'array', 'recpos='=>'int'], 'px_retrieve_record' => ['array', 'pxdoc'=>'resource', 'num'=>'int', 'mode='=>'int'], 'px_set_blob_file' => ['bool', 'pxdoc'=>'resource', 'filename'=>'string'], 'px_set_parameter' => ['bool', 'pxdoc'=>'resource', 'name'=>'string', 'value'=>'string'], 'px_set_tablename' => ['void', 'pxdoc'=>'resource', 'name'=>'string'], 'px_set_targetencoding' => ['bool', 'pxdoc'=>'resource', 'encoding'=>'string'], 'px_set_value' => ['bool', 'pxdoc'=>'resource', 'name'=>'string', 'value'=>'float'], 'px_timestamp2string' => ['string', 'pxdoc'=>'resource', 'value'=>'float', 'format'=>'string'], 'px_update_record' => ['bool', 'pxdoc'=>'resource', 'data'=>'array', 'num'=>'int'], 'qdom_error' => ['string'], 'qdom_tree' => ['QDomDocument', 'doc'=>'string'], 'querymapObj::convertToString' => ['string'], 'querymapObj::free' => ['void'], 'querymapObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], 'querymapObj::updateFromString' => ['int', 'snippet'=>'string'], 'QuickHashIntHash::__construct' => ['void', 'size'=>'int', 'options='=>'int'], 'QuickHashIntHash::add' => ['bool', 'key'=>'int', 'value='=>'int'], 'QuickHashIntHash::delete' => ['bool', 'key'=>'int'], 'QuickHashIntHash::exists' => ['bool', 'key'=>'int'], 'QuickHashIntHash::get' => ['int', 'key'=>'int'], 'QuickHashIntHash::getSize' => ['int'], 'QuickHashIntHash::loadFromFile' => ['QuickHashIntHash', 'filename'=>'string', 'options='=>'int'], 'QuickHashIntHash::loadFromString' => ['QuickHashIntHash', 'contents'=>'string', 'options='=>'int'], 'QuickHashIntHash::saveToFile' => ['void', 'filename'=>'string'], 'QuickHashIntHash::saveToString' => ['string'], 'QuickHashIntHash::set' => ['bool', 'key'=>'int', 'value'=>'int'], 'QuickHashIntHash::update' => ['bool', 'key'=>'int', 'value'=>'int'], 'QuickHashIntSet::__construct' => ['void', 'size'=>'int', 'options='=>'int'], 'QuickHashIntSet::add' => ['bool', 'key'=>'int'], 'QuickHashIntSet::delete' => ['bool', 'key'=>'int'], 'QuickHashIntSet::exists' => ['bool', 'key'=>'int'], 'QuickHashIntSet::getSize' => ['int'], 'QuickHashIntSet::loadFromFile' => ['QuickHashIntSet', 'filename'=>'string', 'size='=>'int', 'options='=>'int'], 'QuickHashIntSet::loadFromString' => ['QuickHashIntSet', 'contents'=>'string', 'size='=>'int', 'options='=>'int'], 'QuickHashIntSet::saveToFile' => ['void', 'filename'=>'string'], 'QuickHashIntSet::saveToString' => ['string'], 'QuickHashIntStringHash::__construct' => ['void', 'size'=>'int', 'options='=>'int'], 'QuickHashIntStringHash::add' => ['bool', 'key'=>'int', 'value'=>'string'], 'QuickHashIntStringHash::delete' => ['bool', 'key'=>'int'], 'QuickHashIntStringHash::exists' => ['bool', 'key'=>'int'], 'QuickHashIntStringHash::get' => ['mixed', 'key'=>'int'], 'QuickHashIntStringHash::getSize' => ['int'], 'QuickHashIntStringHash::loadFromFile' => ['QuickHashIntStringHash', 'filename'=>'string', 'size='=>'int', 'options='=>'int'], 'QuickHashIntStringHash::loadFromString' => ['QuickHashIntStringHash', 'contents'=>'string', 'size='=>'int', 'options='=>'int'], 'QuickHashIntStringHash::saveToFile' => ['void', 'filename'=>'string'], 'QuickHashIntStringHash::saveToString' => ['string'], 'QuickHashIntStringHash::set' => ['int', 'key'=>'int', 'value'=>'string'], 'QuickHashIntStringHash::update' => ['bool', 'key'=>'int', 'value'=>'string'], 'QuickHashStringIntHash::__construct' => ['void', 'size'=>'int', 'options='=>'int'], 'QuickHashStringIntHash::add' => ['bool', 'key'=>'string', 'value'=>'int'], 'QuickHashStringIntHash::delete' => ['bool', 'key'=>'string'], 'QuickHashStringIntHash::exists' => ['bool', 'key'=>'string'], 'QuickHashStringIntHash::get' => ['mixed', 'key'=>'string'], 'QuickHashStringIntHash::getSize' => ['int'], 'QuickHashStringIntHash::loadFromFile' => ['QuickHashStringIntHash', 'filename'=>'string', 'size='=>'int', 'options='=>'int'], 'QuickHashStringIntHash::loadFromString' => ['QuickHashStringIntHash', 'contents'=>'string', 'size='=>'int', 'options='=>'int'], 'QuickHashStringIntHash::saveToFile' => ['void', 'filename'=>'string'], 'QuickHashStringIntHash::saveToString' => ['string'], 'QuickHashStringIntHash::set' => ['int', 'key'=>'string', 'value'=>'int'], 'QuickHashStringIntHash::update' => ['bool', 'key'=>'string', 'value'=>'int'], 'quoted_printable_decode' => ['string', 'str'=>'string'], 'quoted_printable_encode' => ['string', 'str'=>'string'], 'quotemeta' => ['string', 'str'=>'string'], 'rad2deg' => ['float', 'number'=>'float'], 'radius_acct_open' => ['resource|false'], 'radius_add_server' => ['bool', 'radius_handle'=>'resource', 'hostname'=>'string', 'port'=>'int', 'secret'=>'string', 'timeout'=>'int', 'max_tries'=>'int'], 'radius_auth_open' => ['resource|false'], 'radius_close' => ['bool', 'radius_handle'=>'resource'], 'radius_config' => ['bool', 'radius_handle'=>'resource', 'file'=>'string'], 'radius_create_request' => ['bool', 'radius_handle'=>'resource', 'type'=>'int'], 'radius_cvt_addr' => ['string', 'data'=>'string'], 'radius_cvt_int' => ['int', 'data'=>'string'], 'radius_cvt_string' => ['string', 'data'=>'string'], 'radius_demangle' => ['string', 'radius_handle'=>'resource', 'mangled'=>'string'], 'radius_demangle_mppe_key' => ['string', 'radius_handle'=>'resource', 'mangled'=>'string'], 'radius_get_attr' => ['mixed', 'radius_handle'=>'resource'], 'radius_get_tagged_attr_data' => ['string', 'data'=>'string'], 'radius_get_tagged_attr_tag' => ['int', 'data'=>'string'], 'radius_get_vendor_attr' => ['array', 'data'=>'string'], 'radius_put_addr' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'addr'=>'string'], 'radius_put_attr' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'value'=>'string'], 'radius_put_int' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'value'=>'int'], 'radius_put_string' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'value'=>'string'], 'radius_put_vendor_addr' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'addr'=>'string'], 'radius_put_vendor_attr' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'value'=>'string'], 'radius_put_vendor_int' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'value'=>'int'], 'radius_put_vendor_string' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'value'=>'string'], 'radius_request_authenticator' => ['string', 'radius_handle'=>'resource'], 'radius_salt_encrypt_attr' => ['string', 'radius_handle'=>'resource', 'data'=>'string'], 'radius_send_request' => ['int', 'radius_handle'=>'resource'], 'radius_server_secret' => ['string', 'radius_handle'=>'resource'], 'radius_strerror' => ['string', 'radius_handle'=>'resource'], 'rand' => ['int', 'min'=>'int', 'max'=>'int'], 'rand\'1' => ['int'], 'random_bytes' => ['non-empty-string', 'length'=>'positive-int'], 'random_int' => ['int', 'min'=>'int', 'max'=>'int'], 'range' => ['array', 'low'=>'int|float|string', 'high'=>'int|float|string', 'step='=>'int|float'], 'RangeException::__clone' => ['void'], 'RangeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?RangeException)'], 'RangeException::__toString' => ['string'], 'RangeException::getCode' => ['int'], 'RangeException::getFile' => ['string'], 'RangeException::getLine' => ['int'], 'RangeException::getMessage' => ['string'], 'RangeException::getPrevious' => ['Throwable|RangeException|null'], 'RangeException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'RangeException::getTraceAsString' => ['string'], 'rar_allow_broken_set' => ['bool', 'rarfile'=>'RarArchive', 'allow_broken'=>'bool'], 'rar_broken_is' => ['bool', 'rarfile'=>'RarArchive'], 'rar_close' => ['bool', 'rarfile'=>'RarArchive'], 'rar_comment_get' => ['string|null', 'rarfile'=>'RarArchive'], 'rar_entry_get' => ['RarEntry|false', 'rarfile'=>'RarArchive', 'entryname'=>'string'], 'rar_list' => ['RarEntry[]|false', 'rarfile'=>'RarArchive'], 'rar_open' => ['RarArchive|false', 'filename'=>'string', 'password='=>'string', 'volume_callback='=>'callable'], 'rar_solid_is' => ['bool', 'rarfile'=>'RarArchive'], 'rar_wrapper_cache_stats' => ['string'], 'RarArchive::__toString' => ['string'], 'RarArchive::close' => ['bool'], 'RarArchive::getComment' => ['string|null'], 'RarArchive::getEntries' => ['RarEntry[]|false'], 'RarArchive::getEntry' => ['RarEntry|false', 'entryname'=>'string'], 'RarArchive::isBroken' => ['bool'], 'RarArchive::isSolid' => ['bool'], 'RarArchive::open' => ['RarArchive|false', 'filename'=>'string', 'password='=>'string', 'volume_callback='=>'callable'], 'RarArchive::setAllowBroken' => ['bool', 'allow_broken'=>'bool'], 'RarEntry::__toString' => ['string'], 'RarEntry::extract' => ['bool', 'dir'=>'string', 'filepath='=>'string', 'password='=>'string', 'extended_data='=>'bool'], 'RarEntry::getAttr' => ['int'], 'RarEntry::getCrc' => ['string'], 'RarEntry::getFileTime' => ['string'], 'RarEntry::getHostOs' => ['int'], 'RarEntry::getMethod' => ['int'], 'RarEntry::getName' => ['string'], 'RarEntry::getPackedSize' => ['int'], 'RarEntry::getPosition' => ['int'], 'RarEntry::getRedirTarget' => ['string|bool'], 'RarEntry::getRedirType' => ['int|false|null'], 'RarEntry::getStream' => ['resource|false', 'password='=>'string'], 'RarEntry::getUnpackedSize' => ['int'], 'RarEntry::getVersion' => ['int'], 'RarEntry::isDirectory' => ['bool'], 'RarEntry::isEncrypted' => ['bool'], 'RarEntry::isRedirectToDirectory' => ['bool|null'], 'RarException::getCode' => ['int'], 'RarException::getFile' => ['string'], 'RarException::getLine' => ['int'], 'RarException::getMessage' => ['string'], 'RarException::getPrevious' => ['Exception|Throwable'], 'RarException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'RarException::getTraceAsString' => ['string'], 'RarException::isUsingExceptions' => ['bool'], 'RarException::setUsingExceptions' => ['void', 'using_exceptions'=>'bool'], 'rawurldecode' => ['string', 'str'=>'string'], 'rawurlencode' => ['string', 'str'=>'string'], 'read_exif_data' => ['array', 'filename'=>'string|resource', 'sections_needed='=>'string', 'sub_arrays='=>'bool', 'read_thumbnail='=>'bool'], 'readdir' => ['non-empty-string|false', 'dir_handle='=>'resource'], 'readfile' => ['0|positive-int|false', 'filename'=>'string', 'use_include_path='=>'bool', 'context='=>'resource'], 'readgzfile' => ['0|positive-int|false', 'filename'=>'string', 'use_include_path='=>'int'], 'readline' => ['string|false', 'prompt='=>'?string'], 'readline_add_history' => ['bool', 'prompt'=>'string'], 'readline_callback_handler_install' => ['bool', 'prompt'=>'string', 'callback'=>'callable'], 'readline_callback_handler_remove' => ['bool'], 'readline_callback_read_char' => ['void'], 'readline_clear_history' => ['bool'], 'readline_completion_function' => ['bool', 'funcname'=>'callable'], 'readline_info' => ['mixed', 'varname='=>'string', 'newvalue='=>'string'], 'readline_list_history' => ['array'], 'readline_on_new_line' => ['void'], 'readline_read_history' => ['bool', 'filename='=>'string'], 'readline_redisplay' => ['void'], 'readline_write_history' => ['bool', 'filename='=>'string'], 'readlink' => ['string|false', 'filename'=>'string'], 'realpath' => ['non-empty-string|false', 'path'=>'string'], 'realpath_cache_get' => ['array'], 'realpath_cache_size' => ['int'], 'recode' => ['string', 'request'=>'string', 'str'=>'string'], 'recode_file' => ['bool', 'request'=>'string', 'input'=>'resource', 'output'=>'resource'], 'recode_string' => ['string', 'request'=>'string', 'str'=>'string'], 'rectObj::__construct' => ['void'], 'rectObj::draw' => ['int', 'map'=>'mapObj', 'layer'=>'layerObj', 'img'=>'imageObj', 'class_index'=>'int', 'text'=>'string'], 'rectObj::fit' => ['float', 'width'=>'int', 'height'=>'int'], 'rectObj::ms_newRectObj' => ['rectObj'], 'rectObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'], 'rectObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], 'rectObj::setextent' => ['void', 'minx'=>'float', 'miny'=>'float', 'maxx'=>'float', 'maxy'=>'float'], 'RecursiveArrayIterator::__construct' => ['void', 'array='=>'array|object', 'flags='=>'int'], 'RecursiveArrayIterator::append' => ['void', 'value'=>'mixed'], 'RecursiveArrayIterator::asort' => ['void'], 'RecursiveArrayIterator::count' => ['0|positive-int'], 'RecursiveArrayIterator::current' => ['mixed'], 'RecursiveArrayIterator::getArrayCopy' => ['array'], 'RecursiveArrayIterator::getChildren' => ['RecursiveArrayIterator'], 'RecursiveArrayIterator::getFlags' => ['void'], 'RecursiveArrayIterator::hasChildren' => ['bool'], 'RecursiveArrayIterator::key' => ['false|int|string'], 'RecursiveArrayIterator::ksort' => ['void'], 'RecursiveArrayIterator::natcasesort' => ['void'], 'RecursiveArrayIterator::natsort' => ['void'], 'RecursiveArrayIterator::next' => ['void'], 'RecursiveArrayIterator::offsetExists' => ['void', 'index'=>'string'], 'RecursiveArrayIterator::offsetGet' => ['mixed', 'index'=>'string'], 'RecursiveArrayIterator::offsetSet' => ['void', 'index'=>'string', 'newval'=>'string'], 'RecursiveArrayIterator::offsetUnset' => ['void', 'index'=>'string'], 'RecursiveArrayIterator::rewind' => ['void'], 'RecursiveArrayIterator::seek' => ['void', 'position'=>'int'], 'RecursiveArrayIterator::serialize' => ['string'], 'RecursiveArrayIterator::setFlags' => ['void', 'flags'=>'string'], 'RecursiveArrayIterator::uasort' => ['void', 'callback'=>'callable(mixed,mixed):int'], 'RecursiveArrayIterator::uksort' => ['void', 'callback'=>'callable(array-key,array-key):int'], 'RecursiveArrayIterator::unserialize' => ['string', 'serialized'=>'string'], 'RecursiveArrayIterator::valid' => ['bool'], 'RecursiveCachingIterator::__construct' => ['void', 'iterator'=>'Iterator', 'flags'=>''], 'RecursiveCachingIterator::getChildren' => ['RecursiveCachingIterator'], 'RecursiveCachingIterator::hasChildren' => ['bool'], 'RecursiveCallbackFilterIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator', 'func'=>'callable'], 'RecursiveCallbackFilterIterator::getChildren' => ['RecursiveCallbackFilterIterator'], 'RecursiveCallbackFilterIterator::hasChildren' => ['void'], 'RecursiveDirectoryIterator::__construct' => ['void', 'path'=>'string', 'flags='=>'int'], 'RecursiveDirectoryIterator::getChildren' => ['object'], 'RecursiveDirectoryIterator::getSubPath' => ['string'], 'RecursiveDirectoryIterator::getSubPathname' => ['string'], 'RecursiveDirectoryIterator::hasChildren' => ['bool', 'allow_links='=>'bool'], 'RecursiveDirectoryIterator::key' => ['string'], 'RecursiveDirectoryIterator::next' => ['void'], 'RecursiveDirectoryIterator::rewind' => ['void'], 'RecursiveFilterIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator'], 'RecursiveFilterIterator::getChildren' => ['RecursiveFilterIterator'], 'RecursiveFilterIterator::hasChildren' => ['bool'], 'RecursiveIterator::getChildren' => ['RecursiveIterator'], 'RecursiveIterator::hasChildren' => ['bool'], 'RecursiveIteratorIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator|IteratorAggregate', 'mode='=>'int', 'flags='=>'int'], 'RecursiveIteratorIterator::beginChildren' => ['void'], 'RecursiveIteratorIterator::beginIteration' => ['RecursiveIterator'], 'RecursiveIteratorIterator::callGetChildren' => ['RecursiveIterator'], 'RecursiveIteratorIterator::callHasChildren' => ['bool'], 'RecursiveIteratorIterator::current' => ['mixed'], 'RecursiveIteratorIterator::endChildren' => ['void'], 'RecursiveIteratorIterator::endIteration' => ['RecursiveIterator'], 'RecursiveIteratorIterator::getDepth' => ['int'], 'RecursiveIteratorIterator::getInnerIterator' => ['RecursiveIterator'], 'RecursiveIteratorIterator::getMaxDepth' => ['int|false'], 'RecursiveIteratorIterator::getSubIterator' => ['RecursiveIterator', 'level='=>'int'], 'RecursiveIteratorIterator::key' => ['mixed'], 'RecursiveIteratorIterator::next' => ['void'], 'RecursiveIteratorIterator::nextElement' => ['void'], 'RecursiveIteratorIterator::rewind' => ['void'], 'RecursiveIteratorIterator::setMaxDepth' => ['void', 'max_depth='=>'int'], 'RecursiveIteratorIterator::valid' => ['bool'], 'RecursiveRegexIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator', 'regex='=>'string', 'mode='=>'int', 'flags='=>'int', 'preg_flags='=>'int'], 'RecursiveRegexIterator::getChildren' => ['RecursiveRegexIterator'], 'RecursiveRegexIterator::hasChildren' => ['bool'], 'RecursiveTreeIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator|IteratorAggregate', 'flags='=>'int', 'cit_flags='=>'int', 'mode='=>'int'], 'RecursiveTreeIterator::beginChildren' => ['void'], 'RecursiveTreeIterator::beginIteration' => ['RecursiveIterator'], 'RecursiveTreeIterator::callGetChildren' => ['RecursiveIterator'], 'RecursiveTreeIterator::callHasChildren' => ['bool'], 'RecursiveTreeIterator::current' => ['string'], 'RecursiveTreeIterator::endChildren' => ['void'], 'RecursiveTreeIterator::endIteration' => ['void'], 'RecursiveTreeIterator::getEntry' => ['string'], 'RecursiveTreeIterator::getPostfix' => ['string'], 'RecursiveTreeIterator::getPrefix' => ['string'], 'RecursiveTreeIterator::key' => ['string'], 'RecursiveTreeIterator::next' => ['void'], 'RecursiveTreeIterator::nextElement' => ['void'], 'RecursiveTreeIterator::rewind' => ['void'], 'RecursiveTreeIterator::setPostfix' => ['void', 'prefix'=>'string'], 'RecursiveTreeIterator::setPrefixPart' => ['void', 'part'=>'int', 'prefix'=>'string'], 'RecursiveTreeIterator::valid' => ['bool'], 'Redis::__construct' => ['void', 'options='=>'?array{host?:string,port?:int,connectTimeout?:float,auth?:list{string|null|false,string}|list{string},ssl?:array,backoff?:array}'], 'Redis::_compress' => ['string', 'value'=>'string'], 'Redis::_uncompress' => ['string', 'value'=>'string'], 'Redis::_prefix' => ['string', 'key'=>'mixed'], 'Redis::_serialize' => ['mixed', 'value'=>'string'], 'Redis::_unserialize' => ['string', 'value'=>'mixed'], 'Redis::_pack' => ['mixed', 'value'=>'string'], 'Redis::_unpack' => ['string', 'value'=>'mixed'], 'Redis::acl' => ['mixed', 'subcmd'=>'string', '...args='=>'string'], 'Redis::append' => ['__benevolent', 'key'=>'string', 'value'=>'string'], 'Redis::auth' => ['__benevolent', 'credentials'=>'string|string[]'], 'Redis::bgrewriteaof' => ['__benevolent'], 'Redis::bgSave' => ['__benevolent'], 'Redis::bitcount' => ['__benevolent', 'key'=>'string', 'start='=>'int', 'end='=>'int', 'bybit='=>'bool'], 'Redis::bitop' => ['__benevolent', 'operation'=>'string', 'deskey'=>'string', 'srckey'=>'string', '...other_keys'=>'string'], 'Redis::bitpos' => ['__benevolent', 'key'=>'string', 'bit'=>'bool', 'start='=>'int', 'end='=>'int', 'bybit='=>'bool'], 'Redis::blmove' => ['__benevolent', 'src'=>'string', 'dst'=>'string', 'wherefrom'=>'string', 'whereto'=>'string', 'timeout'=>'float'], 'Redis::blmpop' => ['__benevolent', 'timeout'=>'float', 'keys'=>'string[]', 'from'=>'string', 'count='=>'int'], 'Redis::blPop' => ['__benevolent', 'key_or_keys'=>'string|string[]', 'timeout_or_key'=>'string|float|int', '...extra_args'=>'mixed'], 'Redis::blPop\'1' => ['array', 'key'=>'string', 'timeout_or_key'=>'int|string', '...extra_args'=>'int|string'], 'Redis::brPop' => ['__benevolent', 'key_or_keys'=>'string|string[]', 'timeout_or_key'=>'string|float|int', '...extra_args'=>'mixed'], 'Redis::brPop\'1' => ['array', 'key'=>'string', 'timeout_or_key'=>'int|string', '...extra_args'=>'int|string'], 'Redis::brpoplpush' => ['__benevolent', 'src'=>'string', 'dst'=>'string', 'timeout'=>'int|float'], 'Redis::bzPopMax' => ['__benevolent', 'key'=>'string|string[]', 'timeout_or_key'=>'string|int', '...extra_args'=>'mixed'], 'Redis::bzPopMin' => ['__benevolent', 'key'=>'string|string[]', 'timeout_or_key'=>'string|int', '...extra_args'=>'mixed'], 'Redis::bzmpop' => ['__benevolent', 'timeout'=>'float', 'keys'=>'string[]', 'from'=>'string', 'count='=>'int'], 'Redis::clearLastError' => ['bool'], 'Redis::clearTransferredBytes' => ['void'], 'Redis::client' => ['mixed', 'opt'=>'string', '...args='=>'mixed'], 'Redis::close' => ['bool'], 'Redis::command' => ['mixed', 'opt='=>'?string', '...args'=>'mixed'], 'Redis::config' => ['mixed', 'operation'=>'string', 'key_or_settings='=>'array|string[]|string|null', 'value='=>'?string'], 'Redis::connect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'persistent_id='=>'?string', 'retry_interval='=>'int', 'read_timeout='=>'float', 'context='=>'?array{auth?:list{string|null|false,string}|list{string},stream?:array}'], 'Redis::copy' => ['__benevolent', 'src'=>'string', 'dst'=>'string', 'options='=>'?array'], 'Redis::dbSize' => ['__benevolent'], 'Redis::debug' => ['__benevolent', 'key'=>'string'], 'Redis::decr' => ['__benevolent', 'key'=>'string', 'by='=>'int'], 'Redis::decrBy' => ['__benevolent', 'key'=>'string', 'value'=>'int'], 'Redis::decrByFloat' => ['float', 'key'=>'string', 'value'=>'float'], 'Redis::del' => ['__benevolent', 'key'=>'string[]|string', '...other_keys='=>'string'], 'Redis::del\'1' => ['int', 'key'=>'string[]'], 'Redis::delete' => ['__benevolent', 'key'=>'string[]|string', '...other_keys='=>'string'], 'Redis::delete\'1' => ['int', 'key'=>'string[]'], 'Redis::discard' => ['__benevolent'], 'Redis::dump' => ['__benevolent', 'key'=>'string'], 'Redis::echo' => ['__benevolent', 'str'=>'string'], 'Redis::eval' => ['mixed', 'script'=>'string', 'args='=>'array', 'num_keys='=>'int'], 'Redis::eval_ro' => ['mixed', 'script'=>'string', 'args='=>'array', 'num_keys='=>'int'], 'Redis::evalsha' => ['mixed', 'sha1'=>'string', 'args='=>'array', 'num_keys='=>'int'], 'Redis::evalsha_ro' => ['mixed', 'sha1'=>'string', 'args='=>'array', 'num_keys='=>'int'], 'Redis::evaluate' => ['mixed', 'script'=>'string', 'args='=>'array', 'numKeys='=>'int'], 'Redis::exec' => ['__benevolent'], 'Redis::exists' => ['__benevolent', 'keys'=>'string|string[]', '...other_keys='=>'string'], 'Redis::exists\'1' => ['int', '...keys'=>'string'], 'Redis::expire' => ['__benevolent', 'key'=>'string', 'timeout'=>'int', 'mode='=>'?string'], 'Redis::expireAt' => ['__benevolent', 'key'=>'string', 'timeout'=>'int', 'mode='=>'?string'], 'Redis::expiretime' => ['__benevolent', 'key'=>'string'], 'Redis::failover' => ['__benevolent', 'to='=>'?array', 'abort='=>'bool', 'timeout='=>'int'], 'Redis::fcall' => ['mixed', 'fn'=>'string', 'keys='=>'string[]', 'args='=>'array'], 'Redis::fcall_ro' => ['mixed', 'fn'=>'string', 'keys='=>'string[]', 'args='=>'array'], 'Redis::flushAll' => ['__benevolent', 'sync='=>'?bool'], 'Redis::flushDb' => ['__benevolent', 'sync='=>'?bool'], 'Redis::function' => ['__benevolent', 'operation'=>'string', '...args='=>'mixed'], 'Redis::geoadd' => ['__benevolent', 'key'=>'string', 'lng'=>'float', 'lat'=>'float', 'member'=>'string', '...other_triples_and_options='=>'mixed'], 'Redis::geodist' => ['__benevolent', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'], 'Redis::geohash' => ['__benevolent|false>', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'], 'Redis::geopos' => ['__benevolent|false>', 'key'=>'string', 'member'=>'string', '...other_members'=>'string'], 'Redis::georadius' => ['__benevolent>', 'key'=>'string', 'lng'=>'float', 'lat'=>'float', 'radius'=>'float', 'unit'=>'string', 'options='=>'array'], 'Redis::georadiusbymember' => ['__benevolent>', 'key'=>'string', 'lng'=>'float', 'lat'=>'float', 'radius'=>'float', 'unit'=>'string', 'options='=>'array'], 'Redis::georadiusbymember_ro' => ['__benevolent>', 'key'=>'string', 'lng'=>'float', 'lat'=>'float', 'radius'=>'float', 'unit'=>'string', 'options='=>'array'], 'Redis::geosearch' => ['__benevolent>', 'key'=>'string', 'position'=>'array|string', 'shape'=>'array|int|float', 'unit'=>'string', 'options='=>'array'], 'Redis::geosearchstore' => ['__benevolent|int|false>', 'dst'=>'string', 'src'=>'string', 'position'=>'array|string', 'shape'=>'array|int|float', 'unit'=>'string', 'options='=>'array'], 'Redis::get' => ['mixed', 'key'=>'string'], 'Redis::getAuth' => ['string|false|null'], 'Redis::getBit' => ['__benevolent', 'key'=>'string', 'idx'=>'int'], 'Redis::getEx' => ['__benevolent', 'key'=>'string', 'options'=>'?array{EX?:int,PX?:int,EXAT?:int,PXAT?:int,PERSIST?:bool}'], 'Redis::getDBNum' => ['int'], 'Redis::getDel' => ['__benevolent', 'key'=>'string'], 'Redis::getHost' => ['string'], 'Redis::getKeys' => ['array', 'pattern'=>'string'], 'Redis::getLastError' => ['?string'], 'Redis::getMode' => ['int'], 'Redis::getMultiple' => ['array', 'keys'=>'string[]'], 'Redis::getOption' => ['int', 'name'=>'int'], 'Redis::getPersistentID' => ['?string'], 'Redis::getPort' => ['int'], 'Redis::getRange' => ['__benevolent', 'key'=>'string', 'start'=>'int', 'end'=>'int'], 'Redis::getReadTimeout' => ['float'], 'Redis::getset' => ['__benevolent', 'key'=>'string', 'value'=>'mixed'], 'Redis::getTimeout' => ['float|false'], 'Redis::getTransferredBytes' => ['array'], 'Redis::hDel' => ['__benevolent', 'key'=>'string', 'field'=>'string', '...other_fields='=>'string'], 'Redis::hExists' => ['__benevolent', 'key'=>'string', 'field'=>'string'], 'Redis::hGet' => ['__benevolent', 'key'=>'string', 'member'=>'string'], 'Redis::hGetAll' => ['__benevolent', 'key'=>'string'], 'Redis::hIncrBy' => ['__benevolent', 'key'=>'string', 'field'=>'string', 'value'=>'int'], 'Redis::hIncrByFloat' => ['__benevolent', 'key'=>'string', 'field'=>'string', 'value'=>'float'], 'Redis::hKeys' => ['__benevolent', 'key'=>'string'], 'Redis::hLen' => ['__benevolent', 'key'=>'string'], 'Redis::hMget' => ['__benevolent|false>', 'key'=>'string', 'fields'=>'string[]'], 'Redis::hMset' => ['__benevolent', 'key'=>'string', 'fieldvals'=>'array'], 'Redis::hRandField' => ['__benevolent>', 'key'=>'string', 'options'=>'?array{COUNT?:int,WITHVALUES?:bool}'], 'Redis::hscan' => ['__benevolent|bool>', 'key'=>'string', '&iterator'=>'?int', 'pattern='=>'?string', 'count='=>'int'], 'Redis::hSet' => ['__benevolent', 'key'=>'string', 'member'=>'string', 'value'=>'mixed'], 'Redis::hSetNx' => ['__benevolent', 'key'=>'string', 'field'=>'string', 'value'=>'string'], 'Redis::hStrLen' => ['__benevolent', 'key'=>'string', 'field'=>'string'], 'Redis::hVals' => ['__benevolent', 'key'=>'string'], 'Redis::incr' => ['__benevolent', 'key'=>'string', 'by='=>'int'], 'Redis::incrBy' => ['__benevolent', 'key'=>'string', 'value'=>'int'], 'Redis::incrByFloat' => ['__benevolent', 'key'=>'string', 'value'=>'float'], 'Redis::info' => ['__benevolent|false>', '...sections='=>'string'], 'Redis::isConnected' => ['bool'], 'Redis::keys' => ['__benevolent|false>', 'pattern'=>'string'], 'Redis::lastSave' => ['int'], 'Redis::lcs' => ['__benevolent', 'key1'=>'string', 'key2'=>'string', 'options'=>'?array{MINMATCHLEN?:int,WITHMATCHLEN?:bool,LEN?:bool,IDX?:bool}'], 'Redis::lGet' => ['', 'key'=>'string', 'index'=>'int'], 'Redis::lGetRange' => ['', 'key'=>'string', 'start'=>'int', 'end'=>'int'], 'Redis::lindex' => ['null|string|false', 'key'=>'string', 'index'=>'int'], 'Redis::lInsert' => ['__benevolent', 'key'=>'string', 'pos'=>'int', 'pivot'=>'mixed', 'value'=>'mixed'], 'Redis::listTrim' => ['', 'key'=>'string', 'start'=>'int', 'stop'=>'int'], 'Redis::lLen' => ['__benevolent', 'key'=>'string'], 'Redis::lMove' => ['__benevolent', 'src'=>'string', 'dst'=>'string', 'wherefrom'=>'string', 'whereto'=>'string'], 'Redis::lmpop' => ['__benevolent|null|false>', 'keys'=>'string[]', 'from'=>'string', 'count='=>'int'], 'Redis::lPop' => ['__benevolent', 'key'=>'string', 'count='=>'int'], 'Redis::lPos' => ['__benevolent', 'key'=>'string', 'value'=>'mixed', 'options'=>'?array{COUNT?:int,RANK?:int,MAXLEN?:int}'], 'Redis::lPush' => ['__benevolent', 'key'=>'string', '...elements='=>'mixed'], 'Redis::lPushx' => ['__benevolent', 'key'=>'string', 'value'=>'mixed'], 'Redis::lrange' => ['__benevolent', 'key'=>'string', 'start'=>'int', 'end'=>'int'], 'Redis::lrem' => ['__benevolent', 'key'=>'string', 'value'=>'mixed', 'count='=>'int'], 'Redis::lSet' => ['__benevolent', 'key'=>'string', 'index'=>'int', 'value'=>'mixed'], 'Redis::lSize' => ['', 'key'=>'string'], 'Redis::ltrim' => ['__benevolent', 'key'=>'string', 'start'=>'int', 'end'=>'int'], 'Redis::mget' => ['__benevolent>', 'keys'=>'string[]'], 'Redis::migrate' => ['__benevolent', 'host'=>'string', 'port'=>'int', 'key'=>'string|string[]', 'dstdb'=>'int', 'timeout'=>'int', 'copy='=>'bool', 'replace='=>'bool', 'credentials='=>'mixed'], 'Redis::move' => ['__benevolent', 'key'=>'string', 'index'=>'int'], 'Redis::mset' => ['__benevolent', 'key_values'=>'array'], 'Redis::msetnx' => ['__benevolent', 'key_values'=>'array'], 'Redis::multi' => ['__benevolent', 'value='=>'int'], 'Redis::object' => ['__benevolent', 'subcommand'=>'string', 'key'=>'string'], 'Redis::open' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'persistent_id='=>'?string', 'retry_interval='=>'int', 'read_timeout='=>'float', 'context='=>'?array{auth?:list{string|null|false,string}|list{string},stream?:array}'], 'Redis::pconnect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'persistent_id='=>'?string', 'retry_interval='=>'int', 'read_timeout='=>'float', 'context='=>'?array{auth?:list{string|null|false,string}|list{string},stream?:array}'], 'Redis::persist' => ['__benevolent', 'key'=>'string'], 'Redis::pexpire' => ['bool', 'key'=>'string', 'timeout'=>'int', 'mode='=>'?string'], 'Redis::pexpireAt' => ['__benevolent', 'key'=>'string', 'timestamp'=>'int', 'mode='=>'?string'], 'Redis::pexpiretime' => ['__benevolent', 'key'=>'string'], 'Redis::pfadd' => ['__benevolent', 'key'=>'string', 'elements'=>'array'], 'Redis::pfcount' => ['__benevolent', 'key_or_keys'=>'string[]|string'], 'Redis::pfmerge' => ['__benevolent', 'dst'=>'string', 'srckeys'=>'string[]'], 'Redis::ping' => ['__benevolent', 'message='=>'?string'], 'Redis::pipeline' => ['__benevolent'], 'Redis::popen' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'persistent_id='=>'?string', 'retry_interval='=>'int', 'read_timeout='=>'float', 'context='=>'?array{auth?:list{string|null|false,string}|list{string},stream?:array}'], 'Redis::psetex' => ['__benevolent', 'key'=>'string', 'expire'=>'int', 'value'=>'mixed'], 'Redis::psubscribe' => ['bool', 'patterns'=>'string[]', 'cb'=>'callable'], 'Redis::pttl' => ['__benevolent', 'key'=>'string'], 'Redis::publish' => ['__benevolent', 'channel'=>'string', 'message'=>'string'], 'Redis::pubsub' => ['array|int', 'command'=>'string', 'arg'=>'array|string'], 'Redis::punsubscribe' => ['__benevolent', 'patterns='=>'string[]'], 'Redis::randomKey' => ['__benevolent'], 'Redis::rawcommand' => ['mixed', 'command'=>'string', '...args='=>'mixed'], 'Redis::rename' => ['__benevolent', 'old_name'=>'string', 'new_name'=>'string'], 'Redis::renameKey' => ['bool', 'srckey'=>'string', 'dstkey'=>'string'], 'Redis::renameNx' => ['__benevolent', 'old_name'=>'string', 'new_name'=>'string'], 'Redis::reset' => ['__benevolent'], 'Redis::resetStat' => ['bool'], 'Redis::restore' => ['__benevolent', 'key'=>'string', 'ttl'=>'int', 'value'=>'string', 'options='=>'?array{ABSTTL?:bool,REPLACE?:bool,IDLETIME?:int,FREQ?:int}'], 'Redis::role' => ['mixed'], 'Redis::rPop' => ['__benevolent|string|bool>', 'key'=>'string', 'count='=>'int'], 'Redis::rpoplpush' => ['__benevolent', 'srckey'=>'string', 'dstkey'=>'string'], 'Redis::rPush' => ['__benevolent', 'key'=>'string', '...elements='=>'mixed'], 'Redis::rPushx' => ['__benevolent', 'key'=>'string', 'value'=>'mixed'], 'Redis::sAdd' => ['__benevolent', 'key'=>'string', 'value'=>'mixed', '...other_values='=>'string'], 'Redis::sAddArray' => ['int', 'key'=>'string', 'values'=>'array'], 'Redis::save' => ['__benevolent'], 'Redis::scan' => ['array|false', '&iterator'=>'?int', 'pattern='=>'?string', 'count='=>'?int', 'type='=>'?string'], 'Redis::scard' => ['__benevolent', 'key'=>'string'], 'Redis::sContains' => ['', 'key'=>'string', 'value'=>'string'], 'Redis::script' => ['mixed', 'command'=>'string', '...args='=>'mixed'], 'Redis::sDiff' => ['__benevolent|false>', 'key'=>'string', '...other_keys='=>'string'], 'Redis::sDiffStore' => ['__benevolent', 'dst'=>'string', 'key'=>'string', '...other_keys='=>'string'], 'Redis::select' => ['__benevolent', 'db'=>'int'], 'Redis::set' => ['__benevolent', 'key'=>'string', 'value'=>'mixed', 'options='=>'array'], 'Redis::set\'1' => ['bool', 'key'=>'string', 'value'=>'mixed', 'timeout='=>'int'], 'Redis::setBit' => ['__benevolent', 'key'=>'string', 'idx'=>'int', 'value'=>'bool'], 'Redis::setex' => ['__benevolent', 'key'=>'string', 'expire'=>'int', 'value'=>'mixed'], 'Redis::setnx' => ['__benevolent', 'key'=>'string', 'value'=>'mixed'], 'Redis::setOption' => ['bool', 'option'=>'int', 'value'=>'mixed'], 'Redis::setRange' => ['__benevolent', 'key'=>'string', 'index'=>'int', 'value'=>'string'], 'Redis::setTimeout' => ['bool', 'key'=>'string', 'ttl'=>'int'], 'Redis::sGetMembers' => ['array', 'key'=>'string'], 'Redis::sInter' => ['__benevolent|false>', 'key'=>'string', '...other_keys='=>'string'], 'Redis::sintercard' => ['__benevolent', 'keys'=>'string[]', 'limit='=>'int'], 'Redis::sInterStore' => ['__benevolent', 'key'=>'string[]|string', '...other_keys='=>'string'], 'Redis::sismember' => ['__benevolent', 'key'=>'string', 'value'=>'mixed'], 'Redis::slave' => ['bool', 'host'=>'string', 'port'=>'int'], 'Redis::slave\'1' => ['bool', 'host'=>'string', 'port'=>'int'], 'Redis::slaveof' => ['__benevolent', 'host='=>'?string', 'port='=>'int'], 'Redis::slowlog' => ['mixed', 'operation'=>'string', 'length='=>'int'], 'Redis::sMembers' => ['__benevolent|false>', 'key'=>'string'], 'Redis::sMisMember' => ['__benevolent', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'], 'Redis::sMove' => ['__benevolent', 'src'=>'string', 'dst'=>'string', 'value'=>'mixed'], 'Redis::sort' => ['array|int', 'key'=>'string', 'options='=>'?array{SORT?:string,ALPHA?:bool,LIMIT?:array{0:int,1:int},BY?:string,GET?:string}'], 'Redis::sort_ro' => ['array|int', 'key'=>'string', 'options='=>'?array{SORT?:string,ALPHA?:bool,LIMIT?:array{0:int,1:int},BY?:string,GET?:string}'], 'Redis::sPop' => ['__benevolent', 'key'=>'string', 'count='=>'int'], 'Redis::sRandMember' => ['__benevolent', 'key'=>'string', 'count='=>'int'], 'Redis::srem' => ['__benevolent', 'key'=>'string', 'value'=>'mixed', '...other_values='=>'mixed'], 'Redis::sRemove' => ['int', 'key'=>'string', 'member1'=>'string', '...other_members='=>'string'], 'Redis::sscan' => ['__benevolent', 'key'=>'string', '&iterator'=>'?int', 'pattern='=>'?string', 'count='=>'int'], 'Redis::ssubscribe' => ['bool', 'channels'=>'string[]', 'cb'=>'callable'], 'Redis::strlen' => ['__benevolent', 'key'=>'string'], 'Redis::subscribe' => ['bool', 'channels'=>'string[]', 'cb'=>'callable'], 'Redis::substr' => ['', 'key'=>'string', 'start'=>'int', 'end'=>'int'], 'Redis::unlink\'1' => ['int', 'key'=>'string[]'], 'Redis::sUnion' => ['__benevolent|false>', 'key'=>'string', '...other_keys='=>'string'], 'Redis::sUnionStore' => ['__benevolent', 'dst'=>'string', 'key'=>'string', '...other_keys='=>'string'], 'Redis::sunsubscribe' => ['__benevolent', 'channels'=>'string[]'], 'Redis::swapdb' => ['__benevolent', 'src'=>'int', 'dst'=>'int'], 'Redis::time' => ['__benevolent'], 'Redis::ttl' => ['__benevolent', 'key'=>'string'], 'Redis::type' => ['__benevolent', 'key'=>'string'], 'Redis::unlink' => ['__benevolent', 'key'=>'string[]|string', '...other_keys'=>'string'], 'Redis::unsubscribe' => ['__benevolent', 'channels'=>'string[]'], 'Redis::unwatch' => ['__benevolent'], 'Redis::wait' => ['int|false', 'numreplicas'=>'int', 'timeout'=>'int'], 'Redis::watch' => ['__benevolent', 'key'=>'string[]|string', '...other_keys='=>'string'], 'Redis::xack' => ['int|false', 'key'=>'string', 'group'=>'string', 'ids'=>'array'], 'Redis::xadd' => ['__benevolent', 'key'=>'string', 'id'=>'string', 'values'=>'array', 'maxlen='=>'int', 'approx='=>'bool', 'nomkstream='=>'bool'], 'Redis::xclaim' => ['__benevolent', 'key'=>'string', 'group'=>'string', 'consumer'=>'string', 'min_idle'=>'int', 'ids'=>'array', 'options='=>'array'], 'Redis::xdel' => ['__benevolent', 'key'=>'string', 'ids'=>'array'], 'Redis::xgroup' => ['mixed', 'operation'=>'string', 'key='=>'?string', 'group='=>'?string', 'id_or_consumer='=>'?string', 'mkstream='=>'bool', 'entries_read='=>'int'], 'Redis::xinfo' => ['mixed', 'operation'=>'string', 'arg1='=>'?string', 'arg2='=>'?string', 'count='=>'int'], 'Redis::xlen' => ['__benevolent', 'key'=>'string'], 'Redis::xpending' => ['__benevolent', 'key'=>'string', 'group'=>'string', 'start='=>'?string', 'end='=>'?string', 'count='=>'int', 'consumer='=>'?string'], 'Redis::xrange' => ['__benevolent', 'key'=>'string', 'start'=>'string', 'end'=>'string', 'count='=>'int'], 'Redis::xread' => ['__benevolent', 'streams'=>'array', 'count='=>'int', 'block='=>'int'], 'Redis::xreadgroup' => ['__benevolent', 'group'=>'string', 'consumer'=>'string', 'streams'=>'array', 'count='=>'int', 'block='=>'int'], 'Redis::xrevrange' => ['__benevolent', 'key'=>'string', 'end'=>'string', 'start'=>'string', 'count='=>'int'], 'Redis::xtrim' => ['__benevolent', 'key'=>'string', 'threshold'=>'string', 'approx='=>'bool', 'minid='=>'bool', 'limit='=>'int'], 'Redis::zAdd' => ['__benevolent', 'key'=>'string', 'score_or_options'=>'array|float', '...more_scores_and_mems='=>'mixed'], 'Redis::zAdd\'1' => ['int', 'key'=>'string', 'options'=>'array', 'score1'=>'float', 'value1'=>'string', 'score2='=>'float', 'value2='=>'string', 'scoreN='=>'float', 'valueN='=>'string'], 'Redis::zCard' => ['__benevolent', 'key'=>'string'], 'Redis::zCount' => ['__benevolent', 'key'=>'string', 'start'=>'string', 'end'=>'string'], 'Redis::zDelete' => ['int', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'], 'Redis::zDeleteRangeByRank' => ['', 'key'=>'string', 'start'=>'int', 'end'=>'int'], 'Redis::zDeleteRangeByScore' => ['', 'key'=>'string', 'start'=>'float', 'end'=>'float'], 'Redis::zIncrBy' => ['__benevolent', 'key'=>'string', 'value'=>'float', 'member'=>'mixed'], 'Redis::zInter' => ['__benevolent', 'keys'=>'string[]', 'weights='=>'?array', 'options='=>'?array'], 'Redis::zmpop' => ['__benevolent', 'keys'=>'string[]', 'from'=>'string', 'count='=>'int'], 'Redis::zRange' => ['__benevolent', 'key'=>'string', 'start'=>'string|int', 'end'=>'string|int', 'options='=>'array|bool|null'], 'Redis::zRangeByLex' => ['__benevolent', 'key'=>'string', 'min'=>'string', 'max'=>'string', 'offset='=>'int', 'limit='=>'int'], 'Redis::zRangeByScore' => ['__benevolent', 'key'=>'string', 'start'=>'string', 'end'=>'string', 'options='=>'array'], 'Redis::zRank' => ['__benevolent', 'key'=>'string', 'member'=>'mixed'], 'Redis::zRem' => ['__benevolent', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'], 'Redis::zRemove' => ['int', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'], 'Redis::zRemRangeByRank' => ['__benevolent', 'key'=>'string', 'start'=>'int', 'end'=>'int'], 'Redis::zRemRangeByScore' => ['__benevolent', 'key'=>'string', 'start'=>'string', 'end'=>'string'], 'Redis::zRevRange' => ['__benevolent', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'scores='=>'bool|array{withscores:bool}|null'], 'Redis::zRevRangeByLex' => ['__benevolent', 'key'=>'string', 'max'=>'string', 'min'=>'string', 'offset='=>'int', 'limit='=>'int'], 'Redis::zRevRangeByScore' => ['__benevolent', 'key'=>'string', 'max'=>'string', 'min'=>'string', 'options='=>'array|bool'], 'Redis::zRevRank' => ['__benevolent', 'key'=>'string', 'member'=>'mixed'], 'Redis::zscan' => ['__benevolent', 'key'=>'string', '&iterator'=>'?int', 'pattern='=>'?string', 'count='=>'int'], 'Redis::zScore' => ['__benevolent', 'key'=>'string', 'member'=>'mixed'], 'Redis::zSize' => ['', 'key'=>'string'], 'Redis::zUnion' => ['__benevolent', 'keys'=>'string[]', 'weights'=>'?array', 'options='=>'?array'], 'RedisArray::__construct' => ['void', 'name'=>'string'], 'RedisArray::__construct\'1' => ['void', 'hosts'=>'array', 'opts='=>'array'], 'RedisArray::_function' => ['string'], 'RedisArray::_hosts' => ['array'], 'RedisArray::_rehash' => ['', 'callable='=>'callable'], 'RedisArray::_target' => ['string', 'key'=>'string'], 'RedisCluster::__construct' => ['void', 'name'=>'string|null', 'seeds='=>'string[]|null', 'timeout='=>'int|float', 'read_timeout='=>'int|float', 'persistent='=>'bool', 'auth='=>'mixed', 'context='=>'array|null'], 'RedisCluster::_masters' => ['array'], 'RedisCluster::_prefix' => ['string', 'value'=>'mixed'], 'RedisCluster::_serialize' => ['mixed', 'value'=>'mixed'], 'RedisCluster::_unserialize' => ['mixed', 'value'=>'string'], 'RedisCluster::append' => ['int', 'key'=>'string', 'value'=>'string'], 'RedisCluster::bgrewriteaof' => ['bool', 'nodeParams'=>'string'], 'RedisCluster::bgsave' => ['bool', 'nodeParams'=>'string'], 'RedisCluster::bitCount' => ['int', 'key'=>'string'], 'RedisCluster::bitOp' => ['int', 'operation'=>'string', 'retKey'=>'string', 'key1'=>'string', 'key2'=>'string', 'key3='=>'string'], 'RedisCluster::bitpos' => ['int', 'key'=>'string', 'bit'=>'int', 'start='=>'int', 'end='=>'int'], 'RedisCluster::blPop' => ['array', 'keys'=>'array', 'timeout'=>'int'], 'RedisCluster::brPop' => ['array', 'keys'=>'array', 'timeout'=>'int'], 'RedisCluster::brpoplpush' => ['string', 'srcKey'=>'string', 'dstKey'=>'string', 'timeout'=>'int'], 'RedisCluster::clearLastError' => ['bool'], 'RedisCluster::client' => ['', 'nodeParams'=>'string', 'subCmd'=>'', 'args'=>''], 'RedisCluster::close' => [''], 'RedisCluster::cluster' => ['mixed', 'nodeParams'=>'string', 'command'=>'string', 'arguments'=>'mixed'], 'RedisCluster::command' => ['mixed'], 'RedisCluster::config' => ['array', 'nodeParams'=>'string', 'operation'=>'string', 'key'=>'string', 'value'=>'string'], 'RedisCluster::dbSize' => ['int', 'nodeParams'=>'string'], 'RedisCluster::decr' => ['int', 'key'=>'string'], 'RedisCluster::decrBy' => ['int', 'key'=>'string', 'value'=>'int'], 'RedisCluster::del' => ['int', 'key1'=>'int|string', 'key2='=>'int|string', 'key3='=>'int|string'], 'RedisCluster::discard' => [''], 'RedisCluster::dump' => ['string', 'key'=>'string'], 'RedisCluster::echo' => ['mixed', 'nodeParams'=>'string', 'msg'=>'string'], 'RedisCluster::eval' => ['mixed', 'script'=>'', 'args='=>'', 'numKeys='=>''], 'RedisCluster::evalSha' => ['mixed', 'scriptSha'=>'string', 'args='=>'array', 'numKeys='=>'int'], 'RedisCluster::exec' => ['array|void'], 'RedisCluster::exists' => ['bool', 'key'=>'string'], 'RedisCluster::expire' => ['bool', 'key'=>'string', 'ttl'=>'int'], 'RedisCluster::expireAt' => ['bool', 'key'=>'string', 'timestamp'=>'int'], 'RedisCluster::flushAll' => ['bool', 'nodeParams'=>'string'], 'RedisCluster::flushDB' => ['bool', 'nodeParams'=>'string'], 'RedisCluster::geoAdd' => ['', 'key'=>'string', 'longitude'=>'float', 'latitude'=>'float', 'member'=>'string'], 'RedisCluster::geoDist' => ['', 'key'=>'string', 'member1'=>'string', 'member2'=>'string', 'unit='=>'string'], 'RedisCluster::geohash' => ['', 'key'=>'', 'member1'=>'', 'member2='=>'mixed', 'memberN='=>'mixed'], 'RedisCluster::geopos' => ['', 'key'=>'', 'member1'=>'', 'member2='=>'mixed', 'memberN='=>'mixed'], 'RedisCluster::geoRadius' => ['', 'key'=>'string', 'longitude'=>'float', 'latitude'=>'float', 'radius'=>'float', 'radiusUnit'=>'string', 'options'=>'array'], 'RedisCluster::geoRadiusByMember' => ['', 'key'=>'string', 'member'=>'string', 'radius'=>'float', 'radiusUnit'=>'string', 'options'=>'array'], 'RedisCluster::get' => ['bool|string', 'key'=>'string'], 'RedisCluster::getBit' => ['int', 'key'=>'string', 'offset'=>'int'], 'RedisCluster::getLastError' => ['string'], 'RedisCluster::getMode' => ['int'], 'RedisCluster::getOption' => ['int', 'name'=>'int'], 'RedisCluster::getRange' => ['string', 'key'=>'string', 'start'=>'int', 'end'=>'int'], 'RedisCluster::getSet' => ['string', 'key'=>'string', 'value'=>'string'], 'RedisCluster::hDel' => ['int', 'key'=>'string', 'hashKey1'=>'string', 'hashKey2='=>'string', 'hashKeyN='=>'string'], 'RedisCluster::hExists' => ['bool', 'key'=>'string', 'hashKey'=>'string'], 'RedisCluster::hGet' => ['string', 'key'=>'string', 'hashKey'=>'string'], 'RedisCluster::hGetAll' => ['array', 'key'=>'string'], 'RedisCluster::hIncrBy' => ['int', 'key'=>'string', 'hashKey'=>'string', 'value'=>'int'], 'RedisCluster::hIncrByFloat' => ['float', 'key'=>'string', 'field'=>'string', 'increment'=>'float'], 'RedisCluster::hKeys' => ['array', 'key'=>'string'], 'RedisCluster::hLen' => ['int', 'key'=>'string'], 'RedisCluster::hMGet' => ['array', 'key'=>'string', 'hashKeys'=>'array'], 'RedisCluster::hMSet' => ['bool', 'key'=>'string', 'hashKeys'=>'array'], 'RedisCluster::hScan' => ['array', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'], 'RedisCluster::hSet' => ['int', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'], 'RedisCluster::hSetNx' => ['bool', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'], 'RedisCluster::hVals' => ['array', 'key'=>'string'], 'RedisCluster::incr' => ['int', 'key'=>'string'], 'RedisCluster::incrBy' => ['int', 'key'=>'string', 'value'=>'int'], 'RedisCluster::incrByFloat' => ['float', 'key'=>'string', 'increment'=>'float'], 'RedisCluster::info' => ['string', 'option='=>'string'], 'RedisCluster::keys' => ['array', 'pattern'=>'string'], 'RedisCluster::lastSave' => ['int', 'nodeParams'=>'string'], 'RedisCluster::lGet' => ['', 'key'=>'string', 'index'=>'int'], 'RedisCluster::lIndex' => ['string', 'key'=>'string', 'index'=>'int'], 'RedisCluster::lInsert' => ['int', 'key'=>'string', 'position'=>'int', 'pivot'=>'string', 'value'=>'string'], 'RedisCluster::lLen' => ['int', 'key'=>'string'], 'RedisCluster::lPop' => ['string', 'key'=>'string'], 'RedisCluster::lPush' => ['int', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'], 'RedisCluster::lPushx' => ['int', 'key'=>'string', 'value'=>'string'], 'RedisCluster::lRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int'], 'RedisCluster::lRem' => ['int', 'key'=>'string', 'value'=>'string', 'count'=>'int'], 'RedisCluster::lSet' => ['bool', 'key'=>'string', 'index'=>'int', 'value'=>'string'], 'RedisCluster::lTrim' => ['array', 'key'=>'string', 'start'=>'int', 'stop'=>'int'], 'RedisCluster::mget' => ['array', 'array'=>'array'], 'RedisCluster::mset' => ['bool', 'array'=>'array'], 'RedisCluster::msetnx' => ['int', 'array'=>'array'], 'RedisCluster::multi' => ['Redis', 'mode='=>'int'], 'RedisCluster::object' => ['string', 'string='=>'string', 'key='=>'string'], 'RedisCluster::persist' => ['bool', 'key'=>'string'], 'RedisCluster::pExpire' => ['bool', 'key'=>'string', 'ttl'=>'int'], 'RedisCluster::pExpireAt' => ['bool', 'key'=>'string', 'timestamp'=>'int'], 'RedisCluster::pfAdd' => ['bool', 'key'=>'string', 'elements'=>'array'], 'RedisCluster::pfCount' => ['int', 'key'=>'string'], 'RedisCluster::pfMerge' => ['bool', 'destKey'=>'string', 'sourceKeys'=>'array'], 'RedisCluster::ping' => ['string', 'nodeParams'=>'string'], 'RedisCluster::psetex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'], 'RedisCluster::psubscribe' => ['mixed', 'patterns'=>'array', 'callback'=>'string'], 'RedisCluster::pttl' => ['int', 'key'=>'string'], 'RedisCluster::publish' => ['int', 'channel'=>'string', 'message'=>'string'], 'RedisCluster::pubsub' => ['array', 'nodeParams'=>'string', 'keyword'=>'string', '...argument='=>'string'], 'RedisCluster::punSubscribe' => ['', 'channels'=>'', 'callback'=>''], 'RedisCluster::randomKey' => ['string', 'nodeParams'=>'string'], 'RedisCluster::rawCommand' => ['mixed', 'nodeParams'=>'string', 'command'=>'string', 'arguments'=>'mixed'], 'RedisCluster::rename' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string'], 'RedisCluster::renameNx' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string'], 'RedisCluster::restore' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'], 'RedisCluster::role' => ['array', 'nodeParams'=>'string'], 'RedisCluster::rPop' => ['string', 'key'=>'string'], 'RedisCluster::rpoplpush' => ['string', 'srcKey'=>'string', 'dstKey'=>'string'], 'RedisCluster::rPush' => ['int', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'], 'RedisCluster::rPushx' => ['int', 'key'=>'string', 'value'=>'string'], 'RedisCluster::sAdd' => ['int', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'], 'RedisCluster::sAddArray' => ['int', 'key'=>'string', 'valueArray'=>'array'], 'RedisCluster::save' => ['bool', 'nodeParams'=>'string'], 'RedisCluster::scan' => ['array', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'], 'RedisCluster::sCard' => ['int', 'key'=>'string'], 'RedisCluster::script' => ['mixed', 'nodeParams'=>'string', 'command'=>'string', 'script'=>'string'], 'RedisCluster::sDiff' => ['list', 'key1'=>'string', 'key2'=>'string', '...other_keys='=>'string'], 'RedisCluster::sDiffStore' => ['int', 'dstKey'=>'string', 'key1'=>'string', '...other_keys='=>'string'], 'RedisCluster::set' => ['bool', 'key'=>'string', 'value'=>'string', 'timeout='=>'array|int'], 'RedisCluster::setBit' => ['int', 'key'=>'string', 'offset'=>'int', 'value'=>'bool|int'], 'RedisCluster::setex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'], 'RedisCluster::setnx' => ['bool', 'key'=>'string', 'value'=>'string'], 'RedisCluster::setOption' => ['bool', 'name'=>'int', 'value'=>'mixed'], 'RedisCluster::setRange' => ['string', 'key'=>'string', 'offset'=>'int', 'value'=>'string'], 'RedisCluster::sInter' => ['list', 'key'=>'string', '...other_keys='=>'string'], 'RedisCluster::sInterStore' => ['int', 'dstKey'=>'string', 'key'=>'string', '...other_keys='=>'string'], 'RedisCluster::sIsMember' => ['bool', 'key'=>'string', 'value'=>'string'], 'RedisCluster::slowLog' => ['', 'nodeParams'=>'string', 'command'=>'string', 'argument'=>'mixed', '...other_arguments='=>'mixed'], 'RedisCluster::sMembers' => ['list', 'key'=>'string'], 'RedisCluster::sMove' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string', 'member'=>'string'], 'RedisCluster::sort' => ['array', 'key'=>'string', 'option='=>'array'], 'RedisCluster::sPop' => ['string', 'key'=>'string'], 'RedisCluster::sRandMember' => ['array|string', 'key'=>'string', 'count='=>'int'], 'RedisCluster::sRem' => ['int', 'key'=>'string', 'member1'=>'string', '...other_members='=>'string'], 'RedisCluster::sScan' => ['array', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'null', 'count='=>'int'], 'RedisCluster::strlen' => ['0|positive-int', 'key'=>'string'], 'RedisCluster::subscribe' => ['mixed', 'channels'=>'array', 'callback'=>'string'], 'RedisCluster::sUnion' => ['array', 'key1'=>'string', '...other_keys='=>'string'], 'RedisCluster::sUnionStore' => ['int', 'dstKey'=>'string', 'key1'=>'string', '...other_keys='=>'string'], 'RedisCluster::time' => ['array', 'nodeParams'=>'string'], 'RedisCluster::ttl' => ['int', 'key'=>'string'], 'RedisCluster::type' => ['int', 'key'=>'string'], 'RedisCluster::unlink' => ['int', 'key'=>'string', '...other_keys='=>'string'], 'RedisCluster::unSubscribe' => ['', 'channels'=>'', '...other_channels='=>''], 'RedisCluster::unwatch' => [''], 'RedisCluster::watch' => ['void', 'key'=>'string', '...other_keys='=>'string'], 'RedisCluster::xack' => ['', 'str_key'=>'string', 'str_group'=>'string', 'arr_ids'=>'array'], 'RedisCluster::xadd' => ['', 'str_key'=>'string', 'str_id'=>'string', 'arr_fields'=>'array', 'i_maxlen='=>'', 'boo_approximate='=>''], 'RedisCluster::xclaim' => ['', 'str_key'=>'string', 'str_group'=>'string', 'str_consumer'=>'string', 'i_min_idle'=>'', 'arr_ids'=>'array', 'arr_opts='=>'array'], 'RedisCluster::xdel' => ['', 'str_key'=>'string', 'arr_ids'=>'array'], 'RedisCluster::xgroup' => ['', 'str_operation'=>'string', 'str_key='=>'string', 'str_arg1='=>'', 'str_arg2='=>'', 'str_arg3='=>''], 'RedisCluster::xinfo' => ['', 'str_cmd'=>'string', 'str_key='=>'string', 'str_group='=>'string'], 'RedisCluster::xlen' => ['', 'key'=>''], 'RedisCluster::xpending' => ['', 'str_key'=>'string', 'str_group'=>'string', 'str_start='=>'', 'str_end='=>'', 'i_count='=>'', 'str_consumer='=>'string'], 'RedisCluster::xrange' => ['', 'str_key'=>'string', 'str_start'=>'', 'str_end'=>'', 'i_count='=>''], 'RedisCluster::xread' => ['', 'arr_streams'=>'array', 'i_count='=>'', 'i_block='=>''], 'RedisCluster::xreadgroup' => ['', 'str_group'=>'string', 'str_consumer'=>'string', 'arr_streams'=>'array', 'i_count='=>'', 'i_block='=>''], 'RedisCluster::xrevrange' => ['', 'str_key'=>'string', 'str_start'=>'', 'str_end'=>'', 'i_count='=>''], 'RedisCluster::xtrim' => ['', 'str_key'=>'string', 'i_maxlen'=>'', 'boo_approximate='=>''], 'RedisCluster::zAdd' => ['int', 'key'=>'string', 'score1'=>'float', 'value1'=>'string', 'score2='=>'float', 'value2='=>'string', 'scoreN='=>'float', 'valueN='=>'string'], 'RedisCluster::zCard' => ['int', 'key'=>'string'], 'RedisCluster::zCount' => ['int', 'key'=>'string', 'start'=>'string', 'end'=>'string'], 'RedisCluster::zIncrBy' => ['float', 'key'=>'string', 'value'=>'float', 'member'=>'string'], 'RedisCluster::zInterStore' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'], 'RedisCluster::zLexCount' => ['int', 'key'=>'string', 'min'=>'int', 'max'=>'int'], 'RedisCluster::zRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscores='=>'bool'], 'RedisCluster::zRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int', 'offset='=>'int', 'limit='=>'int'], 'RedisCluster::zRangeByScore' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'options='=>'array'], 'RedisCluster::zRank' => ['int', 'key'=>'string', 'member'=>'string'], 'RedisCluster::zRem' => ['int', 'key'=>'string', 'member1'=>'string', '...other_members='=>'string'], 'RedisCluster::zRemRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int'], 'RedisCluster::zRemRangeByRank' => ['int', 'key'=>'string', 'start'=>'int', 'end'=>'int'], 'RedisCluster::zRemRangeByScore' => ['int', 'key'=>'string', 'start'=>'float|string', 'end'=>'float|string'], 'RedisCluster::zRevRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscore='=>'bool'], 'RedisCluster::zRevRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int', 'offset='=>'int', 'limit='=>'int'], 'RedisCluster::zRevRangeByScore' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'options='=>'array'], 'RedisCluster::zRevRank' => ['int', 'key'=>'string', 'member'=>'string'], 'RedisCluster::zScan' => ['array', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'], 'RedisCluster::zScore' => ['float', 'key'=>'string', 'member'=>'string'], 'RedisCluster::zUnionStore' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'], 'Reflection::export' => ['string|null', 'r'=>'reflector', 'return='=>'bool'], 'Reflection::getModifierNames' => ['array', 'modifiers'=>'int'], 'ReflectionClass::__clone' => ['void'], 'ReflectionClass::__construct' => ['void', 'argument'=>'object|string'], 'ReflectionClass::__toString' => ['string'], 'ReflectionClass::export' => ['string|null', 'argument'=>'string|object', 'return='=>'bool'], 'ReflectionClass::getConstant' => ['mixed', 'name'=>'string'], 'ReflectionClass::getConstants' => ['array'], 'ReflectionClass::getConstructor' => ['ReflectionMethod|null'], 'ReflectionClass::getDefaultProperties' => ['array'], 'ReflectionClass::getDocComment' => ['string|false'], 'ReflectionClass::getEndLine' => ['positive-int|false'], 'ReflectionClass::getExtension' => ['ReflectionExtension|null'], 'ReflectionClass::getExtensionName' => ['string|false'], 'ReflectionClass::getFileName' => ['non-empty-string|false'], 'ReflectionClass::getInterfaceNames' => ['list'], 'ReflectionClass::getInterfaces' => ['array'], 'ReflectionClass::getMethod' => ['ReflectionMethod', 'name'=>'string'], 'ReflectionClass::getMethods' => ['list', 'filter='=>'int'], 'ReflectionClass::getModifiers' => ['int'], 'ReflectionClass::getName' => ['class-string'], 'ReflectionClass::getNamespaceName' => ['string'], 'ReflectionClass::getParentClass' => ['ReflectionClass|false'], 'ReflectionClass::getProperties' => ['list', 'filter='=>'int'], 'ReflectionClass::getProperty' => ['ReflectionProperty', 'name'=>'string'], 'ReflectionClass::getReflectionConstant' => ['ReflectionClassConstant|false', 'name'=>'string'], 'ReflectionClass::getReflectionConstants' => ['list'], 'ReflectionClass::getShortName' => ['string'], 'ReflectionClass::getStartLine' => ['positive-int|false'], 'ReflectionClass::getStaticProperties' => ['array'], 'ReflectionClass::getStaticPropertyValue' => ['mixed', 'name'=>'string', 'default='=>'mixed'], 'ReflectionClass::getTraitAliases' => ['array'], 'ReflectionClass::getTraitNames' => ['list'], 'ReflectionClass::getTraits' => ['array'], 'ReflectionClass::hasConstant' => ['bool', 'name'=>'string'], 'ReflectionClass::hasMethod' => ['bool', 'name'=>'string'], 'ReflectionClass::hasProperty' => ['bool', 'name'=>'string'], 'ReflectionClass::implementsInterface' => ['bool', 'interface_name'=>'string|ReflectionClass'], 'ReflectionClass::inNamespace' => ['bool'], 'ReflectionClass::isAbstract' => ['bool'], 'ReflectionClass::isAnonymous' => ['bool'], 'ReflectionClass::isCloneable' => ['bool'], 'ReflectionClass::isFinal' => ['bool'], 'ReflectionClass::isInstance' => ['bool', 'object'=>'object'], 'ReflectionClass::isInstantiable' => ['bool'], 'ReflectionClass::isInterface' => ['bool'], 'ReflectionClass::isInternal' => ['bool'], 'ReflectionClass::isIterable' => ['bool'], 'ReflectionClass::isIterateable' => ['bool'], 'ReflectionClass::isSubclassOf' => ['bool', 'class'=>'string|ReflectionClass'], 'ReflectionClass::isTrait' => ['bool'], 'ReflectionClass::isUserDefined' => ['bool'], 'ReflectionClass::newInstance' => ['object', 'args='=>'mixed', '...args='=>'mixed'], 'ReflectionClass::newInstanceArgs' => ['object', 'args='=>'array'], 'ReflectionClass::newInstanceWithoutConstructor' => ['object'], 'ReflectionClass::setStaticPropertyValue' => ['void', 'name'=>'string', 'value'=>'mixed'], 'ReflectionClassConstant::__construct' => ['void', 'class'=>'mixed', 'name'=>'string'], 'ReflectionClassConstant::__toString' => ['string'], 'ReflectionClassConstant::export' => ['string', 'class'=>'mixed', 'name'=>'string', 'return='=>'bool'], 'ReflectionClassConstant::getDeclaringClass' => ['ReflectionClass'], 'ReflectionClassConstant::getDocComment' => ['string|false'], 'ReflectionClassConstant::getModifiers' => ['int'], 'ReflectionClassConstant::getName' => ['string'], 'ReflectionClassConstant::getValue' => ['mixed'], 'ReflectionClassConstant::isPrivate' => ['bool'], 'ReflectionClassConstant::isProtected' => ['bool'], 'ReflectionClassConstant::isPublic' => ['bool'], 'ReflectionExtension::__clone' => ['void'], 'ReflectionExtension::__construct' => ['void', 'name'=>'string'], 'ReflectionExtension::__toString' => ['string'], 'ReflectionExtension::export' => ['string|null', 'name'=>'string', 'return='=>'bool'], 'ReflectionExtension::getClasses' => ['array'], 'ReflectionExtension::getClassNames' => ['list'], 'ReflectionExtension::getConstants' => ['array'], 'ReflectionExtension::getDependencies' => ['array'], 'ReflectionExtension::getFunctions' => ['array'], 'ReflectionExtension::getINIEntries' => ['array'], 'ReflectionExtension::getName' => ['string'], 'ReflectionExtension::getVersion' => ['string'], 'ReflectionExtension::info' => ['void'], 'ReflectionExtension::isPersistent' => ['void'], 'ReflectionExtension::isTemporary' => ['bool'], 'ReflectionFunction::__construct' => ['void', 'name'=>'string|Closure'], 'ReflectionFunction::__toString' => ['string'], 'ReflectionFunction::export' => ['string|null', 'name'=>'string', 'return='=>'bool'], 'ReflectionFunction::getClosure' => ['Closure'], 'ReflectionFunction::getClosureScopeClass' => ['ReflectionClass'], 'ReflectionFunction::getClosureThis' => ['bool'], 'ReflectionFunction::getDocComment' => ['string|false'], 'ReflectionFunction::getEndLine' => ['positive-int|false'], 'ReflectionFunction::getExtension' => ['ReflectionExtension|null'], 'ReflectionFunction::getExtensionName' => ['string|false'], 'ReflectionFunction::getFileName' => ['non-empty-string|false'], 'ReflectionFunction::getName' => ['non-empty-string'], 'ReflectionFunction::getNamespaceName' => ['string'], 'ReflectionFunction::getNumberOfParameters' => ['int'], 'ReflectionFunction::getNumberOfRequiredParameters' => ['int'], 'ReflectionFunction::getParameters' => ['list'], 'ReflectionFunction::getReturnType' => ['?ReflectionType'], 'ReflectionFunction::getShortName' => ['string'], 'ReflectionFunction::getStartLine' => ['positive-int|false'], 'ReflectionFunction::getStaticVariables' => ['array'], 'ReflectionFunction::inNamespace' => ['bool'], 'ReflectionFunction::invoke' => ['mixed', '...args='=>'mixed'], 'ReflectionFunction::invokeArgs' => ['mixed', 'args'=>'array'], 'ReflectionFunction::isClosure' => ['bool'], 'ReflectionFunction::isDeprecated' => ['bool'], 'ReflectionFunction::isDisabled' => ['bool'], 'ReflectionFunction::isGenerator' => ['bool'], 'ReflectionFunction::isInternal' => ['bool'], 'ReflectionFunction::isUserDefined' => ['bool'], 'ReflectionFunction::isVariadic' => ['bool'], 'ReflectionFunction::returnsReference' => ['bool'], 'ReflectionFunctionAbstract::__clone' => ['void'], 'ReflectionFunctionAbstract::__toString' => ['string'], 'ReflectionFunctionAbstract::getClosureScopeClass' => ['ReflectionClass|null'], 'ReflectionFunctionAbstract::getClosureThis' => ['object|null'], 'ReflectionFunctionAbstract::getDocComment' => ['string|false'], 'ReflectionFunctionAbstract::getEndLine' => ['positive-int|false'], 'ReflectionFunctionAbstract::getExtension' => ['ReflectionExtension|null'], 'ReflectionFunctionAbstract::getExtensionName' => ['string|false'], 'ReflectionFunctionAbstract::getFileName' => ['non-empty-string|false'], 'ReflectionFunctionAbstract::getName' => ['non-empty-string'], 'ReflectionFunctionAbstract::getNamespaceName' => ['string'], 'ReflectionFunctionAbstract::getNumberOfParameters' => ['int'], 'ReflectionFunctionAbstract::getNumberOfRequiredParameters' => ['int'], 'ReflectionFunctionAbstract::getParameters' => ['list'], 'ReflectionFunctionAbstract::getReturnType' => ['?ReflectionType'], 'ReflectionFunctionAbstract::getShortName' => ['string'], 'ReflectionFunctionAbstract::getStartLine' => ['positive-int|false'], 'ReflectionFunctionAbstract::getStaticVariables' => ['array'], 'ReflectionFunctionAbstract::hasReturnType' => ['bool'], 'ReflectionFunctionAbstract::inNamespace' => ['bool'], 'ReflectionFunctionAbstract::isClosure' => ['bool'], 'ReflectionFunctionAbstract::isDeprecated' => ['bool'], 'ReflectionFunctionAbstract::isGenerator' => ['bool'], 'ReflectionFunctionAbstract::isInternal' => ['bool'], 'ReflectionFunctionAbstract::isUserDefined' => ['bool'], 'ReflectionFunctionAbstract::isVariadic' => ['bool'], 'ReflectionFunctionAbstract::returnsReference' => ['bool'], 'ReflectionGenerator::__construct' => ['void', 'generator'=>'object'], 'ReflectionGenerator::getExecutingFile' => ['string'], 'ReflectionGenerator::getExecutingGenerator' => ['Generator'], 'ReflectionGenerator::getExecutingLine' => ['int'], 'ReflectionGenerator::getFunction' => ['ReflectionFunctionAbstract'], 'ReflectionGenerator::getThis' => ['object'], 'ReflectionGenerator::getTrace' => ['list\',args?:mixed[],object?:object}>', 'options'=>'int'], 'ReflectionMethod::__construct' => ['void', 'class'=>'string|object', 'name'=>'string'], 'ReflectionMethod::__construct\'1' => ['void', 'class_method'=>'string'], 'ReflectionMethod::__toString' => ['string'], 'ReflectionMethod::export' => ['string|null', 'class'=>'string', 'name'=>'string', 'return='=>'bool'], 'ReflectionMethod::getClosure' => ['Closure', 'object'=>'?object'], 'ReflectionMethod::getDeclaringClass' => ['ReflectionClass'], 'ReflectionMethod::getModifiers' => ['int'], 'ReflectionMethod::getPrototype' => ['ReflectionMethod'], 'ReflectionMethod::invoke' => ['mixed', 'object'=>'?object', '...args='=>'mixed'], 'ReflectionMethod::invokeArgs' => ['mixed', 'object'=>'?object', 'args'=>'array'], 'ReflectionMethod::isAbstract' => ['bool'], 'ReflectionMethod::isConstructor' => ['bool'], 'ReflectionMethod::isDestructor' => ['bool'], 'ReflectionMethod::isFinal' => ['bool'], 'ReflectionMethod::isPrivate' => ['bool'], 'ReflectionMethod::isProtected' => ['bool'], 'ReflectionMethod::isPublic' => ['bool'], 'ReflectionMethod::isStatic' => ['bool'], 'ReflectionMethod::setAccessible' => ['void', 'visible'=>'bool'], 'ReflectionNamedType::__toString' => ['string'], 'ReflectionNamedType::allowsNull' => ['bool'], 'ReflectionNamedType::getName' => ['string'], 'ReflectionNamedType::isBuiltin' => ['bool'], 'ReflectionObject::__construct' => ['void', 'argument'=>'object'], 'ReflectionObject::export' => ['string|null', 'argument'=>'object', 'return='=>'bool'], 'ReflectionParameter::__clone' => ['void'], 'ReflectionParameter::__construct' => ['void', 'function'=>'', 'parameter'=>''], 'ReflectionParameter::__toString' => ['string'], 'ReflectionParameter::allowsNull' => ['bool'], 'ReflectionParameter::canBePassedByValue' => ['bool'], 'ReflectionParameter::export' => ['string|null', 'function'=>'string', 'parameter'=>'string', 'return='=>'bool'], 'ReflectionParameter::getClass' => ['ReflectionClass|null'], 'ReflectionParameter::getDeclaringClass' => ['ReflectionClass|null'], 'ReflectionParameter::getDeclaringFunction' => ['ReflectionFunctionAbstract'], 'ReflectionParameter::getDefaultValue' => ['mixed'], 'ReflectionParameter::getDefaultValueConstantName' => ['?string'], 'ReflectionParameter::getName' => ['non-empty-string'], 'ReflectionParameter::getPosition' => ['int'], 'ReflectionParameter::getType' => ['ReflectionType|null'], 'ReflectionParameter::hasType' => ['bool'], 'ReflectionParameter::isArray' => ['bool'], 'ReflectionParameter::isCallable' => ['bool'], 'ReflectionParameter::isDefaultValueAvailable' => ['bool'], 'ReflectionParameter::isDefaultValueConstant' => ['bool'], 'ReflectionParameter::isOptional' => ['bool'], 'ReflectionParameter::isPassedByReference' => ['bool'], 'ReflectionParameter::isVariadic' => ['bool'], 'ReflectionProperty::__clone' => ['void'], 'ReflectionProperty::__construct' => ['void', 'class'=>'', 'name'=>'string'], 'ReflectionProperty::__toString' => ['string'], 'ReflectionProperty::export' => ['string|null', 'class'=>'mixed', 'name'=>'string', 'return='=>'bool'], 'ReflectionProperty::getDeclaringClass' => ['ReflectionClass'], 'ReflectionProperty::getDocComment' => ['string|false'], 'ReflectionProperty::getModifiers' => ['int'], 'ReflectionProperty::getName' => ['non-empty-string'], 'ReflectionProperty::getValue' => ['mixed', 'object='=>'object'], 'ReflectionProperty::isDefault' => ['bool'], 'ReflectionProperty::isPrivate' => ['bool'], 'ReflectionProperty::isProtected' => ['bool'], 'ReflectionProperty::isPublic' => ['bool'], 'ReflectionProperty::isStatic' => ['bool'], 'ReflectionProperty::setAccessible' => ['void', 'visible'=>'bool'], 'ReflectionProperty::setValue' => ['void', 'object'=>'null|object', 'value'=>''], 'ReflectionProperty::setValue\'1' => ['void', 'value'=>''], 'ReflectionType::__toString' => ['string'], 'ReflectionType::allowsNull' => ['bool'], 'ReflectionType::isBuiltin' => ['bool'], 'ReflectionZendExtension::__clone' => ['void'], 'ReflectionZendExtension::__construct' => ['void', 'name'=>'string'], 'ReflectionZendExtension::__toString' => ['string'], 'ReflectionZendExtension::export' => ['string|null', 'name'=>'string', 'return='=>'bool'], 'ReflectionZendExtension::getAuthor' => ['string'], 'ReflectionZendExtension::getCopyright' => ['string'], 'ReflectionZendExtension::getName' => ['string'], 'ReflectionZendExtension::getURL' => ['string'], 'ReflectionZendExtension::getVersion' => ['string'], 'Reflector::__toString' => ['string'], 'Reflector::export' => ['?string'], 'RegexIterator::__construct' => ['void', 'iterator'=>'Iterator', 'regex'=>'string', 'mode='=>'int', 'flags='=>'int', 'preg_flags='=>'int'], 'RegexIterator::accept' => ['bool'], 'RegexIterator::getFlags' => ['int'], 'RegexIterator::getMode' => ['int'], 'RegexIterator::getPregFlags' => ['int'], 'RegexIterator::getRegex' => ['string'], 'RegexIterator::setFlags' => ['bool', 'new_flags'=>'int'], 'RegexIterator::setMode' => ['bool', 'new_mode'=>'int'], 'RegexIterator::setPregFlags' => ['bool', 'new_flags'=>'int'], 'register_event_handler' => ['bool', 'event_handler_func'=>'event_handler_func', 'handler_register_name'=>'handler_register_name', 'event_type_mask'=>'event_type_mask'], 'register_shutdown_function' => ['void', 'function'=>'callable', '...parameter='=>'mixed'], 'register_tick_function' => ['bool', 'function'=>'callable(): void', '...args='=>'mixed'], 'rename' => ['bool', 'old_name'=>'string', 'new_name'=>'string', 'context='=>'resource'], 'rename_function' => ['bool', 'original_name'=>'string', 'new_name'=>'string'], 'reset' => ['mixed', '&rw_array'=>'array|object'], 'ResourceBundle::__construct' => ['void', 'locale'=>'string', 'bundlename'=>'string', 'fallback='=>'bool'], 'ResourceBundle::count' => ['0|positive-int'], 'ResourceBundle::create' => ['?ResourceBundle', 'locale'=>'string', 'bundlename'=>'string', 'fallback='=>'bool'], 'ResourceBundle::get' => ['', 'index'=>'string|int', 'fallback='=>'bool'], 'ResourceBundle::getErrorCode' => ['int'], 'ResourceBundle::getErrorMessage' => ['string'], 'ResourceBundle::getLocales' => ['array', 'bundlename'=>'string'], 'resourcebundle_count' => ['int', 'r'=>'resourcebundle'], 'resourcebundle_create' => ['?ResourceBundle', 'locale'=>'string', 'bundlename'=>'string', 'fallback='=>'bool'], 'resourcebundle_get' => ['', 'r'=>'resourcebundle', 'index'=>'string|int', 'fallback='=>'bool'], 'resourcebundle_get_error_code' => ['int', 'r'=>'resourcebundle'], 'resourcebundle_get_error_message' => ['string', 'r'=>'resourcebundle'], 'resourcebundle_locales' => ['array|false', 'bundlename'=>'string'], 'restore_error_handler' => ['true'], 'restore_exception_handler' => ['true'], 'restore_include_path' => ['void'], 'rewind' => ['bool', 'fp'=>'resource'], 'rewinddir' => ['null|false', 'dir_handle='=>'resource'], 'rmdir' => ['bool', 'dirname'=>'string', 'context='=>'resource'], 'round' => ['__benevolent', 'number'=>'float', 'precision='=>'int', 'mode='=>'1|2|3|4'], 'rpm_close' => ['bool', 'rpmr'=>'resource'], 'rpm_get_tag' => ['mixed', 'rpmr'=>'resource', 'tagnum'=>'int'], 'rpm_is_valid' => ['bool', 'filename'=>'string'], 'rpm_open' => ['resource|false', 'filename'=>'string'], 'rpm_version' => ['string'], 'rrd_create' => ['bool', 'filename'=>'string', 'options'=>'array'], 'rrd_error' => ['string'], 'rrd_fetch' => ['array', 'filename'=>'string', 'options'=>'array'], 'rrd_first' => ['int', 'file'=>'string', 'raaindex='=>'int'], 'rrd_graph' => ['array', 'filename'=>'string', 'options'=>'array'], 'rrd_info' => ['array', 'filename'=>'string'], 'rrd_last' => ['int', 'filename'=>'string'], 'rrd_lastupdate' => ['array', 'filename'=>'string'], 'rrd_restore' => ['bool', 'xml_file'=>'string', 'rrd_file'=>'string', 'options='=>'array'], 'rrd_tune' => ['bool', 'filename'=>'string', 'options'=>'array'], 'rrd_update' => ['bool', 'filename'=>'string', 'options'=>'array'], 'rrd_version' => ['string'], 'rrd_xport' => ['array', 'options'=>'array'], 'rrdc_disconnect' => ['void'], 'RRDCreator::__construct' => ['void', 'path'=>'string', 'starttime='=>'string', 'step='=>'int'], 'RRDCreator::addArchive' => ['void', 'description'=>'string'], 'RRDCreator::addDataSource' => ['void', 'description'=>'string'], 'RRDCreator::save' => ['bool'], 'RRDGraph::__construct' => ['void', 'path'=>'string'], 'RRDGraph::save' => ['array'], 'RRDGraph::saveVerbose' => ['array'], 'RRDGraph::setOptions' => ['void', 'options'=>'array'], 'RRDUpdater::__construct' => ['void', 'path'=>'string'], 'RRDUpdater::update' => ['bool', 'values'=>'array', 'time='=>'string'], 'rsort' => ['bool', '&rw_array_arg'=>'array', 'sort_flags='=>'int'], 'rtrim' => ['string', 'str'=>'string', 'character_mask='=>'string'], 'runkit_class_adopt' => ['bool', 'classname'=>'string', 'parentname'=>'string'], 'runkit_class_emancipate' => ['bool', 'classname'=>'string'], 'runkit_constant_add' => ['bool', 'constname'=>'string', 'value'=>'mixed'], 'runkit_constant_redefine' => ['bool', 'constname'=>'string', 'newvalue'=>'mixed'], 'runkit_constant_remove' => ['bool', 'constname'=>'string'], 'runkit_function_add' => ['bool', 'funcname'=>'string', 'arglist'=>'string', 'code'=>'string', 'doccomment='=>'?string'], 'runkit_function_add\'1' => ['bool', 'funcname'=>'string', 'closure'=>'Closure', 'doccomment='=>'?string'], 'runkit_function_copy' => ['bool', 'funcname'=>'string', 'targetname'=>'string'], 'runkit_function_redefine' => ['bool', 'funcname'=>'string', 'arglist'=>'string', 'code'=>'string', 'doccomment='=>'?string'], 'runkit_function_redefine\'1' => ['bool', 'funcname'=>'string', 'closure'=>'Closure', 'doccomment='=>'?string'], 'runkit_function_remove' => ['bool', 'funcname'=>'string'], 'runkit_function_rename' => ['bool', 'funcname'=>'string', 'newname'=>'string'], 'runkit_import' => ['bool', 'filename'=>'string', 'flags='=>'int'], 'runkit_lint' => ['bool', 'code'=>'string'], 'runkit_lint_file' => ['bool', 'filename'=>'string'], 'runkit_method_add' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int', 'doccomment='=>'?string'], 'runkit_method_add\'1' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'closure'=>'Closure', 'flags='=>'int', 'doccomment='=>'?string'], 'runkit_method_copy' => ['bool', 'dclass'=>'string', 'dmethod'=>'string', 'sclass'=>'string', 'smethod='=>'string'], 'runkit_method_redefine' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int', 'doccomment='=>'?string'], 'runkit_method_redefine\'1' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'closure'=>'Closure', 'flags='=>'int', 'doccomment='=>'?string'], 'runkit_method_remove' => ['bool', 'classname'=>'string', 'methodname'=>'string'], 'runkit_method_rename' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'newname'=>'string'], 'runkit_return_value_used' => ['bool'], 'Runkit_Sandbox::__construct' => ['void', 'options='=>'array'], 'runkit_sandbox_output_handler' => ['mixed', 'sandbox'=>'object', 'callback='=>'mixed'], 'Runkit_Sandbox_Parent' => [''], 'Runkit_Sandbox_Parent::__construct' => ['void'], 'runkit_superglobals' => ['array'], 'RuntimeException::__clone' => ['void'], 'RuntimeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?RuntimeException)'], 'RuntimeException::__toString' => ['string'], 'RuntimeException::getCode' => ['int'], 'RuntimeException::getFile' => ['string'], 'RuntimeException::getLine' => ['int'], 'RuntimeException::getMessage' => ['string'], 'RuntimeException::getPrevious' => ['Throwable|RuntimeException|null'], 'RuntimeException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'RuntimeException::getTraceAsString' => ['string'], 'SAMConnection::commit' => ['bool'], 'SAMConnection::connect' => ['bool', 'protocol'=>'string', 'properties='=>'array'], 'SAMConnection::disconnect' => ['bool'], 'SAMConnection::errno' => ['int'], 'SAMConnection::error' => ['string'], 'SAMConnection::isConnected' => ['bool'], 'SAMConnection::peek' => ['SAMMessage', 'target'=>'string', 'properties='=>'array'], 'SAMConnection::peekAll' => ['array', 'target'=>'string', 'properties='=>'array'], 'SAMConnection::receive' => ['SAMMessage', 'target'=>'string', 'properties='=>'array'], 'SAMConnection::remove' => ['SAMMessage', 'target'=>'string', 'properties='=>'array'], 'SAMConnection::rollback' => ['bool'], 'SAMConnection::send' => ['string', 'target'=>'string', 'msg'=>'sammessage', 'properties='=>'array'], 'SAMConnection::setDebug' => ['', 'switch'=>'bool'], 'SAMConnection::subscribe' => ['string', 'targettopic'=>'string'], 'SAMConnection::unsubscribe' => ['bool', 'subscriptionid'=>'string', 'targettopic='=>'string'], 'SAMMessage::body' => ['string'], 'SAMMessage::header' => ['object'], 'sapi_windows_cp_conv' => ['string', 'in_codepage'=>'int|string', 'out_codepage'=>'int|string', 'subject'=>'string'], 'sapi_windows_cp_get' => ['int'], 'sapi_windows_cp_is_utf8' => ['bool'], 'sapi_windows_cp_set' => ['bool', 'code_page'=>'int'], 'sapi_windows_vt100_support' => ['bool', 'stream'=>'resource', 'enable='=>'bool'], 'SCA::createDataObject' => ['SDO_DataObject', 'type_namespace_uri'=>'string', 'type_name'=>'string'], 'SCA::getService' => ['', 'target'=>'string', 'binding='=>'string', 'config='=>'array'], 'SCA_LocalProxy::createDataObject' => ['SDO_DataObject', 'type_namespace_uri'=>'string', 'type_name'=>'string'], 'SCA_SoapProxy::createDataObject' => ['SDO_DataObject', 'type_namespace_uri'=>'string', 'type_name'=>'string'], 'scalebarObj::convertToString' => ['string'], 'scalebarObj::free' => ['void'], 'scalebarObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], 'scalebarObj::setImageColor' => ['int', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], 'scalebarObj::updateFromString' => ['int', 'snippet'=>'string'], 'scandir' => ['list|false', 'dir'=>'string', 'sorting_order='=>'int', 'context='=>'resource'], 'SDO_DAS_ChangeSummary::beginLogging' => [''], 'SDO_DAS_ChangeSummary::endLogging' => [''], 'SDO_DAS_ChangeSummary::getChangedDataObjects' => ['SDO_List'], 'SDO_DAS_ChangeSummary::getChangeType' => ['int', 'dataobject'=>'sdo_dataobject'], 'SDO_DAS_ChangeSummary::getOldContainer' => ['SDO_DataObject', 'data_object'=>'sdo_dataobject'], 'SDO_DAS_ChangeSummary::getOldValues' => ['SDO_List', 'data_object'=>'sdo_dataobject'], 'SDO_DAS_ChangeSummary::isLogging' => ['bool'], 'SDO_DAS_DataFactory::addPropertyToType' => ['', 'parent_type_namespace_uri'=>'string', 'parent_type_name'=>'string', 'property_name'=>'string', 'type_namespace_uri'=>'string', 'type_name'=>'string', 'options='=>'array'], 'SDO_DAS_DataFactory::addType' => ['', 'type_namespace_uri'=>'string', 'type_name'=>'string', 'options='=>'array'], 'SDO_DAS_DataFactory::getDataFactory' => ['SDO_DAS_DataFactory'], 'SDO_DAS_DataObject::getChangeSummary' => ['SDO_DAS_ChangeSummary'], 'SDO_DAS_Relational::__construct' => ['void', 'database_metadata'=>'array', 'application_root_type='=>'string', 'sdo_containment_references_metadata='=>'array'], 'SDO_DAS_Relational::applyChanges' => ['', 'database_handle'=>'pdo', 'root_data_object'=>'sdodataobject'], 'SDO_DAS_Relational::createRootDataObject' => ['SDODataObject'], 'SDO_DAS_Relational::executePreparedQuery' => ['SDODataObject', 'database_handle'=>'pdo', 'prepared_statement'=>'pdostatement', 'value_list'=>'array', 'column_specifier='=>'array'], 'SDO_DAS_Relational::executeQuery' => ['SDODataObject', 'database_handle'=>'pdo', 'sql_statement'=>'string', 'column_specifier='=>'array'], 'SDO_DAS_Setting::getListIndex' => ['int'], 'SDO_DAS_Setting::getPropertyIndex' => ['int'], 'SDO_DAS_Setting::getPropertyName' => ['string'], 'SDO_DAS_Setting::getValue' => [''], 'SDO_DAS_Setting::isSet' => ['bool'], 'SDO_DAS_XML::addTypes' => ['', 'xsd_file'=>'string'], 'SDO_DAS_XML::create' => ['SDO_DAS_XML', 'xsd_file='=>'mixed', 'key='=>'string'], 'SDO_DAS_XML::createDataObject' => ['SDO_DataObject', 'namespace_uri'=>'string', 'type_name'=>'string'], 'SDO_DAS_XML::createDocument' => ['SDO_DAS_XML_Document', 'document_element_name'=>'string', 'document_element_namespace_uri'=>'string', 'dataobject='=>'sdo_dataobject'], 'SDO_DAS_XML::loadFile' => ['SDO_XMLDocument', 'xml_file'=>'string'], 'SDO_DAS_XML::loadString' => ['SDO_DAS_XML_Document', 'xml_string'=>'string'], 'SDO_DAS_XML::saveFile' => ['', 'xdoc'=>'sdo_xmldocument', 'xml_file'=>'string', 'indent='=>'int'], 'SDO_DAS_XML::saveString' => ['string', 'xdoc'=>'sdo_xmldocument', 'indent='=>'int'], 'SDO_DAS_XML_Document::getRootDataObject' => ['SDO_DataObject'], 'SDO_DAS_XML_Document::getRootElementName' => ['string'], 'SDO_DAS_XML_Document::getRootElementURI' => ['string'], 'SDO_DAS_XML_Document::setEncoding' => ['', 'encoding'=>'string'], 'SDO_DAS_XML_Document::setXMLDeclaration' => ['', 'xmldeclatation'=>'bool'], 'SDO_DAS_XML_Document::setXMLVersion' => ['', 'xmlversion'=>'string'], 'SDO_DataFactory::create' => ['void', 'type_namespace_uri'=>'string', 'type_name'=>'string'], 'SDO_DataObject::clear' => ['void'], 'SDO_DataObject::createDataObject' => ['SDO_DataObject', 'identifier'=>''], 'SDO_DataObject::getContainer' => ['SDO_DataObject'], 'SDO_DataObject::getSequence' => ['SDO_Sequence'], 'SDO_DataObject::getTypeName' => ['string'], 'SDO_DataObject::getTypeNamespaceURI' => ['string'], 'SDO_Exception::getCause' => [''], 'SDO_List::insert' => ['void', 'value'=>'mixed', 'index='=>'int'], 'SDO_Model_Property::getContainingType' => ['SDO_Model_Type'], 'SDO_Model_Property::getDefault' => [''], 'SDO_Model_Property::getName' => ['string'], 'SDO_Model_Property::getType' => ['SDO_Model_Type'], 'SDO_Model_Property::isContainment' => ['bool'], 'SDO_Model_Property::isMany' => ['bool'], 'SDO_Model_ReflectionDataObject::__construct' => ['void', 'data_object'=>'sdo_dataobject'], 'SDO_Model_ReflectionDataObject::export' => ['mixed', 'rdo'=>'sdo_model_reflectiondataobject', 'return='=>'bool'], 'SDO_Model_ReflectionDataObject::getContainmentProperty' => ['SDO_Model_Property'], 'SDO_Model_ReflectionDataObject::getInstanceProperties' => ['array'], 'SDO_Model_ReflectionDataObject::getType' => ['SDO_Model_Type'], 'SDO_Model_Type::getBaseType' => ['SDO_Model_Type'], 'SDO_Model_Type::getName' => ['string'], 'SDO_Model_Type::getNamespaceURI' => ['string'], 'SDO_Model_Type::getProperties' => ['array'], 'SDO_Model_Type::getProperty' => ['SDO_Model_Property', 'identifier'=>''], 'SDO_Model_Type::isAbstractType' => ['bool'], 'SDO_Model_Type::isDataType' => ['bool'], 'SDO_Model_Type::isInstance' => ['bool', 'data_object'=>'sdo_dataobject'], 'SDO_Model_Type::isOpenType' => ['bool'], 'SDO_Model_Type::isSequencedType' => ['bool'], 'SDO_Sequence::getProperty' => ['SDO_Model_Property', 'sequence_index'=>'int'], 'SDO_Sequence::insert' => ['void', 'value'=>'mixed', 'sequenceindex='=>'int', 'propertyidentifier='=>'mixed'], 'SDO_Sequence::move' => ['void', 'toindex'=>'int', 'fromindex'=>'int'], 'SeekableIterator::seek' => ['void', 'position'=>'int'], 'sem_acquire' => ['bool', 'sem_identifier'=>'resource', 'nowait='=>'bool'], 'sem_get' => ['resource|false', 'key'=>'int', 'max_acquire='=>'int', 'perm='=>'int', 'auto_release='=>'int'], 'sem_release' => ['bool', 'sem_identifier'=>'resource'], 'sem_remove' => ['bool', 'sem_identifier'=>'resource'], 'Serializable::serialize' => ['string'], 'Serializable::unserialize' => ['void', 'serialized'=>'string'], 'serialize' => ['string', 'variable'=>'mixed'], 'ServerRequest::withInput' => ['ServerRequest', 'input'=>'mixed'], 'ServerRequest::withoutParams' => ['ServerRequest', 'params'=>'int|string'], 'ServerRequest::withParam' => ['ServerRequest', 'key'=>'int|string', 'val'=>'mixed'], 'ServerRequest::withParams' => ['ServerRequest', 'params'=>'mixed'], 'ServerRequest::withUrl' => ['ServerRequest', 'url'=>'array'], 'ServerResponse::addHeader' => ['void', 'label'=>'string', 'value'=>'string'], 'ServerResponse::date' => ['string', 'date'=>'string|DateTimeInterface'], 'ServerResponse::getHeader' => ['string', 'label'=>'string'], 'ServerResponse::getHeaders' => ['string[]'], 'ServerResponse::getStatus' => ['int'], 'ServerResponse::getVersion' => ['string'], 'ServerResponse::setHeader' => ['void', 'label'=>'string', 'value'=>'string'], 'ServerResponse::setStatus' => ['void', 'status'=>'int'], 'ServerResponse::setVersion' => ['void', 'version'=>'string'], 'session_abort' => ['bool'], 'session_cache_expire' => ['int|false', 'new_cache_expire='=>'int'], 'session_cache_limiter' => ['string|false', 'new_cache_limiter='=>'string'], 'session_commit' => ['bool'], 'session_create_id' => ['string|false', 'prefix='=>'string'], 'session_decode' => ['bool', 'data'=>'string'], 'session_destroy' => ['bool'], 'session_encode' => ['string|false'], 'session_gc' => ['int|false'], 'session_get_cookie_params' => ['array{lifetime:0|positive-int,path:non-falsy-string,domain:string,secure:bool,httponly:bool,samesite:string}'], 'session_id' => ['string|false', 'newid='=>'string'], 'session_is_registered' => ['bool', 'name'=>'string'], 'session_module_name' => ['string|false', 'newname='=>'string'], 'session_name' => ['non-falsy-string|false', 'newname='=>'string'], 'session_pgsql_add_error' => ['bool', 'error_level'=>'int', 'error_message='=>'string'], 'session_pgsql_get_error' => ['array', 'with_error_message='=>'bool'], 'session_pgsql_get_field' => ['string'], 'session_pgsql_reset' => ['bool'], 'session_pgsql_set_field' => ['bool', 'value'=>'string'], 'session_pgsql_status' => ['array'], 'session_regenerate_id' => ['bool', 'delete_old_session='=>'bool'], 'session_register' => ['bool', 'name'=>'mixed', '...args='=>'mixed'], 'session_register_shutdown' => ['void'], 'session_reset' => ['bool'], 'session_save_path' => ['string|false', 'newname='=>'string'], 'session_set_cookie_params' => ['bool', 'lifetime'=>'int', 'path='=>'string', 'domain='=>'?string', 'secure='=>'bool', 'httponly='=>'bool'], 'session_set_cookie_params\'1' => ['bool', 'options'=>'array{lifetime?:int,path?:string,domain?:?string,secure?:bool,httponly?:bool,samesite?:string}'], 'session_set_save_handler' => ['bool', 'open'=>'callable(string,string):bool', 'close'=>'callable():bool', 'read'=>'callable(string):string', 'write'=>'callable(string,string):bool', 'destroy'=>'callable(string):bool', 'gc'=>'callable(string):bool', 'create_sid='=>'callable():string', 'validate_sid='=>'callable(string):bool', 'update_timestamp='=>'callable(string):bool'], 'session_set_save_handler\'1' => ['bool', 'sessionhandler'=>'SessionHandlerInterface', 'register_shutdown='=>'bool'], 'session_start' => ['bool', 'options='=>'array'], 'session_status' => ['PHP_SESSION_NONE|PHP_SESSION_DISABLED|PHP_SESSION_ACTIVE'], 'session_unregister' => ['bool', 'name'=>'string'], 'session_unset' => ['bool'], 'session_write_close' => ['bool'], 'SessionHandler::close' => ['bool'], 'SessionHandler::create_sid' => ['char'], 'SessionHandler::destroy' => ['bool', 'id'=>'string'], 'SessionHandler::gc' => ['int|false', 'maxlifetime'=>'int'], 'SessionHandler::open' => ['bool', 'save_path'=>'string', 'session_name'=>'string'], 'SessionHandler::read' => ['string', 'id'=>'string'], 'SessionHandler::updateTimestamp' => ['bool', 'session_id'=>'string', 'session_data'=>'string'], 'SessionHandler::validateId' => ['bool', 'session_id'=>'string'], 'SessionHandler::write' => ['bool', 'id'=>'string', 'data'=>'string'], 'SessionHandlerInterface::close' => ['bool'], 'SessionHandlerInterface::destroy' => ['bool', 'session_id'=>'string'], 'SessionHandlerInterface::gc' => ['int|false', 'maxlifetime'=>'int'], 'SessionHandlerInterface::open' => ['bool', 'save_path'=>'string', 'name'=>'string'], 'SessionHandlerInterface::read' => ['string', 'session_id'=>'string'], 'SessionHandlerInterface::write' => ['bool', 'session_id'=>'string', 'session_data'=>'string'], 'SessionIdInterface::create_sid' => ['string'], 'SessionUpdateTimestampHandler::updateTimestamp' => ['bool', 'id'=>'string', 'data'=>'string'], 'SessionUpdateTimestampHandler::validateId' => ['char', 'id'=>'string'], 'SessionUpdateTimestampHandlerInterface::updateTimestamp' => ['bool', 'key'=>'string', 'val'=>'string'], 'SessionUpdateTimestampHandlerInterface::validateId' => ['bool', 'key'=>'string'], 'set_error_handler' => ['?callable', 'callback'=>'null|callable(int,string,string,int,array):bool', 'error_types='=>'int'], 'set_exception_handler' => ['null|callable(Throwable):void', 'exception_handler'=>'null|callable(Throwable):void'], 'set_file_buffer' => ['int', 'fp'=>'resource', 'buffer'=>'int'], 'set_include_path' => ['string|false', 'new_include_path'=>'string'], 'set_magic_quotes_runtime' => ['bool', 'new_setting'=>'bool'], 'set_time_limit' => ['bool', 'seconds'=>'int'], 'setcookie' => ['bool', 'name'=>'string', 'value='=>'string', 'expires='=>'int', 'path='=>'string', 'domain='=>'string', 'secure='=>'bool', 'httponly='=>'bool'], 'setcookie\'1' => ['bool', 'name'=>'string', 'value='=>'string', 'options='=>'array{ expires?:int, path?:string, domain?:string, secure?:bool, httponly?:bool, samesite?:\'None\'|\'Lax\'|\'Strict\'|\'none\'|\'lax\'|\'strict\'}'], 'setLeftFill' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'setLine' => ['void', 'width'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'setlocale' => ['string|false', 'category'=>'int', 'locale'=>'string|null', '...args='=>'string'], 'setlocale\'1' => ['string|false', 'category'=>'int', 'locale'=>'?array'], 'setrawcookie' => ['bool', 'name'=>'string', 'value='=>'string', 'expires='=>'int', 'path='=>'string', 'domain='=>'string', 'secure='=>'bool', 'httponly='=>'bool'], 'setrawcookie\'1' => ['bool', 'name'=>'string', 'value='=>'string', 'options='=>'array{ expires?:int, path?:string, domain?:string, secure?:bool, httponly?:bool, samesite?:\'None\'|\'Lax\'|\'Strict\'|\'none\'|\'lax\'|\'strict\'}'], 'setRightFill' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'setthreadtitle' => ['bool', 'title'=>'string'], 'settype' => ['bool', '&rw_var'=>'mixed', 'type'=>'string'], 'sha1' => ['non-falsy-string&lowercase-string', 'str'=>'string', 'raw_output='=>'bool'], 'sha1_file' => ['(non-falsy-string&lowercase-string)|false', 'filename'=>'string', 'raw_output='=>'bool'], 'shapefileObj::__construct' => ['void', 'filename'=>'string', 'type'=>'int'], 'shapefileObj::addPoint' => ['int', 'point'=>'pointObj'], 'shapefileObj::addShape' => ['int', 'shape'=>'shapeObj'], 'shapefileObj::free' => ['void'], 'shapefileObj::getExtent' => ['rectObj', 'i'=>'int'], 'shapefileObj::getPoint' => ['shapeObj', 'i'=>'int'], 'shapefileObj::getShape' => ['shapeObj', 'i'=>'int'], 'shapefileObj::getTransformed' => ['shapeObj', 'map'=>'mapObj', 'i'=>'int'], 'shapefileObj::ms_newShapefileObj' => ['shapefileObj', 'filename'=>'string', 'type'=>'int'], 'shapeObj::__construct' => ['void', 'type'=>'int'], 'shapeObj::add' => ['int', 'line'=>'lineObj'], 'shapeObj::boundary' => ['shapeObj'], 'shapeObj::contains' => ['bool', 'point'=>'pointObj'], 'shapeObj::containsShape' => ['int', 'shape2'=>'shapeObj'], 'shapeObj::convexhull' => ['shapeObj'], 'shapeObj::crosses' => ['int', 'shape'=>'shapeObj'], 'shapeObj::difference' => ['shapeObj', 'shape'=>'shapeObj'], 'shapeObj::disjoint' => ['int', 'shape'=>'shapeObj'], 'shapeObj::draw' => ['int', 'map'=>'mapObj', 'layer'=>'layerObj', 'img'=>'imageObj'], 'shapeObj::equals' => ['int', 'shape'=>'shapeObj'], 'shapeObj::free' => ['void'], 'shapeObj::getArea' => ['float'], 'shapeObj::getCentroid' => ['pointObj'], 'shapeObj::getLabelPoint' => ['pointObj'], 'shapeObj::getLength' => ['float'], 'shapeObj::getPointUsingMeasure' => ['pointObj', 'm'=>'float'], 'shapeObj::getValue' => ['string', 'layer'=>'layerObj', 'filedname'=>'string'], 'shapeObj::intersection' => ['shapeObj', 'shape'=>'shapeObj'], 'shapeObj::intersects' => ['bool', 'shape'=>'shapeObj'], 'shapeObj::line' => ['lineObj', 'i'=>'int'], 'shapeObj::ms_shapeObjFromWkt' => ['shapeObj', 'wkt'=>'string'], 'shapeObj::overlaps' => ['int', 'shape'=>'shapeObj'], 'shapeObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'], 'shapeObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], 'shapeObj::setBounds' => ['int'], 'shapeObj::simplify' => ['shapeObj', 'tolerance'=>'float'], 'shapeObj::symdifference' => ['shapeObj', 'shape'=>'shapeObj'], 'shapeObj::topologyPreservingSimplify' => ['shapeObj', 'tolerance'=>'float'], 'shapeObj::touches' => ['int', 'shape'=>'shapeObj'], 'shapeObj::toWkt' => ['string'], 'shapeObj::union' => ['shapeObj', 'shape'=>'shapeObj'], 'shapeObj::within' => ['int', 'shape2'=>'shapeObj'], 'shell_exec' => ['?string', 'cmd'=>'string'], 'shm_attach' => ['resource|false', 'key'=>'int', 'memsize='=>'int', 'perm='=>'int'], 'shm_detach' => ['bool', 'shm_identifier'=>'resource'], 'shm_get_var' => ['mixed', 'id'=>'resource', 'variable_key'=>'int'], 'shm_has_var' => ['bool', 'shm_identifier'=>'resource', 'variable_key'=>'int'], 'shm_put_var' => ['bool', 'shm_identifier'=>'resource', 'variable_key'=>'int', 'variable'=>'mixed'], 'shm_remove' => ['bool', 'shm_identifier'=>'resource'], 'shm_remove_var' => ['bool', 'shm_identifier'=>'resource', 'variable_key'=>'int'], 'shmop_close' => ['void', 'shmid'=>'resource'], 'shmop_delete' => ['bool', 'shmid'=>'resource'], 'shmop_open' => ['resource|false', 'key'=>'int', 'flags'=>'string', 'mode'=>'int', 'size'=>'int'], 'shmop_read' => ['string', 'shmid'=>'resource', 'start'=>'int', 'count'=>'int'], 'shmop_size' => ['int', 'shmid'=>'resource'], 'shmop_write' => ['int', 'shmid'=>'resource', 'data'=>'string', 'offset'=>'int'], 'show_source' => ['', 'file_name'=>'', 'return'=>''], 'shuffle' => ['bool', '&rw_array_arg'=>'array'], 'signeurlpaiement' => ['string', 'clent'=>'string', 'data'=>'string'], 'similar_text' => ['int', 'str1'=>'string', 'str2'=>'string', '&w_percent='=>'float'], 'simplexml_import_dom' => ['SimpleXMLElement|null', 'node'=>'DOMNode', 'class_name='=>'string'], 'simplexml_load_file' => ['SimpleXMLElement|false', 'filename'=>'string', 'class_name='=>'string', 'options='=>'int', 'ns='=>'string', 'is_prefix='=>'bool'], 'simplexml_load_string' => ['SimpleXMLElement|false', 'data'=>'string', 'class_name='=>'string', 'options='=>'int', 'ns='=>'string', 'is_prefix='=>'bool'], 'SimpleXMLElement::__construct' => ['void', 'data'=>'string', 'options='=>'int', 'data_is_url='=>'bool', 'ns='=>'string', 'is_prefix='=>'bool'], 'SimpleXMLElement::__get' => ['static', 'name'=>'string'], 'SimpleXMLElement::__toString' => ['string'], 'SimpleXMLElement::addAttribute' => ['void', 'name'=>'string', 'value='=>'string', 'ns='=>'string'], 'SimpleXMLElement::addChild' => ['__benevolent', 'name'=>'string', 'value='=>'string|null', 'ns='=>'string|null'], 'SimpleXMLElement::asXML' => ['string|bool', 'filename='=>'string'], 'SimpleXMLElement::attributes' => ['__benevolent', 'ns='=>'string', 'is_prefix='=>'bool'], 'SimpleXMLElement::children' => ['__benevolent', 'namespaceOrPrefix='=>'string|null', 'is_prefix='=>'bool'], 'SimpleXMLElement::count' => ['0|positive-int'], 'SimpleXMLElement::getDocNamespaces' => ['string[]|false', 'recursive='=>'bool', 'from_root='=>'bool'], 'SimpleXMLElement::getName' => ['string'], 'SimpleXMLElement::getNamespaces' => ['string[]', 'recursive='=>'bool'], 'SimpleXMLElement::registerXPathNamespace' => ['bool', 'prefix'=>'string', 'ns'=>'string'], 'SimpleXMLElement::xpath' => ['static[]|false|null', 'path'=>'string'], 'SimpleXMLIterator::current' => ['SimpleXMLIterator'], 'SimpleXMLIterator::getChildren' => ['SimpleXMLIterator'], 'SimpleXMLIterator::hasChildren' => ['bool'], 'SimpleXMLIterator::key' => ['string|false'], 'SimpleXMLIterator::next' => ['void'], 'SimpleXMLIterator::rewind' => ['void'], 'SimpleXMLIterator::valid' => ['bool'], 'sin' => ['float', 'number'=>'float'], 'sinh' => ['float', 'number'=>'float'], 'sizeof' => ['int', 'var'=>'Countable|array', 'mode='=>'int'], 'sleep' => ['int|false', 'seconds'=>'int'], 'snmp2_get' => ['string|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmp2_getnext' => ['string|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmp2_real_walk' => ['array|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmp2_set' => ['bool', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'type'=>'string', 'value'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmp2_walk' => ['array|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmp3_get' => ['string|false', 'host'=>'string', 'sec_name'=>'string', 'sec_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'priv_protocol'=>'string', 'priv_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmp3_getnext' => ['string|false', 'host'=>'string', 'sec_name'=>'string', 'sec_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'priv_protocol'=>'string', 'priv_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmp3_real_walk' => ['array|false', 'host'=>'string', 'sec_name'=>'string', 'sec_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'priv_protocol'=>'string', 'priv_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmp3_set' => ['bool', 'host'=>'string', 'sec_name'=>'string', 'sec_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'priv_protocol'=>'string', 'priv_passphrase'=>'string', 'object_id'=>'string', 'type'=>'string', 'value'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmp3_walk' => ['array|false', 'host'=>'string', 'sec_name'=>'string', 'sec_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'priv_protocol'=>'string', 'priv_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'SNMP::__construct' => ['void', 'version'=>'int', 'hostname'=>'string', 'community'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'SNMP::close' => ['bool'], 'SNMP::get' => ['array|string|false', 'object_id'=>'string|array', 'preserve_keys='=>'bool'], 'SNMP::getErrno' => ['int'], 'SNMP::getError' => ['string'], 'SNMP::getnext' => ['string|array|false', 'object_id'=>'string|array'], 'SNMP::set' => ['bool', 'object_id'=>'string|array', 'type'=>'string|array', 'value'=>'mixed'], 'SNMP::setSecurity' => ['bool', 'sec_level'=>'string', 'auth_protocol='=>'string', 'auth_passphrase='=>'string', 'priv_protocol='=>'string', 'priv_passphrase='=>'string', 'contextname='=>'string', 'contextengineid='=>'string'], 'SNMP::walk' => ['array|false', 'object_id'=>'string', 'suffix_as_key='=>'bool', 'non_repeaters='=>'int', 'max_repetitions='=>'int'], 'snmp_get_quick_print' => ['bool'], 'snmp_get_valueretrieval' => ['int'], 'snmp_read_mib' => ['bool', 'filename'=>'string'], 'snmp_set_enum_print' => ['bool', 'enum_print'=>'int'], 'snmp_set_oid_numeric_print' => ['void', 'oid_format'=>'int'], 'snmp_set_oid_output_format' => ['bool', 'oid_format'=>'int'], 'snmp_set_quick_print' => ['bool', 'quick_print'=>'int'], 'snmp_set_valueretrieval' => ['bool', 'method='=>'int'], 'snmpget' => ['string|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmpgetnext' => ['string|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmprealwalk' => ['array|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmpset' => ['bool', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'type'=>'string', 'value'=>'mixed', 'timeout='=>'int', 'retries='=>'int'], 'snmpwalk' => ['array|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'snmpwalkoid' => ['array|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], 'SoapClient::__call' => ['mixed', 'function_name'=>'string', 'arguments'=>'array'], 'SoapClient::__construct' => ['void', 'wsdl'=>'mixed', 'options='=>'array|null'], 'SoapClient::__doRequest' => ['string|null', 'request'=>'string', 'location'=>'string', 'action'=>'string', 'version'=>'int', 'one_way='=>'int'], 'SoapClient::__getCookies' => ['array'], 'SoapClient::__getFunctions' => ['array|null'], 'SoapClient::__getLastRequest' => ['string|null'], 'SoapClient::__getLastRequestHeaders' => ['string|null'], 'SoapClient::__getLastResponse' => ['string|null'], 'SoapClient::__getLastResponseHeaders' => ['string|null'], 'SoapClient::__getTypes' => ['array|null'], 'SoapClient::__setCookie' => ['', 'name'=>'string', 'value='=>'string'], 'SoapClient::__setLocation' => ['string|null', 'new_location='=>'string'], 'SoapClient::__setSoapHeaders' => ['bool', 'soapheaders='=>''], 'SoapClient::__soapCall' => ['mixed', 'function_name'=>'string', 'arguments'=>'array', 'options='=>'array', 'input_headers='=>'SoapHeader|array', '&w_output_headers='=>'array'], 'SoapClient::SoapClient' => ['object', 'wsdl'=>'mixed', 'options='=>'array|null'], 'SoapFault::__construct' => ['void', 'faultcode'=>'string', 'string'=>'string', 'faultactor='=>'string', 'detail='=>'mixed', 'faultname='=>'string', 'headerfault='=>'mixed'], 'SoapFault::__toString' => ['string'], 'SoapFault::SoapFault' => ['object', 'faultcode'=>'string', 'string'=>'string', 'faultactor='=>'string', 'detail='=>'string', 'faultname='=>'string', 'headerfault='=>'string'], 'SoapHeader::__construct' => ['void', 'namespace'=>'string', 'name'=>'string', 'data='=>'mixed', 'mustunderstand='=>'bool', 'actor='=>'string'], 'SoapHeader::SoapHeader' => ['object', 'namespace'=>'string', 'name'=>'string', 'data='=>'mixed', 'mustunderstand='=>'bool', 'actor='=>'string'], 'SoapParam::__construct' => ['void', 'data'=>'mixed', 'name'=>'string'], 'SoapParam::SoapParam' => ['object', 'data'=>'mixed', 'name'=>'string'], 'SoapServer::__construct' => ['void', 'wsdl'=>'?string', 'options='=>'array'], 'SoapServer::addFunction' => ['void', 'functions'=>'mixed'], 'SoapServer::addSoapHeader' => ['void', 'object'=>'soapheader'], 'SoapServer::fault' => ['void', 'code'=>'string', 'string'=>'string', 'actor='=>'string', 'details='=>'string', 'name='=>'string'], 'SoapServer::getFunctions' => ['array'], 'SoapServer::handle' => ['void', 'soap_request='=>'string'], 'SoapServer::setClass' => ['void', 'class_name'=>'string', '...args='=>'mixed'], 'SoapServer::setObject' => ['void', 'obj'=>'object'], 'SoapServer::setPersistence' => ['void', 'mode'=>'int'], 'SoapServer::SoapServer' => ['object', 'wsdl'=>'?string', 'options='=>'array'], 'SoapVar::__construct' => ['void', 'data'=>'mixed', 'encoding'=>'int', 'type_name='=>'string|null', 'type_namespace='=>'string|null', 'node_name='=>'string|null', 'node_namespace='=>'string|null'], 'SoapVar::SoapVar' => ['object', 'data'=>'mixed', 'encoding'=>'int', 'type_name='=>'string|null', 'type_namespace='=>'string|null', 'node_name='=>'string|null', 'node_namespace='=>'string|null'], 'socket_accept' => ['resource|false', 'socket'=>'resource'], 'socket_addrinfo_bind' => ['resource|null|false', 'addrinfo'=>'resource'], 'socket_addrinfo_connect' => ['resource|null|false', 'addrinfo'=>'resource'], 'socket_addrinfo_explain' => ['array', 'addrinfo'=>'resource'], 'socket_addrinfo_lookup' => ['resource[]|false', 'node'=>'string', 'service='=>'mixed', 'hints='=>'array'], 'socket_bind' => ['bool', 'socket'=>'resource', 'addr'=>'string', 'port='=>'int'], 'socket_clear_error' => ['void', 'socket='=>'resource'], 'socket_close' => ['void', 'socket'=>'resource'], 'socket_cmsg_space' => ['int', 'level'=>'int', 'type'=>'int'], 'socket_connect' => ['bool', 'socket'=>'resource', 'addr'=>'string', 'port='=>'int'], 'socket_create' => ['resource|false', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int'], 'socket_create_listen' => ['resource|false', 'port'=>'int', 'backlog='=>'int'], 'socket_create_pair' => ['bool', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int', '&w_fd'=>'resource[]'], 'socket_export_stream' => ['resource|false', 'socket'=>'resource'], 'socket_get_option' => ['mixed', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int'], 'socket_getopt' => ['mixed', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int'], 'socket_getpeername' => ['bool', 'socket'=>'resource', '&w_addr'=>'string', '&w_port='=>'int'], 'socket_getsockname' => ['bool', 'socket'=>'resource', '&w_addr'=>'string', '&w_port='=>'int'], 'socket_import_stream' => ['resource|false', 'stream'=>'resource'], 'socket_last_error' => ['int', 'socket='=>'resource'], 'socket_listen' => ['bool', 'socket'=>'resource', 'backlog='=>'int'], 'socket_read' => ['string|false', 'socket'=>'resource', 'length'=>'int', 'type='=>'int'], 'socket_recv' => ['int|false', 'socket'=>'resource', '&w_buf'=>'string', 'len'=>'int', 'flags'=>'int'], 'socket_recvfrom' => ['int|false', 'socket'=>'resource', '&w_buf'=>'string', 'len'=>'int', 'flags'=>'int', '&w_name'=>'string', '&w_port='=>'int'], 'socket_recvmsg' => ['int|false', 'socket'=>'resource', '&w_message'=>'string', 'flags='=>'int'], 'socket_select' => ['int|false', '&w_read_fds'=>'resource[]|null', '&w_write_fds'=>'resource[]|null', '&w_except_fds'=>'resource[]|null', 'tv_sec'=>'int|null', 'tv_usec='=>'int|null'], 'socket_send' => ['int|false', 'socket'=>'resource', 'buf'=>'string', 'len'=>'int', 'flags'=>'int'], 'socket_sendmsg' => ['int|false', 'socket'=>'resource', 'message'=>'array', 'flags'=>'int'], 'socket_sendto' => ['int|false', 'socket'=>'resource', 'buf'=>'string', 'len'=>'int', 'flags'=>'int', 'addr'=>'string', 'port='=>'int'], 'socket_set_block' => ['bool', 'socket'=>'resource'], 'socket_set_nonblock' => ['bool', 'socket'=>'resource'], 'socket_set_option' => ['bool', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int', 'optval'=>'int|string|array'], 'socket_shutdown' => ['bool', 'socket'=>'resource', 'how='=>'int'], 'socket_strerror' => ['string', 'errno'=>'int'], 'socket_write' => ['int|false', 'socket'=>'resource', 'buf'=>'string', 'length='=>'int'], 'socket_wsaprotocol_info_export' => ['string|false', 'stream'=>'resource', 'target_pid'=>'int'], 'socket_wsaprotocol_info_import' => ['resource|false', 'id'=>'string'], 'socket_wsaprotocol_info_release' => ['bool', 'id'=>'string'], 'Sodium\add' => ['', '&left'=>'string', 'right'=>'string'], 'Sodium\bin2hex' => ['string', 'binary'=>'string'], 'Sodium\compare' => ['int', 'left'=>'string', 'right'=>'string'], 'Sodium\crypto_aead_aes256gcm_decrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'], 'Sodium\crypto_aead_aes256gcm_encrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'], 'Sodium\crypto_aead_aes256gcm_is_available' => ['bool'], 'Sodium\crypto_aead_chacha20poly1305_decrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'], 'Sodium\crypto_aead_chacha20poly1305_encrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'], 'Sodium\crypto_auth' => ['string', 'msg'=>'string', 'key'=>'string'], 'Sodium\crypto_auth_verify' => ['bool', 'mac'=>'string', 'msg'=>'string', 'key'=>'string'], 'Sodium\crypto_box' => ['string', 'msg'=>'string', 'nonce'=>'string', 'keypair'=>'string'], 'Sodium\crypto_box_keypair' => ['string'], 'Sodium\crypto_box_keypair_from_secretkey_and_publickey' => ['string', 'secretkey'=>'string', 'publickey'=>'string'], 'Sodium\crypto_box_open' => ['string', 'msg'=>'string', 'nonce'=>'string', 'keypair'=>'string'], 'Sodium\crypto_box_publickey' => ['string', 'keypair'=>'string'], 'Sodium\crypto_box_publickey_from_secretkey' => ['string', 'secretkey'=>'string'], 'Sodium\crypto_box_seal' => ['string', 'message'=>'string', 'publickey'=>'string'], 'Sodium\crypto_box_seal_open' => ['string', 'encrypted'=>'string', 'keypair'=>'string'], 'Sodium\crypto_box_secretkey' => ['string', 'keypair'=>'string'], 'Sodium\crypto_box_seed_keypair' => ['string', 'seed'=>'string'], 'Sodium\crypto_generichash' => ['string', 'input'=>'string', 'key='=>'string', 'length='=>'int'], 'Sodium\crypto_generichash_final' => ['string', 'state'=>'string', 'length='=>'int'], 'Sodium\crypto_generichash_init' => ['string', 'key='=>'string', 'length='=>'int'], 'Sodium\crypto_generichash_update' => ['bool', '&hashState'=>'string', 'append'=>'string'], 'Sodium\crypto_kx' => ['string', 'secretkey'=>'string', 'publickey'=>'string', 'client_publickey'=>'string', 'server_publickey'=>'string'], 'Sodium\crypto_pwhash' => ['string', 'out_len'=>'int', 'passwd'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], 'Sodium\crypto_pwhash_scryptsalsa208sha256' => ['string', 'out_len'=>'int', 'passwd'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], 'Sodium\crypto_pwhash_scryptsalsa208sha256_str' => ['string', 'passwd'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], 'Sodium\crypto_pwhash_scryptsalsa208sha256_str_verify' => ['bool', 'hash'=>'string', 'passwd'=>'string'], 'Sodium\crypto_pwhash_str' => ['string', 'passwd'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], 'Sodium\crypto_pwhash_str_verify' => ['bool', 'hash'=>'string', 'passwd'=>'string'], 'Sodium\crypto_scalarmult' => ['string', 'ecdhA'=>'string', 'ecdhB'=>'string'], 'Sodium\crypto_scalarmult_base' => ['string', 'sk'=>'string'], 'Sodium\crypto_secretbox' => ['string', 'plaintext'=>'string', 'nonce'=>'string', 'key'=>'string'], 'Sodium\crypto_secretbox_open' => ['string', 'ciphertext'=>'string', 'nonce'=>'string', 'key'=>'string'], 'Sodium\crypto_shorthash' => ['string', 'message'=>'string', 'key'=>'string'], 'Sodium\crypto_sign' => ['string', 'message'=>'string', 'secretkey'=>'string'], 'Sodium\crypto_sign_detached' => ['string', 'message'=>'string', 'secretkey'=>'string'], 'Sodium\crypto_sign_ed25519_pk_to_curve25519' => ['string', 'sign_pk'=>'string'], 'Sodium\crypto_sign_ed25519_sk_to_curve25519' => ['string', 'sign_sk'=>'string'], 'Sodium\crypto_sign_keypair' => ['string'], 'Sodium\crypto_sign_keypair_from_secretkey_and_publickey' => ['string', 'secretkey'=>'string', 'publickey'=>'string'], 'Sodium\crypto_sign_open' => ['string|false', 'signed_message'=>'string', 'publickey'=>'string'], 'Sodium\crypto_sign_publickey' => ['string', 'keypair'=>'string'], 'Sodium\crypto_sign_publickey_from_secretkey' => ['string', 'secretkey'=>'string'], 'Sodium\crypto_sign_secretkey' => ['string', 'keypair'=>'string'], 'Sodium\crypto_sign_seed_keypair' => ['string', 'seed'=>'string'], 'Sodium\crypto_sign_verify_detached' => ['bool', 'signature'=>'string', 'msg'=>'string', 'publickey'=>'string'], 'Sodium\crypto_stream' => ['string', 'length'=>'int', 'nonce'=>'string', 'key'=>'string'], 'Sodium\crypto_stream_xor' => ['string', 'plaintext'=>'string', 'nonce'=>'string', 'key'=>'string'], 'Sodium\hex2bin' => ['string', 'hex'=>'string'], 'Sodium\increment' => ['string', '&nonce'=>'string'], 'Sodium\library_version_major' => ['int'], 'Sodium\library_version_minor' => ['int'], 'Sodium\memcmp' => ['int', 'left'=>'string', 'right'=>'string'], 'Sodium\memzero' => ['', '&target'=>'string'], 'Sodium\randombytes_buf' => ['string', 'length'=>'int'], 'Sodium\randombytes_random16' => ['int|string'], 'Sodium\randombytes_uniform' => ['int', 'upperBoundNonInclusive'=>'int'], 'Sodium\version_string' => ['string'], 'sodium_add' => ['string', 'string_1'=>'string', 'string_2'=>'string'], 'sodium_base642bin' => ['string', 'base64'=>'string', 'variant'=>'int', 'ignore='=>'string'], 'sodium_bin2base64' => ['string', 'binary'=>'string', 'variant'=>'int'], 'sodium_bin2hex' => ['string', 'binary'=>'string'], 'sodium_compare' => ['int', 'string_1'=>'string', 'string_2'=>'string'], 'sodium_crypto_aead_aes256gcm_decrypt' => ['string|false', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], 'sodium_crypto_aead_aes256gcm_encrypt' => ['string', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], 'sodium_crypto_aead_aes256gcm_is_available' => ['bool'], 'sodium_crypto_aead_aes256gcm_keygen' => ['string'], 'sodium_crypto_aead_chacha20poly1305_decrypt' => ['string|false', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], 'sodium_crypto_aead_chacha20poly1305_encrypt' => ['string', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], 'sodium_crypto_aead_chacha20poly1305_ietf_decrypt' => ['string|false', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], 'sodium_crypto_aead_chacha20poly1305_ietf_encrypt' => ['string', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], 'sodium_crypto_aead_chacha20poly1305_ietf_keygen' => ['string'], 'sodium_crypto_aead_chacha20poly1305_keygen' => ['string'], 'sodium_crypto_aead_xchacha20poly1305_ietf_decrypt' => ['string|false', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], 'sodium_crypto_aead_xchacha20poly1305_ietf_encrypt' => ['string', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], 'sodium_crypto_aead_xchacha20poly1305_ietf_keygen' => ['string'], 'sodium_crypto_auth' => ['string', 'message'=>'string', 'key'=>'string'], 'sodium_crypto_auth_keygen' => ['string'], 'sodium_crypto_auth_verify' => ['bool', 'mac'=>'string', 'message'=>'string', 'key'=>'string'], 'sodium_crypto_box' => ['string', 'string'=>'string', 'nonce'=>'string', 'key'=>'string'], 'sodium_crypto_box_keypair' => ['string'], 'sodium_crypto_box_keypair_from_secretkey_and_publickey' => ['string', 'secret_key'=>'string', 'public_key'=>'string'], 'sodium_crypto_box_open' => ['string|false', 'message'=>'string', 'nonce'=>'string', 'message_keypair'=>'string'], 'sodium_crypto_box_publickey' => ['string', 'keypair'=>'string'], 'sodium_crypto_box_publickey_from_secretkey' => ['string', 'secretkey'=>'string'], 'sodium_crypto_box_seal' => ['string', 'message'=>'string', 'publickey'=>'string'], 'sodium_crypto_box_seal_open' => ['string|false', 'message'=>'string', 'recipient_keypair'=>'string'], 'sodium_crypto_box_secretkey' => ['string', 'keypair'=>'string'], 'sodium_crypto_box_seed_keypair' => ['string', 'seed'=>'string'], 'sodium_crypto_generichash' => ['non-empty-string', 'msg'=>'string', 'key='=>'?string', 'length='=>'?int'], 'sodium_crypto_generichash_final' => ['non-empty-string', 'state'=>'non-empty-string', 'length='=>'?int'], 'sodium_crypto_generichash_init' => ['non-empty-string', 'key='=>'?string', 'length='=>'?int'], 'sodium_crypto_generichash_keygen' => ['non-empty-string'], 'sodium_crypto_generichash_update' => ['bool', 'state'=>'non-empty-string', 'string'=>'string'], 'sodium_crypto_kdf_derive_from_key' => ['string', 'subkey_len'=>'int', 'subkey_id'=>'int', 'context'=>'string', 'key'=>'string'], 'sodium_crypto_kdf_keygen' => ['string'], 'sodium_crypto_kx' => ['string', 'secretkey'=>'string', 'publickey'=>'string', 'client_publickey'=>'string', 'server_publickey'=>'string'], 'sodium_crypto_kx_client_session_keys' => ['array', 'client_keypair'=>'string', 'server_key'=>'string'], 'sodium_crypto_kx_keypair' => ['string'], 'sodium_crypto_kx_publickey' => ['string', 'keypair'=>'string'], 'sodium_crypto_kx_secretkey' => ['string', 'keypair'=>'string'], 'sodium_crypto_kx_seed_keypair' => ['string', 'seed'=>'string'], 'sodium_crypto_kx_server_session_keys' => ['array', 'server_keypair'=>'string', 'client_key'=>'string'], 'sodium_crypto_pwhash' => ['string', 'length'=>'int', 'password'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int', 'alg='=>'int'], 'sodium_crypto_pwhash_scryptsalsa208sha256' => ['string', 'length'=>'int', 'password'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], 'sodium_crypto_pwhash_scryptsalsa208sha256_str' => ['string', 'password'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], 'sodium_crypto_pwhash_scryptsalsa208sha256_str_verify' => ['bool', 'hash'=>'string', 'password'=>'string'], 'sodium_crypto_pwhash_str' => ['string', 'password'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], 'sodium_crypto_pwhash_str_needs_rehash' => ['bool', 'password'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], 'sodium_crypto_pwhash_str_verify' => ['bool', 'hash'=>'string', 'password'=>'string'], 'sodium_crypto_scalarmult' => ['string', 'string_1'=>'string', 'string_2'=>'string'], 'sodium_crypto_scalarmult_base' => ['string', 'key'=>'string'], 'sodium_crypto_secretbox' => ['string', 'plaintext'=>'string', 'nonce'=>'string', 'key'=>'string'], 'sodium_crypto_secretbox_keygen' => ['string'], 'sodium_crypto_secretbox_open' => ['string|false', 'ciphertext'=>'string', 'nonce'=>'string', 'key'=>'string'], 'sodium_crypto_secretstream_xchacha20poly1305_init_pull' => ['string', 'header'=>'string', 'key'=>'string'], 'sodium_crypto_secretstream_xchacha20poly1305_init_push' => ['array', 'key'=>'string'], 'sodium_crypto_secretstream_xchacha20poly1305_keygen' => ['string'], 'sodium_crypto_secretstream_xchacha20poly1305_pull' => ['array|false', 'state'=>'string', 'c'=>'string', 'ad='=>'string'], 'sodium_crypto_secretstream_xchacha20poly1305_push' => ['string', 'state'=>'string', 'msg'=>'string', 'ad='=>'string', 'tag='=>'int'], 'sodium_crypto_secretstream_xchacha20poly1305_rekey' => ['void', 'state'=>'string'], 'sodium_crypto_shorthash' => ['string', 'message'=>'string', 'key'=>'string'], 'sodium_crypto_shorthash_keygen' => ['string'], 'sodium_crypto_sign' => ['non-empty-string', 'message'=>'string', 'secretkey'=>'non-empty-string'], 'sodium_crypto_sign_detached' => ['non-empty-string', 'message'=>'string', 'secretkey'=>'non-empty-string'], 'sodium_crypto_sign_ed25519_pk_to_curve25519' => ['non-empty-string', 'ed25519pk'=>'non-empty-string'], 'sodium_crypto_sign_ed25519_sk_to_curve25519' => ['non-empty-string', 'ed25519sk'=>'non-empty-string'], 'sodium_crypto_sign_keypair' => ['non-empty-string'], 'sodium_crypto_sign_keypair_from_secretkey_and_publickey' => ['non-empty-string', 'secret_key'=>'non-empty-string', 'public_key'=>'non-empty-string'], 'sodium_crypto_sign_open' => ['string|false', 'message'=>'string', 'publickey'=>'non-empty-string'], 'sodium_crypto_sign_publickey' => ['non-empty-string', 'keypair'=>'non-empty-string'], 'sodium_crypto_sign_publickey_from_secretkey' => ['non-empty-string', 'secretkey'=>'non-empty-string'], 'sodium_crypto_sign_secretkey' => ['non-empty-string', 'keypair'=>'non-empty-string'], 'sodium_crypto_sign_seed_keypair' => ['non-empty-string', 'seed'=>'non-empty-string'], 'sodium_crypto_sign_verify_detached' => ['bool', 'signature'=>'non-empty-string', 'message'=>'string', 'publickey'=>'non-empty-string'], 'sodium_crypto_stream' => ['string', 'length'=>'int', 'nonce'=>'string', 'key'=>'string'], 'sodium_crypto_stream_keygen' => ['string'], 'sodium_crypto_stream_xor' => ['string', 'message'=>'string', 'nonce'=>'string', 'key'=>'string'], 'sodium_hex2bin' => ['string', 'hex'=>'string', 'ignore='=>'string'], 'sodium_increment' => ['string', '&binary_string'=>'string'], 'sodium_library_version_major' => ['int'], 'sodium_library_version_minor' => ['int'], 'sodium_memcmp' => ['int', 'string_1'=>'string', 'string_2'=>'string'], 'sodium_memzero' => ['void', '&secret'=>'string'], 'sodium_pad' => ['string', 'unpadded'=>'string', 'length'=>'int'], 'sodium_randombytes_buf' => ['string', 'length'=>'int'], 'sodium_randombytes_random16' => ['int|string'], 'sodium_randombytes_uniform' => ['int', 'upperBoundNonInclusive'=>'int'], 'sodium_unpad' => ['string', 'padded'=>'string', 'length'=>'int'], 'sodium_version_string' => ['string'], 'solid_fetch_prev' => ['bool', 'result_id'=>''], 'solr_get_version' => ['string'], 'SolrClient::__construct' => ['void', 'clientOptions'=>'array'], 'SolrClient::__destruct' => [''], 'SolrClient::addDocument' => ['SolrUpdateResponse', 'doc'=>'solrinputdocument', 'allowdups='=>'bool', 'commitwithin='=>'int'], 'SolrClient::addDocuments' => ['SolrUpdateResponse', 'docs'=>'array', 'allowdups='=>'bool', 'commitwithin='=>'int'], 'SolrClient::commit' => ['SolrUpdateResponse', 'maxsegments='=>'int', 'waitflush='=>'bool', 'waitsearcher='=>'bool'], 'SolrClient::deleteById' => ['SolrUpdateResponse', 'id'=>'string'], 'SolrClient::deleteByIds' => ['SolrUpdateResponse', 'ids'=>'array'], 'SolrClient::deleteByQueries' => ['SolrUpdateResponse', 'queries'=>'array'], 'SolrClient::deleteByQuery' => ['SolrUpdateResponse', 'query'=>'string'], 'SolrClient::getById' => ['SolrQueryResponse', 'id'=>'string'], 'SolrClient::getByIds' => ['SolrQueryResponse', 'ids'=>'array'], 'SolrClient::getDebug' => ['string'], 'SolrClient::getOptions' => ['array'], 'SolrClient::optimize' => ['SolrUpdateResponse', 'maxsegments='=>'int', 'waitflush='=>'bool', 'waitsearcher='=>'bool'], 'SolrClient::ping' => ['SolrPingResponse'], 'SolrClient::query' => ['SolrQueryResponse', 'query'=>'solrparams'], 'SolrClient::request' => ['SolrUpdateResponse', 'raw_request'=>'string'], 'SolrClient::rollback' => ['SolrUpdateResponse'], 'SolrClient::setResponseWriter' => ['void', 'responsewriter'=>'string'], 'SolrClient::setServlet' => ['bool', 'type'=>'int', 'value'=>'string'], 'SolrClient::system' => ['void'], 'SolrClient::threads' => ['void'], 'SolrClientException::getInternalInfo' => ['array'], 'SolrCollapseFunction::__toString' => ['string'], 'SolrCollapseFunction::getField' => ['string'], 'SolrCollapseFunction::getHint' => ['string'], 'SolrCollapseFunction::getMax' => ['string'], 'SolrCollapseFunction::getMin' => ['string'], 'SolrCollapseFunction::getNullPolicy' => ['string'], 'SolrCollapseFunction::getSize' => ['int'], 'SolrCollapseFunction::setField' => ['SolrCollapseFunction', 'fieldName'=>'string'], 'SolrCollapseFunction::setHint' => ['SolrCollapseFunction', 'hint'=>'string'], 'SolrCollapseFunction::setMax' => ['SolrCollapseFunction', 'max'=>'string'], 'SolrCollapseFunction::setMin' => ['SolrCollapseFunction', 'min'=>'string'], 'SolrCollapseFunction::setNullPolicy' => ['SolrCollapseFunction', 'nullPolicy'=>'string'], 'SolrCollapseFunction::setSize' => ['SolrCollapseFunction', 'size'=>'int'], 'SolrDisMaxQuery::__construct' => ['void', 'q='=>'string'], 'SolrDisMaxQuery::addBigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost'=>'string', 'slop='=>'string'], 'SolrDisMaxQuery::addBoostQuery' => ['SolrDisMaxQuery', 'field'=>'string', 'value'=>'string', 'boost='=>'string'], 'SolrDisMaxQuery::addExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'], 'SolrDisMaxQuery::addExpandSortField' => ['SolrQuery', 'field'=>'string', 'order'=>'string'], 'SolrDisMaxQuery::addFacetDateField' => ['SolrQuery', 'dateField'=>'string'], 'SolrDisMaxQuery::addFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::addFacetField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::addFacetQuery' => ['SolrQuery', 'facetQuery'=>'string'], 'SolrDisMaxQuery::addField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::addFilterQuery' => ['SolrQuery', 'fq'=>'string'], 'SolrDisMaxQuery::addGroupField' => ['SolrQuery', 'value'=>'string'], 'SolrDisMaxQuery::addGroupFunction' => ['SolrQuery', 'value'=>'string'], 'SolrDisMaxQuery::addGroupQuery' => ['SolrQuery', 'value'=>'string'], 'SolrDisMaxQuery::addGroupSortField' => ['SolrQuery', 'field'=>'string', 'order'=>'int'], 'SolrDisMaxQuery::addHighlightField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::addMltField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::addMltQueryField' => ['SolrQuery', 'field'=>'string', 'boost'=>'float'], 'SolrDisMaxQuery::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'], 'SolrDisMaxQuery::addPhraseField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost'=>'string', 'slop='=>'string'], 'SolrDisMaxQuery::addQueryField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost='=>'string'], 'SolrDisMaxQuery::addSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'int'], 'SolrDisMaxQuery::addStatsFacet' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::addStatsField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::addTrigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost'=>'string', 'slop='=>'string'], 'SolrDisMaxQuery::addUserField' => ['SolrDisMaxQuery', 'field'=>'string'], 'SolrDisMaxQuery::collapse' => ['SolrQuery', 'collapseFunction'=>'SolrCollapseFunction'], 'SolrDisMaxQuery::get' => ['mixed', 'param_name'=>'string'], 'SolrDisMaxQuery::getExpand' => ['bool'], 'SolrDisMaxQuery::getExpandFilterQueries' => ['array'], 'SolrDisMaxQuery::getExpandQuery' => ['array'], 'SolrDisMaxQuery::getExpandRows' => ['int'], 'SolrDisMaxQuery::getExpandSortFields' => ['array'], 'SolrDisMaxQuery::getFacet' => ['bool'], 'SolrDisMaxQuery::getFacetDateEnd' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getFacetDateFields' => ['array'], 'SolrDisMaxQuery::getFacetDateGap' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getFacetDateHardEnd' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getFacetDateOther' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getFacetDateStart' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getFacetFields' => ['array'], 'SolrDisMaxQuery::getFacetLimit' => ['int', 'field_override'=>'string'], 'SolrDisMaxQuery::getFacetMethod' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getFacetMinCount' => ['int', 'field_override'=>'string'], 'SolrDisMaxQuery::getFacetMissing' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getFacetOffset' => ['int', 'field_override'=>'string'], 'SolrDisMaxQuery::getFacetPrefix' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getFacetQueries' => ['string'], 'SolrDisMaxQuery::getFacetSort' => ['int', 'field_override'=>'string'], 'SolrDisMaxQuery::getFields' => ['string'], 'SolrDisMaxQuery::getFilterQueries' => ['string'], 'SolrDisMaxQuery::getGroup' => ['bool'], 'SolrDisMaxQuery::getGroupCachePercent' => ['int'], 'SolrDisMaxQuery::getGroupFacet' => ['bool'], 'SolrDisMaxQuery::getGroupFields' => ['array'], 'SolrDisMaxQuery::getGroupFormat' => ['string'], 'SolrDisMaxQuery::getGroupFunctions' => ['array'], 'SolrDisMaxQuery::getGroupLimit' => ['int'], 'SolrDisMaxQuery::getGroupMain' => ['bool'], 'SolrDisMaxQuery::getGroupNGroups' => ['bool'], 'SolrDisMaxQuery::getGroupOffset' => ['bool'], 'SolrDisMaxQuery::getGroupQueries' => ['array'], 'SolrDisMaxQuery::getGroupSortFields' => ['array'], 'SolrDisMaxQuery::getGroupTruncate' => ['bool'], 'SolrDisMaxQuery::getHighlight' => ['bool'], 'SolrDisMaxQuery::getHighlightAlternateField' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getHighlightFields' => ['array'], 'SolrDisMaxQuery::getHighlightFormatter' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getHighlightFragmenter' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getHighlightFragsize' => ['int', 'field_override'=>'string'], 'SolrDisMaxQuery::getHighlightHighlightMultiTerm' => ['bool'], 'SolrDisMaxQuery::getHighlightMaxAlternateFieldLength' => ['int', 'field_override'=>'string'], 'SolrDisMaxQuery::getHighlightMaxAnalyzedChars' => ['int'], 'SolrDisMaxQuery::getHighlightMergeContiguous' => ['bool', 'field_override'=>'string'], 'SolrDisMaxQuery::getHighlightRegexMaxAnalyzedChars' => ['int'], 'SolrDisMaxQuery::getHighlightRegexPattern' => ['string'], 'SolrDisMaxQuery::getHighlightRegexSlop' => ['float'], 'SolrDisMaxQuery::getHighlightRequireFieldMatch' => ['bool'], 'SolrDisMaxQuery::getHighlightSimplePost' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getHighlightSimplePre' => ['string', 'field_override'=>'string'], 'SolrDisMaxQuery::getHighlightSnippets' => ['int', 'field_override'=>'string'], 'SolrDisMaxQuery::getHighlightUsePhraseHighlighter' => ['bool'], 'SolrDisMaxQuery::getMlt' => ['bool'], 'SolrDisMaxQuery::getMltBoost' => ['bool'], 'SolrDisMaxQuery::getMltCount' => ['int'], 'SolrDisMaxQuery::getMltFields' => ['array'], 'SolrDisMaxQuery::getMltMaxNumQueryTerms' => ['int'], 'SolrDisMaxQuery::getMltMaxNumTokens' => ['int'], 'SolrDisMaxQuery::getMltMaxWordLength' => ['int'], 'SolrDisMaxQuery::getMltMinDocFrequency' => ['int'], 'SolrDisMaxQuery::getMltMinTermFrequency' => ['int'], 'SolrDisMaxQuery::getMltMinWordLength' => ['int'], 'SolrDisMaxQuery::getMltQueryFields' => ['array'], 'SolrDisMaxQuery::getParam' => ['mixed', 'param_name'=>'string'], 'SolrDisMaxQuery::getParams' => ['array'], 'SolrDisMaxQuery::getPreparedParams' => ['array'], 'SolrDisMaxQuery::getQuery' => ['string'], 'SolrDisMaxQuery::getRows' => ['int'], 'SolrDisMaxQuery::getSortFields' => ['array'], 'SolrDisMaxQuery::getStart' => ['int'], 'SolrDisMaxQuery::getStats' => ['bool'], 'SolrDisMaxQuery::getStatsFacets' => ['array'], 'SolrDisMaxQuery::getStatsFields' => ['array'], 'SolrDisMaxQuery::getTerms' => ['bool'], 'SolrDisMaxQuery::getTermsField' => ['string'], 'SolrDisMaxQuery::getTermsIncludeLowerBound' => ['bool'], 'SolrDisMaxQuery::getTermsIncludeUpperBound' => ['bool'], 'SolrDisMaxQuery::getTermsLimit' => ['int'], 'SolrDisMaxQuery::getTermsLowerBound' => ['string'], 'SolrDisMaxQuery::getTermsMaxCount' => ['int'], 'SolrDisMaxQuery::getTermsMinCount' => ['int'], 'SolrDisMaxQuery::getTermsPrefix' => ['string'], 'SolrDisMaxQuery::getTermsReturnRaw' => ['bool'], 'SolrDisMaxQuery::getTermsSort' => ['int'], 'SolrDisMaxQuery::getTermsUpperBound' => ['string'], 'SolrDisMaxQuery::getTimeAllowed' => ['int'], 'SolrDisMaxQuery::removeBigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeBoostQuery' => ['SolrDisMaxQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'], 'SolrDisMaxQuery::removeExpandSortField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeFacetDateField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::removeFacetField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeFacetQuery' => ['SolrQuery', 'value'=>'string'], 'SolrDisMaxQuery::removeField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeFilterQuery' => ['SolrQuery', 'fq'=>'string'], 'SolrDisMaxQuery::removeHighlightField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeMltField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeMltQueryField' => ['SolrQuery', 'queryField'=>'string'], 'SolrDisMaxQuery::removePhraseField' => ['SolrDisMaxQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeQueryField' => ['SolrDisMaxQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeSortField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeStatsFacet' => ['SolrQuery', 'value'=>'string'], 'SolrDisMaxQuery::removeStatsField' => ['SolrQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeTrigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string'], 'SolrDisMaxQuery::removeUserField' => ['SolrDisMaxQuery', 'field'=>'string'], 'SolrDisMaxQuery::serialize' => ['string'], 'SolrDisMaxQuery::set' => ['SolrParams', 'name'=>'string', 'value'=>''], 'SolrDisMaxQuery::setBigramPhraseFields' => ['SolrDisMaxQuery', 'fields'=>'string'], 'SolrDisMaxQuery::setBigramPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'], 'SolrDisMaxQuery::setBoostFunction' => ['SolrDisMaxQuery', 'function'=>'string'], 'SolrDisMaxQuery::setBoostQuery' => ['SolrDisMaxQuery', 'q'=>'string'], 'SolrDisMaxQuery::setEchoHandler' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setEchoParams' => ['SolrQuery', 'type'=>'string'], 'SolrDisMaxQuery::setExpand' => ['SolrQuery', 'value'=>'bool'], 'SolrDisMaxQuery::setExpandQuery' => ['SolrQuery', 'q'=>'string'], 'SolrDisMaxQuery::setExpandRows' => ['SolrQuery', 'value'=>'int'], 'SolrDisMaxQuery::setExplainOther' => ['SolrQuery', 'query'=>'string'], 'SolrDisMaxQuery::setFacet' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setFacetDateEnd' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::setFacetDateGap' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::setFacetDateHardEnd' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::setFacetDateStart' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::setFacetEnumCacheMinDefaultFrequency' => ['SolrQuery', 'frequency'=>'int', 'field_override'=>'string'], 'SolrDisMaxQuery::setFacetLimit' => ['SolrQuery', 'limit'=>'int', 'field_override'=>'string'], 'SolrDisMaxQuery::setFacetMethod' => ['SolrQuery', 'method'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::setFacetMinCount' => ['SolrQuery', 'mincount'=>'int', 'field_override'=>'string'], 'SolrDisMaxQuery::setFacetMissing' => ['SolrQuery', 'flag'=>'bool', 'field_override'=>'string'], 'SolrDisMaxQuery::setFacetOffset' => ['SolrQuery', 'offset'=>'int', 'field_override'=>'string'], 'SolrDisMaxQuery::setFacetPrefix' => ['SolrQuery', 'prefix'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::setFacetSort' => ['SolrQuery', 'facetSort'=>'int', 'field_override'=>'string'], 'SolrDisMaxQuery::setGroup' => ['SolrQuery', 'value'=>'bool'], 'SolrDisMaxQuery::setGroupCachePercent' => ['SolrQuery', 'percent'=>'int'], 'SolrDisMaxQuery::setGroupFacet' => ['SolrQuery', 'value'=>'bool'], 'SolrDisMaxQuery::setGroupFormat' => ['SolrQuery', 'value'=>'string'], 'SolrDisMaxQuery::setGroupLimit' => ['SolrQuery', 'value'=>'int'], 'SolrDisMaxQuery::setGroupMain' => ['SolrQuery', 'value'=>'string'], 'SolrDisMaxQuery::setGroupNGroups' => ['SolrQuery', 'value'=>'bool'], 'SolrDisMaxQuery::setGroupOffset' => ['SolrQuery', 'value'=>'int'], 'SolrDisMaxQuery::setGroupTruncate' => ['SolrQuery', 'value'=>'bool'], 'SolrDisMaxQuery::setHighlight' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setHighlightAlternateField' => ['SolrQuery', 'field'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::setHighlightFormatter' => ['SolrQuery', 'formatter'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::setHighlightFragmenter' => ['SolrQuery', 'fragmenter'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::setHighlightFragsize' => ['SolrQuery', 'size'=>'int', 'field_override'=>'string'], 'SolrDisMaxQuery::setHighlightHighlightMultiTerm' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setHighlightMaxAlternateFieldLength' => ['SolrQuery', 'fieldLength'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::setHighlightMaxAnalyzedChars' => ['SolrQuery', 'value'=>'int'], 'SolrDisMaxQuery::setHighlightMergeContiguous' => ['SolrQuery', 'flag'=>'bool', 'field_override'=>'string'], 'SolrDisMaxQuery::setHighlightRegexMaxAnalyzedChars' => ['SolrQuery', 'maxAnalyzedChars'=>'int'], 'SolrDisMaxQuery::setHighlightRegexPattern' => ['SolrQuery', 'value'=>'string'], 'SolrDisMaxQuery::setHighlightRegexSlop' => ['SolrQuery', 'factor'=>'float'], 'SolrDisMaxQuery::setHighlightRequireFieldMatch' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setHighlightSimplePost' => ['SolrQuery', 'simplePost'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::setHighlightSimplePre' => ['SolrQuery', 'simplePre'=>'string', 'field_override'=>'string'], 'SolrDisMaxQuery::setHighlightSnippets' => ['SolrQuery', 'value'=>'int', 'field_override'=>'string'], 'SolrDisMaxQuery::setHighlightUsePhraseHighlighter' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setMinimumMatch' => ['SolrDisMaxQuery', 'value'=>'string'], 'SolrDisMaxQuery::setMlt' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setMltBoost' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setMltCount' => ['SolrQuery', 'count'=>'int'], 'SolrDisMaxQuery::setMltMaxNumQueryTerms' => ['SolrQuery', 'value'=>'int'], 'SolrDisMaxQuery::setMltMaxNumTokens' => ['SolrQuery', 'value'=>'int'], 'SolrDisMaxQuery::setMltMaxWordLength' => ['SolrQuery', 'maxWordLength'=>'int'], 'SolrDisMaxQuery::setMltMinDocFrequency' => ['SolrQuery', 'minDocFrequency'=>'int'], 'SolrDisMaxQuery::setMltMinTermFrequency' => ['SolrQuery', 'minTermFrequency'=>'int'], 'SolrDisMaxQuery::setMltMinWordLength' => ['SolrQuery', 'minWordLength'=>'int'], 'SolrDisMaxQuery::setOmitHeader' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setParam' => ['SolrParams', 'name'=>'string', 'value'=>''], 'SolrDisMaxQuery::setPhraseFields' => ['SolrDisMaxQuery', 'fields'=>'string'], 'SolrDisMaxQuery::setPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'], 'SolrDisMaxQuery::setQuery' => ['SolrQuery', 'query'=>'string'], 'SolrDisMaxQuery::setQueryAlt' => ['SolrDisMaxQuery', 'q'=>'string'], 'SolrDisMaxQuery::setQueryPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'], 'SolrDisMaxQuery::setRows' => ['SolrQuery', 'rows'=>'int'], 'SolrDisMaxQuery::setShowDebugInfo' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setStart' => ['SolrQuery', 'start'=>'int'], 'SolrDisMaxQuery::setStats' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setTerms' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setTermsField' => ['SolrQuery', 'fieldname'=>'string'], 'SolrDisMaxQuery::setTermsIncludeLowerBound' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setTermsIncludeUpperBound' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setTermsLimit' => ['SolrQuery', 'limit'=>'int'], 'SolrDisMaxQuery::setTermsLowerBound' => ['SolrQuery', 'lowerBound'=>'string'], 'SolrDisMaxQuery::setTermsMaxCount' => ['SolrQuery', 'frequency'=>'int'], 'SolrDisMaxQuery::setTermsMinCount' => ['SolrQuery', 'frequency'=>'int'], 'SolrDisMaxQuery::setTermsPrefix' => ['SolrQuery', 'prefix'=>'string'], 'SolrDisMaxQuery::setTermsReturnRaw' => ['SolrQuery', 'flag'=>'bool'], 'SolrDisMaxQuery::setTermsSort' => ['SolrQuery', 'sortType'=>'int'], 'SolrDisMaxQuery::setTermsUpperBound' => ['SolrQuery', 'upperBound'=>'string'], 'SolrDisMaxQuery::setTieBreaker' => ['SolrDisMaxQuery', 'tieBreaker'=>'string'], 'SolrDisMaxQuery::setTimeAllowed' => ['SolrQuery', 'timeAllowed'=>'int'], 'SolrDisMaxQuery::setTrigramPhraseFields' => ['SolrDisMaxQuery', 'fields'=>'string'], 'SolrDisMaxQuery::setTrigramPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'], 'SolrDisMaxQuery::setUserFields' => ['SolrDisMaxQuery', 'fields'=>'string'], 'SolrDisMaxQuery::toString' => ['string', 'url_encode='=>'bool|false'], 'SolrDisMaxQuery::unserialize' => ['void', 'serialized'=>'string'], 'SolrDisMaxQuery::useDisMaxQueryParser' => ['SolrDisMaxQuery'], 'SolrDisMaxQuery::useEDisMaxQueryParser' => ['SolrDisMaxQuery'], 'SolrDocument::__clone' => ['void'], 'SolrDocument::__construct' => ['void'], 'SolrDocument::__destruct' => [''], 'SolrDocument::__get' => ['SolrDocumentField', 'fieldname'=>'string'], 'SolrDocument::__isset' => ['bool', 'fieldname'=>'string'], 'SolrDocument::__set' => ['bool', 'fieldname'=>'string', 'fieldvalue'=>'string'], 'SolrDocument::__unset' => ['bool', 'fieldname'=>'string'], 'SolrDocument::addField' => ['bool', 'fieldname'=>'string', 'fieldvalue'=>'string'], 'SolrDocument::clear' => ['bool'], 'SolrDocument::current' => ['SolrDocumentField'], 'SolrDocument::deleteField' => ['bool', 'fieldname'=>'string'], 'SolrDocument::fieldExists' => ['bool', 'fieldname'=>'string'], 'SolrDocument::getChildDocuments' => ['array'], 'SolrDocument::getChildDocumentsCount' => ['int'], 'SolrDocument::getField' => ['SolrDocumentField', 'fieldname'=>'string'], 'SolrDocument::getFieldCount' => ['int'], 'SolrDocument::getFieldNames' => ['array'], 'SolrDocument::getInputDocument' => ['SolrInputDocument'], 'SolrDocument::hasChildDocuments' => ['bool'], 'SolrDocument::key' => ['string'], 'SolrDocument::merge' => ['bool', 'sourcedoc'=>'solrdocument', 'overwrite='=>'bool'], 'SolrDocument::next' => ['void'], 'SolrDocument::offsetExists' => ['bool', 'fieldname'=>'string'], 'SolrDocument::offsetGet' => ['SolrDocumentField', 'fieldname'=>'string'], 'SolrDocument::offsetSet' => ['void', 'fieldname'=>'string', 'fieldvalue'=>'string'], 'SolrDocument::offsetUnset' => ['void', 'fieldname'=>'string'], 'SolrDocument::reset' => ['bool'], 'SolrDocument::rewind' => ['void'], 'SolrDocument::serialize' => ['string'], 'SolrDocument::sort' => ['bool', 'sortorderby'=>'int', 'sortdirection='=>'int'], 'SolrDocument::toArray' => ['array'], 'SolrDocument::unserialize' => ['void', 'serialized'=>'string'], 'SolrDocument::valid' => ['bool'], 'SolrDocumentField::__construct' => ['void'], 'SolrDocumentField::__destruct' => [''], 'SolrException::__clone' => ['void'], 'SolrException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Exception)|(?Throwable)'], 'SolrException::__toString' => ['string'], 'SolrException::__wakeup' => ['void'], 'SolrException::getCode' => ['int'], 'SolrException::getFile' => ['string'], 'SolrException::getInternalInfo' => ['array'], 'SolrException::getLine' => ['int'], 'SolrException::getMessage' => ['string'], 'SolrException::getPrevious' => ['Exception|Throwable'], 'SolrException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'SolrException::getTraceAsString' => ['string'], 'SolrGenericResponse::__construct' => ['void'], 'SolrGenericResponse::__destruct' => [''], 'SolrGenericResponse::getDigestedResponse' => ['string'], 'SolrGenericResponse::getHttpStatus' => ['int'], 'SolrGenericResponse::getHttpStatusMessage' => ['string'], 'SolrGenericResponse::getRawRequest' => ['string'], 'SolrGenericResponse::getRawRequestHeaders' => ['string'], 'SolrGenericResponse::getRawResponse' => ['string'], 'SolrGenericResponse::getRawResponseHeaders' => ['string'], 'SolrGenericResponse::getRequestUrl' => ['string'], 'SolrGenericResponse::getResponse' => ['SolrObject'], 'SolrGenericResponse::setParseMode' => ['bool', 'parser_mode='=>'int'], 'SolrGenericResponse::success' => ['bool'], 'SolrIllegalArgumentException::__clone' => ['void'], 'SolrIllegalArgumentException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Exception)|(?Throwable)'], 'SolrIllegalArgumentException::__toString' => ['string'], 'SolrIllegalArgumentException::__wakeup' => ['void'], 'SolrIllegalArgumentException::getCode' => ['int'], 'SolrIllegalArgumentException::getFile' => ['string'], 'SolrIllegalArgumentException::getInternalInfo' => ['array'], 'SolrIllegalArgumentException::getLine' => ['int'], 'SolrIllegalArgumentException::getMessage' => ['string'], 'SolrIllegalArgumentException::getPrevious' => ['Exception|Throwable'], 'SolrIllegalArgumentException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'SolrIllegalArgumentException::getTraceAsString' => ['string'], 'SolrIllegalOperationException::__clone' => ['void'], 'SolrIllegalOperationException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Exception)|(?Throwable)'], 'SolrIllegalOperationException::__toString' => ['string'], 'SolrIllegalOperationException::__wakeup' => ['void'], 'SolrIllegalOperationException::getCode' => ['int'], 'SolrIllegalOperationException::getFile' => ['string'], 'SolrIllegalOperationException::getInternalInfo' => ['array'], 'SolrIllegalOperationException::getLine' => ['int'], 'SolrIllegalOperationException::getMessage' => ['string'], 'SolrIllegalOperationException::getPrevious' => ['Exception|Throwable'], 'SolrIllegalOperationException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'SolrIllegalOperationException::getTraceAsString' => ['string'], 'SolrInputDocument::__clone' => ['void'], 'SolrInputDocument::__construct' => ['void'], 'SolrInputDocument::__destruct' => [''], 'SolrInputDocument::addChildDocument' => ['void', 'child'=>'SolrInputDocument'], 'SolrInputDocument::addChildDocuments' => ['void', 'docs'=>'array'], 'SolrInputDocument::addField' => ['bool', 'fieldname'=>'string', 'fieldvalue'=>'string', 'fieldboostvalue='=>'float'], 'SolrInputDocument::clear' => ['bool'], 'SolrInputDocument::deleteField' => ['bool', 'fieldname'=>'string'], 'SolrInputDocument::fieldExists' => ['bool', 'fieldname'=>'string'], 'SolrInputDocument::getBoost' => ['float'], 'SolrInputDocument::getChildDocuments' => ['array'], 'SolrInputDocument::getChildDocumentsCount' => ['int'], 'SolrInputDocument::getField' => ['SolrDocumentField', 'fieldname'=>'string'], 'SolrInputDocument::getFieldBoost' => ['float', 'fieldname'=>'string'], 'SolrInputDocument::getFieldCount' => ['int'], 'SolrInputDocument::getFieldNames' => ['array'], 'SolrInputDocument::hasChildDocuments' => ['bool'], 'SolrInputDocument::merge' => ['bool', 'sourcedoc'=>'solrinputdocument', 'overwrite='=>'bool'], 'SolrInputDocument::reset' => ['bool'], 'SolrInputDocument::setBoost' => ['bool', 'documentboostvalue'=>'float'], 'SolrInputDocument::setFieldBoost' => ['bool', 'fieldname'=>'string', 'fieldboostvalue'=>'float'], 'SolrInputDocument::sort' => ['bool', 'sortorderby'=>'int', 'sortdirection='=>'int'], 'SolrInputDocument::toArray' => ['array'], 'SolrModifiableParams::__construct' => ['void'], 'SolrModifiableParams::__destruct' => [''], 'SolrModifiableParams::add' => ['SolrParams', 'name'=>'string', 'value'=>'string'], 'SolrModifiableParams::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'], 'SolrModifiableParams::get' => ['mixed', 'param_name'=>'string'], 'SolrModifiableParams::getParam' => ['mixed', 'param_name'=>'string'], 'SolrModifiableParams::getParams' => ['array'], 'SolrModifiableParams::getPreparedParams' => ['array'], 'SolrModifiableParams::serialize' => ['string'], 'SolrModifiableParams::set' => ['SolrParams', 'name'=>'string', 'value'=>''], 'SolrModifiableParams::setParam' => ['SolrParams', 'name'=>'string', 'value'=>''], 'SolrModifiableParams::toString' => ['string', 'url_encode='=>'bool|false'], 'SolrModifiableParams::unserialize' => ['void', 'serialized'=>'string'], 'SolrObject::__construct' => ['void'], 'SolrObject::__destruct' => [''], 'SolrObject::getPropertyNames' => ['array'], 'SolrObject::offsetExists' => ['bool', 'property_name'=>'string'], 'SolrObject::offsetGet' => ['mixed', 'property_name'=>'string'], 'SolrObject::offsetSet' => ['void', 'property_name'=>'string', 'property_value'=>'string'], 'SolrObject::offsetUnset' => ['void', 'property_name'=>'string'], 'SolrParams::__construct' => ['void'], 'SolrParams::add' => ['SolrParams', 'name'=>'string', 'value'=>'string'], 'SolrParams::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'], 'SolrParams::get' => ['mixed', 'param_name'=>'string'], 'SolrParams::getParam' => ['mixed', 'param_name='=>'string'], 'SolrParams::getParams' => ['array'], 'SolrParams::getPreparedParams' => ['array'], 'SolrParams::serialize' => ['string'], 'SolrParams::set' => ['void', 'name'=>'string', 'value'=>'string'], 'SolrParams::setParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'], 'SolrParams::toString' => ['string', 'url_encode='=>'bool'], 'SolrParams::unserialize' => ['void', 'serialized'=>'string'], 'SolrPingResponse::__construct' => ['void'], 'SolrPingResponse::__destruct' => [''], 'SolrPingResponse::getDigestedResponse' => ['string'], 'SolrPingResponse::getHttpStatus' => ['int'], 'SolrPingResponse::getHttpStatusMessage' => ['string'], 'SolrPingResponse::getRawRequest' => ['string'], 'SolrPingResponse::getRawRequestHeaders' => ['string'], 'SolrPingResponse::getRawResponse' => ['string'], 'SolrPingResponse::getRawResponseHeaders' => ['string'], 'SolrPingResponse::getRequestUrl' => ['string'], 'SolrPingResponse::getResponse' => ['string'], 'SolrPingResponse::setParseMode' => ['bool', 'parser_mode='=>'int'], 'SolrPingResponse::success' => ['bool'], 'SolrQuery::__construct' => ['void', 'q='=>'string'], 'SolrQuery::__destruct' => [''], 'SolrQuery::add' => ['SolrParams', 'name'=>'string', 'value'=>'string'], 'SolrQuery::addExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'], 'SolrQuery::addExpandSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'string'], 'SolrQuery::addFacetDateField' => ['SolrQuery', 'datefield'=>'string'], 'SolrQuery::addFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'], 'SolrQuery::addFacetField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::addFacetQuery' => ['SolrQuery', 'facetquery'=>'string'], 'SolrQuery::addField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::addFilterQuery' => ['SolrQuery', 'fq'=>'string'], 'SolrQuery::addGroupField' => ['SolrQuery', 'value'=>'string'], 'SolrQuery::addGroupFunction' => ['SolrQuery', 'value'=>'string'], 'SolrQuery::addGroupQuery' => ['SolrQuery', 'value'=>'string'], 'SolrQuery::addGroupSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'int'], 'SolrQuery::addHighlightField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::addMltField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::addMltQueryField' => ['SolrQuery', 'field'=>'string', 'boost'=>'float'], 'SolrQuery::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'], 'SolrQuery::addSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'int'], 'SolrQuery::addStatsFacet' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::addStatsField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::collapse' => ['SolrQuery', 'collapseFunction'=>'SolrCollapseFunction'], 'SolrQuery::get' => ['mixed', 'param_name'=>'string'], 'SolrQuery::getExpand' => ['bool'], 'SolrQuery::getExpandFilterQueries' => ['array'], 'SolrQuery::getExpandQuery' => ['array'], 'SolrQuery::getExpandRows' => ['int'], 'SolrQuery::getExpandSortFields' => ['array'], 'SolrQuery::getFacet' => ['bool'], 'SolrQuery::getFacetDateEnd' => ['string', 'field_override='=>'string'], 'SolrQuery::getFacetDateFields' => ['array'], 'SolrQuery::getFacetDateGap' => ['string', 'field_override='=>'string'], 'SolrQuery::getFacetDateHardEnd' => ['string', 'field_override='=>'string'], 'SolrQuery::getFacetDateOther' => ['?string', 'field_override='=>'string'], 'SolrQuery::getFacetDateStart' => ['string', 'field_override='=>'string'], 'SolrQuery::getFacetFields' => ['array'], 'SolrQuery::getFacetLimit' => ['int', 'field_override='=>'string'], 'SolrQuery::getFacetMethod' => ['string', 'field_override='=>'string'], 'SolrQuery::getFacetMinCount' => ['int', 'field_override='=>'string'], 'SolrQuery::getFacetMissing' => ['bool', 'field_override='=>'string'], 'SolrQuery::getFacetOffset' => ['int', 'field_override='=>'string'], 'SolrQuery::getFacetPrefix' => ['string', 'field_override='=>'string'], 'SolrQuery::getFacetQueries' => ['array'], 'SolrQuery::getFacetSort' => ['int', 'field_override='=>'string'], 'SolrQuery::getFields' => ['array'], 'SolrQuery::getFilterQueries' => ['array'], 'SolrQuery::getGroup' => ['bool'], 'SolrQuery::getGroupCachePercent' => ['int'], 'SolrQuery::getGroupFacet' => ['bool'], 'SolrQuery::getGroupFields' => ['array'], 'SolrQuery::getGroupFormat' => ['string'], 'SolrQuery::getGroupFunctions' => ['array'], 'SolrQuery::getGroupLimit' => ['int'], 'SolrQuery::getGroupMain' => ['bool'], 'SolrQuery::getGroupNGroups' => ['bool'], 'SolrQuery::getGroupOffset' => ['int'], 'SolrQuery::getGroupQueries' => ['array'], 'SolrQuery::getGroupSortFields' => ['array'], 'SolrQuery::getGroupTruncate' => ['bool'], 'SolrQuery::getHighlight' => ['bool'], 'SolrQuery::getHighlightAlternateField' => ['string', 'field_override='=>'string'], 'SolrQuery::getHighlightFields' => ['array'], 'SolrQuery::getHighlightFormatter' => ['string', 'field_override='=>'string'], 'SolrQuery::getHighlightFragmenter' => ['string', 'field_override='=>'string'], 'SolrQuery::getHighlightFragsize' => ['int', 'field_override='=>'string'], 'SolrQuery::getHighlightHighlightMultiTerm' => ['bool'], 'SolrQuery::getHighlightMaxAlternateFieldLength' => ['int', 'field_override='=>'string'], 'SolrQuery::getHighlightMaxAnalyzedChars' => ['int'], 'SolrQuery::getHighlightMergeContiguous' => ['bool', 'field_override='=>'string'], 'SolrQuery::getHighlightRegexMaxAnalyzedChars' => ['int'], 'SolrQuery::getHighlightRegexPattern' => ['string'], 'SolrQuery::getHighlightRegexSlop' => ['float'], 'SolrQuery::getHighlightRequireFieldMatch' => ['bool'], 'SolrQuery::getHighlightSimplePost' => ['string', 'field_override='=>'string'], 'SolrQuery::getHighlightSimplePre' => ['string', 'field_override='=>'string'], 'SolrQuery::getHighlightSnippets' => ['int', 'field_override='=>'string'], 'SolrQuery::getHighlightUsePhraseHighlighter' => ['bool'], 'SolrQuery::getMlt' => ['bool'], 'SolrQuery::getMltBoost' => ['bool'], 'SolrQuery::getMltCount' => ['int'], 'SolrQuery::getMltFields' => ['array'], 'SolrQuery::getMltMaxNumQueryTerms' => ['int'], 'SolrQuery::getMltMaxNumTokens' => ['int'], 'SolrQuery::getMltMaxWordLength' => ['int'], 'SolrQuery::getMltMinDocFrequency' => ['int'], 'SolrQuery::getMltMinTermFrequency' => ['int'], 'SolrQuery::getMltMinWordLength' => ['int'], 'SolrQuery::getMltQueryFields' => ['array'], 'SolrQuery::getParam' => ['mixed', 'param_name'=>'string'], 'SolrQuery::getParams' => ['array'], 'SolrQuery::getPreparedParams' => ['array'], 'SolrQuery::getQuery' => ['string'], 'SolrQuery::getRows' => ['int'], 'SolrQuery::getSortFields' => ['array'], 'SolrQuery::getStart' => ['int'], 'SolrQuery::getStats' => ['bool'], 'SolrQuery::getStatsFacets' => ['array'], 'SolrQuery::getStatsFields' => ['array'], 'SolrQuery::getTerms' => ['bool'], 'SolrQuery::getTermsField' => ['string'], 'SolrQuery::getTermsIncludeLowerBound' => ['bool'], 'SolrQuery::getTermsIncludeUpperBound' => ['bool'], 'SolrQuery::getTermsLimit' => ['int'], 'SolrQuery::getTermsLowerBound' => ['string'], 'SolrQuery::getTermsMaxCount' => ['int'], 'SolrQuery::getTermsMinCount' => ['int'], 'SolrQuery::getTermsPrefix' => ['string'], 'SolrQuery::getTermsReturnRaw' => ['bool'], 'SolrQuery::getTermsSort' => ['int'], 'SolrQuery::getTermsUpperBound' => ['string'], 'SolrQuery::getTimeAllowed' => ['int'], 'SolrQuery::removeExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'], 'SolrQuery::removeExpandSortField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::removeFacetDateField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::removeFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'], 'SolrQuery::removeFacetField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::removeFacetQuery' => ['SolrQuery', 'value'=>'string'], 'SolrQuery::removeField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::removeFilterQuery' => ['SolrQuery', 'fq'=>'string'], 'SolrQuery::removeHighlightField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::removeMltField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::removeMltQueryField' => ['SolrQuery', 'queryfield'=>'string'], 'SolrQuery::removeSortField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::removeStatsFacet' => ['SolrQuery', 'value'=>'string'], 'SolrQuery::removeStatsField' => ['SolrQuery', 'field'=>'string'], 'SolrQuery::serialize' => ['string'], 'SolrQuery::set' => ['SolrParams', 'name'=>'string', 'value'=>''], 'SolrQuery::setEchoHandler' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setEchoParams' => ['SolrQuery', 'type'=>'string'], 'SolrQuery::setExpand' => ['SolrQuery', 'value'=>'bool'], 'SolrQuery::setExpandQuery' => ['SolrQuery', 'q'=>'string'], 'SolrQuery::setExpandRows' => ['SolrQuery', 'value'=>'int'], 'SolrQuery::setExplainOther' => ['SolrQuery', 'query'=>'string'], 'SolrQuery::setFacet' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setFacetDateEnd' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'], 'SolrQuery::setFacetDateGap' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'], 'SolrQuery::setFacetDateHardEnd' => ['SolrQuery', 'value'=>'bool', 'field_override='=>'string'], 'SolrQuery::setFacetDateStart' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'], 'SolrQuery::setFacetEnumCacheMinDefaultFrequency' => ['SolrQuery', 'frequency'=>'int', 'field_override='=>'string'], 'SolrQuery::setFacetLimit' => ['SolrQuery', 'limit'=>'int', 'field_override='=>'string'], 'SolrQuery::setFacetMethod' => ['SolrQuery', 'method'=>'string', 'field_override='=>'string'], 'SolrQuery::setFacetMinCount' => ['SolrQuery', 'mincount'=>'int', 'field_override='=>'string'], 'SolrQuery::setFacetMissing' => ['SolrQuery', 'flag'=>'bool', 'field_override='=>'string'], 'SolrQuery::setFacetOffset' => ['SolrQuery', 'offset'=>'int', 'field_override='=>'string'], 'SolrQuery::setFacetPrefix' => ['SolrQuery', 'prefix'=>'string', 'field_override='=>'string'], 'SolrQuery::setFacetSort' => ['SolrQuery', 'facetsort'=>'int', 'field_override='=>'string'], 'SolrQuery::setGroup' => ['SolrQuery', 'value'=>'bool'], 'SolrQuery::setGroupCachePercent' => ['SolrQuery', 'percent'=>'int'], 'SolrQuery::setGroupFacet' => ['SolrQuery', 'value'=>'bool'], 'SolrQuery::setGroupFormat' => ['SolrQuery', 'value'=>'string'], 'SolrQuery::setGroupLimit' => ['SolrQuery', 'value'=>'int'], 'SolrQuery::setGroupMain' => ['SolrQuery', 'value'=>'string'], 'SolrQuery::setGroupNGroups' => ['SolrQuery', 'value'=>'bool'], 'SolrQuery::setGroupOffset' => ['SolrQuery', 'value'=>'int'], 'SolrQuery::setGroupTruncate' => ['SolrQuery', 'value'=>'bool'], 'SolrQuery::setHighlight' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setHighlightAlternateField' => ['SolrQuery', 'field'=>'string', 'field_override='=>'string'], 'SolrQuery::setHighlightFormatter' => ['SolrQuery', 'formatter'=>'string', 'field_override='=>'string'], 'SolrQuery::setHighlightFragmenter' => ['SolrQuery', 'fragmenter'=>'string', 'field_override='=>'string'], 'SolrQuery::setHighlightFragsize' => ['SolrQuery', 'size'=>'int', 'field_override='=>'string'], 'SolrQuery::setHighlightHighlightMultiTerm' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setHighlightMaxAlternateFieldLength' => ['SolrQuery', 'fieldlength'=>'int', 'field_override='=>'string'], 'SolrQuery::setHighlightMaxAnalyzedChars' => ['SolrQuery', 'value'=>'int'], 'SolrQuery::setHighlightMergeContiguous' => ['SolrQuery', 'flag'=>'bool', 'field_override='=>'string'], 'SolrQuery::setHighlightRegexMaxAnalyzedChars' => ['SolrQuery', 'maxanalyzedchars'=>'int'], 'SolrQuery::setHighlightRegexPattern' => ['SolrQuery', 'value'=>'string'], 'SolrQuery::setHighlightRegexSlop' => ['SolrQuery', 'factor'=>'float'], 'SolrQuery::setHighlightRequireFieldMatch' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setHighlightSimplePost' => ['SolrQuery', 'simplepost'=>'string', 'field_override='=>'string'], 'SolrQuery::setHighlightSimplePre' => ['SolrQuery', 'simplepre'=>'string', 'field_override='=>'string'], 'SolrQuery::setHighlightSnippets' => ['SolrQuery', 'value'=>'int', 'field_override='=>'string'], 'SolrQuery::setHighlightUsePhraseHighlighter' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setMlt' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setMltBoost' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setMltCount' => ['SolrQuery', 'count'=>'int'], 'SolrQuery::setMltMaxNumQueryTerms' => ['SolrQuery', 'value'=>'int'], 'SolrQuery::setMltMaxNumTokens' => ['SolrQuery', 'value'=>'int'], 'SolrQuery::setMltMaxWordLength' => ['SolrQuery', 'maxwordlength'=>'int'], 'SolrQuery::setMltMinDocFrequency' => ['SolrQuery', 'mindocfrequency'=>'int'], 'SolrQuery::setMltMinTermFrequency' => ['SolrQuery', 'mintermfrequency'=>'int'], 'SolrQuery::setMltMinWordLength' => ['SolrQuery', 'minwordlength'=>'int'], 'SolrQuery::setOmitHeader' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setParam' => ['SolrParams', 'name'=>'string', 'value'=>''], 'SolrQuery::setQuery' => ['SolrQuery', 'query'=>'string'], 'SolrQuery::setRows' => ['SolrQuery', 'rows'=>'int'], 'SolrQuery::setShowDebugInfo' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setStart' => ['SolrQuery', 'start'=>'int'], 'SolrQuery::setStats' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setTerms' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setTermsField' => ['SolrQuery', 'fieldname'=>'string'], 'SolrQuery::setTermsIncludeLowerBound' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setTermsIncludeUpperBound' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setTermsLimit' => ['SolrQuery', 'limit'=>'int'], 'SolrQuery::setTermsLowerBound' => ['SolrQuery', 'lowerbound'=>'string'], 'SolrQuery::setTermsMaxCount' => ['SolrQuery', 'frequency'=>'int'], 'SolrQuery::setTermsMinCount' => ['SolrQuery', 'frequency'=>'int'], 'SolrQuery::setTermsPrefix' => ['SolrQuery', 'prefix'=>'string'], 'SolrQuery::setTermsReturnRaw' => ['SolrQuery', 'flag'=>'bool'], 'SolrQuery::setTermsSort' => ['SolrQuery', 'sorttype'=>'int'], 'SolrQuery::setTermsUpperBound' => ['SolrQuery', 'upperbound'=>'string'], 'SolrQuery::setTimeAllowed' => ['SolrQuery', 'timeallowed'=>'int'], 'SolrQuery::toString' => ['string', 'url_encode='=>'bool|false'], 'SolrQuery::unserialize' => ['void', 'serialized'=>'string'], 'SolrQueryResponse::__construct' => ['void'], 'SolrQueryResponse::__destruct' => [''], 'SolrQueryResponse::getDigestedResponse' => ['string'], 'SolrQueryResponse::getHttpStatus' => ['int'], 'SolrQueryResponse::getHttpStatusMessage' => ['string'], 'SolrQueryResponse::getRawRequest' => ['string'], 'SolrQueryResponse::getRawRequestHeaders' => ['string'], 'SolrQueryResponse::getRawResponse' => ['string'], 'SolrQueryResponse::getRawResponseHeaders' => ['string'], 'SolrQueryResponse::getRequestUrl' => ['string'], 'SolrQueryResponse::getResponse' => ['SolrObject'], 'SolrQueryResponse::setParseMode' => ['bool', 'parser_mode='=>'int'], 'SolrQueryResponse::success' => ['bool'], 'SolrResponse::getDigestedResponse' => ['string'], 'SolrResponse::getHttpStatus' => ['int'], 'SolrResponse::getHttpStatusMessage' => ['string'], 'SolrResponse::getRawRequest' => ['string'], 'SolrResponse::getRawRequestHeaders' => ['string'], 'SolrResponse::getRawResponse' => ['string'], 'SolrResponse::getRawResponseHeaders' => ['string'], 'SolrResponse::getRequestUrl' => ['string'], 'SolrResponse::getResponse' => ['SolrObject'], 'SolrResponse::setParseMode' => ['bool', 'parser_mode='=>'int'], 'SolrResponse::success' => ['bool'], 'SolrServerException::__clone' => ['void'], 'SolrServerException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Exception)|(?Throwable)'], 'SolrServerException::__toString' => ['string'], 'SolrServerException::__wakeup' => ['void'], 'SolrServerException::getCode' => ['int'], 'SolrServerException::getFile' => ['string'], 'SolrServerException::getInternalInfo' => ['array'], 'SolrServerException::getLine' => ['int'], 'SolrServerException::getMessage' => ['string'], 'SolrServerException::getPrevious' => ['Exception|Throwable'], 'SolrServerException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'SolrServerException::getTraceAsString' => ['string'], 'SolrUpdateResponse::__construct' => ['void'], 'SolrUpdateResponse::__destruct' => [''], 'SolrUpdateResponse::getDigestedResponse' => ['string'], 'SolrUpdateResponse::getHttpStatus' => ['int'], 'SolrUpdateResponse::getHttpStatusMessage' => ['string'], 'SolrUpdateResponse::getRawRequest' => ['string'], 'SolrUpdateResponse::getRawRequestHeaders' => ['string'], 'SolrUpdateResponse::getRawResponse' => ['string'], 'SolrUpdateResponse::getRawResponseHeaders' => ['string'], 'SolrUpdateResponse::getRequestUrl' => ['string'], 'SolrUpdateResponse::getResponse' => ['SolrObject'], 'SolrUpdateResponse::setParseMode' => ['bool', 'parser_mode='=>'int'], 'SolrUpdateResponse::success' => ['bool'], 'SolrUtils::digestXmlResponse' => ['SolrObject', 'xmlresponse'=>'string', 'parse_mode='=>'int'], 'SolrUtils::escapeQueryChars' => ['string|false', 'str'=>'string'], 'SolrUtils::getSolrVersion' => ['string'], 'SolrUtils::queryPhrase' => ['string', 'str'=>'string'], 'sort' => ['bool', '&rw_array_arg'=>'array', 'sort_flags='=>'int'], 'soundex' => ['string', 'str'=>'string'], 'SphinxClient::__construct' => ['void'], 'SphinxClient::addQuery' => ['int', 'query'=>'string', 'index='=>'string', 'comment='=>'string'], 'SphinxClient::buildExcerpts' => ['array', 'docs'=>'array', 'index'=>'string', 'words'=>'string', 'opts='=>'array'], 'SphinxClient::buildKeywords' => ['array', 'query'=>'string', 'index'=>'string', 'hits'=>'bool'], 'SphinxClient::close' => ['bool'], 'SphinxClient::escapeString' => ['string', 'string'=>'string'], 'SphinxClient::getLastError' => ['string'], 'SphinxClient::getLastWarning' => ['string'], 'SphinxClient::open' => ['bool'], 'SphinxClient::query' => ['array', 'query'=>'string', 'index='=>'string', 'comment='=>'string'], 'SphinxClient::resetFilters' => ['void'], 'SphinxClient::resetGroupBy' => ['void'], 'SphinxClient::runQueries' => ['array'], 'SphinxClient::setArrayResult' => ['bool', 'array_result'=>'bool'], 'SphinxClient::setConnectTimeout' => ['bool', 'timeout'=>'float'], 'SphinxClient::setFieldWeights' => ['bool', 'weights'=>'array'], 'SphinxClient::setFilter' => ['bool', 'attribute'=>'string', 'values'=>'array', 'exclude='=>'bool'], 'SphinxClient::setFilterFloatRange' => ['bool', 'attribute'=>'string', 'min'=>'float', 'max'=>'float', 'exclude='=>'bool'], 'SphinxClient::setFilterRange' => ['bool', 'attribute'=>'string', 'min'=>'int', 'max'=>'int', 'exclude='=>'bool'], 'SphinxClient::setGeoAnchor' => ['bool', 'attrlat'=>'string', 'attrlong'=>'string', 'latitude'=>'float', 'longitude'=>'float'], 'SphinxClient::setGroupBy' => ['bool', 'attribute'=>'string', 'func'=>'int', 'groupsort='=>'string'], 'SphinxClient::setGroupDistinct' => ['bool', 'attribute'=>'string'], 'SphinxClient::setIDRange' => ['bool', 'min'=>'int', 'max'=>'int'], 'SphinxClient::setIndexWeights' => ['bool', 'weights'=>'array'], 'SphinxClient::setLimits' => ['bool', 'offset'=>'int', 'limit'=>'int', 'max_matches='=>'int', 'cutoff='=>'int'], 'SphinxClient::setMatchMode' => ['bool', 'mode'=>'int'], 'SphinxClient::setMaxQueryTime' => ['bool', 'qtime'=>'int'], 'SphinxClient::setOverride' => ['bool', 'attribute'=>'string', 'type'=>'int', 'values'=>'array'], 'SphinxClient::setRankingMode' => ['bool', 'ranker'=>'int'], 'SphinxClient::setRetries' => ['bool', 'count'=>'int', 'delay='=>'int'], 'SphinxClient::setSelect' => ['bool', 'clause'=>'string'], 'SphinxClient::setServer' => ['bool', 'server'=>'string', 'port'=>'int'], 'SphinxClient::setSortMode' => ['bool', 'mode'=>'int', 'sortby='=>'string'], 'SphinxClient::status' => ['array'], 'SphinxClient::updateAttributes' => ['int', 'index'=>'string', 'attributes'=>'array', 'values'=>'array', 'mva='=>'bool'], 'spl_autoload' => ['void', 'class_name'=>'string', 'file_extensions='=>'string'], 'spl_autoload_call' => ['void', 'class_name'=>'string'], 'spl_autoload_extensions' => ['string', 'file_extensions='=>'string'], 'spl_autoload_functions' => ['false|list'], 'spl_autoload_register' => ['bool', 'autoload_function='=>'callable(string):void', 'throw='=>'bool', 'prepend='=>'bool'], 'spl_autoload_unregister' => ['bool', 'autoload_function'=>'mixed'], 'spl_classes' => ['array'], 'spl_object_hash' => ['string', 'obj'=>'object'], 'spl_object_id' => ['int', 'obj'=>'object'], 'SplDoublyLinkedList::add' => ['void', 'index'=>'mixed', 'newval'=>'mixed'], 'SplDoublyLinkedList::bottom' => ['mixed'], 'SplDoublyLinkedList::count' => ['0|positive-int'], 'SplDoublyLinkedList::current' => ['mixed'], 'SplDoublyLinkedList::getIteratorMode' => ['int'], 'SplDoublyLinkedList::isEmpty' => ['bool'], 'SplDoublyLinkedList::key' => ['mixed'], 'SplDoublyLinkedList::next' => ['void'], 'SplDoublyLinkedList::offsetExists' => ['bool', 'index'=>'mixed'], 'SplDoublyLinkedList::offsetGet' => ['mixed', 'index'=>'mixed'], 'SplDoublyLinkedList::offsetSet' => ['void', 'index'=>'mixed', 'newval'=>'mixed'], 'SplDoublyLinkedList::offsetUnset' => ['void', 'index'=>'mixed'], 'SplDoublyLinkedList::pop' => ['mixed'], 'SplDoublyLinkedList::prev' => ['void'], 'SplDoublyLinkedList::push' => ['void', 'value'=>'mixed'], 'SplDoublyLinkedList::rewind' => ['void'], 'SplDoublyLinkedList::serialize' => ['string'], 'SplDoublyLinkedList::setIteratorMode' => ['int', 'flags'=>'int'], 'SplDoublyLinkedList::shift' => ['mixed'], 'SplDoublyLinkedList::top' => ['mixed'], 'SplDoublyLinkedList::unserialize' => ['void', 'serialized'=>'string'], 'SplDoublyLinkedList::unshift' => ['bool', 'value'=>'mixed'], 'SplDoublyLinkedList::valid' => ['bool'], 'SplEnum::__construct' => ['void', 'initial_value='=>'mixed', 'strict='=>'bool|true'], 'SplEnum::getConstList' => ['array', 'include_default='=>'bool'], 'SplFileInfo::__construct' => ['void', 'file_name'=>'string'], 'SplFileInfo::__toString' => ['string'], 'SplFileInfo::getATime' => ['__benevolent'], 'SplFileInfo::getBasename' => ['string', 'suffix='=>'string'], 'SplFileInfo::getCTime' => ['int'], 'SplFileInfo::getExtension' => ['string'], 'SplFileInfo::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'], 'SplFileInfo::getFilename' => ['string'], 'SplFileInfo::getGroup' => ['__benevolent'], 'SplFileInfo::getInode' => ['__benevolent'], 'SplFileInfo::getLinkTarget' => ['__benevolent'], 'SplFileInfo::getMTime' => ['__benevolent'], 'SplFileInfo::getOwner' => ['__benevolent'], 'SplFileInfo::getPath' => ['string'], 'SplFileInfo::getPathInfo' => ['__benevolent', 'class_name='=>'string'], 'SplFileInfo::getPathname' => ['string'], 'SplFileInfo::getPerms' => ['__benevolent'], 'SplFileInfo::getRealPath' => ['__benevolent'], 'SplFileInfo::getSize' => ['__benevolent'], 'SplFileInfo::getType' => ['__benevolent'], 'SplFileInfo::isDir' => ['bool'], 'SplFileInfo::isExecutable' => ['bool'], 'SplFileInfo::isFile' => ['bool'], 'SplFileInfo::isLink' => ['bool'], 'SplFileInfo::isReadable' => ['bool'], 'SplFileInfo::isWritable' => ['bool'], 'SplFileInfo::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'], 'SplFileInfo::setFileClass' => ['void', 'class_name='=>'string'], 'SplFileInfo::setInfoClass' => ['void', 'class_name='=>'string'], 'SplFileObject::__construct' => ['void', 'filename'=>'string', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>''], 'SplFileObject::__toString' => ['string'], 'SplFileObject::current' => ['string|array|false'], 'SplFileObject::eof' => ['bool'], 'SplFileObject::fflush' => ['bool'], 'SplFileObject::fgetc' => ['string|false'], // Do not believe https://www.php.net/manual/en/splfileobject.fgetcsv#refsect1-splfileobject.fgetcsv-returnvalues 'SplFileObject::fgetcsv' => ['list|array{0: null}|false|null', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'], 'SplFileObject::fgets' => ['string'], 'SplFileObject::fgetss' => ['string|false', 'allowable_tags='=>'string'], 'SplFileObject::flock' => ['bool', 'operation'=>'int', '&w_wouldblock='=>'int'], 'SplFileObject::fpassthru' => ['int'], 'SplFileObject::fputcsv' => ['int|false', 'fields'=>'array', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'], 'SplFileObject::fread' => ['string|false', 'length'=>'int'], 'SplFileObject::fscanf' => ['bool', 'format'=>'string', '&...w_vars='=>'string|int|float'], 'SplFileObject::fseek' => ['int', 'pos'=>'int', 'whence='=>'int'], 'SplFileObject::fstat' => ['array'], 'SplFileObject::ftell' => ['int|false'], 'SplFileObject::ftruncate' => ['bool', 'size'=>'int'], 'SplFileObject::fwrite' => ['int', 'str'=>'string', 'length='=>'int'], 'SplFileObject::getChildren' => ['null'], 'SplFileObject::getCsvControl' => ['array'], 'SplFileObject::getCurrentLine' => ['string'], 'SplFileObject::getFlags' => ['int'], 'SplFileObject::getMaxLineLen' => ['int'], 'SplFileObject::hasChildren' => ['false'], 'SplFileObject::key' => ['int'], 'SplFileObject::next' => ['void'], 'SplFileObject::rewind' => ['void'], 'SplFileObject::seek' => ['void', 'line_pos'=>'int'], 'SplFileObject::setCsvControl' => ['void', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'], 'SplFileObject::setFlags' => ['void', 'flags'=>'int'], 'SplFileObject::setMaxLineLen' => ['void', 'max_len'=>'int'], 'SplFileObject::valid' => ['bool'], 'SplFixedArray::__construct' => ['void', 'size='=>'int'], 'SplFixedArray::__wakeup' => ['void'], 'SplFixedArray::count' => ['0|positive-int'], 'SplFixedArray::current' => ['mixed'], 'SplFixedArray::fromArray' => ['SplFixedArray', 'data'=>'array', 'save_indexes='=>'bool'], 'SplFixedArray::getSize' => ['int'], 'SplFixedArray::key' => ['int'], 'SplFixedArray::next' => ['void'], 'SplFixedArray::offsetExists' => ['bool', 'index'=>'int'], 'SplFixedArray::offsetGet' => ['mixed', 'index'=>'int'], 'SplFixedArray::offsetSet' => ['void', 'index'=>'int', 'newval'=>'mixed'], 'SplFixedArray::offsetUnset' => ['void', 'index'=>'int'], 'SplFixedArray::rewind' => ['void'], 'SplFixedArray::setSize' => ['bool', 'size'=>'int'], 'SplFixedArray::toArray' => ['array'], 'SplFixedArray::valid' => ['bool'], 'SplHeap::compare' => ['int', 'value1'=>'mixed', 'value2'=>'mixed'], 'SplHeap::count' => ['0|positive-int'], 'SplHeap::current' => ['mixed'], 'SplHeap::extract' => ['mixed'], 'SplHeap::insert' => ['bool', 'value'=>'mixed'], 'SplHeap::isCorrupted' => ['int'], 'SplHeap::isEmpty' => ['bool'], 'SplHeap::key' => ['int'], 'SplHeap::next' => ['void'], 'SplHeap::recoverFromCorruption' => ['int'], 'SplHeap::rewind' => ['void'], 'SplHeap::top' => ['mixed'], 'SplHeap::valid' => ['bool'], 'split' => ['array', 'pattern'=>'string', 'string'=>'string', 'limit='=>'int'], 'spliti' => ['array', 'pattern'=>'string', 'string'=>'string', 'limit='=>'int'], 'SplMaxHeap::compare' => ['int', 'a'=>'mixed', 'b'=>'mixed'], 'SplMinHeap::compare' => ['int', 'a'=>'mixed', 'b'=>'mixed'], 'SplObjectStorage::addAll' => ['0|positive-int', 'os'=>'SplObjectStorage'], 'SplObjectStorage::attach' => ['void', 'obj'=>'object', 'inf='=>'mixed'], 'SplObjectStorage::contains' => ['bool', 'obj'=>'object'], 'SplObjectStorage::count' => ['0|positive-int'], 'SplObjectStorage::current' => ['object'], 'SplObjectStorage::detach' => ['void', 'obj'=>'object'], 'SplObjectStorage::getHash' => ['string', 'obj'=>'object'], 'SplObjectStorage::getInfo' => ['mixed'], 'SplObjectStorage::key' => ['int'], 'SplObjectStorage::next' => ['void'], 'SplObjectStorage::offsetExists' => ['bool', 'object'=>'object'], 'SplObjectStorage::offsetGet' => ['mixed', 'obj'=>'object'], 'SplObjectStorage::offsetSet' => ['object', 'object'=>'object', 'data='=>'mixed'], 'SplObjectStorage::offsetUnset' => ['object', 'object'=>'object'], 'SplObjectStorage::removeAll' => ['0|positive-int', 'os'=>'SplObjectStorage'], 'SplObjectStorage::removeAllExcept' => ['0|positive-int', 'os'=>'SplObjectStorage'], 'SplObjectStorage::rewind' => ['void'], 'SplObjectStorage::serialize' => ['string'], 'SplObjectStorage::setInfo' => ['void', 'inf'=>'mixed'], 'SplObjectStorage::unserialize' => ['void', 'serialized'=>'string'], 'SplObjectStorage::valid' => ['bool'], 'SplObserver::update' => ['void', 'subject'=>'SplSubject'], 'SplPriorityQueue::compare' => ['int', 'a'=>'mixed', 'b'=>'mixed'], 'SplPriorityQueue::count' => ['0|positive-int'], 'SplPriorityQueue::current' => ['mixed'], 'SplPriorityQueue::extract' => ['mixed'], 'SplPriorityQueue::getExtractFlags' => ['int'], 'SplPriorityQueue::insert' => ['bool', 'value'=>'mixed', 'priority'=>'mixed'], 'SplPriorityQueue::isEmpty' => ['bool'], 'SplPriorityQueue::key' => ['mixed'], 'SplPriorityQueue::next' => ['void'], 'SplPriorityQueue::recoverFromCorruption' => ['void'], 'SplPriorityQueue::rewind' => ['void'], 'SplPriorityQueue::setExtractFlags' => ['void', 'flags'=>'int'], 'SplPriorityQueue::top' => ['mixed'], 'SplPriorityQueue::valid' => ['bool'], 'SplQueue::dequeue' => ['mixed'], 'SplQueue::enqueue' => ['void', 'value'=>'mixed'], 'SplQueue::setIteratorMode' => ['void', 'mode'=>'int'], 'SplStack::setIteratorMode' => ['void', 'mode'=>'int'], 'SplSubject::attach' => ['void', 'observer'=>'SplObserver'], 'SplSubject::detach' => ['void', 'observer'=>'SplObserver'], 'SplSubject::notify' => ['void'], 'SplTempFileObject::__construct' => ['void', 'max_memory='=>'int'], 'SplType::__construct' => ['void', 'initial_value='=>'mixed', 'strict='=>'bool'], 'Spoofchecker::__construct' => ['void'], 'Spoofchecker::areConfusable' => ['bool', 's1'=>'string', 's2'=>'string', '&w_error='=>'string'], 'Spoofchecker::isSuspicious' => ['bool', 'text'=>'string', '&w_error='=>'string'], 'Spoofchecker::setAllowedLocales' => ['void', 'locale_list'=>'string'], 'Spoofchecker::setChecks' => ['void', 'checks'=>'long'], 'Spoofchecker::setRestrictionLevel' => ['void', 'restriction_level'=>'int'], 'sprintf' => ['string', 'format'=>'string', '...values='=>'__stringAndStringable|int|float|null|bool'], 'sql_regcase' => ['string', 'string'=>'string'], 'SQLite3::__construct' => ['void', 'filename'=>'string', 'flags='=>'int', 'encryption_key='=>'string|null'], 'SQLite3::busyTimeout' => ['bool', 'msecs'=>'int'], 'SQLite3::changes' => ['int'], 'SQLite3::close' => ['bool'], 'SQLite3::createAggregate' => ['bool', 'name'=>'string', 'step_callback'=>'callable', 'final_callback'=>'callable', 'argument_count='=>'int'], 'SQLite3::createCollation' => ['bool', 'name'=>'string', 'callback'=>'callable'], 'SQLite3::createFunction' => ['bool', 'name'=>'string', 'callback'=>'callable', 'argument_count='=>'int', 'flags='=>'int'], 'SQLite3::enableExceptions' => ['bool', 'enableexceptions='=>'bool'], 'SQLite3::escapeString' => ['string', 'value'=>'string'], 'SQLite3::exec' => ['bool', 'query'=>'string'], 'SQLite3::lastErrorCode' => ['int'], 'SQLite3::lastErrorMsg' => ['string'], 'SQLite3::lastInsertRowID' => ['int'], 'SQLite3::loadExtension' => ['bool', 'shared_library'=>'string'], 'SQLite3::open' => ['void', 'filename'=>'string', 'flags='=>'int', 'encryption_key='=>'string|null'], 'SQLite3::openBlob' => ['resource|false', 'table'=>'string', 'column'=>'string', 'rowid'=>'int', 'dbname='=>'string', 'flags='=>'int'], 'SQLite3::prepare' => ['SQLite3Stmt|false', 'query'=>'string'], 'SQLite3::query' => ['SQLite3Result|false', 'query'=>'string'], 'SQLite3::querySingle' => ['array|int|string|bool|float|null|false', 'query'=>'string', 'entire_row='=>'bool'], 'SQLite3::version' => ['array'], 'SQLite3Result::__construct' => ['void'], 'SQLite3Result::columnName' => ['string', 'column_number'=>'int'], 'SQLite3Result::columnType' => ['int', 'column_number'=>'int'], 'SQLite3Result::fetchArray' => ['array|false', 'mode='=>'int'], 'SQLite3Result::finalize' => ['bool'], 'SQLite3Result::numColumns' => ['int'], 'SQLite3Result::reset' => ['bool'], 'SQLite3Stmt::__construct' => ['void', 'dbobject'=>'sqlite3', 'statement'=>'string'], 'SQLite3Stmt::bindParam' => ['bool', 'parameter_name_or_number'=>'string|int', '&rw_parameter'=>'mixed', 'type='=>'int'], 'SQLite3Stmt::bindValue' => ['bool', 'parameter_name_or_number'=>'string|int', 'parameter'=>'mixed', 'type='=>'int'], 'SQLite3Stmt::clear' => ['bool'], 'SQLite3Stmt::close' => ['bool'], 'SQLite3Stmt::execute' => ['false|SQLite3Result'], 'SQLite3Stmt::paramCount' => ['int'], 'SQLite3Stmt::readOnly' => ['bool'], 'SQLite3Stmt::reset' => ['bool'], 'sqlite_array_query' => ['array', 'dbhandle'=>'', 'query'=>'string', 'result_type='=>'int', 'decode_binary='=>'bool'], 'sqlite_busy_timeout' => ['', 'dbhandle'=>'', 'milliseconds'=>'int'], 'sqlite_changes' => ['int', 'dbhandle'=>''], 'sqlite_close' => ['void', 'dbhandle'=>'resource'], 'sqlite_column' => ['', 'result'=>'', 'index_or_name'=>'', 'decode_binary='=>'bool'], 'sqlite_create_aggregate' => ['', 'dbhandle'=>'', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'], 'sqlite_create_function' => ['', 'dbhandle'=>'', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'], 'sqlite_current' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], 'sqlite_error_string' => ['string', 'error_code'=>'int'], 'sqlite_escape_string' => ['string', 'item'=>'string'], 'sqlite_exec' => ['bool', 'dbhandle'=>'', 'query'=>'string', 'error_msg='=>'string'], 'sqlite_factory' => ['SQLiteDatabase', 'filename'=>'string', 'mode='=>'int', 'error_message='=>'string'], 'sqlite_fetch_all' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], 'sqlite_fetch_array' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], 'sqlite_fetch_column_types' => ['array', 'table_name'=>'string', 'dbhandle'=>'', 'result_type='=>'int'], 'sqlite_fetch_object' => ['object', 'result'=>'', 'class_name='=>'string', 'ctor_params='=>'array', 'decode_binary='=>'bool'], 'sqlite_fetch_single' => ['string', 'result'=>'', 'decode_binary='=>'bool'], 'sqlite_field_name' => ['string', 'result'=>'', 'field_index'=>'int'], 'sqlite_has_more' => ['bool', 'result'=>'resource'], 'sqlite_has_prev' => ['bool', 'result'=>''], 'sqlite_key' => ['int', 'result'=>''], 'sqlite_last_error' => ['int', 'dbhandle'=>''], 'sqlite_last_insert_rowid' => ['int', 'dbhandle'=>''], 'sqlite_libencoding' => ['string'], 'sqlite_libversion' => ['string'], 'sqlite_next' => ['bool', 'result'=>''], 'sqlite_num_fields' => ['int', 'result'=>''], 'sqlite_num_rows' => ['int', 'result'=>''], 'sqlite_open' => ['resource|false', 'filename'=>'string', 'mode='=>'int', 'error_message='=>'string'], 'sqlite_popen' => ['resource|false', 'filename'=>'string', 'mode='=>'int', 'error_message='=>'string'], 'sqlite_prev' => ['bool', 'result'=>''], 'sqlite_query' => ['SQLiteResult', 'dbhandle'=>'', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'], 'sqlite_rewind' => ['bool', 'result'=>''], 'sqlite_seek' => ['bool', 'result'=>'', 'rownum'=>'int'], 'sqlite_single_query' => ['array', 'db'=>'', 'query'=>'string', 'first_row_only='=>'bool', 'decode_binary='=>'bool'], 'sqlite_udf_decode_binary' => ['string', 'data'=>'string'], 'sqlite_udf_encode_binary' => ['string', 'data'=>'string'], 'sqlite_unbuffered_query' => ['SQLiteUnbuffered', 'dbhandle'=>'', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'], 'sqlite_valid' => ['bool', 'result'=>''], 'SQLiteDatabase::arrayQuery' => ['array', 'dbhandle'=>'', 'query'=>'string', 'result_type='=>'int', 'decode_binary='=>'bool'], 'SQLiteDatabase::busyTimeout' => ['', 'dbhandle'=>'', 'milliseconds'=>'int'], 'SQLiteDatabase::changes' => ['int', 'dbhandle'=>''], 'SQLiteDatabase::createAggregate' => ['', 'dbhandle'=>'', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'], 'SQLiteDatabase::createFunction' => ['', 'dbhandle'=>'', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'], 'SQLiteDatabase::exec' => ['bool', 'dbhandle'=>'', 'query'=>'string', 'error_msg='=>'string'], 'SQLiteDatabase::fetchColumnTypes' => ['array', 'table_name'=>'string', 'dbhandle'=>'', 'result_type='=>'int'], 'SQLiteDatabase::lastError' => ['int', 'dbhandle'=>''], 'SQLiteDatabase::lastInsertRowid' => ['int', 'dbhandle'=>''], 'SQLiteDatabase::query' => ['SQLiteResult', 'dbhandle'=>'', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'], 'SQLiteDatabase::queryExec' => ['bool', 'query'=>'string', '&w_error_msg='=>'string'], 'SQLiteDatabase::singleQuery' => ['array', 'db'=>'', 'query'=>'string', 'first_row_only='=>'bool', 'decode_binary='=>'bool'], 'SQLiteDatabase::unbufferedQuery' => ['SQLiteUnbuffered', 'dbhandle'=>'', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'], 'SQLiteResult::column' => ['', 'result'=>'', 'index_or_name'=>'', 'decode_binary='=>'bool'], 'SQLiteResult::current' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], 'SQLiteResult::fetch' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], 'SQLiteResult::fetchAll' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], 'SQLiteResult::fetchObject' => ['object', 'result'=>'', 'class_name='=>'string', 'ctor_params='=>'array', 'decode_binary='=>'bool'], 'SQLiteResult::fetchSingle' => ['string', 'result'=>'', 'decode_binary='=>'bool'], 'SQLiteResult::fieldName' => ['string', 'result'=>'', 'field_index'=>'int'], 'SQLiteResult::hasPrev' => ['bool', 'result'=>''], 'SQLiteResult::key' => ['int', 'result'=>''], 'SQLiteResult::next' => ['bool', 'result'=>''], 'SQLiteResult::numFields' => ['int', 'result'=>''], 'SQLiteResult::numRows' => ['int', 'result'=>''], 'SQLiteResult::prev' => ['bool', 'result'=>''], 'SQLiteResult::rewind' => ['bool', 'result'=>''], 'SQLiteResult::seek' => ['bool', 'result'=>'', 'rownum'=>'int'], 'SQLiteResult::valid' => ['bool', 'result'=>''], 'SQLiteUnbuffered::column' => ['', 'result'=>'', 'index_or_name'=>'', 'decode_binary='=>'bool'], 'SQLiteUnbuffered::current' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], 'SQLiteUnbuffered::fetch' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], 'SQLiteUnbuffered::fetchAll' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], 'SQLiteUnbuffered::fetchObject' => ['object', 'result'=>'', 'class_name='=>'string', 'ctor_params='=>'array', 'decode_binary='=>'bool'], 'SQLiteUnbuffered::fetchSingle' => ['string', 'result'=>'', 'decode_binary='=>'bool'], 'SQLiteUnbuffered::fieldName' => ['string', 'result'=>'', 'field_index'=>'int'], 'SQLiteUnbuffered::next' => ['bool', 'result'=>''], 'SQLiteUnbuffered::numFields' => ['int', 'result'=>''], 'SQLiteUnbuffered::valid' => ['bool', 'result'=>''], 'sqlsrv_begin_transaction' => ['bool', 'conn'=>'resource'], 'sqlsrv_cancel' => ['bool', 'stmt'=>'resource'], 'sqlsrv_client_info' => ['array|false', 'conn'=>'resource'], 'sqlsrv_close' => ['bool', 'conn'=>'resource'], 'sqlsrv_commit' => ['bool', 'conn'=>'resource'], 'sqlsrv_configure' => ['bool', 'setting'=>'string', 'value'=>'mixed'], 'sqlsrv_connect' => ['resource|false', 'serverName'=>'string', 'connectionInfo='=>'array'], 'sqlsrv_errors' => ['array|null', 'errorsOrWarnings='=>'int'], 'sqlsrv_execute' => ['bool', 'stmt'=>'resource'], 'sqlsrv_fetch' => ['bool|null', 'stmt'=>'resource', 'row='=>'int', 'offset='=>'int'], 'sqlsrv_fetch_array' => ['array|null|false', 'stmt'=>'resource', 'fetchType='=>'int', 'row='=>'int', 'offset='=>'int'], 'sqlsrv_fetch_object' => ['object|null|false', 'stmt'=>'resource', 'className='=>'string', 'ctorParams='=>'array', 'row='=>'int', 'offset='=>'int'], 'sqlsrv_field_metadata' => ['array|false', 'stmt'=>'resource'], 'sqlsrv_free_stmt' => ['bool', 'stmt'=>'resource'], 'sqlsrv_get_config' => ['mixed', 'setting'=>'string'], 'sqlsrv_get_field' => ['mixed', 'stmt'=>'resource', 'fieldIndex'=>'int', 'getAsType='=>'int'], 'sqlsrv_has_rows' => ['bool', 'stmt'=>'resource'], 'sqlsrv_next_result' => ['bool|null', 'stmt'=>'resource'], 'sqlsrv_num_fields' => ['int|false', 'stmt'=>'resource'], 'sqlsrv_num_rows' => ['int|false', 'stmt'=>'resource'], 'sqlsrv_prepare' => ['resource|false', 'conn'=>'resource', 'sql'=>'string', 'params='=>'array', 'options='=>'array'], 'sqlsrv_query' => ['resource|false', 'conn'=>'resource', 'sql'=>'string', 'params='=>'array', 'options='=>'array'], 'sqlsrv_rollback' => ['bool', 'conn'=>'resource'], 'sqlsrv_rows_affected' => ['int<-1,max>|false', 'stmt'=>'resource'], 'sqlsrv_send_stream_data' => ['bool', 'stmt'=>'resource'], 'sqlsrv_server_info' => ['array', 'conn'=>'resource'], 'sqrt' => ['float', 'number'=>'float'], 'srand' => ['void', 'seed='=>'int', 'mode='=>'int'], 'sscanf' => ['int|null', 'str'=>'string', 'format'=>'string', '&w_war'=>'string|int|float|null', '&...w_vars='=>'string|int|float|null'], 'sscanf\'1' => ['array|null', 'str'=>'string', 'format'=>'string'], 'ssdeep_fuzzy_compare' => ['int', 'signature1'=>'string', 'signature2'=>'string'], 'ssdeep_fuzzy_hash' => ['string', 'to_hash'=>'string'], 'ssdeep_fuzzy_hash_filename' => ['string', 'file_name'=>'string'], 'ssh2_auth_agent' => ['bool', 'session'=>'resource', 'username'=>'string'], 'ssh2_auth_hostbased_file' => ['bool', 'session'=>'resource', 'username'=>'string', 'hostname'=>'string', 'pubkeyfile'=>'string', 'privkeyfile'=>'string', 'passphrase='=>'string', 'local_username='=>'string'], 'ssh2_auth_none' => ['bool|string[]', 'session'=>'resource', 'username'=>'string'], 'ssh2_auth_password' => ['bool', 'session'=>'resource', 'username'=>'string', 'password'=>'string'], 'ssh2_auth_pubkey_file' => ['bool', 'session'=>'resource', 'username'=>'string', 'pubkeyfile'=>'string', 'privkeyfile'=>'string', 'passphrase='=>'string'], 'ssh2_connect' => ['resource|false', 'host'=>'string', 'port='=>'int', 'methods='=>'array', 'callbacks='=>'array'], 'ssh2_disconnect' => ['bool', 'session'=>'resource'], 'ssh2_exec' => ['resource|false', 'session'=>'resource', 'command'=>'string', 'pty='=>'string', 'env='=>'array', 'width='=>'int', 'height='=>'int', 'width_height_type='=>'int'], 'ssh2_fetch_stream' => ['resource|false', 'channel'=>'resource', 'streamid'=>'int'], 'ssh2_fingerprint' => ['string|false', 'session'=>'resource', 'flags='=>'int'], 'ssh2_methods_negotiated' => ['array|false', 'session'=>'resource'], 'ssh2_publickey_add' => ['bool', 'pkey'=>'resource', 'algoname'=>'string', 'blob'=>'string', 'overwrite='=>'bool', 'attributes='=>'array'], 'ssh2_publickey_init' => ['resource|false', 'session'=>'resource'], 'ssh2_publickey_list' => ['array|false', 'pkey'=>'resource'], 'ssh2_publickey_remove' => ['bool', 'pkey'=>'resource', 'algoname'=>'string', 'blob'=>'string'], 'ssh2_scp_recv' => ['bool', 'session'=>'resource', 'remote_file'=>'string', 'local_file'=>'string'], 'ssh2_scp_send' => ['bool', 'session'=>'resource', 'local_file'=>'string', 'remote_file'=>'string', 'create_mode='=>'int'], 'ssh2_sftp' => ['resource|false', 'session'=>'resource'], 'ssh2_sftp_chmod' => ['bool', 'sftp'=>'resource', 'filename'=>'string', 'mode'=>'int'], 'ssh2_sftp_lstat' => ['array|false', 'sftp'=>'resource', 'path'=>'string'], 'ssh2_sftp_mkdir' => ['bool', 'sftp'=>'resource', 'dirname'=>'string', 'mode='=>'int', 'recursive='=>'bool'], 'ssh2_sftp_readlink' => ['string|false', 'sftp'=>'resource', 'link'=>'string'], 'ssh2_sftp_realpath' => ['string|false', 'sftp'=>'resource', 'filename'=>'string'], 'ssh2_sftp_rename' => ['bool', 'sftp'=>'resource', 'from'=>'string', 'to'=>'string'], 'ssh2_sftp_rmdir' => ['bool', 'sftp'=>'resource', 'dirname'=>'string'], 'ssh2_sftp_stat' => ['array|false', 'sftp'=>'resource', 'path'=>'string'], 'ssh2_sftp_symlink' => ['bool', 'sftp'=>'resource', 'target'=>'string', 'link'=>'string'], 'ssh2_sftp_unlink' => ['bool', 'sftp'=>'resource', 'filename'=>'string'], 'ssh2_shell' => ['resource|false', 'session'=>'resource', 'term_type='=>'string', 'env='=>'array', 'width='=>'int', 'height='=>'int', 'width_height_type='=>'int'], 'ssh2_tunnel' => ['resource|false', 'session'=>'resource', 'host'=>'string', 'port'=>'int'], 'stat' => ['array|false', 'filename'=>'string'], 'stats_absolute_deviation' => ['float', 'a'=>'array'], 'stats_cdf_beta' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_cdf_binomial' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_cdf_cauchy' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_cdf_chisquare' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'], 'stats_cdf_exponential' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'], 'stats_cdf_f' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_cdf_gamma' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_cdf_laplace' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_cdf_logistic' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_cdf_negative_binomial' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_cdf_noncentral_chisquare' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_cdf_noncentral_f' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'par4'=>'float', 'which'=>'int'], 'stats_cdf_noncentral_t' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_cdf_normal' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_cdf_poisson' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'], 'stats_cdf_t' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'], 'stats_cdf_uniform' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_cdf_weibull' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_covariance' => ['float', 'a'=>'array', 'b'=>'array'], 'stats_den_uniform' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'], 'stats_dens_beta' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'], 'stats_dens_cauchy' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'], 'stats_dens_chisquare' => ['float', 'x'=>'float', 'dfr'=>'float'], 'stats_dens_exponential' => ['float', 'x'=>'float', 'scale'=>'float'], 'stats_dens_f' => ['float', 'x'=>'float', 'dfr1'=>'float', 'dfr2'=>'float'], 'stats_dens_gamma' => ['float', 'x'=>'float', 'shape'=>'float', 'scale'=>'float'], 'stats_dens_laplace' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'], 'stats_dens_logistic' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'], 'stats_dens_negative_binomial' => ['float', 'x'=>'float', 'n'=>'float', 'pi'=>'float'], 'stats_dens_normal' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'], 'stats_dens_pmf_binomial' => ['float', 'x'=>'float', 'n'=>'float', 'pi'=>'float'], 'stats_dens_pmf_hypergeometric' => ['float', 'n1'=>'float', 'n2'=>'float', 'N1'=>'float', 'N2'=>'float'], 'stats_dens_pmf_negative_binomial' => ['float', 'x'=>'float', 'n'=>'float', 'pi'=>'float'], 'stats_dens_pmf_poisson' => ['float', 'x'=>'float', 'lb'=>'float'], 'stats_dens_t' => ['float', 'x'=>'float', 'dfr'=>'float'], 'stats_dens_uniform' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'], 'stats_dens_weibull' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'], 'stats_harmonic_mean' => ['float', 'a'=>'array'], 'stats_kurtosis' => ['float', 'a'=>'array'], 'stats_rand_gen_beta' => ['float', 'a'=>'float', 'b'=>'float'], 'stats_rand_gen_chisquare' => ['float', 'df'=>'float'], 'stats_rand_gen_exponential' => ['float', 'av'=>'float'], 'stats_rand_gen_f' => ['float', 'dfn'=>'float', 'dfd'=>'float'], 'stats_rand_gen_funiform' => ['float', 'low'=>'float', 'high'=>'float'], 'stats_rand_gen_gamma' => ['float', 'a'=>'float', 'r'=>'float'], 'stats_rand_gen_ibinomial' => ['int', 'n'=>'int', 'pp'=>'float'], 'stats_rand_gen_ibinomial_negative' => ['int', 'n'=>'int', 'p'=>'float'], 'stats_rand_gen_int' => ['int'], 'stats_rand_gen_ipoisson' => ['int', 'mu'=>'float'], 'stats_rand_gen_iuniform' => ['int', 'low'=>'int', 'high'=>'int'], 'stats_rand_gen_noncenral_chisquare' => ['float', 'df'=>'float', 'xnonc'=>'float'], 'stats_rand_gen_noncentral_chisquare' => ['float', 'df'=>'float', 'xnonc'=>'float'], 'stats_rand_gen_noncentral_f' => ['float', 'dfn'=>'float', 'dfd'=>'float', 'xnonc'=>'float'], 'stats_rand_gen_noncentral_t' => ['float', 'df'=>'float', 'xnonc'=>'float'], 'stats_rand_gen_normal' => ['float', 'av'=>'float', 'sd'=>'float'], 'stats_rand_gen_t' => ['float', 'df'=>'float'], 'stats_rand_get_seeds' => ['array'], 'stats_rand_phrase_to_seeds' => ['array', 'phrase'=>'string'], 'stats_rand_ranf' => ['float'], 'stats_rand_setall' => ['void', 'iseed1'=>'int', 'iseed2'=>'int'], 'stats_skew' => ['float', 'a'=>'array'], 'stats_standard_deviation' => ['float', 'a'=>'array', 'sample='=>'bool'], 'stats_stat_binomial_coef' => ['float', 'x'=>'int', 'n'=>'int'], 'stats_stat_correlation' => ['float', 'arr1'=>'array', 'arr2'=>'array'], 'stats_stat_factorial' => ['float', 'n'=>'int'], 'stats_stat_gennch' => ['float', 'n'=>'int'], 'stats_stat_independent_t' => ['float', 'arr1'=>'array', 'arr2'=>'array'], 'stats_stat_innerproduct' => ['float', 'arr1'=>'array', 'arr2'=>'array'], 'stats_stat_noncentral_t' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], 'stats_stat_paired_t' => ['float', 'arr1'=>'array', 'arr2'=>'array'], 'stats_stat_percentile' => ['float', 'df'=>'float', 'xnonc'=>'float'], 'stats_stat_powersum' => ['float', 'arr'=>'array', 'power'=>'float'], 'stats_variance' => ['float', 'a'=>'array', 'sample='=>'bool'], 'Stomp::__construct' => ['void', 'broker='=>'string', 'username='=>'string', 'password='=>'string', 'headers='=>'array'], 'Stomp::__destruct' => ['bool', 'link'=>''], 'Stomp::abort' => ['bool', 'transaction_id'=>'string', 'headers='=>'array', 'link='=>''], 'Stomp::ack' => ['bool', 'msg'=>'', 'headers='=>'array', 'link='=>''], 'Stomp::begin' => ['bool', 'transaction_id'=>'string', 'headers='=>'array', 'link='=>''], 'Stomp::commit' => ['bool', 'transaction_id'=>'string', 'headers='=>'array', 'link='=>''], 'Stomp::error' => ['string', 'link'=>''], 'Stomp::getReadTimeout' => ['array', 'link'=>''], 'Stomp::getSessionId' => ['string', 'link'=>''], 'Stomp::hasFrame' => ['bool', 'link'=>''], 'Stomp::readFrame' => ['array', 'class_name='=>'string', 'link='=>''], 'Stomp::send' => ['bool', 'destination'=>'string', 'msg'=>'', 'headers='=>'array', 'link='=>''], 'Stomp::setReadTimeout' => ['', 'seconds'=>'int', 'microseconds='=>'int', 'link='=>''], 'Stomp::subscribe' => ['bool', 'destination'=>'string', 'headers='=>'array', 'link='=>''], 'Stomp::unsubscribe' => ['bool', 'destination'=>'string', 'headers='=>'array', 'link='=>''], 'stomp_abort' => ['bool', 'transaction_id'=>'string', 'headers='=>'array', 'link='=>''], 'stomp_ack' => ['bool', 'msg'=>'', 'headers='=>'array', 'link='=>''], 'stomp_begin' => ['bool', 'transaction_id'=>'string', 'headers='=>'array', 'link='=>''], 'stomp_close' => ['bool', 'link'=>''], 'stomp_commit' => ['bool', 'transaction_id'=>'string', 'headers='=>'array', 'link='=>''], 'stomp_connect' => ['resource', 'broker='=>'string', 'username='=>'string', 'password='=>'string', 'headers='=>'array'], 'stomp_connect_error' => ['string'], 'stomp_error' => ['string', 'link'=>''], 'stomp_get_read_timeout' => ['array', 'link'=>''], 'stomp_get_session_id' => ['string', 'link'=>''], 'stomp_has_frame' => ['bool', 'link'=>''], 'stomp_read_frame' => ['array', 'class_name='=>'string', 'link='=>''], 'stomp_send' => ['bool', 'destination'=>'string', 'msg'=>'', 'headers='=>'array', 'link='=>''], 'stomp_set_read_timeout' => ['', 'seconds'=>'int', 'microseconds='=>'int', 'link='=>''], 'stomp_subscribe' => ['bool', 'destination'=>'string', 'headers='=>'array', 'link='=>''], 'stomp_unsubscribe' => ['bool', 'destination'=>'string', 'headers='=>'array', 'link='=>''], 'stomp_version' => ['string'], 'StompException::getDetails' => ['string'], 'StompFrame::__construct' => ['void', 'command='=>'string', 'headers='=>'array', 'body='=>'string'], 'str_getcsv' => ['non-empty-list', 'input'=>'string', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'], 'str_ireplace' => ['string|string[]', 'search'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', '&w_replace_count='=>'int'], 'str_pad' => ['string', 'input'=>'string', 'pad_length'=>'int', 'pad_string='=>'string', 'pad_type='=>'int'], 'str_repeat' => ['string', 'input'=>'string', 'multiplier'=>'int'], 'str_replace' => ['string|array', 'search'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', '&w_replace_count='=>'int'], 'str_rot13' => ['string', 'str'=>'string'], 'str_shuffle' => ['string', 'str'=>'string'], 'str_split' => ['non-empty-list|false', 'str'=>'string', 'split_length='=>'positive-int'], 'str_word_count' => ['array|int|false', 'string'=>'string', 'format='=>'int', 'charlist='=>'string'], 'strcasecmp' => ['int<-1, 1>', 'str1'=>'string', 'str2'=>'string'], 'strchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'], 'strcmp' => ['int<-1, 1>', 'str1'=>'string', 'str2'=>'string'], 'strcoll' => ['int<-1, 1>', 'str1'=>'string', 'str2'=>'string'], 'strcspn' => ['int', 'str'=>'string', 'mask'=>'string', 'start='=>'int', 'length='=>'int'], 'stream_bucket_append' => ['void', 'brigade'=>'resource', 'bucket'=>'object'], 'stream_bucket_make_writeable' => ['stdClass|null', 'brigade'=>'resource'], 'stream_bucket_new' => ['object', 'stream'=>'resource', 'buffer'=>'string'], 'stream_bucket_prepend' => ['void', 'brigade'=>'resource', 'bucket'=>'object'], 'stream_context_create' => ['resource', 'options='=>'array', 'params='=>'array'], 'stream_context_get_default' => ['resource', 'options='=>'array'], 'stream_context_get_options' => ['array', 'context'=>'resource'], 'stream_context_get_params' => ['array{notification:string, options:array}', 'context'=>'resource'], 'stream_context_set_default' => ['resource', 'options'=>'array'], 'stream_context_set_option' => ['bool', 'context'=>'', 'wrappername'=>'string', 'optionname'=>'string', 'value'=>''], 'stream_context_set_option\'1' => ['bool', 'context'=>'', 'options'=>'array'], 'stream_context_set_params' => ['bool', 'context'=>'resource', 'options'=>'array'], 'stream_copy_to_stream' => ['int|false', 'source'=>'resource', 'dest'=>'resource', 'maxlen='=>'int', 'pos='=>'int'], 'stream_encoding' => ['bool', 'stream'=>'resource', 'encoding='=>'string'], 'stream_filter_append' => ['resource|false', 'stream'=>'resource', 'filtername'=>'string', 'read_write='=>'int', 'filterparams='=>'array'], 'stream_filter_prepend' => ['resource|false', 'stream'=>'resource', 'filtername'=>'string', 'read_write='=>'int', 'filterparams='=>'array'], 'stream_filter_register' => ['bool', 'filtername'=>'string', 'classname'=>'string'], 'stream_filter_remove' => ['bool', 'stream_filter'=>'resource'], 'stream_get_contents' => ['string|false', 'source'=>'resource', 'maxlen='=>'int', 'offset='=>'int'], 'stream_get_filters' => ['list'], 'stream_get_line' => ['string|false', 'stream'=>'resource', 'maxlen'=>'int', 'ending='=>'string'], 'stream_get_meta_data' => ['array{timed_out:bool,blocked:bool,eof:bool,unread_bytes:int,stream_type:string,wrapper_type:string,wrapper_data:mixed,mode:string,seekable:bool,uri?:string,mediatype?:string,base64?:bool}', 'fp'=>'resource'], 'stream_get_transports' => ['list'], 'stream_get_wrappers' => ['list'], 'stream_is_local' => ['bool', 'stream'=>'resource|string'], 'stream_isatty' => ['bool', 'stream'=>'resource'], 'stream_notification_callback' => ['callback', 'notification_code'=>'int', 'severity'=>'int', 'message'=>'string', 'message_code'=>'int', 'bytes_transferred'=>'int', 'bytes_max'=>'int'], 'stream_resolve_include_path' => ['string|false', 'filename'=>'string'], 'stream_select' => ['int|false', '&rw_read_streams'=>'resource[]|null', '&rw_write_streams'=>'resource[]|null', '&rw_except_streams'=>'resource[]|null', 'tv_sec'=>'?int', 'tv_usec='=>'?int'], 'stream_set_blocking' => ['bool', 'socket'=>'resource', 'mode'=>'bool'], 'stream_set_chunk_size' => ['int|false', 'fp'=>'resource', 'chunk_size'=>'int'], 'stream_set_read_buffer' => ['int', 'fp'=>'resource', 'buffer'=>'int'], 'stream_set_timeout' => ['bool', 'stream'=>'resource', 'seconds'=>'int', 'microseconds='=>'int'], 'stream_set_write_buffer' => ['int', 'fp'=>'resource', 'buffer'=>'int'], 'stream_socket_accept' => ['resource|false', 'serverstream'=>'resource', 'timeout='=>'float', '&w_peername='=>'string'], 'stream_socket_client' => ['resource|false', 'remoteaddress'=>'string', '&w_errcode='=>'int', '&w_errstring='=>'string', 'timeout='=>'float', 'flags='=>'int', 'context='=>'resource'], 'stream_socket_enable_crypto' => ['0|bool', 'stream'=>'resource', 'enable'=>'bool', 'cryptokind='=>'int', 'sessionstream='=>'resource'], 'stream_socket_get_name' => ['string|false', 'stream'=>'resource', 'want_peer'=>'bool'], 'stream_socket_pair' => ['resource[]|false', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int'], 'stream_socket_recvfrom' => ['string|false', 'stream'=>'resource', 'amount'=>'int', 'flags='=>'int', '&w_remote_addr='=>'string'], 'stream_socket_sendto' => ['int|false', 'stream'=>'resource', 'data'=>'string', 'flags='=>'int', 'target_addr='=>'string'], 'stream_socket_server' => ['resource|false', 'localaddress'=>'string', '&w_errcode='=>'int', '&w_errstring='=>'string', 'flags='=>'int', 'context='=>'resource'], 'stream_socket_shutdown' => ['bool', 'stream'=>'resource', 'how'=>'int'], 'stream_supports_lock' => ['bool', 'stream'=>'resource'], 'stream_wrapper_register' => ['bool', 'protocol'=>'string', 'classname'=>'string', 'flags='=>'int'], 'stream_wrapper_restore' => ['bool', 'protocol'=>'string'], 'stream_wrapper_unregister' => ['bool', 'protocol'=>'string'], 'streamWrapper::__construct' => ['void'], 'streamWrapper::__destruct' => [''], 'streamWrapper::dir_closedir' => ['bool'], 'streamWrapper::dir_opendir' => ['bool', 'path'=>'string', 'options'=>'int'], 'streamWrapper::dir_readdir' => ['string'], 'streamWrapper::dir_rewinddir' => ['bool'], 'streamWrapper::mkdir' => ['bool', 'path'=>'string', 'mode'=>'int', 'options'=>'int'], 'streamWrapper::rename' => ['bool', 'path_from'=>'string', 'path_to'=>'string'], 'streamWrapper::rmdir' => ['bool', 'path'=>'string', 'options'=>'int'], 'streamWrapper::stream_cast' => ['resource', 'cast_as'=>'int'], 'streamWrapper::stream_close' => ['void'], 'streamWrapper::stream_eof' => ['bool'], 'streamWrapper::stream_flush' => ['bool'], 'streamWrapper::stream_lock' => ['bool', 'operation'=>'mode'], 'streamWrapper::stream_metadata' => ['bool', 'path'=>'string', 'option'=>'int', 'value'=>'mixed'], 'streamWrapper::stream_open' => ['bool', 'path'=>'string', 'mode'=>'string', 'options'=>'int', 'opened_path'=>'string'], 'streamWrapper::stream_read' => ['string', 'count'=>'int'], 'streamWrapper::stream_seek' => ['bool', 'offset'=>'int', 'whence'=>'int'], 'streamWrapper::stream_set_option' => ['bool', 'option'=>'int', 'arg1'=>'int', 'arg2'=>'int'], 'streamWrapper::stream_stat' => ['array'], 'streamWrapper::stream_tell' => ['int'], 'streamWrapper::stream_truncate' => ['bool', 'new_size'=>'int'], 'streamWrapper::stream_write' => ['int', 'data'=>'string'], 'streamWrapper::unlink' => ['bool', 'path'=>'string'], 'streamWrapper::url_stat' => ['array', 'path'=>'string', 'flags'=>'int'], 'strftime' => ['string|false', 'format'=>'string', 'timestamp='=>'int'], 'strip_tags' => ['string', 'str'=>'string', 'allowable_tags='=>'string'], 'stripcslashes' => ['string', 'str'=>'string'], 'stripos' => ['0|positive-int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'], 'stripslashes' => ['string', 'str'=>'string'], 'stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'mixed', 'before_needle='=>'bool'], 'strlen' => ['0|positive-int', 'string'=>'string'], 'strnatcasecmp' => ['int<-1, 1>', 's1'=>'string', 's2'=>'string'], 'strnatcmp' => ['int<-1, 1>', 's1'=>'string', 's2'=>'string'], 'strncasecmp' => ['int<-1, 1>', 'str1'=>'string', 'str2'=>'string', 'len'=>'int'], 'strncmp' => ['int<-1, 1>', 'str1'=>'string', 'str2'=>'string', 'len'=>'int'], 'strpbrk' => ['string|false', 'haystack'=>'string', 'char_list'=>'string'], 'strpos' => ['positive-int|0|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'], 'strptime' => ['array|false', 'datestr'=>'string', 'format'=>'string'], 'strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'mixed'], 'strrev' => ['string', 'str'=>'string'], 'strripos' => ['0|positive-int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'], 'strrpos' => ['0|positive-int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'], 'strspn' => ['int', 'str'=>'string', 'mask'=>'string', 'start='=>'int', 'len='=>'int'], 'strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'mixed', 'before_needle='=>'bool'], 'strtok' => ['non-empty-string|false', 'str'=>'string', 'token'=>'string'], 'strtok\'1' => ['non-empty-string|false', 'token'=>'string'], 'strtolower' => ['lowercase-string', 'str'=>'string'], 'strtotime' => ['int|false', 'time'=>'string', 'now='=>'int'], 'strtoupper' => ['uppercase-string', 'str'=>'string'], 'strtr' => ['string', 'str'=>'string', 'from'=>'string', 'to'=>'string'], 'strtr\'1' => ['string', 'str'=>'string', 'replace_pairs'=>'array'], 'strval' => ['string', 'var'=>'__stringAndStringable|int|float|bool|resource|null'], 'substr' => ['__benevolent', 'string'=>'string', 'start'=>'int', 'length='=>'int'], 'substr_compare' => ['int<-1, 1>|false', 'main_str'=>'string', 'str'=>'string', 'offset'=>'int', 'length='=>'int', 'case_sensitivity='=>'bool'], 'substr_count' => ['0|positive-int', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'length='=>'int'], 'substr_replace' => ['string|array', 'str'=>'string|array', 'repl'=>'mixed', 'start'=>'mixed', 'length='=>'mixed'], 'suhosin_encrypt_cookie' => ['string', 'name'=>'string', 'value'=>'string'], 'suhosin_get_raw_cookies' => ['array'], 'SVM::__construct' => ['void'], 'svm::crossvalidate' => ['float', 'problem'=>'array', 'number_of_folds'=>'int'], 'SVM::getOptions' => ['array'], 'SVM::setOptions' => ['bool', 'params'=>'array'], 'svm::train' => ['SVMModel', 'problem'=>'array', 'weights='=>'array'], 'SVMModel::__construct' => ['void', 'filename='=>'string'], 'SVMModel::checkProbabilityModel' => ['bool'], 'SVMModel::getLabels' => ['array'], 'SVMModel::getNrClass' => ['int'], 'SVMModel::getSvmType' => ['int'], 'SVMModel::getSvrProbability' => ['float'], 'SVMModel::load' => ['bool', 'filename'=>'string'], 'SVMModel::predict' => ['float', 'data'=>'array'], 'SVMModel::predict_probability' => ['float', 'data'=>'array'], 'SVMModel::save' => ['bool', 'filename'=>'string'], 'svn_add' => ['bool', 'path'=>'string', 'recursive='=>'bool', 'force='=>'bool'], 'svn_auth_get_parameter' => ['string', 'key'=>'string'], 'svn_auth_set_parameter' => ['void', 'key'=>'string', 'value'=>'string'], 'svn_blame' => ['array', 'repository_url'=>'string', 'revision_no='=>'int'], 'svn_cat' => ['string', 'repos_url'=>'string', 'revision_no='=>'int'], 'svn_checkout' => ['bool', 'repos'=>'string', 'targetpath'=>'string', 'revision='=>'int', 'flags='=>'int'], 'svn_cleanup' => ['bool', 'workingdir'=>'string'], 'svn_client_version' => ['string'], 'svn_commit' => ['array', 'log'=>'string', 'targets'=>'array', 'dontrecurse='=>'bool'], 'svn_delete' => ['bool', 'path'=>'string', 'force='=>'bool'], 'svn_diff' => ['array', 'path1'=>'string', 'rev1'=>'int', 'path2'=>'string', 'rev2'=>'int'], 'svn_export' => ['bool', 'frompath'=>'string', 'topath'=>'string', 'working_copy='=>'bool', 'revision_no='=>'int'], 'svn_fs_abort_txn' => ['bool', 'txn'=>'resource'], 'svn_fs_apply_text' => ['resource', 'root'=>'resource', 'path'=>'string'], 'svn_fs_begin_txn2' => ['resource', 'repos'=>'resource', 'rev'=>'int'], 'svn_fs_change_node_prop' => ['bool', 'root'=>'resource', 'path'=>'string', 'name'=>'string', 'value'=>'string'], 'svn_fs_check_path' => ['int', 'fsroot'=>'resource', 'path'=>'string'], 'svn_fs_contents_changed' => ['bool', 'root1'=>'resource', 'path1'=>'string', 'root2'=>'resource', 'path2'=>'string'], 'svn_fs_copy' => ['bool', 'from_root'=>'resource', 'from_path'=>'string', 'to_root'=>'resource', 'to_path'=>'string'], 'svn_fs_delete' => ['bool', 'root'=>'resource', 'path'=>'string'], 'svn_fs_dir_entries' => ['array', 'fsroot'=>'resource', 'path'=>'string'], 'svn_fs_file_contents' => ['resource', 'fsroot'=>'resource', 'path'=>'string'], 'svn_fs_file_length' => ['int', 'fsroot'=>'resource', 'path'=>'string'], 'svn_fs_is_dir' => ['bool', 'root'=>'resource', 'path'=>'string'], 'svn_fs_is_file' => ['bool', 'root'=>'resource', 'path'=>'string'], 'svn_fs_make_dir' => ['bool', 'root'=>'resource', 'path'=>'string'], 'svn_fs_make_file' => ['bool', 'root'=>'resource', 'path'=>'string'], 'svn_fs_node_created_rev' => ['int', 'fsroot'=>'resource', 'path'=>'string'], 'svn_fs_node_prop' => ['string', 'fsroot'=>'resource', 'path'=>'string', 'propname'=>'string'], 'svn_fs_props_changed' => ['bool', 'root1'=>'resource', 'path1'=>'string', 'root2'=>'resource', 'path2'=>'string'], 'svn_fs_revision_prop' => ['string', 'fs'=>'resource', 'revnum'=>'int', 'propname'=>'string'], 'svn_fs_revision_root' => ['resource', 'fs'=>'resource', 'revnum'=>'int'], 'svn_fs_txn_root' => ['resource', 'txn'=>'resource'], 'svn_fs_youngest_rev' => ['int', 'fs'=>'resource'], 'svn_import' => ['bool', 'path'=>'string', 'url'=>'string', 'nonrecursive'=>'bool'], 'svn_log' => ['array', 'repos_url'=>'string', 'start_revision='=>'int', 'end_revision='=>'int', 'limit='=>'int', 'flags='=>'int'], 'svn_ls' => ['array', 'repos_url'=>'string', 'revision_no='=>'int', 'recurse='=>'bool', 'peg='=>'bool'], 'svn_mkdir' => ['bool', 'path'=>'string', 'log_message='=>'string'], 'svn_move' => ['mixed', 'src_path'=>'string', 'dst_path'=>'string', 'force='=>'bool|false'], 'svn_propget' => ['mixed', 'path'=>'string', 'property_name'=>'string', 'recurse='=>'bool|false', 'revision='=>'int'], 'svn_proplist' => ['mixed', 'path'=>'string', 'recurse='=>'bool|false', 'revision='=>'int'], 'svn_repos_create' => ['resource', 'path'=>'string', 'config='=>'array', 'fsconfig='=>'array'], 'svn_repos_fs' => ['resource', 'repos'=>'resource'], 'svn_repos_fs_begin_txn_for_commit' => ['resource', 'repos'=>'resource', 'rev'=>'int', 'author'=>'string', 'log_msg'=>'string'], 'svn_repos_fs_commit_txn' => ['int', 'txn'=>'resource'], 'svn_repos_hotcopy' => ['bool', 'repospath'=>'string', 'destpath'=>'string', 'cleanlogs'=>'bool'], 'svn_repos_open' => ['resource', 'path'=>'string'], 'svn_repos_recover' => ['bool', 'path'=>'string'], 'svn_revert' => ['bool', 'path'=>'string', 'recursive='=>'bool'], 'svn_status' => ['array', 'path'=>'string', 'flags='=>'int'], 'svn_update' => ['int', 'path'=>'string', 'revno='=>'int', 'recurse='=>'bool'], 'swf_actiongeturl' => ['', 'url'=>'string', 'target'=>'string'], 'swf_actiongotoframe' => ['', 'framenumber'=>'int'], 'swf_actiongotolabel' => ['', 'label'=>'string'], 'swf_actionnextframe' => [''], 'swf_actionplay' => [''], 'swf_actionprevframe' => [''], 'swf_actionsettarget' => ['', 'target'=>'string'], 'swf_actionstop' => [''], 'swf_actiontogglequality' => [''], 'swf_actionwaitforframe' => ['', 'framenumber'=>'int', 'skipcount'=>'int'], 'swf_addbuttonrecord' => ['', 'states'=>'int', 'shapeid'=>'int', 'depth'=>'int'], 'swf_addcolor' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float'], 'swf_closefile' => ['', 'return_file='=>'int'], 'swf_definebitmap' => ['', 'objid'=>'int', 'image_name'=>'string'], 'swf_definefont' => ['', 'fontid'=>'int', 'fontname'=>'string'], 'swf_defineline' => ['', 'objid'=>'int', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'width'=>'float'], 'swf_definepoly' => ['', 'objid'=>'int', 'coords'=>'array', 'npoints'=>'int', 'width'=>'float'], 'swf_definerect' => ['', 'objid'=>'int', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'width'=>'float'], 'swf_definetext' => ['', 'objid'=>'int', 'str'=>'string', 'docenter'=>'int'], 'swf_endbutton' => [''], 'swf_enddoaction' => [''], 'swf_endshape' => [''], 'swf_endsymbol' => [''], 'swf_fontsize' => ['', 'size'=>'float'], 'swf_fontslant' => ['', 'slant'=>'float'], 'swf_fonttracking' => ['', 'tracking'=>'float'], 'swf_getbitmapinfo' => ['array', 'bitmapid'=>'int'], 'swf_getfontinfo' => ['array'], 'swf_getframe' => ['int'], 'swf_labelframe' => ['', 'name'=>'string'], 'swf_lookat' => ['', 'view_x'=>'float', 'view_y'=>'float', 'view_z'=>'float', 'reference_x'=>'float', 'reference_y'=>'float', 'reference_z'=>'float', 'twist'=>'float'], 'swf_modifyobject' => ['', 'depth'=>'int', 'how'=>'int'], 'swf_mulcolor' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float'], 'swf_nextid' => ['int'], 'swf_oncondition' => ['', 'transition'=>'int'], 'swf_openfile' => ['', 'filename'=>'string', 'width'=>'float', 'height'=>'float', 'framerate'=>'float', 'r'=>'float', 'g'=>'float', 'b'=>'float'], 'swf_ortho' => ['', 'xmin'=>'float', 'xmax'=>'float', 'ymin'=>'float', 'ymax'=>'float', 'zmin'=>'float', 'zmax'=>'float'], 'swf_ortho2' => ['', 'xmin'=>'float', 'xmax'=>'float', 'ymin'=>'float', 'ymax'=>'float'], 'swf_perspective' => ['', 'fovy'=>'float', 'aspect'=>'float', 'near'=>'float', 'far'=>'float'], 'swf_placeobject' => ['', 'objid'=>'int', 'depth'=>'int'], 'swf_polarview' => ['', 'dist'=>'float', 'azimuth'=>'float', 'incidence'=>'float', 'twist'=>'float'], 'swf_popmatrix' => [''], 'swf_posround' => ['', 'round'=>'int'], 'swf_pushmatrix' => [''], 'swf_removeobject' => ['', 'depth'=>'int'], 'swf_rotate' => ['', 'angle'=>'float', 'axis'=>'string'], 'swf_scale' => ['', 'x'=>'float', 'y'=>'float', 'z'=>'float'], 'swf_setfont' => ['', 'fontid'=>'int'], 'swf_setframe' => ['', 'framenumber'=>'int'], 'swf_shapearc' => ['', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'ang1'=>'float', 'ang2'=>'float'], 'swf_shapecurveto' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float'], 'swf_shapecurveto3' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'], 'swf_shapefillbitmapclip' => ['', 'bitmapid'=>'int'], 'swf_shapefillbitmaptile' => ['', 'bitmapid'=>'int'], 'swf_shapefilloff' => [''], 'swf_shapefillsolid' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float'], 'swf_shapelinesolid' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float', 'width'=>'float'], 'swf_shapelineto' => ['', 'x'=>'float', 'y'=>'float'], 'swf_shapemoveto' => ['', 'x'=>'float', 'y'=>'float'], 'swf_showframe' => [''], 'swf_startbutton' => ['', 'objid'=>'int', 'type'=>'int'], 'swf_startdoaction' => [''], 'swf_startshape' => ['', 'objid'=>'int'], 'swf_startsymbol' => ['', 'objid'=>'int'], 'swf_textwidth' => ['float', 'str'=>'string'], 'swf_translate' => ['', 'x'=>'float', 'y'=>'float', 'z'=>'float'], 'swf_viewport' => ['', 'xmin'=>'float', 'xmax'=>'float', 'ymin'=>'float', 'ymax'=>'float'], 'SWFAction::__construct' => ['void', 'script'=>'string'], 'SWFBitmap::__construct' => ['void', 'file'=>'', 'alphafile='=>''], 'SWFBitmap::getHeight' => ['float'], 'SWFBitmap::getWidth' => ['float'], 'SWFButton::__construct' => ['void'], 'SWFButton::addAction' => ['void', 'action'=>'swfaction', 'flags'=>'int'], 'SWFButton::addASound' => ['SWFSoundInstance', 'sound'=>'swfsound', 'flags'=>'int'], 'SWFButton::addShape' => ['void', 'shape'=>'swfshape', 'flags'=>'int'], 'SWFButton::setAction' => ['void', 'action'=>'swfaction'], 'SWFButton::setDown' => ['void', 'shape'=>'swfshape'], 'SWFButton::setHit' => ['void', 'shape'=>'swfshape'], 'SWFButton::setMenu' => ['void', 'flag'=>'int'], 'SWFButton::setOver' => ['void', 'shape'=>'swfshape'], 'SWFButton::setUp' => ['void', 'shape'=>'swfshape'], 'SWFDisplayItem::addAction' => ['void', 'action'=>'swfaction', 'flags'=>'int'], 'SWFDisplayItem::addColor' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'SWFDisplayItem::endMask' => ['void'], 'SWFDisplayItem::getRot' => ['float'], 'SWFDisplayItem::getX' => ['float'], 'SWFDisplayItem::getXScale' => ['float'], 'SWFDisplayItem::getXSkew' => ['float'], 'SWFDisplayItem::getY' => ['float'], 'SWFDisplayItem::getYScale' => ['float'], 'SWFDisplayItem::getYSkew' => ['float'], 'SWFDisplayItem::move' => ['void', 'dx'=>'float', 'dy'=>'float'], 'SWFDisplayItem::moveTo' => ['void', 'x'=>'float', 'y'=>'float'], 'SWFDisplayItem::multColor' => ['void', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'a='=>'float'], 'SWFDisplayItem::remove' => ['void'], 'SWFDisplayItem::rotate' => ['void', 'angle'=>'float'], 'SWFDisplayItem::rotateTo' => ['void', 'angle'=>'float'], 'SWFDisplayItem::scale' => ['void', 'dx'=>'float', 'dy'=>'float'], 'SWFDisplayItem::scaleTo' => ['void', 'x'=>'float', 'y='=>'float'], 'SWFDisplayItem::setDepth' => ['void', 'depth'=>'int'], 'SWFDisplayItem::setMaskLevel' => ['void', 'level'=>'int'], 'SWFDisplayItem::setMatrix' => ['void', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'x'=>'float', 'y'=>'float'], 'SWFDisplayItem::setName' => ['void', 'name'=>'string'], 'SWFDisplayItem::setRatio' => ['void', 'ratio'=>'float'], 'SWFDisplayItem::skewX' => ['void', 'ddegrees'=>'float'], 'SWFDisplayItem::skewXTo' => ['void', 'degrees'=>'float'], 'SWFDisplayItem::skewY' => ['void', 'ddegrees'=>'float'], 'SWFDisplayItem::skewYTo' => ['void', 'degrees'=>'float'], 'SWFFill::moveTo' => ['void', 'x'=>'float', 'y'=>'float'], 'SWFFill::rotateTo' => ['void', 'angle'=>'float'], 'SWFFill::scaleTo' => ['void', 'x'=>'float', 'y='=>'float'], 'SWFFill::skewXTo' => ['void', 'x'=>'float'], 'SWFFill::skewYTo' => ['void', 'y'=>'float'], 'SWFFont::__construct' => ['void', 'filename'=>'string'], 'SWFFont::getAscent' => ['float'], 'SWFFont::getDescent' => ['float'], 'SWFFont::getLeading' => ['float'], 'SWFFont::getShape' => ['string', 'code'=>'int'], 'SWFFont::getUTF8Width' => ['float', 'string'=>'string'], 'SWFFont::getWidth' => ['float', 'string'=>'string'], 'SWFFontChar::addChars' => ['void', 'char'=>'string'], 'SWFFontChar::addUTF8Chars' => ['void', 'char'=>'string'], 'SWFGradient::__construct' => ['void'], 'SWFGradient::addEntry' => ['void', 'ratio'=>'float', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int'], 'SWFMorph::__construct' => ['void'], 'SWFMorph::getShape1' => ['SWFShape'], 'SWFMorph::getShape2' => ['SWFShape'], 'SWFMovie::__construct' => ['void', 'version='=>'int'], 'SWFMovie::add' => ['mixed', 'instance'=>'object'], 'SWFMovie::addExport' => ['void', 'char'=>'swfcharacter', 'name'=>'string'], 'SWFMovie::addFont' => ['mixed', 'font'=>'swffont'], 'SWFMovie::importChar' => ['SWFSprite', 'libswf'=>'string', 'name'=>'string'], 'SWFMovie::importFont' => ['SWFFontChar', 'libswf'=>'string', 'name'=>'string'], 'SWFMovie::labelFrame' => ['void', 'label'=>'string'], 'SWFMovie::nextFrame' => ['void'], 'SWFMovie::output' => ['int', 'compression='=>'int'], 'SWFMovie::remove' => ['void', 'instance'=>'object'], 'SWFMovie::save' => ['int', 'filename'=>'string', 'compression='=>'int'], 'SWFMovie::saveToFile' => ['int', 'x'=>'resource', 'compression='=>'int'], 'SWFMovie::setbackground' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], 'SWFMovie::setDimension' => ['void', 'width'=>'float', 'height'=>'float'], 'SWFMovie::setFrames' => ['void', 'number'=>'int'], 'SWFMovie::setRate' => ['void', 'rate'=>'float'], 'SWFMovie::startSound' => ['SWFSoundInstance', 'sound'=>'swfsound'], 'SWFMovie::stopSound' => ['void', 'sound'=>'swfsound'], 'SWFMovie::streamMP3' => ['int', 'mp3file'=>'mixed', 'skip='=>'float'], 'SWFMovie::writeExports' => ['void'], 'SWFPrebuiltClip::__construct' => ['void', 'file'=>''], 'SWFShape::__construct' => ['void'], 'SWFShape::addFill' => ['SWFFill', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int', 'bitmap='=>'swfbitmap', 'flags='=>'int', 'gradient='=>'swfgradient'], 'SWFShape::addFill\'1' => ['SWFFill', 'bitmap'=>'SWFBitmap', 'flags='=>'int'], 'SWFShape::addFill\'2' => ['SWFFill', 'gradient'=>'SWFGradient', 'flags='=>'int'], 'SWFShape::drawArc' => ['void', 'r'=>'float', 'startangle'=>'float', 'endangle'=>'float'], 'SWFShape::drawCircle' => ['void', 'r'=>'float'], 'SWFShape::drawCubic' => ['int', 'bx'=>'float', 'by'=>'float', 'cx'=>'float', 'cy'=>'float', 'dx'=>'float', 'dy'=>'float'], 'SWFShape::drawCubicTo' => ['int', 'bx'=>'float', 'by'=>'float', 'cx'=>'float', 'cy'=>'float', 'dx'=>'float', 'dy'=>'float'], 'SWFShape::drawCurve' => ['int', 'controldx'=>'float', 'controldy'=>'float', 'anchordx'=>'float', 'anchordy'=>'float', 'targetdx='=>'float', 'targetdy='=>'float'], 'SWFShape::drawCurveTo' => ['int', 'controlx'=>'float', 'controly'=>'float', 'anchorx'=>'float', 'anchory'=>'float', 'targetx='=>'float', 'targety='=>'float'], 'SWFShape::drawGlyph' => ['void', 'font'=>'swffont', 'character'=>'string', 'size='=>'int'], 'SWFShape::drawLine' => ['void', 'dx'=>'float', 'dy'=>'float'], 'SWFShape::drawLineTo' => ['void', 'x'=>'float', 'y'=>'float'], 'SWFShape::movePen' => ['void', 'dx'=>'float', 'dy'=>'float'], 'SWFShape::movePenTo' => ['void', 'x'=>'float', 'y'=>'float'], 'SWFShape::setLeftFill' => ['', 'fill'=>'swfgradient', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'SWFShape::setLine' => ['', 'shape'=>'swfshape', 'width'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'SWFShape::setRightFill' => ['', 'fill'=>'swfgradient', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'SWFSound' => ['SWFSound', 'filename'=>'string', 'flags='=>'int'], 'SWFSound::__construct' => ['void', 'filename'=>'string', 'flags='=>'int'], 'SWFSoundInstance::loopCount' => ['void', 'point'=>'int'], 'SWFSoundInstance::loopInPoint' => ['void', 'point'=>'int'], 'SWFSoundInstance::loopOutPoint' => ['void', 'point'=>'int'], 'SWFSoundInstance::noMultiple' => ['void'], 'SWFSprite::__construct' => ['void'], 'SWFSprite::add' => ['void', 'object'=>'object'], 'SWFSprite::labelFrame' => ['void', 'label'=>'string'], 'SWFSprite::nextFrame' => ['void'], 'SWFSprite::remove' => ['void', 'object'=>'object'], 'SWFSprite::setFrames' => ['void', 'number'=>'int'], 'SWFSprite::startSound' => ['SWFSoundInstance', 'sount'=>'swfsound'], 'SWFSprite::stopSound' => ['void', 'sount'=>'swfsound'], 'SWFText::__construct' => ['void'], 'SWFText::addString' => ['void', 'string'=>'string'], 'SWFText::addUTF8String' => ['void', 'text'=>'string'], 'SWFText::getAscent' => ['float'], 'SWFText::getDescent' => ['float'], 'SWFText::getLeading' => ['float'], 'SWFText::getUTF8Width' => ['float', 'string'=>'string'], 'SWFText::getWidth' => ['float', 'string'=>'string'], 'SWFText::moveTo' => ['void', 'x'=>'float', 'y'=>'float'], 'SWFText::setColor' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'SWFText::setFont' => ['void', 'font'=>'swffont'], 'SWFText::setHeight' => ['void', 'height'=>'float'], 'SWFText::setSpacing' => ['void', 'spacing'=>'float'], 'SWFTextField::__construct' => ['void', 'flags='=>'int'], 'SWFTextField::addChars' => ['void', 'chars'=>'string'], 'SWFTextField::addString' => ['void', 'string'=>'string'], 'SWFTextField::align' => ['void', 'alignement'=>'int'], 'SWFTextField::setBounds' => ['void', 'width'=>'float', 'height'=>'float'], 'SWFTextField::setColor' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], 'SWFTextField::setFont' => ['void', 'font'=>'swffont'], 'SWFTextField::setHeight' => ['void', 'height'=>'float'], 'SWFTextField::setIndentation' => ['void', 'width'=>'float'], 'SWFTextField::setLeftMargin' => ['void', 'width'=>'float'], 'SWFTextField::setLineSpacing' => ['void', 'height'=>'float'], 'SWFTextField::setMargins' => ['void', 'left'=>'float', 'right'=>'float'], 'SWFTextField::setName' => ['void', 'name'=>'string'], 'SWFTextField::setPadding' => ['void', 'padding'=>'float'], 'SWFTextField::setRightMargin' => ['void', 'width'=>'float'], 'SWFVideoStream::__construct' => ['void', 'file='=>'string'], 'SWFVideoStream::getNumFrames' => ['int'], 'SWFVideoStream::setDimension' => ['void', 'x'=>'int', 'y'=>'int'], 'Swish::__construct' => ['void', 'index_names'=>'string'], 'Swish::getMetaList' => ['array', 'index_name'=>'string'], 'Swish::getPropertyList' => ['array', 'index_name'=>'string'], 'Swish::prepare' => ['object', 'query='=>'string'], 'Swish::query' => ['object', 'query'=>'string'], 'SwishResult::getMetaList' => ['array'], 'SwishResult::stem' => ['array', 'word'=>'string'], 'SwishResults::getParsedWords' => ['array', 'index_name'=>'string'], 'SwishResults::getRemovedStopwords' => ['array', 'index_name'=>'string'], 'SwishResults::nextResult' => ['object'], 'SwishResults::seekResult' => ['int', 'position'=>'int'], 'SwishSearch::execute' => ['object', 'query='=>'string'], 'SwishSearch::resetLimit' => [''], 'SwishSearch::setLimit' => ['', 'property'=>'string', 'low'=>'string', 'high'=>'string'], 'SwishSearch::setPhraseDelimiter' => ['', 'delimiter'=>'string'], 'SwishSearch::setSort' => ['', 'sort'=>'string'], 'SwishSearch::setStructure' => ['', 'structure'=>'int'], 'swoole_async_dns_lookup' => ['bool', 'hostname'=>'string', 'callback'=>'callable'], 'swoole_async_read' => ['bool', 'filename'=>'string', 'callback'=>'callable', 'chunk_size='=>'int', 'offset='=>'int'], 'swoole_async_readfile' => ['bool', 'filename'=>'string', 'callback'=>'string'], 'swoole_async_set' => ['void', 'settings'=>'array'], 'swoole_async_write' => ['bool', 'filename'=>'string', 'content'=>'string', 'offset='=>'int', 'callback='=>'callable'], 'swoole_async_writefile' => ['bool', 'filename'=>'string', 'content'=>'string', 'callback='=>'callable', 'flags='=>'int'], 'swoole_client_select' => ['int', 'read_array'=>'array', 'write_array'=>'array', 'error_array'=>'array', 'timeout='=>'float'], 'swoole_cpu_num' => ['int'], 'swoole_errno' => ['int'], 'swoole_event_add' => ['int', 'fd'=>'int', 'read_callback='=>'callable', 'write_callback='=>'callable', 'events='=>'int'], 'swoole_event_defer' => ['bool', 'callback'=>'callable'], 'swoole_event_del' => ['bool', 'fd'=>'int'], 'swoole_event_exit' => ['void'], 'swoole_event_set' => ['bool', 'fd'=>'int', 'read_callback='=>'callable', 'write_callback='=>'callable', 'events='=>'int'], 'swoole_event_wait' => ['void'], 'swoole_event_write' => ['bool', 'fd'=>'int', 'data'=>'string'], 'swoole_get_local_ip' => ['array'], 'swoole_last_error' => ['int'], 'swoole_load_module' => ['mixed', 'filename'=>'string'], 'swoole_select' => ['int', 'read_array'=>'array', 'write_array'=>'array', 'error_array'=>'array', 'timeout='=>'float'], 'swoole_set_process_name' => ['void', 'process_name'=>'string', 'size='=>'int'], 'swoole_strerror' => ['string', 'errno'=>'int', 'error_type='=>'int'], 'swoole_timer_after' => ['int', 'ms'=>'int', 'callback'=>'callable', 'param='=>'mixed'], 'swoole_timer_exists' => ['bool', 'timer_id'=>'int'], 'swoole_timer_tick' => ['int', 'ms'=>'int', 'callback'=>'callable', 'param='=>'mixed'], 'swoole_version' => ['string'], 'sybase_affected_rows' => ['int', 'link_identifier='=>'resource'], 'sybase_close' => ['bool', 'link_identifier='=>'resource'], 'sybase_connect' => ['resource', 'servername='=>'string', 'username='=>'string', 'password='=>'string', 'charset='=>'string', 'appname='=>'string', 'new='=>'bool'], 'sybase_data_seek' => ['bool', 'result_identifier'=>'resource', 'row_number'=>'int'], 'sybase_deadlock_retry_count' => ['void', 'retry_count'=>'int'], 'sybase_fetch_array' => ['array', 'result'=>'resource'], 'sybase_fetch_assoc' => ['array', 'result'=>'resource'], 'sybase_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'], 'sybase_fetch_object' => ['object', 'result'=>'resource', 'object='=>'mixed'], 'sybase_fetch_row' => ['array|false', 'result'=>'resource'], 'sybase_field_seek' => ['bool', 'result'=>'resource', 'field_offset'=>'int'], 'sybase_free_result' => ['bool', 'result'=>'resource'], 'sybase_get_last_message' => ['string'], 'sybase_min_client_severity' => ['void', 'severity'=>'int'], 'sybase_min_error_severity' => ['void', 'severity'=>'int'], 'sybase_min_message_severity' => ['void', 'severity'=>'int'], 'sybase_min_server_severity' => ['void', 'severity'=>'int'], 'sybase_num_fields' => ['int', 'result'=>'resource'], 'sybase_num_rows' => ['int', 'result'=>'resource'], 'sybase_pconnect' => ['resource|false', 'servername='=>'string', 'username='=>'string', 'password='=>'string', 'charset='=>'string', 'appname='=>'string'], 'sybase_query' => ['mixed', 'query'=>'string', 'link_identifier='=>'resource'], 'sybase_result' => ['string', 'result'=>'resource', 'row'=>'int', 'field'=>'mixed'], 'sybase_select_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'resource'], 'sybase_set_message_handler' => ['bool', 'handler'=>'callable', 'connection='=>'resource'], 'sybase_unbuffered_query' => ['resource|false', 'query'=>'string', 'link_identifier'=>'resource', 'store_result='=>'bool'], 'symbolObj::__construct' => ['void', 'map'=>'mapObj', 'symbolname'=>'string'], 'symbolObj::free' => ['void'], 'symbolObj::getPatternArray' => ['array'], 'symbolObj::getPointsArray' => ['array'], 'symbolObj::ms_newSymbolObj' => ['int', 'map'=>'mapObj', 'symbolname'=>'string'], 'symbolObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], 'symbolObj::setImagePath' => ['int', 'filename'=>'string'], 'symbolObj::setPattern' => ['int', 'int'=>'array'], 'symbolObj::setPoints' => ['int', 'double'=>'array'], 'symlink' => ['bool', 'target'=>'string', 'link'=>'string'], 'SyncEvent::__construct' => ['void', 'name='=>'string', 'manual='=>'bool'], 'SyncEvent::fire' => ['bool'], 'SyncEvent::reset' => ['bool'], 'SyncEvent::wait' => ['bool', 'wait='=>'int'], 'SyncMutex::__construct' => ['void', 'name='=>'string'], 'SyncMutex::lock' => ['bool', 'wait='=>'int'], 'SyncMutex::unlock' => ['bool', 'all='=>'bool'], 'SyncReaderWriter::__construct' => ['void', 'name='=>'string', 'autounlock='=>'bool'], 'SyncReaderWriter::readlock' => ['bool', 'wait='=>'int'], 'SyncReaderWriter::readunlock' => ['bool'], 'SyncReaderWriter::writelock' => ['bool', 'wait='=>'int'], 'SyncReaderWriter::writeunlock' => ['bool'], 'SyncSemaphore::__construct' => ['void', 'name='=>'string', 'initialval='=>'int', 'autounlock='=>'bool'], 'SyncSemaphore::lock' => ['bool', 'wait='=>'int'], 'SyncSemaphore::unlock' => ['bool', '&w_prevcount='=>'int'], 'SyncSharedMemory::__construct' => ['void', 'name'=>'string', 'size'=>'int'], 'SyncSharedMemory::first' => ['bool'], 'SyncSharedMemory::read' => ['', 'start='=>'int', 'length='=>'int'], 'SyncSharedMemory::size' => ['bool'], 'SyncSharedMemory::write' => ['', 'string='=>'string', 'start='=>'int'], 'sys_get_temp_dir' => ['string'], 'sys_getloadavg' => ['array|false'], 'syslog' => ['bool', 'priority'=>'int', 'message'=>'string'], 'system' => ['string|false', 'command'=>'string', '&w_return_value='=>'int'], 'taint' => ['bool', '&rw_string'=>'string', '&...w_other_strings='=>'string'], 'tan' => ['float', 'number'=>'float'], 'tanh' => ['float', 'number'=>'float'], 'tcpwrap_check' => ['bool', 'daemon'=>'string', 'address'=>'string', 'user='=>'string', 'nodns='=>'bool'], 'tempnam' => ['__benevolent', 'dir'=>'string', 'prefix'=>'string'], 'textdomain' => ['string', 'domain'=>'string'], 'Thread::__construct' => ['void'], 'Thread::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'], 'Thread::count' => ['0|positive-int'], 'Thread::getCreatorId' => ['int'], 'Thread::getCurrentThread' => ['Thread|null'], 'Thread::getCurrentThreadId' => ['int'], 'Thread::getThreadId' => ['int'], 'Thread::isJoined' => ['bool'], 'Thread::isRunning' => ['bool'], 'Thread::isStarted' => ['bool'], 'Thread::isTerminated' => ['bool'], 'Thread::join' => ['bool'], 'Thread::merge' => ['bool', 'from'=>'', 'overwrite='=>'mixed'], 'Thread::notify' => ['bool'], 'Thread::notifyOne' => ['bool'], 'Thread::offsetExists' => ['bool', 'offset'=>'mixed'], 'Thread::offsetGet' => ['mixed', 'offset'=>'mixed'], 'Thread::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], 'Thread::offsetUnset' => ['void', 'offset'=>'mixed'], 'Thread::pop' => ['bool'], 'Thread::run' => ['void'], 'Thread::shift' => ['bool'], 'Thread::start' => ['bool', 'options='=>'int'], 'Thread::synchronized' => ['mixed', 'block'=>'Closure', '_='=>'mixed'], 'Thread::wait' => ['bool', 'timeout='=>'int'], 'Threaded::__construct' => ['void'], 'Threaded::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'], 'Threaded::count' => ['0|positive-int'], 'Threaded::extend' => ['bool', 'class'=>'string'], 'Threaded::isRunning' => ['bool'], 'Threaded::isTerminated' => ['bool'], 'Threaded::merge' => ['bool', 'from'=>'mixed', 'overwrite='=>'bool'], 'Threaded::notify' => ['bool'], 'Threaded::notifyOne' => ['bool'], 'Threaded::offsetExists' => ['bool', 'offset'=>'mixed'], 'Threaded::offsetGet' => ['mixed', 'offset'=>'mixed'], 'Threaded::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], 'Threaded::offsetUnset' => ['void', 'offset'=>'mixed'], 'Threaded::pop' => ['bool'], 'Threaded::run' => ['void'], 'Threaded::shift' => ['mixed'], 'Threaded::synchronized' => ['mixed', 'block'=>'Closure', '...args='=>'mixed'], 'Threaded::wait' => ['bool', 'timeout='=>'int'], 'Throwable::__toString' => ['string'], 'Throwable::getCode' => ['mixed'], 'Throwable::getFile' => ['string'], 'Throwable::getLine' => ['int'], 'Throwable::getMessage' => ['string'], 'Throwable::getPrevious' => ['Throwable|null'], 'Throwable::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'Throwable::getTraceAsString' => ['string'], 'tidy::__construct' => ['void', 'filename='=>'string', 'config='=>'', 'encoding='=>'string', 'use_include_path='=>'bool'], 'tidy::body' => ['tidyNode'], 'tidy::cleanRepair' => ['bool'], 'tidy::diagnose' => ['bool'], 'tidy::getConfig' => ['array'], 'tidy::getHtmlVer' => ['int'], 'tidy::getOpt' => ['', 'option'=>'string'], 'tidy::getOptDoc' => ['string', 'optname'=>'string'], 'tidy::getRelease' => ['string'], 'tidy::getStatus' => ['int'], 'tidy::head' => ['tidyNode'], 'tidy::html' => ['tidyNode'], 'tidy::htmlver' => ['int'], 'tidy::isXhtml' => ['bool'], 'tidy::isXml' => ['bool'], 'tidy::parseFile' => ['bool', 'filename'=>'string', 'config='=>'mixed', 'encoding='=>'string', 'use_include_path='=>'bool'], 'tidy::parseString' => ['bool', 'input'=>'string', 'config='=>'mixed', 'encoding='=>'string'], 'tidy::repairFile' => ['string', 'filename'=>'string', 'config='=>'mixed', 'encoding='=>'string', 'use_include_path='=>'bool'], 'tidy::repairString' => ['string', 'data'=>'string', 'config='=>'mixed', 'encoding='=>'string'], 'tidy::root' => ['tidyNode'], 'tidy_access_count' => ['int', 'obj'=>'tidy'], 'tidy_clean_repair' => ['bool', 'obj'=>'tidy'], 'tidy_config_count' => ['int', 'obj'=>'tidy'], 'tidy_diagnose' => ['bool', 'obj'=>'tidy'], 'tidy_error_count' => ['int', 'obj'=>'tidy'], 'tidy_get_body' => ['tidyNode', 'obj'=>'tidy'], 'tidy_get_config' => ['array', 'obj'=>'tidy'], 'tidy_get_error_buffer' => ['string|false', 'obj'=>'tidy'], 'tidy_get_head' => ['tidyNode', 'obj'=>'tidy'], 'tidy_get_html' => ['tidyNode', 'obj'=>'tidy'], 'tidy_get_html_ver' => ['int', 'obj'=>'tidy'], 'tidy_get_opt_doc' => ['string|false', 'obj'=>'tidy', 'optname'=>'string'], 'tidy_get_output' => ['string', 'obj'=>'tidy'], 'tidy_get_release' => ['string'], 'tidy_get_root' => ['tidyNode', 'obj'=>'tidy'], 'tidy_get_status' => ['int', 'obj'=>'tidy'], 'tidy_getopt' => ['mixed', 'option'=>'string', 'obj'=>'tidy'], 'tidy_is_xhtml' => ['bool', 'obj'=>'tidy'], 'tidy_is_xml' => ['bool', 'obj'=>'tidy'], 'tidy_load_config' => ['void', 'filename'=>'string', 'encoding'=>'string'], 'tidy_parse_file' => ['tidy|false', 'file'=>'string', 'config_options='=>'', 'encoding='=>'string', 'use_include_path='=>'bool'], 'tidy_parse_string' => ['tidy|false', 'input'=>'string', 'config_options='=>'', 'encoding='=>'string'], 'tidy_repair_file' => ['string|false', 'filename'=>'string', 'config_file='=>'', 'encoding='=>'string', 'use_include_path='=>'bool'], 'tidy_repair_string' => ['string|false', 'data'=>'string', 'config_file='=>'', 'encoding='=>'string'], 'tidy_reset_config' => ['bool'], 'tidy_save_config' => ['bool', 'filename'=>'string'], 'tidy_set_encoding' => ['bool', 'encoding'=>'string'], 'tidy_setopt' => ['bool', 'option'=>'string', 'value'=>'mixed'], 'tidy_warning_count' => ['int', 'obj'=>'tidy'], 'tidyNode::__construct' => ['void'], 'tidyNode::getParent' => ['tidyNode'], 'tidyNode::hasChildren' => ['bool'], 'tidyNode::hasSiblings' => ['bool'], 'tidyNode::isAsp' => ['bool'], 'tidyNode::isComment' => ['bool'], 'tidyNode::isHtml' => ['bool'], 'tidyNode::isJste' => ['bool'], 'tidyNode::isPhp' => ['bool'], 'tidyNode::isText' => ['bool'], 'time' => ['positive-int'], 'time_nanosleep' => ['array{seconds:0|positive-int,nanoseconds:0|positive-int}|bool', 'seconds'=>'int', 'nanoseconds'=>'int'], 'time_sleep_until' => ['bool', 'timestamp'=>'float'], 'timezone_abbreviations_list' => ['array>'], 'timezone_identifiers_list' => ['list', 'what='=>'int', 'country='=>'?string'], 'timezone_location_get' => ['array{country_code: string, latitude: float, longitude: float, comments: string}|false', 'object'=>'DateTimeZone'], 'timezone_name_from_abbr' => ['string|false', 'abbr'=>'string', 'gmtoffset='=>'int', 'isdst='=>'int'], 'timezone_name_get' => ['string', 'object'=>'DateTimeZone'], 'timezone_offset_get' => ['int', 'object'=>'DateTimeZone', 'datetime'=>'DateTime'], 'timezone_open' => ['DateTimeZone|false', 'timezone'=>'string'], 'timezone_transitions_get' => ['list|false', 'object'=>'DateTimeZone', 'timestamp_begin='=>'int', 'timestamp_end='=>'int'], 'timezone_version_get' => ['string'], 'tmpfile' => ['__benevolent'], 'token_get_all' => ['list', 'source'=>'string', 'flags='=>'int'], 'token_name' => ['non-falsy-string', 'type'=>'int'], 'TokyoTyrant::__construct' => ['void', 'host='=>'string', 'port='=>'int', 'options='=>'array'], 'TokyoTyrant::add' => ['int|float', 'key'=>'string', 'increment'=>'float', 'type='=>'int'], 'TokyoTyrant::connect' => ['TokyoTyrant', 'host'=>'string', 'port='=>'int', 'options='=>'array'], 'TokyoTyrant::connectUri' => ['TokyoTyrant', 'uri'=>'string'], 'TokyoTyrant::copy' => ['TokyoTyrant', 'path'=>'string'], 'TokyoTyrant::ext' => ['string', 'name'=>'string', 'options'=>'int', 'key'=>'string', 'value'=>'string'], 'TokyoTyrant::fwmKeys' => ['array', 'prefix'=>'string', 'max_recs'=>'int'], 'TokyoTyrant::get' => ['array', 'keys'=>'mixed'], 'TokyoTyrant::getIterator' => ['TokyoTyrantIterator'], 'TokyoTyrant::num' => ['int'], 'TokyoTyrant::out' => ['string', 'keys'=>'mixed'], 'TokyoTyrant::put' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'], 'TokyoTyrant::putCat' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'], 'TokyoTyrant::putKeep' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'], 'TokyoTyrant::putNr' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'], 'TokyoTyrant::putShl' => ['mixed', 'key'=>'string', 'value'=>'string', 'width'=>'int'], 'TokyoTyrant::restore' => ['mixed', 'log_dir'=>'string', 'timestamp'=>'int', 'check_consistency='=>'bool'], 'TokyoTyrant::setMaster' => ['mixed', 'host'=>'string', 'port'=>'int', 'timestamp'=>'int', 'check_consistency='=>'bool'], 'TokyoTyrant::size' => ['int', 'key'=>'string'], 'TokyoTyrant::stat' => ['array'], 'TokyoTyrant::sync' => ['mixed'], 'TokyoTyrant::tune' => ['TokyoTyrant', 'timeout'=>'float', 'options='=>'int'], 'TokyoTyrant::vanish' => ['mixed'], 'TokyoTyrantIterator::__construct' => ['void', 'object'=>'mixed'], 'TokyoTyrantIterator::current' => ['mixed'], 'TokyoTyrantIterator::key' => ['mixed'], 'TokyoTyrantIterator::next' => ['mixed'], 'TokyoTyrantIterator::rewind' => ['void'], 'TokyoTyrantIterator::valid' => ['bool'], 'TokyoTyrantQuery::__construct' => ['void', 'table'=>'TokyoTyrantTable'], 'TokyoTyrantQuery::addCond' => ['mixed', 'name'=>'string', 'op'=>'int', 'expr'=>'string'], 'TokyoTyrantQuery::count' => ['0|positive-int'], 'TokyoTyrantQuery::current' => ['array'], 'TokyoTyrantQuery::hint' => ['string'], 'TokyoTyrantQuery::key' => ['string'], 'TokyoTyrantQuery::metaSearch' => ['array', 'queries'=>'array', 'type'=>'int'], 'TokyoTyrantQuery::next' => ['array'], 'TokyoTyrantQuery::out' => ['TokyoTyrantQuery'], 'TokyoTyrantQuery::rewind' => ['bool'], 'TokyoTyrantQuery::search' => ['array'], 'TokyoTyrantQuery::setLimit' => ['mixed', 'max='=>'int', 'skip='=>'int'], 'TokyoTyrantQuery::setOrder' => ['mixed', 'name'=>'string', 'type'=>'int'], 'TokyoTyrantQuery::valid' => ['bool'], 'TokyoTyrantTable::add' => ['void', 'key'=>'string', 'increment'=>'mixed', 'type='=>'string'], 'TokyoTyrantTable::genUid' => ['int'], 'TokyoTyrantTable::get' => ['array', 'keys'=>'mixed'], 'TokyoTyrantTable::getIterator' => ['TokyoTyrantIterator'], 'TokyoTyrantTable::getQuery' => ['TokyoTyrantQuery'], 'TokyoTyrantTable::out' => ['void', 'keys'=>'mixed'], 'TokyoTyrantTable::put' => ['int', 'key'=>'string', 'columns'=>'array'], 'TokyoTyrantTable::putCat' => ['void', 'key'=>'string', 'columns'=>'array'], 'TokyoTyrantTable::putKeep' => ['void', 'key'=>'string', 'columns'=>'array'], 'TokyoTyrantTable::putNr' => ['void', 'keys'=>'mixed', 'value='=>'string'], 'TokyoTyrantTable::putShl' => ['void', 'key'=>'string', 'value'=>'string', 'width'=>'int'], 'TokyoTyrantTable::setIndex' => ['mixed', 'column'=>'string', 'type'=>'int'], 'touch' => ['bool', 'filename'=>'string', 'time='=>'int', 'atime='=>'int'], 'trader_acos' => ['array', 'real'=>'array'], 'trader_ad' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'volume'=>'array'], 'trader_add' => ['array', 'real0'=>'array', 'real1'=>'array'], 'trader_adosc' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'volume'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int'], 'trader_adx' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], 'trader_adxr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], 'trader_apo' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int', 'mAType='=>'int'], 'trader_aroon' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'], 'trader_aroonosc' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'], 'trader_asin' => ['array', 'real'=>'array'], 'trader_atan' => ['array', 'real'=>'array'], 'trader_atr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], 'trader_avgprice' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_bbands' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'nbDevUp='=>'float', 'nbDevDn='=>'float', 'mAType='=>'int'], 'trader_beta' => ['array', 'real0'=>'array', 'real1'=>'array', 'timePeriod='=>'int'], 'trader_bop' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cci' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], 'trader_cdl2crows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdl3blackcrows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdl3inside' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdl3linestrike' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdl3outside' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdl3starsinsouth' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdl3whitesoldiers' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlabandonedbaby' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], 'trader_cdladvanceblock' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlbelthold' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlbreakaway' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlclosingmarubozu' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlconcealbabyswall' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlcounterattack' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdldarkcloudcover' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], 'trader_cdldoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdldojistar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdldragonflydoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlengulfing' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdleveningdojistar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], 'trader_cdleveningstar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], 'trader_cdlgapsidesidewhite' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlgravestonedoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlhammer' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlhangingman' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlharami' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlharamicross' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlhighwave' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlhikkake' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlhikkakemod' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlhomingpigeon' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlidentical3crows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlinneck' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlinvertedhammer' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlkicking' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlkickingbylength' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlladderbottom' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdllongleggeddoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdllongline' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlmarubozu' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlmatchinglow' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlmathold' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], 'trader_cdlmorningdojistar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], 'trader_cdlmorningstar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], 'trader_cdlonneck' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlpiercing' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlrickshawman' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlrisefall3methods' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlseparatinglines' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlshootingstar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlshortline' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlspinningtop' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlstalledpattern' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlsticksandwich' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdltakuri' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdltasukigap' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlthrusting' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdltristar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlunique3river' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlupsidegap2crows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_cdlxsidegap3methods' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_ceil' => ['array', 'real'=>'array'], 'trader_cmo' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_correl' => ['array', 'real0'=>'array', 'real1'=>'array', 'timePeriod='=>'int'], 'trader_cos' => ['array', 'real'=>'array'], 'trader_cosh' => ['array', 'real'=>'array'], 'trader_dema' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_div' => ['array', 'real0'=>'array', 'real1'=>'array'], 'trader_dx' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], 'trader_ema' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_errno' => ['int'], 'trader_exp' => ['array', 'real'=>'array'], 'trader_floor' => ['array', 'real'=>'array'], 'trader_get_compat' => ['int'], 'trader_get_unstable_period' => ['int', 'functionId'=>'int'], 'trader_ht_dcperiod' => ['array', 'real'=>'array'], 'trader_ht_dcphase' => ['array', 'real'=>'array'], 'trader_ht_phasor' => ['array', 'real'=>'array'], 'trader_ht_sine' => ['array', 'real'=>'array'], 'trader_ht_trendline' => ['array', 'real'=>'array'], 'trader_ht_trendmode' => ['array', 'real'=>'array'], 'trader_kama' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_linearreg' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_linearreg_angle' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_linearreg_intercept' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_linearreg_slope' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_ln' => ['array', 'real'=>'array'], 'trader_log10' => ['array', 'real'=>'array'], 'trader_ma' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'mAType='=>'int'], 'trader_macd' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int', 'signalPeriod='=>'int'], 'trader_macdext' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'fastMAType='=>'int', 'slowPeriod='=>'int', 'slowMAType='=>'int', 'signalPeriod='=>'int', 'signalMAType='=>'int'], 'trader_macdfix' => ['array', 'real'=>'array', 'signalPeriod='=>'int'], 'trader_mama' => ['array', 'real'=>'array', 'fastLimit='=>'float', 'slowLimit='=>'float'], 'trader_mavp' => ['array', 'real'=>'array', 'periods'=>'array', 'minPeriod='=>'int', 'maxPeriod='=>'int', 'mAType='=>'int'], 'trader_max' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_maxindex' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_medprice' => ['array', 'high'=>'array', 'low'=>'array'], 'trader_mfi' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'volume'=>'array', 'timePeriod='=>'int'], 'trader_midpoint' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_midprice' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'], 'trader_min' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_minindex' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_minmax' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_minmaxindex' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_minus_di' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], 'trader_minus_dm' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'], 'trader_mom' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_mult' => ['array', 'real0'=>'array', 'real1'=>'array'], 'trader_natr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], 'trader_obv' => ['array', 'real'=>'array', 'volume'=>'array'], 'trader_plus_di' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], 'trader_plus_dm' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'], 'trader_ppo' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int', 'mAType='=>'int'], 'trader_roc' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_rocp' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_rocr' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_rocr100' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_rsi' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_sar' => ['array', 'high'=>'array', 'low'=>'array', 'acceleration='=>'float', 'maximum='=>'float'], 'trader_sarext' => ['array', 'high'=>'array', 'low'=>'array', 'startValue='=>'float', 'offsetOnReverse='=>'float', 'accelerationInitLong='=>'float', 'accelerationLong='=>'float', 'accelerationMaxLong='=>'float', 'accelerationInitShort='=>'float', 'accelerationShort='=>'float', 'accelerationMaxShort='=>'float'], 'trader_set_compat' => ['void', 'compatId'=>'int'], 'trader_set_unstable_period' => ['void', 'functionId'=>'int', 'timePeriod'=>'int'], 'trader_sin' => ['array', 'real'=>'array'], 'trader_sinh' => ['array', 'real'=>'array'], 'trader_sma' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_sqrt' => ['array', 'real'=>'array'], 'trader_stddev' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'nbDev='=>'float'], 'trader_stoch' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'fastK_Period='=>'int', 'slowK_Period='=>'int', 'slowK_MAType='=>'int', 'slowD_Period='=>'int', 'slowD_MAType='=>'int'], 'trader_stochf' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'fastK_Period='=>'int', 'fastD_Period='=>'int', 'fastD_MAType='=>'int'], 'trader_stochrsi' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'fastK_Period='=>'int', 'fastD_Period='=>'int', 'fastD_MAType='=>'int'], 'trader_sub' => ['array', 'real0'=>'array', 'real1'=>'array'], 'trader_sum' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_t3' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'vFactor='=>'float'], 'trader_tan' => ['array', 'real'=>'array'], 'trader_tanh' => ['array', 'real'=>'array'], 'trader_tema' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_trange' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_trima' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_trix' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_tsf' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trader_typprice' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_ultosc' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod1='=>'int', 'timePeriod2='=>'int', 'timePeriod3='=>'int'], 'trader_var' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'nbDev='=>'float'], 'trader_wclprice' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], 'trader_willr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], 'trader_wma' => ['array', 'real'=>'array', 'timePeriod='=>'int'], 'trait_exists' => ['bool', 'traitname'=>'string', 'autoload='=>'bool'], 'Transliterator::create' => ['?Transliterator', 'id'=>'string', 'direction='=>'int'], 'Transliterator::createFromRules' => ['?Transliterator', 'rules'=>'string', 'direction='=>'int'], 'Transliterator::createInverse' => ['?Transliterator'], 'Transliterator::getErrorCode' => ['int|false'], 'Transliterator::getErrorMessage' => ['string|false'], 'Transliterator::listIDs' => ['list|false'], 'Transliterator::transliterate' => ['string|false', 'subject'=>'string', 'start='=>'int', 'end='=>'int'], 'transliterator_create' => ['?Transliterator', 'id'=>'string', 'direction='=>'int'], 'transliterator_create_from_rules' => ['?Transliterator', 'rules'=>'string', 'direction='=>'int'], 'transliterator_create_inverse' => ['?Transliterator', 'obj'=>'Transliterator'], 'transliterator_get_error_code' => ['int|false', 'obj'=>'Transliterator'], 'transliterator_get_error_message' => ['string|false', 'obj'=>'Transliterator'], 'transliterator_list_ids' => ['list|false'], 'transliterator_transliterate' => ['string|false', 'obj'=>'Transliterator|string', 'subject'=>'string', 'start='=>'int', 'end='=>'int'], 'trigger_error' => ['bool', 'message'=>'string', 'error_type='=>'int'], 'trim' => ['string', 'str'=>'string', 'character_mask='=>'string'], 'TypeError::__clone' => ['void'], 'TypeError::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?TypeError)'], 'TypeError::__toString' => ['string'], 'TypeError::getCode' => ['int'], 'TypeError::getFile' => ['string'], 'TypeError::getLine' => ['int'], 'TypeError::getMessage' => ['string'], 'TypeError::getPrevious' => ['Throwable|TypeError|null'], 'TypeError::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'TypeError::getTraceAsString' => ['string'], 'uasort' => ['bool', '&rw_array_arg'=>'array', 'callback'=>'callable(mixed,mixed):int'], 'ucfirst' => ['string', 'str'=>'string'], 'UConverter::__construct' => ['void', 'destination_encoding'=>'string', 'source_encoding='=>'string'], 'UConverter::convert' => ['string', 'str'=>'string', 'reverse='=>'bool'], 'UConverter::fromUCallback' => ['mixed', 'reason'=>'int', 'source'=>'string', 'codePoint'=>'string', '&w_error'=>'int'], 'UConverter::getAliases' => ['array', 'name='=>'string'], 'UConverter::getAvailable' => ['array'], 'UConverter::getDestinationEncoding' => ['string'], 'UConverter::getDestinationType' => ['int'], 'UConverter::getErrorCode' => ['int'], 'UConverter::getErrorMessage' => ['string'], 'UConverter::getSourceEncoding' => ['string'], 'UConverter::getSourceType' => ['int'], 'UConverter::getStandards' => ['array'], 'UConverter::getSubstChars' => ['string'], 'UConverter::reasonText' => ['string', 'reason='=>'int'], 'UConverter::setDestinationEncoding' => ['bool', 'encoding'=>'string'], 'UConverter::setSourceEncoding' => ['bool', 'encoding'=>'string'], 'UConverter::setSubstChars' => ['bool', 'chars'=>'string'], 'UConverter::toUCallback' => ['mixed', 'reason'=>'int', 'source'=>'string', 'codeUnits'=>'string', '&w_error'=>'int'], 'UConverter::transcode' => ['string', 'str'=>'string', 'toEncoding'=>'string', 'fromEncoding'=>'string', 'options='=>'array'], 'ucwords' => ['string', 'str'=>'string', 'delims='=>'string'], 'udm_add_search_limit' => ['bool', 'agent'=>'resource', 'var'=>'int', 'val'=>'string'], 'udm_alloc_agent' => ['resource', 'dbaddr'=>'string', 'dbmode='=>'string'], 'udm_alloc_agent_array' => ['resource', 'databases'=>'array'], 'udm_api_version' => ['int'], 'udm_cat_list' => ['array', 'agent'=>'resource', 'category'=>'string'], 'udm_cat_path' => ['array', 'agent'=>'resource', 'category'=>'string'], 'udm_check_charset' => ['bool', 'agent'=>'resource', 'charset'=>'string'], 'udm_check_stored' => ['int', 'agent'=>'', 'link'=>'int', 'doc_id'=>'string'], 'udm_clear_search_limits' => ['bool', 'agent'=>'resource'], 'udm_close_stored' => ['int', 'agent'=>'', 'link'=>'int'], 'udm_crc32' => ['int', 'agent'=>'resource', 'str'=>'string'], 'udm_errno' => ['int', 'agent'=>'resource'], 'udm_error' => ['string', 'agent'=>'resource'], 'udm_find' => ['resource', 'agent'=>'resource', 'query'=>'string'], 'udm_free_agent' => ['int', 'agent'=>'resource'], 'udm_free_ispell_data' => ['bool', 'agent'=>'int'], 'udm_free_res' => ['bool', 'res'=>'resource'], 'udm_get_doc_count' => ['int', 'agent'=>'resource'], 'udm_get_res_field' => ['string', 'res'=>'resource', 'row'=>'int', 'field'=>'int'], 'udm_get_res_param' => ['string', 'res'=>'resource', 'param'=>'int'], 'udm_hash32' => ['int', 'agent'=>'resource', 'str'=>'string'], 'udm_load_ispell_data' => ['bool', 'agent'=>'resource', 'var'=>'int', 'val1'=>'string', 'val2'=>'string', 'flag'=>'int'], 'udm_open_stored' => ['int', 'agent'=>'', 'storedaddr'=>'string'], 'udm_set_agent_param' => ['bool', 'agent'=>'resource', 'var'=>'int', 'val'=>'string'], 'ui\draw\text\font\fontfamilies' => ['array'], 'ui\quit' => ['void'], 'ui\run' => ['void', 'flags='=>'int'], 'uksort' => ['bool', '&rw_array_arg'=>'array', 'callback'=>'callable(array-key,array-key):int'], 'umask' => ['int', 'mask='=>'int'], 'UnderflowException::__clone' => ['void'], 'UnderflowException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?UnderflowException)'], 'UnderflowException::__toString' => ['string'], 'UnderflowException::getCode' => ['int'], 'UnderflowException::getFile' => ['string'], 'UnderflowException::getLine' => ['int'], 'UnderflowException::getMessage' => ['string'], 'UnderflowException::getPrevious' => ['Throwable|UnderflowException|null'], 'UnderflowException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'UnderflowException::getTraceAsString' => ['string'], 'UnexpectedValueException::__clone' => ['void'], 'UnexpectedValueException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Throwable)|(?UnexpectedValueException)'], 'UnexpectedValueException::__toString' => ['string'], 'UnexpectedValueException::getCode' => ['int'], 'UnexpectedValueException::getFile' => ['string'], 'UnexpectedValueException::getLine' => ['int'], 'UnexpectedValueException::getMessage' => ['string'], 'UnexpectedValueException::getPrevious' => ['Throwable|UnexpectedValueException|null'], 'UnexpectedValueException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'UnexpectedValueException::getTraceAsString' => ['string'], 'uniqid' => ['non-empty-string', 'prefix='=>'string', 'more_entropy='=>'bool'], 'unixtojd' => ['int|false', 'timestamp='=>'int'], 'unlink' => ['bool', 'filename'=>'string', 'context='=>'resource'], 'unpack' => ['array|false', 'format'=>'string', 'data'=>'string', 'offset='=>'int'], 'unregister_tick_function' => ['void', 'function_name'=>'callable'], 'unserialize' => ['mixed', 'variable_representation'=>'string', 'allowed_classes='=>'array{allowed_classes?:string[]|bool}'], 'untaint' => ['bool', '&rw_string'=>'string', '&...rw_strings='=>'string'], 'uopz_add_function' => ['bool', 'class'=>'string', 'function'=>'string', 'handler'=>'Closure', '$flags'=>'bool', '$all'=>'bool'], 'uopz_add_function\'1' => ['bool', 'function'=>'string', 'handler'=>'Closure', '$flags'=>'bool'], 'uopz_allow_exit' => ['void', 'allow'=>'bool'], 'uopz_backup' => ['void', 'class'=>'string', 'function'=>'string'], 'uopz_backup\'1' => ['void', 'function'=>'string'], 'uopz_compose' => ['void', 'name'=>'string', 'classes'=>'array', 'methods='=>'array', 'properties='=>'array', 'flags='=>'int'], 'uopz_copy' => ['Closure', 'class'=>'string', 'function'=>'string'], 'uopz_copy\'1' => ['Closure', 'function'=>'string'], 'uopz_del_function' => ['bool', 'class'=>'string', 'function'=>'string', '$all'=>'bool'], 'uopz_del_function\'1' => ['bool', 'function'=>'string'], 'uopz_delete' => ['void', 'class'=>'string', 'function'=>'string'], 'uopz_delete\'1' => ['void', 'function'=>'string'], 'uopz_extend' => ['void', 'class'=>'string', 'parent'=>'string'], 'uopz_flags' => ['int', 'class'=>'string', 'function'=>'string', 'flags='=>'int'], 'uopz_flags\'1' => ['int', 'function'=>'string', 'flags='=>'int'], 'uopz_function' => ['void', 'class'=>'string', 'function'=>'string', 'handler'=>'Closure', 'modifiers='=>'int'], 'uopz_function\'1' => ['void', 'function'=>'string', 'handler'=>'Closure', 'modifiers='=>'int'], 'uopz_get_exit_status' => ['mixed'], 'uopz_get_hook' => ['Closure', 'class'=>'string', 'function'=>'string'], 'uopz_get_hook\'1' => ['Closure', 'function'=>'string'], 'uopz_get_mock' => ['mixed', 'class'=>'string'], 'uopz_get_property' => ['mixed', 'class'=>'string', 'property'=>'string'], 'uopz_get_property\'1' => ['mixed', 'instance'=>'object', 'property'=>'string'], 'uopz_get_return' => ['mixed', 'class='=>'string', 'function='=>'string'], 'uopz_get_static' => ['array', 'class='=>'string', 'function='=>'string'], 'uopz_get_static\'1' => ['array', 'function='=>'string'], 'uopz_implement' => ['void', 'class'=>'string', 'interface'=>'string'], 'uopz_overload' => ['void', 'opcode'=>'int', 'callable'=>'Callable'], 'uopz_redefine' => ['void', 'class'=>'string', 'constant'=>'string', 'value'=>'mixed'], 'uopz_redefine\'1' => ['void', 'constant'=>'string', 'value'=>'mixed'], 'uopz_rename' => ['void', 'class'=>'string', 'function'=>'string', 'rename'=>'string'], 'uopz_rename\'1' => ['void', 'function'=>'string', 'rename'=>'string'], 'uopz_restore' => ['void', 'class'=>'string', 'function'=>'string'], 'uopz_restore\'1' => ['void', 'function'=>'string'], 'uopz_set_mock' => ['void', 'class'=>'string', 'mock'=>'object|string'], 'uopz_set_property' => ['void', 'class'=>'string', 'property'=>'string', 'value'=>'mixed'], 'uopz_set_property\'1' => ['void', 'instance'=>'object', 'property'=>'string', 'value'=>'mixed'], 'uopz_set_return' => ['bool', 'class'=>'string', 'function'=>'string', 'value'=>'mixed', 'execute='=>'bool'], 'uopz_set_return\'1' => ['bool', 'function'=>'string', 'value'=>'mixed', 'execute='=>'bool'], 'uopz_undefine' => ['void', 'class'=>'string', 'constant'=>'string'], 'uopz_undefine\'1' => ['void', 'constant'=>'string'], 'uopz_set_hook' => ['bool', 'class'=>'string', 'function'=>'string', 'hook'=>'Closure'], 'uopz_set_hook\'1' => ['bool', 'function'=>'string', 'hook'=>'Closure'], 'uopz_unset_mock' => ['void', 'class'=>'string'], 'uopz_unset_return' => ['bool', 'class='=>'string', 'function='=>'string'], 'uopz_unset_return\'1' => ['bool', 'function'=>'string'], 'urldecode' => ['string', 'str'=>'string'], 'urlencode' => ['string', 'str'=>'string'], 'use_soap_error_handler' => ['bool', 'handler='=>'bool'], 'usleep' => ['void', 'micro_seconds'=>'int'], 'usort' => ['bool', '&rw_array_arg'=>'array', 'callback'=>'callable(mixed,mixed):int'], 'utf8_decode' => ['string', 'data'=>'string'], 'utf8_encode' => ['string', 'data'=>'string'], 'V8Js::__construct' => ['void', 'object_name='=>'string', 'variables='=>'array', 'extensions='=>'array', 'report_uncaught_exceptions='=>'bool', 'snapshot_blob='=>'string'], 'V8Js::clearPendingException' => [''], 'V8Js::compileString' => ['resource', 'script'=>'', 'identifier='=>'string'], 'V8Js::createSnapshot' => ['false|string', 'embed_source'=>'string'], 'V8Js::executeScript' => ['', 'script'=>'resource', 'flags='=>'int', 'time_limit='=>'int', 'memory_limit='=>'int'], 'V8Js::executeString' => ['mixed', 'script'=>'string', 'identifier='=>'string', 'flags='=>'int'], 'V8Js::getExtensions' => ['array'], 'V8Js::getPendingException' => ['V8JsException'], 'V8Js::registerExtension' => ['bool', 'extension_name'=>'string', 'script'=>'string', 'dependencies='=>'array', 'auto_enable='=>'bool'], 'V8Js::setAverageObjectSize' => ['', 'average_object_size'=>'int'], 'V8Js::setMemoryLimit' => ['', 'limit'=>'int'], 'V8Js::setModuleLoader' => ['', 'loader'=>'callable'], 'V8Js::setModuleNormaliser' => ['', 'normaliser'=>'callable'], 'V8Js::setTimeLimit' => ['', 'limit'=>'int'], 'V8JsException::getJsFileName' => ['string'], 'V8JsException::getJsLineNumber' => ['int'], 'V8JsException::getJsSourceLine' => ['int'], 'V8JsException::getJsTrace' => ['string'], 'V8JsScriptException::__clone' => ['void'], 'V8JsScriptException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'(?Exception)|(?Throwable)'], 'V8JsScriptException::__toString' => ['string'], 'V8JsScriptException::__wakeup' => ['void'], 'V8JsScriptException::getCode' => ['int'], 'V8JsScriptException::getFile' => ['string'], 'V8JsScriptException::getJsEndColumn' => ['int'], 'V8JsScriptException::getJsFileName' => ['string'], 'V8JsScriptException::getJsLineNumber' => ['int'], 'V8JsScriptException::getJsSourceLine' => ['string'], 'V8JsScriptException::getJsStartColumn' => ['int'], 'V8JsScriptException::getJsTrace' => ['string'], 'V8JsScriptException::getLine' => ['int'], 'V8JsScriptException::getMessage' => ['string'], 'V8JsScriptException::getPrevious' => ['Exception|Throwable'], 'V8JsScriptException::getTrace' => ['list\',args?:mixed[],object?:object}>'], 'V8JsScriptException::getTraceAsString' => ['string'], 'var_dump' => ['void', 'var'=>'mixed', '...args='=>'mixed'], 'var_export' => ['string|null', 'var'=>'mixed', 'return='=>'bool'], 'VARIANT::__construct' => ['void', 'value='=>'mixed', 'type='=>'int', 'codepage='=>'int'], 'variant_abs' => ['mixed', 'left'=>'mixed'], 'variant_add' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'variant_and' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'variant_cast' => ['object', 'variant'=>'object', 'type'=>'int'], 'variant_cat' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'variant_cmp' => ['int', 'left'=>'mixed', 'right'=>'mixed', 'lcid='=>'int', 'flags='=>'int'], 'variant_date_from_timestamp' => ['object', 'timestamp'=>'int'], 'variant_date_to_timestamp' => ['int', 'variant'=>'object'], 'variant_div' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'variant_eqv' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'variant_fix' => ['mixed', 'left'=>'mixed'], 'variant_get_type' => ['int', 'variant'=>'object'], 'variant_idiv' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'variant_imp' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'variant_int' => ['mixed', 'left'=>'mixed'], 'variant_mod' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'variant_mul' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'variant_neg' => ['mixed', 'left'=>'mixed'], 'variant_not' => ['mixed', 'left'=>'mixed'], 'variant_or' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'variant_pow' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'variant_round' => ['mixed', 'left'=>'mixed', 'decimals'=>'int'], 'variant_set' => ['void', 'variant'=>'object', 'value'=>'mixed'], 'variant_set_type' => ['void', 'variant'=>'object', 'type'=>'int'], 'variant_sub' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'variant_xor' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], 'VarnishAdmin::__construct' => ['void', 'args='=>'array'], 'VarnishAdmin::auth' => ['bool'], 'VarnishAdmin::ban' => ['int', 'vcl_regex'=>'string'], 'VarnishAdmin::banUrl' => ['int', 'vcl_regex'=>'string'], 'VarnishAdmin::clearPanic' => ['int'], 'VarnishAdmin::connect' => ['bool'], 'VarnishAdmin::disconnect' => ['bool'], 'VarnishAdmin::getPanic' => ['string'], 'VarnishAdmin::getParams' => ['array'], 'VarnishAdmin::isRunning' => ['bool'], 'VarnishAdmin::setCompat' => ['void', 'compat'=>'int'], 'VarnishAdmin::setHost' => ['void', 'host'=>'string'], 'VarnishAdmin::setIdent' => ['void', 'ident'=>'string'], 'VarnishAdmin::setParam' => ['int', 'name'=>'string', 'value'=>'string|int'], 'VarnishAdmin::setPort' => ['void', 'port'=>'int'], 'VarnishAdmin::setSecret' => ['void', 'secret'=>'string'], 'VarnishAdmin::setTimeout' => ['void', 'timeout'=>'int'], 'VarnishAdmin::start' => ['int'], 'VarnishAdmin::stop' => ['int'], 'VarnishLog::__construct' => ['void', 'args='=>'array'], 'VarnishLog::getLine' => ['array'], 'VarnishLog::getTagName' => ['string', 'index'=>'int'], 'VarnishStat::__construct' => ['void', 'args='=>'array'], 'VarnishStat::getSnapshot' => ['array'], 'version_compare' => ['int', 'version1'=>'string', 'version2'=>'string'], 'version_compare\'1' => ['bool', 'version1'=>'string', 'version2'=>'string', 'operator'=>'string|null'], 'vfprintf' => ['int', 'stream'=>'resource', 'format'=>'string', 'args'=>'array<__stringAndStringable|int|float|null|bool>'], 'virtual' => ['bool', 'uri'=>'string'], 'Volatile::__construct' => ['void'], 'Volatile::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'], 'Volatile::count' => ['0|positive-int'], 'Volatile::extend' => ['bool', 'class'=>'string'], 'Volatile::isRunning' => ['bool'], 'Volatile::isTerminated' => ['bool'], 'Volatile::merge' => ['bool', 'from'=>'mixed', 'overwrite='=>'bool'], 'Volatile::notify' => ['bool'], 'Volatile::notifyOne' => ['bool'], 'Volatile::offsetExists' => ['bool', 'offset'=>'mixed'], 'Volatile::offsetGet' => ['mixed', 'offset'=>'mixed'], 'Volatile::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], 'Volatile::offsetUnset' => ['void', 'offset'=>'mixed'], 'Volatile::pop' => ['bool'], 'Volatile::run' => ['void'], 'Volatile::shift' => ['mixed'], 'Volatile::synchronized' => ['mixed', 'block'=>'Closure', '...args='=>'mixed'], 'Volatile::wait' => ['bool', 'timeout='=>'int'], 'vpopmail_add_alias_domain' => ['bool', 'domain'=>'string', 'aliasdomain'=>'string'], 'vpopmail_add_alias_domain_ex' => ['bool', 'olddomain'=>'string', 'newdomain'=>'string'], 'vpopmail_add_domain' => ['bool', 'domain'=>'string', 'dir'=>'string', 'uid'=>'int', 'gid'=>'int'], 'vpopmail_add_domain_ex' => ['bool', 'domain'=>'string', 'passwd'=>'string', 'quota='=>'string', 'bounce='=>'string', 'apop='=>'bool'], 'vpopmail_add_user' => ['bool', 'user'=>'string', 'domain'=>'string', 'password'=>'string', 'gecos='=>'string', 'apop='=>'bool'], 'vpopmail_alias_add' => ['bool', 'user'=>'string', 'domain'=>'string', 'alias'=>'string'], 'vpopmail_alias_del' => ['bool', 'user'=>'string', 'domain'=>'string'], 'vpopmail_alias_del_domain' => ['bool', 'domain'=>'string'], 'vpopmail_alias_get' => ['array', 'alias'=>'string', 'domain'=>'string'], 'vpopmail_alias_get_all' => ['array', 'domain'=>'string'], 'vpopmail_auth_user' => ['bool', 'user'=>'string', 'domain'=>'string', 'password'=>'string', 'apop='=>'string'], 'vpopmail_del_domain' => ['bool', 'domain'=>'string'], 'vpopmail_del_domain_ex' => ['bool', 'domain'=>'string'], 'vpopmail_del_user' => ['bool', 'user'=>'string', 'domain'=>'string'], 'vpopmail_error' => ['string'], 'vpopmail_passwd' => ['bool', 'user'=>'string', 'domain'=>'string', 'password'=>'string', 'apop='=>'bool'], 'vpopmail_set_user_quota' => ['bool', 'user'=>'string', 'domain'=>'string', 'quota'=>'string'], 'vprintf' => ['int', 'format'=>'string', 'args'=>'array<__stringAndStringable|int|float|null|bool>'], 'vsprintf' => ['string', 'format'=>'string', 'args'=>'array<__stringAndStringable|int|float|null|bool>'], 'w32api_deftype' => ['bool', 'typename'=>'string', 'member1_type'=>'string', 'member1_name'=>'string', '...args='=>'string'], 'w32api_init_dtype' => ['resource', 'typename'=>'string', 'value'=>'', '...args='=>''], 'w32api_invoke_function' => ['', 'funcname'=>'string', 'argument'=>'', '...args='=>''], 'w32api_register_function' => ['bool', 'library'=>'string', 'function_name'=>'string', 'return_type'=>'string'], 'w32api_set_call_method' => ['', 'method'=>'int'], 'wddx_add_vars' => ['bool', 'packet_id'=>'resource', 'var_names'=>'mixed', '...vars='=>'mixed'], 'wddx_deserialize' => ['mixed', 'packet'=>'string'], 'wddx_packet_end' => ['string', 'packet_id'=>'resource'], 'wddx_packet_start' => ['resource', 'comment='=>'string'], 'wddx_serialize_value' => ['string', 'var'=>'mixed', 'comment='=>'string'], 'wddx_serialize_vars' => ['string', 'var_name'=>'mixed', '...vars='=>'mixed'], 'WeakMap::__construct' => ['void'], 'WeakMap::count' => ['0|positive-int'], 'WeakMap::current' => ['mixed'], 'WeakMap::key' => ['object'], 'WeakMap::next' => ['void'], 'WeakMap::offsetExists' => ['bool', 'object'=>'object'], 'WeakMap::offsetGet' => ['mixed', 'object'=>'object'], 'WeakMap::offsetSet' => ['void', 'object'=>'object', 'value'=>'mixed'], 'WeakMap::offsetUnset' => ['void', 'object'=>'object'], 'WeakMap::rewind' => ['void'], 'WeakMap::valid' => ['bool'], 'Weakref::acquire' => ['bool'], 'Weakref::get' => ['object'], 'Weakref::release' => ['bool'], 'Weakref::valid' => ['bool'], 'webObj::convertToString' => ['string'], 'webObj::free' => ['void'], 'webObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], 'webObj::updateFromString' => ['int', 'snippet'=>'string'], 'win32_continue_service' => ['int', 'servicename'=>'string', 'machine='=>'string'], 'win32_create_service' => ['mixed', 'details'=>'array', 'machine='=>'string'], 'win32_delete_service' => ['mixed', 'servicename'=>'string', 'machine='=>'string'], 'win32_get_last_control_message' => ['int'], 'win32_pause_service' => ['int', 'servicename'=>'string', 'machine='=>'string'], 'win32_ps_list_procs' => ['array'], 'win32_ps_stat_mem' => ['array'], 'win32_ps_stat_proc' => ['array', 'pid='=>'int'], 'win32_query_service_status' => ['mixed', 'servicename'=>'string', 'machine='=>'string'], 'win32_set_service_status' => ['bool', 'status'=>'int', 'checkpoint='=>'int'], 'win32_start_service' => ['int', 'servicename'=>'string', 'machine='=>'string'], 'win32_start_service_ctrl_dispatcher' => ['mixed', 'name'=>'string'], 'win32_stop_service' => ['int', 'servicename'=>'string', 'machine='=>'string'], 'wincache_fcache_fileinfo' => ['array', 'summaryonly='=>'bool'], 'wincache_fcache_meminfo' => ['array'], 'wincache_lock' => ['bool', 'key'=>'string', 'isglobal='=>'bool'], 'wincache_ocache_fileinfo' => ['array', 'summaryonly='=>'bool'], 'wincache_ocache_meminfo' => ['array'], 'wincache_refresh_if_changed' => ['bool', 'files='=>'array'], 'wincache_rplist_fileinfo' => ['array', 'summaryonly='=>'bool'], 'wincache_rplist_meminfo' => ['array'], 'wincache_scache_info' => ['array|false', 'summaryonly='=>'bool'], 'wincache_scache_meminfo' => ['array|false'], 'wincache_ucache_add' => ['bool', 'key'=>'string', 'value'=>'', 'ttl='=>'int'], 'wincache_ucache_add\'1' => ['bool', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'], 'wincache_ucache_cas' => ['bool', 'key'=>'string', 'old_value'=>'int', 'new_value'=>'int'], 'wincache_ucache_clear' => ['bool'], 'wincache_ucache_dec' => ['mixed', 'key'=>'string', 'dec_by='=>'int', '&w_success='=>'bool'], 'wincache_ucache_delete' => ['bool', 'key'=>'mixed'], 'wincache_ucache_exists' => ['bool', 'key'=>'string'], 'wincache_ucache_get' => ['mixed', 'key'=>'mixed', '&w_success='=>'bool'], 'wincache_ucache_inc' => ['int|false', 'key'=>'string', 'inc_by='=>'int', '&w_success='=>'bool'], 'wincache_ucache_info' => ['array|false', 'summaryonly='=>'bool', 'key='=>'string'], 'wincache_ucache_meminfo' => ['array'], 'wincache_ucache_set' => ['bool', 'key'=>'', 'value'=>'', 'ttl='=>'int'], 'wincache_ucache_set\'1' => ['bool', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'], 'wincache_unlock' => ['bool', 'key'=>'string'], 'wordwrap' => ['string', 'str'=>'string', 'width='=>'int', 'break='=>'string', 'cut='=>'bool'], 'Worker::__construct' => ['void'], 'Worker::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'], 'Worker::collect' => ['int', 'collector='=>'Callable'], 'Worker::count' => ['0|positive-int'], 'Worker::getCreatorId' => ['int'], 'Worker::getCurrentThread' => ['Thread'], 'Worker::getCurrentThreadId' => ['int'], 'Worker::getStacked' => ['int'], 'Worker::getThreadId' => ['int'], 'Worker::isJoined' => ['bool'], 'Worker::isRunning' => ['bool'], 'Worker::isShutdown' => ['bool'], 'Worker::isStarted' => ['bool'], 'Worker::isTerminated' => ['bool'], 'Worker::join' => ['bool'], 'Worker::merge' => ['bool', 'from'=>'', 'overwrite='=>'mixed'], 'Worker::notify' => ['bool'], 'Worker::notifyOne' => ['bool'], 'Worker::offsetExists' => ['bool', 'offset'=>'mixed'], 'Worker::offsetGet' => ['mixed', 'offset'=>'mixed'], 'Worker::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], 'Worker::offsetUnset' => ['void', 'offset'=>'mixed'], 'Worker::pop' => ['bool'], 'Worker::run' => ['void'], 'Worker::shift' => ['bool'], 'Worker::shutdown' => ['bool'], 'Worker::stack' => ['int', 'work'=>'Threaded'], 'Worker::start' => ['bool', 'options='=>'int'], 'Worker::synchronized' => ['mixed', 'block'=>'Closure', '_='=>'mixed'], 'Worker::unstack' => ['Collectable|null'], 'Worker::wait' => ['bool', 'timeout='=>'int'], 'xattr_get' => ['string', 'filename'=>'string', 'name'=>'string', 'flags='=>'int'], 'xattr_list' => ['array', 'filename'=>'string', 'flags='=>'int'], 'xattr_remove' => ['bool', 'filename'=>'string', 'name'=>'string', 'flags='=>'int'], 'xattr_set' => ['bool', 'filename'=>'string', 'name'=>'string', 'value'=>'string', 'flags='=>'int'], 'xattr_supported' => ['bool', 'filename'=>'string', 'flags='=>'int'], 'xcache_asm' => ['string', 'filename'=>'string'], 'xcache_clear_cache' => ['void', 'type'=>'int', 'id='=>'int'], 'xcache_coredump' => ['string', 'op_type'=>'int'], 'xcache_count' => ['int', 'type'=>'int'], 'xcache_coverager_decode' => ['array', 'data'=>'string'], 'xcache_coverager_get' => ['array', 'clean='=>'bool|false'], 'xcache_coverager_start' => ['void', 'clean='=>'bool|true'], 'xcache_coverager_stop' => ['void', 'clean='=>'bool|false'], 'xcache_dasm_file' => ['string', 'filename'=>'string'], 'xcache_dasm_string' => ['string', 'code'=>'string'], 'xcache_dec' => ['int', 'name'=>'string', 'value='=>'int|mixed', 'ttl='=>'int'], 'xcache_decode' => ['bool', 'filename'=>'string'], 'xcache_encode' => ['string', 'filename'=>'string'], 'xcache_get' => ['mixed', 'name'=>'string'], 'xcache_get_data_type' => ['string', 'type'=>'int'], 'xcache_get_op_spec' => ['string', 'op_type'=>'int'], 'xcache_get_op_type' => ['string', 'op_type'=>'int'], 'xcache_get_opcode' => ['string', 'opcode'=>'int'], 'xcache_get_opcode_spec' => ['string', 'opcode'=>'int'], 'xcache_inc' => ['int', 'name'=>'string', 'value='=>'int|mixed', 'ttl='=>'int'], 'xcache_info' => ['array', 'type'=>'int', 'id'=>'int'], 'xcache_is_autoglobal' => ['string', 'name'=>'string'], 'xcache_isset' => ['bool', 'name'=>'string'], 'xcache_list' => ['array', 'type'=>'int', 'id'=>'int'], 'xcache_set' => ['bool', 'name'=>'string', 'value'=>'mixed', 'ttl='=>'int'], 'xcache_unset' => ['bool', 'name'=>'string'], 'xcache_unset_by_prefix' => ['bool', 'prefix'=>'string'], 'Xcom::__construct' => ['void', 'fabric_url='=>'string', 'fabric_token='=>'string', 'capability_token='=>'string'], 'Xcom::decode' => ['object', 'avro_msg'=>'string', 'json_schema'=>'string'], 'Xcom::encode' => ['string', 'data'=>'stdClass', 'avro_schema'=>'string'], 'Xcom::getDebugOutput' => ['string'], 'Xcom::getLastResponse' => ['string'], 'Xcom::getLastResponseInfo' => ['array'], 'Xcom::getOnboardingURL' => ['string', 'capability_name'=>'string', 'agreement_url'=>'string'], 'Xcom::send' => ['int', 'topic'=>'string', 'data'=>'mixed', 'json_schema='=>'string', 'http_headers='=>'array'], 'Xcom::sendAsync' => ['int', 'topic'=>'string', 'data'=>'mixed', 'json_schema='=>'string', 'http_headers='=>'array'], 'xdebug_break' => ['bool'], 'xdebug_call_class' => ['string', 'depth='=>'int'], 'xdebug_call_file' => ['string', 'depth='=>'int'], 'xdebug_call_function' => ['string', 'depth='=>'int'], 'xdebug_call_line' => ['int', 'depth='=>'int'], 'xdebug_clear_aggr_profiling_data' => ['bool'], 'xdebug_code_coverage_started' => ['bool'], 'xdebug_connect_to_client' => ['bool'], 'xdebug_debug_zval' => ['void', '...varName'=>'string'], 'xdebug_debug_zval_stdout' => ['void', '...varName'=>'string'], 'xdebug_disable' => ['void'], 'xdebug_dump_aggr_profiling_data' => ['bool'], 'xdebug_dump_superglobals' => ['void'], 'xdebug_enable' => ['void'], 'xdebug_get_code_coverage' => ['array'], 'xdebug_get_collected_errors' => ['string', 'clean='=>'bool|false'], 'xdebug_get_declared_vars' => ['array'], 'xdebug_get_formatted_function_stack' => [''], 'xdebug_get_function_count' => ['int'], 'xdebug_get_function_stack' => ['array', 'message='=>'string', 'options='=>'int'], 'xdebug_get_headers' => ['array'], 'xdebug_get_monitored_functions' => ['array'], 'xdebug_get_profiler_filename' => ['string'], 'xdebug_get_stack_depth' => ['int'], 'xdebug_get_tracefile_name' => ['string'], 'xdebug_is_debugger_active' => ['bool'], 'xdebug_is_enabled' => ['bool'], 'xdebug_memory_usage' => ['int'], 'xdebug_notify' => ['bool', 'data'=>'mixed'], 'xdebug_peak_memory_usage' => ['int'], 'xdebug_print_function_stack' => ['array', 'message='=>'string', 'options='=>'int'], 'xdebug_set_filter' => ['void', 'group'=>'int', 'list_type'=>'int', 'configuration'=>'array'], 'xdebug_start_code_coverage' => ['void', 'options='=>'int'], 'xdebug_start_error_collection' => ['void'], 'xdebug_start_function_monitor' => ['void', 'list_of_functions_to_monitor'=>'string[]'], 'xdebug_start_trace' => ['void', 'trace_file'=>'', 'options='=>'int|mixed'], 'xdebug_stop_code_coverage' => ['void', 'cleanup='=>'bool|true'], 'xdebug_stop_error_collection' => ['void'], 'xdebug_stop_function_monitor' => ['void'], 'xdebug_stop_trace' => ['void'], 'xdebug_time_index' => ['float'], 'xdebug_var_dump' => ['void', '...var'=>''], 'xdiff_file_bdiff' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string'], 'xdiff_file_bdiff_size' => ['int', 'file'=>'string'], 'xdiff_file_bpatch' => ['bool', 'file'=>'string', 'patch'=>'string', 'dest'=>'string'], 'xdiff_file_diff' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string', 'context='=>'int', 'minimal='=>'bool'], 'xdiff_file_diff_binary' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string'], 'xdiff_file_merge3' => ['mixed', 'old_file'=>'string', 'new_file1'=>'string', 'new_file2'=>'string', 'dest'=>'string'], 'xdiff_file_patch' => ['mixed', 'file'=>'string', 'patch'=>'string', 'dest'=>'string', 'flags='=>'int'], 'xdiff_file_patch_binary' => ['bool', 'file'=>'string', 'patch'=>'string', 'dest'=>'string'], 'xdiff_file_rabdiff' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string'], 'xdiff_string_bdiff' => ['string', 'old_data'=>'string', 'new_data'=>'string'], 'xdiff_string_bdiff_size' => ['int', 'patch'=>'string'], 'xdiff_string_bpatch' => ['string', 'str'=>'string', 'patch'=>'string'], 'xdiff_string_diff' => ['string', 'old_data'=>'string', 'new_data'=>'string', 'context='=>'int', 'minimal='=>'bool'], 'xdiff_string_diff_binary' => ['string', 'old_data'=>'string', 'new_data'=>'string'], 'xdiff_string_merge3' => ['mixed', 'old_data'=>'string', 'new_data1'=>'string', 'new_data2'=>'string', 'error='=>'string'], 'xdiff_string_patch' => ['string', 'str'=>'string', 'patch'=>'string', 'flags='=>'int', '&w_error='=>'string'], 'xdiff_string_patch_binary' => ['string', 'str'=>'string', 'patch'=>'string'], 'xdiff_string_rabdiff' => ['string', 'old_data'=>'string', 'new_data'=>'string'], 'xhprof_disable' => ['array'], 'xhprof_enable' => ['void', 'flags='=>'int', 'options='=>'array'], 'xhprof_sample_disable' => ['array'], 'xhprof_sample_enable' => ['void'], 'xml_error_string' => ['string', 'code'=>'int'], 'xml_get_current_byte_index' => ['int', 'parser'=>'resource'], 'xml_get_current_column_number' => ['int', 'parser'=>'resource'], 'xml_get_current_line_number' => ['int', 'parser'=>'resource'], 'xml_get_error_code' => ['int', 'parser'=>'resource'], 'xml_parse' => ['int', 'parser'=>'resource', 'data'=>'string', 'isfinal='=>'bool'], 'xml_parse_into_struct' => ['int', 'parser'=>'resource', 'data'=>'string', '&w_values'=>'array', '&w_index='=>'array'], 'xml_parser_create' => ['resource', 'encoding='=>'string'], 'xml_parser_create_ns' => ['resource', 'encoding='=>'string', 'sep='=>'string'], 'xml_parser_free' => ['bool', 'parser'=>'resource'], 'xml_parser_get_option' => ['mixed', 'parser'=>'resource', 'option'=>'int'], 'xml_parser_set_option' => ['bool', 'parser'=>'resource', 'option'=>'int', 'value'=>'mixed'], 'xml_set_character_data_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'callable'], 'xml_set_default_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'callable'], 'xml_set_element_handler' => ['bool', 'parser'=>'resource', 'shdl'=>'callable', 'ehdl'=>'callable'], 'xml_set_end_namespace_decl_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'callable'], 'xml_set_external_entity_ref_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'callable'], 'xml_set_notation_decl_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'callable'], 'xml_set_object' => ['bool', 'parser'=>'resource', 'obj'=>'object'], 'xml_set_processing_instruction_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'callable'], 'xml_set_start_namespace_decl_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'callable'], 'xml_set_unparsed_entity_decl_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'callable'], 'XMLDiff\Base::__construct' => ['void', 'nsname'=>'string'], 'XMLDiff\Base::diff' => ['mixed', 'from'=>'mixed', 'to'=>'mixed'], 'XMLDiff\Base::merge' => ['mixed', 'src'=>'mixed', 'diff'=>'mixed'], 'XMLDiff\DOM::diff' => ['DOMDocument', 'from'=>'DOMDocument', 'to'=>'DOMDocument'], 'XMLDiff\DOM::merge' => ['DOMDocument', 'src'=>'DOMDocument', 'diff'=>'DOMDocument'], 'XMLDiff\File::diff' => ['string', 'from'=>'string', 'to'=>'string'], 'XMLDiff\File::merge' => ['string', 'src'=>'string', 'diff'=>'string'], 'XMLDiff\Memory::diff' => ['string', 'from'=>'string', 'to'=>'string'], 'XMLDiff\Memory::merge' => ['string', 'src'=>'string', 'diff'=>'string'], 'XMLReader::close' => ['bool'], 'XMLReader::expand' => ['DOMNode|false', 'basenode='=>'DOMNode'], 'XMLReader::getAttribute' => ['string|null', 'name'=>'string'], 'XMLReader::getAttributeNo' => ['string|null', 'index'=>'int'], 'XMLReader::getAttributeNs' => ['string|null', 'name'=>'string', 'namespaceuri'=>'string'], 'XMLReader::getParserProperty' => ['bool', 'property'=>'int'], 'XMLReader::isValid' => ['bool'], 'XMLReader::lookupNamespace' => ['?string', 'prefix'=>'string'], 'XMLReader::moveToAttribute' => ['bool', 'name'=>'string'], 'XMLReader::moveToAttributeNo' => ['bool', 'index'=>'int'], 'XMLReader::moveToAttributeNs' => ['bool', 'localname'=>'string', 'namespaceuri'=>'string'], 'XMLReader::moveToElement' => ['bool'], 'XMLReader::moveToFirstAttribute' => ['bool'], 'XMLReader::moveToNextAttribute' => ['bool'], 'XMLReader::next' => ['bool', 'localname='=>'string'], 'XMLReader::open' => ['bool|XMLReader', 'uri'=>'string', 'encoding='=>'?string', 'options='=>'int'], 'XMLReader::read' => ['bool'], 'XMLReader::readInnerXML' => ['string'], 'XMLReader::readOuterXML' => ['string'], 'XMLReader::readString' => ['string'], 'XMLReader::setParserProperty' => ['bool', 'property'=>'int', 'value'=>'bool'], 'XMLReader::setRelaxNGSchema' => ['bool', 'filename'=>'string'], 'XMLReader::setRelaxNGSchemaSource' => ['bool', 'source'=>'string'], 'XMLReader::setSchema' => ['bool', 'filename'=>'string'], 'XMLReader::XML' => ['bool|XMLReader', 'source'=>'string', 'encoding='=>'?string', 'options='=>'int'], 'xmlrpc_decode' => ['?array', 'xml'=>'string', 'encoding='=>'string'], 'xmlrpc_decode_request' => ['?array', 'xml'=>'string', '&w_method'=>'string', 'encoding='=>'string'], 'xmlrpc_encode' => ['string', 'value'=>'mixed'], 'xmlrpc_encode_request' => ['string', 'method'=>'string', 'params'=>'mixed', 'output_options='=>'array'], 'xmlrpc_get_type' => ['string', 'value'=>'mixed'], 'xmlrpc_is_fault' => ['bool', 'arg'=>'array'], 'xmlrpc_parse_method_descriptions' => ['array', 'xml'=>'string'], 'xmlrpc_server_add_introspection_data' => ['int', 'server'=>'resource', 'desc'=>'array'], 'xmlrpc_server_call_method' => ['string', 'server'=>'resource', 'xml'=>'string', 'user_data'=>'mixed', 'output_options='=>'array'], 'xmlrpc_server_create' => ['resource'], 'xmlrpc_server_destroy' => ['int', 'server'=>'resource'], 'xmlrpc_server_register_introspection_callback' => ['bool', 'server'=>'resource', 'function'=>'string'], 'xmlrpc_server_register_method' => ['bool', 'server'=>'resource', 'method_name'=>'string', 'function'=>'string'], 'xmlrpc_set_type' => ['bool', '&rw_value'=>'string|DateTime', 'type'=>'string'], 'XMLWriter::endAttribute' => ['bool'], 'XMLWriter::endCData' => ['bool'], 'XMLWriter::endComment' => ['bool'], 'XMLWriter::endDocument' => ['bool'], 'XMLWriter::endDTD' => ['bool', 'xmlwriter='=>''], 'XMLWriter::endDTDAttlist' => ['bool'], 'XMLWriter::endDTDElement' => ['bool'], 'XMLWriter::endDTDEntity' => ['bool'], 'XMLWriter::endElement' => ['bool'], 'XMLWriter::endPI' => ['bool'], 'XMLWriter::flush' => ['', 'empty='=>'bool', 'xmlwriter='=>''], 'XMLWriter::fullEndElement' => ['bool'], 'XMLWriter::openMemory' => ['bool'], 'XMLWriter::openURI' => ['bool', 'uri'=>'string'], 'XMLWriter::outputMemory' => ['string', 'flush='=>'bool', 'xmlwriter='=>''], 'XMLWriter::setIndent' => ['bool', 'indent'=>'bool'], 'XMLWriter::setIndentString' => ['bool', 'indentstring'=>'string'], 'XMLWriter::startAttribute' => ['bool', 'name'=>'string'], 'XMLWriter::startAttributeNS' => ['bool', 'prefix'=>'string|null', 'name'=>'string', 'uri'=>'string'], 'XMLWriter::startCData' => ['bool'], 'XMLWriter::startComment' => ['bool'], 'XMLWriter::startDocument' => ['bool', 'version='=>'string', 'encoding='=>'string', 'standalone='=>'string'], 'XMLWriter::startDTD' => ['bool', 'qualifiedname'=>'string', 'publicid='=>'string', 'systemid='=>'string'], 'XMLWriter::startDTDAttlist' => ['bool', 'name'=>'string'], 'XMLWriter::startDTDElement' => ['bool', 'qualifiedname'=>'string'], 'XMLWriter::startDTDEntity' => ['bool', 'name'=>'string', 'isparam'=>'bool'], 'XMLWriter::startElement' => ['bool', 'name'=>'string'], 'XMLWriter::startElementNS' => ['bool', 'prefix'=>'string|null', 'name'=>'string', 'uri'=>'string|null'], 'XMLWriter::startPI' => ['bool', 'target'=>'string'], 'XMLWriter::text' => ['bool', 'content'=>'string'], 'XMLWriter::writeAttribute' => ['bool', 'name'=>'string', 'value'=>'string'], 'XMLWriter::writeAttributeNS' => ['bool', 'prefix'=>'string|null', 'name'=>'string', 'uri'=>'string', 'content'=>'string'], 'XMLWriter::writeCData' => ['bool', 'content'=>'string'], 'XMLWriter::writeComment' => ['bool', 'content'=>'string'], 'XMLWriter::writeDTD' => ['bool', 'name'=>'string', 'publicid='=>'string', 'systemid='=>'string', 'subset='=>'string'], 'XMLWriter::writeDTDAttlist' => ['bool', 'name'=>'string', 'content'=>'string'], 'XMLWriter::writeDTDElement' => ['bool', 'name'=>'string', 'content'=>'string'], 'XMLWriter::writeDTDEntity' => ['bool', 'name'=>'string', 'content'=>'string', 'pe'=>'bool', 'pubid'=>'string', 'sysid'=>'string', 'ndataid'=>'string'], 'XMLWriter::writeElement' => ['bool', 'name'=>'string', 'content='=>'string|null'], 'XMLWriter::writeElementNS' => ['bool', 'prefix'=>'string|null', 'name'=>'string', 'uri'=>'string', 'content='=>'string|null'], 'XMLWriter::writePI' => ['bool', 'target'=>'string', 'content'=>'string'], 'XMLWriter::writeRaw' => ['bool', 'content'=>'string'], 'xmlwriter_end_attribute' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_cdata' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_comment' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_document' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_dtd' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_dtd_attlist' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_dtd_element' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_dtd_entity' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_element' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_pi' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_flush' => ['', 'xmlwriter'=>'resource', 'empty='=>'bool'], 'xmlwriter_full_end_element' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_open_memory' => ['resource|false'], 'xmlwriter_open_uri' => ['resource|false', 'source'=>'string'], 'xmlwriter_output_memory' => ['string', 'xmlwriter'=>'resource', 'flush='=>'bool'], 'xmlwriter_set_indent' => ['bool', 'xmlwriter'=>'resource', 'indent'=>'bool'], 'xmlwriter_set_indent_string' => ['bool', 'xmlwriter'=>'resource', 'indentstring'=>'string'], 'xmlwriter_start_attribute' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string'], 'xmlwriter_start_attribute_ns' => ['bool', 'xmlwriter'=>'resource', 'prefix'=>'string|null', 'name'=>'string', 'uri'=>'string'], 'xmlwriter_start_cdata' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_start_comment' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_start_document' => ['bool', 'xmlwriter'=>'resource', 'version'=>'string', 'encoding'=>'string', 'standalone'=>'string'], 'xmlwriter_start_dtd' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'pubid'=>'string', 'sysid'=>'string'], 'xmlwriter_start_dtd_attlist' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string'], 'xmlwriter_start_dtd_element' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string'], 'xmlwriter_start_dtd_entity' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'isparam'=>'bool'], 'xmlwriter_start_element' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string'], 'xmlwriter_start_element_ns' => ['bool', 'xmlwriter'=>'resource', 'prefix'=>'string|null', 'name'=>'string', 'uri'=>'string|null'], 'xmlwriter_start_pi' => ['bool', 'xmlwriter'=>'resource', 'target'=>'string'], 'xmlwriter_text' => ['bool', 'xmlwriter'=>'resource', 'content'=>'string'], 'xmlwriter_write_attribute' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string'], 'xmlwriter_write_attribute_ns' => ['bool', 'xmlwriter'=>'resource', 'prefix'=>'string|null', 'name'=>'string', 'uri'=>'string', 'content'=>'string'], 'xmlwriter_write_cdata' => ['bool', 'xmlwriter'=>'resource', 'content'=>'string'], 'xmlwriter_write_comment' => ['bool', 'xmlwriter'=>'resource', 'content'=>'string'], 'xmlwriter_write_dtd' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'pubid'=>'string', 'sysid'=>'string', 'subset'=>'string'], 'xmlwriter_write_dtd_attlist' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string'], 'xmlwriter_write_dtd_element' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string'], 'xmlwriter_write_dtd_entity' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string', 'pe'=>'int', 'pubid'=>'string', 'sysid'=>'string', 'ndataid'=>'string'], 'xmlwriter_write_element' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string'], 'xmlwriter_write_element_ns' => ['bool', 'xmlwriter'=>'resource', 'prefix'=>'string|null', 'name'=>'string', 'uri'=>'string', 'content'=>'string'], 'xmlwriter_write_pi' => ['bool', 'xmlwriter'=>'resource', 'target'=>'string', 'content'=>'string'], 'xmlwriter_write_raw' => ['bool', 'xmlwriter'=>'resource', 'content'=>'string'], 'xpath_new_context' => ['XPathContext', 'dom_document'=>'DOMDocument'], 'xpath_register_ns' => ['bool', 'xpath_context'=>'xpathcontext', 'prefix'=>'string', 'uri'=>'string'], 'xpath_register_ns_auto' => ['bool', 'xpath_context'=>'xpathcontext', 'context_node='=>'object'], 'xptr_new_context' => ['XPathContext'], 'xsl_xsltprocessor_get_parameter' => ['string', 'namespace'=>'string', 'name'=>'string'], 'xsl_xsltprocessor_get_security_prefs' => ['int'], 'xsl_xsltprocessor_has_exslt_support' => ['bool'], 'xsl_xsltprocessor_register_php_functions' => ['', 'restrict'=>''], 'xsl_xsltprocessor_remove_parameter' => ['bool', 'namespace'=>'string', 'name'=>'string'], 'xsl_xsltprocessor_set_parameter' => ['bool', 'namespace'=>'string', 'name'=>'', 'value'=>'string'], 'xsl_xsltprocessor_set_profiling' => ['bool', 'filename'=>'string'], 'xsl_xsltprocessor_set_security_prefs' => ['int', 'securityprefs'=>'int'], 'xsl_xsltprocessor_transform_to_uri' => ['int', 'doc'=>'DOMDocument', 'uri'=>'string'], 'xsl_xsltprocessor_transform_to_xml' => ['string', 'doc'=>'DOMDocument'], 'xslt_backend_info' => ['string'], 'xslt_backend_name' => ['string'], 'xslt_backend_version' => ['string'], 'xslt_create' => ['resource'], 'xslt_errno' => ['int', 'xh'=>''], 'xslt_error' => ['string', 'xh'=>''], 'xslt_free' => ['', 'xh'=>''], 'xslt_getopt' => ['int', 'processor'=>''], 'xslt_process' => ['', 'xh'=>'', 'xmlcontainer'=>'string', 'xslcontainer'=>'string', 'resultcontainer='=>'string', 'arguments='=>'array', 'parameters='=>'array'], 'xslt_set_base' => ['', 'xh'=>'', 'uri'=>'string'], 'xslt_set_encoding' => ['', 'xh'=>'', 'encoding'=>'string'], 'xslt_set_error_handler' => ['', 'xh'=>'', 'handler'=>''], 'xslt_set_log' => ['', 'xh'=>'', 'log='=>''], 'xslt_set_object' => ['bool', 'processor'=>'', 'obj'=>'object'], 'xslt_set_sax_handler' => ['', 'xh'=>'', 'handlers'=>'array'], 'xslt_set_sax_handlers' => ['', 'processor'=>'', 'handlers'=>'array'], 'xslt_set_scheme_handler' => ['', 'xh'=>'', 'handlers'=>'array'], 'xslt_set_scheme_handlers' => ['', 'xh'=>'', 'handlers'=>'array'], 'xslt_setopt' => ['', 'processor'=>'', 'newmask'=>'int'], 'XSLTProcessor::getParameter' => ['string|false', 'namespaceuri'=>'string', 'localname'=>'string'], 'XsltProcessor::getSecurityPrefs' => ['int'], 'XSLTProcessor::hasExsltSupport' => ['bool'], 'XSLTProcessor::importStylesheet' => ['bool', 'stylesheet'=>'object'], 'XSLTProcessor::registerPHPFunctions' => ['void', 'restrict='=>'mixed'], 'XSLTProcessor::removeParameter' => ['bool', 'namespaceuri'=>'string', 'localname'=>'string'], 'XSLTProcessor::setParameter' => ['bool', 'namespace'=>'string', 'name'=>'string', 'value'=>'string'], 'XSLTProcessor::setParameter\'1' => ['bool', 'namespace'=>'string', 'options'=>'array'], 'XSLTProcessor::setProfiling' => ['bool', 'filename'=>'string'], 'XsltProcessor::setSecurityPrefs' => ['int', 'securityPrefs'=>'int'], 'XSLTProcessor::transformToDoc' => ['DOMDocument|false', 'doc'=>'DOMNode'], 'XSLTProcessor::transformToURI' => ['int', 'doc'=>'DOMDocument', 'uri'=>'string'], 'XSLTProcessor::transformToXML' => ['string|false|null', 'doc'=>'DOMDocument|SimpleXMLElement'], 'Yaconf::get' => ['mixed', 'name'=>'string', 'default_value='=>'mixed'], 'Yaconf::has' => ['bool', 'name'=>'string'], 'Yaf_Action_Abstract::__construct' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract', 'view'=>'Yaf_View_Interface', 'invokeArgs='=>'?array'], 'Yaf_Action_Abstract::display' => ['bool', 'tpl'=>'string', 'parameters='=>'?array'], 'Yaf_Action_Abstract::execute' => ['mixed', 'arg='=>'mixed', '...args='=>'mixed'], 'Yaf_Action_Abstract::forward' => ['bool', 'module'=>'string', 'controller='=>'string', 'action='=>'string', 'parameters='=>'?array'], 'Yaf_Action_Abstract::getController' => ['Yaf_Controller_Abstract'], 'Yaf_Action_Abstract::getInvokeArg' => ['mixed|null', 'name'=>'string'], 'Yaf_Action_Abstract::getInvokeArgs' => ['array'], 'Yaf_Action_Abstract::getModuleName' => ['string'], 'Yaf_Action_Abstract::getRequest' => ['Yaf_Request_Abstract'], 'Yaf_Action_Abstract::getResponse' => ['Yaf_Response_Abstract'], 'Yaf_Action_Abstract::getView' => ['Yaf_View_Interface'], 'Yaf_Action_Abstract::getViewpath' => ['string'], 'Yaf_Action_Abstract::init' => [''], 'Yaf_Action_Abstract::initView' => ['Yaf_Response_Abstract', 'options='=>'?array'], 'Yaf_Action_Abstract::redirect' => ['bool', 'url'=>'string'], 'Yaf_Action_Abstract::render' => ['string', 'tpl'=>'string', 'parameters='=>'?array'], 'Yaf_Action_Abstract::setViewpath' => ['bool', 'view_directory'=>'string'], 'Yaf_Application::__clone' => ['void'], 'Yaf_Application::__construct' => ['void', 'config'=>'mixed', 'envrion='=>'string'], 'Yaf_Application::__destruct' => ['void'], 'Yaf_Application::__sleep' => ['list'], 'Yaf_Application::__wakeup' => ['void'], 'Yaf_Application::app' => ['void'], 'Yaf_Application::bootstrap' => ['void', 'bootstrap='=>'Yaf_Bootstrap_Abstract'], 'Yaf_Application::clearLastError' => ['Yaf_Application'], 'Yaf_Application::environ' => ['void'], 'Yaf_Application::execute' => ['void', 'entry'=>'callable', '...args'=>'string'], 'Yaf_Application::getAppDirectory' => ['Yaf_Application'], 'Yaf_Application::getConfig' => ['Yaf_Config_Abstract'], 'Yaf_Application::getDispatcher' => ['Yaf_Dispatcher'], 'Yaf_Application::getLastErrorMsg' => ['string'], 'Yaf_Application::getLastErrorNo' => ['int'], 'Yaf_Application::getModules' => ['array'], 'Yaf_Application::run' => ['void'], 'Yaf_Application::setAppDirectory' => ['Yaf_Application', 'directory'=>'string'], 'Yaf_Config_Abstract::__get' => ['mixed', 'name'=>'string'], 'Yaf_Config_Abstract::__isset' => ['bool', 'name'=>'string'], 'Yaf_Config_Abstract::count' => ['0|positive-int'], 'Yaf_Config_Abstract::current' => ['mixed'], 'Yaf_Config_Abstract::get' => ['mixed', 'name'=>'?string'], 'Yaf_Config_Abstract::key' => ['int|string|null|bool'], 'Yaf_Config_Abstract::next' => ['void'], 'Yaf_Config_Abstract::offsetExists' => ['bool', 'name'=>'mixed'], 'Yaf_Config_Abstract::offsetGet' => ['mixed', 'name'=>'mixed'], 'Yaf_Config_Abstract::offsetSet' => ['void', 'name'=>'mixed', 'value'=>'mixed'], 'Yaf_Config_Abstract::offsetUnset' => ['void', 'name'=>'mixed'], 'Yaf_Config_Abstract::readonly' => ['bool'], 'Yaf_Config_Abstract::rewind' => ['void'], 'Yaf_Config_Abstract::set' => ['bool', 'name'=>'string', 'value'=>'mixed'], 'Yaf_Config_Abstract::toArray' => ['array'], 'Yaf_Config_Abstract::valid' => ['bool'], 'Yaf_Config_Ini::__construct' => ['void', 'config_file'=>'array|string', 'section='=>'?string'], 'Yaf_Config_Ini::__isset' => ['bool', 'name'=>'string'], 'Yaf_Config_Ini::__set' => ['void', 'name'=>'mixed', 'value'=>'mixed'], 'Yaf_Config_Ini::count' => ['0|positive-int'], 'Yaf_Config_Ini::current' => ['mixed'], 'Yaf_Config_Ini::get' => ['mixed', 'name='=>'?string'], 'Yaf_Config_Ini::key' => ['int|string|null|bool'], 'Yaf_Config_Ini::next' => ['void'], 'Yaf_Config_Ini::offsetExists' => ['bool', 'name'=>'mixed'], 'Yaf_Config_Ini::offsetGet' => ['mixed', 'name'=>'mixed'], 'Yaf_Config_Ini::offsetSet' => ['void', 'name'=>'mixed', 'value'=>'mixed'], 'Yaf_Config_Ini::offsetUnset' => ['void', 'name'=>'mixed'], 'Yaf_Config_Ini::readonly' => ['bool'], 'Yaf_Config_Ini::rewind' => ['void'], 'Yaf_Config_Ini::set' => ['bool', 'name'=>'string', 'value'=>'mixed'], 'Yaf_Config_Ini::toArray' => ['array'], 'Yaf_Config_Ini::valid' => ['bool'], 'Yaf_Config_Simple::__construct' => ['void', 'config_file'=>'array|string', 'section='=>'string'], 'Yaf_Config_Simple::__get' => ['void', 'name='=>'string'], 'Yaf_Config_Simple::__isset' => ['bool', 'name'=>'string'], 'Yaf_Config_Simple::__set' => ['void', 'name'=>'string', 'value'=>'mixed'], 'Yaf_Config_Simple::count' => ['0|positive-int'], 'Yaf_Config_Simple::current' => ['mixed'], 'Yaf_Config_Simple::get' => ['mixed', 'name='=>'?string'], 'Yaf_Config_Simple::key' => ['int|string|null|bool'], 'Yaf_Config_Simple::next' => ['void'], 'Yaf_Config_Simple::offsetExists' => ['bool', 'name'=>'mixed'], 'Yaf_Config_Simple::offsetGet' => ['mixed', 'name'=>'mixed'], 'Yaf_Config_Simple::offsetSet' => ['void', 'name'=>'mixed', 'value'=>'mixed'], 'Yaf_Config_Simple::offsetUnset' => ['void', 'name'=>'mixed'], 'Yaf_Config_Simple::readonly' => ['bool'], 'Yaf_Config_Simple::rewind' => ['void'], 'Yaf_Config_Simple::set' => ['bool', 'name'=>'string', 'value'=>'mixed'], 'Yaf_Config_Simple::toArray' => ['array'], 'Yaf_Config_Simple::valid' => ['bool'], 'Yaf_Controller_Abstract::__clone' => ['void'], 'Yaf_Controller_Abstract::__construct' => ['void'], 'Yaf_Controller_Abstract::display' => ['?bool', 'tpl'=>'string', 'parameters='=>'?array'], 'Yaf_Controller_Abstract::forward' => ['?bool', 'action'=>'string'], 'Yaf_Controller_Abstract::forward\'1' => ['?bool', 'controller'=>'string', 'action'=>'string'], 'Yaf_Controller_Abstract::forward\'2' => ['?bool', 'action'=>'string', 'invoke_args'=>'array'], 'Yaf_Controller_Abstract::forward\'3' => ['?bool', 'module'=>'string', 'controller'=>'string', 'action'=>'string'], 'Yaf_Controller_Abstract::forward\'4' => ['?bool', 'controller'=>'string', 'action'=>'string', 'invoke_args'=>'array'], 'Yaf_Controller_Abstract::forward\'5' => ['?bool', 'module'=>'string', 'controller'=>'string', 'action'=>'string', 'invoke_args'=>'array'], 'Yaf_Controller_Abstract::getInvokeArg' => ['?string', 'name'=>'string'], 'Yaf_Controller_Abstract::getInvokeArgs' => ['?array'], 'Yaf_Controller_Abstract::getModuleName' => ['?string'], 'Yaf_Controller_Abstract::getName' => ['?string'], 'Yaf_Controller_Abstract::getRequest' => ['?Yaf_Request_Abstract'], 'Yaf_Controller_Abstract::getResponse' => ['?Yaf_Response_Abstract'], 'Yaf_Controller_Abstract::getView' => ['?Yaf_View_Interface'], 'Yaf_Controller_Abstract::getViewpath' => ['?string'], 'Yaf_Controller_Abstract::init' => ['void'], 'Yaf_Controller_Abstract::initView' => ['?Yaf_View_Interface', 'options='=>'?array'], 'Yaf_Controller_Abstract::redirect' => ['?bool', 'url'=>'string'], 'Yaf_Controller_Abstract::render' => ['string|null|bool', 'tpl'=>'string', 'parameters='=>'?array'], 'Yaf_Controller_Abstract::setViewpath' => ['?bool', 'view_directory'=>'string'], 'Yaf_Dispatcher::__clone' => ['void'], 'Yaf_Dispatcher::__construct' => ['void'], 'Yaf_Dispatcher::__sleep' => ['list'], 'Yaf_Dispatcher::__wakeup' => ['void'], 'Yaf_Dispatcher::autoRender' => ['Yaf_Dispatcher|false|null', 'flag='=>'?bool'], 'Yaf_Dispatcher::catchException' => ['Yaf_Dispatcher|false|null', 'flag='=>'?bool'], 'Yaf_Dispatcher::disableView' => ['?Yaf_Dispatcher'], 'Yaf_Dispatcher::dispatch' => ['Yaf_Response_Abstract|false|null', 'request'=>'Yaf_Request_Abstract'], 'Yaf_Dispatcher::enableView' => ['?Yaf_Dispatcher'], 'Yaf_Dispatcher::flushInstantly' => ['Yaf_Dispatcher|false|null', 'flag='=>'?bool'], 'Yaf_Dispatcher::getApplication' => ['?Yaf_Application'], 'Yaf_Dispatcher::getDefaultAction' => ['?string'], 'Yaf_Dispatcher::getDefaultController' => ['?string'], 'Yaf_Dispatcher::getDefaultModule' => ['?string'], 'Yaf_Dispatcher::getInstance' => ['?Yaf_Dispatcher'], 'Yaf_Dispatcher::getRequest' => ['?Yaf_Request_Abstract'], 'Yaf_Dispatcher::getResponse' => ['?Yaf_Response_Abstract'], 'Yaf_Dispatcher::getRouter' => ['?Yaf_Router'], 'Yaf_Dispatcher::initView' => ['Yaf_View_Interface|null|false', 'templates_dir'=>'string', 'options='=>'?array'], 'Yaf_Dispatcher::registerPlugin' => ['Yaf_Dispatcher|false|null', 'plugin'=>'Yaf_Plugin_Abstract'], 'Yaf_Dispatcher::returnResponse' => ['Yaf_Dispatcher|false|null', 'flag='=>'bool'], 'Yaf_Dispatcher::setDefaultAction' => ['Yaf_Dispatcher|false|null', 'action'=>'string'], 'Yaf_Dispatcher::setDefaultController' => ['Yaf_Dispatcher|false|null', 'controller'=>'string'], 'Yaf_Dispatcher::setDefaultModule' => ['Yaf_Dispatcher|false|null', 'module'=>'string'], 'Yaf_Dispatcher::setErrorHandler' => ['Yaf_Dispatcher|false|null', 'callback'=>'mixed', 'error_types'=>'int'], 'Yaf_Dispatcher::setRequest' => ['?Yaf_Dispatcher', 'request'=>'Yaf_Request_Abstract'], 'Yaf_Dispatcher::setResponse' => ['?Yaf_Dispatcher', 'response'=>'Yaf_Response_Abstract'], 'Yaf_Dispatcher::setView' => ['?Yaf_Dispatcher', 'view'=>'Yaf_View_Interface'], 'Yaf_Dispatcher::throwException' => ['Yaf_Dispatcher|false|null', 'flag='=>'?bool'], 'Yaf_Exception::__construct' => ['void'], 'Yaf_Exception::getPrevious' => ['void'], 'Yaf_Loader::__clone' => ['void'], 'Yaf_Loader::__construct' => ['void'], 'Yaf_Loader::__sleep' => ['list'], 'Yaf_Loader::__wakeup' => ['void'], 'Yaf_Loader::autoload' => ['void'], 'Yaf_Loader::clearLocalNamespace' => ['void'], 'Yaf_Loader::getInstance' => ['void'], 'Yaf_Loader::getLibraryPath' => ['Yaf_Loader', 'is_global='=>'bool'], 'Yaf_Loader::getLocalNamespace' => ['void'], 'Yaf_Loader::import' => ['void'], 'Yaf_Loader::isLocalName' => ['void'], 'Yaf_Loader::registerLocalNamespace' => ['void', 'prefix'=>'mixed'], 'Yaf_Loader::setLibraryPath' => ['Yaf_Loader', 'directory'=>'string', 'is_global='=>'bool'], 'Yaf_Plugin_Abstract::dispatchLoopShutdown' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], 'Yaf_Plugin_Abstract::dispatchLoopStartup' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], 'Yaf_Plugin_Abstract::postDispatch' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], 'Yaf_Plugin_Abstract::preDispatch' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], 'Yaf_Plugin_Abstract::preResponse' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], 'Yaf_Plugin_Abstract::routerShutdown' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], 'Yaf_Plugin_Abstract::routerStartup' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], 'Yaf_Registry::__clone' => ['void'], 'Yaf_Registry::__construct' => ['void'], 'Yaf_Registry::del' => ['void', 'name'=>'string'], 'Yaf_Registry::get' => ['mixed', 'name'=>'string'], 'Yaf_Registry::has' => ['bool', 'name'=>'string'], 'Yaf_Registry::set' => ['bool', 'name'=>'string', 'value'=>'string'], 'Yaf_Request_Abstract::get' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Abstract::getActionName' => ['?string'], 'Yaf_Request_Abstract::getBaseUri' => ['?string'], 'Yaf_Request_Abstract::getCookie' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Abstract::getControllerName' => ['?string'], 'Yaf_Request_Abstract::getEnv' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Abstract::getException' => ['?Exception'], 'Yaf_Request_Abstract::getFiles' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Abstract::getLanguage' => ['?string'], 'Yaf_Request_Abstract::getMethod' => ['?string'], 'Yaf_Request_Abstract::getModuleName' => ['?string'], 'Yaf_Request_Abstract::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'], 'Yaf_Request_Abstract::getParams' => ['?array'], 'Yaf_Request_Abstract::getPost' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Abstract::getQuery' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Abstract::getRaw' => ['?string'], 'Yaf_Request_Abstract::getRequest' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Abstract::getRequestUri' => ['?string'], 'Yaf_Request_Abstract::getServer' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Abstract::cleanParams' => ['?Yaf_Request_Abstract'], 'Yaf_Request_Abstract::isCli' => ['bool'], 'Yaf_Request_Abstract::isDelete' => ['bool'], 'Yaf_Request_Abstract::isDispatched' => ['bool'], 'Yaf_Request_Abstract::isGet' => ['bool'], 'Yaf_Request_Abstract::isHead' => ['bool'], 'Yaf_Request_Abstract::isOptions' => ['bool'], 'Yaf_Request_Abstract::isPatch' => ['bool'], 'Yaf_Request_Abstract::isPost' => ['bool'], 'Yaf_Request_Abstract::isPut' => ['bool'], 'Yaf_Request_Abstract::isRouted' => ['bool'], 'Yaf_Request_Abstract::isXmlHttpRequest' => ['bool'], 'Yaf_Request_Abstract::setActionName' => ['?Yaf_Request_Abstract', 'action'=>'string', 'format_name='=>'bool|true'], 'Yaf_Request_Abstract::setBaseUri' => ['Yaf_Request_Abstract|false', 'uir'=>'string'], 'Yaf_Request_Abstract::setControllerName' => ['?Yaf_Request_Abstract', 'controller'=>'string', 'format_name='=>'bool|true'], 'Yaf_Request_Abstract::setDispatched' => ['?Yaf_Request_Abstract', 'flag='=>'bool|true'], 'Yaf_Request_Abstract::setModuleName' => ['?Yaf_Request_Abstract', 'module'=>'string', 'format_name='=>'bool|true'], 'Yaf_Request_Abstract::setParam' => ['Yaf_Request_Abstract|false|null', 'name'=>'mixed', 'value='=>'?mixed'], 'Yaf_Request_Abstract::setRequestUri' => ['?Yaf_Request_Abstract', 'uir'=>'string'], 'Yaf_Request_Abstract::setRouted' => ['?Yaf_Request_Abstract', 'flag='=>'bool|true'], 'Yaf_Request_Http::__clone' => ['void'], 'Yaf_Request_Http::__construct' => ['void', 'requestUri='=>'?string', 'baseUri='=>'?string'], 'Yaf_Request_Http::get' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Http::getActionName' => ['?string'], 'Yaf_Request_Http::getBaseUri' => ['?string'], 'Yaf_Request_Http::getCookie' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Http::getControllerName' => ['?string'], 'Yaf_Request_Http::getEnv' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Http::getException' => ['?Exception'], 'Yaf_Request_Http::getFiles' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Http::getLanguage' => ['?string'], 'Yaf_Request_Http::getMethod' => ['?string'], 'Yaf_Request_Http::getModuleName' => ['?string'], 'Yaf_Request_Http::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'], 'Yaf_Request_Http::getParams' => ['?array'], 'Yaf_Request_Http::getPost' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Http::getQuery' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Http::getRaw' => ['?string'], 'Yaf_Request_Http::getRequest' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Http::getRequestUri' => ['?string'], 'Yaf_Request_Http::getServer' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Http::cleanParams' => ['?Yaf_Request_Http'], 'Yaf_Request_Http::isCli' => ['bool'], 'Yaf_Request_Http::isDelete' => ['bool'], 'Yaf_Request_Http::isDispatched' => ['bool'], 'Yaf_Request_Http::isGet' => ['bool'], 'Yaf_Request_Http::isHead' => ['bool'], 'Yaf_Request_Http::isOptions' => ['bool'], 'Yaf_Request_Http::isPatch' => ['bool'], 'Yaf_Request_Http::isPost' => ['bool'], 'Yaf_Request_Http::isPut' => ['bool'], 'Yaf_Request_Http::isRouted' => ['bool'], 'Yaf_Request_Http::isXmlHttpRequest' => ['bool'], 'Yaf_Request_Http::setActionName' => ['?Yaf_Request_Http', 'action'=>'string', 'format_name='=>'bool|true'], 'Yaf_Request_Http::setBaseUri' => ['Yaf_Request_Http|false', 'uir'=>'string'], 'Yaf_Request_Http::setControllerName' => ['?Yaf_Request_Http', 'controller'=>'string', 'format_name='=>'bool|true'], 'Yaf_Request_Http::setDispatched' => ['?Yaf_Request_Http', 'flag='=>'bool|true'], 'Yaf_Request_Http::setModuleName' => ['?Yaf_Request_Http', 'module'=>'string', 'format_name='=>'bool|true'], 'Yaf_Request_Http::setParam' => ['Yaf_Request_Http|false|null', 'name'=>'mixed', 'value='=>'?mixed'], 'Yaf_Request_Http::setRequestUri' => ['?Yaf_Request_Http', 'uir'=>'string'], 'Yaf_Request_Http::setRouted' => ['?Yaf_Request_Http', 'flag='=>'bool|true'], 'Yaf_Request_Simple::__construct' => ['void', 'method='=>'?string', 'module='=>'?string', 'controller='=>'?string', 'action='=>'?string', 'params='=>'?array'], 'Yaf_Request_Simple::get' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Simple::getActionName' => ['?string'], 'Yaf_Request_Simple::getBaseUri' => ['?string'], 'Yaf_Request_Simple::getCookie' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Simple::getControllerName' => ['?string'], 'Yaf_Request_Simple::getEnv' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Simple::getException' => ['?Exception'], 'Yaf_Request_Simple::getFiles' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Simple::getLanguage' => ['?string'], 'Yaf_Request_Simple::getMethod' => ['?string'], 'Yaf_Request_Simple::getModuleName' => ['?string'], 'Yaf_Request_Simple::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'], 'Yaf_Request_Simple::getParams' => ['?array'], 'Yaf_Request_Simple::getPost' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Simple::getQuery' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Simple::getRaw' => ['?string'], 'Yaf_Request_Simple::getRequest' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Simple::getRequestUri' => ['?string'], 'Yaf_Request_Simple::getServer' => ['mixed', 'name='=>'?string', 'default='=>'?mixed'], 'Yaf_Request_Simple::cleanParams' => ['?Yaf_Request_Simple'], 'Yaf_Request_Simple::isCli' => ['bool'], 'Yaf_Request_Simple::isDelete' => ['bool'], 'Yaf_Request_Simple::isDispatched' => ['bool'], 'Yaf_Request_Simple::isGet' => ['bool'], 'Yaf_Request_Simple::isHead' => ['bool'], 'Yaf_Request_Simple::isOptions' => ['bool'], 'Yaf_Request_Simple::isPatch' => ['bool'], 'Yaf_Request_Simple::isPost' => ['bool'], 'Yaf_Request_Simple::isPut' => ['bool'], 'Yaf_Request_Simple::isRouted' => ['bool'], 'Yaf_Request_Simple::isXmlHttpRequest' => ['bool'], 'Yaf_Request_Simple::setActionName' => ['?Yaf_Request_Simple', 'action'=>'string', 'format_name='=>'bool|true'], 'Yaf_Request_Simple::setBaseUri' => ['Yaf_Request_Simple|false', 'uir'=>'string'], 'Yaf_Request_Simple::setControllerName' => ['?Yaf_Request_Simple', 'controller'=>'string', 'format_name='=>'bool|true'], 'Yaf_Request_Simple::setDispatched' => ['?Yaf_Request_Simple', 'flag='=>'bool|true'], 'Yaf_Request_Simple::setModuleName' => ['?Yaf_Request_Simple', 'module'=>'string', 'format_name='=>'bool|true'], 'Yaf_Request_Simple::setParam' => ['Yaf_Request_Simple|bool|null', 'name'=>'mixed', 'value='=>'?mixed'], 'Yaf_Request_Simple::setRequestUri' => ['?Yaf_Request_Simple', 'uir'=>'string'], 'Yaf_Request_Simple::setRouted' => ['?Yaf_Request_Simple', 'flag='=>'bool|true'], 'Yaf_Response_Abstract::__clone' => ['void'], 'Yaf_Response_Abstract::__construct' => ['void'], 'Yaf_Response_Abstract::__destruct' => ['void'], 'Yaf_Response_Abstract::__toString' => ['string'], 'Yaf_Response_Abstract::appendBody' => ['Yaf_Response_Abstract|false|null', 'body'=>'string', 'name='=>'?string'], 'Yaf_Response_Abstract::clearBody' => ['?Yaf_Response_Abstract', 'name='=>'?string'], 'Yaf_Response_Abstract::getBody' => ['mixed', 'name='=>'string'], 'Yaf_Response_Abstract::prependBody' => ['Yaf_Response_Abstract|false|null', 'body'=>'string', 'name='=>'?string'], 'Yaf_Response_Abstract::response' => ['bool'], 'Yaf_Response_Abstract::setBody' => ['Yaf_Response_Abstract|false|null', 'body'=>'string', 'name='=>'?string'], 'Yaf_Response_Abstract::setRedirect' => ['?bool', 'url'=>'string'], 'Yaf_Response_Cli::__clone' => ['void'], 'Yaf_Response_Cli::__construct' => ['void'], 'Yaf_Response_Cli::__destruct' => ['void'], 'Yaf_Response_Cli::__toString' => ['string'], 'Yaf_Response_Cli::appendBody' => ['Yaf_Response_Cli|false|null', 'body'=>'string', 'name='=>'?string'], 'Yaf_Response_Cli::clearBody' => ['?Yaf_Response_Cli', 'name='=>'?string'], 'Yaf_Response_Cli::getBody' => ['mixed', 'name='=>'string'], 'Yaf_Response_Cli::prependBody' => ['Yaf_Response_Cli|false|null', 'body'=>'string', 'name='=>'?string'], 'Yaf_Response_Cli::response' => ['bool'], 'Yaf_Response_Cli::setBody' => ['Yaf_Response_Cli|false|null', 'body'=>'string', 'name='=>'?string'], 'Yaf_Response_Cli::setRedirect' => ['?bool', 'url'=>'string'], 'Yaf_Response_Http::__clone' => ['void'], 'Yaf_Response_Http::__construct' => ['void'], 'Yaf_Response_Http::__destruct' => ['void'], 'Yaf_Response_Http::__toString' => ['string'], 'Yaf_Response_Http::appendBody' => ['Yaf_Response_Http|false|null', 'body'=>'string', 'name='=>'?string'], 'Yaf_Response_Http::clearHeaders' => ['Yaf_Response_Http|false|null'], 'Yaf_Response_Http::clearBody' => ['?Yaf_Response_Http', 'name='=>'?string'], 'Yaf_Response_Http::getBody' => ['mixed', 'name='=>'string'], 'Yaf_Response_Http::getHeader' => ['mixed', 'name='=>'string'], 'Yaf_Response_Http::prependBody' => ['Yaf_Response_Http|false|null', 'body'=>'string', 'name='=>'?string'], 'Yaf_Response_Http::response' => ['?bool'], 'Yaf_Response_Http::setAllHeaders' => ['bool', 'headers'=>'array'], 'Yaf_Response_Http::setBody' => ['Yaf_Response_Http|false|null', 'body'=>'string', 'name='=>'?string'], 'Yaf_Response_Http::setHeader' => ['?bool', 'name'=>'string', 'value'=>'string', 'replace='=>'bool|false', 'response_code='=>'int'], 'Yaf_Response_Http::setRedirect' => ['?bool', 'url'=>'string'], 'Yaf_Route_Interface::__construct' => ['void'], 'Yaf_Route_Interface::assemble' => ['string', 'info'=>'array', 'query='=>'array'], 'Yaf_Route_Interface::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], 'Yaf_Route_Map::__construct' => ['void', 'controller_prefer='=>'string', 'delimiter='=>'string'], 'Yaf_Route_Map::assemble' => ['string', 'info'=>'array', 'query='=>'array'], 'Yaf_Route_Map::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], 'Yaf_Route_Regex::__construct' => ['void', 'match'=>'string', 'route'=>'array', 'map='=>'array', 'verify='=>'array', 'reverse='=>'string'], 'Yaf_Route_Regex::addConfig' => ['Yaf_Router|bool', 'config'=>'Yaf_Config_Abstract'], 'Yaf_Route_Regex::addRoute' => ['Yaf_Router|bool', 'name'=>'string', 'route'=>'Yaf_Route_Interface'], 'Yaf_Route_Regex::assemble' => ['string', 'info'=>'array', 'query='=>'array'], 'Yaf_Route_Regex::getCurrentRoute' => ['string'], 'Yaf_Route_Regex::getRoute' => ['Yaf_Route_Interface', 'name'=>'string'], 'Yaf_Route_Regex::getRoutes' => ['Yaf_Route_Interface[]'], 'Yaf_Route_Regex::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], 'Yaf_Route_Rewrite::__construct' => ['void', 'match'=>'string', 'route'=>'array', 'verify='=>'array'], 'Yaf_Route_Rewrite::addConfig' => ['Yaf_Router|bool', 'config'=>'Yaf_Config_Abstract'], 'Yaf_Route_Rewrite::addRoute' => ['Yaf_Router|bool', 'name'=>'string', 'route'=>'Yaf_Route_Interface'], 'Yaf_Route_Rewrite::assemble' => ['string', 'info'=>'array', 'query='=>'array'], 'Yaf_Route_Rewrite::getCurrentRoute' => ['string'], 'Yaf_Route_Rewrite::getRoute' => ['Yaf_Route_Interface', 'name'=>'string'], 'Yaf_Route_Rewrite::getRoutes' => ['Yaf_Route_Interface[]'], 'Yaf_Route_Rewrite::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], 'Yaf_Route_Simple::__construct' => ['void', 'module_name'=>'string', 'controller_name'=>'string', 'action_name'=>'string'], 'Yaf_Route_Simple::assemble' => ['string', 'info'=>'array', 'query='=>'array'], 'Yaf_Route_Simple::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], 'Yaf_Route_Static::assemble' => ['string', 'info'=>'array', 'query='=>'array'], 'Yaf_Route_Static::match' => ['void', 'uri'=>'string'], 'Yaf_Route_Static::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], 'Yaf_Route_Supervar::__construct' => ['void', 'supervar_name'=>'string'], 'Yaf_Route_Supervar::assemble' => ['string', 'info'=>'array', 'query='=>'array'], 'Yaf_Route_Supervar::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], 'Yaf_Router::__construct' => ['void'], 'Yaf_Router::addConfig' => ['bool', 'config'=>'Yaf_Config_Abstract'], 'Yaf_Router::addRoute' => ['bool', 'name'=>'string', 'route'=>'Yaf_Route_Abstract'], 'Yaf_Router::getCurrentRoute' => ['string'], 'Yaf_Router::getRoute' => ['Yaf_Route_Interface', 'name'=>'string'], 'Yaf_Router::getRoutes' => ['mixed'], 'Yaf_Router::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], 'Yaf_Session::__clone' => ['void'], 'Yaf_Session::__construct' => ['void'], 'Yaf_Session::__get' => ['void', 'name'=>'string'], 'Yaf_Session::__isset' => ['void', 'name'=>'string'], 'Yaf_Session::__set' => ['void', 'name'=>'string', 'value'=>'string'], 'Yaf_Session::__sleep' => ['list'], 'Yaf_Session::__unset' => ['void', 'name'=>'string'], 'Yaf_Session::__wakeup' => ['void'], 'Yaf_Session::count' => ['0|positive-int'], 'Yaf_Session::current' => ['void'], 'Yaf_Session::del' => ['void', 'name'=>'string'], 'Yaf_Session::get' => ['mixed', 'name'=>'string'], 'Yaf_Session::getInstance' => ['void'], 'Yaf_Session::has' => ['void', 'name'=>'string'], 'Yaf_Session::key' => ['void'], 'Yaf_Session::next' => ['void'], 'Yaf_Session::offsetExists' => ['void', 'name'=>'string'], 'Yaf_Session::offsetGet' => ['void', 'name'=>'string'], 'Yaf_Session::offsetSet' => ['void', 'name'=>'string', 'value'=>'string'], 'Yaf_Session::offsetUnset' => ['void', 'name'=>'string'], 'Yaf_Session::rewind' => ['void'], 'Yaf_Session::set' => ['Yaf_Session|bool', 'name'=>'string', 'value'=>'mixed'], 'Yaf_Session::start' => ['void'], 'Yaf_Session::valid' => ['void'], 'Yaf_View_Interface::assign' => ['Yaf_View_Interface|bool', 'name'=>'string', 'value='=>'?mixed'], 'Yaf_View_Interface::display' => ['Yaf_View_Interface|bool', 'tpl'=>'string', 'tpl_vars='=>'?array'], 'Yaf_View_Interface::getScriptPath' => ['string'], 'Yaf_View_Interface::render' => ['string|bool', 'tpl'=>'string', 'tpl_vars='=>'?array'], 'Yaf_View_Interface::setScriptPath' => ['bool', 'template_dir'=>'string'], 'Yaf_View_Simple::__construct' => ['void', 'tempalte_dir'=>'string', 'options='=>'?array'], 'Yaf_View_Simple::__get' => ['mixed', 'name='=>'?string'], 'Yaf_View_Simple::__isset' => ['bool', 'name'=>'string'], 'Yaf_View_Simple::__set' => ['void', 'name'=>'string', 'value'=>'mixed'], 'Yaf_View_Simple::assign' => ['Yaf_View_Simple|false|null', 'name='=>'?mixed', 'default='=>'?mixed'], 'Yaf_View_Simple::assignRef' => ['?Yaf_View_Simple', 'name'=>'string', '&value'=>'mixed'], 'Yaf_View_Simple::clear' => ['?Yaf_View_Simple', 'name='=>'string'], 'Yaf_View_Simple::display' => ['?bool', 'tpl'=>'string', 'tpl_vars='=>'?array'], 'Yaf_View_Simple::eval' => ['string|null|false', 'tpl_str'=>'string', 'vars='=>'?array'], 'Yaf_View_Simple::get' => ['mixed', 'name='=>'?string'], 'Yaf_View_Simple::getScriptPath' => ['?string'], 'Yaf_View_Simple::render' => ['string|null|false', 'tpl'=>'string', 'tpl_vars='=>'?array'], 'Yaf_View_Simple::setScriptPath' => ['Yaf_View_Simple|false|null', 'template_dir'=>'string'], 'yaml_emit' => ['string', 'data'=>'mixed', 'encoding='=>'int', 'linebreak='=>'int'], 'yaml_emit_file' => ['bool', 'filename'=>'string', 'data'=>'mixed', 'encoding='=>'int', 'linebreak='=>'int'], 'yaml_parse' => ['mixed', 'input'=>'string', 'pos='=>'int', '&w_ndocs='=>'int', 'callbacks='=>'array'], 'yaml_parse_file' => ['mixed', 'filename'=>'string', 'pos='=>'int', '&w_ndocs='=>'int', 'callbacks='=>'array'], 'yaml_parse_url' => ['mixed', 'url'=>'string', 'pos='=>'int', '&w_ndocs='=>'int', 'callbacks='=>'array'], 'Yar_Client::__call' => ['void', 'method'=>'string', 'parameters'=>'array'], 'Yar_Client::__construct' => ['void', 'url'=>'string'], 'Yar_Client::setOpt' => ['bool', 'name'=>'int', 'value'=>'mixed'], 'Yar_Client_Exception::getType' => ['void'], 'Yar_Concurrent_Client::call' => ['int', 'uri'=>'string', 'method'=>'string', 'parameters'=>'array', 'callback='=>'callable'], 'Yar_Concurrent_Client::loop' => ['bool', 'callback='=>'callable', 'error_callback='=>'callable'], 'Yar_Concurrent_Client::reset' => ['bool'], 'Yar_Server::__construct' => ['void', 'obj'=>'Object'], 'Yar_Server::handle' => ['bool'], 'Yar_Server_Exception::getType' => ['string'], 'yaz_addinfo' => ['string', 'id'=>'resource'], 'yaz_ccl_conf' => ['void', 'id'=>'resource', 'config'=>'array'], 'yaz_ccl_parse' => ['bool', 'id'=>'resource', 'query'=>'string', '&w_result'=>'array'], 'yaz_close' => ['bool', 'id'=>'resource'], 'yaz_connect' => ['mixed', 'zurl'=>'string', 'options='=>'mixed'], 'yaz_database' => ['bool', 'id'=>'resource', 'databases'=>'string'], 'yaz_element' => ['bool', 'id'=>'resource', 'elementset'=>'string'], 'yaz_errno' => ['int', 'id'=>'resource'], 'yaz_error' => ['string', 'id'=>'resource'], 'yaz_es' => ['void', 'id'=>'resource', 'type'=>'string', 'args'=>'array'], 'yaz_es_result' => ['array', 'id'=>'resource'], 'yaz_get_option' => ['string', 'id'=>'resource', 'name'=>'string'], 'yaz_hits' => ['int', 'id'=>'resource', 'searchresult='=>'array'], 'yaz_itemorder' => ['void', 'id'=>'resource', 'args'=>'array'], 'yaz_present' => ['bool', 'id'=>'resource'], 'yaz_range' => ['void', 'id'=>'resource', 'start'=>'int', 'number'=>'int'], 'yaz_record' => ['string', 'id'=>'resource', 'pos'=>'int', 'type'=>'string'], 'yaz_scan' => ['void', 'id'=>'resource', 'type'=>'string', 'startterm'=>'string', 'flags='=>'array'], 'yaz_scan_result' => ['array', 'id'=>'resource', 'result='=>'array'], 'yaz_schema' => ['void', 'id'=>'resource', 'schema'=>'string'], 'yaz_search' => ['bool', 'id'=>'resource', 'type'=>'string', 'query'=>'string'], 'yaz_set_option' => ['', 'id'=>'', 'name'=>'string', 'value'=>'string', 'options'=>'array'], 'yaz_sort' => ['void', 'id'=>'resource', 'criteria'=>'string'], 'yaz_syntax' => ['void', 'id'=>'resource', 'syntax'=>'string'], 'yaz_wait' => ['mixed', '&rw_options='=>'array'], 'yp_all' => ['void', 'domain'=>'string', 'map'=>'string', 'callback'=>'string'], 'yp_cat' => ['array', 'domain'=>'string', 'map'=>'string'], 'yp_err_string' => ['string', 'errorcode'=>'int'], 'yp_errno' => ['int'], 'yp_first' => ['array', 'domain'=>'string', 'map'=>'string'], 'yp_get_default_domain' => ['string'], 'yp_master' => ['string', 'domain'=>'string', 'map'=>'string'], 'yp_match' => ['string', 'domain'=>'string', 'map'=>'string', 'key'=>'string'], 'yp_next' => ['array', 'domain'=>'string', 'map'=>'string', 'key'=>'string'], 'yp_order' => ['int', 'domain'=>'string', 'map'=>'string'], 'zem_get_extension_info_by_id' => [''], 'zem_get_extension_info_by_name' => [''], 'zem_get_extensions_info' => [''], 'zem_get_license_info' => [''], 'zend_current_obfuscation_level' => ['int'], 'zend_disk_cache_clear' => ['bool', 'namespace='=>'mixed|string'], 'zend_disk_cache_delete' => ['mixed|null', 'key'=>''], 'zend_disk_cache_fetch' => ['mixed|null', 'key'=>''], 'zend_disk_cache_store' => ['bool', 'key'=>'', 'value'=>'', 'ttl='=>'int|mixed'], 'zend_get_id' => ['array', 'all_ids='=>'all_ids|false'], 'zend_is_configuration_changed' => [''], 'zend_loader_current_file' => ['string'], 'zend_loader_enabled' => ['bool'], 'zend_loader_file_encoded' => ['bool'], 'zend_loader_file_licensed' => ['array'], 'zend_loader_install_license' => ['bool', 'license_file'=>'license_file', 'override'=>'override'], 'zend_logo_guid' => ['string'], 'zend_obfuscate_class_name' => ['string', 'class_name'=>'class_name'], 'zend_obfuscate_function_name' => ['string', 'function_name'=>'function_name'], 'zend_optimizer_version' => ['string'], 'zend_runtime_obfuscate' => ['void'], 'zend_send_buffer' => ['null|false', 'buffer'=>'string', 'mime_type='=>'string', 'custom_headers='=>'string'], 'zend_send_file' => ['null|false', 'filename'=>'string', 'mime_type='=>'string', 'custom_headers='=>'string'], 'zend_set_configuration_changed' => [''], 'zend_shm_cache_clear' => ['bool', 'namespace='=>'mixed|string'], 'zend_shm_cache_delete' => ['mixed|null', 'key'=>''], 'zend_shm_cache_fetch' => ['mixed|null', 'key'=>''], 'zend_shm_cache_store' => ['bool', 'key'=>'', 'value'=>'', 'ttl='=>'int|mixed'], 'zend_thread_id' => ['int'], 'zend_version' => ['string'], 'ZendAPI_Job::addJobToQueue' => ['int', 'jobqueue_url'=>'string', 'password'=>'string'], 'ZendAPI_Job::getApplicationID' => [''], 'ZendAPI_Job::getEndTime' => [''], 'ZendAPI_Job::getGlobalVariables' => [''], 'ZendAPI_Job::getHost' => [''], 'ZendAPI_Job::getID' => [''], 'ZendAPI_Job::getInterval' => [''], 'ZendAPI_Job::getJobDependency' => [''], 'ZendAPI_Job::getJobName' => [''], 'ZendAPI_Job::getJobPriority' => [''], 'ZendAPI_Job::getJobStatus' => ['int'], 'ZendAPI_Job::getLastPerformedStatus' => ['int'], 'ZendAPI_Job::getOutput' => ['An'], 'ZendAPI_Job::getPreserved' => [''], 'ZendAPI_Job::getProperties' => ['array'], 'ZendAPI_Job::getScheduledTime' => [''], 'ZendAPI_Job::getScript' => [''], 'ZendAPI_Job::getTimeToNextRepeat' => ['int'], 'ZendAPI_Job::getUserVariables' => [''], 'ZendAPI_Job::setApplicationID' => ['', 'app_id'=>''], 'ZendAPI_Job::setGlobalVariables' => ['', 'vars'=>''], 'ZendAPI_Job::setJobDependency' => ['', 'job_id'=>''], 'ZendAPI_Job::setJobName' => ['', 'name'=>''], 'ZendAPI_Job::setJobPriority' => ['', 'priority'=>'int'], 'ZendAPI_Job::setPreserved' => ['', 'preserved'=>''], 'ZendAPI_Job::setRecurrenceData' => ['', 'interval'=>'', 'end_time='=>'mixed'], 'ZendAPI_Job::setScheduledTime' => ['', 'timestamp'=>''], 'ZendAPI_Job::setScript' => ['', 'script'=>''], 'ZendAPI_Job::setUserVariables' => ['', 'vars'=>''], 'ZendAPI_Job::ZendAPI_Job' => ['Job', 'script'=>'script'], 'ZendAPI_Queue::addJob' => ['int', '&job'=>'Job'], 'ZendAPI_Queue::getAllApplicationIDs' => ['array'], 'ZendAPI_Queue::getAllhosts' => ['array'], 'ZendAPI_Queue::getHistoricJobs' => ['array', 'status'=>'int', 'start_time'=>'', 'end_time'=>'', 'index'=>'int', 'count'=>'int', '&total'=>'int'], 'ZendAPI_Queue::getJob' => ['Job', 'job_id'=>'int'], 'ZendAPI_Queue::getJobsInQueue' => ['array', 'filter_options='=>'array', 'max_jobs='=>'int', 'with_globals_and_output='=>'bool|false'], 'ZendAPI_Queue::getLastError' => ['string'], 'ZendAPI_Queue::getNumOfJobsInQueue' => ['int', 'filter_options='=>'array'], 'ZendAPI_Queue::getStatistics' => ['array'], 'ZendAPI_Queue::isScriptExists' => ['bool', 'path'=>'string'], 'ZendAPI_Queue::isSuspend' => ['bool'], 'ZendAPI_Queue::login' => ['bool', 'password'=>'string', 'application_id='=>'int'], 'ZendAPI_Queue::removeJob' => ['bool', 'job_id'=>'array|int'], 'ZendAPI_Queue::requeueJob' => ['bool', 'job'=>'Job'], 'ZendAPI_Queue::resumeJob' => ['bool', 'job_id'=>'array|int'], 'ZendAPI_Queue::resumeQueue' => ['bool'], 'ZendAPI_Queue::setMaxHistoryTime' => ['bool'], 'ZendAPI_Queue::suspendJob' => ['bool', 'job_id'=>'array|int'], 'ZendAPI_Queue::suspendQueue' => ['bool'], 'ZendAPI_Queue::updateJob' => ['int', '&job'=>'Job'], 'ZendAPI_Queue::zendapi_queue' => ['ZendAPI_Queue', 'queue_url'=>'string'], 'zip_close' => ['void', 'zip'=>'resource'], 'zip_entry_close' => ['bool', 'zip_ent'=>'resource'], 'zip_entry_compressedsize' => ['int|false', 'zip_entry'=>'resource'], 'zip_entry_compressionmethod' => ['string|false', 'zip_entry'=>'resource'], 'zip_entry_filesize' => ['int|false', 'zip_entry'=>'resource'], 'zip_entry_name' => ['string|false', 'zip_entry'=>'resource'], 'zip_entry_open' => ['bool', 'zip_dp'=>'resource', 'zip_entry'=>'resource', 'mode='=>'string'], 'zip_entry_read' => ['string|false', 'zip_entry'=>'resource', 'len='=>'int'], 'zip_open' => ['resource|false|int', 'filename'=>'string'], 'zip_read' => ['resource|false|int', 'zip'=>'resource'], 'ZipArchive::addEmptyDir' => ['bool', 'dirname'=>'string'], 'ZipArchive::addFile' => ['bool', 'filepath'=>'string', 'entryname='=>'string', 'start='=>'int', 'length='=>'int'], 'ZipArchive::addFromString' => ['bool', 'entryname'=>'string', 'content'=>'string'], 'ZipArchive::addGlob' => ['bool', 'pattern'=>'string', 'flags='=>'int', 'options='=>'array'], 'ZipArchive::addPattern' => ['bool', 'pattern'=>'string', 'path='=>'string', 'options='=>'array'], 'ZipArchive::close' => ['bool'], 'ZipArchive::count' => ['0|positive-int'], 'ZipArchive::createEmptyDir' => ['bool', 'dirname'=>'string'], 'ZipArchive::deleteIndex' => ['bool', 'index'=>'int'], 'ZipArchive::deleteName' => ['bool', 'name'=>'string'], 'ZipArchive::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string[]|string'], 'ZipArchive::getArchiveComment' => ['string', 'flags='=>'int'], 'ZipArchive::getCommentIndex' => ['string', 'index'=>'int', 'flags='=>'int'], 'ZipArchive::getCommentName' => ['string', 'name'=>'string', 'flags='=>'int'], 'ZipArchive::getExternalAttributesIndex' => ['bool', 'index'=>'int', '&w_opsys'=>'int', '&w_attr'=>'int', 'flags='=>'int'], 'ZipArchive::getExternalAttributesName' => ['bool', 'name'=>'string', '&w_opsys'=>'int', '&w_attr'=>'int', 'flags='=>'int'], 'ZipArchive::getFromIndex' => ['string|false', 'index'=>'int', 'len='=>'int', 'flags='=>'int'], 'ZipArchive::getFromName' => ['string|false', 'entryname'=>'string', 'len='=>'int', 'flags='=>'int'], 'ZipArchive::getNameIndex' => ['string|false', 'index'=>'int', 'flags='=>'int'], 'ZipArchive::getStatusString' => ['string'], 'ZipArchive::getStream' => ['resource|false', 'entryname'=>'string'], 'ZipArchive::locateName' => ['int|false', 'filename'=>'string', 'flags='=>'int'], 'ZipArchive::open' => ['ZipArchive::ER_*|true', 'source'=>'string', 'flags='=>'int'], 'ZipArchive::renameIndex' => ['bool', 'index'=>'int', 'new_name'=>'string'], 'ZipArchive::renameName' => ['bool', 'name'=>'string', 'new_name'=>'string'], 'ZipArchive::setArchiveComment' => ['bool', 'comment'=>'string'], 'ZipArchive::setCommentIndex' => ['bool', 'index'=>'int', 'comment'=>'string'], 'ZipArchive::setCommentName' => ['bool', 'name'=>'string', 'comment'=>'string'], 'ZipArchive::setCompressionIndex' => ['bool', 'index'=>'int', 'comp_method'=>'int', 'comp_flags='=>'int'], 'ZipArchive::setCompressionName' => ['bool', 'name'=>'string', 'comp_method'=>'int', 'comp_flags='=>'int'], 'ZipArchive::setEncryptionIndex' => ['bool', 'index'=>'int', 'method'=>'string', 'password='=>'string'], 'ZipArchive::setEncryptionName' => ['bool', 'name'=>'string', 'method'=>'int', 'password='=>'string'], 'ZipArchive::setExternalAttributesIndex' => ['bool', 'index'=>'int', 'opsys'=>'int', 'attr'=>'int', 'flags='=>'int'], 'ZipArchive::setExternalAttributesName' => ['bool', 'name'=>'string', 'opsys'=>'int', 'attr'=>'int', 'flags='=>'int'], 'ZipArchive::setPassword' => ['bool', 'password'=>'string'], 'ZipArchive::statIndex' => ['array|false', 'index'=>'int', 'flags='=>'int'], 'ZipArchive::statName' => ['array|false', 'filename'=>'string', 'flags='=>'int'], 'ZipArchive::unchangeAll' => ['bool'], 'ZipArchive::unchangeArchive' => ['bool'], 'ZipArchive::unchangeIndex' => ['bool', 'index'=>'int'], 'ZipArchive::unchangeName' => ['bool', 'name'=>'string'], 'zlib_decode' => ['string|false', 'data'=>'string', 'max_decoded_len='=>'int'], 'zlib_encode' => ['string|false', 'data'=>'string', 'encoding'=>'int', 'level='=>'string|int'], 'zlib_get_coding_type' => ['string|false'], 'ZMQ::__construct' => ['void'], 'ZMQContext::__construct' => ['void', 'io_threads='=>'int', 'is_persistent='=>'bool'], 'ZMQContext::getOpt' => ['mixed', 'key'=>'string'], 'ZMQContext::getSocket' => ['ZMQSocket', 'type'=>'int', 'persistent_id='=>'string', 'on_new_socket='=>'callable'], 'ZMQContext::isPersistent' => ['bool'], 'ZMQContext::setOpt' => ['ZMQContext', 'key'=>'int', 'value'=>'mixed'], 'ZMQDevice::__construct' => ['void', 'frontend'=>'ZMQSocket', 'backend'=>'ZMQSocket', 'listener='=>'ZMQSocket'], 'ZMQDevice::getIdleTimeout' => ['ZMQDevice'], 'ZMQDevice::getTimerTimeout' => ['ZMQDevice'], 'ZMQDevice::run' => ['void'], 'ZMQDevice::setIdleCallback' => ['ZMQDevice', 'cb_func'=>'callable', 'timeout'=>'int', 'user_data='=>'mixed'], 'ZMQDevice::setIdleTimeout' => ['ZMQDevice', 'timeout'=>'int'], 'ZMQDevice::setTimerCallback' => ['ZMQDevice', 'cb_func'=>'callable', 'timeout'=>'int', 'user_data='=>'mixed'], 'ZMQDevice::setTimerTimeout' => ['ZMQDevice', 'timeout'=>'int'], 'ZMQPoll::add' => ['string', 'entry'=>'mixed', 'type'=>'int'], 'ZMQPoll::clear' => ['ZMQPoll'], 'ZMQPoll::count' => ['0|positive-int'], 'ZMQPoll::getLastErrors' => ['array'], 'ZMQPoll::poll' => ['int', '&w_readable'=>'array', '&w_writable'=>'array', 'timeout='=>'int'], 'ZMQPoll::remove' => ['bool', 'item'=>'mixed'], 'ZMQSocket::__construct' => ['void', 'context'=>'ZMQContext', 'type'=>'int', 'persistent_id='=>'string', 'on_new_socket='=>'callable'], 'ZMQSocket::bind' => ['ZMQSocket', 'dsn'=>'string', 'force='=>'bool'], 'ZMQSocket::connect' => ['ZMQSocket', 'dsn'=>'string', 'force='=>'bool'], 'ZMQSocket::disconnect' => ['ZMQSocket', 'dsn'=>'string'], 'ZMQSocket::getEndpoints' => ['array'], 'ZMQSocket::getPersistentId' => ['string'], 'ZMQSocket::getSocketType' => ['int'], 'ZMQSocket::getSockOpt' => ['mixed', 'key'=>'string'], 'ZMQSocket::isPersistent' => ['bool'], 'ZMQSocket::recv' => ['string', 'mode='=>'int'], 'ZMQSocket::recvMulti' => ['string[]', 'mode='=>'int'], 'ZMQSocket::send' => ['ZMQSocket', 'message'=>'array', 'mode='=>'int'], 'ZMQSocket::send\'1' => ['ZMQSocket', 'message'=>'string', 'mode='=>'int'], 'ZMQSocket::sendmulti' => ['ZMQSocket', 'message'=>'array', 'mode='=>'int'], 'ZMQSocket::setSockOpt' => ['ZMQSocket', 'key'=>'int', 'value'=>'mixed'], 'ZMQSocket::unbind' => ['ZMQSocket', 'dsn'=>'string'], 'Zookeeper::addAuth' => ['bool', 'scheme'=>'string', 'cert'=>'string', 'completion_cb='=>'callable'], 'Zookeeper::connect' => ['void', 'host'=>'string', 'watcher_cb='=>'callable', 'recv_timeout='=>'int'], 'Zookeeper::create' => ['string', 'path'=>'string', 'value'=>'string', 'acls'=>'array', 'flags='=>'int'], 'Zookeeper::delete' => ['bool', 'path'=>'string', 'version='=>'int'], 'Zookeeper::exists' => ['bool', 'path'=>'string', 'watcher_cb='=>'callable'], 'Zookeeper::get' => ['string', 'path'=>'string', 'watcher_cb='=>'callable', 'stat='=>'array', 'max_size='=>'int'], 'Zookeeper::getAcl' => ['array', 'path'=>'string'], 'Zookeeper::getChildren' => ['array', 'path'=>'string', 'watcher_cb='=>'callable'], 'Zookeeper::getClientId' => ['int'], 'Zookeeper::getRecvTimeout' => ['int'], 'Zookeeper::getState' => ['int'], 'Zookeeper::isRecoverable' => ['bool'], 'Zookeeper::set' => ['bool', 'path'=>'string', 'value'=>'string', 'version='=>'int', 'stat='=>'array'], 'Zookeeper::setAcl' => ['bool', 'path'=>'string', 'version'=>'int', 'acl'=>'array'], 'Zookeeper::setDebugLevel' => ['bool', 'logLevel'=>'int'], 'Zookeeper::setDeterministicConnOrder' => ['bool', 'yesOrNo'=>'bool'], 'Zookeeper::setLogStream' => ['bool', 'stream'=>'resource'], 'Zookeeper::setWatcher' => ['bool', 'watcher_cb'=>'callable'], 'zookeeper_dispatch' => ['void'], ]; // // Hoa // // // @license // // New BSD License // // Copyright © 2007-2017, Hoa community. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of the Hoa nor the names of its contributors may be // used to endorse or promote products derived from this software without // specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // // Grammar \Hoa\Regex\Grammar. // // Provide grammar of PCRE (Perl Compatible Regular Expression)for the LL(k) // parser. More informations at http://pcre.org/pcre.txt, sections pcrepattern & // pcresyntax. // // @copyright Copyright © 2007-2017 Hoa community. // @license New BSD License // // Character classes. // tokens suffixed with "fc_" are the same as without such suffix but followed by "class:_class" %token negative_class_fc_ \[\^(?=\]) -> class_fc %token class_fc_ \[(?=\]) -> class_fc %token class_fc:_class \] -> class %token negative_class_ \[\^ -> class %token class_ \[ -> class %token class:posix_class \[:\^?[a-z]+:\] %token class:class_ \[ %token class:_class \] -> default %token class:range \- // taken over from literals but class:character has \b support on top (backspace in character classes) %token class:character \\([aefnrtb]|c[\x00-\x7f]) %token class:dynamic_character \\([0-7]{3}|x[0-9a-zA-Z]{2}|x{[0-9a-zA-Z]+}) %token class:character_type \\([CdDhHNRsSvVwWX]|[pP]{[^}]+}) %token class:literal \\.|.|\n // Internal options. // See https://www.regular-expressions.info/refmodifiers.html // and https://www.php.net/manual/en/regexp.reference.internal-options.php %token internal_option \(\?[imsxnJUX^]*-?[imsxnJUX^]+\) // Lookahead and lookbehind assertions. %token lookahead_ \(\?= %token negative_lookahead_ \(\?! %token lookbehind_ \(\?<= %token negative_lookbehind_ \(\? nc %token absolute_reference_ \(\?\((?=\d) -> c %token relative_reference_ \(\?\((?=[\+\-]) -> c %token c:index [\+\-]?\d+ -> default %token assertion_reference_ \(\?\( // Comments. %token comment_ \(\?# -> co %token co:_comment \) -> default %token co:comment .*?(?=(? mark %token mark:name [^)]+ %token mark:_marker \) -> default // Capturing group. %token named_capturing_ \(\?P?< -> nc %token nc:_named_capturing > -> default %token nc:capturing_name .+?(?=(?) %token non_capturing_ \(\?: %token non_capturing_internal_option \(\?[imsxnJUX^]*-?[imsxnJUX^]+: %token non_capturing_reset_ \(\?\| %token atomic_group_ \(\?> %token capturing_ \( %token _capturing \) // Quantifiers (by default, greedy). %token zero_or_one_possessive \?\+ %token zero_or_one_lazy \?\? %token zero_or_one \? %token zero_or_more_possessive \*\+ %token zero_or_more_lazy \*\? %token zero_or_more \* %token one_or_more_possessive \+\+ %token one_or_more_lazy \+\? %token one_or_more \+ %token exactly_n \{[0-9]+\} %token n_to_m_possessive \{[0-9]+,[0-9]+\}\+ %token n_to_m_lazy \{[0-9]+,[0-9]+\}\? %token n_to_m \{[0-9]+,[0-9]+\} %token n_or_more_possessive \{[0-9]+,\}\+ %token n_or_more_lazy \{[0-9]+,\}\? %token n_or_more \{[0-9]+,\} // Alternation. %token alternation \| // Literal. %token character \\([aefnrt]|c[\x00-\x7f]) %token dynamic_character \\([0-7]{3}|x[0-9a-zA-Z]{2}|x{[0-9a-zA-Z]+}) // Please, see PCRESYNTAX(3), General Category properties, PCRE special category // properties and script names for \p{} and \P{}. %token character_type \\([CdDhHNRsSvVwWX]|[pP]{[^}]+}) %token anchor \\([bBAZzG])|\^|\$ %token match_point_reset \\K %token literal \\.|.|\n // Rules. #expression: alternation() alternation: concatenation()? ( concatenation()? #alternation )* concatenation: ( internal_options() | assertion() | quantification() | condition() ) ( ( internal_options() | assertion() | quantification() | condition() ) #concatenation )* #internal_options: #condition: ( ::named_reference_:: ::_named_capturing:: #namedcondition | ( ::relative_reference_:: #relativecondition | ::absolute_reference_:: #absolutecondition ) | ::assertion_reference_:: alternation() #assertioncondition ) ::_capturing:: alternation() ::_capturing:: assertion: ( ::lookahead_:: #lookahead | ::negative_lookahead_:: #negativelookahead | ::lookbehind_:: #lookbehind | ::negative_lookbehind_:: #negativelookbehind ) alternation() ::_capturing:: quantification: ( class() | simple() ) ( quantifier() #quantification )? quantifier: | | | | | | | | | | | | | | | #class: ( ::negative_class_fc_:: #negativeclass <_class> | ::class_fc_:: <_class> | ::negative_class_:: #negativeclass | ::class_:: ) ? ( | | range() ? | literal() )* ? ::_class:: #range: literal() ::range:: literal() simple: capturing() | literal() #capturing: ::marker_:: ::_marker:: #mark | ::comment_:: ? ::_comment:: #comment | ( ::named_capturing_:: ::_named_capturing:: #namedcapturing | ::non_capturing_:: #noncapturing | non_capturing_internal_options() #noncapturing | ::non_capturing_reset_:: #noncapturingreset | ::atomic_group_:: #atomicgroup | ::capturing_:: ) alternation() ::_capturing:: non_capturing_internal_options: literal: | | | | | ['http_get_last_response_headers' => ['list|null'], 'http_clear_last_response_headers' => ['void'], 'mb_lcfirst' => ['string', 'string' => 'string', 'encoding=' => 'string'], 'mb_ucfirst' => ['string', 'string' => 'string', 'encoding=' => 'string']], 'old' => []]; [ 'array_combine' => ['associative-array', 'keys'=>'string[]|int[]', 'values'=>'array'], 'base64_decode' => ['string', 'string'=>'string', 'strict='=>'false'], 'base64_decode\'1' => ['string|false', 'string'=>'string', 'strict='=>'true'], 'bcdiv' => ['string', 'dividend'=>'string', 'divisor'=>'string', 'scale='=>'int'], 'bcmod' => ['string', 'dividend'=>'string', 'divisor'=>'string', 'scale='=>'int'], 'bcpowmod' => ['string', 'base'=>'string', 'exponent'=>'string', 'modulus'=>'string', 'scale='=>'int'], 'call_user_func_array' => ['mixed', 'function'=>'callable', 'parameters'=>'array'], 'ceil' => ['float', 'number'=>'float'], 'com_load_typelib' => ['bool', 'typelib_name'=>'string', 'case_insensitive='=>'true'], 'count_chars' => ['array|string', 'input'=>'string', 'mode='=>'int'], 'curl_init' => ['__benevolent', 'url='=>'string'], 'date_add' => ['DateTime', 'object'=>'DateTime', 'interval'=>'DateInterval'], 'date_date_set' => ['DateTime', 'object'=>'DateTime', 'year'=>'int', 'month'=>'int', 'day'=>'int'], 'date_diff' => ['DateInterval', 'obj1'=>'DateTimeInterface', 'obj2'=>'DateTimeInterface', 'absolute='=>'bool'], 'date_format' => ['string', 'object'=>'DateTimeInterface', 'format'=>'string'], 'date_isodate_set' => ['DateTime', 'object'=>'DateTime', 'year'=>'int', 'week'=>'int', 'day='=>'int|mixed'], 'date_parse' => ['array', 'date'=>'string'], 'date_sub' => ['DateTime', 'object'=>'DateTime', 'interval'=>'DateInterval'], 'date_sun_info' => ['array{sunrise: int|bool,sunset: int|bool,transit: int|bool,civil_twilight_begin: int|bool,civil_twilight_end: int|bool,nautical_twilight_begin: int|bool,nautical_twilight_end: int|bool,astronomical_twilight_begin: int|bool,astronomical_twilight_end: int|bool}', 'time'=>'int', 'latitude'=>'float', 'longitude'=>'float'], 'date_time_set' => ['DateTime', 'object'=>'DateTime', 'hour'=>'int', 'minute'=>'int', 'second='=>'int', 'microseconds='=>'int'], 'date_timestamp_set' => ['DateTime', 'object'=>'DateTime', 'unixtimestamp'=>'int'], 'date_timezone_set' => ['DateTime', 'object'=>'DateTime', 'timezone'=>'DateTimeZone'], 'explode' => ['list', 'separator'=>'non-empty-string', 'str'=>'string', 'limit='=>'int'], 'fdiv' => ['float', 'dividend'=>'float', 'divisor'=>'float'], 'floor' => ['float', 'number'=>'float'], 'forward_static_call_array' => ['mixed', 'function'=>'callable', 'parameters'=>'array'], 'get_debug_type' => ['string', 'var'=>'mixed'], 'get_resource_id' => ['int', 'res'=>'resource'], 'gmdate' => ['string', 'format'=>'string', 'timestamp='=>'int'], 'gmmktime' => ['int|false', 'hour'=>'int', 'minute='=>'int', 'second='=>'int', 'month='=>'int', 'day='=>'int', 'year='=>'int'], 'hash' => ['non-falsy-string', 'algo'=>'string', 'data'=>'string', 'raw_output='=>'bool'], 'hash_hkdf' => ['non-falsy-string', 'algo'=>'string', 'key'=>'string', 'length='=>'int', 'info='=>'string', 'salt='=>'string'], 'hash_hmac' => ['non-falsy-string', 'algo'=>'string', 'data'=>'string', 'key'=>'string', 'raw_output='=>'bool'], 'hash_pbkdf2' => ['non-falsy-string', 'algo'=>'string', 'password'=>'string', 'salt'=>'string', 'iterations'=>'int', 'length='=>'int', 'raw_output='=>'bool'], 'imageaffine' => ['false|object', 'src'=>'resource', 'affine'=>'array', 'clip='=>'array'], 'imagecreate' => ['__benevolent', 'width'=>'int', 'height'=>'int'], 'imagecreatefrombmp' => ['false|object', 'filename'=>'string'], 'imagecreatefromgd' => ['false|object', 'filename'=>'string'], 'imagecreatefromgd2' => ['false|object', 'filename'=>'string'], 'imagecreatefromgd2part' => ['false|object', 'filename'=>'string', 'srcx'=>'int', 'srcy'=>'int', 'width'=>'int', 'height'=>'int'], 'imagecreatefromgif' => ['false|object', 'filename'=>'string'], 'imagecreatefromjpeg' => ['false|object', 'filename'=>'string'], 'imagecreatefrompng' => ['false|object', 'filename'=>'string'], 'imagecreatefromstring' => ['false|object', 'image'=>'string'], 'imagecreatefromwbmp' => ['false|object', 'filename'=>'string'], 'imagecreatefromwebp' => ['false|object', 'filename'=>'string'], 'imagecreatefromxbm' => ['false|object', 'filename'=>'string'], 'imagecreatefromxpm' => ['false|object', 'filename'=>'string'], 'imagecreatetruecolor' => ['__benevolent', 'width'=>'int', 'height'=>'int'], 'imagecrop' => ['false|object', 'im'=>'resource', 'rect'=>'array'], 'imagecropauto' => ['false|object', 'im'=>'resource', 'mode'=>'int', 'threshold'=>'float', 'color'=>'int'], 'imagegetclip' => ['array', 'im'=>'resource'], 'imagegrabscreen' => ['false|object'], 'imagegrabwindow' => ['false|object', 'window_handle'=>'int', 'client_area='=>'int'], 'imagejpeg' => ['bool', 'im'=>'GdImage', 'filename='=>'string|resource|null', 'quality='=>'int'], 'imagerotate' => ['false|object', 'src_im'=>'resource', 'angle'=>'float', 'bgdcolor'=>'int', 'ignoretransparent='=>'int'], 'imagescale' => ['false|object', 'im'=>'resource', 'new_width'=>'int', 'new_height='=>'int', 'method='=>'int'], 'getenv' => ['string|false', 'varname'=>'string', 'local_only='=>'bool'], 'getenv\'1' => ['array', 'varname='=>'null', 'local_only='=>'bool'], 'ldap_set_rebind_proc' => ['bool', 'ldap'=>'resource', 'callback'=>'?callable'], 'mb_decode_numericentity' => ['string|false', 'string'=>'string', 'convmap'=>'array', 'encoding='=>'string'], 'mb_encoding_aliases' => ['list', 'encoding'=>'string'], 'mb_str_split' => ['list', 'str'=>'string', 'split_length='=>'positive-int', 'encoding='=>'string'], 'mb_strlen' => ['0|positive-int', 'str'=>'string', 'encoding='=>'string'], 'mktime' => ['int|false', 'hour'=>'int', 'minute='=>'int', 'second='=>'int', 'month='=>'int', 'day='=>'int', 'year='=>'int'], 'odbc_exec' => ['resource|false', 'connection_id'=>'resource', 'query'=>'string'], 'parse_str' => ['void', 'encoded_string'=>'string', '&w_result'=>'array'], 'password_hash' => ['non-empty-string', 'password'=>'string', 'algo'=>'string|int|null', 'options='=>'array'], 'PDOStatement::fetchAll' => ['array', 'how='=>'int', 'fetch_argument='=>'int|string|callable', 'ctor_args='=>'?array'], 'PhpToken::tokenize' => ['list', 'code'=>'string', 'flags='=>'int'], 'PhpToken::is' => ['bool', 'kind'=>'string|int|string[]|int[]'], 'PhpToken::isIgnorable' => ['bool'], 'PhpToken::getTokenName' => ['non-falsy-string'], 'preg_match_all' => ['0|positive-int|false', 'pattern'=>'string', 'subject'=>'string', '&w_subpatterns='=>'array', 'flags='=>'int', 'offset='=>'int'], 'proc_get_status' => ['array{command: string, pid: int, running: bool, signaled: bool, stopped: bool, exitcode: int, termsig: int, stopsig: int}', 'process'=>'resource'], 'set_error_handler' => ['?callable', 'callback'=>'null|callable(int,string,string,int):bool', 'error_types='=>'int'], 'socket_addrinfo_lookup' => ['AddressInfo[]', 'node'=>'string', 'service='=>'mixed', 'hints='=>'array'], 'socket_select' => ['int|false', '&w_read'=>'Socket[]|null', '&w_write'=>'Socket[]|null', '&w_except'=>'Socket[]|null', 'seconds'=>'int|null', 'microseconds='=>'int'], 'sodium_crypto_aead_chacha20poly1305_ietf_decrypt' => ['string|false', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], 'spl_autoload_functions' => ['list'], 'str_contains' => ['bool', 'haystack'=>'string', 'needle'=>'string'], 'str_split' => ['non-empty-list', 'str'=>'string', 'split_length='=>'positive-int'], 'str_ends_with' => ['bool', 'haystack'=>'string', 'needle'=>'string'], 'str_starts_with' => ['bool', 'haystack'=>'string', 'needle'=>'string'], 'strchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'], 'stripos' => ['0|positive-int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'], 'stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'], 'strpos' => ['positive-int|0|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'], 'strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string'], 'strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'], 'strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'], 'strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'], 'substr' => ['string', 'string'=>'string', 'start'=>'int', 'length='=>'int'], 'round' => ['float', 'number'=>'float', 'precision='=>'int', 'mode='=>'1|2|3|4'], 'version_compare' => ['int|bool', 'version1'=>'string', 'version2'=>'string', 'operator='=>'string|null'], 'xml_parser_create' => ['XMLParser', 'encoding='=>'string'], 'xml_parser_create_ns' => ['XMLParser', 'encoding='=>'string', 'sep='=>'string'], 'xml_parser_free' => ['bool', 'parser'=>'XMLParser'], 'xml_parser_get_option' => ['mixed|false', 'parser'=>'XMLParser', 'option'=>'int'], 'xml_parser_set_option' => ['bool', 'parser'=>'XMLParser', 'option'=>'int', 'value'=>'mixed'], 'xmlwriter_end_attribute' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_end_cdata' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_end_comment' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_end_document' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_end_dtd' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_end_dtd_attlist' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_end_dtd_element' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_end_dtd_entity' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_end_element' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_end_pi' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_flush' => ['mixed', 'xmlwriter'=>'XMLWriter', 'empty='=>'bool'], 'xmlwriter_full_end_element' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_open_memory' => ['XMLWriter'], 'xmlwriter_open_uri' => ['XMLWriter', 'source'=>'string'], 'xmlwriter_output_memory' => ['string', 'xmlwriter'=>'XMLWriter', 'flush='=>'bool'], 'xmlwriter_set_indent' => ['bool', 'xmlwriter'=>'XMLWriter', 'indent'=>'bool'], 'xmlwriter_set_indent_string' => ['bool', 'xmlwriter'=>'XMLWriter', 'indentstring'=>'string'], 'xmlwriter_start_attribute' => ['bool', 'xmlwriter'=>'XMLWriter', 'name'=>'string'], 'xmlwriter_start_attribute_ns' => ['bool', 'xmlwriter'=>'XMLWriter', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string'], 'xmlwriter_start_cdata' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_start_comment' => ['bool', 'xmlwriter'=>'XMLWriter'], 'xmlwriter_start_document' => ['bool', 'xmlwriter'=>'XMLWriter', 'version='=>'string', 'encoding='=>'string', 'standalone='=>'string'], 'xmlwriter_start_dtd' => ['bool', 'xmlwriter'=>'XMLWriter', 'name'=>'string', 'publicid='=>'string', 'sysid='=>'string'], 'xmlwriter_start_dtd_attlist' => ['bool', 'xmlwriter'=>'XMLWriter', 'name'=>'string'], 'xmlwriter_start_dtd_element' => ['bool', 'xmlwriter'=>'XMLWriter', 'name'=>'string'], 'xmlwriter_start_dtd_entity' => ['bool', 'xmlwriter'=>'XMLWriter', 'name'=>'string', 'isparam'=>'bool'], 'xmlwriter_start_element' => ['bool', 'xmlwriter'=>'XMLWriter', 'name'=>'string'], 'xmlwriter_start_element_ns' => ['bool', 'xmlwriter'=>'XMLWriter', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string|null'], 'xmlwriter_start_pi' => ['bool', 'xmlwriter'=>'XMLWriter', 'target'=>'string'], 'xmlwriter_text' => ['bool', 'xmlwriter'=>'XMLWriter', 'content'=>'string'], 'xmlwriter_write_attribute' => ['bool', 'xmlwriter'=>'XMLWriter', 'name'=>'string', 'content'=>'string'], 'xmlwriter_write_attribute_ns' => ['bool', 'xmlwriter'=>'XMLWriter', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string', 'content'=>'string'], 'xmlwriter_write_cdata' => ['bool', 'xmlwriter'=>'XMLWriter', 'content'=>'string'], 'xmlwriter_write_comment' => ['bool', 'xmlwriter'=>'XMLWriter', 'content'=>'string'], 'xmlwriter_write_dtd' => ['bool', 'xmlwriter'=>'XMLWriter', 'name'=>'string', 'publicid='=>'string', 'sysid='=>'string', 'subset='=>'string'], 'xmlwriter_write_dtd_attlist' => ['bool', 'xmlwriter'=>'XMLWriter', 'name'=>'string', 'content'=>'string'], 'xmlwriter_write_dtd_element' => ['bool', 'xmlwriter'=>'XMLWriter', 'name'=>'string', 'content'=>'string'], 'xmlwriter_write_dtd_entity' => ['bool', 'xmlwriter'=>'XMLWriter', 'name'=>'string', 'content'=>'string', 'pe'=>'bool', 'publicid'=>'string', 'sysid'=>'string', 'ndataid'=>'string'], 'xmlwriter_write_element' => ['bool', 'xmlwriter'=>'XMLWriter', 'name'=>'string', 'content'=>'string'], 'xmlwriter_write_element_ns' => ['bool', 'xmlwriter'=>'XMLWriter', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string', 'content'=>'string'], 'xmlwriter_write_pi' => ['bool', 'xmlwriter'=>'XMLWriter', 'target'=>'string', 'content'=>'string'], 'xmlwriter_write_raw' => ['bool', 'xmlwriter'=>'XMLWriter', 'content'=>'string'], ], 'old' => [ 'array_combine' => ['associative-array|false', 'keys'=>'string[]|int[]', 'values'=>'array'], 'bcdiv' => ['?string', 'dividend'=>'string', 'divisor'=>'string', 'scale='=>'int'], 'bcmod' => ['?string', 'dividend'=>'string', 'divisor'=>'string', 'scale='=>'int'], 'bcpowmod' => ['?string', 'base'=>'string', 'exponent'=>'string', 'modulus'=>'string', 'scale='=>'int'], 'ceil' => ['__benevolent', 'number'=>'float'], 'convert_cyr_string' => ['string', 'str'=>'string', 'from'=>'string', 'to'=>'string'], 'com_load_typelib' => ['bool', 'typelib_name'=>'string', 'case_insensitive='=>'bool'], 'count_chars' => ['array|false|string', 'input'=>'string', 'mode='=>'int'], 'curl_init' => ['__benevolent', 'url='=>'string'], 'date_add' => ['DateTime|false', 'object'=>'DateTime', 'interval'=>'DateInterval'], 'date_date_set' => ['DateTime|false', 'object'=>'DateTime', 'year'=>'int', 'month'=>'int', 'day'=>'int'], 'date_diff' => ['DateInterval|false', 'obj1'=>'DateTimeInterface', 'obj2'=>'DateTimeInterface', 'absolute='=>'bool'], 'date_format' => ['string|false', 'object'=>'DateTimeInterface', 'format'=>'string'], 'date_isodate_set' => ['DateTime|false', 'object'=>'DateTime', 'year'=>'int', 'week'=>'int', 'day='=>'int|mixed'], 'date_parse' => ['array|false', 'date'=>'string'], 'date_sub' => ['DateTime|false', 'object'=>'DateTime', 'interval'=>'DateInterval'], 'date_sun_info' => ['__benevolent', 'time'=>'int', 'latitude'=>'float', 'longitude'=>'float'], 'date_time_set' => ['DateTime|false', 'object'=>'DateTime', 'hour'=>'int', 'minute'=>'int', 'second='=>'int', 'microseconds='=>'int'], 'date_timestamp_set' => ['DateTime|false', 'object'=>'DateTime', 'unixtimestamp'=>'int'], 'date_timezone_set' => ['DateTime|false', 'object'=>'DateTime', 'timezone'=>'DateTimeZone'], 'each' => ['array{0:int|string,key:int|string,1:mixed,value:mixed}', '&r_arr'=>'array'], 'ezmlm_hash' => ['int', 'addr'=>'string'], 'fgetss' => ['string|false', 'fp'=>'resource', 'length='=>'0|positive-int', 'allowable_tags='=>'string'], 'floor' => ['__benevolent', 'number'=>'float'], 'get_magic_quotes_gpc' => ['false'], 'gmdate' => ['string|false', 'format'=>'string', 'timestamp='=>'int'], 'gmmktime' => ['int|false', 'hour='=>'int', 'minute='=>'int', 'second='=>'int', 'month='=>'int', 'day='=>'int', 'year='=>'int'], 'gmp_random' => ['GMP', 'limiter='=>'int'], 'gzgetss' => ['string|false', 'zp'=>'resource', 'length'=>'int', 'allowable_tags='=>'string'], 'hash' => ['non-falsy-string|false', 'algo'=>'string', 'data'=>'string', 'raw_output='=>'bool'], 'hash_hkdf' => ['non-falsy-string|false', 'algo'=>'string', 'key'=>'string', 'length='=>'int', 'info='=>'string', 'salt='=>'string'], 'hash_hmac' => ['non-falsy-string|false', 'algo'=>'string', 'data'=>'string', 'key'=>'string', 'raw_output='=>'bool'], 'hash_pbkdf2' => ['non-falsy-string|false', 'algo'=>'string', 'password'=>'string', 'salt'=>'string', 'iterations'=>'int', 'length='=>'int', 'raw_output='=>'bool'], 'hebrevc' => ['string', 'str'=>'string', 'max_chars_per_line='=>'int'], 'image2wbmp' => ['bool', 'im'=>'resource', 'filename='=>'?string', 'threshold='=>'int'], 'imageaffine' => ['resource|false', 'src'=>'resource', 'affine'=>'array', 'clip='=>'array'], 'imagecreate' => ['resource|false', 'x_size'=>'int', 'y_size'=>'int'], 'imagecreatefrombmp' => ['resource|false', 'filename'=>'string'], 'imagecreatefromgd' => ['resource|false', 'filename'=>'string'], 'imagecreatefromgd2' => ['resource|false', 'filename'=>'string'], 'imagecreatefromgd2part' => ['resource|false', 'filename'=>'string', 'srcx'=>'int', 'srcy'=>'int', 'width'=>'int', 'height'=>'int'], 'imagecreatefromgif' => ['resource|false', 'filename'=>'string'], 'imagecreatefromjpeg' => ['resource|false', 'filename'=>'string'], 'imagecreatefrompng' => ['resource|false', 'filename'=>'string'], 'imagecreatefromstring' => ['resource|false', 'image'=>'string'], 'imagecreatefromwbmp' => ['resource|false', 'filename'=>'string'], 'imagecreatefromwebp' => ['resource|false', 'filename'=>'string'], 'imagecreatefromxbm' => ['resource|false', 'filename'=>'string'], 'imagecreatefromxpm' => ['resource|false', 'filename'=>'string'], 'imagecreatetruecolor' => ['resource|false', 'x_size'=>'int', 'y_size'=>'int'], 'imagecrop' => ['resource|false', 'im'=>'resource', 'rect'=>'array'], 'imagecropauto' => ['resource|false', 'im'=>'resource', 'mode'=>'int', 'threshold'=>'float', 'color'=>'int'], 'imagegetclip' => ['array|false', 'im'=>'resource'], 'imagegrabscreen' => ['false|resource'], 'imagegrabwindow' => ['false|resource', 'window_handle'=>'int', 'client_area='=>'int'], 'imagejpeg' => ['bool', 'im'=>'resource', 'filename='=>'string|resource|null', 'quality='=>'int'], 'imagerotate' => ['resource|false', 'src_im'=>'resource', 'angle'=>'float', 'bgdcolor'=>'int', 'ignoretransparent='=>'int'], 'imagescale' => ['resource|false', 'im'=>'resource', 'new_width'=>'int', 'new_height='=>'int', 'method='=>'int'], 'imap_header' => ['stdClass|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'from_length='=>'int', 'subject_length='=>'int', 'default_host='=>'string'], 'implode\'1' => ['string', 'pieces'=>'array'], 'jpeg2wbmp' => ['bool', 'jpegname'=>'string', 'wbmpname'=>'string', 'dest_height'=>'int', 'dest_width'=>'int', 'threshold'=>'int'], 'ldap_control_paged_result' => ['bool', 'link_identifier'=>'resource', 'pagesize'=>'int', 'iscritical='=>'bool', 'cookie='=>'string'], 'ldap_control_paged_result_response' => ['bool', 'link_identifier'=>'resource', 'result_identifier'=>'resource', '&w_cookie='=>'string', '&w_estimated='=>'int'], 'ldap_set_rebind_proc' => ['bool', 'link_identifier'=>'resource', 'callback'=>'callable'], 'ldap_sort' => ['bool', 'link_identifier'=>'resource', 'result_identifier'=>'resource', 'sortfilter'=>'string'], 'mb_decode_numericentity' => ['string|false', 'string'=>'string', 'convmap'=>'array', 'encoding='=>'string', 'is_hex='=>'bool'], 'mb_strlen' => ['0|positive-int', 'str'=>'string', 'encoding='=>'string'], 'mktime' => ['int|false', 'hour='=>'int', 'minute='=>'int', 'second='=>'int', 'month='=>'int', 'day='=>'int', 'year='=>'int'], 'money_format' => ['string', 'format'=>'string', 'value'=>'float'], 'odbc_exec' => ['resource|false', 'connection_id'=>'resource', 'query'=>'string', 'flags='=>'int'], 'parse_str' => ['void', 'encoded_string'=>'string', '&w_result='=>'array'], 'password_hash' => ['__benevolent', 'password'=>'string', 'algo'=>'string|int', 'options='=>'array'], 'png2wbmp' => ['bool', 'pngname'=>'string', 'wbmpname'=>'string', 'dest_height'=>'int', 'dest_width'=>'int', 'threshold'=>'int'], 'proc_get_status' => ['array{command: string, pid: int, running: bool, signaled: bool, stopped: bool, exitcode: int, termsig: int, stopsig: int}|false', 'process'=>'resource'], 'read_exif_data' => ['array', 'filename'=>'string', 'sections_needed='=>'string', 'sub_arrays='=>'bool', 'read_thumbnail='=>'bool'], 'restore_include_path' => ['void'], 'round' => ['__benevolent', 'number'=>'float', 'precision='=>'int', 'mode='=>'1|2|3|4'], 'socket_select' => ['int|false', '&w_read_fds'=>'resource[]|null', '&w_write_fds'=>'resource[]|null', '&w_except_fds'=>'resource[]|null', 'tv_sec'=>'int|null', 'tv_usec='=>'int|null'], 'sodium_crypto_aead_chacha20poly1305_ietf_decrypt' => ['?string|?false', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], 'SplFileObject::fgetss' => ['string|false', 'allowable_tags='=>'string'], 'strchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int', 'before_needle='=>'bool'], 'stripos' => ['0|positive-int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'], 'stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int', 'before_needle='=>'bool'], 'strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'], 'strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int'], 'strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'], 'strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'], 'strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int', 'before_needle='=>'bool'], 'substr' => ['__benevolent', 'string'=>'string', 'start'=>'int', 'length='=>'int'], 'version_compare' => ['int|bool', 'version1'=>'string', 'version2'=>'string', 'operator='=>'string|null'], 'xml_parser_create' => ['resource', 'encoding='=>'string'], 'xml_parser_create_ns' => ['resource', 'encoding='=>'string', 'sep='=>'string'], 'xml_parser_free' => ['bool', 'parser'=>'resource'], 'xml_parser_get_option' => ['mixed|false', 'parser'=>'resource', 'option'=>'int'], 'xml_parser_set_option' => ['bool', 'parser'=>'resource', 'option'=>'int', 'value'=>'mixed'], 'xmlwriter_end_attribute' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_cdata' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_comment' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_document' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_dtd' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_dtd_attlist' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_dtd_element' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_dtd_entity' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_element' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_end_pi' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_flush' => ['mixed', 'xmlwriter'=>'resource', 'empty='=>'bool'], 'xmlwriter_full_end_element' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_open_memory' => ['resource'], 'xmlwriter_open_uri' => ['resource', 'source'=>'string'], 'xmlwriter_output_memory' => ['string', 'xmlwriter'=>'resource', 'flush='=>'bool'], 'xmlwriter_set_indent' => ['bool', 'xmlwriter'=>'resource', 'indent'=>'bool'], 'xmlwriter_set_indent_string' => ['bool', 'xmlwriter'=>'resource', 'indentstring'=>'string'], 'xmlwriter_start_attribute' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string'], 'xmlwriter_start_attribute_ns' => ['bool', 'xmlwriter'=>'resource', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string'], 'xmlwriter_start_cdata' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_start_comment' => ['bool', 'xmlwriter'=>'resource'], 'xmlwriter_start_document' => ['bool', 'xmlwriter'=>'resource', 'version='=>'string', 'encoding='=>'string', 'standalone='=>'string'], 'xmlwriter_start_dtd' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'publicid='=>'string', 'sysid='=>'string'], 'xmlwriter_start_dtd_attlist' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string'], 'xmlwriter_start_dtd_element' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string'], 'xmlwriter_start_dtd_entity' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'isparam'=>'bool'], 'xmlwriter_start_element' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string'], 'xmlwriter_start_element_ns' => ['bool', 'xmlwriter'=>'resource', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string|null'], 'xmlwriter_start_pi' => ['bool', 'xmlwriter'=>'resource', 'target'=>'string'], 'xmlwriter_text' => ['bool', 'xmlwriter'=>'resource', 'content'=>'string'], 'xmlwriter_write_attribute' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string'], 'xmlwriter_write_attribute_ns' => ['bool', 'xmlwriter'=>'resource', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string', 'content'=>'string'], 'xmlwriter_write_cdata' => ['bool', 'xmlwriter'=>'resource', 'content'=>'string'], 'xmlwriter_write_comment' => ['bool', 'xmlwriter'=>'resource', 'content'=>'string'], 'xmlwriter_write_dtd' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'publicid='=>'string', 'sysid='=>'string', 'subset='=>'string'], 'xmlwriter_write_dtd_attlist' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string'], 'xmlwriter_write_dtd_element' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string'], 'xmlwriter_write_dtd_entity' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string', 'pe'=>'bool', 'publicid'=>'string', 'sysid'=>'string', 'ndataid'=>'string'], 'xmlwriter_write_element' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string'], 'xmlwriter_write_element_ns' => ['bool', 'xmlwriter'=>'resource', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string', 'content'=>'string'], 'xmlwriter_write_pi' => ['bool', 'xmlwriter'=>'resource', 'target'=>'string', 'content'=>'string'], 'xmlwriter_write_raw' => ['bool', 'xmlwriter'=>'resource', 'content'=>'string'], ] ]; ['DateTime::modify' => ['static', 'modify' => 'string'], 'DateTimeImmutable::modify' => ['static', 'modify' => 'string'], 'str_decrement' => ['non-empty-string', 'string' => 'non-empty-string'], 'str_increment' => ['non-falsy-string', 'string' => 'non-empty-string'], 'gc_status' => ['array{running:bool,protected:bool,full:bool,runs:int,collected:int,threshold:int,buffer_size:int,roots:int,application_time:float,collector_time:float,destructor_time:float,free_time:float}'], 'stream_get_meta_data' => ['array{timed_out:bool,blocked:bool,eof:bool,unread_bytes:int,stream_type:string,wrapper_type:string,wrapper_data:mixed,mode:string,seekable:bool,uri:string,mediatype?:string,base64?:bool}', 'fp' => 'resource']], 'old' => []]; ['iterator_count' => ['0|positive-int', 'iterator' => 'iterable'], 'iterator_to_array' => ['array', 'iterator' => 'iterable', 'use_keys=' => 'bool'], 'str_split' => ['list', 'str' => 'string', 'split_length=' => 'positive-int']], 'old' => []]; ['error_log' => ['bool', 'message' => 'string', 'message_type=' => '0|1|3|4', 'destination=' => 'string', 'extra_headers=' => 'string'], 'filter_input' => ['mixed', 'type' => 'INPUT_GET|INPUT_POST|INPUT_COOKIE|INPUT_SERVER|INPUT_ENV', 'variable_name' => 'string', 'filter=' => 'int', 'options=' => 'array|int'], 'filter_input_array' => ['array|false|null', 'type' => 'INPUT_GET|INPUT_POST|INPUT_COOKIE|INPUT_SERVER|INPUT_ENV', 'definition=' => 'int|array', 'add_empty=' => 'bool'], 'hash_hkdf' => ['non-falsy-string', 'algo' => 'non-falsy-string', 'key' => 'string', 'length=' => '0|positive-int', 'info=' => 'string', 'salt=' => 'string'], 'hash_pbkdf2' => ['non-empty-string', 'algo' => 'non-falsy-string', 'password' => 'string', 'salt' => 'string', 'iterations' => 'positive-int', 'length=' => '0|positive-int', 'raw_output=' => 'bool'], 'imagecreate' => ['__benevolent', 'width' => 'int<1, max>', 'height' => 'int<1, max>'], 'imagecreatetruecolor' => ['__benevolent', 'width' => 'int<1, max>', 'height' => 'int<1, max>'], 'mb_detect_order' => ['bool|list', 'encoding_list=' => 'non-empty-list|non-falsy-string|null']], 'old' => []]; true as a modification to bin/functionMetadata_original.php. * 3) Contribute the #[Pure] functions without side effects to https://github.com/JetBrains/phpstorm-stubs * 4) Once the PR from 3) is merged, please update the package here and run ./bin/generate-function-metadata.php. */ return [ 'BackedEnum::from' => ['hasSideEffects' => false], 'BackedEnum::tryFrom' => ['hasSideEffects' => false], 'CURLFile::getFilename' => ['hasSideEffects' => false], 'CURLFile::getMimeType' => ['hasSideEffects' => false], 'CURLFile::getPostFilename' => ['hasSideEffects' => false], 'Cassandra\\Exception\\AlreadyExistsException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\AuthenticationException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\ConfigurationException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\DivideByZeroException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\DomainException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\ExecutionException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\InvalidArgumentException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\InvalidQueryException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\InvalidSyntaxException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\IsBootstrappingException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\LogicException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\OverloadedException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\ProtocolException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\RangeException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\ReadTimeoutException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\RuntimeException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\ServerException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\TimeoutException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\TruncateException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\UnauthorizedException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\UnavailableException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\UnpreparedException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\ValidationException::__construct' => ['hasSideEffects' => false], 'Cassandra\\Exception\\WriteTimeoutException::__construct' => ['hasSideEffects' => false], 'Closure::bind' => ['hasSideEffects' => false], 'Closure::bindTo' => ['hasSideEffects' => false], 'Collator::__construct' => ['hasSideEffects' => false], 'Collator::compare' => ['hasSideEffects' => false], 'Collator::getAttribute' => ['hasSideEffects' => false], 'Collator::getErrorCode' => ['hasSideEffects' => false], 'Collator::getErrorMessage' => ['hasSideEffects' => false], 'Collator::getLocale' => ['hasSideEffects' => false], 'Collator::getSortKey' => ['hasSideEffects' => false], 'Collator::getStrength' => ['hasSideEffects' => false], 'DateTime::add' => ['hasSideEffects' => true], 'DateTime::createFromFormat' => ['hasSideEffects' => false], 'DateTime::createFromImmutable' => ['hasSideEffects' => false], 'DateTime::diff' => ['hasSideEffects' => false], 'DateTime::format' => ['hasSideEffects' => false], 'DateTime::getLastErrors' => ['hasSideEffects' => false], 'DateTime::getOffset' => ['hasSideEffects' => false], 'DateTime::getTimestamp' => ['hasSideEffects' => false], 'DateTime::getTimezone' => ['hasSideEffects' => false], 'DateTime::modify' => ['hasSideEffects' => true], 'DateTime::setDate' => ['hasSideEffects' => true], 'DateTime::setISODate' => ['hasSideEffects' => true], 'DateTime::setTime' => ['hasSideEffects' => true], 'DateTime::setTimestamp' => ['hasSideEffects' => true], 'DateTime::setTimezone' => ['hasSideEffects' => true], 'DateTime::sub' => ['hasSideEffects' => true], 'DateTimeImmutable::add' => ['hasSideEffects' => false], 'DateTimeImmutable::createFromFormat' => ['hasSideEffects' => false], 'DateTimeImmutable::createFromMutable' => ['hasSideEffects' => false], 'DateTimeImmutable::diff' => ['hasSideEffects' => false], 'DateTimeImmutable::format' => ['hasSideEffects' => false], 'DateTimeImmutable::getLastErrors' => ['hasSideEffects' => false], 'DateTimeImmutable::getOffset' => ['hasSideEffects' => false], 'DateTimeImmutable::getTimestamp' => ['hasSideEffects' => false], 'DateTimeImmutable::getTimezone' => ['hasSideEffects' => false], 'DateTimeImmutable::modify' => ['hasSideEffects' => false], 'DateTimeImmutable::setDate' => ['hasSideEffects' => false], 'DateTimeImmutable::setISODate' => ['hasSideEffects' => false], 'DateTimeImmutable::setTime' => ['hasSideEffects' => false], 'DateTimeImmutable::setTimestamp' => ['hasSideEffects' => false], 'DateTimeImmutable::setTimezone' => ['hasSideEffects' => false], 'DateTimeImmutable::sub' => ['hasSideEffects' => false], 'Error::__construct' => ['hasSideEffects' => false], 'ErrorException::__construct' => ['hasSideEffects' => false], 'Event::__construct' => ['hasSideEffects' => false], 'EventBase::getFeatures' => ['hasSideEffects' => false], 'EventBase::getMethod' => ['hasSideEffects' => false], 'EventBase::getTimeOfDayCached' => ['hasSideEffects' => false], 'EventBase::gotExit' => ['hasSideEffects' => false], 'EventBase::gotStop' => ['hasSideEffects' => false], 'EventBuffer::__construct' => ['hasSideEffects' => false], 'EventBufferEvent::__construct' => ['hasSideEffects' => false], 'EventBufferEvent::getDnsErrorString' => ['hasSideEffects' => false], 'EventBufferEvent::getEnabled' => ['hasSideEffects' => false], 'EventBufferEvent::getInput' => ['hasSideEffects' => false], 'EventBufferEvent::getOutput' => ['hasSideEffects' => false], 'EventConfig::__construct' => ['hasSideEffects' => false], 'EventDnsBase::__construct' => ['hasSideEffects' => false], 'EventHttpConnection::__construct' => ['hasSideEffects' => false], 'EventHttpRequest::__construct' => ['hasSideEffects' => false], 'EventHttpRequest::getCommand' => ['hasSideEffects' => false], 'EventHttpRequest::getConnection' => ['hasSideEffects' => false], 'EventHttpRequest::getHost' => ['hasSideEffects' => false], 'EventHttpRequest::getInputBuffer' => ['hasSideEffects' => false], 'EventHttpRequest::getInputHeaders' => ['hasSideEffects' => false], 'EventHttpRequest::getOutputBuffer' => ['hasSideEffects' => false], 'EventHttpRequest::getOutputHeaders' => ['hasSideEffects' => false], 'EventHttpRequest::getResponseCode' => ['hasSideEffects' => false], 'EventHttpRequest::getUri' => ['hasSideEffects' => false], 'EventSslContext::__construct' => ['hasSideEffects' => false], 'Exception::__construct' => ['hasSideEffects' => false], 'Exception::getCode' => ['hasSideEffects' => false], 'Exception::getFile' => ['hasSideEffects' => false], 'Exception::getLine' => ['hasSideEffects' => false], 'Exception::getMessage' => ['hasSideEffects' => false], 'Exception::getPrevious' => ['hasSideEffects' => false], 'Exception::getTrace' => ['hasSideEffects' => false], 'Exception::getTraceAsString' => ['hasSideEffects' => false], 'Gmagick::getcopyright' => ['hasSideEffects' => false], 'Gmagick::getfilename' => ['hasSideEffects' => false], 'Gmagick::getimagebackgroundcolor' => ['hasSideEffects' => false], 'Gmagick::getimageblueprimary' => ['hasSideEffects' => false], 'Gmagick::getimagebordercolor' => ['hasSideEffects' => false], 'Gmagick::getimagechanneldepth' => ['hasSideEffects' => false], 'Gmagick::getimagecolors' => ['hasSideEffects' => false], 'Gmagick::getimagecolorspace' => ['hasSideEffects' => false], 'Gmagick::getimagecompose' => ['hasSideEffects' => false], 'Gmagick::getimagedelay' => ['hasSideEffects' => false], 'Gmagick::getimagedepth' => ['hasSideEffects' => false], 'Gmagick::getimagedispose' => ['hasSideEffects' => false], 'Gmagick::getimageextrema' => ['hasSideEffects' => false], 'Gmagick::getimagefilename' => ['hasSideEffects' => false], 'Gmagick::getimageformat' => ['hasSideEffects' => false], 'Gmagick::getimagegamma' => ['hasSideEffects' => false], 'Gmagick::getimagegreenprimary' => ['hasSideEffects' => false], 'Gmagick::getimageheight' => ['hasSideEffects' => false], 'Gmagick::getimagehistogram' => ['hasSideEffects' => false], 'Gmagick::getimageindex' => ['hasSideEffects' => false], 'Gmagick::getimageinterlacescheme' => ['hasSideEffects' => false], 'Gmagick::getimageiterations' => ['hasSideEffects' => false], 'Gmagick::getimagematte' => ['hasSideEffects' => false], 'Gmagick::getimagemattecolor' => ['hasSideEffects' => false], 'Gmagick::getimageprofile' => ['hasSideEffects' => false], 'Gmagick::getimageredprimary' => ['hasSideEffects' => false], 'Gmagick::getimagerenderingintent' => ['hasSideEffects' => false], 'Gmagick::getimageresolution' => ['hasSideEffects' => false], 'Gmagick::getimagescene' => ['hasSideEffects' => false], 'Gmagick::getimagesignature' => ['hasSideEffects' => false], 'Gmagick::getimagetype' => ['hasSideEffects' => false], 'Gmagick::getimageunits' => ['hasSideEffects' => false], 'Gmagick::getimagewhitepoint' => ['hasSideEffects' => false], 'Gmagick::getimagewidth' => ['hasSideEffects' => false], 'Gmagick::getpackagename' => ['hasSideEffects' => false], 'Gmagick::getquantumdepth' => ['hasSideEffects' => false], 'Gmagick::getreleasedate' => ['hasSideEffects' => false], 'Gmagick::getsamplingfactors' => ['hasSideEffects' => false], 'Gmagick::getsize' => ['hasSideEffects' => false], 'Gmagick::getversion' => ['hasSideEffects' => false], 'GmagickDraw::getfillcolor' => ['hasSideEffects' => false], 'GmagickDraw::getfillopacity' => ['hasSideEffects' => false], 'GmagickDraw::getfont' => ['hasSideEffects' => false], 'GmagickDraw::getfontsize' => ['hasSideEffects' => false], 'GmagickDraw::getfontstyle' => ['hasSideEffects' => false], 'GmagickDraw::getfontweight' => ['hasSideEffects' => false], 'GmagickDraw::getstrokecolor' => ['hasSideEffects' => false], 'GmagickDraw::getstrokeopacity' => ['hasSideEffects' => false], 'GmagickDraw::getstrokewidth' => ['hasSideEffects' => false], 'GmagickDraw::gettextdecoration' => ['hasSideEffects' => false], 'GmagickDraw::gettextencoding' => ['hasSideEffects' => false], 'GmagickPixel::getcolor' => ['hasSideEffects' => false], 'GmagickPixel::getcolorcount' => ['hasSideEffects' => false], 'GmagickPixel::getcolorvalue' => ['hasSideEffects' => false], 'HttpMessage::getBody' => ['hasSideEffects' => false], 'HttpMessage::getHeader' => ['hasSideEffects' => false], 'HttpMessage::getHeaders' => ['hasSideEffects' => false], 'HttpMessage::getHttpVersion' => ['hasSideEffects' => false], 'HttpMessage::getInfo' => ['hasSideEffects' => false], 'HttpMessage::getParentMessage' => ['hasSideEffects' => false], 'HttpMessage::getRequestMethod' => ['hasSideEffects' => false], 'HttpMessage::getRequestUrl' => ['hasSideEffects' => false], 'HttpMessage::getResponseCode' => ['hasSideEffects' => false], 'HttpMessage::getResponseStatus' => ['hasSideEffects' => false], 'HttpMessage::getType' => ['hasSideEffects' => false], 'HttpQueryString::get' => ['hasSideEffects' => false], 'HttpQueryString::getArray' => ['hasSideEffects' => false], 'HttpQueryString::getBool' => ['hasSideEffects' => false], 'HttpQueryString::getFloat' => ['hasSideEffects' => false], 'HttpQueryString::getInt' => ['hasSideEffects' => false], 'HttpQueryString::getObject' => ['hasSideEffects' => false], 'HttpQueryString::getString' => ['hasSideEffects' => false], 'HttpRequest::getBody' => ['hasSideEffects' => false], 'HttpRequest::getContentType' => ['hasSideEffects' => false], 'HttpRequest::getCookies' => ['hasSideEffects' => false], 'HttpRequest::getHeaders' => ['hasSideEffects' => false], 'HttpRequest::getHistory' => ['hasSideEffects' => false], 'HttpRequest::getMethod' => ['hasSideEffects' => false], 'HttpRequest::getOptions' => ['hasSideEffects' => false], 'HttpRequest::getPostFields' => ['hasSideEffects' => false], 'HttpRequest::getPostFiles' => ['hasSideEffects' => false], 'HttpRequest::getPutData' => ['hasSideEffects' => false], 'HttpRequest::getPutFile' => ['hasSideEffects' => false], 'HttpRequest::getQueryData' => ['hasSideEffects' => false], 'HttpRequest::getRawPostData' => ['hasSideEffects' => false], 'HttpRequest::getRawRequestMessage' => ['hasSideEffects' => false], 'HttpRequest::getRawResponseMessage' => ['hasSideEffects' => false], 'HttpRequest::getRequestMessage' => ['hasSideEffects' => false], 'HttpRequest::getResponseBody' => ['hasSideEffects' => false], 'HttpRequest::getResponseCode' => ['hasSideEffects' => false], 'HttpRequest::getResponseCookies' => ['hasSideEffects' => false], 'HttpRequest::getResponseData' => ['hasSideEffects' => false], 'HttpRequest::getResponseHeader' => ['hasSideEffects' => false], 'HttpRequest::getResponseInfo' => ['hasSideEffects' => false], 'HttpRequest::getResponseMessage' => ['hasSideEffects' => false], 'HttpRequest::getResponseStatus' => ['hasSideEffects' => false], 'HttpRequest::getSslOptions' => ['hasSideEffects' => false], 'HttpRequest::getUrl' => ['hasSideEffects' => false], 'HttpRequestPool::getAttachedRequests' => ['hasSideEffects' => false], 'HttpRequestPool::getFinishedRequests' => ['hasSideEffects' => false], 'Imagick::getColorspace' => ['hasSideEffects' => false], 'Imagick::getCompression' => ['hasSideEffects' => false], 'Imagick::getCompressionQuality' => ['hasSideEffects' => false], 'Imagick::getConfigureOptions' => ['hasSideEffects' => false], 'Imagick::getFeatures' => ['hasSideEffects' => false], 'Imagick::getFilename' => ['hasSideEffects' => false], 'Imagick::getFont' => ['hasSideEffects' => false], 'Imagick::getFormat' => ['hasSideEffects' => false], 'Imagick::getGravity' => ['hasSideEffects' => false], 'Imagick::getHDRIEnabled' => ['hasSideEffects' => false], 'Imagick::getImage' => ['hasSideEffects' => false], 'Imagick::getImageAlphaChannel' => ['hasSideEffects' => false], 'Imagick::getImageArtifact' => ['hasSideEffects' => false], 'Imagick::getImageAttribute' => ['hasSideEffects' => false], 'Imagick::getImageBackgroundColor' => ['hasSideEffects' => false], 'Imagick::getImageBlob' => ['hasSideEffects' => false], 'Imagick::getImageBluePrimary' => ['hasSideEffects' => false], 'Imagick::getImageBorderColor' => ['hasSideEffects' => false], 'Imagick::getImageChannelDepth' => ['hasSideEffects' => false], 'Imagick::getImageChannelDistortion' => ['hasSideEffects' => false], 'Imagick::getImageChannelDistortions' => ['hasSideEffects' => false], 'Imagick::getImageChannelExtrema' => ['hasSideEffects' => false], 'Imagick::getImageChannelKurtosis' => ['hasSideEffects' => false], 'Imagick::getImageChannelMean' => ['hasSideEffects' => false], 'Imagick::getImageChannelRange' => ['hasSideEffects' => false], 'Imagick::getImageChannelStatistics' => ['hasSideEffects' => false], 'Imagick::getImageClipMask' => ['hasSideEffects' => false], 'Imagick::getImageColormapColor' => ['hasSideEffects' => false], 'Imagick::getImageColors' => ['hasSideEffects' => false], 'Imagick::getImageColorspace' => ['hasSideEffects' => false], 'Imagick::getImageCompose' => ['hasSideEffects' => false], 'Imagick::getImageCompression' => ['hasSideEffects' => false], 'Imagick::getImageCompressionQuality' => ['hasSideEffects' => false], 'Imagick::getImageDelay' => ['hasSideEffects' => false], 'Imagick::getImageDepth' => ['hasSideEffects' => false], 'Imagick::getImageDispose' => ['hasSideEffects' => false], 'Imagick::getImageDistortion' => ['hasSideEffects' => false], 'Imagick::getImageExtrema' => ['hasSideEffects' => false], 'Imagick::getImageFilename' => ['hasSideEffects' => false], 'Imagick::getImageFormat' => ['hasSideEffects' => false], 'Imagick::getImageGamma' => ['hasSideEffects' => false], 'Imagick::getImageGeometry' => ['hasSideEffects' => false], 'Imagick::getImageGravity' => ['hasSideEffects' => false], 'Imagick::getImageGreenPrimary' => ['hasSideEffects' => false], 'Imagick::getImageHeight' => ['hasSideEffects' => false], 'Imagick::getImageHistogram' => ['hasSideEffects' => false], 'Imagick::getImageIndex' => ['hasSideEffects' => false], 'Imagick::getImageInterlaceScheme' => ['hasSideEffects' => false], 'Imagick::getImageInterpolateMethod' => ['hasSideEffects' => false], 'Imagick::getImageIterations' => ['hasSideEffects' => false], 'Imagick::getImageLength' => ['hasSideEffects' => false], 'Imagick::getImageMatte' => ['hasSideEffects' => false], 'Imagick::getImageMatteColor' => ['hasSideEffects' => false], 'Imagick::getImageMimeType' => ['hasSideEffects' => false], 'Imagick::getImageOrientation' => ['hasSideEffects' => false], 'Imagick::getImagePage' => ['hasSideEffects' => false], 'Imagick::getImagePixelColor' => ['hasSideEffects' => false], 'Imagick::getImageProfile' => ['hasSideEffects' => false], 'Imagick::getImageProfiles' => ['hasSideEffects' => false], 'Imagick::getImageProperties' => ['hasSideEffects' => false], 'Imagick::getImageProperty' => ['hasSideEffects' => false], 'Imagick::getImageRedPrimary' => ['hasSideEffects' => false], 'Imagick::getImageRegion' => ['hasSideEffects' => false], 'Imagick::getImageRenderingIntent' => ['hasSideEffects' => false], 'Imagick::getImageResolution' => ['hasSideEffects' => false], 'Imagick::getImageScene' => ['hasSideEffects' => false], 'Imagick::getImageSignature' => ['hasSideEffects' => false], 'Imagick::getImageSize' => ['hasSideEffects' => false], 'Imagick::getImageTicksPerSecond' => ['hasSideEffects' => false], 'Imagick::getImageTotalInkDensity' => ['hasSideEffects' => false], 'Imagick::getImageType' => ['hasSideEffects' => false], 'Imagick::getImageUnits' => ['hasSideEffects' => false], 'Imagick::getImageVirtualPixelMethod' => ['hasSideEffects' => false], 'Imagick::getImageWhitePoint' => ['hasSideEffects' => false], 'Imagick::getImageWidth' => ['hasSideEffects' => false], 'Imagick::getImagesBlob' => ['hasSideEffects' => false], 'Imagick::getInterlaceScheme' => ['hasSideEffects' => false], 'Imagick::getIteratorIndex' => ['hasSideEffects' => false], 'Imagick::getNumberImages' => ['hasSideEffects' => false], 'Imagick::getOption' => ['hasSideEffects' => false], 'Imagick::getPage' => ['hasSideEffects' => false], 'Imagick::getPixelIterator' => ['hasSideEffects' => false], 'Imagick::getPixelRegionIterator' => ['hasSideEffects' => false], 'Imagick::getPointSize' => ['hasSideEffects' => false], 'Imagick::getSamplingFactors' => ['hasSideEffects' => false], 'Imagick::getSize' => ['hasSideEffects' => false], 'Imagick::getSizeOffset' => ['hasSideEffects' => false], 'ImagickDraw::getBorderColor' => ['hasSideEffects' => false], 'ImagickDraw::getClipPath' => ['hasSideEffects' => false], 'ImagickDraw::getClipRule' => ['hasSideEffects' => false], 'ImagickDraw::getClipUnits' => ['hasSideEffects' => false], 'ImagickDraw::getDensity' => ['hasSideEffects' => false], 'ImagickDraw::getFillColor' => ['hasSideEffects' => false], 'ImagickDraw::getFillOpacity' => ['hasSideEffects' => false], 'ImagickDraw::getFillRule' => ['hasSideEffects' => false], 'ImagickDraw::getFont' => ['hasSideEffects' => false], 'ImagickDraw::getFontFamily' => ['hasSideEffects' => false], 'ImagickDraw::getFontResolution' => ['hasSideEffects' => false], 'ImagickDraw::getFontSize' => ['hasSideEffects' => false], 'ImagickDraw::getFontStretch' => ['hasSideEffects' => false], 'ImagickDraw::getFontStyle' => ['hasSideEffects' => false], 'ImagickDraw::getFontWeight' => ['hasSideEffects' => false], 'ImagickDraw::getGravity' => ['hasSideEffects' => false], 'ImagickDraw::getOpacity' => ['hasSideEffects' => false], 'ImagickDraw::getStrokeAntialias' => ['hasSideEffects' => false], 'ImagickDraw::getStrokeColor' => ['hasSideEffects' => false], 'ImagickDraw::getStrokeDashArray' => ['hasSideEffects' => false], 'ImagickDraw::getStrokeDashOffset' => ['hasSideEffects' => false], 'ImagickDraw::getStrokeLineCap' => ['hasSideEffects' => false], 'ImagickDraw::getStrokeLineJoin' => ['hasSideEffects' => false], 'ImagickDraw::getStrokeMiterLimit' => ['hasSideEffects' => false], 'ImagickDraw::getStrokeOpacity' => ['hasSideEffects' => false], 'ImagickDraw::getStrokeWidth' => ['hasSideEffects' => false], 'ImagickDraw::getTextAlignment' => ['hasSideEffects' => false], 'ImagickDraw::getTextAntialias' => ['hasSideEffects' => false], 'ImagickDraw::getTextDecoration' => ['hasSideEffects' => false], 'ImagickDraw::getTextDirection' => ['hasSideEffects' => false], 'ImagickDraw::getTextEncoding' => ['hasSideEffects' => false], 'ImagickDraw::getTextInterLineSpacing' => ['hasSideEffects' => false], 'ImagickDraw::getTextInterWordSpacing' => ['hasSideEffects' => false], 'ImagickDraw::getTextKerning' => ['hasSideEffects' => false], 'ImagickDraw::getTextUnderColor' => ['hasSideEffects' => false], 'ImagickDraw::getVectorGraphics' => ['hasSideEffects' => false], 'ImagickKernel::getMatrix' => ['hasSideEffects' => false], 'ImagickPixel::getColor' => ['hasSideEffects' => false], 'ImagickPixel::getColorAsString' => ['hasSideEffects' => false], 'ImagickPixel::getColorCount' => ['hasSideEffects' => false], 'ImagickPixel::getColorQuantum' => ['hasSideEffects' => false], 'ImagickPixel::getColorValue' => ['hasSideEffects' => false], 'ImagickPixel::getColorValueQuantum' => ['hasSideEffects' => false], 'ImagickPixel::getHSL' => ['hasSideEffects' => false], 'ImagickPixel::getIndex' => ['hasSideEffects' => false], 'ImagickPixelIterator::getCurrentIteratorRow' => ['hasSideEffects' => false], 'ImagickPixelIterator::getIteratorRow' => ['hasSideEffects' => false], 'ImagickPixelIterator::getNextIteratorRow' => ['hasSideEffects' => false], 'ImagickPixelIterator::getPreviousIteratorRow' => ['hasSideEffects' => false], 'IntBackedEnum::from' => ['hasSideEffects' => false], 'IntBackedEnum::tryFrom' => ['hasSideEffects' => false], 'IntlBreakIterator::current' => ['hasSideEffects' => false], 'IntlBreakIterator::getErrorCode' => ['hasSideEffects' => false], 'IntlBreakIterator::getErrorMessage' => ['hasSideEffects' => false], 'IntlBreakIterator::getIterator' => ['hasSideEffects' => false], 'IntlBreakIterator::getLocale' => ['hasSideEffects' => false], 'IntlBreakIterator::getPartsIterator' => ['hasSideEffects' => false], 'IntlBreakIterator::getText' => ['hasSideEffects' => false], 'IntlBreakIterator::isBoundary' => ['hasSideEffects' => false], 'IntlCalendar::after' => ['hasSideEffects' => false], 'IntlCalendar::before' => ['hasSideEffects' => false], 'IntlCalendar::equals' => ['hasSideEffects' => false], 'IntlCalendar::fieldDifference' => ['hasSideEffects' => false], 'IntlCalendar::get' => ['hasSideEffects' => false], 'IntlCalendar::getActualMaximum' => ['hasSideEffects' => false], 'IntlCalendar::getActualMinimum' => ['hasSideEffects' => false], 'IntlCalendar::getDayOfWeekType' => ['hasSideEffects' => false], 'IntlCalendar::getErrorCode' => ['hasSideEffects' => false], 'IntlCalendar::getErrorMessage' => ['hasSideEffects' => false], 'IntlCalendar::getFirstDayOfWeek' => ['hasSideEffects' => false], 'IntlCalendar::getGreatestMinimum' => ['hasSideEffects' => false], 'IntlCalendar::getLeastMaximum' => ['hasSideEffects' => false], 'IntlCalendar::getLocale' => ['hasSideEffects' => false], 'IntlCalendar::getMaximum' => ['hasSideEffects' => false], 'IntlCalendar::getMinimalDaysInFirstWeek' => ['hasSideEffects' => false], 'IntlCalendar::getMinimum' => ['hasSideEffects' => false], 'IntlCalendar::getRepeatedWallTimeOption' => ['hasSideEffects' => false], 'IntlCalendar::getSkippedWallTimeOption' => ['hasSideEffects' => false], 'IntlCalendar::getTime' => ['hasSideEffects' => false], 'IntlCalendar::getTimeZone' => ['hasSideEffects' => false], 'IntlCalendar::getType' => ['hasSideEffects' => false], 'IntlCalendar::getWeekendTransition' => ['hasSideEffects' => false], 'IntlCalendar::inDaylightTime' => ['hasSideEffects' => false], 'IntlCalendar::isEquivalentTo' => ['hasSideEffects' => false], 'IntlCalendar::isLenient' => ['hasSideEffects' => false], 'IntlCalendar::isWeekend' => ['hasSideEffects' => false], 'IntlCalendar::toDateTime' => ['hasSideEffects' => false], 'IntlChar::hasBinaryProperty' => ['hasSideEffects' => false], 'IntlCodePointBreakIterator::getLastCodePoint' => ['hasSideEffects' => false], 'IntlDateFormatter::__construct' => ['hasSideEffects' => false], 'IntlDateFormatter::getCalendar' => ['hasSideEffects' => false], 'IntlDateFormatter::getCalendarObject' => ['hasSideEffects' => false], 'IntlDateFormatter::getDateType' => ['hasSideEffects' => false], 'IntlDateFormatter::getErrorCode' => ['hasSideEffects' => false], 'IntlDateFormatter::getErrorMessage' => ['hasSideEffects' => false], 'IntlDateFormatter::getLocale' => ['hasSideEffects' => false], 'IntlDateFormatter::getPattern' => ['hasSideEffects' => false], 'IntlDateFormatter::getTimeType' => ['hasSideEffects' => false], 'IntlDateFormatter::getTimeZone' => ['hasSideEffects' => false], 'IntlDateFormatter::getTimeZoneId' => ['hasSideEffects' => false], 'IntlDateFormatter::isLenient' => ['hasSideEffects' => false], 'IntlGregorianCalendar::getGregorianChange' => ['hasSideEffects' => false], 'IntlGregorianCalendar::isLeapYear' => ['hasSideEffects' => false], 'IntlPartsIterator::getBreakIterator' => ['hasSideEffects' => false], 'IntlRuleBasedBreakIterator::__construct' => ['hasSideEffects' => false], 'IntlRuleBasedBreakIterator::getBinaryRules' => ['hasSideEffects' => false], 'IntlRuleBasedBreakIterator::getRuleStatus' => ['hasSideEffects' => false], 'IntlRuleBasedBreakIterator::getRuleStatusVec' => ['hasSideEffects' => false], 'IntlRuleBasedBreakIterator::getRules' => ['hasSideEffects' => false], 'IntlTimeZone::getDSTSavings' => ['hasSideEffects' => false], 'IntlTimeZone::getDisplayName' => ['hasSideEffects' => false], 'IntlTimeZone::getErrorCode' => ['hasSideEffects' => false], 'IntlTimeZone::getErrorMessage' => ['hasSideEffects' => false], 'IntlTimeZone::getID' => ['hasSideEffects' => false], 'IntlTimeZone::getRawOffset' => ['hasSideEffects' => false], 'IntlTimeZone::hasSameRules' => ['hasSideEffects' => false], 'IntlTimeZone::toDateTimeZone' => ['hasSideEffects' => false], 'JsonIncrementalParser::__construct' => ['hasSideEffects' => false], 'JsonIncrementalParser::get' => ['hasSideEffects' => false], 'JsonIncrementalParser::getError' => ['hasSideEffects' => false], 'MemcachedException::__construct' => ['hasSideEffects' => false], 'MessageFormatter::__construct' => ['hasSideEffects' => false], 'MessageFormatter::format' => ['hasSideEffects' => false], 'MessageFormatter::getErrorCode' => ['hasSideEffects' => false], 'MessageFormatter::getErrorMessage' => ['hasSideEffects' => false], 'MessageFormatter::getLocale' => ['hasSideEffects' => false], 'MessageFormatter::getPattern' => ['hasSideEffects' => false], 'MessageFormatter::parse' => ['hasSideEffects' => false], 'NumberFormatter::__construct' => ['hasSideEffects' => false], 'NumberFormatter::format' => ['hasSideEffects' => false], 'NumberFormatter::formatCurrency' => ['hasSideEffects' => false], 'NumberFormatter::getAttribute' => ['hasSideEffects' => false], 'NumberFormatter::getErrorCode' => ['hasSideEffects' => false], 'NumberFormatter::getErrorMessage' => ['hasSideEffects' => false], 'NumberFormatter::getLocale' => ['hasSideEffects' => false], 'NumberFormatter::getPattern' => ['hasSideEffects' => false], 'NumberFormatter::getSymbol' => ['hasSideEffects' => false], 'NumberFormatter::getTextAttribute' => ['hasSideEffects' => false], 'ReflectionAttribute::getArguments' => ['hasSideEffects' => false], 'ReflectionAttribute::getName' => ['hasSideEffects' => false], 'ReflectionAttribute::getTarget' => ['hasSideEffects' => false], 'ReflectionAttribute::isRepeated' => ['hasSideEffects' => false], 'ReflectionClass::getAttributes' => ['hasSideEffects' => false], 'ReflectionClass::getConstant' => ['hasSideEffects' => false], 'ReflectionClass::getConstants' => ['hasSideEffects' => false], 'ReflectionClass::getConstructor' => ['hasSideEffects' => false], 'ReflectionClass::getDefaultProperties' => ['hasSideEffects' => false], 'ReflectionClass::getDocComment' => ['hasSideEffects' => false], 'ReflectionClass::getEndLine' => ['hasSideEffects' => false], 'ReflectionClass::getExtension' => ['hasSideEffects' => false], 'ReflectionClass::getExtensionName' => ['hasSideEffects' => false], 'ReflectionClass::getFileName' => ['hasSideEffects' => false], 'ReflectionClass::getInterfaceNames' => ['hasSideEffects' => false], 'ReflectionClass::getInterfaces' => ['hasSideEffects' => false], 'ReflectionClass::getMethod' => ['hasSideEffects' => false], 'ReflectionClass::getMethods' => ['hasSideEffects' => false], 'ReflectionClass::getModifiers' => ['hasSideEffects' => false], 'ReflectionClass::getName' => ['hasSideEffects' => false], 'ReflectionClass::getNamespaceName' => ['hasSideEffects' => false], 'ReflectionClass::getParentClass' => ['hasSideEffects' => false], 'ReflectionClass::getProperties' => ['hasSideEffects' => false], 'ReflectionClass::getProperty' => ['hasSideEffects' => false], 'ReflectionClass::getReflectionConstant' => ['hasSideEffects' => false], 'ReflectionClass::getReflectionConstants' => ['hasSideEffects' => false], 'ReflectionClass::getShortName' => ['hasSideEffects' => false], 'ReflectionClass::getStartLine' => ['hasSideEffects' => false], 'ReflectionClass::getStaticProperties' => ['hasSideEffects' => false], 'ReflectionClass::getStaticPropertyValue' => ['hasSideEffects' => false], 'ReflectionClass::getTraitAliases' => ['hasSideEffects' => false], 'ReflectionClass::getTraitNames' => ['hasSideEffects' => false], 'ReflectionClass::getTraits' => ['hasSideEffects' => false], 'ReflectionClass::isAbstract' => ['hasSideEffects' => false], 'ReflectionClass::isAnonymous' => ['hasSideEffects' => false], 'ReflectionClass::isCloneable' => ['hasSideEffects' => false], 'ReflectionClass::isFinal' => ['hasSideEffects' => false], 'ReflectionClass::isInstance' => ['hasSideEffects' => false], 'ReflectionClass::isInstantiable' => ['hasSideEffects' => false], 'ReflectionClass::isInterface' => ['hasSideEffects' => false], 'ReflectionClass::isInternal' => ['hasSideEffects' => false], 'ReflectionClass::isIterable' => ['hasSideEffects' => false], 'ReflectionClass::isIterateable' => ['hasSideEffects' => false], 'ReflectionClass::isReadOnly' => ['hasSideEffects' => false], 'ReflectionClass::isSubclassOf' => ['hasSideEffects' => false], 'ReflectionClass::isTrait' => ['hasSideEffects' => false], 'ReflectionClass::isUserDefined' => ['hasSideEffects' => false], 'ReflectionClassConstant::getAttributes' => ['hasSideEffects' => false], 'ReflectionClassConstant::getDeclaringClass' => ['hasSideEffects' => false], 'ReflectionClassConstant::getDocComment' => ['hasSideEffects' => false], 'ReflectionClassConstant::getModifiers' => ['hasSideEffects' => false], 'ReflectionClassConstant::getName' => ['hasSideEffects' => false], 'ReflectionClassConstant::getValue' => ['hasSideEffects' => false], 'ReflectionClassConstant::isPrivate' => ['hasSideEffects' => false], 'ReflectionClassConstant::isProtected' => ['hasSideEffects' => false], 'ReflectionClassConstant::isPublic' => ['hasSideEffects' => false], 'ReflectionEnumBackedCase::getBackingValue' => ['hasSideEffects' => false], 'ReflectionEnumUnitCase::getEnum' => ['hasSideEffects' => false], 'ReflectionEnumUnitCase::getValue' => ['hasSideEffects' => false], 'ReflectionExtension::getClassNames' => ['hasSideEffects' => false], 'ReflectionExtension::getClasses' => ['hasSideEffects' => false], 'ReflectionExtension::getConstants' => ['hasSideEffects' => false], 'ReflectionExtension::getDependencies' => ['hasSideEffects' => false], 'ReflectionExtension::getFunctions' => ['hasSideEffects' => false], 'ReflectionExtension::getINIEntries' => ['hasSideEffects' => false], 'ReflectionExtension::getName' => ['hasSideEffects' => false], 'ReflectionExtension::getVersion' => ['hasSideEffects' => false], 'ReflectionExtension::isPersistent' => ['hasSideEffects' => false], 'ReflectionExtension::isTemporary' => ['hasSideEffects' => false], 'ReflectionFunction::getClosure' => ['hasSideEffects' => false], 'ReflectionFunction::isDisabled' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getAttributes' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getClosureCalledClass' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getClosureScopeClass' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getClosureThis' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getClosureUsedVariables' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getDocComment' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getEndLine' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getExtension' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getExtensionName' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getFileName' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getName' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getNamespaceName' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getNumberOfParameters' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getNumberOfRequiredParameters' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getParameters' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getReturnType' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getShortName' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getStartLine' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getStaticVariables' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::getTentativeReturnType' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::hasTentativeReturnType' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::isClosure' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::isDeprecated' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::isGenerator' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::isInternal' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::isStatic' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::isUserDefined' => ['hasSideEffects' => false], 'ReflectionFunctionAbstract::isVariadic' => ['hasSideEffects' => false], 'ReflectionGenerator::getExecutingFile' => ['hasSideEffects' => false], 'ReflectionGenerator::getExecutingGenerator' => ['hasSideEffects' => false], 'ReflectionGenerator::getExecutingLine' => ['hasSideEffects' => false], 'ReflectionGenerator::getFunction' => ['hasSideEffects' => false], 'ReflectionGenerator::getThis' => ['hasSideEffects' => false], 'ReflectionGenerator::getTrace' => ['hasSideEffects' => false], 'ReflectionIntersectionType::getTypes' => ['hasSideEffects' => false], 'ReflectionMethod::getClosure' => ['hasSideEffects' => false], 'ReflectionMethod::getDeclaringClass' => ['hasSideEffects' => false], 'ReflectionMethod::getModifiers' => ['hasSideEffects' => false], 'ReflectionMethod::getPrototype' => ['hasSideEffects' => false], 'ReflectionMethod::isAbstract' => ['hasSideEffects' => false], 'ReflectionMethod::isConstructor' => ['hasSideEffects' => false], 'ReflectionMethod::isDestructor' => ['hasSideEffects' => false], 'ReflectionMethod::isFinal' => ['hasSideEffects' => false], 'ReflectionMethod::isPrivate' => ['hasSideEffects' => false], 'ReflectionMethod::isProtected' => ['hasSideEffects' => false], 'ReflectionMethod::isPublic' => ['hasSideEffects' => false], 'ReflectionMethod::isStatic' => ['hasSideEffects' => false], 'ReflectionMethod::setAccessible' => ['hasSideEffects' => false], 'ReflectionNamedType::getName' => ['hasSideEffects' => false], 'ReflectionNamedType::isBuiltin' => ['hasSideEffects' => false], 'ReflectionParameter::getAttributes' => ['hasSideEffects' => false], 'ReflectionParameter::getClass' => ['hasSideEffects' => false], 'ReflectionParameter::getDeclaringClass' => ['hasSideEffects' => false], 'ReflectionParameter::getDeclaringFunction' => ['hasSideEffects' => false], 'ReflectionParameter::getDefaultValue' => ['hasSideEffects' => false], 'ReflectionParameter::getDefaultValueConstantName' => ['hasSideEffects' => false], 'ReflectionParameter::getName' => ['hasSideEffects' => false], 'ReflectionParameter::getPosition' => ['hasSideEffects' => false], 'ReflectionParameter::getType' => ['hasSideEffects' => false], 'ReflectionParameter::isArray' => ['hasSideEffects' => false], 'ReflectionParameter::isCallable' => ['hasSideEffects' => false], 'ReflectionParameter::isDefaultValueAvailable' => ['hasSideEffects' => false], 'ReflectionParameter::isDefaultValueConstant' => ['hasSideEffects' => false], 'ReflectionParameter::isOptional' => ['hasSideEffects' => false], 'ReflectionParameter::isPassedByReference' => ['hasSideEffects' => false], 'ReflectionParameter::isPromoted' => ['hasSideEffects' => false], 'ReflectionParameter::isVariadic' => ['hasSideEffects' => false], 'ReflectionProperty::getAttributes' => ['hasSideEffects' => false], 'ReflectionProperty::getDeclaringClass' => ['hasSideEffects' => false], 'ReflectionProperty::getDefaultValue' => ['hasSideEffects' => false], 'ReflectionProperty::getDocComment' => ['hasSideEffects' => false], 'ReflectionProperty::getModifiers' => ['hasSideEffects' => false], 'ReflectionProperty::getName' => ['hasSideEffects' => false], 'ReflectionProperty::getType' => ['hasSideEffects' => false], 'ReflectionProperty::getValue' => ['hasSideEffects' => false], 'ReflectionProperty::isDefault' => ['hasSideEffects' => false], 'ReflectionProperty::isInitialized' => ['hasSideEffects' => false], 'ReflectionProperty::isPrivate' => ['hasSideEffects' => false], 'ReflectionProperty::isPromoted' => ['hasSideEffects' => false], 'ReflectionProperty::isProtected' => ['hasSideEffects' => false], 'ReflectionProperty::isPublic' => ['hasSideEffects' => false], 'ReflectionProperty::isStatic' => ['hasSideEffects' => false], 'ReflectionProperty::setAccessible' => ['hasSideEffects' => false], 'ReflectionReference::getId' => ['hasSideEffects' => false], 'ReflectionType::isBuiltin' => ['hasSideEffects' => false], 'ReflectionUnionType::getTypes' => ['hasSideEffects' => false], 'ReflectionZendExtension::getAuthor' => ['hasSideEffects' => false], 'ReflectionZendExtension::getCopyright' => ['hasSideEffects' => false], 'ReflectionZendExtension::getName' => ['hasSideEffects' => false], 'ReflectionZendExtension::getURL' => ['hasSideEffects' => false], 'ReflectionZendExtension::getVersion' => ['hasSideEffects' => false], 'ResourceBundle::__construct' => ['hasSideEffects' => false], 'ResourceBundle::count' => ['hasSideEffects' => false], 'ResourceBundle::get' => ['hasSideEffects' => false], 'ResourceBundle::getErrorCode' => ['hasSideEffects' => false], 'ResourceBundle::getErrorMessage' => ['hasSideEffects' => false], 'ResourceBundle::getIterator' => ['hasSideEffects' => false], 'SQLiteException::__construct' => ['hasSideEffects' => false], 'SimpleXMLElement::__construct' => ['hasSideEffects' => false], 'SimpleXMLElement::children' => ['hasSideEffects' => false], 'SimpleXMLElement::count' => ['hasSideEffects' => false], 'SimpleXMLElement::current' => ['hasSideEffects' => false], 'SimpleXMLElement::getChildren' => ['hasSideEffects' => false], 'SimpleXMLElement::getDocNamespaces' => ['hasSideEffects' => false], 'SimpleXMLElement::getName' => ['hasSideEffects' => false], 'SimpleXMLElement::getNamespaces' => ['hasSideEffects' => false], 'SimpleXMLElement::hasChildren' => ['hasSideEffects' => false], 'SimpleXMLElement::offsetExists' => ['hasSideEffects' => false], 'SimpleXMLElement::offsetGet' => ['hasSideEffects' => false], 'SimpleXMLElement::valid' => ['hasSideEffects' => false], 'SimpleXMLIterator::count' => ['hasSideEffects' => false], 'SimpleXMLIterator::current' => ['hasSideEffects' => false], 'SimpleXMLIterator::getChildren' => ['hasSideEffects' => false], 'SimpleXMLIterator::hasChildren' => ['hasSideEffects' => false], 'SimpleXMLIterator::valid' => ['hasSideEffects' => false], 'SoapFault::__construct' => ['hasSideEffects' => false], 'SplFileObject::fflush' => ['hasSideEffects' => true], 'SplFileObject::fgetc' => ['hasSideEffects' => true], 'SplFileObject::fgetcsv' => ['hasSideEffects' => true], 'SplFileObject::fgets' => ['hasSideEffects' => true], 'SplFileObject::fgetss' => ['hasSideEffects' => true], 'SplFileObject::fpassthru' => ['hasSideEffects' => true], 'SplFileObject::fputcsv' => ['hasSideEffects' => true], 'SplFileObject::fread' => ['hasSideEffects' => true], 'SplFileObject::fscanf' => ['hasSideEffects' => true], 'SplFileObject::fseek' => ['hasSideEffects' => true], 'SplFileObject::ftruncate' => ['hasSideEffects' => true], 'SplFileObject::fwrite' => ['hasSideEffects' => true], 'Spoofchecker::__construct' => ['hasSideEffects' => false], 'StringBackedEnum::from' => ['hasSideEffects' => false], 'StringBackedEnum::tryFrom' => ['hasSideEffects' => false], 'StubTests\\CodeStyle\\BracesOneLineFixer::getDefinition' => ['hasSideEffects' => false], 'StubTests\\Parsers\\ExpectedFunctionArgumentsInfo::__toString' => ['hasSideEffects' => false], 'StubTests\\Parsers\\Visitors\\CoreStubASTVisitor::__construct' => ['hasSideEffects' => false], 'StubTests\\StubsMetaExpectedArgumentsTest::getClassMemberFqn' => ['hasSideEffects' => false], 'StubTests\\StubsParameterNamesTest::printParameters' => ['hasSideEffects' => false], 'Transliterator::createInverse' => ['hasSideEffects' => false], 'Transliterator::getErrorCode' => ['hasSideEffects' => false], 'Transliterator::getErrorMessage' => ['hasSideEffects' => false], 'Transliterator::transliterate' => ['hasSideEffects' => false], 'UConverter::__construct' => ['hasSideEffects' => false], 'UConverter::convert' => ['hasSideEffects' => false], 'UConverter::getDestinationEncoding' => ['hasSideEffects' => false], 'UConverter::getDestinationType' => ['hasSideEffects' => false], 'UConverter::getErrorCode' => ['hasSideEffects' => false], 'UConverter::getErrorMessage' => ['hasSideEffects' => false], 'UConverter::getSourceEncoding' => ['hasSideEffects' => false], 'UConverter::getSourceType' => ['hasSideEffects' => false], 'UConverter::getStandards' => ['hasSideEffects' => false], 'UConverter::getSubstChars' => ['hasSideEffects' => false], 'UConverter::reasonText' => ['hasSideEffects' => false], 'UnitEnum::cases' => ['hasSideEffects' => false], 'WeakMap::count' => ['hasSideEffects' => false], 'WeakMap::getIterator' => ['hasSideEffects' => false], 'WeakMap::offsetExists' => ['hasSideEffects' => false], 'WeakMap::offsetGet' => ['hasSideEffects' => false], 'WeakReference::create' => ['hasSideEffects' => false], 'WeakReference::get' => ['hasSideEffects' => false], 'XmlReader::next' => ['hasSideEffects' => true], 'XmlReader::read' => ['hasSideEffects' => true], 'Zookeeper::getAcl' => ['hasSideEffects' => false], 'Zookeeper::getChildren' => ['hasSideEffects' => false], 'Zookeeper::getClientId' => ['hasSideEffects' => false], 'Zookeeper::getRecvTimeout' => ['hasSideEffects' => false], 'Zookeeper::getState' => ['hasSideEffects' => false], '_' => ['hasSideEffects' => false], 'abs' => ['hasSideEffects' => false], 'acos' => ['hasSideEffects' => false], 'acosh' => ['hasSideEffects' => false], 'addcslashes' => ['hasSideEffects' => false], 'addslashes' => ['hasSideEffects' => false], 'apache_get_modules' => ['hasSideEffects' => false], 'apache_get_version' => ['hasSideEffects' => false], 'apache_getenv' => ['hasSideEffects' => false], 'apache_request_headers' => ['hasSideEffects' => false], 'array_change_key_case' => ['hasSideEffects' => false], 'array_chunk' => ['hasSideEffects' => false], 'array_column' => ['hasSideEffects' => false], 'array_combine' => ['hasSideEffects' => false], 'array_count_values' => ['hasSideEffects' => false], 'array_diff' => ['hasSideEffects' => false], 'array_diff_assoc' => ['hasSideEffects' => false], 'array_diff_key' => ['hasSideEffects' => false], 'array_diff_uassoc' => ['hasSideEffects' => false], 'array_diff_ukey' => ['hasSideEffects' => false], 'array_fill' => ['hasSideEffects' => false], 'array_fill_keys' => ['hasSideEffects' => false], 'array_flip' => ['hasSideEffects' => false], 'array_intersect' => ['hasSideEffects' => false], 'array_intersect_assoc' => ['hasSideEffects' => false], 'array_intersect_key' => ['hasSideEffects' => false], 'array_intersect_uassoc' => ['hasSideEffects' => false], 'array_intersect_ukey' => ['hasSideEffects' => false], 'array_is_list' => ['hasSideEffects' => false], 'array_key_exists' => ['hasSideEffects' => false], 'array_key_first' => ['hasSideEffects' => false], 'array_key_last' => ['hasSideEffects' => false], 'array_keys' => ['hasSideEffects' => false], 'array_merge' => ['hasSideEffects' => false], 'array_merge_recursive' => ['hasSideEffects' => false], 'array_pad' => ['hasSideEffects' => false], 'array_pop' => ['hasSideEffects' => true], 'array_product' => ['hasSideEffects' => false], 'array_push' => ['hasSideEffects' => true], 'array_rand' => ['hasSideEffects' => false], 'array_replace' => ['hasSideEffects' => false], 'array_replace_recursive' => ['hasSideEffects' => false], 'array_reverse' => ['hasSideEffects' => false], 'array_search' => ['hasSideEffects' => false], 'array_shift' => ['hasSideEffects' => true], 'array_slice' => ['hasSideEffects' => false], 'array_sum' => ['hasSideEffects' => false], 'array_udiff' => ['hasSideEffects' => false], 'array_udiff_assoc' => ['hasSideEffects' => false], 'array_udiff_uassoc' => ['hasSideEffects' => false], 'array_uintersect' => ['hasSideEffects' => false], 'array_uintersect_assoc' => ['hasSideEffects' => false], 'array_uintersect_uassoc' => ['hasSideEffects' => false], 'array_unique' => ['hasSideEffects' => false], 'array_unshift' => ['hasSideEffects' => true], 'array_values' => ['hasSideEffects' => false], 'asin' => ['hasSideEffects' => false], 'asinh' => ['hasSideEffects' => false], 'atan' => ['hasSideEffects' => false], 'atan2' => ['hasSideEffects' => false], 'atanh' => ['hasSideEffects' => false], 'base64_decode' => ['hasSideEffects' => false], 'base64_encode' => ['hasSideEffects' => false], 'base_convert' => ['hasSideEffects' => false], 'basename' => ['hasSideEffects' => false], 'bcadd' => ['hasSideEffects' => false], 'bccomp' => ['hasSideEffects' => false], 'bcdiv' => ['hasSideEffects' => false], 'bcmod' => ['hasSideEffects' => false], 'bcmul' => ['hasSideEffects' => false], 'bcpow' => ['hasSideEffects' => false], 'bcpowmod' => ['hasSideEffects' => false], 'bcsqrt' => ['hasSideEffects' => false], 'bcsub' => ['hasSideEffects' => false], 'bin2hex' => ['hasSideEffects' => false], 'bindec' => ['hasSideEffects' => false], 'boolval' => ['hasSideEffects' => false], 'bzcompress' => ['hasSideEffects' => false], 'bzdecompress' => ['hasSideEffects' => false], 'bzerrno' => ['hasSideEffects' => false], 'bzerror' => ['hasSideEffects' => false], 'bzerrstr' => ['hasSideEffects' => false], 'bzopen' => ['hasSideEffects' => false], 'ceil' => ['hasSideEffects' => false], 'checkdate' => ['hasSideEffects' => false], 'checkdnsrr' => ['hasSideEffects' => false], 'chgrp' => ['hasSideEffects' => true], 'chmod' => ['hasSideEffects' => true], 'chop' => ['hasSideEffects' => false], 'chown' => ['hasSideEffects' => true], 'chr' => ['hasSideEffects' => false], 'chunk_split' => ['hasSideEffects' => false], 'class_implements' => ['hasSideEffects' => false], 'class_parents' => ['hasSideEffects' => false], 'cli_get_process_title' => ['hasSideEffects' => false], 'collator_compare' => ['hasSideEffects' => false], 'collator_create' => ['hasSideEffects' => false], 'collator_get_attribute' => ['hasSideEffects' => false], 'collator_get_error_code' => ['hasSideEffects' => false], 'collator_get_error_message' => ['hasSideEffects' => false], 'collator_get_locale' => ['hasSideEffects' => false], 'collator_get_sort_key' => ['hasSideEffects' => false], 'collator_get_strength' => ['hasSideEffects' => false], 'compact' => ['hasSideEffects' => false], 'connection_aborted' => ['hasSideEffects' => true], 'connection_status' => ['hasSideEffects' => true], 'constant' => ['hasSideEffects' => false], 'convert_cyr_string' => ['hasSideEffects' => false], 'convert_uudecode' => ['hasSideEffects' => false], 'convert_uuencode' => ['hasSideEffects' => false], 'copy' => ['hasSideEffects' => true], 'cos' => ['hasSideEffects' => false], 'cosh' => ['hasSideEffects' => false], 'count' => ['hasSideEffects' => false], 'count_chars' => ['hasSideEffects' => false], 'crc32' => ['hasSideEffects' => false], 'crypt' => ['hasSideEffects' => false], 'ctype_alnum' => ['hasSideEffects' => false], 'ctype_alpha' => ['hasSideEffects' => false], 'ctype_cntrl' => ['hasSideEffects' => false], 'ctype_digit' => ['hasSideEffects' => false], 'ctype_graph' => ['hasSideEffects' => false], 'ctype_lower' => ['hasSideEffects' => false], 'ctype_print' => ['hasSideEffects' => false], 'ctype_punct' => ['hasSideEffects' => false], 'ctype_space' => ['hasSideEffects' => false], 'ctype_upper' => ['hasSideEffects' => false], 'ctype_xdigit' => ['hasSideEffects' => false], 'curl_copy_handle' => ['hasSideEffects' => false], 'curl_errno' => ['hasSideEffects' => false], 'curl_error' => ['hasSideEffects' => false], 'curl_escape' => ['hasSideEffects' => false], 'curl_file_create' => ['hasSideEffects' => false], 'curl_getinfo' => ['hasSideEffects' => false], 'curl_multi_errno' => ['hasSideEffects' => false], 'curl_multi_getcontent' => ['hasSideEffects' => false], 'curl_multi_info_read' => ['hasSideEffects' => false], 'curl_share_errno' => ['hasSideEffects' => false], 'curl_share_strerror' => ['hasSideEffects' => false], 'curl_strerror' => ['hasSideEffects' => false], 'curl_unescape' => ['hasSideEffects' => false], 'curl_version' => ['hasSideEffects' => false], 'current' => ['hasSideEffects' => false], 'date' => ['hasSideEffects' => false], 'date_create' => ['hasSideEffects' => false], 'date_create_from_format' => ['hasSideEffects' => false], 'date_create_immutable' => ['hasSideEffects' => false], 'date_create_immutable_from_format' => ['hasSideEffects' => false], 'date_default_timezone_get' => ['hasSideEffects' => false], 'date_diff' => ['hasSideEffects' => false], 'date_format' => ['hasSideEffects' => false], 'date_get_last_errors' => ['hasSideEffects' => false], 'date_interval_create_from_date_string' => ['hasSideEffects' => false], 'date_interval_format' => ['hasSideEffects' => false], 'date_offset_get' => ['hasSideEffects' => false], 'date_parse' => ['hasSideEffects' => false], 'date_parse_from_format' => ['hasSideEffects' => false], 'date_sun_info' => ['hasSideEffects' => false], 'date_sunrise' => ['hasSideEffects' => false], 'date_sunset' => ['hasSideEffects' => false], 'date_timestamp_get' => ['hasSideEffects' => false], 'date_timezone_get' => ['hasSideEffects' => false], 'datefmt_create' => ['hasSideEffects' => false], 'datefmt_format' => ['hasSideEffects' => false], 'datefmt_format_object' => ['hasSideEffects' => false], 'datefmt_get_calendar' => ['hasSideEffects' => false], 'datefmt_get_calendar_object' => ['hasSideEffects' => false], 'datefmt_get_datetype' => ['hasSideEffects' => false], 'datefmt_get_error_code' => ['hasSideEffects' => false], 'datefmt_get_error_message' => ['hasSideEffects' => false], 'datefmt_get_locale' => ['hasSideEffects' => false], 'datefmt_get_pattern' => ['hasSideEffects' => false], 'datefmt_get_timetype' => ['hasSideEffects' => false], 'datefmt_get_timezone' => ['hasSideEffects' => false], 'datefmt_get_timezone_id' => ['hasSideEffects' => false], 'datefmt_is_lenient' => ['hasSideEffects' => false], 'dcngettext' => ['hasSideEffects' => false], 'decbin' => ['hasSideEffects' => false], 'dechex' => ['hasSideEffects' => false], 'decoct' => ['hasSideEffects' => false], 'defined' => ['hasSideEffects' => false], 'deflate_init' => ['hasSideEffects' => false], 'deg2rad' => ['hasSideEffects' => false], 'dirname' => ['hasSideEffects' => false], 'disk_free_space' => ['hasSideEffects' => false], 'disk_total_space' => ['hasSideEffects' => false], 'diskfreespace' => ['hasSideEffects' => false], 'dngettext' => ['hasSideEffects' => false], 'doubleval' => ['hasSideEffects' => false], 'error_get_last' => ['hasSideEffects' => false], 'error_log' => ['hasSideEffects' => true], 'escapeshellarg' => ['hasSideEffects' => false], 'escapeshellcmd' => ['hasSideEffects' => false], 'exp' => ['hasSideEffects' => false], 'explode' => ['hasSideEffects' => false], 'expm1' => ['hasSideEffects' => false], 'extension_loaded' => ['hasSideEffects' => false], 'fclose' => ['hasSideEffects' => true], 'fdiv' => ['hasSideEffects' => false], 'feof' => ['hasSideEffects' => false], 'fflush' => ['hasSideEffects' => true], 'fgetc' => ['hasSideEffects' => true], 'fgetcsv' => ['hasSideEffects' => true], 'fgets' => ['hasSideEffects' => true], 'fgetss' => ['hasSideEffects' => true], 'file' => ['hasSideEffects' => false], 'file_exists' => ['hasSideEffects' => false], 'file_get_contents' => ['hasSideEffects' => true], 'file_put_contents' => ['hasSideEffects' => true], 'fileatime' => ['hasSideEffects' => false], 'filectime' => ['hasSideEffects' => false], 'filegroup' => ['hasSideEffects' => false], 'fileinode' => ['hasSideEffects' => false], 'filemtime' => ['hasSideEffects' => false], 'fileowner' => ['hasSideEffects' => false], 'fileperms' => ['hasSideEffects' => false], 'filesize' => ['hasSideEffects' => false], 'filetype' => ['hasSideEffects' => false], 'filter_has_var' => ['hasSideEffects' => false], 'filter_id' => ['hasSideEffects' => false], 'filter_input' => ['hasSideEffects' => false], 'filter_input_array' => ['hasSideEffects' => false], 'filter_list' => ['hasSideEffects' => false], 'filter_var' => ['hasSideEffects' => false], 'filter_var_array' => ['hasSideEffects' => false], 'finfo::buffer' => ['hasSideEffects' => false], 'finfo::file' => ['hasSideEffects' => false], 'floatval' => ['hasSideEffects' => false], 'flock' => ['hasSideEffects' => true], 'floor' => ['hasSideEffects' => false], 'fmod' => ['hasSideEffects' => false], 'fnmatch' => ['hasSideEffects' => false], 'fopen' => ['hasSideEffects' => true], 'fpassthru' => ['hasSideEffects' => true], 'fputcsv' => ['hasSideEffects' => true], 'fputs' => ['hasSideEffects' => true], 'fread' => ['hasSideEffects' => true], 'fscanf' => ['hasSideEffects' => true], 'fseek' => ['hasSideEffects' => true], 'fstat' => ['hasSideEffects' => false], 'ftell' => ['hasSideEffects' => false], 'ftok' => ['hasSideEffects' => false], 'ftruncate' => ['hasSideEffects' => true], 'func_get_arg' => ['hasSideEffects' => false], 'func_get_args' => ['hasSideEffects' => false], 'func_num_args' => ['hasSideEffects' => false], 'function_exists' => ['hasSideEffects' => false], 'fwrite' => ['hasSideEffects' => true], 'gc_enabled' => ['hasSideEffects' => false], 'gc_status' => ['hasSideEffects' => false], 'gd_info' => ['hasSideEffects' => false], 'geoip_continent_code_by_name' => ['hasSideEffects' => false], 'geoip_country_code3_by_name' => ['hasSideEffects' => false], 'geoip_country_code_by_name' => ['hasSideEffects' => false], 'geoip_country_name_by_name' => ['hasSideEffects' => false], 'geoip_database_info' => ['hasSideEffects' => false], 'geoip_db_avail' => ['hasSideEffects' => false], 'geoip_db_filename' => ['hasSideEffects' => false], 'geoip_db_get_all_info' => ['hasSideEffects' => false], 'geoip_id_by_name' => ['hasSideEffects' => false], 'geoip_isp_by_name' => ['hasSideEffects' => false], 'geoip_org_by_name' => ['hasSideEffects' => false], 'geoip_record_by_name' => ['hasSideEffects' => false], 'geoip_region_by_name' => ['hasSideEffects' => false], 'geoip_region_name_by_code' => ['hasSideEffects' => false], 'geoip_time_zone_by_country_and_region' => ['hasSideEffects' => false], 'get_browser' => ['hasSideEffects' => false], 'get_called_class' => ['hasSideEffects' => false], 'get_cfg_var' => ['hasSideEffects' => false], 'get_class' => ['hasSideEffects' => false], 'get_class_methods' => ['hasSideEffects' => false], 'get_class_vars' => ['hasSideEffects' => false], 'get_current_user' => ['hasSideEffects' => false], 'get_debug_type' => ['hasSideEffects' => false], 'get_declared_classes' => ['hasSideEffects' => false], 'get_declared_interfaces' => ['hasSideEffects' => false], 'get_declared_traits' => ['hasSideEffects' => false], 'get_defined_constants' => ['hasSideEffects' => false], 'get_defined_functions' => ['hasSideEffects' => false], 'get_defined_vars' => ['hasSideEffects' => false], 'get_extension_funcs' => ['hasSideEffects' => false], 'get_headers' => ['hasSideEffects' => false], 'get_html_translation_table' => ['hasSideEffects' => false], 'get_include_path' => ['hasSideEffects' => false], 'get_included_files' => ['hasSideEffects' => false], 'get_loaded_extensions' => ['hasSideEffects' => false], 'get_meta_tags' => ['hasSideEffects' => false], 'get_object_vars' => ['hasSideEffects' => false], 'get_parent_class' => ['hasSideEffects' => false], 'get_required_files' => ['hasSideEffects' => false], 'get_resource_id' => ['hasSideEffects' => false], 'get_resources' => ['hasSideEffects' => false], 'getallheaders' => ['hasSideEffects' => false], 'getcwd' => ['hasSideEffects' => false], 'getdate' => ['hasSideEffects' => false], 'getenv' => ['hasSideEffects' => false], 'gethostbyaddr' => ['hasSideEffects' => false], 'gethostbyname' => ['hasSideEffects' => false], 'gethostbynamel' => ['hasSideEffects' => false], 'gethostname' => ['hasSideEffects' => false], 'getlastmod' => ['hasSideEffects' => false], 'getmygid' => ['hasSideEffects' => false], 'getmyinode' => ['hasSideEffects' => false], 'getmypid' => ['hasSideEffects' => false], 'getmyuid' => ['hasSideEffects' => false], 'getprotobyname' => ['hasSideEffects' => false], 'getprotobynumber' => ['hasSideEffects' => false], 'getrandmax' => ['hasSideEffects' => false], 'getrusage' => ['hasSideEffects' => false], 'getservbyname' => ['hasSideEffects' => false], 'getservbyport' => ['hasSideEffects' => false], 'gettext' => ['hasSideEffects' => false], 'gettimeofday' => ['hasSideEffects' => false], 'gettype' => ['hasSideEffects' => false], 'glob' => ['hasSideEffects' => false], 'gmdate' => ['hasSideEffects' => false], 'gmmktime' => ['hasSideEffects' => false], 'gmp_abs' => ['hasSideEffects' => false], 'gmp_add' => ['hasSideEffects' => false], 'gmp_and' => ['hasSideEffects' => false], 'gmp_binomial' => ['hasSideEffects' => false], 'gmp_cmp' => ['hasSideEffects' => false], 'gmp_com' => ['hasSideEffects' => false], 'gmp_div' => ['hasSideEffects' => false], 'gmp_div_q' => ['hasSideEffects' => false], 'gmp_div_qr' => ['hasSideEffects' => false], 'gmp_div_r' => ['hasSideEffects' => false], 'gmp_divexact' => ['hasSideEffects' => false], 'gmp_export' => ['hasSideEffects' => false], 'gmp_fact' => ['hasSideEffects' => false], 'gmp_gcd' => ['hasSideEffects' => false], 'gmp_gcdext' => ['hasSideEffects' => false], 'gmp_hamdist' => ['hasSideEffects' => false], 'gmp_import' => ['hasSideEffects' => false], 'gmp_init' => ['hasSideEffects' => false], 'gmp_intval' => ['hasSideEffects' => false], 'gmp_invert' => ['hasSideEffects' => false], 'gmp_jacobi' => ['hasSideEffects' => false], 'gmp_kronecker' => ['hasSideEffects' => false], 'gmp_lcm' => ['hasSideEffects' => false], 'gmp_legendre' => ['hasSideEffects' => false], 'gmp_mod' => ['hasSideEffects' => false], 'gmp_mul' => ['hasSideEffects' => false], 'gmp_neg' => ['hasSideEffects' => false], 'gmp_nextprime' => ['hasSideEffects' => false], 'gmp_or' => ['hasSideEffects' => false], 'gmp_perfect_power' => ['hasSideEffects' => false], 'gmp_perfect_square' => ['hasSideEffects' => false], 'gmp_popcount' => ['hasSideEffects' => false], 'gmp_pow' => ['hasSideEffects' => false], 'gmp_powm' => ['hasSideEffects' => false], 'gmp_prob_prime' => ['hasSideEffects' => false], 'gmp_root' => ['hasSideEffects' => false], 'gmp_rootrem' => ['hasSideEffects' => false], 'gmp_scan0' => ['hasSideEffects' => false], 'gmp_scan1' => ['hasSideEffects' => false], 'gmp_sign' => ['hasSideEffects' => false], 'gmp_sqrt' => ['hasSideEffects' => false], 'gmp_sqrtrem' => ['hasSideEffects' => false], 'gmp_strval' => ['hasSideEffects' => false], 'gmp_sub' => ['hasSideEffects' => false], 'gmp_testbit' => ['hasSideEffects' => false], 'gmp_xor' => ['hasSideEffects' => false], 'grapheme_stripos' => ['hasSideEffects' => false], 'grapheme_stristr' => ['hasSideEffects' => false], 'grapheme_strlen' => ['hasSideEffects' => false], 'grapheme_strpos' => ['hasSideEffects' => false], 'grapheme_strripos' => ['hasSideEffects' => false], 'grapheme_strrpos' => ['hasSideEffects' => false], 'grapheme_strstr' => ['hasSideEffects' => false], 'grapheme_substr' => ['hasSideEffects' => false], 'gzcompress' => ['hasSideEffects' => false], 'gzdecode' => ['hasSideEffects' => false], 'gzdeflate' => ['hasSideEffects' => false], 'gzencode' => ['hasSideEffects' => false], 'gzinflate' => ['hasSideEffects' => false], 'gzuncompress' => ['hasSideEffects' => false], 'hash' => ['hasSideEffects' => false], 'hash_algos' => ['hasSideEffects' => false], 'hash_copy' => ['hasSideEffects' => false], 'hash_equals' => ['hasSideEffects' => false], 'hash_file' => ['hasSideEffects' => false], 'hash_hkdf' => ['hasSideEffects' => false], 'hash_hmac' => ['hasSideEffects' => false], 'hash_hmac_algos' => ['hasSideEffects' => false], 'hash_hmac_file' => ['hasSideEffects' => false], 'hash_init' => ['hasSideEffects' => false], 'hash_pbkdf2' => ['hasSideEffects' => false], 'headers_list' => ['hasSideEffects' => false], 'hebrev' => ['hasSideEffects' => false], 'hexdec' => ['hasSideEffects' => false], 'hrtime' => ['hasSideEffects' => false], 'html_entity_decode' => ['hasSideEffects' => false], 'htmlentities' => ['hasSideEffects' => false], 'htmlspecialchars' => ['hasSideEffects' => false], 'htmlspecialchars_decode' => ['hasSideEffects' => false], 'http_build_cookie' => ['hasSideEffects' => false], 'http_build_query' => ['hasSideEffects' => false], 'http_build_str' => ['hasSideEffects' => false], 'http_cache_etag' => ['hasSideEffects' => false], 'http_cache_last_modified' => ['hasSideEffects' => false], 'http_chunked_decode' => ['hasSideEffects' => false], 'http_date' => ['hasSideEffects' => false], 'http_deflate' => ['hasSideEffects' => false], 'http_get_request_body' => ['hasSideEffects' => false], 'http_get_request_body_stream' => ['hasSideEffects' => false], 'http_get_request_headers' => ['hasSideEffects' => false], 'http_inflate' => ['hasSideEffects' => false], 'http_match_etag' => ['hasSideEffects' => false], 'http_match_modified' => ['hasSideEffects' => false], 'http_match_request_header' => ['hasSideEffects' => false], 'http_parse_cookie' => ['hasSideEffects' => false], 'http_parse_headers' => ['hasSideEffects' => false], 'http_parse_message' => ['hasSideEffects' => false], 'http_parse_params' => ['hasSideEffects' => false], 'http_request_body_encode' => ['hasSideEffects' => false], 'http_request_method_exists' => ['hasSideEffects' => false], 'http_request_method_name' => ['hasSideEffects' => false], 'http_support' => ['hasSideEffects' => false], 'hypot' => ['hasSideEffects' => false], 'iconv' => ['hasSideEffects' => false], 'iconv_get_encoding' => ['hasSideEffects' => false], 'iconv_mime_decode' => ['hasSideEffects' => false], 'iconv_mime_decode_headers' => ['hasSideEffects' => false], 'iconv_mime_encode' => ['hasSideEffects' => false], 'iconv_strlen' => ['hasSideEffects' => false], 'iconv_strpos' => ['hasSideEffects' => false], 'iconv_strrpos' => ['hasSideEffects' => false], 'iconv_substr' => ['hasSideEffects' => false], 'idate' => ['hasSideEffects' => false], 'image_type_to_extension' => ['hasSideEffects' => false], 'image_type_to_mime_type' => ['hasSideEffects' => false], 'imagecolorat' => ['hasSideEffects' => false], 'imagecolorclosest' => ['hasSideEffects' => false], 'imagecolorclosestalpha' => ['hasSideEffects' => false], 'imagecolorclosesthwb' => ['hasSideEffects' => false], 'imagecolorexact' => ['hasSideEffects' => false], 'imagecolorexactalpha' => ['hasSideEffects' => false], 'imagecolorresolve' => ['hasSideEffects' => false], 'imagecolorresolvealpha' => ['hasSideEffects' => false], 'imagecolorsforindex' => ['hasSideEffects' => false], 'imagecolorstotal' => ['hasSideEffects' => false], 'imagecreate' => ['hasSideEffects' => false], 'imagecreatefromstring' => ['hasSideEffects' => false], 'imagecreatetruecolor' => ['hasSideEffects' => false], 'imagefontheight' => ['hasSideEffects' => false], 'imagefontwidth' => ['hasSideEffects' => false], 'imageftbbox' => ['hasSideEffects' => false], 'imagegetinterpolation' => ['hasSideEffects' => false], 'imagegrabscreen' => ['hasSideEffects' => false], 'imagegrabwindow' => ['hasSideEffects' => false], 'imageistruecolor' => ['hasSideEffects' => false], 'imagesx' => ['hasSideEffects' => false], 'imagesy' => ['hasSideEffects' => false], 'imagettfbbox' => ['hasSideEffects' => false], 'imagetypes' => ['hasSideEffects' => false], 'implode' => ['hasSideEffects' => false], 'in_array' => ['hasSideEffects' => false], 'inet_ntop' => ['hasSideEffects' => false], 'inet_pton' => ['hasSideEffects' => false], 'inflate_get_read_len' => ['hasSideEffects' => false], 'inflate_get_status' => ['hasSideEffects' => false], 'inflate_init' => ['hasSideEffects' => false], 'ini_get' => ['hasSideEffects' => false], 'ini_get_all' => ['hasSideEffects' => false], 'intcal_get_maximum' => ['hasSideEffects' => false], 'intdiv' => ['hasSideEffects' => false], 'intl_error_name' => ['hasSideEffects' => false], 'intl_get' => ['hasSideEffects' => false], 'intl_get_error_code' => ['hasSideEffects' => false], 'intl_get_error_message' => ['hasSideEffects' => false], 'intl_is_failure' => ['hasSideEffects' => false], 'intlcal_after' => ['hasSideEffects' => false], 'intlcal_before' => ['hasSideEffects' => false], 'intlcal_create_instance' => ['hasSideEffects' => false], 'intlcal_equals' => ['hasSideEffects' => false], 'intlcal_field_difference' => ['hasSideEffects' => false], 'intlcal_from_date_time' => ['hasSideEffects' => false], 'intlcal_get' => ['hasSideEffects' => false], 'intlcal_get_actual_maximum' => ['hasSideEffects' => false], 'intlcal_get_actual_minimum' => ['hasSideEffects' => false], 'intlcal_get_available_locales' => ['hasSideEffects' => false], 'intlcal_get_day_of_week_type' => ['hasSideEffects' => false], 'intlcal_get_error_code' => ['hasSideEffects' => false], 'intlcal_get_error_message' => ['hasSideEffects' => false], 'intlcal_get_first_day_of_week' => ['hasSideEffects' => false], 'intlcal_get_greatest_minimum' => ['hasSideEffects' => false], 'intlcal_get_keyword_values_for_locale' => ['hasSideEffects' => false], 'intlcal_get_least_maximum' => ['hasSideEffects' => false], 'intlcal_get_locale' => ['hasSideEffects' => false], 'intlcal_get_maximum' => ['hasSideEffects' => false], 'intlcal_get_minimal_days_in_first_week' => ['hasSideEffects' => false], 'intlcal_get_minimum' => ['hasSideEffects' => false], 'intlcal_get_now' => ['hasSideEffects' => false], 'intlcal_get_repeated_wall_time_option' => ['hasSideEffects' => false], 'intlcal_get_skipped_wall_time_option' => ['hasSideEffects' => false], 'intlcal_get_time' => ['hasSideEffects' => false], 'intlcal_get_time_zone' => ['hasSideEffects' => false], 'intlcal_get_type' => ['hasSideEffects' => false], 'intlcal_get_weekend_transition' => ['hasSideEffects' => false], 'intlcal_greates_minimum' => ['hasSideEffects' => false], 'intlcal_in_daylight_time' => ['hasSideEffects' => false], 'intlcal_is_equivalent_to' => ['hasSideEffects' => false], 'intlcal_is_lenient' => ['hasSideEffects' => false], 'intlcal_is_set' => ['hasSideEffects' => false], 'intlcal_is_weekend' => ['hasSideEffects' => false], 'intlcal_to_date_time' => ['hasSideEffects' => false], 'intlgregcal_create_instance' => ['hasSideEffects' => false], 'intlgregcal_get_gregorian_change' => ['hasSideEffects' => false], 'intlgregcal_is_leap_year' => ['hasSideEffects' => false], 'intltz_count_equivalent_ids' => ['hasSideEffects' => false], 'intltz_create_default' => ['hasSideEffects' => false], 'intltz_create_enumeration' => ['hasSideEffects' => false], 'intltz_create_time_zone' => ['hasSideEffects' => false], 'intltz_create_time_zone_id_enumeration' => ['hasSideEffects' => false], 'intltz_from_date_time_zone' => ['hasSideEffects' => false], 'intltz_get_canonical_id' => ['hasSideEffects' => false], 'intltz_get_display_name' => ['hasSideEffects' => false], 'intltz_get_dst_savings' => ['hasSideEffects' => false], 'intltz_get_equivalent_id' => ['hasSideEffects' => false], 'intltz_get_error_code' => ['hasSideEffects' => false], 'intltz_get_error_message' => ['hasSideEffects' => false], 'intltz_get_gmt' => ['hasSideEffects' => false], 'intltz_get_id' => ['hasSideEffects' => false], 'intltz_get_offset' => ['hasSideEffects' => false], 'intltz_get_raw_offset' => ['hasSideEffects' => false], 'intltz_get_region' => ['hasSideEffects' => false], 'intltz_get_tz_data_version' => ['hasSideEffects' => false], 'intltz_get_unknown' => ['hasSideEffects' => false], 'intltz_getgmt' => ['hasSideEffects' => false], 'intltz_has_same_rules' => ['hasSideEffects' => false], 'intltz_to_date_time_zone' => ['hasSideEffects' => false], 'intltz_use_daylight_time' => ['hasSideEffects' => false], 'intlz_create_default' => ['hasSideEffects' => false], 'intval' => ['hasSideEffects' => false], 'ip2long' => ['hasSideEffects' => false], 'iptcparse' => ['hasSideEffects' => false], 'is_a' => ['hasSideEffects' => false], 'is_array' => ['hasSideEffects' => false], 'is_bool' => ['hasSideEffects' => false], 'is_countable' => ['hasSideEffects' => false], 'is_dir' => ['hasSideEffects' => false], 'is_double' => ['hasSideEffects' => false], 'is_executable' => ['hasSideEffects' => false], 'is_file' => ['hasSideEffects' => false], 'is_finite' => ['hasSideEffects' => false], 'is_float' => ['hasSideEffects' => false], 'is_infinite' => ['hasSideEffects' => false], 'is_int' => ['hasSideEffects' => false], 'is_integer' => ['hasSideEffects' => false], 'is_iterable' => ['hasSideEffects' => false], 'is_link' => ['hasSideEffects' => false], 'is_long' => ['hasSideEffects' => false], 'is_nan' => ['hasSideEffects' => false], 'is_null' => ['hasSideEffects' => false], 'is_numeric' => ['hasSideEffects' => false], 'is_object' => ['hasSideEffects' => false], 'is_readable' => ['hasSideEffects' => false], 'is_real' => ['hasSideEffects' => false], 'is_resource' => ['hasSideEffects' => false], 'is_scalar' => ['hasSideEffects' => false], 'is_string' => ['hasSideEffects' => false], 'is_subclass_of' => ['hasSideEffects' => false], 'is_uploaded_file' => ['hasSideEffects' => false], 'is_writable' => ['hasSideEffects' => false], 'is_writeable' => ['hasSideEffects' => false], 'iterator_count' => ['hasSideEffects' => false], 'join' => ['hasSideEffects' => false], 'json_last_error' => ['hasSideEffects' => false], 'json_last_error_msg' => ['hasSideEffects' => false], 'json_validate' => ['hasSideEffects' => false], 'key' => ['hasSideEffects' => false], 'key_exists' => ['hasSideEffects' => false], 'lcfirst' => ['hasSideEffects' => false], 'lchgrp' => ['hasSideEffects' => true], 'lchown' => ['hasSideEffects' => true], 'libxml_get_errors' => ['hasSideEffects' => false], 'libxml_get_last_error' => ['hasSideEffects' => false], 'link' => ['hasSideEffects' => true], 'linkinfo' => ['hasSideEffects' => false], 'locale_accept_from_http' => ['hasSideEffects' => false], 'locale_canonicalize' => ['hasSideEffects' => false], 'locale_compose' => ['hasSideEffects' => false], 'locale_filter_matches' => ['hasSideEffects' => false], 'locale_get_all_variants' => ['hasSideEffects' => false], 'locale_get_default' => ['hasSideEffects' => false], 'locale_get_display_language' => ['hasSideEffects' => false], 'locale_get_display_name' => ['hasSideEffects' => false], 'locale_get_display_region' => ['hasSideEffects' => false], 'locale_get_display_script' => ['hasSideEffects' => false], 'locale_get_display_variant' => ['hasSideEffects' => false], 'locale_get_keywords' => ['hasSideEffects' => false], 'locale_get_primary_language' => ['hasSideEffects' => false], 'locale_get_region' => ['hasSideEffects' => false], 'locale_get_script' => ['hasSideEffects' => false], 'locale_lookup' => ['hasSideEffects' => false], 'locale_parse' => ['hasSideEffects' => false], 'localeconv' => ['hasSideEffects' => false], 'localtime' => ['hasSideEffects' => false], 'log' => ['hasSideEffects' => false], 'log10' => ['hasSideEffects' => false], 'log1p' => ['hasSideEffects' => false], 'long2ip' => ['hasSideEffects' => false], 'lstat' => ['hasSideEffects' => false], 'ltrim' => ['hasSideEffects' => false], 'max' => ['hasSideEffects' => false], 'mb_check_encoding' => ['hasSideEffects' => false], 'mb_chr' => ['hasSideEffects' => false], 'mb_convert_case' => ['hasSideEffects' => false], 'mb_convert_encoding' => ['hasSideEffects' => false], 'mb_convert_kana' => ['hasSideEffects' => false], 'mb_decode_mimeheader' => ['hasSideEffects' => false], 'mb_decode_numericentity' => ['hasSideEffects' => false], 'mb_detect_encoding' => ['hasSideEffects' => false], 'mb_encode_mimeheader' => ['hasSideEffects' => false], 'mb_encode_numericentity' => ['hasSideEffects' => false], 'mb_encoding_aliases' => ['hasSideEffects' => false], 'mb_ereg_match' => ['hasSideEffects' => false], 'mb_ereg_replace' => ['hasSideEffects' => false], 'mb_ereg_search' => ['hasSideEffects' => false], 'mb_ereg_search_getpos' => ['hasSideEffects' => false], 'mb_ereg_search_getregs' => ['hasSideEffects' => false], 'mb_ereg_search_pos' => ['hasSideEffects' => false], 'mb_ereg_search_regs' => ['hasSideEffects' => false], 'mb_ereg_search_setpos' => ['hasSideEffects' => false], 'mb_eregi_replace' => ['hasSideEffects' => false], 'mb_get_info' => ['hasSideEffects' => false], 'mb_http_input' => ['hasSideEffects' => false], 'mb_list_encodings' => ['hasSideEffects' => false], 'mb_ord' => ['hasSideEffects' => false], 'mb_output_handler' => ['hasSideEffects' => false], 'mb_preferred_mime_name' => ['hasSideEffects' => false], 'mb_scrub' => ['hasSideEffects' => false], 'mb_split' => ['hasSideEffects' => false], 'mb_str_pad' => ['hasSideEffects' => false], 'mb_str_split' => ['hasSideEffects' => false], 'mb_strcut' => ['hasSideEffects' => false], 'mb_strimwidth' => ['hasSideEffects' => false], 'mb_stripos' => ['hasSideEffects' => false], 'mb_stristr' => ['hasSideEffects' => false], 'mb_strlen' => ['hasSideEffects' => false], 'mb_strpos' => ['hasSideEffects' => false], 'mb_strrchr' => ['hasSideEffects' => false], 'mb_strrichr' => ['hasSideEffects' => false], 'mb_strripos' => ['hasSideEffects' => false], 'mb_strrpos' => ['hasSideEffects' => false], 'mb_strstr' => ['hasSideEffects' => false], 'mb_strtolower' => ['hasSideEffects' => false], 'mb_strtoupper' => ['hasSideEffects' => false], 'mb_strwidth' => ['hasSideEffects' => false], 'mb_substr' => ['hasSideEffects' => false], 'mb_substr_count' => ['hasSideEffects' => false], 'mbereg_search_setpos' => ['hasSideEffects' => false], 'md5' => ['hasSideEffects' => false], 'md5_file' => ['hasSideEffects' => false], 'memory_get_peak_usage' => ['hasSideEffects' => false], 'memory_get_usage' => ['hasSideEffects' => false], 'metaphone' => ['hasSideEffects' => false], 'method_exists' => ['hasSideEffects' => false], 'mhash' => ['hasSideEffects' => false], 'mhash_count' => ['hasSideEffects' => false], 'mhash_get_block_size' => ['hasSideEffects' => false], 'mhash_get_hash_name' => ['hasSideEffects' => false], 'mhash_keygen_s2k' => ['hasSideEffects' => false], 'microtime' => ['hasSideEffects' => false], 'min' => ['hasSideEffects' => false], 'mkdir' => ['hasSideEffects' => true], 'mktime' => ['hasSideEffects' => false], 'move_uploaded_file' => ['hasSideEffects' => true], 'msgfmt_create' => ['hasSideEffects' => false], 'msgfmt_format' => ['hasSideEffects' => false], 'msgfmt_format_message' => ['hasSideEffects' => false], 'msgfmt_get_error_code' => ['hasSideEffects' => false], 'msgfmt_get_error_message' => ['hasSideEffects' => false], 'msgfmt_get_locale' => ['hasSideEffects' => false], 'msgfmt_get_pattern' => ['hasSideEffects' => false], 'msgfmt_parse' => ['hasSideEffects' => false], 'msgfmt_parse_message' => ['hasSideEffects' => false], 'mt_getrandmax' => ['hasSideEffects' => false], 'mt_rand' => ['hasSideEffects' => true], 'net_get_interfaces' => ['hasSideEffects' => false], 'ngettext' => ['hasSideEffects' => false], 'nl2br' => ['hasSideEffects' => false], 'nl_langinfo' => ['hasSideEffects' => false], 'normalizer_get_raw_decomposition' => ['hasSideEffects' => false], 'normalizer_is_normalized' => ['hasSideEffects' => false], 'normalizer_normalize' => ['hasSideEffects' => false], 'number_format' => ['hasSideEffects' => false], 'numfmt_create' => ['hasSideEffects' => false], 'numfmt_format' => ['hasSideEffects' => false], 'numfmt_format_currency' => ['hasSideEffects' => false], 'numfmt_get_attribute' => ['hasSideEffects' => false], 'numfmt_get_error_code' => ['hasSideEffects' => false], 'numfmt_get_error_message' => ['hasSideEffects' => false], 'numfmt_get_locale' => ['hasSideEffects' => false], 'numfmt_get_pattern' => ['hasSideEffects' => false], 'numfmt_get_symbol' => ['hasSideEffects' => false], 'numfmt_get_text_attribute' => ['hasSideEffects' => false], 'numfmt_parse' => ['hasSideEffects' => false], 'ob_etaghandler' => ['hasSideEffects' => false], 'ob_get_contents' => ['hasSideEffects' => false], 'ob_iconv_handler' => ['hasSideEffects' => false], 'octdec' => ['hasSideEffects' => false], 'ord' => ['hasSideEffects' => false], 'pack' => ['hasSideEffects' => false], 'pam_auth' => ['hasSideEffects' => false], 'pam_chpass' => ['hasSideEffects' => false], 'parse_ini_file' => ['hasSideEffects' => false], 'parse_ini_string' => ['hasSideEffects' => false], 'parse_url' => ['hasSideEffects' => false], 'pathinfo' => ['hasSideEffects' => false], 'pclose' => ['hasSideEffects' => true], 'pcntl_errno' => ['hasSideEffects' => false], 'pcntl_get_last_error' => ['hasSideEffects' => false], 'pcntl_getpriority' => ['hasSideEffects' => false], 'pcntl_strerror' => ['hasSideEffects' => false], 'pcntl_wexitstatus' => ['hasSideEffects' => false], 'pcntl_wifcontinued' => ['hasSideEffects' => false], 'pcntl_wifexited' => ['hasSideEffects' => false], 'pcntl_wifsignaled' => ['hasSideEffects' => false], 'pcntl_wifstopped' => ['hasSideEffects' => false], 'pcntl_wstopsig' => ['hasSideEffects' => false], 'pcntl_wtermsig' => ['hasSideEffects' => false], 'pdo_drivers' => ['hasSideEffects' => false], 'php_ini_loaded_file' => ['hasSideEffects' => false], 'php_ini_scanned_files' => ['hasSideEffects' => false], 'php_logo_guid' => ['hasSideEffects' => false], 'php_sapi_name' => ['hasSideEffects' => false], 'php_strip_whitespace' => ['hasSideEffects' => false], 'php_uname' => ['hasSideEffects' => false], 'phpversion' => ['hasSideEffects' => false], 'pi' => ['hasSideEffects' => false], 'popen' => ['hasSideEffects' => true], 'pos' => ['hasSideEffects' => false], 'posix_ctermid' => ['hasSideEffects' => false], 'posix_errno' => ['hasSideEffects' => false], 'posix_get_last_error' => ['hasSideEffects' => false], 'posix_getcwd' => ['hasSideEffects' => false], 'posix_getegid' => ['hasSideEffects' => false], 'posix_geteuid' => ['hasSideEffects' => false], 'posix_getgid' => ['hasSideEffects' => false], 'posix_getgrgid' => ['hasSideEffects' => false], 'posix_getgrnam' => ['hasSideEffects' => false], 'posix_getgroups' => ['hasSideEffects' => false], 'posix_getlogin' => ['hasSideEffects' => false], 'posix_getpgid' => ['hasSideEffects' => false], 'posix_getpgrp' => ['hasSideEffects' => false], 'posix_getpid' => ['hasSideEffects' => false], 'posix_getppid' => ['hasSideEffects' => false], 'posix_getpwnam' => ['hasSideEffects' => false], 'posix_getpwuid' => ['hasSideEffects' => false], 'posix_getrlimit' => ['hasSideEffects' => false], 'posix_getsid' => ['hasSideEffects' => false], 'posix_getuid' => ['hasSideEffects' => false], 'posix_initgroups' => ['hasSideEffects' => false], 'posix_isatty' => ['hasSideEffects' => false], 'posix_strerror' => ['hasSideEffects' => false], 'posix_times' => ['hasSideEffects' => false], 'posix_ttyname' => ['hasSideEffects' => false], 'posix_uname' => ['hasSideEffects' => false], 'pow' => ['hasSideEffects' => false], 'preg_grep' => ['hasSideEffects' => false], 'preg_last_error' => ['hasSideEffects' => false], 'preg_last_error_msg' => ['hasSideEffects' => false], 'preg_quote' => ['hasSideEffects' => false], 'preg_split' => ['hasSideEffects' => false], 'property_exists' => ['hasSideEffects' => false], 'quoted_printable_decode' => ['hasSideEffects' => false], 'quoted_printable_encode' => ['hasSideEffects' => false], 'quotemeta' => ['hasSideEffects' => false], 'rad2deg' => ['hasSideEffects' => false], 'rand' => ['hasSideEffects' => true], 'random_bytes' => ['hasSideEffects' => true], 'random_int' => ['hasSideEffects' => true], 'range' => ['hasSideEffects' => false], 'rawurldecode' => ['hasSideEffects' => false], 'rawurlencode' => ['hasSideEffects' => false], 'readfile' => ['hasSideEffects' => true], 'readlink' => ['hasSideEffects' => false], 'realpath' => ['hasSideEffects' => false], 'realpath_cache_get' => ['hasSideEffects' => false], 'realpath_cache_size' => ['hasSideEffects' => false], 'rename' => ['hasSideEffects' => true], 'resourcebundle_count' => ['hasSideEffects' => false], 'resourcebundle_create' => ['hasSideEffects' => false], 'resourcebundle_get' => ['hasSideEffects' => false], 'resourcebundle_get_error_code' => ['hasSideEffects' => false], 'resourcebundle_get_error_message' => ['hasSideEffects' => false], 'resourcebundle_locales' => ['hasSideEffects' => false], 'rewind' => ['hasSideEffects' => true], 'rmdir' => ['hasSideEffects' => true], 'round' => ['hasSideEffects' => false], 'rtrim' => ['hasSideEffects' => false], 'sha1' => ['hasSideEffects' => false], 'sha1_file' => ['hasSideEffects' => false], 'sin' => ['hasSideEffects' => false], 'sinh' => ['hasSideEffects' => false], 'sizeof' => ['hasSideEffects' => false], 'soundex' => ['hasSideEffects' => false], 'spl_classes' => ['hasSideEffects' => false], 'spl_object_hash' => ['hasSideEffects' => false], 'sprintf' => ['hasSideEffects' => false], 'sqrt' => ['hasSideEffects' => false], 'stat' => ['hasSideEffects' => false], 'str_contains' => ['hasSideEffects' => false], 'str_decrement' => ['hasSideEffects' => false], 'str_ends_with' => ['hasSideEffects' => false], 'str_getcsv' => ['hasSideEffects' => false], 'str_increment' => ['hasSideEffects' => false], 'str_pad' => ['hasSideEffects' => false], 'str_repeat' => ['hasSideEffects' => false], 'str_rot13' => ['hasSideEffects' => false], 'str_split' => ['hasSideEffects' => false], 'str_starts_with' => ['hasSideEffects' => false], 'str_word_count' => ['hasSideEffects' => false], 'strcasecmp' => ['hasSideEffects' => false], 'strchr' => ['hasSideEffects' => false], 'strcmp' => ['hasSideEffects' => false], 'strcoll' => ['hasSideEffects' => false], 'strcspn' => ['hasSideEffects' => false], 'stream_get_filters' => ['hasSideEffects' => false], 'stream_get_transports' => ['hasSideEffects' => false], 'stream_get_wrappers' => ['hasSideEffects' => false], 'stream_is_local' => ['hasSideEffects' => false], 'stream_isatty' => ['hasSideEffects' => false], 'strip_tags' => ['hasSideEffects' => false], 'stripcslashes' => ['hasSideEffects' => false], 'stripos' => ['hasSideEffects' => false], 'stripslashes' => ['hasSideEffects' => false], 'stristr' => ['hasSideEffects' => false], 'strlen' => ['hasSideEffects' => false], 'strnatcasecmp' => ['hasSideEffects' => false], 'strnatcmp' => ['hasSideEffects' => false], 'strncasecmp' => ['hasSideEffects' => false], 'strncmp' => ['hasSideEffects' => false], 'strpbrk' => ['hasSideEffects' => false], 'strpos' => ['hasSideEffects' => false], 'strptime' => ['hasSideEffects' => false], 'strrchr' => ['hasSideEffects' => false], 'strrev' => ['hasSideEffects' => false], 'strripos' => ['hasSideEffects' => false], 'strrpos' => ['hasSideEffects' => false], 'strspn' => ['hasSideEffects' => false], 'strstr' => ['hasSideEffects' => false], 'strtolower' => ['hasSideEffects' => false], 'strtotime' => ['hasSideEffects' => false], 'strtoupper' => ['hasSideEffects' => false], 'strtr' => ['hasSideEffects' => false], 'strval' => ['hasSideEffects' => false], 'substr' => ['hasSideEffects' => false], 'substr_compare' => ['hasSideEffects' => false], 'substr_count' => ['hasSideEffects' => false], 'substr_replace' => ['hasSideEffects' => false], 'symlink' => ['hasSideEffects' => true], 'sys_getloadavg' => ['hasSideEffects' => false], 'tan' => ['hasSideEffects' => false], 'tanh' => ['hasSideEffects' => false], 'tempnam' => ['hasSideEffects' => true], 'timezone_abbreviations_list' => ['hasSideEffects' => false], 'timezone_identifiers_list' => ['hasSideEffects' => false], 'timezone_location_get' => ['hasSideEffects' => false], 'timezone_name_from_abbr' => ['hasSideEffects' => false], 'timezone_name_get' => ['hasSideEffects' => false], 'timezone_offset_get' => ['hasSideEffects' => false], 'timezone_open' => ['hasSideEffects' => false], 'timezone_transitions_get' => ['hasSideEffects' => false], 'timezone_version_get' => ['hasSideEffects' => false], 'tmpfile' => ['hasSideEffects' => true], 'token_get_all' => ['hasSideEffects' => false], 'token_name' => ['hasSideEffects' => false], 'touch' => ['hasSideEffects' => true], 'transliterator_create' => ['hasSideEffects' => false], 'transliterator_create_from_rules' => ['hasSideEffects' => false], 'transliterator_create_inverse' => ['hasSideEffects' => false], 'transliterator_get_error_code' => ['hasSideEffects' => false], 'transliterator_get_error_message' => ['hasSideEffects' => false], 'transliterator_list_ids' => ['hasSideEffects' => false], 'transliterator_transliterate' => ['hasSideEffects' => false], 'trim' => ['hasSideEffects' => false], 'ucfirst' => ['hasSideEffects' => false], 'ucwords' => ['hasSideEffects' => false], 'umask' => ['hasSideEffects' => true], 'unlink' => ['hasSideEffects' => true], 'unpack' => ['hasSideEffects' => false], 'urldecode' => ['hasSideEffects' => false], 'urlencode' => ['hasSideEffects' => false], 'utf8_decode' => ['hasSideEffects' => false], 'utf8_encode' => ['hasSideEffects' => false], 'vsprintf' => ['hasSideEffects' => false], 'wordwrap' => ['hasSideEffects' => false], 'xml_error_string' => ['hasSideEffects' => false], 'xml_get_current_byte_index' => ['hasSideEffects' => false], 'xml_get_current_column_number' => ['hasSideEffects' => false], 'xml_get_current_line_number' => ['hasSideEffects' => false], 'xml_get_error_code' => ['hasSideEffects' => false], 'xml_parser_create' => ['hasSideEffects' => false], 'xml_parser_create_ns' => ['hasSideEffects' => false], 'xml_parser_get_option' => ['hasSideEffects' => false], 'zend_version' => ['hasSideEffects' => false], 'zlib_decode' => ['hasSideEffects' => false], 'zlib_encode' => ['hasSideEffects' => false], 'zlib_get_coding_type' => ['hasSideEffects' => false], ]; ['bcadd' => ['numeric-string', 'left_operand' => 'numeric-string', 'right_operand' => 'numeric-string', 'scale=' => 'int'], 'bccomp' => ['int', 'left_operand' => 'numeric-string', 'right_operand' => 'numeric-string', 'scale=' => 'int'], 'bcdiv' => ['numeric-string|null', 'left_operand' => 'numeric-string', 'right_operand' => 'numeric-string', 'scale=' => 'int'], 'bcmod' => ['numeric-string|null', 'left_operand' => 'string', 'right_operand' => 'numeric-string', 'scale=' => 'int'], 'bcmul' => ['numeric-string', 'left_operand' => 'numeric-string', 'right_operand' => 'numeric-string', 'scale=' => 'int'], 'bcpow' => ['numeric-string', 'base' => 'numeric-string', 'exponent' => 'numeric-string', 'scale=' => 'int'], 'bcpowmod' => ['numeric-string|null', 'base' => 'numeric-string', 'exponent' => 'numeric-string', 'modulus' => 'string', 'scale=' => 'int'], 'bcsqrt' => ['numeric-string', 'operand' => 'numeric-string', 'scale=' => 'int'], 'bcsub' => ['numeric-string', 'left_operand' => 'numeric-string', 'right_operand' => 'numeric-string', 'scale=' => 'int'], 'Closure::bind' => ['Closure', 'old' => 'Closure', 'to' => '?object', 'scope=' => 'object|class-string|\'static\'|null'], 'Closure::bindTo' => ['Closure', 'new' => '?object', 'newscope=' => 'object|class-string|\'static\'|null'], 'error_log' => ['bool', 'message' => 'string', 'message_type=' => '0|1|2|3|4', 'destination=' => 'string', 'extra_headers=' => 'string'], 'SplFileObject::flock' => ['bool', 'operation' => 'int-mask', '&w_wouldblock=' => '0|1'], 'Imagick::adaptiveBlurImage' => ['bool', 'radius' => 'float', 'sigma' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::adaptiveSharpenImage' => ['bool', 'radius' => 'float', 'sigma' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::addNoiseImage' => ['bool', 'noise_type' => 'Imagick::NOISE_*', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::autoGammaImage' => ['bool', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::autoLevelImage' => ['bool', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::blurImage' => ['bool', 'radius' => 'float', 'sigma' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::brightnessContrastImage' => ['bool', 'brightness' => 'float', 'contrast' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::clampImage' => ['bool', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::combineImages' => ['Imagick', 'channeltype' => 'Imagick::CHANNEL_*'], 'Imagick::compareImageChannels' => ['array{Imagick,float}', 'image' => 'imagick', 'channeltype' => 'Imagick::CHANNEL_*', 'metrictype' => 'Imagick::METRIC_*'], 'Imagick::compareImageLayers' => ['Imagick', 'method' => 'Imagick::LAYERMETHOD_*'], 'Imagick::compareImages' => ['array{Imagick,float}', 'compare' => 'imagick', 'metric' => 'Imagick::METRIC_*'], 'Imagick::compositeImage' => ['bool', 'composite_object' => 'imagick', 'composite' => 'Imagick::COMPOSITE_*', 'x' => 'int', 'y' => 'int', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::contrastStretchImage' => ['bool', 'black_point' => 'float', 'white_point' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::convolveImage' => ['bool', 'kernel' => 'array', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::distortImage' => ['bool', 'method' => 'Imagick::DISTORTION_*', 'arguments' => 'array', 'bestfit' => 'bool'], 'Imagick::evaluateImage' => ['bool', 'op' => 'Imagick::EVALUATE_*', 'constant' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::exportImagePixels' => ['list', 'x' => 'int', 'y' => 'int', 'width' => 'int', 'height' => 'int', 'map' => 'string', 'storage' => 'Imagick::PIXEL_*'], 'Imagick::floodFillPaintImage' => ['bool', 'fill' => 'mixed', 'fuzz' => 'float', 'target' => 'mixed', 'x' => 'int', 'y' => 'int', 'invert' => 'bool', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::functionImage' => ['bool', 'function' => 'Imagick::FUNCTION_*', 'arguments' => 'array', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::fxImage' => ['Imagick', 'expression' => 'string', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::gammaImage' => ['bool', 'gamma' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::gaussianBlurImage' => ['bool', 'radius' => 'float', 'sigma' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::getImageChannelDepth' => ['int', 'channel' => 'Imagick::CHANNEL_*'], 'Imagick::getImageChannelDistortion' => ['float', 'reference' => 'imagick', 'channel' => 'Imagick::CHANNEL_*', 'metric' => 'Imagick::METRIC_*'], 'Imagick::getImageChannelDistortions' => ['float', 'reference' => 'imagick', 'metric' => 'Imagick::METRIC_*', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::getImageChannelExtrema' => ['array{minima:0|positive-int,maxima:0|positive-int}', 'channel' => 'Imagick::CHANNEL_*'], 'Imagick::getImageChannelKurtosis' => ['array{kurtosis:float,skewness:float}', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::getImageChannelMean' => ['array{mean:float,standardDeviation:float}', 'channel' => 'Imagick::CHANNEL_*'], 'Imagick::getImageChannelRange' => ['array{minima:float,maxima:float}', 'channel' => 'Imagick::CHANNEL_*'], 'Imagick::getImageDistortion' => ['float', 'reference' => 'magickwand', 'metric' => 'Imagick::METRIC_*'], 'Imagick::getResource' => ['int', 'type' => 'Imagick::RESOURCETYPE_*'], 'Imagick::getResourceLimit' => ['int', 'type' => 'Imagick::RESOURCETYPE_*'], 'Imagick::importImagePixels' => ['bool', 'x' => 'int', 'y' => 'int', 'width' => 'int', 'height' => 'int', 'map' => 'string', 'storage' => 'Imagick::PIXEL_*', 'pixels' => 'array'], 'Imagick::levelImage' => ['bool', 'blackpoint' => 'float', 'gamma' => 'float', 'whitepoint' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::mergeImageLayers' => ['Imagick', 'layer_method' => 'Imagick::LAYERMETHOD_*'], 'Imagick::montageImage' => ['Imagick', 'draw' => 'imagickdraw', 'tile_geometry' => 'string', 'thumbnail_geometry' => 'string', 'mode' => 'Imagick::MONTAGEMODE_*', 'frame' => 'string'], 'Imagick::morphology' => ['bool', 'morphologyMethod' => 'Imagick::MORPHOLOGY_*', 'iterations' => 'int', 'ImagickKernel' => 'ImagickKernel', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::motionBlurImage' => ['bool', 'radius' => 'float', 'sigma' => 'float', 'angle' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::negateImage' => ['bool', 'gray' => 'bool', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::normalizeImage' => ['bool', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::opaquePaintImage' => ['bool', 'target' => 'mixed', 'fill' => 'mixed', 'fuzz' => 'float', 'invert' => 'bool', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::orderedPosterizeImage' => ['bool', 'threshold_map' => 'string', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::paintFloodfillImage' => ['bool', 'fill' => 'mixed', 'fuzz' => 'float', 'bordercolor' => 'mixed', 'x' => 'int', 'y' => 'int', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::paintOpaqueImage' => ['bool', 'target' => 'mixed', 'fill' => 'mixed', 'fuzz' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::radialBlurImage' => ['bool', 'angle' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::randomThresholdImage' => ['bool', 'low' => 'float', 'high' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::remapImage' => ['bool', 'replacement' => 'imagick', 'dither' => 'Imagick::DITHERMETHOD_*'], 'Imagick::rotationalBlurImage' => ['bool', 'float' => 'string', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::segmentImage' => ['bool', 'colorspace' => 'Imagick::COLORSPACE_*', 'cluster_threshold' => 'float', 'smooth_threshold' => 'float', 'verbose=' => 'bool'], 'Imagick::selectiveBlurImage' => ['bool', 'radius' => 'float', 'sigma' => 'float', 'threshold' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::separateImageChannel' => ['bool', 'channel' => 'Imagick::CHANNEL_*'], 'Imagick::setColorspace' => ['bool', 'colorspace' => 'Imagick::COLORSPACE_*'], 'Imagick::setCompression' => ['bool', 'compression' => 'Imagick::COMPRESSION_*'], 'Imagick::setGravity' => ['bool', 'gravity' => 'Imagick::GRAVITY_*'], 'Imagick::setImageAlphaChannel' => ['bool', 'mode' => 'Imagick::ALPHACHANNEL_*'], 'Imagick::setImageChannelDepth' => ['bool', 'channel' => 'Imagick::CHANNEL_*', 'depth' => 'int'], 'Imagick::setImageChannelMask' => ['', 'channel' => 'Imagick::CHANNEL_*'], 'Imagick::setImageClipMask' => ['bool', 'clip_mask' => 'imagick'], 'Imagick::setImageColormapColor' => ['bool', 'index' => 'int', 'color' => 'imagickpixel'], 'Imagick::setImageColorspace' => ['bool', 'colorspace' => 'Imagick::COLORSPACE_*'], 'Imagick::setImageCompose' => ['bool', 'compose' => 'Imagick::COMPOSITE_*'], 'Imagick::setImageCompression' => ['bool', 'compression' => 'Imagick::COMPRESSION_*'], 'Imagick::setImageDispose' => ['bool', 'dispose' => 'Imagick::DISPOSE_*'], 'Imagick::setImageGravity' => ['bool', 'gravity' => 'Imagick::GRAVITY_*'], 'Imagick::setImageInterlaceScheme' => ['bool', 'interlace_scheme' => 'Imagick::INTERLACE_*'], 'Imagick::setImageInterpolateMethod' => ['bool', 'method' => 'Imagick::INTERPOLATE_*'], 'Imagick::setImageOrientation' => ['bool', 'orientation' => 'Imagick::ORIENTATION_*'], 'Imagick::setImageRenderingIntent' => ['bool', 'rendering_intent' => 'Imagick::RENDERINGINTENT_*'], 'Imagick::setImageType' => ['bool', 'image_type' => 'Imagick::IMGTYPE_*'], 'Imagick::setType' => ['bool', 'image_type' => 'Imagick::IMGTYPE_*'], 'Imagick::sharpenImage' => ['bool', 'radius' => 'float', 'sigma' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::sigmoidalContrastImage' => ['bool', 'sharpen' => 'bool', 'alpha' => 'float', 'beta' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::similarityImage' => ['Imagick', 'imagick' => 'Imagick', '&bestMatch' => 'array', '&similarity' => 'float', 'similarity_threshold' => 'float', 'metric' => 'Imagick::METRIC_*'], 'Imagick::sparseColorImage' => ['bool', 'sparse_method' => 'Imagick::SPARSECOLORMETHOD_*', 'arguments' => 'array', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::statisticImage' => ['bool', 'type' => 'Imagick::STATISTIC_*', 'width' => 'int', 'height' => 'int', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::thresholdImage' => ['bool', 'threshold' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'Imagick::transformImageColorspace' => ['bool', 'colorspace' => 'Imagick::COLORSPACE_*'], 'Imagick::unsharpMaskImage' => ['bool', 'radius' => 'float', 'sigma' => 'float', 'amount' => 'float', 'threshold' => 'float', 'channel=' => 'Imagick::CHANNEL_*'], 'ImagickDraw::color' => ['bool', 'x' => 'float', 'y' => 'float', 'paintmethod' => 'Imagick::PAINT_*'], 'ImagickDraw::composite' => ['bool', 'compose' => 'Imagick::COMPOSITE_*', 'x' => 'float', 'y' => 'float', 'width' => 'float', 'height' => 'float', 'compositewand' => 'imagick'], 'ImagickDraw::getFillRule' => ['Imagick::FILLRULE_*'], 'ImagickDraw::getFontStretch' => ['Imagick::STRETCH_*'], 'ImagickDraw::getFontStyle' => ['Imagick::STYLE_*'], 'ImagickDraw::getGravity' => ['Imagick::GRAVITY_*'], 'ImagickDraw::getStrokeLineCap' => ['Imagick::LINECAP_*'], 'ImagickDraw::getStrokeLineJoin' => ['Imagick::LINEJOIN_*'], 'ImagickDraw::getTextAlignment' => ['Imagick::ALIGN_*'], 'ImagickDraw::getTextDecoration' => ['Imagick::DECORATION_*'], 'ImagickDraw::matte' => ['bool', 'x' => 'float', 'y' => 'float', 'paintmethod' => 'Imagick::PAINT_*'], 'ImagickDraw::setClipRule' => ['bool', 'fill_rule' => 'Imagick::FILLRULE_*'], 'ImagickDraw::setFillRule' => ['bool', 'fill_rule' => 'Imagick::FILLRULE_*'], 'ImagickDraw::setFontStretch' => ['bool', 'fontstretch' => 'Imagick::STRETCH_*'], 'ImagickDraw::setFontStyle' => ['bool', 'style' => 'Imagick::STYLE_*'], 'ImagickDraw::setGravity' => ['bool', 'gravity' => 'Imagick::GRAVITY_*'], 'ImagickDraw::setStrokeLineCap' => ['bool', 'linecap' => 'Imagick::LINECAP_*'], 'ImagickDraw::setStrokeLineJoin' => ['bool', 'linejoin' => 'Imagick::LINEJOIN_*'], 'ImagickDraw::setTextAlignment' => ['bool', 'alignment' => 'Imagick::ALIGN_*'], 'ImagickDraw::setTextAntialias' => ['bool', 'antialias' => 'bool'], 'ImagickDraw::setTextDecoration' => ['bool', 'decoration' => 'Imagick::DECORATION_*'], 'ImagickKernel::fromBuiltin' => ['ImagickKernel', 'kernelType' => 'Imagick::KERNEL_*', 'kernelString' => 'string'], 'ImagickKernel::scale' => ['void', 'scale' => 'float', 'normalizeFlag' => 'Imagick::NORMALIZE_KERNEL_*'], 'imagecolorallocate' => ['int<0, max>|false', 'im' => 'resource', 'red' => 'int<0, 255>', 'green' => 'int<0, 255>', 'blue' => 'int<0, 255>'], 'imagecolorallocatealpha' => ['int<0, max>|false', 'im' => 'resource', 'red' => 'int<0, 255>', 'green' => 'int<0, 255>', 'blue' => 'int<0, 255>', 'alpha' => 'int<0, 127>'], 'imagecolorclosest' => ['int<0, max>', 'im' => 'resource', 'red' => 'int<0, 255>', 'green' => 'int<0, 255>', 'blue' => 'int<0, 255>'], 'imagecolorclosestalpha' => ['int<0, max>', 'im' => 'resource', 'red' => 'int<0, 255>', 'green' => 'int<0, 255>', 'blue' => 'int<0, 255>', 'alpha' => 'int<0, 127>'], 'imagecolorclosesthwb' => ['int<0, max>', 'im' => 'resource', 'red' => 'int<0, 255>', 'green' => 'int<0, 255>', 'blue' => 'int<0, 255>'], 'imagecolorexact' => ['int<0, max>|false', 'im' => 'resource', 'red' => 'int<0, 255>', 'green' => 'int<0, 255>', 'blue' => 'int<0, 255>'], 'imagecolorexactalpha' => ['int<0, max>|false', 'im' => 'resource', 'red' => 'int<0, 255>', 'green' => 'int<0, 255>', 'blue' => 'int<0, 255>', 'alpha' => 'int<0, 127>'], 'imagecolorresolve' => ['int<0, max>', 'im' => 'resource', 'red' => 'int<0, 255>', 'green' => 'int<0, 255>', 'blue' => 'int<0, 255>'], 'imagecolorresolvealpha' => ['int<0, max>', 'im' => 'resource', 'red' => 'int<0, 255>', 'green' => 'int<0, 255>', 'blue' => 'int<0, 255>', 'alpha' => 'int<0, 127>'], 'imagecolorset' => ['void', 'im' => 'resource', 'col' => 'int', 'red' => 'int<0, 255>', 'green' => 'int<0, 255>', 'blue' => 'int<0, 255>', 'alpha=' => 'int<0, 127>'], 'imagecreate' => ['__benevolent', 'x_size' => 'int<1, max>', 'y_size' => 'int<1, max>'], 'imagecreatetruecolor' => ['__benevolent', 'x_size' => 'int<1, max>', 'y_size' => 'int<1, max>'], 'max' => ['', '...arg1' => 'non-empty-array'], 'mb_detect_order' => ['bool|list', 'encoding_list=' => 'non-empty-list|non-falsy-string'], 'min' => ['', '...arg1' => 'non-empty-array'], 'file' => ['list|false', 'filename' => 'string', 'flags=' => 'int-mask', 'context=' => 'resource'], 'flock' => ['bool', 'fp' => 'resource', 'operation' => 'int-mask', '&w_wouldblock=' => '0|1'], 'ftp_append' => ['bool', 'ftp' => 'resource', 'remote_file' => 'string', 'local_file' => 'string', 'mode=' => 'FTP_ASCII|FTP_BINARY'], 'ftp_fget' => ['bool', 'stream' => 'resource', 'fp' => 'resource', 'remote_file' => 'string', 'mode=' => 'FTP_ASCII|FTP_BINARY', 'resumepos=' => 'int'], 'ftp_fput' => ['bool', 'stream' => 'resource', 'remote_file' => 'string', 'fp' => 'resource', 'mode=' => 'FTP_ASCII|FTP_BINARY', 'startpos=' => 'int'], 'ftp_get' => ['bool', 'stream' => 'resource', 'local_file' => 'string', 'remote_file' => 'string', 'mode=' => 'FTP_ASCII|FTP_BINARY', 'resume_pos=' => 'int'], 'ftp_nb_fget' => ['int', 'stream' => 'resource', 'fp' => 'resource', 'remote_file' => 'string', 'mode=' => 'FTP_ASCII|FTP_BINARY', 'resumepos=' => 'int'], 'ftp_nb_fput' => ['int', 'stream' => 'resource', 'remote_file' => 'string', 'fp' => 'resource', 'mode=' => 'FTP_ASCII|FTP_BINARY', 'startpos=' => 'int'], 'ftp_nb_get' => ['int|false', 'stream' => 'resource', 'local_file' => 'string', 'remote_file' => 'string', 'mode=' => 'FTP_ASCII|FTP_BINARY', 'resume_pos=' => 'int'], 'ftp_nb_put' => ['int|false', 'stream' => 'resource', 'remote_file' => 'string', 'local_file' => 'string', 'mode=' => 'FTP_ASCII|FTP_BINARY', 'startpos=' => 'int'], 'ftp_put' => ['bool', 'stream' => 'resource', 'remote_file' => 'string', 'local_file' => 'string', 'mode=' => 'FTP_ASCII|FTP_BINARY', 'startpos=' => 'int'], 'scandir' => ['list|false', 'dir' => 'string', 'sorting_order=' => 'SCANDIR_SORT_ASCENDING|SCANDIR_SORT_DESCENDING| SCANDIR_SORT_NONE', 'context=' => 'resource'], 'stream_socket_client' => ['resource|false', 'remoteaddress' => 'string', '&w_errcode=' => 'int', '&w_errstring=' => 'string', 'timeout=' => 'float', 'flags=' => 'int-mask', 'context=' => 'resource'], 'stream_socket_enable_crypto' => ['0|bool', 'stream' => 'resource', 'enable' => 'bool', 'crypto_method=' => 'STREAM_CRYPTO_METHOD_SSLv2_CLIENT|STREAM_CRYPTO_METHOD_SSLv3_CLIENT|STREAM_CRYPTO_METHOD_SSLv23_CLIENT|STREAM_CRYPTO_METHOD_ANY_CLIENT|STREAM_CRYPTO_METHOD_TLS_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT|STREAM_CRYPTO_METHOD_SSLv2_SERVER|STREAM_CRYPTO_METHOD_SSLv3_SERVER|STREAM_CRYPTO_METHOD_SSLv23_SERVER|STREAM_CRYPTO_METHOD_ANY_SERVER|STREAM_CRYPTO_METHOD_TLS_SERVER|STREAM_CRYPTO_METHOD_TLSv1_0_SERVER|STREAM_CRYPTO_METHOD_TLSv1_1_SERVER|STREAM_CRYPTO_METHOD_TLSv1_2_SERVER|STREAM_CRYPTO_METHOD_TLSv1_3_SERVER', 'session_stream=' => 'resource'], 'extract' => ['0|positive-int', 'array' => 'array', 'flags=' => 'EXTR_OVERWRITE|EXTR_SKIP|EXTR_PREFIX_SAME|EXTR_PREFIX_ALL|EXTR_PREFIX_INVALID|EXTR_IF_EXISTS|EXTR_PREFIX_IF_EXISTS|EXTR_REFS', 'prefix=' => 'string|null'], 'RecursiveIteratorIterator::__construct' => ['void', 'iterator' => 'RecursiveIterator|IteratorAggregate', 'mode=' => 'RecursiveIteratorIterator::LEAVES_ONLY|RecursiveIteratorIterator::SELF_FIRST|RecursiveIteratorIterator::CHILD_FIRST', 'flags=' => '0|RecursiveIteratorIterator::CATCH_GET_CHILD'], 'Locale::composeLocale' => ['string|false', 'subtags' => 'array{language:string, script?:string, region?:string, variant?:array, private?:array, extlang?:array, variant0?:string, variant1?:string, variant2?:string, variant3?:string, variant4?:string, variant5?:string, variant6?:string, variant7?:string, variant8?:string, variant9?:string, variant10?:string, variant11?:string, variant12?:string, variant13?:string, variant14?:string, private0?:string, private1?:string, private2?:string, private3?:string, private4?:string, private5?:string, private6?:string, private7?:string, private8?:string, private9?:string, private10?:string, private11?:string, private12?:string, private13?:string, private14?:string, extlang0?:string, extlang1?:string, extlang2?:string}'], 'locale_compose' => ['string|false', 'subtags' => 'array{language:string, script?:string, region?:string, variant?:array, private?:array, extlang?:array, variant0?:string, variant1?:string, variant2?:string, variant3?:string, variant4?:string, variant5?:string, variant6?:string, variant7?:string, variant8?:string, variant9?:string, variant10?:string, variant11?:string, variant12?:string, variant13?:string, variant14?:string, private0?:string, private1?:string, private2?:string, private3?:string, private4?:string, private5?:string, private6?:string, private7?:string, private8?:string, private9?:string, private10?:string, private11?:string, private12?:string, private13?:string, private14?:string, extlang0?:string, extlang1?:string, extlang2?:string}'], 'count' => ['0|positive-int', 'var' => 'Countable|array', 'mode=' => '0|1']], 'old' => []]; ['mysqli_fetch_field' => ['(stdClass&object{name: string, orgname: string, table: string, orgtable: string, def: string, db: string, catalog: "def", max_length: 0, length: int, charsetnr: string, flags: int, type: int, decimals: int})|false', 'result' => 'mysqli_result'], 'mysqli_fetch_field_direct' => ['(stdClass&object{name: string, orgname: string, table: string, orgtable: string, def: string, db: string, catalog: "def", max_length: 0, length: int, charsetnr: string, flags: int, type: int, decimals: int})|false', 'result' => 'mysqli_result', 'fieldnr' => 'int'], 'mysqli_fetch_fields' => ['list', 'result' => 'mysqli_result'], 'mysqli_result::fetch_field' => ['(stdClass&object{name: string, orgname: string, table: string, orgtable: string, def: string, db: string, catalog: "def", max_length: 0, length: int, charsetnr: string, flags: int, type: int, decimals: int})|false'], 'mysqli_result::fetch_field_direct' => ['(stdClass&object{name: string, orgname: string, table: string, orgtable: string, def: string, db: string, catalog: "def", max_length: 0, length: int, charsetnr: string, flags: int, type: int, decimals: int})|false', 'fieldnr' => 'int'], 'mysqli_result::fetch_fields' => ['list'], 'UnitEnum::cases' => ['list']], 'old' => ['pg_escape_bytea' => ['string', 'connection' => 'resource', 'data' => 'string'], 'pg_escape_bytea\'1' => ['string', 'data' => 'string'], 'pg_escape_identifier' => ['string|false', 'connection' => 'resource', 'data' => 'string'], 'pg_escape_identifier\'1' => ['string', 'data' => 'string'], 'pg_escape_literal' => ['string|false', 'connection' => 'resource', 'data' => 'string'], 'pg_escape_literal\'1' => ['string', 'data' => 'string'], 'pg_escape_string' => ['string', 'connection' => 'resource', 'data' => 'string'], 'pg_escape_string\'1' => ['string', 'data' => 'string'], 'pg_execute' => ['resource|false', 'connection' => 'resource', 'stmtname' => 'string', 'params' => 'array'], 'pg_execute\'1' => ['resource|false', 'stmtname' => 'string', 'params' => 'array'], 'pg_fetch_object' => ['object|false', 'result' => '', 'row=' => '?int', 'result_type=' => 'int'], 'pg_fetch_object\'1' => ['object', 'result' => '', 'row=' => '?int', 'class_name=' => 'string', 'ctor_params=' => 'array'], 'pg_fetch_result' => ['', 'result' => '', 'field_name' => 'string|int'], 'pg_fetch_result\'1' => ['', 'result' => '', 'row_number' => 'int', 'field_name' => 'string|int'], 'pg_field_is_null' => ['int|false', 'result' => '', 'field_name_or_number' => 'string|int'], 'pg_field_is_null\'1' => ['int', 'result' => '', 'row' => 'int', 'field_name_or_number' => 'string|int'], 'pg_field_prtlen' => ['int|false', 'result' => '', 'field_name_or_number' => ''], 'pg_field_prtlen\'1' => ['int', 'result' => '', 'row' => 'int', 'field_name_or_number' => 'string|int'], 'pg_lo_export' => ['bool', 'connection' => 'resource', 'oid' => 'int', 'filename' => 'string'], 'pg_lo_export\'1' => ['bool', 'oid' => 'int', 'pathname' => 'string'], 'pg_lo_import' => ['int|false', 'connection' => 'resource', 'pathname' => 'string', 'oid' => ''], 'pg_lo_import\'1' => ['int', 'pathname' => 'string', 'oid' => ''], 'pg_parameter_status' => ['string|false', 'connection' => 'resource', 'param_name' => 'string'], 'pg_parameter_status\'1' => ['string|false', 'param_name' => 'string'], 'pg_prepare' => ['resource|false', 'connection' => 'resource', 'stmtname' => 'string', 'query' => 'string'], 'pg_prepare\'1' => ['resource|false', 'stmtname' => 'string', 'query' => 'string'], 'pg_put_line' => ['bool', 'connection' => 'resource', 'data' => 'string'], 'pg_put_line\'1' => ['bool', 'data' => 'string'], 'pg_query' => ['resource|false', 'connection' => 'resource', 'query' => 'string'], 'pg_query\'1' => ['resource|false', 'query' => 'string'], 'pg_query_params' => ['resource|false', 'connection' => 'resource', 'query' => 'string', 'params' => 'array'], 'pg_query_params\'1' => ['resource|false', 'query' => 'string', 'params' => 'array'], 'pg_set_client_encoding' => ['int', 'connection' => 'resource', 'encoding' => 'string'], 'pg_set_client_encoding\'1' => ['int', 'encoding' => 'string'], 'pg_set_error_verbosity' => ['int|false', 'connection' => 'resource', 'verbosity' => 'int'], 'pg_set_error_verbosity\'1' => ['int', 'verbosity' => 'int'], 'pg_tty' => ['string', 'connection=' => 'resource'], 'pg_tty\'1' => ['string'], 'pg_untrace' => ['bool', 'connection=' => 'resource'], 'pg_untrace\'1' => ['bool']]]; path = $path; } } container = $container; } public function getRegistry() : OperatorTypeSpecifyingExtensionRegistry { if ($this->registry === null) { $this->registry = new OperatorTypeSpecifyingExtensionRegistry($this->container->getByType(Broker::class), $this->container->getServicesByTag(BrokerFactory::OPERATOR_TYPE_SPECIFYING_EXTENSION_TAG)); } return $this->registry; } } container = $container; } public function getFunctionParameterClosureTypeExtensions() : array { return $this->container->getServicesByTag(self::FUNCTION_TAG); } public function getMethodParameterClosureTypeExtensions() : array { return $this->container->getServicesByTag(self::METHOD_TAG); } public function getStaticMethodParameterClosureTypeExtensions() : array { return $this->container->getServicesByTag(self::STATIC_METHOD_TAG); } } container = $container; } public function getDynamicFunctionThrowTypeExtensions() : array { return $this->container->getServicesByTag(self::FUNCTION_TAG); } public function getDynamicMethodThrowTypeExtensions() : array { return $this->container->getServicesByTag(self::METHOD_TAG); } public function getDynamicStaticMethodThrowTypeExtensions() : array { return $this->container->getServicesByTag(self::STATIC_METHOD_TAG); } } container = $container; } public function getFunctionParameterOutTypeExtensions() : array { return $this->container->getServicesByTag(self::FUNCTION_TAG); } public function getMethodParameterOutTypeExtensions() : array { return $this->container->getServicesByTag(self::METHOD_TAG); } public function getStaticMethodParameterOutTypeExtensions() : array { return $this->container->getServicesByTag(self::STATIC_METHOD_TAG); } } container = $container; } public function getRegistry() : ExpressionTypeResolverExtensionRegistry { if ($this->registry === null) { $this->registry = new ExpressionTypeResolverExtensionRegistry($this->container->getServicesByTag(BrokerFactory::EXPRESSION_TYPE_RESOLVER_EXTENSION_TAG)); } return $this->registry; } } container = $container; } public function getRegistry() : DynamicReturnTypeExtensionRegistry { if ($this->registry === null) { $this->registry = new DynamicReturnTypeExtensionRegistry($this->container->getByType(Broker::class), $this->container->getByType(ReflectionProvider::class), $this->container->getServicesByTag(BrokerFactory::DYNAMIC_METHOD_RETURN_TYPE_EXTENSION_TAG), $this->container->getServicesByTag(BrokerFactory::DYNAMIC_STATIC_METHOD_RETURN_TYPE_EXTENSION_TAG), $this->container->getServicesByTag(BrokerFactory::DYNAMIC_FUNCTION_RETURN_TYPE_EXTENSION_TAG)); } return $this->registry; } } process((array) Neon::decode($contents), '', $file); } catch (Exception $e) { throw new Exception(sprintf('Error while loading %s: %s', $file, $e->getMessage())); } } /** * @param mixed[] $arr * @return mixed[] */ public function process(array $arr, string $fileKey, string $file) : array { $res = []; foreach ($arr as $key => $val) { if (is_string($key) && substr($key, -1) === self::PREVENT_MERGING_SUFFIX) { if (!is_array($val) && $val !== null) { throw new InvalidConfigurationException(sprintf('Replacing operator is available only for arrays, item \'%s\' is not array.', $key)); } $key = substr($key, 0, -1); $val[Helpers::PREVENT_MERGING] = \true; } $keyToResolve = $fileKey; if (is_int($key)) { $keyToResolve .= '[]'; } else { $keyToResolve .= '[' . $key . ']'; } if (is_array($val)) { if (!is_int($key)) { $fileKeyToPass = $fileKey . '[' . $key . ']'; } else { $fileKeyToPass = $fileKey . '[]'; } $val = $this->process($val, $fileKeyToPass, $file); } elseif ($val instanceof Entity) { if (!is_int($key)) { $fileKeyToPass = $fileKey . '(' . $key . ')'; } else { $fileKeyToPass = $fileKey . '()'; } if ($val->value === Neon::CHAIN) { $tmp = null; foreach ($this->process($val->attributes, $fileKeyToPass, $file) as $st) { $tmp = new Statement($tmp === null ? $st->getEntity() : [$tmp, ltrim(implode('::', (array) $st->getEntity()), ':')], $st->arguments); } $val = $tmp; } else { if (in_array($keyToResolve, ['[parameters][excludePaths][]', '[parameters][excludePaths][analyse][]', '[parameters][excludePaths][analyseAndScan][]'], \true) && count($val->attributes) === 1 && $val->attributes[0] === '?' && is_string($val->value) && !str_contains($val->value, '%') && !str_starts_with($val->value, '*')) { $fileHelper = $this->createFileHelperByFile($file); $val = new OptionalPath($fileHelper->normalizePath($fileHelper->absolutizePath($val->value))); } else { $tmp = $this->process([$val->value], $fileKeyToPass, $file); $val = new Statement($tmp[0], $this->process($val->attributes, $fileKeyToPass, $file)); } } } if (in_array($keyToResolve, ['[parameters][paths][]', '[parameters][excludes_analyse][]', '[parameters][excludePaths][]', '[parameters][excludePaths][analyse][]', '[parameters][excludePaths][analyseAndScan][]', '[parameters][ignoreErrors][][paths][]', '[parameters][ignoreErrors][][path]', '[parameters][bootstrapFiles][]', '[parameters][scanFiles][]', '[parameters][scanDirectories][]', '[parameters][tmpDir]', '[parameters][pro][tmpDir]', '[parameters][memoryLimitFile]', '[parameters][benchmarkFile]', '[parameters][stubFiles][]', '[parameters][symfony][console_application_loader]', '[parameters][symfony][consoleApplicationLoader]', '[parameters][symfony][container_xml_path]', '[parameters][symfony][containerXmlPath]', '[parameters][doctrine][objectManagerLoader]'], \true) && is_string($val) && !str_contains($val, '%') && !str_starts_with($val, '*')) { $fileHelper = $this->createFileHelperByFile($file); $val = $fileHelper->normalizePath($fileHelper->absolutizePath($val)); } if ($keyToResolve === '[parameters][excludePaths]' && $val !== null && array_values($val) === $val) { $val = ['analyseAndScan' => $val, 'analyse' => []]; } $res[$key] = $val; } return $res; } /** * @param mixed[] $data */ public function dump(array $data) : string { array_walk_recursive($data, static function (&$val) : void { if (!$val instanceof Statement) { return; } $val = self::statementToEntity($val); }); return "# generated by Nette\n\n" . Neon::encode($data, Neon::BLOCK); } private static function statementToEntity(Statement $val) : Entity { array_walk_recursive($val->arguments, static function (&$val) : void { if ($val instanceof Statement) { $val = self::statementToEntity($val); } elseif ($val instanceof Reference) { $val = '@' . $val->getValue(); } }); $entity = $val->getEntity(); if ($entity instanceof Reference) { $entity = '@' . $entity->getValue(); } elseif (is_array($entity)) { if ($entity[0] instanceof Statement) { return new Entity(Neon::CHAIN, [self::statementToEntity($entity[0]), new Entity('::' . $entity[1], $val->arguments)]); } elseif ($entity[0] instanceof Reference) { $entity = '@' . $entity[0]->getValue() . '::' . $entity[1]; } elseif (is_string($entity[0])) { $entity = $entity[0] . '::' . $entity[1]; } } return new Entity($entity, $val->arguments); } private function createFileHelperByFile(string $file) : FileHelper { $dir = dirname($file); if (!isset($this->fileHelpers[$dir])) { $this->fileHelpers[$dir] = new FileHelper($dir); } return $this->fileHelpers[$dir]; } } $bool, BrokerFactory::METHODS_CLASS_REFLECTION_EXTENSION_TAG => $bool, BrokerFactory::DYNAMIC_METHOD_RETURN_TYPE_EXTENSION_TAG => $bool, BrokerFactory::DYNAMIC_STATIC_METHOD_RETURN_TYPE_EXTENSION_TAG => $bool, BrokerFactory::DYNAMIC_FUNCTION_RETURN_TYPE_EXTENSION_TAG => $bool, BrokerFactory::EXPRESSION_TYPE_RESOLVER_EXTENSION_TAG => $bool, BrokerFactory::OPERATOR_TYPE_SPECIFYING_EXTENSION_TAG => $bool, BrokerFactory::ALLOWED_SUB_TYPES_CLASS_REFLECTION_EXTENSION_TAG => $bool, LazyRegistry::RULE_TAG => $bool, TypeNodeResolverExtension::EXTENSION_TAG => $bool, StubFilesExtension::EXTENSION_TAG => $bool, AlwaysUsedClassConstantsExtensionProvider::EXTENSION_TAG => $bool, ReadWritePropertiesExtensionProvider::EXTENSION_TAG => $bool, TypeSpecifierFactory::FUNCTION_TYPE_SPECIFYING_EXTENSION_TAG => $bool, TypeSpecifierFactory::METHOD_TYPE_SPECIFYING_EXTENSION_TAG => $bool, TypeSpecifierFactory::STATIC_METHOD_TYPE_SPECIFYING_EXTENSION_TAG => $bool, RichParser::VISITOR_SERVICE_TAG => $bool, CollectorRegistryFactory::COLLECTOR_TAG => $bool, LazyDynamicThrowTypeExtensionProvider::FUNCTION_TAG => $bool, LazyDynamicThrowTypeExtensionProvider::METHOD_TAG => $bool, LazyDynamicThrowTypeExtensionProvider::STATIC_METHOD_TAG => $bool, LazyParameterClosureTypeExtensionProvider::FUNCTION_TAG => $bool, LazyParameterClosureTypeExtensionProvider::METHOD_TAG => $bool, LazyParameterClosureTypeExtensionProvider::STATIC_METHOD_TAG => $bool, LazyParameterOutTypeExtensionProvider::FUNCTION_TAG => $bool, LazyParameterOutTypeExtensionProvider::METHOD_TAG => $bool, LazyParameterOutTypeExtensionProvider::STATIC_METHOD_TAG => $bool, DiagnoseExtension::EXTENSION_TAG => $bool])->min(1)); } public function beforeCompile() : void { /** @var mixed[] $config */ $config = $this->config; $builder = $this->getContainerBuilder(); foreach ($config as $type => $tags) { $services = $builder->findByType($type); if (count($services) === 0) { throw new ShouldNotHappenException(sprintf('No services of type "%s" found.', $type)); } foreach ($services as $service) { foreach ($tags as $tag => $parameter) { if (is_array($parameter)) { $parameter = array_reduce($parameter, static function ($carry, $item) { return $carry && (bool) $item; }, \true); } if ((bool) $parameter) { $service->addTag($tag); continue; } } } } } } currentWorkingDirectory = $currentWorkingDirectory; $this->tempDirectory = $tempDirectory; $this->additionalConfigFiles = $additionalConfigFiles; $this->analysedPaths = $analysedPaths; $this->composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; $this->analysedPathsFromConfig = $analysedPathsFromConfig; $this->usedLevel = $usedLevel; $this->generateBaselineFile = $generateBaselineFile; $this->cliAutoloadFile = $cliAutoloadFile; $this->singleReflectionFile = $singleReflectionFile; $this->singleReflectionInsteadOfFile = $singleReflectionInsteadOfFile; } /** * @param string[] $additionalConfigFiles */ public function create(array $additionalConfigFiles) : \PHPStan\DependencyInjection\Container { $containerFactory = new \PHPStan\DependencyInjection\ContainerFactory($this->currentWorkingDirectory); return $containerFactory->create($this->tempDirectory, array_merge($this->additionalConfigFiles, $additionalConfigFiles), $this->analysedPaths, $this->composerAutoloaderProjectPaths, $this->analysedPathsFromConfig, $this->usedLevel, $this->generateBaselineFile, $this->cliAutoloadFile, $this->singleReflectionFile, $this->singleReflectionInsteadOfFile); } } container = $container; } public function hasService(string $serviceName) : bool { return $this->container->hasService($serviceName); } /** * @return mixed */ public function getService(string $serviceName) { return $this->container->getService($serviceName); } /** * @template T of object * @param class-string $className * @return T */ public function getByType(string $className) { return $this->container->getByType($className); } /** * @param class-string $className * @return string[] */ public function findServiceNamesByType(string $className) : array { return $this->container->findByType($className); } /** * @return mixed[] */ public function getServicesByTag(string $tagName) : array { return $this->tagsToServices($this->container->findByTag($tagName)); } /** * @return mixed[] */ public function getParameters() : array { return $this->container->getParameters(); } public function hasParameter(string $parameterName) : bool { return array_key_exists($parameterName, $this->container->getParameters()); } /** * @return mixed */ public function getParameter(string $parameterName) { if (!$this->hasParameter($parameterName)) { throw new ParameterNotFoundException($parameterName); } return $this->container->getParameter($parameterName); } /** * @param mixed[] $tags * @return mixed[] */ private function tagsToServices(array $tags) : array { return array_map(function (string $serviceName) { return $this->getService($serviceName); }, array_keys($tags)); } } fileHelper = $fileHelper; $this->rootDir = $rootDir; $this->currentWorkingDirectory = $currentWorkingDirectory; $this->generateBaselineFile = $generateBaselineFile; } public function createLoader() : Loader { $loader = new \PHPStan\DependencyInjection\NeonLoader($this->fileHelper, $this->generateBaselineFile); $loader->addAdapter('dist', \PHPStan\DependencyInjection\NeonAdapter::class); $loader->addAdapter('neon', \PHPStan\DependencyInjection\NeonAdapter::class); $loader->setParameters(['rootDir' => $this->rootDir, 'currentWorkingDirectory' => $this->currentWorkingDirectory, 'env' => getenv()]); return $loader; } } files = $files; parent::__construct(sprintf('These files are included multiple times: %s', implode(', ', $this->files))); } /** * @return string[] */ public function getFiles() : array { return $this->files; } } container = $container; } public function getRegistry() : ClassReflectionExtensionRegistry { if ($this->registry === null) { $phpClassReflectionExtension = $this->container->getByType(PhpClassReflectionExtension::class); $annotationsMethodsClassReflectionExtension = $this->container->getByType(AnnotationsMethodsClassReflectionExtension::class); $annotationsPropertiesClassReflectionExtension = $this->container->getByType(AnnotationsPropertiesClassReflectionExtension::class); $mixinMethodsClassReflectionExtension = $this->container->getByType(MixinMethodsClassReflectionExtension::class); $mixinPropertiesClassReflectionExtension = $this->container->getByType(MixinPropertiesClassReflectionExtension::class); $soapClientMethodsClassReflectionExtension = $this->container->getByType(SoapClientMethodsClassReflectionExtension::class); $this->registry = new ClassReflectionExtensionRegistry($this->container->getByType(Broker::class), array_merge([$phpClassReflectionExtension], $this->container->getServicesByTag(BrokerFactory::PROPERTIES_CLASS_REFLECTION_EXTENSION_TAG), [$annotationsPropertiesClassReflectionExtension, $mixinPropertiesClassReflectionExtension]), array_merge([$phpClassReflectionExtension], $this->container->getServicesByTag(BrokerFactory::METHODS_CLASS_REFLECTION_EXTENSION_TAG), [$annotationsMethodsClassReflectionExtension, $mixinMethodsClassReflectionExtension, $soapClientMethodsClassReflectionExtension]), $this->container->getServicesByTag(BrokerFactory::ALLOWED_SUB_TYPES_CLASS_REFLECTION_EXTENSION_TAG), $this->container->getByType(RequireExtendsPropertiesClassReflectionExtension::class), $this->container->getByType(RequireExtendsMethodsClassReflectionExtension::class)); } return $this->registry; } } min(1); } } currentWorkingDirectory = $currentWorkingDirectory; $this->checkDuplicateFiles = $checkDuplicateFiles; $this->fileHelper = new FileHelper($currentWorkingDirectory); $rootDir = __DIR__ . '/../..'; $originalRootDir = $this->fileHelper->normalizePath($rootDir); if (extension_loaded('phar')) { $pharPath = Phar::running(\false); if ($pharPath !== '') { $rootDir = dirname($pharPath); } } $this->rootDirectory = $this->fileHelper->normalizePath($rootDir); $this->configDirectory = $originalRootDir . '/conf'; } /** * @param string[] $additionalConfigFiles * @param string[] $analysedPaths * @param string[] $composerAutoloaderProjectPaths * @param string[] $analysedPathsFromConfig */ public function create(string $tempDirectory, array $additionalConfigFiles, array $analysedPaths, array $composerAutoloaderProjectPaths = [], array $analysedPathsFromConfig = [], string $usedLevel = CommandHelper::DEFAULT_LEVEL, ?string $generateBaselineFile = null, ?string $cliAutoloadFile = null, ?string $singleReflectionFile = null, ?string $singleReflectionInsteadOfFile = null) : \PHPStan\DependencyInjection\Container { [$allConfigFiles, $projectConfig] = $this->detectDuplicateIncludedFiles(array_merge([__DIR__ . '/../../conf/parametersSchema.neon'], $additionalConfigFiles), ['rootDir' => $this->rootDirectory, 'currentWorkingDirectory' => $this->currentWorkingDirectory, 'env' => getenv()]); $configurator = new \PHPStan\DependencyInjection\Configurator(new \PHPStan\DependencyInjection\LoaderFactory($this->fileHelper, $this->rootDirectory, $this->currentWorkingDirectory, $generateBaselineFile)); $configurator->defaultExtensions = ['php' => PhpExtension::class, 'extensions' => ExtensionsExtension::class]; $configurator->setDebugMode(\true); $configurator->setTempDirectory($tempDirectory); $configurator->addParameters(['rootDir' => $this->rootDirectory, 'currentWorkingDirectory' => $this->currentWorkingDirectory, 'cliArgumentsVariablesRegistered' => ini_get('register_argc_argv') === '1', 'tmpDir' => $tempDirectory, 'additionalConfigFiles' => $additionalConfigFiles, 'allConfigFiles' => $allConfigFiles, 'composerAutoloaderProjectPaths' => $composerAutoloaderProjectPaths, 'generateBaselineFile' => $generateBaselineFile, 'usedLevel' => $usedLevel, 'cliAutoloadFile' => $cliAutoloadFile]); $configurator->addDynamicParameters(['singleReflectionFile' => $singleReflectionFile, 'singleReflectionInsteadOfFile' => $singleReflectionInsteadOfFile, 'analysedPaths' => $analysedPaths, 'analysedPathsFromConfig' => $analysedPathsFromConfig, 'env' => getenv()]); $configurator->addConfig($this->configDirectory . '/config.neon'); foreach ($additionalConfigFiles as $additionalConfigFile) { $configurator->addConfig($additionalConfigFile); } $configurator->setAllConfigFiles($allConfigFiles); $container = $configurator->createContainer()->getByType(\PHPStan\DependencyInjection\Container::class); $this->validateParameters($container->getParameters(), $projectConfig['parametersSchema']); self::postInitializeContainer($container); return $container; } /** @internal */ public static function postInitializeContainer(\PHPStan\DependencyInjection\Container $container) : void { $containerId = spl_object_id($container); if ($containerId === self::$lastInitializedContainerId) { return; } self::$lastInitializedContainerId = $containerId; /** @var SourceLocator $sourceLocator */ $sourceLocator = $container->getService('betterReflectionSourceLocator'); /** @var Reflector $reflector */ $reflector = $container->getService('betterReflectionReflector'); /** @var Parser $phpParser */ $phpParser = $container->getService('phpParserDecorator'); BetterReflection::populate($container->getByType(PhpVersion::class)->getVersionId(), $sourceLocator, $reflector, $phpParser, $container->getByType(PhpStormStubsSourceStubber::class), $container->getByType(Printer::class)); $broker = $container->getByType(Broker::class); Broker::registerInstance($broker); ReflectionProviderStaticAccessor::registerInstance($container->getByType(ReflectionProvider::class)); PhpVersionStaticAccessor::registerInstance($container->getByType(PhpVersion::class)); ObjectType::resetCaches(); $container->getService('typeSpecifier'); \PHPStan\DependencyInjection\BleedingEdgeToggle::setBleedingEdge($container->getParameter('featureToggles')['bleedingEdge']); AccessoryArrayListType::setListTypeEnabled($container->getParameter('featureToggles')['listType']); TemplateTypeVariance::setInvarianceCompositionEnabled($container->getParameter('featureToggles')['invarianceComposition']); } public function clearOldContainers(string $tempDirectory) : void { $configurator = new \PHPStan\DependencyInjection\Configurator(new \PHPStan\DependencyInjection\LoaderFactory($this->fileHelper, $this->rootDirectory, $this->currentWorkingDirectory, null)); $configurator->setDebugMode(\true); $configurator->setTempDirectory($tempDirectory); $containerDirectory = $configurator->getContainerCacheDirectory(); if (!is_dir($containerDirectory)) { return; } $finder = new Finder(); $finder->name('Container_*')->in($containerDirectory); $twoDaysAgo = time() - 24 * 60 * 60 * 2; foreach ($finder as $containerFile) { $path = $containerFile->getRealPath(); if ($path === \false) { continue; } if ($containerFile->getATime() > $twoDaysAgo) { continue; } if ($containerFile->getCTime() > $twoDaysAgo) { continue; } @unlink($path); } } public function getCurrentWorkingDirectory() : string { return $this->currentWorkingDirectory; } public function getRootDirectory() : string { return $this->rootDirectory; } public function getConfigDirectory() : string { return $this->configDirectory; } /** * @param string[] $configFiles * @param array $loaderParameters * @return array{list, array} * @throws DuplicateIncludedFilesException */ private function detectDuplicateIncludedFiles(array $configFiles, array $loaderParameters) : array { $neonAdapter = new \PHPStan\DependencyInjection\NeonAdapter(); $phpAdapter = new PhpAdapter(); $allConfigFiles = []; $configArray = []; foreach ($configFiles as $configFile) { [$tmpConfigFiles, $tmpConfigArray] = self::getConfigFiles($this->fileHelper, $neonAdapter, $phpAdapter, $configFile, $loaderParameters, null); $allConfigFiles = array_merge($allConfigFiles, $tmpConfigFiles); /** @var array $configArray */ $configArray = \_PHPStan_c2fbb2235\Nette\Schema\Helpers::merge($tmpConfigArray, $configArray); } $normalized = array_map(function (string $file) : string { return $this->fileHelper->normalizePath($file); }, $allConfigFiles); $deduplicated = array_unique($normalized); if (count($normalized) <= count($deduplicated)) { return [$normalized, $configArray]; } if (!$this->checkDuplicateFiles) { return [$normalized, $configArray]; } $duplicateFiles = array_unique(array_diff_key($normalized, $deduplicated)); throw new \PHPStan\DependencyInjection\DuplicateIncludedFilesException($duplicateFiles); } /** * @param array $loaderParameters * @return array{list, array} */ private static function getConfigFiles(FileHelper $fileHelper, \PHPStan\DependencyInjection\NeonAdapter $neonAdapter, PhpAdapter $phpAdapter, string $configFile, array $loaderParameters, ?string $generateBaselineFile) : array { if ($generateBaselineFile === $fileHelper->normalizePath($configFile)) { return [[], []]; } if (!is_file($configFile) || !is_readable($configFile)) { return [[], []]; } if (str_ends_with($configFile, '.php')) { $data = $phpAdapter->load($configFile); } else { $data = $neonAdapter->load($configFile); } $allConfigFiles = [$configFile]; if (isset($data['includes'])) { Validators::assert($data['includes'], 'list', sprintf("section 'includes' in file '%s'", $configFile)); $includes = Helpers::expand($data['includes'], $loaderParameters); foreach ($includes as $include) { $include = self::expandIncludedFile($include, $configFile); [$tmpConfigFiles, $tmpConfigArray] = self::getConfigFiles($fileHelper, $neonAdapter, $phpAdapter, $include, $loaderParameters, $generateBaselineFile); $allConfigFiles = array_merge($allConfigFiles, $tmpConfigFiles); /** @var array $data */ $data = \_PHPStan_c2fbb2235\Nette\Schema\Helpers::merge($tmpConfigArray, $data); } } return [$allConfigFiles, $data]; } private static function expandIncludedFile(string $includedFile, string $mainFile) : string { return Strings::match($includedFile, '#([a-z]+:)?[/\\\\]#Ai') !== null ? $includedFile : dirname($mainFile) . '/' . $includedFile; } /** * @param array $parameters * @param array $parametersSchema */ private function validateParameters(array $parameters, array $parametersSchema) : void { if (!(bool) $parameters['__validate']) { return; } $schema = $this->processArgument(new Statement('schema', [new Statement('structure', [$parametersSchema])])); $processor = new Processor(); $processor->onNewContext[] = static function (SchemaContext $context) : void { $context->path = ['parameters']; }; $processor->process($schema, $parameters); } /** * @param Statement[] $statements */ private function processSchema(array $statements, bool $required = \true) : Schema { if (count($statements) === 0) { throw new ShouldNotHappenException(); } $parameterSchema = null; foreach ($statements as $statement) { $processedArguments = array_map(function ($argument) { return $this->processArgument($argument); }, $statement->arguments); if ($parameterSchema === null) { /** @var Type|AnyOf|Structure $parameterSchema */ $parameterSchema = Expect::{$statement->getEntity()}(...$processedArguments); } else { $parameterSchema->{$statement->getEntity()}(...$processedArguments); } } if ($required) { $parameterSchema->required(); } return $parameterSchema; } /** * @param mixed $argument * @return mixed */ private function processArgument($argument, bool $required = \true) { if ($argument instanceof Statement) { if ($argument->entity === 'schema') { $arguments = []; foreach ($argument->arguments as $schemaArgument) { if (!$schemaArgument instanceof Statement) { throw new ShouldNotHappenException('schema() should contain another statement().'); } $arguments[] = $schemaArgument; } if (count($arguments) === 0) { throw new ShouldNotHappenException('schema() should have at least one argument.'); } return $this->processSchema($arguments, $required); } return $this->processSchema([$argument], $required); } elseif (is_array($argument)) { $processedArray = []; foreach ($argument as $key => $val) { $required = $key[0] !== '?'; $key = $required ? $key : substr($key, 1); $processedArray[$key] = $this->processArgument($val, $required); } return $processedArray; } return $argument; } } fileHelper = $fileHelper; $this->generateBaselineFile = $generateBaselineFile; } /** * @return mixed[] */ public function load(string $file, ?bool $merge = \true) : array { if ($this->generateBaselineFile === null) { return parent::load($file, $merge); } $normalizedFile = $this->fileHelper->normalizePath($file); if ($this->generateBaselineFile === $normalizedFile) { return []; } return parent::load($file, $merge); } } $projectConfig * @return list */ public static function getServiceClassNames(array $projectConfig) : array { $services = array_merge($projectConfig['services'] ?? [], $projectConfig['rules'] ?? []); $classes = []; foreach ($services as $service) { $classes = array_merge($classes, self::getClassesFromConfigDefinition($service)); if (!is_array($service)) { continue; } foreach (['class', 'factory', 'implement'] as $key) { if (!isset($service[$key])) { continue; } $classes = array_merge($classes, self::getClassesFromConfigDefinition($service[$key])); } } return array_values(array_unique($classes)); } /** * @param mixed $definition * @return string[] */ private static function getClassesFromConfigDefinition($definition) : array { if (is_string($definition)) { return [$definition]; } if ($definition instanceof Statement) { $entity = $definition->entity; if (is_string($entity)) { return [$entity]; } elseif (is_array($entity) && isset($entity[0]) && is_string($entity[0])) { return [$entity[0]]; } } return []; } } errors = $errors; parent::__construct(implode("\n", $this->errors)); } /** * @return string[] */ public function getErrors() : array { return $this->errors; } } */ private $servicesByType = []; public function __construct(\PHPStan\DependencyInjection\Container $originalContainer) { $this->originalContainer = $originalContainer; } public function hasService(string $serviceName) : bool { return $this->originalContainer->hasService($serviceName); } public function getService(string $serviceName) { return $this->originalContainer->getService($serviceName); } public function getByType(string $className) { if (array_key_exists($className, $this->servicesByType)) { return $this->servicesByType[$className]; } $service = $this->originalContainer->getByType($className); $this->servicesByType[$className] = $service; return $service; } public function findServiceNamesByType(string $className) : array { return $this->originalContainer->findServiceNamesByType($className); } public function getServicesByTag(string $tagName) : array { return $this->originalContainer->getServicesByTag($tagName); } public function getParameters() : array { return $this->originalContainer->getParameters(); } public function hasParameter(string $parameterName) : bool { return $this->originalContainer->hasParameter($parameterName); } public function getParameter(string $parameterName) { return $this->originalContainer->getParameter($parameterName); } } loaderFactory = $loaderFactory; parent::__construct(); } protected function createLoader() : Loader { return $this->loaderFactory->createLoader(); } /** * @param string[] $allConfigFiles */ public function setAllConfigFiles(array $allConfigFiles) : void { $this->allConfigFiles = $allConfigFiles; } /** * @return mixed[] */ protected function getDefaultParameters() : array { return []; } public function getContainerCacheDirectory() : string { return $this->getCacheDirectory() . '/nette.configurator'; } public function loadContainer() : string { $loader = new ContainerLoader($this->getContainerCacheDirectory(), $this->staticParameters['debugMode']); return $loader->load([$this, 'generateContainer'], [$this->staticParameters, array_keys($this->dynamicParameters), $this->configs, PHP_VERSION_ID - PHP_RELEASE_VERSION, \PHPStan\DependencyInjection\NeonAdapter::CACHE_KEY, $this->getAllConfigFilesHashes()]); } public function createContainer(bool $initialize = \true) : OriginalNetteContainer { set_error_handler(static function (int $errno) : bool { if ((error_reporting() & $errno) === 0) { // silence @ operator return \true; } return $errno === E_USER_DEPRECATED; }); try { $container = parent::createContainer($initialize); } finally { restore_error_handler(); } return $container; } /** * @return string[] */ private function getAllConfigFilesHashes() : array { $hashes = []; foreach ($this->allConfigFiles as $file) { $hash = sha1_file($file); if ($hash === \false) { throw new CouldNotReadFileException($file); } $hashes[$file] = $hash; } return $hashes; } } errors = $errors; parent::__construct(implode("\n", $this->errors)); } /** * @return string[] */ public function getErrors() : array { return $this->errors; } } getContainerBuilder(); if (!$builder->parameters['__validate']) { return; } $ignoreErrors = $builder->parameters['ignoreErrors']; if (count($ignoreErrors) === 0) { return; } $noImplicitWildcard = $builder->parameters['featureToggles']['noImplicitWildcard']; /** @throws void */ $parser = Llk::load(new Read(__DIR__ . '/../../resources/RegexGrammar.pp')); $reflectionProvider = new DummyReflectionProvider(); $reflectionProviderProvider = new DirectReflectionProviderProvider($reflectionProvider); ReflectionProviderStaticAccessor::registerInstance($reflectionProvider); PhpVersionStaticAccessor::registerInstance(new PhpVersion(PHP_VERSION_ID)); $constantResolver = new ConstantResolver($reflectionProviderProvider, []); $ignoredRegexValidator = new IgnoredRegexValidator($parser, new TypeStringResolver(new Lexer(), new TypeParser(new ConstExprParser($builder->parameters['featureToggles']['unescapeStrings'])), new TypeNodeResolver(new DirectTypeNodeResolverExtensionRegistryProvider(new class implements TypeNodeResolverExtensionRegistry { public function getExtensions() : array { return []; } }), $reflectionProviderProvider, new DirectTypeAliasResolverProvider(new class implements TypeAliasResolver { public function hasTypeAlias(string $aliasName, ?string $classNameScope) : bool { return \false; } public function resolveTypeAlias(string $aliasName, NameScope $nameScope) : ?Type { return null; } }), $constantResolver, new InitializerExprTypeResolver($constantResolver, $reflectionProviderProvider, new PhpVersion(PHP_VERSION_ID), new class implements OperatorTypeSpecifyingExtensionRegistryProvider { public function getRegistry() : OperatorTypeSpecifyingExtensionRegistry { return new OperatorTypeSpecifyingExtensionRegistry(null, []); } }, new OversizedArrayBuilder())))); $errors = []; foreach ($ignoreErrors as $ignoreError) { if (is_array($ignoreError)) { if (isset($ignoreError['count'])) { continue; // ignoreError coming from baseline will be correct } if (isset($ignoreError['messages'])) { $ignoreMessages = $ignoreError['messages']; } elseif (isset($ignoreError['message'])) { $ignoreMessages = [$ignoreError['message']]; } else { continue; } } else { $ignoreMessages = [$ignoreError]; } foreach ($ignoreMessages as $ignoreMessage) { $error = $this->validateMessage($ignoredRegexValidator, $ignoreMessage); if ($error === null) { continue; } $errors[] = $error; } } $reportUnmatched = (bool) $builder->parameters['reportUnmatchedIgnoredErrors']; if ($noImplicitWildcard && $reportUnmatched) { foreach ($ignoreErrors as $ignoreError) { if (!is_array($ignoreError)) { continue; } if (isset($ignoreError['path'])) { $ignorePaths = [$ignoreError['path']]; } elseif (isset($ignoreError['paths'])) { $ignorePaths = $ignoreError['paths']; } else { continue; } foreach ($ignorePaths as $ignorePath) { if (FileExcluder::isAbsolutePath($ignorePath)) { if (is_dir($ignorePath)) { continue; } if (is_file($ignorePath)) { continue; } } if (FileExcluder::isFnmatchPattern($ignorePath)) { continue; } $errors[] = sprintf('Path %s is neither a directory, nor a file path, nor a fnmatch pattern.', $ignorePath); } } } if (count($errors) === 0) { return; } throw new \PHPStan\DependencyInjection\InvalidIgnoredErrorPatternsException($errors); } private function validateMessage(IgnoredRegexValidator $ignoredRegexValidator, string $ignoreMessage) : ?string { try { Strings::match('', $ignoreMessage); $validationResult = $ignoredRegexValidator->validate($ignoreMessage); $ignoredTypes = $validationResult->getIgnoredTypes(); if (count($ignoredTypes) > 0) { return $this->createIgnoredTypesError($ignoreMessage, $ignoredTypes); } if ($validationResult->hasAnchorsInTheMiddle()) { return $this->createAnchorInTheMiddleError($ignoreMessage); } if ($validationResult->areAllErrorsIgnored()) { return sprintf("Ignored error %s has an unescaped '%s' which leads to ignoring all errors. Use '%s' instead.", $ignoreMessage, $validationResult->getWrongSequence(), $validationResult->getEscapedWrongSequence()); } } catch (RegexpException $e) { return $e->getMessage(); } return null; } /** * @param array $ignoredTypes */ private function createIgnoredTypesError(string $regex, array $ignoredTypes) : string { return sprintf("Ignored error %s has an unescaped '|' which leads to ignoring more errors than intended. Use '\\|' instead.\n%s", $regex, sprintf("It ignores all errors containing the following types:\n%s", implode("\n", array_map(static function (string $typeDescription) : string { return sprintf('* %s', $typeDescription); }, array_keys($ignoredTypes))))); } private function createAnchorInTheMiddleError(string $regex) : string { return sprintf("Ignored error %s has an unescaped anchor '\$' in the middle. This leads to unintended behavior. Use '\\\$' instead.", $regex); } } $className * @return T */ public function getByType(string $className); /** * @param class-string $className * @return string[] */ public function findServiceNamesByType(string $className) : array; /** * @return mixed[] */ public function getServicesByTag(string $tagName) : array; /** * @return mixed[] */ public function getParameters() : array; public function hasParameter(string $parameterName) : bool; /** * @return mixed * @throws ParameterNotFoundException */ public function getParameter(string $parameterName); } getContainerBuilder(); $excludePaths = $builder->parameters['excludePaths']; if ($excludePaths === null) { return; } $errors = []; $noImplicitWildcard = $builder->parameters['featureToggles']['noImplicitWildcard']; if ($builder->parameters['__validate'] && $noImplicitWildcard) { $paths = []; if (array_key_exists('analyse', $excludePaths)) { $paths = $excludePaths['analyse']; } if (array_key_exists('analyseAndScan', $excludePaths)) { $paths = array_merge($paths, $excludePaths['analyseAndScan']); } foreach ($paths as $path) { if ($path instanceof OptionalPath) { continue; } if (FileExcluder::isAbsolutePath($path)) { if (is_dir($path)) { continue; } if (is_file($path)) { continue; } } if (FileExcluder::isFnmatchPattern($path)) { continue; } $errors[] = sprintf('Path %s is neither a directory, nor a file path, nor a fnmatch pattern.', $path); } } $newExcludePaths = []; if (array_key_exists('analyseAndScan', $excludePaths)) { $newExcludePaths['analyseAndScan'] = $excludePaths['analyseAndScan']; } if (array_key_exists('analyse', $excludePaths)) { $newExcludePaths['analyse'] = $excludePaths['analyse']; } foreach ($newExcludePaths as $key => $p) { $newExcludePaths[$key] = array_map(static function ($path) { return $path instanceof OptionalPath ? $path->path : $path; }, $p); } $builder->parameters['excludePaths'] = $newExcludePaths; if (count($errors) === 0) { return; } throw new \PHPStan\DependencyInjection\InvalidExcludePathsException($errors); } } config; $builder = $this->getContainerBuilder(); foreach ($config as $key => $rule) { $builder->addDefinition($this->prefix((string) $key))->setFactory($rule)->setAutowired($rule)->addTag(LazyRegistry::RULE_TAG); } } } parser = $parser; $this->visitor = $visitor; } /** * @return RootExportedNode[] */ public function fetchNodes(string $fileName) : array { $nodeTraverser = new NodeTraverser(); $nodeTraverser->addVisitor($this->visitor); try { $ast = $this->parser->parseFile($fileName); } catch (ParserErrorsException $e) { return []; } $this->visitor->reset($fileName); $nodeTraverser->traverse($ast); return $this->visitor->getExportedNodes(); } } exportedNodeResolver = $exportedNodeResolver; } public function reset(string $fileName) : void { $this->fileName = $fileName; $this->currentNodes = []; } /** * @return RootExportedNode[] */ public function getExportedNodes() : array { return $this->currentNodes; } public function enterNode(Node $node) : ?int { if ($this->fileName === null) { throw new ShouldNotHappenException(); } $exportedNode = $this->exportedNodeResolver->resolve($this->fileName, $node); if ($exportedNode !== null) { $this->currentNodes[] = $exportedNode; } if ($node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Stmt\Function_ || $node instanceof Node\Stmt\Trait_) { return NodeTraverser::DONT_TRAVERSE_CHILDREN; } return null; } } name = $name; $this->phpDoc = $phpDoc; $this->extends = $extends; $this->statements = $statements; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } if ($this->phpDoc === null) { if ($node->phpDoc !== null) { return \false; } } elseif ($node->phpDoc !== null) { if (!$this->phpDoc->equals($node->phpDoc)) { return \false; } } else { return \false; } if (count($this->statements) !== count($node->statements)) { return \false; } foreach ($this->statements as $i => $statement) { if ($statement->equals($node->statements[$i])) { continue; } return \false; } return $this->name === $node->name && $this->extends === $node->extends; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['name'], $properties['phpDoc'], $properties['extends'], $properties['statements']); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['name' => $this->name, 'phpDoc' => $this->phpDoc, 'extends' => $this->extends, 'statements' => $this->statements]]; } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['name'], $data['phpDoc'] !== null ? \PHPStan\Dependency\ExportedNode\ExportedPhpDocNode::decode($data['phpDoc']['data']) : null, $data['extends'], array_map(static function (array $node) : ExportedNode { $nodeType = $node['type']; return $nodeType::decode($node['data']); }, $data['statements'])); } /** * @return self::TYPE_INTERFACE */ public function getType() : string { return self::TYPE_INTERFACE; } public function getName() : string { return $this->name; } } name = $name; $this->phpDoc = $phpDoc; $this->abstract = $abstract; $this->final = $final; $this->extends = $extends; $this->implements = $implements; $this->usedTraits = $usedTraits; $this->traitUseAdaptations = $traitUseAdaptations; $this->statements = $statements; $this->attributes = $attributes; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } if ($this->phpDoc === null) { if ($node->phpDoc !== null) { return \false; } } elseif ($node->phpDoc !== null) { if (!$this->phpDoc->equals($node->phpDoc)) { return \false; } } else { return \false; } if (count($this->attributes) !== count($node->attributes)) { return \false; } foreach ($this->attributes as $i => $attribute) { if (!$attribute->equals($node->attributes[$i])) { return \false; } } if (count($this->traitUseAdaptations) !== count($node->traitUseAdaptations)) { return \false; } foreach ($this->traitUseAdaptations as $i => $ourTraitUseAdaptation) { $theirTraitUseAdaptation = $node->traitUseAdaptations[$i]; if (!$ourTraitUseAdaptation->equals($theirTraitUseAdaptation)) { return \false; } } if (count($this->statements) !== count($node->statements)) { return \false; } foreach ($this->statements as $i => $statement) { if ($statement->equals($node->statements[$i])) { continue; } return \false; } return $this->name === $node->name && $this->abstract === $node->abstract && $this->final === $node->final && $this->extends === $node->extends && $this->implements === $node->implements && $this->usedTraits === $node->usedTraits; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['name'], $properties['phpDoc'], $properties['abstract'], $properties['final'], $properties['extends'], $properties['implements'], $properties['usedTraits'], $properties['traitUseAdaptations'], $properties['statements'], $properties['attributes']); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['name' => $this->name, 'phpDoc' => $this->phpDoc, 'abstract' => $this->abstract, 'final' => $this->final, 'extends' => $this->extends, 'implements' => $this->implements, 'usedTraits' => $this->usedTraits, 'traitUseAdaptations' => $this->traitUseAdaptations, 'statements' => $this->statements, 'attributes' => $this->attributes]]; } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['name'], $data['phpDoc'] !== null ? \PHPStan\Dependency\ExportedNode\ExportedPhpDocNode::decode($data['phpDoc']['data']) : null, $data['abstract'], $data['final'], $data['extends'], $data['implements'], $data['usedTraits'], array_map(static function (array $traitUseAdaptationData) : \PHPStan\Dependency\ExportedNode\ExportedTraitUseAdaptation { if ($traitUseAdaptationData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedTraitUseAdaptation::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedTraitUseAdaptation::decode($traitUseAdaptationData['data']); }, $data['traitUseAdaptations']), array_map(static function (array $node) : ExportedNode { $nodeType = $node['type']; return $nodeType::decode($node['data']); }, $data['statements']), array_map(static function (array $attributeData) : \PHPStan\Dependency\ExportedNode\ExportedAttributeNode { if ($attributeData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::decode($attributeData['data']); }, $data['attributes'])); } /** * @return self::TYPE_CLASS */ public function getType() : string { return self::TYPE_CLASS; } public function getName() : string { return $this->name; } } name = $name; $this->value = $value; $this->attributes = $attributes; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } if (count($this->attributes) !== count($node->attributes)) { return \false; } foreach ($this->attributes as $i => $attribute) { if (!$attribute->equals($node->attributes[$i])) { return \false; } } return $this->name === $node->name && $this->value === $node->value; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['name'], $properties['value'], $properties['attributes']); } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['name'], $data['value'], array_map(static function (array $attributeData) : \PHPStan\Dependency\ExportedNode\ExportedAttributeNode { if ($attributeData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::decode($attributeData['data']); }, $data['attributes'])); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['name' => $this->name, 'value' => $this->value, 'attributes' => $this->attributes]]; } } name = $name; $this->value = $value; $this->phpDoc = $phpDoc; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } if ($this->phpDoc === null) { if ($node->phpDoc !== null) { return \false; } } elseif ($node->phpDoc !== null) { if (!$this->phpDoc->equals($node->phpDoc)) { return \false; } } else { return \false; } return $this->name === $node->name && $this->value === $node->value; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['name'], $properties['value'], $properties['phpDoc']); } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['name'], $data['value'], $data['phpDoc'] !== null ? \PHPStan\Dependency\ExportedNode\ExportedPhpDocNode::decode($data['phpDoc']['data']) : null); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['name' => $this->name, 'value' => $this->value, 'phpDoc' => $this->phpDoc]]; } } name = $name; $this->type = $type; $this->byRef = $byRef; $this->variadic = $variadic; $this->hasDefault = $hasDefault; $this->attributes = $attributes; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } if (count($this->attributes) !== count($node->attributes)) { return \false; } foreach ($this->attributes as $i => $attribute) { if (!$attribute->equals($node->attributes[$i])) { return \false; } } return $this->name === $node->name && $this->type === $node->type && $this->byRef === $node->byRef && $this->variadic === $node->variadic && $this->hasDefault === $node->hasDefault; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['name'], $properties['type'], $properties['byRef'], $properties['variadic'], $properties['hasDefault'], $properties['attributes']); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['name' => $this->name, 'type' => $this->type, 'byRef' => $this->byRef, 'variadic' => $this->variadic, 'hasDefault' => $this->hasDefault, 'attributes' => $this->attributes]]; } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['name'], $data['type'], $data['byRef'], $data['variadic'], $data['hasDefault'], array_map(static function (array $attributeData) : \PHPStan\Dependency\ExportedNode\ExportedAttributeNode { if ($attributeData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::decode($attributeData['data']); }, $data['attributes'])); } } */ private $args; /** * @param array $args argument name or index(string|int) => value expression (string) */ public function __construct(string $name, array $args) { $this->name = $name; $this->args = $args; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } if ($this->name !== $node->name) { return \false; } if (count($this->args) !== count($node->args)) { return \false; } foreach ($this->args as $argName => $argValue) { if (!isset($node->args[$argName]) || $argValue !== $node->args[$argName]) { return \false; } } return \true; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['name'], $properties['args']); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['name' => $this->name, 'args' => $this->args]]; } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['name'], $data['args']); } } name = $name; $this->phpDoc = $phpDoc; $this->usedTraits = $usedTraits; $this->traitUseAdaptations = $traitUseAdaptations; $this->statements = $statements; $this->attributes = $attributes; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } if ($this->phpDoc === null) { if ($node->phpDoc !== null) { return \false; } } elseif ($node->phpDoc !== null) { if (!$this->phpDoc->equals($node->phpDoc)) { return \false; } } else { return \false; } if (count($this->attributes) !== count($node->attributes)) { return \false; } foreach ($this->attributes as $i => $attribute) { if (!$attribute->equals($node->attributes[$i])) { return \false; } } if (count($this->traitUseAdaptations) !== count($node->traitUseAdaptations)) { return \false; } foreach ($this->traitUseAdaptations as $i => $ourTraitUseAdaptation) { $theirTraitUseAdaptation = $node->traitUseAdaptations[$i]; if (!$ourTraitUseAdaptation->equals($theirTraitUseAdaptation)) { return \false; } } if (count($this->statements) !== count($node->statements)) { return \false; } foreach ($this->statements as $i => $statement) { if ($statement->equals($node->statements[$i])) { continue; } return \false; } return $this->name === $node->name && $this->usedTraits === $node->usedTraits; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['name'], $properties['phpDoc'], $properties['usedTraits'], $properties['traitUseAdaptations'], $properties['statements'], $properties['attributes']); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['name' => $this->name, 'phpDoc' => $this->phpDoc, 'usedTraits' => $this->usedTraits, 'traitUseAdaptations' => $this->traitUseAdaptations, 'statements' => $this->statements, 'attributes' => $this->attributes]]; } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['name'], $data['phpDoc'] !== null ? \PHPStan\Dependency\ExportedNode\ExportedPhpDocNode::decode($data['phpDoc']['data']) : null, $data['usedTraits'], array_map(static function (array $traitUseAdaptationData) : \PHPStan\Dependency\ExportedNode\ExportedTraitUseAdaptation { if ($traitUseAdaptationData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedTraitUseAdaptation::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedTraitUseAdaptation::decode($traitUseAdaptationData['data']); }, $data['traitUseAdaptations']), array_map(static function (array $node) : ExportedNode { $nodeType = $node['type']; return $nodeType::decode($node['data']); }, $data['statements']), array_map(static function (array $attributeData) : \PHPStan\Dependency\ExportedNode\ExportedAttributeNode { if ($attributeData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::decode($attributeData['data']); }, $data['attributes'])); } /** * @return self::TYPE_TRAIT */ public function getType() : string { return self::TYPE_TRAIT; } public function getName() : string { return $this->name; } } name = $name; $this->phpDoc = $phpDoc; $this->byRef = $byRef; $this->returnType = $returnType; $this->parameters = $parameters; $this->attributes = $attributes; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } if (count($this->parameters) !== count($node->parameters)) { return \false; } foreach ($this->parameters as $i => $ourParameter) { $theirParameter = $node->parameters[$i]; if (!$ourParameter->equals($theirParameter)) { return \false; } } if ($this->phpDoc === null) { if ($node->phpDoc !== null) { return \false; } } elseif ($node->phpDoc !== null) { if (!$this->phpDoc->equals($node->phpDoc)) { return \false; } } else { return \false; } if (count($this->attributes) !== count($node->attributes)) { return \false; } foreach ($this->attributes as $i => $attribute) { if (!$attribute->equals($node->attributes[$i])) { return \false; } } return $this->name === $node->name && $this->byRef === $node->byRef && $this->returnType === $node->returnType; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['name'], $properties['phpDoc'], $properties['byRef'], $properties['returnType'], $properties['parameters'], $properties['attributes']); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['name' => $this->name, 'phpDoc' => $this->phpDoc, 'byRef' => $this->byRef, 'returnType' => $this->returnType, 'parameters' => $this->parameters, 'attributes' => $this->attributes]]; } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['name'], $data['phpDoc'] !== null ? \PHPStan\Dependency\ExportedNode\ExportedPhpDocNode::decode($data['phpDoc']['data']) : null, $data['byRef'], $data['returnType'], array_map(static function (array $parameterData) : \PHPStan\Dependency\ExportedNode\ExportedParameterNode { if ($parameterData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedParameterNode::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedParameterNode::decode($parameterData['data']); }, $data['parameters']), array_map(static function (array $attributeData) : \PHPStan\Dependency\ExportedNode\ExportedAttributeNode { if ($attributeData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::decode($attributeData['data']); }, $data['attributes'])); } /** * @return self::TYPE_FUNCTION */ public function getType() : string { return self::TYPE_FUNCTION; } public function getName() : string { return $this->name; } } constants = $constants; $this->public = $public; $this->private = $private; $this->final = $final; $this->phpDoc = $phpDoc; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } if ($this->phpDoc === null) { if ($node->phpDoc !== null) { return \false; } } elseif ($node->phpDoc !== null) { if (!$this->phpDoc->equals($node->phpDoc)) { return \false; } } else { return \false; } if (count($this->constants) !== count($node->constants)) { return \false; } foreach ($this->constants as $i => $constant) { if (!$constant->equals($node->constants[$i])) { return \false; } } return $this->public === $node->public && $this->private === $node->private && $this->final === $node->final; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['constants'], $properties['public'], $properties['private'], $properties['final'], $properties['phpDoc']); } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self(array_map(static function (array $constantData) : \PHPStan\Dependency\ExportedNode\ExportedClassConstantNode { if ($constantData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedClassConstantNode::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedClassConstantNode::decode($constantData['data']); }, $data['constants']), $data['public'], $data['private'], $data['final'], $data['phpDoc'] !== null ? \PHPStan\Dependency\ExportedNode\ExportedPhpDocNode::decode($data['phpDoc']['data']) : null); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['constants' => $this->constants, 'public' => $this->public, 'private' => $this->private, 'final' => $this->final, 'phpDoc' => $this->phpDoc]]; } } traitName = $traitName; $this->method = $method; $this->newModifier = $newModifier; $this->newName = $newName; $this->insteadOfs = $insteadOfs; } public static function createAlias(?string $traitName, string $method, ?int $newModifier, ?string $newName) : self { return new self($traitName, $method, $newModifier, $newName, null); } /** * @param string[] $insteadOfs */ public static function createPrecedence(?string $traitName, string $method, array $insteadOfs) : self { return new self($traitName, $method, null, null, $insteadOfs); } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } return $this->traitName === $node->traitName && $this->method === $node->method && $this->newModifier === $node->newModifier && $this->newName === $node->newName && $this->insteadOfs === $node->insteadOfs; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['traitName'], $properties['method'], $properties['newModifier'], $properties['newName'], $properties['insteadOfs']); } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['traitName'], $data['method'], $data['newModifier'], $data['newName'], $data['insteadOfs']); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['traitName' => $this->traitName, 'method' => $this->method, 'newModifier' => $this->newModifier, 'newName' => $this->newName, 'insteadOfs' => $this->insteadOfs]]; } } */ private $uses; /** * @var array */ private $constUses; /** * @param array $uses alias(string) => fullName(string) * @param array $constUses alias(string) => fullName(string) */ public function __construct(string $phpDocString, ?string $namespace, array $uses, array $constUses) { $this->phpDocString = $phpDocString; $this->namespace = $namespace; $this->uses = $uses; $this->constUses = $constUses; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } return $this->phpDocString === $node->phpDocString && $this->namespace === $node->namespace && $this->uses === $node->uses && $this->constUses === $node->constUses; } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['phpDocString' => $this->phpDocString, 'namespace' => $this->namespace, 'uses' => $this->uses, 'constUses' => $this->constUses]]; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['phpDocString'], $properties['namespace'], $properties['uses'], $properties['constUses'] ?? []); } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['phpDocString'], $data['namespace'], $data['uses'], $data['constUses'] ?? []); } } name = $name; $this->phpDoc = $phpDoc; $this->byRef = $byRef; $this->public = $public; $this->private = $private; $this->abstract = $abstract; $this->final = $final; $this->static = $static; $this->returnType = $returnType; $this->parameters = $parameters; $this->attributes = $attributes; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } if (count($this->parameters) !== count($node->parameters)) { return \false; } foreach ($this->parameters as $i => $ourParameter) { $theirParameter = $node->parameters[$i]; if (!$ourParameter->equals($theirParameter)) { return \false; } } if ($this->phpDoc === null) { if ($node->phpDoc !== null) { return \false; } } elseif ($node->phpDoc !== null) { if (!$this->phpDoc->equals($node->phpDoc)) { return \false; } } else { return \false; } if (count($this->attributes) !== count($node->attributes)) { return \false; } foreach ($this->attributes as $i => $attribute) { if (!$attribute->equals($node->attributes[$i])) { return \false; } } return $this->name === $node->name && $this->byRef === $node->byRef && $this->public === $node->public && $this->private === $node->private && $this->abstract === $node->abstract && $this->final === $node->final && $this->static === $node->static && $this->returnType === $node->returnType; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['name'], $properties['phpDoc'], $properties['byRef'], $properties['public'], $properties['private'], $properties['abstract'], $properties['final'], $properties['static'], $properties['returnType'], $properties['parameters'], $properties['attributes']); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['name' => $this->name, 'phpDoc' => $this->phpDoc, 'byRef' => $this->byRef, 'public' => $this->public, 'private' => $this->private, 'abstract' => $this->abstract, 'final' => $this->final, 'static' => $this->static, 'returnType' => $this->returnType, 'parameters' => $this->parameters, 'attributes' => $this->attributes]]; } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['name'], $data['phpDoc'] !== null ? \PHPStan\Dependency\ExportedNode\ExportedPhpDocNode::decode($data['phpDoc']['data']) : null, $data['byRef'], $data['public'], $data['private'], $data['abstract'], $data['final'], $data['static'], $data['returnType'], array_map(static function (array $parameterData) : \PHPStan\Dependency\ExportedNode\ExportedParameterNode { if ($parameterData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedParameterNode::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedParameterNode::decode($parameterData['data']); }, $data['parameters']), array_map(static function (array $attributeData) : \PHPStan\Dependency\ExportedNode\ExportedAttributeNode { if ($attributeData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::decode($attributeData['data']); }, $data['attributes'])); } } names = $names; $this->phpDoc = $phpDoc; $this->type = $type; $this->public = $public; $this->private = $private; $this->static = $static; $this->readonly = $readonly; $this->attributes = $attributes; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } if ($this->phpDoc === null) { if ($node->phpDoc !== null) { return \false; } } elseif ($node->phpDoc !== null) { if (!$this->phpDoc->equals($node->phpDoc)) { return \false; } } else { return \false; } if (count($this->names) !== count($node->names)) { return \false; } foreach ($this->names as $i => $name) { if ($name !== $node->names[$i]) { return \false; } } if (count($this->attributes) !== count($node->attributes)) { return \false; } foreach ($this->attributes as $i => $attribute) { if (!$attribute->equals($node->attributes[$i])) { return \false; } } return $this->type === $node->type && $this->public === $node->public && $this->private === $node->private && $this->static === $node->static && $this->readonly === $node->readonly; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['names'], $properties['phpDoc'], $properties['type'], $properties['public'], $properties['private'], $properties['static'], $properties['readonly'], $properties['attributes']); } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['names'], $data['phpDoc'] !== null ? \PHPStan\Dependency\ExportedNode\ExportedPhpDocNode::decode($data['phpDoc']['data']) : null, $data['type'], $data['public'], $data['private'], $data['static'], $data['readonly'], array_map(static function (array $attributeData) : \PHPStan\Dependency\ExportedNode\ExportedAttributeNode { if ($attributeData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::decode($attributeData['data']); }, $data['attributes'])); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['names' => $this->names, 'phpDoc' => $this->phpDoc, 'type' => $this->type, 'public' => $this->public, 'private' => $this->private, 'static' => $this->static, 'readonly' => $this->readonly, 'attributes' => $this->attributes]]; } } name = $name; $this->scalarType = $scalarType; $this->phpDoc = $phpDoc; $this->implements = $implements; $this->statements = $statements; $this->attributes = $attributes; } public function equals(ExportedNode $node) : bool { if (!$node instanceof self) { return \false; } if ($this->phpDoc === null) { if ($node->phpDoc !== null) { return \false; } } elseif ($node->phpDoc !== null) { if (!$this->phpDoc->equals($node->phpDoc)) { return \false; } } else { return \false; } if (count($this->statements) !== count($node->statements)) { return \false; } foreach ($this->statements as $i => $statement) { if ($statement->equals($node->statements[$i])) { continue; } return \false; } if (count($this->attributes) !== count($node->attributes)) { return \false; } foreach ($this->attributes as $i => $attribute) { if (!$attribute->equals($node->attributes[$i])) { return \false; } } return $this->name === $node->name && $this->scalarType === $node->scalarType && $this->implements === $node->implements; } /** * @param mixed[] $properties * @return self */ public static function __set_state(array $properties) : ExportedNode { return new self($properties['name'], $properties['scalarType'], $properties['phpDoc'], $properties['implements'], $properties['statements'], $properties['attributes']); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => self::class, 'data' => ['name' => $this->name, 'scalarType' => $this->scalarType, 'phpDoc' => $this->phpDoc, 'implements' => $this->implements, 'statements' => $this->statements, 'attributes' => $this->attributes]]; } /** * @param mixed[] $data * @return self */ public static function decode(array $data) : ExportedNode { return new self($data['name'], $data['scalarType'], $data['phpDoc'] !== null ? \PHPStan\Dependency\ExportedNode\ExportedPhpDocNode::decode($data['phpDoc']['data']) : null, $data['implements'], array_map(static function (array $node) : ExportedNode { $nodeType = $node['type']; return $nodeType::decode($node['data']); }, $data['statements']), array_map(static function (array $attributeData) : \PHPStan\Dependency\ExportedNode\ExportedAttributeNode { if ($attributeData['type'] !== \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::class) { throw new ShouldNotHappenException(); } return \PHPStan\Dependency\ExportedNode\ExportedAttributeNode::decode($attributeData['data']); }, $data['attributes'])); } /** * @return self::TYPE_ENUM */ public function getType() : string { return self::TYPE_ENUM; } public function getName() : string { return $this->name; } } fileHelper = $fileHelper; $this->reflectionProvider = $reflectionProvider; $this->exportedNodeResolver = $exportedNodeResolver; $this->fileTypeMapper = $fileTypeMapper; } public function resolveDependencies(Node $node, Scope $scope) : \PHPStan\Dependency\NodeDependencies { $dependenciesReflections = []; if ($node instanceof Node\Stmt\Class_) { if ($node->namespacedName !== null) { $this->addClassToDependencies($node->namespacedName->toString(), $dependenciesReflections); } if ($node->extends !== null) { $this->addClassToDependencies($node->extends->toString(), $dependenciesReflections); } foreach ($node->implements as $className) { $this->addClassToDependencies($className->toString(), $dependenciesReflections); } } elseif ($node instanceof Node\Stmt\Interface_) { if ($node->namespacedName !== null) { $this->addClassToDependencies($node->namespacedName->toString(), $dependenciesReflections); } foreach ($node->extends as $className) { $this->addClassToDependencies($className->toString(), $dependenciesReflections); } } elseif ($node instanceof Node\Stmt\Enum_) { if ($node->namespacedName !== null) { $this->addClassToDependencies($node->namespacedName->toString(), $dependenciesReflections); } foreach ($node->implements as $className) { $this->addClassToDependencies($className->toString(), $dependenciesReflections); } } elseif ($node instanceof InClassMethodNode) { $nativeMethod = $node->getMethodReflection(); $this->extractThrowType($nativeMethod->getThrowType(), $dependenciesReflections); $this->extractFromParametersAcceptor($nativeMethod, $dependenciesReflections); foreach ($nativeMethod->getAsserts()->getAll() as $assertTag) { foreach ($assertTag->getType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } foreach ($assertTag->getOriginalType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } if ($nativeMethod->getSelfOutType() !== null) { foreach ($nativeMethod->getSelfOutType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } elseif ($node instanceof ClassPropertyNode) { $nativeTypeNode = $node->getNativeType(); if ($nativeTypeNode !== null) { $nativeType = ParserNodeTypeToPHPStanType::resolve($nativeTypeNode, $node->getClassReflection()); foreach ($nativeType->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } $phpDocType = $node->getPhpDocType(); if ($phpDocType !== null) { foreach ($phpDocType->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } elseif ($node instanceof InFunctionNode) { $functionReflection = $node->getFunctionReflection(); $this->extractThrowType($functionReflection->getThrowType(), $dependenciesReflections); $this->extractFromParametersAcceptor($functionReflection, $dependenciesReflections); foreach ($functionReflection->getAsserts()->getAll() as $assertTag) { foreach ($assertTag->getType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } foreach ($assertTag->getOriginalType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } elseif ($node instanceof Closure || $node instanceof Node\Expr\ArrowFunction) { $closureType = $scope->getType($node); if ($closureType instanceof ClosureType) { foreach ($closureType->getParameters() as $parameter) { $referencedClasses = $parameter->getType()->getReferencedClasses(); foreach ($referencedClasses as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } $returnTypeReferencedClasses = $closureType->getReturnType()->getReferencedClasses(); foreach ($returnTypeReferencedClasses as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } elseif ($node instanceof Node\Expr\FuncCall) { $functionName = $node->name; if ($functionName instanceof Node\Name) { try { $functionReflection = $this->getFunctionReflection($functionName, $scope); $dependenciesReflections[] = $functionReflection; foreach ($functionReflection->getVariants() as $functionVariant) { foreach ($functionVariant->getParameters() as $parameter) { if ($parameter->getOutType() !== null) { foreach ($parameter->getOutType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } if ($parameter->getClosureThisType() === null) { continue; } foreach ($parameter->getClosureThisType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } foreach ($functionReflection->getAsserts()->getAll() as $assertTag) { foreach ($assertTag->getType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } foreach ($assertTag->getOriginalType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } catch (FunctionNotFoundException $e) { // pass } } else { $calledType = $scope->getType($functionName); if ($calledType->isCallable()->yes()) { $variants = $calledType->getCallableParametersAcceptors($scope); foreach ($variants as $variant) { $referencedClasses = $variant->getReturnType()->getReferencedClasses(); foreach ($referencedClasses as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } foreach ($variant->getParameters() as $parameter) { if (!$parameter instanceof ParameterReflectionWithPhpDocs) { continue; } if ($parameter->getOutType() !== null) { foreach ($parameter->getOutType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } if ($parameter->getClosureThisType() === null) { continue; } foreach ($parameter->getClosureThisType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } } } $returnType = $scope->getType($node); foreach ($returnType->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } elseif ($node instanceof Node\Expr\MethodCall) { $calledOnType = $scope->getType($node->var); $classNames = $calledOnType->getReferencedClasses(); foreach ($classNames as $className) { $this->addClassToDependencies($className, $dependenciesReflections); } $returnType = $scope->getType($node); foreach ($returnType->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } if ($node->name instanceof Node\Identifier) { $methodReflection = $scope->getMethodReflection($calledOnType, $node->name->toString()); if ($methodReflection !== null) { $this->addClassToDependencies($methodReflection->getDeclaringClass()->getName(), $dependenciesReflections); foreach ($methodReflection->getVariants() as $methodVariant) { foreach ($methodVariant->getParameters() as $parameter) { if ($parameter->getOutType() !== null) { foreach ($parameter->getOutType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } if ($parameter->getClosureThisType() === null) { continue; } foreach ($parameter->getClosureThisType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } foreach ($methodReflection->getAsserts()->getAll() as $assertTag) { foreach ($assertTag->getType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } foreach ($assertTag->getOriginalType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } if ($methodReflection->getSelfOutType() !== null) { foreach ($methodReflection->getSelfOutType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } } } elseif ($node instanceof Node\Expr\PropertyFetch) { $fetchedOnType = $scope->getType($node->var); $classNames = $fetchedOnType->getReferencedClasses(); foreach ($classNames as $className) { $this->addClassToDependencies($className, $dependenciesReflections); } $propertyType = $scope->getType($node); foreach ($propertyType->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } if ($node->name instanceof Node\Identifier) { $propertyReflection = $scope->getPropertyReflection($fetchedOnType, $node->name->toString()); if ($propertyReflection !== null) { $this->addClassToDependencies($propertyReflection->getDeclaringClass()->getName(), $dependenciesReflections); } } } elseif ($node instanceof Node\Expr\StaticCall) { if ($node->class instanceof Node\Name) { $this->addClassToDependencies($scope->resolveName($node->class), $dependenciesReflections); } else { foreach ($scope->getType($node->class)->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } $returnType = $scope->getType($node); foreach ($returnType->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } if ($node->name instanceof Node\Identifier) { if ($node->class instanceof Node\Name) { $className = $scope->resolveName($node->class); if ($this->reflectionProvider->hasClass($className)) { $methodClassReflection = $this->reflectionProvider->getClass($className); if ($methodClassReflection->hasMethod($node->name->toString())) { $methodReflection = $methodClassReflection->getMethod($node->name->toString(), $scope); $this->addClassToDependencies($methodReflection->getDeclaringClass()->getName(), $dependenciesReflections); foreach ($methodReflection->getVariants() as $methodVariant) { foreach ($methodVariant->getParameters() as $parameter) { if ($parameter->getOutType() !== null) { foreach ($parameter->getOutType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } if ($parameter->getClosureThisType() === null) { continue; } foreach ($parameter->getClosureThisType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } } } } else { $methodReflection = $scope->getMethodReflection($scope->getType($node->class), $node->name->toString()); if ($methodReflection !== null) { $this->addClassToDependencies($methodReflection->getDeclaringClass()->getName(), $dependenciesReflections); foreach ($methodReflection->getVariants() as $methodVariant) { foreach ($methodVariant->getParameters() as $parameter) { if ($parameter->getOutType() !== null) { foreach ($parameter->getOutType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } if ($parameter->getClosureThisType() === null) { continue; } foreach ($parameter->getClosureThisType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } } } } } elseif ($node instanceof Node\Expr\ClassConstFetch) { if ($node->class instanceof Node\Name) { $this->addClassToDependencies($scope->resolveName($node->class), $dependenciesReflections); } else { foreach ($scope->getType($node->class)->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } $returnType = $scope->getType($node); foreach ($returnType->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } if ($node->name instanceof Node\Identifier && $node->name->toLowerString() !== 'class') { if ($node->class instanceof Node\Name) { $className = $scope->resolveName($node->class); if ($this->reflectionProvider->hasClass($className)) { $constantClassReflection = $this->reflectionProvider->getClass($className); if ($constantClassReflection->hasConstant($node->name->toString())) { $constantReflection = $constantClassReflection->getConstant($node->name->toString()); $this->addClassToDependencies($constantReflection->getDeclaringClass()->getName(), $dependenciesReflections); } } } else { $constantReflection = $scope->getConstantReflection($scope->getType($node->class), $node->name->toString()); if ($constantReflection !== null) { $this->addClassToDependencies($constantReflection->getDeclaringClass()->getName(), $dependenciesReflections); } } } } elseif ($node instanceof Node\Expr\StaticPropertyFetch) { if ($node->class instanceof Node\Name) { $this->addClassToDependencies($scope->resolveName($node->class), $dependenciesReflections); } else { foreach ($scope->getType($node->class)->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } $returnType = $scope->getType($node); foreach ($returnType->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } if ($node->name instanceof Node\Identifier) { if ($node->class instanceof Node\Name) { $className = $scope->resolveName($node->class); if ($this->reflectionProvider->hasClass($className)) { $propertyClassReflection = $this->reflectionProvider->getClass($className); if ($propertyClassReflection->hasProperty($node->name->toString())) { $propertyReflection = $propertyClassReflection->getProperty($node->name->toString(), $scope); $this->addClassToDependencies($propertyReflection->getDeclaringClass()->getName(), $dependenciesReflections); } } } else { $propertyReflection = $scope->getPropertyReflection($scope->getType($node->class), $node->name->toString()); if ($propertyReflection !== null) { $this->addClassToDependencies($propertyReflection->getDeclaringClass()->getName(), $dependenciesReflections); } } } } elseif ($node instanceof Node\Expr\New_ && $node->class instanceof Node\Name) { $this->addClassToDependencies($scope->resolveName($node->class), $dependenciesReflections); } elseif ($node instanceof Node\Stmt\Trait_ && $node->namespacedName !== null) { try { $classReflection = $this->reflectionProvider->getClass($node->namespacedName->toString()); foreach ($classReflection->getRequireImplementsTags() as $implementsTag) { foreach ($implementsTag->getType()->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } catch (ClassNotFoundException $e) { // pass } } elseif ($node instanceof Node\Stmt\TraitUse) { foreach ($node->traits as $traitName) { $this->addClassToDependencies($traitName->toString(), $dependenciesReflections); } $docComment = $node->getDocComment(); if ($docComment !== null) { $usesTags = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $scope->isInClass() ? $scope->getClassReflection()->getName() : null, $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, null, $docComment->getText())->getUsesTags(); foreach ($usesTags as $usesTag) { foreach ($usesTag->getType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } } elseif ($node instanceof Node\Expr\Instanceof_) { if ($node->class instanceof Name) { $this->addClassToDependencies($scope->resolveName($node->class), $dependenciesReflections); } } elseif ($node instanceof Node\Stmt\Catch_) { foreach ($node->types as $type) { $this->addClassToDependencies($scope->resolveName($type), $dependenciesReflections); } } elseif ($node instanceof ArrayDimFetch && $node->dim !== null) { $varType = $scope->getType($node->var); $dimType = $scope->getType($node->dim); foreach ($varType->getOffsetValueType($dimType)->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } elseif ($node instanceof Foreach_) { $exprType = $scope->getType($node->expr); if ($node->keyVar !== null) { foreach ($scope->getIterableKeyType($exprType)->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } foreach ($scope->getIterableValueType($exprType)->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } elseif ($node instanceof Array_ && $this->considerArrayForCallableTest($scope, $node)) { $arrayType = $scope->getType($node); if (!$arrayType->isCallable()->no()) { foreach ($arrayType->getCallableParametersAcceptors($scope) as $variant) { $referencedClasses = $variant->getReturnType()->getReferencedClasses(); foreach ($referencedClasses as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } } return new \PHPStan\Dependency\NodeDependencies($this->fileHelper, $dependenciesReflections, $this->exportedNodeResolver->resolve($scope->getFile(), $node)); } public function resolveUsedTraitDependencies(InClassNode $inClassNode) : \PHPStan\Dependency\NodeDependencies { $dependenciesReflections = []; foreach ($inClassNode->getClassReflection()->getTraits(\true) as $trait) { $dependenciesReflections[] = $trait; } return new \PHPStan\Dependency\NodeDependencies($this->fileHelper, $dependenciesReflections, null); } private function considerArrayForCallableTest(Scope $scope, Array_ $arrayNode) : bool { $items = $arrayNode->items; if (count($items) !== 2) { return \false; } if ($items[0] === null) { return \false; } $itemType = $scope->getType($items[0]->value); return $itemType->isClassStringType()->yes(); } /** * @param array $dependenciesReflections */ private function addClassToDependencies(string $className, array &$dependenciesReflections) : void { try { $classReflection = $this->reflectionProvider->getClass($className); } catch (ClassNotFoundException $e) { return; } do { $dependenciesReflections[] = $classReflection; foreach ($classReflection->getInterfaces() as $interface) { $dependenciesReflections[] = $interface; } foreach ($classReflection->getTraits(\true) as $trait) { $dependenciesReflections[] = $trait; } foreach ($classReflection->getResolvedMixinTypes() as $mixinType) { foreach ($mixinType->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass); } } foreach ($classReflection->getRequireExtendsTags() as $extendsTag) { foreach ($extendsTag->getType()->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass); } } foreach ($classReflection->getTemplateTags() as $templateTag) { foreach ($templateTag->getBound()->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass); } $default = $templateTag->getDefault(); if ($default === null) { continue; } foreach ($default->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass); } } foreach ($classReflection->getPropertyTags() as $propertyTag) { if ($propertyTag->isReadable()) { foreach ($propertyTag->getReadableType()->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass); } } if (!$propertyTag->isWritable()) { continue; } foreach ($propertyTag->getWritableType()->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass); } } foreach ($classReflection->getMethodTags() as $methodTag) { foreach ($methodTag->getReturnType()->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass); } foreach ($methodTag->getParameters() as $parameter) { foreach ($parameter->getType()->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass); } if ($parameter->getDefaultValue() === null) { continue; } foreach ($parameter->getDefaultValue()->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass); } } } foreach ($classReflection->getExtendsTags() as $extendsTag) { foreach ($extendsTag->getType()->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass); } } foreach ($classReflection->getImplementsTags() as $implementsTag) { foreach ($implementsTag->getType()->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass); } } $phpDoc = $classReflection->getResolvedPhpDoc(); if ($phpDoc !== null) { foreach ($phpDoc->getTypeAliasImportTags() as $importTag) { $dependenciesReflections[] = $this->reflectionProvider->getClass($importTag->getImportedFrom()); } } $classReflection = $classReflection->getParentClass(); } while ($classReflection !== null); } private function getFunctionReflection(Node\Name $nameNode, ?Scope $scope) : FunctionReflection { return $this->reflectionProvider->getFunction($nameNode, $scope); } /** * @param array $dependenciesReflections */ private function extractFromParametersAcceptor(ParametersAcceptorWithPhpDocs $parametersAcceptor, array &$dependenciesReflections) : void { foreach ($parametersAcceptor->getParameters() as $parameter) { $referencedClasses = array_merge($parameter->getNativeType()->getReferencedClasses(), $parameter->getPhpDocType()->getReferencedClasses()); foreach ($referencedClasses as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } if ($parameter->getOutType() !== null) { foreach ($parameter->getOutType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } if ($parameter->getClosureThisType() === null) { continue; } foreach ($parameter->getClosureThisType()->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } $returnTypeReferencedClasses = array_merge($parametersAcceptor->getNativeReturnType()->getReferencedClasses(), $parametersAcceptor->getPhpDocReturnType()->getReferencedClasses()); foreach ($returnTypeReferencedClasses as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } /** * @param array $dependenciesReflections */ private function extractThrowType(?Type $throwType, array &$dependenciesReflections) : void { if ($throwType === null) { return; } foreach ($throwType->getReferencedClasses() as $referencedClass) { $this->addClassToDependencies($referencedClass, $dependenciesReflections); } } } */ private $reflections; /** * @var ?RootExportedNode */ private $exportedNode; /** * @param array $reflections */ public function __construct(FileHelper $fileHelper, array $reflections, ?\PHPStan\Dependency\RootExportedNode $exportedNode) { $this->fileHelper = $fileHelper; $this->reflections = $reflections; $this->exportedNode = $exportedNode; } /** * @param array $analysedFiles * @return string[] */ public function getFileDependencies(string $currentFile, array $analysedFiles) : array { $dependencies = []; foreach ($this->reflections as $dependencyReflection) { $dependencyFile = $dependencyReflection->getFileName(); if ($dependencyFile === null) { continue; } $dependencyFile = $this->fileHelper->normalizePath($dependencyFile); if ($currentFile === $dependencyFile) { continue; } if (!isset($analysedFiles[$dependencyFile])) { continue; } $dependencies[$dependencyFile] = $dependencyFile; } return array_values($dependencies); } public function getExportedNode() : ?\PHPStan\Dependency\RootExportedNode { return $this->exportedNode; } } fileTypeMapper = $fileTypeMapper; $this->exprPrinter = $exprPrinter; } public function resolve(string $fileName, Node $node) : ?\PHPStan\Dependency\RootExportedNode { if ($node instanceof Class_ && isset($node->namespacedName)) { $docComment = $node->getDocComment(); $extendsName = null; if ($node->extends !== null) { $extendsName = $node->extends->toString(); } $implementsNames = []; foreach ($node->implements as $className) { $implementsNames[] = $className->toString(); } $usedTraits = []; $adaptations = []; foreach ($node->getTraitUses() as $traitUse) { foreach ($traitUse->traits as $usedTraitName) { $usedTraits[] = $usedTraitName->toString(); } foreach ($traitUse->adaptations as $adaptation) { $adaptations[] = $adaptation; } } $className = $node->namespacedName->toString(); return new ExportedClassNode($className, $this->exportPhpDocNode($fileName, $className, null, $docComment !== null ? $docComment->getText() : null), $node->isAbstract(), $node->isFinal(), $extendsName, $implementsNames, $usedTraits, array_map(static function (Node\Stmt\TraitUseAdaptation $adaptation) : ExportedTraitUseAdaptation { if ($adaptation instanceof Node\Stmt\TraitUseAdaptation\Alias) { return ExportedTraitUseAdaptation::createAlias($adaptation->trait !== null ? $adaptation->trait->toString() : null, $adaptation->method->toString(), $adaptation->newModifier, $adaptation->newName !== null ? $adaptation->newName->toString() : null); } if ($adaptation instanceof Node\Stmt\TraitUseAdaptation\Precedence) { return ExportedTraitUseAdaptation::createPrecedence($adaptation->trait !== null ? $adaptation->trait->toString() : null, $adaptation->method->toString(), array_map(static function (Name $name) : string { return $name->toString(); }, $adaptation->insteadof)); } throw new ShouldNotHappenException(); }, $adaptations), $this->exportClassStatements($node->stmts, $fileName, $className), $this->exportAttributeNodes($node->attrGroups)); } if ($node instanceof Node\Stmt\Interface_ && isset($node->namespacedName)) { $extendsNames = array_map(static function (Name $name) : string { return (string) $name; }, $node->extends); $docComment = $node->getDocComment(); $interfaceName = $node->namespacedName->toString(); return new ExportedInterfaceNode($interfaceName, $this->exportPhpDocNode($fileName, $interfaceName, null, $docComment !== null ? $docComment->getText() : null), $extendsNames, $this->exportClassStatements($node->stmts, $fileName, $interfaceName)); } if ($node instanceof Node\Stmt\Enum_ && $node->namespacedName !== null) { $implementsNames = array_map(static function (Name $name) : string { return (string) $name; }, $node->implements); $docComment = $node->getDocComment(); $enumName = $node->namespacedName->toString(); $scalarType = null; if ($node->scalarType !== null) { $scalarType = $node->scalarType->toString(); } return new ExportedEnumNode($enumName, $scalarType, $this->exportPhpDocNode($fileName, $enumName, null, $docComment !== null ? $docComment->getText() : null), $implementsNames, $this->exportClassStatements($node->stmts, $fileName, $enumName), $this->exportAttributeNodes($node->attrGroups)); } if ($node instanceof Node\Stmt\Trait_ && isset($node->namespacedName)) { $docComment = $node->getDocComment(); $usedTraits = []; $adaptations = []; foreach ($node->getTraitUses() as $traitUse) { foreach ($traitUse->traits as $usedTraitName) { $usedTraits[] = $usedTraitName->toString(); } foreach ($traitUse->adaptations as $adaptation) { $adaptations[] = $adaptation; } } $className = $node->namespacedName->toString(); return new ExportedTraitNode($className, $this->exportPhpDocNode($fileName, $className, null, $docComment !== null ? $docComment->getText() : null), $usedTraits, array_map(static function (Node\Stmt\TraitUseAdaptation $adaptation) : ExportedTraitUseAdaptation { if ($adaptation instanceof Node\Stmt\TraitUseAdaptation\Alias) { return ExportedTraitUseAdaptation::createAlias($adaptation->trait !== null ? $adaptation->trait->toString() : null, $adaptation->method->toString(), $adaptation->newModifier, $adaptation->newName !== null ? $adaptation->newName->toString() : null); } if ($adaptation instanceof Node\Stmt\TraitUseAdaptation\Precedence) { return ExportedTraitUseAdaptation::createPrecedence($adaptation->trait !== null ? $adaptation->trait->toString() : null, $adaptation->method->toString(), array_map(static function (Name $name) : string { return $name->toString(); }, $adaptation->insteadof)); } throw new ShouldNotHappenException(); }, $adaptations), $this->exportClassStatements($node->stmts, $fileName, $className), $this->exportAttributeNodes($node->attrGroups)); } if ($node instanceof Function_) { $functionName = $node->name->name; if (isset($node->namespacedName)) { $functionName = (string) $node->namespacedName; } $docComment = $node->getDocComment(); return new ExportedFunctionNode($functionName, $this->exportPhpDocNode($fileName, null, $functionName, $docComment !== null ? $docComment->getText() : null), $node->byRef, NodeTypePrinter::printType($node->returnType), $this->exportParameterNodes($node->params), $this->exportAttributeNodes($node->attrGroups)); } return null; } /** * @param Node\Param[] $params * @return ExportedParameterNode[] */ private function exportParameterNodes(array $params) : array { $nodes = []; foreach ($params as $param) { if (!$param->var instanceof Node\Expr\Variable || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } $type = $param->type; if ($type !== null && $param->default instanceof Node\Expr\ConstFetch && $param->default->name->toLowerString() === 'null') { if ($type instanceof Node\UnionType) { $innerTypes = $type->types; $innerTypes[] = new Name('null'); $type = new Node\UnionType($innerTypes); } elseif ($type instanceof Node\Identifier || $type instanceof Name) { $type = new Node\NullableType($type); } } $nodes[] = new ExportedParameterNode($param->var->name, NodeTypePrinter::printType($type), $param->byRef, $param->variadic, $param->default !== null, $this->exportAttributeNodes($param->attrGroups)); } return $nodes; } private function exportPhpDocNode(string $file, ?string $className, ?string $functionName, ?string $text) : ?ExportedPhpDocNode { if ($text === null) { return null; } $resolvedPhpDocBlock = $this->fileTypeMapper->getResolvedPhpDoc($file, $className, null, $functionName, $text); $nameScope = $resolvedPhpDocBlock->getNullableNameScope(); if ($nameScope === null) { return null; } return new ExportedPhpDocNode($text, $nameScope->getNamespace(), $nameScope->getUses(), $nameScope->getConstUses()); } /** * @param Node\Stmt[] $statements * @return ExportedNode[] */ private function exportClassStatements(array $statements, string $fileName, string $namespacedName) : array { $exportedNodes = []; foreach ($statements as $statement) { $exportedNode = $this->exportClassStatement($statement, $fileName, $namespacedName); if ($exportedNode === null) { continue; } $exportedNodes[] = $exportedNode; } return $exportedNodes; } private function exportClassStatement(Node\Stmt $node, string $fileName, string $namespacedName) : ?\PHPStan\Dependency\ExportedNode { if ($node instanceof ClassMethod) { if ($node->isAbstract() || $node->isFinal() || !$node->isPrivate()) { $methodName = $node->name->toString(); $docComment = $node->getDocComment(); return new ExportedMethodNode($methodName, $this->exportPhpDocNode($fileName, $namespacedName, $methodName, $docComment !== null ? $docComment->getText() : null), $node->byRef, $node->isPublic(), $node->isPrivate(), $node->isAbstract(), $node->isFinal(), $node->isStatic(), NodeTypePrinter::printType($node->returnType), $this->exportParameterNodes($node->params), $this->exportAttributeNodes($node->attrGroups)); } } if ($node instanceof Node\Stmt\Property) { if ($node->isPrivate()) { return null; } $docComment = $node->getDocComment(); return new ExportedPropertiesNode(array_map(static function (Node\Stmt\PropertyProperty $prop) : string { return $prop->name->toString(); }, $node->props), $this->exportPhpDocNode($fileName, $namespacedName, null, $docComment !== null ? $docComment->getText() : null), NodeTypePrinter::printType($node->type), $node->isPublic(), $node->isPrivate(), $node->isStatic(), $node->isReadonly(), $this->exportAttributeNodes($node->attrGroups)); } if ($node instanceof Node\Stmt\ClassConst) { if ($node->isPrivate()) { return null; } $docComment = $node->getDocComment(); $constants = []; foreach ($node->consts as $const) { $constants[] = new ExportedClassConstantNode($const->name->toString(), $this->exprPrinter->printExpr($const->value), $this->exportAttributeNodes($node->attrGroups)); } return new ExportedClassConstantsNode($constants, $node->isPublic(), $node->isPrivate(), $node->isFinal(), $this->exportPhpDocNode($fileName, $namespacedName, null, $docComment !== null ? $docComment->getText() : null)); } if ($node instanceof Node\Stmt\EnumCase) { $docComment = $node->getDocComment(); return new ExportedEnumCaseNode($node->name->toString(), $node->expr !== null ? $this->exprPrinter->printExpr($node->expr) : null, $this->exportPhpDocNode($fileName, $namespacedName, null, $docComment !== null ? $docComment->getText() : null)); } return null; } /** * @param Node\AttributeGroup[] $attributeGroups * @return ExportedAttributeNode[] */ private function exportAttributeNodes(array $attributeGroups) : array { $nodes = []; foreach ($attributeGroups as $attributeGroup) { foreach ($attributeGroup->attrs as $attribute) { $args = []; foreach ($attribute->args as $i => $arg) { $args[$arg->name->name ?? $i] = $this->exprPrinter->printExpr($arg->value); } $nodes[] = new ExportedAttributeNode($attribute->name->toString(), $args); } } return $nodes; } } */ private static $containers = []; /** @api */ public static function getContainer() : Container { $additionalConfigFiles = static::getAdditionalConfigFiles(); $additionalConfigFiles[] = __DIR__ . '/TestCase.neon'; $cacheKey = sha1(implode("\n", $additionalConfigFiles)); if (!isset(self::$containers[$cacheKey])) { $tmpDir = sys_get_temp_dir() . '/phpstan-tests'; try { DirectoryCreator::ensureDirectoryExists($tmpDir, 0777); } catch (DirectoryCreatorException $e) { self::fail($e->getMessage()); } $rootDir = __DIR__ . '/../..'; $fileHelper = new FileHelper($rootDir); $rootDir = $fileHelper->normalizePath($rootDir, '/'); $containerFactory = new ContainerFactory($rootDir); $container = $containerFactory->create($tmpDir, array_merge([$containerFactory->getConfigDirectory() . '/config.level8.neon'], $additionalConfigFiles), []); self::$containers[$cacheKey] = $container; foreach ($container->getParameter('bootstrapFiles') as $bootstrapFile) { (static function (string $file) use($container) : void { require_once $file; })($bootstrapFile); } if (PHP_VERSION_ID >= 80000) { require_once __DIR__ . '/../../stubs/runtime/Enum/UnitEnum.php'; require_once __DIR__ . '/../../stubs/runtime/Enum/BackedEnum.php'; require_once __DIR__ . '/../../stubs/runtime/Enum/ReflectionEnum.php'; require_once __DIR__ . '/../../stubs/runtime/Enum/ReflectionEnumUnitCase.php'; require_once __DIR__ . '/../../stubs/runtime/Enum/ReflectionEnumBackedCase.php'; } } else { ContainerFactory::postInitializeContainer(self::$containers[$cacheKey]); } return self::$containers[$cacheKey]; } /** * @return string[] */ public static function getAdditionalConfigFiles() : array { return []; } public static function getParser() : Parser { /** @var Parser $parser */ $parser = self::getContainer()->getService('defaultAnalysisParser'); return $parser; } /** * @api * @deprecated Use createReflectionProvider() instead */ public function createBroker() : Broker { return self::getContainer()->getByType(Broker::class); } /** @api */ public static function createReflectionProvider() : ReflectionProvider { return self::getContainer()->getByType(ReflectionProvider::class); } public static function getReflector() : Reflector { return self::getContainer()->getService('betterReflectionReflector'); } /** * @deprecated Use getReflector() instead. * @return array{ClassReflector, FunctionReflector, ConstantReflector} */ public static function getReflectors() : array { return [self::getContainer()->getService('betterReflectionClassReflector'), self::getContainer()->getService('betterReflectionFunctionReflector'), self::getContainer()->getService('betterReflectionConstantReflector')]; } public static function getClassReflectionExtensionRegistryProvider() : ClassReflectionExtensionRegistryProvider { return self::getContainer()->getByType(ClassReflectionExtensionRegistryProvider::class); } /** * @param string[] $dynamicConstantNames */ public static function createScopeFactory(ReflectionProvider $reflectionProvider, TypeSpecifier $typeSpecifier, array $dynamicConstantNames = []) : ScopeFactory { $container = self::getContainer(); if (count($dynamicConstantNames) === 0) { $dynamicConstantNames = $container->getParameter('dynamicConstantNames'); } $reflectionProviderProvider = new DirectReflectionProviderProvider($reflectionProvider); $constantResolver = new ConstantResolver($reflectionProviderProvider, $dynamicConstantNames); $initializerExprTypeResolver = new InitializerExprTypeResolver($constantResolver, $reflectionProviderProvider, $container->getByType(PhpVersion::class), $container->getByType(OperatorTypeSpecifyingExtensionRegistryProvider::class), new OversizedArrayBuilder(), $container->getParameter('usePathConstantsAsConstantString')); return new ScopeFactory(new DirectInternalScopeFactory(MutatingScope::class, $reflectionProvider, $initializerExprTypeResolver, $container->getByType(DynamicReturnTypeExtensionRegistryProvider::class), $container->getByType(ExpressionTypeResolverExtensionRegistryProvider::class), $container->getByType(ExprPrinter::class), $typeSpecifier, new PropertyReflectionFinder(), self::getParser(), $container->getByType(NodeScopeResolver::class), new RicherScopeGetTypeHelper($initializerExprTypeResolver), $container->getByType(PhpVersion::class), $container->getParameter('featureToggles')['explicitMixedInUnknownGenericNew'], $container->getParameter('featureToggles')['explicitMixedForGlobalVariables'], $constantResolver)); } /** * @param array $globalTypeAliases */ public static function createTypeAliasResolver(array $globalTypeAliases, ReflectionProvider $reflectionProvider) : TypeAliasResolver { $container = self::getContainer(); return new UsefulTypeAliasResolver($globalTypeAliases, $container->getByType(TypeStringResolver::class), $container->getByType(TypeNodeResolver::class), $reflectionProvider); } protected function shouldTreatPhpDocTypesAsCertain() : bool { return \true; } public static function getFileHelper() : FileHelper { return self::getContainer()->getByType(FileHelper::class); } /** * Provides a DIRECTORY_SEPARATOR agnostic assertion helper, to compare file paths. * */ protected function assertSamePaths(string $expected, string $actual, string $message = '') : void { $expected = $this->getFileHelper()->normalizePath($expected); $actual = $this->getFileHelper()->normalizePath($actual); $this->assertSame($expected, $actual, $message); } /** * @param Error[]|string[] $errors */ protected function assertNoErrors(array $errors) : void { try { $this->assertCount(0, $errors); } catch (ExpectationFailedException $e) { $messages = []; foreach ($errors as $error) { if ($error instanceof Error) { $messages[] = sprintf("- %s\n in %s on line %d\n", rtrim($error->getMessage(), '.'), $error->getFile(), $error->getLine()); } else { $messages[] = $error; } } $this->fail($e->getMessage() . "\n\nEmitted errors:\n" . implode("\n", $messages)); } } protected function skipIfNotOnWindows() : void { if (DIRECTORY_SEPARATOR === '\\') { return; } self::markTestSkipped(); } protected function skipIfNotOnUnix() : void { if (DIRECTORY_SEPARATOR === '/') { return; } self::markTestSkipped(); } } */ private $outputStream = []; /** @var array */ private $output = []; private function getOutputStream(bool $decorated = \false, bool $verbose = \false) : StreamOutput { $kind = $decorated ? self::KIND_DECORATED : self::KIND_PLAIN; $kind .= $verbose ? self::KIND_VERBOSE : self::KIND_NOT_VERBOSE; if (!isset($this->outputStream[$kind])) { $resource = fopen('php://memory', 'w', \false); if ($resource === \false) { throw new ShouldNotHappenException(); } $verbosity = $verbose ? StreamOutput::VERBOSITY_VERBOSE : StreamOutput::VERBOSITY_NORMAL; $this->outputStream[$kind] = new StreamOutput($resource, $verbosity, $decorated); } return $this->outputStream[$kind]; } protected function getOutput(bool $decorated = \false, bool $verbose = \false) : Output { $kind = $decorated ? self::KIND_DECORATED : self::KIND_PLAIN; $kind .= $verbose ? self::KIND_VERBOSE : self::KIND_NOT_VERBOSE; if (!isset($this->output[$kind])) { $outputStream = $this->getOutputStream($decorated, $verbose); $errorConsoleStyle = new ErrorsConsoleStyle(new StringInput(''), $outputStream); $this->output[$kind] = new SymfonyOutput($outputStream, new SymfonyStyle($errorConsoleStyle)); } return $this->output[$kind]; } protected function getOutputContent(bool $decorated = \false, bool $verbose = \false) : string { rewind($this->getOutputStream($decorated, $verbose)->getStream()); $contents = stream_get_contents($this->getOutputStream($decorated, $verbose)->getStream()); if ($contents === \false) { throw new ShouldNotHappenException(); } return $this->rtrimMultiline($contents); } /** * @param array{int, int}|int $numFileErrors */ protected function getAnalysisResult($numFileErrors, int $numGenericErrors) : AnalysisResult { if (is_int($numFileErrors)) { $offsetFileErrors = 0; } else { [$offsetFileErrors, $numFileErrors] = $numFileErrors; } if (!in_array($numFileErrors, range(0, 6), \true) || !in_array($offsetFileErrors, range(0, 6), \true) || !in_array($numGenericErrors, range(0, 2), \true)) { throw new ShouldNotHappenException(); } $fileErrors = array_slice([new Error('Foo', self::DIRECTORY_PATH . '/folder with unicode 😃/file name with "spaces" and unicode 😃.php', 4), new Error('Foo', self::DIRECTORY_PATH . '/foo.php', 1), new Error("Bar\nBar2", self::DIRECTORY_PATH . '/foo.php', 5, \true, null, null, 'a tip'), new Error("Bar\nBar2", self::DIRECTORY_PATH . '/folder with unicode 😃/file name with "spaces" and unicode 😃.php', 2), new Error("Bar\nBar2", self::DIRECTORY_PATH . '/foo.php', null), new Error('Foobar\\Buz', self::DIRECTORY_PATH . '/foo.php', 5, \true, null, null, 'a tip', null, null, 'foobar.buz')], $offsetFileErrors, $numFileErrors); $genericErrors = array_slice(['first generic error', 'second generic'], 0, $numGenericErrors); return new AnalysisResult($fileErrors, $genericErrors, [], [], [], \false, null, \true, 0, \false, []); } private function rtrimMultiline(string $output) : string { $result = array_map(static function (string $line) : string { return rtrim($line, " \r\n"); }, explode("\n", $output)); return implode("\n", $result); } } , analyseAndScan?: array}|null */ private $excludePaths; /** @var array> */ private static $composerSourceLocatorsCache = []; /** * @param string[] $fileExtensions * @param string[] $obsoleteExcludesAnalyse * @param array{analyse?: array, analyseAndScan?: array}|null $excludePaths */ public function __construct(ComposerJsonAndInstalledJsonSourceLocatorMaker $composerJsonAndInstalledJsonSourceLocatorMaker, Parser $phpParser, Parser $php8Parser, FileNodesFetcher $fileNodesFetcher, PhpStormStubsSourceStubber $phpstormStubsSourceStubber, ReflectionSourceStubber $reflectionSourceStubber, PhpVersion $phpVersion, array $fileExtensions, array $obsoleteExcludesAnalyse, ?array $excludePaths) { $this->composerJsonAndInstalledJsonSourceLocatorMaker = $composerJsonAndInstalledJsonSourceLocatorMaker; $this->phpParser = $phpParser; $this->php8Parser = $php8Parser; $this->fileNodesFetcher = $fileNodesFetcher; $this->phpstormStubsSourceStubber = $phpstormStubsSourceStubber; $this->reflectionSourceStubber = $reflectionSourceStubber; $this->phpVersion = $phpVersion; $this->fileExtensions = $fileExtensions; $this->obsoleteExcludesAnalyse = $obsoleteExcludesAnalyse; $this->excludePaths = $excludePaths; } public function create() : SourceLocator { $classLoaders = ClassLoader::getRegisteredLoaders(); $classLoaderReflection = new ReflectionClass(ClassLoader::class); $cacheKey = sha1(serialize([$this->phpVersion->getVersionId(), $this->fileExtensions, $this->obsoleteExcludesAnalyse, $this->excludePaths])); if ($classLoaderReflection->hasProperty('vendorDir') && !isset(self::$composerSourceLocatorsCache[$cacheKey])) { $composerLocators = []; $vendorDirProperty = $classLoaderReflection->getProperty('vendorDir'); $vendorDirProperty->setAccessible(\true); foreach ($classLoaders as $classLoader) { $composerProjectPath = dirname($vendorDirProperty->getValue($classLoader)); if (!is_file($composerProjectPath . '/composer.json')) { continue; } $composerSourceLocator = $this->composerJsonAndInstalledJsonSourceLocatorMaker->create($composerProjectPath); if ($composerSourceLocator === null) { continue; } $composerLocators[] = $composerSourceLocator; } self::$composerSourceLocatorsCache[$cacheKey] = $composerLocators; } $locators = self::$composerSourceLocatorsCache[$cacheKey] ?? []; $astLocator = new Locator($this->phpParser); $astPhp8Locator = new Locator($this->php8Parser); $locators[] = new PhpInternalSourceLocator($astPhp8Locator, $this->phpstormStubsSourceStubber); $locators[] = new AutoloadSourceLocator($this->fileNodesFetcher, \true); $locators[] = new PhpVersionBlacklistSourceLocator(new PhpInternalSourceLocator($astLocator, $this->reflectionSourceStubber), $this->phpstormStubsSourceStubber); $locators[] = new PhpVersionBlacklistSourceLocator(new EvaledCodeSourceLocator($astLocator, $this->reflectionSourceStubber), $this->phpstormStubsSourceStubber); return new MemoizingSourceLocator(new AggregateSourceLocator($locators)); } } getService('typeSpecifier'); $fileHelper = self::getContainer()->getByType(FileHelper::class); $resolver = new NodeScopeResolver($reflectionProvider, self::getContainer()->getByType(InitializerExprTypeResolver::class), self::getReflector(), self::getClassReflectionExtensionRegistryProvider(), self::getContainer()->getByType(ParameterOutTypeExtensionProvider::class), self::getParser(), self::getContainer()->getByType(FileTypeMapper::class), self::getContainer()->getByType(StubPhpDocProvider::class), self::getContainer()->getByType(PhpVersion::class), self::getContainer()->getByType(SignatureMapProvider::class), self::getContainer()->getByType(PhpDocInheritanceResolver::class), self::getContainer()->getByType(FileHelper::class), $typeSpecifier, self::getContainer()->getByType(DynamicThrowTypeExtensionProvider::class), self::getContainer()->getByType(ReadWritePropertiesExtensionProvider::class), self::getContainer()->getByType(ParameterClosureTypeExtensionProvider::class), self::createScopeFactory($reflectionProvider, $typeSpecifier), self::getContainer()->getParameter('polluteScopeWithLoopInitialAssignments'), self::getContainer()->getParameter('polluteScopeWithAlwaysIterableForeach'), static::getEarlyTerminatingMethodCalls(), static::getEarlyTerminatingFunctionCalls(), self::getContainer()->getParameter('universalObjectCratesClasses'), self::getContainer()->getParameter('exceptions')['implicitThrows'], self::getContainer()->getParameter('treatPhpDocTypesAsCertain'), self::getContainer()->getParameter('featureToggles')['detectDeadTypeInMultiCatch'], self::getContainer()->getParameter('featureToggles')['paramOutType'], self::getContainer()->getParameter('featureToggles')['preciseMissingReturn'], self::getContainer()->getParameter('featureToggles')['explicitThrow']); $resolver->setAnalysedFiles(array_map(static function (string $file) use($fileHelper) : string { return $fileHelper->normalizePath($file); }, array_merge([$file], static::getAdditionalAnalysedFiles()))); $scopeFactory = self::createScopeFactory($reflectionProvider, $typeSpecifier, $dynamicConstantNames); $scope = $scopeFactory->create(ScopeContext::create($file)); $resolver->processNodes(self::getParser()->parseFile($file), $scope, $callback); } /** * @api * @param mixed ...$args */ public function assertFileAsserts(string $assertType, string $file, ...$args) : void { if ($assertType === 'type') { if ($args[0] instanceof Type) { // backward compatibility $expectedType = $args[0]; $this->assertInstanceOf(ConstantScalarType::class, $expectedType); $expected = $expectedType->getValue(); $actualType = $args[1]; $actual = $actualType->describe(VerbosityLevel::precise()); } else { $expected = $args[0]; $actual = $args[1]; } $this->assertSame($expected, $actual, sprintf('Expected type %s, got type %s in %s on line %d.', $expected, $actual, $file, $args[2])); } elseif ($assertType === 'variableCertainty') { $expectedCertainty = $args[0]; $actualCertainty = $args[1]; $variableName = $args[2]; $this->assertTrue($expectedCertainty->equals($actualCertainty), sprintf('Expected %s, actual certainty of %s is %s in %s on line %d.', $expectedCertainty->describe(), $variableName, $actualCertainty->describe(), $file, $args[3])); } } /** * @api * @return array */ public static function gatherAssertTypes(string $file) : array { $fileHelper = self::getContainer()->getByType(FileHelper::class); $relativePathHelper = new SystemAgnosticSimpleRelativePathHelper($fileHelper); $file = $fileHelper->normalizePath($file); $asserts = []; self::processFile($file, static function (Node $node, Scope $scope) use(&$asserts, $file, $relativePathHelper) : void { if (!$node instanceof Node\Expr\FuncCall) { return; } $nameNode = $node->name; if (!$nameNode instanceof Name) { return; } $functionName = $nameNode->toString(); if (in_array(strtolower($functionName), ['asserttype', 'assertnativetype', 'assertvariablecertainty'], \true)) { self::fail(sprintf('Missing use statement for %s() in %s on line %d.', $functionName, $relativePathHelper->getRelativePath($file), $node->getStartLine())); } elseif ($functionName === 'PHPStan\\Testing\\assertType') { $expectedType = $scope->getType($node->getArgs()[0]->value); if (!$expectedType instanceof ConstantScalarType) { self::fail(sprintf('Expected type must be a literal string, %s given in %s on line %d.', $expectedType->describe(VerbosityLevel::precise()), $relativePathHelper->getRelativePath($file), $node->getLine())); } $actualType = $scope->getType($node->getArgs()[1]->value); $assert = ['type', $file, $expectedType->getValue(), $actualType->describe(VerbosityLevel::precise()), $node->getStartLine()]; } elseif ($functionName === 'PHPStan\\Testing\\assertNativeType') { $expectedType = $scope->getType($node->getArgs()[0]->value); if (!$expectedType instanceof ConstantScalarType) { self::fail(sprintf('Expected type must be a literal string, %s given in %s on line %d.', $expectedType->describe(VerbosityLevel::precise()), $relativePathHelper->getRelativePath($file), $node->getLine())); } $actualType = $scope->getNativeType($node->getArgs()[1]->value); $assert = ['type', $file, $expectedType->getValue(), $actualType->describe(VerbosityLevel::precise()), $node->getStartLine()]; } elseif ($functionName === 'PHPStan\\Testing\\assertVariableCertainty') { $certainty = $node->getArgs()[0]->value; if (!$certainty instanceof StaticCall) { self::fail(sprintf('First argument of %s() must be TrinaryLogic call', $functionName)); } if (!$certainty->class instanceof Node\Name) { self::fail(sprintf('ERROR: Invalid TrinaryLogic call.')); } if ($certainty->class->toString() !== 'PHPStan\\TrinaryLogic') { self::fail(sprintf('ERROR: Invalid TrinaryLogic call.')); } if (!$certainty->name instanceof Node\Identifier) { self::fail(sprintf('ERROR: Invalid TrinaryLogic call.')); } // @phpstan-ignore staticMethod.dynamicName $expectedertaintyValue = TrinaryLogic::{$certainty->name->toString()}(); $variable = $node->getArgs()[1]->value; if ($variable instanceof Node\Expr\Variable && is_string($variable->name)) { $actualCertaintyValue = $scope->hasVariableType($variable->name); $variableDescription = sprintf('variable $%s', $variable->name); } elseif ($variable instanceof Node\Expr\ArrayDimFetch && $variable->dim !== null) { $offset = $scope->getType($variable->dim); $actualCertaintyValue = $scope->getType($variable->var)->hasOffsetValueType($offset); $variableDescription = sprintf('offset %s', $offset->describe(VerbosityLevel::precise())); } else { self::fail(sprintf('ERROR: Invalid assertVariableCertainty call.')); } $assert = ['variableCertainty', $file, $expectedertaintyValue, $actualCertaintyValue, $variableDescription, $node->getStartLine()]; } else { $correctFunction = null; $assertFunctions = ['assertType' => 'PHPStan\\Testing\\assertType', 'assertNativeType' => 'PHPStan\\Testing\\assertNativeType', 'assertVariableCertainty' => 'PHPStan\\Testing\\assertVariableCertainty']; foreach ($assertFunctions as $assertFn => $fqFunctionName) { if (stripos($functionName, $assertFn) === \false) { continue; } $correctFunction = $fqFunctionName; } if ($correctFunction === null) { return; } self::fail(sprintf('Function %s imported with wrong namespace %s called in %s on line %d.', $correctFunction, $functionName, $relativePathHelper->getRelativePath($file), $node->getStartLine())); } if (count($node->getArgs()) !== 2) { self::fail(sprintf('ERROR: Wrong %s() call in %s on line %d.', $functionName, $relativePathHelper->getRelativePath($file), $node->getStartLine())); } $asserts[$file . ':' . $node->getStartLine()] = $assert; }); if (count($asserts) === 0) { self::fail(sprintf('File %s does not contain any asserts', $file)); } return $asserts; } /** * @api * @return array */ public static function gatherAssertTypesFromDirectory(string $directory) : array { $asserts = []; foreach (self::findTestDataFilesFromDirectory($directory) as $path) { foreach (self::gatherAssertTypes($path) as $key => $assert) { $asserts[$key] = $assert; } } return $asserts; } /** * @return list */ public static function findTestDataFilesFromDirectory(string $directory) : array { if (!is_dir($directory)) { self::fail(sprintf('Directory %s does not exist.', $directory)); } $finder = new Finder(); $finder->followLinks(); $files = []; foreach ($finder->files()->name('*.php')->in($directory) as $fileInfo) { $path = $fileInfo->getPathname(); if (self::isFileLintSkipped($path)) { continue; } $files[] = $path; } return $files; } /** * From https://github.com/php-parallel-lint/PHP-Parallel-Lint/blob/0c2706086ac36dce31967cb36062ff8915fe03f7/bin/skip-linting.php * * Copyright (c) 2012, Jakub Onderka */ private static function isFileLintSkipped(string $file) : bool { $f = @fopen($file, 'r'); if ($f !== \false) { $firstLine = fgets($f); if ($firstLine === \false) { return \false; } // ignore shebang line if (strpos($firstLine, '#!') === 0) { $firstLine = fgets($f); if ($firstLine === \false) { return \false; } } @fclose($f); if (preg_match('~> */ protected function getCollectors() : array { return []; } /** * @return ReadWritePropertiesExtension[] */ protected function getReadWritePropertiesExtensions() : array { return []; } protected function getTypeSpecifier() : TypeSpecifier { return self::getContainer()->getService('typeSpecifier'); } private function getAnalyser(DirectRuleRegistry $ruleRegistry) : Analyser { if ($this->analyser === null) { $collectorRegistry = new CollectorRegistry($this->getCollectors()); $reflectionProvider = $this->createReflectionProvider(); $typeSpecifier = $this->getTypeSpecifier(); $readWritePropertiesExtensions = $this->getReadWritePropertiesExtensions(); $nodeScopeResolver = new NodeScopeResolver($reflectionProvider, self::getContainer()->getByType(InitializerExprTypeResolver::class), self::getReflector(), self::getClassReflectionExtensionRegistryProvider(), self::getContainer()->getByType(ParameterOutTypeExtensionProvider::class), $this->getParser(), self::getContainer()->getByType(FileTypeMapper::class), self::getContainer()->getByType(StubPhpDocProvider::class), self::getContainer()->getByType(PhpVersion::class), self::getContainer()->getByType(SignatureMapProvider::class), self::getContainer()->getByType(PhpDocInheritanceResolver::class), self::getContainer()->getByType(FileHelper::class), $typeSpecifier, self::getContainer()->getByType(DynamicThrowTypeExtensionProvider::class), $readWritePropertiesExtensions !== [] ? new DirectReadWritePropertiesExtensionProvider($readWritePropertiesExtensions) : self::getContainer()->getByType(ReadWritePropertiesExtensionProvider::class), self::getContainer()->getByType(ParameterClosureTypeExtensionProvider::class), self::createScopeFactory($reflectionProvider, $typeSpecifier), $this->shouldPolluteScopeWithLoopInitialAssignments(), $this->shouldPolluteScopeWithAlwaysIterableForeach(), [], [], self::getContainer()->getParameter('universalObjectCratesClasses'), self::getContainer()->getParameter('exceptions')['implicitThrows'], $this->shouldTreatPhpDocTypesAsCertain(), self::getContainer()->getParameter('featureToggles')['detectDeadTypeInMultiCatch'], self::getContainer()->getParameter('featureToggles')['paramOutType'], self::getContainer()->getParameter('featureToggles')['preciseMissingReturn'], self::getContainer()->getParameter('featureToggles')['explicitThrow']); $fileAnalyser = new FileAnalyser($this->createScopeFactory($reflectionProvider, $typeSpecifier), $nodeScopeResolver, $this->getParser(), self::getContainer()->getByType(DependencyResolver::class), new RuleErrorTransformer(), new LocalIgnoresProcessor()); $this->analyser = new Analyser($fileAnalyser, $ruleRegistry, $collectorRegistry, $nodeScopeResolver, 50); } return $this->analyser; } /** * @param string[] $files * @param list $expectedErrors */ public function analyse(array $files, array $expectedErrors) : void { $actualErrors = $this->gatherAnalyserErrors($files); $strictlyTypedSprintf = static function (int $line, string $message, ?string $tip) : string { $message = sprintf('%02d: %s', $line, $message); if ($tip !== null) { $message .= "\n 💡 " . $tip; } return $message; }; $expectedErrors = array_map(static function (array $error) use($strictlyTypedSprintf) : string { return $strictlyTypedSprintf($error[1], $error[0], $error[2] ?? null); }, $expectedErrors); $actualErrors = array_map(static function (Error $error) use($strictlyTypedSprintf) : string { $line = $error->getLine(); if ($line === null) { return $strictlyTypedSprintf(-1, $error->getMessage(), $error->getTip()); } return $strictlyTypedSprintf($line, $error->getMessage(), $error->getTip()); }, $actualErrors); $this->assertSame(implode("\n", $expectedErrors) . "\n", implode("\n", $actualErrors) . "\n"); } /** * @param string[] $files * @return list */ public function gatherAnalyserErrors(array $files) : array { $ruleRegistry = new DirectRuleRegistry([$this->getRule()]); $files = array_map([$this->getFileHelper(), 'normalizePath'], $files); $analyserResult = $this->getAnalyser($ruleRegistry)->analyse($files, null, null, \true); if (count($analyserResult->getInternalErrors()) > 0) { $this->fail(implode("\n", array_map(static function (InternalError $internalError) { return $internalError->getMessage(); }, $analyserResult->getInternalErrors()))); } if ($this->shouldFailOnPhpErrors() && count($analyserResult->getAllPhpErrors()) > 0) { $this->fail(implode("\n", array_map(static function (Error $error) : string { return sprintf('%s on %s:%d', $error->getMessage(), $error->getFile(), $error->getLine()); }, $analyserResult->getAllPhpErrors()))); } $finalizer = new AnalyserResultFinalizer($ruleRegistry, new RuleErrorTransformer(), $this->createScopeFactory($this->createReflectionProvider(), $this->getTypeSpecifier()), new LocalIgnoresProcessor(), \true); return $finalizer->finalize($analyserResult, \false, \true)->getAnalyserResult()->getUnorderedErrors(); } protected function shouldPolluteScopeWithLoopInitialAssignments() : bool { return \false; } protected function shouldPolluteScopeWithAlwaysIterableForeach() : bool { return \true; } protected function shouldFailOnPhpErrors() : bool { return \true; } public static function getAdditionalConfigFiles() : array { return [__DIR__ . '/../../conf/bleedingEdge.neon']; } } > */ public abstract function dataTopics() : array; public abstract function getDataPath() : string; public abstract function getPhpStanExecutablePath() : string; public abstract function getPhpStanConfigPath() : ?string; protected function getResultSuffix() : string { return ''; } protected function shouldAutoloadAnalysedFile() : bool { return \true; } /** * @dataProvider dataTopics */ public function testLevels(string $topic) : void { $file = sprintf('%s' . DIRECTORY_SEPARATOR . '%s.php', $this->getDataPath(), $topic); $command = escapeshellcmd($this->getPhpStanExecutablePath()); $configPath = $this->getPhpStanConfigPath(); $fileHelper = new FileHelper(__DIR__ . '/../..'); $previousMessages = []; $exceptions = []; exec(sprintf('%s %s clear-result-cache %s 2>&1', escapeshellarg(PHP_BINARY), $command, $configPath !== null ? '--configuration ' . escapeshellarg($configPath) : ''), $clearResultCacheOutputLines, $clearResultCacheExitCode); if ($clearResultCacheExitCode !== 0) { throw new ShouldNotHappenException('Could not clear result cache: ' . implode("\n", $clearResultCacheOutputLines)); } putenv('__PHPSTAN_FORCE_VALIDATE_STUB_FILES=1'); foreach (range(0, 9) as $level) { unset($outputLines); exec(sprintf('%s %s analyse --no-progress --error-format=prettyJson --level=%d %s %s %s', escapeshellarg(PHP_BINARY), $command, $level, $configPath !== null ? '--configuration ' . escapeshellarg($configPath) : '', $this->shouldAutoloadAnalysedFile() ? sprintf('--autoload-file %s', escapeshellarg($file)) : '', escapeshellarg($file)), $outputLines); $output = implode("\n", $outputLines); try { $actualJson = Json::decode($output, Json::FORCE_ARRAY); } catch (JsonException $e) { throw new JsonException(sprintf('Cannot decode: %s', $output)); } if (count($actualJson['files']) > 0) { $normalizedFilePath = $fileHelper->normalizePath($file); if (!isset($actualJson['files'][$normalizedFilePath])) { $messagesBeforeDiffing = []; } else { $messagesBeforeDiffing = $actualJson['files'][$normalizedFilePath]['messages']; } foreach ($this->getAdditionalAnalysedFiles() as $additionalAnalysedFile) { $normalizedAdditionalFilePath = $fileHelper->normalizePath($additionalAnalysedFile); if (!isset($actualJson['files'][$normalizedAdditionalFilePath])) { continue; } $messagesBeforeDiffing = array_merge($messagesBeforeDiffing, $actualJson['files'][$normalizedAdditionalFilePath]['messages']); } } else { $messagesBeforeDiffing = []; } $messages = []; foreach ($messagesBeforeDiffing as $message) { foreach ($previousMessages as $lastMessage) { if ($message['message'] === $lastMessage['message'] && $message['line'] === $lastMessage['line']) { continue 2; } } unset($message['tip']); unset($message['identifier']); $messages[] = $message; } $missingMessages = []; foreach ($previousMessages as $previousMessage) { foreach ($messagesBeforeDiffing as $message) { if ($previousMessage['message'] === $message['message'] && $previousMessage['line'] === $message['line']) { continue 2; } } unset($previousMessage['tip']); $missingMessages[] = $previousMessage; } $previousMessages = array_merge($previousMessages, $messages); $expectedJsonFile = sprintf('%s/%s-%d%s.json', $this->getDataPath(), $topic, $level, $this->getResultSuffix()); $exception = $this->compareFiles($expectedJsonFile, $messages); if ($exception !== null) { $exceptions[] = $exception; } $expectedJsonMissingFile = sprintf('%s/%s-%d-missing%s.json', $this->getDataPath(), $topic, $level, $this->getResultSuffix()); $exception = $this->compareFiles($expectedJsonMissingFile, $missingMessages); if ($exception === null) { continue; } $exceptions[] = $exception; } if (count($exceptions) > 0) { throw $exceptions[0]; } } /** * @return string[] */ public function getAdditionalAnalysedFiles() : array { return []; } /** * @param string[] $expectedMessages */ private function compareFiles(string $expectedJsonFile, array $expectedMessages) : ?AssertionFailedError { if (count($expectedMessages) === 0) { try { self::ourCustomAssertFileDoesNotExist($expectedJsonFile); return null; } catch (AssertionFailedError $e) { unlink($expectedJsonFile); return $e; } } $actualOutput = Json::encode($expectedMessages, Json::PRETTY); try { $this->assertJsonStringEqualsJsonFile($expectedJsonFile, $actualOutput); } catch (AssertionFailedError $e) { FileWriter::write($expectedJsonFile, $actualOutput); return $e; } return null; } public static function ourCustomAssertFileDoesNotExist(string $filename, string $message = '') : void { // this method is no longer called assertFileDoesNotExist because this method is final in PHPUnit 10 if (!method_exists(parent::class, 'assertFileDoesNotExist')) { parent::assertFileNotExists($filename, $message); return; } parent::assertFileDoesNotExist($filename, $message); } } parameters: inferPrivatePropertyTypeFromConstructor: true featureToggles: checkUnresolvableParameterTypes: true services: - class: PHPStan\Testing\TestCaseSourceLocatorFactory arguments: phpParser: @phpParserDecorator php8Parser: @php8PhpParser fileExtensions: %fileExtensions% obsoleteExcludesAnalyse: %excludes_analyse% excludePaths: %excludePaths% cacheStorage: class: PHPStan\Cache\MemoryCacheStorage arguments!: [] currentPhpVersionSimpleParser!: factory: @currentPhpVersionRichParser currentPhpVersionLexer: class: PhpParser\Lexer factory: @PHPStan\Parser\LexerFactory::createEmulative() betterReflectionSourceLocator: class: PHPStan\BetterReflection\SourceLocator\Type\SourceLocator factory: @PHPStan\Testing\TestCaseSourceLocatorFactory::create() autowired: false reflectionProvider: factory: @betterReflectionProvider arguments!: [] autowired: - PHPStan\Reflection\ReflectionProvider keyType = $keyType; $this->itemType = $itemType; } public function getKeyType() : \PHPStan\Type\Type { return $this->keyType; } public function getItemType() : \PHPStan\Type\Type { return $this->itemType; } /** * @return string[] */ public function getReferencedClasses() : array { return array_merge($this->keyType->getReferencedClasses(), $this->getItemType()->getReferencedClasses()); } public function getObjectClassNames() : array { return []; } public function getObjectClassReflections() : array { return []; } public function getConstantStrings() : array { return []; } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type->isConstantArray()->yes() && $type->isIterableAtLeastOnce()->no()) { return \PHPStan\Type\AcceptsResult::createYes(); } if ($type->isIterable()->yes()) { return $this->getIterableValueType()->acceptsWithReason($type->getIterableValueType(), $strictTypes)->and($this->getIterableKeyType()->acceptsWithReason($type->getIterableKeyType(), $strictTypes)); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return \PHPStan\Type\AcceptsResult::createNo(); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } return (new \PHPStan\Type\IsSuperTypeOfResult($type->isIterable(), []))->and($this->getIterableValueType()->isSuperTypeOfWithReason($type->getIterableValueType()))->and($this->getIterableKeyType()->isSuperTypeOfWithReason($type->getIterableKeyType())); } public function isSuperTypeOfMixed(\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isIterable()->and($this->isNestedTypeSuperTypeOf($this->getIterableValueType(), $type->getIterableValueType()))->and($this->isNestedTypeSuperTypeOf($this->getIterableKeyType(), $type->getIterableKeyType())); } private function isNestedTypeSuperTypeOf(\PHPStan\Type\Type $a, \PHPStan\Type\Type $b) : TrinaryLogic { if (!$a instanceof \PHPStan\Type\MixedType || !$b instanceof \PHPStan\Type\MixedType) { return $a->isSuperTypeOf($b); } if ($a instanceof TemplateMixedType || $b instanceof TemplateMixedType) { return $a->isSuperTypeOf($b); } if ($a->isExplicitMixed()) { if ($b->isExplicitMixed()) { return TrinaryLogic::createYes(); } return TrinaryLogic::createMaybe(); } return TrinaryLogic::createYes(); } public function isSubTypeOf(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(\PHPStan\Type\Type $otherType) : \PHPStan\Type\IsSuperTypeOfResult { if ($otherType instanceof \PHPStan\Type\IntersectionType || $otherType instanceof \PHPStan\Type\UnionType) { return $otherType->isSuperTypeOfWithReason(new \PHPStan\Type\UnionType([new \PHPStan\Type\ArrayType($this->keyType, $this->itemType), new \PHPStan\Type\IntersectionType([new \PHPStan\Type\ObjectType(Traversable::class), $this])])); } if ($otherType instanceof self) { $limit = \PHPStan\Type\IsSuperTypeOfResult::createYes(); } else { $limit = \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } if ($otherType->isConstantArray()->yes() && $otherType->isIterableAtLeastOnce()->no()) { return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } return $limit->and(new \PHPStan\Type\IsSuperTypeOfResult($otherType->isIterable(), []), $otherType->getIterableValueType()->isSuperTypeOfWithReason($this->itemType), $otherType->getIterableKeyType()->isSuperTypeOfWithReason($this->keyType)); } public function isAcceptedBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : \PHPStan\Type\AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(\PHPStan\Type\Type $type) : bool { if (!$type instanceof self) { return \false; } return $this->keyType->equals($type->keyType) && $this->itemType->equals($type->itemType); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { $isMixedKeyType = $this->keyType instanceof \PHPStan\Type\MixedType && $this->keyType->describe(\PHPStan\Type\VerbosityLevel::precise()) === 'mixed'; $isMixedItemType = $this->itemType instanceof \PHPStan\Type\MixedType && $this->itemType->describe(\PHPStan\Type\VerbosityLevel::precise()) === 'mixed'; if ($isMixedKeyType) { if ($isMixedItemType) { return 'iterable'; } return sprintf('iterable<%s>', $this->itemType->describe($level)); } return sprintf('iterable<%s, %s>', $this->keyType->describe($level), $this->itemType->describe($level)); } public function hasOffsetValueType(\PHPStan\Type\Type $offsetType) : TrinaryLogic { if ($this->getIterableKeyType()->isSuperTypeOf($offsetType)->no()) { return TrinaryLogic::createNo(); } return TrinaryLogic::createMaybe(); } public function toNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toAbsoluteNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toString() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toInteger() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toFloat() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toArray() : \PHPStan\Type\Type { return new \PHPStan\Type\ArrayType($this->keyType, $this->getItemType()); } public function toArrayKey() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isIterable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isIterableAtLeastOnce() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getArraySize() : \PHPStan\Type\Type { return \PHPStan\Type\IntegerRangeType::fromInterval(0, null); } public function getIterableKeyType() : \PHPStan\Type\Type { return $this->keyType; } public function getFirstIterableKeyType() : \PHPStan\Type\Type { return $this->keyType; } public function getLastIterableKeyType() : \PHPStan\Type\Type { return $this->keyType; } public function getIterableValueType() : \PHPStan\Type\Type { return $this->getItemType(); } public function getFirstIterableValueType() : \PHPStan\Type\Type { return $this->getItemType(); } public function getLastIterableValueType() : \PHPStan\Type\Type { return $this->getItemType(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ObjectWithoutClassType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createNo(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function getEnumCases() : array { return []; } public function inferTemplateTypes(\PHPStan\Type\Type $receivedType) : TemplateTypeMap { if ($receivedType instanceof \PHPStan\Type\UnionType || $receivedType instanceof \PHPStan\Type\IntersectionType) { return $receivedType->inferTemplateTypesOn($this); } if (!$receivedType->isIterable()->yes()) { return TemplateTypeMap::createEmpty(); } $keyTypeMap = $this->getIterableKeyType()->inferTemplateTypes($receivedType->getIterableKeyType()); $valueTypeMap = $this->getIterableValueType()->inferTemplateTypes($receivedType->getIterableValueType()); return $keyTypeMap->union($valueTypeMap); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { $variance = $positionVariance->compose(TemplateTypeVariance::createCovariant()); return array_merge($this->getIterableKeyType()->getReferencedTemplateTypes($variance), $this->getIterableValueType()->getReferencedTemplateTypes($variance)); } public function traverse(callable $cb) : \PHPStan\Type\Type { $keyType = $cb($this->keyType); $itemType = $cb($this->itemType); if ($keyType !== $this->keyType || $itemType !== $this->itemType) { return new self($keyType, $itemType); } return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { $keyType = $cb($this->keyType, $right->getIterableKeyType()); $itemType = $cb($this->itemType, $right->getIterableValueType()); if ($keyType !== $this->keyType || $itemType !== $this->itemType) { return new self($keyType, $itemType); } return $this; } public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type { $arrayType = new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType(), new \PHPStan\Type\MixedType()); if ($typeToRemove->isSuperTypeOf($arrayType)->yes()) { return new GenericObjectType(Traversable::class, [$this->getIterableKeyType(), $this->getIterableValueType()]); } $traversableType = new \PHPStan\Type\ObjectType(Traversable::class); if ($typeToRemove->isSuperTypeOf($traversableType)->yes()) { return new \PHPStan\Type\ArrayType($this->getIterableKeyType(), $this->getIterableValueType()); } return null; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { $isMixedKeyType = $this->keyType instanceof \PHPStan\Type\MixedType && $this->keyType->describe(\PHPStan\Type\VerbosityLevel::precise()) === 'mixed'; $isMixedItemType = $this->itemType instanceof \PHPStan\Type\MixedType && $this->itemType->describe(\PHPStan\Type\VerbosityLevel::precise()) === 'mixed'; if ($isMixedKeyType) { if ($isMixedItemType) { return new IdentifierTypeNode('iterable'); } return new GenericTypeNode(new IdentifierTypeNode('iterable'), [$this->itemType->toPhpDocNode()]); } return new GenericTypeNode(new IdentifierTypeNode('iterable'), [$this->keyType->toPhpDocNode(), $this->itemType->toPhpDocNode()]); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['keyType'], $properties['itemType']); } } min = $min; $this->max = $max; parent::__construct(); assert($min === null || $max === null || $min <= $max); assert($min !== null || $max !== null); } public static function fromInterval(?int $min, ?int $max, int $shift = 0) : \PHPStan\Type\Type { if ($min !== null && $max !== null) { if ($min > $max) { return new \PHPStan\Type\NeverType(); } if ($min === $max) { return new ConstantIntegerType($min + $shift); } } if ($min === null && $max === null) { return new \PHPStan\Type\IntegerType(); } return (new self($min, $max))->shift($shift); } protected static function isDisjoint(?int $minA, ?int $maxA, ?int $minB, ?int $maxB, bool $touchingIsDisjoint = \true) : bool { $offset = $touchingIsDisjoint ? 0 : 1; return $minA !== null && $maxB !== null && $minA > $maxB + $offset || $maxA !== null && $minB !== null && $maxA + $offset < $minB; } /** * Return the range of integers smaller than the given value * * @param int|float $value */ public static function createAllSmallerThan($value) : \PHPStan\Type\Type { if (is_int($value)) { return self::fromInterval(null, $value, -1); } if ($value > PHP_INT_MAX) { return new \PHPStan\Type\IntegerType(); } if ($value <= PHP_INT_MIN) { return new \PHPStan\Type\NeverType(); } return self::fromInterval(null, (int) ceil($value), -1); } /** * Return the range of integers smaller than or equal to the given value * * @param int|float $value */ public static function createAllSmallerThanOrEqualTo($value) : \PHPStan\Type\Type { if (is_int($value)) { return self::fromInterval(null, $value); } if ($value >= PHP_INT_MAX) { return new \PHPStan\Type\IntegerType(); } if ($value < PHP_INT_MIN) { return new \PHPStan\Type\NeverType(); } return self::fromInterval(null, (int) floor($value)); } /** * Return the range of integers greater than the given value * * @param int|float $value */ public static function createAllGreaterThan($value) : \PHPStan\Type\Type { if (is_int($value)) { return self::fromInterval($value, null, 1); } if ($value < PHP_INT_MIN) { return new \PHPStan\Type\IntegerType(); } if ($value >= PHP_INT_MAX) { return new \PHPStan\Type\NeverType(); } return self::fromInterval((int) floor($value), null, 1); } /** * Return the range of integers greater than or equal to the given value * * @param int|float $value */ public static function createAllGreaterThanOrEqualTo($value) : \PHPStan\Type\Type { if (is_int($value)) { return self::fromInterval($value, null); } if ($value <= PHP_INT_MIN) { return new \PHPStan\Type\IntegerType(); } if ($value > PHP_INT_MAX) { return new \PHPStan\Type\NeverType(); } return self::fromInterval((int) ceil($value), null); } public function getMin() : ?int { return $this->min; } public function getMax() : ?int { return $this->max; } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return sprintf('int<%s, %s>', $this->min ?? 'min', $this->max ?? 'max'); } public function shift(int $amount) : \PHPStan\Type\Type { if ($amount === 0) { return $this; } $min = $this->min; $max = $this->max; if ($amount < 0) { if ($max !== null) { if ($max < PHP_INT_MIN - $amount) { return new \PHPStan\Type\NeverType(); } $max += $amount; } if ($min !== null) { $min = $min < PHP_INT_MIN - $amount ? null : $min + $amount; } } else { if ($min !== null) { if ($min > PHP_INT_MAX - $amount) { return new \PHPStan\Type\NeverType(); } $min += $amount; } if ($max !== null) { $max = $max > PHP_INT_MAX - $amount ? null : $max + $amount; } } return self::fromInterval($min, $max); } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof parent) { return $this->isSuperTypeOfWithReason($type)->toAcceptsResult(); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return \PHPStan\Type\AcceptsResult::createNo(); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self || $type instanceof ConstantIntegerType) { if ($type instanceof self) { $typeMin = $type->min; $typeMax = $type->max; } else { $typeMin = $type->getValue(); $typeMax = $type->getValue(); } if (self::isDisjoint($this->min, $this->max, $typeMin, $typeMax)) { return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } if (($this->min === null || $typeMin !== null && $this->min <= $typeMin) && ($this->max === null || $typeMax !== null && $this->max >= $typeMax)) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } if ($type instanceof parent) { return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } public function isSubTypeOf(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(\PHPStan\Type\Type $otherType) : \PHPStan\Type\IsSuperTypeOfResult { if ($otherType instanceof parent) { return $otherType->isSuperTypeOfWithReason($this); } if ($otherType instanceof \PHPStan\Type\UnionType) { return $this->isSubTypeOfUnionWithReason($otherType); } if ($otherType instanceof \PHPStan\Type\IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } private function isSubTypeOfUnionWithReason(\PHPStan\Type\UnionType $otherType) : \PHPStan\Type\IsSuperTypeOfResult { if ($this->min !== null && $this->max !== null) { $matchingConstantIntegers = array_filter($otherType->getTypes(), function (\PHPStan\Type\Type $type) : bool { return $type instanceof ConstantIntegerType && $type->getValue() >= $this->min && $type->getValue() <= $this->max; }); if (count($matchingConstantIntegers) === $this->max - $this->min + 1) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } } return \PHPStan\Type\IsSuperTypeOfResult::createNo()->or(...array_map(function (\PHPStan\Type\Type $innerType) { return $this->isSubTypeOfWithReason($innerType); }, $otherType->getTypes())); } public function isAcceptedBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : \PHPStan\Type\AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self && $this->min === $type->min && $this->max === $type->max; } public function generalize(\PHPStan\Type\GeneralizePrecision $precision) : \PHPStan\Type\Type { return new \PHPStan\Type\IntegerType(); } public function isSmallerThan(\PHPStan\Type\Type $otherType) : TrinaryLogic { if ($this->min === null) { $minIsSmaller = TrinaryLogic::createYes(); } else { $minIsSmaller = (new ConstantIntegerType($this->min))->isSmallerThan($otherType); } if ($this->max === null) { $maxIsSmaller = TrinaryLogic::createNo(); } else { $maxIsSmaller = (new ConstantIntegerType($this->max))->isSmallerThan($otherType); } return TrinaryLogic::extremeIdentity($minIsSmaller, $maxIsSmaller); } public function isSmallerThanOrEqual(\PHPStan\Type\Type $otherType) : TrinaryLogic { if ($this->min === null) { $minIsSmaller = TrinaryLogic::createYes(); } else { $minIsSmaller = (new ConstantIntegerType($this->min))->isSmallerThanOrEqual($otherType); } if ($this->max === null) { $maxIsSmaller = TrinaryLogic::createNo(); } else { $maxIsSmaller = (new ConstantIntegerType($this->max))->isSmallerThanOrEqual($otherType); } return TrinaryLogic::extremeIdentity($minIsSmaller, $maxIsSmaller); } public function isGreaterThan(\PHPStan\Type\Type $otherType) : TrinaryLogic { if ($this->min === null) { $minIsSmaller = TrinaryLogic::createNo(); } else { $minIsSmaller = $otherType->isSmallerThan(new ConstantIntegerType($this->min)); } if ($this->max === null) { $maxIsSmaller = TrinaryLogic::createYes(); } else { $maxIsSmaller = $otherType->isSmallerThan(new ConstantIntegerType($this->max)); } return TrinaryLogic::extremeIdentity($minIsSmaller, $maxIsSmaller); } public function isGreaterThanOrEqual(\PHPStan\Type\Type $otherType) : TrinaryLogic { if ($this->min === null) { $minIsSmaller = TrinaryLogic::createNo(); } else { $minIsSmaller = $otherType->isSmallerThanOrEqual(new ConstantIntegerType($this->min)); } if ($this->max === null) { $maxIsSmaller = TrinaryLogic::createYes(); } else { $maxIsSmaller = $otherType->isSmallerThanOrEqual(new ConstantIntegerType($this->max)); } return TrinaryLogic::extremeIdentity($minIsSmaller, $maxIsSmaller); } public function getSmallerType() : \PHPStan\Type\Type { $subtractedTypes = [new ConstantBooleanType(\true)]; if ($this->max !== null) { $subtractedTypes[] = self::createAllGreaterThanOrEqualTo($this->max); } return \PHPStan\Type\TypeCombinator::remove(new \PHPStan\Type\MixedType(), \PHPStan\Type\TypeCombinator::union(...$subtractedTypes)); } public function getSmallerOrEqualType() : \PHPStan\Type\Type { $subtractedTypes = []; if ($this->max !== null) { $subtractedTypes[] = self::createAllGreaterThan($this->max); } return \PHPStan\Type\TypeCombinator::remove(new \PHPStan\Type\MixedType(), \PHPStan\Type\TypeCombinator::union(...$subtractedTypes)); } public function getGreaterType() : \PHPStan\Type\Type { $subtractedTypes = [new \PHPStan\Type\NullType(), new ConstantBooleanType(\false)]; if ($this->min !== null) { $subtractedTypes[] = self::createAllSmallerThanOrEqualTo($this->min); } if ($this->min !== null && $this->min > 0 || $this->max !== null && $this->max < 0) { $subtractedTypes[] = new ConstantBooleanType(\true); } return \PHPStan\Type\TypeCombinator::remove(new \PHPStan\Type\MixedType(), \PHPStan\Type\TypeCombinator::union(...$subtractedTypes)); } public function getGreaterOrEqualType() : \PHPStan\Type\Type { $subtractedTypes = []; if ($this->min !== null) { $subtractedTypes[] = self::createAllSmallerThan($this->min); } if ($this->min !== null && $this->min > 0 || $this->max !== null && $this->max < 0) { $subtractedTypes[] = new \PHPStan\Type\NullType(); $subtractedTypes[] = new ConstantBooleanType(\false); } return \PHPStan\Type\TypeCombinator::remove(new \PHPStan\Type\MixedType(), \PHPStan\Type\TypeCombinator::union(...$subtractedTypes)); } public function toBoolean() : \PHPStan\Type\BooleanType { $isZero = (new ConstantIntegerType(0))->isSuperTypeOf($this); if ($isZero->no()) { return new ConstantBooleanType(\true); } if ($isZero->maybe()) { return new \PHPStan\Type\BooleanType(); } return new ConstantBooleanType(\false); } public function toAbsoluteNumber() : \PHPStan\Type\Type { if ($this->min !== null && $this->min >= 0) { return $this; } if ($this->max === null || $this->max >= 0) { $inversedMin = $this->min !== null ? $this->min * -1 : null; return self::fromInterval(0, $inversedMin !== null && $this->max !== null ? max($inversedMin, $this->max) : null); } return self::fromInterval($this->max * -1, $this->min !== null ? $this->min * -1 : null); } public function toString() : \PHPStan\Type\Type { $finiteTypes = $this->getFiniteTypes(); if ($finiteTypes !== []) { return \PHPStan\Type\TypeCombinator::union(...$finiteTypes)->toString(); } $isZero = (new ConstantIntegerType(0))->isSuperTypeOf($this); if ($isZero->no()) { return new \PHPStan\Type\IntersectionType([new \PHPStan\Type\StringType(), new AccessoryLowercaseStringType(), new AccessoryUppercaseStringType(), new AccessoryNumericStringType(), new AccessoryNonFalsyStringType()]); } return new \PHPStan\Type\IntersectionType([new \PHPStan\Type\StringType(), new AccessoryLowercaseStringType(), new AccessoryUppercaseStringType(), new AccessoryNumericStringType()]); } /** * Return the union with another type, but only if it can be expressed in a simpler way than using UnionType * */ public function tryUnion(\PHPStan\Type\Type $otherType) : ?\PHPStan\Type\Type { if ($otherType instanceof self || $otherType instanceof ConstantIntegerType) { if ($otherType instanceof self) { $otherMin = $otherType->min; $otherMax = $otherType->max; } else { $otherMin = $otherType->getValue(); $otherMax = $otherType->getValue(); } if (self::isDisjoint($this->min, $this->max, $otherMin, $otherMax, \false)) { return null; } return self::fromInterval($this->min !== null && $otherMin !== null ? min($this->min, $otherMin) : null, $this->max !== null && $otherMax !== null ? max($this->max, $otherMax) : null); } if (get_class($otherType) === parent::class) { return $otherType; } return null; } /** * Return the intersection with another type, but only if it can be expressed in a simpler way than using * IntersectionType * */ public function tryIntersect(\PHPStan\Type\Type $otherType) : ?\PHPStan\Type\Type { if ($otherType instanceof self || $otherType instanceof ConstantIntegerType) { if ($otherType instanceof self) { $otherMin = $otherType->min; $otherMax = $otherType->max; } else { $otherMin = $otherType->getValue(); $otherMax = $otherType->getValue(); } if (self::isDisjoint($this->min, $this->max, $otherMin, $otherMax, \false)) { return new \PHPStan\Type\NeverType(); } if ($this->min === null) { $newMin = $otherMin; } elseif ($otherMin === null) { $newMin = $this->min; } else { $newMin = max($this->min, $otherMin); } if ($this->max === null) { $newMax = $otherMax; } elseif ($otherMax === null) { $newMax = $this->max; } else { $newMax = min($this->max, $otherMax); } return self::fromInterval($newMin, $newMax); } if (get_class($otherType) === parent::class) { return $this; } return null; } /** * Return the different with another type, or null if it cannot be represented. * */ public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type { if (get_class($typeToRemove) === parent::class) { return new \PHPStan\Type\NeverType(); } if ($typeToRemove instanceof self || $typeToRemove instanceof ConstantIntegerType) { if ($typeToRemove instanceof self) { $removeMin = $typeToRemove->min; $removeMax = $typeToRemove->max; } else { $removeMin = $typeToRemove->getValue(); $removeMax = $typeToRemove->getValue(); } if ($this->min !== null && $removeMax !== null && $removeMax < $this->min || $this->max !== null && $removeMin !== null && $this->max < $removeMin) { return $this; } if ($removeMin !== null && $removeMin !== PHP_INT_MIN) { $lowerPart = self::fromInterval($this->min, $removeMin - 1); } else { $lowerPart = null; } if ($removeMax !== null && $removeMax !== PHP_INT_MAX) { $upperPart = self::fromInterval($removeMax + 1, $this->max); } else { $upperPart = null; } if ($lowerPart !== null && $upperPart !== null) { return \PHPStan\Type\TypeCombinator::union($lowerPart, $upperPart); } return $lowerPart ?? $upperPart; } return null; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { if ($exponent instanceof \PHPStan\Type\UnionType) { $results = []; foreach ($exponent->getTypes() as $unionType) { $results[] = $this->exponentiate($unionType); } return \PHPStan\Type\TypeCombinator::union(...$results); } if ($exponent instanceof \PHPStan\Type\IntegerRangeType) { $min = null; $max = null; if ($this->getMin() !== null && $exponent->getMin() !== null) { $min = $this->getMin() ** $exponent->getMin(); } if ($this->getMax() !== null && $exponent->getMax() !== null) { $max = $this->getMax() ** $exponent->getMax(); } if (($min !== null || $max !== null) && !is_float($min) && !is_float($max)) { return self::fromInterval($min, $max); } } if ($exponent instanceof \PHPStan\Type\ConstantScalarType) { $exponentValue = $exponent->getValue(); if (is_int($exponentValue)) { $min = null; $max = null; if ($this->getMin() !== null) { $min = $this->getMin() ** $exponentValue; } if ($this->getMax() !== null) { $max = $this->getMax() ** $exponentValue; } if (!is_float($min) && !is_float($max)) { return self::fromInterval($min, $max); } } } return parent::exponentiate($exponent); } /** * @return list */ public function getFiniteTypes() : array { if ($this->min === null || $this->max === null) { return []; } $size = $this->max - $this->min; if ($size > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT) { return []; } $types = []; for ($i = $this->min; $i <= $this->max; $i++) { $types[] = new ConstantIntegerType($i); } return $types; } public function toPhpDocNode() : TypeNode { if ($this->min === null) { $min = new IdentifierTypeNode('min'); } else { $min = new ConstTypeNode(new ConstExprIntegerNode((string) $this->min)); } if ($this->max === null) { $max = new IdentifierTypeNode('max'); } else { $max = new ConstTypeNode(new ConstExprIntegerNode((string) $this->max)); } return new GenericTypeNode(new IdentifierTypeNode('int'), [$min, $max]); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { if ($this->isSmallerThan($type)->yes() || $this->isGreaterThan($type)->yes()) { return new ConstantBooleanType(\false); } return parent::looseCompare($type, $phpVersion); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['min'], $properties['max']); } } subject = $subject; $this->target = $target; $this->if = $if; $this->else = $else; $this->negated = $negated; } public function getSubject() : \PHPStan\Type\Type { return $this->subject; } public function getTarget() : \PHPStan\Type\Type { return $this->target; } public function getIf() : \PHPStan\Type\Type { return $this->if; } public function getElse() : \PHPStan\Type\Type { return $this->else; } public function isNegated() : bool { return $this->negated; } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self) { return $this->if->isSuperTypeOfWithReason($type->if)->and($this->else->isSuperTypeOfWithReason($type->else)); } return $this->isSuperTypeOfDefault($type); } public function getReferencedClasses() : array { return array_merge($this->subject->getReferencedClasses(), $this->target->getReferencedClasses(), $this->if->getReferencedClasses(), $this->else->getReferencedClasses()); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { return array_merge($this->subject->getReferencedTemplateTypes($positionVariance), $this->target->getReferencedTemplateTypes($positionVariance), $this->if->getReferencedTemplateTypes($positionVariance), $this->else->getReferencedTemplateTypes($positionVariance)); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self && $this->subject->equals($type->subject) && $this->target->equals($type->target) && $this->if->equals($type->if) && $this->else->equals($type->else); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return sprintf('(%s %s %s ? %s : %s)', $this->subject->describe($level), $this->negated ? 'is not' : 'is', $this->target->describe($level), $this->if->describe($level), $this->else->describe($level)); } public function isResolvable() : bool { return !\PHPStan\Type\TypeUtils::containsTemplateType($this->subject) && !\PHPStan\Type\TypeUtils::containsTemplateType($this->target); } protected function getResult() : \PHPStan\Type\Type { $isSuperType = $this->target->isSuperTypeOf($this->subject); if ($isSuperType->yes()) { return !$this->negated ? $this->getNormalizedIf() : $this->getNormalizedElse(); } if ($isSuperType->no()) { return !$this->negated ? $this->getNormalizedElse() : $this->getNormalizedIf(); } return \PHPStan\Type\TypeCombinator::union($this->getNormalizedIf(), $this->getNormalizedElse()); } public function traverse(callable $cb) : \PHPStan\Type\Type { $subject = $cb($this->subject); $target = $cb($this->target); $if = $cb($this->getNormalizedIf()); $else = $cb($this->getNormalizedElse()); if ($this->subject === $subject && $this->target === $target && $this->getNormalizedIf() === $if && $this->getNormalizedElse() === $else) { return $this; } return new self($subject, $target, $if, $else, $this->negated); } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if (!$right instanceof self) { return $this; } $subject = $cb($this->subject, $right->subject); $target = $cb($this->target, $right->target); $if = $cb($this->getNormalizedIf(), $right->getNormalizedIf()); $else = $cb($this->getNormalizedElse(), $right->getNormalizedElse()); if ($this->subject === $subject && $this->target === $target && $this->getNormalizedIf() === $if && $this->getNormalizedElse() === $else) { return $this; } return new self($subject, $target, $if, $else, $this->negated); } public function toPhpDocNode() : TypeNode { return new ConditionalTypeNode($this->subject->toPhpDocNode(), $this->target->toPhpDocNode(), $this->if->toPhpDocNode(), $this->else->toPhpDocNode(), $this->negated); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['subject'], $properties['target'], $properties['if'], $properties['else'], $properties['negated']); } private function getNormalizedIf() : \PHPStan\Type\Type { return $this->normalizedIf = $this->normalizedIf ?? \PHPStan\Type\TypeTraverser::map($this->if, function (\PHPStan\Type\Type $type, callable $traverse) { return $type === $this->subject ? !$this->negated ? $this->getSubjectWithTargetIntersectedType() : $this->getSubjectWithTargetRemovedType() : $traverse($type); }); } private function getNormalizedElse() : \PHPStan\Type\Type { return $this->normalizedElse = $this->normalizedElse ?? \PHPStan\Type\TypeTraverser::map($this->else, function (\PHPStan\Type\Type $type, callable $traverse) { return $type === $this->subject ? !$this->negated ? $this->getSubjectWithTargetRemovedType() : $this->getSubjectWithTargetIntersectedType() : $traverse($type); }); } private function getSubjectWithTargetIntersectedType() : \PHPStan\Type\Type { return $this->subjectWithTargetIntersectedType = $this->subjectWithTargetIntersectedType ?? \PHPStan\Type\TypeCombinator::intersect($this->subject, $this->target); } private function getSubjectWithTargetRemovedType() : \PHPStan\Type\Type { return $this->subjectWithTargetRemovedType = $this->subjectWithTargetRemovedType ?? \PHPStan\Type\TypeCombinator::remove($this->subject, $this->target); } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return new \PHPStan\Type\AcceptsResult($type->isVoid()->or($type->isNull()), []); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self; } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return 'void'; } public function toNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toAbsoluteNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toString() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toInteger() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toFloat() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toArray() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toArrayKey() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createNo(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function traverse(callable $cb) : \PHPStan\Type\Type { return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { return $this; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('void'); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self(); } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { return \PHPStan\Type\AcceptsResult::createYes(); } public function isAcceptedBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($acceptingType instanceof self) { return \PHPStan\Type\AcceptsResult::createYes(); } if ($acceptingType instanceof \PHPStan\Type\MixedType && !$acceptingType instanceof TemplateMixedType) { return \PHPStan\Type\AcceptsResult::createYes(); } return \PHPStan\Type\AcceptsResult::createMaybe(); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } public function isSubTypeOf(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(\PHPStan\Type\Type $otherType) : \PHPStan\Type\IsSuperTypeOfResult { if ($otherType instanceof self) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } if ($otherType instanceof \PHPStan\Type\MixedType && !$otherType instanceof TemplateMixedType) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self; } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return $level->handle(static function () { return 'mixed'; }, static function () { return 'mixed'; }, static function () { return 'mixed'; }, static function () { return 'strict-mixed'; }); } public function getTemplateType(string $ancestorClassName, string $templateTypeName) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function isObject() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isEnum() : TrinaryLogic { return TrinaryLogic::createNo(); } public function canAccessProperties() : TrinaryLogic { return TrinaryLogic::createNo(); } public function hasProperty(string $propertyName) : TrinaryLogic { return TrinaryLogic::createNo(); } public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection { throw new ShouldNotHappenException(); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { throw new ShouldNotHappenException(); } public function canCallMethods() : TrinaryLogic { return TrinaryLogic::createNo(); } public function hasMethod(string $methodName) : TrinaryLogic { return TrinaryLogic::createNo(); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { throw new ShouldNotHappenException(); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { throw new ShouldNotHappenException(); } public function canAccessConstants() : TrinaryLogic { return TrinaryLogic::createNo(); } public function hasConstant(string $constantName) : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstant(string $constantName) : ConstantReflection { throw new ShouldNotHappenException(); } public function isIterable() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isIterableAtLeastOnce() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getIterableKeyType() : \PHPStan\Type\Type { return $this; } public function getIterableValueType() : \PHPStan\Type\Type { return $this; } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createNo(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function hasOffsetValueType(\PHPStan\Type\Type $offsetType) : TrinaryLogic { return TrinaryLogic::createNo(); } public function getOffsetValueType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function setOffsetValueType(?\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType, bool $unionValues = \true) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function setExistingOffsetValueType(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function unsetOffset(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function isCallable() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { return []; } public function isCloneable() : TrinaryLogic { return TrinaryLogic::createNo(); } public function toBoolean() : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function toNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toAbsoluteNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toInteger() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toFloat() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toString() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toArray() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toArrayKey() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function inferTemplateTypes(\PHPStan\Type\Type $receivedType) : TemplateTypeMap { return TemplateTypeMap::createEmpty(); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { return []; } public function getEnumCases() : array { return []; } public function traverse(callable $cb) : \PHPStan\Type\Type { return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { return $this; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('mixed'); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self(); } } */ private $templateTags; use MaybeArrayTypeTrait; use MaybeIterableTypeTrait; use MaybeObjectTypeTrait; use MaybeOffsetAccessibleTypeTrait; use TruthyBooleanTypeTrait; use UndecidedComparisonCompoundTypeTrait; use NonRemoveableTypeTrait; use NonGeneralizableTypeTrait; /** @var array */ private $parameters; /** * @var Type */ private $returnType; /** * @var bool */ private $isCommonCallable; /** * @var TemplateTypeMap */ private $templateTypeMap; /** * @var TemplateTypeMap */ private $resolvedTemplateTypeMap; /** * @var TrinaryLogic */ private $isPure; /** * @api * @param array|null $parameters * @param array $templateTags */ public function __construct(?array $parameters = null, ?\PHPStan\Type\Type $returnType = null, bool $variadic = \true, ?TemplateTypeMap $templateTypeMap = null, ?TemplateTypeMap $resolvedTemplateTypeMap = null, array $templateTags = [], ?TrinaryLogic $isPure = null) { $this->variadic = $variadic; $this->templateTags = $templateTags; $this->parameters = $parameters ?? []; $this->returnType = $returnType ?? new \PHPStan\Type\MixedType(); $this->isCommonCallable = $parameters === null && $returnType === null; $this->templateTypeMap = $templateTypeMap ?? TemplateTypeMap::createEmpty(); $this->resolvedTemplateTypeMap = $resolvedTemplateTypeMap ?? TemplateTypeMap::createEmpty(); $this->isPure = $isPure ?? TrinaryLogic::createMaybe(); } /** * @return array */ public function getTemplateTags() : array { return $this->templateTags; } public function isPure() : TrinaryLogic { return $this->isPure; } /** * @return string[] */ public function getReferencedClasses() : array { $classes = []; foreach ($this->parameters as $parameter) { $classes = array_merge($classes, $parameter->getType()->getReferencedClasses()); } return array_merge($classes, $this->returnType->getReferencedClasses()); } public function getObjectClassNames() : array { return []; } public function getObjectClassReflections() : array { return []; } public function getConstantStrings() : array { return []; } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof \PHPStan\Type\CompoundType && !$type instanceof self) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return $this->isSuperTypeOfInternal($type, \true)->toAcceptsResult(); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof \PHPStan\Type\CompoundType && !$type instanceof self) { return $type->isSubTypeOfWithReason($this); } return $this->isSuperTypeOfInternal($type, \false); } private function isSuperTypeOfInternal(\PHPStan\Type\Type $type, bool $treatMixedAsAny) : \PHPStan\Type\IsSuperTypeOfResult { $isCallable = new \PHPStan\Type\IsSuperTypeOfResult($type->isCallable(), []); if ($isCallable->no()) { return $isCallable; } static $scope; if ($scope === null) { $scope = new OutOfClassScope(); } if ($this->isCommonCallable) { if ($this->isPure()->yes()) { $typePure = TrinaryLogic::createYes(); foreach ($type->getCallableParametersAcceptors($scope) as $variant) { $typePure = $typePure->and($variant->isPure()); } return $isCallable->and(new \PHPStan\Type\IsSuperTypeOfResult($typePure, [])); } return $isCallable; } $parameterTypes = array_map(static function ($parameter) { return $parameter->getType(); }, $this->getParameters()); $variantsResult = null; foreach ($type->getCallableParametersAcceptors($scope) as $variant) { $variant = ParametersAcceptorSelector::selectFromTypes($parameterTypes, [$variant], \false); if (!$variant instanceof CallableParametersAcceptor) { return \PHPStan\Type\IsSuperTypeOfResult::createNo([]); } $isSuperType = \PHPStan\Type\CallableTypeHelper::isParametersAcceptorSuperTypeOf($this, $variant, $treatMixedAsAny); if ($variantsResult === null) { $variantsResult = $isSuperType; } else { $variantsResult = $variantsResult->or($isSuperType); } } if ($variantsResult === null) { throw new ShouldNotHappenException(); } return $isCallable->and($variantsResult); } public function isSubTypeOf(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(\PHPStan\Type\Type $otherType) : \PHPStan\Type\IsSuperTypeOfResult { if ($otherType instanceof \PHPStan\Type\IntersectionType || $otherType instanceof \PHPStan\Type\UnionType) { return $otherType->isSuperTypeOfWithReason($this); } return (new \PHPStan\Type\IsSuperTypeOfResult($otherType->isCallable(), []))->and($otherType instanceof self ? \PHPStan\Type\IsSuperTypeOfResult::createYes() : \PHPStan\Type\IsSuperTypeOfResult::createMaybe()); } public function isAcceptedBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : \PHPStan\Type\AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(\PHPStan\Type\Type $type) : bool { if (!$type instanceof self) { return \false; } return $this->describe(\PHPStan\Type\VerbosityLevel::precise()) === $type->describe(\PHPStan\Type\VerbosityLevel::precise()); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return $level->handle(static function () : string { return 'callable'; }, function () : string { $printer = new Printer(); $selfWithoutParameterNames = new self(array_map(static function (ParameterReflection $p) : ParameterReflection { return new DummyParameter('', $p->getType(), $p->isOptional() && !$p->isVariadic(), PassedByReference::createNo(), $p->isVariadic(), $p->getDefaultValue()); }, $this->parameters), $this->returnType, $this->variadic, $this->templateTypeMap, $this->resolvedTemplateTypeMap, $this->templateTags, $this->isPure); return $printer->print($selfWithoutParameterNames->toPhpDocNode()); }); } public function isCallable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { return [$this]; } public function getThrowPoints() : array { return [SimpleThrowPoint::createImplicit()]; } public function getImpurePoints() : array { $pure = $this->isPure(); if ($pure->yes()) { return []; } return [new SimpleImpurePoint('functionCall', 'call to a callable', $pure->no())]; } public function getInvalidateExpressions() : array { return []; } public function getUsedVariables() : array { return []; } public function acceptsNamedArguments() : bool { return \true; } public function toNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toAbsoluteNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toString() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toInteger() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toFloat() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toArray() : \PHPStan\Type\Type { return new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType(), new \PHPStan\Type\MixedType()); } public function toArrayKey() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getTemplateTypeMap() : TemplateTypeMap { return $this->templateTypeMap; } public function getResolvedTemplateTypeMap() : TemplateTypeMap { return $this->resolvedTemplateTypeMap; } public function getCallSiteVarianceMap() : TemplateTypeVarianceMap { return TemplateTypeVarianceMap::createEmpty(); } /** * @return array */ public function getParameters() : array { return $this->parameters; } public function isVariadic() : bool { return $this->variadic; } public function getReturnType() : \PHPStan\Type\Type { return $this->returnType; } public function inferTemplateTypes(\PHPStan\Type\Type $receivedType) : TemplateTypeMap { if ($receivedType instanceof \PHPStan\Type\UnionType || $receivedType instanceof \PHPStan\Type\IntersectionType) { return $receivedType->inferTemplateTypesOn($this); } if (!$receivedType->isCallable()->yes()) { return TemplateTypeMap::createEmpty(); } $parametersAcceptors = $receivedType->getCallableParametersAcceptors(new OutOfClassScope()); $typeMap = TemplateTypeMap::createEmpty(); foreach ($parametersAcceptors as $parametersAcceptor) { $typeMap = $typeMap->union($this->inferTemplateTypesOnParametersAcceptor($parametersAcceptor)); } return $typeMap; } private function inferTemplateTypesOnParametersAcceptor(ParametersAcceptor $parametersAcceptor) : TemplateTypeMap { $parameterTypes = array_map(static function ($parameter) { return $parameter->getType(); }, $this->getParameters()); $parametersAcceptor = ParametersAcceptorSelector::selectFromTypes($parameterTypes, [$parametersAcceptor], \false); $args = $parametersAcceptor->getParameters(); $returnType = $parametersAcceptor->getReturnType(); $typeMap = TemplateTypeMap::createEmpty(); foreach ($this->getParameters() as $i => $param) { $paramType = $param->getType(); if (isset($args[$i])) { $argType = $args[$i]->getType(); } elseif ($paramType instanceof TemplateType) { $argType = TemplateTypeHelper::resolveToBounds($paramType); } else { $argType = new \PHPStan\Type\NeverType(); } $typeMap = $typeMap->union($paramType->inferTemplateTypes($argType)->convertToLowerBoundTypes()); } return $typeMap->union($this->getReturnType()->inferTemplateTypes($returnType)); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { $references = $this->getReturnType()->getReferencedTemplateTypes($positionVariance->compose(TemplateTypeVariance::createCovariant())); $paramVariance = $positionVariance->compose(TemplateTypeVariance::createContravariant()); foreach ($this->getParameters() as $param) { foreach ($param->getType()->getReferencedTemplateTypes($paramVariance) as $reference) { $references[] = $reference; } } return $references; } public function traverse(callable $cb) : \PHPStan\Type\Type { if ($this->isCommonCallable) { return $this; } $parameters = array_map(static function (ParameterReflection $param) use($cb) : NativeParameterReflection { $defaultValue = $param->getDefaultValue(); return new NativeParameterReflection($param->getName(), $param->isOptional(), $cb($param->getType()), $param->passedByReference(), $param->isVariadic(), $defaultValue !== null ? $cb($defaultValue) : null); }, $this->getParameters()); return new self($parameters, $cb($this->getReturnType()), $this->isVariadic(), $this->templateTypeMap, $this->resolvedTemplateTypeMap, $this->templateTags, $this->isPure); } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if ($this->isCommonCallable) { return $this; } if (!$right->isCallable()->yes()) { return $this; } $rightAcceptors = $right->getCallableParametersAcceptors(new OutOfClassScope()); if (count($rightAcceptors) !== 1) { return $this; } $rightParameters = $rightAcceptors[0]->getParameters(); if (count($this->getParameters()) !== count($rightParameters)) { return $this; } $parameters = []; foreach ($this->getParameters() as $i => $leftParam) { $rightParam = $rightParameters[$i]; $leftDefaultValue = $leftParam->getDefaultValue(); $rightDefaultValue = $rightParam->getDefaultValue(); $defaultValue = $leftDefaultValue; if ($leftDefaultValue !== null && $rightDefaultValue !== null) { $defaultValue = $cb($leftDefaultValue, $rightDefaultValue); } $parameters[] = new NativeParameterReflection($leftParam->getName(), $leftParam->isOptional(), $cb($leftParam->getType(), $rightParam->getType()), $leftParam->passedByReference(), $leftParam->isVariadic(), $defaultValue); } return new self($parameters, $cb($this->getReturnType(), $rightAcceptors[0]->getReturnType()), $this->isVariadic(), $this->templateTypeMap, $this->resolvedTemplateTypeMap, $this->templateTags, $this->isPure); } public function isOversizedArray() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ObjectWithoutClassType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ObjectWithoutClassType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function getEnumCases() : array { return []; } public function isCommonCallable() : bool { return $this->isCommonCallable; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { if ($this->isCommonCallable) { return new IdentifierTypeNode($this->isPure()->yes() ? 'pure-callable' : 'callable'); } $parameters = []; foreach ($this->parameters as $parameter) { $parameters[] = new CallableTypeParameterNode($parameter->getType()->toPhpDocNode(), !$parameter->passedByReference()->no(), $parameter->isVariadic(), $parameter->getName() === '' ? '' : '$' . $parameter->getName(), $parameter->isOptional()); } $templateTags = []; foreach ($this->templateTags as $templateName => $templateTag) { $templateTags[] = new TemplateTagValueNode($templateName, $templateTag->getBound()->toPhpDocNode(), ''); } return new CallableTypeNode(new IdentifierTypeNode($this->isPure->yes() ? 'pure-callable' : 'callable'), $parameters, $this->returnType->toPhpDocNode(), $templateTags); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self((bool) $properties['isCommonCallable'] ? null : $properties['parameters'], (bool) $properties['isCommonCallable'] ? null : $properties['returnType'], $properties['variadic'], $properties['templateTypeMap'], $properties['resolvedTemplateTypeMap'], $properties['templateTags'], $properties['isPure']); } } subtractedType = $subtractedType; } /** * @return string[] */ public function getReferencedClasses() : array { return []; } public function getObjectClassNames() : array { return []; } public function getObjectClassReflections() : array { return []; } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return \PHPStan\Type\AcceptsResult::createFromBoolean($type instanceof self || $type instanceof \PHPStan\Type\ObjectShapeType || $type->getObjectClassNames() !== []); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } if ($type instanceof self) { if ($this->subtractedType === null) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } if ($type->subtractedType !== null) { $isSuperType = $type->subtractedType->isSuperTypeOfWithReason($this->subtractedType); if ($isSuperType->yes()) { return $isSuperType; } } return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } if ($type instanceof \PHPStan\Type\ObjectShapeType) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } if ($type->getObjectClassNames() === []) { return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } if ($this->subtractedType === null) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } return $this->subtractedType->isSuperTypeOfWithReason($type)->negate(); } public function equals(\PHPStan\Type\Type $type) : bool { if (!$type instanceof self) { return \false; } if ($this->subtractedType === null) { if ($type->subtractedType === null) { return \true; } return \false; } if ($type->subtractedType === null) { return \false; } return $this->subtractedType->equals($type->subtractedType); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return $level->handle(static function () : string { return 'object'; }, static function () : string { return 'object'; }, function () use($level) : string { $description = 'object'; if ($this->subtractedType !== null) { $description .= $this->subtractedType instanceof \PHPStan\Type\UnionType ? sprintf('~(%s)', $this->subtractedType->describe($level)) : sprintf('~%s', $this->subtractedType->describe($level)); } return $description; }); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getEnumCases() : array { return []; } public function subtract(\PHPStan\Type\Type $type) : \PHPStan\Type\Type { if ($type instanceof self) { return new \PHPStan\Type\NeverType(); } if ($this->subtractedType !== null) { $type = \PHPStan\Type\TypeCombinator::union($this->subtractedType, $type); } return new self($type); } public function getTypeWithoutSubtractedType() : \PHPStan\Type\Type { return new self(); } public function changeSubtractedType(?\PHPStan\Type\Type $subtractedType) : \PHPStan\Type\Type { return new self($subtractedType); } public function getSubtractedType() : ?\PHPStan\Type\Type { return $this->subtractedType; } public function traverse(callable $cb) : \PHPStan\Type\Type { $subtractedType = $this->subtractedType !== null ? $cb($this->subtractedType) : null; if ($subtractedType !== $this->subtractedType) { return new self($subtractedType); } return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if ($this->subtractedType === null) { return $this; } return new self(); } public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type { if ($this->isSuperTypeOf($typeToRemove)->yes()) { return $this->subtract($typeToRemove); } return null; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { if (!$exponent instanceof \PHPStan\Type\NeverType && !$this->isSuperTypeOf($exponent)->no()) { return \PHPStan\Type\TypeCombinator::union($this, $exponent); } return new \PHPStan\Type\BenevolentUnionType([new \PHPStan\Type\FloatType(), new \PHPStan\Type\IntegerType()]); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('object'); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['subtractedType'] ?? null); } } itemType = $itemType; if ($keyType->describe(\PHPStan\Type\VerbosityLevel::value()) === '(int|string)') { $keyType = new \PHPStan\Type\MixedType(); } if ($keyType instanceof \PHPStan\Type\StrictMixedType && !$keyType instanceof TemplateStrictMixedType) { $keyType = new \PHPStan\Type\UnionType([new \PHPStan\Type\StringType(), new \PHPStan\Type\IntegerType()]); } $this->keyType = $keyType; } public function getKeyType() : \PHPStan\Type\Type { return $this->keyType; } public function getItemType() : \PHPStan\Type\Type { return $this->itemType; } /** * @return string[] */ public function getReferencedClasses() : array { return array_merge($this->keyType->getReferencedClasses(), $this->getItemType()->getReferencedClasses()); } public function getObjectClassNames() : array { return []; } public function getObjectClassReflections() : array { return []; } public function getArrays() : array { return [$this]; } public function getConstantArrays() : array { return []; } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } if ($type instanceof ConstantArrayType) { $result = \PHPStan\Type\AcceptsResult::createYes(); $thisKeyType = $this->keyType; $itemType = $this->getItemType(); foreach ($type->getKeyTypes() as $i => $keyType) { $valueType = $type->getValueTypes()[$i]; $acceptsKey = $thisKeyType->acceptsWithReason($keyType, $strictTypes); $acceptsValue = $itemType->acceptsWithReason($valueType, $strictTypes); $result = $result->and($acceptsKey)->and($acceptsValue); } return $result; } if ($type instanceof \PHPStan\Type\ArrayType) { return $this->getItemType()->acceptsWithReason($type->getItemType(), $strictTypes)->and($this->keyType->acceptsWithReason($type->keyType, $strictTypes)); } return \PHPStan\Type\AcceptsResult::createNo(); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self) { return $this->getItemType()->isSuperTypeOfWithReason($type->getItemType())->and($this->getIterableKeyType()->isSuperTypeOfWithReason($type->getIterableKeyType())); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self && $type->isConstantArray()->no() && $this->getItemType()->equals($type->getIterableValueType()) && $this->keyType->equals($type->keyType); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { $isMixedKeyType = $this->keyType instanceof \PHPStan\Type\MixedType && $this->keyType->describe(\PHPStan\Type\VerbosityLevel::precise()) === 'mixed'; $isMixedItemType = $this->itemType instanceof \PHPStan\Type\MixedType && $this->itemType->describe(\PHPStan\Type\VerbosityLevel::precise()) === 'mixed'; $valueHandler = function () use($level, $isMixedKeyType, $isMixedItemType) : string { if ($isMixedKeyType || $this->keyType instanceof \PHPStan\Type\NeverType) { if ($isMixedItemType || $this->itemType instanceof \PHPStan\Type\NeverType) { return 'array'; } return sprintf('array<%s>', $this->itemType->describe($level)); } return sprintf('array<%s, %s>', $this->keyType->describe($level), $this->itemType->describe($level)); }; return $level->handle($valueHandler, $valueHandler, function () use($level, $isMixedKeyType, $isMixedItemType) : string { if ($isMixedKeyType) { if ($isMixedItemType) { return 'array'; } return sprintf('array<%s>', $this->itemType->describe($level)); } return sprintf('array<%s, %s>', $this->keyType->describe($level), $this->itemType->describe($level)); }); } /** * @deprecated */ public function generalizeKeys() : self { return new self($this->keyType->generalize(\PHPStan\Type\GeneralizePrecision::lessSpecific()), $this->itemType); } public function generalizeValues() : self { return new self($this->keyType, $this->itemType->generalize(\PHPStan\Type\GeneralizePrecision::lessSpecific())); } public function getKeysArray() : \PHPStan\Type\Type { return AccessoryArrayListType::intersectWith(new self(new \PHPStan\Type\IntegerType(), $this->getIterableKeyType())); } public function getValuesArray() : \PHPStan\Type\Type { return AccessoryArrayListType::intersectWith(new self(new \PHPStan\Type\IntegerType(), $this->itemType)); } public function isIterable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isIterableAtLeastOnce() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getArraySize() : \PHPStan\Type\Type { return \PHPStan\Type\IntegerRangeType::fromInterval(0, null); } public function getIterableKeyType() : \PHPStan\Type\Type { $keyType = $this->keyType; if ($keyType instanceof \PHPStan\Type\MixedType && !$keyType instanceof TemplateMixedType) { return new \PHPStan\Type\BenevolentUnionType([new \PHPStan\Type\IntegerType(), new \PHPStan\Type\StringType()]); } if ($keyType instanceof \PHPStan\Type\StrictMixedType) { return new \PHPStan\Type\BenevolentUnionType([new \PHPStan\Type\IntegerType(), new \PHPStan\Type\StringType()]); } return $keyType; } public function getFirstIterableKeyType() : \PHPStan\Type\Type { return $this->getIterableKeyType(); } public function getLastIterableKeyType() : \PHPStan\Type\Type { return $this->getIterableKeyType(); } public function getIterableValueType() : \PHPStan\Type\Type { return $this->getItemType(); } public function getFirstIterableValueType() : \PHPStan\Type\Type { return $this->getItemType(); } public function getLastIterableValueType() : \PHPStan\Type\Type { return $this->getItemType(); } public function isArray() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isConstantArray() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isOversizedArray() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isList() : TrinaryLogic { if (\PHPStan\Type\IntegerRangeType::fromInterval(0, null)->isSuperTypeOf($this->getKeyType())->no()) { return TrinaryLogic::createNo(); } if ($this->getKeyType()->isSuperTypeOf(new ConstantIntegerType(0))->no()) { return TrinaryLogic::createNo(); } return TrinaryLogic::createMaybe(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createNo(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(\PHPStan\Type\Type $offsetType) : TrinaryLogic { $offsetType = $offsetType->toArrayKey(); if ($this->getKeyType()->isSuperTypeOf($offsetType)->no() && ($offsetType->isString()->no() || !$offsetType->isConstantScalarValue()->no())) { return TrinaryLogic::createNo(); } return TrinaryLogic::createMaybe(); } public function getOffsetValueType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { $offsetType = $offsetType->toArrayKey(); if ($this->getKeyType()->isSuperTypeOf($offsetType)->no() && ($offsetType->isString()->no() || !$offsetType->isConstantScalarValue()->no())) { return new \PHPStan\Type\ErrorType(); } $type = $this->getItemType(); if ($type instanceof \PHPStan\Type\ErrorType) { return new \PHPStan\Type\MixedType(); } return $type; } public function setOffsetValueType(?\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType, bool $unionValues = \true) : \PHPStan\Type\Type { if ($offsetType === null) { $isKeyTypeInteger = $this->keyType->isInteger(); if ($isKeyTypeInteger->no()) { $offsetType = new \PHPStan\Type\IntegerType(); } elseif ($isKeyTypeInteger->yes()) { /** @var list $constantScalars */ $constantScalars = $this->keyType->getConstantScalarTypes(); if (count($constantScalars) > 0) { foreach ($constantScalars as $constantScalar) { $constantScalars[] = \PHPStan\Type\ConstantTypeHelper::getTypeFromValue($constantScalar->getValue() + 1); } $offsetType = \PHPStan\Type\TypeCombinator::union(...$constantScalars); } else { $offsetType = $this->keyType; } } else { $integerTypes = []; \PHPStan\Type\TypeTraverser::map($this->keyType, static function (\PHPStan\Type\Type $type, callable $traverse) use(&$integerTypes) : \PHPStan\Type\Type { if ($type instanceof \PHPStan\Type\UnionType) { return $traverse($type); } $isInteger = $type->isInteger(); if ($isInteger->yes()) { $integerTypes[] = $type; } return $type; }); if (count($integerTypes) === 0) { $offsetType = $this->keyType; } else { $offsetType = \PHPStan\Type\TypeCombinator::union(...$integerTypes); } } } else { $offsetType = $offsetType->toArrayKey(); } if ($offsetType instanceof ConstantStringType || $offsetType instanceof ConstantIntegerType) { if ($offsetType->isSuperTypeOf($this->keyType)->yes()) { $builder = ConstantArrayTypeBuilder::createEmpty(); $builder->setOffsetValueType($offsetType, $valueType); return $builder->getArray(); } return \PHPStan\Type\TypeCombinator::intersect(new self(\PHPStan\Type\TypeCombinator::union($this->keyType, $offsetType), \PHPStan\Type\TypeCombinator::union($this->itemType, $valueType)), new HasOffsetValueType($offsetType, $valueType), new NonEmptyArrayType()); } return \PHPStan\Type\TypeCombinator::intersect(new self(\PHPStan\Type\TypeCombinator::union($this->keyType, $offsetType), $unionValues ? \PHPStan\Type\TypeCombinator::union($this->itemType, $valueType) : $valueType), new NonEmptyArrayType()); } public function setExistingOffsetValueType(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return new self($this->keyType, \PHPStan\Type\TypeCombinator::union($this->itemType, $valueType)); } public function unsetOffset(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { $offsetType = $offsetType->toArrayKey(); if (($offsetType instanceof ConstantIntegerType || $offsetType instanceof ConstantStringType) && !$this->keyType->isSuperTypeOf($offsetType)->no()) { $keyType = \PHPStan\Type\TypeCombinator::remove($this->keyType, $offsetType); if ($keyType instanceof \PHPStan\Type\NeverType) { return new ConstantArrayType([], []); } return new self($keyType, $this->itemType); } return $this; } public function chunkArray(\PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { $chunkType = $preserveKeys->yes() ? $this : AccessoryArrayListType::intersectWith(new \PHPStan\Type\ArrayType(new \PHPStan\Type\IntegerType(), $this->getIterableValueType())); $chunkType = \PHPStan\Type\TypeCombinator::intersect($chunkType, new NonEmptyArrayType()); $arrayType = AccessoryArrayListType::intersectWith(new \PHPStan\Type\ArrayType(new \PHPStan\Type\IntegerType(), $chunkType)); return $this->isIterableAtLeastOnce()->yes() ? \PHPStan\Type\TypeCombinator::intersect($arrayType, new NonEmptyArrayType()) : $arrayType; } public function fillKeysArray(\PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { $itemType = $this->getItemType(); if ($itemType->isInteger()->no()) { $stringKeyType = $itemType->toString(); if ($stringKeyType instanceof \PHPStan\Type\ErrorType) { return $stringKeyType; } return new \PHPStan\Type\ArrayType($stringKeyType, $valueType); } return new \PHPStan\Type\ArrayType($itemType, $valueType); } public function flipArray() : \PHPStan\Type\Type { return new self($this->getIterableValueType()->toArrayKey(), $this->getIterableKeyType()); } public function intersectKeyArray(\PHPStan\Type\Type $otherArraysType) : \PHPStan\Type\Type { $isKeySuperType = $otherArraysType->getIterableKeyType()->isSuperTypeOf($this->getIterableKeyType()); if ($isKeySuperType->no()) { return ConstantArrayTypeBuilder::createEmpty()->getArray(); } if ($isKeySuperType->yes()) { return $this; } return new self($otherArraysType->getIterableKeyType(), $this->getIterableValueType()); } public function popArray() : \PHPStan\Type\Type { return $this; } public function reverseArray(TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return $this; } public function searchArray(\PHPStan\Type\Type $needleType) : \PHPStan\Type\Type { return \PHPStan\Type\TypeCombinator::union($this->getIterableKeyType(), new ConstantBooleanType(\false)); } public function shiftArray() : \PHPStan\Type\Type { return $this; } public function shuffleArray() : \PHPStan\Type\Type { return AccessoryArrayListType::intersectWith(new self(new \PHPStan\Type\IntegerType(), $this->itemType)); } public function sliceArray(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return $this; } public function isCallable() : TrinaryLogic { return TrinaryLogic::createMaybe()->and($this->itemType->isString()); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { if ($this->isCallable()->no()) { throw new ShouldNotHappenException(); } return [new TrivialParametersAcceptor()]; } public function toNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toAbsoluteNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toString() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toInteger() : \PHPStan\Type\Type { return \PHPStan\Type\TypeCombinator::union(new ConstantIntegerType(0), new ConstantIntegerType(1)); } public function toFloat() : \PHPStan\Type\Type { return \PHPStan\Type\TypeCombinator::union(new ConstantFloatType(0.0), new ConstantFloatType(1.0)); } public function toArray() : \PHPStan\Type\Type { return $this; } public function toArrayKey() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } /** @deprecated Use getArraySize() instead */ public function count() : \PHPStan\Type\Type { return $this->getArraySize(); } /** @deprecated Use $offsetType->toArrayKey() instead */ public static function castToArrayKeyType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return $offsetType->toArrayKey(); } public function inferTemplateTypes(\PHPStan\Type\Type $receivedType) : TemplateTypeMap { if ($receivedType instanceof \PHPStan\Type\UnionType || $receivedType instanceof \PHPStan\Type\IntersectionType) { return $receivedType->inferTemplateTypesOn($this); } if ($receivedType->isArray()->yes()) { $keyTypeMap = $this->getIterableKeyType()->inferTemplateTypes($receivedType->getIterableKeyType()); $itemTypeMap = $this->getItemType()->inferTemplateTypes($receivedType->getIterableValueType()); return $keyTypeMap->union($itemTypeMap); } return TemplateTypeMap::createEmpty(); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { $variance = $positionVariance->compose(TemplateTypeVariance::createCovariant()); return array_merge($this->getIterableKeyType()->getReferencedTemplateTypes($variance), $this->getItemType()->getReferencedTemplateTypes($variance)); } public function traverse(callable $cb) : \PHPStan\Type\Type { $keyType = $cb($this->keyType); $itemType = $cb($this->itemType); if ($keyType !== $this->keyType || $itemType !== $this->itemType) { if ($keyType instanceof \PHPStan\Type\NeverType && $itemType instanceof \PHPStan\Type\NeverType) { return new ConstantArrayType([], []); } return new self($keyType, $itemType); } return $this; } public function toPhpDocNode() : TypeNode { $isMixedKeyType = $this->keyType instanceof \PHPStan\Type\MixedType && $this->keyType->describe(\PHPStan\Type\VerbosityLevel::precise()) === 'mixed'; $isMixedItemType = $this->itemType instanceof \PHPStan\Type\MixedType && $this->itemType->describe(\PHPStan\Type\VerbosityLevel::precise()) === 'mixed'; if ($isMixedKeyType) { if ($isMixedItemType) { return new IdentifierTypeNode('array'); } return new GenericTypeNode(new IdentifierTypeNode('array'), [$this->itemType->toPhpDocNode()]); } return new GenericTypeNode(new IdentifierTypeNode('array'), [$this->keyType->toPhpDocNode(), $this->itemType->toPhpDocNode()]); } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { $keyType = $cb($this->keyType, $right->getIterableKeyType()); $itemType = $cb($this->itemType, $right->getIterableValueType()); if ($keyType !== $this->keyType || $itemType !== $this->itemType) { if ($keyType instanceof \PHPStan\Type\NeverType && $itemType instanceof \PHPStan\Type\NeverType) { return new ConstantArrayType([], []); } return new self($keyType, $itemType); } return $this; } public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type { if ($typeToRemove->isConstantArray()->yes() && $typeToRemove->isIterableAtLeastOnce()->no()) { return \PHPStan\Type\TypeCombinator::intersect($this, new NonEmptyArrayType()); } if ($typeToRemove instanceof NonEmptyArrayType) { return new ConstantArrayType([], []); } if ($this->isConstantArray()->yes() && $typeToRemove instanceof HasOffsetType) { return $this->unsetOffset($typeToRemove->getOffsetType()); } if ($this->isConstantArray()->yes() && $typeToRemove instanceof HasOffsetValueType) { return $this->unsetOffset($typeToRemove->getOffsetType()); } return null; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getFiniteTypes() : array { return []; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['keyType'], $properties['itemType']); } } type = $type; } public function getType() : \PHPStan\Type\Type { return $this->type; } public function getReferencedClasses() : array { return $this->type->getReferencedClasses(); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { return $this->type->getReferencedTemplateTypes($positionVariance); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self && $this->type->equals($type->type); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return sprintf('new<%s>', $this->type->describe($level)); } public function isResolvable() : bool { return !\PHPStan\Type\TypeUtils::containsTemplateType($this->type); } protected function getResult() : \PHPStan\Type\Type { return $this->type->getObjectTypeOrClassStringObjectType(); } /** * @param callable(Type): Type $cb */ public function traverse(callable $cb) : \PHPStan\Type\Type { $type = $cb($this->type); if ($this->type === $type) { return $this; } return new self($type); } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if (!$right instanceof self) { return $this; } $type = $cb($this->type, $right->type); if ($this->type === $type) { return $this; } return new self($type); } public function toPhpDocNode() : TypeNode { return new GenericTypeNode(new IdentifierTypeNode('new'), [$this->type->toPhpDocNode()]); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['type']); } } value = $value; parent::__construct(); } public function getValue() : int { return $this->value; } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof self) { return $this->value === $type->value ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createNo(); } if ($type instanceof IntegerRangeType) { $min = $type->getMin(); $max = $type->getMax(); if (($min === null || $min <= $this->value) && ($max === null || $this->value <= $max)) { return IsSuperTypeOfResult::createMaybe(); } return IsSuperTypeOfResult::createNo(); } if ($type instanceof parent) { return IsSuperTypeOfResult::createMaybe(); } if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } return IsSuperTypeOfResult::createNo(); } public function describe(VerbosityLevel $level) : string { return $level->handle(static function () : string { return 'int'; }, function () : string { return sprintf('%s', $this->value); }); } public function toFloat() : Type { return new \PHPStan\Type\Constant\ConstantFloatType($this->value); } public function toAbsoluteNumber() : Type { return new self(abs($this->value)); } public function toString() : Type { return new \PHPStan\Type\Constant\ConstantStringType((string) $this->value); } public function toArrayKey() : Type { return $this; } public function generalize(GeneralizePrecision $precision) : Type { return new IntegerType(); } /** * @return ConstTypeNode */ public function toPhpDocNode() : TypeNode { return new ConstTypeNode(new ConstExprIntegerNode((string) $this->value)); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : Type { return new self($properties['value']); } } value = $value; parent::__construct(); } public function getValue() : bool { return $this->value; } public function describe(VerbosityLevel $level) : string { return $this->value ? 'true' : 'false'; } public function getSmallerType() : Type { if ($this->value) { return StaticTypeFactory::falsey(); } return new NeverType(); } public function getSmallerOrEqualType() : Type { if ($this->value) { return new MixedType(); } return StaticTypeFactory::falsey(); } public function getGreaterType() : Type { if ($this->value) { return new NeverType(); } return StaticTypeFactory::truthy(); } public function getGreaterOrEqualType() : Type { if ($this->value) { return StaticTypeFactory::truthy(); } return new MixedType(); } public function toBoolean() : BooleanType { return $this; } public function toNumber() : Type { return new \PHPStan\Type\Constant\ConstantIntegerType((int) $this->value); } public function toAbsoluteNumber() : Type { return $this->toNumber()->toAbsoluteNumber(); } public function toString() : Type { return new \PHPStan\Type\Constant\ConstantStringType((string) $this->value); } public function toInteger() : Type { return new \PHPStan\Type\Constant\ConstantIntegerType((int) $this->value); } public function toFloat() : Type { return new \PHPStan\Type\Constant\ConstantFloatType((float) $this->value); } public function toArrayKey() : Type { return new \PHPStan\Type\Constant\ConstantIntegerType((int) $this->value); } public function isTrue() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->value === \true); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->value === \false); } public function generalize(GeneralizePrecision $precision) : Type { return new BooleanType(); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode($this->value ? 'true' : 'false'); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : Type { return new self($properties['value']); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { if ($type->isObject()->yes()) { return $this; } return $this->scalarLooseCompare($type, $phpVersion); } } value = $value; $this->isClassString = $isClassString; parent::__construct(); } public function getValue() : string { return $this->value; } public function getConstantStrings() : array { return [$this]; } public function isClassStringType() : TrinaryLogic { if ($this->isClassString) { return TrinaryLogic::createYes(); } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); return TrinaryLogic::createFromBoolean($reflectionProvider->hasClass($this->value)); } public function getClassStringObjectType() : Type { if ($this->isClassStringType()->yes()) { return new ObjectType($this->value); } return new ErrorType(); } public function getObjectTypeOrClassStringObjectType() : Type { return $this->getClassStringObjectType(); } /** * @deprecated use isClassStringType() instead */ public function isClassString() : bool { return $this->isClassStringType()->yes(); } public function describe(VerbosityLevel $level) : string { return $level->handle(static function () : string { return 'string'; }, function () : string { $value = $this->value; if (!$this->isClassString) { try { $value = Strings::truncate($value, self::DESCRIBE_LIMIT); } catch (RegexpException $e) { $value = substr($value, 0, self::DESCRIBE_LIMIT) . "…"; } } return self::export($value); }, function () : string { return self::export($this->value); }); } private function export(string $value) : string { $escapedValue = addcslashes($value, "\x00..\x1f"); if ($escapedValue !== $value) { return '"' . addcslashes($value, "\x00..\x1f\\\"") . '"'; } return "'" . addcslashes($value, '\\\'') . "'"; } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof GenericClassStringType) { $genericType = $type->getGenericType(); if ($genericType instanceof MixedType) { return IsSuperTypeOfResult::createMaybe(); } if ($genericType instanceof StaticType) { $genericType = $genericType->getStaticObjectType(); } // We are transforming constant class-string to ObjectType. But we need to filter out // an uncertainty originating in possible ObjectType's class subtypes. $objectType = $this->getObjectType(); // Do not use TemplateType's isSuperTypeOf handling directly because it takes ObjectType // uncertainty into account. if ($genericType instanceof TemplateType) { $isSuperType = $genericType->getBound()->isSuperTypeOfWithReason($objectType); } else { $isSuperType = $genericType->isSuperTypeOfWithReason($objectType); } // Explicitly handle the uncertainty for Yes & Maybe. if ($isSuperType->yes()) { return IsSuperTypeOfResult::createMaybe(); } return IsSuperTypeOfResult::createNo(); } if ($type instanceof ClassStringType) { return $this->isClassStringType()->yes() ? IsSuperTypeOfResult::createMaybe() : IsSuperTypeOfResult::createNo(); } if ($type instanceof self) { return $this->value === $type->value ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createNo(); } if ($type instanceof parent) { return IsSuperTypeOfResult::createMaybe(); } if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } return IsSuperTypeOfResult::createNo(); } public function isCallable() : TrinaryLogic { if ($this->value === '') { return TrinaryLogic::createNo(); } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); // 'my_function' if ($reflectionProvider->hasFunction(new Name($this->value), null)) { return TrinaryLogic::createYes(); } // 'MyClass::myStaticFunction' $matches = Strings::match($this->value, '#^([a-zA-Z_\\x7f-\\xff\\\\][a-zA-Z0-9_\\x7f-\\xff\\\\]*)::([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)\\z#'); if ($matches !== null) { if (!$reflectionProvider->hasClass($matches[1])) { return TrinaryLogic::createMaybe(); } $phpVersion = PhpVersionStaticAccessor::getInstance(); $classRef = $reflectionProvider->getClass($matches[1]); if ($classRef->hasMethod($matches[2])) { $method = $classRef->getMethod($matches[2], new OutOfClassScope()); if (BleedingEdgeToggle::isBleedingEdge() && !$phpVersion->supportsCallableInstanceMethods() && !$method->isStatic()) { return TrinaryLogic::createNo(); } return TrinaryLogic::createYes(); } if (!$classRef->getNativeReflection()->isFinal()) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createNo(); } return TrinaryLogic::createNo(); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { if ($this->value === '') { return []; } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); // 'my_function' $functionName = new Name($this->value); if ($reflectionProvider->hasFunction($functionName, null)) { $function = $reflectionProvider->getFunction($functionName, null); return FunctionCallableVariant::createFromVariants($function, $function->getVariants()); } // 'MyClass::myStaticFunction' $matches = Strings::match($this->value, '#^([a-zA-Z_\\x7f-\\xff\\\\][a-zA-Z0-9_\\x7f-\\xff\\\\]*)::([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)\\z#'); if ($matches !== null) { if (!$reflectionProvider->hasClass($matches[1])) { return [new TrivialParametersAcceptor()]; } $classReflection = $reflectionProvider->getClass($matches[1]); if ($classReflection->hasMethod($matches[2])) { $method = $classReflection->getMethod($matches[2], $scope); if (!$scope->canCallMethod($method)) { return [new InaccessibleMethod($method)]; } return FunctionCallableVariant::createFromVariants($method, $method->getVariants()); } if (!$classReflection->getNativeReflection()->isFinal()) { return [new TrivialParametersAcceptor()]; } } throw new ShouldNotHappenException(); } public function toNumber() : Type { if (is_numeric($this->value)) { $value = $this->value; $value = +$value; if (is_float($value)) { return new \PHPStan\Type\Constant\ConstantFloatType($value); } return new \PHPStan\Type\Constant\ConstantIntegerType($value); } return new ErrorType(); } public function toAbsoluteNumber() : Type { return $this->toNumber()->toAbsoluteNumber(); } public function toInteger() : Type { return new \PHPStan\Type\Constant\ConstantIntegerType((int) $this->value); } public function toFloat() : Type { return new \PHPStan\Type\Constant\ConstantFloatType((float) $this->value); } public function toArrayKey() : Type { if ($this->arrayKeyType !== null) { return $this->arrayKeyType; } /** @var int|string $offsetValue */ $offsetValue = key([$this->value => null]); return $this->arrayKeyType = is_int($offsetValue) ? new \PHPStan\Type\Constant\ConstantIntegerType($offsetValue) : new \PHPStan\Type\Constant\ConstantStringType($offsetValue); } public function isString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createFromBoolean(is_numeric($this->getValue())); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->getValue() !== ''); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createFromBoolean(!in_array($this->getValue(), ['', '0'], \true)); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createFromBoolean(strtolower($this->value) === $this->value); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createFromBoolean(strtoupper($this->value) === $this->value); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { if ($offsetType->isInteger()->yes()) { $strlen = strlen($this->value); $strLenType = IntegerRangeType::fromInterval(-$strlen, $strlen - 1); return $strLenType->isSuperTypeOf($offsetType); } return parent::hasOffsetValueType($offsetType); } public function getOffsetValueType(Type $offsetType) : Type { if ($offsetType->isInteger()->yes()) { $strlen = strlen($this->value); $strLenType = IntegerRangeType::fromInterval(-$strlen, $strlen - 1); if ($offsetType instanceof \PHPStan\Type\Constant\ConstantIntegerType) { if ($strLenType->isSuperTypeOf($offsetType)->yes()) { return new self($this->value[$offsetType->getValue()]); } return new ErrorType(); } $intersected = TypeCombinator::intersect($strLenType, $offsetType); if ($intersected instanceof IntegerRangeType) { $finiteTypes = $intersected->getFiniteTypes(); if ($finiteTypes === []) { return parent::getOffsetValueType($offsetType); } $chars = []; foreach ($finiteTypes as $constantInteger) { $chars[] = new self($this->value[$constantInteger->getValue()]); } if (!$strLenType->isSuperTypeOf($offsetType)->yes()) { $chars[] = new self(''); } return TypeCombinator::union(...$chars); } } return parent::getOffsetValueType($offsetType); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { $valueStringType = $valueType->toString(); if ($valueStringType instanceof ErrorType) { return new ErrorType(); } if ($offsetType instanceof \PHPStan\Type\Constant\ConstantIntegerType && $valueStringType instanceof \PHPStan\Type\Constant\ConstantStringType) { $value = $this->value; $offsetValue = $offsetType->getValue(); if ($offsetValue < 0) { return new ErrorType(); } $stringValue = $valueStringType->getValue(); if (strlen($stringValue) !== 1) { return new ErrorType(); } $value[$offsetValue] = $stringValue; return new self($value); } return parent::setOffsetValueType($offsetType, $valueType); } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { return parent::setOffsetValueType($offsetType, $valueType); } public function append(self $otherString) : self { return new self($this->getValue() . $otherString->getValue()); } public function generalize(GeneralizePrecision $precision) : Type { if ($this->isClassString) { if ($precision->isMoreSpecific()) { return new ClassStringType(); } return new StringType(); } if ($this->getValue() !== '' && $precision->isMoreSpecific()) { $accessories = [new StringType(), new AccessoryLiteralStringType()]; if (is_numeric($this->getValue())) { $accessories[] = new AccessoryNumericStringType(); } if ($this->getValue() !== '0') { $accessories[] = new AccessoryNonFalsyStringType(); } else { $accessories[] = new AccessoryNonEmptyStringType(); } if (strtolower($this->getValue()) === $this->getValue()) { $accessories[] = new AccessoryLowercaseStringType(); } if (strtoupper($this->getValue()) === $this->getValue()) { $accessories[] = new AccessoryUppercaseStringType(); } return new IntersectionType($accessories); } if ($precision->isMoreSpecific()) { return new IntersectionType([new StringType(), new AccessoryLiteralStringType()]); } return new StringType(); } public function getSmallerType() : Type { $subtractedTypes = [new \PHPStan\Type\Constant\ConstantBooleanType(\true), IntegerRangeType::createAllGreaterThanOrEqualTo((float) $this->value)]; if ($this->value === '') { $subtractedTypes[] = new NullType(); $subtractedTypes[] = new StringType(); } if (!(bool) $this->value) { $subtractedTypes[] = new \PHPStan\Type\Constant\ConstantBooleanType(\false); } return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } public function getSmallerOrEqualType() : Type { $subtractedTypes = [IntegerRangeType::createAllGreaterThan((float) $this->value)]; if (!(bool) $this->value) { $subtractedTypes[] = new \PHPStan\Type\Constant\ConstantBooleanType(\true); } return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } public function getGreaterType() : Type { $subtractedTypes = [new \PHPStan\Type\Constant\ConstantBooleanType(\false), IntegerRangeType::createAllSmallerThanOrEqualTo((float) $this->value)]; if ((bool) $this->value) { $subtractedTypes[] = new \PHPStan\Type\Constant\ConstantBooleanType(\true); } return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } public function getGreaterOrEqualType() : Type { $subtractedTypes = [IntegerRangeType::createAllSmallerThan((float) $this->value)]; if ((bool) $this->value) { $subtractedTypes[] = new \PHPStan\Type\Constant\ConstantBooleanType(\false); } return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } public function canAccessConstants() : TrinaryLogic { return $this->isClassStringType(); } public function hasConstant(string $constantName) : TrinaryLogic { return $this->getObjectType()->hasConstant($constantName); } public function getConstant(string $constantName) : ConstantReflection { return $this->getObjectType()->getConstant($constantName); } private function getObjectType() : ObjectType { return $this->objectType = $this->objectType ?? new ObjectType($this->value); } public function toPhpDocNode() : TypeNode { if (substr_count($this->value, "\n") > 0) { return $this->generalize(GeneralizePrecision::moreSpecific())->toPhpDocNode(); } return new ConstTypeNode(new QuoteAwareConstExprStringNode($this->value, QuoteAwareConstExprStringNode::SINGLE_QUOTED)); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : Type { return new self($properties['value'], $properties['isClassString'] ?? \false); } } value); } } items; for ($i = 0; $i < count($items); $i++) { $item = $items[$i]; if ($item === null) { continue; } if (!$item->unpack) { continue; } $valueType = $getTypeCallback($item->value); if ($valueType instanceof \PHPStan\Type\Constant\ConstantArrayType) { array_splice($items, $i, 1); foreach ($valueType->getKeyTypes() as $j => $innerKeyType) { $innerValueType = $valueType->getValueTypes()[$j]; if ($innerKeyType->isString()->no()) { $keyExpr = null; } else { $keyExpr = new TypeExpr($innerKeyType); } array_splice($items, $i++, 0, [new Expr\ArrayItem(new TypeExpr($innerValueType), $keyExpr)]); } } else { array_splice($items, $i, 1, [new Expr\ArrayItem(new TypeExpr($valueType->getIterableValueType()), new TypeExpr($valueType->getIterableKeyType()))]); } } foreach ($items as $item) { if ($item === null) { continue; } if ($item->unpack) { throw new ShouldNotHappenException(); } if ($item->key !== null) { $itemKeyType = $getTypeCallback($item->key); if (!$itemKeyType instanceof \PHPStan\Type\Constant\ConstantIntegerType) { $isList = \false; } elseif ($itemKeyType->getValue() !== $nextAutoIndex) { $isList = \false; $nextAutoIndex = $itemKeyType->getValue() + 1; } else { $nextAutoIndex++; } } else { $itemKeyType = new \PHPStan\Type\Constant\ConstantIntegerType($nextAutoIndex); $nextAutoIndex++; } $generalizedKeyType = $itemKeyType->generalize(GeneralizePrecision::moreSpecific()); $keyTypes[$generalizedKeyType->describe(VerbosityLevel::precise())] = $generalizedKeyType; $itemValueType = $getTypeCallback($item->value); $generalizedValueType = $itemValueType->generalize(GeneralizePrecision::moreSpecific()); $valueTypes[$generalizedValueType->describe(VerbosityLevel::precise())] = $generalizedValueType; } $keyType = TypeCombinator::union(...array_values($keyTypes)); $valueType = TypeCombinator::union(...array_values($valueTypes)); $arrayType = new ArrayType($keyType, $valueType); if ($isList) { $arrayType = AccessoryArrayListType::intersectWith($arrayType); } return TypeCombinator::intersect($arrayType, new NonEmptyArrayType(), new OversizedArrayType()); } } value = $value; parent::__construct(); } public function getValue() : float { return $this->value; } public function equals(Type $type) : bool { return $type instanceof self && ($this->value === $type->value || is_nan($this->value) && is_nan($type->value)); } private function castFloatToString(float $value) : string { $precisionBackup = ini_get('precision'); ini_set('precision', '-1'); try { $valueStr = (string) $value; if (is_finite($value) && !str_contains($valueStr, '.')) { $valueStr .= '.0'; } return $valueStr; } finally { ini_set('precision', $precisionBackup); } } public function describe(VerbosityLevel $level) : string { return $level->handle(static function () : string { return 'float'; }, function () : string { return $this->castFloatToString($this->value); }); } public function toString() : Type { return new \PHPStan\Type\Constant\ConstantStringType((string) $this->value); } public function toInteger() : Type { return new \PHPStan\Type\Constant\ConstantIntegerType((int) $this->value); } public function toAbsoluteNumber() : Type { return new self(abs($this->value)); } public function toArrayKey() : Type { return new \PHPStan\Type\Constant\ConstantIntegerType((int) $this->value); } public function generalize(GeneralizePrecision $precision) : Type { return new FloatType(); } /** * @return ConstTypeNode */ public function toPhpDocNode() : TypeNode { return new ConstTypeNode(new ConstExprFloatNode($this->castFloatToString($this->value))); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : Type { return new self($properties['value']); } } */ private $keyTypes; /** * @var array */ private $valueTypes; /** * @var int[] */ private $optionalKeys; private const DESCRIBE_LIMIT = 8; private const CHUNK_FINITE_TYPES_LIMIT = 5; /** * @var TrinaryLogic */ private $isList; /** @var self[]|null */ private $allArrays = null; /** @var non-empty-list */ private $nextAutoIndexes; /** * @api * @param array $keyTypes * @param array $valueTypes * @param non-empty-list|int $nextAutoIndexes * @param int[] $optionalKeys * @param bool|TrinaryLogic $isList */ public function __construct(array $keyTypes, array $valueTypes, $nextAutoIndexes = [0], array $optionalKeys = [], $isList = \false) { $this->keyTypes = $keyTypes; $this->valueTypes = $valueTypes; $this->optionalKeys = $optionalKeys; assert(count($keyTypes) === count($valueTypes)); if (is_int($nextAutoIndexes)) { $nextAutoIndexes = [$nextAutoIndexes]; } $this->nextAutoIndexes = $nextAutoIndexes; $keyTypesCount = count($this->keyTypes); if ($keyTypesCount === 0) { $keyType = new NeverType(\true); $isList = TrinaryLogic::createYes(); } elseif ($keyTypesCount === 1) { $keyType = $this->keyTypes[0]; } else { $keyType = new UnionType($this->keyTypes); } if (is_bool($isList)) { $isList = TrinaryLogic::createFromBoolean($isList); } $this->isList = $isList; parent::__construct($keyType, count($valueTypes) > 0 ? TypeCombinator::union(...$valueTypes) : new NeverType(\true)); } public function getConstantArrays() : array { return [$this]; } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createYes(); } /** @deprecated Use isIterableAtLeastOnce()->no() instead */ public function isEmpty() : bool { return count($this->keyTypes) === 0; } /** * @return non-empty-list */ public function getNextAutoIndexes() : array { return $this->nextAutoIndexes; } /** * @deprecated */ public function getNextAutoIndex() : int { return $this->nextAutoIndexes[count($this->nextAutoIndexes) - 1]; } /** * @return int[] */ public function getOptionalKeys() : array { return $this->optionalKeys; } /** * @return self[] */ public function getAllArrays() : array { if ($this->allArrays !== null) { return $this->allArrays; } if (count($this->optionalKeys) <= 10) { $optionalKeysCombinations = $this->powerSet($this->optionalKeys); } else { $optionalKeysCombinations = [[], $this->optionalKeys]; } $requiredKeys = []; foreach (array_keys($this->keyTypes) as $i) { if (in_array($i, $this->optionalKeys, \true)) { continue; } $requiredKeys[] = $i; } $arrays = []; foreach ($optionalKeysCombinations as $combination) { $keys = array_merge($requiredKeys, $combination); sort($keys); if ($this->isList->yes() && array_keys($keys) !== $keys) { continue; } $builder = \PHPStan\Type\Constant\ConstantArrayTypeBuilder::createEmpty(); foreach ($keys as $i) { $builder->setOffsetValueType($this->keyTypes[$i], $this->valueTypes[$i]); } $array = $builder->getArray(); if (!$array instanceof \PHPStan\Type\Constant\ConstantArrayType) { throw new ShouldNotHappenException(); } $arrays[] = $array; } return $this->allArrays = $arrays; } /** * @template T * @param T[] $in * @return T[][] */ private function powerSet(array $in) : array { $count = count($in); $members = pow(2, $count); $return = []; for ($i = 0; $i < $members; $i++) { $b = sprintf('%0' . $count . 'b', $i); $out = []; for ($j = 0; $j < $count; $j++) { if ($b[$j] !== '1') { continue; } $out[] = $in[$j]; } $return[] = $out; } return $return; } /** * @return array */ public function getKeyTypes() : array { return $this->keyTypes; } /** @deprecated Use getFirstIterableKeyType() instead */ public function getFirstKeyType() : Type { return $this->getFirstIterableKeyType(); } /** @deprecated Use getLastIterableKeyType() instead */ public function getLastKeyType() : Type { return $this->getLastIterableKeyType(); } /** * @return array */ public function getValueTypes() : array { return $this->valueTypes; } /** @deprecated Use getFirstIterableValueType() instead */ public function getFirstValueType() : Type { return $this->getFirstIterableValueType(); } /** @deprecated Use getLastIterableValueType() instead */ public function getLastValueType() : Type { return $this->getLastIterableValueType(); } public function isOptionalKey(int $i) : bool { return in_array($i, $this->optionalKeys, \true); } public function accepts(Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType && !$type instanceof IntersectionType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } if ($type instanceof self && count($this->keyTypes) === 0) { return AcceptsResult::createFromBoolean(count($type->keyTypes) === 0); } $result = AcceptsResult::createYes(); foreach ($this->keyTypes as $i => $keyType) { $valueType = $this->valueTypes[$i]; $hasOffsetValueType = $type->hasOffsetValueType($keyType); $hasOffset = new AcceptsResult($hasOffsetValueType, $hasOffsetValueType->yes() || !$type->isConstantArray()->yes() ? [] : [sprintf('Array %s have offset %s.', $hasOffsetValueType->no() ? 'does not' : 'might not', $keyType->describe(VerbosityLevel::value()))]); if ($hasOffset->no()) { if ($this->isOptionalKey($i)) { continue; } return $hasOffset; } if ($hasOffset->maybe() && $this->isOptionalKey($i)) { $hasOffset = AcceptsResult::createYes(); } $result = $result->and($hasOffset); $otherValueType = $type->getOffsetValueType($keyType); $verbosity = VerbosityLevel::getRecommendedLevelByType($valueType, $otherValueType); $acceptsValue = $valueType->acceptsWithReason($otherValueType, $strictTypes)->decorateReasons(static function (string $reason) use($keyType, $valueType, $verbosity, $otherValueType) { return sprintf('Offset %s (%s) does not accept type %s: %s', $keyType->describe(VerbosityLevel::precise()), $valueType->describe($verbosity), $otherValueType->describe($verbosity), $reason); }); if (!$acceptsValue->yes() && count($acceptsValue->reasons) === 0 && $type->isConstantArray()->yes()) { $acceptsValue = new AcceptsResult($acceptsValue->result, [sprintf('Offset %s (%s) does not accept type %s.', $keyType->describe(VerbosityLevel::precise()), $valueType->describe($verbosity), $otherValueType->describe($verbosity))]); } if ($acceptsValue->no()) { return $acceptsValue; } $result = $result->and($acceptsValue); } $result = $result->and(new AcceptsResult($type->isArray(), [])); if ($type->isOversizedArray()->yes()) { if (!$result->no()) { return AcceptsResult::createYes(); } } return $result; } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof self) { if (count($this->keyTypes) === 0) { return new IsSuperTypeOfResult($type->isIterableAtLeastOnce()->negate(), []); } $results = []; foreach ($this->keyTypes as $i => $keyType) { $hasOffset = $type->hasOffsetValueType($keyType); if ($hasOffset->no()) { if (!$this->isOptionalKey($i)) { return IsSuperTypeOfResult::createNo(); } $results[] = IsSuperTypeOfResult::createYes(); continue; } elseif ($hasOffset->maybe() && !$this->isOptionalKey($i)) { $results[] = IsSuperTypeOfResult::createMaybe(); } $isValueSuperType = $this->valueTypes[$i]->isSuperTypeOfWithReason($type->getOffsetValueType($keyType)); if ($isValueSuperType->no()) { return $isValueSuperType->decorateReasons(static function (string $reason) use($keyType) { return sprintf('Offset %s: %s', $keyType->describe(VerbosityLevel::value()), $reason); }); } $results[] = $isValueSuperType; } return IsSuperTypeOfResult::createYes()->and(...$results); } if ($type instanceof ArrayType) { $result = IsSuperTypeOfResult::createMaybe(); if (count($this->keyTypes) === 0) { return $result; } $isKeySuperType = $this->getKeyType()->isSuperTypeOfWithReason($type->getKeyType()); if ($isKeySuperType->no()) { return $isKeySuperType; } return $result->and($isKeySuperType, $this->getItemType()->isSuperTypeOfWithReason($type->getItemType())); } if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } return IsSuperTypeOfResult::createNo(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { if ($this->isIterableAtLeastOnce()->no() && count($type->getConstantScalarValues()) === 1) { // @phpstan-ignore equal.invalid, equal.notAllowed return new \PHPStan\Type\Constant\ConstantBooleanType($type->getConstantScalarValues()[0] == []); // phpcs:ignore } return new BooleanType(); } public function equals(Type $type) : bool { if (!$type instanceof self) { return \false; } if (count($this->keyTypes) !== count($type->keyTypes)) { return \false; } foreach ($this->keyTypes as $i => $keyType) { $valueType = $this->valueTypes[$i]; if (!$valueType->equals($type->valueTypes[$i])) { return \false; } if (!$keyType->equals($type->keyTypes[$i])) { return \false; } } if ($this->optionalKeys !== $type->optionalKeys) { return \false; } return \true; } public function isCallable() : TrinaryLogic { $typeAndMethods = $this->findTypeAndMethodNames(); if ($typeAndMethods === []) { return TrinaryLogic::createNo(); } $results = array_map(static function (\PHPStan\Type\Constant\ConstantArrayTypeAndMethod $typeAndMethod) : TrinaryLogic { return $typeAndMethod->getCertainty(); }, $typeAndMethods); return TrinaryLogic::createYes()->and(...$results); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { $typeAndMethodNames = $this->findTypeAndMethodNames(); if ($typeAndMethodNames === []) { throw new ShouldNotHappenException(); } $acceptors = []; foreach ($typeAndMethodNames as $typeAndMethodName) { if ($typeAndMethodName->isUnknown() || !$typeAndMethodName->getCertainty()->yes()) { $acceptors[] = new TrivialParametersAcceptor(); continue; } $method = $typeAndMethodName->getType()->getMethod($typeAndMethodName->getMethod(), $scope); if (!$scope->canCallMethod($method)) { $acceptors[] = new InaccessibleMethod($method); continue; } array_push($acceptors, ...FunctionCallableVariant::createFromVariants($method, $method->getVariants())); } return $acceptors; } /** * @return array{Type, Type}|array{} */ private function getClassOrObjectAndMethods() : array { if (count($this->keyTypes) !== 2) { return []; } $classOrObject = null; $method = null; foreach ($this->keyTypes as $i => $keyType) { if ($keyType->isSuperTypeOf(new \PHPStan\Type\Constant\ConstantIntegerType(0))->yes()) { $classOrObject = $this->valueTypes[$i]; continue; } if (!$keyType->isSuperTypeOf(new \PHPStan\Type\Constant\ConstantIntegerType(1))->yes()) { continue; } $method = $this->valueTypes[$i]; } if ($classOrObject === null || $method === null) { return []; } return [$classOrObject, $method]; } /** @deprecated Use findTypeAndMethodNames() instead */ public function findTypeAndMethodName() : ?\PHPStan\Type\Constant\ConstantArrayTypeAndMethod { $callableArray = $this->getClassOrObjectAndMethods(); if ($callableArray === []) { return null; } [$classOrObject, $method] = $callableArray; if (!$method instanceof \PHPStan\Type\Constant\ConstantStringType) { return \PHPStan\Type\Constant\ConstantArrayTypeAndMethod::createUnknown(); } $type = $classOrObject->getObjectTypeOrClassStringObjectType(); if (!$type->isObject()->yes()) { return \PHPStan\Type\Constant\ConstantArrayTypeAndMethod::createUnknown(); } $has = $type->hasMethod($method->getValue()); if (!$has->no()) { if ($this->isOptionalKey(0) || $this->isOptionalKey(1)) { $has = $has->and(TrinaryLogic::createMaybe()); } return \PHPStan\Type\Constant\ConstantArrayTypeAndMethod::createConcrete($type, $method->getValue(), $has); } return null; } /** @return ConstantArrayTypeAndMethod[] */ public function findTypeAndMethodNames() : array { $callableArray = $this->getClassOrObjectAndMethods(); if ($callableArray === []) { return []; } [$classOrObject, $methods] = $callableArray; if (count($methods->getConstantStrings()) === 0) { return [\PHPStan\Type\Constant\ConstantArrayTypeAndMethod::createUnknown()]; } $type = $classOrObject->getObjectTypeOrClassStringObjectType(); if (!$type->isObject()->yes()) { return [\PHPStan\Type\Constant\ConstantArrayTypeAndMethod::createUnknown()]; } $typeAndMethods = []; $phpVersion = PhpVersionStaticAccessor::getInstance(); foreach ($methods->getConstantStrings() as $method) { $has = $type->hasMethod($method->getValue()); if ($has->no()) { continue; } if (BleedingEdgeToggle::isBleedingEdge() && $has->yes() && !$phpVersion->supportsCallableInstanceMethods()) { $methodReflection = $type->getMethod($method->getValue(), new OutOfClassScope()); if ($classOrObject->isString()->yes() && !$methodReflection->isStatic()) { continue; } } if ($this->isOptionalKey(0) || $this->isOptionalKey(1)) { $has = $has->and(TrinaryLogic::createMaybe()); } $typeAndMethods[] = \PHPStan\Type\Constant\ConstantArrayTypeAndMethod::createConcrete($type, $method->getValue(), $has); } return $typeAndMethods; } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { $offsetArrayKeyType = $offsetType->toArrayKey(); return $this->recursiveHasOffsetValueType($offsetArrayKeyType); } private function recursiveHasOffsetValueType(Type $offsetType) : TrinaryLogic { if ($offsetType instanceof UnionType) { $results = []; foreach ($offsetType->getTypes() as $innerType) { $results[] = $this->recursiveHasOffsetValueType($innerType); } return TrinaryLogic::extremeIdentity(...$results); } if ($offsetType instanceof IntegerRangeType) { $finiteTypes = $offsetType->getFiniteTypes(); if ($finiteTypes !== []) { $results = []; foreach ($finiteTypes as $innerType) { $results[] = $this->recursiveHasOffsetValueType($innerType); } return TrinaryLogic::extremeIdentity(...$results); } } $result = TrinaryLogic::createNo(); foreach ($this->keyTypes as $i => $keyType) { if ($keyType instanceof \PHPStan\Type\Constant\ConstantIntegerType && !$offsetType->isString()->no() && $offsetType->isConstantScalarValue()->no()) { return TrinaryLogic::createMaybe(); } $has = $keyType->isSuperTypeOf($offsetType); if ($has->yes()) { if ($this->isOptionalKey($i)) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createYes(); } if (!$has->maybe()) { continue; } $result = TrinaryLogic::createMaybe(); } return $result; } public function getOffsetValueType(Type $offsetType) : Type { if (count($this->keyTypes) === 0) { return new ErrorType(); } $offsetType = $offsetType->toArrayKey(); $matchingValueTypes = []; $all = \true; $maybeAll = \true; foreach ($this->keyTypes as $i => $keyType) { if ($keyType->isSuperTypeOf($offsetType)->no()) { $all = \false; if ($keyType instanceof \PHPStan\Type\Constant\ConstantIntegerType && !$offsetType->isString()->no() && $offsetType->isConstantScalarValue()->no()) { continue; } $maybeAll = \false; continue; } $matchingValueTypes[] = $this->valueTypes[$i]; } if ($all) { return $this->getIterableValueType(); } if (count($matchingValueTypes) > 0) { $type = TypeCombinator::union(...$matchingValueTypes); if ($type instanceof ErrorType) { return new MixedType(); } return $type; } if ($maybeAll) { return $this->getIterableValueType(); } return new ErrorType(); // undefined offset } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { $builder = \PHPStan\Type\Constant\ConstantArrayTypeBuilder::createFromConstantArray($this); $builder->setOffsetValueType($offsetType, $valueType); return $builder->getArray(); } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { $offsetType = $offsetType->toArrayKey(); $builder = \PHPStan\Type\Constant\ConstantArrayTypeBuilder::createFromConstantArray($this); foreach ($this->keyTypes as $keyType) { if ($offsetType->isSuperTypeOf($keyType)->no()) { continue; } $builder->setOffsetValueType($keyType, $valueType); } return $builder->getArray(); } public function unsetOffset(Type $offsetType) : Type { $offsetType = $offsetType->toArrayKey(); if ($offsetType instanceof \PHPStan\Type\Constant\ConstantIntegerType || $offsetType instanceof \PHPStan\Type\Constant\ConstantStringType) { foreach ($this->keyTypes as $i => $keyType) { if ($keyType->getValue() !== $offsetType->getValue()) { continue; } $keyTypes = $this->keyTypes; unset($keyTypes[$i]); $valueTypes = $this->valueTypes; unset($valueTypes[$i]); $newKeyTypes = []; $newValueTypes = []; $newOptionalKeys = []; $k = 0; foreach ($keyTypes as $j => $newKeyType) { $newKeyTypes[] = $newKeyType; $newValueTypes[] = $valueTypes[$j]; if (in_array($j, $this->optionalKeys, \true)) { $newOptionalKeys[] = $k; } $k++; } return new self($newKeyTypes, $newValueTypes, $this->nextAutoIndexes, $newOptionalKeys, TrinaryLogic::createNo()); } return $this; } $constantScalars = $offsetType->getConstantScalarTypes(); if (count($constantScalars) > 0) { $optionalKeys = $this->optionalKeys; foreach ($constantScalars as $constantScalar) { $constantScalar = $constantScalar->toArrayKey(); if (!$constantScalar instanceof \PHPStan\Type\Constant\ConstantIntegerType && !$constantScalar instanceof \PHPStan\Type\Constant\ConstantStringType) { continue; } foreach ($this->keyTypes as $i => $keyType) { if ($keyType->getValue() !== $constantScalar->getValue()) { continue; } if (in_array($i, $optionalKeys, \true)) { continue 2; } $optionalKeys[] = $i; } } return new self($this->keyTypes, $this->valueTypes, $this->nextAutoIndexes, $optionalKeys, TrinaryLogic::createNo()); } $optionalKeys = $this->optionalKeys; $isList = $this->isList; foreach ($this->keyTypes as $i => $keyType) { if (!$offsetType->isSuperTypeOf($keyType)->yes()) { continue; } $optionalKeys[] = $i; $isList = TrinaryLogic::createNo(); } $optionalKeys = array_values(array_unique($optionalKeys)); return new self($this->keyTypes, $this->valueTypes, $this->nextAutoIndexes, $optionalKeys, $isList); } public function chunkArray(Type $lengthType, TrinaryLogic $preserveKeys) : Type { $biggerOne = IntegerRangeType::fromInterval(1, null); $finiteTypes = $lengthType->getFiniteTypes(); if ($biggerOne->isSuperTypeOf($lengthType)->yes() && count($finiteTypes) < self::CHUNK_FINITE_TYPES_LIMIT) { $results = []; foreach ($finiteTypes as $finiteType) { if (!$finiteType instanceof \PHPStan\Type\Constant\ConstantIntegerType || $finiteType->getValue() < 1) { return parent::chunkArray($lengthType, $preserveKeys); } $length = $finiteType->getValue(); $builder = \PHPStan\Type\Constant\ConstantArrayTypeBuilder::createEmpty(); $keyTypesCount = count($this->keyTypes); for ($i = 0; $i < $keyTypesCount; $i += $length) { $chunk = $this->sliceArray(new \PHPStan\Type\Constant\ConstantIntegerType($i), new \PHPStan\Type\Constant\ConstantIntegerType($length), TrinaryLogic::createYes()); $builder->setOffsetValueType(null, $preserveKeys->yes() ? $chunk : $chunk->getValuesArray()); } $results[] = $builder->getArray(); } return TypeCombinator::union(...$results); } return parent::chunkArray($lengthType, $preserveKeys); } public function fillKeysArray(Type $valueType) : Type { $builder = \PHPStan\Type\Constant\ConstantArrayTypeBuilder::createEmpty(); foreach ($this->valueTypes as $i => $keyType) { if ($keyType->isInteger()->no()) { $stringKeyType = $keyType->toString(); if ($stringKeyType instanceof ErrorType) { return $stringKeyType; } $builder->setOffsetValueType($stringKeyType, $valueType, $this->isOptionalKey($i)); } else { $builder->setOffsetValueType($keyType, $valueType, $this->isOptionalKey($i)); } } return $builder->getArray(); } public function flipArray() : Type { $builder = \PHPStan\Type\Constant\ConstantArrayTypeBuilder::createEmpty(); foreach ($this->keyTypes as $i => $keyType) { $valueType = $this->valueTypes[$i]; $builder->setOffsetValueType($valueType->toArrayKey(), $keyType, $this->isOptionalKey($i)); } return $builder->getArray(); } public function intersectKeyArray(Type $otherArraysType) : Type { $builder = \PHPStan\Type\Constant\ConstantArrayTypeBuilder::createEmpty(); foreach ($this->keyTypes as $i => $keyType) { $valueType = $this->valueTypes[$i]; $has = $otherArraysType->hasOffsetValueType($keyType); if ($has->no()) { continue; } $builder->setOffsetValueType($keyType, $valueType, $this->isOptionalKey($i) || !$has->yes()); } return $builder->getArray(); } public function popArray() : Type { return $this->removeLastElements(1); } public function reverseArray(TrinaryLogic $preserveKeys) : Type { $builder = \PHPStan\Type\Constant\ConstantArrayTypeBuilder::createEmpty(); for ($i = count($this->keyTypes) - 1; $i >= 0; $i--) { $offsetType = $preserveKeys->yes() || $this->keyTypes[$i]->isInteger()->no() ? $this->keyTypes[$i] : null; $builder->setOffsetValueType($offsetType, $this->valueTypes[$i], $this->isOptionalKey($i)); } return $builder->getArray(); } public function searchArray(Type $needleType) : Type { $matches = []; $hasIdenticalValue = \false; foreach ($this->valueTypes as $index => $valueType) { $isNeedleSuperType = $valueType->isSuperTypeOf($needleType); if ($isNeedleSuperType->no()) { continue; } if ($needleType instanceof ConstantScalarType && $valueType instanceof ConstantScalarType && $needleType->getValue() === $valueType->getValue() && !$this->isOptionalKey($index)) { $hasIdenticalValue = \true; } $matches[] = $this->keyTypes[$index]; } if (count($matches) > 0) { if ($hasIdenticalValue) { return TypeCombinator::union(...$matches); } return TypeCombinator::union(new \PHPStan\Type\Constant\ConstantBooleanType(\false), ...$matches); } return new \PHPStan\Type\Constant\ConstantBooleanType(\false); } public function shiftArray() : Type { return $this->removeFirstElements(1); } public function shuffleArray() : Type { $valuesArray = $this->getValuesArray(); $isIterableAtLeastOnce = $valuesArray->isIterableAtLeastOnce(); if ($isIterableAtLeastOnce->no()) { return $valuesArray; } $generalizedArray = new ArrayType($valuesArray->getIterableKeyType(), $valuesArray->getItemType()); if ($isIterableAtLeastOnce->yes()) { $generalizedArray = TypeCombinator::intersect($generalizedArray, new NonEmptyArrayType()); } if ($valuesArray->isList->yes()) { $generalizedArray = AccessoryArrayListType::intersectWith($generalizedArray); } return $generalizedArray; } public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $preserveKeys) : Type { $keyTypesCount = count($this->keyTypes); if ($keyTypesCount === 0) { return $this; } $offset = $offsetType instanceof \PHPStan\Type\Constant\ConstantIntegerType ? $offsetType->getValue() : 0; $length = $lengthType instanceof \PHPStan\Type\Constant\ConstantIntegerType ? $lengthType->getValue() : $keyTypesCount; if ($length < 0) { // Negative lengths prevent access to the most right n elements return $this->removeLastElements($length * -1)->sliceArray($offsetType, new NullType(), $preserveKeys); } if ($keyTypesCount + $offset <= 0) { // A negative offset cannot reach left outside the array $offset = 0; } if ($offset < 0) { /* * Transforms the problem with the negative offset in one with a positive offset using array reversion. * The reason is belows handling of optional keys which works only from left to right. * * e.g. * array{a: 0, b: 1, c: 2, d: 3, e: 4} * with offset -4 and length 2 (which would be sliced to array{b: 1, c: 2}) * * is transformed via reversion to * * array{e: 4, d: 3, c: 2, b: 1, a: 0} * with offset 2 and length 2 (which will be sliced to array{c: 2, b: 1} and then reversed again) */ $offset *= -1; $reversedLength = min($length, $offset); $reversedOffset = $offset - $reversedLength; return $this->reverseArray(TrinaryLogic::createYes())->sliceArray(new \PHPStan\Type\Constant\ConstantIntegerType($reversedOffset), new \PHPStan\Type\Constant\ConstantIntegerType($reversedLength), $preserveKeys)->reverseArray(TrinaryLogic::createYes()); } if ($offset > 0) { return $this->removeFirstElements($offset, \false)->sliceArray(new \PHPStan\Type\Constant\ConstantIntegerType(0), $lengthType, $preserveKeys); } $builder = \PHPStan\Type\Constant\ConstantArrayTypeBuilder::createEmpty(); $nonOptionalElementsCount = 0; $hasOptional = \false; for ($i = 0; $nonOptionalElementsCount < $length && $i < $keyTypesCount; $i++) { $isOptional = $this->isOptionalKey($i); if (!$isOptional) { $nonOptionalElementsCount++; } else { $hasOptional = \true; } $isLastElement = $nonOptionalElementsCount >= $length || $i + 1 >= $keyTypesCount; if ($isLastElement && $length < $keyTypesCount && $hasOptional) { // If the slice is not full yet, but has at least one optional key // the last non-optional element is going to be optional. // Otherwise, it would not fit into the slice if previous non-optional keys are there. $isOptional = \true; } $builder->setOffsetValueType($this->keyTypes[$i], $this->valueTypes[$i], $isOptional); } $slice = $builder->getArray(); if (!$slice instanceof self) { throw new ShouldNotHappenException(); } return $preserveKeys->yes() ? $slice : $slice->reindex(); } public function isIterableAtLeastOnce() : TrinaryLogic { $keysCount = count($this->keyTypes); if ($keysCount === 0) { return TrinaryLogic::createNo(); } $optionalKeysCount = count($this->optionalKeys); if ($optionalKeysCount < $keysCount) { return TrinaryLogic::createYes(); } return TrinaryLogic::createMaybe(); } public function getArraySize() : Type { $optionalKeysCount = count($this->optionalKeys); $totalKeysCount = count($this->getKeyTypes()); if ($optionalKeysCount === 0) { return new \PHPStan\Type\Constant\ConstantIntegerType($totalKeysCount); } return IntegerRangeType::fromInterval($totalKeysCount - $optionalKeysCount, $totalKeysCount); } public function getFirstIterableKeyType() : Type { $keyTypes = []; foreach ($this->keyTypes as $i => $keyType) { $keyTypes[] = $keyType; if (!$this->isOptionalKey($i)) { break; } } return TypeCombinator::union(...$keyTypes); } public function getLastIterableKeyType() : Type { $keyTypes = []; for ($i = count($this->keyTypes) - 1; $i >= 0; $i--) { $keyTypes[] = $this->keyTypes[$i]; if (!$this->isOptionalKey($i)) { break; } } return TypeCombinator::union(...$keyTypes); } public function getFirstIterableValueType() : Type { $valueTypes = []; foreach ($this->valueTypes as $i => $valueType) { $valueTypes[] = $valueType; if (!$this->isOptionalKey($i)) { break; } } return TypeCombinator::union(...$valueTypes); } public function getLastIterableValueType() : Type { $valueTypes = []; for ($i = count($this->keyTypes) - 1; $i >= 0; $i--) { $valueTypes[] = $this->valueTypes[$i]; if (!$this->isOptionalKey($i)) { break; } } return TypeCombinator::union(...$valueTypes); } public function isConstantArray() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isList() : TrinaryLogic { return $this->isList; } /** @deprecated Use popArray() instead */ public function removeLast() : self { return $this->removeLastElements(1); } /** @param positive-int $length */ private function removeLastElements(int $length) : self { $keyTypesCount = count($this->keyTypes); if ($keyTypesCount === 0) { return $this; } $keyTypes = $this->keyTypes; $valueTypes = $this->valueTypes; $optionalKeys = $this->optionalKeys; $nextAutoindex = $this->nextAutoIndexes; $optionalKeysRemoved = 0; $newLength = $keyTypesCount - $length; for ($i = $keyTypesCount - 1; $i >= 0; $i--) { $isOptional = $this->isOptionalKey($i); if ($i >= $newLength) { if ($isOptional) { $optionalKeysRemoved++; foreach ($optionalKeys as $key => $value) { if ($value === $i) { unset($optionalKeys[$key]); break; } } } $removedKeyType = array_pop($keyTypes); array_pop($valueTypes); $nextAutoindex = $removedKeyType instanceof \PHPStan\Type\Constant\ConstantIntegerType ? $removedKeyType->getValue() : $this->getNextAutoIndex(); // @phpstan-ignore method.deprecated continue; } if ($isOptional || $optionalKeysRemoved <= 0) { continue; } $optionalKeys[] = $i; $optionalKeysRemoved--; } return new self($keyTypes, $valueTypes, $nextAutoindex, array_values($optionalKeys), $this->isList); } /** @deprecated Use shiftArray() instead */ public function removeFirst() : self { return $this->removeFirstElements(1); } /** @param positive-int $length */ private function removeFirstElements(int $length, bool $reindex = \true) : self { $builder = \PHPStan\Type\Constant\ConstantArrayTypeBuilder::createEmpty(); $optionalKeysIgnored = 0; foreach ($this->keyTypes as $i => $keyType) { $isOptional = $this->isOptionalKey($i); if ($i <= $length - 1) { if ($isOptional) { $optionalKeysIgnored++; } continue; } if (!$isOptional && $optionalKeysIgnored > 0) { $isOptional = \true; $optionalKeysIgnored--; } $valueType = $this->valueTypes[$i]; if ($reindex && $keyType instanceof \PHPStan\Type\Constant\ConstantIntegerType) { $keyType = null; } $builder->setOffsetValueType($keyType, $valueType, $isOptional); } $array = $builder->getArray(); if (!$array instanceof self) { throw new ShouldNotHappenException(); } return $array; } /** @deprecated Use sliceArray() instead */ public function slice(int $offset, ?int $limit, bool $preserveKeys = \false) : self { $array = $this->sliceArray(ConstantTypeHelper::getTypeFromValue($offset), ConstantTypeHelper::getTypeFromValue($limit), TrinaryLogic::createFromBoolean($preserveKeys)); if (!$array instanceof self) { throw new ShouldNotHappenException(); } return $array; } /** @deprecated Use reverseArray() instead */ public function reverse(bool $preserveKeys = \false) : self { $array = $this->reverseArray(TrinaryLogic::createFromBoolean($preserveKeys)); if (!$array instanceof self) { throw new ShouldNotHappenException(); } return $array; } /** * @deprecated Use chunkArray() instead * @param positive-int $length */ public function chunk(int $length, bool $preserveKeys = \false) : self { $builder = \PHPStan\Type\Constant\ConstantArrayTypeBuilder::createEmpty(); $keyTypesCount = count($this->keyTypes); for ($i = 0; $i < $keyTypesCount; $i += $length) { $chunk = $this->slice($i, $length, \true); $builder->setOffsetValueType(null, $preserveKeys ? $chunk : $chunk->getValuesArray()); } $chunks = $builder->getArray(); if (!$chunks instanceof self) { throw new ShouldNotHappenException(); } return $chunks; } private function reindex() : self { $keyTypes = []; $autoIndex = 0; foreach ($this->keyTypes as $keyType) { if (!$keyType instanceof \PHPStan\Type\Constant\ConstantIntegerType) { $keyTypes[] = $keyType; continue; } $keyTypes[] = new \PHPStan\Type\Constant\ConstantIntegerType($autoIndex); $autoIndex++; } return new self($keyTypes, $this->valueTypes, [$autoIndex], $this->optionalKeys, TrinaryLogic::createYes()); } public function toBoolean() : BooleanType { return $this->getArraySize()->toBoolean(); } public function toInteger() : Type { return $this->toBoolean()->toInteger(); } public function toFloat() : Type { return $this->toBoolean()->toFloat(); } public function generalize(GeneralizePrecision $precision) : Type { if (count($this->keyTypes) === 0) { return $this; } if ($precision->isTemplateArgument()) { return $this->traverse(static function (Type $type) use($precision) { return $type->generalize($precision); }); } $arrayType = new ArrayType($this->getIterableKeyType()->generalize($precision), $this->getItemType()->generalize($precision)); $keyTypesCount = count($this->keyTypes); $optionalKeysCount = count($this->optionalKeys); $accessoryTypes = []; if ($precision->isMoreSpecific() && $keyTypesCount - $optionalKeysCount < 32) { foreach ($this->keyTypes as $i => $keyType) { if ($this->isOptionalKey($i)) { continue; } $accessoryTypes[] = new HasOffsetValueType($keyType, $this->valueTypes[$i]->generalize($precision)); } } elseif ($keyTypesCount > $optionalKeysCount) { $accessoryTypes[] = new NonEmptyArrayType(); } if ($this->isList()->yes()) { $arrayType = AccessoryArrayListType::intersectWith($arrayType); } if (count($accessoryTypes) > 0) { return TypeCombinator::intersect($arrayType, ...$accessoryTypes); } return $arrayType; } /** * @return self */ public function generalizeValues() : ArrayType { $valueTypes = []; foreach ($this->valueTypes as $valueType) { $valueTypes[] = $valueType->generalize(GeneralizePrecision::lessSpecific()); } return new self($this->keyTypes, $valueTypes, $this->nextAutoIndexes, $this->optionalKeys, $this->isList); } /** @deprecated */ public function generalizeToArray() : Type { $isIterableAtLeastOnce = $this->isIterableAtLeastOnce(); if ($isIterableAtLeastOnce->no()) { return $this; } $arrayType = new ArrayType($this->getIterableKeyType(), $this->getItemType()); if ($isIterableAtLeastOnce->yes()) { $arrayType = TypeCombinator::intersect($arrayType, new NonEmptyArrayType()); } if ($this->isList->yes()) { $arrayType = AccessoryArrayListType::intersectWith($arrayType); } return $arrayType; } /** * @return self */ public function getKeysArray() : Type { return $this->getKeysOrValuesArray($this->keyTypes); } /** * @return self */ public function getValuesArray() : Type { return $this->getKeysOrValuesArray($this->valueTypes); } /** * @param array $types */ private function getKeysOrValuesArray(array $types) : self { $count = count($types); $autoIndexes = range($count - count($this->optionalKeys), $count); assert($autoIndexes !== []); if ($this->isList->yes()) { // Optimized version for lists: Assume that if a later key exists, then earlier keys also exist. $keyTypes = array_map(static function (int $i) : \PHPStan\Type\Constant\ConstantIntegerType { return new \PHPStan\Type\Constant\ConstantIntegerType($i); }, array_keys($types)); return new self($keyTypes, $types, $autoIndexes, $this->optionalKeys, TrinaryLogic::createYes()); } $keyTypes = []; $valueTypes = []; $optionalKeys = []; $maxIndex = 0; foreach ($types as $i => $type) { $keyTypes[] = new \PHPStan\Type\Constant\ConstantIntegerType($i); if ($this->isOptionalKey($maxIndex)) { // move $maxIndex to next non-optional key do { $maxIndex++; } while ($maxIndex < $count && $this->isOptionalKey($maxIndex)); } if ($i === $maxIndex) { $valueTypes[] = $type; } else { $valueTypes[] = TypeCombinator::union(...array_slice($types, $i, $maxIndex - $i + 1)); if ($maxIndex >= $count) { $optionalKeys[] = $i; } } $maxIndex++; } return new self($keyTypes, $valueTypes, $autoIndexes, $optionalKeys, TrinaryLogic::createYes()); } /** @deprecated Use getArraySize() instead */ public function count() : Type { return $this->getArraySize(); } public function describe(VerbosityLevel $level) : string { $describeValue = function (bool $truncate) use($level) : string { $items = []; $values = []; $exportValuesOnly = \true; foreach ($this->keyTypes as $i => $keyType) { $valueType = $this->valueTypes[$i]; if ($keyType->getValue() !== $i) { $exportValuesOnly = \false; } $isOptional = $this->isOptionalKey($i); if ($isOptional) { $exportValuesOnly = \false; } $keyDescription = $keyType->getValue(); if (is_string($keyDescription)) { if (str_contains($keyDescription, '"')) { $keyDescription = sprintf('\'%s\'', $keyDescription); } elseif (str_contains($keyDescription, '\'')) { $keyDescription = sprintf('"%s"', $keyDescription); } } $valueTypeDescription = $valueType->describe($level); $items[] = sprintf('%s%s: %s', $keyDescription, $isOptional ? '?' : '', $valueTypeDescription); $values[] = $valueTypeDescription; } $append = ''; if ($truncate && count($items) > self::DESCRIBE_LIMIT) { $items = array_slice($items, 0, self::DESCRIBE_LIMIT); $values = array_slice($values, 0, self::DESCRIBE_LIMIT); $append = ', ...'; } return sprintf('array{%s%s}', implode(', ', $exportValuesOnly ? $values : $items), $append); }; return $level->handle(function () use($level) : string { return parent::describe($level); }, static function () use($describeValue) : string { return $describeValue(\true); }, static function () use($describeValue) : string { return $describeValue(\false); }); } public function inferTemplateTypes(Type $receivedType) : TemplateTypeMap { if ($receivedType instanceof UnionType || $receivedType instanceof IntersectionType) { return $receivedType->inferTemplateTypesOn($this); } if ($receivedType instanceof self) { $typeMap = TemplateTypeMap::createEmpty(); foreach ($this->keyTypes as $i => $keyType) { $valueType = $this->valueTypes[$i]; if ($receivedType->hasOffsetValueType($keyType)->no()) { continue; } $receivedValueType = $receivedType->getOffsetValueType($keyType); $typeMap = $typeMap->union($valueType->inferTemplateTypes($receivedValueType)); } return $typeMap; } return parent::inferTemplateTypes($receivedType); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { $variance = $positionVariance->compose(TemplateTypeVariance::createCovariant()); $references = []; foreach ($this->keyTypes as $type) { foreach ($type->getReferencedTemplateTypes($variance) as $reference) { $references[] = $reference; } } foreach ($this->valueTypes as $type) { foreach ($type->getReferencedTemplateTypes($variance) as $reference) { $references[] = $reference; } } return $references; } public function traverse(callable $cb) : Type { $valueTypes = []; $stillOriginal = \true; foreach ($this->valueTypes as $valueType) { $transformedValueType = $cb($valueType); if ($transformedValueType !== $valueType) { $stillOriginal = \false; } $valueTypes[] = $transformedValueType; } if ($stillOriginal) { return $this; } return new self($this->keyTypes, $valueTypes, $this->nextAutoIndexes, $this->optionalKeys, $this->isList); } public function traverseSimultaneously(Type $right, callable $cb) : Type { if (!$right->isArray()->yes()) { return $this; } $valueTypes = []; $stillOriginal = \true; foreach ($this->valueTypes as $i => $valueType) { $keyType = $this->keyTypes[$i]; $transformedValueType = $cb($valueType, $right->getOffsetValueType($keyType)); if ($transformedValueType !== $valueType) { $stillOriginal = \false; } $valueTypes[] = $transformedValueType; } if ($stillOriginal) { return $this; } return new self($this->keyTypes, $valueTypes, $this->nextAutoIndexes, $this->optionalKeys, $this->isList); } public function isKeysSupersetOf(self $otherArray) : bool { $keyTypesCount = count($this->keyTypes); $otherKeyTypesCount = count($otherArray->keyTypes); if ($keyTypesCount < $otherKeyTypesCount) { return \false; } if ($otherKeyTypesCount === 0) { return $keyTypesCount === 0; } $failOnDifferentValueType = $keyTypesCount !== $otherKeyTypesCount || $keyTypesCount < 2; $keyTypes = $this->keyTypes; foreach ($otherArray->keyTypes as $j => $keyType) { $i = self::findKeyIndex($keyType, $keyTypes); if ($i === null) { return \false; } unset($keyTypes[$i]); $valueType = $this->valueTypes[$i]; $otherValueType = $otherArray->valueTypes[$j]; if (!$otherValueType->isSuperTypeOf($valueType)->no()) { continue; } if ($failOnDifferentValueType) { return \false; } $failOnDifferentValueType = \true; } $requiredKeyCount = 0; foreach (array_keys($keyTypes) as $i) { if ($this->isOptionalKey($i)) { continue; } $requiredKeyCount++; if ($requiredKeyCount > 1) { return \false; } } return \true; } public function mergeWith(self $otherArray) : self { // only call this after verifying isKeysSupersetOf, or if losing tagged unions is not an issue $valueTypes = $this->valueTypes; $optionalKeys = $this->optionalKeys; foreach ($this->keyTypes as $i => $keyType) { $otherIndex = $otherArray->getKeyIndex($keyType); if ($otherIndex === null) { $optionalKeys[] = $i; continue; } if ($otherArray->isOptionalKey($otherIndex)) { $optionalKeys[] = $i; } $otherValueType = $otherArray->valueTypes[$otherIndex]; $valueTypes[$i] = TypeCombinator::union($valueTypes[$i], $otherValueType); } $optionalKeys = array_values(array_unique($optionalKeys)); $nextAutoIndexes = array_values(array_unique(array_merge($this->nextAutoIndexes, $otherArray->nextAutoIndexes))); sort($nextAutoIndexes); return new self($this->keyTypes, $valueTypes, $nextAutoIndexes, $optionalKeys, $this->isList->and($otherArray->isList)); } /** * @param ConstantIntegerType|ConstantStringType $otherKeyType */ private function getKeyIndex($otherKeyType) : ?int { return self::findKeyIndex($otherKeyType, $this->keyTypes); } /** * @param ConstantIntegerType|ConstantStringType $otherKeyType * @param array $keyTypes */ private static function findKeyIndex($otherKeyType, array $keyTypes) : ?int { foreach ($keyTypes as $i => $keyType) { if ($keyType->equals($otherKeyType)) { return $i; } } return null; } public function makeOffsetRequired(Type $offsetType) : self { $offsetType = $offsetType->toArrayKey(); $optionalKeys = $this->optionalKeys; foreach ($this->keyTypes as $i => $keyType) { if (!$keyType->equals($offsetType)) { continue; } foreach ($optionalKeys as $j => $key) { if ($i === $key) { unset($optionalKeys[$j]); return new self($this->keyTypes, $this->valueTypes, $this->nextAutoIndexes, array_values($optionalKeys), $this->isList); } } break; } return $this; } public function toPhpDocNode() : TypeNode { $items = []; $values = []; $exportValuesOnly = \true; foreach ($this->keyTypes as $i => $keyType) { if ($keyType->getValue() !== $i) { $exportValuesOnly = \false; } $keyPhpDocNode = $keyType->toPhpDocNode(); if (!$keyPhpDocNode instanceof ConstTypeNode) { continue; } $valueType = $this->valueTypes[$i]; /** @var ConstExprStringNode|ConstExprIntegerNode $keyNode */ $keyNode = $keyPhpDocNode->constExpr; if ($keyNode instanceof ConstExprStringNode) { $value = $keyNode->value; if (self::isValidIdentifier($value)) { $keyNode = new IdentifierTypeNode($value); } } $isOptional = $this->isOptionalKey($i); if ($isOptional) { $exportValuesOnly = \false; } $items[] = new ArrayShapeItemNode($keyNode, $isOptional, $valueType->toPhpDocNode()); $values[] = new ArrayShapeItemNode(null, $isOptional, $valueType->toPhpDocNode()); } return new ArrayShapeNode($exportValuesOnly ? $values : $items); } public static function isValidIdentifier(string $value) : bool { $result = Strings::match($value, '~^(?:[\\\\]?+[a-z_\\x80-\\xFF][0-9a-z_\\x80-\\xFF-]*+)++$~si'); return $result !== null; } public function getFiniteTypes() : array { $arraysArraysForCombinations = []; $count = 0; foreach ($this->getAllArrays() as $array) { $values = $array->getValueTypes(); $arraysForCombinations = []; $combinationCount = 1; foreach ($values as $valueType) { $finiteTypes = $valueType->getFiniteTypes(); if ($finiteTypes === []) { return []; } $arraysForCombinations[] = $finiteTypes; $combinationCount *= count($finiteTypes); } $arraysArraysForCombinations[] = $arraysForCombinations; $count += $combinationCount; } if ($count > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT) { return []; } $finiteTypes = []; foreach ($arraysArraysForCombinations as $arraysForCombinations) { $combinations = CombinationsHelper::combinations($arraysForCombinations); foreach ($combinations as $combination) { $builder = \PHPStan\Type\Constant\ConstantArrayTypeBuilder::createEmpty(); foreach ($combination as $i => $v) { $builder->setOffsetValueType($this->keyTypes[$i], $v); } $finiteTypes[] = $builder->getArray(); } } return $finiteTypes; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : Type { return new self($properties['keyTypes'], $properties['valueTypes'], $properties['nextAutoIndexes'] ?? $properties['nextAutoIndex'], $properties['optionalKeys'] ?? [], $properties['isList'] ?? TrinaryLogic::createNo()); } } type = $type; $this->method = $method; $this->certainty = $certainty; } public static function createConcrete(Type $type, string $method, TrinaryLogic $certainty) : self { if ($certainty->no()) { throw new ShouldNotHappenException(); } return new self($type, $method, $certainty); } public static function createUnknown() : self { return new self(null, null, TrinaryLogic::createMaybe()); } public function isUnknown() : bool { return $this->type === null; } public function getType() : Type { if ($this->type === null) { throw new ShouldNotHappenException(); } return $this->type; } public function getMethod() : string { if ($this->method === null) { throw new ShouldNotHappenException(); } return $this->method; } public function getCertainty() : TrinaryLogic { return $this->certainty; } } */ private $keyTypes; /** * @var array */ private $valueTypes; /** * @var non-empty-list */ private $nextAutoIndexes; /** * @var array */ private $optionalKeys; /** * @var TrinaryLogic */ private $isList; public const ARRAY_COUNT_LIMIT = 256; /** * @var bool */ private $degradeToGeneralArray = \false; /** * @var bool */ private $oversized = \false; /** * @param array $keyTypes * @param array $valueTypes * @param non-empty-list $nextAutoIndexes * @param array $optionalKeys */ private function __construct(array $keyTypes, array $valueTypes, array $nextAutoIndexes, array $optionalKeys, TrinaryLogic $isList) { $this->keyTypes = $keyTypes; $this->valueTypes = $valueTypes; $this->nextAutoIndexes = $nextAutoIndexes; $this->optionalKeys = $optionalKeys; $this->isList = $isList; } public static function createEmpty() : self { return new self([], [], [0], [], TrinaryLogic::createYes()); } public static function createFromConstantArray(\PHPStan\Type\Constant\ConstantArrayType $startArrayType) : self { $builder = new self($startArrayType->getKeyTypes(), $startArrayType->getValueTypes(), $startArrayType->getNextAutoIndexes(), $startArrayType->getOptionalKeys(), $startArrayType->isList()); if (count($startArrayType->getKeyTypes()) > self::ARRAY_COUNT_LIMIT) { $builder->degradeToGeneralArray(\true); } return $builder; } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $optional = \false) : void { if ($offsetType !== null) { $offsetType = $offsetType->toArrayKey(); } if (!$this->degradeToGeneralArray) { if ($offsetType === null) { $newAutoIndexes = $optional ? $this->nextAutoIndexes : []; $hasOptional = \false; foreach ($this->keyTypes as $i => $keyType) { if (!$keyType instanceof \PHPStan\Type\Constant\ConstantIntegerType) { continue; } if (!in_array($keyType->getValue(), $this->nextAutoIndexes, \true)) { continue; } $this->valueTypes[$i] = TypeCombinator::union($this->valueTypes[$i], $valueType); if (!$hasOptional && !$optional) { $this->optionalKeys = array_values(array_filter($this->optionalKeys, static function (int $index) use($i) : bool { return $index !== $i; })); } /** @var int|float $newAutoIndex */ $newAutoIndex = $keyType->getValue() + 1; if (is_float($newAutoIndex)) { $newAutoIndex = $keyType->getValue(); } $newAutoIndexes[] = $newAutoIndex; $hasOptional = \true; } $max = max($this->nextAutoIndexes); $this->keyTypes[] = new \PHPStan\Type\Constant\ConstantIntegerType($max); $this->valueTypes[] = $valueType; /** @var int|float $newAutoIndex */ $newAutoIndex = $max + 1; if (is_float($newAutoIndex)) { $newAutoIndex = $max; } $newAutoIndexes[] = $newAutoIndex; $this->nextAutoIndexes = array_values(array_unique($newAutoIndexes)); if ($optional || $hasOptional) { $this->optionalKeys[] = count($this->keyTypes) - 1; } if (count($this->keyTypes) > self::ARRAY_COUNT_LIMIT) { $this->degradeToGeneralArray = \true; $this->oversized = \true; } return; } if ($offsetType instanceof \PHPStan\Type\Constant\ConstantIntegerType || $offsetType instanceof \PHPStan\Type\Constant\ConstantStringType) { /** @var ConstantIntegerType|ConstantStringType $keyType */ foreach ($this->keyTypes as $i => $keyType) { if ($keyType->getValue() !== $offsetType->getValue()) { continue; } if ($optional) { $valueType = TypeCombinator::union($valueType, $this->valueTypes[$i]); } $this->valueTypes[$i] = $valueType; if (!$optional) { $this->optionalKeys = array_values(array_filter($this->optionalKeys, static function (int $index) use($i) : bool { return $index !== $i; })); if ($keyType instanceof \PHPStan\Type\Constant\ConstantIntegerType) { $nextAutoIndexes = array_values(array_filter($this->nextAutoIndexes, static function (int $index) use($keyType) { return $index > $keyType->getValue(); })); if (count($nextAutoIndexes) === 0) { throw new ShouldNotHappenException(); } $this->nextAutoIndexes = $nextAutoIndexes; } } return; } $this->keyTypes[] = $offsetType; $this->valueTypes[] = $valueType; if ($offsetType instanceof \PHPStan\Type\Constant\ConstantIntegerType) { $min = min($this->nextAutoIndexes); $max = max($this->nextAutoIndexes); if ($offsetType->getValue() > $min) { if ($offsetType->getValue() <= $max) { $this->isList = $this->isList->and(TrinaryLogic::createMaybe()); } else { $this->isList = TrinaryLogic::createNo(); } } if ($offsetType->getValue() >= $max) { /** @var int|float $newAutoIndex */ $newAutoIndex = $offsetType->getValue() + 1; if (is_float($newAutoIndex)) { $newAutoIndex = $max; } if (!$optional) { $this->nextAutoIndexes = [$newAutoIndex]; } else { $this->nextAutoIndexes[] = $newAutoIndex; } } } else { $this->isList = TrinaryLogic::createNo(); } if ($optional) { $this->optionalKeys[] = count($this->keyTypes) - 1; } if (count($this->keyTypes) > self::ARRAY_COUNT_LIMIT) { $this->degradeToGeneralArray = \true; $this->oversized = \true; } return; } $scalarTypes = $offsetType->getConstantScalarTypes(); if (count($scalarTypes) === 0) { $integerRanges = TypeUtils::getIntegerRanges($offsetType); if (count($integerRanges) > 0) { foreach ($integerRanges as $integerRange) { if ($integerRange->getMin() === null) { break; } if ($integerRange->getMax() === null) { break; } $rangeLength = $integerRange->getMax() - $integerRange->getMin(); if ($rangeLength >= self::ARRAY_COUNT_LIMIT) { $scalarTypes = []; break; } foreach (range($integerRange->getMin(), $integerRange->getMax()) as $rangeValue) { $scalarTypes[] = new \PHPStan\Type\Constant\ConstantIntegerType($rangeValue); } } } } if (count($scalarTypes) > 0 && count($scalarTypes) < self::ARRAY_COUNT_LIMIT) { $match = \true; $valueTypes = $this->valueTypes; foreach ($scalarTypes as $scalarType) { $scalarOffsetType = $scalarType->toArrayKey(); if (!$scalarOffsetType instanceof \PHPStan\Type\Constant\ConstantIntegerType && !$scalarOffsetType instanceof \PHPStan\Type\Constant\ConstantStringType) { throw new ShouldNotHappenException(); } $offsetMatch = \false; /** @var ConstantIntegerType|ConstantStringType $keyType */ foreach ($this->keyTypes as $i => $keyType) { if ($keyType->getValue() !== $scalarOffsetType->getValue()) { continue; } $valueTypes[$i] = TypeCombinator::union($valueTypes[$i], $valueType); $offsetMatch = \true; } if ($offsetMatch) { continue; } $match = \false; } if ($match) { $this->valueTypes = $valueTypes; return; } } $this->isList = TrinaryLogic::createNo(); } if ($offsetType === null) { $offsetType = TypeCombinator::union(...array_map(static function (int $index) { return new \PHPStan\Type\Constant\ConstantIntegerType($index); }, $this->nextAutoIndexes)); } else { $this->isList = TrinaryLogic::createNo(); } $this->keyTypes[] = $offsetType; $this->valueTypes[] = $valueType; if ($optional) { $this->optionalKeys[] = count($this->keyTypes) - 1; } $this->degradeToGeneralArray = \true; } public function degradeToGeneralArray(bool $oversized = \false) : void { $this->degradeToGeneralArray = \true; $this->oversized = $this->oversized || $oversized; } public function getArray() : Type { $keyTypesCount = count($this->keyTypes); if ($keyTypesCount === 0) { return new \PHPStan\Type\Constant\ConstantArrayType([], []); } if (!$this->degradeToGeneralArray) { /** @var array $keyTypes */ $keyTypes = $this->keyTypes; return new \PHPStan\Type\Constant\ConstantArrayType($keyTypes, $this->valueTypes, $this->nextAutoIndexes, $this->optionalKeys, $this->isList); } $array = new ArrayType(TypeCombinator::union(...$this->keyTypes), TypeCombinator::union(...$this->valueTypes)); if (count($this->optionalKeys) < $keyTypesCount) { $array = TypeCombinator::intersect($array, new NonEmptyArrayType()); } if ($this->oversized) { $array = TypeCombinator::intersect($array, new OversizedArrayType()); } if ($this->isList->yes()) { $array = AccessoryArrayListType::intersectWith($array); } return $array; } public function isList() : bool { return $this->isList->yes(); } } value = $value; } /** * @param self::* $value */ private static function create(int $value) : self { self::$registry[$value] = self::$registry[$value] ?? new self($value); return self::$registry[$value]; } /** @return self::* */ public function getLevelValue() : int { return $this->value; } /** @api */ public static function typeOnly() : self { return self::create(self::TYPE_ONLY); } /** @api */ public static function value() : self { return self::create(self::VALUE); } /** @api */ public static function precise() : self { return self::create(self::PRECISE); } /** @api */ public static function cache() : self { return self::create(self::CACHE); } public function isTypeOnly() : bool { return $this->value === self::TYPE_ONLY; } public function isValue() : bool { return $this->value === self::VALUE; } public function isPrecise() : bool { return $this->value === self::PRECISE; } /** @api */ public static function getRecommendedLevelByType(\PHPStan\Type\Type $acceptingType, ?\PHPStan\Type\Type $acceptedType = null) : self { $moreVerboseCallback = static function (\PHPStan\Type\Type $type, callable $traverse) use(&$moreVerbose, &$veryVerbose) : \PHPStan\Type\Type { if ($type->isCallable()->yes()) { $moreVerbose = \true; // Keep checking if we need to be very verbose. return $traverse($type); } if ($type->isConstantValue()->yes() && $type->isNull()->no()) { $moreVerbose = \true; // For ConstantArrayType we need to keep checking if we need to be very verbose. if (!$type->isArray()->no()) { return $traverse($type); } return $type; } if ($type instanceof AccessoryNonEmptyStringType || $type instanceof AccessoryNonFalsyStringType || $type instanceof AccessoryLiteralStringType || $type instanceof AccessoryNumericStringType || $type instanceof NonEmptyArrayType || $type instanceof AccessoryArrayListType) { $moreVerbose = \true; return $type; } if ($type instanceof AccessoryLowercaseStringType || $type instanceof AccessoryUppercaseStringType) { $moreVerbose = \true; $veryVerbose = \true; return $type; } if ($type instanceof \PHPStan\Type\IntegerRangeType) { $moreVerbose = \true; return $type; } return $traverse($type); }; /** @var bool $moreVerbose */ $moreVerbose = \false; /** @var bool $veryVerbose */ $veryVerbose = \false; \PHPStan\Type\TypeTraverser::map($acceptingType, $moreVerboseCallback); if ($veryVerbose) { return self::precise(); } if ($moreVerbose) { $verbosity = self::value(); } if ($acceptedType === null) { return $verbosity ?? self::typeOnly(); } $containsInvariantTemplateType = \false; \PHPStan\Type\TypeTraverser::map($acceptingType, static function (\PHPStan\Type\Type $type, callable $traverse) use(&$containsInvariantTemplateType) : \PHPStan\Type\Type { if ($type instanceof GenericObjectType || $type instanceof GenericStaticType) { $reflection = $type->getClassReflection(); if ($reflection !== null) { $templateTypeMap = $reflection->getTemplateTypeMap(); foreach ($templateTypeMap->getTypes() as $templateType) { if (!$templateType instanceof TemplateType) { continue; } if (!$templateType->getVariance()->invariant()) { continue; } $containsInvariantTemplateType = \true; return $type; } } } return $traverse($type); }); if (!$containsInvariantTemplateType) { return $verbosity ?? self::typeOnly(); } /** @var bool $moreVerbose */ $moreVerbose = \false; /** @var bool $veryVerbose */ $veryVerbose = \false; \PHPStan\Type\TypeTraverser::map($acceptedType, $moreVerboseCallback); if ($veryVerbose) { return self::precise(); } return $moreVerbose ? self::value() : $verbosity ?? self::typeOnly(); } /** * @param callable(): string $typeOnlyCallback * @param callable(): string $valueCallback * @param callable(): string|null $preciseCallback * @param callable(): string|null $cacheCallback */ public function handle(callable $typeOnlyCallback, callable $valueCallback, ?callable $preciseCallback = null, ?callable $cacheCallback = null) : string { if ($this->value === self::TYPE_ONLY) { return $typeOnlyCallback(); } if ($this->value === self::VALUE) { return $valueCallback(); } if ($this->value === self::PRECISE) { if ($preciseCallback !== null) { return $preciseCallback(); } return $valueCallback(); } if ($cacheCallback !== null) { return $cacheCallback(); } if ($preciseCallback !== null) { return $preciseCallback(); } return $valueCallback(); } } 1024) { return $types; } usort($types, static function (\PHPStan\Type\Type $a, \PHPStan\Type\Type $b) : int { if ($a instanceof \PHPStan\Type\NullType) { return 1; } elseif ($b instanceof \PHPStan\Type\NullType) { return -1; } if ($a instanceof AccessoryType) { if ($b instanceof AccessoryType) { return self::compareStrings($a->describe(\PHPStan\Type\VerbosityLevel::value()), $b->describe(\PHPStan\Type\VerbosityLevel::value())); } return 1; } if ($b instanceof AccessoryType) { return -1; } $aIsBool = $a instanceof ConstantBooleanType; $bIsBool = $b instanceof ConstantBooleanType; if ($aIsBool && !$bIsBool) { return 1; } elseif ($bIsBool && !$aIsBool) { return -1; } if ($a instanceof \PHPStan\Type\ConstantScalarType && !$b instanceof \PHPStan\Type\ConstantScalarType) { return -1; } elseif (!$a instanceof \PHPStan\Type\ConstantScalarType && $b instanceof \PHPStan\Type\ConstantScalarType) { return 1; } if (($a instanceof ConstantIntegerType || $a instanceof ConstantFloatType) && ($b instanceof ConstantIntegerType || $b instanceof ConstantFloatType)) { $cmp = $a->getValue() <=> $b->getValue(); if ($cmp !== 0) { return $cmp; } if ($a instanceof ConstantIntegerType && $b instanceof ConstantFloatType) { return -1; } if ($b instanceof ConstantIntegerType && $a instanceof ConstantFloatType) { return 1; } return 0; } if ($a instanceof \PHPStan\Type\IntegerRangeType && $b instanceof \PHPStan\Type\IntegerRangeType) { return ($a->getMin() ?? PHP_INT_MIN) <=> ($b->getMin() ?? PHP_INT_MIN); } if ($a instanceof \PHPStan\Type\IntegerRangeType && $b instanceof \PHPStan\Type\IntegerType) { return 1; } if ($b instanceof \PHPStan\Type\IntegerRangeType && $a instanceof \PHPStan\Type\IntegerType) { return -1; } if ($a instanceof ConstantStringType && $b instanceof ConstantStringType) { return self::compareStrings($a->getValue(), $b->getValue()); } if ($a->isConstantArray()->yes() && $b->isConstantArray()->yes()) { if ($a->isIterableAtLeastOnce()->no()) { if ($b->isIterableAtLeastOnce()->no()) { return 0; } return -1; } elseif ($b->isIterableAtLeastOnce()->no()) { return 1; } return self::compareStrings($a->describe(\PHPStan\Type\VerbosityLevel::value()), $b->describe(\PHPStan\Type\VerbosityLevel::value())); } if (($a instanceof \PHPStan\Type\CallableType || $a instanceof \PHPStan\Type\ClosureType) && ($b instanceof \PHPStan\Type\CallableType || $b instanceof \PHPStan\Type\ClosureType)) { return self::compareStrings($a->describe(\PHPStan\Type\VerbosityLevel::value()), $b->describe(\PHPStan\Type\VerbosityLevel::value())); } if ($a->isString()->yes() && $b->isString()->yes()) { return self::compareStrings($a->describe(\PHPStan\Type\VerbosityLevel::precise()), $b->describe(\PHPStan\Type\VerbosityLevel::precise())); } return self::compareStrings($a->describe(\PHPStan\Type\VerbosityLevel::typeOnly()), $b->describe(\PHPStan\Type\VerbosityLevel::typeOnly())); }); return $types; } private static function compareStrings(string $a, string $b) : int { $cmp = strcasecmp($a, $b); if ($cmp !== 0) { return $cmp; } return $a <=> $b; } } */ private $resolvedPhpDocBlockCache = []; /** * @var int */ private $resolvedPhpDocBlockCacheCount = 0; public function __construct(ReflectionProviderProvider $reflectionProviderProvider, Parser $phpParser, PhpDocStringResolver $phpDocStringResolver, PhpDocNodeResolver $phpDocNodeResolver, AnonymousClassNameHelper $anonymousClassNameHelper, FileHelper $fileHelper) { $this->reflectionProviderProvider = $reflectionProviderProvider; $this->phpParser = $phpParser; $this->phpDocStringResolver = $phpDocStringResolver; $this->phpDocNodeResolver = $phpDocNodeResolver; $this->anonymousClassNameHelper = $anonymousClassNameHelper; $this->fileHelper = $fileHelper; } /** @api */ public function getResolvedPhpDoc(?string $fileName, ?string $className, ?string $traitName, ?string $functionName, string $docComment) : ResolvedPhpDocBlock { if ($className === null && $traitName !== null) { throw new ShouldNotHappenException(); } if ($docComment === '') { return ResolvedPhpDocBlock::createEmpty(); } if ($fileName !== null) { $fileName = $this->fileHelper->normalizePath($fileName); } $nameScopeKey = $this->getNameScopeKey($fileName, $className, $traitName, $functionName); $phpDocKey = md5(sprintf('%s-%s', $nameScopeKey, $docComment)); if (isset($this->resolvedPhpDocBlockCache[$phpDocKey])) { return $this->resolvedPhpDocBlockCache[$phpDocKey]; } if ($fileName === null) { return $this->createResolvedPhpDocBlock($phpDocKey, new NameScope(null, []), $docComment, null); } try { $nameScope = $this->getNameScope($fileName, $className, $traitName, $functionName); } catch (NameScopeAlreadyBeingCreatedException $e) { return ResolvedPhpDocBlock::createEmpty(); } return $this->createResolvedPhpDocBlock($phpDocKey, $nameScope, $docComment, $fileName); } /** * @throws NameScopeAlreadyBeingCreatedException */ public function getNameScope(string $fileName, ?string $className, ?string $traitName, ?string $functionName) : NameScope { $nameScopeKey = $this->getNameScopeKey($fileName, $className, $traitName, $functionName); $nameScopeMap = []; if (!isset($this->inProcess[$fileName])) { $nameScopeMap = $this->getNameScopeMap($fileName); } if (isset($nameScopeMap[$nameScopeKey])) { return $nameScopeMap[$nameScopeKey]; } if (!isset($this->inProcess[$fileName][$nameScopeKey])) { // wrong $fileName due to traits throw new NameScopeAlreadyBeingCreatedException(); } if ($this->inProcess[$fileName][$nameScopeKey] === \true) { // PHPDoc has cyclic dependency throw new NameScopeAlreadyBeingCreatedException(); } if (is_callable($this->inProcess[$fileName][$nameScopeKey])) { $resolveCallback = $this->inProcess[$fileName][$nameScopeKey]; $this->inProcess[$fileName][$nameScopeKey] = \true; $this->inProcess[$fileName][$nameScopeKey] = $resolveCallback(); } return $this->inProcess[$fileName][$nameScopeKey]; } private function createResolvedPhpDocBlock(string $phpDocKey, NameScope $nameScope, string $phpDocString, ?string $fileName) : ResolvedPhpDocBlock { $phpDocNode = $this->phpDocStringResolver->resolve($phpDocString); if ($this->resolvedPhpDocBlockCacheCount >= 2048) { $this->resolvedPhpDocBlockCache = array_slice($this->resolvedPhpDocBlockCache, 1, null, \true); $this->resolvedPhpDocBlockCacheCount--; } $templateTypeMap = $nameScope->getTemplateTypeMap(); $phpDocTemplateTypes = []; $templateTags = $this->phpDocNodeResolver->resolveTemplateTags($phpDocNode, $nameScope); foreach (array_keys($templateTags) as $name) { $templateType = $templateTypeMap->getType($name); if ($templateType === null) { continue; } $phpDocTemplateTypes[$name] = $templateType; } $this->resolvedPhpDocBlockCache[$phpDocKey] = ResolvedPhpDocBlock::create($phpDocNode, $phpDocString, $fileName, $nameScope, new TemplateTypeMap($phpDocTemplateTypes), $templateTags, $this->phpDocNodeResolver, $this->reflectionProviderProvider->getReflectionProvider()); $this->resolvedPhpDocBlockCacheCount++; return $this->resolvedPhpDocBlockCache[$phpDocKey]; } /** * @return NameScope[] */ private function getNameScopeMap(string $fileName) : array { if (!isset($this->memoryCache[$fileName])) { $map = $this->createResolvedPhpDocMap($fileName); if ($this->memoryCacheCount >= 2048) { $this->memoryCache = array_slice($this->memoryCache, 1, null, \true); $this->memoryCacheCount--; } $this->memoryCache[$fileName] = $map; $this->memoryCacheCount++; } return $this->memoryCache[$fileName]; } /** * @return NameScope[] */ private function createResolvedPhpDocMap(string $fileName) : array { $phpDocNodeMap = $this->createPhpDocNodeMap($fileName, null, $fileName, [], $fileName); $nameScopeMap = $this->createNameScopeMap($fileName, null, null, [], $fileName, $phpDocNodeMap); $resolvedNameScopeMap = []; try { $this->inProcess[$fileName] = $nameScopeMap; foreach ($nameScopeMap as $nameScopeKey => $resolveCallback) { $this->inProcess[$fileName][$nameScopeKey] = \true; $this->inProcess[$fileName][$nameScopeKey] = $data = $resolveCallback(); $resolvedNameScopeMap[$nameScopeKey] = $data; } } finally { unset($this->inProcess[$fileName]); } return $resolvedNameScopeMap; } /** * @param array $traitMethodAliases * @return array */ private function createPhpDocNodeMap(string $fileName, ?string $lookForTrait, ?string $traitUseClass, array $traitMethodAliases, string $originalClassFileName) : array { /** @var array $phpDocNodeMap */ $phpDocNodeMap = []; /** @var string[] $classStack */ $classStack = []; if ($lookForTrait !== null && $traitUseClass !== null) { $classStack[] = $traitUseClass; } $namespace = null; $traitFound = \false; /** @var array $functionStack */ $functionStack = []; $this->processNodes($this->phpParser->parseFile($fileName), function (Node $node) use($fileName, $lookForTrait, &$traitFound, $traitMethodAliases, $originalClassFileName, &$phpDocNodeMap, &$classStack, &$namespace, &$functionStack) : ?int { if ($node instanceof Node\Stmt\ClassLike) { if ($traitFound && $fileName === $originalClassFileName) { return self::SKIP_NODE; } if ($lookForTrait !== null && !$traitFound) { if (!$node instanceof Node\Stmt\Trait_) { return self::SKIP_NODE; } if ((string) $node->namespacedName !== $lookForTrait) { return self::SKIP_NODE; } $traitFound = \true; $functionStack[] = null; } else { if ($node->name === null) { if (!$node instanceof Node\Stmt\Class_) { throw new ShouldNotHappenException(); } $className = $this->anonymousClassNameHelper->getAnonymousClassName($node, $fileName); } elseif ($node instanceof Node\Stmt\Class_ && $node->isAnonymous()) { $className = $node->name->name; } else { if ($traitFound) { return self::SKIP_NODE; } $className = ltrim(sprintf('%s\\%s', $namespace, $node->name->name), '\\'); } $classStack[] = $className; $functionStack[] = null; } } elseif ($node instanceof Node\Stmt\ClassMethod) { if (array_key_exists($node->name->name, $traitMethodAliases)) { $functionStack[] = $traitMethodAliases[$node->name->name]; } else { $functionStack[] = $node->name->name; } } elseif ($node instanceof Node\Stmt\Function_) { $functionStack[] = ltrim(sprintf('%s\\%s', $namespace, $node->name->name), '\\'); } $className = $classStack[count($classStack) - 1] ?? null; $functionName = $functionStack[count($functionStack) - 1] ?? null; if ($node instanceof Node\Stmt\ClassLike || $node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Stmt\Function_) { $docComment = GetLastDocComment::forNode($node); if ($docComment !== null) { $nameScopeKey = $this->getNameScopeKey($originalClassFileName, $className, $lookForTrait, $functionName); $phpDocNodeMap[$nameScopeKey] = $this->phpDocStringResolver->resolve($docComment); } return null; } if ($node instanceof Node\Stmt\Namespace_) { $namespace = $node->name !== null ? (string) $node->name : null; } elseif ($node instanceof Node\Stmt\TraitUse) { $traitMethodAliases = []; foreach ($node->adaptations as $traitUseAdaptation) { if (!$traitUseAdaptation instanceof Node\Stmt\TraitUseAdaptation\Alias) { continue; } if ($traitUseAdaptation->newName === null) { continue; } $methodName = $traitUseAdaptation->method->toString(); $newTraitName = $traitUseAdaptation->newName->toString(); if ($traitUseAdaptation->trait === null) { foreach ($node->traits as $traitName) { $traitMethodAliases[$traitName->toString()][$methodName] = $newTraitName; } continue; } $traitMethodAliases[$traitUseAdaptation->trait->toString()][$methodName] = $newTraitName; } foreach ($node->traits as $traitName) { /** @var class-string $traitName */ $traitName = (string) $traitName; $reflectionProvider = $this->reflectionProviderProvider->getReflectionProvider(); if (!$reflectionProvider->hasClass($traitName)) { continue; } $traitReflection = $reflectionProvider->getClass($traitName); if (!$traitReflection->isTrait()) { continue; } if ($traitReflection->getFileName() === null) { continue; } if (!is_file($traitReflection->getFileName())) { continue; } $className = $classStack[count($classStack) - 1] ?? null; if ($className === null) { throw new ShouldNotHappenException(); } $phpDocNodeMap = array_merge($phpDocNodeMap, $this->createPhpDocNodeMap($traitReflection->getFileName(), $traitName, $className, $traitMethodAliases[$traitName] ?? [], $originalClassFileName)); } } return null; }, static function (Node $node) use(&$namespace, &$functionStack, &$classStack) : void { if ($node instanceof Node\Stmt\ClassLike) { if (count($classStack) === 0) { throw new ShouldNotHappenException(); } array_pop($classStack); if (count($functionStack) === 0) { throw new ShouldNotHappenException(); } array_pop($functionStack); } elseif ($node instanceof Node\Stmt\Namespace_) { $namespace = null; } elseif ($node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Stmt\Function_) { if (count($functionStack) === 0) { throw new ShouldNotHappenException(); } array_pop($functionStack); } }); return $phpDocNodeMap; } /** * @param array $traitMethodAliases * @param array $phpDocNodeMap * @return (callable(): NameScope)[] */ private function createNameScopeMap(string $fileName, ?string $lookForTrait, ?string $traitUseClass, array $traitMethodAliases, string $originalClassFileName, array $phpDocNodeMap) : array { /** @var (callable(): NameScope)[] $nameScopeMap */ $nameScopeMap = []; /** @var (callable(): TemplateTypeMap)[] $typeMapStack */ $typeMapStack = []; /** @var array> $typeAliasStack */ $typeAliasStack = []; /** @var string[] $classStack */ $classStack = []; if ($lookForTrait !== null && $traitUseClass !== null) { $classStack[] = $traitUseClass; $typeAliasStack[] = []; } $namespace = null; $traitFound = \false; /** @var array $functionStack */ $functionStack = []; $uses = []; $constUses = []; $this->processNodes($this->phpParser->parseFile($fileName), function (Node $node) use($fileName, $lookForTrait, $phpDocNodeMap, &$traitFound, $traitMethodAliases, $originalClassFileName, &$nameScopeMap, &$classStack, &$typeAliasStack, &$namespace, &$functionStack, &$uses, &$typeMapStack, &$constUses) : ?int { if ($node instanceof Node\Stmt\ClassLike) { if ($traitFound && $fileName === $originalClassFileName) { return self::SKIP_NODE; } if ($lookForTrait !== null && !$traitFound) { if (!$node instanceof Node\Stmt\Trait_) { return self::SKIP_NODE; } if ((string) $node->namespacedName !== $lookForTrait) { return self::SKIP_NODE; } $traitFound = \true; $traitNameScopeKey = $this->getNameScopeKey($originalClassFileName, $classStack[count($classStack) - 1] ?? null, $lookForTrait, null); if (array_key_exists($traitNameScopeKey, $phpDocNodeMap)) { $typeAliasStack[] = $this->getTypeAliasesMap($phpDocNodeMap[$traitNameScopeKey]); } else { $typeAliasStack[] = []; } $functionStack[] = null; } else { if ($node->name === null) { if (!$node instanceof Node\Stmt\Class_) { throw new ShouldNotHappenException(); } $className = $this->anonymousClassNameHelper->getAnonymousClassName($node, $fileName); } elseif ($node instanceof Node\Stmt\Class_ && $node->isAnonymous()) { $className = $node->name->name; } else { if ($traitFound) { return self::SKIP_NODE; } $className = ltrim(sprintf('%s\\%s', $namespace, $node->name->name), '\\'); } $classStack[] = $className; $classNameScopeKey = $this->getNameScopeKey($originalClassFileName, $className, $lookForTrait, null); if (array_key_exists($classNameScopeKey, $phpDocNodeMap)) { $typeAliasStack[] = $this->getTypeAliasesMap($phpDocNodeMap[$classNameScopeKey]); } else { $typeAliasStack[] = []; } $functionStack[] = null; } } elseif ($node instanceof Node\Stmt\ClassMethod) { if (array_key_exists($node->name->name, $traitMethodAliases)) { $functionStack[] = $traitMethodAliases[$node->name->name]; } else { $functionStack[] = $node->name->name; } } elseif ($node instanceof Node\Stmt\Function_) { $functionStack[] = ltrim(sprintf('%s\\%s', $namespace, $node->name->name), '\\'); } $className = $classStack[count($classStack) - 1] ?? null; $functionName = $functionStack[count($functionStack) - 1] ?? null; $nameScopeKey = $this->getNameScopeKey($originalClassFileName, $className, $lookForTrait, $functionName); if ($namespace === '') { throw new ShouldNotHappenException('Namespace cannot be empty.'); } if ($node instanceof Node\Stmt\ClassLike || $node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Stmt\Function_) { if (array_key_exists($nameScopeKey, $phpDocNodeMap)) { $phpDocNode = $phpDocNodeMap[$nameScopeKey]; $typeMapStack[] = function () use($namespace, $uses, $className, $lookForTrait, $functionName, $phpDocNode, $typeMapStack, $typeAliasStack, $constUses) : TemplateTypeMap { $typeMapCb = $typeMapStack[count($typeMapStack) - 1] ?? null; $currentTypeMap = $typeMapCb !== null ? $typeMapCb() : null; $typeAliasesMap = $typeAliasStack[count($typeAliasStack) - 1] ?? []; $nameScope = new NameScope($namespace, $uses, $className, $functionName, $currentTypeMap, $typeAliasesMap, \false, $constUses, $lookForTrait); $templateTags = $this->phpDocNodeResolver->resolveTemplateTags($phpDocNode, $nameScope); $templateTypeScope = $nameScope->getTemplateTypeScope(); if ($templateTypeScope === null) { throw new ShouldNotHappenException(); } $templateTypeMap = new TemplateTypeMap(array_map(static function (TemplateTag $tag) use($templateTypeScope) : \PHPStan\Type\Type { return TemplateTypeFactory::fromTemplateTag($templateTypeScope, $tag); }, $templateTags)); $nameScope = $nameScope->withTemplateTypeMap($templateTypeMap); $templateTags = $this->phpDocNodeResolver->resolveTemplateTags($phpDocNode, $nameScope); $templateTypeMap = new TemplateTypeMap(array_map(static function (TemplateTag $tag) use($templateTypeScope) : \PHPStan\Type\Type { return TemplateTypeFactory::fromTemplateTag($templateTypeScope, $tag); }, $templateTags)); return new TemplateTypeMap(array_merge($currentTypeMap !== null ? $currentTypeMap->getTypes() : [], $templateTypeMap->getTypes())); }; } } $typeMapCb = $typeMapStack[count($typeMapStack) - 1] ?? null; $typeAliasesMap = $typeAliasStack[count($typeAliasStack) - 1] ?? []; if ($node instanceof Node\Stmt && !$node instanceof Node\Stmt\Namespace_ && !$node instanceof Node\Stmt\Declare_ && !$node instanceof Node\Stmt\DeclareDeclare && !$node instanceof Node\Stmt\Use_ && !$node instanceof Node\Stmt\UseUse && !$node instanceof Node\Stmt\GroupUse && !$node instanceof Node\Stmt\TraitUse && !$node instanceof Node\Stmt\TraitUseAdaptation && !$node instanceof Node\Stmt\InlineHTML && !($node instanceof Node\Stmt\Expression && $node->expr instanceof Node\Expr\Include_) && !array_key_exists($nameScopeKey, $nameScopeMap)) { $nameScopeMap[$nameScopeKey] = static function () use($namespace, $uses, $className, $functionName, $typeMapCb, $typeAliasesMap, $constUses, $lookForTrait) : NameScope { return new NameScope($namespace, $uses, $className, $functionName, $typeMapCb !== null ? $typeMapCb() : TemplateTypeMap::createEmpty(), $typeAliasesMap, \false, $constUses, $lookForTrait); }; } if ($node instanceof Node\Stmt\ClassLike || $node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Stmt\Function_) { if (array_key_exists($nameScopeKey, $phpDocNodeMap)) { return self::POP_TYPE_MAP_STACK; } return null; } if ($node instanceof Node\Stmt\Namespace_) { $namespace = $node->name !== null ? (string) $node->name : null; } elseif ($node instanceof Node\Stmt\Use_) { if ($node->type === Node\Stmt\Use_::TYPE_NORMAL) { foreach ($node->uses as $use) { $uses[strtolower($use->getAlias()->name)] = (string) $use->name; } } elseif ($node->type === Node\Stmt\Use_::TYPE_CONSTANT) { foreach ($node->uses as $use) { $constUses[strtolower($use->getAlias()->name)] = (string) $use->name; } } } elseif ($node instanceof Node\Stmt\GroupUse) { $prefix = (string) $node->prefix; foreach ($node->uses as $use) { if ($node->type === Node\Stmt\Use_::TYPE_NORMAL || $use->type === Node\Stmt\Use_::TYPE_NORMAL) { $uses[strtolower($use->getAlias()->name)] = sprintf('%s\\%s', $prefix, (string) $use->name); } elseif ($node->type === Node\Stmt\Use_::TYPE_CONSTANT || $use->type === Node\Stmt\Use_::TYPE_CONSTANT) { $constUses[strtolower($use->getAlias()->name)] = sprintf('%s\\%s', $prefix, (string) $use->name); } } } elseif ($node instanceof Node\Stmt\TraitUse) { $traitMethodAliases = []; foreach ($node->adaptations as $traitUseAdaptation) { if (!$traitUseAdaptation instanceof Node\Stmt\TraitUseAdaptation\Alias) { continue; } if ($traitUseAdaptation->newName === null) { continue; } $methodName = $traitUseAdaptation->method->toString(); $newTraitName = $traitUseAdaptation->newName->toString(); if ($traitUseAdaptation->trait === null) { foreach ($node->traits as $traitName) { $traitMethodAliases[$traitName->toString()][$methodName] = $newTraitName; } continue; } $traitMethodAliases[$traitUseAdaptation->trait->toString()][$methodName] = $newTraitName; } $useDocComment = null; if ($node->getDocComment() !== null) { $useDocComment = $node->getDocComment()->getText(); } foreach ($node->traits as $traitName) { /** @var class-string $traitName */ $traitName = (string) $traitName; $reflectionProvider = $this->reflectionProviderProvider->getReflectionProvider(); if (!$reflectionProvider->hasClass($traitName)) { continue; } $traitReflection = $reflectionProvider->getClass($traitName); if (!$traitReflection->isTrait()) { continue; } if ($traitReflection->getFileName() === null) { continue; } if (!is_file($traitReflection->getFileName())) { continue; } $className = $classStack[count($classStack) - 1] ?? null; if ($className === null) { throw new ShouldNotHappenException(); } $traitPhpDocMap = $this->createNameScopeMap($traitReflection->getFileName(), $traitName, $className, $traitMethodAliases[$traitName] ?? [], $originalClassFileName, $phpDocNodeMap); $finalTraitPhpDocMap = []; foreach ($traitPhpDocMap as $nameScopeTraitKey => $callback) { $finalTraitPhpDocMap[$nameScopeTraitKey] = function () use($callback, $traitReflection, $fileName, $className, $lookForTrait, $useDocComment) : NameScope { /** @var NameScope $original */ $original = $callback(); if (!$traitReflection->isGeneric()) { return $original; } $traitTemplateTypeMap = $traitReflection->getTemplateTypeMap(); $useType = null; if ($useDocComment !== null) { $useTags = $this->getResolvedPhpDoc($fileName, $className, $lookForTrait, null, $useDocComment)->getUsesTags(); foreach ($useTags as $useTag) { $useTagType = $useTag->getType(); if (!$useTagType instanceof GenericObjectType) { continue; } if ($useTagType->getClassName() !== $traitReflection->getName()) { continue; } $useType = $useTagType; break; } } if ($useType === null) { return $original->withTemplateTypeMap($traitTemplateTypeMap->resolveToBounds()); } $transformedTraitTypeMap = $traitReflection->typeMapFromList($useType->getTypes()); return $original->withTemplateTypeMap($traitTemplateTypeMap->map(static function (string $name, \PHPStan\Type\Type $type) use($transformedTraitTypeMap) : \PHPStan\Type\Type { return TemplateTypeHelper::resolveTemplateTypes($type, $transformedTraitTypeMap, TemplateTypeVarianceMap::createEmpty(), TemplateTypeVariance::createStatic()); })); }; } $nameScopeMap = array_merge($nameScopeMap, $finalTraitPhpDocMap); } } return null; }, static function (Node $node, $callbackResult) use(&$namespace, &$functionStack, &$classStack, &$typeAliasStack, &$uses, &$typeMapStack, &$constUses) : void { if ($node instanceof Node\Stmt\ClassLike) { if (count($classStack) === 0) { throw new ShouldNotHappenException(); } array_pop($classStack); if (count($typeAliasStack) === 0) { throw new ShouldNotHappenException(); } array_pop($typeAliasStack); if (count($functionStack) === 0) { throw new ShouldNotHappenException(); } array_pop($functionStack); } elseif ($node instanceof Node\Stmt\Namespace_) { $namespace = null; $uses = []; $constUses = []; } elseif ($node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Stmt\Function_) { if (count($functionStack) === 0) { throw new ShouldNotHappenException(); } array_pop($functionStack); } if ($callbackResult !== self::POP_TYPE_MAP_STACK) { return; } if (count($typeMapStack) === 0) { throw new ShouldNotHappenException(); } array_pop($typeMapStack); }); if (count($typeMapStack) > 0) { throw new ShouldNotHappenException(); } return $nameScopeMap; } /** * @return array */ private function getTypeAliasesMap(PhpDocNode $phpDocNode) : array { $nameScope = new NameScope(null, []); $aliasesMap = []; foreach (array_keys($this->phpDocNodeResolver->resolveTypeAliasImportTags($phpDocNode, $nameScope)) as $key) { $aliasesMap[$key] = \true; } foreach (array_keys($this->phpDocNodeResolver->resolveTypeAliasTags($phpDocNode, $nameScope)) as $key) { $aliasesMap[$key] = \true; } return $aliasesMap; } /** * @param Node[]|Node|scalar|null $node * @param Closure(Node $node): mixed $nodeCallback * @param Closure(Node $node, mixed $callbackResult): void $endNodeCallback */ private function processNodes($node, Closure $nodeCallback, Closure $endNodeCallback) : void { if ($node instanceof Node) { $callbackResult = $nodeCallback($node); if ($callbackResult === self::SKIP_NODE) { return; } foreach ($node->getSubNodeNames() as $subNodeName) { $subNode = $node->{$subNodeName}; $this->processNodes($subNode, $nodeCallback, $endNodeCallback); } $endNodeCallback($node, $callbackResult); } elseif (is_array($node)) { foreach ($node as $subNode) { $this->processNodes($subNode, $nodeCallback, $endNodeCallback); } } } private function getNameScopeKey(?string $file, ?string $class, ?string $trait, ?string $function) : string { if ($class === null && $trait === null && $function === null) { return md5(sprintf('%s', $file ?? 'no-file')); } if ($class !== null && str_contains($class, 'class@anonymous')) { throw new ShouldNotHappenException('Wrong anonymous class name, FilTypeMapper should be called with ClassReflection::getName().'); } return md5(sprintf('%s-%s-%s-%s', $file ?? 'no-file', $class, $trait, $function)); } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return new \PHPStan\Type\AcceptsResult($type->isClassStringType(), []); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } return new \PHPStan\Type\IsSuperTypeOfResult($type->isClassStringType(), []); } public function isString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createYes(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ObjectWithoutClassType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ObjectWithoutClassType(); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('class-string'); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self(); } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof self || $type->isInteger()->yes()) { return \PHPStan\Type\AcceptsResult::createYes(); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return \PHPStan\Type\AcceptsResult::createNo(); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } public function equals(\PHPStan\Type\Type $type) : bool { return get_class($type) === static::class; } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return 'float'; } public function toNumber() : \PHPStan\Type\Type { return $this; } public function toAbsoluteNumber() : \PHPStan\Type\Type { return $this; } public function toFloat() : \PHPStan\Type\Type { return $this; } public function toInteger() : \PHPStan\Type\Type { return new \PHPStan\Type\IntegerType(); } public function toString() : \PHPStan\Type\Type { return new \PHPStan\Type\IntersectionType([new \PHPStan\Type\StringType(), new AccessoryUppercaseStringType(), new AccessoryNumericStringType()]); } public function toArray() : \PHPStan\Type\Type { return new ConstantArrayType([new ConstantIntegerType(0)], [$this], [1], [], TrinaryLogic::createYes()); } public function toArrayKey() : \PHPStan\Type\Type { return new \PHPStan\Type\IntegerType(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createYes(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function traverse(callable $cb) : \PHPStan\Type\Type { return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { return $this; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return \PHPStan\Type\ExponentiateHelper::exponentiate($this, $exponent); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('float'); } public function getFiniteTypes() : array { return []; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self(); } } reflectionProvider = $reflectionProvider; } /** * @param non-empty-string $constName */ public function bitwiseOrContainsConstant(Expr $expr, Scope $scope, string $constName) : TrinaryLogic { if ($expr instanceof ConstFetch) { if ((string) $expr->name === $constName) { return TrinaryLogic::createYes(); } $resolveConstantName = $this->reflectionProvider->resolveConstantName($expr->name, $scope); if ($resolveConstantName !== null) { if ($resolveConstantName === $constName) { return TrinaryLogic::createYes(); } return TrinaryLogic::createNo(); } } if ($expr instanceof BitwiseOr) { return TrinaryLogic::createFromBoolean($this->bitwiseOrContainsConstant($expr->left, $scope, $constName)->yes() || $this->bitwiseOrContainsConstant($expr->right, $scope, $constName)->yes()); } $fqcn = new FullyQualified($constName); if ($this->reflectionProvider->hasConstant($fqcn, $scope)) { $constant = $this->reflectionProvider->getConstant($fqcn, $scope); $valueType = $constant->getValueType(); if ($valueType instanceof ConstantIntegerType) { return $this->exprContainsIntFlag($expr, $scope, $valueType->getValue()); } } return TrinaryLogic::createNo(); } private function exprContainsIntFlag(Expr $expr, Scope $scope, int $flag) : TrinaryLogic { $exprType = $scope->getType($expr); if ($exprType instanceof \PHPStan\Type\UnionType) { $allTypesContainFlag = \true; $someTypesContainFlag = \false; foreach ($exprType->getTypes() as $type) { $containsFlag = $this->typeContainsIntFlag($type, $flag); if (!$containsFlag->yes()) { $allTypesContainFlag = \false; } if (!$containsFlag->yes() && !$containsFlag->maybe()) { continue; } $someTypesContainFlag = \true; } if ($allTypesContainFlag) { return TrinaryLogic::createYes(); } if ($someTypesContainFlag) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createNo(); } return $this->typeContainsIntFlag($exprType, $flag); } private function typeContainsIntFlag(\PHPStan\Type\Type $type, int $flag) : TrinaryLogic { if ($type instanceof ConstantIntegerType) { if (($type->getValue() & $flag) === $flag) { return TrinaryLogic::createYes(); } return TrinaryLogic::createNo(); } if ($type->isInteger()->yes() || $type instanceof \PHPStan\Type\MixedType) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createNo(); } } type = $type; } public function getType() : \PHPStan\Type\Type { return $this->type; } public function getReferencedClasses() : array { return $this->type->getReferencedClasses(); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { return $this->type->getReferencedTemplateTypes($positionVariance); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self && $this->type->equals($type->type); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return sprintf('key-of<%s>', $this->type->describe($level)); } public function isResolvable() : bool { return !\PHPStan\Type\TypeUtils::containsTemplateType($this->type); } protected function getResult() : \PHPStan\Type\Type { return $this->type->getIterableKeyType(); } /** * @param callable(Type): Type $cb */ public function traverse(callable $cb) : \PHPStan\Type\Type { $type = $cb($this->type); if ($this->type === $type) { return $this; } return new self($type); } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if (!$right instanceof self) { return $this; } $type = $cb($this->type, $right->type); if ($this->type === $type) { return $this; } return new self($type); } public function toPhpDocNode() : TypeNode { return new GenericTypeNode(new IdentifierTypeNode('key-of'), [$this->type->toPhpDocNode()]); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['type']); } } container = $container; } public function getTypeAliasResolver() : \PHPStan\Type\TypeAliasResolver { return $this->container->getByType(\PHPStan\Type\TypeAliasResolver::class); } } typeNode = $typeNode; $this->nameScope = $nameScope; } public static function invalid() : self { $self = new self(new IdentifierTypeNode('*ERROR*'), new NameScope(null, [])); $self->resolvedType = new \PHPStan\Type\CircularTypeAliasErrorType(); return $self; } public function resolve(TypeNodeResolver $typeNodeResolver) : \PHPStan\Type\Type { if ($this->resolvedType === null) { $this->resolvedType = $typeNodeResolver->resolve($this->typeNode, $this->nameScope); } return $this->resolvedType; } } getMin(); $removeValueMax = $typeToRemove->getMax(); } else { $removeValueMin = $typeToRemove->getValue(); $removeValueMax = $typeToRemove->getValue(); } $lowerPart = $removeValueMin !== null ? \PHPStan\Type\IntegerRangeType::fromInterval(null, $removeValueMin, -1) : null; $upperPart = $removeValueMax !== null ? \PHPStan\Type\IntegerRangeType::fromInterval($removeValueMax, null, +1) : null; if ($lowerPart !== null && $upperPart !== null) { return new \PHPStan\Type\UnionType([$lowerPart, $upperPart]); } return $lowerPart ?? $upperPart ?? new \PHPStan\Type\NeverType(); } return null; } public function getFiniteTypes() : array { return []; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return \PHPStan\Type\ExponentiateHelper::exponentiate($this, $exponent); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('int'); } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof self) { return \PHPStan\Type\AcceptsResult::createYes(); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return \PHPStan\Type\AcceptsResult::createNo(); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self; } public function isSmallerThan(\PHPStan\Type\Type $otherType) : TrinaryLogic { if ($otherType instanceof \PHPStan\Type\ConstantScalarType) { return TrinaryLogic::createFromBoolean(null < $otherType->getValue()); } if ($otherType instanceof \PHPStan\Type\CompoundType) { return $otherType->isGreaterThan($this); } return TrinaryLogic::createMaybe(); } public function isSmallerThanOrEqual(\PHPStan\Type\Type $otherType) : TrinaryLogic { if ($otherType instanceof \PHPStan\Type\ConstantScalarType) { return TrinaryLogic::createFromBoolean(null <= $otherType->getValue()); } if ($otherType instanceof \PHPStan\Type\CompoundType) { return $otherType->isGreaterThanOrEqual($this); } return TrinaryLogic::createMaybe(); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return 'null'; } public function toNumber() : \PHPStan\Type\Type { return new ConstantIntegerType(0); } public function toAbsoluteNumber() : \PHPStan\Type\Type { return $this->toNumber()->toAbsoluteNumber(); } public function toString() : \PHPStan\Type\Type { return new ConstantStringType(''); } public function toInteger() : \PHPStan\Type\Type { return $this->toNumber(); } public function toFloat() : \PHPStan\Type\Type { return $this->toNumber()->toFloat(); } public function toArray() : \PHPStan\Type\Type { return new ConstantArrayType([], []); } public function toArrayKey() : \PHPStan\Type\Type { return new ConstantStringType(''); } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(\PHPStan\Type\Type $offsetType) : TrinaryLogic { return TrinaryLogic::createNo(); } public function getOffsetValueType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function setOffsetValueType(?\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType, bool $unionValues = \true) : \PHPStan\Type\Type { $array = new ConstantArrayType([], []); return $array->setOffsetValueType($offsetType, $valueType, $unionValues); } public function setExistingOffsetValueType(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return $this; } public function unsetOffset(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return $this; } public function traverse(callable $cb) : \PHPStan\Type\Type { return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { return $this; } public function isNull() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createYes(); } public function getConstantScalarTypes() : array { return [$this]; } public function getConstantScalarValues() : array { return [$this->getValue()]; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createNo(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { if ($type instanceof \PHPStan\Type\ConstantScalarType) { return \PHPStan\Type\LooseComparisonHelper::compareConstantScalars($this, $type, $phpVersion); } if ($type->isConstantArray()->yes() && $type->isIterableAtLeastOnce()->no()) { // @phpstan-ignore equal.alwaysTrue, equal.notAllowed return new ConstantBooleanType($this->getValue() == []); // phpcs:ignore } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->looseCompare($this, $phpVersion); } return new \PHPStan\Type\BooleanType(); } public function getSmallerType() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function getSmallerOrEqualType() : \PHPStan\Type\Type { // All falsey types except '0' return new \PHPStan\Type\UnionType([new \PHPStan\Type\NullType(), new ConstantBooleanType(\false), new ConstantIntegerType(0), new ConstantFloatType(0.0), new ConstantStringType(''), new ConstantArrayType([], [])]); } public function getGreaterType() : \PHPStan\Type\Type { // All truthy types, but also '0' return new \PHPStan\Type\MixedType(\false, new \PHPStan\Type\UnionType([new \PHPStan\Type\NullType(), new ConstantBooleanType(\false), new ConstantIntegerType(0), new ConstantFloatType(0.0), new ConstantStringType(''), new ConstantArrayType([], [])])); } public function getGreaterOrEqualType() : \PHPStan\Type\Type { return new \PHPStan\Type\MixedType(); } public function getFiniteTypes() : array { return [$this]; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return new \PHPStan\Type\UnionType([new ConstantIntegerType(0), new ConstantIntegerType(1)]); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('null'); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self(); } } enumCaseName = $enumCaseName; parent::__construct($className, null, $classReflection); } public function getEnumCaseName() : string { return $this->enumCaseName; } public function describe(VerbosityLevel $level) : string { $parent = parent::describe($level); return sprintf('%s::%s', $parent, $this->enumCaseName); } public function equals(Type $type) : bool { if (!$type instanceof self) { return \false; } return $this->enumCaseName === $type->enumCaseName && $this->getClassName() === $type->getClassName(); } public function accepts(Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { return $this->isSuperTypeOfWithReason($type)->toAcceptsResult(); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof self) { return IsSuperTypeOfResult::createFromBoolean($this->enumCaseName === $type->enumCaseName && $this->getClassName() === $type->getClassName()); } if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } if ($type instanceof SubtractableType && $type->getSubtractedType() !== null) { $isSuperType = $type->getSubtractedType()->isSuperTypeOfWithReason($this); if ($isSuperType->yes()) { return IsSuperTypeOfResult::createNo(); } } $parent = new parent($this->getClassName(), $this->getSubtractedType(), $this->getClassReflection()); return $parent->isSuperTypeOfWithReason($type)->and(IsSuperTypeOfResult::createMaybe()); } public function subtract(Type $type) : Type { return $this; } public function getTypeWithoutSubtractedType() : Type { return $this; } public function changeSubtractedType(?Type $subtractedType) : Type { return $this; } public function getSubtractedType() : ?Type { return null; } public function tryRemove(Type $typeToRemove) : ?Type { if ($this->isSuperTypeOf($typeToRemove)->yes()) { return $this->subtract($typeToRemove); } return null; } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return parent::getUnresolvedPropertyPrototype($propertyName, $scope); } if ($propertyName === 'name') { return new EnumUnresolvedPropertyPrototypeReflection(new EnumPropertyReflection($classReflection, new ConstantStringType($this->enumCaseName))); } if ($classReflection->isBackedEnum() && $propertyName === 'value') { if ($classReflection->hasEnumCase($this->enumCaseName)) { $enumCase = $classReflection->getEnumCase($this->enumCaseName); $valueType = $enumCase->getBackingValueType(); if ($valueType === null) { throw new ShouldNotHappenException(); } return new EnumUnresolvedPropertyPrototypeReflection(new EnumPropertyReflection($classReflection, $valueType)); } } return parent::getUnresolvedPropertyPrototype($propertyName, $scope); } public function getBackingValueType() : ?Type { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return null; } if (!$classReflection->isBackedEnum()) { return null; } if ($classReflection->hasEnumCase($this->enumCaseName)) { $enumCase = $classReflection->getEnumCase($this->enumCaseName); return $enumCase->getBackingValueType(); } return null; } public function generalize(GeneralizePrecision $precision) : Type { return new parent($this->getClassName(), null, $this->getClassReflection()); } public function isSmallerThan(Type $otherType) : TrinaryLogic { return TrinaryLogic::createNo(); } public function isSmallerThanOrEqual(Type $otherType) : TrinaryLogic { return TrinaryLogic::createNo(); } public function getEnumCases() : array { return [$this]; } public function toPhpDocNode() : TypeNode { return new ConstTypeNode(new ConstFetchNode($this->getClassName(), $this->getEnumCaseName())); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : Type { return new self($properties['className'], $properties['enumCaseName'], null); } } getTypes() as $unionType) { $results[] = self::exponentiate($base, $unionType); } return \PHPStan\Type\TypeCombinator::union(...$results); } if ($exponent instanceof \PHPStan\Type\NeverType) { return new \PHPStan\Type\NeverType(); } $allowedExponentTypes = new \PHPStan\Type\UnionType([new \PHPStan\Type\IntegerType(), new \PHPStan\Type\FloatType(), new \PHPStan\Type\StringType(), new \PHPStan\Type\BooleanType(), new \PHPStan\Type\NullType()]); if (!$allowedExponentTypes->isSuperTypeOf($exponent)->yes()) { return new \PHPStan\Type\ErrorType(); } if ($base instanceof \PHPStan\Type\ConstantScalarType) { $result = self::exponentiateConstantScalar($base, $exponent); if ($result !== null) { return $result; } } // exponentiation of a float, stays a float $isFloatBase = $base->isFloat()->yes(); $isLooseZero = (new ConstantIntegerType(0))->isSuperTypeOf($exponent->toNumber()); if ($isLooseZero->yes()) { if ($isFloatBase) { return new ConstantFloatType(1); } return new ConstantIntegerType(1); } $isLooseOne = (new ConstantIntegerType(1))->isSuperTypeOf($exponent->toNumber()); if ($isLooseOne->yes()) { $possibleResults = new \PHPStan\Type\UnionType([new \PHPStan\Type\FloatType(), new \PHPStan\Type\IntegerType()]); if ($possibleResults->isSuperTypeOf($base)->yes()) { return $base; } } if ($isFloatBase) { return new \PHPStan\Type\FloatType(); } return new \PHPStan\Type\BenevolentUnionType([new \PHPStan\Type\FloatType(), new \PHPStan\Type\IntegerType()]); } private static function exponentiateConstantScalar(\PHPStan\Type\ConstantScalarType $base, \PHPStan\Type\Type $exponent) : ?\PHPStan\Type\Type { if ($exponent instanceof \PHPStan\Type\IntegerRangeType) { $min = null; $max = null; if ($exponent->getMin() !== null) { $min = self::pow($base->getValue(), $exponent->getMin()); if ($min === null) { return new \PHPStan\Type\ErrorType(); } } if ($exponent->getMax() !== null) { $max = self::pow($base->getValue(), $exponent->getMax()); if ($max === null) { return new \PHPStan\Type\ErrorType(); } } if (!is_float($min) && !is_float($max)) { return \PHPStan\Type\IntegerRangeType::fromInterval($min, $max); } } if ($exponent instanceof \PHPStan\Type\ConstantScalarType) { $result = self::pow($base->getValue(), $exponent->getValue()); if ($result === null) { return new \PHPStan\Type\ErrorType(); } if (is_int($result)) { return new ConstantIntegerType($result); } return new ConstantFloatType($result); } return null; } /** * @return float|int|null * @param mixed $base * @param mixed $exp */ private static function pow($base, $exp) { if (is_string($base) && !is_numeric($base)) { return null; } if (is_string($exp) && !is_numeric($exp)) { return null; } return pow($base, $exp); } } typeAliasResolver = $typeAliasResolver; } public function getTypeAliasResolver() : \PHPStan\Type\TypeAliasResolver { return $this->typeAliasResolver; } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof static) { return \PHPStan\Type\AcceptsResult::createYes(); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return \PHPStan\Type\AcceptsResult::createNo(); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } public function equals(\PHPStan\Type\Type $type) : bool { return get_class($type) === static::class; } public function traverse(callable $cb) : \PHPStan\Type\Type { return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { return $this; } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } } *@readonly */ public $reasons; /** * @param T $type * @param list $reasons */ public function __construct(\PHPStan\Type\Type $type, array $reasons) { $this->type = $type; $this->reasons = $reasons; } } value = $value; } private static function create(int $value) : self { self::$registry[$value] = self::$registry[$value] ?? new self($value); return self::$registry[$value]; } /** @api */ public static function lessSpecific() : self { return self::create(self::LESS_SPECIFIC); } /** @api */ public static function moreSpecific() : self { return self::create(self::MORE_SPECIFIC); } /** @api */ public static function templateArgument() : self { return self::create(self::TEMPLATE_ARGUMENT); } public function isLessSpecific() : bool { return $this->value === self::LESS_SPECIFIC; } public function isMoreSpecific() : bool { return $this->value === self::MORE_SPECIFIC; } public function isTemplateArgument() : bool { return $this->value === self::TEMPLATE_ARGUMENT; } } isSuperTypeOf($type)->no()) { return self::union($type, $nullType); } return $type; } public static function remove(\PHPStan\Type\Type $fromType, \PHPStan\Type\Type $typeToRemove) : \PHPStan\Type\Type { if ($typeToRemove instanceof \PHPStan\Type\UnionType) { foreach ($typeToRemove->getTypes() as $unionTypeToRemove) { $fromType = self::remove($fromType, $unionTypeToRemove); } return $fromType; } $isSuperType = $typeToRemove->isSuperTypeOf($fromType); if ($isSuperType->yes()) { return new \PHPStan\Type\NeverType(); } if ($isSuperType->no()) { return $fromType; } if ($typeToRemove instanceof \PHPStan\Type\MixedType) { $typeToRemoveSubtractedType = $typeToRemove->getSubtractedType(); if ($typeToRemoveSubtractedType !== null) { return self::intersect($fromType, $typeToRemoveSubtractedType); } } $removed = $fromType->tryRemove($typeToRemove); if ($removed !== null) { return $removed; } $fromFiniteTypes = $fromType->getFiniteTypes(); if (count($fromFiniteTypes) > 0) { $finiteTypesToRemove = $typeToRemove->getFiniteTypes(); if (count($finiteTypesToRemove) === 1) { $result = []; foreach ($fromFiniteTypes as $finiteType) { if ($finiteType->equals($finiteTypesToRemove[0])) { continue; } $result[] = $finiteType; } if (count($result) === count($fromFiniteTypes)) { return $fromType; } if (count($result) === 0) { return new \PHPStan\Type\NeverType(); } if (count($result) === 1) { return $result[0]; } return new \PHPStan\Type\UnionType($result); } } return $fromType; } public static function removeNull(\PHPStan\Type\Type $type) : \PHPStan\Type\Type { if (self::containsNull($type)) { return self::remove($type, new \PHPStan\Type\NullType()); } return $type; } public static function containsNull(\PHPStan\Type\Type $type) : bool { if ($type instanceof \PHPStan\Type\UnionType) { foreach ($type->getTypes() as $innerType) { if ($innerType instanceof \PHPStan\Type\NullType) { return \true; } } return \false; } return $type instanceof \PHPStan\Type\NullType; } public static function union(\PHPStan\Type\Type ...$types) : \PHPStan\Type\Type { $typesCount = count($types); if ($typesCount === 0) { return new \PHPStan\Type\NeverType(); } $benevolentTypes = []; $benevolentUnionObject = null; // transform A | (B | C) to A | B | C for ($i = 0; $i < $typesCount; $i++) { if ($types[$i] instanceof \PHPStan\Type\BenevolentUnionType) { if ($types[$i] instanceof TemplateBenevolentUnionType && $benevolentUnionObject === null) { $benevolentUnionObject = $types[$i]; } $benevolentTypesCount = 0; $typesInner = $types[$i]->getTypes(); foreach ($typesInner as $benevolentInnerType) { $benevolentTypesCount++; $benevolentTypes[$benevolentInnerType->describe(\PHPStan\Type\VerbosityLevel::value())] = $benevolentInnerType; } array_splice($types, $i, 1, $typesInner); $typesCount += $benevolentTypesCount - 1; continue; } if (!$types[$i] instanceof \PHPStan\Type\UnionType) { continue; } if ($types[$i] instanceof TemplateType) { continue; } $typesInner = $types[$i]->getTypes(); array_splice($types, $i, 1, $typesInner); $typesCount += count($typesInner) - 1; } if ($typesCount === 1) { return $types[0]; } $arrayTypes = []; $scalarTypes = []; $hasGenericScalarTypes = []; $enumCaseTypes = []; for ($i = 0; $i < $typesCount; $i++) { if ($types[$i] instanceof \PHPStan\Type\ConstantScalarType) { $type = $types[$i]; $scalarTypes[get_class($type)][md5($type->describe(\PHPStan\Type\VerbosityLevel::cache()))] = $type; unset($types[$i]); continue; } if ($types[$i] instanceof \PHPStan\Type\BooleanType) { $hasGenericScalarTypes[ConstantBooleanType::class] = \true; } if ($types[$i] instanceof \PHPStan\Type\FloatType) { $hasGenericScalarTypes[ConstantFloatType::class] = \true; } if ($types[$i] instanceof \PHPStan\Type\IntegerType && !$types[$i] instanceof \PHPStan\Type\IntegerRangeType) { $hasGenericScalarTypes[ConstantIntegerType::class] = \true; } if ($types[$i] instanceof \PHPStan\Type\StringType && !$types[$i] instanceof \PHPStan\Type\ClassStringType) { $hasGenericScalarTypes[ConstantStringType::class] = \true; } $enumCases = $types[$i]->getEnumCases(); if (count($enumCases) === 1) { $enumCaseTypes[$types[$i]->describe(\PHPStan\Type\VerbosityLevel::cache())] = $types[$i]; unset($types[$i]); continue; } if (!$types[$i]->isArray()->yes()) { continue; } $arrayTypes[] = $types[$i]; unset($types[$i]); } foreach ($scalarTypes as $classType => $scalarTypeItems) { $scalarTypes[$classType] = array_values($scalarTypeItems); } $enumCaseTypes = array_values($enumCaseTypes); $types = array_values($types); $typesCount = count($types); foreach ($scalarTypes as $classType => $scalarTypeItems) { if (isset($hasGenericScalarTypes[$classType])) { unset($scalarTypes[$classType]); continue; } if ($classType === ConstantBooleanType::class && count($scalarTypeItems) === 2) { $types[] = new \PHPStan\Type\BooleanType(); $typesCount++; unset($scalarTypes[$classType]); continue; } $scalarTypeItemsCount = count($scalarTypeItems); for ($i = 0; $i < $typesCount; $i++) { for ($j = 0; $j < $scalarTypeItemsCount; $j++) { $compareResult = self::compareTypesInUnion($types[$i], $scalarTypeItems[$j]); if ($compareResult === null) { continue; } [$a, $b] = $compareResult; if ($a !== null) { $types[$i] = $a; array_splice($scalarTypeItems, $j--, 1); $scalarTypeItemsCount--; continue 1; } if ($b !== null) { $scalarTypeItems[$j] = $b; array_splice($types, $i--, 1); $typesCount--; continue 2; } } } $scalarTypes[$classType] = $scalarTypeItems; } if (count($types) > 16) { $newTypes = []; foreach ($types as $type) { $newTypes[$type->describe(\PHPStan\Type\VerbosityLevel::cache())] = $type; } $types = array_values($newTypes); } $types = array_merge($types, self::processArrayTypes($arrayTypes)); $typesCount = count($types); // transform A | A to A // transform A | never to A for ($i = 0; $i < $typesCount; $i++) { for ($j = $i + 1; $j < $typesCount; $j++) { $compareResult = self::compareTypesInUnion($types[$i], $types[$j]); if ($compareResult === null) { continue; } [$a, $b] = $compareResult; if ($a !== null) { $types[$i] = $a; array_splice($types, $j--, 1); $typesCount--; continue 1; } if ($b !== null) { $types[$j] = $b; array_splice($types, $i--, 1); $typesCount--; continue 2; } } } $enumCasesCount = count($enumCaseTypes); for ($i = 0; $i < $typesCount; $i++) { for ($j = 0; $j < $enumCasesCount; $j++) { $compareResult = self::compareTypesInUnion($types[$i], $enumCaseTypes[$j]); if ($compareResult === null) { continue; } [$a, $b] = $compareResult; if ($a !== null) { $types[$i] = $a; array_splice($enumCaseTypes, $j--, 1); $enumCasesCount--; continue 1; } if ($b !== null) { $enumCaseTypes[$j] = $b; array_splice($types, $i--, 1); $typesCount--; continue 2; } } } foreach ($enumCaseTypes as $enumCaseType) { $types[] = $enumCaseType; $typesCount++; } foreach ($scalarTypes as $scalarTypeItems) { foreach ($scalarTypeItems as $scalarType) { $types[] = $scalarType; $typesCount++; } } if ($typesCount === 0) { return new \PHPStan\Type\NeverType(); } if ($typesCount === 1) { return $types[0]; } if ($benevolentTypes !== []) { $tempTypes = $types; foreach ($tempTypes as $i => $type) { if (!isset($benevolentTypes[$type->describe(\PHPStan\Type\VerbosityLevel::value())])) { break; } unset($tempTypes[$i]); } if ($tempTypes === []) { if ($benevolentUnionObject instanceof TemplateBenevolentUnionType) { return $benevolentUnionObject->withTypes($types); } return new \PHPStan\Type\BenevolentUnionType($types, \true); } } return new \PHPStan\Type\UnionType($types, \true); } /** * @return array{Type, null}|array{null, Type}|null */ private static function compareTypesInUnion(\PHPStan\Type\Type $a, \PHPStan\Type\Type $b) : ?array { if ($a instanceof \PHPStan\Type\IntegerRangeType) { $type = $a->tryUnion($b); if ($type !== null) { $a = $type; return [$a, null]; } } if ($b instanceof \PHPStan\Type\IntegerRangeType) { $type = $b->tryUnion($a); if ($type !== null) { $b = $type; return [null, $b]; } } if ($a instanceof \PHPStan\Type\IntegerRangeType && $b instanceof \PHPStan\Type\IntegerRangeType) { return null; } if ($a instanceof HasOffsetValueType && $b instanceof HasOffsetValueType) { if ($a->getOffsetType()->equals($b->getOffsetType())) { return [new HasOffsetValueType($a->getOffsetType(), self::union($a->getValueType(), $b->getValueType())), null]; } } if ($a->isConstantArray()->yes() && $b->isConstantArray()->yes()) { return null; } // simplify string[] | int[] to (string|int)[] if ($a instanceof \PHPStan\Type\IterableType && $b instanceof \PHPStan\Type\IterableType) { return [new \PHPStan\Type\IterableType(self::union($a->getIterableKeyType(), $b->getIterableKeyType()), self::union($a->getIterableValueType(), $b->getIterableValueType())), null]; } if ($a instanceof \PHPStan\Type\SubtractableType) { $typeWithoutSubtractedTypeA = $a->getTypeWithoutSubtractedType(); if ($typeWithoutSubtractedTypeA instanceof \PHPStan\Type\MixedType && $b instanceof \PHPStan\Type\MixedType) { $isSuperType = $typeWithoutSubtractedTypeA->isSuperTypeOfMixed($b); } else { $isSuperType = $typeWithoutSubtractedTypeA->isSuperTypeOf($b); } if ($isSuperType->yes()) { $a = self::intersectWithSubtractedType($a, $b); return [$a, null]; } } if ($b instanceof \PHPStan\Type\SubtractableType) { $typeWithoutSubtractedTypeB = $b->getTypeWithoutSubtractedType(); if ($typeWithoutSubtractedTypeB instanceof \PHPStan\Type\MixedType && $a instanceof \PHPStan\Type\MixedType) { $isSuperType = $typeWithoutSubtractedTypeB->isSuperTypeOfMixed($a); } else { $isSuperType = $typeWithoutSubtractedTypeB->isSuperTypeOf($a); } if ($isSuperType->yes()) { $b = self::intersectWithSubtractedType($b, $a); return [null, $b]; } } if ($b->isSuperTypeOf($a)->yes()) { return [null, $b]; } if ($a->isSuperTypeOf($b)->yes()) { return [$a, null]; } if ($a instanceof ConstantStringType && $a->getValue() === '' && ($b->describe(\PHPStan\Type\VerbosityLevel::value()) === 'non-empty-string' || $b->describe(\PHPStan\Type\VerbosityLevel::value()) === 'non-falsy-string')) { return [null, self::intersect(new \PHPStan\Type\StringType(), ...self::getAccessoryCaseStringTypes($b))]; } if ($b instanceof ConstantStringType && $b->getValue() === '' && ($a->describe(\PHPStan\Type\VerbosityLevel::value()) === 'non-empty-string' || $a->describe(\PHPStan\Type\VerbosityLevel::value()) === 'non-falsy-string')) { return [self::intersect(new \PHPStan\Type\StringType(), ...self::getAccessoryCaseStringTypes($a)), null]; } if ($a instanceof ConstantStringType && $a->getValue() === '0' && $b->describe(\PHPStan\Type\VerbosityLevel::value()) === 'non-falsy-string') { return [null, self::intersect(new \PHPStan\Type\StringType(), new AccessoryNonEmptyStringType(), ...self::getAccessoryCaseStringTypes($b))]; } if ($b instanceof ConstantStringType && $b->getValue() === '0' && $a->describe(\PHPStan\Type\VerbosityLevel::value()) === 'non-falsy-string') { return [self::intersect(new \PHPStan\Type\StringType(), new AccessoryNonEmptyStringType(), ...self::getAccessoryCaseStringTypes($a)), null]; } return null; } /** * @return array */ private static function getAccessoryCaseStringTypes(\PHPStan\Type\Type $type) : array { $accessory = []; if ($type->isLowercaseString()->yes()) { $accessory[] = new AccessoryLowercaseStringType(); } if ($type->isUppercaseString()->yes()) { $accessory[] = new AccessoryUppercaseStringType(); } return $accessory; } private static function unionWithSubtractedType(\PHPStan\Type\Type $type, ?\PHPStan\Type\Type $subtractedType) : \PHPStan\Type\Type { if ($subtractedType === null) { return $type; } if ($type instanceof \PHPStan\Type\SubtractableType) { $subtractedType = $type->getSubtractedType() === null ? $subtractedType : self::union($type->getSubtractedType(), $subtractedType); if ($subtractedType instanceof \PHPStan\Type\NeverType) { $subtractedType = null; } return $type->changeSubtractedType($subtractedType); } if ($subtractedType->isSuperTypeOf($type)->yes()) { return new \PHPStan\Type\NeverType(); } return self::remove($type, $subtractedType); } private static function intersectWithSubtractedType(\PHPStan\Type\SubtractableType $a, \PHPStan\Type\Type $b) : \PHPStan\Type\Type { if ($a->getSubtractedType() === null) { return $a; } if ($b instanceof \PHPStan\Type\IntersectionType) { $subtractableTypes = []; foreach ($b->getTypes() as $innerType) { if (!$innerType instanceof \PHPStan\Type\SubtractableType) { continue; } $subtractableTypes[] = $innerType; } if (count($subtractableTypes) === 0) { return $a->getTypeWithoutSubtractedType(); } $subtractedTypes = []; foreach ($subtractableTypes as $subtractableType) { if ($subtractableType->getSubtractedType() === null) { continue; } $subtractedTypes[] = $subtractableType->getSubtractedType(); } if (count($subtractedTypes) === 0) { return $a->getTypeWithoutSubtractedType(); } $subtractedType = self::union(...$subtractedTypes); } elseif ($b instanceof \PHPStan\Type\SubtractableType) { $subtractedType = $b->getSubtractedType(); if ($subtractedType === null) { return $a->getTypeWithoutSubtractedType(); } } else { $subtractedTypeTmp = self::intersect($a->getTypeWithoutSubtractedType(), $a->getSubtractedType()); if ($b->isSuperTypeOf($subtractedTypeTmp)->yes()) { return $a->getTypeWithoutSubtractedType(); } $subtractedType = new \PHPStan\Type\MixedType(\false, $b); } $subtractedType = self::intersect($a->getSubtractedType(), $subtractedType); if ($subtractedType instanceof \PHPStan\Type\NeverType) { $subtractedType = null; } return $a->changeSubtractedType($subtractedType); } /** * @param Type[] $arrayTypes * @return Type[] */ private static function processArrayAccessoryTypes(array $arrayTypes) : array { $accessoryTypes = []; foreach ($arrayTypes as $i => $arrayType) { if ($arrayType instanceof \PHPStan\Type\IntersectionType) { foreach ($arrayType->getTypes() as $innerType) { if ($innerType instanceof TemplateType) { break; } if (!$innerType instanceof AccessoryType && !$innerType instanceof \PHPStan\Type\CallableType) { continue; } if ($innerType instanceof HasOffsetType) { $offset = $innerType->getOffsetType(); if ($offset instanceof ConstantStringType || $offset instanceof ConstantIntegerType) { $innerType = new HasOffsetValueType($offset, $arrayType->getIterableValueType()); } } if ($innerType instanceof HasOffsetValueType) { $accessoryTypes[sprintf('hasOffsetValue(%s)', $innerType->getOffsetType()->describe(\PHPStan\Type\VerbosityLevel::cache()))][$i] = $innerType; continue; } $accessoryTypes[$innerType->describe(\PHPStan\Type\VerbosityLevel::cache())][$i] = $innerType; } } if (!$arrayType->isConstantArray()->yes()) { continue; } $constantArrays = $arrayType->getConstantArrays(); foreach ($constantArrays as $constantArray) { if ($constantArray->isList()->yes() && AccessoryArrayListType::isListTypeEnabled()) { $list = new AccessoryArrayListType(); $accessoryTypes[$list->describe(\PHPStan\Type\VerbosityLevel::cache())][$i] = $list; } if (!$constantArray->isIterableAtLeastOnce()->yes()) { continue; } $nonEmpty = new NonEmptyArrayType(); $accessoryTypes[$nonEmpty->describe(\PHPStan\Type\VerbosityLevel::cache())][$i] = $nonEmpty; } } $commonAccessoryTypes = []; $arrayTypeCount = count($arrayTypes); foreach ($accessoryTypes as $accessoryType) { if (count($accessoryType) !== $arrayTypeCount) { $firstKey = array_key_first($accessoryType); if ($accessoryType[$firstKey] instanceof OversizedArrayType) { $commonAccessoryTypes[] = $accessoryType[$firstKey]; } continue; } if ($accessoryType[0] instanceof HasOffsetValueType) { $commonAccessoryTypes[] = self::union(...$accessoryType); continue; } $commonAccessoryTypes[] = $accessoryType[0]; } return $commonAccessoryTypes; } /** * @param list $arrayTypes * @return Type[] */ private static function processArrayTypes(array $arrayTypes) : array { if ($arrayTypes === []) { return []; } $accessoryTypes = self::processArrayAccessoryTypes($arrayTypes); if (count($arrayTypes) === 1) { return [self::intersect(...$arrayTypes, ...$accessoryTypes)]; } $keyTypesForGeneralArray = []; $valueTypesForGeneralArray = []; $generalArrayOccurred = \false; $constantKeyTypesNumbered = []; $filledArrays = 0; $overflowed = \false; /** @var int|float $nextConstantKeyTypeIndex */ $nextConstantKeyTypeIndex = 1; $constantArraysMap = array_map(static function (\PHPStan\Type\Type $t) { return $t->getConstantArrays(); }, $arrayTypes); foreach ($arrayTypes as $arrayIdx => $arrayType) { $constantArrays = $constantArraysMap[$arrayIdx]; $isConstantArray = $constantArrays !== []; if (!$isConstantArray || !$arrayType->isIterableAtLeastOnce()->no()) { $filledArrays++; } if ($generalArrayOccurred || !$isConstantArray) { foreach ($arrayType->getArrays() as $type) { $keyTypesForGeneralArray[] = $type->getIterableKeyType(); $valueTypesForGeneralArray[] = $type->getItemType(); $generalArrayOccurred = \true; } continue; } $constantArrays = $arrayType->getConstantArrays(); foreach ($constantArrays as $constantArray) { foreach ($constantArray->getKeyTypes() as $i => $keyType) { $keyTypesForGeneralArray[] = $keyType; $valueTypesForGeneralArray[] = $constantArray->getValueTypes()[$i]; $keyTypeValue = $keyType->getValue(); if (array_key_exists($keyTypeValue, $constantKeyTypesNumbered)) { continue; } $constantKeyTypesNumbered[$keyTypeValue] = $nextConstantKeyTypeIndex; $nextConstantKeyTypeIndex *= 2; if (!is_int($nextConstantKeyTypeIndex)) { $generalArrayOccurred = \true; $overflowed = \true; continue 2; } } } } if ($generalArrayOccurred && (!$overflowed || $filledArrays > 1)) { $reducedArrayTypes = self::reduceArrays($arrayTypes, \false); if (count($reducedArrayTypes) === 1) { return [self::intersect($reducedArrayTypes[0], ...$accessoryTypes)]; } $scopes = []; $useTemplateArray = \true; foreach ($arrayTypes as $arrayType) { if (!$arrayType instanceof TemplateArrayType) { $useTemplateArray = \false; break; } $scopes[$arrayType->getScope()->describe()] = $arrayType; } $arrayType = new \PHPStan\Type\ArrayType(self::union(...$keyTypesForGeneralArray), self::union(...self::optimizeConstantArrays($valueTypesForGeneralArray))); if ($useTemplateArray && count($scopes) === 1) { $templateArray = array_values($scopes)[0]; $arrayType = new TemplateArrayType($templateArray->getScope(), $templateArray->getStrategy(), $templateArray->getVariance(), $templateArray->getName(), $arrayType, $templateArray->getDefault()); } return [self::intersect($arrayType, ...$accessoryTypes)]; } $reducedArrayTypes = self::reduceArrays($arrayTypes, \true); return array_map(static function (\PHPStan\Type\Type $arrayType) use($accessoryTypes) { return self::intersect($arrayType, ...$accessoryTypes); }, self::optimizeConstantArrays($reducedArrayTypes)); } /** * @param Type[] $types * @return Type[] */ private static function optimizeConstantArrays(array $types) : array { $constantArrayValuesCount = self::countConstantArrayValueTypes($types); if ($constantArrayValuesCount <= ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) { return $types; } $results = []; $eachIsOversized = \true; foreach ($types as $type) { $isOversized = \false; $result = \PHPStan\Type\TypeTraverser::map($type, static function (\PHPStan\Type\Type $type, callable $traverse) use(&$isOversized) : \PHPStan\Type\Type { if (!$type instanceof ConstantArrayType) { return $traverse($type); } if ($type->isIterableAtLeastOnce()->no()) { return $type; } $isOversized = \true; $isList = \true; $valueTypes = []; $keyTypes = []; $nextAutoIndex = 0; foreach ($type->getKeyTypes() as $i => $innerKeyType) { if (!$innerKeyType instanceof ConstantIntegerType) { $isList = \false; } elseif ($innerKeyType->getValue() !== $nextAutoIndex) { $isList = \false; $nextAutoIndex = $innerKeyType->getValue() + 1; } else { $nextAutoIndex++; } $generalizedKeyType = $innerKeyType->generalize(\PHPStan\Type\GeneralizePrecision::moreSpecific()); $keyTypes[$generalizedKeyType->describe(\PHPStan\Type\VerbosityLevel::precise())] = $generalizedKeyType; $innerValueType = $type->getValueTypes()[$i]; $generalizedValueType = \PHPStan\Type\TypeTraverser::map($innerValueType, static function (\PHPStan\Type\Type $type) use($traverse) : \PHPStan\Type\Type { if ($type instanceof \PHPStan\Type\ArrayType) { return \PHPStan\Type\TypeCombinator::intersect($type, new OversizedArrayType()); } if ($type instanceof \PHPStan\Type\ConstantScalarType) { return $type->generalize(\PHPStan\Type\GeneralizePrecision::moreSpecific()); } return $traverse($type); }); $valueTypes[$generalizedValueType->describe(\PHPStan\Type\VerbosityLevel::precise())] = $generalizedValueType; } $keyType = \PHPStan\Type\TypeCombinator::union(...array_values($keyTypes)); $valueType = \PHPStan\Type\TypeCombinator::union(...array_values($valueTypes)); $arrayType = new \PHPStan\Type\ArrayType($keyType, $valueType); if ($isList) { $arrayType = AccessoryArrayListType::intersectWith($arrayType); } return \PHPStan\Type\TypeCombinator::intersect($arrayType, new NonEmptyArrayType(), new OversizedArrayType()); }); if (!$isOversized) { $eachIsOversized = \false; } $results[] = $result; } if ($eachIsOversized) { $eachIsList = \true; $keyTypes = []; $valueTypes = []; foreach ($results as $result) { $keyTypes[] = $result->getIterableKeyType(); $valueTypes[] = $result->getLastIterableValueType(); if ($result->isList()->yes()) { continue; } $eachIsList = \false; } $keyType = self::union(...$keyTypes); $valueType = self::union(...$valueTypes); $arrayType = new \PHPStan\Type\ArrayType($keyType, $valueType); if ($eachIsList) { $arrayType = self::intersect($arrayType, new AccessoryArrayListType()); } return [self::intersect($arrayType, new NonEmptyArrayType(), new OversizedArrayType())]; } return $results; } /** * @param Type[] $types */ public static function countConstantArrayValueTypes(array $types) : int { $constantArrayValuesCount = 0; foreach ($types as $type) { \PHPStan\Type\TypeTraverser::map($type, static function (\PHPStan\Type\Type $type, callable $traverse) use(&$constantArrayValuesCount) : \PHPStan\Type\Type { if ($type instanceof ConstantArrayType) { $constantArrayValuesCount += count($type->getValueTypes()); } return $traverse($type); }); } return $constantArrayValuesCount; } /** * @param list $constantArrays * @return list */ private static function reduceArrays(array $constantArrays, bool $preserveTaggedUnions) : array { $newArrays = []; $arraysToProcess = []; $emptyArray = null; foreach ($constantArrays as $constantArray) { if (!$constantArray->isConstantArray()->yes()) { // This is an optimization for current use-case of $preserveTaggedUnions=false, where we need // one constant array as a result, or we generalize the $constantArrays. if (!$preserveTaggedUnions) { return $constantArrays; } $newArrays[] = $constantArray; continue; } if ($constantArray->isIterableAtLeastOnce()->no()) { $emptyArray = $constantArray; continue; } $arraysToProcess = array_merge($arraysToProcess, $constantArray->getConstantArrays()); } if ($emptyArray !== null) { $newArrays[] = $emptyArray; } $arraysToProcessPerKey = []; foreach ($arraysToProcess as $i => $arrayToProcess) { foreach ($arrayToProcess->getKeyTypes() as $keyType) { $arraysToProcessPerKey[$keyType->getValue()][] = $i; } } $eligibleCombinations = []; foreach ($arraysToProcessPerKey as $arrays) { for ($i = 0, $arraysCount = count($arrays); $i < $arraysCount - 1; $i++) { for ($j = $i + 1; $j < $arraysCount; $j++) { $eligibleCombinations[$arrays[$i]][$arrays[$j]] = $eligibleCombinations[$arrays[$i]][$arrays[$j]] ?? 0; $eligibleCombinations[$arrays[$i]][$arrays[$j]]++; } } } foreach ($eligibleCombinations as $i => $other) { if (!array_key_exists($i, $arraysToProcess)) { continue; } foreach ($other as $j => $overlappingKeysCount) { if (!array_key_exists($j, $arraysToProcess)) { continue; } if ($preserveTaggedUnions && $overlappingKeysCount === count($arraysToProcess[$i]->getKeyTypes()) && $arraysToProcess[$j]->isKeysSupersetOf($arraysToProcess[$i])) { $arraysToProcess[$j] = $arraysToProcess[$j]->mergeWith($arraysToProcess[$i]); unset($arraysToProcess[$i]); continue 2; } if ($preserveTaggedUnions && $overlappingKeysCount === count($arraysToProcess[$j]->getKeyTypes()) && $arraysToProcess[$i]->isKeysSupersetOf($arraysToProcess[$j])) { $arraysToProcess[$i] = $arraysToProcess[$i]->mergeWith($arraysToProcess[$j]); unset($arraysToProcess[$j]); continue 1; } if (!$preserveTaggedUnions && $overlappingKeysCount === count($arraysToProcess[$i]->getKeyTypes()) && $overlappingKeysCount === count($arraysToProcess[$j]->getKeyTypes())) { $arraysToProcess[$j] = $arraysToProcess[$j]->mergeWith($arraysToProcess[$i]); unset($arraysToProcess[$i]); continue 2; } } } return array_merge($newArrays, $arraysToProcess); } public static function intersect(\PHPStan\Type\Type ...$types) : \PHPStan\Type\Type { $types = array_values($types); $typesCount = count($types); if ($typesCount === 0) { return new \PHPStan\Type\NeverType(); } if ($typesCount === 1) { return $types[0]; } $sortTypes = static function (\PHPStan\Type\Type $a, \PHPStan\Type\Type $b) : int { if (!$a instanceof \PHPStan\Type\UnionType || !$b instanceof \PHPStan\Type\UnionType) { return 0; } if ($a instanceof TemplateType) { return -1; } if ($b instanceof TemplateType) { return 1; } if ($a instanceof \PHPStan\Type\BenevolentUnionType) { return -1; } if ($b instanceof \PHPStan\Type\BenevolentUnionType) { return 1; } return 0; }; usort($types, $sortTypes); // transform A & (B | C) to (A & B) | (A & C) foreach ($types as $i => $type) { if (!$type instanceof \PHPStan\Type\UnionType) { continue; } $topLevelUnionSubTypes = []; $innerTypes = $type->getTypes(); usort($innerTypes, $sortTypes); $slice1 = array_slice($types, 0, $i); $slice2 = array_slice($types, $i + 1); foreach ($innerTypes as $innerUnionSubType) { $topLevelUnionSubTypes[] = self::intersect($innerUnionSubType, ...$slice1, ...$slice2); } $union = self::union(...$topLevelUnionSubTypes); if ($union instanceof \PHPStan\Type\NeverType) { return $union; } if ($type instanceof \PHPStan\Type\BenevolentUnionType) { $union = \PHPStan\Type\TypeUtils::toBenevolentUnion($union); } if ($type instanceof TemplateUnionType || $type instanceof TemplateBenevolentUnionType) { $union = TemplateTypeFactory::create($type->getScope(), $type->getName(), $union, $type->getVariance(), $type->getStrategy(), $type->getDefault()); } return $union; } $typesCount = count($types); // transform A & (B & C) to A & B & C for ($i = 0; $i < $typesCount; $i++) { $type = $types[$i]; if (!$type instanceof \PHPStan\Type\IntersectionType) { continue; } array_splice($types, $i--, 1, $type->getTypes()); $typesCount = count($types); } $hasOffsetValueTypeCount = 0; $newTypes = []; foreach ($types as $type) { if (!$type instanceof HasOffsetValueType) { $newTypes[] = $type; continue; } $hasOffsetValueTypeCount++; } if ($hasOffsetValueTypeCount > 32) { $newTypes[] = new OversizedArrayType(); $types = $newTypes; $typesCount = count($types); } usort($types, static function (\PHPStan\Type\Type $a, \PHPStan\Type\Type $b) : int { // move subtractables with subtracts before those without to avoid loosing them in the union logic if ($a instanceof \PHPStan\Type\SubtractableType && $a->getSubtractedType() !== null) { return -1; } if ($b instanceof \PHPStan\Type\SubtractableType && $b->getSubtractedType() !== null) { return 1; } if ($a instanceof ConstantArrayType && !$b instanceof ConstantArrayType) { return -1; } if ($b instanceof ConstantArrayType && !$a instanceof ConstantArrayType) { return 1; } return 0; }); // transform IntegerType & ConstantIntegerType to ConstantIntegerType // transform Child & Parent to Child // transform Object & ~null to Object // transform A & A to A // transform int[] & string to never // transform callable & int to never // transform A & ~A to never // transform int & string to never for ($i = 0; $i < $typesCount; $i++) { for ($j = $i + 1; $j < $typesCount; $j++) { if ($types[$j] instanceof \PHPStan\Type\SubtractableType) { $typeWithoutSubtractedTypeA = $types[$j]->getTypeWithoutSubtractedType(); if ($typeWithoutSubtractedTypeA instanceof \PHPStan\Type\MixedType && $types[$i] instanceof \PHPStan\Type\MixedType) { $isSuperTypeSubtractableA = $typeWithoutSubtractedTypeA->isSuperTypeOfMixed($types[$i]); } else { $isSuperTypeSubtractableA = $typeWithoutSubtractedTypeA->isSuperTypeOf($types[$i]); } if ($isSuperTypeSubtractableA->yes()) { $types[$i] = self::unionWithSubtractedType($types[$i], $types[$j]->getSubtractedType()); array_splice($types, $j--, 1); $typesCount--; continue 1; } } if ($types[$i] instanceof \PHPStan\Type\SubtractableType) { $typeWithoutSubtractedTypeB = $types[$i]->getTypeWithoutSubtractedType(); if ($typeWithoutSubtractedTypeB instanceof \PHPStan\Type\MixedType && $types[$j] instanceof \PHPStan\Type\MixedType) { $isSuperTypeSubtractableB = $typeWithoutSubtractedTypeB->isSuperTypeOfMixed($types[$j]); } else { $isSuperTypeSubtractableB = $typeWithoutSubtractedTypeB->isSuperTypeOf($types[$j]); } if ($isSuperTypeSubtractableB->yes()) { $types[$j] = self::unionWithSubtractedType($types[$j], $types[$i]->getSubtractedType()); array_splice($types, $i--, 1); $typesCount--; continue 2; } } if ($types[$i] instanceof \PHPStan\Type\IntegerRangeType) { $intersectionType = $types[$i]->tryIntersect($types[$j]); if ($intersectionType !== null) { $types[$j] = $intersectionType; array_splice($types, $i--, 1); $typesCount--; continue 2; } } if ($types[$j] instanceof \PHPStan\Type\IterableType) { $isSuperTypeA = $types[$j]->isSuperTypeOfMixed($types[$i]); } else { $isSuperTypeA = $types[$j]->isSuperTypeOf($types[$i]); } if ($isSuperTypeA->yes()) { array_splice($types, $j--, 1); $typesCount--; continue; } if ($types[$i] instanceof \PHPStan\Type\IterableType) { $isSuperTypeB = $types[$i]->isSuperTypeOfMixed($types[$j]); } else { $isSuperTypeB = $types[$i]->isSuperTypeOf($types[$j]); } if ($isSuperTypeB->maybe()) { if ($types[$i] instanceof ConstantArrayType && $types[$j] instanceof HasOffsetType) { $types[$i] = $types[$i]->makeOffsetRequired($types[$j]->getOffsetType()); array_splice($types, $j--, 1); $typesCount--; continue; } if ($types[$j] instanceof ConstantArrayType && $types[$i] instanceof HasOffsetType) { $types[$j] = $types[$j]->makeOffsetRequired($types[$i]->getOffsetType()); array_splice($types, $i--, 1); $typesCount--; continue 2; } if ($types[$i] instanceof ConstantArrayType && $types[$j] instanceof HasOffsetValueType) { $offsetType = $types[$j]->getOffsetType(); $valueType = $types[$j]->getValueType(); $newValueType = self::intersect($types[$i]->getOffsetValueType($offsetType), $valueType); if ($newValueType instanceof \PHPStan\Type\NeverType) { return $newValueType; } $types[$i] = $types[$i]->setOffsetValueType($offsetType, $newValueType); array_splice($types, $j--, 1); $typesCount--; continue; } if ($types[$j] instanceof ConstantArrayType && $types[$i] instanceof HasOffsetValueType) { $offsetType = $types[$i]->getOffsetType(); $valueType = $types[$i]->getValueType(); $newValueType = self::intersect($types[$j]->getOffsetValueType($offsetType), $valueType); if ($newValueType instanceof \PHPStan\Type\NeverType) { return $newValueType; } $types[$j] = $types[$j]->setOffsetValueType($offsetType, $newValueType); array_splice($types, $i--, 1); $typesCount--; continue 2; } if ($types[$i] instanceof OversizedArrayType && $types[$j] instanceof HasOffsetValueType) { array_splice($types, $j--, 1); $typesCount--; continue; } if ($types[$j] instanceof OversizedArrayType && $types[$i] instanceof HasOffsetValueType) { array_splice($types, $i--, 1); $typesCount--; continue 2; } if ($types[$i] instanceof \PHPStan\Type\ObjectShapeType && $types[$j] instanceof HasPropertyType) { $types[$i] = $types[$i]->makePropertyRequired($types[$j]->getPropertyName()); array_splice($types, $j--, 1); $typesCount--; continue; } if ($types[$j] instanceof \PHPStan\Type\ObjectShapeType && $types[$i] instanceof HasPropertyType) { $types[$j] = $types[$j]->makePropertyRequired($types[$i]->getPropertyName()); array_splice($types, $i--, 1); $typesCount--; continue 2; } if ($types[$i] instanceof ConstantArrayType && $types[$j] instanceof \PHPStan\Type\ArrayType) { $newArray = ConstantArrayTypeBuilder::createEmpty(); $valueTypes = $types[$i]->getValueTypes(); foreach ($types[$i]->getKeyTypes() as $k => $keyType) { $newArray->setOffsetValueType(self::intersect($keyType, $types[$j]->getIterableKeyType()), self::intersect($valueTypes[$k], $types[$j]->getIterableValueType()), $types[$i]->isOptionalKey($k) && !$types[$j]->hasOffsetValueType($keyType)->yes()); } $types[$i] = $newArray->getArray(); array_splice($types, $j--, 1); $typesCount--; continue 2; } if ($types[$j] instanceof ConstantArrayType && $types[$i] instanceof \PHPStan\Type\ArrayType) { $newArray = ConstantArrayTypeBuilder::createEmpty(); $valueTypes = $types[$j]->getValueTypes(); foreach ($types[$j]->getKeyTypes() as $k => $keyType) { $newArray->setOffsetValueType(self::intersect($keyType, $types[$i]->getIterableKeyType()), self::intersect($valueTypes[$k], $types[$i]->getIterableValueType()), $types[$j]->isOptionalKey($k) && !$types[$i]->hasOffsetValueType($keyType)->yes()); } $types[$j] = $newArray->getArray(); array_splice($types, $i--, 1); $typesCount--; continue 2; } if (($types[$i] instanceof \PHPStan\Type\ArrayType || $types[$i] instanceof \PHPStan\Type\IterableType) && ($types[$j] instanceof \PHPStan\Type\ArrayType || $types[$j] instanceof \PHPStan\Type\IterableType)) { $keyType = self::intersect($types[$i]->getIterableKeyType(), $types[$j]->getKeyType()); $itemType = self::intersect($types[$i]->getItemType(), $types[$j]->getItemType()); if ($types[$i] instanceof \PHPStan\Type\IterableType && $types[$j] instanceof \PHPStan\Type\IterableType) { $types[$j] = new \PHPStan\Type\IterableType($keyType, $itemType); } else { $types[$j] = new \PHPStan\Type\ArrayType($keyType, $itemType); } array_splice($types, $i--, 1); $typesCount--; continue 2; } if ($types[$i] instanceof GenericClassStringType && $types[$j] instanceof GenericClassStringType) { $genericType = self::intersect($types[$i]->getGenericType(), $types[$j]->getGenericType()); $types[$i] = new GenericClassStringType($genericType); array_splice($types, $j--, 1); $typesCount--; continue; } if ($types[$i] instanceof \PHPStan\Type\ArrayType && get_class($types[$i]) === \PHPStan\Type\ArrayType::class && $types[$j] instanceof AccessoryArrayListType && !$types[$j]->getIterableKeyType()->isSuperTypeOf($types[$i]->getIterableKeyType())->yes()) { $keyType = self::intersect($types[$i]->getIterableKeyType(), $types[$j]->getIterableKeyType()); if ($keyType instanceof \PHPStan\Type\NeverType) { return $keyType; } $types[$i] = new \PHPStan\Type\ArrayType($keyType, $types[$i]->getItemType()); continue; } continue; } if ($isSuperTypeB->yes()) { array_splice($types, $i--, 1); $typesCount--; continue 2; } if ($isSuperTypeA->no()) { return new \PHPStan\Type\NeverType(); } } } if ($typesCount === 1) { return $types[0]; } return new \PHPStan\Type\IntersectionType($types); } public static function removeFalsey(\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return self::remove($type, \PHPStan\Type\StaticTypeFactory::falsey()); } public static function removeTruthy(\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return self::remove($type, \PHPStan\Type\StaticTypeFactory::truthy()); } } toInteger(); } public function toAbsoluteNumber() : \PHPStan\Type\Type { return $this->toNumber()->toAbsoluteNumber(); } public function toString() : \PHPStan\Type\Type { return \PHPStan\Type\TypeCombinator::union(new ConstantStringType(''), new ConstantStringType('1')); } public function toInteger() : \PHPStan\Type\Type { return \PHPStan\Type\TypeCombinator::union(new ConstantIntegerType(0), new ConstantIntegerType(1)); } public function toFloat() : \PHPStan\Type\Type { return \PHPStan\Type\TypeCombinator::union(new ConstantFloatType(0.0), new ConstantFloatType(1.0)); } public function toArray() : \PHPStan\Type\Type { return new ConstantArrayType([new ConstantIntegerType(0)], [$this], [1], [], TrinaryLogic::createYes()); } public function toArrayKey() : \PHPStan\Type\Type { return new \PHPStan\Type\UnionType([new ConstantIntegerType(0), new ConstantIntegerType(1)]); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isTrue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createYes(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type { if ($typeToRemove instanceof ConstantBooleanType) { return new ConstantBooleanType(!$typeToRemove->getValue()); } return null; } public function getFiniteTypes() : array { return [new ConstantBooleanType(\true), new ConstantBooleanType(\false)]; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return \PHPStan\Type\ExponentiateHelper::exponentiate($this, $exponent); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('bool'); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self(); } } phpVersion = $phpVersion; $this->regexExpressionHelper = $regexExpressionHelper; } /** * @return array{array, list}|null */ public function parseGroups(string $regex) : ?array { if (self::$parser === null) { /** @throws void */ self::$parser = Llk::load(new Read(__DIR__ . '/../../../resources/RegexGrammar.pp')); } try { Strings::match('', $regex); } catch (RegexpException $e) { // pattern is invalid, so let the RegularExpressionPatternRule report it return null; } $modifiers = $this->regexExpressionHelper->getPatternModifiers($regex) ?? ''; foreach (self::NOT_SUPPORTED_MODIFIERS as $notSupportedModifier) { if (str_contains($modifiers, $notSupportedModifier)) { return null; } } if (str_contains($modifiers, 'x')) { // in freespacing mode the # character starts a comment and runs until the end of the line $regex = preg_replace('/(?regexExpressionHelper->removeDelimitersAndModifiers($regex); try { $ast = self::$parser->parse($rawRegex); } catch (Exception $e) { return null; } $this->updateAlternationAstRemoveVerticalBarsAndAddEmptyToken($ast); $this->updateCapturingAstAddEmptyToken($ast); $captureOnlyNamed = \false; if ($this->phpVersion->supportsPregCaptureOnlyNamedGroups()) { $captureOnlyNamed = str_contains($modifiers, 'n'); } $astWalkResult = $this->walkRegexAst($ast, null, 0, \false, null, $captureOnlyNamed, \false, $modifiers, \PHPStan\Type\Regex\RegexAstWalkResult::createEmpty()); return [$astWalkResult->getCapturingGroups(), $astWalkResult->getMarkVerbs()]; } private function createEmptyTokenTreeNode(TreeNode $parentAst) : TreeNode { return new TreeNode('token', ['token' => 'literal', 'value' => '', 'namespace' => 'default'], [], $parentAst); } private function updateAlternationAstRemoveVerticalBarsAndAddEmptyToken(TreeNode $ast) : void { $children = $ast->getChildren(); foreach ($children as $i => $child) { $this->updateAlternationAstRemoveVerticalBarsAndAddEmptyToken($child); if ($ast->getId() !== '#alternation' || $child->getValueToken() !== 'alternation') { continue; } unset($children[$i]); if ($i !== 0 && isset($children[$i + 1]) && $children[$i + 1]->getValueToken() !== 'alternation') { continue; } $children[$i] = $this->createEmptyTokenTreeNode($ast); } $ast->setChildren(array_values($children)); } private function updateCapturingAstAddEmptyToken(TreeNode $ast) : void { foreach ($ast->getChildren() as $child) { $this->updateCapturingAstAddEmptyToken($child); } if ($ast->getId() !== '#capturing' || $ast->getChildren() !== []) { return; } $emptyAlternationAst = new TreeNode('#alternation', null, [], $ast); $emptyAlternationAst->setChildren([$this->createEmptyTokenTreeNode($emptyAlternationAst)]); $ast->setChildren([$emptyAlternationAst]); } /** * @param RegexCapturingGroup|RegexNonCapturingGroup|null $parentGroup */ private function walkRegexAst(TreeNode $ast, ?\PHPStan\Type\Regex\RegexAlternation $alternation, int $combinationIndex, bool $inOptionalQuantification, $parentGroup, bool $captureOnlyNamed, bool $repeatedMoreThanOnce, string $patternModifiers, \PHPStan\Type\Regex\RegexAstWalkResult $astWalkResult) : \PHPStan\Type\Regex\RegexAstWalkResult { $group = null; if ($ast->getId() === '#capturing') { $astWalkResult = $astWalkResult->nextCaptureGroupId(); $group = new \PHPStan\Type\Regex\RegexCapturingGroup($astWalkResult->getCaptureGroupId(), null, $alternation, $inOptionalQuantification, $parentGroup, $this->createGroupType($ast, $this->allowConstantTypes($patternModifiers, $repeatedMoreThanOnce, $parentGroup), $patternModifiers)); $parentGroup = $group; } elseif ($ast->getId() === '#namedcapturing') { $astWalkResult = $astWalkResult->nextCaptureGroupId(); $name = $ast->getChild(0)->getValueValue(); $group = new \PHPStan\Type\Regex\RegexCapturingGroup($astWalkResult->getCaptureGroupId(), $name, $alternation, $inOptionalQuantification, $parentGroup, $this->createGroupType($ast, $this->allowConstantTypes($patternModifiers, $repeatedMoreThanOnce, $parentGroup), $patternModifiers)); $parentGroup = $group; } elseif ($ast->getId() === '#noncapturing') { $group = new \PHPStan\Type\Regex\RegexNonCapturingGroup($alternation, $inOptionalQuantification, $parentGroup, \false); $parentGroup = $group; } elseif ($ast->getId() === '#noncapturingreset') { $group = new \PHPStan\Type\Regex\RegexNonCapturingGroup($alternation, $inOptionalQuantification, $parentGroup, \true); $parentGroup = $group; } $inOptionalQuantification = \false; if ($ast->getId() === '#quantification') { [$min, $max] = $this->getQuantificationRange($ast); if ($min === 0) { $inOptionalQuantification = \true; } if ($max === null || $max > 1) { $repeatedMoreThanOnce = \true; } } if ($ast->getId() === '#alternation') { $astWalkResult = $astWalkResult->nextAlternationId(); $alternation = new \PHPStan\Type\Regex\RegexAlternation($astWalkResult->getAlternationId(), count($ast->getChildren())); } if ($ast->getId() === '#mark') { return $astWalkResult->markVerb($ast->getChild(0)->getValueValue()); } if ($group instanceof \PHPStan\Type\Regex\RegexCapturingGroup && (!$captureOnlyNamed || $group->isNamed())) { $astWalkResult = $astWalkResult->addCapturingGroup($group); if ($alternation !== null) { $alternation->pushGroup($combinationIndex, $group); } } foreach ($ast->getChildren() as $child) { $astWalkResult = $this->walkRegexAst($child, $alternation, $combinationIndex, $inOptionalQuantification, $parentGroup, $captureOnlyNamed, $repeatedMoreThanOnce, $patternModifiers, $astWalkResult); if ($ast->getId() !== '#alternation') { continue; } $combinationIndex++; } return $astWalkResult; } /** * @param RegexCapturingGroup|RegexNonCapturingGroup|null $parentGroup */ private function allowConstantTypes(string $patternModifiers, bool $repeatedMoreThanOnce, $parentGroup) : bool { if (str_contains($patternModifiers, 'i')) { // if caseless, we don't use constant types // because it likely yields too many combinations return \false; } if ($repeatedMoreThanOnce) { return \false; } if ($parentGroup !== null && $parentGroup->resetsGroupCounter()) { return \false; } return \true; } /** @return array{?int, ?int} */ private function getQuantificationRange(TreeNode $node) : array { if ($node->getId() !== '#quantification') { throw new ShouldNotHappenException(); } $min = null; $max = null; $lastChild = $node->getChild($node->getChildrenNumber() - 1); $value = $lastChild->getValue(); // normalize away possessive and lazy quantifier-modifiers $token = str_replace(['_possessive', '_lazy'], '', $value['token']); $value = rtrim($value['value'], '+?'); if ($token === 'n_to_m') { if (sscanf($value, '{%d,%d}', $n, $m) !== 2 || !is_int($n) || !is_int($m)) { throw new ShouldNotHappenException(); } $min = $n; $max = $m; } elseif ($token === 'n_or_more') { if (sscanf($value, '{%d,}', $n) !== 1 || !is_int($n)) { throw new ShouldNotHappenException(); } $min = $n; } elseif ($token === 'exactly_n') { if (sscanf($value, '{%d}', $n) !== 1 || !is_int($n)) { throw new ShouldNotHappenException(); } $min = $n; $max = $n; } elseif ($token === 'zero_or_one') { $min = 0; $max = 1; } elseif ($token === 'zero_or_more') { $min = 0; } elseif ($token === 'one_or_more') { $min = 1; } return [$min, $max]; } private function createGroupType(TreeNode $group, bool $maybeConstant, string $patternModifiers) : Type { $rootAlternation = $this->getRootAlternation($group); if ($rootAlternation !== null) { $types = []; foreach ($rootAlternation->getChildren() as $alternative) { $types[] = $this->createGroupType($alternative, $maybeConstant, $patternModifiers); } return TypeCombinator::union(...$types); } $walkResult = $this->walkGroupAst($group, \false, \false, $patternModifiers, \PHPStan\Type\Regex\RegexGroupWalkResult::createEmpty()); if ($maybeConstant && $walkResult->getOnlyLiterals() !== null && $walkResult->getOnlyLiterals() !== []) { $result = []; foreach ($walkResult->getOnlyLiterals() as $literal) { $result[] = new ConstantStringType($literal); } return TypeCombinator::union(...$result); } if ($walkResult->isNumeric()->yes()) { if ($walkResult->isNonFalsy()->yes()) { return new IntersectionType([new StringType(), new AccessoryNumericStringType(), new AccessoryNonFalsyStringType()]); } $result = new IntersectionType([new StringType(), new AccessoryNumericStringType()]); if (!$walkResult->isNonEmpty()->yes()) { return TypeCombinator::union(new ConstantStringType(''), $result); } return $result; } elseif ($walkResult->isNonFalsy()->yes()) { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } elseif ($walkResult->isNonEmpty()->yes()) { return new IntersectionType([new StringType(), new AccessoryNonEmptyStringType()]); } return new StringType(); } private function getRootAlternation(TreeNode $group) : ?TreeNode { if ($group->getId() === '#capturing' && count($group->getChildren()) === 1 && $group->getChild(0)->getId() === '#alternation') { return $group->getChild(0); } // 1st token within a named capturing group is a token holding the group-name if ($group->getId() === '#namedcapturing' && count($group->getChildren()) === 2 && $group->getChild(1)->getId() === '#alternation') { return $group->getChild(1); } return null; } private function walkGroupAst(TreeNode $ast, bool $inAlternation, bool $inClass, string $patternModifiers, \PHPStan\Type\Regex\RegexGroupWalkResult $walkResult) : \PHPStan\Type\Regex\RegexGroupWalkResult { $children = $ast->getChildren(); if ($ast->getId() === '#concatenation' && count($children) > 0 && !$walkResult->isInOptionalQuantification()) { $meaningfulTokens = 0; foreach ($children as $child) { $nonFalsy = \false; if ($this->isMaybeEmptyNode($child, $patternModifiers, $nonFalsy)) { continue; } $meaningfulTokens++; if (!$nonFalsy || $inAlternation) { continue; } // a single token non-falsy on its own $walkResult = $walkResult->nonFalsy(TrinaryLogic::createYes()); break; } if ($meaningfulTokens > 0) { $walkResult = $walkResult->nonEmpty(TrinaryLogic::createYes()); // two non-empty tokens concatenated results in a non-falsy string if ($meaningfulTokens > 1 && !$inAlternation) { $walkResult = $walkResult->nonFalsy(TrinaryLogic::createYes()); } } } elseif ($ast->getId() === '#quantification') { [$min] = $this->getQuantificationRange($ast); if ($min === 0) { $walkResult = $walkResult->inOptionalQuantification(\true); } if (!$walkResult->isInOptionalQuantification()) { if ($min >= 1) { $walkResult = $walkResult->nonEmpty(TrinaryLogic::createYes()); } if ($min >= 2 && !$inAlternation) { $walkResult = $walkResult->nonFalsy(TrinaryLogic::createYes()); } } $walkResult = $walkResult->onlyLiterals(null); } elseif ($ast->getId() === '#class' && $walkResult->getOnlyLiterals() !== null) { $inClass = \true; $newLiterals = []; foreach ($children as $child) { $oldLiterals = $walkResult->getOnlyLiterals(); $this->getLiteralValue($child, $oldLiterals, \true, $patternModifiers, \true); foreach ($oldLiterals ?? [] as $oldLiteral) { $newLiterals[] = $oldLiteral; } } $walkResult = $walkResult->onlyLiterals($newLiterals); } elseif ($ast->getId() === 'token') { $onlyLiterals = $walkResult->getOnlyLiterals(); $literalValue = $this->getLiteralValue($ast, $onlyLiterals, !$inClass, $patternModifiers, \false); $walkResult = $walkResult->onlyLiterals($onlyLiterals); if ($literalValue !== null) { if (Strings::match($literalValue, '/^\\d+$/') === null) { $walkResult = $walkResult->numeric(TrinaryLogic::createNo()); } elseif ($walkResult->isNumeric()->maybe()) { $walkResult = $walkResult->numeric(TrinaryLogic::createYes()); } if (!$walkResult->isInOptionalQuantification() && $literalValue !== '') { $walkResult = $walkResult->nonEmpty(TrinaryLogic::createYes()); } } } elseif (!in_array($ast->getId(), ['#capturing', '#namedcapturing', '#alternation'], \true)) { $walkResult = $walkResult->onlyLiterals(null); } if ($ast->getId() === '#alternation') { $newLiterals = []; foreach ($children as $child) { $walkResult = $this->walkGroupAst($child, \true, $inClass, $patternModifiers, $walkResult->onlyLiterals([])); if ($newLiterals === null) { continue; } if (count($walkResult->getOnlyLiterals() ?? []) > 0) { foreach ($walkResult->getOnlyLiterals() as $alternationLiterals) { $newLiterals[] = $alternationLiterals; } } else { $newLiterals = null; } } return $walkResult->onlyLiterals($newLiterals); } // [^0-9] should not parse as numeric-string, and [^list-everything-but-numbers] is technically // doable but really silly compared to just \d so we can safely assume the string is not numeric // for negative classes if ($ast->getId() === '#negativeclass') { $walkResult = $walkResult->numeric(TrinaryLogic::createNo()); } foreach ($children as $child) { $walkResult = $this->walkGroupAst($child, $inAlternation, $inClass, $patternModifiers, $walkResult); } return $walkResult; } private function isMaybeEmptyNode(TreeNode $node, string $patternModifiers, bool &$isNonFalsy) : bool { if ($node->getId() === '#quantification') { [$min] = $this->getQuantificationRange($node); if ($min > 0) { return \false; } if ($min === 0) { return \true; } } $literal = $this->getLiteralValue($node, $onlyLiterals, \false, $patternModifiers, \false); if ($literal !== null) { if ($literal !== '' && $literal !== '0') { $isNonFalsy = \true; } return $literal === ''; } foreach ($node->getChildren() as $child) { if (!$this->isMaybeEmptyNode($child, $patternModifiers, $isNonFalsy)) { return \false; } } return \true; } /** * @param array|null $onlyLiterals */ private function getLiteralValue(TreeNode $node, ?array &$onlyLiterals, bool $appendLiterals, string $patternModifiers, bool $inCharacterClass) : ?string { if ($node->getId() !== 'token') { return null; } // token is the token name from grammar without the namespace so literal and class:literal are both called literal here $token = $node->getValueToken(); $value = $node->getValueValue(); if (in_array($token, [ 'literal', // literal "-" in front/back of a character class like '[-a-z]' or '[abc-]', not forming a range 'range', // literal "[" or "]" inside character classes '[[]' or '[]]' 'class_', '_class', ], \true)) { if (str_contains($patternModifiers, 'x') && trim($value) === '') { return null; } $isEscaped = \false; if (strlen($value) > 1 && $value[0] === '\\') { $value = substr($value, 1) ?: ''; $isEscaped = \true; } if ($appendLiterals && $onlyLiterals !== null) { if (in_array($value, ['.'], \true) && !($isEscaped || $inCharacterClass)) { $onlyLiterals = null; } else { if ($onlyLiterals === []) { $onlyLiterals = [$value]; } else { foreach ($onlyLiterals as &$literal) { $literal .= $value; } } } } return $value; } if (!in_array($token, ['capturing_name'], \true)) { $onlyLiterals = null; } // character escape sequences, just return a fixed string if (in_array($token, ['character', 'dynamic_character', 'character_type'], \true)) { if ($token === 'character_type' && $value === '\\d') { return '0'; } return $value; } // [:digit:] and the like, more support coming later if ($token === 'posix_class') { if ($value === '[:digit:]') { return '0'; } if (in_array($value, ['[:alpha:]', '[:alnum:]', '[:upper:]', '[:lower:]', '[:word:]', '[:ascii:]', '[:print:]', '[:xdigit:]', '[:graph:]'], \true)) { return 'a'; } if ($value === '[:blank:]') { return " \t"; } if ($value === '[:cntrl:]') { return "\x00\x1f"; } if ($value === '[:space:]') { return " \t\r\n\v\f"; } if ($value === '[:punct:]') { return '!"#$%&\'()*+,\\-./:;<=>?@[\\]^_`{|}~'; } } if ($token === 'anchor' || $token === 'match_point_reset') { return ''; } return null; } } |null */ private $onlyLiterals; /** * @var TrinaryLogic */ private $isNonEmpty; /** * @var TrinaryLogic */ private $isNonFalsy; /** * @var TrinaryLogic */ private $isNumeric; /** * @param array|null $onlyLiterals */ public function __construct(bool $inOptionalQuantification, ?array $onlyLiterals, TrinaryLogic $isNonEmpty, TrinaryLogic $isNonFalsy, TrinaryLogic $isNumeric) { $this->inOptionalQuantification = $inOptionalQuantification; $this->onlyLiterals = $onlyLiterals; $this->isNonEmpty = $isNonEmpty; $this->isNonFalsy = $isNonFalsy; $this->isNumeric = $isNumeric; } public static function createEmpty() : self { return new self(\false, [], TrinaryLogic::createMaybe(), TrinaryLogic::createMaybe(), TrinaryLogic::createMaybe()); } public function inOptionalQuantification(bool $inOptionalQuantification) : self { return new self($inOptionalQuantification, $this->onlyLiterals, $this->isNonEmpty, $this->isNonFalsy, $this->isNumeric); } /** * @param array|null $onlyLiterals */ public function onlyLiterals(?array $onlyLiterals) : self { return new self($this->inOptionalQuantification, $onlyLiterals, $this->isNonEmpty, $this->isNonFalsy, $this->isNumeric); } public function nonEmpty(TrinaryLogic $nonEmpty) : self { return new self($this->inOptionalQuantification, $this->onlyLiterals, $nonEmpty, $this->isNonFalsy, $this->isNumeric); } public function nonFalsy(TrinaryLogic $nonFalsy) : self { return new self($this->inOptionalQuantification, $this->onlyLiterals, $this->isNonEmpty, $nonFalsy, $this->isNumeric); } public function numeric(TrinaryLogic $numeric) : self { return new self($this->inOptionalQuantification, $this->onlyLiterals, $this->isNonEmpty, $this->isNonFalsy, $numeric); } public function isInOptionalQuantification() : bool { return $this->inOptionalQuantification; } /** * @return array|null */ public function getOnlyLiterals() : ?array { return $this->onlyLiterals; } public function isNonEmpty() : TrinaryLogic { return $this->isNonEmpty; } public function isNonFalsy() : TrinaryLogic { return $this->isNonFalsy; } public function isNumeric() : TrinaryLogic { return $this->isNumeric; } } alternation = $alternation; $this->inOptionalQuantification = $inOptionalQuantification; $this->parent = $parent; $this->resetGroupCounter = $resetGroupCounter; } /** @phpstan-assert-if-true !null $this->getAlternationId() */ public function inAlternation() : bool { return $this->alternation !== null; } public function getAlternationId() : ?int { if ($this->alternation === null) { return null; } return $this->alternation->getId(); } public function isOptional() : bool { return $this->inAlternation() || $this->inOptionalQuantification || $this->parent !== null && $this->parent->isOptional(); } public function isTopLevel() : bool { return $this->parent === null || $this->parent instanceof \PHPStan\Type\Regex\RegexNonCapturingGroup && $this->parent->isTopLevel(); } /** * @return RegexCapturingGroup|RegexNonCapturingGroup|null */ public function getParent() { return $this->parent; } public function resetsGroupCounter() : bool { return $this->resetGroupCounter; } } */ private $capturingGroups; /** * @var list */ private $markVerbs; /** * @param array $capturingGroups * @param list $markVerbs */ public function __construct(int $alternationId, int $captureGroupId, array $capturingGroups, array $markVerbs) { $this->alternationId = $alternationId; $this->captureGroupId = $captureGroupId; $this->capturingGroups = $capturingGroups; $this->markVerbs = $markVerbs; } public static function createEmpty() : self { return new self( -1, // use different start-index for groups to make it easier to distinguish groupids from other ids 100, [], [] ); } public function nextAlternationId() : self { return new self($this->alternationId + 1, $this->captureGroupId, $this->capturingGroups, $this->markVerbs); } public function nextCaptureGroupId() : self { return new self($this->alternationId, $this->captureGroupId + 1, $this->capturingGroups, $this->markVerbs); } public function addCapturingGroup(\PHPStan\Type\Regex\RegexCapturingGroup $group) : self { $capturingGroups = $this->capturingGroups; $capturingGroups[$group->getId()] = $group; return new self($this->alternationId, $this->captureGroupId, $capturingGroups, $this->markVerbs); } public function markVerb(string $markVerb) : self { $verbs = $this->markVerbs; $verbs[] = $markVerb; return new self($this->alternationId, $this->captureGroupId, $this->capturingGroups, $verbs); } public function getAlternationId() : int { return $this->alternationId; } public function getCaptureGroupId() : int { return $this->captureGroupId; } /** * @return array */ public function getCapturingGroups() : array { return $this->capturingGroups; } /** * @return list */ public function getMarkVerbs() : array { return $this->markVerbs; } } initializerExprTypeResolver = $initializerExprTypeResolver; } /** * Ignores preg_quote() calls in the concatenation as these are not relevant for array-shape matching. * * This assumption only works for the ArrayShapeMatcher therefore it is not implemented for the common case in Scope. * * see https://github.com/phpstan/phpstan-src/pull/3233#discussion_r1676938085 */ public function resolvePatternConcat(Concat $concat, Scope $scope) : Type { $resolver = new class($scope) { /** * @var Scope */ private $scope; public function __construct(Scope $scope) { $this->scope = $scope; } public function resolve(Expr $expr) : Type { // assume preg_quote() cannot create capturing groups or contain meta characters. // replace it with a pattern which matches anything, does not affect $matches results // and does not produce regex errors when followed by a quantifier. // this allows us to turn string concatenations with preg_quote() into static analyzable strings. if ($expr instanceof Expr\FuncCall && $expr->name instanceof Name && $expr->name->toLowerString() === 'preg_quote') { return new ConstantStringType('(?:.*)'); } if ($expr instanceof Concat) { $left = $this->resolve($expr->left); $right = $this->resolve($expr->right); $strings = []; foreach ($left->toString()->getConstantStrings() as $leftString) { foreach ($right->toString()->getConstantStrings() as $rightString) { $strings[] = new ConstantStringType($leftString->getValue() . $rightString->getValue()); } } return TypeCombinator::union(...$strings); } return $this->scope->getType($expr); } }; return $this->initializerExprTypeResolver->getConcatType($concat->left, $concat->right, static function (Expr $expr) use($resolver) : Type { return $resolver->resolve($expr); }); } public function getPatternModifiers(string $pattern) : ?string { $endDelimiterPos = $this->getEndDelimiterPos($pattern); if ($endDelimiterPos === \false) { return null; } return substr($pattern, $endDelimiterPos + 1); } public function removeDelimitersAndModifiers(string $pattern) : string { $pattern = ltrim($pattern); $endDelimiterPos = $this->getEndDelimiterPos($pattern); if ($endDelimiterPos === \false) { return $pattern; } return substr($pattern, 1, $endDelimiterPos - 1); } /** * @return false|int */ private function getEndDelimiterPos(string $pattern) { $startDelimiter = $this->getPatternDelimiter($pattern); if ($startDelimiter === null) { return \false; } // delimiter variants, see https://www.php.net/manual/en/regexp.reference.delimiters.php $bracketStyleDelimiters = ['{' => '}', '(' => ')', '[' => ']', '<' => '>']; if (array_key_exists($startDelimiter, $bracketStyleDelimiters)) { $endDelimiterPos = strrpos($pattern, $bracketStyleDelimiters[$startDelimiter]); } else { // same start and end delimiter $endDelimiterPos = strrpos($pattern, $startDelimiter); } return $endDelimiterPos; } /** * Get delimiters from non-constant patterns, if possible. * * @return string[] */ public function getPatternDelimiters(Concat $concat, Scope $scope) : array { if ($concat->left instanceof Concat) { return $this->getPatternDelimiters($concat->left, $scope); } $left = $scope->getType($concat->left); $delimiters = []; foreach ($left->getConstantStrings() as $leftString) { $delimiter = $this->getPatternDelimiter($leftString->getValue()); if ($delimiter === null) { continue; } $delimiters[] = $delimiter; } return $delimiters; } private function getPatternDelimiter(string $regex) : ?string { $regex = ltrim($regex); if ($regex === '') { return null; } return substr($regex, 0, 1); } } > */ private $groupCombinations = []; public function __construct(int $alternationId, int $alternationsCount) { $this->alternationId = $alternationId; $this->alternationsCount = $alternationsCount; } public function getId() : int { return $this->alternationId; } public function pushGroup(int $combinationIndex, \PHPStan\Type\Regex\RegexCapturingGroup $group) : void { if (!array_key_exists($combinationIndex, $this->groupCombinations)) { $this->groupCombinations[$combinationIndex] = []; } $this->groupCombinations[$combinationIndex][] = $group->getId(); } public function getAlternationsCount() : int { return $this->alternationsCount; } /** * @return array> */ public function getGroupCombinations() : array { return $this->groupCombinations; } } id = $id; $this->name = $name; $this->alternation = $alternation; $this->inOptionalQuantification = $inOptionalQuantification; $this->parent = $parent; $this->type = $type; } public function getId() : int { return $this->id; } public function forceNonOptional() : void { $this->forceNonOptional = \true; } public function forceType(Type $type) : void { $this->forceType = $type; } public function clearOverrides() : void { $this->forceNonOptional = \false; $this->forceType = null; } public function resetsGroupCounter() : bool { return $this->parent instanceof \PHPStan\Type\Regex\RegexNonCapturingGroup && $this->parent->resetsGroupCounter(); } /** * @phpstan-assert-if-true !null $this->getAlternationId() * @phpstan-assert-if-true !null $this->getAlternation() */ public function inAlternation() : bool { return $this->alternation !== null; } public function getAlternation() : ?\PHPStan\Type\Regex\RegexAlternation { return $this->alternation; } public function getAlternationId() : ?int { if ($this->alternation === null) { return null; } return $this->alternation->getId(); } public function isOptional() : bool { if ($this->forceNonOptional) { return \false; } return $this->inAlternation() || $this->inOptionalQuantification || $this->parent !== null && $this->parent->isOptional(); } public function inOptionalQuantification() : bool { return $this->inOptionalQuantification; } public function inOptionalAlternation() : bool { if (!$this->inAlternation()) { return \false; } $parent = $this->parent; while ($parent !== null && $parent->getAlternationId() === $this->getAlternationId()) { if (!$parent instanceof \PHPStan\Type\Regex\RegexNonCapturingGroup) { return \false; } $parent = $parent->getParent(); } return $parent !== null && $parent->isOptional(); } public function isTopLevel() : bool { return $this->parent === null || $this->parent instanceof \PHPStan\Type\Regex\RegexNonCapturingGroup && $this->parent->isTopLevel(); } /** @phpstan-assert-if-true !null $this->getName() */ public function isNamed() : bool { return $this->name !== null; } public function getName() : ?string { return $this->name; } public function getType() : Type { if ($this->forceType !== null) { return $this->forceType; } return $this->type; } } handle(function () use($level) : string { return parent::describe($level); }, function () use($level) : string { return parent::describe($level); }, static function () : string { return '*ERROR*'; }); } public function getIterableKeyType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getIterableValueType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function subtract(\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return new self(); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self(); } } reflectionProvider = $reflectionProvider; $this->dynamicMethodReturnTypeExtensions = $dynamicMethodReturnTypeExtensions; $this->dynamicStaticMethodReturnTypeExtensions = $dynamicStaticMethodReturnTypeExtensions; $this->dynamicFunctionReturnTypeExtensions = $dynamicFunctionReturnTypeExtensions; foreach (array_merge($dynamicMethodReturnTypeExtensions, $dynamicStaticMethodReturnTypeExtensions, $dynamicFunctionReturnTypeExtensions) as $extension) { if (!$extension instanceof BrokerAwareExtension) { continue; } $extension->setBroker($broker); } } /** * @return DynamicMethodReturnTypeExtension[] */ public function getDynamicMethodReturnTypeExtensionsForClass(string $className) : array { if ($this->dynamicMethodReturnTypeExtensionsByClass === null) { $byClass = []; foreach ($this->dynamicMethodReturnTypeExtensions as $extension) { $byClass[strtolower($extension->getClass())][] = $extension; } $this->dynamicMethodReturnTypeExtensionsByClass = $byClass; } return $this->getDynamicExtensionsForType($this->dynamicMethodReturnTypeExtensionsByClass, $className); } /** * @return DynamicStaticMethodReturnTypeExtension[] */ public function getDynamicStaticMethodReturnTypeExtensionsForClass(string $className) : array { if ($this->dynamicStaticMethodReturnTypeExtensionsByClass === null) { $byClass = []; foreach ($this->dynamicStaticMethodReturnTypeExtensions as $extension) { $byClass[strtolower($extension->getClass())][] = $extension; } $this->dynamicStaticMethodReturnTypeExtensionsByClass = $byClass; } return $this->getDynamicExtensionsForType($this->dynamicStaticMethodReturnTypeExtensionsByClass, $className); } /** * @param DynamicMethodReturnTypeExtension[][]|DynamicStaticMethodReturnTypeExtension[][] $extensions * @return mixed[] */ private function getDynamicExtensionsForType(array $extensions, string $className) : array { if (!$this->reflectionProvider->hasClass($className)) { return []; } $extensionsForClass = [[]]; $class = $this->reflectionProvider->getClass($className); foreach (array_merge([$className], $class->getParentClassesNames(), $class->getNativeReflection()->getInterfaceNames()) as $extensionClassName) { $extensionClassName = strtolower($extensionClassName); if (!isset($extensions[$extensionClassName])) { continue; } $extensionsForClass[] = $extensions[$extensionClassName]; } return array_merge(...$extensionsForClass); } /** * @return DynamicFunctionReturnTypeExtension[] */ public function getDynamicFunctionReturnTypeExtensions() : array { return $this->dynamicFunctionReturnTypeExtensions; } } type = $type; $this->ancestorClassName = $ancestorClassName; $this->templateTypeName = $templateTypeName; } public function getReferencedClasses() : array { return $this->type->getReferencedClasses(); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { return $this->type->getReferencedTemplateTypes($positionVariance); } public function equals(Type $type) : bool { return $type instanceof self && $this->type->equals($type->type); } public function describe(VerbosityLevel $level) : string { return sprintf('template-type<%s, %s, %s>', $this->type->describe($level), $this->ancestorClassName, $this->templateTypeName); } public function isResolvable() : bool { return !TypeUtils::containsTemplateType($this->type); } protected function getResult() : Type { return $this->type->getTemplateType($this->ancestorClassName, $this->templateTypeName); } /** * @param callable(Type): Type $cb */ public function traverse(callable $cb) : Type { $type = $cb($this->type); if ($this->type === $type) { return $this; } return new self($type, $this->ancestorClassName, $this->templateTypeName); } public function traverseSimultaneously(Type $right, callable $cb) : Type { if (!$right instanceof self) { return $this; } $type = $cb($this->type, $right->type); if ($this->type === $type) { return $this; } return new self($type, $this->ancestorClassName, $this->templateTypeName); } public function toPhpDocNode() : TypeNode { return new GenericTypeNode(new IdentifierTypeNode('template-type'), [$this->type->toPhpDocNode(), new IdentifierTypeNode($this->ancestorClassName), new ConstTypeNode(new QuoteAwareConstExprStringNode($this->templateTypeName, QuoteAwareConstExprStringNode::SINGLE_QUOTED))]); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : Type { return new self($properties['type'], $properties['ancestorClassName'], $properties['templateTypeName']); } } describe(\PHPStan\Type\VerbosityLevel::value()); if (isset(self::$context[$key])) { return new \PHPStan\Type\ErrorType(); } try { self::$context[$key] = \true; return $callback(); } finally { unset(self::$context[$key]); } } } isInteger()->and(TrinaryLogic::createMaybe()); } public function getOffsetValueType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { if ($this->hasOffsetValueType($offsetType)->no()) { return new \PHPStan\Type\ErrorType(); } return new \PHPStan\Type\IntersectionType([new \PHPStan\Type\StringType(), new AccessoryNonEmptyStringType()]); } public function setOffsetValueType(?\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType, bool $unionValues = \true) : \PHPStan\Type\Type { if ($offsetType === null) { return new \PHPStan\Type\ErrorType(); } $valueStringType = $valueType->toString(); if ($valueStringType instanceof \PHPStan\Type\ErrorType) { return new \PHPStan\Type\ErrorType(); } if ($offsetType->isInteger()->yes() || $offsetType instanceof \PHPStan\Type\MixedType) { return new \PHPStan\Type\IntersectionType([new \PHPStan\Type\StringType(), new AccessoryNonEmptyStringType()]); } return new \PHPStan\Type\ErrorType(); } public function setExistingOffsetValueType(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return $this; } public function unsetOffset(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof self) { return \PHPStan\Type\AcceptsResult::createYes(); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } $thatClassNames = $type->getObjectClassNames(); if (count($thatClassNames) > 1) { throw new ShouldNotHappenException(); } if ($thatClassNames === [] || $strictTypes) { return \PHPStan\Type\AcceptsResult::createNo(); } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if (!$reflectionProvider->hasClass($thatClassNames[0])) { return \PHPStan\Type\AcceptsResult::createNo(); } $typeClass = $reflectionProvider->getClass($thatClassNames[0]); return \PHPStan\Type\AcceptsResult::createFromBoolean($typeClass->hasNativeMethod('__toString')); } public function toNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toAbsoluteNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toInteger() : \PHPStan\Type\Type { return new \PHPStan\Type\IntegerType(); } public function toFloat() : \PHPStan\Type\Type { return new \PHPStan\Type\FloatType(); } public function toString() : \PHPStan\Type\Type { return $this; } public function toArray() : \PHPStan\Type\Type { return new ConstantArrayType([new ConstantIntegerType(0)], [$this], [1], [], TrinaryLogic::createYes()); } public function toArrayKey() : \PHPStan\Type\Type { return $this; } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ObjectWithoutClassType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ObjectWithoutClassType(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createYes(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function hasMethod(string $methodName) : TrinaryLogic { if ($this->isClassStringType()->yes()) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createNo(); } public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type { if ($typeToRemove instanceof ConstantStringType && $typeToRemove->getValue() === '') { return \PHPStan\Type\TypeCombinator::intersect($this, new AccessoryNonEmptyStringType()); } if ($typeToRemove instanceof AccessoryNonEmptyStringType) { return new ConstantStringType(''); } return null; } public function getFiniteTypes() : array { return []; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return \PHPStan\Type\ExponentiateHelper::exponentiate($this, $exponent); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('string'); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self(); } } type = $type; } public function getReferencedClasses() : array { return $this->type->getReferencedClasses(); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { return $this->type->getReferencedTemplateTypes($positionVariance); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self && $this->type->equals($type->type); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return sprintf('value-of<%s>', $this->type->describe($level)); } public function isResolvable() : bool { return !\PHPStan\Type\TypeUtils::containsTemplateType($this->type); } protected function getResult() : \PHPStan\Type\Type { if ($this->type->isEnum()->yes()) { $valueTypes = []; foreach ($this->type->getEnumCases() as $enumCase) { $valueType = $enumCase->getBackingValueType(); if ($valueType === null) { continue; } $valueTypes[] = $valueType; } return \PHPStan\Type\TypeCombinator::union(...$valueTypes); } return $this->type->getIterableValueType(); } /** * @param callable(Type): Type $cb */ public function traverse(callable $cb) : \PHPStan\Type\Type { $type = $cb($this->type); if ($this->type === $type) { return $this; } return new self($type); } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if (!$right instanceof self) { return $this; } $type = $cb($this->type, $right->type); if ($this->type === $type) { return $this; } return new self($type); } public function toPhpDocNode() : TypeNode { return new GenericTypeNode(new IdentifierTypeNode('value-of'), [$this->type->toPhpDocNode()]); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['type']); } } getAllArrays(); } if ($type instanceof \PHPStan\Type\ArrayType) { return [$type]; } if ($type instanceof \PHPStan\Type\UnionType) { $matchingTypes = []; foreach ($type->getTypes() as $innerType) { if (!$innerType instanceof \PHPStan\Type\ArrayType) { return []; } foreach (self::getArrays($innerType) as $innerInnerType) { $matchingTypes[] = $innerInnerType; } } return $matchingTypes; } if ($type instanceof \PHPStan\Type\IntersectionType) { $matchingTypes = []; foreach ($type->getTypes() as $innerType) { if (!$innerType instanceof \PHPStan\Type\ArrayType) { continue; } foreach (self::getArrays($innerType) as $innerInnerType) { $matchingTypes[] = $innerInnerType; } } return $matchingTypes; } return []; } /** * @return ConstantArrayType[] * * @deprecated Use PHPStan\Type\Type::getConstantArrays() instead and handle optional keys if necessary. */ public static function getConstantArrays(\PHPStan\Type\Type $type) : array { if ($type instanceof ConstantArrayType) { return $type->getAllArrays(); } if ($type instanceof \PHPStan\Type\UnionType) { $matchingTypes = []; foreach ($type->getTypes() as $innerType) { if (!$innerType instanceof ConstantArrayType) { return []; } foreach (self::getConstantArrays($innerType) as $innerInnerType) { $matchingTypes[] = $innerInnerType; } } return $matchingTypes; } return []; } /** * @return ConstantStringType[] * * @deprecated Use PHPStan\Type\Type::getConstantStrings() instead */ public static function getConstantStrings(\PHPStan\Type\Type $type) : array { return self::map(ConstantStringType::class, $type, \false); } /** * @return ConstantIntegerType[] */ public static function getConstantIntegers(\PHPStan\Type\Type $type) : array { return self::map(ConstantIntegerType::class, $type, \false); } /** * @deprecated Use Type::isConstantValue() or Type::generalize() * @return ConstantType[] */ public static function getConstantTypes(\PHPStan\Type\Type $type) : array { return self::map(\PHPStan\Type\ConstantType::class, $type, \false); } /** * @deprecated Use Type::isConstantValue() or Type::generalize() * @return ConstantType[] */ public static function getAnyConstantTypes(\PHPStan\Type\Type $type) : array { return self::map(\PHPStan\Type\ConstantType::class, $type, \false, \false); } /** * @return ArrayType[] * * @deprecated Use PHPStan\Type\Type::getArrays() instead. */ public static function getAnyArrays(\PHPStan\Type\Type $type) : array { return self::map(\PHPStan\Type\ArrayType::class, $type, \true, \false); } /** * @deprecated Use PHPStan\Type\Type::generalize() instead. */ public static function generalizeType(\PHPStan\Type\Type $type, \PHPStan\Type\GeneralizePrecision $precision) : \PHPStan\Type\Type { return $type->generalize($precision); } /** * @return list * * @deprecated Use Type::getObjectClassNames() instead. */ public static function getDirectClassNames(\PHPStan\Type\Type $type) : array { if ($type instanceof \PHPStan\Type\TypeWithClassName) { return [$type->getClassName()]; } if ($type instanceof \PHPStan\Type\UnionType || $type instanceof \PHPStan\Type\IntersectionType) { $classNames = []; foreach ($type->getTypes() as $innerType) { foreach (self::getDirectClassNames($innerType) as $n) { $classNames[] = $n; } } return array_values(array_unique($classNames)); } return []; } /** * @return IntegerRangeType[] */ public static function getIntegerRanges(\PHPStan\Type\Type $type) : array { return self::map(\PHPStan\Type\IntegerRangeType::class, $type, \false); } /** * @deprecated Use Type::isConstantScalarValue() or Type::getConstantScalarTypes() or Type::getConstantScalarValues() * @return ConstantScalarType[] */ public static function getConstantScalars(\PHPStan\Type\Type $type) : array { return self::map(\PHPStan\Type\ConstantScalarType::class, $type, \false); } /** * @deprecated Use Type::getEnumCases() * @return EnumCaseObjectType[] */ public static function getEnumCaseObjects(\PHPStan\Type\Type $type) : array { return self::map(EnumCaseObjectType::class, $type, \false); } /** * @internal * @return ConstantArrayType[] * * @deprecated Use PHPStan\Type\Type::getConstantArrays(). */ public static function getOldConstantArrays(\PHPStan\Type\Type $type) : array { return self::map(ConstantArrayType::class, $type, \false); } /** * @return mixed[] */ private static function map(string $typeClass, \PHPStan\Type\Type $type, bool $inspectIntersections, bool $stopOnUnmatched = \true) : array { if ($type instanceof $typeClass) { return [$type]; } if ($type instanceof \PHPStan\Type\UnionType) { $matchingTypes = []; foreach ($type->getTypes() as $innerType) { $matchingInner = self::map($typeClass, $innerType, $inspectIntersections, $stopOnUnmatched); if ($matchingInner === []) { if ($stopOnUnmatched) { return []; } continue; } foreach ($matchingInner as $innerMapped) { $matchingTypes[] = $innerMapped; } } return $matchingTypes; } if ($inspectIntersections && $type instanceof \PHPStan\Type\IntersectionType) { $matchingTypes = []; foreach ($type->getTypes() as $innerType) { if (!$innerType instanceof $typeClass) { if ($stopOnUnmatched) { return []; } continue; } $matchingTypes[] = $innerType; } return $matchingTypes; } return []; } public static function toBenevolentUnion(\PHPStan\Type\Type $type) : \PHPStan\Type\Type { if ($type instanceof \PHPStan\Type\BenevolentUnionType) { return $type; } if ($type instanceof \PHPStan\Type\UnionType) { return new \PHPStan\Type\BenevolentUnionType($type->getTypes()); } return $type; } /** * @return ($type is UnionType ? UnionType : Type) */ public static function toStrictUnion(\PHPStan\Type\Type $type) : \PHPStan\Type\Type { if ($type instanceof TemplateBenevolentUnionType) { return new TemplateUnionType($type->getScope(), $type->getStrategy(), $type->getVariance(), $type->getName(), static::toStrictUnion($type->getBound()), $type->getDefault()); } if ($type instanceof \PHPStan\Type\BenevolentUnionType) { return new \PHPStan\Type\UnionType($type->getTypes()); } return $type; } /** * @return Type[] */ public static function flattenTypes(\PHPStan\Type\Type $type) : array { if ($type instanceof ConstantArrayType) { return $type->getAllArrays(); } if ($type instanceof \PHPStan\Type\UnionType) { $types = []; foreach ($type->getTypes() as $innerType) { if ($innerType instanceof ConstantArrayType) { foreach ($innerType->getAllArrays() as $array) { $types[] = $array; } continue; } $types[] = $innerType; } return $types; } return [$type]; } public static function findThisType(\PHPStan\Type\Type $type) : ?\PHPStan\Type\ThisType { if ($type instanceof \PHPStan\Type\ThisType) { return $type; } if ($type instanceof \PHPStan\Type\UnionType || $type instanceof \PHPStan\Type\IntersectionType) { foreach ($type->getTypes() as $innerType) { $thisType = self::findThisType($innerType); if ($thisType !== null) { return $thisType; } } } return null; } /** * @return HasPropertyType[] */ public static function getHasPropertyTypes(\PHPStan\Type\Type $type) : array { if ($type instanceof HasPropertyType) { return [$type]; } if ($type instanceof \PHPStan\Type\UnionType || $type instanceof \PHPStan\Type\IntersectionType) { $hasPropertyTypes = [[]]; foreach ($type->getTypes() as $innerType) { $hasPropertyTypes[] = self::getHasPropertyTypes($innerType); } return array_merge(...$hasPropertyTypes); } return []; } /** * @return AccessoryType[] */ public static function getAccessoryTypes(\PHPStan\Type\Type $type) : array { return self::map(AccessoryType::class, $type, \true, \false); } /** @deprecated Use PHPStan\Type\Type::isCallable() instead. */ public static function containsCallable(\PHPStan\Type\Type $type) : bool { if ($type->isCallable()->yes()) { return \true; } if ($type instanceof \PHPStan\Type\UnionType) { foreach ($type->getTypes() as $innerType) { if ($innerType->isCallable()->yes()) { return \true; } } } return \false; } public static function containsTemplateType(\PHPStan\Type\Type $type) : bool { $containsTemplateType = \false; \PHPStan\Type\TypeTraverser::map($type, static function (\PHPStan\Type\Type $type, callable $traverse) use(&$containsTemplateType) : \PHPStan\Type\Type { if ($type instanceof TemplateType) { $containsTemplateType = \true; } return $containsTemplateType ? $type : $traverse($type); }); return $containsTemplateType; } public static function resolveLateResolvableTypes(\PHPStan\Type\Type $type, bool $resolveUnresolvableTypes = \true) : \PHPStan\Type\Type { /** @var int $ignoreResolveUnresolvableTypesLevel */ $ignoreResolveUnresolvableTypesLevel = 0; return \PHPStan\Type\TypeTraverser::map($type, static function (\PHPStan\Type\Type $type, callable $traverse) use($resolveUnresolvableTypes, &$ignoreResolveUnresolvableTypesLevel) : \PHPStan\Type\Type { while ($type instanceof \PHPStan\Type\LateResolvableType && ($resolveUnresolvableTypes && $ignoreResolveUnresolvableTypesLevel === 0 || $type->isResolvable())) { $type = $type->resolve(); } if ($type instanceof \PHPStan\Type\CallableType || $type instanceof \PHPStan\Type\ClosureType) { $ignoreResolveUnresolvableTypesLevel++; $result = $traverse($type); $ignoreResolveUnresolvableTypesLevel--; return $result; } return $traverse($type); }); } } */ private $templateTags; /** * @var SimpleThrowPoint[] */ private $throwPoints; /** * @var InvalidateExprNode[] */ private $invalidateExpressions; /** * @var string[] */ private $usedVariables; /** * @var bool */ private $acceptsNamedArguments; use NonArrayTypeTrait; use NonIterableTypeTrait; use UndecidedComparisonTypeTrait; use NonOffsetAccessibleTypeTrait; use NonRemoveableTypeTrait; use NonGeneralizableTypeTrait; /** @var array */ private $parameters; /** * @var Type */ private $returnType; /** * @var bool */ private $isCommonCallable; /** * @var ObjectType */ private $objectType; /** * @var TemplateTypeMap */ private $templateTypeMap; /** * @var TemplateTypeMap */ private $resolvedTemplateTypeMap; /** * @var TemplateTypeVarianceMap */ private $callSiteVarianceMap; /** @var SimpleImpurePoint[] */ private $impurePoints; /** * @api * @param array|null $parameters * @param array $templateTags * @param SimpleThrowPoint[] $throwPoints * @param ?SimpleImpurePoint[] $impurePoints * @param InvalidateExprNode[] $invalidateExpressions * @param string[] $usedVariables */ public function __construct(?array $parameters = null, ?\PHPStan\Type\Type $returnType = null, bool $variadic = \true, ?TemplateTypeMap $templateTypeMap = null, ?TemplateTypeMap $resolvedTemplateTypeMap = null, ?TemplateTypeVarianceMap $callSiteVarianceMap = null, array $templateTags = [], array $throwPoints = [], ?array $impurePoints = null, array $invalidateExpressions = [], array $usedVariables = [], bool $acceptsNamedArguments = \true) { $this->variadic = $variadic; $this->templateTags = $templateTags; $this->throwPoints = $throwPoints; $this->invalidateExpressions = $invalidateExpressions; $this->usedVariables = $usedVariables; $this->acceptsNamedArguments = $acceptsNamedArguments; $this->parameters = $parameters ?? []; $this->returnType = $returnType ?? new \PHPStan\Type\MixedType(); $this->isCommonCallable = $parameters === null && $returnType === null; $this->objectType = new \PHPStan\Type\ObjectType(Closure::class); $this->templateTypeMap = $templateTypeMap ?? TemplateTypeMap::createEmpty(); $this->resolvedTemplateTypeMap = $resolvedTemplateTypeMap ?? TemplateTypeMap::createEmpty(); $this->callSiteVarianceMap = $callSiteVarianceMap ?? TemplateTypeVarianceMap::createEmpty(); $this->impurePoints = $impurePoints ?? [new SimpleImpurePoint('functionCall', 'call to an unknown Closure', \false)]; } /** * @return array */ public function getTemplateTags() : array { return $this->templateTags; } public static function createPure() : self { return new self(null, null, \true, null, null, null, [], [], []); } public function isPure() : TrinaryLogic { $impurePoints = $this->getImpurePoints(); if (count($impurePoints) === 0) { return TrinaryLogic::createYes(); } $certainCount = 0; foreach ($impurePoints as $impurePoint) { if (!$impurePoint->isCertain()) { continue; } $certainCount++; } return $certainCount > 0 ? TrinaryLogic::createNo() : TrinaryLogic::createMaybe(); } public function getClassName() : string { return $this->objectType->getClassName(); } public function getClassReflection() : ?ClassReflection { return $this->objectType->getClassReflection(); } public function getAncestorWithClassName(string $className) : ?\PHPStan\Type\TypeWithClassName { return $this->objectType->getAncestorWithClassName($className); } /** * @return string[] */ public function getReferencedClasses() : array { $classes = $this->objectType->getReferencedClasses(); foreach ($this->parameters as $parameter) { $classes = array_merge($classes, $parameter->getType()->getReferencedClasses()); } return array_merge($classes, $this->returnType->getReferencedClasses()); } public function getObjectClassNames() : array { return $this->objectType->getObjectClassNames(); } public function getObjectClassReflections() : array { return $this->objectType->getObjectClassReflections(); } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } if (!$type instanceof \PHPStan\Type\ClosureType) { return $this->objectType->acceptsWithReason($type, $strictTypes); } return $this->isSuperTypeOfInternal($type, \true)->toAcceptsResult(); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } return $this->isSuperTypeOfInternal($type, \false); } private function isSuperTypeOfInternal(\PHPStan\Type\Type $type, bool $treatMixedAsAny) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self) { $parameterTypes = array_map(static function ($parameter) { return $parameter->getType(); }, $this->getParameters()); $variant = ParametersAcceptorSelector::selectFromTypes($parameterTypes, [$type], \false); if (!$variant instanceof CallableParametersAcceptor) { return \PHPStan\Type\IsSuperTypeOfResult::createNo([]); } return \PHPStan\Type\CallableTypeHelper::isParametersAcceptorSuperTypeOf($this, $variant, $treatMixedAsAny); } if ($type->getObjectClassNames() === [Closure::class]) { return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } return $this->objectType->isSuperTypeOfWithReason($type); } public function equals(\PHPStan\Type\Type $type) : bool { if (!$type instanceof self) { return \false; } return $this->describe(\PHPStan\Type\VerbosityLevel::precise()) === $type->describe(\PHPStan\Type\VerbosityLevel::precise()); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return $level->handle(static function () : string { return 'Closure'; }, function () : string { if ($this->isCommonCallable) { return $this->isPure()->yes() ? 'pure-Closure' : 'Closure'; } $printer = new Printer(); $selfWithoutParameterNames = new self(array_map(static function (ParameterReflection $p) : ParameterReflection { return new DummyParameter('', $p->getType(), $p->isOptional() && !$p->isVariadic(), PassedByReference::createNo(), $p->isVariadic(), $p->getDefaultValue()); }, $this->parameters), $this->returnType, $this->variadic, $this->templateTypeMap, $this->resolvedTemplateTypeMap, $this->callSiteVarianceMap, $this->templateTags, $this->throwPoints, $this->impurePoints, $this->invalidateExpressions, $this->usedVariables); return $printer->print($selfWithoutParameterNames->toPhpDocNode()); }); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isObject() : TrinaryLogic { return $this->objectType->isObject(); } public function isEnum() : TrinaryLogic { return $this->objectType->isEnum(); } public function getTemplateType(string $ancestorClassName, string $templateTypeName) : \PHPStan\Type\Type { return $this->objectType->getTemplateType($ancestorClassName, $templateTypeName); } public function canAccessProperties() : TrinaryLogic { return $this->objectType->canAccessProperties(); } public function hasProperty(string $propertyName) : TrinaryLogic { return $this->objectType->hasProperty($propertyName); } public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection { return $this->objectType->getProperty($propertyName, $scope); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { return $this->objectType->getUnresolvedPropertyPrototype($propertyName, $scope); } public function canCallMethods() : TrinaryLogic { return $this->objectType->canCallMethods(); } public function hasMethod(string $methodName) : TrinaryLogic { return $this->objectType->hasMethod($methodName); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { return $this->getUnresolvedMethodPrototype($methodName, $scope)->getTransformedMethod(); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { if ($methodName === 'call') { return new ClosureCallUnresolvedMethodPrototypeReflection($this->objectType->getUnresolvedMethodPrototype($methodName, $scope), $this); } return $this->objectType->getUnresolvedMethodPrototype($methodName, $scope); } public function canAccessConstants() : TrinaryLogic { return $this->objectType->canAccessConstants(); } public function hasConstant(string $constantName) : TrinaryLogic { return $this->objectType->hasConstant($constantName); } public function getConstant(string $constantName) : ConstantReflection { return $this->objectType->getConstant($constantName); } public function getConstantStrings() : array { return []; } public function isIterable() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isIterableAtLeastOnce() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isCallable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function getEnumCases() : array { return []; } public function isCommonCallable() : bool { return $this->isCommonCallable; } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { return [$this]; } public function getThrowPoints() : array { return $this->throwPoints; } public function getImpurePoints() : array { return $this->impurePoints; } public function getInvalidateExpressions() : array { return $this->invalidateExpressions; } public function getUsedVariables() : array { return $this->usedVariables; } public function acceptsNamedArguments() : bool { return $this->acceptsNamedArguments; } public function isCloneable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function toBoolean() : \PHPStan\Type\BooleanType { return new ConstantBooleanType(\true); } public function toNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toAbsoluteNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toInteger() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toFloat() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toString() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toArray() : \PHPStan\Type\Type { return new ConstantArrayType([new ConstantIntegerType(0)], [$this], [1], [], TrinaryLogic::createYes()); } public function toArrayKey() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getTemplateTypeMap() : TemplateTypeMap { return $this->templateTypeMap; } public function getResolvedTemplateTypeMap() : TemplateTypeMap { return $this->resolvedTemplateTypeMap; } public function getCallSiteVarianceMap() : TemplateTypeVarianceMap { return $this->callSiteVarianceMap; } /** * @return array */ public function getParameters() : array { return $this->parameters; } public function isVariadic() : bool { return $this->variadic; } public function getReturnType() : \PHPStan\Type\Type { return $this->returnType; } public function inferTemplateTypes(\PHPStan\Type\Type $receivedType) : TemplateTypeMap { if ($receivedType instanceof \PHPStan\Type\UnionType || $receivedType instanceof \PHPStan\Type\IntersectionType) { return $receivedType->inferTemplateTypesOn($this); } if ($receivedType->isCallable()->no() || !$receivedType instanceof self) { return TemplateTypeMap::createEmpty(); } $parametersAcceptors = $receivedType->getCallableParametersAcceptors(new OutOfClassScope()); $typeMap = TemplateTypeMap::createEmpty(); foreach ($parametersAcceptors as $parametersAcceptor) { $typeMap = $typeMap->union($this->inferTemplateTypesOnParametersAcceptor($parametersAcceptor)); } return $typeMap; } private function inferTemplateTypesOnParametersAcceptor(ParametersAcceptor $parametersAcceptor) : TemplateTypeMap { $parameterTypes = array_map(static function ($parameter) { return $parameter->getType(); }, $this->getParameters()); $parametersAcceptor = ParametersAcceptorSelector::selectFromTypes($parameterTypes, [$parametersAcceptor], \false); $args = $parametersAcceptor->getParameters(); $returnType = $parametersAcceptor->getReturnType(); $typeMap = TemplateTypeMap::createEmpty(); foreach ($this->getParameters() as $i => $param) { $paramType = $param->getType(); if (isset($args[$i])) { $argType = $args[$i]->getType(); } elseif ($paramType instanceof TemplateType) { $argType = TemplateTypeHelper::resolveToBounds($paramType); } else { $argType = new \PHPStan\Type\NeverType(); } $typeMap = $typeMap->union($paramType->inferTemplateTypes($argType)->convertToLowerBoundTypes()); } return $typeMap->union($this->getReturnType()->inferTemplateTypes($returnType)); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { $references = $this->getReturnType()->getReferencedTemplateTypes($positionVariance->compose(TemplateTypeVariance::createCovariant())); $paramVariance = $positionVariance->compose(TemplateTypeVariance::createContravariant()); foreach ($this->getParameters() as $param) { foreach ($param->getType()->getReferencedTemplateTypes($paramVariance) as $reference) { $references[] = $reference; } } return $references; } public function traverse(callable $cb) : \PHPStan\Type\Type { if ($this->isCommonCallable) { return $this; } return new self(array_map(static function (ParameterReflection $param) use($cb) : NativeParameterReflection { $defaultValue = $param->getDefaultValue(); return new NativeParameterReflection($param->getName(), $param->isOptional(), $cb($param->getType()), $param->passedByReference(), $param->isVariadic(), $defaultValue !== null ? $cb($defaultValue) : null); }, $this->getParameters()), $cb($this->getReturnType()), $this->isVariadic(), $this->templateTypeMap, $this->resolvedTemplateTypeMap, $this->callSiteVarianceMap, $this->templateTags, $this->throwPoints, $this->impurePoints, $this->invalidateExpressions, $this->usedVariables, $this->acceptsNamedArguments); } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if ($this->isCommonCallable) { return $this; } if (!$right instanceof self) { return $this; } $rightParameters = $right->getParameters(); if (count($this->getParameters()) !== count($rightParameters)) { return $this; } $parameters = []; foreach ($this->getParameters() as $i => $leftParam) { $rightParam = $rightParameters[$i]; $leftDefaultValue = $leftParam->getDefaultValue(); $rightDefaultValue = $rightParam->getDefaultValue(); $defaultValue = $leftDefaultValue; if ($leftDefaultValue !== null && $rightDefaultValue !== null) { $defaultValue = $cb($leftDefaultValue, $rightDefaultValue); } $parameters[] = new NativeParameterReflection($leftParam->getName(), $leftParam->isOptional(), $cb($leftParam->getType(), $rightParam->getType()), $leftParam->passedByReference(), $leftParam->isVariadic(), $defaultValue); } return new self($parameters, $cb($this->getReturnType(), $right->getReturnType()), $this->isVariadic(), $this->templateTypeMap, $this->resolvedTemplateTypeMap, $this->callSiteVarianceMap, $this->templateTags, $this->throwPoints, $this->impurePoints, $this->invalidateExpressions, $this->usedVariables, $this->acceptsNamedArguments); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return $this; } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createNo(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { if ($this->isCommonCallable) { return new IdentifierTypeNode($this->isPure()->yes() ? 'pure-Closure' : 'Closure'); } $parameters = []; foreach ($this->parameters as $parameter) { $parameters[] = new CallableTypeParameterNode($parameter->getType()->toPhpDocNode(), !$parameter->passedByReference()->no(), $parameter->isVariadic(), $parameter->getName() === '' ? '' : '$' . $parameter->getName(), $parameter->isOptional()); } $templateTags = []; foreach ($this->templateTags as $templateName => $templateTag) { $templateTags[] = new TemplateTagValueNode($templateName, $templateTag->getBound()->toPhpDocNode(), ''); } return new CallableTypeNode(new IdentifierTypeNode('Closure'), $parameters, $this->returnType->toPhpDocNode(), $templateTags); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['parameters'], $properties['returnType'], $properties['variadic'], $properties['templateTypeMap'], $properties['resolvedTemplateTypeMap'], $properties['callSiteVarianceMap'], $properties['templateTags'], $properties['throwPoints'], $properties['impurePoints'], $properties['invalidateExpressions'], $properties['usedVariables'], $properties['acceptsNamedArguments']); } } */ private $globalTypeAliases; /** * @var TypeStringResolver */ private $typeStringResolver; /** * @var TypeNodeResolver */ private $typeNodeResolver; /** * @var ReflectionProvider */ private $reflectionProvider; /** @var array */ private $resolvedGlobalTypeAliases = []; /** @var array */ private $resolvedLocalTypeAliases = []; /** @var array */ private $resolvingClassTypeAliases = []; /** @var array */ private $inProcess = []; /** * @param array $globalTypeAliases */ public function __construct(array $globalTypeAliases, TypeStringResolver $typeStringResolver, TypeNodeResolver $typeNodeResolver, ReflectionProvider $reflectionProvider) { $this->globalTypeAliases = $globalTypeAliases; $this->typeStringResolver = $typeStringResolver; $this->typeNodeResolver = $typeNodeResolver; $this->reflectionProvider = $reflectionProvider; } public function hasTypeAlias(string $aliasName, ?string $classNameScope) : bool { $hasGlobalTypeAlias = array_key_exists($aliasName, $this->globalTypeAliases); if ($hasGlobalTypeAlias) { return \true; } if ($classNameScope === null || !$this->reflectionProvider->hasClass($classNameScope)) { return \false; } $classReflection = $this->reflectionProvider->getClass($classNameScope); $localTypeAliases = $classReflection->getTypeAliases(); return array_key_exists($aliasName, $localTypeAliases); } public function resolveTypeAlias(string $aliasName, NameScope $nameScope) : ?\PHPStan\Type\Type { return $this->resolveLocalTypeAlias($aliasName, $nameScope) ?? $this->resolveGlobalTypeAlias($aliasName, $nameScope); } private function resolveLocalTypeAlias(string $aliasName, NameScope $nameScope) : ?\PHPStan\Type\Type { if (array_key_exists($aliasName, $this->globalTypeAliases)) { return null; } if (!$nameScope->hasTypeAlias($aliasName)) { return null; } $className = $nameScope->getClassNameForTypeAlias(); if ($className === null) { return null; } $aliasNameInClassScope = $className . '::' . $aliasName; if (array_key_exists($aliasNameInClassScope, $this->resolvedLocalTypeAliases)) { return $this->resolvedLocalTypeAliases[$aliasNameInClassScope]; } // prevent infinite recursion if (array_key_exists($className, $this->resolvingClassTypeAliases)) { return null; } $this->resolvingClassTypeAliases[$className] = \true; if (!$this->reflectionProvider->hasClass($className)) { unset($this->resolvingClassTypeAliases[$className]); return null; } $classReflection = $this->reflectionProvider->getClass($className); $localTypeAliases = $classReflection->getTypeAliases(); unset($this->resolvingClassTypeAliases[$className]); if (!array_key_exists($aliasName, $localTypeAliases)) { return null; } if (array_key_exists($aliasNameInClassScope, $this->inProcess)) { // resolve circular reference as ErrorType to make it easier to detect throw new \PHPStan\Type\CircularTypeAliasDefinitionException(); } $this->inProcess[$aliasNameInClassScope] = \true; try { $unresolvedAlias = $localTypeAliases[$aliasName]; $resolvedAliasType = $unresolvedAlias->resolve($this->typeNodeResolver); } catch (\PHPStan\Type\CircularTypeAliasDefinitionException $e) { $resolvedAliasType = new \PHPStan\Type\CircularTypeAliasErrorType(); } $this->resolvedLocalTypeAliases[$aliasNameInClassScope] = $resolvedAliasType; unset($this->inProcess[$aliasNameInClassScope]); return $resolvedAliasType; } private function resolveGlobalTypeAlias(string $aliasName, NameScope $nameScope) : ?\PHPStan\Type\Type { if (!array_key_exists($aliasName, $this->globalTypeAliases)) { return null; } if (array_key_exists($aliasName, $this->resolvedGlobalTypeAliases)) { return $this->resolvedGlobalTypeAliases[$aliasName]; } if ($this->reflectionProvider->hasClass($nameScope->resolveStringName($aliasName))) { throw new ShouldNotHappenException(sprintf('Type alias %s already exists as a class.', $aliasName)); } if (array_key_exists($aliasName, $this->inProcess)) { throw new ShouldNotHappenException(sprintf('Circular definition for type alias %s.', $aliasName)); } $this->inProcess[$aliasName] = \true; $aliasTypeString = $this->globalTypeAliases[$aliasName]; $aliasType = $this->typeStringResolver->resolve($aliasTypeString); $this->resolvedGlobalTypeAliases[$aliasName] = $aliasType; unset($this->inProcess[$aliasName]); return $aliasType; } } */ private $cachedDescriptions = []; /** * @api * @param Type[] $types */ public function __construct(array $types, bool $normalized = \false) { $this->types = $types; $this->normalized = $normalized; $throwException = static function () use($types) : void { throw new ShouldNotHappenException(sprintf('Cannot create %s with: %s', self::class, implode(', ', array_map(static function (\PHPStan\Type\Type $type) : string { return $type->describe(\PHPStan\Type\VerbosityLevel::value()); }, $types)))); }; if (count($types) < 2) { $throwException(); } foreach ($types as $type) { if (!$type instanceof \PHPStan\Type\UnionType) { continue; } if ($type instanceof TemplateType) { continue; } $throwException(); } } /** * @return Type[] */ public function getTypes() : array { return $this->types; } /** * @param callable(Type $type): bool $filterCb */ public function filterTypes(callable $filterCb) : \PHPStan\Type\Type { $newTypes = []; $changed = \false; foreach ($this->getTypes() as $innerType) { if (!$filterCb($innerType)) { $changed = \true; continue; } $newTypes[] = $innerType; } if (!$changed) { return $this; } return \PHPStan\Type\TypeCombinator::union(...$newTypes); } public function isNormalized() : bool { return $this->normalized; } /** * @return Type[] */ protected function getSortedTypes() : array { if ($this->sortedTypes) { return $this->types; } $this->types = \PHPStan\Type\UnionTypeHelper::sortTypes($this->types); $this->sortedTypes = \true; return $this->types; } /** * @return string[] */ public function getReferencedClasses() : array { $classes = []; foreach ($this->types as $type) { foreach ($type->getReferencedClasses() as $className) { $classes[] = $className; } } return $classes; } public function getObjectClassNames() : array { return array_values(array_unique($this->pickFromTypes(static function (\PHPStan\Type\Type $type) { return $type->getObjectClassNames(); }, static function (\PHPStan\Type\Type $type) { return $type->isObject()->yes(); }))); } public function getObjectClassReflections() : array { return $this->pickFromTypes(static function (\PHPStan\Type\Type $type) { return $type->getObjectClassReflections(); }, static function (\PHPStan\Type\Type $type) { return $type->isObject()->yes(); }); } public function getArrays() : array { return $this->pickFromTypes(static function (\PHPStan\Type\Type $type) { return $type->getArrays(); }, static function (\PHPStan\Type\Type $type) { return $type->isArray()->yes(); }); } public function getConstantArrays() : array { return $this->pickFromTypes(static function (\PHPStan\Type\Type $type) { return $type->getConstantArrays(); }, static function (\PHPStan\Type\Type $type) { return $type->isArray()->yes(); }); } public function getConstantStrings() : array { return $this->pickFromTypes(static function (\PHPStan\Type\Type $type) { return $type->getConstantStrings(); }, static function (\PHPStan\Type\Type $type) { return $type->isString()->yes(); }); } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type->equals(new \PHPStan\Type\ObjectType(DateTimeInterface::class)) && $this->accepts(new \PHPStan\Type\UnionType([new \PHPStan\Type\ObjectType(DateTime::class), new \PHPStan\Type\ObjectType(DateTimeImmutable::class)]), $strictTypes)->yes()) { return \PHPStan\Type\AcceptsResult::createYes(); } $result = \PHPStan\Type\AcceptsResult::createNo(); foreach ($this->getSortedTypes() as $i => $innerType) { $result = $result->or($innerType->acceptsWithReason($type, $strictTypes)->decorateReasons(static function (string $reason) use($i) { return sprintf('Type #%d from the union: %s', $i + 1, $reason); })); } if ($result->yes()) { return $result; } if ($type instanceof \PHPStan\Type\CompoundType && !$type instanceof \PHPStan\Type\CallableType && !$type instanceof TemplateType && !$type instanceof \PHPStan\Type\IntersectionType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } if ($type instanceof TemplateUnionType) { return $result->or($type->isAcceptedWithReasonBy($this, $strictTypes)); } if ($type->isEnum()->yes() && !$this->isEnum()->no()) { $enumCasesUnion = \PHPStan\Type\TypeCombinator::union(...$type->getEnumCases()); if (!$type->equals($enumCasesUnion)) { return $this->acceptsWithReason($enumCasesUnion, $strictTypes); } } return $result; } public function isSuperTypeOf(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->isSuperTypeOfWithReason($otherType)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $otherType) : \PHPStan\Type\IsSuperTypeOfResult { if ($otherType instanceof self && !$otherType instanceof TemplateUnionType || $otherType instanceof \PHPStan\Type\IterableType && !$otherType instanceof TemplateIterableType || $otherType instanceof \PHPStan\Type\NeverType || $otherType instanceof \PHPStan\Type\ConditionalType || $otherType instanceof \PHPStan\Type\ConditionalTypeForParameter || $otherType instanceof \PHPStan\Type\IntegerRangeType) { return $otherType->isSubTypeOfWithReason($this); } $results = []; foreach ($this->types as $innerType) { $result = $innerType->isSuperTypeOfWithReason($otherType); if ($result->yes()) { return $result; } $results[] = $result; } $result = \PHPStan\Type\IsSuperTypeOfResult::createNo()->or(...$results); if ($otherType instanceof TemplateUnionType) { return $result->or($otherType->isSubTypeOfWithReason($this)); } return $result; } public function isSubTypeOf(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(\PHPStan\Type\Type $otherType) : \PHPStan\Type\IsSuperTypeOfResult { return \PHPStan\Type\IsSuperTypeOfResult::extremeIdentity(...array_map(static function (\PHPStan\Type\Type $innerType) use($otherType) { return $otherType->isSuperTypeOfWithReason($innerType); }, $this->types)); } public function isAcceptedBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : \PHPStan\Type\AcceptsResult { return \PHPStan\Type\AcceptsResult::extremeIdentity(...array_map(static function (\PHPStan\Type\Type $innerType) use($acceptingType, $strictTypes) { return $acceptingType->acceptsWithReason($innerType, $strictTypes); }, $this->types)); } public function equals(\PHPStan\Type\Type $type) : bool { if (!$type instanceof static) { return \false; } if (count($this->types) !== count($type->types)) { return \false; } $otherTypes = $type->types; foreach ($this->types as $innerType) { $match = \false; foreach ($otherTypes as $i => $otherType) { if (!$innerType->equals($otherType)) { continue; } $match = \true; unset($otherTypes[$i]); break; } if (!$match) { return \false; } } return count($otherTypes) === 0; } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { if (isset($this->cachedDescriptions[$level->getLevelValue()])) { return $this->cachedDescriptions[$level->getLevelValue()]; } $joinTypes = static function (array $types) use($level) : string { $typeNames = []; foreach ($types as $i => $type) { if ($type instanceof \PHPStan\Type\ClosureType || $type instanceof \PHPStan\Type\CallableType || $type instanceof TemplateUnionType) { $typeNames[] = sprintf('(%s)', $type->describe($level)); } elseif ($type instanceof TemplateType) { $isLast = $i >= count($types) - 1; $bound = $type->getBound(); if (!$isLast && ($level->isTypeOnly() || $level->isValue()) && !($bound instanceof \PHPStan\Type\MixedType && $bound->getSubtractedType() === null && !$bound instanceof TemplateMixedType)) { $typeNames[] = sprintf('(%s)', $type->describe($level)); } else { $typeNames[] = $type->describe($level); } } elseif ($type instanceof \PHPStan\Type\IntersectionType) { $intersectionDescription = $type->describe($level); if (str_contains($intersectionDescription, '&')) { $typeNames[] = sprintf('(%s)', $type->describe($level)); } else { $typeNames[] = $intersectionDescription; } } else { $typeNames[] = $type->describe($level); } } if ($level->isPrecise()) { $duplicates = array_diff_assoc($typeNames, array_unique($typeNames)); if (count($duplicates) > 0) { $indexByDuplicate = array_fill_keys($duplicates, 0); foreach ($typeNames as $key => $typeName) { if (!isset($indexByDuplicate[$typeName])) { continue; } $typeNames[$key] = $typeName . '#' . ++$indexByDuplicate[$typeName]; } } } else { $typeNames = array_unique($typeNames); } if (count($typeNames) > 1024) { return implode('|', array_slice($typeNames, 0, 1024)) . "|…"; } return implode('|', $typeNames); }; return $this->cachedDescriptions[$level->getLevelValue()] = $level->handle(function () use($joinTypes) : string { $types = \PHPStan\Type\TypeCombinator::union(...array_map(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { if ($type->isConstantValue()->yes() && $type->isTrue()->or($type->isFalse())->no()) { return $type->generalize(\PHPStan\Type\GeneralizePrecision::lessSpecific()); } return $type; }, $this->getSortedTypes())); if ($types instanceof \PHPStan\Type\UnionType) { return $joinTypes($types->getSortedTypes()); } return $joinTypes([$types]); }, function () use($joinTypes) : string { return $joinTypes($this->getSortedTypes()); }); } /** * @param callable(Type $type): TrinaryLogic $canCallback * @param callable(Type $type): TrinaryLogic $hasCallback */ private function hasInternal(callable $canCallback, callable $hasCallback) : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->types, static function (\PHPStan\Type\Type $type) use($canCallback, $hasCallback) : TrinaryLogic { if ($canCallback($type)->no()) { return TrinaryLogic::createNo(); } return $hasCallback($type); }); } /** * @template TObject of object * @param callable(Type $type): TrinaryLogic $hasCallback * @param callable(Type $type): TObject $getCallback * @return TObject */ private function getInternal(callable $hasCallback, callable $getCallback) : object { /** @var TrinaryLogic|null $result */ $result = null; /** @var TObject|null $object */ $object = null; foreach ($this->types as $type) { $has = $hasCallback($type); if (!$has->yes()) { continue; } if ($result !== null && $result->compareTo($has) !== $has) { continue; } $get = $getCallback($type); $result = $has; $object = $get; } if ($object === null) { throw new ShouldNotHappenException(); } return $object; } public function getTemplateType(string $ancestorClassName, string $templateTypeName) : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) use($ancestorClassName, $templateTypeName) : \PHPStan\Type\Type { return $type->getTemplateType($ancestorClassName, $templateTypeName); }); } public function isObject() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isObject(); }); } public function isEnum() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isEnum(); }); } public function canAccessProperties() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->canAccessProperties(); }); } public function hasProperty(string $propertyName) : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) use($propertyName) : TrinaryLogic { return $type->hasProperty($propertyName); }); } public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection { return $this->getUnresolvedPropertyPrototype($propertyName, $scope)->getTransformedProperty(); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { $propertyPrototypes = []; foreach ($this->types as $type) { if (!$type->hasProperty($propertyName)->yes()) { continue; } $propertyPrototypes[] = $type->getUnresolvedPropertyPrototype($propertyName, $scope)->withFechedOnType($this); } $propertiesCount = count($propertyPrototypes); if ($propertiesCount === 0) { throw new ShouldNotHappenException(); } if ($propertiesCount === 1) { return $propertyPrototypes[0]; } return new UnionTypeUnresolvedPropertyPrototypeReflection($propertyName, $propertyPrototypes); } public function canCallMethods() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->canCallMethods(); }); } public function hasMethod(string $methodName) : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) use($methodName) : TrinaryLogic { return $type->hasMethod($methodName); }); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { return $this->getUnresolvedMethodPrototype($methodName, $scope)->getTransformedMethod(); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { $methodPrototypes = []; foreach ($this->types as $type) { if (!$type->hasMethod($methodName)->yes()) { continue; } $methodPrototypes[] = $type->getUnresolvedMethodPrototype($methodName, $scope)->withCalledOnType($this); } $methodsCount = count($methodPrototypes); if ($methodsCount === 0) { throw new ShouldNotHappenException(); } if ($methodsCount === 1) { return $methodPrototypes[0]; } return new UnionTypeUnresolvedMethodPrototypeReflection($methodName, $methodPrototypes); } public function canAccessConstants() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->canAccessConstants(); }); } public function hasConstant(string $constantName) : TrinaryLogic { return $this->hasInternal(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->canAccessConstants(); }, static function (\PHPStan\Type\Type $type) use($constantName) : TrinaryLogic { return $type->hasConstant($constantName); }); } public function getConstant(string $constantName) : ConstantReflection { return $this->getInternal(static function (\PHPStan\Type\Type $type) use($constantName) : TrinaryLogic { return $type->hasConstant($constantName); }, static function (\PHPStan\Type\Type $type) use($constantName) : ConstantReflection { return $type->getConstant($constantName); }); } public function isIterable() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isIterable(); }); } public function isIterableAtLeastOnce() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isIterableAtLeastOnce(); }); } public function getArraySize() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getArraySize(); }); } public function getIterableKeyType() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getIterableKeyType(); }); } public function getFirstIterableKeyType() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getFirstIterableKeyType(); }); } public function getLastIterableKeyType() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getLastIterableKeyType(); }); } public function getIterableValueType() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getIterableValueType(); }); } public function getFirstIterableValueType() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getFirstIterableValueType(); }); } public function getLastIterableValueType() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getLastIterableValueType(); }); } public function isArray() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isArray(); }); } public function isConstantArray() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isConstantArray(); }); } public function isOversizedArray() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isOversizedArray(); }); } public function isList() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isList(); }); } public function isString() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isString(); }); } public function isNumericString() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isNumericString(); }); } public function isNonEmptyString() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isNonEmptyString(); }); } public function isNonFalsyString() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isNonFalsyString(); }); } public function isLiteralString() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isLiteralString(); }); } public function isLowercaseString() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isLowercaseString(); }); } public function isUppercaseString() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isUppercaseString(); }); } public function isClassStringType() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isClassStringType(); }); } public function getClassStringObjectType() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getClassStringObjectType(); }); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getObjectTypeOrClassStringObjectType(); }); } public function isVoid() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isVoid(); }); } public function isScalar() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isScalar(); }); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function isOffsetAccessible() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isOffsetAccessible(); }); } public function isOffsetAccessLegal() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isOffsetAccessLegal(); }); } public function hasOffsetValueType(\PHPStan\Type\Type $offsetType) : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) use($offsetType) : TrinaryLogic { return $type->hasOffsetValueType($offsetType); }); } public function getOffsetValueType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { $types = []; foreach ($this->types as $innerType) { $valueType = $innerType->getOffsetValueType($offsetType); if ($valueType instanceof \PHPStan\Type\ErrorType) { continue; } $types[] = $valueType; } if (count($types) === 0) { return new \PHPStan\Type\ErrorType(); } return \PHPStan\Type\TypeCombinator::union(...$types); } public function setOffsetValueType(?\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType, bool $unionValues = \true) : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) use($offsetType, $valueType, $unionValues) : \PHPStan\Type\Type { return $type->setOffsetValueType($offsetType, $valueType, $unionValues); }); } public function setExistingOffsetValueType(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) use($offsetType, $valueType) : \PHPStan\Type\Type { return $type->setExistingOffsetValueType($offsetType, $valueType); }); } public function unsetOffset(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) use($offsetType) : \PHPStan\Type\Type { return $type->unsetOffset($offsetType); }); } public function getKeysArray() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getKeysArray(); }); } public function getValuesArray() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getValuesArray(); }); } public function chunkArray(\PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) use($lengthType, $preserveKeys) : \PHPStan\Type\Type { return $type->chunkArray($lengthType, $preserveKeys); }); } public function fillKeysArray(\PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) use($valueType) : \PHPStan\Type\Type { return $type->fillKeysArray($valueType); }); } public function flipArray() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->flipArray(); }); } public function intersectKeyArray(\PHPStan\Type\Type $otherArraysType) : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) use($otherArraysType) : \PHPStan\Type\Type { return $type->intersectKeyArray($otherArraysType); }); } public function popArray() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->popArray(); }); } public function reverseArray(TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) use($preserveKeys) : \PHPStan\Type\Type { return $type->reverseArray($preserveKeys); }); } public function searchArray(\PHPStan\Type\Type $needleType) : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) use($needleType) : \PHPStan\Type\Type { return $type->searchArray($needleType); }); } public function shiftArray() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->shiftArray(); }); } public function shuffleArray() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->shuffleArray(); }); } public function sliceArray(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) use($offsetType, $lengthType, $preserveKeys) : \PHPStan\Type\Type { return $type->sliceArray($offsetType, $lengthType, $preserveKeys); }); } public function getEnumCases() : array { return $this->pickFromTypes(static function (\PHPStan\Type\Type $type) { return $type->getEnumCases(); }, static function (\PHPStan\Type\Type $type) { return $type->isObject()->yes(); }); } public function isCallable() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isCallable(); }); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { $acceptors = []; foreach ($this->types as $type) { if ($type->isCallable()->no()) { continue; } $acceptors = array_merge($acceptors, $type->getCallableParametersAcceptors($scope)); } if (count($acceptors) === 0) { throw new ShouldNotHappenException(); } return $acceptors; } public function isCloneable() : TrinaryLogic { return $this->unionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isCloneable(); }); } public function isSmallerThan(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) use($otherType) : TrinaryLogic { return $type->isSmallerThan($otherType); }); } public function isSmallerThanOrEqual(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) use($otherType) : TrinaryLogic { return $type->isSmallerThanOrEqual($otherType); }); } public function isNull() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isNull(); }); } public function isConstantValue() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isConstantValue(); }); } public function isConstantScalarValue() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isConstantScalarValue(); }); } public function getConstantScalarTypes() : array { return $this->notBenevolentPickFromTypes(static function (\PHPStan\Type\Type $type) { return $type->getConstantScalarTypes(); }); } public function getConstantScalarValues() : array { return $this->notBenevolentPickFromTypes(static function (\PHPStan\Type\Type $type) { return $type->getConstantScalarValues(); }); } public function isTrue() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isTrue(); }); } public function isFalse() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isFalse(); }); } public function isBoolean() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isBoolean(); }); } public function isFloat() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isFloat(); }); } public function isInteger() : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isInteger(); }); } public function getSmallerType() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getSmallerType(); }); } public function getSmallerOrEqualType() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getSmallerOrEqualType(); }); } public function getGreaterType() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getGreaterType(); }); } public function getGreaterOrEqualType() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getGreaterOrEqualType(); }); } public function isGreaterThan(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) use($otherType) : TrinaryLogic { return $otherType->isSmallerThan($type); }); } public function isGreaterThanOrEqual(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->notBenevolentUnionResults(static function (\PHPStan\Type\Type $type) use($otherType) : TrinaryLogic { return $otherType->isSmallerThanOrEqual($type); }); } public function toBoolean() : \PHPStan\Type\BooleanType { /** @var BooleanType $type */ $type = $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\BooleanType { return $type->toBoolean(); }); return $type; } public function toNumber() : \PHPStan\Type\Type { $type = $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toNumber(); }); return $type; } public function toAbsoluteNumber() : \PHPStan\Type\Type { $type = $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toAbsoluteNumber(); }); return $type; } public function toString() : \PHPStan\Type\Type { $type = $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toString(); }); return $type; } public function toInteger() : \PHPStan\Type\Type { $type = $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toInteger(); }); return $type; } public function toFloat() : \PHPStan\Type\Type { $type = $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toFloat(); }); return $type; } public function toArray() : \PHPStan\Type\Type { $type = $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toArray(); }); return $type; } public function toArrayKey() : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toArrayKey(); }); } public function inferTemplateTypes(\PHPStan\Type\Type $receivedType) : TemplateTypeMap { $types = TemplateTypeMap::createEmpty(); if ($receivedType instanceof \PHPStan\Type\UnionType) { $myTypes = []; $remainingReceivedTypes = []; foreach ($receivedType->getTypes() as $receivedInnerType) { foreach ($this->types as $type) { if ($type->isSuperTypeOf($receivedInnerType)->yes()) { $types = $types->union($type->inferTemplateTypes($receivedInnerType)); continue 2; } $myTypes[] = $type; } $remainingReceivedTypes[] = $receivedInnerType; } if (count($remainingReceivedTypes) === 0) { return $types; } $receivedType = \PHPStan\Type\TypeCombinator::union(...$remainingReceivedTypes); } else { $myTypes = $this->types; } foreach ($myTypes as $type) { if ($type instanceof TemplateType || $type instanceof GenericClassStringType && $type->getGenericType() instanceof TemplateType) { continue; } $types = $types->union($type->inferTemplateTypes($receivedType)); } if (!$types->isEmpty()) { return $types; } foreach ($myTypes as $type) { $types = $types->union($type->inferTemplateTypes($receivedType)); } return $types; } public function inferTemplateTypesOn(\PHPStan\Type\Type $templateType) : TemplateTypeMap { $types = TemplateTypeMap::createEmpty(); foreach ($this->types as $type) { $types = $types->union($templateType->inferTemplateTypes($type)); } return $types; } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { $references = []; foreach ($this->types as $type) { foreach ($type->getReferencedTemplateTypes($positionVariance) as $reference) { $references[] = $reference; } } return $references; } public function traverse(callable $cb) : \PHPStan\Type\Type { $types = []; $changed = \false; foreach ($this->types as $type) { $newType = $cb($type); if ($type !== $newType) { $changed = \true; } $types[] = $newType; } if ($changed) { return \PHPStan\Type\TypeCombinator::union(...$types); } return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { $types = []; $changed = \false; if (!$right instanceof self) { return $this; } if (count($this->getTypes()) !== count($right->getTypes())) { return $this; } foreach ($this->getSortedTypes() as $i => $leftType) { $rightType = $right->getSortedTypes()[$i]; $newType = $cb($leftType, $rightType); if ($leftType !== $newType) { $changed = \true; } $types[] = $newType; } if ($changed) { return \PHPStan\Type\TypeCombinator::union(...$types); } return $this; } public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) use($typeToRemove) : \PHPStan\Type\Type { return \PHPStan\Type\TypeCombinator::remove($type, $typeToRemove); }); } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return $this->unionTypes(static function (\PHPStan\Type\Type $type) use($exponent) : \PHPStan\Type\Type { return $type->exponentiate($exponent); }); } public function getFiniteTypes() : array { $types = $this->notBenevolentPickFromTypes(static function (\PHPStan\Type\Type $type) { return $type->getFiniteTypes(); }); $uniquedTypes = []; foreach ($types as $type) { $uniquedTypes[md5($type->describe(\PHPStan\Type\VerbosityLevel::cache()))] = $type; } if (count($uniquedTypes) > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT) { return []; } return array_values($uniquedTypes); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['types'], $properties['normalized']); } /** * @param callable(Type $type): TrinaryLogic $getResult */ protected function unionResults(callable $getResult) : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->types, $getResult); } /** * @param callable(Type $type): TrinaryLogic $getResult */ private function notBenevolentUnionResults(callable $getResult) : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->types, $getResult); } /** * @param callable(Type $type): Type $getType */ protected function unionTypes(callable $getType) : \PHPStan\Type\Type { return \PHPStan\Type\TypeCombinator::union(...array_map($getType, $this->types)); } /** * @template T of Type * @param callable(Type $type): list $getTypes * @return list * * @deprecated Use pickFromTypes() instead. */ protected function pickTypes(callable $getTypes) : array { return $this->pickFromTypes($getTypes, static function () { return \false; }); } /** * @template T * @param callable(Type $type): list $getValues * @param callable(Type $type): bool $criteria * @return list */ protected function pickFromTypes(callable $getValues, callable $criteria) : array { $values = []; foreach ($this->types as $type) { $innerValues = $getValues($type); if ($innerValues === []) { return []; } foreach ($innerValues as $innerType) { $values[] = $innerType; } } return $values; } public function toPhpDocNode() : TypeNode { return new UnionTypeNode(array_map(static function (\PHPStan\Type\Type $type) { return $type->toPhpDocNode(); }, $this->getSortedTypes())); } /** * @template T * @param callable(Type $type): list $getValues * @return list */ private function notBenevolentPickFromTypes(callable $getValues) : array { $values = []; foreach ($this->types as $type) { $innerValues = $getValues($type); if ($innerValues === []) { return []; } foreach ($innerValues as $innerType) { $values[] = $innerType; } } return $values; } } > */ private static $superTypes = []; /** * @var ?self */ private $cachedParent = null; /** @var self[]|null */ private $cachedInterfaces = null; /** @var array>> */ private static $methods = []; /** @var array>> */ private static $properties = []; /** @var array> */ private static $ancestors = []; /** @var array */ private $currentAncestors = []; /** * @var ?string */ private $cachedDescription = null; /** @var array> */ private static $enumCases = []; /** @api */ public function __construct(string $className, ?\PHPStan\Type\Type $subtractedType = null, ?ClassReflection $classReflection = null) { $this->className = $className; $this->classReflection = $classReflection; if ($subtractedType instanceof \PHPStan\Type\NeverType) { $subtractedType = null; } $this->subtractedType = $subtractedType; } public static function resetCaches() : void { self::$superTypes = []; self::$methods = []; self::$properties = []; self::$ancestors = []; self::$enumCases = []; } private static function createFromReflection(ClassReflection $reflection) : self { if (!$reflection->isGeneric()) { return new \PHPStan\Type\ObjectType($reflection->getName()); } return new GenericObjectType($reflection->getName(), $reflection->typeMapToList($reflection->getActiveTemplateTypeMap()), null, null, $reflection->varianceMapToList($reflection->getCallSiteVarianceMap())); } public function getClassName() : string { return $this->className; } public function hasProperty(string $propertyName) : TrinaryLogic { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return TrinaryLogic::createMaybe(); } $classHasProperty = \PHPStan\Type\RecursionGuard::run($this, static function () use($classReflection, $propertyName) : bool { return $classReflection->hasProperty($propertyName); }); if ($classHasProperty === \true || $classHasProperty instanceof \PHPStan\Type\ErrorType) { return TrinaryLogic::createYes(); } if ($classReflection->allowsDynamicProperties()) { return TrinaryLogic::createMaybe(); } if (!$classReflection->isFinal()) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createNo(); } public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection { return $this->getUnresolvedPropertyPrototype($propertyName, $scope)->getTransformedProperty(); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { if (!$scope->isInClass()) { $canAccessProperty = 'no'; } else { $canAccessProperty = $scope->getClassReflection()->getName(); } $description = $this->describeCache(); if (isset(self::$properties[$description][$propertyName][$canAccessProperty])) { return self::$properties[$description][$propertyName][$canAccessProperty]; } $nakedClassReflection = $this->getNakedClassReflection(); if ($nakedClassReflection === null) { throw new ClassNotFoundException($this->className); } if ($nakedClassReflection->isEnum()) { if ($propertyName === 'name' || $propertyName === 'value' && $nakedClassReflection->isBackedEnum()) { $properties = []; foreach ($this->getEnumCases() as $enumCase) { $properties[] = $enumCase->getUnresolvedPropertyPrototype($propertyName, $scope); } if (count($properties) > 0) { if (count($properties) === 1) { return $properties[0]; } return new UnionTypeUnresolvedPropertyPrototypeReflection($propertyName, $properties); } } } if (!$nakedClassReflection->hasNativeProperty($propertyName)) { $nakedClassReflection = $this->getClassReflection(); } if ($nakedClassReflection === null) { throw new ClassNotFoundException($this->className); } $property = \PHPStan\Type\RecursionGuard::run($this, static function () use($nakedClassReflection, $propertyName, $scope) { return $nakedClassReflection->getProperty($propertyName, $scope); }); if ($property instanceof \PHPStan\Type\ErrorType) { $property = new DummyPropertyReflection(); return new CallbackUnresolvedPropertyPrototypeReflection($property, $property->getDeclaringClass(), \false, static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type; }); } $ancestor = $this->getAncestorWithClassName($property->getDeclaringClass()->getName()); $resolvedClassReflection = null; if ($ancestor !== null && $ancestor->hasProperty($propertyName)->yes()) { $resolvedClassReflection = $ancestor->getClassReflection(); if ($ancestor !== $this) { $property = $ancestor->getUnresolvedPropertyPrototype($propertyName, $scope)->getNakedProperty(); } } if ($resolvedClassReflection === null) { $resolvedClassReflection = $property->getDeclaringClass(); } return self::$properties[$description][$propertyName][$canAccessProperty] = new CalledOnTypeUnresolvedPropertyPrototypeReflection($property, $resolvedClassReflection, \true, $this); } /** * @deprecated Not in use anymore. */ public function getPropertyWithoutTransformingStatic(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection { $classReflection = $this->getNakedClassReflection(); if ($classReflection === null) { throw new ClassNotFoundException($this->className); } if (!$classReflection->hasProperty($propertyName)) { $classReflection = $this->getClassReflection(); } if ($classReflection === null) { throw new ClassNotFoundException($this->className); } return $classReflection->getProperty($propertyName, $scope); } /** * @return string[] */ public function getReferencedClasses() : array { return [$this->className]; } public function getObjectClassNames() : array { if ($this->className === '') { return []; } return [$this->className]; } public function getObjectClassReflections() : array { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return []; } return [$classReflection]; } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof \PHPStan\Type\StaticType) { return $this->checkSubclassAcceptability($type->getClassName()); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } if ($type instanceof \PHPStan\Type\ClosureType) { return new \PHPStan\Type\AcceptsResult($this->isInstanceOf(Closure::class), []); } if ($type instanceof \PHPStan\Type\ObjectWithoutClassType) { return \PHPStan\Type\AcceptsResult::createMaybe(); } $thatClassNames = $type->getObjectClassNames(); if (count($thatClassNames) > 1) { throw new ShouldNotHappenException(); } if ($thatClassNames === []) { return \PHPStan\Type\AcceptsResult::createNo(); } return $this->checkSubclassAcceptability($thatClassNames[0]); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { $thatClassNames = $type->getObjectClassNames(); if (!$type instanceof \PHPStan\Type\CompoundType && $thatClassNames === [] && !$type instanceof \PHPStan\Type\ObjectWithoutClassType) { return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } $thisDescription = $this->describeCache(); if ($type instanceof self) { $description = $type->describeCache(); } else { $description = $type->describe(\PHPStan\Type\VerbosityLevel::cache()); } if (isset(self::$superTypes[$thisDescription][$description])) { return self::$superTypes[$thisDescription][$description]; } if ($type instanceof \PHPStan\Type\CompoundType) { return self::$superTypes[$thisDescription][$description] = $type->isSubTypeOfWithReason($this); } if ($type instanceof \PHPStan\Type\ClosureType) { return self::$superTypes[$thisDescription][$description] = new \PHPStan\Type\IsSuperTypeOfResult($this->isInstanceOf(Closure::class), []); } if ($type instanceof \PHPStan\Type\ObjectWithoutClassType) { if ($type->getSubtractedType() !== null) { $isSuperType = $type->getSubtractedType()->isSuperTypeOf($this); if ($isSuperType->yes()) { return self::$superTypes[$thisDescription][$description] = \PHPStan\Type\IsSuperTypeOfResult::createNo(); } } return self::$superTypes[$thisDescription][$description] = \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } $transformResult = static function (\PHPStan\Type\IsSuperTypeOfResult $result) { return $result; }; if ($this->subtractedType !== null) { $isSuperType = $this->subtractedType->isSuperTypeOfWithReason($type); if ($isSuperType->yes()) { return self::$superTypes[$thisDescription][$description] = \PHPStan\Type\IsSuperTypeOfResult::createNo(); } if ($isSuperType->maybe()) { $transformResult = static function (\PHPStan\Type\IsSuperTypeOfResult $result) { return $result->and(\PHPStan\Type\IsSuperTypeOfResult::createMaybe()); }; } } if ($type instanceof \PHPStan\Type\SubtractableType && $type->getSubtractedType() !== null) { $isSuperType = $type->getSubtractedType()->isSuperTypeOfWithReason($this); if ($isSuperType->yes()) { return self::$superTypes[$thisDescription][$description] = \PHPStan\Type\IsSuperTypeOfResult::createNo(); } } $thisClassName = $this->className; if (count($thatClassNames) > 1) { throw new ShouldNotHappenException(); } if ($thatClassNames[0] === $thisClassName) { return $transformResult(\PHPStan\Type\IsSuperTypeOfResult::createYes()); } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); $thisClassReflection = $this->getClassReflection(); if ($thisClassReflection === null || !$reflectionProvider->hasClass($thatClassNames[0])) { return self::$superTypes[$thisDescription][$description] = \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } $thatClassReflection = $reflectionProvider->getClass($thatClassNames[0]); if ($thisClassReflection->isTrait() || $thatClassReflection->isTrait()) { return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } if ($thisClassReflection->getName() === $thatClassReflection->getName()) { return self::$superTypes[$thisDescription][$description] = $transformResult(\PHPStan\Type\IsSuperTypeOfResult::createYes()); } if ($thatClassReflection->isSubclassOf($thisClassName)) { return self::$superTypes[$thisDescription][$description] = $transformResult(\PHPStan\Type\IsSuperTypeOfResult::createYes()); } if ($thisClassReflection->isSubclassOf($thatClassNames[0])) { return self::$superTypes[$thisDescription][$description] = \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } if ($thisClassReflection->isInterface() && !$thatClassReflection->getNativeReflection()->isFinal()) { return self::$superTypes[$thisDescription][$description] = \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } if ($thatClassReflection->isInterface() && !$thisClassReflection->getNativeReflection()->isFinal()) { return self::$superTypes[$thisDescription][$description] = \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } return self::$superTypes[$thisDescription][$description] = \PHPStan\Type\IsSuperTypeOfResult::createNo(); } public function equals(\PHPStan\Type\Type $type) : bool { if (!$type instanceof self) { return \false; } if ($type instanceof EnumCaseObjectType) { return \false; } if ($this->className !== $type->className) { return \false; } if ($this->subtractedType === null) { return $type->subtractedType === null; } if ($type->subtractedType === null) { return \false; } return $this->subtractedType->equals($type->subtractedType); } private function checkSubclassAcceptability(string $thatClass) : \PHPStan\Type\AcceptsResult { if ($this->className === $thatClass) { return \PHPStan\Type\AcceptsResult::createYes(); } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if ($this->getClassReflection() === null || !$reflectionProvider->hasClass($thatClass)) { return \PHPStan\Type\AcceptsResult::createNo(); } $thisReflection = $this->getClassReflection(); $thatReflection = $reflectionProvider->getClass($thatClass); if ($thisReflection->getName() === $thatReflection->getName()) { // class alias return \PHPStan\Type\AcceptsResult::createYes(); } if ($thisReflection->isInterface() && $thatReflection->isInterface()) { return \PHPStan\Type\AcceptsResult::createFromBoolean($thatReflection->implementsInterface($thisReflection->getName())); } return \PHPStan\Type\AcceptsResult::createFromBoolean($thatReflection->isSubclassOf($thisReflection->getName())); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { $preciseNameCallback = function () : string { $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if (!$reflectionProvider->hasClass($this->className)) { return $this->className; } return $reflectionProvider->getClassName($this->className); }; $preciseWithSubtracted = function () use($level) : string { $description = $this->className; if ($this->subtractedType !== null) { $description .= $this->subtractedType instanceof \PHPStan\Type\UnionType ? sprintf('~(%s)', $this->subtractedType->describe($level)) : sprintf('~%s', $this->subtractedType->describe($level)); } return $description; }; return $level->handle($preciseNameCallback, $preciseNameCallback, $preciseWithSubtracted, function () use($preciseWithSubtracted) : string { $reflection = $this->classReflection; $line = ''; if ($reflection !== null) { $line .= '-'; $line .= (string) $reflection->getNativeReflection()->getStartLine(); $line .= '-'; } return $preciseWithSubtracted() . '-' . static::class . '-' . $line . $this->describeAdditionalCacheKey(); }); } protected function describeAdditionalCacheKey() : string { return ''; } private function describeCache() : string { if ($this->cachedDescription !== null) { return $this->cachedDescription; } if (static::class !== self::class) { return $this->cachedDescription = $this->describe(\PHPStan\Type\VerbosityLevel::cache()); } $description = $this->className; if ($this instanceof GenericObjectType) { $description .= '<'; $typeDescriptions = []; foreach ($this->getTypes() as $type) { $typeDescriptions[] = $type->describe(\PHPStan\Type\VerbosityLevel::cache()); } $description .= '<' . implode(', ', $typeDescriptions) . '>'; } if ($this->subtractedType !== null) { $description .= $this->subtractedType instanceof \PHPStan\Type\UnionType ? sprintf('~(%s)', $this->subtractedType->describe(\PHPStan\Type\VerbosityLevel::cache())) : sprintf('~%s', $this->subtractedType->describe(\PHPStan\Type\VerbosityLevel::cache())); } $reflection = $this->classReflection; if ($reflection !== null) { $description .= '-'; $description .= (string) $reflection->getNativeReflection()->getStartLine(); $description .= '-'; } return $this->cachedDescription = $description; } public function toNumber() : \PHPStan\Type\Type { if ($this->isInstanceOf('SimpleXMLElement')->yes()) { return new \PHPStan\Type\UnionType([new \PHPStan\Type\FloatType(), new \PHPStan\Type\IntegerType()]); } return new \PHPStan\Type\ErrorType(); } public function toAbsoluteNumber() : \PHPStan\Type\Type { return $this->toNumber()->toAbsoluteNumber(); } public function toInteger() : \PHPStan\Type\Type { if ($this->isInstanceOf('SimpleXMLElement')->yes()) { return new \PHPStan\Type\IntegerType(); } if (in_array($this->getClassName(), ['CurlHandle', 'CurlMultiHandle'], \true)) { return new \PHPStan\Type\IntegerType(); } return new \PHPStan\Type\ErrorType(); } public function toFloat() : \PHPStan\Type\Type { if ($this->isInstanceOf('SimpleXMLElement')->yes()) { return new \PHPStan\Type\FloatType(); } return new \PHPStan\Type\ErrorType(); } public function toString() : \PHPStan\Type\Type { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return new \PHPStan\Type\ErrorType(); } if ($classReflection->hasNativeMethod('__toString')) { return $this->getMethod('__toString', new OutOfClassScope())->getOnlyVariant()->getReturnType(); } return new \PHPStan\Type\ErrorType(); } public function toArray() : \PHPStan\Type\Type { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType(), new \PHPStan\Type\MixedType()); } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if (!$classReflection->getNativeReflection()->isUserDefined() || $classReflection->is(ArrayObject::class) || UniversalObjectCratesClassReflectionExtension::isUniversalObjectCrate($reflectionProvider, Broker::getInstance()->getUniversalObjectCratesClasses(), $classReflection)) { return new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType(), new \PHPStan\Type\MixedType()); } $arrayKeys = []; $arrayValues = []; $isFinal = $classReflection->isFinal(); do { foreach ($classReflection->getNativeReflection()->getProperties() as $nativeProperty) { if ($nativeProperty->isStatic()) { continue; } $declaringClass = $reflectionProvider->getClass($nativeProperty->getDeclaringClass()->getName()); $property = $declaringClass->getNativeProperty($nativeProperty->getName()); $keyName = $nativeProperty->getName(); if ($nativeProperty->isPrivate()) { $keyName = sprintf("\x00%s\x00%s", $declaringClass->getName(), $keyName); } elseif ($nativeProperty->isProtected()) { $keyName = sprintf("\x00*\x00%s", $keyName); } $arrayKeys[] = new ConstantStringType($keyName); $arrayValues[] = $property->getReadableType(); } $classReflection = $classReflection->getParentClass(); } while ($classReflection !== null); if (!$isFinal && count($arrayKeys) === 0) { return new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType(), new \PHPStan\Type\MixedType()); } return new ConstantArrayType($arrayKeys, $arrayValues); } public function toArrayKey() : \PHPStan\Type\Type { return $this->toString(); } public function toBoolean() : \PHPStan\Type\BooleanType { if ($this->isInstanceOf('SimpleXMLElement')->yes()) { return new \PHPStan\Type\BooleanType(); } return new ConstantBooleanType(\true); } public function isObject() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isEnum() : TrinaryLogic { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createFromBoolean($classReflection->isEnum()); } public function canAccessProperties() : TrinaryLogic { return TrinaryLogic::createYes(); } public function canCallMethods() : TrinaryLogic { if (strtolower($this->className) === 'stdclass') { return TrinaryLogic::createNo(); } return TrinaryLogic::createYes(); } public function hasMethod(string $methodName) : TrinaryLogic { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return TrinaryLogic::createMaybe(); } if ($classReflection->hasMethod($methodName)) { return TrinaryLogic::createYes(); } if ($classReflection->isFinal()) { return TrinaryLogic::createNo(); } return TrinaryLogic::createMaybe(); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { return $this->getUnresolvedMethodPrototype($methodName, $scope)->getTransformedMethod(); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { if (!$scope->isInClass()) { $canCallMethod = 'no'; } else { $canCallMethod = $scope->getClassReflection()->getName(); } $description = $this->describeCache(); if (isset(self::$methods[$description][$methodName][$canCallMethod])) { return self::$methods[$description][$methodName][$canCallMethod]; } $nakedClassReflection = $this->getNakedClassReflection(); if ($nakedClassReflection === null) { throw new ClassNotFoundException($this->className); } if (!$nakedClassReflection->hasNativeMethod($methodName)) { $nakedClassReflection = $this->getClassReflection(); } if ($nakedClassReflection === null) { throw new ClassNotFoundException($this->className); } $method = $nakedClassReflection->getMethod($methodName, $scope); $ancestor = $this->getAncestorWithClassName($method->getDeclaringClass()->getName()); $resolvedClassReflection = null; if ($ancestor !== null) { $resolvedClassReflection = $ancestor->getClassReflection(); if ($ancestor !== $this) { $method = $ancestor->getUnresolvedMethodPrototype($methodName, $scope)->getNakedMethod(); } } if ($resolvedClassReflection === null) { $resolvedClassReflection = $method->getDeclaringClass(); } return self::$methods[$description][$methodName][$canCallMethod] = new CalledOnTypeUnresolvedMethodPrototypeReflection($method, $resolvedClassReflection, \true, $this); } public function canAccessConstants() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasConstant(string $constantName) : TrinaryLogic { $class = $this->getClassReflection(); if ($class === null) { return TrinaryLogic::createNo(); } return TrinaryLogic::createFromBoolean($class->hasConstant($constantName)); } public function getConstant(string $constantName) : ConstantReflection { $class = $this->getClassReflection(); if ($class === null) { throw new ClassNotFoundException($this->className); } return $class->getConstant($constantName); } public function getTemplateType(string $ancestorClassName, string $templateTypeName) : \PHPStan\Type\Type { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return new \PHPStan\Type\ErrorType(); } $ancestorClassReflection = $classReflection->getAncestorWithClassName($ancestorClassName); if ($ancestorClassReflection === null) { return new \PHPStan\Type\ErrorType(); } $activeTemplateTypeMap = $ancestorClassReflection->getPossiblyIncompleteActiveTemplateTypeMap(); $type = $activeTemplateTypeMap->getType($templateTypeName); if ($type === null) { return new \PHPStan\Type\ErrorType(); } if ($type instanceof \PHPStan\Type\ErrorType) { $templateTypeMap = $ancestorClassReflection->getTemplateTypeMap(); $templateType = $templateTypeMap->getType($templateTypeName); if ($templateType === null) { return $type; } $bound = TemplateTypeHelper::resolveToBounds($templateType); if ($bound instanceof \PHPStan\Type\MixedType && $bound->isExplicitMixed()) { return new \PHPStan\Type\MixedType(\false); } return TemplateTypeHelper::resolveToDefaults($templateType); } return $type; } public function getConstantStrings() : array { return []; } public function isIterable() : TrinaryLogic { return $this->isInstanceOf(Traversable::class); } public function isIterableAtLeastOnce() : TrinaryLogic { return $this->isInstanceOf(Traversable::class)->and(TrinaryLogic::createMaybe()); } public function getArraySize() : \PHPStan\Type\Type { if ($this->isInstanceOf(Countable::class)->no()) { return new \PHPStan\Type\ErrorType(); } return \PHPStan\Type\IntegerRangeType::fromInterval(0, null); } public function getIterableKeyType() : \PHPStan\Type\Type { $isTraversable = \false; if ($this->isInstanceOf(IteratorAggregate::class)->yes()) { $keyType = \PHPStan\Type\RecursionGuard::run($this, function () : \PHPStan\Type\Type { return $this->getMethod('getIterator', new OutOfClassScope())->getOnlyVariant()->getReturnType()->getIterableKeyType(); }); $isTraversable = \true; if (!$keyType instanceof \PHPStan\Type\MixedType || $keyType->isExplicitMixed()) { return $keyType; } } $extraOffsetAccessible = $this->isExtraOffsetAccessibleClass()->yes(); if (!$extraOffsetAccessible && $this->isInstanceOf(Traversable::class)->yes()) { $isTraversable = \true; $tKey = $this->getTemplateType(Traversable::class, 'TKey'); if (!$tKey instanceof \PHPStan\Type\ErrorType) { if (!$tKey instanceof \PHPStan\Type\MixedType || $tKey->isExplicitMixed()) { return $tKey; } } } if ($this->isInstanceOf(Iterator::class)->yes()) { return \PHPStan\Type\RecursionGuard::run($this, function () : \PHPStan\Type\Type { return $this->getMethod('key', new OutOfClassScope())->getOnlyVariant()->getReturnType(); }); } if ($extraOffsetAccessible) { return new \PHPStan\Type\MixedType(\true); } if ($isTraversable) { return new \PHPStan\Type\MixedType(); } return new \PHPStan\Type\ErrorType(); } public function getFirstIterableKeyType() : \PHPStan\Type\Type { return $this->getIterableKeyType(); } public function getLastIterableKeyType() : \PHPStan\Type\Type { return $this->getIterableKeyType(); } public function getIterableValueType() : \PHPStan\Type\Type { $isTraversable = \false; if ($this->isInstanceOf(IteratorAggregate::class)->yes()) { $valueType = \PHPStan\Type\RecursionGuard::run($this, function () : \PHPStan\Type\Type { return $this->getMethod('getIterator', new OutOfClassScope())->getOnlyVariant()->getReturnType()->getIterableValueType(); }); $isTraversable = \true; if (!$valueType instanceof \PHPStan\Type\MixedType || $valueType->isExplicitMixed()) { return $valueType; } } $extraOffsetAccessible = $this->isExtraOffsetAccessibleClass()->yes(); if (!$extraOffsetAccessible && $this->isInstanceOf(Traversable::class)->yes()) { $isTraversable = \true; $tValue = $this->getTemplateType(Traversable::class, 'TValue'); if (!$tValue instanceof \PHPStan\Type\ErrorType) { if (!$tValue instanceof \PHPStan\Type\MixedType || $tValue->isExplicitMixed()) { return $tValue; } } } if ($this->isInstanceOf(Iterator::class)->yes()) { return \PHPStan\Type\RecursionGuard::run($this, function () : \PHPStan\Type\Type { return $this->getMethod('current', new OutOfClassScope())->getOnlyVariant()->getReturnType(); }); } if ($extraOffsetAccessible) { return new \PHPStan\Type\MixedType(\true); } if ($isTraversable) { return new \PHPStan\Type\MixedType(); } return new \PHPStan\Type\ErrorType(); } public function getFirstIterableValueType() : \PHPStan\Type\Type { return $this->getIterableValueType(); } public function getLastIterableValueType() : \PHPStan\Type\Type { return $this->getIterableValueType(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return $this; } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createNo(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { if ($type->isTrue()->yes()) { return new ConstantBooleanType(\true); } return $type->isFalse()->yes() ? new ConstantBooleanType(\false) : new \PHPStan\Type\BooleanType(); } private function isExtraOffsetAccessibleClass() : TrinaryLogic { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return TrinaryLogic::createMaybe(); } foreach (self::EXTRA_OFFSET_CLASSES as $extraOffsetClass) { if ($classReflection->getName() === $extraOffsetClass) { return TrinaryLogic::createYes(); } if ($classReflection->isSubclassOf($extraOffsetClass)) { return TrinaryLogic::createYes(); } } if ($classReflection->isInterface()) { return TrinaryLogic::createMaybe(); } if ($classReflection->isFinal()) { return TrinaryLogic::createNo(); } return TrinaryLogic::createMaybe(); } public function isOffsetAccessible() : TrinaryLogic { return $this->isInstanceOf(ArrayAccess::class)->or($this->isExtraOffsetAccessibleClass()); } public function isOffsetAccessLegal() : TrinaryLogic { return $this->isOffsetAccessible(); } public function hasOffsetValueType(\PHPStan\Type\Type $offsetType) : TrinaryLogic { if ($this->isInstanceOf(ArrayAccess::class)->yes()) { $acceptedOffsetType = \PHPStan\Type\RecursionGuard::run($this, function () : \PHPStan\Type\Type { $parameters = $this->getMethod('offsetSet', new OutOfClassScope())->getOnlyVariant()->getParameters(); if (count($parameters) < 2) { throw new ShouldNotHappenException(sprintf('Method %s::%s() has less than 2 parameters.', $this->className, 'offsetSet')); } $offsetParameter = $parameters[0]; return $offsetParameter->getType(); }); if ($acceptedOffsetType->isSuperTypeOf($offsetType)->no()) { return TrinaryLogic::createNo(); } return TrinaryLogic::createMaybe(); } return $this->isExtraOffsetAccessibleClass()->and(TrinaryLogic::createMaybe()); } public function getOffsetValueType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { if (!$this->isExtraOffsetAccessibleClass()->no()) { return new \PHPStan\Type\MixedType(); } if ($this->isInstanceOf(ArrayAccess::class)->yes()) { return \PHPStan\Type\RecursionGuard::run($this, function () : \PHPStan\Type\Type { return $this->getMethod('offsetGet', new OutOfClassScope())->getOnlyVariant()->getReturnType(); }); } return new \PHPStan\Type\ErrorType(); } public function setOffsetValueType(?\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType, bool $unionValues = \true) : \PHPStan\Type\Type { if ($this->isOffsetAccessible()->no()) { return new \PHPStan\Type\ErrorType(); } if ($this->isInstanceOf(ArrayAccess::class)->yes()) { $acceptedValueType = new \PHPStan\Type\NeverType(); $acceptedOffsetType = \PHPStan\Type\RecursionGuard::run($this, function () use(&$acceptedValueType) : \PHPStan\Type\Type { $parameters = $this->getMethod('offsetSet', new OutOfClassScope())->getOnlyVariant()->getParameters(); if (count($parameters) < 2) { throw new ShouldNotHappenException(sprintf('Method %s::%s() has less than 2 parameters.', $this->className, 'offsetSet')); } $offsetParameter = $parameters[0]; $acceptedValueType = $parameters[1]->getType(); return $offsetParameter->getType(); }); if ($offsetType === null) { $offsetType = new \PHPStan\Type\NullType(); } if (!$offsetType instanceof \PHPStan\Type\MixedType && !$acceptedOffsetType->isSuperTypeOf($offsetType)->yes() || !$valueType instanceof \PHPStan\Type\MixedType && !$acceptedValueType->isSuperTypeOf($valueType)->yes()) { return new \PHPStan\Type\ErrorType(); } } // in the future we may return intersection of $this and OffsetAccessibleType() return $this; } public function setExistingOffsetValueType(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { if ($this->isOffsetAccessible()->no()) { return new \PHPStan\Type\ErrorType(); } return $this; } public function unsetOffset(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { if ($this->isOffsetAccessible()->no()) { return new \PHPStan\Type\ErrorType(); } return $this; } public function getEnumCases() : array { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return []; } if (!$classReflection->isEnum()) { return []; } $cacheKey = $this->describeCache(); if (array_key_exists($cacheKey, self::$enumCases)) { return self::$enumCases[$cacheKey]; } $className = $classReflection->getName(); if ($this->subtractedType !== null) { $subtractedEnumCaseNames = []; foreach ($this->subtractedType->getEnumCases() as $subtractedCase) { $subtractedEnumCaseNames[$subtractedCase->getEnumCaseName()] = \true; } $cases = []; foreach ($classReflection->getEnumCases() as $enumCase) { if (array_key_exists($enumCase->getName(), $subtractedEnumCaseNames)) { continue; } $cases[] = new EnumCaseObjectType($className, $enumCase->getName(), $classReflection); } } else { $cases = []; foreach ($classReflection->getEnumCases() as $enumCase) { $cases[] = new EnumCaseObjectType($className, $enumCase->getName(), $classReflection); } } return self::$enumCases[$cacheKey] = $cases; } public function isCallable() : TrinaryLogic { $parametersAcceptors = \PHPStan\Type\RecursionGuard::run($this, function () { return $this->findCallableParametersAcceptors(); }); if ($parametersAcceptors === null) { return TrinaryLogic::createNo(); } if ($parametersAcceptors instanceof \PHPStan\Type\ErrorType) { return TrinaryLogic::createNo(); } if (count($parametersAcceptors) === 1 && $parametersAcceptors[0] instanceof TrivialParametersAcceptor) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createYes(); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { if ($this->className === Closure::class) { return [new TrivialParametersAcceptor('Closure')]; } $parametersAcceptors = $this->findCallableParametersAcceptors(); if ($parametersAcceptors === null) { throw new ShouldNotHappenException(); } return $parametersAcceptors; } /** * @return CallableParametersAcceptor[]|null */ private function findCallableParametersAcceptors() : ?array { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return [new TrivialParametersAcceptor()]; } if ($classReflection->hasNativeMethod('__invoke')) { $method = $this->getMethod('__invoke', new OutOfClassScope()); return FunctionCallableVariant::createFromVariants($method, $method->getVariants()); } if (!$classReflection->getNativeReflection()->isFinal()) { return [new TrivialParametersAcceptor()]; } return null; } public function isCloneable() : TrinaryLogic { return TrinaryLogic::createYes(); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['className'], $properties['subtractedType'] ?? null); } public function isInstanceOf(string $className) : TrinaryLogic { $classReflection = $this->getClassReflection(); if ($classReflection === null) { return TrinaryLogic::createMaybe(); } if ($classReflection->getName() === $className || $classReflection->isSubclassOf($className)) { return TrinaryLogic::createYes(); } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if ($reflectionProvider->hasClass($className)) { $thatClassReflection = $reflectionProvider->getClass($className); if ($thatClassReflection->isFinal()) { return TrinaryLogic::createNo(); } } if ($classReflection->isInterface()) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createNo(); } public function subtract(\PHPStan\Type\Type $type) : \PHPStan\Type\Type { if ($this->subtractedType !== null) { $type = \PHPStan\Type\TypeCombinator::union($this->subtractedType, $type); } return $this->changeSubtractedType($type); } public function getTypeWithoutSubtractedType() : \PHPStan\Type\Type { return $this->changeSubtractedType(null); } public function changeSubtractedType(?\PHPStan\Type\Type $subtractedType) : \PHPStan\Type\Type { if ($subtractedType !== null) { $classReflection = $this->getClassReflection(); $allowedSubTypes = $classReflection !== null ? $classReflection->getAllowedSubTypes() : null; if ($allowedSubTypes !== null) { $preciseVerbosity = \PHPStan\Type\VerbosityLevel::precise(); $originalAllowedSubTypes = $allowedSubTypes; $subtractedSubTypes = []; $subtractedTypes = \PHPStan\Type\TypeUtils::flattenTypes($subtractedType); foreach ($subtractedTypes as $subType) { foreach ($allowedSubTypes as $key => $allowedSubType) { if ($subType->equals($allowedSubType)) { $description = $allowedSubType->describe($preciseVerbosity); $subtractedSubTypes[$description] = $subType; unset($allowedSubTypes[$key]); continue 2; } } return new self($this->className, $subtractedType); } if (count($allowedSubTypes) === 1) { return array_values($allowedSubTypes)[0]; } $subtractedSubTypes = array_values($subtractedSubTypes); $subtractedSubTypesCount = count($subtractedSubTypes); if ($subtractedSubTypesCount === count($originalAllowedSubTypes)) { return new \PHPStan\Type\NeverType(); } if ($subtractedSubTypesCount === 0) { return new self($this->className); } if ($subtractedSubTypesCount === 1) { return new self($this->className, $subtractedSubTypes[0]); } return new self($this->className, new \PHPStan\Type\UnionType($subtractedSubTypes)); } } if ($this->subtractedType === null && $subtractedType === null) { return $this; } return new self($this->className, $subtractedType); } public function getSubtractedType() : ?\PHPStan\Type\Type { return $this->subtractedType; } public function traverse(callable $cb) : \PHPStan\Type\Type { $subtractedType = $this->subtractedType !== null ? $cb($this->subtractedType) : null; if ($subtractedType !== $this->subtractedType) { return new self($this->className, $subtractedType); } return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if ($this->subtractedType === null) { return $this; } return new self($this->className); } public function getNakedClassReflection() : ?ClassReflection { if ($this->classReflection !== null) { return $this->classReflection; } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if (!$reflectionProvider->hasClass($this->className)) { return null; } return $reflectionProvider->getClass($this->className); } public function getClassReflection() : ?ClassReflection { if ($this->classReflection !== null) { return $this->classReflection; } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if (!$reflectionProvider->hasClass($this->className)) { return null; } $classReflection = $reflectionProvider->getClass($this->className); if ($classReflection->isGeneric()) { return $classReflection->withTypes(array_values($classReflection->getTemplateTypeMap()->map(static function () : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); })->getTypes())); } return $classReflection; } /** * @return self|null */ public function getAncestorWithClassName(string $className) : ?\PHPStan\Type\TypeWithClassName { if ($this->className === $className) { return $this; } if ($this->classReflection !== null && $className === $this->classReflection->getName()) { return $this; } if (array_key_exists($className, $this->currentAncestors)) { return $this->currentAncestors[$className]; } $description = $this->describeCache(); if (array_key_exists($description, self::$ancestors) && array_key_exists($className, self::$ancestors[$description])) { return self::$ancestors[$description][$className]; } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if (!$reflectionProvider->hasClass($className)) { return self::$ancestors[$description][$className] = $this->currentAncestors[$className] = null; } $theirReflection = $reflectionProvider->getClass($className); $thisReflection = $this->getClassReflection(); if ($thisReflection === null) { return self::$ancestors[$description][$className] = $this->currentAncestors[$className] = null; } if ($theirReflection->getName() === $thisReflection->getName()) { return self::$ancestors[$description][$className] = $this->currentAncestors[$className] = $this; } foreach ($this->getInterfaces() as $interface) { $ancestor = $interface->getAncestorWithClassName($className); if ($ancestor !== null) { return self::$ancestors[$description][$className] = $this->currentAncestors[$className] = $ancestor; } } $parent = $this->getParent(); if ($parent !== null) { $ancestor = $parent->getAncestorWithClassName($className); if ($ancestor !== null) { return self::$ancestors[$description][$className] = $this->currentAncestors[$className] = $ancestor; } } return self::$ancestors[$description][$className] = $this->currentAncestors[$className] = null; } private function getParent() : ?\PHPStan\Type\ObjectType { if ($this->cachedParent !== null) { return $this->cachedParent; } $thisReflection = $this->getClassReflection(); if ($thisReflection === null) { return null; } $parentReflection = $thisReflection->getParentClass(); if ($parentReflection === null) { return null; } return $this->cachedParent = self::createFromReflection($parentReflection); } /** @return ObjectType[] */ private function getInterfaces() : array { if ($this->cachedInterfaces !== null) { return $this->cachedInterfaces; } $thisReflection = $this->getClassReflection(); if ($thisReflection === null) { return $this->cachedInterfaces = []; } return $this->cachedInterfaces = array_map(static function (ClassReflection $interfaceReflection) : self { return self::createFromReflection($interfaceReflection); }, $thisReflection->getInterfaces()); } public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type { if ($this->getClassName() === DateTimeInterface::class) { if ($typeToRemove instanceof \PHPStan\Type\ObjectType && $typeToRemove->getClassName() === DateTimeImmutable::class) { return new \PHPStan\Type\ObjectType(DateTime::class); } if ($typeToRemove instanceof \PHPStan\Type\ObjectType && $typeToRemove->getClassName() === DateTime::class) { return new \PHPStan\Type\ObjectType(DateTimeImmutable::class); } } if ($this->getClassName() === Throwable::class) { if ($typeToRemove instanceof \PHPStan\Type\ObjectType && $typeToRemove->getClassName() === Error::class) { return new \PHPStan\Type\ObjectType(Exception::class); // phpcs:ignore SlevomatCodingStandard.Exceptions.ReferenceThrowableOnly.ReferencedGeneralException } if ($typeToRemove instanceof \PHPStan\Type\ObjectType && $typeToRemove->getClassName() === Exception::class) { // phpcs:ignore SlevomatCodingStandard.Exceptions.ReferenceThrowableOnly.ReferencedGeneralException return new \PHPStan\Type\ObjectType(Error::class); } } if ($this->isSuperTypeOf($typeToRemove)->yes()) { return $this->subtract($typeToRemove); } return null; } public function getFiniteTypes() : array { return $this->getEnumCases(); } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { $object = new \PHPStan\Type\ObjectWithoutClassType(); if (!$exponent instanceof \PHPStan\Type\NeverType && !$object->isSuperTypeOf($this)->no() && !$object->isSuperTypeOf($exponent)->no()) { return \PHPStan\Type\TypeCombinator::union($this, $exponent); } return new \PHPStan\Type\ErrorType(); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode($this->getClassName()); } } parameterName = $parameterName; $this->target = $target; $this->if = $if; $this->else = $else; $this->negated = $negated; } public function getParameterName() : string { return $this->parameterName; } public function getTarget() : \PHPStan\Type\Type { return $this->target; } public function getIf() : \PHPStan\Type\Type { return $this->if; } public function getElse() : \PHPStan\Type\Type { return $this->else; } public function isNegated() : bool { return $this->negated; } public function changeParameterName(string $parameterName) : self { return new self($parameterName, $this->target, $this->if, $this->else, $this->negated); } public function toConditional(\PHPStan\Type\Type $subject) : \PHPStan\Type\Type { return new \PHPStan\Type\ConditionalType($subject, $this->target, $this->if, $this->else, $this->negated); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self) { return $this->if->isSuperTypeOfWithReason($type->if)->and($this->else->isSuperTypeOfWithReason($type->else)); } return $this->isSuperTypeOfDefault($type); } public function getReferencedClasses() : array { return array_merge($this->target->getReferencedClasses(), $this->if->getReferencedClasses(), $this->else->getReferencedClasses()); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { return array_merge($this->target->getReferencedTemplateTypes($positionVariance), $this->if->getReferencedTemplateTypes($positionVariance), $this->else->getReferencedTemplateTypes($positionVariance)); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self && $this->parameterName === $type->parameterName && $this->target->equals($type->target) && $this->if->equals($type->if) && $this->else->equals($type->else); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return sprintf('(%s %s %s ? %s : %s)', $this->parameterName, $this->negated ? 'is not' : 'is', $this->target->describe($level), $this->if->describe($level), $this->else->describe($level)); } public function isResolvable() : bool { return \false; } protected function getResult() : \PHPStan\Type\Type { return \PHPStan\Type\TypeCombinator::union($this->if, $this->else); } public function traverse(callable $cb) : \PHPStan\Type\Type { $target = $cb($this->target); $if = $cb($this->if); $else = $cb($this->else); if ($this->target === $target && $this->if === $if && $this->else === $else) { return $this; } return new self($this->parameterName, $target, $if, $else, $this->negated); } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if (!$right instanceof self) { return $this; } $target = $cb($this->target, $right->target); $if = $cb($this->if, $right->if); $else = $cb($this->else, $right->else); if ($this->target === $target && $this->if === $if && $this->else === $else) { return $this; } return new self($this->parameterName, $target, $if, $else, $this->negated); } public function toPhpDocNode() : TypeNode { return new ConditionalTypeForParameterNode($this->parameterName, $this->target->toPhpDocNode(), $this->if->toPhpDocNode(), $this->else->toPhpDocNode(), $this->negated); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['parameterName'], $properties['target'], $properties['if'], $properties['else'], $properties['negated']); } } type = $type; } public function getDeclaringClass() : ClassReflection { $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); return $reflectionProvider->getClass(stdClass::class); } public function isStatic() : bool { return \false; } public function isPrivate() : bool { return \false; } public function isPublic() : bool { return \true; } public function getDocComment() : ?string { return null; } public function getReadableType() : \PHPStan\Type\Type { return $this->type; } public function getWritableType() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function canChangeTypeAfterAssignment() : bool { return \false; } public function isReadable() : bool { return \true; } public function isWritable() : bool { return \false; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDeprecatedDescription() : ?string { return null; } public function isInternal() : TrinaryLogic { return TrinaryLogic::createNo(); } } castsNumbersToStringsOnLooseComparison()) { $isNumber = new \PHPStan\Type\UnionType([new \PHPStan\Type\IntegerType(), new \PHPStan\Type\FloatType()]); if ($leftType->isString()->yes() && $leftType->isNumericString()->no() && $isNumber->isSuperTypeOf($rightType)->yes()) { $stringValue = (string) $rightType->getValue(); return new ConstantBooleanType($stringValue === $leftType->getValue()); } if ($rightType->isString()->yes() && $rightType->isNumericString()->no() && $isNumber->isSuperTypeOf($leftType)->yes()) { $stringValue = (string) $leftType->getValue(); return new ConstantBooleanType($stringValue === $rightType->getValue()); } } else { if ($leftType->isString()->yes() && $leftType->isNumericString()->no() && $rightType->isFloat()->yes()) { $numericPart = (float) $leftType->getValue(); return new ConstantBooleanType($numericPart === $rightType->getValue()); } if ($rightType->isString()->yes() && $rightType->isNumericString()->no() && $leftType->isFloat()->yes()) { $numericPart = (float) $rightType->getValue(); return new ConstantBooleanType($numericPart === $leftType->getValue()); } if ($leftType->isString()->yes() && $leftType->isNumericString()->no() && $rightType->isInteger()->yes()) { $numericPart = (int) $leftType->getValue(); return new ConstantBooleanType($numericPart === $rightType->getValue()); } if ($rightType->isString()->yes() && $rightType->isNumericString()->no() && $leftType->isInteger()->yes()) { $numericPart = (int) $rightType->getValue(); return new ConstantBooleanType($numericPart === $leftType->getValue()); } } // @phpstan-ignore equal.notAllowed return new ConstantBooleanType($leftType->getValue() == $rightType->getValue()); // phpcs:ignore } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } $isArray = $type->isArray(); $isList = $type->isList(); return new AcceptsResult($isArray->and($isList), []); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($this->equals($type)) { return IsSuperTypeOfResult::createYes(); } if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } return new IsSuperTypeOfResult($type->isArray()->and($type->isList()), []); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } return (new IsSuperTypeOfResult($otherType->isArray()->and($otherType->isList()), []))->and($otherType instanceof self ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createMaybe()); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self; } public function describe(VerbosityLevel $level) : string { return 'list'; } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { return $this->getIterableKeyType()->isSuperTypeOf($offsetType)->and(TrinaryLogic::createMaybe()); } public function getOffsetValueType(Type $offsetType) : Type { return new MixedType(); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { if ($offsetType === null || (new ConstantIntegerType(0))->isSuperTypeOf($offsetType)->yes()) { return $this; } return new ErrorType(); } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { if ((new ConstantIntegerType(0))->isSuperTypeOf($offsetType)->yes()) { return $this; } return new ErrorType(); } public function unsetOffset(Type $offsetType) : Type { if ($this->hasOffsetValueType($offsetType)->no()) { return $this; } return new ErrorType(); } public function getKeysArray() : Type { return $this; } public function getValuesArray() : Type { return $this; } public function chunkArray(Type $lengthType, TrinaryLogic $preserveKeys) : Type { return $this; } public function fillKeysArray(Type $valueType) : Type { return new MixedType(); } public function flipArray() : Type { return new MixedType(); } public function intersectKeyArray(Type $otherArraysType) : Type { if ($otherArraysType->isList()->yes()) { return $this; } return new MixedType(); } public function popArray() : Type { return $this; } public function reverseArray(TrinaryLogic $preserveKeys) : Type { if ($preserveKeys->no()) { return $this; } return new MixedType(); } public function searchArray(Type $needleType) : Type { return new MixedType(); } public function shiftArray() : Type { return $this; } public function shuffleArray() : Type { return $this; } public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $preserveKeys) : Type { if ($preserveKeys->no()) { return $this; } if ((new ConstantIntegerType(0))->isSuperTypeOf($offsetType)->yes()) { return $this; } return new MixedType(); } public function isIterable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isIterableAtLeastOnce() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getArraySize() : Type { return IntegerRangeType::fromInterval(0, null); } public function getIterableKeyType() : Type { return IntegerRangeType::fromInterval(0, null); } public function getFirstIterableKeyType() : Type { return new ConstantIntegerType(0); } public function getLastIterableKeyType() : Type { return $this->getIterableKeyType(); } public function getIterableValueType() : Type { return new MixedType(); } public function getFirstIterableValueType() : Type { return new MixedType(); } public function getLastIterableValueType() : Type { return new MixedType(); } public function isArray() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isConstantArray() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isOversizedArray() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isList() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : Type { return new ErrorType(); } public function getObjectTypeOrClassStringObjectType() : Type { return new ErrorType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createNo(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function toNumber() : Type { return new ErrorType(); } public function toAbsoluteNumber() : Type { return new ErrorType(); } public function toInteger() : Type { return TypeCombinator::union(new ConstantIntegerType(0), new ConstantIntegerType(1)); } public function toFloat() : Type { return TypeCombinator::union(new ConstantFloatType(0.0), new ConstantFloatType(1.0)); } public function toString() : Type { return new ErrorType(); } public function toArray() : Type { return $this; } public function toArrayKey() : Type { return new ErrorType(); } public function traverse(callable $cb) : Type { return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { return $this; } public static function __set_state(array $properties) : Type { return new self(); } public static function setListTypeEnabled(bool $enabled) : void { self::$enabled = $enabled; } public static function isListTypeEnabled() : bool { return self::$enabled; } public static function intersectWith(Type $type) : Type { if (self::$enabled) { return TypeCombinator::intersect($type, new self()); } return $type; } public function exponentiate(Type $exponent) : Type { return new ErrorType(); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('list'); } } methodName = $methodName; } public function getReferencedClasses() : array { return []; } public function getObjectClassNames() : array { return []; } public function getObjectClassReflections() : array { return []; } private function getCanonicalMethodName() : string { return strtolower($this->methodName); } public function accepts(Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return AcceptsResult::createFromBoolean($this->equals($type)); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { return new IsSuperTypeOfResult($type->hasMethod($this->methodName), []); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } if ($this->isCallable()->yes() && $otherType->isCallable()->yes()) { return IsSuperTypeOfResult::createYes(); } if ($otherType instanceof self) { $limit = IsSuperTypeOfResult::createYes(); } else { $limit = IsSuperTypeOfResult::createMaybe(); } return $limit->and(new IsSuperTypeOfResult($otherType->hasMethod($this->methodName), [])); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self && $this->getCanonicalMethodName() === $type->getCanonicalMethodName(); } public function describe(VerbosityLevel $level) : string { return sprintf('hasMethod(%s)', $this->methodName); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function hasMethod(string $methodName) : TrinaryLogic { if ($this->getCanonicalMethodName() === strtolower($methodName)) { return TrinaryLogic::createYes(); } return TrinaryLogic::createMaybe(); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { return $this->getUnresolvedMethodPrototype($methodName, $scope)->getTransformedMethod(); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { $method = new DummyMethodReflection($this->methodName); return new CallbackUnresolvedMethodPrototypeReflection($method, $method->getDeclaringClass(), \false, static function (Type $type) : Type { return $type; }); } public function isCallable() : TrinaryLogic { if ($this->getCanonicalMethodName() === '__invoke') { return TrinaryLogic::createYes(); } return TrinaryLogic::createMaybe(); } public function toString() : Type { if ($this->getCanonicalMethodName() === '__tostring') { return new StringType(); } return new ErrorType(); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { return [new TrivialParametersAcceptor()]; } public function getEnumCases() : array { return []; } public function traverse(callable $cb) : Type { return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { return $this; } public function exponentiate(Type $exponent) : Type { return new ErrorType(); } public function getFiniteTypes() : array { return []; } public static function __set_state(array $properties) : Type { return new self($properties['methodName']); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode(''); // no PHPDoc representation } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } $isArray = $type->isArray(); $isIterableAtLeastOnce = $type->isIterableAtLeastOnce(); return new AcceptsResult($isArray->and($isIterableAtLeastOnce), []); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($this->equals($type)) { return IsSuperTypeOfResult::createYes(); } if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } return new IsSuperTypeOfResult($type->isArray()->and($type->isIterableAtLeastOnce()), []); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } return (new IsSuperTypeOfResult($otherType->isArray()->and($otherType->isIterableAtLeastOnce()), []))->and($otherType instanceof self ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createMaybe()); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self; } public function describe(VerbosityLevel $level) : string { return 'non-empty-array'; } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getOffsetValueType(Type $offsetType) : Type { return new MixedType(); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { return $this; } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { return $this; } public function unsetOffset(Type $offsetType) : Type { return new ErrorType(); } public function getKeysArray() : Type { return $this; } public function getValuesArray() : Type { return $this; } public function chunkArray(Type $lengthType, TrinaryLogic $preserveKeys) : Type { return $this; } public function fillKeysArray(Type $valueType) : Type { return $this; } public function flipArray() : Type { return $this; } public function intersectKeyArray(Type $otherArraysType) : Type { return new MixedType(); } public function popArray() : Type { return new MixedType(); } public function reverseArray(TrinaryLogic $preserveKeys) : Type { return $this; } public function searchArray(Type $needleType) : Type { return new MixedType(); } public function shiftArray() : Type { return new MixedType(); } public function shuffleArray() : Type { return $this; } public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $preserveKeys) : Type { if ((new ConstantIntegerType(0))->isSuperTypeOf($offsetType)->yes() && ($lengthType->isNull()->yes() || IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($lengthType)->yes())) { return $this; } return new MixedType(); } public function isIterable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isIterableAtLeastOnce() : TrinaryLogic { return TrinaryLogic::createYes(); } public function getArraySize() : Type { return IntegerRangeType::fromInterval(1, null); } public function getIterableKeyType() : Type { return new MixedType(); } public function getFirstIterableKeyType() : Type { return new MixedType(); } public function getLastIterableKeyType() : Type { return new MixedType(); } public function getIterableValueType() : Type { return new MixedType(); } public function getFirstIterableValueType() : Type { return new MixedType(); } public function getLastIterableValueType() : Type { return new MixedType(); } public function isArray() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isConstantArray() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isOversizedArray() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isList() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : Type { return new ErrorType(); } public function getObjectTypeOrClassStringObjectType() : Type { return new ErrorType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createNo(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function toNumber() : Type { return new ErrorType(); } public function toAbsoluteNumber() : Type { return new ErrorType(); } public function toInteger() : Type { return new ConstantIntegerType(1); } public function toFloat() : Type { return new ConstantFloatType(1.0); } public function toString() : Type { return new ErrorType(); } public function toArray() : Type { return $this; } public function toArrayKey() : Type { return new ErrorType(); } public function traverse(callable $cb) : Type { return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { return $this; } public function exponentiate(Type $exponent) : Type { return new ErrorType(); } public function getFiniteTypes() : array { return []; } public static function __set_state(array $properties) : Type { return new self(); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('non-empty-array'); } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof MixedType) { return AcceptsResult::createNo(); } if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return new AcceptsResult($type->isLiteralString(), []); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } if ($this->equals($type)) { return IsSuperTypeOfResult::createYes(); } return new IsSuperTypeOfResult($type->isLiteralString(), []); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } return (new IsSuperTypeOfResult($otherType->isLiteralString(), []))->and($otherType instanceof self ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createMaybe()); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self; } public function describe(VerbosityLevel $level) : string { return 'literal-string'; } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { return $offsetType->isInteger()->and(TrinaryLogic::createMaybe()); } public function getOffsetValueType(Type $offsetType) : Type { if ($this->hasOffsetValueType($offsetType)->no()) { return new ErrorType(); } return new StringType(); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { $stringOffset = (new StringType())->setOffsetValueType($offsetType, $valueType, $unionValues); if ($stringOffset instanceof ErrorType) { return $stringOffset; } if ($valueType->isLiteralString()->yes()) { return $this; } return new StringType(); } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { return $this; } public function unsetOffset(Type $offsetType) : Type { return new ErrorType(); } public function toNumber() : Type { return new ErrorType(); } public function toAbsoluteNumber() : Type { return new ErrorType(); } public function toInteger() : Type { return new IntegerType(); } public function toFloat() : Type { return new FloatType(); } public function toString() : Type { return $this; } public function toBoolean() : BooleanType { return new BooleanType(); } public function toArray() : Type { return new ConstantArrayType([new ConstantIntegerType(0)], [$this], [1], [], TrinaryLogic::createYes()); } public function toArrayKey() : Type { return $this; } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function getObjectTypeOrClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function hasMethod(string $methodName) : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createYes(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function traverse(callable $cb) : Type { return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { return $this; } public function generalize(GeneralizePrecision $precision) : Type { return new StringType(); } public static function __set_state(array $properties) : Type { return new self(); } public function exponentiate(Type $exponent) : Type { return new BenevolentUnionType([new FloatType(), new IntegerType()]); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('literal-string'); } } offsetType = $offsetType; $this->valueType = $valueType; } /** * @return ConstantStringType|ConstantIntegerType */ public function getOffsetType() { return $this->offsetType; } public function getValueType() : Type { return $this->valueType; } public function getReferencedClasses() : array { return []; } public function getObjectClassNames() : array { return []; } public function getObjectClassReflections() : array { return []; } public function getConstantStrings() : array { return []; } public function accepts(Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } $result = new AcceptsResult($type->isOffsetAccessible()->and($type->hasOffsetValueType($this->offsetType)), []); return $result->and($this->valueType->acceptsWithReason($type->getOffsetValueType($this->offsetType), $strictTypes)); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($this->equals($type)) { return IsSuperTypeOfResult::createYes(); } $result = new IsSuperTypeOfResult($type->isOffsetAccessible()->and($type->hasOffsetValueType($this->offsetType)), []); return $result->and($this->valueType->isSuperTypeOfWithReason($type->getOffsetValueType($this->offsetType))); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } $result = new IsSuperTypeOfResult($otherType->isOffsetAccessible()->and($otherType->hasOffsetValueType($this->offsetType)), []); return $result->and($otherType->getOffsetValueType($this->offsetType)->isSuperTypeOfWithReason($this->valueType))->and($otherType instanceof self ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createMaybe()); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self && $this->offsetType->equals($type->offsetType) && $this->valueType->equals($type->valueType); } public function describe(VerbosityLevel $level) : string { return sprintf('hasOffsetValue(%s, %s)', $this->offsetType->describe($level), $this->valueType->describe($level)); } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { if ($offsetType->isConstantScalarValue()->yes() && $offsetType->equals($this->offsetType)) { return TrinaryLogic::createYes(); } return TrinaryLogic::createMaybe(); } public function getOffsetValueType(Type $offsetType) : Type { if ($offsetType->isConstantScalarValue()->yes() && $offsetType->equals($this->offsetType)) { return $this->valueType; } return new MixedType(); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { if ($offsetType === null) { return $this; } if (!$offsetType->equals($this->offsetType)) { return $this; } if (!$offsetType instanceof ConstantIntegerType && !$offsetType instanceof ConstantStringType) { throw new ShouldNotHappenException(); } return new self($offsetType, $valueType); } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { return new self($this->offsetType, $valueType); } public function unsetOffset(Type $offsetType) : Type { if ($this->offsetType->isSuperTypeOf($offsetType)->yes()) { return new ErrorType(); } return $this; } public function getKeysArray() : Type { return new \PHPStan\Type\Accessory\NonEmptyArrayType(); } public function getValuesArray() : Type { return new \PHPStan\Type\Accessory\NonEmptyArrayType(); } public function chunkArray(Type $lengthType, TrinaryLogic $preserveKeys) : Type { return new \PHPStan\Type\Accessory\NonEmptyArrayType(); } public function fillKeysArray(Type $valueType) : Type { return new \PHPStan\Type\Accessory\NonEmptyArrayType(); } public function flipArray() : Type { $valueType = $this->valueType->toArrayKey(); if ($valueType instanceof ConstantIntegerType || $valueType instanceof ConstantStringType) { return new self($valueType, $this->offsetType); } return new MixedType(); } public function intersectKeyArray(Type $otherArraysType) : Type { if ($otherArraysType->hasOffsetValueType($this->offsetType)->yes()) { return $this; } return new MixedType(); } public function reverseArray(TrinaryLogic $preserveKeys) : Type { if ($preserveKeys->yes()) { return $this; } return new \PHPStan\Type\Accessory\NonEmptyArrayType(); } public function searchArray(Type $needleType) : Type { if ($needleType instanceof ConstantScalarType && $this->valueType instanceof ConstantScalarType && $needleType->getValue() === $this->valueType->getValue()) { return new UnionType([new IntegerType(), new StringType()]); } return new MixedType(); } public function shuffleArray() : Type { return new \PHPStan\Type\Accessory\NonEmptyArrayType(); } public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $preserveKeys) : Type { if ($this->offsetType->isSuperTypeOf($offsetType)->yes() && ($lengthType->isNull()->yes() || IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($lengthType)->yes())) { return $preserveKeys->yes() ? TypeCombinator::intersect($this, new \PHPStan\Type\Accessory\NonEmptyArrayType()) : new \PHPStan\Type\Accessory\NonEmptyArrayType(); } return new MixedType(); } public function isIterableAtLeastOnce() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isList() : TrinaryLogic { if ($this->offsetType->isString()->yes()) { return TrinaryLogic::createNo(); } return TrinaryLogic::createMaybe(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function getObjectTypeOrClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function toNumber() : Type { return new ErrorType(); } public function toAbsoluteNumber() : Type { return new ErrorType(); } public function toInteger() : Type { return new ErrorType(); } public function toFloat() : Type { return new ErrorType(); } public function toString() : Type { return new ErrorType(); } public function toArray() : Type { return new MixedType(); } public function toArrayKey() : Type { return new ErrorType(); } public function getEnumCases() : array { return []; } public function traverse(callable $cb) : Type { $newValueType = $cb($this->valueType); if ($newValueType === $this->valueType) { return $this; } return new self($this->offsetType, $newValueType); } public function traverseSimultaneously(Type $right, callable $cb) : Type { $newValueType = $cb($this->valueType, $right->getOffsetValueType($this->offsetType)); if ($newValueType === $this->valueType) { return $this; } return new self($this->offsetType, $newValueType); } public function exponentiate(Type $exponent) : Type { return new ErrorType(); } public function getFiniteTypes() : array { return []; } public static function __set_state(array $properties) : Type { return new self($properties['offsetType'], $properties['valueType']); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode(''); // no PHPDoc representation } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return new AcceptsResult($type->isUppercaseString(), []); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } if ($this->equals($type)) { return IsSuperTypeOfResult::createYes(); } return new IsSuperTypeOfResult($type->isUppercaseString(), []); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } return (new IsSuperTypeOfResult($otherType->isUppercaseString(), []))->and($otherType instanceof self ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createMaybe()); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self; } public function describe(VerbosityLevel $level) : string { return 'uppercase-string'; } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { return $offsetType->isInteger()->and(TrinaryLogic::createMaybe()); } public function getOffsetValueType(Type $offsetType) : Type { if ($this->hasOffsetValueType($offsetType)->no()) { return new ErrorType(); } return new IntersectionType([new StringType(), new \PHPStan\Type\Accessory\AccessoryUppercaseStringType()]); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { $stringOffset = (new StringType())->setOffsetValueType($offsetType, $valueType, $unionValues); if ($stringOffset instanceof ErrorType) { return $stringOffset; } if ($valueType->isUppercaseString()->yes()) { return $this; } return new StringType(); } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { return $this; } public function unsetOffset(Type $offsetType) : Type { return new ErrorType(); } public function toNumber() : Type { return new ErrorType(); } public function toAbsoluteNumber() : Type { return new ErrorType(); } public function toInteger() : Type { return new IntegerType(); } public function toFloat() : Type { return new FloatType(); } public function toString() : Type { return $this; } public function toBoolean() : BooleanType { return new BooleanType(); } public function toArray() : Type { return new ConstantArrayType([new ConstantIntegerType(0)], [$this], [1], [], TrinaryLogic::createYes()); } public function toArrayKey() : Type { return $this; } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function getObjectTypeOrClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function hasMethod(string $methodName) : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createYes(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function traverse(callable $cb) : Type { return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { return $this; } public function generalize(GeneralizePrecision $precision) : Type { return new StringType(); } public static function __set_state(array $properties) : Type { return new self(); } public function exponentiate(Type $exponent) : Type { return new BenevolentUnionType([new FloatType(), new IntegerType()]); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('uppercase-string'); } } propertyName = $propertyName; } /** * @return string[] */ public function getReferencedClasses() : array { return []; } public function getObjectClassNames() : array { return []; } public function getObjectClassReflections() : array { return []; } public function getConstantStrings() : array { return []; } public function getPropertyName() : string { return $this->propertyName; } public function accepts(Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return AcceptsResult::createFromBoolean($this->equals($type)); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { return new IsSuperTypeOfResult($type->hasProperty($this->propertyName), []); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } if ($otherType instanceof self) { $limit = IsSuperTypeOfResult::createYes(); } else { $limit = IsSuperTypeOfResult::createMaybe(); } return $limit->and(new IsSuperTypeOfResult($otherType->hasProperty($this->propertyName), [])); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self && $this->propertyName === $type->propertyName; } public function describe(VerbosityLevel $level) : string { return sprintf('hasProperty(%s)', $this->propertyName); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function hasProperty(string $propertyName) : TrinaryLogic { if ($this->propertyName === $propertyName) { return TrinaryLogic::createYes(); } return TrinaryLogic::createMaybe(); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { return [new TrivialParametersAcceptor()]; } public function getEnumCases() : array { return []; } public function traverse(callable $cb) : Type { return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { return $this; } public function exponentiate(Type $exponent) : Type { return new ErrorType(); } public function getFiniteTypes() : array { return []; } public static function __set_state(array $properties) : Type { return new self($properties['propertyName']); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode(''); // no PHPDoc representation } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return new AcceptsResult($type->isNonFalsyString(), []); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } if ($this->equals($type)) { return IsSuperTypeOfResult::createYes(); } return new IsSuperTypeOfResult($type->isNonFalsyString(), []); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } if ($otherType instanceof \PHPStan\Type\Accessory\AccessoryNonEmptyStringType) { return IsSuperTypeOfResult::createYes(); } return (new IsSuperTypeOfResult($otherType->isNonFalsyString(), []))->and($otherType instanceof self ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createMaybe()); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self; } public function describe(VerbosityLevel $level) : string { return 'non-falsy-string'; } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { return $offsetType->isInteger()->and(TrinaryLogic::createMaybe()); } public function getOffsetValueType(Type $offsetType) : Type { if ($this->hasOffsetValueType($offsetType)->no()) { return new ErrorType(); } return new StringType(); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { $stringOffset = (new StringType())->setOffsetValueType($offsetType, $valueType, $unionValues); if ($stringOffset instanceof ErrorType) { return $stringOffset; } if ($valueType->isNonFalsyString()->yes()) { return $this; } return new StringType(); } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { return $this; } public function unsetOffset(Type $offsetType) : Type { return new ErrorType(); } public function toNumber() : Type { return new ErrorType(); } public function toAbsoluteNumber() : Type { return new ErrorType(); } public function toInteger() : Type { return new IntegerType(); } public function toFloat() : Type { return new FloatType(); } public function toString() : Type { return $this; } public function toArray() : Type { return new ConstantArrayType([new ConstantIntegerType(0)], [$this], [1], [], TrinaryLogic::createYes()); } public function toArrayKey() : Type { return $this; } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function getObjectTypeOrClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createYes(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function traverse(callable $cb) : Type { return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { return $this; } public function generalize(GeneralizePrecision $precision) : Type { return new StringType(); } public static function __set_state(array $properties) : Type { return new self(); } public function exponentiate(Type $exponent) : Type { return new BenevolentUnionType([new FloatType(), new IntegerType()]); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('non-falsy-string'); } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return new AcceptsResult($type->isNumericString(), []); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } if ($this->equals($type)) { return IsSuperTypeOfResult::createYes(); } return new IsSuperTypeOfResult($type->isNumericString(), []); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } return (new IsSuperTypeOfResult($otherType->isNumericString(), []))->and($otherType instanceof self ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createMaybe()); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { if ($acceptingType->isNonFalsyString()->yes()) { return AcceptsResult::createMaybe(); } if ($acceptingType->isNonEmptyString()->yes()) { return AcceptsResult::createYes(); } return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self; } public function describe(VerbosityLevel $level) : string { return 'numeric-string'; } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { return $offsetType->isInteger()->and(TrinaryLogic::createMaybe()); } public function getOffsetValueType(Type $offsetType) : Type { if ($this->hasOffsetValueType($offsetType)->no()) { return new ErrorType(); } return new StringType(); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { $stringOffset = (new StringType())->setOffsetValueType($offsetType, $valueType, $unionValues); if ($stringOffset instanceof ErrorType) { return $stringOffset; } return $this; } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { return $this; } public function unsetOffset(Type $offsetType) : Type { return new ErrorType(); } public function toNumber() : Type { return new UnionType([$this->toInteger(), $this->toFloat()]); } public function toAbsoluteNumber() : Type { return $this->toNumber()->toAbsoluteNumber(); } public function toInteger() : Type { return new IntegerType(); } public function toFloat() : Type { return new FloatType(); } public function toString() : Type { return $this; } public function toArray() : Type { return new ConstantArrayType([new ConstantIntegerType(0)], [$this], [1], [], TrinaryLogic::createYes()); } public function toArrayKey() : Type { return new UnionType([new IntegerType(), new IntersectionType([new StringType(), new \PHPStan\Type\Accessory\AccessoryNumericStringType()])]); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : Type { return new ErrorType(); } public function getObjectTypeOrClassStringObjectType() : Type { return new ErrorType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createYes(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function traverse(callable $cb) : Type { return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { return $this; } public function generalize(GeneralizePrecision $precision) : Type { return new StringType(); } public static function __set_state(array $properties) : Type { return new self(); } public function tryRemove(Type $typeToRemove) : ?Type { if ($typeToRemove instanceof ConstantStringType && $typeToRemove->getValue() === '0') { return TypeCombinator::intersect($this, new \PHPStan\Type\Accessory\AccessoryNonFalsyStringType()); } return null; } public function exponentiate(Type $exponent) : Type { return new BenevolentUnionType([new FloatType(), new IntegerType()]); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('numeric-string'); } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type->isNonEmptyString()->yes()) { return AcceptsResult::createYes(); } if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return new AcceptsResult($type->isNonEmptyString(), []); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } if ($this->equals($type)) { return IsSuperTypeOfResult::createYes(); } if ($type->isNonFalsyString()->yes()) { return IsSuperTypeOfResult::createYes(); } return new IsSuperTypeOfResult($type->isNonEmptyString(), []); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } return (new IsSuperTypeOfResult($otherType->isNonEmptyString(), []))->and($otherType instanceof self ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createMaybe()); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self; } public function describe(VerbosityLevel $level) : string { return 'non-empty-string'; } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { return $offsetType->isInteger()->and(TrinaryLogic::createMaybe()); } public function getOffsetValueType(Type $offsetType) : Type { if ($this->hasOffsetValueType($offsetType)->no()) { return new ErrorType(); } if ((new ConstantIntegerType(0))->isSuperTypeOf($offsetType)->yes()) { return new IntersectionType([new StringType(), new \PHPStan\Type\Accessory\AccessoryNonEmptyStringType()]); } return new StringType(); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { $stringOffset = (new StringType())->setOffsetValueType($offsetType, $valueType, $unionValues); if ($stringOffset instanceof ErrorType) { return $stringOffset; } return $this; } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { return $this; } public function unsetOffset(Type $offsetType) : Type { return new ErrorType(); } public function toNumber() : Type { return new ErrorType(); } public function toAbsoluteNumber() : Type { return new ErrorType(); } public function toInteger() : Type { return new IntegerType(); } public function toFloat() : Type { return new FloatType(); } public function toString() : Type { return $this; } public function toArray() : Type { return new ConstantArrayType([new ConstantIntegerType(0)], [$this], [1], [], TrinaryLogic::createYes()); } public function toArrayKey() : Type { return $this; } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function getObjectTypeOrClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createYes(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function traverse(callable $cb) : Type { return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { return $this; } public function generalize(GeneralizePrecision $precision) : Type { return new StringType(); } public static function __set_state(array $properties) : Type { return new self(); } public function tryRemove(Type $typeToRemove) : ?Type { if ($typeToRemove instanceof ConstantStringType && $typeToRemove->getValue() === '0') { return TypeCombinator::intersect($this, new \PHPStan\Type\Accessory\AccessoryNonFalsyStringType()); } return null; } public function exponentiate(Type $exponent) : Type { return new BenevolentUnionType([new FloatType(), new IntegerType()]); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('non-empty-string'); } } offsetType = $offsetType; } /** * @return ConstantStringType|ConstantIntegerType */ public function getOffsetType() : Type { return $this->offsetType; } public function getReferencedClasses() : array { return []; } public function getObjectClassNames() : array { return []; } public function getObjectClassReflections() : array { return []; } public function getConstantStrings() : array { return []; } public function accepts(Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return new AcceptsResult($type->isOffsetAccessible()->and($type->hasOffsetValueType($this->offsetType)), []); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($this->equals($type)) { return IsSuperTypeOfResult::createYes(); } return new IsSuperTypeOfResult($type->isOffsetAccessible()->and($type->hasOffsetValueType($this->offsetType)), []); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } $result = new IsSuperTypeOfResult($otherType->isOffsetAccessible()->and($otherType->hasOffsetValueType($this->offsetType)), []); return $result->and($otherType instanceof self ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createMaybe()); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self && $this->offsetType->equals($type->offsetType); } public function describe(VerbosityLevel $level) : string { return sprintf('hasOffset(%s)', $this->offsetType->describe($level)); } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { if ($offsetType->isConstantScalarValue()->yes() && $offsetType->equals($this->offsetType)) { return TrinaryLogic::createYes(); } return TrinaryLogic::createMaybe(); } public function getOffsetValueType(Type $offsetType) : Type { return new MixedType(); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { return $this; } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { return $this; } public function unsetOffset(Type $offsetType) : Type { if ($this->offsetType->isSuperTypeOf($offsetType)->yes()) { return new ErrorType(); } return $this; } public function chunkArray(Type $lengthType, TrinaryLogic $preserveKeys) : Type { return new \PHPStan\Type\Accessory\NonEmptyArrayType(); } public function fillKeysArray(Type $valueType) : Type { return new \PHPStan\Type\Accessory\NonEmptyArrayType(); } public function intersectKeyArray(Type $otherArraysType) : Type { if ($otherArraysType->hasOffsetValueType($this->offsetType)->yes()) { return $this; } return new MixedType(); } public function reverseArray(TrinaryLogic $preserveKeys) : Type { if ($preserveKeys->yes()) { return $this; } return new \PHPStan\Type\Accessory\NonEmptyArrayType(); } public function shuffleArray() : Type { return new \PHPStan\Type\Accessory\NonEmptyArrayType(); } public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $preserveKeys) : Type { if ($this->offsetType->isSuperTypeOf($offsetType)->yes() && ($lengthType->isNull()->yes() || IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($lengthType)->yes())) { return $preserveKeys->yes() ? TypeCombinator::intersect($this, new \PHPStan\Type\Accessory\NonEmptyArrayType()) : new \PHPStan\Type\Accessory\NonEmptyArrayType(); } return new MixedType(); } public function isIterableAtLeastOnce() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isList() : TrinaryLogic { if ($this->offsetType->isString()->yes()) { return TrinaryLogic::createNo(); } return TrinaryLogic::createMaybe(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function getObjectTypeOrClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function getKeysArray() : Type { return new \PHPStan\Type\Accessory\NonEmptyArrayType(); } public function getValuesArray() : Type { return new \PHPStan\Type\Accessory\NonEmptyArrayType(); } public function toNumber() : Type { return new ErrorType(); } public function toAbsoluteNumber() : Type { return new ErrorType(); } public function toInteger() : Type { return new ErrorType(); } public function toFloat() : Type { return new ErrorType(); } public function toString() : Type { return new ErrorType(); } public function toArray() : Type { return new MixedType(); } public function toArrayKey() : Type { return new ErrorType(); } public function getEnumCases() : array { return []; } public function traverse(callable $cb) : Type { return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { return $this; } public function exponentiate(Type $exponent) : Type { return new ErrorType(); } public function getFiniteTypes() : array { return []; } public static function __set_state(array $properties) : Type { return new self($properties['offsetType']); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode(''); // no PHPDoc representation } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return new AcceptsResult($type->isArray()->and($type->isIterableAtLeastOnce()), []); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($this->equals($type)) { return IsSuperTypeOfResult::createYes(); } if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } return new IsSuperTypeOfResult($type->isArray()->and($type->isOversizedArray()), []); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } return (new IsSuperTypeOfResult($otherType->isArray()->and($otherType->isOversizedArray()), []))->and($otherType instanceof self ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createMaybe()); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self; } public function describe(VerbosityLevel $level) : string { return 'oversized-array'; } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getOffsetValueType(Type $offsetType) : Type { return new MixedType(); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { return $this; } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { return $this; } public function unsetOffset(Type $offsetType) : Type { return new ErrorType(); } public function getKeysArray() : Type { return $this; } public function getValuesArray() : Type { return $this; } public function chunkArray(Type $lengthType, TrinaryLogic $preserveKeys) : Type { return $this; } public function fillKeysArray(Type $valueType) : Type { return $this; } public function flipArray() : Type { return $this; } public function intersectKeyArray(Type $otherArraysType) : Type { return $this; } public function popArray() : Type { return $this; } public function reverseArray(TrinaryLogic $preserveKeys) : Type { return $this; } public function searchArray(Type $needleType) : Type { return new MixedType(); } public function shiftArray() : Type { return $this; } public function shuffleArray() : Type { return $this; } public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $preserveKeys) : Type { return $this; } public function isIterable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isIterableAtLeastOnce() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getArraySize() : Type { return IntegerRangeType::fromInterval(0, null); } public function getIterableKeyType() : Type { return new MixedType(); } public function getFirstIterableKeyType() : Type { return new MixedType(); } public function getLastIterableKeyType() : Type { return new MixedType(); } public function getIterableValueType() : Type { return new MixedType(); } public function getFirstIterableValueType() : Type { return new MixedType(); } public function getLastIterableValueType() : Type { return new MixedType(); } public function isArray() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isConstantArray() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isOversizedArray() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isList() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : Type { return new ErrorType(); } public function getObjectTypeOrClassStringObjectType() : Type { return new ErrorType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createNo(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function toNumber() : Type { return new ErrorType(); } public function toAbsoluteNumber() : Type { return new ErrorType(); } public function toInteger() : Type { return new ConstantIntegerType(1); } public function toFloat() : Type { return new ConstantFloatType(1.0); } public function toString() : Type { return new ErrorType(); } public function toArray() : Type { return new MixedType(); } public function toArrayKey() : Type { return new ErrorType(); } public function traverse(callable $cb) : Type { return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { return $this; } public function exponentiate(Type $exponent) : Type { return new ErrorType(); } public function getFiniteTypes() : array { return []; } public static function __set_state(array $properties) : Type { return new self(); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode(''); // no PHPDoc representation } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return new AcceptsResult($type->isLowercaseString(), []); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } if ($this->equals($type)) { return IsSuperTypeOfResult::createYes(); } return new IsSuperTypeOfResult($type->isLowercaseString(), []); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { return $otherType->isSuperTypeOfWithReason($this); } return (new IsSuperTypeOfResult($otherType->isLowercaseString(), []))->and($otherType instanceof self ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createMaybe()); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function equals(Type $type) : bool { return $type instanceof self; } public function describe(VerbosityLevel $level) : string { return 'lowercase-string'; } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { return $offsetType->isInteger()->and(TrinaryLogic::createMaybe()); } public function getOffsetValueType(Type $offsetType) : Type { if ($this->hasOffsetValueType($offsetType)->no()) { return new ErrorType(); } return new IntersectionType([new StringType(), new \PHPStan\Type\Accessory\AccessoryLowercaseStringType()]); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { $stringOffset = (new StringType())->setOffsetValueType($offsetType, $valueType, $unionValues); if ($stringOffset instanceof ErrorType) { return $stringOffset; } if ($valueType->isLowercaseString()->yes()) { return $this; } return new StringType(); } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { return $this; } public function unsetOffset(Type $offsetType) : Type { return new ErrorType(); } public function toNumber() : Type { return new ErrorType(); } public function toAbsoluteNumber() : Type { return new ErrorType(); } public function toInteger() : Type { return new IntegerType(); } public function toFloat() : Type { return new FloatType(); } public function toString() : Type { return $this; } public function toBoolean() : BooleanType { return new BooleanType(); } public function toArray() : Type { return new ConstantArrayType([new ConstantIntegerType(0)], [$this], [1], [], TrinaryLogic::createYes()); } public function toArrayKey() : Type { return $this; } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function getObjectTypeOrClassStringObjectType() : Type { return new ObjectWithoutClassType(); } public function hasMethod(string $methodName) : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createYes(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function traverse(callable $cb) : Type { return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { return $this; } public function generalize(GeneralizePrecision $precision) : Type { return new StringType(); } public static function __set_state(array $properties) : Type { return new self(); } public function exponentiate(Type $exponent) : Type { return new BenevolentUnionType([new FloatType(), new IntegerType()]); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('lowercase-string'); } } classReflection = $classReflection; if ($subtractedType instanceof \PHPStan\Type\NeverType) { $subtractedType = null; } $this->subtractedType = $subtractedType; $this->baseClass = $classReflection->getName(); } public function getClassName() : string { return $this->baseClass; } public function getClassReflection() : ClassReflection { return $this->classReflection; } public function getAncestorWithClassName(string $className) : ?\PHPStan\Type\TypeWithClassName { $ancestor = $this->getStaticObjectType()->getAncestorWithClassName($className); if ($ancestor === null) { return null; } $classReflection = $ancestor->getClassReflection(); if ($classReflection !== null) { return $this->changeBaseClass($classReflection); } return null; } public function getStaticObjectType() : \PHPStan\Type\ObjectType { if ($this->staticObjectType === null) { if ($this->classReflection->isGeneric()) { $typeMap = $this->classReflection->getActiveTemplateTypeMap()->map(static function (string $name, \PHPStan\Type\Type $type) : \PHPStan\Type\Type { return TemplateTypeHelper::toArgument($type); }); $varianceMap = $this->classReflection->getCallSiteVarianceMap(); return $this->staticObjectType = new GenericObjectType($this->classReflection->getName(), $this->classReflection->typeMapToList($typeMap), $this->subtractedType, null, $this->classReflection->varianceMapToList($varianceMap)); } return $this->staticObjectType = new \PHPStan\Type\ObjectType($this->classReflection->getName(), $this->subtractedType, $this->classReflection); } return $this->staticObjectType; } /** * @return string[] */ public function getReferencedClasses() : array { return $this->getStaticObjectType()->getReferencedClasses(); } public function getObjectClassNames() : array { return $this->getStaticObjectType()->getObjectClassNames(); } public function getObjectClassReflections() : array { return $this->getStaticObjectType()->getObjectClassReflections(); } public function getArrays() : array { return $this->getStaticObjectType()->getArrays(); } public function getConstantArrays() : array { return $this->getStaticObjectType()->getConstantArrays(); } public function getConstantStrings() : array { return $this->getStaticObjectType()->getConstantStrings(); } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } if (!$type instanceof static) { return \PHPStan\Type\AcceptsResult::createNo(); } return $this->getStaticObjectType()->acceptsWithReason($type->getStaticObjectType(), $strictTypes); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self) { return $this->getStaticObjectType()->isSuperTypeOfWithReason($type); } if ($type instanceof \PHPStan\Type\ObjectWithoutClassType) { return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } if ($type instanceof \PHPStan\Type\ObjectType) { $result = $this->getStaticObjectType()->isSuperTypeOfWithReason($type); if ($result->yes()) { $classReflection = $type->getClassReflection(); if ($classReflection !== null && $classReflection->isFinal()) { return $result; } } return $result->and(\PHPStan\Type\IsSuperTypeOfResult::createMaybe()); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } public function equals(\PHPStan\Type\Type $type) : bool { if (get_class($type) !== static::class) { return \false; } return $this->getStaticObjectType()->equals($type->getStaticObjectType()); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return sprintf('static(%s)', $this->getStaticObjectType()->describe($level)); } public function getTemplateType(string $ancestorClassName, string $templateTypeName) : \PHPStan\Type\Type { return $this->getStaticObjectType()->getTemplateType($ancestorClassName, $templateTypeName); } public function isObject() : TrinaryLogic { return $this->getStaticObjectType()->isObject(); } public function isEnum() : TrinaryLogic { return $this->getStaticObjectType()->isEnum(); } public function canAccessProperties() : TrinaryLogic { return $this->getStaticObjectType()->canAccessProperties(); } public function hasProperty(string $propertyName) : TrinaryLogic { return $this->getStaticObjectType()->hasProperty($propertyName); } public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection { return $this->getUnresolvedPropertyPrototype($propertyName, $scope)->getTransformedProperty(); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { $staticObject = $this->getStaticObjectType(); $nakedProperty = $staticObject->getUnresolvedPropertyPrototype($propertyName, $scope)->getNakedProperty(); $ancestor = $this->getAncestorWithClassName($nakedProperty->getDeclaringClass()->getName()); $classReflection = null; if ($ancestor !== null) { $classReflection = $ancestor->getClassReflection(); } if ($classReflection === null) { $classReflection = $nakedProperty->getDeclaringClass(); } return new CallbackUnresolvedPropertyPrototypeReflection($nakedProperty, $classReflection, \false, function (\PHPStan\Type\Type $type) use($scope) : \PHPStan\Type\Type { return $this->transformStaticType($type, $scope); }); } public function canCallMethods() : TrinaryLogic { return $this->getStaticObjectType()->canCallMethods(); } public function hasMethod(string $methodName) : TrinaryLogic { return $this->getStaticObjectType()->hasMethod($methodName); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { return $this->getUnresolvedMethodPrototype($methodName, $scope)->getTransformedMethod(); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { $staticObject = $this->getStaticObjectType(); $nakedMethod = $staticObject->getUnresolvedMethodPrototype($methodName, $scope)->getNakedMethod(); $ancestor = $this->getAncestorWithClassName($nakedMethod->getDeclaringClass()->getName()); $classReflection = null; if ($ancestor !== null) { $classReflection = $ancestor->getClassReflection(); } if ($classReflection === null) { $classReflection = $nakedMethod->getDeclaringClass(); } return new CallbackUnresolvedMethodPrototypeReflection($nakedMethod, $classReflection, \false, function (\PHPStan\Type\Type $type) use($scope) : \PHPStan\Type\Type { return $this->transformStaticType($type, $scope); }); } private function transformStaticType(\PHPStan\Type\Type $type, ClassMemberAccessAnswerer $scope) : \PHPStan\Type\Type { return \PHPStan\Type\TypeTraverser::map($type, function (\PHPStan\Type\Type $type, callable $traverse) use($scope) : \PHPStan\Type\Type { if ($type instanceof \PHPStan\Type\StaticType) { $classReflection = $this->classReflection; $isFinal = \false; if ($scope->isInClass()) { $classReflection = $scope->getClassReflection(); $isFinal = $classReflection->isFinal(); } $type = $type->changeBaseClass($classReflection); if (!$isFinal || $type instanceof \PHPStan\Type\ThisType) { return $traverse($type); } return $traverse($type->getStaticObjectType()); } return $traverse($type); }); } public function canAccessConstants() : TrinaryLogic { return $this->getStaticObjectType()->canAccessConstants(); } public function hasConstant(string $constantName) : TrinaryLogic { return $this->getStaticObjectType()->hasConstant($constantName); } public function getConstant(string $constantName) : ConstantReflection { return $this->getStaticObjectType()->getConstant($constantName); } public function changeBaseClass(ClassReflection $classReflection) : self { return new self($classReflection, $this->subtractedType); } public function isIterable() : TrinaryLogic { return $this->getStaticObjectType()->isIterable(); } public function isIterableAtLeastOnce() : TrinaryLogic { return $this->getStaticObjectType()->isIterableAtLeastOnce(); } public function getArraySize() : \PHPStan\Type\Type { return $this->getStaticObjectType()->getArraySize(); } public function getIterableKeyType() : \PHPStan\Type\Type { return $this->getStaticObjectType()->getIterableKeyType(); } public function getFirstIterableKeyType() : \PHPStan\Type\Type { return $this->getStaticObjectType()->getFirstIterableKeyType(); } public function getLastIterableKeyType() : \PHPStan\Type\Type { return $this->getStaticObjectType()->getLastIterableKeyType(); } public function getIterableValueType() : \PHPStan\Type\Type { return $this->getStaticObjectType()->getIterableValueType(); } public function getFirstIterableValueType() : \PHPStan\Type\Type { return $this->getStaticObjectType()->getFirstIterableValueType(); } public function getLastIterableValueType() : \PHPStan\Type\Type { return $this->getStaticObjectType()->getLastIterableValueType(); } public function isOffsetAccessible() : TrinaryLogic { return $this->getStaticObjectType()->isOffsetAccessible(); } public function isOffsetAccessLegal() : TrinaryLogic { return $this->getStaticObjectType()->isOffsetAccessLegal(); } public function hasOffsetValueType(\PHPStan\Type\Type $offsetType) : TrinaryLogic { return $this->getStaticObjectType()->hasOffsetValueType($offsetType); } public function getOffsetValueType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return $this->getStaticObjectType()->getOffsetValueType($offsetType); } public function setOffsetValueType(?\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType, bool $unionValues = \true) : \PHPStan\Type\Type { return $this->getStaticObjectType()->setOffsetValueType($offsetType, $valueType, $unionValues); } public function setExistingOffsetValueType(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return $this->getStaticObjectType()->setExistingOffsetValueType($offsetType, $valueType); } public function unsetOffset(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return $this->getStaticObjectType()->unsetOffset($offsetType); } public function getKeysArray() : \PHPStan\Type\Type { return $this->getStaticObjectType()->getKeysArray(); } public function getValuesArray() : \PHPStan\Type\Type { return $this->getStaticObjectType()->getValuesArray(); } public function chunkArray(\PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return $this->getStaticObjectType()->chunkArray($lengthType, $preserveKeys); } public function fillKeysArray(\PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return $this->getStaticObjectType()->fillKeysArray($valueType); } public function flipArray() : \PHPStan\Type\Type { return $this->getStaticObjectType()->flipArray(); } public function intersectKeyArray(\PHPStan\Type\Type $otherArraysType) : \PHPStan\Type\Type { return $this->getStaticObjectType()->intersectKeyArray($otherArraysType); } public function popArray() : \PHPStan\Type\Type { return $this->getStaticObjectType()->popArray(); } public function reverseArray(TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return $this->getStaticObjectType()->reverseArray($preserveKeys); } public function searchArray(\PHPStan\Type\Type $needleType) : \PHPStan\Type\Type { return $this->getStaticObjectType()->searchArray($needleType); } public function shiftArray() : \PHPStan\Type\Type { return $this->getStaticObjectType()->shiftArray(); } public function shuffleArray() : \PHPStan\Type\Type { return $this->getStaticObjectType()->shuffleArray(); } public function sliceArray(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return $this->getStaticObjectType()->sliceArray($offsetType, $lengthType, $preserveKeys); } public function isCallable() : TrinaryLogic { return $this->getStaticObjectType()->isCallable(); } public function getEnumCases() : array { return $this->getStaticObjectType()->getEnumCases(); } public function isArray() : TrinaryLogic { return $this->getStaticObjectType()->isArray(); } public function isConstantArray() : TrinaryLogic { return $this->getStaticObjectType()->isConstantArray(); } public function isOversizedArray() : TrinaryLogic { return $this->getStaticObjectType()->isOversizedArray(); } public function isList() : TrinaryLogic { return $this->getStaticObjectType()->isList(); } public function isNull() : TrinaryLogic { return $this->getStaticObjectType()->isNull(); } public function isConstantValue() : TrinaryLogic { return $this->getStaticObjectType()->isConstantValue(); } public function isConstantScalarValue() : TrinaryLogic { return $this->getStaticObjectType()->isConstantScalarValue(); } public function getConstantScalarTypes() : array { return $this->getStaticObjectType()->getConstantScalarTypes(); } public function getConstantScalarValues() : array { return $this->getStaticObjectType()->getConstantScalarValues(); } public function isTrue() : TrinaryLogic { return $this->getStaticObjectType()->isTrue(); } public function isFalse() : TrinaryLogic { return $this->getStaticObjectType()->isFalse(); } public function isBoolean() : TrinaryLogic { return $this->getStaticObjectType()->isBoolean(); } public function isFloat() : TrinaryLogic { return $this->getStaticObjectType()->isFloat(); } public function isInteger() : TrinaryLogic { return $this->getStaticObjectType()->isInteger(); } public function isString() : TrinaryLogic { return $this->getStaticObjectType()->isString(); } public function isNumericString() : TrinaryLogic { return $this->getStaticObjectType()->isNumericString(); } public function isNonEmptyString() : TrinaryLogic { return $this->getStaticObjectType()->isNonEmptyString(); } public function isNonFalsyString() : TrinaryLogic { return $this->getStaticObjectType()->isNonFalsyString(); } public function isLiteralString() : TrinaryLogic { return $this->getStaticObjectType()->isLiteralString(); } public function isLowercaseString() : TrinaryLogic { return $this->getStaticObjectType()->isLowercaseString(); } public function isUppercaseString() : TrinaryLogic { return $this->getStaticObjectType()->isUppercaseString(); } public function isClassStringType() : TrinaryLogic { return $this->getStaticObjectType()->isClassStringType(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return $this->getStaticObjectType()->getClassStringObjectType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return $this; } public function isVoid() : TrinaryLogic { return $this->getStaticObjectType()->isVoid(); } public function isScalar() : TrinaryLogic { return $this->getStaticObjectType()->isScalar(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { return $this->getStaticObjectType()->getCallableParametersAcceptors($scope); } public function isCloneable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function toNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toAbsoluteNumber() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toString() : \PHPStan\Type\Type { return $this->getStaticObjectType()->toString(); } public function toInteger() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toFloat() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function toArray() : \PHPStan\Type\Type { return $this->getStaticObjectType()->toArray(); } public function toArrayKey() : \PHPStan\Type\Type { return $this->getStaticObjectType()->toArrayKey(); } public function toBoolean() : \PHPStan\Type\BooleanType { return $this->getStaticObjectType()->toBoolean(); } public function traverse(callable $cb) : \PHPStan\Type\Type { $subtractedType = $this->subtractedType !== null ? $cb($this->subtractedType) : null; if ($subtractedType !== $this->subtractedType) { return new self($this->classReflection, $subtractedType); } return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if ($this->subtractedType === null) { return $this; } return new self($this->classReflection); } public function subtract(\PHPStan\Type\Type $type) : \PHPStan\Type\Type { if ($this->subtractedType !== null) { $type = \PHPStan\Type\TypeCombinator::union($this->subtractedType, $type); } return $this->changeSubtractedType($type); } public function getTypeWithoutSubtractedType() : \PHPStan\Type\Type { return $this->changeSubtractedType(null); } public function changeSubtractedType(?\PHPStan\Type\Type $subtractedType) : \PHPStan\Type\Type { if ($subtractedType !== null) { $classReflection = $this->getClassReflection(); if ($classReflection->getAllowedSubTypes() !== null) { $objectType = $this->getStaticObjectType()->changeSubtractedType($subtractedType); if ($objectType instanceof \PHPStan\Type\NeverType) { return $objectType; } if ($objectType instanceof \PHPStan\Type\ObjectType && $objectType->getSubtractedType() !== null) { return new self($classReflection, $objectType->getSubtractedType()); } return \PHPStan\Type\TypeCombinator::intersect($this, $objectType); } } return new self($this->classReflection, $subtractedType); } public function getSubtractedType() : ?\PHPStan\Type\Type { return $this->subtractedType; } public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type { if ($this->getStaticObjectType()->isSuperTypeOf($typeToRemove)->yes()) { return $this->subtract($typeToRemove); } return null; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return $this->getStaticObjectType()->exponentiate($exponent); } public function getFiniteTypes() : array { return $this->getStaticObjectType()->getFiniteTypes(); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('static'); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if ($reflectionProvider->hasClass($properties['baseClass'])) { return new self($reflectionProvider->getClass($properties['baseClass']), $properties['subtractedType'] ?? null); } return new \PHPStan\Type\ErrorType(); } } */ public $reasons; /** * @api * @param list $reasons */ public function __construct(TrinaryLogic $result, array $reasons) { $this->result = $result; $this->reasons = $reasons; } public function yes() : bool { return $this->result->yes(); } public function maybe() : bool { return $this->result->maybe(); } public function no() : bool { return $this->result->no(); } public static function createYes() : self { return new self(TrinaryLogic::createYes(), []); } /** * @param list $reasons */ public static function createNo(array $reasons = []) : self { return new self(TrinaryLogic::createNo(), $reasons); } public static function createMaybe() : self { return new self(TrinaryLogic::createMaybe(), []); } public static function createFromBoolean(bool $value) : self { return new self(TrinaryLogic::createFromBoolean($value), []); } public function toAcceptsResult() : \PHPStan\Type\AcceptsResult { return new \PHPStan\Type\AcceptsResult($this->result, $this->reasons); } public function and(self ...$others) : self { $results = []; $reasons = []; foreach ($others as $other) { $results[] = $other->result; $reasons[] = $other->reasons; } return new self($this->result->and(...$results), array_values(array_unique(array_merge($this->reasons, ...$reasons)))); } public function or(self ...$others) : self { $results = []; $reasons = []; foreach ($others as $other) { $results[] = $other->result; $reasons[] = $other->reasons; } return new self($this->result->or(...$results), array_values(array_unique(array_merge($this->reasons, ...$reasons)))); } /** * @param callable(string): string $cb */ public function decorateReasons(callable $cb) : self { $reasons = []; foreach ($this->reasons as $reason) { $reasons[] = $cb($reason); } return new self($this->result, $reasons); } public static function extremeIdentity(self ...$operands) : self { if ($operands === []) { throw new ShouldNotHappenException(); } $result = TrinaryLogic::extremeIdentity(...array_map(static function (self $result) { return $result->result; }, $operands)); return new self($result, self::mergeReasons($operands)); } public static function maxMin(self ...$operands) : self { if ($operands === []) { throw new ShouldNotHappenException(); } $result = TrinaryLogic::maxMin(...array_map(static function (self $result) { return $result->result; }, $operands)); return new self($result, self::mergeReasons($operands)); } public function negate() : self { return new self($this->result->negate(), $this->reasons); } /** * @param array $operands * * @return list */ private static function mergeReasons(array $operands) : array { $reasons = []; foreach ($operands as $operand) { foreach ($operand->reasons as $reason) { $reasons[] = $reason; } } return array_values(array_unique($reasons)); } } */ private $properties; /** * @var list */ private $optionalProperties; use ObjectTypeTrait; use UndecidedComparisonTypeTrait; use NonGeneralizableTypeTrait; /** * @api * @param array $properties * @param list $optionalProperties */ public function __construct(array $properties, array $optionalProperties) { $this->properties = $properties; $this->optionalProperties = $optionalProperties; } /** * @return array */ public function getProperties() : array { return $this->properties; } /** * @return list */ public function getOptionalProperties() : array { return $this->optionalProperties; } public function getReferencedClasses() : array { $classes = []; foreach ($this->properties as $propertyType) { foreach ($propertyType->getReferencedClasses() as $referencedClass) { $classes[] = $referencedClass; } } return $classes; } public function getObjectClassNames() : array { return []; } public function getObjectClassReflections() : array { return []; } public function hasProperty(string $propertyName) : TrinaryLogic { if (!array_key_exists($propertyName, $this->properties)) { return TrinaryLogic::createNo(); } if (in_array($propertyName, $this->optionalProperties, \true)) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createYes(); } public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection { return $this->getUnresolvedPropertyPrototype($propertyName, $scope)->getTransformedProperty(); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { if (!array_key_exists($propertyName, $this->properties)) { throw new ShouldNotHappenException(); } $property = new \PHPStan\Type\ObjectShapePropertyReflection($this->properties[$propertyName]); return new CallbackUnresolvedPropertyPrototypeReflection($property, $property->getDeclaringClass(), \false, static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type; }); } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); foreach ($type->getObjectClassReflections() as $classReflection) { if (!UniversalObjectCratesClassReflectionExtension::isUniversalObjectCrate($reflectionProvider, Broker::getInstance()->getUniversalObjectCratesClasses(), $classReflection)) { continue; } return \PHPStan\Type\AcceptsResult::createMaybe(); } $result = \PHPStan\Type\AcceptsResult::createYes(); $scope = new OutOfClassScope(); foreach ($this->properties as $propertyName => $propertyType) { $typeHasProperty = $type->hasProperty($propertyName); $hasProperty = new \PHPStan\Type\AcceptsResult($typeHasProperty, $typeHasProperty->yes() ? [] : [sprintf('%s %s have property $%s.', $type->describe(\PHPStan\Type\VerbosityLevel::typeOnly()), $typeHasProperty->no() ? 'does not' : 'might not', $propertyName)]); if ($hasProperty->no()) { if (in_array($propertyName, $this->optionalProperties, \true)) { continue; } return $hasProperty; } if ($hasProperty->maybe() && in_array($propertyName, $this->optionalProperties, \true)) { $hasProperty = \PHPStan\Type\AcceptsResult::createYes(); } $result = $result->and($hasProperty); try { $otherProperty = $type->getProperty($propertyName, $scope); } catch (MissingPropertyFromReflectionException $e) { return new \PHPStan\Type\AcceptsResult($result->result, [sprintf('%s %s not have property $%s.', $type->describe(\PHPStan\Type\VerbosityLevel::typeOnly()), $result->no() ? 'does' : 'might', $propertyName)]); } if (!$otherProperty->isPublic()) { return new \PHPStan\Type\AcceptsResult(TrinaryLogic::createNo(), [sprintf('Property %s::$%s is not public.', $otherProperty->getDeclaringClass()->getDisplayName(), $propertyName)]); } if ($otherProperty->isStatic()) { return new \PHPStan\Type\AcceptsResult(TrinaryLogic::createNo(), [sprintf('Property %s::$%s is static.', $otherProperty->getDeclaringClass()->getDisplayName(), $propertyName)]); } if (!$otherProperty->isReadable()) { return new \PHPStan\Type\AcceptsResult(TrinaryLogic::createNo(), [sprintf('Property %s::$%s is not readable.', $otherProperty->getDeclaringClass()->getDisplayName(), $propertyName)]); } $otherPropertyType = $otherProperty->getReadableType(); $verbosity = \PHPStan\Type\VerbosityLevel::getRecommendedLevelByType($propertyType, $otherPropertyType); $acceptsValue = $propertyType->acceptsWithReason($otherPropertyType, $strictTypes)->decorateReasons(static function (string $reason) use($propertyName, $propertyType, $verbosity, $otherPropertyType) { return sprintf('Property ($%s) type %s does not accept type %s: %s', $propertyName, $propertyType->describe($verbosity), $otherPropertyType->describe($verbosity), $reason); }); if (!$acceptsValue->yes() && count($acceptsValue->reasons) === 0) { $acceptsValue = new \PHPStan\Type\AcceptsResult($acceptsValue->result, [sprintf('Property ($%s) type %s does not accept type %s.', $propertyName, $propertyType->describe($verbosity), $otherPropertyType->describe($verbosity))]); } if ($acceptsValue->no()) { return $acceptsValue; } $result = $result->and($acceptsValue); } return $result->and(new \PHPStan\Type\AcceptsResult($type->isObject(), [])); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } if ($type instanceof \PHPStan\Type\ObjectWithoutClassType) { return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); foreach ($type->getObjectClassReflections() as $classReflection) { if (!UniversalObjectCratesClassReflectionExtension::isUniversalObjectCrate($reflectionProvider, Broker::getInstance()->getUniversalObjectCratesClasses(), $classReflection)) { continue; } return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } $result = \PHPStan\Type\IsSuperTypeOfResult::createYes(); $scope = new OutOfClassScope(); foreach ($this->properties as $propertyName => $propertyType) { $hasProperty = new \PHPStan\Type\IsSuperTypeOfResult($type->hasProperty($propertyName), []); if ($hasProperty->no()) { if (in_array($propertyName, $this->optionalProperties, \true)) { continue; } return $hasProperty; } if ($hasProperty->maybe() && in_array($propertyName, $this->optionalProperties, \true)) { $hasProperty = \PHPStan\Type\IsSuperTypeOfResult::createYes(); } $result = $result->and($hasProperty); try { $otherProperty = $type->getProperty($propertyName, $scope); } catch (MissingPropertyFromReflectionException $e) { return $result; } if (!$otherProperty->isPublic()) { return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } if ($otherProperty->isStatic()) { return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } if (!$otherProperty->isReadable()) { return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } $otherPropertyType = $otherProperty->getReadableType(); $isSuperType = $propertyType->isSuperTypeOfWithReason($otherPropertyType); if ($isSuperType->no()) { return $isSuperType; } $result = $result->and($isSuperType); } return $result->and(new \PHPStan\Type\IsSuperTypeOfResult($type->isObject(), [])); } public function equals(\PHPStan\Type\Type $type) : bool { if (!$type instanceof self) { return \false; } if (count($this->properties) !== count($type->properties)) { return \false; } foreach ($this->properties as $name => $propertyType) { if (!array_key_exists($name, $type->properties)) { return \false; } if (!$propertyType->equals($type->properties[$name])) { return \false; } } if (count($this->optionalProperties) !== count($type->optionalProperties)) { return \false; } foreach ($this->optionalProperties as $name) { if (in_array($name, $type->optionalProperties, \true)) { continue; } return \false; } return \true; } public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type { if ($typeToRemove instanceof HasPropertyType) { $properties = $this->properties; unset($properties[$typeToRemove->getPropertyName()]); $optionalProperties = array_values(array_filter($this->optionalProperties, static function (string $propertyName) use($typeToRemove) { return $propertyName !== $typeToRemove->getPropertyName(); })); return new self($properties, $optionalProperties); } return null; } public function makePropertyRequired(string $propertyName) : self { if (array_key_exists($propertyName, $this->properties)) { $optionalProperties = array_values(array_filter($this->optionalProperties, static function (string $currentPropertyName) use($propertyName) { return $currentPropertyName !== $propertyName; })); return new self($this->properties, $optionalProperties); } return $this; } public function inferTemplateTypes(\PHPStan\Type\Type $receivedType) : TemplateTypeMap { if ($receivedType instanceof \PHPStan\Type\UnionType || $receivedType instanceof \PHPStan\Type\IntersectionType) { return $receivedType->inferTemplateTypesOn($this); } if ($receivedType instanceof self) { $typeMap = TemplateTypeMap::createEmpty(); $scope = new OutOfClassScope(); foreach ($this->properties as $name => $propertyType) { if ($receivedType->hasProperty($name)->no()) { continue; } try { $receivedProperty = $receivedType->getProperty($name, $scope); } catch (MissingPropertyFromReflectionException $e) { continue; } if (!$receivedProperty->isPublic()) { continue; } if ($receivedProperty->isStatic()) { continue; } $receivedPropertyType = $receivedProperty->getReadableType(); $typeMap = $typeMap->union($propertyType->inferTemplateTypes($receivedPropertyType)); } return $typeMap; } return TemplateTypeMap::createEmpty(); } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { $variance = $positionVariance->compose(TemplateTypeVariance::createCovariant()); $references = []; foreach ($this->properties as $propertyType) { foreach ($propertyType->getReferencedTemplateTypes($variance) as $reference) { $references[] = $reference; } } return $references; } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { $callback = function () use($level) : string { $items = []; foreach ($this->properties as $name => $propertyType) { $optional = in_array($name, $this->optionalProperties, \true); $items[] = sprintf('%s%s: %s', $name, $optional ? '?' : '', $propertyType->describe($level)); } return sprintf('object{%s}', implode(', ', $items)); }; return $level->handle($callback, $callback); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getEnumCases() : array { return []; } public function traverse(callable $cb) : \PHPStan\Type\Type { $properties = []; $stillOriginal = \true; foreach ($this->properties as $name => $propertyType) { $transformed = $cb($propertyType); if ($transformed !== $propertyType) { $stillOriginal = \false; } $properties[$name] = $transformed; } if ($stillOriginal) { return $this; } return new self($properties, $this->optionalProperties); } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if (!$right->isObject()->yes()) { return $this; } $properties = []; $stillOriginal = \true; $scope = new OutOfClassScope(); foreach ($this->properties as $name => $propertyType) { if (!$right->hasProperty($name)->yes()) { return $this; } $transformed = $cb($propertyType, $right->getProperty($name, $scope)->getReadableType()); if ($transformed !== $propertyType) { $stillOriginal = \false; } $properties[$name] = $transformed; } if ($stillOriginal) { return $this; } return new self($properties, $this->optionalProperties); } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { if (!$exponent instanceof \PHPStan\Type\NeverType && !$this->isSuperTypeOf($exponent)->no()) { return \PHPStan\Type\TypeCombinator::union($this, $exponent); } return new \PHPStan\Type\BenevolentUnionType([new \PHPStan\Type\FloatType(), new \PHPStan\Type\IntegerType()]); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { $items = []; foreach ($this->properties as $name => $type) { if (ConstantArrayType::isValidIdentifier($name)) { $keyNode = new IdentifierTypeNode($name); } else { $keyPhpDocNode = (new ConstantStringType($name))->toPhpDocNode(); if (!$keyPhpDocNode instanceof ConstTypeNode) { continue; } /** @var ConstExprStringNode $keyNode */ $keyNode = $keyPhpDocNode->constExpr; } $items[] = new ObjectShapeItemNode($keyNode, in_array($name, $this->optionalProperties, \true), $type->toPhpDocNode()); } return new ObjectShapeNode($items); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['properties'], $properties['optionalProperties']); } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, StrictMixedType $bound, ?Type $default) { $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } public function isSuperTypeOfMixed(MixedType $type) : TrinaryLogic { return $this->isSuperTypeOf($type); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; use UndecidedComparisonCompoundTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, ArrayType $bound, ?Type $default) { parent::__construct($bound->getKeyType(), $bound->getItemType()); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } protected function shouldGeneralizeInferredType() : bool { return \false; } } */ private $types; /** * @var ?ClassReflection */ private $classReflection; /** * @var array */ private $variances; /** * @api * @param array $types * @param array $variances */ public function __construct(string $mainType, array $types, ?Type $subtractedType = null, ?ClassReflection $classReflection = null, array $variances = []) { $this->types = $types; $this->classReflection = $classReflection; $this->variances = $variances; parent::__construct($mainType, $subtractedType, $classReflection); } public function describe(VerbosityLevel $level) : string { return sprintf('%s<%s>', parent::describe($level), implode(', ', array_map(static function (Type $type, ?\PHPStan\Type\Generic\TemplateTypeVariance $variance = null) use($level) : string { return \PHPStan\Type\Generic\TypeProjectionHelper::describe($type, $variance, $level); }, $this->types, $this->variances))); } public function equals(Type $type) : bool { if (!$type instanceof self) { return \false; } if (!parent::equals($type)) { return \false; } if (count($this->types) !== count($type->types)) { return \false; } foreach ($this->types as $i => $genericType) { $otherGenericType = $type->types[$i]; if (!$genericType->equals($otherGenericType)) { return \false; } $variance = $this->variances[$i] ?? \PHPStan\Type\Generic\TemplateTypeVariance::createInvariant(); $otherVariance = $type->variances[$i] ?? \PHPStan\Type\Generic\TemplateTypeVariance::createInvariant(); if (!$variance->equals($otherVariance)) { return \false; } } return \true; } /** * @return string[] */ public function getReferencedClasses() : array { $classes = parent::getReferencedClasses(); foreach ($this->types as $type) { foreach ($type->getReferencedClasses() as $referencedClass) { $classes[] = $referencedClass; } } return $classes; } /** @return array */ public function getTypes() : array { return $this->types; } /** @return array */ public function getVariances() : array { return $this->variances; } public function accepts(Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return $this->isSuperTypeOfInternal($type, \true)->toAcceptsResult(); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } return $this->isSuperTypeOfInternal($type, \false); } private function isSuperTypeOfInternal(Type $type, bool $acceptsContext) : IsSuperTypeOfResult { $nakedSuperTypeOf = parent::isSuperTypeOfWithReason($type); if ($nakedSuperTypeOf->no()) { return $nakedSuperTypeOf; } if (!$type instanceof ObjectType) { return $nakedSuperTypeOf; } $ancestor = $type->getAncestorWithClassName($this->getClassName()); if ($ancestor === null) { return $nakedSuperTypeOf; } if (!$ancestor instanceof self) { if ($acceptsContext) { return $nakedSuperTypeOf; } return $nakedSuperTypeOf->and(IsSuperTypeOfResult::createMaybe()); } if (count($this->types) !== count($ancestor->types)) { return IsSuperTypeOfResult::createNo(); } $classReflection = $this->getClassReflection(); if ($classReflection === null) { return $nakedSuperTypeOf; } $typeList = $classReflection->typeMapToList($classReflection->getTemplateTypeMap()); $results = []; foreach ($typeList as $i => $templateType) { if (!isset($ancestor->types[$i])) { continue; } if (!isset($this->types[$i])) { continue; } if ($templateType instanceof ErrorType) { continue; } if (!$templateType instanceof \PHPStan\Type\Generic\TemplateType) { throw new ShouldNotHappenException(); } $thisVariance = $this->variances[$i] ?? \PHPStan\Type\Generic\TemplateTypeVariance::createInvariant(); $ancestorVariance = $ancestor->variances[$i] ?? \PHPStan\Type\Generic\TemplateTypeVariance::createInvariant(); if (!$thisVariance->invariant()) { $result = $thisVariance->isValidVarianceWithReason($templateType, $this->types[$i], $ancestor->types[$i]); $results[] = new IsSuperTypeOfResult($result->result, $result->reasons); } else { $result = $templateType->isValidVarianceWithReason($this->types[$i], $ancestor->types[$i]); $results[] = new IsSuperTypeOfResult($result->result, $result->reasons); } $results[] = IsSuperTypeOfResult::createFromBoolean($thisVariance->validPosition($ancestorVariance)); } if (count($results) === 0) { return $nakedSuperTypeOf; } $result = IsSuperTypeOfResult::createYes(); foreach ($results as $innerResult) { $result = $result->and($innerResult); } return $result; } public function getClassReflection() : ?ClassReflection { if ($this->classReflection !== null) { return $this->classReflection; } $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if (!$reflectionProvider->hasClass($this->getClassName())) { return null; } return $this->classReflection = $reflectionProvider->getClass($this->getClassName())->withTypes($this->types)->withVariances($this->variances); } public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection { return $this->getUnresolvedPropertyPrototype($propertyName, $scope)->getTransformedProperty(); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { $prototype = parent::getUnresolvedPropertyPrototype($propertyName, $scope); return $prototype->doNotResolveTemplateTypeMapToBounds(); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { return $this->getUnresolvedMethodPrototype($methodName, $scope)->getTransformedMethod(); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { $prototype = parent::getUnresolvedMethodPrototype($methodName, $scope); return $prototype->doNotResolveTemplateTypeMapToBounds(); } public function inferTemplateTypes(Type $receivedType) : \PHPStan\Type\Generic\TemplateTypeMap { if ($receivedType instanceof UnionType || $receivedType instanceof IntersectionType) { return $receivedType->inferTemplateTypesOn($this); } if (!$receivedType instanceof TypeWithClassName) { return \PHPStan\Type\Generic\TemplateTypeMap::createEmpty(); } $ancestor = $receivedType->getAncestorWithClassName($this->getClassName()); if ($ancestor === null) { return \PHPStan\Type\Generic\TemplateTypeMap::createEmpty(); } $ancestorClassReflection = $ancestor->getClassReflection(); if ($ancestorClassReflection === null) { return \PHPStan\Type\Generic\TemplateTypeMap::createEmpty(); } $otherTypes = $ancestorClassReflection->typeMapToList($ancestorClassReflection->getActiveTemplateTypeMap()); $typeMap = \PHPStan\Type\Generic\TemplateTypeMap::createEmpty(); foreach ($this->getTypes() as $i => $type) { $other = $otherTypes[$i] ?? new ErrorType(); $typeMap = $typeMap->union($type->inferTemplateTypes($other)); } return $typeMap; } public function getReferencedTemplateTypes(\PHPStan\Type\Generic\TemplateTypeVariance $positionVariance) : array { $classReflection = $this->getClassReflection(); if ($classReflection !== null) { $typeList = $classReflection->typeMapToList($classReflection->getTemplateTypeMap()); } else { $typeList = []; } $references = []; foreach ($this->types as $i => $type) { $effectiveVariance = $this->variances[$i] ?? \PHPStan\Type\Generic\TemplateTypeVariance::createInvariant(); if ($effectiveVariance->invariant() && isset($typeList[$i]) && $typeList[$i] instanceof \PHPStan\Type\Generic\TemplateType) { $effectiveVariance = $typeList[$i]->getVariance(); } $variance = $positionVariance->compose($effectiveVariance); foreach ($type->getReferencedTemplateTypes($variance) as $reference) { $references[] = $reference; } } return $references; } public function traverse(callable $cb) : Type { $subtractedType = $this->getSubtractedType() !== null ? $cb($this->getSubtractedType()) : null; $typesChanged = \false; $types = []; foreach ($this->types as $type) { $newType = $cb($type); $types[] = $newType; if ($newType === $type) { continue; } $typesChanged = \true; } if ($subtractedType !== $this->getSubtractedType() || $typesChanged) { return $this->recreate($this->getClassName(), $types, $subtractedType, $this->variances); } return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { if (!$right instanceof TypeWithClassName) { return $this; } $ancestor = $right->getAncestorWithClassName($this->getClassName()); if (!$ancestor instanceof self) { return $this; } if (count($this->types) !== count($ancestor->types)) { return $this; } $typesChanged = \false; $types = []; foreach ($this->types as $i => $leftType) { $rightType = $ancestor->types[$i]; $newType = $cb($leftType, $rightType); $types[] = $newType; if ($newType === $leftType) { continue; } $typesChanged = \true; } if ($typesChanged) { return $this->recreate($this->getClassName(), $types, null); } return $this; } /** * @param Type[] $types * @param TemplateTypeVariance[] $variances */ protected function recreate(string $className, array $types, ?Type $subtractedType, array $variances = []) : self { return new self($className, $types, $subtractedType, null, $variances); } public function changeSubtractedType(?Type $subtractedType) : Type { return new self($this->getClassName(), $this->types, $subtractedType, null, $this->variances); } public function toPhpDocNode() : TypeNode { /** @var IdentifierTypeNode $parent */ $parent = parent::toPhpDocNode(); return new GenericTypeNode($parent, array_map(static function (Type $type) { return $type->toPhpDocNode(); }, $this->types), array_map(static function (\PHPStan\Type\Generic\TemplateTypeVariance $variance) { return $variance->toPhpDocNodeVariance(); }, $this->variances)); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : Type { return new self($properties['className'], $properties['types'], $properties['subtractedType'] ?? null, null, $properties['variances'] ?? []); } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, UnionType $bound, ?Type $default) { parent::__construct($bound->getTypes()); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } public function filterTypes(callable $filterCb) : Type { $result = parent::filterTypes($filterCb); if (!$result instanceof \PHPStan\Type\Generic\TemplateType) { return \PHPStan\Type\Generic\TemplateTypeFactory::create($this->getScope(), $this->getName(), $result, $this->getVariance(), $this->getStrategy(), $this->getDefault()); } return $result; } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, IntersectionType $bound, ?Type $default) { parent::__construct($bound->getTypes()); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } } */ private $types; /** * @var array */ private $lowerBoundTypes; /** * @var ?TemplateTypeMap */ private static $empty = null; /** * @var ?TemplateTypeMap */ private $resolvedToBounds = null; /** * @api * @param array $types * @param array $lowerBoundTypes */ public function __construct(array $types, array $lowerBoundTypes = []) { $this->types = $types; $this->lowerBoundTypes = $lowerBoundTypes; } public function convertToLowerBoundTypes() : self { $lowerBoundTypes = $this->types; foreach ($this->lowerBoundTypes as $name => $type) { if (isset($lowerBoundTypes[$name])) { $intersection = TypeCombinator::intersect($lowerBoundTypes[$name], $type); if ($intersection instanceof NeverType) { continue; } $lowerBoundTypes[$name] = $intersection; } else { $lowerBoundTypes[$name] = $type; } } return new self([], $lowerBoundTypes); } public static function createEmpty() : self { $empty = self::$empty; if ($empty !== null) { return $empty; } $empty = new self([], []); self::$empty = $empty; return $empty; } public function isEmpty() : bool { return $this->count() === 0; } public function count() : int { return count($this->types + $this->lowerBoundTypes); } /** @return array */ public function getTypes() : array { $types = $this->types; foreach ($this->lowerBoundTypes as $name => $type) { if (array_key_exists($name, $types)) { continue; } $types[$name] = $type; } return $types; } public function hasType(string $name) : bool { return array_key_exists($name, $this->getTypes()); } public function getType(string $name) : ?Type { return $this->getTypes()[$name] ?? null; } public function unsetType(string $name) : self { if (!$this->hasType($name)) { return $this; } $types = $this->types; $lowerBoundTypes = $this->lowerBoundTypes; unset($types[$name]); unset($lowerBoundTypes[$name]); if (count($types) === 0 && count($lowerBoundTypes) === 0) { return self::createEmpty(); } return new self($types, $lowerBoundTypes); } public function union(self $other) : self { $result = $this->types; foreach ($other->types as $name => $type) { if (isset($result[$name])) { $result[$name] = TypeCombinator::union($result[$name], $type); } else { $result[$name] = $type; } } $resultLowerBoundTypes = $this->lowerBoundTypes; foreach ($other->lowerBoundTypes as $name => $type) { if (isset($resultLowerBoundTypes[$name])) { $intersection = TypeCombinator::intersect($resultLowerBoundTypes[$name], $type); if ($intersection instanceof NeverType) { continue; } $resultLowerBoundTypes[$name] = $intersection; } else { $resultLowerBoundTypes[$name] = $type; } } return new self($result, $resultLowerBoundTypes); } public function benevolentUnion(self $other) : self { $result = $this->types; foreach ($other->types as $name => $type) { if (isset($result[$name])) { $result[$name] = TypeUtils::toBenevolentUnion(TypeCombinator::union($result[$name], $type)); } else { $result[$name] = $type; } } $resultLowerBoundTypes = $this->lowerBoundTypes; foreach ($other->lowerBoundTypes as $name => $type) { if (isset($resultLowerBoundTypes[$name])) { $intersection = TypeCombinator::intersect($resultLowerBoundTypes[$name], $type); if ($intersection instanceof NeverType) { continue; } $resultLowerBoundTypes[$name] = $intersection; } else { $resultLowerBoundTypes[$name] = $type; } } return new self($result, $resultLowerBoundTypes); } public function intersect(self $other) : self { $result = $this->types; foreach ($other->types as $name => $type) { if (isset($result[$name])) { $result[$name] = TypeCombinator::intersect($result[$name], $type); } else { $result[$name] = $type; } } $resultLowerBoundTypes = $this->lowerBoundTypes; foreach ($other->lowerBoundTypes as $name => $type) { if (isset($resultLowerBoundTypes[$name])) { $resultLowerBoundTypes[$name] = TypeCombinator::union($resultLowerBoundTypes[$name], $type); } else { $resultLowerBoundTypes[$name] = $type; } } return new self($result, $resultLowerBoundTypes); } /** @param callable(string,Type):Type $cb */ public function map(callable $cb) : self { $types = []; foreach ($this->getTypes() as $name => $type) { $types[$name] = $cb($name, $type); } return new self($types); } public function resolveToBounds() : self { if ($this->resolvedToBounds !== null) { return $this->resolvedToBounds; } return $this->resolvedToBounds = $this->map(static function (string $name, Type $type) : Type { return TypeTraverser::map($type, static function (Type $type, callable $traverse) : Type { return $type instanceof \PHPStan\Type\Generic\TemplateType ? $traverse($type->getDefault() ?? $type->getBound()) : $traverse($type); }); }); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self { return new self($properties['types'], $properties['lowerBoundTypes'] ?? []); } } getReferencedTemplateTypes($positionVariance); return TypeTraverser::map($type, static function (Type $type, callable $traverse) use($standins, $references, $callSiteVariances, $keepErrorTypes) : Type { if ($type instanceof \PHPStan\Type\Generic\TemplateType && !$type->isArgument()) { $newType = $standins->getType($type->getName()); $variance = \PHPStan\Type\Generic\TemplateTypeVariance::createInvariant(); foreach ($references as $reference) { // this uses identity to distinguish between different occurrences of the same template type // see https://github.com/phpstan/phpstan-src/pull/2485#discussion_r1328555397 for details if ($reference->getType() === $type) { $variance = $reference->getPositionVariance(); break; } } if ($newType === null) { return $traverse($type); } if ($newType instanceof ErrorType && !$keepErrorTypes) { return $traverse($type->getDefault() ?? $type->getBound()); } $callSiteVariance = $callSiteVariances->getVariance($type->getName()); if ($callSiteVariance === null || $callSiteVariance->invariant()) { return $newType; } if (!$callSiteVariance->covariant() && $variance->covariant()) { return $traverse($type->getBound()); } if (!$callSiteVariance->contravariant() && $variance->contravariant()) { return new NonAcceptingNeverType(); } return $newType; } return $traverse($type); }); } public static function resolveToDefaults(Type $type) : Type { return TypeTraverser::map($type, static function (Type $type, callable $traverse) : Type { if ($type instanceof \PHPStan\Type\Generic\TemplateType) { return $traverse($type->getDefault() ?? $type->getBound()); } return $traverse($type); }); } public static function resolveToBounds(Type $type) : Type { return TypeTraverser::map($type, static function (Type $type, callable $traverse) : Type { if ($type instanceof \PHPStan\Type\Generic\TemplateType) { return $traverse($type->getBound()); } return $traverse($type); }); } /** * @template T of Type * @param T $type * @return T */ public static function toArgument(Type $type) : Type { $ownedTemplates = []; /** @var T */ return TypeTraverser::map($type, static function (Type $type, callable $traverse) use(&$ownedTemplates) : Type { if ($type instanceof ParametersAcceptor) { $templateTypeMap = $type->getTemplateTypeMap(); foreach ($type->getParameters() as $parameter) { $parameterType = $parameter->getType(); if (!$parameterType instanceof \PHPStan\Type\Generic\TemplateType || !$templateTypeMap->hasType($parameterType->getName())) { continue; } $ownedTemplates[] = $parameterType; } $returnType = $type->getReturnType(); if ($returnType instanceof \PHPStan\Type\Generic\TemplateType && $templateTypeMap->hasType($returnType->getName())) { $ownedTemplates[] = $returnType; } } foreach ($ownedTemplates as $ownedTemplate) { if ($ownedTemplate === $type) { return $traverse($type); } } if ($type instanceof \PHPStan\Type\Generic\TemplateType) { return $traverse($type->toArgument()); } return $traverse($type); }); } public static function generalizeInferredTemplateType(\PHPStan\Type\Generic\TemplateType $templateType, Type $type) : Type { if (!$templateType->getVariance()->covariant()) { $isArrayKey = $templateType->getBound()->describe(VerbosityLevel::precise()) === '(int|string)'; if ($type->isScalar()->yes() && $isArrayKey) { $type = $type->generalize(GeneralizePrecision::templateArgument()); } elseif ($type->isConstantValue()->yes() && (!$templateType->getBound()->isScalar()->yes() || $isArrayKey)) { $type = $type->generalize(GeneralizePrecision::templateArgument()); } } return $type; } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; use UndecidedComparisonCompoundTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, KeyOfType $bound, ?Type $default) { parent::__construct($bound->getType()); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } protected function getResult() : Type { $result = $this->getBound()->getResult(); return \PHPStan\Type\Generic\TemplateTypeFactory::create($this->getScope(), $this->getName(), $result, $this->getVariance(), $this->getStrategy(), $this->getDefault()); } protected function shouldGeneralizeInferredType() : bool { return \false; } } isAcceptedWithReasonBy($left, $strictTypes); } else { $accepts = $left->getBound()->acceptsWithReason($right, $strictTypes)->and(AcceptsResult::createMaybe()); if ($accepts->maybe()) { $verbosity = VerbosityLevel::getRecommendedLevelByType($left, $right); return new AcceptsResult($accepts->result, array_merge($accepts->reasons, [sprintf('Type %s is not always the same as %s. It breaks the contract for some argument types, typically subtypes.', $right->describe($verbosity), $left->getName())])); } } return $accepts; } public function isArgument() : bool { return \true; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self { return new self(); } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, ObjectType $bound, ?Type $default) { parent::__construct($bound->getClassName()); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } } */ private $types; /** * @var ?Type */ private $subtractedType; /** * @var array */ private $variances; /** * @var ?ObjectType */ private $staticObjectType = null; /** * @var string */ private $baseClass; /** * @api * @param array $types * @param array $variances */ public function __construct(ClassReflection $classReflection, array $types, ?Type $subtractedType, array $variances) { $this->classReflection = $classReflection; $this->types = $types; $this->subtractedType = $subtractedType; $this->variances = $variances; if (count($this->types) === 0) { throw new ShouldNotHappenException('Cannot create GenericStaticType with zero types.'); } parent::__construct($classReflection, $subtractedType); $this->baseClass = $classReflection->getName(); } public function getClassName() : string { return $this->baseClass; } /** * @return array */ public function getTypes() : array { return $this->types; } /** @return array */ public function getVariances() : array { return $this->variances; } public function getStaticObjectType() : ObjectType { if ($this->staticObjectType === null) { if ($this->classReflection->isGeneric()) { return $this->staticObjectType = new \PHPStan\Type\Generic\GenericObjectType($this->classReflection->getName(), $this->types, $this->subtractedType, $this->classReflection, $this->variances); } return $this->staticObjectType = parent::getStaticObjectType(); } return $this->staticObjectType; } public function changeBaseClass(ClassReflection $classReflection) : StaticType { if ($classReflection->getName() === $this->getClassName()) { return $this; } if (!$classReflection->isGeneric()) { return new StaticType($classReflection); } $templateTags = $this->getClassReflection()->getTemplateTags(); $i = 0; $indexedTypes = []; $indexedVariances = []; foreach ($templateTags as $typeName => $tag) { if (!array_key_exists($i, $this->types)) { break; } if (!array_key_exists($i, $this->variances)) { break; } $indexedTypes[$typeName] = $this->types[$i]; $indexedVariances[$typeName] = $this->variances[$i]; $i++; } $newType = new \PHPStan\Type\Generic\GenericObjectType($classReflection->getName(), $classReflection->typeMapToList($classReflection->getTemplateTypeMap())); $ancestorType = $newType->getAncestorWithClassName($this->getClassName()); if ($ancestorType === null) { return new self($classReflection, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()), $this->subtractedType, $classReflection->varianceMapToList($classReflection->getCallSiteVarianceMap())); } $ancestorClassReflection = $ancestorType->getClassReflection(); if ($ancestorClassReflection === null) { return new self($classReflection, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()), $this->subtractedType, $classReflection->varianceMapToList($classReflection->getCallSiteVarianceMap())); } $newClassTypes = []; $newClassVariances = []; foreach ($ancestorClassReflection->getActiveTemplateTypeMap()->getTypes() as $typeName => $templateType) { if (!$templateType instanceof \PHPStan\Type\Generic\TemplateType) { continue; } if (!array_key_exists($typeName, $indexedTypes)) { continue; } $newClassTypes[$templateType->getName()] = $indexedTypes[$typeName]; $newClassVariances[$templateType->getName()] = $indexedVariances[$typeName]; } return new self($classReflection, $classReflection->typeMapToList(new \PHPStan\Type\Generic\TemplateTypeMap($newClassTypes)), $this->subtractedType, $classReflection->varianceMapToList(new \PHPStan\Type\Generic\TemplateTypeVarianceMap($newClassVariances))); } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } if ($type instanceof self) { return $this->getStaticObjectType()->isSuperTypeOfWithReason($type->getStaticObjectType()); } return parent::isSuperTypeOfWithReason($type)->and(IsSuperTypeOfResult::createMaybe()); } public function traverse(callable $cb) : Type { $subtractedType = $this->getSubtractedType() !== null ? $cb($this->getSubtractedType()) : null; $typesChanged = \false; $types = []; foreach ($this->types as $type) { $newType = $cb($type); $types[] = $newType; if ($newType === $type) { continue; } $typesChanged = \true; } if ($subtractedType !== $this->getSubtractedType() || $typesChanged) { return new self($this->classReflection, $types, $subtractedType, $this->variances); } return $this; } public function traverseSimultaneously(Type $right, callable $cb) : Type { if (!$right instanceof TypeWithClassName) { return $this; } $ancestor = $right->getAncestorWithClassName($this->getClassName()); if (!$ancestor instanceof self) { return $this; } if (count($this->types) !== count($ancestor->types)) { return $this; } $typesChanged = \false; $types = []; foreach ($this->types as $i => $leftType) { $rightType = $ancestor->types[$i]; $newType = $cb($leftType, $rightType); $types[] = $newType; if ($newType === $leftType) { continue; } $typesChanged = \true; } if ($typesChanged) { return new self($this->classReflection, $types, null, $this->variances); } return $this; } public function changeSubtractedType(?Type $subtractedType) : Type { if ($subtractedType !== null) { $classReflection = $this->getClassReflection(); if ($classReflection->getAllowedSubTypes() !== null) { $objectType = $this->getStaticObjectType()->changeSubtractedType($subtractedType); if ($objectType instanceof NeverType) { return $objectType; } if ($objectType instanceof ObjectType && $objectType->getSubtractedType() !== null) { return new self($classReflection, $this->types, $objectType->getSubtractedType(), $this->variances); } return TypeCombinator::intersect($this, $objectType); } } return new self($this->classReflection, $this->types, $subtractedType, $this->variances); } public function inferTemplateTypes(Type $receivedType) : \PHPStan\Type\Generic\TemplateTypeMap { return $this->getStaticObjectType()->inferTemplateTypes($receivedType); } public function getReferencedTemplateTypes(\PHPStan\Type\Generic\TemplateTypeVariance $positionVariance) : array { return $this->getStaticObjectType()->getReferencedTemplateTypes($positionVariance); } public function toPhpDocNode() : TypeNode { /** @var IdentifierTypeNode $parent */ $parent = parent::toPhpDocNode(); return new GenericTypeNode($parent, array_map(static function (Type $type) { return $type->toPhpDocNode(); }, $this->types), array_map(static function (\PHPStan\Type\Generic\TemplateTypeVariance $variance) { return $variance->toPhpDocNodeVariance(); }, $this->variances)); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : Type { $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if ($reflectionProvider->hasClass($properties['baseClass'])) { return new self($reflectionProvider->getClass($properties['baseClass']), $properties['types'], $properties['subtractedType'], $properties['variances']); } return new ErrorType(); } } describe($level); if ($variance === null || $variance->invariant()) { return $describedType; } if ($variance->bivariant()) { return '*'; } return sprintf('%s %s', $variance->describe(), $describedType); } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; use UndecidedComparisonCompoundTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, IterableType $bound, ?Type $default) { parent::__construct($bound->getKeyType(), $bound->getItemType()); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } } isAcceptedWithReasonBy($left, $strictTypes); } return $left->getBound()->acceptsWithReason($right, $strictTypes); } public function isArgument() : bool { return \false; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self { return new self(); } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; use UndecidedComparisonCompoundTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, StringType $bound, ?Type $default) { parent::__construct(); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } protected function shouldGeneralizeInferredType() : bool { return \false; } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, ObjectWithoutClassType $bound, ?Type $default) { parent::__construct(); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; use UndecidedComparisonCompoundTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, ConstantStringType $bound, ?Type $default) { parent::__construct($bound->getValue()); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } protected function shouldGeneralizeInferredType() : bool { return \false; } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; use UndecidedComparisonCompoundTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, ObjectShapeType $bound, ?Type $default) { parent::__construct($bound->getProperties(), $bound->getOptionalProperties()); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } protected function shouldGeneralizeInferredType() : bool { return \false; } } name; } public function getScope() : \PHPStan\Type\Generic\TemplateTypeScope { return $this->scope; } /** @return TBound */ public function getBound() : Type { return $this->bound; } public function getDefault() : ?Type { return $this->default; } public function describe(VerbosityLevel $level) : string { $basicDescription = function () use($level) : string { // @phpstan-ignore booleanAnd.alwaysFalse, instanceof.alwaysFalse, booleanAnd.alwaysFalse, instanceof.alwaysFalse, instanceof.alwaysTrue if ($this->bound instanceof MixedType && $this->bound->getSubtractedType() === null && !$this->bound instanceof \PHPStan\Type\Generic\TemplateMixedType) { $boundDescription = ''; } else { $boundDescription = sprintf(' of %s', $this->bound->describe($level)); } $defaultDescription = $this->default !== null ? sprintf(' = %s', $this->default->describe($level)) : ''; return sprintf('%s%s%s', $this->name, $boundDescription, $defaultDescription); }; return $level->handle($basicDescription, $basicDescription, function () use($basicDescription) : string { return sprintf('%s (%s, %s)', $basicDescription(), $this->scope->describe(), $this->isArgument() ? 'argument' : 'parameter'); }); } public function isArgument() : bool { return $this->strategy->isArgument(); } public function toArgument() : \PHPStan\Type\Generic\TemplateType { return new self($this->scope, new \PHPStan\Type\Generic\TemplateTypeArgumentStrategy(), $this->variance, $this->name, \PHPStan\Type\Generic\TemplateTypeHelper::toArgument($this->getBound()), $this->default !== null ? \PHPStan\Type\Generic\TemplateTypeHelper::toArgument($this->default) : null); } public function isValidVariance(Type $a, Type $b) : TrinaryLogic { return $this->isValidVarianceWithReason($a, $b)->result; } public function isValidVarianceWithReason(Type $a, Type $b) : AcceptsResult { return $this->variance->isValidVarianceWithReason($this, $a, $b); } public function subtract(Type $typeToRemove) : Type { $removedBound = TypeCombinator::remove($this->getBound(), $typeToRemove); return \PHPStan\Type\Generic\TemplateTypeFactory::create($this->getScope(), $this->getName(), $removedBound, $this->getVariance(), $this->getStrategy(), $this->getDefault()); } public function getTypeWithoutSubtractedType() : Type { $bound = $this->getBound(); if (!$bound instanceof SubtractableType) { // @phpstan-ignore instanceof.alwaysTrue return $this; } return \PHPStan\Type\Generic\TemplateTypeFactory::create($this->getScope(), $this->getName(), $bound->getTypeWithoutSubtractedType(), $this->getVariance(), $this->getStrategy(), $this->getDefault()); } public function changeSubtractedType(?Type $subtractedType) : Type { $bound = $this->getBound(); if (!$bound instanceof SubtractableType) { // @phpstan-ignore instanceof.alwaysTrue return $this; } return \PHPStan\Type\Generic\TemplateTypeFactory::create($this->getScope(), $this->getName(), $bound->changeSubtractedType($subtractedType), $this->getVariance(), $this->getStrategy(), $this->getDefault()); } public function getSubtractedType() : ?Type { $bound = $this->getBound(); if (!$bound instanceof SubtractableType) { // @phpstan-ignore instanceof.alwaysTrue return null; } return $bound->getSubtractedType(); } public function equals(Type $type) : bool { return $type instanceof self && $type->scope->equals($this->scope) && $type->name === $this->name && $this->bound->equals($type->bound) && ($this->default === null && $type->default === null || $this->default !== null && $type->default !== null && $this->default->equals($type->default)); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { /** @var TBound $bound */ $bound = $this->getBound(); if (!$acceptingType instanceof $bound && !$this instanceof $acceptingType && !$acceptingType instanceof \PHPStan\Type\Generic\TemplateType && ($acceptingType instanceof UnionType || $acceptingType instanceof IntersectionType)) { return $acceptingType->acceptsWithReason($this, $strictTypes); } if (!$acceptingType instanceof \PHPStan\Type\Generic\TemplateType) { return $acceptingType->acceptsWithReason($this->getBound(), $strictTypes); } if ($this->getScope()->equals($acceptingType->getScope()) && $this->getName() === $acceptingType->getName()) { return $acceptingType->getBound()->acceptsWithReason($this->getBound(), $strictTypes); } return $acceptingType->getBound()->acceptsWithReason($this->getBound(), $strictTypes)->and(new AcceptsResult(TrinaryLogic::createMaybe(), [])); } public function accepts(Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { return $this->strategy->accepts($this, $type, $strictTypes); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof \PHPStan\Type\Generic\TemplateType || $type instanceof IntersectionType) { return $type->isSubTypeOfWithReason($this); } if ($type instanceof NeverType) { return IsSuperTypeOfResult::createYes(); } return $this->getBound()->isSuperTypeOfWithReason($type)->and(IsSuperTypeOfResult::createMaybe()); } public function isSubTypeOf(Type $type) : TrinaryLogic { return $this->isSubTypeOfWithReason($type)->result; } public function isSubTypeOfWithReason(Type $type) : IsSuperTypeOfResult { /** @var TBound $bound */ $bound = $this->getBound(); if (!$type instanceof $bound && !$this instanceof $type && !$type instanceof \PHPStan\Type\Generic\TemplateType && ($type instanceof UnionType || $type instanceof IntersectionType)) { return $type->isSuperTypeOfWithReason($this); } if (!$type instanceof \PHPStan\Type\Generic\TemplateType) { return $type->isSuperTypeOfWithReason($this->getBound()); } if ($this->getScope()->equals($type->getScope()) && $this->getName() === $type->getName()) { return $type->getBound()->isSuperTypeOfWithReason($this->getBound()); } return $type->getBound()->isSuperTypeOfWithReason($this->getBound())->and(IsSuperTypeOfResult::createMaybe()); } public function toArrayKey() : Type { return $this; } public function inferTemplateTypes(Type $receivedType) : \PHPStan\Type\Generic\TemplateTypeMap { if ($receivedType instanceof \PHPStan\Type\Generic\TemplateType && $this->getBound()->isSuperTypeOf($receivedType->getBound())->yes()) { return new \PHPStan\Type\Generic\TemplateTypeMap([$this->name => $receivedType]); } $map = $this->getBound()->inferTemplateTypes($receivedType); $resolvedBound = TypeUtils::resolveLateResolvableTypes(\PHPStan\Type\Generic\TemplateTypeHelper::resolveTemplateTypes($this->getBound(), $map, \PHPStan\Type\Generic\TemplateTypeVarianceMap::createEmpty(), \PHPStan\Type\Generic\TemplateTypeVariance::createStatic())); if ($resolvedBound->isSuperTypeOf($receivedType)->yes()) { if (!BleedingEdgeToggle::isBleedingEdge() && $this->shouldGeneralizeInferredType()) { $generalizedType = $receivedType->generalize(GeneralizePrecision::templateArgument()); if ($resolvedBound->isSuperTypeOf($generalizedType)->yes()) { $receivedType = $generalizedType; } } return (new \PHPStan\Type\Generic\TemplateTypeMap([$this->name => $receivedType]))->union($map); } return $map; } public function getReferencedTemplateTypes(\PHPStan\Type\Generic\TemplateTypeVariance $positionVariance) : array { return [new \PHPStan\Type\Generic\TemplateTypeReference($this, $positionVariance)]; } public function getVariance() : \PHPStan\Type\Generic\TemplateTypeVariance { return $this->variance; } public function getStrategy() : \PHPStan\Type\Generic\TemplateTypeStrategy { return $this->strategy; } protected function shouldGeneralizeInferredType() : bool { return \true; } public function traverse(callable $cb) : Type { $bound = $cb($this->getBound()); $default = $this->getDefault() !== null ? $cb($this->getDefault()) : null; if ($this->getBound() === $bound && $this->getDefault() === $default) { return $this; } return \PHPStan\Type\Generic\TemplateTypeFactory::create($this->getScope(), $this->getName(), $bound, $this->getVariance(), $this->getStrategy(), $default); } public function traverseSimultaneously(Type $right, callable $cb) : Type { if (!$right instanceof \PHPStan\Type\Generic\TemplateType) { return $this; } $bound = $cb($this->getBound(), $right->getBound()); $default = $this->getDefault() !== null && $right->getDefault() !== null ? $cb($this->getDefault(), $right->getDefault()) : null; if ($this->getBound() === $bound && $this->getDefault() === $default) { return $this; } return \PHPStan\Type\Generic\TemplateTypeFactory::create($this->getScope(), $this->getName(), $bound, $this->getVariance(), $this->getStrategy(), $default); } public function tryRemove(Type $typeToRemove) : ?Type { $bound = TypeCombinator::remove($this->getBound(), $typeToRemove); if ($this->getBound() === $bound) { return null; } return \PHPStan\Type\Generic\TemplateTypeFactory::create($this->getScope(), $this->getName(), $bound, $this->getVariance(), $this->getStrategy(), $this->getDefault()); } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode($this->name); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : Type { return new self($properties['scope'], $properties['strategy'], $properties['variance'], $properties['name'], $properties['bound'], $properties['default'] ?? null); } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; use UndecidedComparisonCompoundTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, BooleanType $bound, ?Type $default) { parent::__construct(); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } protected function shouldGeneralizeInferredType() : bool { return \false; } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, \PHPStan\Type\Generic\GenericObjectType $bound, ?Type $default) { parent::__construct($bound->getClassName(), $bound->getTypes(), null, null, $bound->getVariances()); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } protected function recreate(string $className, array $types, ?Type $subtractedType, array $variances = []) : \PHPStan\Type\Generic\GenericObjectType { return new self($this->scope, $this->strategy, $this->variance, $this->name, $this->getBound(), $this->default); } } type = $type; $this->positionVariance = $positionVariance; } public function getType() : \PHPStan\Type\Generic\TemplateType { return $this->type; } public function getPositionVariance() : \PHPStan\Type\Generic\TemplateTypeVariance { return $this->positionVariance; } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; use UndecidedComparisonCompoundTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, IntegerType $bound, ?Type $default) { parent::__construct(); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } protected function shouldGeneralizeInferredType() : bool { return \false; } } type = $type; parent::__construct(); } public function getReferencedClasses() : array { return $this->type->getReferencedClasses(); } public function getGenericType() : Type { return $this->type; } public function getClassStringObjectType() : Type { return $this->getGenericType(); } public function getObjectTypeOrClassStringObjectType() : Type { return $this->getClassStringObjectType(); } public function describe(VerbosityLevel $level) : string { return sprintf('%s<%s>', parent::describe($level), $this->type->describe($level)); } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } if ($type instanceof ConstantStringType) { if (!$type->isClassStringType()->yes()) { return AcceptsResult::createNo(); } $objectType = new ObjectType($type->getValue()); } elseif ($type instanceof self) { $objectType = $type->type; } elseif ($type instanceof ClassStringType) { $objectType = new ObjectWithoutClassType(); } elseif ($type instanceof StringType) { return AcceptsResult::createMaybe(); } else { return AcceptsResult::createNo(); } return $this->type->acceptsWithReason($objectType, $strictTypes); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } if ($type instanceof ConstantStringType) { $genericType = $this->type; if ($genericType instanceof MixedType) { return IsSuperTypeOfResult::createYes(); } if ($genericType instanceof StaticType) { $genericType = $genericType->getStaticObjectType(); } // We are transforming constant class-string to ObjectType. But we need to filter out // an uncertainty originating in possible ObjectType's class subtypes. $objectType = new ObjectType($type->getValue()); // Do not use TemplateType's isSuperTypeOf handling directly because it takes ObjectType // uncertainty into account. if ($genericType instanceof \PHPStan\Type\Generic\TemplateType) { $isSuperType = $genericType->getBound()->isSuperTypeOfWithReason($objectType); } else { $isSuperType = $genericType->isSuperTypeOfWithReason($objectType); } if (!$type->isClassStringType()->yes()) { $isSuperType = $isSuperType->and(IsSuperTypeOfResult::createMaybe()); } return $isSuperType; } elseif ($type instanceof self) { return $this->type->isSuperTypeOfWithReason($type->type); } elseif ($type instanceof StringType) { return IsSuperTypeOfResult::createMaybe(); } return IsSuperTypeOfResult::createNo(); } public function traverse(callable $cb) : Type { $newType = $cb($this->type); if ($newType === $this->type) { return $this; } return new self($newType); } public function traverseSimultaneously(Type $right, callable $cb) : Type { $newType = $cb($this->type, $right->getClassStringObjectType()); if ($newType === $this->type) { return $this; } return new self($newType); } public function inferTemplateTypes(Type $receivedType) : \PHPStan\Type\Generic\TemplateTypeMap { if ($receivedType instanceof UnionType || $receivedType instanceof IntersectionType) { return $receivedType->inferTemplateTypesOn($this); } if ($receivedType instanceof ConstantStringType) { $typeToInfer = new ObjectType($receivedType->getValue()); } elseif ($receivedType instanceof self) { $typeToInfer = $receivedType->type; } elseif ($receivedType->isClassStringType()->yes()) { $typeToInfer = $this->type; if ($typeToInfer instanceof \PHPStan\Type\Generic\TemplateType) { $typeToInfer = $typeToInfer->getBound(); } $typeToInfer = TypeCombinator::intersect($typeToInfer, new ObjectWithoutClassType()); } else { return \PHPStan\Type\Generic\TemplateTypeMap::createEmpty(); } return $this->type->inferTemplateTypes($typeToInfer); } public function getReferencedTemplateTypes(\PHPStan\Type\Generic\TemplateTypeVariance $positionVariance) : array { $variance = $positionVariance->compose(\PHPStan\Type\Generic\TemplateTypeVariance::createCovariant()); return $this->type->getReferencedTemplateTypes($variance); } public function equals(Type $type) : bool { if (!$type instanceof self) { return \false; } if (!parent::equals($type)) { return \false; } if (!$this->type->equals($type->type)) { return \false; } return \true; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : Type { return new self($properties['type']); } public function toPhpDocNode() : TypeNode { return new GenericTypeNode(new IdentifierTypeNode('class-string'), [$this->type->toPhpDocNode()]); } public function tryRemove(Type $typeToRemove) : ?Type { if ($typeToRemove instanceof ConstantStringType && $typeToRemove->isClassStringType()->yes()) { $generic = $this->getGenericType(); $genericObjectClassNames = $generic->getObjectClassNames(); if (count($genericObjectClassNames) === 1) { $classReflection = ReflectionProviderStaticAccessor::getInstance()->getClass($genericObjectClassNames[0]); if ($classReflection->isFinal() && $genericObjectClassNames[0] === $typeToRemove->getValue()) { return new NeverType(); } } } return parent::tryRemove($typeToRemove); } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; use UndecidedComparisonCompoundTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, ConstantIntegerType $bound, ?Type $default) { parent::__construct($bound->getValue()); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } protected function shouldGeneralizeInferredType() : bool { return \false; } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; use UndecidedComparisonCompoundTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, ConstantArrayType $bound, ?Type $default) { parent::__construct($bound->getKeyTypes(), $bound->getValueTypes(), $bound->getNextAutoIndexes(), $bound->getOptionalKeys(), $bound->isList()); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } protected function shouldGeneralizeInferredType() : bool { return \false; } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; use UndecidedComparisonCompoundTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, FloatType $bound, ?Type $default) { parent::__construct(); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } protected function shouldGeneralizeInferredType() : bool { return \false; } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, BenevolentUnionType $bound, ?Type $default) { parent::__construct($bound->getTypes()); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } /** @param Type[] $types */ public function withTypes(array $types) : self { return new self($this->scope, $this->strategy, $this->variance, $this->name, new BenevolentUnionType($types), $this->default); } public function filterTypes(callable $filterCb) : Type { $result = parent::filterTypes($filterCb); if (!$result instanceof \PHPStan\Type\Generic\TemplateType) { return \PHPStan\Type\Generic\TemplateTypeFactory::create($this->getScope(), $this->getName(), $result, $this->getVariance(), $this->getStrategy(), $this->getDefault()); } return $result; } } value = $value; } private static function create(int $value) : self { self::$registry[$value] = self::$registry[$value] ?? new self($value); return self::$registry[$value]; } public static function createInvariant() : self { return self::create(self::INVARIANT); } public static function createCovariant() : self { return self::create(self::COVARIANT); } public static function createContravariant() : self { return self::create(self::CONTRAVARIANT); } public static function createStatic() : self { return self::create(self::STATIC); } public static function createBivariant() : self { return self::create(self::BIVARIANT); } public function invariant() : bool { return $this->value === self::INVARIANT; } public function covariant() : bool { return $this->value === self::COVARIANT; } public function contravariant() : bool { return $this->value === self::CONTRAVARIANT; } public function static() : bool { return $this->value === self::STATIC; } public function bivariant() : bool { return $this->value === self::BIVARIANT; } public function compose(self $other) : self { if ($this->contravariant()) { if ($other->contravariant()) { return self::createCovariant(); } if ($other->covariant()) { return self::createContravariant(); } if ($other->bivariant()) { return self::createBivariant(); } return self::createInvariant(); } if ($this->covariant()) { if ($other->contravariant()) { return self::createContravariant(); } if ($other->covariant()) { return self::createCovariant(); } if ($other->bivariant()) { return self::createBivariant(); } return self::createInvariant(); } if (self::$invarianceCompositionEnabled && $this->invariant()) { return self::createInvariant(); } if ($this->bivariant()) { return self::createBivariant(); } return $other; } public function isValidVariance(Type $a, Type $b) : TrinaryLogic { return $this->isValidVarianceWithReason(null, $a, $b)->result; } public function isValidVarianceWithReason(?\PHPStan\Type\Generic\TemplateType $templateType, Type $a, Type $b) : AcceptsResult { if ($b instanceof NeverType) { return AcceptsResult::createYes(); } if ($a instanceof MixedType && !$a instanceof \PHPStan\Type\Generic\TemplateType) { return AcceptsResult::createYes(); } if ($a instanceof BenevolentUnionType) { if (!$a->isSuperTypeOf($b)->no()) { return AcceptsResult::createYes(); } } if ($b instanceof BenevolentUnionType) { if (!$b->isSuperTypeOf($a)->no()) { return AcceptsResult::createYes(); } } if ($b instanceof MixedType && !$b instanceof \PHPStan\Type\Generic\TemplateType) { return AcceptsResult::createYes(); } if ($this->invariant()) { $result = $a->equals($b); $reasons = []; if (!$result) { if ($templateType !== null && $templateType->getScope()->getClassName() !== null && $a->isSuperTypeOf($b)->yes()) { $reasons[] = sprintf('Template type %s on class %s is not covariant. Learn more: https://phpstan.org/blog/whats-up-with-template-covariant', $templateType->getName(), $templateType->getScope()->getClassName()); } } return new AcceptsResult(TrinaryLogic::createFromBoolean($result), $reasons); } if ($this->covariant()) { return $a->isSuperTypeOfWithReason($b)->toAcceptsResult(); } if ($this->contravariant()) { return $b->isSuperTypeOfWithReason($a)->toAcceptsResult(); } if ($this->bivariant()) { return AcceptsResult::createYes(); } throw new ShouldNotHappenException(); } public function equals(self $other) : bool { return $other->value === $this->value; } public function validPosition(self $other) : bool { return $other->value === $this->value || $other->invariant() || $this->bivariant() || $this->static(); } public function describe() : string { switch ($this->value) { case self::INVARIANT: return 'invariant'; case self::COVARIANT: return 'covariant'; case self::CONTRAVARIANT: return 'contravariant'; case self::STATIC: return 'static'; case self::BIVARIANT: return 'bivariant'; } throw new ShouldNotHappenException(); } /** * @return GenericTypeNode::VARIANCE_* */ public function toPhpDocNodeVariance() : string { switch ($this->value) { case self::INVARIANT: return GenericTypeNode::VARIANCE_INVARIANT; case self::COVARIANT: return GenericTypeNode::VARIANCE_COVARIANT; case self::CONTRAVARIANT: return GenericTypeNode::VARIANCE_CONTRAVARIANT; case self::BIVARIANT: return GenericTypeNode::VARIANCE_BIVARIANT; } throw new ShouldNotHappenException(); } /** * @param array{value: int} $properties */ public static function __set_state(array $properties) : self { return new self($properties['value']); } public static function setInvarianceCompositionEnabled(bool $enabled) : void { self::$invarianceCompositionEnabled = $enabled; } } getName(), $tag->getBound(), $tag->getVariance(), null, $tag->getDefault()); } } className = $className; $this->functionName = $functionName; } /** @api */ public function getClassName() : ?string { return $this->className; } /** @api */ public function getFunctionName() : ?string { return $this->functionName; } /** @api */ public function equals(self $other) : bool { return $this->className === $other->className && $this->functionName === $other->functionName; } /** @api */ public function describe() : string { if ($this->className === null && $this->functionName === null) { return 'anonymous function'; } if ($this->className === null) { return sprintf('function %s()', $this->functionName); } if ($this->functionName === null) { return sprintf('class %s', $this->className); } return sprintf('method %s::%s()', $this->className, $this->functionName); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self { return new self($properties['className'], $properties['functionName']); } } */ private $variances; /** * @var ?TemplateTypeVarianceMap */ private static $empty = null; /** * @api * @param array $variances */ public function __construct(array $variances) { $this->variances = $variances; } public static function createEmpty() : self { $empty = self::$empty; if ($empty !== null) { return $empty; } $empty = new self([]); self::$empty = $empty; return $empty; } /** @return array */ public function getVariances() : array { return $this->variances; } public function hasVariance(string $name) : bool { return array_key_exists($name, $this->getVariances()); } public function getVariance(string $name) : ?\PHPStan\Type\Generic\TemplateTypeVariance { return $this->getVariances()[$name] ?? null; } } */ use \PHPStan\Type\Generic\TemplateTypeTrait; /** * @param non-empty-string $name */ public function __construct(\PHPStan\Type\Generic\TemplateTypeScope $scope, \PHPStan\Type\Generic\TemplateTypeStrategy $templateTypeStrategy, \PHPStan\Type\Generic\TemplateTypeVariance $templateTypeVariance, string $name, MixedType $bound, ?Type $default) { parent::__construct(\true); $this->scope = $scope; $this->strategy = $templateTypeStrategy; $this->variance = $templateTypeVariance; $this->name = $name; $this->bound = $bound; $this->default = $default; } public function isSuperTypeOfMixed(MixedType $type) : TrinaryLogic { return $this->isSuperTypeOf($type); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { $isSuperType = $this->isSuperTypeOfWithReason($acceptingType)->toAcceptsResult(); if ($isSuperType->no()) { return $isSuperType; } return AcceptsResult::createYes(); } public function toStrictMixedType() : \PHPStan\Type\Generic\TemplateStrictMixedType { return new \PHPStan\Type\Generic\TemplateStrictMixedType($this->scope, $this->strategy, $this->variance, $this->name, new StrictMixedType(), $this->default); } } getValue()); * } * // Replaces the current type, and don't traverse * return new MixedType(); * }); * * @api * @param callable(Type $type, callable(Type): Type $traverse): Type $cb */ public static function map(\PHPStan\Type\Type $type, callable $cb) : \PHPStan\Type\Type { $self = new self($cb); return $self->mapInternal($type); } /** @param callable(Type $type, callable(Type): Type $traverse): Type $cb */ private function __construct(callable $cb) { $this->cb = $cb; } /** @internal */ public function mapInternal(\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return ($this->cb)($type, [$this, 'traverseInternal']); } /** @internal */ public function traverseInternal(\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->traverse([$this, 'mapInternal']); } } isExplicit = $isExplicit; } public function isExplicit() : bool { return $this->isExplicit; } /** * @return string[] */ public function getReferencedClasses() : array { return []; } public function getArrays() : array { return []; } public function getConstantArrays() : array { return []; } public function getObjectClassNames() : array { return []; } public function getObjectClassReflections() : array { return []; } public function getConstantStrings() : array { return []; } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { return \PHPStan\Type\AcceptsResult::createYes(); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self; } public function isSubTypeOf(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(\PHPStan\Type\Type $otherType) : \PHPStan\Type\IsSuperTypeOfResult { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } public function isAcceptedBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : \PHPStan\Type\AcceptsResult { return $this->isSubTypeOfWithReason($acceptingType)->toAcceptsResult(); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return '*NEVER*'; } public function getTemplateType(string $ancestorClassName, string $templateTypeName) : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function isObject() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isEnum() : TrinaryLogic { return TrinaryLogic::createNo(); } public function canAccessProperties() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasProperty(string $propertyName) : TrinaryLogic { return TrinaryLogic::createNo(); } public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection { throw new ShouldNotHappenException(); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { throw new ShouldNotHappenException(); } public function canCallMethods() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasMethod(string $methodName) : TrinaryLogic { return TrinaryLogic::createNo(); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { throw new ShouldNotHappenException(); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { throw new ShouldNotHappenException(); } public function canAccessConstants() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasConstant(string $constantName) : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstant(string $constantName) : ConstantReflection { throw new ShouldNotHappenException(); } public function isIterable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isIterableAtLeastOnce() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getArraySize() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function getIterableKeyType() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function getFirstIterableKeyType() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function getLastIterableKeyType() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function getIterableValueType() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function getFirstIterableValueType() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function getLastIterableValueType() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function isArray() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantArray() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isOversizedArray() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isList() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isOffsetAccessible() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isOffsetAccessLegal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasOffsetValueType(\PHPStan\Type\Type $offsetType) : TrinaryLogic { return TrinaryLogic::createYes(); } public function getOffsetValueType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function setOffsetValueType(?\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType, bool $unionValues = \true) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function setExistingOffsetValueType(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function unsetOffset(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function getKeysArray() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function getValuesArray() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function chunkArray(\PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function fillKeysArray(\PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function flipArray() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function intersectKeyArray(\PHPStan\Type\Type $otherArraysType) : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function popArray() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function reverseArray(TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function searchArray(\PHPStan\Type\Type $needleType) : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function shiftArray() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function shuffleArray() : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function sliceArray(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return new \PHPStan\Type\NeverType(); } public function isCallable() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { throw new ShouldNotHappenException(); } public function isCloneable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function toNumber() : \PHPStan\Type\Type { return $this; } public function toAbsoluteNumber() : \PHPStan\Type\Type { return $this; } public function toString() : \PHPStan\Type\Type { return $this; } public function toInteger() : \PHPStan\Type\Type { return $this; } public function toFloat() : \PHPStan\Type\Type { return $this; } public function toArray() : \PHPStan\Type\Type { return $this; } public function toArrayKey() : \PHPStan\Type\Type { return $this; } public function traverse(callable $cb) : \PHPStan\Type\Type { return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { return $this; } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return new \PHPStan\Type\ErrorType(); } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createNo(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function getEnumCases() : array { return []; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return $this; } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('never'); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['isExplicit']); } } isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } if ($type instanceof parent) { return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { if ($type instanceof \PHPStan\Type\NeverType) { return \PHPStan\Type\AcceptsResult::createYes(); } return \PHPStan\Type\AcceptsResult::createNo(); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return 'never'; } } ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) { $arrayBuilder->degradeToGeneralArray(\true); } foreach ($value as $k => $v) { $arrayBuilder->setOffsetValueType(self::getTypeFromValue($k), self::getTypeFromValue($v)); } return $arrayBuilder->getArray(); } elseif (is_object($value)) { $class = get_class($value); /** phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName */ if (function_exists('enum_exists') && \enum_exists($class)) { /** @var UnitEnum $value */ return new EnumCaseObjectType($class, $value->name); } /** phpcs:enable */ return new \PHPStan\Type\ObjectType(get_class($value)); } return new \PHPStan\Type\MixedType(); } } isExplicitMixed = $isExplicitMixed; if ($subtractedType instanceof \PHPStan\Type\NeverType) { $subtractedType = null; } $this->subtractedType = $subtractedType; } /** * @return string[] */ public function getReferencedClasses() : array { return []; } public function getObjectClassNames() : array { return []; } public function getObjectClassReflections() : array { return []; } public function getArrays() : array { return []; } public function getConstantArrays() : array { return []; } public function getConstantStrings() : array { return []; } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { return \PHPStan\Type\AcceptsResult::createYes(); } public function isSuperTypeOfMixed(\PHPStan\Type\MixedType $type) : TrinaryLogic { if ($this->subtractedType === null) { if ($this->isExplicitMixed) { if ($type->isExplicitMixed) { return TrinaryLogic::createYes(); } return TrinaryLogic::createMaybe(); } return TrinaryLogic::createYes(); } if ($type->subtractedType === null) { return TrinaryLogic::createMaybe(); } $isSuperType = $type->subtractedType->isSuperTypeOf($this->subtractedType); if ($isSuperType->yes()) { if ($this->isExplicitMixed) { if ($type->isExplicitMixed) { return TrinaryLogic::createYes(); } return TrinaryLogic::createMaybe(); } return TrinaryLogic::createYes(); } return TrinaryLogic::createMaybe(); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($this->subtractedType === null || $type instanceof \PHPStan\Type\NeverType) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } if ($type instanceof self) { if ($type->subtractedType === null) { return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } $isSuperType = $type->subtractedType->isSuperTypeOfWithReason($this->subtractedType); if ($isSuperType->yes()) { return $isSuperType; } return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } $result = $this->subtractedType->isSuperTypeOfWithReason($type)->negate(); if ($result->no()) { return \PHPStan\Type\IsSuperTypeOfResult::createNo([sprintf('Type %s has already been eliminated from %s.', $this->subtractedType->describe(\PHPStan\Type\VerbosityLevel::precise()), $this->describe(\PHPStan\Type\VerbosityLevel::typeOnly()))]); } return $result; } public function setOffsetValueType(?\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType, bool $unionValues = \true) : \PHPStan\Type\Type { return new self($this->isExplicitMixed); } public function setExistingOffsetValueType(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return new self($this->isExplicitMixed); } public function unsetOffset(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { if ($this->subtractedType !== null) { return new self($this->isExplicitMixed, \PHPStan\Type\TypeCombinator::remove($this->subtractedType, new ConstantArrayType([], []))); } return $this; } public function getKeysArray() : \PHPStan\Type\Type { if ($this->isArray()->no()) { return new \PHPStan\Type\ErrorType(); } return AccessoryArrayListType::intersectWith(new \PHPStan\Type\ArrayType(new \PHPStan\Type\IntegerType(), new \PHPStan\Type\UnionType([new \PHPStan\Type\IntegerType(), new \PHPStan\Type\StringType()]))); } public function getValuesArray() : \PHPStan\Type\Type { if ($this->isArray()->no()) { return new \PHPStan\Type\ErrorType(); } return AccessoryArrayListType::intersectWith(new \PHPStan\Type\ArrayType(new \PHPStan\Type\IntegerType(), new \PHPStan\Type\MixedType($this->isExplicitMixed))); } public function chunkArray(\PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { if ($this->isArray()->no()) { return new \PHPStan\Type\ErrorType(); } return AccessoryArrayListType::intersectWith(new \PHPStan\Type\ArrayType(new \PHPStan\Type\IntegerType(), new \PHPStan\Type\MixedType($this->isExplicitMixed))); } public function fillKeysArray(\PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { if ($this->isArray()->no()) { return new \PHPStan\Type\ErrorType(); } return new \PHPStan\Type\ArrayType($this->getIterableValueType(), $valueType); } public function flipArray() : \PHPStan\Type\Type { if ($this->isArray()->no()) { return new \PHPStan\Type\ErrorType(); } return new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType($this->isExplicitMixed), new \PHPStan\Type\MixedType($this->isExplicitMixed)); } public function intersectKeyArray(\PHPStan\Type\Type $otherArraysType) : \PHPStan\Type\Type { if ($this->isArray()->no()) { return new \PHPStan\Type\ErrorType(); } return new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType($this->isExplicitMixed), new \PHPStan\Type\MixedType($this->isExplicitMixed)); } public function popArray() : \PHPStan\Type\Type { if ($this->isArray()->no()) { return new \PHPStan\Type\ErrorType(); } return new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType($this->isExplicitMixed), new \PHPStan\Type\MixedType($this->isExplicitMixed)); } public function reverseArray(TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { if ($this->isArray()->no()) { return new \PHPStan\Type\ErrorType(); } return new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType($this->isExplicitMixed), new \PHPStan\Type\MixedType($this->isExplicitMixed)); } public function searchArray(\PHPStan\Type\Type $needleType) : \PHPStan\Type\Type { if ($this->isArray()->no()) { return new \PHPStan\Type\ErrorType(); } return \PHPStan\Type\TypeCombinator::union(new \PHPStan\Type\IntegerType(), new \PHPStan\Type\StringType(), new ConstantBooleanType(\false)); } public function shiftArray() : \PHPStan\Type\Type { if ($this->isArray()->no()) { return new \PHPStan\Type\ErrorType(); } return new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType($this->isExplicitMixed), new \PHPStan\Type\MixedType($this->isExplicitMixed)); } public function shuffleArray() : \PHPStan\Type\Type { if ($this->isArray()->no()) { return new \PHPStan\Type\ErrorType(); } return AccessoryArrayListType::intersectWith(new \PHPStan\Type\ArrayType(new \PHPStan\Type\IntegerType(), new \PHPStan\Type\MixedType($this->isExplicitMixed))); } public function sliceArray(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { if ($this->isArray()->no()) { return new \PHPStan\Type\ErrorType(); } return new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType($this->isExplicitMixed), new \PHPStan\Type\MixedType($this->isExplicitMixed)); } public function isCallable() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\CallableType())->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function getEnumCases() : array { return []; } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { return [new TrivialParametersAcceptor()]; } public function equals(\PHPStan\Type\Type $type) : bool { if (!$type instanceof self) { return \false; } if ($this->subtractedType === null) { if ($type->subtractedType === null) { return \true; } return \false; } if ($type->subtractedType === null) { return \false; } return $this->subtractedType->equals($type->subtractedType); } public function isSubTypeOf(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(\PHPStan\Type\Type $otherType) : \PHPStan\Type\IsSuperTypeOfResult { if ($otherType instanceof self && !$otherType instanceof TemplateMixedType) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } if ($this->subtractedType !== null) { $isSuperType = $this->subtractedType->isSuperTypeOfWithReason($otherType); if ($isSuperType->yes()) { return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } } return \PHPStan\Type\IsSuperTypeOfResult::createMaybe(); } public function isAcceptedBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : \PHPStan\Type\AcceptsResult { $isSuperType = $this->isSuperTypeOfWithReason($acceptingType)->toAcceptsResult(); if ($isSuperType->no()) { return $isSuperType; } return \PHPStan\Type\AcceptsResult::createYes(); } public function getTemplateType(string $ancestorClassName, string $templateTypeName) : \PHPStan\Type\Type { return new self(); } public function isObject() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\ObjectWithoutClassType())->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isEnum() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\ObjectWithoutClassType())->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function canAccessProperties() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasProperty(string $propertyName) : TrinaryLogic { return TrinaryLogic::createYes(); } public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection { return $this->getUnresolvedPropertyPrototype($propertyName, $scope)->getTransformedProperty(); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { $property = new DummyPropertyReflection(); return new CallbackUnresolvedPropertyPrototypeReflection($property, $property->getDeclaringClass(), \false, static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type; }); } public function canCallMethods() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasMethod(string $methodName) : TrinaryLogic { return TrinaryLogic::createYes(); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { return $this->getUnresolvedMethodPrototype($methodName, $scope)->getTransformedMethod(); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { $method = new DummyMethodReflection($methodName); return new CallbackUnresolvedMethodPrototypeReflection($method, $method->getDeclaringClass(), \false, static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type; }); } public function canAccessConstants() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasConstant(string $constantName) : TrinaryLogic { return TrinaryLogic::createYes(); } public function getConstant(string $constantName) : ConstantReflection { return new DummyConstantReflection($constantName); } public function isCloneable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return $level->handle(static function () : string { return 'mixed'; }, static function () : string { return 'mixed'; }, function () use($level) : string { $description = 'mixed'; if ($this->subtractedType !== null) { $description .= $this->subtractedType instanceof \PHPStan\Type\UnionType ? sprintf('~(%s)', $this->subtractedType->describe($level)) : sprintf('~%s', $this->subtractedType->describe($level)); } return $description; }, function () use($level) : string { $description = 'mixed'; if ($this->subtractedType !== null) { $description .= $this->subtractedType instanceof \PHPStan\Type\UnionType ? sprintf('~(%s)', $this->subtractedType->describe($level)) : sprintf('~%s', $this->subtractedType->describe($level)); } if ($this->isExplicitMixed) { $description .= '=explicit'; } else { $description .= '=implicit'; } return $description; }); } public function toBoolean() : \PHPStan\Type\BooleanType { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(\PHPStan\Type\StaticTypeFactory::falsey())->yes()) { return new ConstantBooleanType(\true); } } return new \PHPStan\Type\BooleanType(); } public function toNumber() : \PHPStan\Type\Type { return \PHPStan\Type\TypeCombinator::union($this->toInteger(), $this->toFloat()); } public function toAbsoluteNumber() : \PHPStan\Type\Type { return $this->toNumber()->toAbsoluteNumber(); } public function toInteger() : \PHPStan\Type\Type { $castsToZero = new \PHPStan\Type\UnionType([new \PHPStan\Type\NullType(), new ConstantBooleanType(\false), new ConstantIntegerType(0), new ConstantArrayType([], []), new \PHPStan\Type\StringType(), new \PHPStan\Type\FloatType()]); if ($this->subtractedType !== null && $this->subtractedType->isSuperTypeOf($castsToZero)->yes()) { return new \PHPStan\Type\UnionType([\PHPStan\Type\IntegerRangeType::fromInterval(null, -1), \PHPStan\Type\IntegerRangeType::fromInterval(1, null)]); } return new \PHPStan\Type\IntegerType(); } public function toFloat() : \PHPStan\Type\Type { return new \PHPStan\Type\FloatType(); } public function toString() : \PHPStan\Type\Type { if ($this->subtractedType !== null) { $castsToEmptyString = new \PHPStan\Type\UnionType([new \PHPStan\Type\NullType(), new ConstantBooleanType(\false), new ConstantStringType('')]); if ($this->subtractedType->isSuperTypeOf($castsToEmptyString)->yes()) { $accessories = [new \PHPStan\Type\StringType(), new AccessoryNonEmptyStringType()]; $castsToZeroString = new \PHPStan\Type\UnionType([new ConstantFloatType(0.0), new ConstantStringType('0'), new ConstantIntegerType(0)]); if ($this->subtractedType->isSuperTypeOf($castsToZeroString)->yes()) { $accessories[] = new AccessoryNonFalsyStringType(); } return new \PHPStan\Type\IntersectionType($accessories); } } return new \PHPStan\Type\StringType(); } public function toArray() : \PHPStan\Type\Type { $mixed = new self($this->isExplicitMixed); return new \PHPStan\Type\ArrayType($mixed, $mixed); } public function toArrayKey() : \PHPStan\Type\Type { return new \PHPStan\Type\BenevolentUnionType([new \PHPStan\Type\IntegerType(), new \PHPStan\Type\StringType()]); } public function isIterable() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\IterableType(new \PHPStan\Type\MixedType(), new \PHPStan\Type\MixedType()))->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isIterableAtLeastOnce() : TrinaryLogic { return $this->isIterable(); } public function getArraySize() : \PHPStan\Type\Type { if ($this->isIterable()->no()) { return new \PHPStan\Type\ErrorType(); } return \PHPStan\Type\IntegerRangeType::fromInterval(0, null); } public function getIterableKeyType() : \PHPStan\Type\Type { return new self($this->isExplicitMixed); } public function getFirstIterableKeyType() : \PHPStan\Type\Type { return new self($this->isExplicitMixed); } public function getLastIterableKeyType() : \PHPStan\Type\Type { return new self($this->isExplicitMixed); } public function getIterableValueType() : \PHPStan\Type\Type { return new self($this->isExplicitMixed); } public function getFirstIterableValueType() : \PHPStan\Type\Type { return new self($this->isExplicitMixed); } public function getLastIterableValueType() : \PHPStan\Type\Type { return new self($this->isExplicitMixed); } public function isOffsetAccessible() : TrinaryLogic { if ($this->subtractedType !== null) { $offsetAccessibles = new \PHPStan\Type\UnionType([new \PHPStan\Type\StringType(), new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType(), new \PHPStan\Type\MixedType()), new \PHPStan\Type\ObjectType(ArrayAccess::class)]); if ($this->subtractedType->isSuperTypeOf($offsetAccessibles)->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isOffsetAccessLegal() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\ObjectWithoutClassType())->yes()) { return TrinaryLogic::createYes(); } } return TrinaryLogic::createMaybe(); } public function hasOffsetValueType(\PHPStan\Type\Type $offsetType) : TrinaryLogic { if ($this->isOffsetAccessible()->no()) { return TrinaryLogic::createNo(); } return TrinaryLogic::createMaybe(); } public function getOffsetValueType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return new self($this->isExplicitMixed); } public function isExplicitMixed() : bool { return $this->isExplicitMixed; } public function subtract(\PHPStan\Type\Type $type) : \PHPStan\Type\Type { if ($type instanceof self && !$type instanceof TemplateType) { return new \PHPStan\Type\NeverType(); } if ($this->subtractedType !== null) { $type = \PHPStan\Type\TypeCombinator::union($this->subtractedType, $type); } return new self($this->isExplicitMixed, $type); } public function getTypeWithoutSubtractedType() : \PHPStan\Type\Type { return new self($this->isExplicitMixed); } public function changeSubtractedType(?\PHPStan\Type\Type $subtractedType) : \PHPStan\Type\Type { return new self($this->isExplicitMixed, $subtractedType); } public function getSubtractedType() : ?\PHPStan\Type\Type { return $this->subtractedType; } public function traverse(callable $cb) : \PHPStan\Type\Type { return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { return $this; } public function isArray() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType(), new \PHPStan\Type\MixedType()))->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isConstantArray() : TrinaryLogic { return $this->isArray(); } public function isOversizedArray() : TrinaryLogic { if ($this->subtractedType !== null) { $oversizedArray = \PHPStan\Type\TypeCombinator::intersect(new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType(), new \PHPStan\Type\MixedType()), new OversizedArrayType()); if ($this->subtractedType->isSuperTypeOf($oversizedArray)->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isList() : TrinaryLogic { if ($this->subtractedType !== null) { $list = \PHPStan\Type\TypeCombinator::intersect(new \PHPStan\Type\ArrayType(new \PHPStan\Type\IntegerType(), new \PHPStan\Type\MixedType()), new AccessoryArrayListType()); if ($this->subtractedType->isSuperTypeOf($list)->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isNull() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\NullType())->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new ConstantBooleanType(\true))->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isFalse() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new ConstantBooleanType(\false))->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isBoolean() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\BooleanType())->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isFloat() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\FloatType())->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isInteger() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\IntegerType())->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isString() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\StringType())->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isNumericString() : TrinaryLogic { if ($this->subtractedType !== null) { $numericString = \PHPStan\Type\TypeCombinator::intersect(new \PHPStan\Type\StringType(), new AccessoryNumericStringType()); if ($this->subtractedType->isSuperTypeOf($numericString)->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isNonEmptyString() : TrinaryLogic { if ($this->subtractedType !== null) { $nonEmptyString = \PHPStan\Type\TypeCombinator::intersect(new \PHPStan\Type\StringType(), new AccessoryNonEmptyStringType()); if ($this->subtractedType->isSuperTypeOf($nonEmptyString)->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isNonFalsyString() : TrinaryLogic { if ($this->subtractedType !== null) { $nonFalsyString = \PHPStan\Type\TypeCombinator::intersect(new \PHPStan\Type\StringType(), new AccessoryNonFalsyStringType()); if ($this->subtractedType->isSuperTypeOf($nonFalsyString)->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isLiteralString() : TrinaryLogic { if ($this->subtractedType !== null) { $literalString = \PHPStan\Type\TypeCombinator::intersect(new \PHPStan\Type\StringType(), new AccessoryLiteralStringType()); if ($this->subtractedType->isSuperTypeOf($literalString)->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isLowercaseString() : TrinaryLogic { if ($this->subtractedType !== null) { $lowercaseString = \PHPStan\Type\TypeCombinator::intersect(new \PHPStan\Type\StringType(), new AccessoryLowercaseStringType()); if ($this->subtractedType->isSuperTypeOf($lowercaseString)->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isUppercaseString() : TrinaryLogic { if ($this->subtractedType !== null) { $uppercaseString = \PHPStan\Type\TypeCombinator::intersect(new \PHPStan\Type\StringType(), new AccessoryUppercaseStringType()); if ($this->subtractedType->isSuperTypeOf($uppercaseString)->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isClassStringType() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\StringType())->yes()) { return TrinaryLogic::createNo(); } if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\ClassStringType())->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function getClassStringObjectType() : \PHPStan\Type\Type { if (!$this->isClassStringType()->no()) { return new \PHPStan\Type\ObjectWithoutClassType(); } return new \PHPStan\Type\ErrorType(); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { $objectOrClass = new \PHPStan\Type\UnionType([new \PHPStan\Type\ObjectWithoutClassType(), new \PHPStan\Type\ClassStringType()]); if (!$this->isSuperTypeOf($objectOrClass)->no()) { return new \PHPStan\Type\ObjectWithoutClassType(); } return new \PHPStan\Type\ErrorType(); } public function isVoid() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\VoidType())->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function isScalar() : TrinaryLogic { if ($this->subtractedType !== null) { if ($this->subtractedType->isSuperTypeOf(new \PHPStan\Type\UnionType([new \PHPStan\Type\BooleanType(), new \PHPStan\Type\FloatType(), new \PHPStan\Type\IntegerType(), new \PHPStan\Type\StringType()]))->yes()) { return TrinaryLogic::createNo(); } } return TrinaryLogic::createMaybe(); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type { if ($this->isSuperTypeOf($typeToRemove)->yes()) { return $this->subtract($typeToRemove); } return null; } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return new \PHPStan\Type\BenevolentUnionType([new \PHPStan\Type\FloatType(), new \PHPStan\Type\IntegerType()]); } public function getFiniteTypes() : array { return []; } public function toPhpDocNode() : TypeNode { return new IdentifierTypeNode('mixed'); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['isExplicitMixed'], $properties['subtractedType'] ?? null); } } type = $type; $this->offset = $offset; } public function getReferencedClasses() : array { return array_merge($this->type->getReferencedClasses(), $this->offset->getReferencedClasses()); } public function getObjectClassNames() : array { return []; } public function getObjectClassReflections() : array { return []; } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { return array_merge($this->type->getReferencedTemplateTypes($positionVariance), $this->offset->getReferencedTemplateTypes($positionVariance)); } public function equals(\PHPStan\Type\Type $type) : bool { return $type instanceof self && $this->type->equals($type->type) && $this->offset->equals($type->offset); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { $printer = new Printer(); return $printer->print($this->toPhpDocNode()); } public function isResolvable() : bool { return !\PHPStan\Type\TypeUtils::containsTemplateType($this->type) && !\PHPStan\Type\TypeUtils::containsTemplateType($this->offset); } protected function getResult() : \PHPStan\Type\Type { return $this->type->getOffsetValueType($this->offset); } /** * @param callable(Type): Type $cb */ public function traverse(callable $cb) : \PHPStan\Type\Type { $type = $cb($this->type); $offset = $cb($this->offset); if ($this->type === $type && $this->offset === $offset) { return $this; } return new self($type, $offset); } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if (!$right instanceof self) { return $this; } $type = $cb($this->type, $right->type); $offset = $cb($this->offset, $right->offset); if ($this->type === $type && $this->offset === $offset) { return $this; } return new self($type, $offset); } public function toPhpDocNode() : TypeNode { return new OffsetAccessTypeNode($this->type->toPhpDocNode(), $this->offset->toPhpDocNode()); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['type'], $properties['offset']); } } getClassReflection(); if ($classReflection === null) { return null; } $ancestorClassReflection = $classReflection->getAncestorWithClassName($genericClassName); if ($ancestorClassReflection === null) { return null; } $activeTemplateTypeMap = $ancestorClassReflection->getPossiblyIncompleteActiveTemplateTypeMap(); $type = $activeTemplateTypeMap->getType($typeVariableName); if ($type instanceof \PHPStan\Type\ErrorType) { $templateTypeMap = $ancestorClassReflection->getTemplateTypeMap(); $templateType = $templateTypeMap->getType($typeVariableName); if ($templateType === null) { return $type; } $bound = TemplateTypeHelper::resolveToBounds($templateType); if ($bound instanceof \PHPStan\Type\MixedType && $bound->isExplicitMixed()) { return new \PHPStan\Type\MixedType(\false); } return TemplateTypeHelper::resolveToDefaults($templateType); } return $type; } } getName(); } elseif ($lowercasedClassName === 'parent' && $classReflection !== null && $classReflection->getParentClass() !== null) { $typeClassName = $classReflection->getParentClass()->getName(); } return new \PHPStan\Type\ObjectType($typeClassName); } elseif ($type instanceof NullableType) { return \PHPStan\Type\TypeCombinator::addNull(self::resolve($type->type, $classReflection)); } elseif ($type instanceof Node\UnionType) { $types = []; foreach ($type->types as $unionTypeType) { $types[] = self::resolve($unionTypeType, $classReflection); } return \PHPStan\Type\TypeCombinator::union(...$types); } elseif ($type instanceof Node\IntersectionType) { $types = []; foreach ($type->types as $intersectionTypeType) { $innerType = self::resolve($intersectionTypeType, $classReflection); if (!$innerType->isObject()->yes()) { return new \PHPStan\Type\NeverType(); } $types[] = $innerType; } return \PHPStan\Type\TypeCombinator::intersect(...$types); } elseif (!$type instanceof Identifier) { throw new ShouldNotHappenException(get_class($type)); } $type = $type->name; if ($type === 'string') { return new \PHPStan\Type\StringType(); } elseif ($type === 'int') { return new \PHPStan\Type\IntegerType(); } elseif ($type === 'bool') { return new \PHPStan\Type\BooleanType(); } elseif ($type === 'float') { return new \PHPStan\Type\FloatType(); } elseif ($type === 'callable') { return new \PHPStan\Type\CallableType(); } elseif ($type === 'array') { return new \PHPStan\Type\ArrayType(new \PHPStan\Type\MixedType(), new \PHPStan\Type\MixedType()); } elseif ($type === 'iterable') { return new \PHPStan\Type\IterableType(new \PHPStan\Type\MixedType(), new \PHPStan\Type\MixedType()); } elseif ($type === 'void') { return new \PHPStan\Type\VoidType(); } elseif ($type === 'object') { return new \PHPStan\Type\ObjectWithoutClassType(); } elseif ($type === 'true') { return new ConstantBooleanType(\true); } elseif ($type === 'false') { return new ConstantBooleanType(\false); } elseif ($type === 'null') { return new \PHPStan\Type\NullType(); } elseif ($type === 'mixed') { return new \PHPStan\Type\MixedType(\true); } elseif ($type === 'never') { return new \PHPStan\Type\NonAcceptingNeverType(); } return new \PHPStan\Type\MixedType(); } } */ public $reasons; /** * @api * @param list $reasons */ public function __construct(TrinaryLogic $result, array $reasons) { $this->result = $result; $this->reasons = $reasons; } public function yes() : bool { return $this->result->yes(); } public function maybe() : bool { return $this->result->maybe(); } public function no() : bool { return $this->result->no(); } public static function createYes() : self { return new self(TrinaryLogic::createYes(), []); } /** * @param list $reasons */ public static function createNo(array $reasons = []) : self { return new self(TrinaryLogic::createNo(), $reasons); } public static function createMaybe() : self { return new self(TrinaryLogic::createMaybe(), []); } public static function createFromBoolean(bool $value) : self { return new self(TrinaryLogic::createFromBoolean($value), []); } public function and(self $other) : self { return new self($this->result->and($other->result), array_values(array_unique(array_merge($this->reasons, $other->reasons)))); } public function or(self $other) : self { return new self($this->result->or($other->result), array_values(array_unique(array_merge($this->reasons, $other->reasons)))); } /** * @param callable(string): string $cb */ public function decorateReasons(callable $cb) : self { $reasons = []; foreach ($this->reasons as $reason) { $reasons[] = $cb($reason); } return new self($this->result, $reasons); } public static function extremeIdentity(self ...$operands) : self { if ($operands === []) { throw new ShouldNotHappenException(); } $result = TrinaryLogic::extremeIdentity(...array_map(static function (self $result) { return $result->result; }, $operands)); $reasons = []; foreach ($operands as $operand) { foreach ($operand->reasons as $reason) { $reasons[] = $reason; } } return new self($result, array_values(array_unique($reasons))); } public static function maxMin(self ...$operands) : self { if ($operands === []) { throw new ShouldNotHappenException(); } $result = TrinaryLogic::maxMin(...array_map(static function (self $result) { return $result->result; }, $operands)); $reasons = []; foreach ($operands as $operand) { foreach ($operand->reasons as $reason) { $reasons[] = $reason; } } return new self($result, array_values(array_unique($reasons))); } } getName() === 'preg_filter'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $defaultReturn = ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->getArgs(), $functionReflection->getVariants())->getReturnType(); $argsCount = count($functionCall->getArgs()); if ($argsCount < 3) { return $defaultReturn; } $subjectType = $scope->getType($functionCall->getArgs()[2]->value); if ($subjectType->isArray()->yes()) { return new ArrayType(new IntegerType(), new StringType()); } if ($subjectType->isString()->yes()) { return new UnionType([new StringType(), new NullType()]); } return $defaultReturn; } } explicitMixed = $explicitMixed; } public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool { return strtolower($functionReflection->getName()) === 'is_array' && !$context->null(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { if (!isset($node->getArgs()[0])) { return new SpecifiedTypes(); } if ($context->null()) { throw new ShouldNotHappenException(); } return $this->typeSpecifier->create($node->getArgs()[0]->value, new ArrayType(new MixedType($this->explicitMixed), new MixedType($this->explicitMixed)), $context, \false, $scope); } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } } bitwiseFlagAnalyser = $bitwiseFlagAnalyser; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return strtolower($functionReflection->getName()) === 'preg_split'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $flagsArg = $functionCall->getArgs()[3] ?? null; if ($flagsArg !== null && $this->bitwiseFlagAnalyser->bitwiseOrContainsConstant($flagsArg->value, $scope, 'PREG_SPLIT_OFFSET_CAPTURE')->yes()) { $type = new ArrayType(new IntegerType(), new ConstantArrayType([new ConstantIntegerType(0), new ConstantIntegerType(1)], [new StringType(), IntegerRangeType::fromInterval(0, null)], [2], [], TrinaryLogic::createYes())); return TypeCombinator::union(AccessoryArrayListType::intersectWith($type), new ConstantBooleanType(\false)); } return null; } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return in_array($functionReflection->getName(), ['round', 'ceil', 'floor'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { // PHP 7 can return either a float or false. // PHP 8 can either return a float or fatal. $defaultReturnType = null; if ($this->phpVersion->hasStricterRoundFunctions()) { // PHP 8 fatals with a missing parameter. $noArgsReturnType = new NeverType(\true); } else { // PHP 7 returns null with a missing parameter. $noArgsReturnType = new NullType(); } if (count($functionCall->getArgs()) < 1) { return $noArgsReturnType; } $firstArgType = $scope->getType($functionCall->getArgs()[0]->value); if ($firstArgType instanceof MixedType) { return $defaultReturnType; } if ($this->phpVersion->hasStricterRoundFunctions()) { $allowed = TypeCombinator::union(new IntegerType(), new FloatType()); if (!$scope->isDeclareStrictTypes()) { $allowed = TypeCombinator::union($allowed, new IntersectionType([new StringType(), new AccessoryNumericStringType()]), new NullType(), new BooleanType()); } if ($allowed->isSuperTypeOf($firstArgType)->no()) { // PHP 8 fatals if the parameter is not an integer or float. return new NeverType(\true); } } elseif ($firstArgType->isArray()->yes()) { // PHP 7 returns false if the parameter is an array. return new ConstantBooleanType(\false); } return new FloatType(); } } getName(), ['date_create', 'date_create_immutable'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 1) { return null; } $datetimes = $scope->getType($functionCall->getArgs()[0]->value)->getConstantStrings(); if (count($datetimes) === 0) { return null; } $types = []; $className = $functionReflection->getName() === 'date_create' ? DateTime::class : DateTimeImmutable::class; foreach ($datetimes as $constantString) { $isValid = date_create($constantString->getValue()) !== \false; $types[] = $isValid ? new ObjectType($className) : new ConstantBooleanType(\false); } return TypeCombinator::union(...$types); } } getName()) === 'is_iterable' && !$context->null(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { if ($context->null()) { throw new ShouldNotHappenException(); } if (!isset($node->getArgs()[0])) { return new SpecifiedTypes(); } return $this->typeSpecifier->create($node->getArgs()[0]->value, new IterableType(new MixedType(), new MixedType()), $context, \false, $scope); } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } } getName() === 'get_defined_vars'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { if ($scope->canAnyVariableExist()) { return new ArrayType(new StringType(), new MixedType()); } $typeBuilder = ConstantArrayTypeBuilder::createEmpty(); foreach ($scope->getDefinedVariables() as $variable) { $typeBuilder->setOffsetValueType(new ConstantStringType($variable), $scope->getVariableType($variable), \false); } foreach ($scope->getMaybeDefinedVariables() as $variable) { $typeBuilder->setOffsetValueType(new ConstantStringType($variable), $scope->getVariableType($variable), \true); } return $typeBuilder->getArray(); } } getName() === 'getCode'; } public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : Type { $type = $scope->getType($methodCall->var); $types = []; $pdoException = new ObjectType('PDOException'); foreach ($type->getObjectClassNames() as $class) { $classType = new ObjectType($class); if ($classType->getClassReflection() !== null) { $classReflection = $classType->getClassReflection(); foreach ($classReflection->getMethodTags() as $methodName => $methodTag) { if (strtolower($methodName) !== 'getcode') { continue; } $types[] = $methodTag->getReturnType(); continue 2; } } if ($pdoException->isSuperTypeOf($classType)->yes()) { $types[] = new BenevolentUnionType([new IntegerType(), new StringType()]); continue; } if (in_array(strtolower($class), ['throwable', 'exception', 'runtimeexception'], \true)) { $types[] = new BenevolentUnionType([new IntegerType(), new StringType()]); continue; } $types[] = new IntegerType(); } if (count($types) === 0) { return new ErrorType(); } return TypeCombinator::union(...$types); } } getName(), $this->functions, \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) === 0) { return null; } $argType = $scope->getType($functionCall->getArgs()[0]->value); $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); if ($iterableAtLeastOnce->no()) { return new ConstantBooleanType(\false); } $itemType = $functionReflection->getName() === 'reset' ? $argType->getFirstIterableValueType() : $argType->getLastIterableValueType(); if ($iterableAtLeastOnce->yes()) { return $itemType; } return TypeCombinator::union($itemType, new ConstantBooleanType(\false)); } } methodExistsExtension = $methodExistsExtension; } public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool { return strtolower($functionReflection->getName()) === 'is_callable' && !$context->null(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { if ($context->null()) { throw new ShouldNotHappenException(); } if (!isset($node->getArgs()[0])) { return new SpecifiedTypes(); } $value = $node->getArgs()[0]->value; $valueType = $scope->getType($value); if ($value instanceof Array_ && count($value->items) === 2 && $valueType->isConstantArray()->yes() && !$valueType->isCallable()->no()) { if ($value->items[0] === null || $value->items[1] === null) { throw new ShouldNotHappenException(); } $functionCall = new FuncCall(new Name('method_exists'), [new Arg($value->items[0]->value), new Arg($value->items[1]->value)]); return $this->methodExistsExtension->specifyTypes($functionReflection, $functionCall, $scope, $context); } return $this->typeSpecifier->create($value, new CallableType(), $context, \false, $scope); } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'trigger_error'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) === 0) { return null; } if (count($args) === 1) { return new ConstantBooleanType(\true); } $errorType = $scope->getType($args[1]->value); if ($errorType instanceof ConstantIntegerType) { $errorLevel = $errorType->getValue(); if ($errorLevel === E_USER_ERROR) { return new NeverType(\true); } if (!in_array($errorLevel, [E_USER_WARNING, E_USER_NOTICE, E_USER_DEPRECATED], \true)) { if ($this->phpVersion->throwsValueErrorForInternalFunctions()) { return new NeverType(\true); } return new ConstantBooleanType(\false); } return new ConstantBooleanType(\true); } return null; } } getName() === 'array_merge'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (!isset($args[0])) { return null; } $argTypes = []; $optionalArgTypes = []; foreach ($args as $arg) { $argType = $scope->getType($arg->value); if ($arg->unpack) { if ($argType->isConstantArray()->yes()) { foreach ($argType->getConstantArrays() as $constantArray) { foreach ($constantArray->getValueTypes() as $valueType) { $argTypes[] = $valueType; } } } else { $argTypes[] = $argType->getIterableValueType(); } if (!$argType->isIterableAtLeastOnce()->yes()) { // unpacked params can be empty, making them optional $optionalArgTypesOffset = count($argTypes) - 1; foreach (array_keys($argTypes) as $key) { $optionalArgTypes[] = $optionalArgTypesOffset + $key; } } } else { $argTypes[] = $argType; } } $allConstant = TrinaryLogic::createYes()->lazyAnd($argTypes, static function (Type $argType) { return $argType->isConstantArray(); }); if ($allConstant->yes()) { $newArrayBuilder = ConstantArrayTypeBuilder::createEmpty(); foreach ($argTypes as $argType) { /** @var array $keyTypes */ $keyTypes = []; foreach ($argType->getConstantArrays() as $constantArray) { foreach ($constantArray->getKeyTypes() as $keyType) { $keyTypes[$keyType->getValue()] = $keyType; } } foreach ($keyTypes as $keyType) { $newArrayBuilder->setOffsetValueType($keyType instanceof ConstantIntegerType ? null : $keyType, $argType->getOffsetValueType($keyType), !$argType->hasOffsetValueType($keyType)->yes()); } } return $newArrayBuilder->getArray(); } $keyTypes = []; $valueTypes = []; $nonEmpty = \false; $isList = \true; foreach ($argTypes as $key => $argType) { $keyType = $argType->getIterableKeyType(); $keyTypes[] = $keyType; $valueTypes[] = $argType->getIterableValueType(); if (!(new IntegerType())->isSuperTypeOf($keyType)->yes()) { $isList = \false; } if (in_array($key, $optionalArgTypes, \true) || !$argType->isIterableAtLeastOnce()->yes()) { continue; } $nonEmpty = \true; } $keyType = TypeCombinator::union(...$keyTypes); if ($keyType instanceof NeverType) { return new ConstantArrayType([], []); } $arrayType = new ArrayType($keyType, TypeCombinator::union(...$valueTypes)); if ($nonEmpty) { $arrayType = TypeCombinator::intersect($arrayType, new NonEmptyArrayType()); } if ($isList) { $arrayType = AccessoryArrayListType::intersectWith($arrayType); } return $arrayType; } } reflectionProvider = $reflectionProvider; } public function isStaticMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getName() === '__construct' && $methodReflection->getDeclaringClass()->getName() === ReflectionFunction::class; } public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->getArgs()) < 1) { return $methodReflection->getThrowType(); } $valueType = $scope->getType($methodCall->getArgs()[0]->value); foreach ($valueType->getConstantStrings() as $constantString) { if ($constantString->getValue() === '') { return null; } if (!$this->reflectionProvider->hasFunction(new Name($constantString->getValue()), $scope)) { return $methodReflection->getThrowType(); } $valueType = TypeCombinator::remove($valueType, $constantString); } if (!$valueType instanceof NeverType) { return $methodReflection->getThrowType(); } return null; } } getName(), ['date_create_from_format', 'date_create_immutable_from_format'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 2) { return null; } $formats = $scope->getType($functionCall->getArgs()[0]->value)->getConstantStrings(); $datetimes = $scope->getType($functionCall->getArgs()[1]->value)->getConstantStrings(); if (count($formats) === 0 || count($datetimes) === 0) { return null; } $types = []; $className = $functionReflection->getName() === 'date_create_from_format' ? DateTime::class : DateTimeImmutable::class; foreach ($formats as $formatConstantString) { foreach ($datetimes as $datetimeConstantString) { $isValid = DateTime::createFromFormat($formatConstantString->getValue(), $datetimeConstantString->getValue()) !== \false; $types[] = $isValid ? new ObjectType($className) : new ConstantBooleanType(\false); } } return TypeCombinator::union(...$types); } } getName() === 'ini_get'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) < 1) { return null; } $numericString = TypeCombinator::intersect(new StringType(), new AccessoryNumericStringType()); $types = ['date.timezone' => new StringType(), 'memory_limit' => new StringType(), 'max_execution_time' => $numericString, 'max_input_time' => $numericString, 'default_socket_timeout' => $numericString, 'precision' => $numericString]; $argType = $scope->getType($args[0]->value); $results = []; foreach ($argType->getConstantStrings() as $constantString) { if (!array_key_exists($constantString->getValue(), $types)) { return null; } $results[] = $types[$constantString->getValue()]; } if (count($results) > 0) { return TypeCombinator::union(...$results); } return null; } } getName() === 'array_change_key_case'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $arrayType = $scope->getType($functionCall->getArgs()[0]->value); if (!isset($functionCall->getArgs()[1])) { $case = CASE_LOWER; } else { $caseType = $scope->getType($functionCall->getArgs()[1]->value); $scalarValues = $caseType->getConstantScalarValues(); if (count($scalarValues) === 1) { $case = (int) $scalarValues[0]; } else { $case = null; } } $constantArrays = $arrayType->getConstantArrays(); if (count($constantArrays) > 0) { $arrayTypes = []; foreach ($constantArrays as $constantArray) { $newConstantArrayBuilder = ConstantArrayTypeBuilder::createEmpty(); $valueTypes = $constantArray->getValueTypes(); foreach ($constantArray->getKeyTypes() as $i => $keyType) { $valueType = $valueTypes[$i]; $constantStrings = $keyType->getConstantStrings(); if (count($constantStrings) > 0) { $keyType = TypeCombinator::union(...array_map(function (ConstantStringType $type) use($case) : Type { return $this->mapConstantString($type, $case); }, $constantStrings)); } $newConstantArrayBuilder->setOffsetValueType($keyType, $valueType, $constantArray->isOptionalKey($i)); } $newConstantArrayType = $newConstantArrayBuilder->getArray(); if ($constantArray->isList()->yes()) { $newConstantArrayType = AccessoryArrayListType::intersectWith($newConstantArrayType); } $arrayTypes[] = $newConstantArrayType; } $newArrayType = TypeCombinator::union(...$arrayTypes); } else { $keysType = $arrayType->getIterableKeyType(); $keysType = TypeTraverser::map($keysType, function (Type $type, callable $traverse) use($case) : Type { if ($type instanceof UnionType) { return $traverse($type); } $constantStrings = $type->getConstantStrings(); if (count($constantStrings) > 0) { return TypeCombinator::union(...array_map(function (ConstantStringType $type) use($case) : Type { return $this->mapConstantString($type, $case); }, $constantStrings)); } if ($type->isString()->yes()) { $types = [new StringType()]; if ($type->isNonFalsyString()->yes()) { $types[] = new AccessoryNonFalsyStringType(); } elseif ($type->isNonEmptyString()->yes()) { $types[] = new AccessoryNonEmptyStringType(); } if ($type->isNumericString()->yes()) { $types[] = new AccessoryNumericStringType(); } if ($case === CASE_LOWER) { $types[] = new AccessoryLowercaseStringType(); } elseif ($case === CASE_UPPER) { $types[] = new AccessoryUppercaseStringType(); } return TypeCombinator::intersect(...$types); } return $type; }); $newArrayType = TypeCombinator::intersect(new ArrayType($keysType, $arrayType->getIterableValueType()), ...TypeUtils::getAccessoryTypes($arrayType)); } if ($arrayType->isIterableAtLeastOnce()->yes()) { $newArrayType = TypeCombinator::intersect($newArrayType, new NonEmptyArrayType()); } return $newArrayType; } private function mapConstantString(ConstantStringType $type, ?int $case) : Type { if ($case === CASE_LOWER) { return new ConstantStringType(strtolower($type->getValue())); } elseif ($case === CASE_UPPER) { return new ConstantStringType(strtoupper($type->getValue())); } return TypeCombinator::union(new ConstantStringType(strtolower($type->getValue())), new ConstantStringType(strtoupper($type->getValue()))); } } getName() === 'str_word_count'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, Node\Expr\FuncCall $functionCall, Scope $scope) : Type { $argsCount = count($functionCall->getArgs()); if ($argsCount === 1) { return new IntegerType(); } elseif ($argsCount === 2 || $argsCount === 3) { $formatType = $scope->getType($functionCall->getArgs()[1]->value); if ($formatType instanceof ConstantIntegerType) { $val = $formatType->getValue(); if ($val === 0) { // return word count return new IntegerType(); } elseif ($val === 1 || $val === 2) { // return [word] or [offset => word] return new ArrayType(new IntegerType(), new StringType()); } // return false, invalid format value specified return new ConstantBooleanType(\false); } // Could be invalid format type as well, but parameter type checks will catch that. return new UnionType([new IntegerType(), new ArrayType(new IntegerType(), new StringType()), new ConstantBooleanType(\false)]); } // else fatal error; too many or too few arguments return new ErrorType(); } } arrayFilterFunctionReturnTypeHelper = $arrayFilterFunctionReturnTypeHelper; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'array_find'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 2) { return null; } $arrayType = $scope->getType($functionCall->getArgs()[0]->value); if (count($arrayType->getArrays()) < 1) { return null; } $arrayArg = $functionCall->getArgs()[0]->value ?? null; $callbackArg = $functionCall->getArgs()[1]->value ?? null; $resultTypes = $this->arrayFilterFunctionReturnTypeHelper->getType($scope, $arrayArg, $callbackArg, null); $resultType = TypeCombinator::union(...array_map(static function ($type) { return $type->getIterableValueType(); }, $resultTypes->getArrays())); return $resultTypes->isIterableAtLeastOnce()->yes() ? $resultType : TypeCombinator::addNull($resultType); } } getConstantStrings() as $formatString) { $types[] = $this->buildReturnTypeFromFormat($formatString->getValue(), $useMicrosec); } if (count($types) === 0) { $types[] = $formatType->isNonEmptyString()->yes() ? new IntersectionType([new StringType(), new AccessoryNonEmptyStringType()]) : new StringType(); } $type = TypeCombinator::union(...$types); if ($type->isNumericString()->no() && $formatType->isNonEmptyString()->yes()) { $type = TypeCombinator::union($type, new IntersectionType([new StringType(), new AccessoryNonEmptyStringType()])); } return $type; } public function buildReturnTypeFromFormat(string $formatString, bool $useMicrosec) : Type { // see see https://www.php.net/manual/en/datetime.format.php switch ($formatString) { case 'd': return $this->buildNumericRangeType(1, 31, \true); case 'j': return $this->buildNumericRangeType(1, 31, \false); case 'N': return $this->buildNumericRangeType(1, 7, \false); case 'w': return $this->buildNumericRangeType(0, 6, \false); case 'm': return $this->buildNumericRangeType(1, 12, \true); case 'n': return $this->buildNumericRangeType(1, 12, \false); case 't': return $this->buildNumericRangeType(28, 31, \false); case 'L': return $this->buildNumericRangeType(0, 1, \false); case 'g': return $this->buildNumericRangeType(1, 12, \false); case 'G': return $this->buildNumericRangeType(0, 23, \false); case 'h': return $this->buildNumericRangeType(1, 12, \true); case 'H': return $this->buildNumericRangeType(0, 23, \true); case 'I': return $this->buildNumericRangeType(0, 1, \false); case 'u': return $useMicrosec ? new IntersectionType([new StringType(), new AccessoryNonFalsyStringType(), new AccessoryNumericStringType()]) : new ConstantStringType('000000'); case 'v': return $useMicrosec ? new IntersectionType([new StringType(), new AccessoryNonFalsyStringType(), new AccessoryNumericStringType()]) : new ConstantStringType('000'); } $date = date($formatString); // If parameter string is not included, returned as ConstantStringType if ($date === $formatString) { return new ConstantStringType($date); } if (is_numeric($date)) { return new IntersectionType([new StringType(), new AccessoryNumericStringType()]); } return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } private function buildNumericRangeType(int $min, int $max, bool $zeroPad) : Type { $types = []; for ($i = $min; $i <= $max; $i++) { $string = (string) $i; if ($zeroPad) { $string = str_pad($string, 2, '0', STR_PAD_LEFT); } $types[] = new ConstantStringType($string); } return new UnionType($types); } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'mb_substitute_character'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $minCodePoint = $this->phpVersion->getVersionId() < 80000 ? 1 : 0; $maxCodePoint = $this->phpVersion->supportsAllUnicodeScalarCodePointsInMbSubstituteCharacter() ? 0x10ffff : 0xfffe; $ranges = []; if ($this->phpVersion->supportsAllUnicodeScalarCodePointsInMbSubstituteCharacter()) { // Surrogates aren't valid in PHP 7.2+ $ranges[] = IntegerRangeType::fromInterval($minCodePoint, 0xd7ff); $ranges[] = IntegerRangeType::fromInterval(0xe000, $maxCodePoint); } else { $ranges[] = IntegerRangeType::fromInterval($minCodePoint, $maxCodePoint); } if (!isset($functionCall->getArgs()[0])) { return TypeCombinator::union(new ConstantStringType('none'), new ConstantStringType('long'), new ConstantStringType('entity'), ...$ranges); } $argType = $scope->getType($functionCall->getArgs()[0]->value); $isString = $argType->isString(); $isNull = $argType->isNull(); $isInteger = $argType->isInteger(); if ($isString->no() && $isNull->no() && $isInteger->no()) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } return new BooleanType(); } if ($isInteger->yes()) { $invalidRanges = []; foreach ($ranges as $range) { $isInRange = $range->isSuperTypeOf($argType); if ($isInRange->yes()) { return new ConstantBooleanType(\true); } $invalidRanges[] = $isInRange->no(); } if ($argType instanceof ConstantIntegerType || !in_array(\false, $invalidRanges, \true)) { if ($this->phpVersion->throwsValueErrorForInternalFunctions()) { return new NeverType(); } return new ConstantBooleanType(\false); } } elseif ($isString->yes()) { if ($argType->isNonEmptyString()->no()) { // The empty string was a valid alias for "none" in PHP < 8. if ($this->phpVersion->isEmptyStringValidAliasForNoneInMbSubstituteCharacter()) { return new ConstantBooleanType(\true); } return new NeverType(); } if (!$this->phpVersion->isNumericStringValidArgInMbSubstituteCharacter() && $argType->isNumericString()->yes()) { return new NeverType(); } if ($argType instanceof ConstantStringType) { $value = strtolower($argType->getValue()); if (in_array($value, ['none', 'long', 'entity'], \true)) { return new ConstantBooleanType(\true); } if ($argType->isNumericString()->yes()) { $codePoint = (int) $value; $isValid = $codePoint >= $minCodePoint && $codePoint <= $maxCodePoint; if ($this->phpVersion->supportsAllUnicodeScalarCodePointsInMbSubstituteCharacter()) { $isValid = $isValid && ($codePoint < 0xd800 || $codePoint > 0xdfff); } return new ConstantBooleanType($isValid); } if ($this->phpVersion->throwsValueErrorForInternalFunctions()) { return new NeverType(); } return new ConstantBooleanType(\false); } } elseif ($isNull->yes()) { // The $substitute_character arg is nullable in PHP 8+ return new ConstantBooleanType($this->phpVersion->isNullValidArgInMbSubstituteCharacter()); } return new BooleanType(); } } typeSpecifier = $typeSpecifier; } public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool { return $functionReflection->getName() === 'define' && $context->null() && count($node->getArgs()) >= 2; } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { $constantName = $scope->getType($node->getArgs()[0]->value); if (!$constantName instanceof ConstantStringType || $constantName->getValue() === '') { return new SpecifiedTypes([], []); } return $this->typeSpecifier->create(new Node\Expr\ConstFetch(new Node\Name\FullyQualified($constantName->getValue())), $scope->getType($node->getArgs()[1]->value), TypeSpecifierContext::createTruthy(), \true, $scope); } } getName() === 'pow'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 2) { return null; } return $scope->getType(new Pow($functionCall->getArgs()[0]->value, $functionCall->getArgs()[1]->value)); } } 0, 'array_diff_assoc' => 0, 'array_diff_key' => 0, 'array_diff_uassoc' => 0, 'array_diff_ukey' => 0, 'array_diff' => 0, 'array_udiff_assoc' => 0, 'array_udiff_uassoc' => 0, 'array_udiff' => 0, 'array_intersect_assoc' => 0, 'array_intersect_uassoc' => 0, 'array_intersect_ukey' => 0, 'array_intersect' => 0, 'array_uintersect_assoc' => 0, 'array_uintersect_uassoc' => 0, 'array_uintersect' => 0]; public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return array_key_exists($functionReflection->getName(), self::FUNCTION_NAMES); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $argumentPosition = self::FUNCTION_NAMES[$functionReflection->getName()]; if (!isset($functionCall->getArgs()[$argumentPosition])) { return null; } $argument = $functionCall->getArgs()[$argumentPosition]; $argumentType = $scope->getType($argument->value); $argumentKeyType = $argumentType->getIterableKeyType(); $argumentValueType = $argumentType->getIterableValueType(); if ($argument->unpack) { $argumentKeyType = $argumentKeyType->generalize(GeneralizePrecision::moreSpecific()); $argumentValueType = $argumentValueType->getIterableValueType()->generalize(GeneralizePrecision::moreSpecific()); } $array = new ArrayType($argumentKeyType, $argumentValueType); if ($functionReflection->getName() === 'array_unique' && $argumentType->isIterableAtLeastOnce()->yes()) { $array = TypeCombinator::intersect($array, new NonEmptyArrayType()); } return $array; } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'highlight_string'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $args = $functionCall->getArgs(); if (count($args) < 2) { if ($this->phpVersion->highlightStringDoesNotReturnFalse()) { return new ConstantBooleanType(\true); } return new BooleanType(); } $returnType = $scope->getType($args[1]->value); if ($returnType->isTrue()->yes()) { return new StringType(); } if ($this->phpVersion->highlightStringDoesNotReturnFalse()) { return new ConstantBooleanType(\true); } return new BooleanType(); } } getName() === 'version_compare'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 2) { return null; } $version1Strings = $scope->getType($functionCall->getArgs()[0]->value)->getConstantStrings(); $version2Strings = $scope->getType($functionCall->getArgs()[1]->value)->getConstantStrings(); $counts = [count($version1Strings), count($version2Strings)]; if (isset($functionCall->getArgs()[2])) { $operatorStrings = $scope->getType($functionCall->getArgs()[2]->value)->getConstantStrings(); $counts[] = count($operatorStrings); $returnType = new BooleanType(); } else { $returnType = TypeCombinator::union(new ConstantIntegerType(-1), new ConstantIntegerType(0), new ConstantIntegerType(1)); } if (count(array_filter($counts, static function (int $count) : bool { return $count === 0; })) > 0) { return $returnType; // one of the arguments is not a constant string } if (count(array_filter($counts, static function (int $count) : bool { return $count > 1; })) > 1) { return $returnType; // more than one argument can have multiple possibilities, avoid combinatorial explosion } $types = []; foreach ($version1Strings as $version1String) { foreach ($version2Strings as $version2String) { if (isset($operatorStrings)) { foreach ($operatorStrings as $operatorString) { $value = version_compare($version1String->getValue(), $version2String->getValue(), $operatorString->getValue()); $types[$value] = new ConstantBooleanType($value); } } else { $value = version_compare($version1String->getValue(), $version2String->getValue()); $types[$value] = new ConstantIntegerType($value); } } } return TypeCombinator::union(...$types); } } constantHelper = $constantHelper; } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool { return $functionReflection->getName() === 'defined' && count($node->getArgs()) >= 1 && $context->true(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { $constantName = $scope->getType($node->getArgs()[0]->value); if (!$constantName instanceof ConstantStringType || $constantName->getValue() === '') { return new SpecifiedTypes([], []); } $expr = $this->constantHelper->createExprFromConstantName($constantName->getValue()); if ($expr === null) { return new SpecifiedTypes([], []); } return $this->typeSpecifier->create($expr, new MixedType(), $context, \false, $scope); } } getName() === 'get_class'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $args = $functionCall->getArgs(); if (count($args) === 0) { if ($scope->isInTrait()) { return new ClassStringType(); } if ($scope->isInClass()) { return new ConstantStringType($scope->getClassReflection()->getName(), \true); } return new ConstantBooleanType(\false); } $argType = $scope->getType($args[0]->value); if ($scope->isInTrait() && TypeUtils::findThisType($argType) !== null) { return new ClassStringType(); } return TypeTraverser::map($argType, static function (Type $type, callable $traverse) : Type { if ($type instanceof UnionType || $type instanceof IntersectionType) { return $traverse($type); } if ($type instanceof EnumCaseObjectType) { return new GenericClassStringType(new ObjectType($type->getClassName())); } $objectClassNames = $type->getObjectClassNames(); if ($type instanceof TemplateType && $objectClassNames === []) { if ($type instanceof ObjectWithoutClassType) { return new GenericClassStringType($type); } return new UnionType([new GenericClassStringType($type), new ConstantBooleanType(\false)]); } elseif ($type instanceof MixedType) { return new UnionType([new ClassStringType(), new ConstantBooleanType(\false)]); } elseif ($type instanceof StaticType) { return new GenericClassStringType($type->getStaticObjectType()); } elseif ($objectClassNames !== []) { return new GenericClassStringType($type); } elseif ($type instanceof ObjectWithoutClassType) { return new ClassStringType(); } return new ConstantBooleanType(\false); }); } } phpVersion = $phpVersion; } public function isStaticMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getName() === '__construct' && $methodReflection->getDeclaringClass()->getName() === DateInterval::class; } public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->getArgs()) === 0) { return $methodReflection->getThrowType(); } $valueType = $scope->getType($methodCall->getArgs()[0]->value); $constantStrings = $valueType->getConstantStrings(); foreach ($constantStrings as $constantString) { try { new DateInterval($constantString->getValue()); } catch (\Exception $e) { // phpcs:ignore return $this->exceptionType(); } $valueType = TypeCombinator::remove($valueType, $constantString); } if (!$valueType instanceof NeverType) { return $this->exceptionType(); } return null; } private function exceptionType() : Type { if ($this->phpVersion->hasDateTimeExceptions()) { return new ObjectType('DateMalformedIntervalStringException'); } return new ObjectType('Exception'); } } getName() === 'bind'; } public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : ?Type { $closureType = $scope->getType($methodCall->getArgs()[0]->value); if (!$closureType instanceof ClosureType) { return null; } return $closureType; } } getName() === 'get_called_class'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { if ($scope->isInClass()) { return $scope->getType(new ClassConstFetch(new Name('static'), 'class')); } return new ConstantBooleanType(\false); } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return in_array($functionReflection->getName(), ['substr', 'mb_substr'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) < 2) { return null; } $string = $scope->getType($args[0]->value); $offset = $scope->getType($args[1]->value); $negativeOffset = IntegerRangeType::fromInterval(null, -1)->isSuperTypeOf($offset)->yes(); $zeroOffset = (new ConstantIntegerType(0))->isSuperTypeOf($offset)->yes(); $length = null; $positiveLength = \false; $maybeOneLength = \false; if (count($args) === 3) { $length = $scope->getType($args[2]->value); $positiveLength = IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($length)->yes(); $maybeOneLength = !(new ConstantIntegerType(1))->isSuperTypeOf($length)->no(); } $constantStrings = $string->getConstantStrings(); if (count($constantStrings) > 0 && $offset instanceof ConstantIntegerType && ($length === null || $length instanceof ConstantIntegerType)) { $results = []; foreach ($constantStrings as $constantString) { if ($length !== null) { if ($functionReflection->getName() === 'mb_substr') { $substr = mb_substr($constantString->getValue(), $offset->getValue(), $length->getValue()); } else { $substr = substr($constantString->getValue(), $offset->getValue(), $length->getValue()); } } else { if ($functionReflection->getName() === 'mb_substr') { $substr = mb_substr($constantString->getValue(), $offset->getValue()); } else { $substr = substr($constantString->getValue(), $offset->getValue()); } } if (is_bool($substr)) { $results[] = new ConstantBooleanType($substr); } else { $results[] = new ConstantStringType($substr); } } return TypeCombinator::union(...$results); } $accessoryTypes = []; $isNotEmpty = \false; if ($string->isLowercaseString()->yes()) { $accessoryTypes[] = new AccessoryLowercaseStringType(); } if ($string->isUppercaseString()->yes()) { $accessoryTypes[] = new AccessoryUppercaseStringType(); } if ($string->isNonEmptyString()->yes() && ($negativeOffset || $zeroOffset && $positiveLength)) { $isNotEmpty = \true; if ($string->isNonFalsyString()->yes() && !$maybeOneLength) { $accessoryTypes[] = new AccessoryNonFalsyStringType(); } else { $accessoryTypes[] = new AccessoryNonEmptyStringType(); } } if (count($accessoryTypes) > 0) { $accessoryTypes[] = new StringType(); if (!$isNotEmpty && $this->phpVersion->substrReturnFalseInsteadOfEmptyString()) { return TypeCombinator::union(new ConstantBooleanType(\false), new IntersectionType($accessoryTypes)); } return new IntersectionType($accessoryTypes); } return null; } } typeSpecifier = $typeSpecifier; } public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool { return in_array($functionReflection->getName(), ['array_key_exists', 'key_exists'], \true) && !$context->null(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { if (count($node->getArgs()) < 2) { return new SpecifiedTypes(); } $key = $node->getArgs()[0]->value; $array = $node->getArgs()[1]->value; $keyType = $scope->getType($key); $arrayType = $scope->getType($array); if (!$keyType instanceof ConstantIntegerType && !$keyType instanceof ConstantStringType && !$arrayType->isIterableAtLeastOnce()->no()) { if ($context->true()) { $arrayKeyType = $arrayType->getIterableKeyType(); if ($keyType->isString()->yes()) { $arrayKeyType = $arrayKeyType->toString(); } elseif ($keyType->isString()->maybe()) { $arrayKeyType = TypeCombinator::union($arrayKeyType, $arrayKeyType->toString()); } $specifiedTypes = $this->typeSpecifier->create($key, $arrayKeyType, $context, \false, $scope); $arrayDimFetch = new ArrayDimFetch($array, $key); return $specifiedTypes->unionWith($this->typeSpecifier->create($arrayDimFetch, $arrayType->getIterableValueType(), $context, \false, $scope, new Identical($arrayDimFetch, new ConstFetch(new Name('__PHPSTAN_FAUX_CONSTANT'))))); } return new SpecifiedTypes(); } if ($context->true()) { $type = TypeCombinator::intersect(new ArrayType(new MixedType(), new MixedType()), new HasOffsetType($keyType)); } else { $type = new HasOffsetType($keyType); } return $this->typeSpecifier->create($array, $type, $context, \false, $scope); } } regexShapeMatcher = $regexShapeMatcher; } public function isFunctionSupported(FunctionReflection $functionReflection, ParameterReflection $parameter) : bool { return in_array(strtolower($functionReflection->getName()), ['preg_match', 'preg_match_all'], \true) && in_array($parameter->getName(), ['subpatterns', 'matches'], \true); } public function getParameterOutTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $funcCall, ParameterReflection $parameter, Scope $scope) : ?Type { $args = $funcCall->getArgs(); $patternArg = $args[0] ?? null; $matchesArg = $args[2] ?? null; $flagsArg = $args[3] ?? null; if ($patternArg === null || $matchesArg === null) { return null; } $flagsType = null; if ($flagsArg !== null) { $flagsType = $scope->getType($flagsArg->value); } if ($functionReflection->getName() === 'preg_match') { return $this->regexShapeMatcher->matchExpr($patternArg->value, $flagsType, TrinaryLogic::createMaybe(), $scope); } return $this->regexShapeMatcher->matchAllExpr($patternArg->value, $flagsType, TrinaryLogic::createMaybe(), $scope); } } getName() === 'ltrim'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) !== 2) { return null; } $string = $scope->getType($functionCall->getArgs()[0]->value); $trimChars = $scope->getType($functionCall->getArgs()[1]->value); if ($trimChars instanceof ConstantStringType && $trimChars->getValue() === '\\' && $string->isClassStringType()->yes()) { if ($string instanceof ConstantStringType) { return new ConstantStringType(ltrim($string->getValue(), $trimChars->getValue()), \true); } return new ClassStringType(); } return null; } } |null */ private $componentTypesPairedConstants = null; /** @var array|null */ private $componentTypesPairedStrings = null; /** @var array|null */ private $componentTypesPairedConstantsForLowercaseString = null; /** @var array|null */ private $componentTypesPairedStringsForLowercaseString = null; /** * @var ?Type */ private $allComponentsTogetherType = null; /** * @var ?Type */ private $allComponentsTogetherTypeForLowercaseString = null; public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'parse_url'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 1) { return null; } $this->cacheReturnTypes(); $urlType = $scope->getType($functionCall->getArgs()[0]->value); if (count($functionCall->getArgs()) > 1) { $componentType = $scope->getType($functionCall->getArgs()[1]->value); if (!$componentType->isConstantValue()->yes()) { return $this->createAllComponentsReturnType($urlType->isLowercaseString()->yes()); } $componentType = $componentType->toInteger(); if (!$componentType instanceof ConstantIntegerType) { return $this->createAllComponentsReturnType($urlType->isLowercaseString()->yes()); } } else { $componentType = new ConstantIntegerType(-1); } if (count($urlType->getConstantStrings()) > 0) { $types = []; foreach ($urlType->getConstantStrings() as $constantString) { try { $result = @parse_url($constantString->getValue(), $componentType->getValue()); } catch (ValueError $e) { $types[] = new ConstantBooleanType(\false); continue; } $types[] = $scope->getTypeFromValue($result); } return TypeCombinator::union(...$types); } if ($componentType->getValue() === -1) { return TypeCombinator::union($this->createComponentsArray($urlType->isLowercaseString()->yes()), new ConstantBooleanType(\false)); } if ($urlType->isLowercaseString()->yes()) { return $this->componentTypesPairedConstantsForLowercaseString[$componentType->getValue()] ?? new ConstantBooleanType(\false); } return $this->componentTypesPairedConstants[$componentType->getValue()] ?? new ConstantBooleanType(\false); } private function createAllComponentsReturnType(bool $urlIsLowercase) : Type { if ($urlIsLowercase) { if ($this->allComponentsTogetherTypeForLowercaseString === null) { $returnTypes = [new ConstantBooleanType(\false), new NullType(), IntegerRangeType::fromInterval(0, 65535), new IntersectionType([new StringType(), new AccessoryLowercaseStringType()]), $this->createComponentsArray(\true)]; $this->allComponentsTogetherTypeForLowercaseString = TypeCombinator::union(...$returnTypes); } return $this->allComponentsTogetherTypeForLowercaseString; } if ($this->allComponentsTogetherType === null) { $returnTypes = [new ConstantBooleanType(\false), new NullType(), IntegerRangeType::fromInterval(0, 65535), new StringType(), $this->createComponentsArray(\false)]; $this->allComponentsTogetherType = TypeCombinator::union(...$returnTypes); } return $this->allComponentsTogetherType; } private function createComponentsArray(bool $urlIsLowercase) : Type { $builder = ConstantArrayTypeBuilder::createEmpty(); if ($urlIsLowercase) { if ($this->componentTypesPairedStringsForLowercaseString === null) { throw new ShouldNotHappenException(); } foreach ($this->componentTypesPairedStringsForLowercaseString as $componentName => $componentValueType) { $builder->setOffsetValueType(new ConstantStringType($componentName), $componentValueType, \true); } } else { if ($this->componentTypesPairedStrings === null) { throw new ShouldNotHappenException(); } foreach ($this->componentTypesPairedStrings as $componentName => $componentValueType) { $builder->setOffsetValueType(new ConstantStringType($componentName), $componentValueType, \true); } } return $builder->getArray(); } private function cacheReturnTypes() : void { if ($this->componentTypesPairedConstants !== null) { return; } $string = new StringType(); $lowercaseString = new IntersectionType([new StringType(), new AccessoryLowercaseStringType()]); $port = IntegerRangeType::fromInterval(0, 65535); $false = new ConstantBooleanType(\false); $null = new NullType(); $stringOrFalseOrNull = TypeCombinator::union($string, $false, $null); $lowercaseStringOrFalseOrNull = TypeCombinator::union($lowercaseString, $false, $null); $portOrFalseOrNull = TypeCombinator::union($port, $false, $null); $this->componentTypesPairedConstants = [PHP_URL_SCHEME => $stringOrFalseOrNull, PHP_URL_HOST => $stringOrFalseOrNull, PHP_URL_PORT => $portOrFalseOrNull, PHP_URL_USER => $stringOrFalseOrNull, PHP_URL_PASS => $stringOrFalseOrNull, PHP_URL_PATH => $stringOrFalseOrNull, PHP_URL_QUERY => $stringOrFalseOrNull, PHP_URL_FRAGMENT => $stringOrFalseOrNull]; $this->componentTypesPairedConstantsForLowercaseString = [PHP_URL_SCHEME => $lowercaseStringOrFalseOrNull, PHP_URL_HOST => $lowercaseStringOrFalseOrNull, PHP_URL_PORT => $portOrFalseOrNull, PHP_URL_USER => $lowercaseStringOrFalseOrNull, PHP_URL_PASS => $lowercaseStringOrFalseOrNull, PHP_URL_PATH => $lowercaseStringOrFalseOrNull, PHP_URL_QUERY => $lowercaseStringOrFalseOrNull, PHP_URL_FRAGMENT => $lowercaseStringOrFalseOrNull]; $this->componentTypesPairedStrings = ['scheme' => $string, 'host' => $string, 'port' => $port, 'user' => $string, 'pass' => $string, 'path' => $string, 'query' => $string, 'fragment' => $string]; $this->componentTypesPairedStringsForLowercaseString = ['scheme' => $lowercaseString, 'host' => $lowercaseString, 'port' => $port, 'user' => $lowercaseString, 'pass' => $lowercaseString, 'path' => $lowercaseString, 'query' => $lowercaseString, 'fragment' => $lowercaseString]; } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return strtolower($functionReflection->getName()) === 'array_keys'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) !== 1) { return null; } $arrayType = $scope->getType($functionCall->getArgs()[0]->value); if ($arrayType->isArray()->no()) { return $this->phpVersion->arrayFunctionsReturnNullWithNonArray() ? new NullType() : new NeverType(); } return $arrayType->getKeysArray(); } } getName() === 'array_key_first'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $argType = $scope->getType($functionCall->getArgs()[0]->value); $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); if ($iterableAtLeastOnce->no()) { return new NullType(); } $keyType = $argType->getFirstIterableKeyType(); if ($iterableAtLeastOnce->yes()) { return $keyType; } return TypeCombinator::union($keyType, new NullType()); } } getName() === '__construct'; } public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : Type { if (!isset($methodCall->getArgs()[0])) { return new ObjectType(DatePeriod::class); } if (!$methodCall->class instanceof Name) { return new ObjectType(DatePeriod::class); } $className = $scope->resolveName($methodCall->class); if (strtolower($className) !== 'dateperiod') { return new ObjectType($className); } $firstArgType = $scope->getType($methodCall->getArgs()[0]->value); if ($firstArgType->isString()->yes()) { $firstArgType = new ObjectType(DateTime::class); } $thirdArgType = null; if (isset($methodCall->getArgs()[2])) { $thirdArgType = $scope->getType($methodCall->getArgs()[2]->value); } if (!$thirdArgType instanceof Type) { return new GenericObjectType(DatePeriod::class, [$firstArgType, new NullType(), new IntegerType()]); } if ((new ObjectType(DateTimeInterface::class))->isSuperTypeOf($thirdArgType)->yes()) { return new GenericObjectType(DatePeriod::class, [$firstArgType, $thirdArgType, new NullType()]); } if ($thirdArgType->isInteger()->yes()) { return new GenericObjectType(DatePeriod::class, [$firstArgType, new NullType(), $thirdArgType]); } return new ObjectType(DatePeriod::class); } } getName() === 'array_map'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $numArgs = count($functionCall->getArgs()); if ($numArgs < 2) { return null; } $singleArrayArgument = !isset($functionCall->getArgs()[2]); $callableType = $scope->getType($functionCall->getArgs()[0]->value); $callableIsNull = $callableType->isNull()->yes(); $callableParametersAcceptors = null; if ($callableType->isCallable()->yes()) { $callableParametersAcceptors = $callableType->getCallableParametersAcceptors($scope); $valueType = ParametersAcceptorSelector::selectFromTypes(array_map(static function (Node\Arg $arg) use($scope) { return $scope->getType($arg->value)->getIterableValueType(); }, array_slice($functionCall->getArgs(), 1)), $callableParametersAcceptors, \false)->getReturnType(); } elseif ($callableIsNull) { $arrayBuilder = ConstantArrayTypeBuilder::createEmpty(); $argTypes = []; $areAllSameSize = \true; $expectedSize = null; foreach (array_slice($functionCall->getArgs(), 1) as $index => $arg) { $argTypes[$index] = $argType = $scope->getType($arg->value); if (!$areAllSameSize || $numArgs === 2) { continue; } $arraySizes = $argType->getArraySize()->getConstantScalarValues(); if ($arraySizes === []) { $areAllSameSize = \false; continue; } foreach ($arraySizes as $size) { $expectedSize = $expectedSize ?? $size; if ($expectedSize === $size) { continue; } $areAllSameSize = \false; continue 2; } } if (!$areAllSameSize) { $firstArr = $functionCall->getArgs()[1]->value; $identities = []; foreach (array_slice($functionCall->getArgs(), 2) as $arg) { $identities[] = new Node\Expr\BinaryOp\Identical($firstArr, $arg->value); } $and = array_reduce($identities, static function (Node\Expr $a, Node\Expr $b) { return new Node\Expr\BinaryOp\BooleanAnd($a, $b); }, new Node\Expr\ConstFetch(new Node\Name('true'))); $areAllSameSize = $scope->getType($and)->isTrue()->yes(); } $addNull = !$areAllSameSize; foreach ($argTypes as $index => $argType) { $offsetValueType = $argType->getIterableValueType(); if ($addNull) { $offsetValueType = TypeCombinator::addNull($offsetValueType); } $arrayBuilder->setOffsetValueType(new ConstantIntegerType($index), $offsetValueType); } $valueType = $arrayBuilder->getArray(); } else { $valueType = new MixedType(); } $arrayType = $scope->getType($functionCall->getArgs()[1]->value); if ($singleArrayArgument) { if ($callableIsNull) { return $arrayType; } $constantArrays = $arrayType->getConstantArrays(); if (count($constantArrays) > 0) { $arrayTypes = []; $totalCount = TypeCombinator::countConstantArrayValueTypes($constantArrays) * TypeCombinator::countConstantArrayValueTypes([$valueType]); if ($totalCount < ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) { foreach ($constantArrays as $constantArray) { $returnedArrayBuilder = ConstantArrayTypeBuilder::createEmpty(); $valueTypes = $constantArray->getValueTypes(); foreach ($constantArray->getKeyTypes() as $i => $keyType) { $returnedArrayBuilder->setOffsetValueType($keyType, $callableParametersAcceptors !== null ? ParametersAcceptorSelector::selectFromTypes([$valueTypes[$i]], $callableParametersAcceptors, \false)->getReturnType() : $valueType, $constantArray->isOptionalKey($i)); } $returnedArray = $returnedArrayBuilder->getArray(); if ($constantArray->isList()->yes()) { $returnedArray = AccessoryArrayListType::intersectWith($returnedArray); } $arrayTypes[] = $returnedArray; } $mappedArrayType = TypeCombinator::union(...$arrayTypes); } else { $mappedArrayType = TypeCombinator::intersect(new ArrayType($arrayType->getIterableKeyType(), $valueType), ...TypeUtils::getAccessoryTypes($arrayType)); } } elseif ($arrayType->isArray()->yes()) { $mappedArrayType = TypeCombinator::intersect(new ArrayType($arrayType->getIterableKeyType(), $valueType), ...TypeUtils::getAccessoryTypes($arrayType)); } else { $mappedArrayType = new ArrayType(new MixedType(), $valueType); } } else { $mappedArrayType = AccessoryArrayListType::intersectWith(TypeCombinator::intersect(new ArrayType(new IntegerType(), $valueType), ...TypeUtils::getAccessoryTypes($arrayType))); } if ($arrayType->isIterableAtLeastOnce()->yes()) { $mappedArrayType = TypeCombinator::intersect($mappedArrayType, new NonEmptyArrayType()); } return $mappedArrayType; } } reflectionProvider = $reflectionProvider; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'get_parent_class'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) === 0) { if ($scope->isInTrait()) { return null; } if ($scope->isInClass()) { return $this->findParentClassType($scope->getClassReflection()); } return new ConstantBooleanType(\false); } $argType = $scope->getType($functionCall->getArgs()[0]->value); if ($scope->isInTrait() && TypeUtils::findThisType($argType) !== null) { return null; } $constantStrings = $argType->getConstantStrings(); if (count($constantStrings) > 0) { return TypeCombinator::union(...array_map(function (ConstantStringType $stringType) : Type { return $this->findParentClassNameType($stringType->getValue()); }, $constantStrings)); } $classNames = $argType->getObjectClassNames(); if (count($classNames) > 0) { return TypeCombinator::union(...array_map(function (string $classNames) : Type { return $this->findParentClassNameType($classNames); }, $classNames)); } return null; } private function findParentClassNameType(string $className) : Type { if (!$this->reflectionProvider->hasClass($className)) { return new UnionType([new ClassStringType(), new ConstantBooleanType(\false)]); } $classReflection = $this->reflectionProvider->getClass($className); if ($classReflection->isInterface()) { return new UnionType([new ClassStringType(), new ConstantBooleanType(\false)]); } return $this->findParentClassType($classReflection); } private function findParentClassType(ClassReflection $classReflection) : Type { $parentClass = $classReflection->getParentClass(); if ($parentClass === null) { return new ConstantBooleanType(\false); } return new ConstantStringType($parentClass->getName(), \true); } } filterFunctionReturnTypeHelper = $filterFunctionReturnTypeHelper; $this->reflectionProvider = $reflectionProvider; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return in_array(strtolower($functionReflection->getName()), ['filter_var_array', 'filter_input_array'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 2) { return null; } $functionName = strtolower($functionReflection->getName()); $inputArgType = $scope->getType($functionCall->getArgs()[0]->value); $inputConstantArrayType = null; if ($functionName === 'filter_var_array') { if ($inputArgType->isArray()->no()) { return new NeverType(); } $inputConstantArrayType = $inputArgType->getConstantArrays()[0] ?? null; } elseif ($functionName === 'filter_input_array') { $supportedTypes = TypeCombinator::union($this->reflectionProvider->getConstant(new Node\Name('INPUT_GET'), null)->getValueType(), $this->reflectionProvider->getConstant(new Node\Name('INPUT_POST'), null)->getValueType(), $this->reflectionProvider->getConstant(new Node\Name('INPUT_COOKIE'), null)->getValueType(), $this->reflectionProvider->getConstant(new Node\Name('INPUT_SERVER'), null)->getValueType(), $this->reflectionProvider->getConstant(new Node\Name('INPUT_ENV'), null)->getValueType()); if (!$inputArgType->isInteger()->yes() || $supportedTypes->isSuperTypeOf($inputArgType)->no()) { return null; } // Pragmatical solution since global expressions are not passed through the scope for performance reasons // See https://github.com/phpstan/phpstan-src/pull/2012 for details $inputArgType = new ArrayType(new StringType(), new MixedType()); } $filterArgType = $scope->getType($functionCall->getArgs()[1]->value); $filterConstantArrayType = $filterArgType->getConstantArrays()[0] ?? null; $addEmptyType = isset($functionCall->getArgs()[2]) ? $scope->getType($functionCall->getArgs()[2]->value) : null; $addEmpty = $addEmptyType === null || $addEmptyType->isTrue()->yes(); $valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty(); if ($filterArgType instanceof ConstantIntegerType) { if ($inputConstantArrayType === null) { $isList = $inputArgType->isList()->yes(); $valueType = $this->filterFunctionReturnTypeHelper->getType($inputArgType->getIterableValueType(), $filterArgType, null); $arrayType = new ArrayType($inputArgType->getIterableKeyType(), $valueType); return $isList ? AccessoryArrayListType::intersectWith($arrayType) : $arrayType; } // Override $add_empty option $addEmpty = \false; $keysType = $inputConstantArrayType; $inputKeysList = array_map(static function ($type) { return $type->getValue(); }, $inputConstantArrayType->getKeyTypes()); $filterTypesMap = array_fill_keys($inputKeysList, $filterArgType); $inputTypesMap = array_combine($inputKeysList, $inputConstantArrayType->getValueTypes()); $optionalKeys = []; foreach ($inputConstantArrayType->getOptionalKeys() as $index) { if (!isset($inputKeysList[$index])) { continue; } $optionalKeys[] = $inputKeysList[$index]; } } elseif ($filterConstantArrayType === null) { if ($inputConstantArrayType === null) { $isList = $inputArgType->isList()->yes(); $valueType = $this->filterFunctionReturnTypeHelper->getType($inputArgType, $filterArgType, null); $arrayType = new ArrayType($inputArgType->getIterableKeyType(), $addEmpty ? TypeCombinator::addNull($valueType) : $valueType); return $isList ? AccessoryArrayListType::intersectWith($arrayType) : $arrayType; } return null; } else { $keysType = $filterConstantArrayType; $filterKeyTypes = $filterConstantArrayType->getKeyTypes(); $filterKeysList = array_map(static function ($type) { return $type->getValue(); }, $filterKeyTypes); $filterTypesMap = array_combine($filterKeysList, $keysType->getValueTypes()); if ($inputConstantArrayType !== null) { $inputKeysList = array_map(static function ($type) { return $type->getValue(); }, $inputConstantArrayType->getKeyTypes()); $inputTypesMap = array_combine($inputKeysList, $inputConstantArrayType->getValueTypes()); $optionalKeys = []; foreach ($inputConstantArrayType->getOptionalKeys() as $index) { if (!isset($inputKeysList[$index])) { continue; } $optionalKeys[] = $inputKeysList[$index]; } } else { $optionalKeys = $filterKeysList; $inputTypesMap = array_fill_keys($optionalKeys, $inputArgType->getIterableValueType()); } } foreach ($keysType->getKeyTypes() as $keyType) { $optional = \false; $key = $keyType->getValue(); $inputType = $inputTypesMap[$key] ?? null; if ($inputType === null) { if ($addEmpty) { $valueTypesBuilder->setOffsetValueType($keyType, new NullType()); } continue; } [$filterType, $flagsType] = $this->fetchFilter($filterTypesMap[$key] ?? new MixedType()); $valueType = $this->filterFunctionReturnTypeHelper->getType($inputType, $filterType, $flagsType); if (in_array($key, $optionalKeys, \true)) { if ($addEmpty) { $valueType = TypeCombinator::addNull($valueType); } else { $optional = \true; } } $valueTypesBuilder->setOffsetValueType($keyType, $valueType, $optional); } return $valueTypesBuilder->getArray(); } /** @return array{?Type, ?Type} */ public function fetchFilter(Type $type) : array { if (!$type->isArray()->yes()) { return [$type, null]; } $filterKey = new ConstantStringType('filter'); if (!$type->hasOffsetValueType($filterKey)->yes()) { return [$type, null]; } $filterOffsetType = $type->getOffsetValueType($filterKey); $filterType = null; if (count($filterOffsetType->getConstantScalarTypes()) > 0) { $filterType = TypeCombinator::union(...$filterOffsetType->getConstantScalarTypes()); } return [$filterType, $type]; } } getName() === 'bindTo'; } public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : ?Type { $closureType = $scope->getType($methodCall->var); if (!$closureType instanceof ClosureType) { return null; } return $closureType; } } getName() === 'strlen'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) === 0) { return null; } $argType = $scope->getType($args[0]->value); if ($argType->isSuperTypeOf(new BooleanType())->yes()) { $constantScalars = TypeCombinator::remove($argType, new BooleanType())->getConstantScalarTypes(); if (count($constantScalars) > 0) { $constantScalars[] = new ConstantBooleanType(\true); $constantScalars[] = new ConstantBooleanType(\false); } } else { $constantScalars = $argType->getConstantScalarTypes(); } $lengths = []; foreach ($constantScalars as $constantScalar) { $stringScalar = $constantScalar->toString(); if (!$stringScalar instanceof ConstantStringType) { $lengths = []; break; } $length = strlen($stringScalar->getValue()); $lengths[] = $length; } $isNonEmpty = $argType->isNonEmptyString(); $numeric = TypeCombinator::union(new IntegerType(), new FloatType()); $range = null; if (count($lengths) > 0) { $lengths = array_unique($lengths); sort($lengths); if ($lengths === range(min($lengths), max($lengths))) { $range = IntegerRangeType::fromInterval(min($lengths), max($lengths)); } else { $range = TypeCombinator::union(...array_map(static function ($l) { return new ConstantIntegerType($l); }, $lengths)); } } elseif ($argType->isBoolean()->yes()) { $range = IntegerRangeType::fromInterval(0, 1); } elseif ($isNonEmpty->yes() || $numeric->isSuperTypeOf($argType)->yes() || TypeCombinator::remove($argType, $numeric)->isNonEmptyString()->yes()) { $range = IntegerRangeType::fromInterval(1, null); } elseif ($argType->isString()->yes() && $isNonEmpty->no()) { $range = new ConstantIntegerType(0); } return $range; } } typeSpecifier = $typeSpecifier; } public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool { return $functionReflection->getName() === 'method_exists' && $context->true() && count($node->getArgs()) >= 2; } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { $methodNameType = $scope->getType($node->getArgs()[1]->value); if (!$methodNameType instanceof ConstantStringType) { return new SpecifiedTypes([], []); } $objectType = $scope->getType($node->getArgs()[0]->value); if ($objectType->isString()->yes()) { if ($objectType->isClassStringType()->yes()) { return $this->typeSpecifier->create($node->getArgs()[0]->value, new IntersectionType([$objectType, new HasMethodType($methodNameType->getValue())]), $context, \false, $scope); } return new SpecifiedTypes([], []); } return $this->typeSpecifier->create($node->getArgs()[0]->value, new UnionType([new IntersectionType([new ObjectWithoutClassType(), new HasMethodType($methodNameType->getValue())]), new ClassStringType()]), $context, \false, $scope); } } getName(), self::FUNCTIONS, \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { if (count($functionCall->getArgs()) === 0) { return new NullType(); } $argType = $scope->getType($functionCall->getArgs()[0]->value); switch ($functionReflection->getName()) { case 'strval': return $argType->toString(); case 'intval': $type = $argType->toInteger(); return $type instanceof ErrorType ? new IntegerType() : $type; case 'boolval': return $argType->toBoolean(); case 'floatval': case 'doubleval': $type = $argType->toFloat(); return $type instanceof ErrorType ? new FloatType() : $type; default: throw new ShouldNotHappenException(); } } } getName() === 'assert' && isset($node->getArgs()[0]); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { return $this->typeSpecifier->specifyTypesInCondition($scope, $node->getArgs()[0]->value, TypeSpecifierContext::createTruthy()); } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } } dateFunctionReturnTypeHelper = $dateFunctionReturnTypeHelper; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'date_format'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { if (count($functionCall->getArgs()) < 2) { return new StringType(); } return $this->dateFunctionReturnTypeHelper->getTypeFromFormatType($scope->getType($functionCall->getArgs()[1]->value), \true); } } filterFunctionReturnTypeHelper = $filterFunctionReturnTypeHelper; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return strtolower($functionReflection->getName()) === 'filter_var'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 1) { return null; } $inputType = $scope->getType($functionCall->getArgs()[0]->value); $filterType = isset($functionCall->getArgs()[1]) ? $scope->getType($functionCall->getArgs()[1]->value) : null; $flagsType = isset($functionCall->getArgs()[2]) ? $scope->getType($functionCall->getArgs()[2]->value) : null; return $this->filterFunctionReturnTypeHelper->getType($inputType, $filterType, $flagsType); } } getName() === 'array_pop'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $argType = $scope->getType($functionCall->getArgs()[0]->value); $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); if ($iterableAtLeastOnce->no()) { return new NullType(); } $itemType = $argType->getLastIterableValueType(); if ($iterableAtLeastOnce->yes()) { return $itemType; } return TypeCombinator::union($itemType, new NullType()); } } getObjectClassNames(); if ($allowString) { foreach ($objectOrClassType->getConstantStrings() as $constantString) { $objectOrClassTypeClassNames[] = $constantString->getValue(); } $objectOrClassTypeClassNames = array_values(array_unique($objectOrClassTypeClassNames)); } return TypeTraverser::map($classType, static function (Type $type, callable $traverse) use($objectOrClassTypeClassNames, $allowString, $allowSameClass) : Type { if ($type instanceof UnionType || $type instanceof IntersectionType) { return $traverse($type); } if ($type instanceof ConstantStringType) { if (!$allowSameClass && $objectOrClassTypeClassNames === [$type->getValue()]) { return new NeverType(); } if ($allowString) { return TypeCombinator::union(new ObjectType($type->getValue()), new GenericClassStringType(new ObjectType($type->getValue()))); } return new ObjectType($type->getValue()); } if ($type instanceof GenericClassStringType) { if ($allowString) { return TypeCombinator::union($type->getGenericType(), $type); } return $type->getGenericType(); } if ($allowString) { return TypeCombinator::union(new ObjectWithoutClassType(), new ClassStringType()); } return new ObjectWithoutClassType(); }); } } getName() === 'str_pad'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $args = $functionCall->getArgs(); if (count($args) < 2) { return new StringType(); } $inputType = $scope->getType($args[0]->value); $lengthType = $scope->getType($args[1]->value); $accessoryTypes = []; if ($inputType->isNonFalsyString()->yes()) { $accessoryTypes[] = new AccessoryNonFalsyStringType(); } elseif ($inputType->isNonEmptyString()->yes() || IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($lengthType)->yes()) { $accessoryTypes[] = new AccessoryNonEmptyStringType(); } if (count($args) < 3) { $padStringType = null; } else { $padStringType = $scope->getType($args[2]->value); } if ($inputType->isLiteralString()->yes() && ($padStringType === null || $padStringType->isLiteralString()->yes())) { $accessoryTypes[] = new AccessoryLiteralStringType(); } if ($inputType->isLowercaseString()->yes() && ($padStringType === null || $padStringType->isLowercaseString()->yes())) { $accessoryTypes[] = new AccessoryLowercaseStringType(); } if ($inputType->isUppercaseString()->yes() && ($padStringType === null || $padStringType->isUppercaseString()->yes())) { $accessoryTypes[] = new AccessoryUppercaseStringType(); } if (count($accessoryTypes) > 0) { $accessoryTypes[] = new StringType(); return new IntersectionType($accessoryTypes); } return new StringType(); } } getName(), ['str_increment', 'str_decrement'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $fnName = $functionReflection->getName(); $args = $functionCall->getArgs(); if (count($args) !== 1) { return null; } $argType = $scope->getType($args[0]->value); if (count($argType->getConstantScalarValues()) === 0) { return null; } $types = []; foreach ($argType->getConstantScalarValues() as $value) { if (!(is_string($value) || is_int($value) || is_float($value))) { continue; } $string = (string) $value; if (preg_match('/\\A(?:0|[1-9A-Za-z][0-9A-Za-z]*)+\\z/', $string) < 1) { continue; } $result = null; if ($fnName === 'str_increment') { $result = $this->increment($string); } elseif ($fnName === 'str_decrement') { $result = $this->decrement($string); } if ($result === null) { continue; } $types[] = new ConstantStringType($result); } return count($types) === 0 ? new ErrorType() : TypeCombinator::union(...$types); } private function increment(string $s) : string { if (is_numeric($s)) { $offset = stripos($s, 'e'); if ($offset !== \false) { // Using increment operator would cast the string to float // Therefore we manually increment it to convert it to an "f"/"F" that doesn't get affected $c = $s[$offset]; $c++; $s[$offset] = $c; $s++; $s[$offset] = ['f' => 'e', 'F' => 'E', 'g' => 'f', 'G' => 'F'][$s[$offset]]; return $s; } } return (string) ++$s; } private function decrement(string $s) : ?string { if (in_array($s, ['a', 'A', '0'], \true)) { return null; } $decremented = str_split($s, 1); $position = count($decremented) - 1; $carry = \false; $map = ['0' => '9', 'A' => 'Z', 'a' => 'z']; do { $c = $decremented[$position]; if (!in_array($c, ['a', 'A', '0'], \true)) { $carry = \false; $decremented[$position] = chr(ord($c) - 1); } else { $carry = \true; $decremented[$position] = $map[$c]; } } while ($carry && $position-- > 0); if ($carry || count($decremented) > 1 && $decremented[0] === '0') { if (count($decremented) === 1) { return null; } unset($decremented[0]); } return implode($decremented); } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'array_search'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $argsCount = count($functionCall->getArgs()); if ($argsCount < 2) { return null; } $haystackArgType = $scope->getType($functionCall->getArgs()[1]->value); if ($haystackArgType->isArray()->no()) { return $this->phpVersion->arrayFunctionsReturnNullWithNonArray() ? new NullType() : new NeverType(); } if ($argsCount < 3) { return TypeCombinator::union($haystackArgType->getIterableKeyType(), new ConstantBooleanType(\false)); } $strictArgType = $scope->getType($functionCall->getArgs()[2]->value); if (!$strictArgType->isTrue()->yes()) { return TypeCombinator::union($haystackArgType->getIterableKeyType(), new ConstantBooleanType(\false)); } $needleArgType = $scope->getType($functionCall->getArgs()[0]->value); if ($haystackArgType->getIterableValueType()->isSuperTypeOf($needleArgType)->no()) { return new ConstantBooleanType(\false); } return $haystackArgType->searchArray($needleArgType); } } getName() === 'array_reduce'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[1])) { return null; } $callbackType = $scope->getType($functionCall->getArgs()[1]->value); if ($callbackType->isCallable()->no()) { return null; } $callbackReturnType = ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->getArgs(), $callbackType->getCallableParametersAcceptors($scope))->getReturnType(); if (isset($functionCall->getArgs()[2])) { $initialType = $scope->getType($functionCall->getArgs()[2]->value); } else { $initialType = new NullType(); } $arraysType = $scope->getType($functionCall->getArgs()[0]->value); $constantArrays = $arraysType->getConstantArrays(); if (count($constantArrays) > 0) { $onlyEmpty = TrinaryLogic::createYes(); $onlyNonEmpty = TrinaryLogic::createYes(); foreach ($constantArrays as $constantArray) { $iterableAtLeastOnce = $constantArray->isIterableAtLeastOnce(); $onlyEmpty = $onlyEmpty->and($iterableAtLeastOnce->negate()); $onlyNonEmpty = $onlyNonEmpty->and($iterableAtLeastOnce); } if ($onlyEmpty->yes()) { return $initialType; } if ($onlyNonEmpty->yes()) { return $callbackReturnType; } } return TypeCombinator::union($callbackReturnType, $initialType); } } className = $className; } public function getClass() : string { return $this->className; } public function isMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getDeclaringClass()->getName() === $this->className && $methodReflection->getName() === 'getAttributes'; } public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->getArgs()) === 0) { return null; } $argType = $scope->getType($methodCall->getArgs()[0]->value); $classType = $argType->getClassStringObjectType(); return AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new GenericObjectType(ReflectionAttribute::class, [$classType]))); } } regexGroupParser = $regexGroupParser; $this->regexExpressionHelper = $regexExpressionHelper; $this->phpVersion = $phpVersion; } public function matchAllExpr(Expr $patternExpr, ?Type $flagsType, TrinaryLogic $wasMatched, Scope $scope) : ?Type { return $this->matchPatternType($this->getPatternType($patternExpr, $scope), $flagsType, $wasMatched, \true); } public function matchExpr(Expr $patternExpr, ?Type $flagsType, TrinaryLogic $wasMatched, Scope $scope) : ?Type { return $this->matchPatternType($this->getPatternType($patternExpr, $scope), $flagsType, $wasMatched, \false); } /** * @deprecated use matchExpr() instead for a more precise result */ public function matchType(Type $patternType, ?Type $flagsType, TrinaryLogic $wasMatched) : ?Type { return $this->matchPatternType($patternType, $flagsType, $wasMatched, \false); } private function matchPatternType(Type $patternType, ?Type $flagsType, TrinaryLogic $wasMatched, bool $matchesAll) : ?Type { if ($wasMatched->no()) { return new ConstantArrayType([], []); } $constantStrings = $patternType->getConstantStrings(); if (count($constantStrings) === 0) { return null; } $flags = null; if ($flagsType !== null) { if (!$flagsType instanceof ConstantIntegerType) { return null; } /** @var int-mask $flags */ $flags = $flagsType->getValue() & (PREG_OFFSET_CAPTURE | PREG_PATTERN_ORDER | PREG_SET_ORDER | PREG_UNMATCHED_AS_NULL | self::PREG_UNMATCHED_AS_NULL_ON_72_73); // some other unsupported/unexpected flag was passed in if ($flags !== $flagsType->getValue()) { return null; } } $matchedTypes = []; foreach ($constantStrings as $constantString) { $matched = $this->matchRegex($constantString->getValue(), $flags, $wasMatched, $matchesAll); if ($matched === null) { return null; } $matchedTypes[] = $matched; } if (count($matchedTypes) === 1) { return $matchedTypes[0]; } return TypeCombinator::union(...$matchedTypes); } /** * @param int-mask|null $flags */ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched, bool $matchesAll) : ?Type { $parseResult = $this->regexGroupParser->parseGroups($regex); if ($parseResult === null) { // regex could not be parsed by Hoa/Regex return null; } [$groupList, $markVerbs] = $parseResult; $trailingOptionals = 0; foreach (array_reverse($groupList) as $captureGroup) { if (!$captureGroup->isOptional()) { break; } $trailingOptionals++; } $onlyOptionalTopLevelGroup = $this->getOnlyOptionalTopLevelGroup($groupList); $onlyTopLevelAlternation = $this->getOnlyTopLevelAlternation($groupList); $flags = $flags ?? 0; if (!$matchesAll && $wasMatched->yes() && $onlyOptionalTopLevelGroup !== null) { // if only one top level capturing optional group exists // we build a more precise tagged union of a empty-match and a match with the group $onlyOptionalTopLevelGroup->forceNonOptional(); $combiType = $this->buildArrayType($groupList, $wasMatched, $trailingOptionals, $flags, $markVerbs, $matchesAll); if (!$this->containsUnmatchedAsNull($flags, $matchesAll)) { // positive match has a subject but not any capturing group $combiType = TypeCombinator::union(new ConstantArrayType([new ConstantIntegerType(0)], [$this->createSubjectValueType($flags, $matchesAll)], [1], [], \true), $combiType); } $onlyOptionalTopLevelGroup->clearOverrides(); return $combiType; } elseif (!$matchesAll && $onlyOptionalTopLevelGroup === null && $onlyTopLevelAlternation !== null && !$wasMatched->no()) { // if only a single top level alternation exist built a more precise tagged union $combiTypes = []; $isOptionalAlternation = \false; foreach ($onlyTopLevelAlternation->getGroupCombinations() as $groupCombo) { $comboList = $groupList; $beforeCurrentCombo = \true; foreach ($comboList as $groupId => $group) { if (in_array($groupId, $groupCombo, \true)) { $isOptionalAlternation = $group->inOptionalAlternation(); $group->forceNonOptional(); $beforeCurrentCombo = \false; } elseif ($beforeCurrentCombo && !$group->resetsGroupCounter()) { $group->forceNonOptional(); $group->forceType($this->containsUnmatchedAsNull($flags, $matchesAll) ? new NullType() : new ConstantStringType('')); } elseif ($group->getAlternationId() === $onlyTopLevelAlternation->getId() && !$this->containsUnmatchedAsNull($flags, $matchesAll)) { unset($comboList[$groupId]); } } $combiType = $this->buildArrayType($comboList, $wasMatched, $trailingOptionals, $flags, $markVerbs, $matchesAll); $combiTypes[] = $combiType; foreach ($groupCombo as $groupId) { $group = $comboList[$groupId]; $group->clearOverrides(); } } if (!$this->containsUnmatchedAsNull($flags, $matchesAll) && ($onlyTopLevelAlternation->getAlternationsCount() !== count($onlyTopLevelAlternation->getGroupCombinations()) || $isOptionalAlternation)) { // positive match has a subject but not any capturing group $combiTypes[] = new ConstantArrayType([new ConstantIntegerType(0)], [$this->createSubjectValueType($flags, $matchesAll)], [1], [], \true); } return TypeCombinator::union(...$combiTypes); } // the general case, which should work in all cases but does not yield the most // precise result possible in some cases return $this->buildArrayType($groupList, $wasMatched, $trailingOptionals, $flags, $markVerbs, $matchesAll); } /** * @param array $captureGroups */ private function getOnlyOptionalTopLevelGroup(array $captureGroups) : ?RegexCapturingGroup { $group = null; foreach ($captureGroups as $captureGroup) { if (!$captureGroup->isTopLevel()) { continue; } if (!$captureGroup->isOptional()) { return null; } if ($group !== null) { return null; } $group = $captureGroup; } return $group; } /** * @param array $captureGroups */ private function getOnlyTopLevelAlternation(array $captureGroups) : ?RegexAlternation { $alternation = null; foreach ($captureGroups as $captureGroup) { if (!$captureGroup->isTopLevel()) { continue; } if (!$captureGroup->inAlternation()) { return null; } if ($captureGroup->inOptionalQuantification()) { return null; } if ($alternation === null) { $alternation = $captureGroup->getAlternation(); } elseif ($alternation->getId() !== $captureGroup->getAlternation()->getId()) { return null; } } return $alternation; } /** * @param array $captureGroups * @param list $markVerbs */ private function buildArrayType(array $captureGroups, TrinaryLogic $wasMatched, int $trailingOptionals, int $flags, array $markVerbs, bool $matchesAll) : Type { $builder = ConstantArrayTypeBuilder::createEmpty(); // first item in matches contains the overall match. $builder->setOffsetValueType($this->getKeyType(0), $this->createSubjectValueType($flags, $matchesAll), $this->isSubjectOptional($wasMatched, $matchesAll)); $countGroups = count($captureGroups); $i = 0; foreach ($captureGroups as $captureGroup) { $isTrailingOptional = $i >= $countGroups - $trailingOptionals; $isLastGroup = $i === $countGroups - 1; $groupValueType = $this->createGroupValueType($captureGroup, $wasMatched, $flags, $isTrailingOptional, $isLastGroup, $matchesAll); $optional = $this->isGroupOptional($captureGroup, $wasMatched, $flags, $isTrailingOptional, $matchesAll); if ($captureGroup->isNamed()) { $builder->setOffsetValueType($this->getKeyType($captureGroup->getName()), $groupValueType, $optional); } $builder->setOffsetValueType($this->getKeyType($i + 1), $groupValueType, $optional); $i++; } if (count($markVerbs) > 0) { $markTypes = []; foreach ($markVerbs as $mark) { $markTypes[] = new ConstantStringType($mark); } $builder->setOffsetValueType($this->getKeyType('MARK'), TypeCombinator::union(...$markTypes), \true); } if ($matchesAll && $this->containsSetOrder($flags)) { $arrayType = AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $builder->getArray())); if (!$wasMatched->yes()) { $arrayType = TypeCombinator::union(new ConstantArrayType([], []), $arrayType); } return $arrayType; } return $builder->getArray(); } private function isSubjectOptional(TrinaryLogic $wasMatched, bool $matchesAll) : bool { if ($matchesAll) { return \false; } return !$wasMatched->yes(); } private function createSubjectValueType(int $flags, bool $matchesAll) : Type { $subjectValueType = TypeCombinator::removeNull($this->getValueType(new StringType(), $flags, $matchesAll)); if ($matchesAll) { if ($this->containsPatternOrder($flags)) { $subjectValueType = AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $subjectValueType)); } } return $subjectValueType; } private function isGroupOptional(RegexCapturingGroup $captureGroup, TrinaryLogic $wasMatched, int $flags, bool $isTrailingOptional, bool $matchesAll) : bool { if ($matchesAll) { if ($isTrailingOptional && !$this->containsUnmatchedAsNull($flags, $matchesAll) && $this->containsSetOrder($flags)) { return \true; } return \false; } if (!$wasMatched->yes()) { $optional = \true; } else { if (!$isTrailingOptional) { $optional = \false; } elseif ($this->containsUnmatchedAsNull($flags, $matchesAll)) { $optional = \false; } else { $optional = $captureGroup->isOptional(); } } return $optional; } private function createGroupValueType(RegexCapturingGroup $captureGroup, TrinaryLogic $wasMatched, int $flags, bool $isTrailingOptional, bool $isLastGroup, bool $matchesAll) : Type { if ($matchesAll) { if (!$this->containsSetOrder($flags) && !$this->containsUnmatchedAsNull($flags, $matchesAll) && $captureGroup->isOptional() || $this->containsSetOrder($flags) && !$this->containsUnmatchedAsNull($flags, $matchesAll) && $captureGroup->isOptional() && !$isTrailingOptional) { $groupValueType = $this->getValueType(TypeCombinator::union($captureGroup->getType(), new ConstantStringType('')), $flags, $matchesAll); $groupValueType = TypeCombinator::removeNull($groupValueType); } else { $groupValueType = $this->getValueType($captureGroup->getType(), $flags, $matchesAll); } if (!$isTrailingOptional && $this->containsUnmatchedAsNull($flags, $matchesAll) && !$captureGroup->isOptional()) { $groupValueType = TypeCombinator::removeNull($groupValueType); } if ($this->containsPatternOrder($flags)) { $groupValueType = AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $groupValueType)); } return $groupValueType; } if (!$isLastGroup && !$this->containsUnmatchedAsNull($flags, $matchesAll) && $captureGroup->isOptional()) { $groupValueType = $this->getValueType(TypeCombinator::union($captureGroup->getType(), new ConstantStringType('')), $flags, $matchesAll); } else { $groupValueType = $this->getValueType($captureGroup->getType(), $flags, $matchesAll); } if ($wasMatched->yes()) { if (!$isTrailingOptional && $this->containsUnmatchedAsNull($flags, $matchesAll) && !$captureGroup->isOptional()) { $groupValueType = TypeCombinator::removeNull($groupValueType); } } return $groupValueType; } private function containsOffsetCapture(int $flags) : bool { return ($flags & PREG_OFFSET_CAPTURE) !== 0; } private function containsPatternOrder(int $flags) : bool { // If no order flag is given, PREG_PATTERN_ORDER is assumed. return !$this->containsSetOrder($flags); } private function containsSetOrder(int $flags) : bool { return ($flags & PREG_SET_ORDER) !== 0; } private function containsUnmatchedAsNull(int $flags, bool $matchesAll) : bool { if ($matchesAll) { // preg_match_all() with PREG_UNMATCHED_AS_NULL works consistently across php-versions // https://3v4l.org/tKmPn return ($flags & PREG_UNMATCHED_AS_NULL) !== 0; } return ($flags & PREG_UNMATCHED_AS_NULL) !== 0 && (($flags & self::PREG_UNMATCHED_AS_NULL_ON_72_73) !== 0 || $this->phpVersion->supportsPregUnmatchedAsNull()); } /** * @param int|string $key */ private function getKeyType($key) : Type { if (is_string($key)) { return new ConstantStringType($key); } return new ConstantIntegerType($key); } private function getValueType(Type $baseType, int $flags, bool $matchesAll) : Type { $valueType = $baseType; // unmatched groups return -1 as offset $offsetType = IntegerRangeType::fromInterval(-1, null); if ($this->containsUnmatchedAsNull($flags, $matchesAll)) { $valueType = TypeCombinator::addNull($valueType); } if ($this->containsOffsetCapture($flags)) { $builder = ConstantArrayTypeBuilder::createEmpty(); $builder->setOffsetValueType(new ConstantIntegerType(0), $valueType); $builder->setOffsetValueType(new ConstantIntegerType(1), $offsetType); return $builder->getArray(); } return $valueType; } private function getPatternType(Expr $patternExpr, Scope $scope) : Type { if ($patternExpr instanceof Expr\BinaryOp\Concat) { return $this->regexExpressionHelper->resolvePatternConcat($patternExpr, $scope); } return $scope->getType($patternExpr); } } reflectionProvider = $reflectionProvider; } public function isStaticMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getName() === '__construct' && $methodReflection->getDeclaringClass()->getName() === ReflectionMethod::class; } public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->getArgs()) < 2) { return $methodReflection->getThrowType(); } $valueType = $scope->getType($methodCall->getArgs()[0]->value); $propertyType = $scope->getType($methodCall->getArgs()[1]->value); foreach (TypeUtils::flattenTypes($valueType) as $type) { if ($type instanceof GenericClassStringType) { $classes = $type->getGenericType()->getObjectClassNames(); } elseif ($type instanceof ConstantStringType && $this->reflectionProvider->hasClass($type->getValue())) { $classes = [$type->getValue()]; } else { return $methodReflection->getThrowType(); } foreach ($classes as $class) { $classReflection = $this->reflectionProvider->getClass($class); foreach ($propertyType->getConstantStrings() as $constantPropertyString) { if (!$classReflection->hasMethod($constantPropertyString->getValue())) { return $methodReflection->getThrowType(); } } } $valueType = TypeCombinator::remove($valueType, $type); } if (!$valueType instanceof NeverType) { return $methodReflection->getThrowType(); } // Look for non constantStrings value. foreach ($propertyType->getConstantStrings() as $constantPropertyString) { $propertyType = TypeCombinator::remove($propertyType, $constantPropertyString); } if (!$propertyType instanceof NeverType) { return $methodReflection->getThrowType(); } return null; } } phpVersion = $phpVersion; } public function isStaticMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getName() === '__construct' && in_array($methodReflection->getDeclaringClass()->getName(), [DateTime::class, DateTimeImmutable::class], \true); } public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->getArgs()) === 0) { return null; } $valueType = $scope->getType($methodCall->getArgs()[0]->value); $constantStrings = $valueType->getConstantStrings(); foreach ($constantStrings as $constantString) { try { new DateTime($constantString->getValue()); } catch (\Exception $e) { // phpcs:ignore return $this->exceptionType(); } $valueType = TypeCombinator::remove($valueType, $constantString); } if (!$valueType instanceof NeverType) { return $this->exceptionType(); } return null; } private function exceptionType() : Type { if ($this->phpVersion->hasDateTimeExceptions()) { return new ObjectType('DateMalformedStringException'); } return new ObjectType('Exception'); } } constantHelper = $constantHelper; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'constant'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 1) { return null; } $nameType = $scope->getType($functionCall->getArgs()[0]->value); $results = []; foreach ($nameType->getConstantStrings() as $constantName) { $expr = $this->constantHelper->createExprFromConstantName($constantName->getValue()); if ($expr === null) { return new ErrorType(); } $results[] = $scope->getType($expr); } if (count($results) > 0) { return TypeCombinator::union(...$results); } return null; } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return strtolower($functionReflection->getName()) === 'array_values'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) !== 1) { return null; } $arrayType = $scope->getType($functionCall->getArgs()[0]->value); if ($arrayType->isArray()->no()) { return $this->phpVersion->arrayFunctionsReturnNullWithNonArray() ? new NullType() : new NeverType(); } return $arrayType->getValuesArray(); } } getName() === '__construct' && $methodReflection->getDeclaringClass()->getName() === ReflectionClass::class; } public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->getArgs()) < 1) { return $methodReflection->getThrowType(); } $valueType = $scope->getType($methodCall->getArgs()[0]->value); $classOrString = new UnionType([new ClassStringType(), new ObjectWithoutClassType()]); if ($classOrString->isSuperTypeOf($valueType)->yes()) { return null; } return $methodReflection->getThrowType(); } } */ private $argumentPositions = ['json_encode' => 1, 'json_decode' => 3]; public function __construct(ReflectionProvider $reflectionProvider, BitwiseFlagHelper $bitwiseFlagAnalyser) { $this->reflectionProvider = $reflectionProvider; $this->bitwiseFlagAnalyser = $bitwiseFlagAnalyser; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { if ($functionReflection->getName() === 'json_decode') { return \true; } return $functionReflection->getName() === 'json_encode' && $this->reflectionProvider->hasConstant(new FullyQualified('JSON_THROW_ON_ERROR'), null); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $argumentPosition = $this->argumentPositions[$functionReflection->getName()]; $defaultReturnType = ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->getArgs(), $functionReflection->getVariants())->getReturnType(); if ($functionReflection->getName() === 'json_decode') { $defaultReturnType = $this->narrowTypeForJsonDecode($functionCall, $scope, $defaultReturnType); } if (!isset($functionCall->getArgs()[$argumentPosition])) { return $defaultReturnType; } $optionsExpr = $functionCall->getArgs()[$argumentPosition]->value; if ($functionReflection->getName() === 'json_encode' && $this->bitwiseFlagAnalyser->bitwiseOrContainsConstant($optionsExpr, $scope, 'JSON_THROW_ON_ERROR')->yes()) { return TypeCombinator::remove($defaultReturnType, new ConstantBooleanType(\false)); } return $defaultReturnType; } private function narrowTypeForJsonDecode(FuncCall $funcCall, Scope $scope, Type $fallbackType) : Type { $args = $funcCall->getArgs(); $isForceArray = $this->isForceArray($funcCall, $scope); if (!isset($args[0])) { return $fallbackType; } $firstValueType = $scope->getType($args[0]->value); if ($firstValueType instanceof ConstantStringType) { return $this->resolveConstantStringType($firstValueType, $isForceArray); } if ($isForceArray) { return TypeCombinator::remove($fallbackType, new ObjectWithoutClassType()); } return $fallbackType; } /** * Is "json_decode(..., true)"? */ private function isForceArray(FuncCall $funcCall, Scope $scope) : bool { $args = $funcCall->getArgs(); if (!isset($args[1])) { return \false; } $secondArgType = $scope->getType($args[1]->value); $secondArgValue = $secondArgType instanceof ConstantScalarType ? $secondArgType->getValue() : null; if (is_bool($secondArgValue)) { return $secondArgValue; } if ($secondArgValue !== null || !isset($args[3])) { return \false; } // depends on used constants, @see https://www.php.net/manual/en/json.constants.php#constant.json-object-as-array return $this->bitwiseFlagAnalyser->bitwiseOrContainsConstant($args[3]->value, $scope, 'JSON_OBJECT_AS_ARRAY')->yes(); } private function resolveConstantStringType(ConstantStringType $constantStringType, bool $isForceArray) : Type { $decodedValue = json_decode($constantStringType->getValue(), $isForceArray); return ConstantTypeHelper::getTypeFromValue($decodedValue); } } getName() === 'base64_decode'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { if (!isset($functionCall->getArgs()[1])) { return new StringType(); } $argType = $scope->getType($functionCall->getArgs()[1]->value); if ($argType instanceof MixedType) { return new BenevolentUnionType([new StringType(), new ConstantBooleanType(\false)]); } $isTrueType = $argType->isTrue(); $isFalseType = $argType->isFalse(); $compareTypes = $isTrueType->compareTo($isFalseType); if ($compareTypes === $isTrueType) { return new UnionType([new StringType(), new ConstantBooleanType(\false)]); } if ($compareTypes === $isFalseType) { return new StringType(); } // second argument could be interpreted as true if (!$isTrueType->no()) { return new UnionType([new StringType(), new ConstantBooleanType(\false)]); } return new StringType(); } } getName() === 'get_debug_type'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 1) { return null; } $argType = $scope->getType($functionCall->getArgs()[0]->value); if ($argType instanceof UnionType) { return new UnionType(array_map(Closure::fromCallable([self::class, 'resolveOneType']), $argType->getTypes())); } return self::resolveOneType($argType); } /** * @see https://www.php.net/manual/en/function.get-debug-type.php#refsect1-function.get-debug-type-returnvalues * @see https://github.com/php/php-src/commit/ef0e4478c51540510b67f7781ad240f5e0592ee4 */ private static function resolveOneType(Type $type) : Type { if ($type->isNull()->yes()) { return new ConstantStringType('null'); } if ($type->isBoolean()->yes()) { return new ConstantStringType('bool'); } if ($type->isInteger()->yes()) { return new ConstantStringType('int'); } if ($type->isFloat()->yes()) { return new ConstantStringType('float'); } if ($type->isString()->yes()) { return new ConstantStringType('string'); } if ($type->isArray()->yes()) { return new ConstantStringType('array'); } // "resources" type+state is skipped since we cannot infer the state if ($type->isObject()->yes()) { $reflections = $type->getObjectClassReflections(); $types = []; foreach ($reflections as $reflection) { // if the class is not final, the actual returned string might be of a child class if ($reflection->isFinal() && !$reflection->isAnonymous()) { $types[] = new ConstantStringType($reflection->getName()); } if ($reflection->isAnonymous()) { // phpcs:ignore $parentClass = $reflection->getParentClass(); $implementedInterfaces = $reflection->getImmediateInterfaces(); if ($parentClass !== null) { $types[] = new ConstantStringType($parentClass->getName() . '@anonymous'); } elseif ($implementedInterfaces !== []) { $firstInterface = $implementedInterfaces[array_key_first($implementedInterfaces)]; $types[] = new ConstantStringType($firstInterface->getName() . '@anonymous'); } else { $types[] = new ConstantStringType('class@anonymous'); } } } switch (count($types)) { case 0: return new StringType(); case 1: return $types[0]; default: return new UnionType($types); } } return new StringType(); } } getName() === 'str_repeat'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $args = $functionCall->getArgs(); if (count($args) < 2) { return new StringType(); } $multiplierType = $scope->getType($args[1]->value); if ((new ConstantIntegerType(0))->isSuperTypeOf($multiplierType)->yes()) { return new ConstantStringType(''); } if (IntegerRangeType::fromInterval(null, 0)->isSuperTypeOf($multiplierType)->yes()) { return new NeverType(); } $inputType = $scope->getType($args[0]->value); if ($inputType instanceof ConstantStringType && $multiplierType instanceof ConstantIntegerType && strlen($inputType->getValue()) * $multiplierType->getValue() < 100) { return new ConstantStringType(str_repeat($inputType->getValue(), $multiplierType->getValue())); } $accessoryTypes = []; if ($inputType->isNonEmptyString()->yes()) { if (IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($multiplierType)->yes()) { if ($inputType->isNonFalsyString()->yes()) { $accessoryTypes[] = new AccessoryNonFalsyStringType(); } else { $accessoryTypes[] = new AccessoryNonEmptyStringType(); } } } if ($inputType->isLiteralString()->yes()) { $accessoryTypes[] = new AccessoryLiteralStringType(); if ($inputType->isNumericString()->yes() && IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($multiplierType)->yes()) { $onlyNumbers = \true; foreach ($inputType->getConstantStrings() as $constantString) { if (Strings::match($constantString->getValue(), '#^[0-9]+$#') === null) { $onlyNumbers = \false; break; } } if ($onlyNumbers) { $accessoryTypes[] = new AccessoryNumericStringType(); } } } if ($inputType->isLowercaseString()->yes()) { $accessoryTypes[] = new AccessoryLowercaseStringType(); } if ($inputType->isUppercaseString()->yes()) { $accessoryTypes[] = new AccessoryUppercaseStringType(); } if (count($accessoryTypes) > 0) { $accessoryTypes[] = new StringType(); return new IntersectionType($accessoryTypes); } return new StringType(); } } phpVersion = $phpVersion; } public function isMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getName() === 'modify' && in_array($methodReflection->getDeclaringClass()->getName(), [DateTime::class, DateTimeImmutable::class], \true); } public function getThrowTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->getArgs()) === 0) { return null; } if (!$this->phpVersion->hasDateTimeExceptions()) { return null; } $valueType = $scope->getType($methodCall->getArgs()[0]->value); $constantStrings = $valueType->getConstantStrings(); foreach ($constantStrings as $constantString) { try { $dateTime = new DateTime(); $dateTime->modify($constantString->getValue()); } catch (\Exception $e) { // phpcs:ignore return $this->exceptionType(); } $valueType = TypeCombinator::remove($valueType, $constantString); } if (!$valueType instanceof NeverType) { return $this->exceptionType(); } return null; } private function exceptionType() : Type { if ($this->phpVersion->hasDateTimeExceptions()) { return new ObjectType('DateMalformedStringException'); } return new ObjectType('Exception'); } } checkMaybeUndefinedVariables = $checkMaybeUndefinedVariables; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'compact'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) === 0) { return null; } if ($scope->canAnyVariableExist() && !$this->checkMaybeUndefinedVariables) { return null; } $array = ConstantArrayTypeBuilder::createEmpty(); foreach ($functionCall->getArgs() as $arg) { $type = $scope->getType($arg->value); $constantStrings = $this->findConstantStrings($type); if ($constantStrings === null) { return null; } foreach ($constantStrings as $constantString) { $has = $scope->hasVariableType($constantString->getValue()); if ($has->no()) { continue; } $array->setOffsetValueType($constantString, $scope->getVariableType($constantString->getValue()), $has->maybe()); } } return $array->getArray(); } /** * @return array|null */ private function findConstantStrings(Type $type) : ?array { if ($type instanceof ConstantStringType) { return [$type]; } if ($type instanceof ConstantArrayType) { $result = []; foreach ($type->getValueTypes() as $valueType) { $constantStrings = $this->findConstantStrings($valueType); if ($constantStrings === null) { return null; } $result = array_merge($result, $constantStrings); } return $result; } return null; } } */ private $dateTimeClass; /** @param class-string $dateTimeClass */ public function __construct(PhpVersion $phpVersion, string $dateTimeClass = DateTime::class) { $this->phpVersion = $phpVersion; $this->dateTimeClass = $dateTimeClass; } public function getClass() : string { return $this->dateTimeClass; } public function isMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getName() === 'modify'; } public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->getArgs()) < 1) { return null; } $valueType = $scope->getType($methodCall->getArgs()[0]->value); $constantStrings = $valueType->getConstantStrings(); $hasFalse = \false; $hasDateTime = \false; foreach ($constantStrings as $constantString) { try { $result = @(new DateTime())->modify($constantString->getValue()); } catch (Throwable $e) { $valueType = TypeCombinator::remove($valueType, $constantString); continue; } if ($result === \false) { $hasFalse = \true; } else { $hasDateTime = \true; } $valueType = TypeCombinator::remove($valueType, $constantString); } if (!$valueType instanceof NeverType) { return null; } if ($hasFalse) { if (!$hasDateTime) { return new ConstantBooleanType(\false); } return null; } elseif ($hasDateTime) { return $scope->getType($methodCall->var); } if ($this->phpVersion->hasDateTimeExceptions()) { return new NeverType(); } return null; } } getName()) === 'iterator_to_array'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $arguments = $functionCall->getArgs(); if ($arguments === []) { return null; } $traversableType = $scope->getType($arguments[0]->value); if (isset($arguments[1])) { $preserveKeysType = $scope->getType($arguments[1]->value); if ($preserveKeysType->isFalse()->yes()) { return AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $traversableType->getIterableValueType())); } } $arrayKeyType = $traversableType->getIterableKeyType()->toArrayKey(); if ($arrayKeyType instanceof ErrorType) { return new NeverType(\true); } return new ArrayType($arrayKeyType, $traversableType->getIterableValueType()); } } getName() === 'array_find_key'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 2) { return null; } $arrayType = $scope->getType($functionCall->getArgs()[0]->value); if (count($arrayType->getArrays()) < 1) { return null; } return TypeCombinator::union($arrayType->getIterableKeyType(), new NullType()); } } getName() === 'dio_stat'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $valueType = new IntegerType(); $builder = ConstantArrayTypeBuilder::createEmpty(); $keys = ['device', 'inode', 'mode', 'nlink', 'uid', 'gid', 'device_type', 'size', 'blocksize', 'blocks', 'atime', 'mtime', 'ctime']; foreach ($keys as $key) { $builder->setOffsetValueType(new ConstantStringType($key), $valueType); } return TypeCombinator::addNull($builder->getArray()); } } getName() === 'assert'; } public function getThrowTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $funcCall, Scope $scope) : ?Type { if (count($funcCall->getArgs()) < 2) { return $functionReflection->getThrowType(); } $customThrow = $scope->getType($funcCall->getArgs()[1]->value); if ((new ObjectType(Throwable::class))->isSuperTypeOf($customThrow)->yes()) { return $customThrow; } return $functionReflection->getThrowType(); } } getName() === 'fromCallable'; } public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : ?Type { if (!isset($methodCall->getArgs()[0])) { return null; } $callableType = $scope->getType($methodCall->getArgs()[0]->value); if ($callableType->isCallable()->no()) { return new ErrorType(); } $closureTypes = []; foreach ($callableType->getCallableParametersAcceptors($scope) as $variant) { $parameters = $variant->getParameters(); $closureTypes[] = new ClosureType($parameters, $variant->getReturnType(), $variant->isVariadic(), $variant->getTemplateTypeMap(), $variant->getResolvedTemplateTypeMap(), $variant instanceof ParametersAcceptorWithPhpDocs ? $variant->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(), [], $variant->getThrowPoints(), $variant->getImpurePoints(), $variant->getInvalidateExpressions(), $variant->getUsedVariables(), $variant->acceptsNamedArguments()); } return TypeCombinator::union(...$closureTypes); } } getName(), ['next', 'prev'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $argType = $scope->getType($functionCall->getArgs()[0]->value); $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); if ($iterableAtLeastOnce->no()) { return new ConstantBooleanType(\false); } $valueType = $argType->getIterableValueType(); return TypeCombinator::union($valueType, new ConstantBooleanType(\false)); } } getName() === 'openssl_encrypt' && $parameter->getName() === 'tag'; } public function getParameterOutTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $funcCall, ParameterReflection $parameter, Scope $scope) : ?Type { $args = $funcCall->getArgs(); $cipherArg = $args[1] ?? null; if ($cipherArg === null) { return null; } $tagTypes = []; foreach ($scope->getType($cipherArg->value)->getConstantStrings() as $cipherType) { $cipher = strtolower($cipherType->getValue()); $mode = substr($cipher, -3); if (!in_array($cipher, openssl_get_cipher_methods(), \true)) { $tagTypes[] = new NullType(); continue; } if (in_array($mode, ['gcm', 'ccm'], \true)) { $tagTypes[] = TypeCombinator::intersect(new StringType(), new AccessoryNonEmptyStringType()); continue; } $tagTypes[] = new NullType(); } if ($tagTypes === []) { return TypeCombinator::addNull(TypeCombinator::intersect(new StringType(), new AccessoryNonEmptyStringType())); } return TypeCombinator::union(...$tagTypes); } } getName() === 'gettype'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 1) { return null; } $valueType = $scope->getType($functionCall->getArgs()[0]->value); return TypeTraverser::map($valueType, static function (Type $valueType, callable $traverse) : Type { if ($valueType instanceof UnionType || $valueType instanceof IntersectionType) { return $traverse($valueType); } if ($valueType->isString()->yes()) { return new ConstantStringType('string'); } if ($valueType->isArray()->yes()) { return new ConstantStringType('array'); } if ($valueType->isBoolean()->yes()) { return new ConstantStringType('boolean'); } $resource = new ResourceType(); if ($resource->isSuperTypeOf($valueType)->yes()) { return new UnionType([new ConstantStringType('resource'), new ConstantStringType('resource (closed)')]); } if ($valueType->isInteger()->yes()) { return new ConstantStringType('integer'); } if ($valueType->isFloat()->yes()) { // for historical reasons "double" is returned in case of a float, and not simply "float" return new ConstantStringType('double'); } if ($valueType->isNull()->yes()) { return new ConstantStringType('NULL'); } if ($valueType->isObject()->yes()) { return new ConstantStringType('object'); } return TypeCombinator::union(new ConstantStringType('string'), new ConstantStringType('array'), new ConstantStringType('boolean'), new ConstantStringType('resource'), new ConstantStringType('resource (closed)'), new ConstantStringType('integer'), new ConstantStringType('double'), new ConstantStringType('NULL'), new ConstantStringType('object'), new ConstantStringType('unknown type')); }); } } getName() === 'array_shift'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $argType = $scope->getType($functionCall->getArgs()[0]->value); $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); if ($iterableAtLeastOnce->no()) { return new NullType(); } $itemType = $argType->getFirstIterableValueType(); if ($iterableAtLeastOnce->yes()) { return $itemType; } return TypeCombinator::union($itemType, new NullType()); } } getName() === 'createFromDateString'; } public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : ?Type { $arguments = $methodCall->getArgs(); if (!isset($arguments[0])) { return null; } $strings = $scope->getType($arguments[0]->value)->getConstantStrings(); $possibleReturnTypes = []; foreach ($strings as $string) { try { $result = @DateInterval::createFromDateString($string->getValue()); } catch (Throwable $e) { $possibleReturnTypes[] = \false; continue; } $possibleReturnTypes[] = $result instanceof DateInterval ? DateInterval::class : \false; } // the error case, when wrong types are passed if (count($possibleReturnTypes) === 0) { return null; } if (in_array(\false, $possibleReturnTypes, \true) && in_array(DateInterval::class, $possibleReturnTypes, \true)) { return null; } if (in_array(\false, $possibleReturnTypes, \true)) { return new ConstantBooleanType(\false); } return new ObjectType(DateInterval::class); } } reflectionProvider = $reflectionProvider; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'pathinfo'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, Node\Expr\FuncCall $functionCall, Scope $scope) : ?Type { $argsCount = count($functionCall->getArgs()); if ($argsCount === 0) { return null; } $pathType = $scope->getType($functionCall->getArgs()[0]->value); $builder = ConstantArrayTypeBuilder::createEmpty(); $builder->setOffsetValueType(new ConstantStringType('dirname'), new StringType(), !$pathType->isNonEmptyString()->yes()); $builder->setOffsetValueType(new ConstantStringType('basename'), new StringType()); $builder->setOffsetValueType(new ConstantStringType('extension'), new StringType(), \true); $builder->setOffsetValueType(new ConstantStringType('filename'), new StringType()); $arrayType = $builder->getArray(); if ($argsCount === 1) { return $arrayType; } $flagsType = $scope->getType($functionCall->getArgs()[1]->value); $scalarValues = $flagsType->getConstantScalarValues(); if ($scalarValues !== []) { $pathInfoAll = $this->getConstant('PATHINFO_ALL'); if ($pathInfoAll === null) { return null; } $result = []; foreach ($scalarValues as $scalarValue) { if ($scalarValue === $pathInfoAll) { $result[] = $arrayType; } else { $result[] = new StringType(); } } return TypeCombinator::union(...$result); } return TypeCombinator::union($arrayType, new StringType()); } /** * @param non-empty-string $constantName */ private function getConstant(string $constantName) : ?int { if (!$this->reflectionProvider->hasConstant(new Node\Name($constantName), null)) { return null; } $constant = $this->reflectionProvider->getConstant(new Node\Name($constantName), null); $valueType = $constant->getValueType(); if (!$valueType instanceof ConstantIntegerType) { throw new ShouldNotHappenException(sprintf('Constant %s does not have integer type.', $constantName)); } return $valueType->getValue(); } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'array_reverse'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $type = $scope->getType($functionCall->getArgs()[0]->value); if ($type->isArray()->no()) { return $this->phpVersion->arrayFunctionsReturnNullWithNonArray() ? new NullType() : new NeverType(); } $preserveKeysType = isset($functionCall->getArgs()[1]) ? $scope->getType($functionCall->getArgs()[1]->value) : new ConstantBooleanType(\false); return $type->reverseArray($preserveKeysType->isTrue()); } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'explode'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) < 2) { return null; } $delimiterType = $scope->getType($args[0]->value); $isEmptyString = (new ConstantStringType(''))->isSuperTypeOf($delimiterType); if ($isEmptyString->yes()) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } return new ConstantBooleanType(\false); } $stringType = $scope->getType($args[1]->value); $accessory = []; if ($stringType->isLowercaseString()->yes()) { $accessory[] = new AccessoryLowercaseStringType(); } if ($stringType->isUppercaseString()->yes()) { $accessory[] = new AccessoryUppercaseStringType(); } if (count($accessory) > 0) { $accessory[] = new StringType(); $returnValueType = new IntersectionType($accessory); } else { $returnValueType = new StringType(); } $returnType = AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $returnValueType)); if (!isset($args[2]) || IntegerRangeType::fromInterval(0, null)->isSuperTypeOf($scope->getType($args[2]->value))->yes()) { $returnType = TypeCombinator::intersect($returnType, new NonEmptyArrayType()); } if (!$this->phpVersion->throwsValueErrorForInternalFunctions() && $isEmptyString->maybe()) { $returnType = TypeCombinator::union($returnType, new ConstantBooleanType(\false)); } if ($delimiterType instanceof MixedType) { $returnType = TypeUtils::toBenevolentUnion($returnType); } return $returnType; } } reflectionProvider = $reflectionProvider; } public function isStaticMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getName() === '__construct' && $methodReflection->getDeclaringClass()->getName() === ReflectionProperty::class; } public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->getArgs()) < 2) { return $methodReflection->getThrowType(); } $valueType = $scope->getType($methodCall->getArgs()[0]->value); $propertyType = $scope->getType($methodCall->getArgs()[1]->value); foreach ($valueType->getConstantStrings() as $constantString) { if (!$this->reflectionProvider->hasClass($constantString->getValue())) { return $methodReflection->getThrowType(); } $classReflection = $this->reflectionProvider->getClass($constantString->getValue()); foreach ($propertyType->getConstantStrings() as $constantPropertyString) { if (!$classReflection->hasProperty($constantPropertyString->getValue())) { return $methodReflection->getThrowType(); } } $valueType = TypeCombinator::remove($valueType, $constantString); } if (!$valueType instanceof NeverType) { return $methodReflection->getThrowType(); } // Look for non constantStrings value. foreach ($propertyType->getConstantStrings() as $constantPropertyString) { $propertyType = TypeCombinator::remove($propertyType, $constantPropertyString); } if (!$propertyType instanceof NeverType) { return $methodReflection->getThrowType(); } return null; } } getName() === 'array_splice'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $arrayArg = $scope->getType($functionCall->getArgs()[0]->value); return new ArrayType($arrayArg->getIterableKeyType(), $arrayArg->getIterableValueType()); } } reflectionProvider = $reflectionProvider; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'curl_getinfo'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 1) { return null; } if (count($functionCall->getArgs()) <= 1) { return $this->createAllComponentsReturnType(); } $componentType = $scope->getType($functionCall->getArgs()[1]->value); if (!$componentType->isNull()->no()) { return $this->createAllComponentsReturnType(); } $componentType = $componentType->toInteger(); if (!$componentType instanceof ConstantIntegerType) { return $this->createAllComponentsReturnType(); } $stringType = new StringType(); $integerType = new IntegerType(); $floatType = new FloatType(); $falseType = new ConstantBooleanType(\false); $stringFalseType = TypeCombinator::union($stringType, $falseType); $integerStringArrayType = new ArrayType($integerType, $stringType); $nestedStringStringArrayType = new ArrayType($integerType, new ArrayType($stringType, $stringType)); $componentTypesPairedConstants = ['CURLINFO_EFFECTIVE_URL' => $stringType, 'CURLINFO_FILETIME' => $integerType, 'CURLINFO_TOTAL_TIME' => $floatType, 'CURLINFO_NAMELOOKUP_TIME' => $floatType, 'CURLINFO_CONNECT_TIME' => $floatType, 'CURLINFO_PRETRANSFER_TIME' => $floatType, 'CURLINFO_STARTTRANSFER_TIME' => $floatType, 'CURLINFO_REDIRECT_COUNT' => $integerType, 'CURLINFO_REDIRECT_TIME' => $floatType, 'CURLINFO_REDIRECT_URL' => $stringType, 'CURLINFO_PRIMARY_IP' => $stringType, 'CURLINFO_PRIMARY_PORT' => $integerType, 'CURLINFO_LOCAL_IP' => $stringType, 'CURLINFO_LOCAL_PORT' => $integerType, 'CURLINFO_SIZE_UPLOAD' => $integerType, 'CURLINFO_SIZE_DOWNLOAD' => $integerType, 'CURLINFO_SPEED_DOWNLOAD' => $integerType, 'CURLINFO_SPEED_UPLOAD' => $integerType, 'CURLINFO_HEADER_SIZE' => $integerType, 'CURLINFO_HEADER_OUT' => $stringFalseType, 'CURLINFO_REQUEST_SIZE' => $integerType, 'CURLINFO_SSL_VERIFYRESULT' => $integerType, 'CURLINFO_CONTENT_LENGTH_DOWNLOAD' => $floatType, 'CURLINFO_CONTENT_LENGTH_UPLOAD' => $floatType, 'CURLINFO_CONTENT_TYPE' => $stringFalseType, 'CURLINFO_PRIVATE' => $stringFalseType, 'CURLINFO_RESPONSE_CODE' => $integerType, 'CURLINFO_HTTP_CONNECTCODE' => $integerType, 'CURLINFO_HTTPAUTH_AVAIL' => $integerType, 'CURLINFO_PROXYAUTH_AVAIL' => $integerType, 'CURLINFO_OS_ERRNO' => $integerType, 'CURLINFO_NUM_CONNECTS' => $integerType, 'CURLINFO_SSL_ENGINES' => $integerStringArrayType, 'CURLINFO_COOKIELIST' => $integerStringArrayType, 'CURLINFO_FTP_ENTRY_PATH' => $stringFalseType, 'CURLINFO_APPCONNECT_TIME' => $floatType, 'CURLINFO_CERTINFO' => $nestedStringStringArrayType, 'CURLINFO_CONDITION_UNMET' => $integerType, 'CURLINFO_RTSP_CLIENT_CSEQ' => $integerType, 'CURLINFO_RTSP_CSEQ_RECV' => $integerType, 'CURLINFO_RTSP_SERVER_CSEQ' => $integerType, 'CURLINFO_RTSP_SESSION_ID' => $integerType, 'CURLINFO_HTTP_VERSION' => $integerType, 'CURLINFO_PROTOCOL' => $stringType, 'CURLINFO_PROXY_SSL_VERIFYRESULT' => $integerType, 'CURLINFO_SCHEME' => $stringType, 'CURLINFO_CONTENT_LENGTH_DOWNLOAD_T' => $integerType, 'CURLINFO_CONTENT_LENGTH_UPLOAD_T' => $integerType, 'CURLINFO_SIZE_DOWNLOAD_T' => $integerType, 'CURLINFO_SIZE_UPLOAD_T' => $integerType, 'CURLINFO_SPEED_DOWNLOAD_T' => $integerType, 'CURLINFO_SPEED_UPLOAD_T' => $integerType, 'CURLINFO_APPCONNECT_TIME_T' => $integerType, 'CURLINFO_CONNECT_TIME_T' => $integerType, 'CURLINFO_FILETIME_T' => $integerType, 'CURLINFO_NAMELOOKUP_TIME_T' => $integerType, 'CURLINFO_PRETRANSFER_TIME_T' => $integerType, 'CURLINFO_REDIRECT_TIME_T' => $integerType, 'CURLINFO_STARTTRANSFER_TIME_T' => $integerType, 'CURLINFO_TOTAL_TIME_T' => $integerType]; foreach ($componentTypesPairedConstants as $constantName => $type) { $constantNameNode = new Name($constantName); if ($this->reflectionProvider->hasConstant($constantNameNode, $scope) === \false) { continue; } $valueType = $this->reflectionProvider->getConstant($constantNameNode, $scope)->getValueType(); if ($componentType->isSuperTypeOf($valueType)->yes()) { return $type; } } return $falseType; } private function createAllComponentsReturnType() : Type { $returnTypes = [new ConstantBooleanType(\false)]; $builder = ConstantArrayTypeBuilder::createEmpty(); $stringType = new StringType(); $integerType = new IntegerType(); $floatType = new FloatType(); $stringOrNullType = TypeCombinator::union($stringType, new NullType()); $nestedStringStringArrayType = new ArrayType($integerType, new ArrayType($stringType, $stringType)); $componentTypesPairedStrings = ['url' => $stringType, 'content_type' => $stringOrNullType, 'http_code' => $integerType, 'header_size' => $integerType, 'request_size' => $integerType, 'filetime' => $integerType, 'ssl_verify_result' => $integerType, 'redirect_count' => $integerType, 'total_time' => $floatType, 'namelookup_time' => $floatType, 'connect_time' => $floatType, 'pretransfer_time' => $floatType, 'size_upload' => $floatType, 'size_download' => $floatType, 'speed_download' => $floatType, 'speed_upload' => $floatType, 'download_content_length' => $floatType, 'upload_content_length' => $floatType, 'starttransfer_time' => $floatType, 'redirect_time' => $floatType, 'redirect_url' => $stringType, 'primary_ip' => $stringType, 'certinfo' => $nestedStringStringArrayType, 'primary_port' => $integerType, 'local_ip' => $stringType, 'local_port' => $integerType, 'http_version' => $integerType, 'protocol' => $integerType, 'ssl_verifyresult' => $integerType, 'scheme' => $stringType]; foreach ($componentTypesPairedStrings as $componentName => $componentValueType) { $builder->setOffsetValueType(new ConstantStringType($componentName), $componentValueType); } $returnTypes[] = $builder->getArray(); return TypeUtils::toBenevolentUnion(TypeCombinator::union(...$returnTypes)); } } getName() === 'strtotime'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $defaultReturnType = ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->getArgs(), $functionReflection->getVariants())->getReturnType(); if (count($functionCall->getArgs()) === 0) { return $defaultReturnType; } $argType = $scope->getType($functionCall->getArgs()[0]->value); if ($argType instanceof MixedType) { return TypeUtils::toBenevolentUnion($defaultReturnType); } $results = array_unique(array_map(static function (ConstantStringType $string) { return strtotime($string->getValue()); }, $argType->getConstantStrings())); $resultTypes = array_unique(array_map(static function ($value) : string { return gettype($value); }, $results)); if (count($resultTypes) !== 1 || count($results) === 0) { return $defaultReturnType; } if ($results[0] === \false) { return new ConstantBooleanType(\false); } // 2nd param $baseTimestamp is too non-deterministic so simply return int if (count($functionCall->getArgs()) > 1) { return new IntegerType(); } // if it is positive we can narrow down to positive-int as long as time flows forward if (min(array_map('intval', $results)) > 0) { return IntegerRangeType::createAllGreaterThan(0); } return new IntegerType(); } } getName() === 'hrtime'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $arrayType = new ConstantArrayType([new ConstantIntegerType(0), new ConstantIntegerType(1)], [new IntegerType(), new IntegerType()], [2], [], TrinaryLogic::createYes()); $numberType = TypeUtils::toBenevolentUnion(TypeCombinator::union(new IntegerType(), new FloatType())); if (count($functionCall->getArgs()) < 1) { return $arrayType; } $argType = $scope->getType($functionCall->getArgs()[0]->value); $isTrueType = $argType->isTrue(); $isFalseType = $argType->isFalse(); $compareTypes = $isTrueType->compareTo($isFalseType); if ($compareTypes === $isTrueType) { return $numberType; } if ($compareTypes === $isFalseType) { return $arrayType; } return TypeCombinator::union($arrayType, $numberType); } } getName() === '__construct' && $methodReflection->getDeclaringClass()->getName() === SimpleXMLElement::class; } public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->getArgs()) === 0) { return $methodReflection->getThrowType(); } $valueType = $scope->getType($methodCall->getArgs()[0]->value); $constantStrings = $valueType->getConstantStrings(); $internalErrorsOld = libxml_use_internal_errors(\true); try { foreach ($constantStrings as $constantString) { try { new SimpleXMLElement($constantString->getValue()); } catch (\Exception $e) { // phpcs:ignore return $methodReflection->getThrowType(); } $valueType = TypeCombinator::remove($valueType, $constantString); } } finally { libxml_use_internal_errors($internalErrorsOld); } if (!$valueType instanceof NeverType) { return $methodReflection->getThrowType(); } return null; } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'array_slice'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) < 2) { return null; } $arrayType = $scope->getType($args[0]->value); if ($arrayType->isArray()->no()) { return $this->phpVersion->arrayFunctionsReturnNullWithNonArray() ? new NullType() : new NeverType(); } $offsetType = $scope->getType($args[1]->value); $lengthType = isset($args[2]) ? $scope->getType($args[2]->value) : new NullType(); $preserveKeysType = isset($args[3]) ? $scope->getType($args[3]->value) : new ConstantBooleanType(\false); return $arrayType->sliceArray($offsetType, $lengthType, $preserveKeysType->isTrue()); } } getName(), ['sscanf', 'fscanf'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) !== 2) { return null; } $formatType = $scope->getType($args[1]->value); if (!$formatType instanceof ConstantStringType) { return null; } if (preg_match_all('/%(\\d*)(\\[[^\\]]+\\]|[cdeEfosux]{1})/', $formatType->getValue(), $matches) > 0) { $arrayBuilder = ConstantArrayTypeBuilder::createEmpty(); for ($i = 0; $i < count($matches[0]); $i++) { $length = $matches[1][$i]; $specifier = $matches[2][$i]; $type = new StringType(); if ($length !== '') { if ((int) $length > 1) { $type = new IntersectionType([$type, new AccessoryNonFalsyStringType()]); } else { $type = new IntersectionType([$type, new AccessoryNonEmptyStringType()]); } } if (in_array($specifier, ['d', 'o', 'u', 'x'], \true)) { $type = new IntegerType(); } if (in_array($specifier, ['e', 'E', 'f'], \true)) { $type = new FloatType(); } $type = TypeCombinator::addNull($type); $arrayBuilder->setOffsetValueType(new ConstantIntegerType($i), $type); } return TypeCombinator::addNull($arrayBuilder->getArray()); } return null; } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'array_fill'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 3) { return null; } $numberType = $scope->getType($functionCall->getArgs()[1]->value); $isValidNumberType = IntegerRangeType::fromInterval(0, null)->isSuperTypeOf($numberType); // check against negative-int, which is not allowed if ($isValidNumberType->no()) { if ($this->phpVersion->throwsValueErrorForInternalFunctions()) { return new NeverType(); } return new ConstantBooleanType(\false); } $startIndexType = $scope->getType($functionCall->getArgs()[0]->value); $valueType = $scope->getType($functionCall->getArgs()[2]->value); if ($startIndexType instanceof ConstantIntegerType && $numberType instanceof ConstantIntegerType && $numberType->getValue() <= self::MAX_SIZE_USE_CONSTANT_ARRAY) { $arrayBuilder = ConstantArrayTypeBuilder::createEmpty(); $nextIndex = $startIndexType->getValue(); for ($i = 0; $i < $numberType->getValue(); $i++) { $arrayBuilder->setOffsetValueType(new ConstantIntegerType($nextIndex), $valueType); if ($nextIndex < 0) { $nextIndex = 0; } else { $nextIndex++; } } return $arrayBuilder->getArray(); } $resultType = new ArrayType(new IntegerType(), $valueType); if ((new ConstantIntegerType(0))->isSuperTypeOf($startIndexType)->yes()) { $resultType = AccessoryArrayListType::intersectWith($resultType); } if (IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($numberType)->yes()) { $resultType = TypeCombinator::intersect($resultType, new NonEmptyArrayType()); } if (!$isValidNumberType->yes() && !$this->phpVersion->throwsValueErrorForInternalFunctions()) { $resultType = TypeCombinator::union($resultType, new ConstantBooleanType(\false)); } return $resultType; } } getName() === 'open'; } public function isStaticMethodSupported(MethodReflection $methodReflection) : bool { return $this->isMethodSupported($methodReflection); } public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : Type { return new BooleanType(); } public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : Type { return new UnionType([new ObjectType(self::XML_READER_CLASS), new ConstantBooleanType(\false)]); } } getName() === 'strrev'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) < 1) { return null; } $inputType = $scope->getType($args[0]->value); $constantStrings = $inputType->getConstantStrings(); if (count($constantStrings) > 0) { $resultTypes = []; foreach ($constantStrings as $constantString) { $resultTypes[] = new ConstantStringType(strrev($constantString->getValue())); } return TypeCombinator::union(...$resultTypes); } $accessoryTypes = []; if ($inputType->isNonFalsyString()->yes()) { $accessoryTypes[] = new AccessoryNonFalsyStringType(); } elseif ($inputType->isNonEmptyString()->yes()) { $accessoryTypes[] = new AccessoryNonEmptyStringType(); } if ($inputType->isLowercaseString()->yes()) { $accessoryTypes[] = new AccessoryLowercaseStringType(); } if ($inputType->isUppercaseString()->yes()) { $accessoryTypes[] = new AccessoryUppercaseStringType(); } if (count($accessoryTypes) > 0) { $accessoryTypes[] = new StringType(); return new IntersectionType($accessoryTypes); } return null; } } [1, 0], 'str_contains' => [0, 1], 'str_starts_with' => [0, 1], 'str_ends_with' => [0, 1], 'strpos' => [0, 1], 'strrpos' => [0, 1], 'stripos' => [0, 1], 'strripos' => [0, 1], 'strstr' => [0, 1], 'mb_strpos' => [0, 1], 'mb_strrpos' => [0, 1], 'mb_stripos' => [0, 1], 'mb_strripos' => [0, 1], 'mb_strstr' => [0, 1]]; /** * @var TypeSpecifier */ private $typeSpecifier; public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool { return array_key_exists(strtolower($functionReflection->getName()), self::STR_CONTAINING_FUNCTIONS) && $context->true(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { $args = $node->getArgs(); if (count($args) >= 2) { [$hackstackArg, $needleArg] = self::STR_CONTAINING_FUNCTIONS[strtolower($functionReflection->getName())]; $haystackType = $scope->getType($args[$hackstackArg]->value); $needleType = $scope->getType($args[$needleArg]->value)->toString(); if ($needleType->isNonEmptyString()->yes() && $haystackType->isString()->yes()) { $accessories = [new StringType()]; if ($needleType->isNonFalsyString()->yes()) { $accessories[] = new AccessoryNonFalsyStringType(); } else { $accessories[] = new AccessoryNonEmptyStringType(); } if ($haystackType->isLiteralString()->yes()) { $accessories[] = new AccessoryLiteralStringType(); } if ($haystackType->isNumericString()->yes()) { $accessories[] = new AccessoryNumericStringType(); } return $this->typeSpecifier->create($args[$hackstackArg]->value, new IntersectionType($accessories), $context, \false, $scope, new BooleanAnd(new NotIdentical($args[$needleArg]->value, new String_('')), new FuncCall(new Name('FAUX_FUNCTION'), [new Arg($args[$needleArg]->value)]))); } } return new SpecifiedTypes(); } } getName(), ['get', 'remove'], \true); } public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : ?Type { $argsCount = count($methodCall->getArgs()); if ($argsCount > 1) { return null; } if ($argsCount === 0) { return null; } $mapType = $scope->getType($methodCall->var); if (!$mapType instanceof TypeWithClassName) { return null; } $mapAncestor = $mapType->getAncestorWithClassName('Ds\\Map'); if ($mapAncestor === null) { return null; } $mapAncestorClass = $mapAncestor->getClassReflection(); if ($mapAncestorClass === null) { return null; } $valueType = $mapAncestorClass->getActiveTemplateTypeMap()->getType('TValue'); if ($valueType === null) { return null; } return $valueType; } } regexShapeMatcher = $regexShapeMatcher; } public function isFunctionSupported(FunctionReflection $functionReflection, ParameterReflection $parameter) : bool { return $functionReflection->getName() === 'preg_replace_callback' && $parameter->getName() === 'callback'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, ParameterReflection $parameter, Scope $scope) : ?Type { $args = $functionCall->getArgs(); $patternArg = $args[0] ?? null; $flagsArg = $args[5] ?? null; if ($patternArg === null) { return null; } $flagsType = null; if ($flagsArg !== null) { $flagsType = $scope->getType($flagsArg->value); } $matchesType = $this->regexShapeMatcher->matchExpr($patternArg->value, $flagsType, TrinaryLogic::createYes(), $scope); if ($matchesType === null) { return null; } return new ClosureType([new NativeParameterReflection($parameter->getName(), $parameter->isOptional(), $matchesType, $parameter->passedByReference(), $parameter->isVariadic(), $parameter->getDefaultValue())], new StringType()); } } getName() === 'gettimeofday'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $arrayType = new ConstantArrayType([new ConstantStringType('sec'), new ConstantStringType('usec'), new ConstantStringType('minuteswest'), new ConstantStringType('dsttime')], [new IntegerType(), new IntegerType(), new IntegerType(), new IntegerType()]); $floatType = new FloatType(); if (!isset($functionCall->getArgs()[0])) { return $arrayType; } $argType = $scope->getType($functionCall->getArgs()[0]->value); $isTrueType = $argType->isTrue(); $isFalseType = $argType->isFalse(); $compareTypes = $isTrueType->compareTo($isFalseType); if ($compareTypes === $isTrueType) { return $floatType; } if ($compareTypes === $isFalseType) { return $arrayType; } if ($argType instanceof MixedType) { return new BenevolentUnionType([$arrayType, $floatType]); } return new UnionType([$arrayType, $floatType]); } } getName(), ['trim', 'rtrim', 'ltrim'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) < 1) { return null; } $stringType = $scope->getType($args[0]->value); $accessory = []; if ($stringType->isLowercaseString()->yes()) { $accessory[] = new AccessoryLowercaseStringType(); } if ($stringType->isUppercaseString()->yes()) { $accessory[] = new AccessoryUppercaseStringType(); } if (count($accessory) > 0) { $accessory[] = new StringType(); return new IntersectionType($accessory); } return new StringType(); } } getName(), ['random_int', 'rand', 'mt_rand'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (in_array($functionReflection->getName(), ['rand', 'mt_rand'], \true) && count($functionCall->getArgs()) === 0) { return IntegerRangeType::fromInterval(0, null); } if (count($functionCall->getArgs()) < 2) { return null; } $minType = $scope->getType($functionCall->getArgs()[0]->value)->toInteger(); $maxType = $scope->getType($functionCall->getArgs()[1]->value)->toInteger(); return $this->createRange($minType, $maxType); } private function createRange(Type $minType, Type $maxType) : Type { $minValues = array_map(static function (Type $type) : ?int { if ($type instanceof IntegerRangeType) { return $type->getMin(); } if ($type instanceof ConstantIntegerType) { return $type->getValue(); } return null; }, $minType instanceof UnionType ? $minType->getTypes() : [$minType]); $maxValues = array_map(static function (Type $type) : ?int { if ($type instanceof IntegerRangeType) { return $type->getMax(); } if ($type instanceof ConstantIntegerType) { return $type->getValue(); } return null; }, $maxType instanceof UnionType ? $maxType->getTypes() : [$maxType]); assert(count($minValues) > 0); assert(count($maxValues) > 0); return IntegerRangeType::fromInterval(in_array(null, $minValues, \true) ? null : min($minValues), in_array(null, $maxValues, \true) ? null : max($maxValues)); } } getName() === 'SimpleXMLElement' || $classReflection->isSubclassOf('SimpleXMLElement'); } public function getProperty(ClassReflection $classReflection, string $propertyName) : PropertyReflection { return new SimpleXMLElementProperty($classReflection, new BenevolentUnionType([new ObjectType($classReflection->getName()), new NullType()])); } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return in_array($functionReflection->getName(), ['bcdiv', 'bcmod', 'bcpowmod', 'bcsqrt'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { if ($functionReflection->getName() === 'bcsqrt') { return $this->getTypeForBcSqrt($functionCall, $scope); } if ($functionReflection->getName() === 'bcpowmod') { return $this->getTypeForBcPowMod($functionCall, $scope); } $stringAndNumericStringType = TypeCombinator::intersect(new StringType(), new AccessoryNumericStringType()); if (isset($functionCall->getArgs()[1]) === \false) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } return new NullType(); } if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { $defaultReturnType = $stringAndNumericStringType; } else { $defaultReturnType = new UnionType([$stringAndNumericStringType, new NullType()]); } $secondArgument = $scope->getType($functionCall->getArgs()[1]->value); $secondArgumentIsNumeric = $secondArgument instanceof ConstantScalarType && is_numeric($secondArgument->getValue()) || $secondArgument->isInteger()->yes(); if ($secondArgument instanceof ConstantScalarType && ($this->isZero($secondArgument->getValue()) || !$secondArgumentIsNumeric)) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } return new NullType(); } if (isset($functionCall->getArgs()[2]) === \false) { if ($secondArgument instanceof ConstantScalarType || $secondArgumentIsNumeric) { return $stringAndNumericStringType; } return $defaultReturnType; } $thirdArgument = $scope->getType($functionCall->getArgs()[2]->value); $thirdArgumentIsNumeric = \false; $thirdArgumentIsNegative = \false; if ($thirdArgument instanceof ConstantScalarType && is_numeric($thirdArgument->getValue())) { $thirdArgumentIsNumeric = \true; $thirdArgumentIsNegative = $thirdArgument->getValue() < 0; } elseif ($thirdArgument->isInteger()->yes()) { $thirdArgumentIsNumeric = \true; if (IntegerRangeType::fromInterval(null, -1)->isSuperTypeOf($thirdArgument)->yes()) { $thirdArgumentIsNegative = \true; } } if ($thirdArgument instanceof ConstantScalarType && !is_numeric($thirdArgument->getValue())) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } return new NullType(); } if ($this->phpVersion->throwsTypeErrorForInternalFunctions() && $thirdArgumentIsNegative) { return new NeverType(); } if (($secondArgument instanceof ConstantScalarType || $secondArgumentIsNumeric) && $thirdArgumentIsNumeric) { return $stringAndNumericStringType; } return $defaultReturnType; } /** * bcsqrt * https://www.php.net/manual/en/function.bcsqrt.php * > Returns the square root as a string, or NULL if operand is negative. * */ private function getTypeForBcSqrt(FuncCall $functionCall, Scope $scope) : Type { $stringAndNumericStringType = TypeCombinator::intersect(new StringType(), new AccessoryNumericStringType()); if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { $defaultReturnType = $stringAndNumericStringType; } else { $defaultReturnType = new UnionType([$stringAndNumericStringType, new NullType()]); } if (isset($functionCall->getArgs()[0]) === \false) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } return $defaultReturnType; } $firstArgument = $scope->getType($functionCall->getArgs()[0]->value); $firstArgumentIsPositive = $firstArgument instanceof ConstantScalarType && is_numeric($firstArgument->getValue()) && $firstArgument->getValue() >= 0; $firstArgumentIsNegative = $firstArgument instanceof ConstantScalarType && is_numeric($firstArgument->getValue()) && $firstArgument->getValue() < 0; if ($firstArgument instanceof UnaryMinus || $firstArgumentIsNegative) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } return new NullType(); } if (isset($functionCall->getArgs()[1]) === \false) { if ($firstArgumentIsPositive) { return $stringAndNumericStringType; } return $defaultReturnType; } $secondArgument = $scope->getType($functionCall->getArgs()[1]->value); $secondArgumentIsValid = $secondArgument instanceof ConstantScalarType && is_numeric($secondArgument->getValue()) && !$this->isZero($secondArgument->getValue()); $secondArgumentIsNonNumeric = $secondArgument instanceof ConstantScalarType && !is_numeric($secondArgument->getValue()); $secondArgumentIsNegative = $secondArgument instanceof ConstantScalarType && is_numeric($secondArgument->getValue()) && $secondArgument->getValue() < 0; if ($secondArgumentIsNonNumeric) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } return new NullType(); } if ($secondArgument instanceof UnaryMinus || $secondArgumentIsNegative) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } } if ($firstArgumentIsPositive && $secondArgumentIsValid) { return $stringAndNumericStringType; } return $defaultReturnType; } /** * bcpowmod() * https://www.php.net/manual/en/function.bcpowmod.php * > Returns the result as a string, or FALSE if modulus is 0 or exponent is negative. */ private function getTypeForBcPowMod(FuncCall $functionCall, Scope $scope) : Type { if ($this->phpVersion->throwsTypeErrorForInternalFunctions() && isset($functionCall->getArgs()[0]) === \false) { return new NeverType(); } $stringAndNumericStringType = TypeCombinator::intersect(new StringType(), new AccessoryNumericStringType()); if (isset($functionCall->getArgs()[1]) === \false) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } return new UnionType([$stringAndNumericStringType, new ConstantBooleanType(\false)]); } $exponent = $scope->getType($functionCall->getArgs()[1]->value); // Expontent is non numeric if ($this->phpVersion->throwsTypeErrorForInternalFunctions() && $exponent instanceof ConstantScalarType && !is_numeric($exponent->getValue())) { return new NeverType(); } $exponentIsNegative = IntegerRangeType::fromInterval(null, 0)->isSuperTypeOf($exponent)->yes(); if ($exponent instanceof ConstantScalarType) { $exponentIsNegative = is_numeric($exponent->getValue()) && $exponent->getValue() < 0; } if ($exponentIsNegative) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } return new ConstantBooleanType(\false); } if (isset($functionCall->getArgs()[2])) { $modulus = $scope->getType($functionCall->getArgs()[2]->value); $modulusIsZero = $modulus instanceof ConstantScalarType && $this->isZero($modulus->getValue()); $modulusIsNonNumeric = $modulus instanceof ConstantScalarType && !is_numeric($modulus->getValue()); if ($modulusIsZero || $modulusIsNonNumeric) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } return new ConstantBooleanType(\false); } if ($modulus instanceof ConstantScalarType) { return $stringAndNumericStringType; } } else { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } } if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return $stringAndNumericStringType; } return new UnionType([$stringAndNumericStringType, new ConstantBooleanType(\false)]); } /** * Utility to help us determine if value is zero. Handles cases where we pass "0.000" too. * * @param mixed $value */ private function isZero($value) : bool { if (is_numeric($value) === \false) { return \false; } if ($value > 0 || $value < 0) { return \false; } return \true; } } getName() === 'array_key_last'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $argType = $scope->getType($functionCall->getArgs()[0]->value); $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); if ($iterableAtLeastOnce->no()) { return new NullType(); } $keyType = $argType->getLastIterableKeyType(); if ($iterableAtLeastOnce->yes()) { return $keyType; } return TypeCombinator::union($keyType, new NullType()); } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'array_chunk'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 2) { return null; } $arrayType = $scope->getType($functionCall->getArgs()[0]->value); if ($arrayType->isArray()->no()) { return $this->phpVersion->arrayFunctionsReturnNullWithNonArray() ? new NullType() : new NeverType(); } $lengthType = $scope->getType($functionCall->getArgs()[1]->value); $negativeOrZero = IntegerRangeType::fromInterval(null, 0); if ($negativeOrZero->isSuperTypeOf($lengthType)->yes()) { return $this->phpVersion->throwsValueErrorForInternalFunctions() ? new NeverType() : new NullType(); } $preserveKeysType = isset($functionCall->getArgs()[2]) ? $scope->getType($functionCall->getArgs()[2]->value) : new ConstantBooleanType(\false); return $arrayType->chunkArray($lengthType, $preserveKeysType->isTrue()); } } getName(), ['sprintf', 'vsprintf'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) === 0) { return null; } $constantType = $this->getConstantType($args, $functionReflection, $scope); if ($constantType !== null) { return $constantType; } $formatType = $scope->getType($args[0]->value); $formatStrings = $formatType->getConstantStrings(); $isLowercase = $formatType->isLowercaseString()->yes() && $this->allValuesSatisfies($functionReflection, $scope, $args, static function (Type $type) : bool { return $type->toString()->isLowercaseString()->yes(); }); $singlePlaceholderEarlyReturn = []; $allPatternsNonEmpty = count($formatStrings) !== 0; $allPatternsNonFalsy = count($formatStrings) !== 0; foreach ($formatStrings as $constantString) { $constantParts = $this->getFormatConstantParts($constantString->getValue(), $functionReflection, $functionCall, $scope); if ($constantParts !== null) { if ($constantParts->isNonFalsyString()->yes()) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf // keep all bool flags as is } elseif ($constantParts->isNonEmptyString()->yes()) { $allPatternsNonFalsy = \false; } else { $allPatternsNonEmpty = \false; $allPatternsNonFalsy = \false; } } else { $allPatternsNonEmpty = \false; $allPatternsNonFalsy = \false; } if (is_array($singlePlaceholderEarlyReturn) && preg_match('/^%(?P[0-9]*\\$)?(?P[0-9]*)\\.?[0-9]*(?P[sbdeEfFgGhHouxX])$/', $constantString->getValue(), $matches) === 1) { if ($matches['argnum'] !== '') { // invalid positional argument if ($matches['argnum'] === '0$') { return null; } $checkArg = intval(substr($matches['argnum'], 0, -1)); } else { $checkArg = 1; } $checkArgType = $this->getValueType($functionReflection, $scope, $args, $checkArg); if ($checkArgType === null) { return null; } // if the format string is just a placeholder and specified an argument // of stringy type, then the return value will be of the same type if ($matches['specifier'] === 's' && ($checkArgType->isString()->yes() || $checkArgType->isInteger()->yes())) { if ($checkArgType instanceof IntegerRangeType) { $constArgTypes = $checkArgType->getFiniteTypes(); } else { $constArgTypes = $checkArgType->getConstantScalarTypes(); } if ($constArgTypes !== []) { $printfArgs = array_fill(0, count($args) - 1, ''); foreach ($constArgTypes as $constArgType) { $printfArgs[$checkArg - 1] = $constArgType->getValue(); try { $singlePlaceholderEarlyReturn[] = new ConstantStringType(@sprintf($constantString->getValue(), ...$printfArgs)); } catch (Throwable $e) { continue 2; } } continue; } $singlePlaceholderEarlyReturn[] = $checkArgType->toString(); } elseif ($matches['specifier'] !== 's') { $singlePlaceholderEarlyReturn[] = $this->getStringReturnType(new AccessoryNumericStringType(), $isLowercase); } continue; } $singlePlaceholderEarlyReturn = null; } if (is_array($singlePlaceholderEarlyReturn) && count($singlePlaceholderEarlyReturn) > 0) { return TypeCombinator::union(...$singlePlaceholderEarlyReturn); } if ($allPatternsNonFalsy) { return $this->getStringReturnType(new AccessoryNonFalsyStringType(), $isLowercase); } $isNonEmpty = $allPatternsNonEmpty; if (!$isNonEmpty && $formatType->isNonEmptyString()->yes()) { $isNonEmpty = $this->allValuesSatisfies($functionReflection, $scope, $args, static function (Type $type) : bool { return $type->toString()->isNonEmptyString()->yes(); }); } if ($isNonEmpty) { return $this->getStringReturnType(new AccessoryNonEmptyStringType(), $isLowercase); } return $this->getStringReturnType(null, $isLowercase); } /** * @param array $args * @param callable(Type): bool $cb */ private function allValuesSatisfies(FunctionReflection $functionReflection, Scope $scope, array $args, callable $cb) : bool { if ($functionReflection->getName() === 'sprintf' && count($args) >= 2) { foreach ($args as $key => $arg) { if ($key === 0) { continue; } if (!$cb($scope->getType($arg->value))) { return \false; } } return \true; } if ($functionReflection->getName() === 'vsprintf' && count($args) >= 2) { return $cb($scope->getType($args[1]->value)->getIterableValueType()); } return \false; } /** * @param Arg[] $args */ private function getValueType(FunctionReflection $functionReflection, Scope $scope, array $args, int $argNumber) : ?Type { if ($functionReflection->getName() === 'sprintf') { // constant string specifies a numbered argument that does not exist if (!array_key_exists($argNumber, $args)) { return null; } return $scope->getType($args[$argNumber]->value); } if ($functionReflection->getName() === 'vsprintf') { if (!array_key_exists(1, $args)) { return null; } $valuesType = $scope->getType($args[1]->value); $resultTypes = []; $valuesConstantArrays = $valuesType->getConstantArrays(); foreach ($valuesConstantArrays as $valuesConstantArray) { // vsprintf does not care about the keys of the array, only the order $types = array_values($valuesConstantArray->getValueTypes()); if (!array_key_exists($argNumber - 1, $types)) { return null; } $resultTypes[] = $types[$argNumber - 1]; } if (count($resultTypes) === 0) { return $valuesType->getIterableValueType(); } return TypeCombinator::union(...$resultTypes); } return null; } /** * Detect constant strings in the format which neither depend on placeholders nor on given value arguments. */ private function getFormatConstantParts(string $format, FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?ConstantStringType { $args = $functionCall->getArgs(); if ($functionReflection->getName() === 'sprintf') { $valuesCount = count($args) - 1; } elseif ($functionReflection->getName() === 'vsprintf' && count($args) >= 2) { $arraySize = $scope->getType($args[1]->value)->getArraySize(); if (!$arraySize instanceof ConstantIntegerType) { return null; } $valuesCount = $arraySize->getValue(); } else { return null; } if ($valuesCount <= 0) { return null; } $dummyValues = array_fill(0, $valuesCount, ''); try { $formatted = @vsprintf($format, $dummyValues); if ($formatted === \false) { // @phpstan-ignore identical.alwaysFalse (PHP7.2 compat) return null; } return new ConstantStringType($formatted); } catch (Throwable $e) { return null; } } /** * @param Arg[] $args */ private function getConstantType(array $args, FunctionReflection $functionReflection, Scope $scope) : ?Type { $values = []; $combinationsCount = 1; foreach ($args as $arg) { if ($arg->unpack) { return null; } $argType = $scope->getType($arg->value); $constantScalarValues = $argType->getConstantScalarValues(); if (count($constantScalarValues) === 0) { if ($argType instanceof IntegerRangeType) { foreach ($argType->getFiniteTypes() as $finiteType) { $constantScalarValues[] = $finiteType->getValue(); } } } if (count($constantScalarValues) === 0) { return null; } $values[] = $constantScalarValues; $combinationsCount *= count($constantScalarValues); } if ($combinationsCount > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT) { return null; } $combinations = CombinationsHelper::combinations($values); $returnTypes = []; foreach ($combinations as $combination) { $format = array_shift($combination); if (!is_string($format)) { return null; } try { if ($functionReflection->getName() === 'sprintf') { $returnTypes[] = $scope->getTypeFromValue(@sprintf($format, ...$combination)); } else { $returnTypes[] = $scope->getTypeFromValue(@vsprintf($format, $combination)); } } catch (Throwable $e) { return null; } } if (count($returnTypes) > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT) { return null; } return TypeCombinator::union(...$returnTypes); } private function getStringReturnType(?AccessoryType $accessoryType, bool $isLowercase) : Type { $accessoryTypes = []; if ($accessoryType !== null) { $accessoryTypes[] = $accessoryType; } if ($isLowercase) { $accessoryTypes[] = new AccessoryLowercaseStringType(); } if (count($accessoryTypes) === 0) { return new StringType(); } $accessoryTypes[] = new StringType(); return new IntersectionType($accessoryTypes); } } getName() === 'current'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $argType = $scope->getType($functionCall->getArgs()[0]->value); $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); if ($iterableAtLeastOnce->no()) { return new ConstantBooleanType(\false); } $keyType = $argType->getIterableValueType(); if ($iterableAtLeastOnce->yes()) { return $keyType; } return TypeCombinator::union($keyType, new ConstantBooleanType(\false)); } } getName() === 'strtok'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) !== 2) { return null; } $delimiterType = $scope->getType($functionCall->getArgs()[0]->value); $isEmptyString = (new ConstantStringType(''))->isSuperTypeOf($delimiterType); if ($isEmptyString->yes()) { return new ConstantBooleanType(\false); } if ($isEmptyString->no()) { return new IntersectionType([new StringType(), new AccessoryNonEmptyStringType()]); } return null; } } phpVersion = $phpVersion; } public function isStaticMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getName() === '__construct' && $methodReflection->getDeclaringClass()->getName() === DateTimeZone::class; } public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->getArgs()) === 0) { return null; } $valueType = $scope->getType($methodCall->getArgs()[0]->value); $constantStrings = $valueType->getConstantStrings(); foreach ($constantStrings as $constantString) { try { new DateTimeZone($constantString->getValue()); } catch (\Exception $e) { // phpcs:ignore return $this->exceptionType(); } $valueType = TypeCombinator::remove($valueType, $constantString); } if (!$valueType instanceof NeverType) { return $this->exceptionType(); } return null; } private function exceptionType() : Type { if ($this->phpVersion->hasDateTimeExceptions()) { return new ObjectType('DateInvalidTimeZoneException'); } return new ObjectType('Exception'); } } typeSpecifier = $typeSpecifier; } public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool { return strtolower($functionReflection->getName()) === 'in_array' && !$context->null(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { $argsCount = count($node->getArgs()); if ($argsCount < 2) { return new SpecifiedTypes(); } $isStrictComparison = \false; if ($argsCount >= 3) { $strictNodeType = $scope->getType($node->getArgs()[2]->value); $isStrictComparison = $strictNodeType->isTrue()->yes(); } $needleExpr = $node->getArgs()[0]->value; $arrayExpr = $node->getArgs()[1]->value; $needleType = $scope->getType($needleExpr); $arrayType = $scope->getType($arrayExpr); $arrayValueType = $arrayType->getIterableValueType(); $isStrictComparison = $isStrictComparison || $needleType->isEnum()->yes() || $arrayValueType->isEnum()->yes() || $needleType->isString()->yes() && $arrayValueType->isString()->yes() || $needleType->isInteger()->yes() && $arrayValueType->isInteger()->yes() || $needleType->isFloat()->yes() && $arrayValueType->isFloat()->yes() || $needleType->isBoolean()->yes() && $arrayValueType->isBoolean()->yes(); if ($arrayExpr instanceof Array_) { $types = null; foreach ($arrayExpr->items as $item) { if ($item === null) { continue; } if ($item->unpack) { $types = null; break; } if ($isStrictComparison) { $itemTypes = $this->typeSpecifier->resolveIdentical(new Identical($needleExpr, $item->value), $scope, $context, null); } else { $itemTypes = $this->typeSpecifier->resolveEqual(new Equal($needleExpr, $item->value), $scope, $context, null); } if ($types === null) { $types = $itemTypes; continue; } $types = $context->true() ? $types->normalize($scope)->intersectWith($itemTypes->normalize($scope)) : $types->unionWith($itemTypes); } if ($types !== null) { return $types; } } if (!$isStrictComparison) { if ($context->true() && $arrayType->isArray()->yes() && $arrayType->getIterableValueType()->isSuperTypeOf($needleType)->yes()) { return $this->typeSpecifier->create($node->getArgs()[1]->value, TypeCombinator::intersect($arrayType, new NonEmptyArrayType()), $context, \false, $scope); } return new SpecifiedTypes(); } $specifiedTypes = new SpecifiedTypes(); if ($context->true() || $context->false() && (count(TypeUtils::getConstantScalars($arrayValueType)) > 0 || count(TypeUtils::getEnumCaseObjects($arrayValueType)) > 0)) { $specifiedTypes = $this->typeSpecifier->create($needleExpr, $arrayValueType, $context, \false, $scope); if ($needleExpr instanceof AlwaysRememberedExpr) { $specifiedTypes = $specifiedTypes->unionWith($this->typeSpecifier->create($needleExpr->getExpr(), $arrayValueType, $context, \false, $scope)); } } if ($context->true() || $context->false() && (count(TypeUtils::getConstantScalars($needleType)) === 1 || count(TypeUtils::getEnumCaseObjects($needleType)) === 1)) { if ($context->true()) { $arrayValueType = TypeCombinator::union($arrayValueType, $needleType); } else { $arrayValueType = TypeCombinator::remove($arrayValueType, $needleType); } $specifiedTypes = $specifiedTypes->unionWith($this->typeSpecifier->create($node->getArgs()[1]->value, new ArrayType(new MixedType(), $arrayValueType), TypeSpecifierContext::createTrue(), \false, $scope)); } if ($context->true() && $arrayType->isArray()->yes()) { $specifiedTypes = $specifiedTypes->unionWith($this->typeSpecifier->create($node->getArgs()[1]->value, TypeCombinator::intersect($arrayType, new NonEmptyArrayType()), $context, \false, $scope)); } return $specifiedTypes; } } 2, 'preg_replace_callback' => 2, 'preg_replace_callback_array' => 1, 'str_replace' => 2, 'str_ireplace' => 2, 'substr_replace' => 0, 'strtr' => 0]; private const FUNCTIONS_REPLACE_POSITION = ['preg_replace' => 1, 'str_replace' => 1, 'str_ireplace' => 1, 'substr_replace' => 1, 'strtr' => 2]; public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return array_key_exists($functionReflection->getName(), self::FUNCTIONS_SUBJECT_POSITION); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $type = $this->getPreliminarilyResolvedTypeFromFunctionCall($functionReflection, $functionCall, $scope); if ($this->canReturnNull($functionReflection, $functionCall, $scope)) { $type = TypeCombinator::addNull($type); } return $type; } private function getPreliminarilyResolvedTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $subjectArgumentType = $this->getSubjectType($functionReflection, $functionCall, $scope); $defaultReturnType = ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->getArgs(), $functionReflection->getVariants())->getReturnType(); if ($subjectArgumentType === null) { return $defaultReturnType; } if ($subjectArgumentType instanceof MixedType) { return TypeUtils::toBenevolentUnion($defaultReturnType); } if (array_key_exists($functionReflection->getName(), self::FUNCTIONS_REPLACE_POSITION)) { $replaceArgumentPosition = self::FUNCTIONS_REPLACE_POSITION[$functionReflection->getName()]; if (count($functionCall->getArgs()) > $replaceArgumentPosition) { $replaceArgumentType = $scope->getType($functionCall->getArgs()[$replaceArgumentPosition]->value); $accessories = []; if ($subjectArgumentType->isNonFalsyString()->yes() && $replaceArgumentType->isNonFalsyString()->yes()) { $accessories[] = new AccessoryNonFalsyStringType(); } elseif ($subjectArgumentType->isNonEmptyString()->yes() && $replaceArgumentType->isNonEmptyString()->yes()) { $accessories[] = new AccessoryNonEmptyStringType(); } if ($subjectArgumentType->isLowercaseString()->yes() && $replaceArgumentType->isLowercaseString()->yes()) { $accessories[] = new AccessoryLowercaseStringType(); } if ($subjectArgumentType->isUppercaseString()->yes() && $replaceArgumentType->isUppercaseString()->yes()) { $accessories[] = new AccessoryUppercaseStringType(); } if (count($accessories) > 0) { $accessories[] = new StringType(); return new IntersectionType($accessories); } } } $isStringSuperType = $subjectArgumentType->isString(); $isArraySuperType = $subjectArgumentType->isArray(); $compareSuperTypes = $isStringSuperType->compareTo($isArraySuperType); if ($compareSuperTypes === $isStringSuperType) { return new StringType(); } elseif ($compareSuperTypes === $isArraySuperType) { $subjectArrays = $subjectArgumentType->getArrays(); if (count($subjectArrays) > 0) { $result = []; foreach ($subjectArrays as $arrayType) { $constantArrays = $arrayType->getConstantArrays(); if ($constantArrays !== [] && in_array($functionReflection->getName(), ['preg_replace', 'preg_replace_callback', 'preg_replace_callback_array'], \true)) { foreach ($constantArrays as $constantArray) { $generalizedArray = $constantArray->generalizeValues(); $builder = ConstantArrayTypeBuilder::createEmpty(); // turn all keys optional foreach ($constantArray->getKeyTypes() as $keyType) { $builder->setOffsetValueType($keyType, $generalizedArray->getOffsetValueType($keyType), \true); } $result[] = $builder->getArray(); } continue; } $result[] = $arrayType->generalizeValues(); } return TypeCombinator::union(...$result); } return $subjectArgumentType; } return $defaultReturnType; } private function getSubjectType(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $argumentPosition = self::FUNCTIONS_SUBJECT_POSITION[$functionReflection->getName()]; if (count($functionCall->getArgs()) <= $argumentPosition) { return null; } return $scope->getType($functionCall->getArgs()[$argumentPosition]->value); } private function canReturnNull(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : bool { if (in_array($functionReflection->getName(), ['preg_replace', 'preg_replace_callback', 'preg_replace_callback_array'], \true) && count($functionCall->getArgs()) > 0) { $subjectArgumentType = $this->getSubjectType($functionReflection, $functionCall, $scope); if ($subjectArgumentType !== null && $subjectArgumentType->isArray()->yes()) { return \false; } } $possibleTypes = ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->getArgs(), $functionReflection->getVariants())->getReturnType(); // resolve conditional return types $possibleTypes = TypeUtils::resolveLateResolvableTypes($possibleTypes); return TypeCombinator::containsNull($possibleTypes); } } |null */ private $filterTypeMap = null; /** @var array>|null */ private $filterTypeOptions = null; /** * @var ?Type */ private $supportedFilterInputTypes = null; public function __construct(ReflectionProvider $reflectionProvider, PhpVersion $phpVersion) { $this->reflectionProvider = $reflectionProvider; $this->phpVersion = $phpVersion; $this->flagsString = new ConstantStringType('flags'); } public function getOffsetValueType(Type $inputType, Type $offsetType, ?Type $filterType, ?Type $flagsType) : Type { $inexistentOffsetType = $this->hasFlag($this->getConstant('FILTER_NULL_ON_FAILURE'), $flagsType) ? new ConstantBooleanType(\false) : new NullType(); $hasOffsetValueType = $inputType->hasOffsetValueType($offsetType); if ($hasOffsetValueType->no()) { return $inexistentOffsetType; } $filteredType = $this->getType($inputType->getOffsetValueType($offsetType), $filterType, $flagsType); return $hasOffsetValueType->maybe() ? TypeCombinator::union($filteredType, $inexistentOffsetType) : $filteredType; } public function getInputType(Type $typeType, Type $varNameType, ?Type $filterType, ?Type $flagsType) : Type { $this->supportedFilterInputTypes = $this->supportedFilterInputTypes ?? TypeCombinator::union($this->reflectionProvider->getConstant(new Node\Name('INPUT_GET'), null)->getValueType(), $this->reflectionProvider->getConstant(new Node\Name('INPUT_POST'), null)->getValueType(), $this->reflectionProvider->getConstant(new Node\Name('INPUT_COOKIE'), null)->getValueType(), $this->reflectionProvider->getConstant(new Node\Name('INPUT_SERVER'), null)->getValueType(), $this->reflectionProvider->getConstant(new Node\Name('INPUT_ENV'), null)->getValueType()); if (!$typeType->isInteger()->yes() || $this->supportedFilterInputTypes->isSuperTypeOf($typeType)->no()) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } // Using a null as input mimics pre PHP 8 behaviour where filter_input // would return the same as if the offset does not exist $inputType = new NullType(); } else { // Pragmatical solution since global expressions are not passed through the scope for performance reasons // See https://github.com/phpstan/phpstan-src/pull/2012 for details $inputType = new ArrayType(new StringType(), new MixedType()); } return $this->getOffsetValueType($inputType, $varNameType, $filterType, $flagsType); } public function getType(Type $inputType, ?Type $filterType, ?Type $flagsType) : Type { $mixedType = new MixedType(); if ($filterType === null) { $filterValue = $this->getConstant('FILTER_DEFAULT'); } else { if (!$filterType instanceof ConstantIntegerType) { return $mixedType; } $filterValue = $filterType->getValue(); } if ($flagsType === null) { $flagsType = new ConstantIntegerType(0); } $hasOptions = $this->hasOptions($flagsType); $options = $hasOptions->yes() ? $this->getOptions($flagsType, $filterValue) : []; $defaultType = $options['default'] ?? ($this->hasFlag($this->getConstant('FILTER_NULL_ON_FAILURE'), $flagsType) ? new NullType() : new ConstantBooleanType(\false)); $inputIsArray = $inputType->isArray(); $hasRequireArrayFlag = $this->hasFlag($this->getConstant('FILTER_REQUIRE_ARRAY'), $flagsType); if ($inputIsArray->no() && $hasRequireArrayFlag) { return $defaultType; } $hasForceArrayFlag = $this->hasFlag($this->getConstant('FILTER_FORCE_ARRAY'), $flagsType); if ($inputIsArray->yes() && ($hasRequireArrayFlag || $hasForceArrayFlag)) { $inputArrayKeyType = $inputType->getIterableKeyType(); $inputType = $inputType->getIterableValueType(); } if ($inputType->isScalar()->no() && $inputType->isNull()->no()) { return $defaultType; } $exactType = $this->determineExactType($inputType, $filterValue, $defaultType, $flagsType); $type = $exactType ?? $this->getFilterTypeMap()[$filterValue] ?? $mixedType; $type = $this->applyRangeOptions($type, $options, $defaultType); if ($inputType->isNonEmptyString()->yes() && $type->isString()->yes() && !$this->canStringBeSanitized($filterValue, $flagsType)) { $accessory = new AccessoryNonEmptyStringType(); if ($inputType->isNonFalsyString()->yes()) { $accessory = new AccessoryNonFalsyStringType(); } $type = TypeCombinator::intersect($type, $accessory); } if ($hasRequireArrayFlag) { $type = new ArrayType($inputArrayKeyType ?? $mixedType, $type); } if ($exactType === null || $hasOptions->maybe() || !$inputType->equals($type) && $inputType->isSuperTypeOf($type)->yes()) { if ($defaultType->isSuperTypeOf($type)->no()) { $type = TypeCombinator::union($type, $defaultType); } } if (!$hasRequireArrayFlag && $hasForceArrayFlag) { return new ArrayType($inputArrayKeyType ?? $mixedType, $type); } return $type; } /** * @return array */ private function getFilterTypeMap() : array { if ($this->filterTypeMap !== null) { return $this->filterTypeMap; } $booleanType = new BooleanType(); $floatType = new FloatType(); $intType = new IntegerType(); $stringType = new StringType(); $nonFalsyStringType = TypeCombinator::intersect($stringType, new AccessoryNonFalsyStringType()); $this->filterTypeMap = [$this->getConstant('FILTER_UNSAFE_RAW') => $stringType, $this->getConstant('FILTER_SANITIZE_EMAIL') => $stringType, $this->getConstant('FILTER_SANITIZE_ENCODED') => $stringType, $this->getConstant('FILTER_SANITIZE_NUMBER_FLOAT') => $stringType, $this->getConstant('FILTER_SANITIZE_NUMBER_INT') => $stringType, $this->getConstant('FILTER_SANITIZE_SPECIAL_CHARS') => $stringType, $this->getConstant('FILTER_SANITIZE_STRING') => $stringType, $this->getConstant('FILTER_SANITIZE_URL') => $stringType, $this->getConstant('FILTER_VALIDATE_BOOLEAN') => $booleanType, $this->getConstant('FILTER_VALIDATE_DOMAIN') => $stringType, $this->getConstant('FILTER_VALIDATE_EMAIL') => $nonFalsyStringType, $this->getConstant('FILTER_VALIDATE_FLOAT') => $floatType, $this->getConstant('FILTER_VALIDATE_INT') => $intType, $this->getConstant('FILTER_VALIDATE_IP') => $nonFalsyStringType, $this->getConstant('FILTER_VALIDATE_MAC') => $nonFalsyStringType, $this->getConstant('FILTER_VALIDATE_REGEXP') => $stringType, $this->getConstant('FILTER_VALIDATE_URL') => $nonFalsyStringType]; if ($this->reflectionProvider->hasConstant(new Node\Name('FILTER_SANITIZE_MAGIC_QUOTES'), null)) { $this->filterTypeMap[$this->getConstant('FILTER_SANITIZE_MAGIC_QUOTES')] = $stringType; } if ($this->reflectionProvider->hasConstant(new Node\Name('FILTER_SANITIZE_ADD_SLASHES'), null)) { $this->filterTypeMap[$this->getConstant('FILTER_SANITIZE_ADD_SLASHES')] = $stringType; } return $this->filterTypeMap; } /** * @return array> */ private function getFilterTypeOptions() : array { if ($this->filterTypeOptions !== null) { return $this->filterTypeOptions; } $this->filterTypeOptions = [$this->getConstant('FILTER_VALIDATE_INT') => ['min_range', 'max_range']]; return $this->filterTypeOptions; } /** * @param non-empty-string $constantName */ private function getConstant(string $constantName) : int { $constant = $this->reflectionProvider->getConstant(new Node\Name($constantName), null); $valueType = $constant->getValueType(); if (!$valueType instanceof ConstantIntegerType) { throw new ShouldNotHappenException(sprintf('Constant %s does not have integer type.', $constantName)); } return $valueType->getValue(); } private function determineExactType(Type $in, int $filterValue, Type $defaultType, ?Type $flagsType) : ?Type { if ($filterValue === $this->getConstant('FILTER_VALIDATE_BOOLEAN')) { if ($in->isBoolean()->yes()) { return $in; } if ($in->isNull()->yes()) { return $defaultType; } } if ($filterValue === $this->getConstant('FILTER_VALIDATE_FLOAT')) { if ($in->isFloat()->yes()) { return $in; } if ($in->isInteger()->yes()) { return $in->toFloat(); } if ($in->isTrue()->yes()) { return new ConstantFloatType(1); } if ($in->isFalse()->yes() || $in->isNull()->yes()) { return $defaultType; } } if ($filterValue === $this->getConstant('FILTER_VALIDATE_INT')) { if ($in->isInteger()->yes()) { return $in; } if ($in->isTrue()->yes()) { return new ConstantIntegerType(1); } if ($in->isFalse()->yes() || $in->isNull()->yes()) { return $defaultType; } if ($in instanceof ConstantFloatType) { return $in->getValue() - (int) $in->getValue() === 0.0 ? $in->toInteger() : $defaultType; } if ($in instanceof ConstantStringType) { $value = $in->getValue(); $allowOctal = $this->hasFlag($this->getConstant('FILTER_FLAG_ALLOW_OCTAL'), $flagsType); $allowHex = $this->hasFlag($this->getConstant('FILTER_FLAG_ALLOW_HEX'), $flagsType); if ($allowOctal && preg_match('/\\A0[oO][0-7]+\\z/', $value) === 1) { $octalValue = octdec($value); return is_int($octalValue) ? new ConstantIntegerType($octalValue) : $defaultType; } if ($allowHex && preg_match('/\\A0[xX][0-9A-Fa-f]+\\z/', $value) === 1) { $hexValue = hexdec($value); return is_int($hexValue) ? new ConstantIntegerType($hexValue) : $defaultType; } return preg_match('/\\A[+-]?(?:0|[1-9][0-9]*)\\z/', $value) === 1 ? $in->toInteger() : $defaultType; } } if ($filterValue === $this->getConstant('FILTER_DEFAULT')) { if (!$this->canStringBeSanitized($filterValue, $flagsType) && $in->isString()->yes()) { return $in; } if ($in->isBoolean()->yes() || $in->isFloat()->yes() || $in->isInteger()->yes() || $in->isNull()->yes()) { return $in->toString(); } } return null; } /** @param array $typeOptions */ private function applyRangeOptions(Type $type, array $typeOptions, Type $defaultType) : Type { if (!$type->isInteger()->yes()) { return $type; } $range = []; if (isset($typeOptions['min_range'])) { if ($typeOptions['min_range'] instanceof ConstantScalarType) { $range['min'] = (int) $typeOptions['min_range']->getValue(); } elseif ($typeOptions['min_range'] instanceof IntegerRangeType) { $range['min'] = $typeOptions['min_range']->getMin(); } else { $range['min'] = null; } } if (isset($typeOptions['max_range'])) { if ($typeOptions['max_range'] instanceof ConstantScalarType) { $range['max'] = (int) $typeOptions['max_range']->getValue(); } elseif ($typeOptions['max_range'] instanceof IntegerRangeType) { $range['max'] = $typeOptions['max_range']->getMax(); } else { $range['max'] = null; } } if (array_key_exists('min', $range) || array_key_exists('max', $range)) { $min = $range['min'] ?? null; $max = $range['max'] ?? null; $rangeType = IntegerRangeType::fromInterval($min, $max); $rangeTypeIsSuperType = $rangeType->isSuperTypeOf($type); if ($rangeTypeIsSuperType->no()) { // e.g. if 9 is filtered with a range of int<17, 19> return $defaultType; } if ($rangeTypeIsSuperType->yes() && !$rangeType->equals($type)) { // e.g. if 18 or int<18, 19> are filtered with a range of int<17, 19> return $type; } // Open ranges on either side means that the input is potentially not part of the range return $min === null || $max === null ? TypeCombinator::union($rangeType, $defaultType) : $rangeType; } return $type; } private function hasOptions(Type $flagsType) : TrinaryLogic { return $flagsType->isArray()->and($flagsType->hasOffsetValueType(new ConstantStringType('options'))); } /** @return array */ private function getOptions(Type $flagsType, int $filterValue) : array { $options = []; $optionsType = $flagsType->getOffsetValueType(new ConstantStringType('options')); if (!$optionsType->isConstantArray()->yes()) { return $options; } $optionNames = array_merge(['default'], $this->getFilterTypeOptions()[$filterValue] ?? []); foreach ($optionNames as $optionName) { $optionalNameType = new ConstantStringType($optionName); if (!$optionsType->hasOffsetValueType($optionalNameType)->yes()) { $options[$optionName] = null; continue; } $options[$optionName] = $optionsType->getOffsetValueType($optionalNameType); } return $options; } private function hasFlag(int $flag, ?Type $flagsType) : bool { if ($flagsType === null) { return \false; } $type = $this->getFlagsValue($flagsType); return $type instanceof ConstantIntegerType && ($type->getValue() & $flag) === $flag; } private function getFlagsValue(Type $exprType) : Type { if (!$exprType->isConstantArray()->yes()) { return $exprType; } return $exprType->getOffsetValueType($this->flagsString); } private function canStringBeSanitized(int $filterValue, ?Type $flagsType) : bool { // If it is a validation filter, the string will not be changed if (($filterValue & self::VALIDATION_FILTER_BITMASK) !== 0) { return \false; } // FILTER_DEFAULT will not sanitize, unless it has FILTER_FLAG_STRIP_LOW, // FILTER_FLAG_STRIP_HIGH, or FILTER_FLAG_STRIP_BACKTICK if ($filterValue === $this->getConstant('FILTER_DEFAULT')) { return $this->hasFlag($this->getConstant('FILTER_FLAG_STRIP_LOW'), $flagsType) || $this->hasFlag($this->getConstant('FILTER_FLAG_STRIP_HIGH'), $flagsType) || $this->hasFlag($this->getConstant('FILTER_FLAG_STRIP_BACKTICK'), $flagsType); } return \true; } } reflectionProvider = $reflectionProvider; } public function getType(Scope $scope, ?Expr $arrayArg, ?Expr $callbackArg, ?Expr $flagArg) : Type { if ($arrayArg === null) { return new ArrayType(new MixedType(), new MixedType()); } $arrayArgType = $scope->getType($arrayArg); $arrayArgType = TypeUtils::toBenevolentUnion($arrayArgType); $keyType = $arrayArgType->getIterableKeyType(); $itemType = $arrayArgType->getIterableValueType(); if ($itemType instanceof NeverType || $keyType instanceof NeverType) { return new ConstantArrayType([], []); } if ($arrayArgType instanceof MixedType) { return new BenevolentUnionType([new ArrayType(new MixedType(), new MixedType()), new NullType()]); } if ($callbackArg === null || $scope->getType($callbackArg)->isNull()->yes()) { return TypeCombinator::union(...array_map([$this, 'removeFalsey'], $arrayArgType->getArrays())); } $mode = $this->determineMode($flagArg, $scope); if ($mode === null) { return new ArrayType($keyType, $itemType); } if ($callbackArg instanceof Closure && count($callbackArg->stmts) === 1 && count($callbackArg->params) > 0) { $statement = $callbackArg->stmts[0]; if ($statement instanceof Return_ && $statement->expr !== null) { if ($mode === self::USE_ITEM) { $keyVar = null; $itemVar = $callbackArg->params[0]->var; } elseif ($mode === self::USE_KEY) { $keyVar = $callbackArg->params[0]->var; $itemVar = null; } elseif ($mode === self::USE_BOTH) { $keyVar = $callbackArg->params[1]->var ?? null; $itemVar = $callbackArg->params[0]->var; } return $this->filterByTruthyValue($scope, $itemVar, $arrayArgType, $keyVar, $statement->expr); } } elseif ($callbackArg instanceof ArrowFunction && count($callbackArg->params) > 0) { if ($mode === self::USE_ITEM) { $keyVar = null; $itemVar = $callbackArg->params[0]->var; } elseif ($mode === self::USE_KEY) { $keyVar = $callbackArg->params[0]->var; $itemVar = null; } elseif ($mode === self::USE_BOTH) { $keyVar = $callbackArg->params[1]->var ?? null; $itemVar = $callbackArg->params[0]->var; } return $this->filterByTruthyValue($scope, $itemVar, $arrayArgType, $keyVar, $callbackArg->expr); } elseif (($callbackArg instanceof FuncCall || $callbackArg instanceof MethodCall || $callbackArg instanceof StaticCall) && $callbackArg->isFirstClassCallable()) { [$args, $itemVar, $keyVar] = $this->createDummyArgs($mode); $expr = clone $callbackArg; $expr->args = $args; return $this->filterByTruthyValue($scope, $itemVar, $arrayArgType, $keyVar, $expr); } else { $constantStrings = $scope->getType($callbackArg)->getConstantStrings(); if (count($constantStrings) > 0) { $results = []; [$args, $itemVar, $keyVar] = $this->createDummyArgs($mode); foreach ($constantStrings as $constantString) { $funcName = self::createFunctionName($constantString->getValue()); if ($funcName === null) { $results[] = new ErrorType(); continue; } $expr = new FuncCall($funcName, $args); $results[] = $this->filterByTruthyValue($scope, $itemVar, $arrayArgType, $keyVar, $expr); } return TypeCombinator::union(...$results); } } return new ArrayType($keyType, $itemType); } private function removeFalsey(Type $type) : Type { $falseyTypes = StaticTypeFactory::falsey(); if (count($type->getConstantArrays()) > 0) { $result = []; foreach ($type->getConstantArrays() as $constantArray) { $keys = $constantArray->getKeyTypes(); $values = $constantArray->getValueTypes(); $builder = ConstantArrayTypeBuilder::createEmpty(); foreach ($values as $offset => $value) { $isFalsey = $falseyTypes->isSuperTypeOf($value); if ($isFalsey->maybe()) { $builder->setOffsetValueType($keys[$offset], TypeCombinator::remove($value, $falseyTypes), \true); } elseif ($isFalsey->no()) { $builder->setOffsetValueType($keys[$offset], $value, $constantArray->isOptionalKey($offset)); } } $result[] = $builder->getArray(); } return TypeCombinator::union(...$result); } $keyType = $type->getIterableKeyType(); $valueType = $type->getIterableValueType(); $valueType = TypeCombinator::remove($valueType, $falseyTypes); if ($valueType instanceof NeverType) { return new ConstantArrayType([], []); } return new ArrayType($keyType, $valueType); } /** * @param Error|Variable|null $itemVar * @param Error|Variable|null $keyVar */ private function filterByTruthyValue(Scope $scope, $itemVar, Type $arrayType, $keyVar, Expr $expr) : Type { if (!$scope instanceof MutatingScope) { throw new ShouldNotHappenException(); } $constantArrays = $arrayType->getConstantArrays(); if (count($constantArrays) > 0) { $results = []; foreach ($constantArrays as $constantArray) { $builder = ConstantArrayTypeBuilder::createEmpty(); $optionalKeys = $constantArray->getOptionalKeys(); foreach ($constantArray->getKeyTypes() as $i => $keyType) { $itemType = $constantArray->getValueTypes()[$i]; [$newKeyType, $newItemType, $optional] = $this->processKeyAndItemType($scope, $keyType, $itemType, $itemVar, $keyVar, $expr); $optional = $optional || in_array($i, $optionalKeys, \true); if ($newKeyType instanceof NeverType || $newItemType instanceof NeverType) { continue; } if ($itemType->equals($newItemType) && $keyType->equals($newKeyType)) { $builder->setOffsetValueType($keyType, $itemType, $optional); continue; } $builder->setOffsetValueType($newKeyType, $newItemType, \true); } $results[] = $builder->getArray(); } return TypeCombinator::union(...$results); } [$newKeyType, $newItemType] = $this->processKeyAndItemType($scope, $arrayType->getIterableKeyType(), $arrayType->getIterableValueType(), $itemVar, $keyVar, $expr); if ($newItemType instanceof NeverType || $newKeyType instanceof NeverType) { return new ConstantArrayType([], []); } return new ArrayType($newKeyType, $newItemType); } /** * @return array{Type, Type, bool} * @param Error|Variable|null $itemVar * @param Error|Variable|null $keyVar */ private function processKeyAndItemType(MutatingScope $scope, Type $keyType, Type $itemType, $itemVar, $keyVar, Expr $expr) : array { $itemVarName = null; if ($itemVar !== null) { if (!$itemVar instanceof Variable || !is_string($itemVar->name)) { throw new ShouldNotHappenException(); } $itemVarName = $itemVar->name; $scope = $scope->assignVariable($itemVarName, $itemType, new MixedType()); } $keyVarName = null; if ($keyVar !== null) { if (!$keyVar instanceof Variable || !is_string($keyVar->name)) { throw new ShouldNotHappenException(); } $keyVarName = $keyVar->name; $scope = $scope->assignVariable($keyVarName, $keyType, new MixedType()); } $booleanResult = $scope->getType($expr)->toBoolean(); if ($booleanResult->isFalse()->yes()) { return [new NeverType(), new NeverType(), \false]; } $scope = $scope->filterByTruthyValue($expr); return [$keyVarName !== null ? $scope->getVariableType($keyVarName) : $keyType, $itemVarName !== null ? $scope->getVariableType($itemVarName) : $itemType, !$booleanResult->isTrue()->yes()]; } private static function createFunctionName(string $funcName) : ?Name { if ($funcName === '') { return null; } if ($funcName[0] === '\\') { $funcName = substr($funcName, 1); if ($funcName === '') { return null; } return new Name\FullyQualified($funcName); } return new Name($funcName); } /** * @param self::USE_* $mode * @return array{list, ?Variable, ?Variable} */ private function createDummyArgs(int $mode) : array { if ($mode === self::USE_ITEM) { $itemVar = new Variable('item'); $keyVar = null; $args = [new Arg($itemVar)]; } elseif ($mode === self::USE_KEY) { $itemVar = null; $keyVar = new Variable('key'); $args = [new Arg($keyVar)]; } elseif ($mode === self::USE_BOTH) { $itemVar = new Variable('item'); $keyVar = new Variable('key'); $args = [new Arg($itemVar), new Arg($keyVar)]; } return [$args, $itemVar, $keyVar]; } /** * @param non-empty-string $constantName */ private function getConstant(string $constantName) : int { $constant = $this->reflectionProvider->getConstant(new Name($constantName), null); $valueType = $constant->getValueType(); if (!$valueType instanceof ConstantIntegerType) { throw new ShouldNotHappenException(sprintf('Constant %s does not have integer type.', $constantName)); } return $valueType->getValue(); } /** * @return self::USE_*|null */ private function determineMode(?Expr $flagArg, Scope $scope) : ?int { if ($flagArg === null) { return self::USE_ITEM; } $flagValues = $scope->getType($flagArg)->getConstantScalarValues(); if (count($flagValues) !== 1) { return null; } if ($flagValues[0] === $this->getConstant('ARRAY_FILTER_USE_KEY')) { return self::USE_KEY; } elseif ($flagValues[0] === $this->getConstant('ARRAY_FILTER_USE_BOTH')) { return self::USE_BOTH; } return null; } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'mb_strlen'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) === 0) { return null; } $encodings = []; if (count($functionCall->getArgs()) === 1) { // there is a chance to get an unsupported encoding 'pass' or 'none' here on PHP 7.3-7.4 $encodings = [mb_internal_encoding()]; } elseif (count($functionCall->getArgs()) === 2) { // custom encoding is specified $encodings = array_map(static function (ConstantStringType $t) { return $t->getValue(); }, $scope->getType($functionCall->getArgs()[1]->value)->getConstantStrings()); } if (count($encodings) > 0) { for ($i = 0; $i < count($encodings); $i++) { if ($this->isSupportedEncoding($encodings[$i])) { continue; } $encodings[$i] = self::UNSUPPORTED_ENCODING; } $encodings = array_unique($encodings); if (in_array(self::UNSUPPORTED_ENCODING, $encodings, \true) && count($encodings) === 1) { if ($this->phpVersion->throwsOnInvalidMbStringEncoding()) { return new NeverType(); } return new ConstantBooleanType(\false); } } else { // if there aren't encoding constants, use all available encodings $encodings = array_merge($this->getSupportedEncodings(), [self::UNSUPPORTED_ENCODING]); } $argType = $scope->getType($args[0]->value); if ($argType->isSuperTypeOf(new BooleanType())->yes()) { $constantScalars = TypeCombinator::remove($argType, new BooleanType())->getConstantScalarTypes(); if (count($constantScalars) > 0) { $constantScalars[] = new ConstantBooleanType(\true); $constantScalars[] = new ConstantBooleanType(\false); } } else { $constantScalars = $argType->getConstantScalarTypes(); } $lengths = []; foreach ($constantScalars as $constantScalar) { $stringScalar = $constantScalar->toString(); if (!$stringScalar instanceof ConstantStringType) { $lengths = []; break; } foreach ($encodings as $encoding) { if (!$this->isSupportedEncoding($encoding)) { continue; } $length = @mb_strlen($stringScalar->getValue(), $encoding); if ($length === \false) { throw new ShouldNotHappenException(sprintf('Got false on a supported encoding %s and value %s', $encoding, var_export($stringScalar->getValue(), \true))); } $lengths[] = $length; } } $isNonEmpty = $argType->isNonEmptyString(); $numeric = TypeCombinator::union(new IntegerType(), new FloatType()); if (count($lengths) > 0) { $lengths = array_unique($lengths); sort($lengths); if ($lengths === range(min($lengths), max($lengths))) { $range = IntegerRangeType::fromInterval(min($lengths), max($lengths)); } else { $range = TypeCombinator::union(...array_map(static function ($l) { return new ConstantIntegerType($l); }, $lengths)); } } elseif ($argType->isBoolean()->yes()) { $range = IntegerRangeType::fromInterval(0, 1); } elseif ($isNonEmpty->yes() || $numeric->isSuperTypeOf($argType)->yes() || TypeCombinator::remove($argType, $numeric)->isNonEmptyString()->yes()) { $range = IntegerRangeType::fromInterval(1, null); } elseif ($argType->isString()->yes() && $isNonEmpty->no()) { $range = new ConstantIntegerType(0); } else { $range = TypeCombinator::remove(ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->getArgs(), $functionReflection->getVariants())->getReturnType(), new ConstantBooleanType(\false)); } if (!$this->phpVersion->throwsOnInvalidMbStringEncoding() && in_array(self::UNSUPPORTED_ENCODING, $encodings, \true)) { return TypeCombinator::union($range, new ConstantBooleanType(\false)); } return $range; } } propertyReflectionFinder = $propertyReflectionFinder; } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool { return $functionReflection->getName() === 'property_exists' && $context->true() && count($node->getArgs()) >= 2; } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { $propertyNameType = $scope->getType($node->getArgs()[1]->value); if (!$propertyNameType instanceof ConstantStringType) { return new SpecifiedTypes([], []); } $objectType = $scope->getType($node->getArgs()[0]->value); if ($objectType instanceof ConstantStringType) { return new SpecifiedTypes([], []); } elseif ($objectType->isObject()->yes()) { $propertyNode = new PropertyFetch($node->getArgs()[0]->value, new Identifier($propertyNameType->getValue())); } else { return new SpecifiedTypes([], []); } $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($propertyNode, $scope); if ($propertyReflection !== null) { if (!$propertyReflection->isNative()) { return new SpecifiedTypes([], []); } } return $this->typeSpecifier->create($node->getArgs()[0]->value, new IntersectionType([new ObjectWithoutClassType(), new HasPropertyType($propertyNameType->getValue())]), $context, \false, $scope); } } getName() === 'microtime'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { if (count($functionCall->getArgs()) < 1) { return new StringType(); } $argType = $scope->getType($functionCall->getArgs()[0]->value); $isTrueType = $argType->isTrue(); $isFalseType = $argType->isFalse(); $compareTypes = $isTrueType->compareTo($isFalseType); if ($compareTypes === $isTrueType) { return new FloatType(); } if ($compareTypes === $isFalseType) { return new StringType(); } if ($argType instanceof MixedType) { return new BenevolentUnionType([new StringType(), new FloatType()]); } return new UnionType([new StringType(), new FloatType()]); } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'array_flip'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) !== 1) { return null; } $arrayType = $scope->getType($functionCall->getArgs()[0]->value); if ($arrayType->isArray()->no()) { return $this->phpVersion->arrayFunctionsReturnNullWithNonArray() ? new NullType() : new NeverType(); } return $arrayType->flipArray(); } } getName() === 'abs'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (!isset($args[0])) { return null; } $inputType = $scope->getType($args[0]->value); $outputType = $inputType->toAbsoluteNumber(); if ($outputType instanceof ErrorType) { return null; } return $outputType; } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return in_array($functionReflection->getName(), ['min', 'max'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } if (count($functionCall->getArgs()) === 1) { $argType = $scope->getType($functionCall->getArgs()[0]->value); if ($argType->isArray()->yes()) { return $this->processArrayType($functionReflection->getName(), $argType); } return new ErrorType(); } // rewrite min($x, $y) as $x < $y ? $x : $y // we don't handle arrays, which have different semantics $functionName = $functionReflection->getName(); $args = $functionCall->getArgs(); if (count($functionCall->getArgs()) === 2) { $argType0 = $scope->getType($args[0]->value); $argType1 = $scope->getType($args[1]->value); if ($argType0->isArray()->no() && $argType1->isArray()->no()) { if ($functionName === 'min') { return $scope->getType(new Ternary(new Smaller($args[0]->value, $args[1]->value), $args[0]->value, $args[1]->value)); } elseif ($functionName === 'max') { return $scope->getType(new Ternary(new Smaller($args[0]->value, $args[1]->value), $args[1]->value, $args[0]->value)); } } } $argumentTypes = []; foreach ($functionCall->getArgs() as $arg) { $argType = $scope->getType($arg->value); if ($arg->unpack) { $iterableValueType = $argType->getIterableValueType(); if ($iterableValueType instanceof UnionType) { foreach ($iterableValueType->getTypes() as $innerType) { $argumentTypes[] = $innerType; } } else { $argumentTypes[] = $iterableValueType; } continue; } $argumentTypes[] = $argType; } return $this->processType($functionName, $argumentTypes); } private function processArrayType(string $functionName, Type $argType) : Type { $constArrayTypes = $argType->getConstantArrays(); if (count($constArrayTypes) > 0) { $resultTypes = []; foreach ($constArrayTypes as $constArrayType) { $isIterable = $constArrayType->isIterableAtLeastOnce(); if ($isIterable->no() && !$this->phpVersion->throwsValueErrorForInternalFunctions()) { $resultTypes[] = new ConstantBooleanType(\false); continue; } $argumentTypes = []; if (!$isIterable->yes() && !$this->phpVersion->throwsValueErrorForInternalFunctions()) { $argumentTypes[] = new ConstantBooleanType(\false); } foreach ($constArrayType->getValueTypes() as $innerType) { $argumentTypes[] = $innerType; } $resultTypes[] = $this->processType($functionName, $argumentTypes); } return TypeCombinator::union(...$resultTypes); } $isIterable = $argType->isIterableAtLeastOnce(); if ($isIterable->no() && !$this->phpVersion->throwsValueErrorForInternalFunctions()) { return new ConstantBooleanType(\false); } $iterableValueType = $argType->getIterableValueType(); $argumentTypes = []; if (!$isIterable->yes() && !$this->phpVersion->throwsValueErrorForInternalFunctions()) { $argumentTypes[] = new ConstantBooleanType(\false); } $argumentTypes[] = $iterableValueType; return $this->processType($functionName, $argumentTypes); } /** * @param Type[] $types */ private function processType(string $functionName, array $types) : Type { $resultType = null; foreach ($types as $type) { if ($resultType === null) { $resultType = $type; continue; } $compareResult = $this->compareTypes($resultType, $type); if ($compareResult === null) { return TypeCombinator::union(...$types); } if ($functionName === 'min') { if ($compareResult === $type) { $resultType = $type; } } elseif ($functionName === 'max') { if ($compareResult === $resultType) { $resultType = $type; } } } if ($resultType === null) { return new ErrorType(); } return $resultType; } private function compareTypes(Type $firstType, Type $secondType) : ?Type { if ($firstType->isArray()->yes() && $secondType->isConstantScalarValue()->yes()) { return $secondType; } if ($firstType->isConstantScalarValue()->yes() && $secondType->isArray()->yes()) { return $firstType; } if ($firstType instanceof ConstantArrayType && $secondType instanceof ConstantArrayType) { if ($secondType->getArraySize() < $firstType->getArraySize()) { return $secondType; } elseif ($firstType->getArraySize() < $secondType->getArraySize()) { return $firstType; } foreach ($firstType->getValueTypes() as $i => $firstValueType) { $secondValueType = $secondType->getValueTypes()[$i]; $compareResult = $this->compareTypes($firstValueType, $secondValueType); if ($compareResult === $firstValueType) { return $firstType; } if ($compareResult === $secondValueType) { return $secondType; } } return null; } if ($firstType instanceof ConstantScalarType && $secondType instanceof ConstantScalarType) { if ($secondType->getValue() < $firstType->getValue()) { return $secondType; } if ($firstType->getValue() < $secondType->getValue()) { return $firstType; } } return null; } } getName() === 'xpath'; } public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : ?Type { if (!isset($methodCall->getArgs()[0])) { return null; } $argType = $scope->getType($methodCall->getArgs()[0]->value); $xmlElement = new SimpleXMLElement(''); foreach ($argType->getConstantStrings() as $constantString) { $result = @$xmlElement->xpath($constantString->getValue()); if ($result === \false) { // We can't be sure since it's maybe a namespaced xpath return null; } $argType = TypeCombinator::remove($argType, $constantString); } if (!$argType instanceof NeverType) { return null; } return new ArrayType(new MixedType(), $scope->getType($methodCall->var)); } } isAFunctionTypeSpecifyingHelper = $isAFunctionTypeSpecifyingHelper; } public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool { return strtolower($functionReflection->getName()) === 'is_a' && !$context->null(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { if (count($node->getArgs()) < 2) { return new SpecifiedTypes(); } $classType = $scope->getType($node->getArgs()[1]->value); if (!$classType instanceof ConstantStringType && !$context->true()) { return new SpecifiedTypes([], []); } $objectOrClassType = $scope->getType($node->getArgs()[0]->value); $allowStringType = isset($node->getArgs()[2]) ? $scope->getType($node->getArgs()[2]->value) : new ConstantBooleanType(\false); $allowString = !$allowStringType->equals(new ConstantBooleanType(\false)); $resultType = $this->isAFunctionTypeSpecifyingHelper->determineType($objectOrClassType, $classType, $allowString, \true); // prevent false-positives in IsAFunctionTypeSpecifyingHelper if ($classType->getConstantStrings() === [] && $resultType->isSuperTypeOf($objectOrClassType)->yes()) { return new SpecifiedTypes([], []); } return $this->typeSpecifier->create($node->getArgs()[0]->value, $resultType, $context, \false, $scope); } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } } typeSpecifier = $typeSpecifier; } public function getClass() : string { return ReflectionClass::class; } public function isMethodSupported(MethodReflection $methodReflection, MethodCall $node, TypeSpecifierContext $context) : bool { return $methodReflection->getName() === 'isSubclassOf' && isset($node->getArgs()[0]) && $context->true(); } public function specifyTypes(MethodReflection $methodReflection, MethodCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { $valueType = $scope->getType($node->getArgs()[0]->value); if (!$valueType instanceof ConstantStringType) { return new SpecifiedTypes([], []); } return $this->typeSpecifier->create($node->var, new GenericObjectType(ReflectionClass::class, [new ObjectType($valueType->getValue())]), $context, \false, $scope); } } getName() === 'array_sum'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $argType = $scope->getType($functionCall->getArgs()[0]->value); $resultTypes = []; if (count($argType->getConstantArrays()) > 0) { foreach ($argType->getConstantArrays() as $constantArray) { $node = new LNumber(0); foreach ($constantArray->getValueTypes() as $i => $type) { if ($constantArray->isOptionalKey($i)) { $node = new Plus($node, new TypeExpr(TypeCombinator::union($type, new ConstantIntegerType(0)))); } else { $node = new Plus($node, new TypeExpr($type)); } } $resultTypes[] = $scope->getType($node); } } else { $itemType = $argType->getIterableValueType(); $mulNode = new Mul(new TypeExpr($itemType), new TypeExpr(IntegerRangeType::fromInterval(0, null))); $resultTypes[] = $scope->getType(new Plus(new TypeExpr($itemType), $mulNode)); } if (!$argType->isIterableAtLeastOnce()->yes()) { $resultTypes[] = new ConstantIntegerType(0); } return TypeCombinator::union(...$resultTypes)->toNumber(); } } null() && count($node->getArgs()) >= 1 && in_array($functionReflection->getName(), ['sizeof', 'count'], \true); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { if (!$scope->getType($node->getArgs()[0]->value)->isArray()->yes()) { return new SpecifiedTypes([], []); } return $this->typeSpecifier->create($node->getArgs()[0]->value, new NonEmptyArrayType(), $context, \false, $scope); } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } } 1, 'mb_regex_encoding' => 1, 'mb_internal_encoding' => 1, 'mb_encoding_aliases' => 1, 'mb_chr' => 2, 'mb_ord' => 2]; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return array_key_exists($functionReflection->getName(), $this->encodingPositionMap); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $returnType = ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->getArgs(), $functionReflection->getVariants())->getReturnType(); $positionEncodingParam = $this->encodingPositionMap[$functionReflection->getName()]; if (count($functionCall->getArgs()) < $positionEncodingParam) { return TypeCombinator::remove($returnType, new BooleanType()); } $strings = $scope->getType($functionCall->getArgs()[$positionEncodingParam - 1]->value)->getConstantStrings(); $results = array_unique(array_map(function (ConstantStringType $encoding) : bool { return $this->isSupportedEncoding($encoding->getValue()); }, $strings)); if ($returnType->equals(new UnionType([new StringType(), new BooleanType()]))) { return count($results) === 1 ? new ConstantBooleanType($results[0]) : new BooleanType(); } if (count($results) === 1) { $invalidEncodingReturn = new ConstantBooleanType(\false); if ($this->phpVersion->throwsOnInvalidMbStringEncoding()) { $invalidEncodingReturn = new NeverType(); } return $results[0] ? TypeCombinator::remove($returnType, new ConstantBooleanType(\false)) : $invalidEncodingReturn; } return $returnType; } } dateFunctionReturnTypeHelper = $dateFunctionReturnTypeHelper; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'date'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) === 0) { return null; } return $this->dateFunctionReturnTypeHelper->getTypeFromFormatType($scope->getType($functionCall->getArgs()[0]->value), \false); } } minimum arity] */ private const FUNCTIONS = ['strtoupper' => 1, 'strtolower' => 1, 'mb_strtoupper' => 1, 'mb_strtolower' => 1, 'lcfirst' => 1, 'ucfirst' => 1, 'mb_lcfirst' => 1, 'mb_ucfirst' => 1, 'ucwords' => 1, 'mb_convert_case' => 2, 'mb_convert_kana' => 1]; public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return isset(self::FUNCTIONS[$functionReflection->getName()]); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $fnName = $functionReflection->getName(); $args = $functionCall->getArgs(); if (count($args) < self::FUNCTIONS[$fnName]) { return null; } $argType = $scope->getType($args[0]->value); if (!is_callable($fnName)) { return null; } $modes = []; $keepLowercase = \false; $forceLowercase = \false; $keepUppercase = \false; $forceUppercase = \false; if ($fnName === 'mb_convert_case') { $modeType = $scope->getType($args[1]->value); $modes = array_map(static function ($mode) { return $mode->getValue(); }, TypeUtils::getConstantIntegers($modeType)); if (count($modes) > 0) { $forceLowercase = count(array_diff($modes, [MB_CASE_LOWER, 5])) === 0; $keepLowercase = count(array_diff($modes, [ MB_CASE_LOWER, 5, // MB_CASE_LOWER_SIMPLE 3, // MB_CASE_FOLD, 7, ])) === 0; $forceUppercase = count(array_diff($modes, [MB_CASE_UPPER, 4])) === 0; $keepUppercase = count(array_diff($modes, [ MB_CASE_UPPER, 4, // MB_CASE_UPPER_SIMPLE 3, // MB_CASE_FOLD, 7, ])) === 0; } } elseif (in_array($fnName, ['ucwords', 'mb_convert_kana'], \true)) { if (count($args) >= 2) { $modeType = $scope->getType($args[1]->value); $modes = array_map(static function ($mode) { return $mode->getValue(); }, $modeType->getConstantStrings()); } else { $modes = $fnName === 'mb_convert_kana' ? ['KV'] : [" \t\r\n\f\v"]; } } elseif (in_array($fnName, ['strtolower', 'mb_strtolower'], \true)) { $forceLowercase = \true; } elseif (in_array($fnName, ['lcfirst', 'mb_lcfirst'], \true)) { $keepLowercase = \true; } elseif (in_array($fnName, ['strtoupper', 'mb_strtoupper'], \true)) { $forceUppercase = \true; } elseif (in_array($fnName, ['ucfirst', 'mb_ucfirst'], \true)) { $keepUppercase = \true; } $constantStrings = array_map(static function ($type) { return $type->getValue(); }, $argType->getConstantStrings()); if (count($constantStrings) > 0 && mb_check_encoding($constantStrings, 'UTF-8')) { $strings = []; $parameters = []; if (in_array($fnName, ['ucwords', 'mb_convert_case', 'mb_convert_kana'], \true)) { foreach ($modes as $mode) { foreach ($constantStrings as $constantString) { $parameters[] = [$constantString, $mode]; } } } else { $parameters = array_map(static function ($s) { return [$s]; }, $constantStrings); } foreach ($parameters as $parameter) { $strings[] = $fnName(...$parameter); } if (count($strings) !== 0 && mb_check_encoding($strings, 'UTF-8')) { return TypeCombinator::union(...array_map(static function ($s) { return new ConstantStringType($s); }, $strings)); } } $accessoryTypes = []; $argStringType = $argType->toString(); if ($forceLowercase || $keepLowercase && $argStringType->isLowercaseString()->yes()) { $accessoryTypes[] = new AccessoryLowercaseStringType(); } if ($forceUppercase || $keepUppercase && $argStringType->isUppercaseString()->yes()) { $accessoryTypes[] = new AccessoryUppercaseStringType(); } if ($argStringType->isNumericString()->yes()) { $accessoryTypes[] = new AccessoryNumericStringType(); } elseif ($argStringType->isNonFalsyString()->yes()) { $accessoryTypes[] = new AccessoryNonFalsyStringType(); } elseif ($argStringType->isNonEmptyString()->yes()) { $accessoryTypes[] = new AccessoryNonEmptyStringType(); } if (count($accessoryTypes) > 0) { $accessoryTypes[] = new StringType(); return new IntersectionType($accessoryTypes); } return new StringType(); } } reflectionProvider = $reflectionProvider; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->universalObjectCratesClasses = $universalObjectCratesClasses; $this->nullContextForVoidReturningFunctions = $nullContextForVoidReturningFunctions; } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return in_array($functionReflection->getName(), ['array_key_exists', 'key_exists', 'in_array', 'is_subclass_of'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) === 0) { return null; } $isAlways = $this->getHelper()->findSpecifiedType($scope, $functionCall); if ($isAlways === null) { return null; } return new ConstantBooleanType($isAlways); } private function getHelper() : ImpossibleCheckTypeHelper { if ($this->helper === null) { $this->helper = new ImpossibleCheckTypeHelper($this->reflectionProvider, $this->typeSpecifier, $this->universalObjectCratesClasses, $this->treatPhpDocTypesAsCertain, $this->nullContextForVoidReturningFunctions); } return $this->helper; } } getName(), ['class_exists', 'interface_exists', 'trait_exists', 'enum_exists'], \true) && isset($node->getArgs()[0]) && $context->true(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { $argType = $scope->getType($node->getArgs()[0]->value); if ($argType instanceof ConstantStringType) { return $this->typeSpecifier->create(new FuncCall(new FullyQualified('class_exists'), [new Arg(new String_(ltrim($argType->getValue(), '\\')))]), new ConstantBooleanType(\true), $context, \false, $scope); } $narrowedType = new ClassStringType(); if ($functionReflection->getName() === 'enum_exists') { $narrowedType = new GenericClassStringType(new ObjectType('UnitEnum')); } return $this->typeSpecifier->create($node->getArgs()[0]->value, $narrowedType, $context, \false, $scope); } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } } getName()) === 'array_replace'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (!isset($args[0])) { return null; } $argTypes = []; $optionalArgTypes = []; foreach ($args as $arg) { $argType = $scope->getType($arg->value); if ($arg->unpack) { if ($argType->isConstantArray()->yes()) { foreach ($argType->getConstantArrays() as $constantArray) { foreach ($constantArray->getValueTypes() as $valueType) { $argTypes[] = $valueType; } } } else { $argTypes[] = $argType->getIterableValueType(); } if (!$argType->isIterableAtLeastOnce()->yes()) { // unpacked params can be empty, making them optional $optionalArgTypesOffset = count($argTypes) - 1; foreach (array_keys($argTypes) as $key) { $optionalArgTypes[] = $optionalArgTypesOffset + $key; } } } else { $argTypes[] = $argType; } } $allConstant = TrinaryLogic::createYes()->lazyAnd($argTypes, static function (Type $argType) { return $argType->isConstantArray(); }); if ($allConstant->yes()) { $newArrayBuilder = ConstantArrayTypeBuilder::createEmpty(); foreach ($argTypes as $argType) { /** @var array $keyTypes */ $keyTypes = []; foreach ($argType->getConstantArrays() as $constantArray) { foreach ($constantArray->getKeyTypes() as $keyType) { $keyTypes[$keyType->getValue()] = $keyType; } } foreach ($keyTypes as $keyType) { $newArrayBuilder->setOffsetValueType($keyType, $argType->getOffsetValueType($keyType), !$argType->hasOffsetValueType($keyType)->yes()); } } return $newArrayBuilder->getArray(); } $keyTypes = []; $valueTypes = []; $nonEmpty = \false; $isList = \true; foreach ($argTypes as $key => $argType) { $keyType = $argType->getIterableKeyType(); $keyTypes[] = $keyType; $valueTypes[] = $argType->getIterableValueType(); if (!$argType->isList()->yes()) { $isList = \false; } if (in_array($key, $optionalArgTypes, \true) || !$argType->isIterableAtLeastOnce()->yes()) { continue; } $nonEmpty = \true; } $keyType = TypeCombinator::union(...$keyTypes); if ($keyType instanceof NeverType) { return new ConstantArrayType([], []); } $arrayType = new ArrayType($keyType, TypeCombinator::union(...$valueTypes)); if ($nonEmpty) { $arrayType = TypeCombinator::intersect($arrayType, new NonEmptyArrayType()); } if ($isList) { $arrayType = TypeCombinator::intersect($arrayType, new AccessoryArrayListType()); } return $arrayType; } } getName()) === 'ctype_digit' && !$context->null(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { if (!isset($node->getArgs()[0])) { return new SpecifiedTypes(); } if ($context->null()) { throw new ShouldNotHappenException(); } $exprArg = $node->getArgs()[0]->value; if ($context->true() && $scope->getType($exprArg)->isNumericString()->yes()) { return new SpecifiedTypes(); } $types = [ IntegerRangeType::fromInterval(48, 57), // ASCII-codes for 0-9 IntegerRangeType::createAllGreaterThanOrEqualTo(256), ]; if ($context->true()) { $types[] = new IntersectionType([new StringType(), new AccessoryNumericStringType()]); } $unionType = TypeCombinator::union(...$types); $specifiedTypes = $this->typeSpecifier->create($exprArg, $unionType, $context, \false, $scope); if ($exprArg instanceof Cast\String_) { $castedType = new UnionType([IntegerRangeType::fromInterval(0, null), new IntersectionType([new StringType(), new AccessoryNumericStringType()]), new ConstantBooleanType(\true)]); $specifiedTypes = $specifiedTypes->unionWith($this->typeSpecifier->create($exprArg->expr, $castedType, $context, \false, $scope)); } return $specifiedTypes; } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } } getSupportedEncodings(), \true); } /** @return string[] */ private function getSupportedEncodings() : array { if (!is_null($this->supportedEncodings)) { return $this->supportedEncodings; } $supportedEncodings = []; if (function_exists('mb_list_encodings')) { foreach (mb_list_encodings() as $encoding) { $aliases = @mb_encoding_aliases($encoding); if ($aliases === \false) { throw new ShouldNotHappenException(); } $supportedEncodings = array_merge($supportedEncodings, $aliases, [$encoding]); } } $this->supportedEncodings = array_map('strtoupper', $supportedEncodings); // PHP 7.3 and 7.4 claims 'pass' and its alias 'none' to be supported, but actually 'pass' was removed in 7.3 if (!$this->phpVersion->supportsPassNoneEncodings()) { $this->supportedEncodings = array_filter($this->supportedEncodings, static function (string $enc) { return !in_array($enc, ['PASS', 'NONE'], \true); }); } return $this->supportedEncodings; } } getName() === 'number_format'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $stringType = new StringType(); if (!isset($functionCall->getArgs()[3])) { return $stringType; } $thousandsType = $scope->getType($functionCall->getArgs()[3]->value); $decimalType = $scope->getType($functionCall->getArgs()[2]->value); if (!$thousandsType instanceof ConstantStringType || $thousandsType->getValue() !== '') { return $stringType; } if (!$decimalType instanceof ConstantScalarType || !in_array($decimalType->getValue(), [null, '.', ''], \true)) { return $stringType; } return new IntersectionType([$stringType, new AccessoryNumericStringType()]); } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return in_array($functionReflection->getName(), ['str_split', 'mb_str_split'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 1) { return null; } if (count($functionCall->getArgs()) >= 2) { $splitLengthType = $scope->getType($functionCall->getArgs()[1]->value); if ($splitLengthType instanceof ConstantIntegerType) { $splitLength = $splitLengthType->getValue(); if ($splitLength < 1) { return new ConstantBooleanType(\false); } } } else { $splitLength = 1; } $encoding = null; if ($functionReflection->getName() === 'mb_str_split') { if (count($functionCall->getArgs()) >= 3) { $strings = $scope->getType($functionCall->getArgs()[2]->value)->getConstantStrings(); $values = array_unique(array_map(static function (ConstantStringType $encoding) : string { return $encoding->getValue(); }, $strings)); if (count($values) !== 1) { return null; } $encoding = $values[0]; if (!$this->isSupportedEncoding($encoding)) { return new ConstantBooleanType(\false); } } else { $encoding = mb_internal_encoding(); } } if (!isset($splitLength)) { return null; } $stringType = $scope->getType($functionCall->getArgs()[0]->value); $constantStrings = $stringType->getConstantStrings(); if (count($constantStrings) > 0) { $results = []; foreach ($constantStrings as $constantString) { $items = $encoding === null ? str_split($constantString->getValue(), $splitLength) : @mb_str_split($constantString->getValue(), $splitLength, $encoding); if ($items === \false) { throw new ShouldNotHappenException(); } $results[] = self::createConstantArrayFrom($items, $scope); } return TypeCombinator::union(...$results); } $returnType = AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new StringType())); return $encoding === null && !$this->phpVersion->strSplitReturnsEmptyArray() ? TypeCombinator::intersect($returnType, new NonEmptyArrayType()) : $returnType; } /** * @param string[] $constantArray */ private static function createConstantArrayFrom(array $constantArray, Scope $scope) : ConstantArrayType { $keyTypes = []; $valueTypes = []; $isList = \true; $i = 0; foreach ($constantArray as $key => $value) { $keyType = $scope->getTypeFromValue($key); if (!$keyType instanceof ConstantIntegerType) { throw new ShouldNotHappenException(); } $keyTypes[] = $keyType; $valueTypes[] = $scope->getTypeFromValue($value); $isList = $isList && $key === $i; $i++; } return new ConstantArrayType($keyTypes, $valueTypes, $isList ? [$i] : [0], [], TrinaryLogic::createFromBoolean(array_is_list($constantArray))); } } dateFunctionReturnTypeHelper = $dateFunctionReturnTypeHelper; } public function getClass() : string { return DateTimeInterface::class; } public function isMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getName() === 'format'; } public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : Type { if (count($methodCall->getArgs()) === 0) { return new StringType(); } return $this->dateFunctionReturnTypeHelper->getTypeFromFormatType($scope->getType($methodCall->getArgs()[0]->value), \true); } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'array_fill_keys'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 2) { return null; } $keysType = $scope->getType($functionCall->getArgs()[0]->value); if ($keysType->isArray()->no()) { return $this->phpVersion->arrayFunctionsReturnNullWithNonArray() ? new NullType() : new NeverType(); } return $keysType->fillKeysArray($scope->getType($functionCall->getArgs()[1]->value)); } } getDeclaringClass()->getName() === 'Ds\\Map' && ($methodReflection->getName() === 'get' || $methodReflection->getName() === 'remove'); } public function getThrowTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->args) < 2) { return $methodReflection->getThrowType(); } return new VoidType(); } } getName() === 'asXML'; } public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : Type { if (count($methodCall->getArgs()) === 1) { return new BooleanType(); } return new UnionType([new StringType(), new ConstantBooleanType(\false)]); } } getName(), ['from', 'tryFrom'], \true); } public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope) : ?Type { if (!$methodReflection->getDeclaringClass()->isBackedEnum()) { return null; } $arguments = $methodCall->getArgs(); if (count($arguments) < 1) { return null; } $valueType = $scope->getType($arguments[0]->value); $enumCases = $methodReflection->getDeclaringClass()->getEnumCases(); if (count($enumCases) === 0) { if ($methodReflection->getName() === 'tryFrom') { return new NullType(); } return null; } if (count($valueType->getConstantScalarValues()) === 0) { return null; } $resultEnumCases = []; $addNull = \false; foreach ($valueType->getConstantScalarValues() as $value) { $hasMatching = \false; foreach ($enumCases as $enumCase) { if ($enumCase->getBackingValueType() === null) { continue; } $enumCaseValues = $enumCase->getBackingValueType()->getConstantScalarValues(); if (count($enumCaseValues) !== 1) { continue; } if ($value === $enumCaseValues[0]) { $resultEnumCases[] = new EnumCaseObjectType($enumCase->getDeclaringEnum()->getName(), $enumCase->getName(), $enumCase->getDeclaringEnum()); $hasMatching = \true; break; } } if ($hasMatching) { continue; } $addNull = \true; } if (count($resultEnumCases) === 0) { if ($methodReflection->getName() === 'tryFrom') { return new NullType(); } return null; } $result = TypeCombinator::union(...$resultEnumCases); if ($addNull && $methodReflection->getName() === 'tryFrom') { return TypeCombinator::addNull($result); } return $result; } } getName() === 'array_rand'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $argsCount = count($functionCall->getArgs()); if ($argsCount < 1) { return null; } $firstArgType = $scope->getType($functionCall->getArgs()[0]->value); $isInteger = $firstArgType->getIterableKeyType()->isInteger(); $isString = $firstArgType->getIterableKeyType()->isString(); if ($isInteger->yes()) { $valueType = new IntegerType(); } elseif ($isString->yes()) { $valueType = new StringType(); } else { $valueType = new UnionType([new IntegerType(), new StringType()]); } if ($argsCount < 2) { return $valueType; } $secondArgType = $scope->getType($functionCall->getArgs()[1]->value); $one = new ConstantIntegerType(1); if ($one->isSuperTypeOf($secondArgType)->yes()) { return $valueType; } $bigger2 = IntegerRangeType::fromInterval(2, null); if ($bigger2->isSuperTypeOf($secondArgType)->yes()) { return new ArrayType(new IntegerType(), $valueType); } return TypeCombinator::union($valueType, new ArrayType(new IntegerType(), $valueType)); } } getName() === 'function_exists' && isset($node->getArgs()[0]) && $context->true(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { $argType = $scope->getType($node->getArgs()[0]->value); if ($argType instanceof ConstantStringType) { return $this->typeSpecifier->create(new FuncCall(new FullyQualified('function_exists'), [new Arg(new String_(ltrim($argType->getValue(), '\\')))]), new ConstantBooleanType(\true), $context, \false, $scope); } return $this->typeSpecifier->create($node->getArgs()[0]->value, new CallableType(), $context, \false, $scope); } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } } getName(), ['stat', 'lstat', 'fstat', 'ssh2_sftp_stat'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { return TypeCombinator::union($this->getReturnType(), new ConstantBooleanType(\false)); } public function getClass() : string { return SplFileObject::class; } public function isMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getName() === 'fstat'; } public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : Type { return $this->getReturnType(); } private function getReturnType() : Type { $valueType = new IntegerType(); $builder = ConstantArrayTypeBuilder::createEmpty(); $keys = ['dev', 'ino', 'mode', 'nlink', 'uid', 'gid', 'rdev', 'size', 'atime', 'mtime', 'ctime', 'blksize', 'blocks']; foreach ($keys as $key) { $builder->setOffsetValueType(null, $valueType); } foreach ($keys as $key) { $builder->setOffsetValueType(new ConstantStringType($key), $valueType); } return $builder->getArray(); } } 1, 'json_decode' => 3]; public function __construct(ReflectionProvider $reflectionProvider, BitwiseFlagHelper $bitwiseFlagAnalyser) { $this->reflectionProvider = $reflectionProvider; $this->bitwiseFlagAnalyser = $bitwiseFlagAnalyser; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return in_array($functionReflection->getName(), ['json_encode', 'json_decode'], \true) && $this->reflectionProvider->hasConstant(new Name\FullyQualified('JSON_THROW_ON_ERROR'), null); } public function getThrowTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $argumentPosition = self::ARGUMENTS_POSITIONS[$functionReflection->getName()]; if (!isset($functionCall->getArgs()[$argumentPosition])) { return null; } $optionsExpr = $functionCall->getArgs()[$argumentPosition]->value; if (!$this->bitwiseFlagAnalyser->bitwiseOrContainsConstant($optionsExpr, $scope, 'JSON_THROW_ON_ERROR')->no()) { return new ObjectType('JsonException'); } return null; } } filterFunctionReturnTypeHelper = $filterFunctionReturnTypeHelper; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'filter_input'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 2) { return null; } return $this->filterFunctionReturnTypeHelper->getInputType($scope->getType($functionCall->getArgs()[0]->value), $scope->getType($functionCall->getArgs()[1]->value), isset($functionCall->getArgs()[2]) ? $scope->getType($functionCall->getArgs()[2]->value) : null, isset($functionCall->getArgs()[3]) ? $scope->getType($functionCall->getArgs()[3]->value) : null); } } getName()) === 'settype' && count($node->getArgs()) > 1 && $context->null(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { $value = $node->getArgs()[0]->value; $valueType = $scope->getType($value); $castType = $scope->getType($node->getArgs()[1]->value); $constantStrings = $castType->getConstantStrings(); if (count($constantStrings) < 1) { return new SpecifiedTypes(); } $types = []; foreach ($constantStrings as $constantString) { switch ($constantString->getValue()) { case 'bool': case 'boolean': $types[] = $valueType->toBoolean(); break; case 'int': case 'integer': $types[] = $valueType->toInteger(); break; case 'float': case 'double': $types[] = $valueType->toFloat(); break; case 'string': $types[] = $valueType->toString(); break; case 'array': $types[] = $valueType->toArray(); break; case 'object': $types[] = new ObjectType(stdClass::class); break; case 'null': $types[] = new NullType(); break; default: $types[] = new ErrorType(); } } return $this->typeSpecifier->create($value, TypeCombinator::union(...$types), TypeSpecifierContext::createTruthy(), \true, $scope); } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } } getName(), ['sizeof', 'count'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 1) { return null; } if (count($functionCall->getArgs()) > 1) { $mode = $scope->getType($functionCall->getArgs()[1]->value); if ($mode->isSuperTypeOf(new ConstantIntegerType(COUNT_RECURSIVE))->yes()) { return null; } } return $scope->getType($functionCall->getArgs()[0]->value)->getArraySize(); } } getName() === 'intdiv'; } public function getThrowTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $funcCall, Scope $scope) : ?Type { if (count($funcCall->getArgs()) < 2) { return $functionReflection->getThrowType(); } $valueType = $scope->getType($funcCall->getArgs()[0]->value)->toInteger(); $containsMin = $valueType->isSuperTypeOf(new ConstantIntegerType(PHP_INT_MIN)); $divisorType = $scope->getType($funcCall->getArgs()[1]->value)->toInteger(); if (!$containsMin->no()) { $divisionByMinusOne = $divisorType->isSuperTypeOf(new ConstantIntegerType(-1)); if (!$divisionByMinusOne->no()) { return new ObjectType(ArithmeticError::class); } } $divisionByZero = $divisorType->isSuperTypeOf(new ConstantIntegerType(0)); if (!$divisionByZero->no()) { return new ObjectType(DivisionByZeroError::class); } return null; } } getName(), ['addslashes', 'addcslashes', 'escapeshellarg', 'escapeshellcmd', 'htmlspecialchars', 'htmlentities', 'urlencode', 'urldecode', 'preg_quote', 'rawurlencode', 'rawurldecode'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) === 0) { return null; } $argType = $scope->getType($args[0]->value); if ($argType->isNonFalsyString()->yes()) { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($argType->isNonEmptyString()->yes()) { return new IntersectionType([new StringType(), new AccessoryNonEmptyStringType()]); } return new StringType(); } } getName(), ['class_implements', 'class_uses', 'class_parents'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) < 1) { return null; } $firstArgType = $scope->getType($args[0]->value); $autoload = TrinaryLogic::createYes(); if (isset($args[1])) { $autoload = $scope->getType($args[1]->value)->isTrue(); } $isObject = $firstArgType->isObject(); $variant = ParametersAcceptorSelector::selectFromArgs($scope, $args, $functionReflection->getVariants()); if ($isObject->yes()) { return TypeCombinator::remove($variant->getReturnType(), new ConstantBooleanType(\false)); } $isClassStringOrObject = (new UnionType([new ObjectWithoutClassType(), new ClassStringType()]))->isSuperTypeOf($firstArgType); if ($isClassStringOrObject->yes()) { if ($autoload->yes()) { return TypeUtils::toBenevolentUnion($variant->getReturnType()); } return $variant->getReturnType(); } if ($firstArgType->isClassStringType()->no()) { return new ConstantBooleanType(\false); } return null; } } arrayFilterFunctionReturnTypeHelper = $arrayFilterFunctionReturnTypeHelper; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'array_filter'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $arrayArg = $functionCall->getArgs()[0]->value ?? null; $callbackArg = $functionCall->getArgs()[1]->value ?? null; $flagArg = $functionCall->getArgs()[2]->value ?? null; return $this->arrayFilterFunctionReturnTypeHelper->getType($scope, $arrayArg, $callbackArg, $flagArg); } } getName() === 'range'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 2) { return null; } $startType = $scope->getType($functionCall->getArgs()[0]->value); $endType = $scope->getType($functionCall->getArgs()[1]->value); $stepType = count($functionCall->getArgs()) >= 3 ? $scope->getType($functionCall->getArgs()[2]->value) : new ConstantIntegerType(1); $constantReturnTypes = []; $startConstants = $startType->getConstantScalarTypes(); foreach ($startConstants as $startConstant) { if (!$startConstant instanceof ConstantIntegerType && !$startConstant instanceof ConstantFloatType && !$startConstant instanceof ConstantStringType) { continue; } $endConstants = $endType->getConstantScalarTypes(); foreach ($endConstants as $endConstant) { if (!$endConstant instanceof ConstantIntegerType && !$endConstant instanceof ConstantFloatType && !$endConstant instanceof ConstantStringType) { continue; } $stepConstants = $stepType->getConstantScalarTypes(); foreach ($stepConstants as $stepConstant) { if (!$stepConstant instanceof ConstantIntegerType && !$stepConstant instanceof ConstantFloatType) { continue; } try { $rangeValues = @range($startConstant->getValue(), $endConstant->getValue(), $stepConstant->getValue()); } catch (ValueError $e) { continue; } // @phpstan-ignore function.alreadyNarrowedType if (!is_array($rangeValues)) { continue; } if (count($rangeValues) > self::RANGE_LENGTH_THRESHOLD) { if ($startConstant instanceof ConstantIntegerType && $endConstant instanceof ConstantIntegerType && $stepConstant instanceof ConstantIntegerType) { if ($startConstant->getValue() > $endConstant->getValue()) { $tmp = $startConstant; $startConstant = $endConstant; $endConstant = $tmp; } return AccessoryArrayListType::intersectWith(TypeCombinator::intersect(new ArrayType(new IntegerType(), IntegerRangeType::fromInterval($startConstant->getValue(), $endConstant->getValue())), new NonEmptyArrayType())); } if ($stepType->isFloat()->yes()) { return AccessoryArrayListType::intersectWith(TypeCombinator::intersect(new ArrayType(new IntegerType(), new FloatType()), new NonEmptyArrayType())); } return AccessoryArrayListType::intersectWith(TypeCombinator::intersect(new ArrayType(new IntegerType(), TypeCombinator::union($startConstant->generalize(GeneralizePrecision::moreSpecific()), $endConstant->generalize(GeneralizePrecision::moreSpecific()), $stepType->generalize(GeneralizePrecision::moreSpecific()))), new NonEmptyArrayType())); } $arrayBuilder = ConstantArrayTypeBuilder::createEmpty(); foreach ($rangeValues as $value) { $arrayBuilder->setOffsetValueType(null, $scope->getTypeFromValue($value)); } $constantReturnTypes[] = $arrayBuilder->getArray(); } } } if (count($constantReturnTypes) > 0) { return TypeCombinator::union(...$constantReturnTypes); } $argType = TypeCombinator::union($startType, $endType); $isInteger = $argType->isInteger()->yes(); $isStepInteger = $stepType->isInteger()->yes(); if ($isInteger && $isStepInteger) { if ($argType instanceof IntegerRangeType) { return AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $argType)); } return AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new IntegerType())); } if ($argType->isFloat()->yes()) { return AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new FloatType())); } $numberType = new UnionType([new IntegerType(), new FloatType()]); $isNumber = $numberType->isSuperTypeOf($argType)->yes(); $isNumericString = $argType->isNumericString()->yes(); if ($isNumber || $isNumericString) { return AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $numberType)); } if ($argType->isString()->yes()) { return AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new StringType())); } return AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new BenevolentUnionType([new IntegerType(), new FloatType(), new StringType()]))); } } getName(), ['implode', 'join'], \true); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : Type { $args = $functionCall->getArgs(); if (count($args) === 1) { $argType = $scope->getType($args[0]->value); if ($argType->isArray()->yes()) { return $this->implode($argType, new ConstantStringType('')); } } if (count($args) !== 2) { return new StringType(); } $separatorType = $scope->getType($args[0]->value); $arrayType = $scope->getType($args[1]->value); return $this->implode($arrayType, $separatorType); } private function implode(Type $arrayType, Type $separatorType) : Type { if (count($arrayType->getConstantArrays()) > 0 && count($separatorType->getConstantStrings()) > 0) { $result = []; foreach ($separatorType->getConstantStrings() as $separator) { foreach ($arrayType->getConstantArrays() as $constantArray) { $constantType = $this->inferConstantType($constantArray, $separator); if ($constantType !== null) { $result[] = $constantType; continue; } $result = []; break 2; } } if (count($result) > 0) { return TypeCombinator::union(...$result); } } $accessoryTypes = []; $valueTypeAsString = $arrayType->getIterableValueType()->toString(); if ($arrayType->isIterableAtLeastOnce()->yes()) { if ($valueTypeAsString->isNonFalsyString()->yes() || $separatorType->isNonFalsyString()->yes()) { $accessoryTypes[] = new AccessoryNonFalsyStringType(); } elseif ($valueTypeAsString->isNonEmptyString()->yes() || $separatorType->isNonEmptyString()->yes()) { $accessoryTypes[] = new AccessoryNonEmptyStringType(); } } // implode is one of the four functions that can produce literal strings as blessed by the original RFC: wiki.php.net/rfc/is_literal if ($arrayType->getIterableValueType()->isLiteralString()->yes() && $separatorType->isLiteralString()->yes()) { $accessoryTypes[] = new AccessoryLiteralStringType(); } if ($valueTypeAsString->isLowercaseString()->yes() && $separatorType->isLowercaseString()->yes()) { $accessoryTypes[] = new AccessoryLowercaseStringType(); } if ($valueTypeAsString->isUppercaseString()->yes() && $separatorType->isUppercaseString()->yes()) { $accessoryTypes[] = new AccessoryUppercaseStringType(); } if (count($accessoryTypes) > 0) { $accessoryTypes[] = new StringType(); return new IntersectionType($accessoryTypes); } return new StringType(); } private function inferConstantType(ConstantArrayType $arrayType, ConstantStringType $separatorType) : ?Type { $strings = []; foreach ($arrayType->getAllArrays() as $array) { $valueTypes = $array->getValueTypes(); $arrayValues = []; $combinationsCount = 1; foreach ($valueTypes as $valueType) { $constScalars = $valueType->getConstantScalarValues(); if (count($constScalars) === 0) { return null; } $arrayValues[] = $constScalars; $combinationsCount *= count($constScalars); } if ($combinationsCount > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT) { return null; } $combinations = CombinationsHelper::combinations($arrayValues); foreach ($combinations as $combination) { $strings[] = new ConstantStringType(implode($separatorType->getValue(), $combination)); } } if (count($strings) > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT) { return null; } return TypeCombinator::union(...$strings); } } phpVersion = $phpVersion; } public function isMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getName() === 'sub' && in_array($methodReflection->getDeclaringClass()->getName(), [DateTime::class, DateTimeImmutable::class], \true); } public function getThrowTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : ?Type { if (count($methodCall->getArgs()) === 0) { return null; } if (!$this->phpVersion->hasDateTimeExceptions()) { return null; } return new ObjectType('DateInvalidOperationException'); } } ['cryptographic' => \false, 'possiblyFalse' => \false, 'binary' => 2], 'hash_file' => ['cryptographic' => \false, 'possiblyFalse' => \true, 'binary' => 2], 'hash_hkdf' => ['cryptographic' => \true, 'possiblyFalse' => \false, 'binary' => \true], 'hash_hmac' => ['cryptographic' => \true, 'possiblyFalse' => \false, 'binary' => 3], 'hash_hmac_file' => ['cryptographic' => \true, 'possiblyFalse' => \true, 'binary' => 3], 'hash_pbkdf2' => ['cryptographic' => \true, 'possiblyFalse' => \false, 'binary' => 5]]; private const NON_CRYPTOGRAPHIC_ALGORITHMS = ['adler32', 'crc32', 'crc32b', 'crc32c', 'fnv132', 'fnv1a32', 'fnv164', 'fnv1a64', 'joaat', 'murmur3a', 'murmur3c', 'murmur3f', 'xxh32', 'xxh64', 'xxh3', 'xxh128']; /** @var array */ private $hashAlgorithms; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; $this->hashAlgorithms = hash_algos(); } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { $name = strtolower($functionReflection->getName()); return isset(self::SUPPORTED_FUNCTIONS[$name]); } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $functionData = self::SUPPORTED_FUNCTIONS[strtolower($functionReflection->getName())]; if (is_bool($functionData['binary'])) { $binaryType = new ConstantBooleanType($functionData['binary']); } elseif (isset($functionCall->getArgs()[$functionData['binary']])) { $binaryType = $scope->getType($functionCall->getArgs()[$functionData['binary']]->value); } else { $binaryType = new ConstantBooleanType(\false); } $stringTypes = [new StringType(), new AccessoryNonFalsyStringType()]; if ($binaryType->isFalse()->yes()) { $stringTypes[] = new AccessoryLowercaseStringType(); } $stringReturnType = new IntersectionType($stringTypes); $algorithmType = $scope->getType($functionCall->getArgs()[0]->value); $constantAlgorithmTypes = $algorithmType->getConstantStrings(); if (count($constantAlgorithmTypes) === 0) { if ($functionData['possiblyFalse'] || !$this->phpVersion->throwsValueErrorForInternalFunctions()) { return TypeUtils::toBenevolentUnion(TypeCombinator::union($stringReturnType, new ConstantBooleanType(\false))); } return $stringReturnType; } $neverType = new NeverType(); $falseType = new ConstantBooleanType(\false); $invalidAlgorithmType = $this->phpVersion->throwsValueErrorForInternalFunctions() ? $neverType : $falseType; $returnTypes = array_map(function (ConstantStringType $type) use($functionData, $stringReturnType, $invalidAlgorithmType) { $algorithm = strtolower($type->getValue()); if (!in_array($algorithm, $this->hashAlgorithms, \true)) { return $invalidAlgorithmType; } if ($functionData['cryptographic'] && in_array($algorithm, self::NON_CRYPTOGRAPHIC_ALGORITHMS, \true)) { return $invalidAlgorithmType; } return $stringReturnType; }, $constantAlgorithmTypes); $returnType = TypeCombinator::union(...$returnTypes); if ($functionData['possiblyFalse'] && !$neverType->isSuperTypeOf($returnType)->yes()) { $returnType = TypeCombinator::union($returnType, $falseType); } return $returnType; } } getName() === 'key'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $argType = $scope->getType($functionCall->getArgs()[0]->value); $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); if ($iterableAtLeastOnce->no()) { return new NullType(); } $keyType = $argType->getIterableKeyType(); if ($iterableAtLeastOnce->yes()) { return $keyType; } return TypeCombinator::union($keyType, new NullType()); } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'mb_convert_encoding'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (!isset($functionCall->getArgs()[0])) { return null; } $argType = $scope->getType($functionCall->getArgs()[0]->value); $initialReturnType = ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->getArgs(), $functionReflection->getVariants())->getReturnType(); $result = TypeCombinator::intersect($initialReturnType, $this->generalizeStringType($argType)); if ($result instanceof NeverType) { $result = $initialReturnType; } if ($this->phpVersion->throwsValueErrorForInternalFunctions()) { if (!isset($functionCall->getArgs()[2])) { return TypeCombinator::remove($result, new ConstantBooleanType(\false)); } $fromEncodingArgType = $scope->getType($functionCall->getArgs()[2]->value); $returnFalseIfCannotDetectEncoding = \false; if (!$fromEncodingArgType->isArray()->no()) { $constantArrays = $fromEncodingArgType->getConstantArrays(); if (count($constantArrays) > 0) { foreach ($constantArrays as $constantArray) { if (count($constantArray->getValueTypes()) > 1) { $returnFalseIfCannotDetectEncoding = \true; break; } } } else { $returnFalseIfCannotDetectEncoding = \true; } } if (!$returnFalseIfCannotDetectEncoding && !$fromEncodingArgType->isString()->no()) { $constantStrings = $fromEncodingArgType->getConstantStrings(); if (count($constantStrings) > 0) { foreach ($constantStrings as $constantString) { if (str_contains($constantString->getValue(), ',')) { $returnFalseIfCannotDetectEncoding = \true; break; } } } else { $returnFalseIfCannotDetectEncoding = \true; } } if (!$returnFalseIfCannotDetectEncoding) { return TypeCombinator::remove($result, new ConstantBooleanType(\false)); } } return TypeCombinator::union($result, new ConstantBooleanType(\false)); } public function generalizeStringType(Type $type) : Type { if ($type instanceof UnionType) { return $type->traverse([$this, 'generalizeStringType']); } if ($type->isString()->yes()) { return new StringType(); } $constantArrays = $type->getConstantArrays(); if (count($constantArrays) > 0) { $types = []; foreach ($constantArrays as $constantArray) { $types[] = $constantArray->traverse([$this, 'generalizeStringType']); } return TypeCombinator::union(...$types); } if ($type->isArray()->yes()) { $newArrayType = new ArrayType($type->getIterableKeyType(), $this->generalizeStringType($type->getIterableValueType())); if ($type->isIterableAtLeastOnce()->yes()) { $newArrayType = TypeCombinator::intersect($newArrayType, new NonEmptyArrayType()); } if ($type->isList()->yes()) { $newArrayType = TypeCombinator::intersect($newArrayType, new AccessoryArrayListType()); } return $newArrayType; } return $type; } } getName()), ['parse_str', 'mb_parse_str'], \true) && $parameter->getName() === 'result'; } public function getParameterOutTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $funcCall, ParameterReflection $parameter, Scope $scope) : ?Type { $args = $funcCall->getArgs(); if (count($args) < 1) { return null; } $stringType = $scope->getType($args[0]->value); $accessory = []; if ($stringType->isLowercaseString()->yes()) { $accessory[] = new AccessoryLowercaseStringType(); } if ($stringType->isUppercaseString()->yes()) { $accessory[] = new AccessoryUppercaseStringType(); } if (count($accessory) > 0) { $accessory[] = new StringType(); $valueType = new IntersectionType($accessory); } else { $valueType = new StringType(); } return new ArrayType(new UnionType([new StringType(), new IntegerType()]), new UnionType([new ArrayType(new MixedType(), new MixedType(\true)), $valueType])); } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'array_column'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $numArgs = count($functionCall->getArgs()); if ($numArgs < 2) { return null; } $arrayType = $scope->getType($functionCall->getArgs()[0]->value); $columnType = $scope->getType($functionCall->getArgs()[1]->value); $indexType = $numArgs >= 3 ? $scope->getType($functionCall->getArgs()[2]->value) : null; $constantArrayTypes = $arrayType->getConstantArrays(); if (count($constantArrayTypes) === 1) { $type = $this->handleConstantArray($constantArrayTypes[0], $columnType, $indexType, $scope); if ($type !== null) { return $type; } } return $this->handleAnyArray($arrayType, $columnType, $indexType, $scope); } private function handleAnyArray(Type $arrayType, Type $columnType, ?Type $indexType, Scope $scope) : Type { $iterableAtLeastOnce = $arrayType->isIterableAtLeastOnce(); if ($iterableAtLeastOnce->no()) { return new ConstantArrayType([], []); } $iterableValueType = $arrayType->getIterableValueType(); $returnValueType = $this->getOffsetOrProperty($iterableValueType, $columnType, $scope, \false); if ($returnValueType === null) { $returnValueType = $this->getOffsetOrProperty($iterableValueType, $columnType, $scope, \true); $iterableAtLeastOnce = TrinaryLogic::createMaybe(); if ($returnValueType === null) { throw new ShouldNotHappenException(); } } if ($returnValueType instanceof NeverType) { return new ConstantArrayType([], []); } if ($indexType !== null) { $type = $this->getOffsetOrProperty($iterableValueType, $indexType, $scope, \false); if ($type !== null) { $returnKeyType = $type; } else { $type = $this->getOffsetOrProperty($iterableValueType, $indexType, $scope, \true); if ($type !== null) { $returnKeyType = TypeCombinator::union($type, new IntegerType()); } else { $returnKeyType = new IntegerType(); } } } else { $returnKeyType = new IntegerType(); } $returnType = new ArrayType($this->castToArrayKeyType($returnKeyType), $returnValueType); if ($iterableAtLeastOnce->yes()) { $returnType = TypeCombinator::intersect($returnType, new NonEmptyArrayType()); } if ($indexType === null) { $returnType = AccessoryArrayListType::intersectWith($returnType); } return $returnType; } private function handleConstantArray(ConstantArrayType $arrayType, Type $columnType, ?Type $indexType, Scope $scope) : ?Type { $builder = ConstantArrayTypeBuilder::createEmpty(); foreach ($arrayType->getValueTypes() as $i => $iterableValueType) { $valueType = $this->getOffsetOrProperty($iterableValueType, $columnType, $scope, \false); if ($valueType === null) { return null; } if ($valueType instanceof NeverType) { continue; } if ($indexType !== null) { $type = $this->getOffsetOrProperty($iterableValueType, $indexType, $scope, \false); if ($type !== null) { $keyType = $type; } else { $type = $this->getOffsetOrProperty($iterableValueType, $indexType, $scope, \true); if ($type !== null) { $keyType = TypeCombinator::union($type, new IntegerType()); } else { $keyType = null; } } } else { $keyType = null; } if ($keyType !== null) { $keyType = $this->castToArrayKeyType($keyType); } $builder->setOffsetValueType($keyType, $valueType, $arrayType->isOptionalKey($i)); } return $builder->getArray(); } private function getOffsetOrProperty(Type $type, Type $offsetOrProperty, Scope $scope, bool $allowMaybe) : ?Type { $offsetIsNull = $offsetOrProperty->isNull(); if ($offsetIsNull->yes()) { return $type; } $returnTypes = []; if ($offsetIsNull->maybe()) { $returnTypes[] = $type; } if (!$type->canAccessProperties()->no()) { $propertyTypes = $offsetOrProperty->getConstantStrings(); if ($propertyTypes === []) { return new MixedType(); } foreach ($propertyTypes as $propertyType) { $propertyName = $propertyType->getValue(); $hasProperty = $type->hasProperty($propertyName); if ($hasProperty->maybe()) { return $allowMaybe ? new MixedType() : null; } if (!$hasProperty->yes()) { continue; } $returnTypes[] = $type->getProperty($propertyName, $scope)->getReadableType(); } } if ($type->isOffsetAccessible()->yes()) { $hasOffset = $type->hasOffsetValueType($offsetOrProperty); if (!$allowMaybe && $hasOffset->maybe()) { return null; } if (!$hasOffset->no()) { $returnTypes[] = $type->getOffsetValueType($offsetOrProperty); } } if ($returnTypes === []) { return new NeverType(); } return TypeCombinator::union(...$returnTypes); } private function castToArrayKeyType(Type $type) : Type { $isArray = $type->isArray(); if ($isArray->yes()) { return $this->phpVersion->throwsTypeErrorForInternalFunctions() ? new NeverType() : new IntegerType(); } if ($isArray->no()) { return $type->toArrayKey(); } $withoutArrayType = TypeCombinator::remove($type, new ArrayType(new MixedType(), new MixedType())); $keyType = $withoutArrayType->toArrayKey(); if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return $keyType; } return TypeCombinator::union($keyType, new IntegerType()); } } isAFunctionTypeSpecifyingHelper = $isAFunctionTypeSpecifyingHelper; } public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool { return strtolower($functionReflection->getName()) === 'is_subclass_of' && !$context->null(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { if (!$context->true() || count($node->getArgs()) < 2) { return new SpecifiedTypes(); } $objectOrClassType = $scope->getType($node->getArgs()[0]->value); $classType = $scope->getType($node->getArgs()[1]->value); $allowStringType = isset($node->getArgs()[2]) ? $scope->getType($node->getArgs()[2]->value) : new ConstantBooleanType(\true); $allowString = !$allowStringType->equals(new ConstantBooleanType(\false)); // prevent false-positives in IsAFunctionTypeSpecifyingHelper if ($objectOrClassType instanceof GenericClassStringType && $classType instanceof GenericClassStringType) { return new SpecifiedTypes([], []); } $resultType = $this->isAFunctionTypeSpecifyingHelper->determineType($objectOrClassType, $classType, $allowString, \false); // prevent false-positives in IsAFunctionTypeSpecifyingHelper if ($classType->getConstantStrings() === [] && $resultType->isSuperTypeOf($objectOrClassType)->yes()) { return new SpecifiedTypes([], []); } return $this->typeSpecifier->create($node->getArgs()[0]->value, $resultType, $context, \false, $scope); } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'array_combine'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { if (count($functionCall->getArgs()) < 2) { return null; } $firstArg = $functionCall->getArgs()[0]->value; $secondArg = $functionCall->getArgs()[1]->value; $keysParamType = $scope->getType($firstArg); $valuesParamType = $scope->getType($secondArg); if ($keysParamType instanceof ConstantArrayType && $valuesParamType instanceof ConstantArrayType) { $keyTypes = $keysParamType->getValueTypes(); $valueTypes = $valuesParamType->getValueTypes(); if (count($keyTypes) !== count($valueTypes)) { if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return new NeverType(); } return new ConstantBooleanType(\false); } $keyTypes = $this->sanitizeConstantArrayKeyTypes($keyTypes); if ($keyTypes !== null) { $builder = ConstantArrayTypeBuilder::createEmpty(); foreach ($keyTypes as $i => $keyType) { $valueType = $valueTypes[$i]; $builder->setOffsetValueType($keyType, $valueType); } return $builder->getArray(); } } if ($keysParamType->isArray()->yes()) { $itemType = $keysParamType->getIterableValueType(); if ($itemType->isInteger()->no()) { if ($itemType->toString() instanceof ErrorType) { return new NeverType(); } $keyType = $itemType->toString(); } else { $keyType = $itemType; } } else { $keyType = new MixedType(); } $arrayType = new ArrayType($keyType, $valuesParamType->isArray()->yes() ? $valuesParamType->getIterableValueType() : new MixedType()); if ($keysParamType->isIterableAtLeastOnce()->yes() && $valuesParamType->isIterableAtLeastOnce()->yes()) { $arrayType = TypeCombinator::intersect($arrayType, new NonEmptyArrayType()); } if ($this->phpVersion->throwsTypeErrorForInternalFunctions()) { return $arrayType; } if ($firstArg instanceof Variable && $secondArg instanceof Variable && $firstArg->name === $secondArg->name) { return $arrayType; } return new UnionType([$arrayType, new ConstantBooleanType(\false)]); } /** * @param array $types * * @return array|null */ private function sanitizeConstantArrayKeyTypes(array $types) : ?array { $sanitizedTypes = []; foreach ($types as $type) { if ($type->isInteger()->no() && !$type->toString() instanceof ErrorType) { $type = $type->toString(); } if (!$type instanceof ConstantIntegerType && !$type instanceof ConstantStringType) { return null; } $sanitizedTypes[] = $type; } return $sanitizedTypes; } } phpVersion = $phpVersion; } public function isFunctionSupported(FunctionReflection $functionReflection) : bool { return $functionReflection->getName() === 'array_intersect_key'; } public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope) : ?Type { $args = $functionCall->getArgs(); if (count($args) === 0) { return null; } $argTypes = []; foreach ($args as $arg) { $argType = $scope->getType($arg->value); if ($arg->unpack) { $argTypes[] = $argType->getIterableValueType(); continue; } $argTypes[] = $argType; } $firstArrayType = $argTypes[0]; $otherArraysType = TypeCombinator::union(...array_slice($argTypes, 1)); $onlyOneArrayGiven = count($argTypes) === 1; if ($firstArrayType->isArray()->no() || !$onlyOneArrayGiven && $otherArraysType->isArray()->no()) { return $this->phpVersion->arrayFunctionsReturnNullWithNonArray() ? new NullType() : new NeverType(); } if ($onlyOneArrayGiven) { return $firstArrayType; } return $firstArrayType->intersectKeyArray($otherArraysType); } } = 2) { $fqcn = ltrim($classConstParts[0], '\\'); if ($fqcn === '') { return null; } $classConstName = new FullyQualified($fqcn); if ($classConstName->isSpecialClassName()) { $classConstName = new Name($classConstName->toString()); } return new ClassConstFetch($classConstName, new Identifier($classConstParts[1])); } return new ConstFetch(new FullyQualified($constantName)); } } getName()) === 'array_search' && $context->true(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { $arrayArg = $node->getArgs()[1]->value ?? null; if ($arrayArg === null) { return new SpecifiedTypes(); } return $this->typeSpecifier->create($arrayArg, TypeCombinator::intersect(new ArrayType(new MixedType(), new MixedType()), new NonEmptyArrayType()), $context, \false, $scope); } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } } regexShapeMatcher = $regexShapeMatcher; } public function setTypeSpecifier(TypeSpecifier $typeSpecifier) : void { $this->typeSpecifier = $typeSpecifier; } public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context) : bool { return in_array(strtolower($functionReflection->getName()), ['preg_match', 'preg_match_all'], \true) && !$context->null(); } public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context) : SpecifiedTypes { $args = $node->getArgs(); $patternArg = $args[0] ?? null; $matchesArg = $args[2] ?? null; $flagsArg = $args[3] ?? null; if ($patternArg === null || $matchesArg === null) { return new SpecifiedTypes(); } $flagsType = null; if ($flagsArg !== null) { $flagsType = $scope->getType($flagsArg->value); } if ($functionReflection->getName() === 'preg_match') { $matchedType = $this->regexShapeMatcher->matchExpr($patternArg->value, $flagsType, TrinaryLogic::createFromBoolean($context->true()), $scope); } else { $matchedType = $this->regexShapeMatcher->matchAllExpr($patternArg->value, $flagsType, TrinaryLogic::createFromBoolean($context->true()), $scope); } if ($matchedType === null) { return new SpecifiedTypes(); } $overwrite = \false; if ($context->false()) { $overwrite = \true; $context = $context->negate(); } return $this->typeSpecifier->create($matchesArg->value, $matchedType, $context, $overwrite, $scope, $node); } } getSubtractedType()); } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return sprintf('$this(%s)', $this->getStaticObjectType()->describe($level)); } public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof self) { return $this->getStaticObjectType()->isSuperTypeOfWithReason($type); } if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } $parent = new parent($this->getClassReflection(), $this->getSubtractedType()); return $parent->isSuperTypeOfWithReason($type)->and(\PHPStan\Type\IsSuperTypeOfResult::createMaybe()); } public function changeSubtractedType(?\PHPStan\Type\Type $subtractedType) : \PHPStan\Type\Type { $type = parent::changeSubtractedType($subtractedType); if ($type instanceof parent) { return new self($type->getClassReflection(), $subtractedType); } return $type; } public function traverse(callable $cb) : \PHPStan\Type\Type { $subtractedType = $this->getSubtractedType() !== null ? $cb($this->getSubtractedType()) : null; if ($subtractedType !== $this->getSubtractedType()) { return new self($this->getClassReflection(), $subtractedType); } return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { if ($this->getSubtractedType() === null) { return $this; } return new self($this->getClassReflection()); } public function toPhpDocNode() : TypeNode { return new ThisTypeNode(); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if ($reflectionProvider->hasClass($properties['baseClass'])) { return new self($reflectionProvider->getClass($properties['baseClass']), $properties['subtractedType'] ?? null); } return new \PHPStan\Type\ErrorType(); } } getTypes() as $type) { $result = $getType($type); if ($result instanceof \PHPStan\Type\ErrorType) { continue; } $resultTypes[] = $result; } if (count($resultTypes) === 0) { return new \PHPStan\Type\ErrorType(); } return \PHPStan\Type\TypeUtils::toBenevolentUnion(\PHPStan\Type\TypeCombinator::union(...$resultTypes)); } protected function pickFromTypes(callable $getValues, callable $criteria) : array { $values = []; foreach ($this->getTypes() as $type) { $innerValues = $getValues($type); if ($innerValues === [] && $criteria($type)) { return []; } foreach ($innerValues as $innerType) { $values[] = $innerType; } } return $values; } public function getOffsetValueType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { $types = []; foreach ($this->getTypes() as $innerType) { $valueType = $innerType->getOffsetValueType($offsetType); if ($valueType instanceof \PHPStan\Type\ErrorType) { continue; } $types[] = $valueType; } if (count($types) === 0) { return new \PHPStan\Type\ErrorType(); } return \PHPStan\Type\TypeUtils::toBenevolentUnion(\PHPStan\Type\TypeCombinator::union(...$types)); } protected function unionResults(callable $getResult) : TrinaryLogic { return TrinaryLogic::createNo()->lazyOr($this->getTypes(), $getResult); } public function isAcceptedBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : \PHPStan\Type\AcceptsResult { $result = \PHPStan\Type\AcceptsResult::createNo(); foreach ($this->getTypes() as $innerType) { $result = $result->or($acceptingType->acceptsWithReason($innerType, $strictTypes)); } return $result; } public function inferTemplateTypes(\PHPStan\Type\Type $receivedType) : TemplateTypeMap { $types = TemplateTypeMap::createEmpty(); foreach ($this->getTypes() as $type) { $types = $types->benevolentUnion($type->inferTemplateTypes($receivedType)); } return $types; } public function inferTemplateTypesOn(\PHPStan\Type\Type $templateType) : TemplateTypeMap { $types = TemplateTypeMap::createEmpty(); foreach ($this->getTypes() as $type) { $types = $types->benevolentUnion($templateType->inferTemplateTypes($type)); } return $types; } public function traverse(callable $cb) : \PHPStan\Type\Type { $types = []; $changed = \false; foreach ($this->getTypes() as $type) { $newType = $cb($type); if ($type !== $newType) { $changed = \true; } $types[] = $newType; } if ($changed) { return \PHPStan\Type\TypeUtils::toBenevolentUnion(\PHPStan\Type\TypeCombinator::union(...$types)); } return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { $types = []; $changed = \false; if (!$right instanceof \PHPStan\Type\UnionType) { return $this; } if (count($this->getTypes()) !== count($right->getTypes())) { return $this; } foreach ($this->getSortedTypes() as $i => $leftType) { $rightType = $right->getSortedTypes()[$i]; $newType = $cb($leftType, $rightType); if ($leftType !== $newType) { $changed = \true; } $types[] = $newType; } if ($changed) { return \PHPStan\Type\TypeUtils::toBenevolentUnion(\PHPStan\Type\TypeCombinator::union(...$types)); } return $this; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['types']); } } */ private $extensions; /** * @param array $extensions */ public function __construct(array $extensions) { $this->extensions = $extensions; } /** * @return array */ public function getExtensions() : array { return $this->extensions; } } getName(); } return $selfClass !== null ? new \PHPStan\Type\ObjectType($selfClass) : new \PHPStan\Type\ErrorType(); case 'parent': $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if (is_string($selfClass)) { if ($reflectionProvider->hasClass($selfClass)) { $selfClass = $reflectionProvider->getClass($selfClass); } else { $selfClass = null; } } if ($selfClass !== null) { if ($selfClass->getParentClass() !== null) { return new \PHPStan\Type\ObjectType($selfClass->getParentClass()->getName()); } } return new \PHPStan\Type\NonexistentParentClassType(); case 'static': $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); if (is_string($selfClass)) { if ($reflectionProvider->hasClass($selfClass)) { $selfClass = $reflectionProvider->getClass($selfClass); } else { $selfClass = null; } } if ($selfClass !== null) { return new \PHPStan\Type\StaticType($selfClass); } return new \PHPStan\Type\ErrorType(); case 'null': return new \PHPStan\Type\NullType(); case 'never': return new \PHPStan\Type\NonAcceptingNeverType(); default: return new \PHPStan\Type\ObjectType($typeString); } } /** @api *@param ClassReflection|string|null $selfClass */ public static function decideTypeFromReflection(?ReflectionType $reflectionType, ?\PHPStan\Type\Type $phpDocType = null, $selfClass = null, bool $isVariadic = \false) : \PHPStan\Type\Type { if ($reflectionType === null) { if ($isVariadic && $phpDocType instanceof \PHPStan\Type\ArrayType) { $phpDocType = $phpDocType->getItemType(); } return $phpDocType ?? new \PHPStan\Type\MixedType(); } if ($reflectionType instanceof ReflectionUnionType) { $type = \PHPStan\Type\TypeCombinator::union(...array_map(static function (ReflectionType $type) use($selfClass) : \PHPStan\Type\Type { return self::decideTypeFromReflection($type, null, $selfClass, \false); }, $reflectionType->getTypes())); return self::decideType($type, $phpDocType); } if ($reflectionType instanceof ReflectionIntersectionType) { $types = []; foreach ($reflectionType->getTypes() as $innerReflectionType) { $innerType = self::decideTypeFromReflection($innerReflectionType, null, $selfClass, \false); if (!$innerType->isObject()->yes()) { return new \PHPStan\Type\NeverType(); } $types[] = $innerType; } return self::decideType(\PHPStan\Type\TypeCombinator::intersect(...$types), $phpDocType); } if (!$reflectionType instanceof ReflectionNamedType) { throw new ShouldNotHappenException(sprintf('Unexpected type: %s', get_class($reflectionType))); } $reflectionTypeString = $reflectionType->getName(); $loweredReflectionTypeString = strtolower($reflectionTypeString); if (str_ends_with($loweredReflectionTypeString, '\\object')) { $reflectionTypeString = 'object'; } elseif (str_ends_with($loweredReflectionTypeString, '\\mixed')) { $reflectionTypeString = 'mixed'; } elseif (str_ends_with($loweredReflectionTypeString, '\\true')) { $reflectionTypeString = 'true'; } elseif (str_ends_with($loweredReflectionTypeString, '\\false')) { $reflectionTypeString = 'false'; } elseif (str_ends_with($loweredReflectionTypeString, '\\null')) { $reflectionTypeString = 'null'; } elseif (str_ends_with($loweredReflectionTypeString, '\\never')) { $reflectionTypeString = 'never'; } $type = self::getTypeObjectFromTypehint($reflectionTypeString, $selfClass); if ($reflectionType->allowsNull()) { $type = \PHPStan\Type\TypeCombinator::addNull($type); } elseif ($phpDocType !== null) { $phpDocType = \PHPStan\Type\TypeCombinator::removeNull($phpDocType); } return self::decideType($type, $phpDocType); } public static function decideType(\PHPStan\Type\Type $type, ?\PHPStan\Type\Type $phpDocType = null) : \PHPStan\Type\Type { if ($type instanceof \PHPStan\Type\BenevolentUnionType) { return $type; } if ($phpDocType !== null && !$phpDocType instanceof \PHPStan\Type\ErrorType) { if ($phpDocType instanceof \PHPStan\Type\NeverType && $phpDocType->isExplicit()) { return $phpDocType; } if ($type instanceof \PHPStan\Type\MixedType && !$type->isExplicitMixed() && $phpDocType->isVoid()->yes()) { return $phpDocType; } if (\PHPStan\Type\TypeCombinator::removeNull($type) instanceof \PHPStan\Type\IterableType) { if ($phpDocType instanceof \PHPStan\Type\UnionType) { $innerTypes = []; foreach ($phpDocType->getTypes() as $innerType) { if ($innerType instanceof \PHPStan\Type\ArrayType) { $innerTypes[] = new \PHPStan\Type\IterableType($innerType->getIterableKeyType(), $innerType->getItemType()); } else { $innerTypes[] = $innerType; } } $phpDocType = new \PHPStan\Type\UnionType($innerTypes); } elseif ($phpDocType instanceof \PHPStan\Type\ArrayType) { $phpDocType = new \PHPStan\Type\IterableType($phpDocType->getKeyType(), $phpDocType->getItemType()); } } if ($type->isCallable()->yes() && $phpDocType->isCallable()->yes() || (!$phpDocType instanceof \PHPStan\Type\NeverType || $type instanceof \PHPStan\Type\MixedType && !$type->isExplicitMixed()) && $type->isSuperTypeOf(TemplateTypeHelper::resolveToBounds($phpDocType))->yes()) { $resultType = $phpDocType; } else { $resultType = $type; } if ($type instanceof \PHPStan\Type\UnionType) { $addToUnionTypes = []; foreach ($type->getTypes() as $innerType) { if (!$innerType->isSuperTypeOf($resultType)->no()) { continue; } $addToUnionTypes[] = $innerType; } if (count($addToUnionTypes) > 0) { $type = \PHPStan\Type\TypeCombinator::union($resultType, ...$addToUnionTypes); } else { $type = $resultType; } } elseif (\PHPStan\Type\TypeCombinator::containsNull($type)) { $type = \PHPStan\Type\TypeCombinator::addNull($resultType); } else { $type = $resultType; } } return $type; } } initializerExprTypeResolver = $initializerExprTypeResolver; $this->reflectionSourceStubber = $reflectionSourceStubber; $this->reflector = $reflector; $this->parser = $parser; } /** * @param Closure(): mixed $closure */ public function fromClosureObject(Closure $closure) : \PHPStan\Type\ClosureType { $stubData = $this->reflectionSourceStubber->generateFunctionStubFromReflection(new ReflectionFunction($closure)); if ($stubData === null) { throw new ShouldNotHappenException('Closure reflection not found.'); } $source = $stubData->getStub(); $source = str_replace('{closure}', 'foo', $source); $locatedSource = new LocatedSource($source, '{closure}', $stubData->getFileName()); $find = new FindReflectionsInTree(new NodeToReflection()); $ast = $this->parser->parse($locatedSource->getSource()); if ($ast === null) { throw new ShouldNotHappenException('Closure reflection not found.'); } /** @var list<\PHPStan\BetterReflection\Reflection\ReflectionFunction> $reflections */ $reflections = $find($this->reflector, $ast, new IdentifierType(IdentifierType::IDENTIFIER_FUNCTION), $locatedSource); if (count($reflections) !== 1) { throw new ShouldNotHappenException('Closure reflection not found.'); } $betterReflectionFunction = $reflections[0]; $parameters = array_map(function (BetterReflectionParameter $parameter) { return new class($parameter, $this->initializerExprTypeResolver) implements ParameterReflection { /** * @var BetterReflectionParameter */ private $reflection; /** * @var InitializerExprTypeResolver */ private $initializerExprTypeResolver; public function __construct(BetterReflectionParameter $reflection, InitializerExprTypeResolver $initializerExprTypeResolver) { $this->reflection = $reflection; $this->initializerExprTypeResolver = $initializerExprTypeResolver; } public function getName() : string { return $this->reflection->getName(); } public function isOptional() : bool { return $this->reflection->isOptional(); } public function getType() : \PHPStan\Type\Type { return \PHPStan\Type\TypehintHelper::decideTypeFromReflection(ReflectionType::fromTypeOrNull($this->reflection->getType()), null, null, $this->reflection->isVariadic()); } public function passedByReference() : PassedByReference { return $this->reflection->isPassedByReference() ? PassedByReference::createCreatesNewVariable() : PassedByReference::createNo(); } public function isVariadic() : bool { return $this->reflection->isVariadic(); } public function getDefaultValue() : ?\PHPStan\Type\Type { if (!$this->reflection->isDefaultValueAvailable()) { return null; } $defaultExpr = $this->reflection->getDefaultValueExpression(); if ($defaultExpr === null) { return null; } return $this->initializerExprTypeResolver->getType($defaultExpr, InitializerExprContext::fromReflectionParameter(new ReflectionParameter($this->reflection))); } }; }, $betterReflectionFunction->getParameters()); return new \PHPStan\Type\ClosureType($parameters, \PHPStan\Type\TypehintHelper::decideTypeFromReflection(ReflectionType::fromTypeOrNull($betterReflectionFunction->getReturnType())), $betterReflectionFunction->isVariadic()); } } isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult { if ($type instanceof \PHPStan\Type\CompoundType) { return $type->isSubTypeOfWithReason($this); } $thatClassNames = $type->getObjectClassNames(); if ($thatClassNames === []) { return parent::isSuperTypeOfWithReason($type); } $result = \PHPStan\Type\IsSuperTypeOfResult::createNo(); $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); foreach ($thatClassNames as $thatClassName) { if (!$reflectionProvider->hasClass($thatClassName)) { return \PHPStan\Type\IsSuperTypeOfResult::createNo(); } $typeClass = $reflectionProvider->getClass($thatClassName); $result = $result->or(\PHPStan\Type\IsSuperTypeOfResult::createFromBoolean($typeClass->hasNativeMethod('__toString'))); } return $result; } public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult { $thatClassNames = $type->getObjectClassNames(); if ($thatClassNames === []) { return parent::acceptsWithReason($type, $strictTypes); } $result = \PHPStan\Type\AcceptsResult::createNo(); $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); foreach ($thatClassNames as $thatClassName) { if (!$reflectionProvider->hasClass($thatClassName)) { return \PHPStan\Type\AcceptsResult::createNo(); } $typeClass = $reflectionProvider->getClass($thatClassName); $result = $result->or(\PHPStan\Type\AcceptsResult::createFromBoolean($typeClass->hasNativeMethod('__toString'))); } return $result; } } getParameters(); $ourParameters = $ours->getParameters(); $lastParameter = null; foreach ($theirParameters as $theirParameter) { $lastParameter = $theirParameter; } $theirParameterCount = count($theirParameters); $ourParameterCount = count($ourParameters); if ($lastParameter !== null && $lastParameter->isVariadic() && $theirParameterCount < $ourParameterCount) { foreach ($ourParameters as $i => $ourParameter) { if (array_key_exists($i, $theirParameters)) { continue; } $theirParameters[] = $lastParameter; } } $result = \PHPStan\Type\IsSuperTypeOfResult::createYes(); foreach ($theirParameters as $i => $theirParameter) { $parameterDescription = $theirParameter->getName() === '' ? sprintf('#%d', $i + 1) : sprintf('#%d $%s', $i + 1, $theirParameter->getName()); if (!isset($ourParameters[$i])) { if ($theirParameter->isOptional()) { continue; } $accepts = new \PHPStan\Type\IsSuperTypeOfResult(TrinaryLogic::createNo(), [sprintf('Parameter %s of passed callable is required but accepting callable does not have that parameter. It will be called without it.', $parameterDescription)]); $result = $result->and($accepts); continue; } $ourParameter = $ourParameters[$i]; $ourParameterType = $ourParameter->getType(); if ($ourParameter->isOptional() && !$theirParameter->isOptional()) { $accepts = new \PHPStan\Type\IsSuperTypeOfResult(TrinaryLogic::createNo(), [sprintf('Parameter %s of passed callable is required but the parameter of accepting callable is optional. It might be called without it.', $parameterDescription)]); $result = $result->and($accepts); } if ($treatMixedAsAny) { $isSuperType = $theirParameter->getType()->acceptsWithReason($ourParameterType, \true); $isSuperType = new \PHPStan\Type\IsSuperTypeOfResult($isSuperType->result, $isSuperType->reasons); } else { $isSuperType = $theirParameter->getType()->isSuperTypeOfWithReason($ourParameterType); } if ($isSuperType->maybe()) { $verbosity = \PHPStan\Type\VerbosityLevel::getRecommendedLevelByType($theirParameter->getType(), $ourParameterType); $isSuperType = new \PHPStan\Type\IsSuperTypeOfResult($isSuperType->result, array_merge($isSuperType->reasons, [sprintf('Type %s of parameter %s of passed callable needs to be same or wider than parameter type %s of accepting callable.', $theirParameter->getType()->describe($verbosity), $parameterDescription, $ourParameterType->describe($verbosity))])); } $result = $result->and($isSuperType); } if (!$treatMixedAsAny && $theirParameterCount < $ourParameterCount) { $result = $result->and(\PHPStan\Type\IsSuperTypeOfResult::createMaybe()); } $theirReturnType = $theirs->getReturnType(); if ($treatMixedAsAny) { $isReturnTypeSuperType = $ours->getReturnType()->acceptsWithReason($theirReturnType, \true); $isReturnTypeSuperType = new \PHPStan\Type\IsSuperTypeOfResult($isReturnTypeSuperType->result, $isReturnTypeSuperType->reasons); } else { $isReturnTypeSuperType = $ours->getReturnType()->isSuperTypeOfWithReason($theirReturnType); } $pure = $ours->isPure(); if ($pure->yes()) { $result = $result->and(new \PHPStan\Type\IsSuperTypeOfResult($theirs->isPure(), [])); } elseif ($pure->no()) { $result = $result->and(new \PHPStan\Type\IsSuperTypeOfResult($theirs->isPure()->negate(), [])); } return $result->and($isReturnTypeSuperType); } } */ public function getObjectClassNames() : array; /** * @return list */ public function getObjectClassReflections() : array; /** * Returns object type Foo for class-string and 'Foo' (if Foo is a valid class). */ public function getClassStringObjectType() : \PHPStan\Type\Type; /** * Returns object type Foo for class-string, 'Foo' (if Foo is a valid class), * and object type Foo. */ public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type; public function isObject() : TrinaryLogic; public function isEnum() : TrinaryLogic; /** @return list */ public function getArrays() : array; /** @return list */ public function getConstantArrays() : array; /** @return list */ public function getConstantStrings() : array; public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic; /** * This is like accepts() but gives reasons * why the type was not/might not be accepted in some non-intuitive scenarios. * * In PHPStan 2.0 this method will be removed and the return type of accepts() * will change to AcceptsResult. */ public function acceptsWithReason(\PHPStan\Type\Type $type, bool $strictTypes) : \PHPStan\Type\AcceptsResult; public function isSuperTypeOf(\PHPStan\Type\Type $type) : TrinaryLogic; /** * This is like isSuperTypeOf() but gives reasons * why the type was not/might not be accepted in some non-intuitive scenarios. * * In PHPStan 2.0 this method will be removed and the return type of isSuperTypeOf() * will change to IsSuperTypeOfResult. */ public function isSuperTypeOfWithReason(\PHPStan\Type\Type $type) : \PHPStan\Type\IsSuperTypeOfResult; public function equals(\PHPStan\Type\Type $type) : bool; public function describe(\PHPStan\Type\VerbosityLevel $level) : string; public function canAccessProperties() : TrinaryLogic; public function hasProperty(string $propertyName) : TrinaryLogic; /** * @return ExtendedPropertyReflection */ public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection; public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection; public function canCallMethods() : TrinaryLogic; public function hasMethod(string $methodName) : TrinaryLogic; public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection; public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection; public function canAccessConstants() : TrinaryLogic; public function hasConstant(string $constantName) : TrinaryLogic; public function getConstant(string $constantName) : ConstantReflection; public function isIterable() : TrinaryLogic; public function isIterableAtLeastOnce() : TrinaryLogic; public function getArraySize() : \PHPStan\Type\Type; public function getIterableKeyType() : \PHPStan\Type\Type; public function getFirstIterableKeyType() : \PHPStan\Type\Type; public function getLastIterableKeyType() : \PHPStan\Type\Type; public function getIterableValueType() : \PHPStan\Type\Type; public function getFirstIterableValueType() : \PHPStan\Type\Type; public function getLastIterableValueType() : \PHPStan\Type\Type; public function isArray() : TrinaryLogic; public function isConstantArray() : TrinaryLogic; public function isOversizedArray() : TrinaryLogic; public function isList() : TrinaryLogic; public function isOffsetAccessible() : TrinaryLogic; public function isOffsetAccessLegal() : TrinaryLogic; public function hasOffsetValueType(\PHPStan\Type\Type $offsetType) : TrinaryLogic; public function getOffsetValueType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type; public function setOffsetValueType(?\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType, bool $unionValues = \true) : \PHPStan\Type\Type; public function setExistingOffsetValueType(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType) : \PHPStan\Type\Type; public function unsetOffset(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type; public function getKeysArray() : \PHPStan\Type\Type; public function getValuesArray() : \PHPStan\Type\Type; public function chunkArray(\PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type; public function fillKeysArray(\PHPStan\Type\Type $valueType) : \PHPStan\Type\Type; public function flipArray() : \PHPStan\Type\Type; public function intersectKeyArray(\PHPStan\Type\Type $otherArraysType) : \PHPStan\Type\Type; public function popArray() : \PHPStan\Type\Type; public function reverseArray(TrinaryLogic $preserveKeys) : \PHPStan\Type\Type; public function searchArray(\PHPStan\Type\Type $needleType) : \PHPStan\Type\Type; public function shiftArray() : \PHPStan\Type\Type; public function shuffleArray() : \PHPStan\Type\Type; public function sliceArray(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type; /** * @return list */ public function getEnumCases() : array; /** * Returns a list of finite values. * * Examples: * * - for bool: [true, false] * - for int<0, 3>: [0, 1, 2, 3] * - for enums: list of enum cases * - for scalars: the scalar itself * * For infinite types it returns an empty array. * * @return list */ public function getFiniteTypes() : array; public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type; public function isCallable() : TrinaryLogic; /** * @return CallableParametersAcceptor[] */ public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array; public function isCloneable() : TrinaryLogic; public function toBoolean() : \PHPStan\Type\BooleanType; public function toNumber() : \PHPStan\Type\Type; public function toInteger() : \PHPStan\Type\Type; public function toFloat() : \PHPStan\Type\Type; public function toString() : \PHPStan\Type\Type; public function toArray() : \PHPStan\Type\Type; public function toArrayKey() : \PHPStan\Type\Type; public function isSmallerThan(\PHPStan\Type\Type $otherType) : TrinaryLogic; public function isSmallerThanOrEqual(\PHPStan\Type\Type $otherType) : TrinaryLogic; /** * Is Type of a known constant value? Includes literal strings, integers, floats, true, false, null, and array shapes. */ public function isConstantValue() : TrinaryLogic; /** * Is Type of a known constant scalar value? Includes literal strings, integers, floats, true, false, and null. */ public function isConstantScalarValue() : TrinaryLogic; /** * @return list */ public function getConstantScalarTypes() : array; /** * @return list */ public function getConstantScalarValues() : array; public function isNull() : TrinaryLogic; public function isTrue() : TrinaryLogic; public function isFalse() : TrinaryLogic; public function isBoolean() : TrinaryLogic; public function isFloat() : TrinaryLogic; public function isInteger() : TrinaryLogic; public function isString() : TrinaryLogic; public function isNumericString() : TrinaryLogic; public function isNonEmptyString() : TrinaryLogic; public function isNonFalsyString() : TrinaryLogic; public function isLiteralString() : TrinaryLogic; public function isLowercaseString() : TrinaryLogic; public function isUppercaseString() : TrinaryLogic; public function isClassStringType() : TrinaryLogic; public function isVoid() : TrinaryLogic; public function isScalar() : TrinaryLogic; public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType; public function getSmallerType() : \PHPStan\Type\Type; public function getSmallerOrEqualType() : \PHPStan\Type\Type; public function getGreaterType() : \PHPStan\Type\Type; public function getGreaterOrEqualType() : \PHPStan\Type\Type; /** * Returns actual template type for a given object. * * Example: * * @-template T * class Foo {} * * // $fooType is Foo * $t = $fooType->getTemplateType(Foo::class, 'T'); * $t->isInteger(); // yes * * Returns ErrorType in case of a missing type. * * @param class-string $ancestorClassName */ public function getTemplateType(string $ancestorClassName, string $templateTypeName) : \PHPStan\Type\Type; /** * Infers template types * * Infers the real Type of the TemplateTypes found in $this, based on * the received Type. */ public function inferTemplateTypes(\PHPStan\Type\Type $receivedType) : TemplateTypeMap; /** * Returns the template types referenced by this Type, recursively * * The return value is a list of TemplateTypeReferences, who contain the * referenced template type as well as the variance position in which it was * found. * * For example, calling this on array,Bar> (with T a template type) * will return one TemplateTypeReference for the type T. * * @param TemplateTypeVariance $positionVariance The variance position in * which the receiver type was * found. * * @return TemplateTypeReference[] */ public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array; public function toAbsoluteNumber() : \PHPStan\Type\Type; /** * Traverses inner types * * Returns a new instance with all inner types mapped through $cb. Might * return the same instance if inner types did not change. * * @param callable(Type):Type $cb */ public function traverse(callable $cb) : \PHPStan\Type\Type; /** * Traverses inner types while keeping the same context in another type. * * @param callable(Type $left, Type $right): Type $cb */ public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type; public function toPhpDocNode() : TypeNode; /** * Return the difference with another type, or null if it cannot be represented. * * @see TypeCombinator::remove() */ public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type; public function generalize(\PHPStan\Type\GeneralizePrecision $precision) : \PHPStan\Type\Type; /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self; } extensions = $extensions; if ($broker === null) { return; } foreach ($extensions as $extension) { if (!$extension instanceof BrokerAwareExtension) { continue; } $extension->setBroker($broker); } } /** * @return OperatorTypeSpecifyingExtension[] */ public function getOperatorTypeSpecifyingExtensions(string $operator, \PHPStan\Type\Type $leftType, \PHPStan\Type\Type $rightType) : array { return array_values(array_filter($this->extensions, static function (\PHPStan\Type\OperatorTypeSpecifyingExtension $extension) use($operator, $leftType, $rightType) : bool { return $extension->isOperatorSupported($operator, $leftType, $rightType); })); } } resolve()->getObjectClassNames(); } public function getObjectClassReflections() : array { return $this->resolve()->getObjectClassReflections(); } public function getArrays() : array { return $this->resolve()->getArrays(); } public function getConstantArrays() : array { return $this->resolve()->getConstantArrays(); } public function getConstantStrings() : array { return $this->resolve()->getConstantStrings(); } public function accepts(Type $type, bool $strictTypes) : TrinaryLogic { return $this->resolve()->accepts($type, $strictTypes); } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { return $this->resolve()->acceptsWithReason($type, $strictTypes); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { return $this->isSuperTypeOfDefault($type); } private function isSuperTypeOfDefault(Type $type) : IsSuperTypeOfResult { if ($type instanceof NeverType) { return IsSuperTypeOfResult::createYes(); } if ($type instanceof LateResolvableType) { $type = $type->resolve(); } $isSuperType = $this->resolve()->isSuperTypeOfWithReason($type); if (!$this->isResolvable()) { $isSuperType = $isSuperType->and(IsSuperTypeOfResult::createMaybe()); } return $isSuperType; } public function getTemplateType(string $ancestorClassName, string $templateTypeName) : Type { return $this->resolve()->getTemplateType($ancestorClassName, $templateTypeName); } public function isObject() : TrinaryLogic { return $this->resolve()->isObject(); } public function isEnum() : TrinaryLogic { return $this->resolve()->isEnum(); } public function canAccessProperties() : TrinaryLogic { return $this->resolve()->canAccessProperties(); } public function hasProperty(string $propertyName) : TrinaryLogic { return $this->resolve()->hasProperty($propertyName); } public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection { return $this->resolve()->getProperty($propertyName, $scope); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { return $this->resolve()->getUnresolvedPropertyPrototype($propertyName, $scope); } public function canCallMethods() : TrinaryLogic { return $this->resolve()->canCallMethods(); } public function hasMethod(string $methodName) : TrinaryLogic { return $this->resolve()->hasMethod($methodName); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { return $this->resolve()->getMethod($methodName, $scope); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { return $this->resolve()->getUnresolvedMethodPrototype($methodName, $scope); } public function canAccessConstants() : TrinaryLogic { return $this->resolve()->canAccessConstants(); } public function hasConstant(string $constantName) : TrinaryLogic { return $this->resolve()->hasConstant($constantName); } public function getConstant(string $constantName) : ConstantReflection { return $this->resolve()->getConstant($constantName); } public function isIterable() : TrinaryLogic { return $this->resolve()->isIterable(); } public function isIterableAtLeastOnce() : TrinaryLogic { return $this->resolve()->isIterableAtLeastOnce(); } public function getArraySize() : Type { return $this->resolve()->getArraySize(); } public function getIterableKeyType() : Type { return $this->resolve()->getIterableKeyType(); } public function getFirstIterableKeyType() : Type { return $this->resolve()->getFirstIterableKeyType(); } public function getLastIterableKeyType() : Type { return $this->resolve()->getLastIterableKeyType(); } public function getIterableValueType() : Type { return $this->resolve()->getIterableValueType(); } public function getFirstIterableValueType() : Type { return $this->resolve()->getFirstIterableValueType(); } public function getLastIterableValueType() : Type { return $this->resolve()->getLastIterableValueType(); } public function isArray() : TrinaryLogic { return $this->resolve()->isArray(); } public function isConstantArray() : TrinaryLogic { return $this->resolve()->isConstantArray(); } public function isOversizedArray() : TrinaryLogic { return $this->resolve()->isOversizedArray(); } public function isList() : TrinaryLogic { return $this->resolve()->isList(); } public function isOffsetAccessible() : TrinaryLogic { return $this->resolve()->isOffsetAccessible(); } public function isOffsetAccessLegal() : TrinaryLogic { return $this->resolve()->isOffsetAccessLegal(); } public function hasOffsetValueType(Type $offsetType) : TrinaryLogic { return $this->resolve()->hasOffsetValueType($offsetType); } public function getOffsetValueType(Type $offsetType) : Type { return $this->resolve()->getOffsetValueType($offsetType); } public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = \true) : Type { return $this->resolve()->setOffsetValueType($offsetType, $valueType, $unionValues); } public function setExistingOffsetValueType(Type $offsetType, Type $valueType) : Type { return $this->resolve()->setExistingOffsetValueType($offsetType, $valueType); } public function unsetOffset(Type $offsetType) : Type { return $this->resolve()->unsetOffset($offsetType); } public function getKeysArray() : Type { return $this->resolve()->getKeysArray(); } public function getValuesArray() : Type { return $this->resolve()->getValuesArray(); } public function chunkArray(Type $lengthType, TrinaryLogic $preserveKeys) : Type { return $this->resolve()->chunkArray($lengthType, $preserveKeys); } public function fillKeysArray(Type $valueType) : Type { return $this->resolve()->fillKeysArray($valueType); } public function flipArray() : Type { return $this->resolve()->flipArray(); } public function intersectKeyArray(Type $otherArraysType) : Type { return $this->resolve()->intersectKeyArray($otherArraysType); } public function popArray() : Type { return $this->resolve()->popArray(); } public function reverseArray(TrinaryLogic $preserveKeys) : Type { return $this->resolve()->reverseArray($preserveKeys); } public function searchArray(Type $needleType) : Type { return $this->resolve()->searchArray($needleType); } public function shiftArray() : Type { return $this->resolve()->shiftArray(); } public function shuffleArray() : Type { return $this->resolve()->shuffleArray(); } public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $preserveKeys) : Type { return $this->resolve()->sliceArray($offsetType, $lengthType, $preserveKeys); } public function isCallable() : TrinaryLogic { return $this->resolve()->isCallable(); } public function getEnumCases() : array { return $this->resolve()->getEnumCases(); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { return $this->resolve()->getCallableParametersAcceptors($scope); } public function isCloneable() : TrinaryLogic { return $this->resolve()->isCloneable(); } public function toBoolean() : BooleanType { return $this->resolve()->toBoolean(); } public function toNumber() : Type { return $this->resolve()->toNumber(); } public function toAbsoluteNumber() : Type { return $this->resolve()->toAbsoluteNumber(); } public function toInteger() : Type { return $this->resolve()->toInteger(); } public function toFloat() : Type { return $this->resolve()->toFloat(); } public function toString() : Type { return $this->resolve()->toString(); } public function toArray() : Type { return $this->resolve()->toArray(); } public function toArrayKey() : Type { return $this->resolve()->toArrayKey(); } public function isSmallerThan(Type $otherType) : TrinaryLogic { return $this->resolve()->isSmallerThan($otherType); } public function isSmallerThanOrEqual(Type $otherType) : TrinaryLogic { return $this->resolve()->isSmallerThanOrEqual($otherType); } public function isNull() : TrinaryLogic { return $this->resolve()->isNull(); } public function isConstantValue() : TrinaryLogic { return $this->resolve()->isConstantValue(); } public function isConstantScalarValue() : TrinaryLogic { return $this->resolve()->isConstantScalarValue(); } public function getConstantScalarTypes() : array { return $this->resolve()->getConstantScalarTypes(); } public function getConstantScalarValues() : array { return $this->resolve()->getConstantScalarValues(); } public function isTrue() : TrinaryLogic { return $this->resolve()->isTrue(); } public function isFalse() : TrinaryLogic { return $this->resolve()->isFalse(); } public function isBoolean() : TrinaryLogic { return $this->resolve()->isBoolean(); } public function isFloat() : TrinaryLogic { return $this->resolve()->isFloat(); } public function isInteger() : TrinaryLogic { return $this->resolve()->isInteger(); } public function isString() : TrinaryLogic { return $this->resolve()->isString(); } public function isNumericString() : TrinaryLogic { return $this->resolve()->isNumericString(); } public function isNonEmptyString() : TrinaryLogic { return $this->resolve()->isNonEmptyString(); } public function isNonFalsyString() : TrinaryLogic { return $this->resolve()->isNonFalsyString(); } public function isLiteralString() : TrinaryLogic { return $this->resolve()->isLiteralString(); } public function isLowercaseString() : TrinaryLogic { return $this->resolve()->isLowercaseString(); } public function isUppercaseString() : TrinaryLogic { return $this->resolve()->isUppercaseString(); } public function isClassStringType() : TrinaryLogic { return $this->resolve()->isClassStringType(); } public function getClassStringObjectType() : Type { return $this->resolve()->getClassStringObjectType(); } public function getObjectTypeOrClassStringObjectType() : Type { return $this->resolve()->getObjectTypeOrClassStringObjectType(); } public function isVoid() : TrinaryLogic { return $this->resolve()->isVoid(); } public function isScalar() : TrinaryLogic { return $this->resolve()->isScalar(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function getSmallerType() : Type { return $this->resolve()->getSmallerType(); } public function getSmallerOrEqualType() : Type { return $this->resolve()->getSmallerOrEqualType(); } public function getGreaterType() : Type { return $this->resolve()->getGreaterType(); } public function getGreaterOrEqualType() : Type { return $this->resolve()->getGreaterOrEqualType(); } public function inferTemplateTypes(Type $receivedType) : TemplateTypeMap { return $this->resolve()->inferTemplateTypes($receivedType); } public function tryRemove(Type $typeToRemove) : ?Type { return $this->resolve()->tryRemove($typeToRemove); } public function isSubTypeOf(Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(Type $otherType) : IsSuperTypeOfResult { $result = $this->resolve(); if ($result instanceof CompoundType) { return $result->isSubTypeOfWithReason($otherType); } return $otherType->isSuperTypeOfWithReason($result); } public function isAcceptedBy(Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes) : AcceptsResult { $result = $this->resolve(); if ($result instanceof CompoundType) { return $result->isAcceptedWithReasonBy($acceptingType, $strictTypes); } return $acceptingType->acceptsWithReason($result, $strictTypes); } public function isGreaterThan(Type $otherType) : TrinaryLogic { $result = $this->resolve(); if ($result instanceof CompoundType) { return $result->isGreaterThan($otherType); } return $otherType->isSmallerThan($result); } public function isGreaterThanOrEqual(Type $otherType) : TrinaryLogic { $result = $this->resolve(); if ($result instanceof CompoundType) { return $result->isGreaterThanOrEqual($otherType); } return $otherType->isSmallerThanOrEqual($result); } public function exponentiate(Type $exponent) : Type { return $this->resolve()->exponentiate($exponent); } public function getFiniteTypes() : array { return $this->resolve()->getFiniteTypes(); } public function resolve() : Type { if ($this->result === null) { return $this->result = $this->getResult(); } return $this->result; } protected abstract function getResult() : Type; } isIterable()->no()) { return new ErrorType(); } if ($this->isIterableAtLeastOnce()->yes()) { return IntegerRangeType::fromInterval(1, null); } return IntegerRangeType::fromInterval(0, null); } public function getIterableKeyType() : Type { return new MixedType(); } public function getFirstIterableKeyType() : Type { return new MixedType(); } public function getLastIterableKeyType() : Type { return new MixedType(); } public function getIterableValueType() : Type { return new MixedType(); } public function getFirstIterableValueType() : Type { return new MixedType(); } public function getLastIterableValueType() : Type { return new MixedType(); } } traverse(static function (Type $type) use($precision) { return $type->generalize($precision); }); } } acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(Type $type, bool $strictTypes) : AcceptsResult { if ($type instanceof self) { return AcceptsResult::createFromBoolean($this->equals($type)); } if ($type instanceof CompoundType) { return $type->isAcceptedWithReasonBy($this, $strictTypes); } return parent::acceptsWithReason($type, $strictTypes)->and(AcceptsResult::createMaybe()); } public function isSuperTypeOf(Type $type) : TrinaryLogic { return $this->isSuperTypeOfWithReason($type)->result; } public function isSuperTypeOfWithReason(Type $type) : IsSuperTypeOfResult { if ($type instanceof self) { return IsSuperTypeOfResult::createFromBoolean($this->equals($type)); } if ($type instanceof parent) { return IsSuperTypeOfResult::createMaybe(); } if ($type instanceof CompoundType) { return $type->isSubTypeOfWithReason($this); } return IsSuperTypeOfResult::createNo(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { if (!$this instanceof ConstantScalarType) { throw new ShouldNotHappenException(); } if ($type instanceof ConstantScalarType) { return LooseComparisonHelper::compareConstantScalars($this, $type, $phpVersion); } if ($type->isConstantArray()->yes() && $type->isIterableAtLeastOnce()->no()) { // @phpstan-ignore equal.notAllowed, equal.invalid return new ConstantBooleanType($this->getValue() == []); // phpcs:ignore } if ($type instanceof CompoundType) { return $type->looseCompare($this, $phpVersion); } return parent::looseCompare($type, $phpVersion); } public function equals(Type $type) : bool { return $type instanceof self && $this->value === $type->value; } public function isSmallerThan(Type $otherType) : TrinaryLogic { if ($otherType instanceof ConstantScalarType) { return TrinaryLogic::createFromBoolean($this->value < $otherType->getValue()); } if ($otherType instanceof CompoundType) { return $otherType->isGreaterThan($this); } return TrinaryLogic::createMaybe(); } public function isSmallerThanOrEqual(Type $otherType) : TrinaryLogic { if ($otherType instanceof ConstantScalarType) { return TrinaryLogic::createFromBoolean($this->value <= $otherType->getValue()); } if ($otherType instanceof CompoundType) { return $otherType->isGreaterThanOrEqual($this); } return TrinaryLogic::createMaybe(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createYes(); } public function getConstantScalarTypes() : array { return [$this]; } public function getConstantScalarValues() : array { return [$this->getValue()]; } public function getFiniteTypes() : array { return [$this]; } } value)]; if (!(bool) $this->value) { $subtractedTypes[] = new NullType(); $subtractedTypes[] = new ConstantBooleanType(\false); $subtractedTypes[] = new ConstantFloatType(0.0); // subtract range when we support float-ranges } return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } public function getSmallerOrEqualType() : Type { $subtractedTypes = [IntegerRangeType::createAllGreaterThan($this->value)]; if (!(bool) $this->value) { $subtractedTypes[] = new ConstantBooleanType(\true); } return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } public function getGreaterType() : Type { $subtractedTypes = [ new NullType(), new ConstantBooleanType(\false), new ConstantFloatType(0.0), // subtract range when we support float-ranges IntegerRangeType::createAllSmallerThanOrEqualTo($this->value), ]; if ((bool) $this->value) { $subtractedTypes[] = new ConstantBooleanType(\true); } return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } public function getGreaterOrEqualType() : Type { $subtractedTypes = [IntegerRangeType::createAllSmallerThan($this->value)]; if ((bool) $this->value) { $subtractedTypes[] = new NullType(); $subtractedTypes[] = new ConstantBooleanType(\false); $subtractedTypes[] = new ConstantFloatType(0.0); // subtract range when we support float-ranges } return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } } getUnresolvedPropertyPrototype($propertyName, $scope)->getTransformedProperty(); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { $property = new DummyPropertyReflection(); return new CallbackUnresolvedPropertyPrototypeReflection($property, $property->getDeclaringClass(), \false, static function (Type $type) : Type { return $type; }); } public function canCallMethods() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasMethod(string $methodName) : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { return $this->getUnresolvedMethodPrototype($methodName, $scope)->getTransformedMethod(); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { $method = new DummyMethodReflection($methodName); return new CallbackUnresolvedMethodPrototypeReflection($method, $method->getDeclaringClass(), \false, static function (Type $type) : Type { return $type; }); } public function canAccessConstants() : TrinaryLogic { return TrinaryLogic::createYes(); } public function hasConstant(string $constantName) : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getConstant(string $constantName) : ConstantReflection { return new DummyConstantReflection($constantName); } public function getConstantStrings() : array { return []; } public function isCloneable() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isNull() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isConstantScalarValue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getConstantScalarTypes() : array { return []; } public function getConstantScalarValues() : array { return []; } public function isTrue() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFalse() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isBoolean() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFloat() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInteger() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNumericString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonEmptyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isNonFalsyString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLiteralString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isLowercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isUppercaseString() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isClassStringType() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getClassStringObjectType() : Type { return new ErrorType(); } public function getObjectTypeOrClassStringObjectType() : Type { return $this; } public function isVoid() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isScalar() : TrinaryLogic { return TrinaryLogic::createNo(); } public function looseCompare(Type $type, PhpVersion $phpVersion) : BooleanType { return new BooleanType(); } public function toNumber() : Type { return new ErrorType(); } public function toAbsoluteNumber() : Type { return new ErrorType(); } public function toString() : Type { return new ErrorType(); } public function toInteger() : Type { return new ErrorType(); } public function toFloat() : Type { return new ErrorType(); } public function toArray() : Type { return new ArrayType(new MixedType(), new MixedType()); } public function toArrayKey() : Type { return new StringType(); } } getUnresolvedPropertyPrototype($propertyName, $scope)->getTransformedProperty(); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { $property = new DummyPropertyReflection(); return new CallbackUnresolvedPropertyPrototypeReflection($property, $property->getDeclaringClass(), \false, static function (Type $type) : Type { return $type; }); } public function canCallMethods() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function hasMethod(string $methodName) : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { return $this->getUnresolvedMethodPrototype($methodName, $scope)->getTransformedMethod(); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { $method = new DummyMethodReflection($methodName); return new CallbackUnresolvedMethodPrototypeReflection($method, $method->getDeclaringClass(), \false, static function (Type $type) : Type { return $type; }); } public function canAccessConstants() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function hasConstant(string $constantName) : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getConstant(string $constantName) : ConstantReflection { return new DummyConstantReflection($constantName); } public function isCloneable() : TrinaryLogic { return TrinaryLogic::createMaybe(); } } types = $types; if (count($types) < 2) { throw new ShouldNotHappenException(sprintf('Cannot create %s with: %s', self::class, implode(', ', array_map(static function (\PHPStan\Type\Type $type) : string { return $type->describe(\PHPStan\Type\VerbosityLevel::value()); }, $types)))); } } /** * @return Type[] */ public function getTypes() : array { return $this->types; } /** * @return Type[] */ private function getSortedTypes() : array { if ($this->sortedTypes) { return $this->types; } $this->types = \PHPStan\Type\UnionTypeHelper::sortTypes($this->types); $this->sortedTypes = \true; return $this->types; } public function inferTemplateTypesOn(\PHPStan\Type\Type $templateType) : TemplateTypeMap { $types = TemplateTypeMap::createEmpty(); foreach ($this->types as $type) { $types = $types->intersect($templateType->inferTemplateTypes($type)); } return $types; } public function getReferencedClasses() : array { $classes = []; foreach ($this->types as $type) { foreach ($type->getReferencedClasses() as $className) { $classes[] = $className; } } return $classes; } public function getObjectClassNames() : array { $objectClassNames = []; foreach ($this->types as $type) { $innerObjectClassNames = $type->getObjectClassNames(); foreach ($innerObjectClassNames as $innerObjectClassName) { $objectClassNames[] = $innerObjectClassName; } } return array_values(array_unique($objectClassNames)); } public function getObjectClassReflections() : array { $reflections = []; foreach ($this->types as $type) { foreach ($type->getObjectClassReflections() as $reflection) { $reflections[] = $reflection; } } return $reflections; } public function getArrays() : array { $arrays = []; foreach ($this->types as $type) { foreach ($type->getArrays() as $array) { $arrays[] = $array; } } return $arrays; } public function getConstantArrays() : array { $constantArrays = []; foreach ($this->types as $type) { foreach ($type->getConstantArrays() as $constantArray) { $constantArrays[] = $constantArray; } } return $constantArrays; } public function getConstantStrings() : array { $strings = []; foreach ($this->types as $type) { foreach ($type->getConstantStrings() as $string) { $strings[] = $string; } } return $strings; } public function accepts(\PHPStan\Type\Type $type, bool $strictTypes) : TrinaryLogic { return $this->acceptsWithReason($type, $strictTypes)->result; } public function acceptsWithReason(\PHPStan\Type\Type $otherType, bool $strictTypes) : \PHPStan\Type\AcceptsResult { $result = \PHPStan\Type\AcceptsResult::createYes(); foreach ($this->types as $type) { $result = $result->and($type->acceptsWithReason($otherType, $strictTypes)); } if (!$result->yes()) { $isList = $otherType->isList(); $reasons = $result->reasons; $verbosity = \PHPStan\Type\VerbosityLevel::getRecommendedLevelByType($this, $otherType); if ($this->isList()->yes() && !$isList->yes()) { $reasons[] = sprintf('%s %s a list.', $otherType->describe($verbosity), $isList->no() ? 'is not' : 'might not be'); } $isNonEmpty = $otherType->isIterableAtLeastOnce(); if ($this->isIterableAtLeastOnce()->yes() && !$isNonEmpty->yes()) { $reasons[] = sprintf('%s %s empty.', $otherType->describe($verbosity), $isNonEmpty->no() ? 'is' : 'might be'); } if (count($reasons) > 0) { return new \PHPStan\Type\AcceptsResult($result->result, $reasons); } } return $result; } public function isSuperTypeOf(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->isSuperTypeOfWithReason($otherType)->result; } public function isSuperTypeOfWithReason(\PHPStan\Type\Type $otherType) : \PHPStan\Type\IsSuperTypeOfResult { if ($otherType instanceof \PHPStan\Type\IntersectionType && $this->equals($otherType)) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } if ($otherType instanceof \PHPStan\Type\NeverType) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } return \PHPStan\Type\IsSuperTypeOfResult::createYes()->and(...array_map(static function (\PHPStan\Type\Type $innerType) use($otherType) { return $innerType->isSuperTypeOfWithReason($otherType); }, $this->types)); } public function isSubTypeOf(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->isSubTypeOfWithReason($otherType)->result; } public function isSubTypeOfWithReason(\PHPStan\Type\Type $otherType) : \PHPStan\Type\IsSuperTypeOfResult { if (($otherType instanceof self || $otherType instanceof \PHPStan\Type\UnionType) && !$otherType instanceof TemplateType) { return $otherType->isSuperTypeOfWithReason($this); } $result = \PHPStan\Type\IsSuperTypeOfResult::maxMin(...array_map(static function (\PHPStan\Type\Type $innerType) use($otherType) { return $otherType->isSuperTypeOfWithReason($innerType); }, $this->types)); if ($this->isOversizedArray()->yes()) { if (!$result->no()) { return \PHPStan\Type\IsSuperTypeOfResult::createYes(); } } return $result; } public function isAcceptedBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : TrinaryLogic { return $this->isAcceptedWithReasonBy($acceptingType, $strictTypes)->result; } public function isAcceptedWithReasonBy(\PHPStan\Type\Type $acceptingType, bool $strictTypes) : \PHPStan\Type\AcceptsResult { $result = \PHPStan\Type\AcceptsResult::maxMin(...array_map(static function (\PHPStan\Type\Type $innerType) use($acceptingType, $strictTypes) { return $acceptingType->acceptsWithReason($innerType, $strictTypes); }, $this->types)); if ($this->isOversizedArray()->yes()) { if (!$result->no()) { return \PHPStan\Type\AcceptsResult::createYes(); } } return $result; } public function equals(\PHPStan\Type\Type $type) : bool { if (!$type instanceof static) { return \false; } if (count($this->types) !== count($type->types)) { return \false; } $otherTypes = $type->types; foreach ($this->types as $innerType) { $match = \false; foreach ($otherTypes as $i => $otherType) { if (!$innerType->equals($otherType)) { continue; } $match = \true; unset($otherTypes[$i]); break; } if (!$match) { return \false; } } return count($otherTypes) === 0; } public function describe(\PHPStan\Type\VerbosityLevel $level) : string { return $level->handle(function () use($level) : string { $typeNames = []; foreach ($this->getSortedTypes() as $type) { if ($type instanceof AccessoryType) { continue; } $typeNames[] = $type->generalize(\PHPStan\Type\GeneralizePrecision::lessSpecific())->describe($level); } return implode('&', $typeNames); }, function () use($level) : string { return $this->describeItself($level, \true); }, function () use($level) : string { return $this->describeItself($level, \false); }); } private function describeItself(\PHPStan\Type\VerbosityLevel $level, bool $skipAccessoryTypes) : string { $baseTypes = []; $typesToDescribe = []; $skipTypeNames = []; $nonEmptyStr = \false; $nonFalsyStr = \false; foreach ($this->getSortedTypes() as $i => $type) { if ($type instanceof AccessoryNonEmptyStringType || $type instanceof AccessoryLiteralStringType || $type instanceof AccessoryNumericStringType || $type instanceof AccessoryNonFalsyStringType || $type instanceof AccessoryLowercaseStringType || $type instanceof AccessoryUppercaseStringType) { if (($type instanceof AccessoryLowercaseStringType || $type instanceof AccessoryUppercaseStringType) && !$level->isPrecise()) { continue; } if ($type instanceof AccessoryNonFalsyStringType) { $nonFalsyStr = \true; } if ($type instanceof AccessoryNonEmptyStringType) { $nonEmptyStr = \true; } if ($nonEmptyStr && $nonFalsyStr) { // prevent redundant 'non-empty-string&non-falsy-string' foreach ($typesToDescribe as $key => $typeToDescribe) { if (!$typeToDescribe instanceof AccessoryNonEmptyStringType) { continue; } unset($typesToDescribe[$key]); } } $typesToDescribe[$i] = $type; $skipTypeNames[] = 'string'; continue; } if ($type instanceof NonEmptyArrayType || $type instanceof AccessoryArrayListType) { $typesToDescribe[$i] = $type; $skipTypeNames[] = 'array'; continue; } if ($type instanceof \PHPStan\Type\CallableType && $type->isCommonCallable()) { $typesToDescribe[$i] = $type; $skipTypeNames[] = 'object'; $skipTypeNames[] = 'string'; continue; } if (!$type instanceof AccessoryType) { $baseTypes[$i] = $type; continue; } if ($skipAccessoryTypes) { continue; } $typesToDescribe[$i] = $type; } $describedTypes = []; foreach ($baseTypes as $i => $type) { $typeDescription = $type->describe($level); if (in_array($typeDescription, ['object', 'string'], \true) && in_array($typeDescription, $skipTypeNames, \true)) { foreach ($typesToDescribe as $j => $typeToDescribe) { if ($typeToDescribe instanceof \PHPStan\Type\CallableType && $typeToDescribe->isCommonCallable()) { $describedTypes[$i] = 'callable-' . $typeDescription; unset($typesToDescribe[$j]); continue 2; } } } if (str_starts_with($typeDescription, 'array<') && in_array('array', $skipTypeNames, \true)) { $nonEmpty = \false; $typeName = 'array'; foreach ($typesToDescribe as $j => $typeToDescribe) { if ($typeToDescribe instanceof AccessoryArrayListType && substr($typeDescription, 0, strlen('array, ')) === 'array, ') { $typeName = 'list'; $typeDescription = 'array<' . substr($typeDescription, strlen('array, ')); } elseif ($typeToDescribe instanceof NonEmptyArrayType) { $nonEmpty = \true; } else { continue; } unset($typesToDescribe[$j]); } if ($nonEmpty) { $typeName = 'non-empty-' . $typeName; } $describedTypes[$i] = $typeName . '<' . substr($typeDescription, strlen('array<')); continue; } if (in_array($typeDescription, $skipTypeNames, \true)) { continue; } $describedTypes[$i] = $type->describe($level); } foreach ($typesToDescribe as $i => $typeToDescribe) { $describedTypes[$i] = $typeToDescribe->describe($level); } ksort($describedTypes); return implode('&', $describedTypes); } public function getTemplateType(string $ancestorClassName, string $templateTypeName) : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($ancestorClassName, $templateTypeName) : \PHPStan\Type\Type { return $type->getTemplateType($ancestorClassName, $templateTypeName); }); } public function isObject() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isObject(); }); } public function isEnum() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isEnum(); }); } public function canAccessProperties() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->canAccessProperties(); }); } public function hasProperty(string $propertyName) : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) use($propertyName) : TrinaryLogic { return $type->hasProperty($propertyName); }); } public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope) : PropertyReflection { return $this->getUnresolvedPropertyPrototype($propertyName, $scope)->getTransformedProperty(); } public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope) : UnresolvedPropertyPrototypeReflection { $propertyPrototypes = []; foreach ($this->types as $type) { if (!$type->hasProperty($propertyName)->yes()) { continue; } $propertyPrototypes[] = $type->getUnresolvedPropertyPrototype($propertyName, $scope)->withFechedOnType($this); } $propertiesCount = count($propertyPrototypes); if ($propertiesCount === 0) { throw new ShouldNotHappenException(); } if ($propertiesCount === 1) { return $propertyPrototypes[0]; } return new IntersectionTypeUnresolvedPropertyPrototypeReflection($propertyName, $propertyPrototypes); } public function canCallMethods() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->canCallMethods(); }); } public function hasMethod(string $methodName) : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) use($methodName) : TrinaryLogic { return $type->hasMethod($methodName); }); } public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope) : ExtendedMethodReflection { return $this->getUnresolvedMethodPrototype($methodName, $scope)->getTransformedMethod(); } public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAccessAnswerer $scope) : UnresolvedMethodPrototypeReflection { $methodPrototypes = []; foreach ($this->types as $type) { if (!$type->hasMethod($methodName)->yes()) { continue; } $methodPrototypes[] = $type->getUnresolvedMethodPrototype($methodName, $scope)->withCalledOnType($this); } $methodsCount = count($methodPrototypes); if ($methodsCount === 0) { throw new ShouldNotHappenException(); } if ($methodsCount === 1) { return $methodPrototypes[0]; } return new IntersectionTypeUnresolvedMethodPrototypeReflection($methodName, $methodPrototypes); } public function canAccessConstants() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->canAccessConstants(); }); } public function hasConstant(string $constantName) : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) use($constantName) : TrinaryLogic { return $type->hasConstant($constantName); }); } public function getConstant(string $constantName) : ConstantReflection { foreach ($this->types as $type) { if ($type->hasConstant($constantName)->yes()) { return $type->getConstant($constantName); } } throw new ShouldNotHappenException(); } public function isIterable() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isIterable(); }); } public function isIterableAtLeastOnce() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isIterableAtLeastOnce(); }); } public function getArraySize() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getArraySize(); }); } public function getIterableKeyType() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getIterableKeyType(); }); } public function getFirstIterableKeyType() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getFirstIterableKeyType(); }); } public function getLastIterableKeyType() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getLastIterableKeyType(); }); } public function getIterableValueType() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getIterableValueType(); }); } public function getFirstIterableValueType() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getFirstIterableValueType(); }); } public function getLastIterableValueType() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getLastIterableValueType(); }); } public function isArray() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isArray(); }); } public function isConstantArray() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isConstantArray(); }); } public function isOversizedArray() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isOversizedArray(); }); } public function isList() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isList(); }); } public function isString() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isString(); }); } public function isNumericString() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isNumericString(); }); } public function isNonEmptyString() : TrinaryLogic { if ($this->isCallable()->yes() && $this->isString()->yes()) { return TrinaryLogic::createYes(); } return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isNonEmptyString(); }); } public function isNonFalsyString() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isNonFalsyString(); }); } public function isLiteralString() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isLiteralString(); }); } public function isLowercaseString() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isLowercaseString(); }); } public function isUppercaseString() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isUppercaseString(); }); } public function isClassStringType() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isClassStringType(); }); } public function getClassStringObjectType() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getClassStringObjectType(); }); } public function getObjectTypeOrClassStringObjectType() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getObjectTypeOrClassStringObjectType(); }); } public function isVoid() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isVoid(); }); } public function isScalar() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isScalar(); }); } public function looseCompare(\PHPStan\Type\Type $type, PhpVersion $phpVersion) : \PHPStan\Type\BooleanType { return new \PHPStan\Type\BooleanType(); } public function isOffsetAccessible() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isOffsetAccessible(); }); } public function isOffsetAccessLegal() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isOffsetAccessLegal(); }); } public function hasOffsetValueType(\PHPStan\Type\Type $offsetType) : TrinaryLogic { if ($this->isList()->yes() && $this->isIterableAtLeastOnce()->yes()) { $arrayKeyOffsetType = $offsetType->toArrayKey(); if ((new ConstantIntegerType(0))->isSuperTypeOf($arrayKeyOffsetType)->yes()) { return TrinaryLogic::createYes(); } } return $this->intersectResults(static function (\PHPStan\Type\Type $type) use($offsetType) : TrinaryLogic { return $type->hasOffsetValueType($offsetType); }); } public function getOffsetValueType(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { $result = $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($offsetType) : \PHPStan\Type\Type { return $type->getOffsetValueType($offsetType); }); if ($this->isOversizedArray()->yes()) { return \PHPStan\Type\TypeUtils::toBenevolentUnion($result); } return $result; } public function setOffsetValueType(?\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType, bool $unionValues = \true) : \PHPStan\Type\Type { if ($this->isOversizedArray()->yes()) { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($offsetType, $valueType, $unionValues) : \PHPStan\Type\Type { // avoid new HasOffsetValueType being intersected with oversized array if (!$type instanceof \PHPStan\Type\ArrayType) { return $type->setOffsetValueType($offsetType, $valueType, $unionValues); } if (!$offsetType instanceof ConstantStringType && !$offsetType instanceof ConstantIntegerType) { return $type->setOffsetValueType($offsetType, $valueType, $unionValues); } if (!$offsetType->isSuperTypeOf($type->getKeyType())->yes()) { return $type->setOffsetValueType($offsetType, $valueType, $unionValues); } return \PHPStan\Type\TypeCombinator::intersect(new \PHPStan\Type\ArrayType(\PHPStan\Type\TypeCombinator::union($type->getKeyType(), $offsetType), \PHPStan\Type\TypeCombinator::union($type->getItemType(), $valueType)), new NonEmptyArrayType()); }); } $result = $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($offsetType, $valueType, $unionValues) : \PHPStan\Type\Type { return $type->setOffsetValueType($offsetType, $valueType, $unionValues); }); if ($offsetType !== null && $this->isList()->yes() && $this->isIterableAtLeastOnce()->yes() && (new ConstantIntegerType(1))->isSuperTypeOf($offsetType)->yes()) { $result = AccessoryArrayListType::intersectWith($result); } return $result; } public function setExistingOffsetValueType(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($offsetType, $valueType) : \PHPStan\Type\Type { return $type->setExistingOffsetValueType($offsetType, $valueType); }); } public function unsetOffset(\PHPStan\Type\Type $offsetType) : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($offsetType) : \PHPStan\Type\Type { return $type->unsetOffset($offsetType); }); } public function getKeysArray() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getKeysArray(); }); } public function getValuesArray() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getValuesArray(); }); } public function chunkArray(\PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($lengthType, $preserveKeys) : \PHPStan\Type\Type { return $type->chunkArray($lengthType, $preserveKeys); }); } public function fillKeysArray(\PHPStan\Type\Type $valueType) : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($valueType) : \PHPStan\Type\Type { return $type->fillKeysArray($valueType); }); } public function flipArray() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->flipArray(); }); } public function intersectKeyArray(\PHPStan\Type\Type $otherArraysType) : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($otherArraysType) : \PHPStan\Type\Type { return $type->intersectKeyArray($otherArraysType); }); } public function popArray() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->popArray(); }); } public function reverseArray(TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($preserveKeys) : \PHPStan\Type\Type { return $type->reverseArray($preserveKeys); }); } public function searchArray(\PHPStan\Type\Type $needleType) : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($needleType) : \PHPStan\Type\Type { return $type->searchArray($needleType); }); } public function shiftArray() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->shiftArray(); }); } public function shuffleArray() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->shuffleArray(); }); } public function sliceArray(\PHPStan\Type\Type $offsetType, \PHPStan\Type\Type $lengthType, TrinaryLogic $preserveKeys) : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($offsetType, $lengthType, $preserveKeys) : \PHPStan\Type\Type { return $type->sliceArray($offsetType, $lengthType, $preserveKeys); }); } public function getEnumCases() : array { $compare = []; foreach ($this->types as $type) { $oneType = []; foreach ($type->getEnumCases() as $enumCase) { $oneType[$enumCase->getClassName() . '::' . $enumCase->getEnumCaseName()] = $enumCase; } $compare[] = $oneType; } return array_values(array_intersect_key(...$compare)); } public function isCallable() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isCallable(); }); } public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope) : array { if ($this->isCallable()->no()) { throw new ShouldNotHappenException(); } return [new TrivialParametersAcceptor()]; } public function isCloneable() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isCloneable(); }); } public function isSmallerThan(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) use($otherType) : TrinaryLogic { return $type->isSmallerThan($otherType); }); } public function isSmallerThanOrEqual(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) use($otherType) : TrinaryLogic { return $type->isSmallerThanOrEqual($otherType); }); } public function isNull() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isNull(); }); } public function isConstantValue() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isConstantValue(); }); } public function isConstantScalarValue() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isConstantScalarValue(); }); } public function getConstantScalarTypes() : array { $scalarTypes = []; foreach ($this->types as $type) { foreach ($type->getConstantScalarTypes() as $scalarType) { $scalarTypes[] = $scalarType; } } return $scalarTypes; } public function getConstantScalarValues() : array { $values = []; foreach ($this->types as $type) { foreach ($type->getConstantScalarValues() as $value) { $values[] = $value; } } return $values; } public function isTrue() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isTrue(); }); } public function isFalse() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isFalse(); }); } public function isBoolean() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isBoolean(); }); } public function isFloat() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isFloat(); }); } public function isInteger() : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) : TrinaryLogic { return $type->isInteger(); }); } public function isGreaterThan(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) use($otherType) : TrinaryLogic { return $otherType->isSmallerThan($type); }); } public function isGreaterThanOrEqual(\PHPStan\Type\Type $otherType) : TrinaryLogic { return $this->intersectResults(static function (\PHPStan\Type\Type $type) use($otherType) : TrinaryLogic { return $otherType->isSmallerThanOrEqual($type); }); } public function getSmallerType() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getSmallerType(); }); } public function getSmallerOrEqualType() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getSmallerOrEqualType(); }); } public function getGreaterType() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getGreaterType(); }); } public function getGreaterOrEqualType() : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->getGreaterOrEqualType(); }); } public function toBoolean() : \PHPStan\Type\BooleanType { $type = $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\BooleanType { return $type->toBoolean(); }); if (!$type instanceof \PHPStan\Type\BooleanType) { return new \PHPStan\Type\BooleanType(); } return $type; } public function toNumber() : \PHPStan\Type\Type { $type = $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toNumber(); }); return $type; } public function toAbsoluteNumber() : \PHPStan\Type\Type { $type = $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toAbsoluteNumber(); }); return $type; } public function toString() : \PHPStan\Type\Type { $type = $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toString(); }); return $type; } public function toInteger() : \PHPStan\Type\Type { $type = $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toInteger(); }); return $type; } public function toFloat() : \PHPStan\Type\Type { $type = $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toFloat(); }); return $type; } public function toArray() : \PHPStan\Type\Type { $type = $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toArray(); }); return $type; } public function toArrayKey() : \PHPStan\Type\Type { if ($this->isNumericString()->yes()) { return \PHPStan\Type\TypeCombinator::union(new \PHPStan\Type\IntegerType(), $this); } if ($this->isString()->yes()) { return $this; } return $this->intersectTypes(static function (\PHPStan\Type\Type $type) : \PHPStan\Type\Type { return $type->toArrayKey(); }); } public function inferTemplateTypes(\PHPStan\Type\Type $receivedType) : TemplateTypeMap { $types = TemplateTypeMap::createEmpty(); foreach ($this->types as $type) { $types = $types->intersect($type->inferTemplateTypes($receivedType)); } return $types; } public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance) : array { $references = []; foreach ($this->types as $type) { foreach ($type->getReferencedTemplateTypes($positionVariance) as $reference) { $references[] = $reference; } } return $references; } public function traverse(callable $cb) : \PHPStan\Type\Type { $types = []; $changed = \false; foreach ($this->types as $type) { $newType = $cb($type); if ($type !== $newType) { $changed = \true; } $types[] = $newType; } if ($changed) { return \PHPStan\Type\TypeCombinator::intersect(...$types); } return $this; } public function traverseSimultaneously(\PHPStan\Type\Type $right, callable $cb) : \PHPStan\Type\Type { $types = []; $changed = \false; if (!$right instanceof self) { return $this; } if (count($this->getTypes()) !== count($right->getTypes())) { return $this; } foreach ($this->getSortedTypes() as $i => $leftType) { $rightType = $right->getSortedTypes()[$i]; $newType = $cb($leftType, $rightType); if ($leftType !== $newType) { $changed = \true; } $types[] = $newType; } if ($changed) { return \PHPStan\Type\TypeCombinator::intersect(...$types); } return $this; } public function tryRemove(\PHPStan\Type\Type $typeToRemove) : ?\PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($typeToRemove) : \PHPStan\Type\Type { return \PHPStan\Type\TypeCombinator::remove($type, $typeToRemove); }); } public function exponentiate(\PHPStan\Type\Type $exponent) : \PHPStan\Type\Type { return $this->intersectTypes(static function (\PHPStan\Type\Type $type) use($exponent) : \PHPStan\Type\Type { return $type->exponentiate($exponent); }); } public function getFiniteTypes() : array { $compare = []; foreach ($this->types as $type) { $oneType = []; foreach ($type->getFiniteTypes() as $finiteType) { $oneType[md5($finiteType->describe(\PHPStan\Type\VerbosityLevel::typeOnly()))] = $finiteType; } $compare[] = $oneType; } $result = array_values(array_intersect_key(...$compare)); if (count($result) > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT) { return []; } return $result; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : \PHPStan\Type\Type { return new self($properties['types']); } /** * @param callable(Type $type): TrinaryLogic $getResult */ private function intersectResults(callable $getResult) : TrinaryLogic { return TrinaryLogic::lazyMaxMin($this->types, $getResult); } /** * @param callable(Type $type): Type $getType */ private function intersectTypes(callable $getType) : \PHPStan\Type\Type { $operands = array_map($getType, $this->types); return \PHPStan\Type\TypeCombinator::intersect(...$operands); } public function toPhpDocNode() : TypeNode { $baseTypes = []; $typesToDescribe = []; $skipTypeNames = []; $nonEmptyStr = \false; $nonFalsyStr = \false; foreach ($this->getSortedTypes() as $i => $type) { if ($type instanceof AccessoryNonEmptyStringType || $type instanceof AccessoryLiteralStringType || $type instanceof AccessoryNumericStringType || $type instanceof AccessoryNonFalsyStringType || $type instanceof AccessoryLowercaseStringType || $type instanceof AccessoryUppercaseStringType) { if ($type instanceof AccessoryNonFalsyStringType) { $nonFalsyStr = \true; } if ($type instanceof AccessoryNonEmptyStringType) { $nonEmptyStr = \true; } if ($nonEmptyStr && $nonFalsyStr) { // prevent redundant 'non-empty-string&non-falsy-string' foreach ($typesToDescribe as $key => $typeToDescribe) { if (!$typeToDescribe instanceof AccessoryNonEmptyStringType) { continue; } unset($typesToDescribe[$key]); } } $typesToDescribe[$i] = $type; $skipTypeNames[] = 'string'; continue; } if ($type instanceof NonEmptyArrayType || $type instanceof AccessoryArrayListType) { $typesToDescribe[$i] = $type; $skipTypeNames[] = 'array'; continue; } if (!$type instanceof AccessoryType) { $baseTypes[$i] = $type; continue; } $accessoryPhpDocNode = $type->toPhpDocNode(); if ($accessoryPhpDocNode instanceof IdentifierTypeNode && $accessoryPhpDocNode->name === '') { continue; } $typesToDescribe[$i] = $type; } $describedTypes = []; foreach ($baseTypes as $i => $type) { $typeNode = $type->toPhpDocNode(); if ($typeNode instanceof GenericTypeNode && $typeNode->type->name === 'array') { $nonEmpty = \false; $typeName = 'array'; foreach ($typesToDescribe as $j => $typeToDescribe) { if ($typeToDescribe instanceof AccessoryArrayListType) { $typeName = 'list'; if (count($typeNode->genericTypes) > 1) { array_shift($typeNode->genericTypes); } } elseif ($typeToDescribe instanceof NonEmptyArrayType) { $nonEmpty = \true; } else { continue; } unset($typesToDescribe[$j]); } if ($nonEmpty) { $typeName = 'non-empty-' . $typeName; } $describedTypes[$i] = new GenericTypeNode(new IdentifierTypeNode($typeName), $typeNode->genericTypes); continue; } if ($typeNode instanceof IdentifierTypeNode && in_array($typeNode->name, $skipTypeNames, \true)) { continue; } $describedTypes[$i] = $typeNode; } foreach ($typesToDescribe as $i => $typeToDescribe) { $describedTypes[$i] = $typeToDescribe->toPhpDocNode(); } ksort($describedTypes); $describedTypes = array_values($describedTypes); if (count($describedTypes) === 1) { return $describedTypes[0]; } return new IntersectionTypeNode($describedTypes); } } mapInternal($left, $right); } /** @param callable(Type $left, Type $right, callable(Type, Type): Type $traverse): Type $cb */ private function __construct(callable $cb) { $this->cb = $cb; } /** @internal */ public function mapInternal(\PHPStan\Type\Type $left, \PHPStan\Type\Type $right) : \PHPStan\Type\Type { return ($this->cb)($left, $right, [$this, 'traverseInternal']); } /** @internal */ public function traverseInternal(\PHPStan\Type\Type $left, \PHPStan\Type\Type $right) : \PHPStan\Type\Type { return $left->traverseSimultaneously($right, [$this, 'mapInternal']); } } className = $className; parent::__construct(sprintf('Class %s was not found while trying to analyse it - discovering symbols is probably not configured properly.', $className)); } public function getClassName() : string { return $this->className; } public function getTip() : string { return 'Learn more at https://phpstan.org/user-guide/discovering-symbols'; } } fileHelper = $fileHelper; $this->relativePathHelper = $relativePathHelper; } public function getAnonymousClassName(Node\Stmt\Class_ $classNode, string $filename) : string { if (isset($classNode->namespacedName)) { throw new ShouldNotHappenException(); } $filename = $this->relativePathHelper->getRelativePath($this->fileHelper->normalizePath($filename, '/')); /** @var int|null $lineIndex */ $lineIndex = $classNode->getAttribute(AnonymousClassVisitor::ATTRIBUTE_LINE_INDEX); if ($lineIndex === null) { $hash = md5(sprintf('%s:%s', $filename, $classNode->getStartLine())); } else { $hash = md5(sprintf('%s:%s:%d', $filename, $classNode->getStartLine(), $lineIndex)); } return sprintf('AnonymousClass%s', $hash); } } getMessage(), $functionName), 0, $previous); } else { parent::__construct(sprintf('Class %s not found.', $functionName), 0); } $this->className = $functionName; } public function getClassName() : string { return $this->className; } public function getTip() : string { return 'Learn more at https://phpstan.org/user-guide/discovering-symbols'; } } constantName = $constantName; parent::__construct(sprintf('Constant %s not found.', $constantName)); } public function getConstantName() : string { return $this->constantName; } public function getTip() : string { return 'Learn more at https://phpstan.org/user-guide/discovering-symbols'; } } functionName = $functionName; parent::__construct(sprintf('Function %s not found while trying to analyse it - discovering symbols is probably not configured properly.', $functionName)); } public function getFunctionName() : string { return $this->functionName; } public function getTip() : string { return 'Learn more at https://phpstan.org/user-guide/discovering-symbols'; } } reflectionProvider = $reflectionProvider; $this->universalObjectCratesClasses = $universalObjectCratesClasses; } public static function registerInstance(\PHPStan\Broker\Broker $broker) : void { self::$instance = $broker; } /** * @deprecated Use PHPStan\Reflection\ReflectionProviderStaticAccessor instead */ public static function getInstance() : \PHPStan\Broker\Broker { if (self::$instance === null) { throw new ShouldNotHappenException(); } return self::$instance; } /** * @deprecated Use PHPStan\Reflection\ReflectionProvider instead */ public function hasClass(string $className) : bool { return $this->reflectionProvider->hasClass($className); } /** * @deprecated Use PHPStan\Reflection\ReflectionProvider instead */ public function getClass(string $className) : ClassReflection { return $this->reflectionProvider->getClass($className); } /** * @deprecated Use PHPStan\Reflection\ReflectionProvider instead */ public function getClassName(string $className) : string { return $this->reflectionProvider->getClassName($className); } /** * @deprecated Use PHPStan\Reflection\ReflectionProvider instead */ public function supportsAnonymousClasses() : bool { return $this->reflectionProvider->supportsAnonymousClasses(); } /** * @deprecated Use PHPStan\Reflection\ReflectionProvider instead */ public function getAnonymousClassReflection(Node\Stmt\Class_ $classNode, Scope $scope) : ClassReflection { return $this->reflectionProvider->getAnonymousClassReflection($classNode, $scope); } /** * @deprecated Use PHPStan\Reflection\ReflectionProvider instead */ public function hasFunction(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : bool { return $this->reflectionProvider->hasFunction($nameNode, $namespaceAnswerer); } /** * @deprecated Use PHPStan\Reflection\ReflectionProvider instead */ public function getFunction(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : FunctionReflection { return $this->reflectionProvider->getFunction($nameNode, $namespaceAnswerer); } /** * @deprecated Use PHPStan\Reflection\ReflectionProvider instead */ public function resolveFunctionName(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : ?string { return $this->reflectionProvider->resolveFunctionName($nameNode, $namespaceAnswerer); } /** * @deprecated Use PHPStan\Reflection\ReflectionProvider instead */ public function hasConstant(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : bool { return $this->reflectionProvider->hasConstant($nameNode, $namespaceAnswerer); } /** * @deprecated Use PHPStan\Reflection\ReflectionProvider instead */ public function getConstant(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : GlobalConstantReflection { return $this->reflectionProvider->getConstant($nameNode, $namespaceAnswerer); } /** * @deprecated Use PHPStan\Reflection\ReflectionProvider instead */ public function resolveConstantName(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : ?string { return $this->reflectionProvider->resolveConstantName($nameNode, $namespaceAnswerer); } /** * @deprecated Inject %universalObjectCratesClasses% parameter instead. * * @return string[] */ public function getUniversalObjectCratesClasses() : array { return $this->universalObjectCratesClasses; } } container = $container; } public function create() : \PHPStan\Broker\Broker { return new \PHPStan\Broker\Broker($this->container->getByType(ReflectionProvider::class), $this->container->getParameter('universalObjectCratesClasses')); } } registry = $registry; } public function getRegistry() : \PHPStan\PhpDoc\TypeNodeResolverExtensionRegistry { return $this->registry; } } */ private $genericTypeResolvingStack = []; public function __construct(\PHPStan\PhpDoc\TypeNodeResolverExtensionRegistryProvider $extensionRegistryProvider, ReflectionProvider\ReflectionProviderProvider $reflectionProviderProvider, TypeAliasResolverProvider $typeAliasResolverProvider, ConstantResolver $constantResolver, InitializerExprTypeResolver $initializerExprTypeResolver) { $this->extensionRegistryProvider = $extensionRegistryProvider; $this->reflectionProviderProvider = $reflectionProviderProvider; $this->typeAliasResolverProvider = $typeAliasResolverProvider; $this->constantResolver = $constantResolver; $this->initializerExprTypeResolver = $initializerExprTypeResolver; } /** @api */ public function resolve(TypeNode $typeNode, NameScope $nameScope) : Type { foreach ($this->extensionRegistryProvider->getRegistry()->getExtensions() as $extension) { $type = $extension->resolve($typeNode, $nameScope); if ($type !== null) { return $type; } } if ($typeNode instanceof IdentifierTypeNode) { return $this->resolveIdentifierTypeNode($typeNode, $nameScope); } elseif ($typeNode instanceof ThisTypeNode) { return $this->resolveThisTypeNode($typeNode, $nameScope); } elseif ($typeNode instanceof NullableTypeNode) { return $this->resolveNullableTypeNode($typeNode, $nameScope); } elseif ($typeNode instanceof UnionTypeNode) { return $this->resolveUnionTypeNode($typeNode, $nameScope); } elseif ($typeNode instanceof IntersectionTypeNode) { return $this->resolveIntersectionTypeNode($typeNode, $nameScope); } elseif ($typeNode instanceof ConditionalTypeNode) { return $this->resolveConditionalTypeNode($typeNode, $nameScope); } elseif ($typeNode instanceof ConditionalTypeForParameterNode) { return $this->resolveConditionalTypeForParameterNode($typeNode, $nameScope); } elseif ($typeNode instanceof ArrayTypeNode) { return $this->resolveArrayTypeNode($typeNode, $nameScope); } elseif ($typeNode instanceof GenericTypeNode) { return $this->resolveGenericTypeNode($typeNode, $nameScope); } elseif ($typeNode instanceof CallableTypeNode) { return $this->resolveCallableTypeNode($typeNode, $nameScope); } elseif ($typeNode instanceof ArrayShapeNode) { return $this->resolveArrayShapeNode($typeNode, $nameScope); } elseif ($typeNode instanceof ObjectShapeNode) { return $this->resolveObjectShapeNode($typeNode, $nameScope); } elseif ($typeNode instanceof ConstTypeNode) { return $this->resolveConstTypeNode($typeNode, $nameScope); } elseif ($typeNode instanceof OffsetAccessTypeNode) { return $this->resolveOffsetAccessNode($typeNode, $nameScope); } elseif ($typeNode instanceof InvalidTypeNode) { return new MixedType(\true); } return new ErrorType(); } private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameScope $nameScope) : Type { switch (strtolower($typeNode->name)) { case 'int': case 'integer': return new IntegerType(); case 'positive-int': return IntegerRangeType::fromInterval(1, null); case 'negative-int': return IntegerRangeType::fromInterval(null, -1); case 'non-positive-int': return IntegerRangeType::fromInterval(null, 0); case 'non-negative-int': return IntegerRangeType::fromInterval(0, null); case 'non-zero-int': return new UnionType([IntegerRangeType::fromInterval(null, -1), IntegerRangeType::fromInterval(1, null)]); case 'string': return new StringType(); case 'lowercase-string': return new IntersectionType([new StringType(), new AccessoryLowercaseStringType()]); case 'uppercase-string': return new IntersectionType([new StringType(), new AccessoryUppercaseStringType()]); case 'literal-string': return new IntersectionType([new StringType(), new AccessoryLiteralStringType()]); case 'class-string': case 'interface-string': case 'trait-string': case 'enum-string': return new ClassStringType(); case 'callable-string': return new IntersectionType([new StringType(), new CallableType()]); case 'array-key': return new BenevolentUnionType([new IntegerType(), new StringType()]); case 'scalar': $type = $this->tryResolvePseudoTypeClassType($typeNode, $nameScope); if ($type !== null) { return $type; } return new UnionType([new IntegerType(), new FloatType(), new StringType(), new BooleanType()]); case 'empty-scalar': return TypeCombinator::intersect(new UnionType([new IntegerType(), new FloatType(), new StringType(), new BooleanType()]), StaticTypeFactory::falsey()); case 'non-empty-scalar': return TypeCombinator::remove(new UnionType([new IntegerType(), new FloatType(), new StringType(), new BooleanType()]), StaticTypeFactory::falsey()); case 'number': $type = $this->tryResolvePseudoTypeClassType($typeNode, $nameScope); if ($type !== null) { return $type; } return new UnionType([new IntegerType(), new FloatType()]); case 'numeric': $type = $this->tryResolvePseudoTypeClassType($typeNode, $nameScope); if ($type !== null) { return $type; } return new UnionType([new IntegerType(), new FloatType(), new IntersectionType([new StringType(), new AccessoryNumericStringType()])]); case 'numeric-string': return new IntersectionType([new StringType(), new AccessoryNumericStringType()]); case 'non-empty-string': return new IntersectionType([new StringType(), new AccessoryNonEmptyStringType()]); case 'non-empty-lowercase-string': return new IntersectionType([new StringType(), new AccessoryNonEmptyStringType(), new AccessoryLowercaseStringType()]); case 'non-empty-uppercase-string': return new IntersectionType([new StringType(), new AccessoryNonEmptyStringType(), new AccessoryUppercaseStringType()]); case 'truthy-string': case 'non-falsy-string': return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); case 'non-empty-literal-string': return new IntersectionType([new StringType(), new AccessoryNonEmptyStringType(), new AccessoryLiteralStringType()]); case 'bool': return new BooleanType(); case 'boolean': $type = $this->tryResolvePseudoTypeClassType($typeNode, $nameScope); if ($type !== null) { return $type; } return new BooleanType(); case 'true': return new ConstantBooleanType(\true); case 'false': return new ConstantBooleanType(\false); case 'null': return new NullType(); case 'float': return new FloatType(); case 'double': $type = $this->tryResolvePseudoTypeClassType($typeNode, $nameScope); if ($type !== null) { return $type; } return new FloatType(); case 'array': case 'associative-array': return new ArrayType(new MixedType(), new MixedType()); case 'non-empty-array': return TypeCombinator::intersect(new ArrayType(new MixedType(), new MixedType()), new NonEmptyArrayType()); case 'iterable': return new IterableType(new MixedType(), new MixedType()); case 'callable': return new CallableType(); case 'pure-callable': return new CallableType(null, null, \true, null, null, [], TrinaryLogic::createYes()); case 'pure-closure': return ClosureType::createPure(); case 'resource': $type = $this->tryResolvePseudoTypeClassType($typeNode, $nameScope); if ($type !== null) { return $type; } return new ResourceType(); case 'open-resource': case 'closed-resource': return new ResourceType(); case 'mixed': return new MixedType(\true); case 'non-empty-mixed': return new MixedType(\true, StaticTypeFactory::falsey()); case 'void': return new VoidType(); case 'object': return new ObjectWithoutClassType(); case 'callable-object': return new IntersectionType([new ObjectWithoutClassType(), new CallableType()]); case 'callable-array': return new IntersectionType([new ArrayType(new MixedType(), new MixedType()), new CallableType()]); case 'never': case 'noreturn': $type = $this->tryResolvePseudoTypeClassType($typeNode, $nameScope); if ($type !== null) { return $type; } return new NonAcceptingNeverType(); case 'never-return': case 'never-returns': case 'no-return': return new NonAcceptingNeverType(); case 'list': return AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new MixedType())); case 'non-empty-list': return AccessoryArrayListType::intersectWith(TypeCombinator::intersect(new ArrayType(new IntegerType(), new MixedType()), new NonEmptyArrayType())); case '__always-list': return TypeCombinator::intersect(new ArrayType(new IntegerType(), new MixedType()), new AccessoryArrayListType()); case 'empty': $type = $this->tryResolvePseudoTypeClassType($typeNode, $nameScope); if ($type !== null) { return $type; } return StaticTypeFactory::falsey(); case '__stringandstringable': return new StringAlwaysAcceptingObjectWithToStringType(); } if ($nameScope->getClassName() !== null) { switch (strtolower($typeNode->name)) { case 'self': return new ObjectType($nameScope->getClassName()); case 'static': if ($this->getReflectionProvider()->hasClass($nameScope->getClassName())) { $classReflection = $this->getReflectionProvider()->getClass($nameScope->getClassName()); return new StaticType($classReflection); } return new ErrorType(); case 'parent': if ($this->getReflectionProvider()->hasClass($nameScope->getClassName())) { $classReflection = $this->getReflectionProvider()->getClass($nameScope->getClassName()); if ($classReflection->getParentClass() !== null) { return new ObjectType($classReflection->getParentClass()->getName()); } } return new NonexistentParentClassType(); } } if (!$nameScope->shouldBypassTypeAliases()) { $typeAlias = $this->getTypeAliasResolver()->resolveTypeAlias($typeNode->name, $nameScope); if ($typeAlias !== null) { return $typeAlias; } } $templateType = $nameScope->resolveTemplateTypeName($typeNode->name); if ($templateType !== null) { return $templateType; } $stringName = $nameScope->resolveStringName($typeNode->name); if (str_contains($stringName, '-') && !str_starts_with($stringName, 'OCI-')) { return new ErrorType(); } if ($this->mightBeConstant($typeNode->name) && !$this->getReflectionProvider()->hasClass($stringName)) { $constType = $this->tryResolveConstant($typeNode->name, $nameScope); if ($constType !== null) { return $constType; } } return new ObjectType($stringName); } private function mightBeConstant(string $name) : bool { return preg_match('((?:^|\\\\)[A-Z_][A-Z0-9_]*$)', $name) > 0; } private function tryResolveConstant(string $name, NameScope $nameScope) : ?Type { foreach ($nameScope->resolveConstantNames($name) as $constName) { $nameNode = new Name\FullyQualified(explode('\\', $constName)); $constType = $this->constantResolver->resolveConstant($nameNode, null); if ($constType !== null) { return $constType; } } return null; } private function tryResolvePseudoTypeClassType(IdentifierTypeNode $typeNode, NameScope $nameScope) : ?Type { if ($nameScope->hasUseAlias($typeNode->name)) { return new ObjectType($nameScope->resolveStringName($typeNode->name)); } if ($nameScope->getNamespace() === null) { return null; } $className = $nameScope->resolveStringName($typeNode->name); if ($this->getReflectionProvider()->hasClass($className)) { return new ObjectType($className); } return null; } private function resolveThisTypeNode(ThisTypeNode $typeNode, NameScope $nameScope) : Type { $className = $nameScope->getClassName(); if ($className !== null) { if ($this->getReflectionProvider()->hasClass($className)) { return new ThisType($this->getReflectionProvider()->getClass($className)); } } return new ErrorType(); } private function resolveNullableTypeNode(NullableTypeNode $typeNode, NameScope $nameScope) : Type { return TypeCombinator::union($this->resolve($typeNode->type, $nameScope), new NullType()); } private function resolveUnionTypeNode(UnionTypeNode $typeNode, NameScope $nameScope) : Type { $iterableTypeNodes = []; $otherTypeNodes = []; foreach ($typeNode->types as $innerTypeNode) { if ($innerTypeNode instanceof ArrayTypeNode) { $iterableTypeNodes[] = $innerTypeNode->type; } else { $otherTypeNodes[] = $innerTypeNode; } } $otherTypeTypes = $this->resolveMultiple($otherTypeNodes, $nameScope); if (count($iterableTypeNodes) > 0) { $arrayTypeTypes = $this->resolveMultiple($iterableTypeNodes, $nameScope); $arrayTypeType = TypeCombinator::union(...$arrayTypeTypes); $addArray = \true; foreach ($otherTypeTypes as &$type) { if (!$type->isIterable()->yes() || !$type->getIterableValueType()->isSuperTypeOf($arrayTypeType)->yes()) { continue; } if ($type instanceof ObjectType) { $type = new IntersectionType([$type, new IterableType(new MixedType(), $arrayTypeType)]); } elseif ($type instanceof ArrayType) { $type = new ArrayType(new MixedType(), $arrayTypeType); } elseif ($type instanceof IterableType) { $type = new IterableType(new MixedType(), $arrayTypeType); } else { continue; } $addArray = \false; } if ($addArray) { $otherTypeTypes[] = new ArrayType(new MixedType(), $arrayTypeType); } } return TypeCombinator::union(...$otherTypeTypes); } private function resolveIntersectionTypeNode(IntersectionTypeNode $typeNode, NameScope $nameScope) : Type { $types = $this->resolveMultiple($typeNode->types, $nameScope); return TypeCombinator::intersect(...$types); } private function resolveConditionalTypeNode(ConditionalTypeNode $typeNode, NameScope $nameScope) : Type { return new ConditionalType($this->resolve($typeNode->subjectType, $nameScope), $this->resolve($typeNode->targetType, $nameScope), $this->resolve($typeNode->if, $nameScope), $this->resolve($typeNode->else, $nameScope), $typeNode->negated); } private function resolveConditionalTypeForParameterNode(ConditionalTypeForParameterNode $typeNode, NameScope $nameScope) : Type { return new ConditionalTypeForParameter($typeNode->parameterName, $this->resolve($typeNode->targetType, $nameScope), $this->resolve($typeNode->if, $nameScope), $this->resolve($typeNode->else, $nameScope), $typeNode->negated); } private function resolveArrayTypeNode(ArrayTypeNode $typeNode, NameScope $nameScope) : Type { $itemType = $this->resolve($typeNode->type, $nameScope); return new ArrayType(new BenevolentUnionType([new IntegerType(), new StringType()]), $itemType); } private function resolveGenericTypeNode(GenericTypeNode $typeNode, NameScope $nameScope) : Type { $mainTypeName = strtolower($typeNode->type->name); $genericTypes = $this->resolveMultiple($typeNode->genericTypes, $nameScope); $variances = array_map(static function (string $variance) : TemplateTypeVariance { switch ($variance) { case GenericTypeNode::VARIANCE_INVARIANT: return TemplateTypeVariance::createInvariant(); case GenericTypeNode::VARIANCE_COVARIANT: return TemplateTypeVariance::createCovariant(); case GenericTypeNode::VARIANCE_CONTRAVARIANT: return TemplateTypeVariance::createContravariant(); case GenericTypeNode::VARIANCE_BIVARIANT: return TemplateTypeVariance::createBivariant(); } }, $typeNode->variances); if (in_array($mainTypeName, ['array', 'non-empty-array'], \true)) { if (count($genericTypes) === 1) { // array $arrayType = new ArrayType(new BenevolentUnionType([new IntegerType(), new StringType()]), $genericTypes[0]); } elseif (count($genericTypes) === 2) { // array $keyType = TypeCombinator::intersect($genericTypes[0], new UnionType([new IntegerType(), new StringType()])); $arrayType = new ArrayType($keyType->toArrayKey(), $genericTypes[1]); } else { return new ErrorType(); } if ($mainTypeName === 'non-empty-array') { return TypeCombinator::intersect($arrayType, new NonEmptyArrayType()); } return $arrayType; } elseif (in_array($mainTypeName, ['list', 'non-empty-list'], \true)) { if (count($genericTypes) === 1) { // list $listType = AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $genericTypes[0])); if ($mainTypeName === 'non-empty-list') { return TypeCombinator::intersect($listType, new NonEmptyArrayType()); } return $listType; } return new ErrorType(); } elseif ($mainTypeName === 'iterable') { if (count($genericTypes) === 1) { // iterable return new IterableType(new MixedType(\true), $genericTypes[0]); } if (count($genericTypes) === 2) { // iterable return new IterableType($genericTypes[0], $genericTypes[1]); } } elseif (in_array($mainTypeName, ['class-string', 'interface-string'], \true)) { if (count($genericTypes) === 1) { $genericType = $genericTypes[0]; if ($genericType->isObject()->yes() || $genericType instanceof MixedType) { return new GenericClassStringType($genericType); } } return new ErrorType(); } elseif ($mainTypeName === 'int') { if (count($genericTypes) === 2) { // int, int<1, 3> if ($genericTypes[0] instanceof ConstantIntegerType) { $min = $genericTypes[0]->getValue(); } elseif ($typeNode->genericTypes[0] instanceof IdentifierTypeNode && $typeNode->genericTypes[0]->name === 'min') { $min = null; } else { return new ErrorType(); } if ($genericTypes[1] instanceof ConstantIntegerType) { $max = $genericTypes[1]->getValue(); } elseif ($typeNode->genericTypes[1] instanceof IdentifierTypeNode && $typeNode->genericTypes[1]->name === 'max') { $max = null; } else { return new ErrorType(); } return IntegerRangeType::fromInterval($min, $max); } } elseif ($mainTypeName === 'key-of') { if (count($genericTypes) === 1) { // key-of $type = new KeyOfType($genericTypes[0]); return $type->isResolvable() ? $type->resolve() : $type; } return new ErrorType(); } elseif ($mainTypeName === 'value-of') { if (count($genericTypes) === 1) { // value-of $type = new ValueOfType($genericTypes[0]); return $type->isResolvable() ? $type->resolve() : $type; } return new ErrorType(); } elseif ($mainTypeName === 'int-mask-of') { if (count($genericTypes) === 1) { // int-mask-of $maskType = $this->expandIntMaskToType($genericTypes[0]); if ($maskType !== null) { return $maskType; } } return new ErrorType(); } elseif ($mainTypeName === 'int-mask') { if (count($genericTypes) > 0) { // int-mask<1, 2, 4> $maskType = $this->expandIntMaskToType(TypeCombinator::union(...$genericTypes)); if ($maskType !== null) { return $maskType; } } return new ErrorType(); } elseif ($mainTypeName === '__benevolent') { if (count($genericTypes) === 1) { return TypeUtils::toBenevolentUnion($genericTypes[0]); } return new ErrorType(); } elseif ($mainTypeName === 'template-type') { if (count($genericTypes) === 3) { $result = []; /** @var class-string $ancestorClassName */ foreach ($genericTypes[1]->getObjectClassNames() as $ancestorClassName) { foreach ($genericTypes[2]->getConstantStrings() as $templateTypeName) { $result[] = new GetTemplateTypeType($genericTypes[0], $ancestorClassName, $templateTypeName->getValue()); } } return TypeCombinator::union(...$result); } return new ErrorType(); } elseif ($mainTypeName === 'new') { if (count($genericTypes) === 1) { $type = new NewObjectType($genericTypes[0]); return $type->isResolvable() ? $type->resolve() : $type; } return new ErrorType(); } elseif ($mainTypeName === 'static') { if ($nameScope->getClassName() !== null && $this->getReflectionProvider()->hasClass($nameScope->getClassName())) { $classReflection = $this->getReflectionProvider()->getClass($nameScope->getClassName()); return new GenericStaticType($classReflection, $genericTypes, null, $variances); } return new ErrorType(); } $mainType = $this->resolveIdentifierTypeNode($typeNode->type, $nameScope); $mainTypeObjectClassNames = $mainType->getObjectClassNames(); if (count($mainTypeObjectClassNames) > 1) { if ($mainType instanceof TemplateType) { return new ErrorType(); } throw new ShouldNotHappenException(); } $mainTypeClassName = $mainTypeObjectClassNames[0] ?? null; if ($mainTypeClassName !== null) { if (!$this->getReflectionProvider()->hasClass($mainTypeClassName)) { return new GenericObjectType($mainTypeClassName, $genericTypes, null, null, $variances); } $classReflection = $this->getReflectionProvider()->getClass($mainTypeClassName); if ($classReflection->isGeneric()) { $templateTypes = array_values($classReflection->getTemplateTypeMap()->getTypes()); for ($i = count($genericTypes), $templateTypesCount = count($templateTypes); $i < $templateTypesCount; $i++) { $templateType = $templateTypes[$i]; if (!$templateType instanceof TemplateType || $templateType->getDefault() === null) { continue; } $genericTypes[] = $templateType->getDefault(); } if (in_array($mainTypeClassName, [Traversable::class, IteratorAggregate::class, Iterator::class], \true)) { if (count($genericTypes) === 1) { return new GenericObjectType($mainTypeClassName, [new MixedType(\true), $genericTypes[0]], null, null, [TemplateTypeVariance::createInvariant(), $variances[0]]); } if (count($genericTypes) === 2) { return new GenericObjectType($mainTypeClassName, [$genericTypes[0], $genericTypes[1]], null, null, [$variances[0], $variances[1]]); } } if ($mainTypeClassName === Generator::class) { if (count($genericTypes) === 1) { $mixed = new MixedType(\true); return new GenericObjectType($mainTypeClassName, [$mixed, $genericTypes[0], $mixed, $mixed], null, null, [TemplateTypeVariance::createInvariant(), $variances[0], TemplateTypeVariance::createInvariant(), TemplateTypeVariance::createInvariant()]); } if (count($genericTypes) === 2) { $mixed = new MixedType(\true); return new GenericObjectType($mainTypeClassName, [$genericTypes[0], $genericTypes[1], $mixed, $mixed], null, null, [$variances[0], $variances[1], TemplateTypeVariance::createInvariant(), TemplateTypeVariance::createInvariant()]); } } if (!$mainType->isIterable()->yes()) { return new GenericObjectType($mainTypeClassName, $genericTypes, null, null, $variances); } if (count($genericTypes) !== 1 || $classReflection->getTemplateTypeMap()->count() === 1) { return new GenericObjectType($mainTypeClassName, $genericTypes, null, null, $variances); } } } if ($mainType->isIterable()->yes()) { if ($mainTypeClassName !== null) { if (isset($this->genericTypeResolvingStack[$mainTypeClassName])) { return new ErrorType(); } $this->genericTypeResolvingStack[$mainTypeClassName] = \true; } try { if (count($genericTypes) === 1) { // Foo return TypeCombinator::intersect($mainType, new IterableType(new MixedType(\true), $genericTypes[0])); } if (count($genericTypes) === 2) { // Foo return TypeCombinator::intersect($mainType, new IterableType($genericTypes[0], $genericTypes[1])); } } finally { if ($mainTypeClassName !== null) { unset($this->genericTypeResolvingStack[$mainTypeClassName]); } } } if ($mainTypeClassName !== null) { return new GenericObjectType($mainTypeClassName, $genericTypes, null, null, $variances); } return new ErrorType(); } private function resolveCallableTypeNode(CallableTypeNode $typeNode, NameScope $nameScope) : Type { $templateTags = []; if (count($typeNode->templateTypes ?? []) > 0) { foreach ($typeNode->templateTypes as $templateType) { $templateTags[$templateType->name] = new TemplateTag($templateType->name, $templateType->bound !== null ? $this->resolve($templateType->bound, $nameScope) : new MixedType(), $templateType->default !== null ? $this->resolve($templateType->default, $nameScope) : null, TemplateTypeVariance::createInvariant()); } $templateTypeScope = TemplateTypeScope::createWithAnonymousFunction(); $templateTypeMap = new TemplateTypeMap(array_map(static function (TemplateTag $tag) use($templateTypeScope) : Type { return TemplateTypeFactory::fromTemplateTag($templateTypeScope, $tag); }, $templateTags)); $nameScope = $nameScope->withTemplateTypeMap($templateTypeMap); } else { $templateTypeMap = TemplateTypeMap::createEmpty(); } $mainType = $this->resolve($typeNode->identifier, $nameScope); $isVariadic = \false; $parameters = array_map(function (CallableTypeParameterNode $parameterNode) use($nameScope, &$isVariadic) : NativeParameterReflection { $isVariadic = $isVariadic || $parameterNode->isVariadic; $parameterName = $parameterNode->parameterName; if (str_starts_with($parameterName, '$')) { $parameterName = substr($parameterName, 1); } return new NativeParameterReflection($parameterName, $parameterNode->isOptional || $parameterNode->isVariadic, $this->resolve($parameterNode->type, $nameScope), $parameterNode->isReference ? PassedByReference::createCreatesNewVariable() : PassedByReference::createNo(), $parameterNode->isVariadic, null); }, $typeNode->parameters); $returnType = $this->resolve($typeNode->returnType, $nameScope); if ($mainType instanceof CallableType) { $pure = $mainType->isPure(); if ($pure->yes() && $returnType->isVoid()->yes()) { return new ErrorType(); } return new CallableType($parameters, $returnType, $isVariadic, $templateTypeMap, null, $templateTags, $pure); } elseif ($mainType instanceof ObjectType && $mainType->getClassName() === Closure::class) { return new ClosureType($parameters, $returnType, $isVariadic, $templateTypeMap, null, null, $templateTags, [], [new SimpleImpurePoint('functionCall', 'call to a Closure', \false)]); } elseif ($mainType instanceof ClosureType) { $closure = new ClosureType($parameters, $returnType, $isVariadic, $templateTypeMap, null, null, $templateTags, [], $mainType->getImpurePoints(), $mainType->getInvalidateExpressions(), $mainType->getUsedVariables(), $mainType->acceptsNamedArguments()); if ($closure->isPure()->yes() && $returnType->isVoid()->yes()) { return new ErrorType(); } return $closure; } return new ErrorType(); } private function resolveArrayShapeNode(ArrayShapeNode $typeNode, NameScope $nameScope) : Type { $builder = ConstantArrayTypeBuilder::createEmpty(); if (count($typeNode->items) > ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) { $builder->degradeToGeneralArray(\true); } foreach ($typeNode->items as $itemNode) { $offsetType = null; if ($itemNode->keyName instanceof ConstExprIntegerNode) { $offsetType = new ConstantIntegerType((int) $itemNode->keyName->value); } elseif ($itemNode->keyName instanceof IdentifierTypeNode) { $offsetType = new ConstantStringType($itemNode->keyName->name); } elseif ($itemNode->keyName instanceof ConstExprStringNode) { $offsetType = new ConstantStringType($itemNode->keyName->value); } elseif ($itemNode->keyName !== null) { throw new ShouldNotHappenException('Unsupported key node type: ' . get_class($itemNode->keyName)); } $builder->setOffsetValueType($offsetType, $this->resolve($itemNode->valueType, $nameScope), $itemNode->optional); } $arrayType = $builder->getArray(); if (in_array($typeNode->kind, [ArrayShapeNode::KIND_LIST, ArrayShapeNode::KIND_NON_EMPTY_LIST], \true)) { $arrayType = AccessoryArrayListType::intersectWith($arrayType); } if (in_array($typeNode->kind, [ArrayShapeNode::KIND_NON_EMPTY_ARRAY, ArrayShapeNode::KIND_NON_EMPTY_LIST], \true)) { $arrayType = TypeCombinator::intersect($arrayType, new NonEmptyArrayType()); } return $arrayType; } private function resolveObjectShapeNode(ObjectShapeNode $typeNode, NameScope $nameScope) : Type { $properties = []; $optionalProperties = []; foreach ($typeNode->items as $itemNode) { if ($itemNode->keyName instanceof IdentifierTypeNode) { $propertyName = $itemNode->keyName->name; } elseif ($itemNode->keyName instanceof ConstExprStringNode) { $propertyName = $itemNode->keyName->value; } if ($itemNode->optional) { $optionalProperties[] = $propertyName; } $properties[$propertyName] = $this->resolve($itemNode->valueType, $nameScope); } return new ObjectShapeType($properties, $optionalProperties); } private function resolveConstTypeNode(ConstTypeNode $typeNode, NameScope $nameScope) : Type { $constExpr = $typeNode->constExpr; if ($constExpr instanceof ConstExprArrayNode) { throw new ShouldNotHappenException(); // we prefer array shapes } if ($constExpr instanceof ConstExprFalseNode || $constExpr instanceof ConstExprTrueNode || $constExpr instanceof ConstExprNullNode) { throw new ShouldNotHappenException(); // we prefer IdentifierTypeNode } if ($constExpr instanceof ConstFetchNode) { if ($constExpr->className === '') { throw new ShouldNotHappenException(); // global constant should get parsed as class name in IdentifierTypeNode } if ($nameScope->getClassName() !== null) { switch (strtolower($constExpr->className)) { case 'static': case 'self': $className = $nameScope->getClassName(); break; case 'parent': if ($this->getReflectionProvider()->hasClass($nameScope->getClassName())) { $classReflection = $this->getReflectionProvider()->getClass($nameScope->getClassName()); if ($classReflection->getParentClass() === null) { return new ErrorType(); } $className = $classReflection->getParentClass()->getName(); } break; } } if (!isset($className)) { $className = $nameScope->resolveStringName($constExpr->className); } if (!$this->getReflectionProvider()->hasClass($className)) { return new ErrorType(); } $classReflection = $this->getReflectionProvider()->getClass($className); $constantName = $constExpr->name; if (Strings::contains($constantName, '*')) { // convert * into .*? and escape everything else so the constants can be matched against the pattern $pattern = '{^' . str_replace('\\*', '.*?', preg_quote($constantName)) . '$}D'; $constantTypes = []; foreach ($classReflection->getNativeReflection()->getReflectionConstants() as $reflectionConstant) { $classConstantName = $reflectionConstant->getName(); if (Strings::match($classConstantName, $pattern) === null) { continue; } if ($classReflection->isEnum() && $classReflection->hasEnumCase($classConstantName)) { $constantTypes[] = new EnumCaseObjectType($classReflection->getName(), $classConstantName); continue; } $declaringClassName = $reflectionConstant->getDeclaringClass()->getName(); if (!$this->getReflectionProvider()->hasClass($declaringClassName)) { continue; } $constantTypes[] = $this->initializerExprTypeResolver->getType($reflectionConstant->getValueExpression(), InitializerExprContext::fromClassReflection($this->getReflectionProvider()->getClass($declaringClassName))); } if (count($constantTypes) === 0) { return new ErrorType(); } return TypeCombinator::union(...$constantTypes); } if (!$classReflection->hasConstant($constantName)) { return new ErrorType(); } if ($classReflection->isEnum() && $classReflection->hasEnumCase($constantName)) { return new EnumCaseObjectType($classReflection->getName(), $constantName); } $reflectionConstant = $classReflection->getNativeReflection()->getReflectionConstant($constantName); if ($reflectionConstant === \false) { return new ErrorType(); } $declaringClass = $reflectionConstant->getDeclaringClass(); return $this->initializerExprTypeResolver->getType($reflectionConstant->getValueExpression(), InitializerExprContext::fromClass($declaringClass->getName(), $declaringClass->getFileName() ?: null)); } if ($constExpr instanceof ConstExprFloatNode) { return new ConstantFloatType((float) $constExpr->value); } if ($constExpr instanceof ConstExprIntegerNode) { return new ConstantIntegerType((int) $constExpr->value); } if ($constExpr instanceof ConstExprStringNode) { return new ConstantStringType($constExpr->value); } return new ErrorType(); } private function resolveOffsetAccessNode(OffsetAccessTypeNode $typeNode, NameScope $nameScope) : Type { $type = $this->resolve($typeNode->type, $nameScope); $offset = $this->resolve($typeNode->offset, $nameScope); if ($type->isOffsetAccessible()->no() || $type->hasOffsetValueType($offset)->no()) { return new ErrorType(); } return new OffsetAccessType($type, $offset); } private function expandIntMaskToType(Type $type) : ?Type { $ints = array_map(static function (ConstantIntegerType $type) { return $type->getValue(); }, TypeUtils::getConstantIntegers($type)); if (count($ints) === 0) { return null; } $values = []; foreach ($ints as $int) { if ($int !== 0 && !array_key_exists($int, $values)) { foreach ($values as $value) { $computedValue = $value | $int; $values[$computedValue] = $computedValue; } } $values[$int] = $int; } $values[0] = 0; $min = min($values); $max = max($values); if ($max - $min === count($values) - 1) { return IntegerRangeType::fromInterval($min, $max); } if (count($values) > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT) { return IntegerRangeType::fromInterval($min, $max); } return TypeCombinator::union(...array_map(static function ($value) { return new ConstantIntegerType($value); }, $values)); } /** * @api * @param TypeNode[] $typeNodes * @return Type[] */ public function resolveMultiple(array $typeNodes, NameScope $nameScope) : array { $types = []; foreach ($typeNodes as $typeNode) { $types[] = $this->resolve($typeNode, $nameScope); } return $types; } private function getReflectionProvider() : ReflectionProvider { return $this->reflectionProviderProvider->getReflectionProvider(); } private function getTypeAliasResolver() : TypeAliasResolver { return $this->typeAliasResolverProvider->getTypeAliasResolver(); } } */ private $templateTags; /** * @var PhpDocNodeResolver */ private $phpDocNodeResolver; /** * @var ReflectionProvider */ private $reflectionProvider; /** @var array<(string|int), VarTag>|false */ private $varTags = \false; /** @var array|false */ private $methodTags = \false; /** @var array|false */ private $propertyTags = \false; /** @var array|false */ private $extendsTags = \false; /** @var array|false */ private $implementsTags = \false; /** @var array|false */ private $usesTags = \false; /** @var array|false */ private $paramTags = \false; /** @var array|false */ private $paramOutTags = \false; /** @var array|false */ private $paramsImmediatelyInvokedCallable = \false; /** @var array|false */ private $paramClosureThisTags = \false; /** * @var ReturnTag|false|null */ private $returnTag = \false; /** * @var ThrowsTag|false|null */ private $throwsTag = \false; /** @var array|false */ private $mixinTags = \false; /** @var array|false */ private $requireExtendsTags = \false; /** @var array|false */ private $requireImplementsTags = \false; /** @var array|false */ private $typeAliasTags = \false; /** @var array|false */ private $typeAliasImportTags = \false; /** @var array|false */ private $assertTags = \false; /** * @var SelfOutTypeTag|false|null */ private $selfOutTypeTag = \false; /** * @var DeprecatedTag|false|null */ private $deprecatedTag = \false; /** * @var ?bool */ private $isDeprecated = null; /** * @var ?bool */ private $isNotDeprecated = null; /** * @var ?bool */ private $isInternal = null; /** * @var ?bool */ private $isFinal = null; /** @var bool|'notLoaded'|null */ private $isPure = 'notLoaded'; /** * @var ?bool */ private $isReadOnly = null; /** * @var ?bool */ private $isImmutable = null; /** * @var ?bool */ private $isAllowedPrivateMutation = null; /** * @var ?bool */ private $hasConsistentConstructor = null; /** * @var ?bool */ private $acceptsNamedArguments = null; private function __construct() { } /** * @param TemplateTag[] $templateTags */ public static function create(PhpDocNode $phpDocNode, string $phpDocString, ?string $filename, NameScope $nameScope, TemplateTypeMap $templateTypeMap, array $templateTags, \PHPStan\PhpDoc\PhpDocNodeResolver $phpDocNodeResolver, ReflectionProvider $reflectionProvider) : self { // new property also needs to be added to withNameScope(), createEmpty() and merge() $self = new self(); $self->phpDocNode = $phpDocNode; $self->phpDocNodes = [$phpDocNode]; $self->phpDocString = $phpDocString; $self->filename = $filename; $self->nameScope = $nameScope; $self->templateTypeMap = $templateTypeMap; $self->templateTags = $templateTags; $self->phpDocNodeResolver = $phpDocNodeResolver; $self->reflectionProvider = $reflectionProvider; return $self; } public function withNameScope(NameScope $nameScope) : self { $self = new self(); $self->phpDocNode = $this->phpDocNode; $self->phpDocNodes = $this->phpDocNodes; $self->phpDocString = $this->phpDocString; $self->filename = $this->filename; $self->nameScope = $nameScope; $self->templateTypeMap = $this->templateTypeMap; $self->templateTags = $this->templateTags; $self->phpDocNodeResolver = $this->phpDocNodeResolver; $self->reflectionProvider = $this->reflectionProvider; return $self; } public static function createEmpty() : self { // new property also needs to be added to merge() $self = new self(); $self->phpDocString = self::EMPTY_DOC_STRING; $self->phpDocNodes = []; $self->filename = null; $self->templateTypeMap = TemplateTypeMap::createEmpty(); $self->templateTags = []; $self->varTags = []; $self->methodTags = []; $self->propertyTags = []; $self->extendsTags = []; $self->implementsTags = []; $self->usesTags = []; $self->paramTags = []; $self->paramOutTags = []; $self->paramsImmediatelyInvokedCallable = []; $self->paramClosureThisTags = []; $self->returnTag = null; $self->throwsTag = null; $self->mixinTags = []; $self->requireExtendsTags = []; $self->requireImplementsTags = []; $self->typeAliasTags = []; $self->typeAliasImportTags = []; $self->assertTags = []; $self->selfOutTypeTag = null; $self->deprecatedTag = null; $self->isDeprecated = \false; $self->isNotDeprecated = \false; $self->isInternal = \false; $self->isFinal = \false; $self->isPure = null; $self->isReadOnly = \false; $self->isImmutable = \false; $self->isAllowedPrivateMutation = \false; $self->hasConsistentConstructor = \false; $self->acceptsNamedArguments = \true; return $self; } /** * @param array $parents * @param array $parentPhpDocBlocks */ public function merge(array $parents, array $parentPhpDocBlocks) : self { $className = $this->nameScope !== null ? $this->nameScope->getClassName() : null; $classReflection = $className !== null && $this->reflectionProvider->hasClass($className) ? $this->reflectionProvider->getClass($className) : null; // new property also needs to be added to createEmpty() $result = new self(); // we will resolve everything on $this here so these properties don't have to be populated // skip $result->phpDocNode $phpDocNodes = $this->phpDocNodes; $acceptsNamedArguments = $this->acceptsNamedArguments(); foreach ($parents as $parent) { foreach ($parent->phpDocNodes as $phpDocNode) { $phpDocNodes[] = $phpDocNode; $acceptsNamedArguments = $acceptsNamedArguments && $parent->acceptsNamedArguments(); } } $result->phpDocNodes = $phpDocNodes; $result->phpDocString = $this->phpDocString; $result->filename = $this->filename; // skip $result->nameScope $result->templateTypeMap = $this->templateTypeMap; $result->templateTags = $this->templateTags; // skip $result->phpDocNodeResolver $result->varTags = self::mergeVarTags($this->getVarTags(), $parents, $parentPhpDocBlocks); $result->methodTags = $this->getMethodTags(); $result->propertyTags = $this->getPropertyTags(); $result->extendsTags = $this->getExtendsTags(); $result->implementsTags = $this->getImplementsTags(); $result->usesTags = $this->getUsesTags(); $result->paramTags = self::mergeParamTags($this->getParamTags(), $parents, $parentPhpDocBlocks); $result->paramOutTags = self::mergeParamOutTags($this->getParamOutTags(), $parents, $parentPhpDocBlocks); $result->paramsImmediatelyInvokedCallable = self::mergeParamsImmediatelyInvokedCallable($this->getParamsImmediatelyInvokedCallable(), $parents, $parentPhpDocBlocks); $result->paramClosureThisTags = self::mergeParamClosureThisTags($this->getParamClosureThisTags(), $parents, $parentPhpDocBlocks); $result->returnTag = self::mergeReturnTags($this->getReturnTag(), $classReflection, $parents, $parentPhpDocBlocks); $result->throwsTag = self::mergeThrowsTags($this->getThrowsTag(), $parents); $result->mixinTags = $this->getMixinTags(); $result->requireExtendsTags = $this->getRequireExtendsTags(); $result->requireImplementsTags = $this->getRequireImplementsTags(); $result->typeAliasTags = $this->getTypeAliasTags(); $result->typeAliasImportTags = $this->getTypeAliasImportTags(); $result->assertTags = self::mergeAssertTags($this->getAssertTags(), $parents, $parentPhpDocBlocks); $result->selfOutTypeTag = self::mergeSelfOutTypeTags($this->getSelfOutTag(), $parents); $result->deprecatedTag = self::mergeDeprecatedTags($this->getDeprecatedTag(), $this->isNotDeprecated(), $parents); $result->isDeprecated = $result->deprecatedTag !== null; $result->isNotDeprecated = $this->isNotDeprecated(); $result->isInternal = $this->isInternal(); $result->isFinal = $this->isFinal(); $result->isPure = self::mergePureTags($this->isPure(), $parents); $result->isReadOnly = $this->isReadOnly(); $result->isImmutable = $this->isImmutable(); $result->isAllowedPrivateMutation = $this->isAllowedPrivateMutation(); $result->hasConsistentConstructor = $this->hasConsistentConstructor(); $result->acceptsNamedArguments = $acceptsNamedArguments; return $result; } /** * @param array $parameterNameMapping */ public function changeParameterNamesByMapping(array $parameterNameMapping) : self { if (count($this->phpDocNodes) === 0) { return $this; } $mapParameterCb = static function (Type $type, callable $traverse) use($parameterNameMapping) : Type { if ($type instanceof ConditionalTypeForParameter) { $parameterName = substr($type->getParameterName(), 1); if (array_key_exists($parameterName, $parameterNameMapping)) { $type = $type->changeParameterName('$' . $parameterNameMapping[$parameterName]); } } return $traverse($type); }; $newParamTags = []; foreach ($this->getParamTags() as $key => $paramTag) { if (!array_key_exists($key, $parameterNameMapping)) { continue; } $transformedType = TypeTraverser::map($paramTag->getType(), $mapParameterCb); $newParamTags[$parameterNameMapping[$key]] = $paramTag->withType($transformedType); } $newParamOutTags = []; foreach ($this->getParamOutTags() as $key => $paramOutTag) { if (!array_key_exists($key, $parameterNameMapping)) { continue; } $transformedType = TypeTraverser::map($paramOutTag->getType(), $mapParameterCb); $newParamOutTags[$parameterNameMapping[$key]] = $paramOutTag->withType($transformedType); } $newParamsImmediatelyInvokedCallable = []; foreach ($this->getParamsImmediatelyInvokedCallable() as $key => $immediatelyInvokedCallable) { if (!array_key_exists($key, $parameterNameMapping)) { continue; } $newParamsImmediatelyInvokedCallable[$parameterNameMapping[$key]] = $immediatelyInvokedCallable; } $paramClosureThisTags = $this->getParamClosureThisTags(); $newParamClosureThisTags = []; foreach ($paramClosureThisTags as $key => $paramClosureThisTag) { if (!array_key_exists($key, $parameterNameMapping)) { continue; } $transformedType = TypeTraverser::map($paramClosureThisTag->getType(), $mapParameterCb); $newParamClosureThisTags[$parameterNameMapping[$key]] = $paramClosureThisTag->withType($transformedType); } $returnTag = $this->getReturnTag(); if ($returnTag !== null) { $transformedType = TypeTraverser::map($returnTag->getType(), $mapParameterCb); $returnTag = $returnTag->withType($transformedType); } $assertTags = $this->getAssertTags(); if (count($assertTags) > 0) { $assertTags = array_map(static function (AssertTag $tag) use($parameterNameMapping) : AssertTag { $parameterName = substr($tag->getParameter()->getParameterName(), 1); if (array_key_exists($parameterName, $parameterNameMapping)) { $tag = $tag->withParameter($tag->getParameter()->changeParameterName('$' . $parameterNameMapping[$parameterName])); } return $tag; }, $assertTags); } $self = new self(); $self->phpDocNode = $this->phpDocNode; $self->phpDocNodes = $this->phpDocNodes; $self->phpDocString = $this->phpDocString; $self->filename = $this->filename; $self->nameScope = $this->nameScope; $self->templateTypeMap = $this->templateTypeMap; $self->templateTags = $this->templateTags; $self->phpDocNodeResolver = $this->phpDocNodeResolver; $self->reflectionProvider = $this->reflectionProvider; $self->varTags = $this->varTags; $self->methodTags = $this->methodTags; $self->propertyTags = $this->propertyTags; $self->extendsTags = $this->extendsTags; $self->implementsTags = $this->implementsTags; $self->usesTags = $this->usesTags; $self->paramTags = $newParamTags; $self->paramOutTags = $newParamOutTags; $self->paramsImmediatelyInvokedCallable = $newParamsImmediatelyInvokedCallable; $self->paramClosureThisTags = $newParamClosureThisTags; $self->returnTag = $returnTag; $self->throwsTag = $this->throwsTag; $self->mixinTags = $this->mixinTags; $self->requireImplementsTags = $this->requireImplementsTags; $self->requireExtendsTags = $this->requireExtendsTags; $self->typeAliasTags = $this->typeAliasTags; $self->typeAliasImportTags = $this->typeAliasImportTags; $self->assertTags = $assertTags; $self->selfOutTypeTag = $this->selfOutTypeTag; $self->deprecatedTag = $this->deprecatedTag; $self->isDeprecated = $this->isDeprecated; $self->isNotDeprecated = $this->isNotDeprecated; $self->isInternal = $this->isInternal; $self->isFinal = $this->isFinal; $self->isPure = $this->isPure; return $self; } public function hasPhpDocString() : bool { return $this->phpDocString !== self::EMPTY_DOC_STRING; } public function getPhpDocString() : string { return $this->phpDocString; } /** * @return PhpDocNode[] */ public function getPhpDocNodes() : array { return $this->phpDocNodes; } public function getFilename() : ?string { return $this->filename; } private function getNameScope() : NameScope { return $this->nameScope; } public function getNullableNameScope() : ?NameScope { return $this->nameScope; } /** * @return array<(string|int), VarTag> */ public function getVarTags() : array { if ($this->varTags === \false) { $this->varTags = $this->phpDocNodeResolver->resolveVarTags($this->phpDocNode, $this->getNameScope()); } return $this->varTags; } /** * @return array */ public function getMethodTags() : array { if ($this->methodTags === \false) { $this->methodTags = $this->phpDocNodeResolver->resolveMethodTags($this->phpDocNode, $this->getNameScope()); } return $this->methodTags; } /** * @return array */ public function getPropertyTags() : array { if ($this->propertyTags === \false) { $this->propertyTags = $this->phpDocNodeResolver->resolvePropertyTags($this->phpDocNode, $this->getNameScope()); } return $this->propertyTags; } /** * @return array */ public function getTemplateTags() : array { return $this->templateTags; } /** * @return array */ public function getExtendsTags() : array { if ($this->extendsTags === \false) { $this->extendsTags = $this->phpDocNodeResolver->resolveExtendsTags($this->phpDocNode, $this->getNameScope()); } return $this->extendsTags; } /** * @return array */ public function getImplementsTags() : array { if ($this->implementsTags === \false) { $this->implementsTags = $this->phpDocNodeResolver->resolveImplementsTags($this->phpDocNode, $this->getNameScope()); } return $this->implementsTags; } /** * @return array */ public function getUsesTags() : array { if ($this->usesTags === \false) { $this->usesTags = $this->phpDocNodeResolver->resolveUsesTags($this->phpDocNode, $this->getNameScope()); } return $this->usesTags; } /** * @return array */ public function getParamTags() : array { if ($this->paramTags === \false) { $this->paramTags = $this->phpDocNodeResolver->resolveParamTags($this->phpDocNode, $this->getNameScope()); } return $this->paramTags; } /** * @return array */ public function getParamOutTags() : array { if ($this->paramOutTags === \false) { $this->paramOutTags = $this->phpDocNodeResolver->resolveParamOutTags($this->phpDocNode, $this->getNameScope()); } return $this->paramOutTags; } /** * @return array */ public function getParamsImmediatelyInvokedCallable() : array { if ($this->paramsImmediatelyInvokedCallable === \false) { $this->paramsImmediatelyInvokedCallable = $this->phpDocNodeResolver->resolveParamImmediatelyInvokedCallable($this->phpDocNode); } return $this->paramsImmediatelyInvokedCallable; } /** * @return array */ public function getParamClosureThisTags() : array { if ($this->paramClosureThisTags === \false) { $this->paramClosureThisTags = $this->phpDocNodeResolver->resolveParamClosureThisTags($this->phpDocNode, $this->getNameScope()); } return $this->paramClosureThisTags; } public function getReturnTag() : ?ReturnTag { if (is_bool($this->returnTag)) { $this->returnTag = $this->phpDocNodeResolver->resolveReturnTag($this->phpDocNode, $this->getNameScope()); } return $this->returnTag; } public function getThrowsTag() : ?ThrowsTag { if (is_bool($this->throwsTag)) { $this->throwsTag = $this->phpDocNodeResolver->resolveThrowsTags($this->phpDocNode, $this->getNameScope()); } return $this->throwsTag; } /** * @return array */ public function getMixinTags() : array { if ($this->mixinTags === \false) { $this->mixinTags = $this->phpDocNodeResolver->resolveMixinTags($this->phpDocNode, $this->getNameScope()); } return $this->mixinTags; } /** * @return array */ public function getRequireExtendsTags() : array { if ($this->requireExtendsTags === \false) { $this->requireExtendsTags = $this->phpDocNodeResolver->resolveRequireExtendsTags($this->phpDocNode, $this->getNameScope()); } return $this->requireExtendsTags; } /** * @return array */ public function getRequireImplementsTags() : array { if ($this->requireImplementsTags === \false) { $this->requireImplementsTags = $this->phpDocNodeResolver->resolveRequireImplementsTags($this->phpDocNode, $this->getNameScope()); } return $this->requireImplementsTags; } /** * @return array */ public function getTypeAliasTags() : array { if ($this->typeAliasTags === \false) { $this->typeAliasTags = $this->phpDocNodeResolver->resolveTypeAliasTags($this->phpDocNode, $this->getNameScope()); } return $this->typeAliasTags; } /** * @return array */ public function getTypeAliasImportTags() : array { if ($this->typeAliasImportTags === \false) { $this->typeAliasImportTags = $this->phpDocNodeResolver->resolveTypeAliasImportTags($this->phpDocNode, $this->getNameScope()); } return $this->typeAliasImportTags; } /** * @return array */ public function getAssertTags() : array { if ($this->assertTags === \false) { $this->assertTags = $this->phpDocNodeResolver->resolveAssertTags($this->phpDocNode, $this->getNameScope()); } return $this->assertTags; } public function getSelfOutTag() : ?SelfOutTypeTag { if ($this->selfOutTypeTag === \false) { $this->selfOutTypeTag = $this->phpDocNodeResolver->resolveSelfOutTypeTag($this->phpDocNode, $this->getNameScope()); } return $this->selfOutTypeTag; } public function getDeprecatedTag() : ?DeprecatedTag { if (is_bool($this->deprecatedTag)) { $this->deprecatedTag = $this->phpDocNodeResolver->resolveDeprecatedTag($this->phpDocNode, $this->getNameScope()); } return $this->deprecatedTag; } public function isDeprecated() : bool { if ($this->isDeprecated === null) { $this->isDeprecated = $this->phpDocNodeResolver->resolveIsDeprecated($this->phpDocNode); } return $this->isDeprecated; } /** * @internal */ public function isNotDeprecated() : bool { if ($this->isNotDeprecated === null) { $this->isNotDeprecated = $this->phpDocNodeResolver->resolveIsNotDeprecated($this->phpDocNode); } return $this->isNotDeprecated; } public function isInternal() : bool { if ($this->isInternal === null) { $this->isInternal = $this->phpDocNodeResolver->resolveIsInternal($this->phpDocNode); } return $this->isInternal; } public function isFinal() : bool { if ($this->isFinal === null) { $this->isFinal = $this->phpDocNodeResolver->resolveIsFinal($this->phpDocNode); } return $this->isFinal; } public function hasConsistentConstructor() : bool { if ($this->hasConsistentConstructor === null) { $this->hasConsistentConstructor = $this->phpDocNodeResolver->resolveHasConsistentConstructor($this->phpDocNode); } return $this->hasConsistentConstructor; } public function acceptsNamedArguments() : bool { if ($this->acceptsNamedArguments === null) { $this->acceptsNamedArguments = $this->phpDocNodeResolver->resolveAcceptsNamedArguments($this->phpDocNode); } return $this->acceptsNamedArguments; } public function getTemplateTypeMap() : TemplateTypeMap { return $this->templateTypeMap; } public function isPure() : ?bool { if ($this->isPure === 'notLoaded') { $pure = $this->phpDocNodeResolver->resolveIsPure($this->phpDocNode); if ($pure) { $this->isPure = \true; return $this->isPure; } $impure = $this->phpDocNodeResolver->resolveIsImpure($this->phpDocNode); if ($impure) { $this->isPure = \false; return $this->isPure; } $this->isPure = null; } return $this->isPure; } public function isReadOnly() : bool { if ($this->isReadOnly === null) { $this->isReadOnly = $this->phpDocNodeResolver->resolveIsReadOnly($this->phpDocNode); } return $this->isReadOnly; } public function isImmutable() : bool { if ($this->isImmutable === null) { $this->isImmutable = $this->phpDocNodeResolver->resolveIsImmutable($this->phpDocNode); } return $this->isImmutable; } public function isAllowedPrivateMutation() : bool { if ($this->isAllowedPrivateMutation === null) { $this->isAllowedPrivateMutation = $this->phpDocNodeResolver->resolveAllowPrivateMutation($this->phpDocNode); } return $this->isAllowedPrivateMutation; } /** * @param array $varTags * @param array $parents * @param array $parentPhpDocBlocks * @return array */ private static function mergeVarTags(array $varTags, array $parents, array $parentPhpDocBlocks) : array { // Only allow one var tag per comment. Check the parent if child does not have this tag. if (count($varTags) > 0) { return $varTags; } foreach ($parents as $i => $parent) { $result = self::mergeOneParentVarTags($parent, $parentPhpDocBlocks[$i]); if ($result === null) { continue; } return $result; } return []; } /** * @return array|null */ private static function mergeOneParentVarTags(self $parent, \PHPStan\PhpDoc\PhpDocBlock $phpDocBlock) : ?array { foreach ($parent->getVarTags() as $key => $parentVarTag) { return [$key => self::resolveTemplateTypeInTag($parentVarTag->toImplicit(), $phpDocBlock, TemplateTypeVariance::createInvariant())]; } return null; } /** * @param array $paramTags * @param array $parents * @param array $parentPhpDocBlocks * @return array */ private static function mergeParamTags(array $paramTags, array $parents, array $parentPhpDocBlocks) : array { foreach ($parents as $i => $parent) { $paramTags = self::mergeOneParentParamTags($paramTags, $parent, $parentPhpDocBlocks[$i]); } return $paramTags; } /** * @param array $paramTags * @return array */ private static function mergeOneParentParamTags(array $paramTags, self $parent, \PHPStan\PhpDoc\PhpDocBlock $phpDocBlock) : array { $parentParamTags = $phpDocBlock->transformArrayKeysWithParameterNameMapping($parent->getParamTags()); foreach ($parentParamTags as $name => $parentParamTag) { if (array_key_exists($name, $paramTags)) { continue; } $paramTags[$name] = self::resolveTemplateTypeInTag($parentParamTag->withType($phpDocBlock->transformConditionalReturnTypeWithParameterNameMapping($parentParamTag->getType())), $phpDocBlock, TemplateTypeVariance::createContravariant()); } return $paramTags; } /** * @param array $parents * @param array $parentPhpDocBlocks * @return ReturnTag|Null */ private static function mergeReturnTags(?ReturnTag $returnTag, ?ClassReflection $classReflection, array $parents, array $parentPhpDocBlocks) : ?ReturnTag { if ($returnTag !== null) { return $returnTag; } foreach ($parents as $i => $parent) { $result = self::mergeOneParentReturnTag($returnTag, $classReflection, $parent, $parentPhpDocBlocks[$i]); if ($result === null) { continue; } return $result; } return null; } private static function mergeOneParentReturnTag(?ReturnTag $returnTag, ?ClassReflection $classReflection, self $parent, \PHPStan\PhpDoc\PhpDocBlock $phpDocBlock) : ?ReturnTag { $parentReturnTag = $parent->getReturnTag(); if ($parentReturnTag === null) { return $returnTag; } $parentType = $parentReturnTag->getType(); if ($classReflection !== null) { $parentType = TypeTraverser::map($parentType, static function (Type $type, callable $traverse) use($classReflection) : Type { if ($type instanceof StaticType) { return $type->changeBaseClass($classReflection); } return $traverse($type); }); $parentReturnTag = $parentReturnTag->withType($parentType); } // Each parent would overwrite the previous one except if it returns a less specific type. // Do not care for incompatible types as there is a separate rule for that. if ($returnTag !== null && $parentType->isSuperTypeOf($returnTag->getType())->yes()) { return null; } return self::resolveTemplateTypeInTag($parentReturnTag->withType($phpDocBlock->transformConditionalReturnTypeWithParameterNameMapping($parentReturnTag->getType()))->toImplicit(), $phpDocBlock, TemplateTypeVariance::createCovariant()); } /** * @param array $assertTags * @param array $parents * @param array $parentPhpDocBlocks * @return array */ private static function mergeAssertTags(array $assertTags, array $parents, array $parentPhpDocBlocks) : array { if (count($assertTags) > 0) { return $assertTags; } foreach ($parents as $i => $parent) { $result = $parent->getAssertTags(); if (count($result) === 0) { continue; } $phpDocBlock = $parentPhpDocBlocks[$i]; return array_map(static function (AssertTag $assertTag) use($phpDocBlock) { return self::resolveTemplateTypeInTag($assertTag->withParameter($phpDocBlock->transformAssertTagParameterWithParameterNameMapping($assertTag->getParameter()))->toImplicit(), $phpDocBlock, TemplateTypeVariance::createCovariant()); }, $result); } return $assertTags; } /** * @param array $parents */ private static function mergeSelfOutTypeTags(?SelfOutTypeTag $selfOutTypeTag, array $parents) : ?SelfOutTypeTag { if ($selfOutTypeTag !== null) { return $selfOutTypeTag; } foreach ($parents as $parent) { $result = $parent->getSelfOutTag(); if ($result === null) { continue; } return $result; } return null; } /** * @param array $parents */ private static function mergeDeprecatedTags(?DeprecatedTag $deprecatedTag, bool $hasNotDeprecatedTag, array $parents) : ?DeprecatedTag { if ($deprecatedTag !== null) { return $deprecatedTag; } if ($hasNotDeprecatedTag) { return null; } foreach ($parents as $parent) { $result = $parent->getDeprecatedTag(); if ($result === null && !$parent->isNotDeprecated()) { continue; } return $result; } return null; } /** * @param array $parents */ private static function mergeThrowsTags(?ThrowsTag $throwsTag, array $parents) : ?ThrowsTag { if ($throwsTag !== null) { return $throwsTag; } foreach ($parents as $parent) { $result = $parent->getThrowsTag(); if ($result === null) { continue; } return $result; } return null; } /** * @param array $paramOutTags * @param array $parents * @param array $parentPhpDocBlocks * @return array */ private static function mergeParamOutTags(array $paramOutTags, array $parents, array $parentPhpDocBlocks) : array { foreach ($parents as $i => $parent) { $paramOutTags = self::mergeOneParentParamOutTags($paramOutTags, $parent, $parentPhpDocBlocks[$i]); } return $paramOutTags; } /** * @param array $paramOutTags * @return array */ private static function mergeOneParentParamOutTags(array $paramOutTags, self $parent, \PHPStan\PhpDoc\PhpDocBlock $phpDocBlock) : array { $parentParamOutTags = $phpDocBlock->transformArrayKeysWithParameterNameMapping($parent->getParamOutTags()); foreach ($parentParamOutTags as $name => $parentParamTag) { if (array_key_exists($name, $paramOutTags)) { continue; } $paramOutTags[$name] = self::resolveTemplateTypeInTag($parentParamTag->withType($phpDocBlock->transformConditionalReturnTypeWithParameterNameMapping($parentParamTag->getType())), $phpDocBlock, TemplateTypeVariance::createCovariant()); } return $paramOutTags; } /** * @param array $paramsImmediatelyInvokedCallable * @param array $parents * @param array $parentPhpDocBlocks * @return array */ private static function mergeParamsImmediatelyInvokedCallable(array $paramsImmediatelyInvokedCallable, array $parents, array $parentPhpDocBlocks) : array { foreach ($parents as $i => $parent) { $paramsImmediatelyInvokedCallable = self::mergeOneParentParamImmediatelyInvokedCallable($paramsImmediatelyInvokedCallable, $parent, $parentPhpDocBlocks[$i]); } return $paramsImmediatelyInvokedCallable; } /** * @param array $paramsImmediatelyInvokedCallable * @return array */ private static function mergeOneParentParamImmediatelyInvokedCallable(array $paramsImmediatelyInvokedCallable, self $parent, \PHPStan\PhpDoc\PhpDocBlock $phpDocBlock) : array { $parentImmediatelyInvokedCallable = $phpDocBlock->transformArrayKeysWithParameterNameMapping($parent->getParamsImmediatelyInvokedCallable()); foreach ($parentImmediatelyInvokedCallable as $name => $parentIsImmediatelyInvokedCallable) { if (array_key_exists($name, $paramsImmediatelyInvokedCallable)) { continue; } $paramsImmediatelyInvokedCallable[$name] = $parentIsImmediatelyInvokedCallable; } return $paramsImmediatelyInvokedCallable; } /** * @param array $paramsClosureThisTags * @param array $parents * @param array $parentPhpDocBlocks * @return array */ private static function mergeParamClosureThisTags(array $paramsClosureThisTags, array $parents, array $parentPhpDocBlocks) : array { foreach ($parents as $i => $parent) { $paramsClosureThisTags = self::mergeOneParentParamClosureThisTag($paramsClosureThisTags, $parent, $parentPhpDocBlocks[$i]); } return $paramsClosureThisTags; } /** * @param array $paramsClosureThisTags * @return array */ private static function mergeOneParentParamClosureThisTag(array $paramsClosureThisTags, self $parent, \PHPStan\PhpDoc\PhpDocBlock $phpDocBlock) : array { $parentClosureThisTags = $phpDocBlock->transformArrayKeysWithParameterNameMapping($parent->getParamClosureThisTags()); foreach ($parentClosureThisTags as $name => $parentParamClosureThisTag) { if (array_key_exists($name, $paramsClosureThisTags)) { continue; } $paramsClosureThisTags[$name] = self::resolveTemplateTypeInTag($parentParamClosureThisTag->withType($phpDocBlock->transformConditionalReturnTypeWithParameterNameMapping($parentParamClosureThisTag->getType())), $phpDocBlock, TemplateTypeVariance::createContravariant()); } return $paramsClosureThisTags; } /** * @param array $parents */ private static function mergePureTags(?bool $isPure, array $parents) : ?bool { if ($isPure !== null) { return $isPure; } foreach ($parents as $parent) { $parentIsPure = $parent->isPure(); if ($parentIsPure === null) { continue; } return $parentIsPure; } return null; } /** * @template T of TypedTag * @param T $tag * @return T */ private static function resolveTemplateTypeInTag(TypedTag $tag, \PHPStan\PhpDoc\PhpDocBlock $phpDocBlock, TemplateTypeVariance $positionVariance) : TypedTag { $type = TemplateTypeHelper::resolveTemplateTypes($tag->getType(), $phpDocBlock->getClassReflection()->getActiveTemplateTypeMap(), $phpDocBlock->getClassReflection()->getCallSiteVarianceMap(), $positionVariance); return $tag->withType($type); } } container = $container; $this->stubFiles = $stubFiles; $this->composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; } public function getStubFiles() : array { if ($this->cachedFiles !== null) { return $this->cachedFiles; } $files = $this->stubFiles; $extensions = $this->container->getServicesByTag(\PHPStan\PhpDoc\StubFilesExtension::EXTENSION_TAG); foreach ($extensions as $extension) { foreach ($extension->getFiles() as $extensionFile) { $files[] = $extensionFile; } } return $this->cachedFiles = $files; } public function getProjectStubFiles() : array { if ($this->cachedProjectFiles !== null) { return $this->cachedProjectFiles; } $filteredStubFiles = $this->getStubFiles(); foreach ($this->composerAutoloaderProjectPaths as $composerAutoloaderProjectPath) { $composerConfig = ComposerHelper::getComposerConfig($composerAutoloaderProjectPath); if ($composerConfig === null) { continue; } $vendorDir = ComposerHelper::getVendorDirFromComposerConfig($composerAutoloaderProjectPath, $composerConfig); $vendorDir = strtr($vendorDir, '\\', '/'); $filteredStubFiles = array_filter($filteredStubFiles, static function (string $file) use($vendorDir) : bool { return !str_contains(strtr($file, '\\', '/'), $vendorDir); }); } return $this->cachedProjectFiles = array_values($filteredStubFiles); } } type = $type; $this->readableType = $readableType; $this->writableType = $writableType; } /** * @deprecated Use getReadableType() / getWritableType() */ public function getType() : Type { return $this->type; } public function getReadableType() : ?Type { return $this->readableType; } public function getWritableType() : ?Type { return $this->writableType; } /** * @phpstan-assert-if-true !null $this->getReadableType() */ public function isReadable() : bool { return $this->readableType !== null; } /** * @phpstan-assert-if-true !null $this->getWritableType() */ public function isWritable() : bool { return $this->writableType !== null; } } importedAlias = $importedAlias; $this->importedFrom = $importedFrom; $this->importedAs = $importedAs; } public function getImportedAlias() : string { return $this->importedAlias; } public function getImportedFrom() : string { return $this->importedFrom; } public function getImportedAs() : ?string { return $this->importedAs; } } type = $type; } public function getType() : Type { return $this->type; } } if = $if; $this->type = $type; $this->parameter = $parameter; $this->negated = $negated; $this->equality = $equality; $this->isExplicit = $isExplicit; } /** * @return self::NULL|self::IF_TRUE|self::IF_FALSE */ public function getIf() : string { return $this->if; } public function getType() : Type { return $this->type; } public function getOriginalType() : Type { return $this->originalType = $this->originalType ?? $this->type; } public function getParameter() : \PHPStan\PhpDoc\Tag\AssertTagParameter { return $this->parameter; } public function isNegated() : bool { return $this->negated; } public function isEquality() : bool { return $this->equality; } /** * @return static */ public function withType(Type $type) : \PHPStan\PhpDoc\Tag\TypedTag { $tag = new self($this->if, $type, $this->parameter, $this->negated, $this->equality, $this->isExplicit); $tag->originalType = $this->getOriginalType(); return $tag; } public function withParameter(\PHPStan\PhpDoc\Tag\AssertTagParameter $parameter) : self { $tag = new self($this->if, $this->type, $parameter, $this->negated, $this->equality, $this->isExplicit); $tag->originalType = $this->getOriginalType(); return $tag; } public function negate() : self { if ($this->isEquality()) { throw new ShouldNotHappenException(); } $tag = new self($this->if, $this->type, $this->parameter, !$this->negated, $this->equality, $this->isExplicit); $tag->originalType = $this->getOriginalType(); return $tag; } public function isExplicit() : bool { return $this->isExplicit; } public function toImplicit() : self { return new self($this->if, $this->type, $this->parameter, $this->negated, $this->equality, \false); } } type = $type; } public function getType() : Type { return $this->type; } /** * @return self */ public function withType(Type $type) : \PHPStan\PhpDoc\Tag\TypedTag { return new self($type); } } type = $type; } public function getType() : Type { return $this->type; } } type = $type; } public function getType() : Type { return $this->type; } /** * @return self */ public function withType(Type $type) : \PHPStan\PhpDoc\Tag\TypedTag { return new self($type); } } name = $name; $this->bound = $bound; $this->default = $default; $this->variance = $variance; } /** * @return non-empty-string */ public function getName() : string { return $this->name; } public function getBound() : Type { return $this->bound; } public function getDefault() : ?Type { return $this->default; } public function getVariance() : TemplateTypeVariance { return $this->variance; } } aliasName = $aliasName; $this->typeNode = $typeNode; $this->nameScope = $nameScope; } public function getAliasName() : string { return $this->aliasName; } public function getTypeAlias() : TypeAlias { return new TypeAlias($this->typeNode, $this->nameScope); } } type = $type; $this->passedByReference = $passedByReference; $this->isOptional = $isOptional; $this->isVariadic = $isVariadic; $this->defaultValue = $defaultValue; } public function getType() : Type { return $this->type; } public function passedByReference() : PassedByReference { return $this->passedByReference; } public function isOptional() : bool { return $this->isOptional; } public function isVariadic() : bool { return $this->isVariadic; } public function getDefaultValue() : ?Type { return $this->defaultValue; } } message = $message; } public function getMessage() : ?string { return $this->message; } } type = $type; $this->isExplicit = $isExplicit; } public function getType() : Type { return $this->type; } public function isExplicit() : bool { return $this->isExplicit; } /** * @return self */ public function withType(Type $type) : \PHPStan\PhpDoc\Tag\TypedTag { return new self($type, $this->isExplicit); } public function toImplicit() : self { return new self($this->type, \false); } } type = $type; } public function getType() : Type { return $this->type; } /** * @return self */ public function withType(Type $type) : \PHPStan\PhpDoc\Tag\TypedTag { return new self($type); } } */ private $parameters; /** * @var array */ private $templateTags; /** * @param array $parameters * @param array $templateTags */ public function __construct(Type $returnType, bool $isStatic, array $parameters, array $templateTags = []) { $this->returnType = $returnType; $this->isStatic = $isStatic; $this->parameters = $parameters; $this->templateTags = $templateTags; } public function getReturnType() : Type { return $this->returnType; } public function isStatic() : bool { return $this->isStatic; } /** * @return array */ public function getParameters() : array { return $this->parameters; } /** * @return array */ public function getTemplateTags() : array { return $this->templateTags; } } parameterName = $parameterName; $this->property = $property; $this->method = $method; } public function getParameterName() : string { return $this->parameterName; } public function changeParameterName(string $parameterName) : self { return new self($parameterName, $this->property, $this->method); } public function describe() : string { if ($this->property !== null) { return sprintf('%s->%s', $this->parameterName, $this->property); } if ($this->method !== null) { return sprintf('%s->%s()', $this->parameterName, $this->method); } return $this->parameterName; } public function getExpr(Expr $parameter) : Expr { if ($this->property !== null) { return new Expr\PropertyFetch($parameter, $this->property); } if ($this->method !== null) { return new Expr\MethodCall($parameter, $this->method); } return $parameter; } } type = $type; } public function getType() : Type { return $this->type; } } type = $type; $this->isVariadic = $isVariadic; } public function getType() : Type { return $this->type; } public function isVariadic() : bool { return $this->isVariadic; } /** * @return self */ public function withType(Type $type) : \PHPStan\PhpDoc\Tag\TypedTag { return new self($type, $this->isVariadic); } } type = $type; } public function getType() : Type { return $this->type; } } type = $type; } public function getType() : Type { return $this->type; } } type = $type; } public function getType() : Type { return $this->type; } } type = $type; $this->isExplicit = $isExplicit; } public function getType() : Type { return $this->type; } /** * @return self */ public function withType(Type $type) : \PHPStan\PhpDoc\Tag\TypedTag { return new self($type, $this->isExplicit); } public function isExplicit() : bool { return $this->isExplicit; } public function toImplicit() : self { return new self($this->type, \false); } } type = $type; } public function getType() : Type { return $this->type; } } */ private $parameterNameMapping; /** * @var array */ private $parents; /** * @param array $parameterNameMapping * @param array $parents */ private function __construct(string $docComment, ?string $file, ClassReflection $classReflection, ?string $trait, bool $explicit, array $parameterNameMapping, array $parents) { $this->docComment = $docComment; $this->file = $file; $this->classReflection = $classReflection; $this->trait = $trait; $this->explicit = $explicit; $this->parameterNameMapping = $parameterNameMapping; $this->parents = $parents; } public function getDocComment() : string { return $this->docComment; } public function getFile() : ?string { return $this->file; } public function getClassReflection() : ClassReflection { return $this->classReflection; } public function getTrait() : ?string { return $this->trait; } public function isExplicit() : bool { return $this->explicit; } /** * @return array */ public function getParents() : array { return $this->parents; } /** * @template T * @param array $array * @return array */ public function transformArrayKeysWithParameterNameMapping(array $array) : array { $newArray = []; foreach ($array as $key => $value) { if (!array_key_exists($key, $this->parameterNameMapping)) { continue; } $newArray[$this->parameterNameMapping[$key]] = $value; } return $newArray; } public function transformConditionalReturnTypeWithParameterNameMapping(Type $type) : Type { return TypeTraverser::map($type, function (Type $type, callable $traverse) : Type { if ($type instanceof ConditionalTypeForParameter) { $parameterName = substr($type->getParameterName(), 1); if (array_key_exists($parameterName, $this->parameterNameMapping)) { $type = $type->changeParameterName('$' . $this->parameterNameMapping[$parameterName]); } } return $traverse($type); }); } public function transformAssertTagParameterWithParameterNameMapping(AssertTagParameter $parameter) : AssertTagParameter { $parameterName = substr($parameter->getParameterName(), 1); if (array_key_exists($parameterName, $this->parameterNameMapping)) { $parameter = $parameter->changeParameterName('$' . $this->parameterNameMapping[$parameterName]); } return $parameter; } public static function resolvePhpDocBlockForProperty(?string $docComment, ClassReflection $classReflection, ?string $trait, string $propertyName, ?string $file, ?bool $explicit) : self { $docBlocksFromParents = []; foreach (self::getParentReflections($classReflection) as $parentReflection) { $oneResult = self::resolvePropertyPhpDocBlockFromClass($parentReflection, $propertyName, $explicit ?? $docComment !== null); if ($oneResult === null) { // Null if it is private or from a wrong trait. continue; } $docBlocksFromParents[] = $oneResult; } return new self($docComment ?? \PHPStan\PhpDoc\ResolvedPhpDocBlock::EMPTY_DOC_STRING, $file, $classReflection, $trait, $explicit ?? \true, [], $docBlocksFromParents); } public static function resolvePhpDocBlockForConstant(?string $docComment, ClassReflection $classReflection, string $constantName, ?string $file, ?bool $explicit) : self { $docBlocksFromParents = []; foreach (self::getParentReflections($classReflection) as $parentReflection) { $oneResult = self::resolveConstantPhpDocBlockFromClass($parentReflection, $constantName, $explicit ?? $docComment !== null); if ($oneResult === null) { // Null if it is private or from a wrong trait. continue; } $docBlocksFromParents[] = $oneResult; } return new self($docComment ?? \PHPStan\PhpDoc\ResolvedPhpDocBlock::EMPTY_DOC_STRING, $file, $classReflection, null, $explicit ?? \true, [], $docBlocksFromParents); } /** * @param array $originalPositionalParameterNames * @param array $newPositionalParameterNames */ public static function resolvePhpDocBlockForMethod(?string $docComment, ClassReflection $classReflection, ?string $trait, string $methodName, ?string $file, ?bool $explicit, array $originalPositionalParameterNames, array $newPositionalParameterNames) : self { $docBlocksFromParents = []; foreach (self::getParentReflections($classReflection) as $parentReflection) { $oneResult = self::resolveMethodPhpDocBlockFromClass($parentReflection, $methodName, $explicit ?? $docComment !== null, $newPositionalParameterNames); if ($oneResult === null) { // Null if it is private or from a wrong trait. continue; } $docBlocksFromParents[] = $oneResult; } foreach ($classReflection->getTraits(\true) as $traitReflection) { if (!$traitReflection->hasNativeMethod($methodName)) { continue; } $traitMethod = $traitReflection->getNativeMethod($methodName); $abstract = $traitMethod->isAbstract(); if (is_bool($abstract)) { if (!$abstract) { continue; } } elseif (!$abstract->yes()) { continue; } $methodVariant = $traitMethod->getOnlyVariant(); $positionalMethodParameterNames = []; foreach ($methodVariant->getParameters() as $methodParameter) { $positionalMethodParameterNames[] = $methodParameter->getName(); } $docBlocksFromParents[] = new self($traitMethod->getDocComment() ?? \PHPStan\PhpDoc\ResolvedPhpDocBlock::EMPTY_DOC_STRING, $classReflection->getFileName(), $classReflection, $traitReflection->getName(), $explicit ?? $traitMethod->getDocComment() !== null, self::remapParameterNames($newPositionalParameterNames, $positionalMethodParameterNames), []); } return new self($docComment ?? \PHPStan\PhpDoc\ResolvedPhpDocBlock::EMPTY_DOC_STRING, $file, $classReflection, $trait, $explicit ?? \true, self::remapParameterNames($originalPositionalParameterNames, $newPositionalParameterNames), $docBlocksFromParents); } /** * @param array $originalPositionalParameterNames * @param array $newPositionalParameterNames * @return array */ private static function remapParameterNames(array $originalPositionalParameterNames, array $newPositionalParameterNames) : array { $parameterNameMapping = []; foreach ($originalPositionalParameterNames as $i => $parameterName) { if (!array_key_exists($i, $newPositionalParameterNames)) { continue; } $parameterNameMapping[$newPositionalParameterNames[$i]] = $parameterName; } return $parameterNameMapping; } /** * @return array */ private static function getParentReflections(ClassReflection $classReflection) : array { $result = []; $parent = $classReflection->getParentClass(); if ($parent !== null) { $result[] = $parent; } foreach ($classReflection->getInterfaces() as $interface) { $result[] = $interface; } return $result; } private static function resolveConstantPhpDocBlockFromClass(ClassReflection $classReflection, string $name, bool $explicit) : ?self { if ($classReflection->hasConstant($name)) { $parentReflection = $classReflection->getConstant($name); if ($parentReflection->isPrivate()) { return null; } $classReflection = $parentReflection->getDeclaringClass(); return self::resolvePhpDocBlockForConstant($parentReflection->getDocComment() ?? \PHPStan\PhpDoc\ResolvedPhpDocBlock::EMPTY_DOC_STRING, $classReflection, $name, $classReflection->getFileName(), $explicit); } return null; } private static function resolvePropertyPhpDocBlockFromClass(ClassReflection $classReflection, string $name, bool $explicit) : ?self { if ($classReflection->hasNativeProperty($name)) { $parentReflection = $classReflection->getNativeProperty($name); if ($parentReflection->isPrivate()) { return null; } $classReflection = $parentReflection->getDeclaringClass(); $traitReflection = $parentReflection->getDeclaringTrait(); $trait = $traitReflection !== null ? $traitReflection->getName() : null; return self::resolvePhpDocBlockForProperty($parentReflection->getDocComment() ?? \PHPStan\PhpDoc\ResolvedPhpDocBlock::EMPTY_DOC_STRING, $classReflection, $trait, $name, $classReflection->getFileName(), $explicit); } return null; } /** * @param array $positionalParameterNames */ private static function resolveMethodPhpDocBlockFromClass(ClassReflection $classReflection, string $name, bool $explicit, array $positionalParameterNames) : ?self { if ($classReflection->hasNativeMethod($name)) { $parentReflection = $classReflection->getNativeMethod($name); if ($parentReflection->isPrivate()) { return null; } $classReflection = $parentReflection->getDeclaringClass(); $traitReflection = null; if ($parentReflection instanceof PhpMethodReflection || $parentReflection instanceof ResolvedMethodReflection) { $traitReflection = $parentReflection->getDeclaringTrait(); } $methodVariants = $parentReflection->getVariants(); $positionalMethodParameterNames = []; $lowercaseMethodName = strtolower($parentReflection->getName()); if (count($methodVariants) === 1 && $lowercaseMethodName !== '__construct' && $lowercaseMethodName !== strtolower($parentReflection->getDeclaringClass()->getName())) { $methodParameters = $methodVariants[0]->getParameters(); foreach ($methodParameters as $methodParameter) { $positionalMethodParameterNames[] = $methodParameter->getName(); } } else { $positionalMethodParameterNames = $positionalParameterNames; } $trait = $traitReflection !== null ? $traitReflection->getName() : null; return self::resolvePhpDocBlockForMethod($parentReflection->getDocComment() ?? \PHPStan\PhpDoc\ResolvedPhpDocBlock::EMPTY_DOC_STRING, $classReflection, $trait, $name, $classReflection->getFileName(), $explicit, $positionalParameterNames, $positionalMethodParameterNames); } return null; } } phpVersion = $phpVersion; } public function getFiles() : array { if (!$this->phpVersion->supportsEnums()) { return []; } return [__DIR__ . '/../../stubs/ReflectionEnum.stub']; } } typeLexer = $typeLexer; $this->typeParser = $typeParser; $this->typeNodeResolver = $typeNodeResolver; } /** @api */ public function resolve(string $typeString, ?NameScope $nameScope = null) : Type { $tokens = new TokenIterator($this->typeLexer->tokenize($typeString)); $typeNode = $this->typeParser->parse($tokens); $tokens->consumeTokenType(Lexer::TOKEN_END); // @phpstan-ignore missingType.checkedException return $this->typeNodeResolver->resolve($typeNode, $nameScope ?? new NameScope(null, [])); } } */ private $classMap = []; /** @var array> */ private $propertyMap = []; /** @var array> */ private $constantMap = []; /** @var array> */ private $methodMap = []; /** @var array */ private $functionMap = []; /** * @var bool */ private $initialized = \false; /** * @var bool */ private $initializing = \false; /** @var array */ private $knownClassesDocComments = []; /** @var array */ private $knownFunctionsDocComments = []; /** @var array> */ private $knownPropertiesDocComments = []; /** @var array> */ private $knownConstantsDocComments = []; /** @var array> */ private $knownMethodsDocComments = []; /** @var array>> */ private $knownMethodsParameterNames = []; /** @var array> */ private $knownFunctionParameterNames = []; public function __construct(Parser $parser, FileTypeMapper $fileTypeMapper, \PHPStan\PhpDoc\StubFilesProvider $stubFilesProvider) { $this->parser = $parser; $this->fileTypeMapper = $fileTypeMapper; $this->stubFilesProvider = $stubFilesProvider; } public function findClassPhpDoc(string $className) : ?\PHPStan\PhpDoc\ResolvedPhpDocBlock { if (!$this->isKnownClass($className)) { return null; } if (array_key_exists($className, $this->classMap)) { return $this->classMap[$className]; } if (array_key_exists($className, $this->knownClassesDocComments)) { [$file, $docComment] = $this->knownClassesDocComments[$className]; $this->classMap[$className] = $this->fileTypeMapper->getResolvedPhpDoc($file, $className, null, null, $docComment); return $this->classMap[$className]; } return null; } public function findPropertyPhpDoc(string $className, string $propertyName) : ?\PHPStan\PhpDoc\ResolvedPhpDocBlock { if (!$this->isKnownClass($className)) { return null; } if (array_key_exists($propertyName, $this->propertyMap[$className])) { return $this->propertyMap[$className][$propertyName]; } if (array_key_exists($propertyName, $this->knownPropertiesDocComments[$className])) { [$file, $docComment] = $this->knownPropertiesDocComments[$className][$propertyName]; $this->propertyMap[$className][$propertyName] = $this->fileTypeMapper->getResolvedPhpDoc($file, $className, null, null, $docComment); return $this->propertyMap[$className][$propertyName]; } return null; } public function findClassConstantPhpDoc(string $className, string $constantName) : ?\PHPStan\PhpDoc\ResolvedPhpDocBlock { if (!$this->isKnownClass($className)) { return null; } if (array_key_exists($constantName, $this->constantMap[$className])) { return $this->constantMap[$className][$constantName]; } if (array_key_exists($constantName, $this->knownConstantsDocComments[$className])) { [$file, $docComment] = $this->knownConstantsDocComments[$className][$constantName]; $this->constantMap[$className][$constantName] = $this->fileTypeMapper->getResolvedPhpDoc($file, $className, null, null, $docComment); return $this->constantMap[$className][$constantName]; } return null; } /** * @param array $positionalParameterNames */ public function findMethodPhpDoc(string $className, string $implementingClassName, string $methodName, array $positionalParameterNames) : ?\PHPStan\PhpDoc\ResolvedPhpDocBlock { if (!$this->isKnownClass($className)) { return null; } if (array_key_exists($methodName, $this->methodMap[$className])) { return $this->methodMap[$className][$methodName]; } if (array_key_exists($methodName, $this->knownMethodsDocComments[$className])) { [$file, $docComment] = $this->knownMethodsDocComments[$className][$methodName]; $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($file, $className, null, $methodName, $docComment); if (!isset($this->knownMethodsParameterNames[$className][$methodName])) { throw new ShouldNotHappenException(); } if ($className !== $implementingClassName && $resolvedPhpDoc->getNullableNameScope() !== null) { $resolvedPhpDoc = $resolvedPhpDoc->withNameScope($resolvedPhpDoc->getNullableNameScope()->withClassName($implementingClassName)); } $methodParameterNames = $this->knownMethodsParameterNames[$className][$methodName]; $parameterNameMapping = []; foreach ($positionalParameterNames as $i => $parameterName) { if (!array_key_exists($i, $methodParameterNames)) { continue; } $parameterNameMapping[$methodParameterNames[$i]] = $parameterName; } return $resolvedPhpDoc->changeParameterNamesByMapping($parameterNameMapping); } return null; } /** * @param array $positionalParameterNames * @throws ShouldNotHappenException */ public function findFunctionPhpDoc(string $functionName, array $positionalParameterNames) : ?\PHPStan\PhpDoc\ResolvedPhpDocBlock { if (!$this->isKnownFunction($functionName)) { return null; } if (array_key_exists($functionName, $this->functionMap)) { return $this->functionMap[$functionName]; } if (array_key_exists($functionName, $this->knownFunctionsDocComments)) { [$file, $docComment] = $this->knownFunctionsDocComments[$functionName]; $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($file, null, null, $functionName, $docComment); if (!isset($this->knownFunctionParameterNames[$functionName])) { throw new ShouldNotHappenException(); } $functionParameterNames = $this->knownFunctionParameterNames[$functionName]; $parameterNameMapping = []; foreach ($positionalParameterNames as $i => $parameterName) { if (!array_key_exists($i, $functionParameterNames)) { continue; } $parameterNameMapping[$functionParameterNames[$i]] = $parameterName; } $this->functionMap[$functionName] = $resolvedPhpDoc->changeParameterNamesByMapping($parameterNameMapping); return $this->functionMap[$functionName]; } return null; } public function isKnownClass(string $className) : bool { $this->initializeKnownElements(); if (array_key_exists($className, $this->classMap)) { return \true; } return array_key_exists($className, $this->knownClassesDocComments); } private function isKnownFunction(string $functionName) : bool { $this->initializeKnownElements(); if (array_key_exists($functionName, $this->functionMap)) { return \true; } return array_key_exists($functionName, $this->knownFunctionsDocComments); } private function initializeKnownElements() : void { if ($this->initializing) { throw new ShouldNotHappenException(); } if ($this->initialized) { return; } $this->initializing = \true; try { foreach ($this->stubFilesProvider->getStubFiles() as $stubFile) { $nodes = $this->parser->parseFile($stubFile); foreach ($nodes as $node) { $this->initializeKnownElementNode($stubFile, $node); } } } finally { $this->initializing = \false; $this->initialized = \true; } } private function initializeKnownElementNode(string $stubFile, Node $node) : void { if ($node instanceof Node\Stmt\Namespace_) { foreach ($node->stmts as $stmt) { $this->initializeKnownElementNode($stubFile, $stmt); } return; } if ($node instanceof Node\Stmt\Function_) { $functionName = (string) $node->namespacedName; $docComment = $node->getDocComment(); if ($docComment === null) { $this->functionMap[$functionName] = null; return; } $this->knownFunctionParameterNames[$functionName] = array_map(static function (Node\Param $param) : string { if (!$param->var instanceof Variable || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } return $param->var->name; }, $node->getParams()); $this->knownFunctionsDocComments[$functionName] = [$stubFile, $docComment->getText()]; return; } if (!$node instanceof Class_ && !$node instanceof Interface_ && !$node instanceof Trait_ && !$node instanceof Node\Stmt\Enum_) { return; } if (!isset($node->namespacedName)) { return; } $className = (string) $node->namespacedName; $docComment = $node->getDocComment(); if ($docComment === null) { $this->classMap[$className] = null; } else { $this->knownClassesDocComments[$className] = [$stubFile, $docComment->getText()]; } $this->methodMap[$className] = []; $this->propertyMap[$className] = []; $this->constantMap[$className] = []; $this->knownPropertiesDocComments[$className] = []; $this->knownConstantsDocComments[$className] = []; $this->knownMethodsDocComments[$className] = []; foreach ($node->stmts as $stmt) { $docComment = $stmt->getDocComment(); if ($stmt instanceof Node\Stmt\Property) { foreach ($stmt->props as $property) { if ($docComment === null) { $this->propertyMap[$className][$property->name->toString()] = null; continue; } $this->knownPropertiesDocComments[$className][$property->name->toString()] = [$stubFile, $docComment->getText()]; } } elseif ($stmt instanceof Node\Stmt\ClassConst) { foreach ($stmt->consts as $const) { if ($docComment === null) { $this->constantMap[$className][$const->name->toString()] = null; continue; } $this->knownConstantsDocComments[$className][$const->name->toString()] = [$stubFile, $docComment->getText()]; } } elseif ($stmt instanceof Node\Stmt\ClassMethod) { if ($docComment === null) { $this->methodMap[$className][$stmt->name->toString()] = null; continue; } $methodName = $stmt->name->toString(); $this->knownMethodsDocComments[$className][$methodName] = [$stubFile, $docComment->getText()]; $this->knownMethodsParameterNames[$className][$methodName] = array_map(static function (Node\Param $param) : string { if (!$param->var instanceof Variable || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } return $param->var->name; }, $stmt->getParams()); } } } } unescapeStrings = $unescapeStrings; } public function create() : ConstExprParser { return new ConstExprParser($this->unescapeStrings, $this->unescapeStrings); } } container = $container; } public function getRegistry() : \PHPStan\PhpDoc\TypeNodeResolverExtensionRegistry { if ($this->registry === null) { $this->registry = new \PHPStan\PhpDoc\TypeNodeResolverExtensionAwareRegistry($this->container->getByType(\PHPStan\PhpDoc\TypeNodeResolver::class), $this->container->getServicesByTag(\PHPStan\PhpDoc\TypeNodeResolverExtension::EXTENSION_TAG)); } return $this->registry; } } phpDocLexer = $phpDocLexer; $this->phpDocParser = $phpDocParser; } public function resolve(string $phpDocString) : PhpDocNode { $tokens = new TokenIterator($this->phpDocLexer->tokenize($phpDocString)); $phpDocNode = $this->phpDocParser->parse($tokens); $tokens->consumeTokenType(Lexer::TOKEN_END); // @phpstan-ignore missingType.checkedException return $phpDocNode; } } php8Parser = $php8Parser; $this->phpStormStubsSourceStubber = $phpStormStubsSourceStubber; $this->optimizedSingleFileSourceLocatorRepository = $optimizedSingleFileSourceLocatorRepository; $this->optimizedPsrAutoloaderLocatorFactory = $optimizedPsrAutoloaderLocatorFactory; $this->stubFilesProvider = $stubFilesProvider; } public function create() : SourceLocator { $locators = []; $astPhp8Locator = new Locator($this->php8Parser); foreach ($this->stubFilesProvider->getStubFiles() as $stubFile) { $locators[] = $this->optimizedSingleFileSourceLocatorRepository->getOrCreate($stubFile); } $locators[] = $this->optimizedPsrAutoloaderLocatorFactory->create(Psr4Mapping::fromArrayMappings(['PHPStan\\' => [dirname(__DIR__) . '/']])); $locators[] = $this->optimizedPsrAutoloaderLocatorFactory->create(Psr4Mapping::fromArrayMappings(['PhpParser\\' => [dirname(__DIR__, 2) . '/vendor/nikic/php-parser/lib/PhpParser/']])); $locators[] = new PhpInternalSourceLocator($astPhp8Locator, $this->phpStormStubsSourceStubber); return new MemoizingSourceLocator(new AggregateSourceLocator($locators)); } } phpVersion = $phpVersion; } public function getFiles() : array { if (!$this->phpVersion->supportsJsonValidate()) { return []; } return [__DIR__ . '/../../stubs/json_validate.stub']; } } derivativeContainerFactory = $derivativeContainerFactory; $this->duplicateStubs = $duplicateStubs; } /** * @param string[] $stubFiles * @return list */ public function validate(array $stubFiles, bool $debug) : array { if (count($stubFiles) === 0) { return []; } $originalBroker = Broker::getInstance(); $originalReflectionProvider = ReflectionProviderStaticAccessor::getInstance(); $originalPhpVersion = PhpVersionStaticAccessor::getInstance(); $container = $this->derivativeContainerFactory->create([__DIR__ . '/../../conf/config.stubValidator.neon']); $ruleRegistry = $this->getRuleRegistry($container); $collectorRegistry = $this->getCollectorRegistry($container); $fileAnalyser = $container->getByType(FileAnalyser::class); $nodeScopeResolver = $container->getByType(NodeScopeResolver::class); $nodeScopeResolver->setAnalysedFiles($stubFiles); $pathRoutingParser = $container->getService('pathRoutingParser'); $pathRoutingParser->setAnalysedFiles($stubFiles); $analysedFiles = array_fill_keys($stubFiles, \true); $errors = []; foreach ($stubFiles as $stubFile) { try { $tmpErrors = $fileAnalyser->analyseFile($stubFile, $analysedFiles, $ruleRegistry, $collectorRegistry, static function () : void { })->getErrors(); foreach ($tmpErrors as $tmpError) { $errors[] = $tmpError->withoutTip()->doNotIgnore(); } } catch (Throwable $e) { if ($debug) { throw $e; } $internalErrorMessage = sprintf('Internal error: %s', $e->getMessage()); $errors[] = (new Error($internalErrorMessage, $stubFile, null, $e))->withIdentifier('phpstan.internal')->withMetadata([InternalError::STACK_TRACE_METADATA_KEY => InternalError::prepareTrace($e), InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); } } Broker::registerInstance($originalBroker); ReflectionProviderStaticAccessor::registerInstance($originalReflectionProvider); PhpVersionStaticAccessor::registerInstance($originalPhpVersion); ObjectType::resetCaches(); return $errors; } private function getRuleRegistry(Container $container) : RuleRegistry { $fileTypeMapper = $container->getByType(FileTypeMapper::class); $genericObjectTypeCheck = $container->getByType(GenericObjectTypeCheck::class); $genericAncestorsCheck = $container->getByType(GenericAncestorsCheck::class); $templateTypeCheck = $container->getByType(TemplateTypeCheck::class); $varianceCheck = $container->getByType(VarianceCheck::class); $reflectionProvider = $container->getByType(ReflectionProvider::class); $classNameCheck = $container->getByType(ClassNameCheck::class); $functionDefinitionCheck = $container->getByType(FunctionDefinitionCheck::class); $missingTypehintCheck = $container->getByType(MissingTypehintCheck::class); $unresolvableTypeHelper = $container->getByType(UnresolvableTypeHelper::class); $crossCheckInterfacesHelper = $container->getByType(CrossCheckInterfacesHelper::class); $phpVersion = $container->getByType(PhpVersion::class); $localTypeAliasesCheck = $container->getByType(LocalTypeAliasesCheck::class); $phpClassReflectionExtension = $container->getByType(PhpClassReflectionExtension::class); $genericCallableRuleHelper = $container->getByType(GenericCallableRuleHelper::class); $methodTagTemplateTypeCheck = $container->getByType(MethodTagTemplateTypeCheck::class); $mixinCheck = $container->getByType(MixinCheck::class); $rules = [ // level 0 new ExistingClassesInClassImplementsRule($classNameCheck, $reflectionProvider), new ExistingClassesInInterfaceExtendsRule($classNameCheck, $reflectionProvider), new ExistingClassInClassExtendsRule($classNameCheck, $reflectionProvider), new ExistingClassInTraitUseRule($classNameCheck, $reflectionProvider), new ExistingClassesInTypehintsRule($functionDefinitionCheck), new \PHPStan\Rules\Functions\ExistingClassesInTypehintsRule($functionDefinitionCheck), new ExistingClassesInPropertiesRule($reflectionProvider, $classNameCheck, $unresolvableTypeHelper, $phpVersion, \true, \false), new OverridingMethodRule($phpVersion, new MethodSignatureRule($phpClassReflectionExtension, \true, \true, $container->getParameter('featureToggles')['abstractTraitMethod']), \true, new MethodParameterComparisonHelper($phpVersion, $container->getParameter('featureToggles')['genericPrototypeMessage']), $phpClassReflectionExtension, $container->getParameter('featureToggles')['genericPrototypeMessage'], $container->getParameter('featureToggles')['finalByPhpDoc'], $container->getParameter('checkMissingOverrideMethodAttribute')), new DuplicateDeclarationRule(), new LocalTypeAliasesRule($localTypeAliasesCheck), new LocalTypeTraitAliasesRule($localTypeAliasesCheck, $reflectionProvider), // level 2 new ClassAncestorsRule($genericAncestorsCheck, $crossCheckInterfacesHelper), new ClassTemplateTypeRule($templateTypeCheck), new FunctionTemplateTypeRule($fileTypeMapper, $templateTypeCheck), new FunctionSignatureVarianceRule($varianceCheck), new InterfaceAncestorsRule($genericAncestorsCheck, $crossCheckInterfacesHelper), new InterfaceTemplateTypeRule($templateTypeCheck), new MethodTemplateTypeRule($fileTypeMapper, $templateTypeCheck), new MethodTagTemplateTypeRule($methodTagTemplateTypeCheck), new MethodSignatureVarianceRule($varianceCheck), new TraitTemplateTypeRule($fileTypeMapper, $templateTypeCheck), new IncompatiblePhpDocTypeRule($fileTypeMapper, $genericObjectTypeCheck, $unresolvableTypeHelper, $genericCallableRuleHelper), new IncompatiblePropertyPhpDocTypeRule($genericObjectTypeCheck, $unresolvableTypeHelper, $genericCallableRuleHelper), new InvalidPhpDocTagValueRule($container->getByType(Lexer::class), $container->getByType(PhpDocParser::class), $container->getParameter('featureToggles')['allInvalidPhpDocs'], $container->getParameter('featureToggles')['invalidPhpDocTagLine']), new IncompatibleParamImmediatelyInvokedCallableRule($fileTypeMapper), new IncompatibleSelfOutTypeRule($unresolvableTypeHelper, $genericObjectTypeCheck), new IncompatibleClassConstantPhpDocTypeRule($genericObjectTypeCheck, $unresolvableTypeHelper), new InvalidThrowsPhpDocValueRule($fileTypeMapper), // level 6 new MissingFunctionParameterTypehintRule($missingTypehintCheck, $container->getParameter('featureToggles')['paramOutType']), new MissingFunctionReturnTypehintRule($missingTypehintCheck), new MissingMethodParameterTypehintRule($missingTypehintCheck, $container->getParameter('featureToggles')['paramOutType']), new MissingMethodReturnTypehintRule($missingTypehintCheck), new MissingPropertyTypehintRule($missingTypehintCheck), ]; if ($this->duplicateStubs) { $reflector = $container->getService('stubReflector'); $relativePathHelper = $container->getService('simpleRelativePathHelper'); $rules[] = new DuplicateClassDeclarationRule($reflector, $relativePathHelper); $rules[] = new DuplicateFunctionDeclarationRule($reflector, $relativePathHelper); } if ((bool) $container->getParameter('featureToggles')['allInvalidPhpDocs']) { $rules[] = new InvalidPHPStanDocTagRule($container->getByType(Lexer::class), $container->getByType(PhpDocParser::class), \true); } if ((bool) $container->getParameter('featureToggles')['absentTypeChecks']) { $rules[] = new MissingMethodSelfOutTypeRule($missingTypehintCheck); $methodTagCheck = new MethodTagCheck($reflectionProvider, $classNameCheck, $genericObjectTypeCheck, $missingTypehintCheck, $unresolvableTypeHelper, \true, \true); $rules[] = new MethodTagRule($methodTagCheck); $rules[] = new MethodTagTraitRule($methodTagCheck, $reflectionProvider); $rules[] = new MethodTagTraitUseRule($methodTagCheck); $propertyTagCheck = new PropertyTagCheck($reflectionProvider, $classNameCheck, $genericObjectTypeCheck, $missingTypehintCheck, $unresolvableTypeHelper, \true, \true); $rules[] = new PropertyTagRule($propertyTagCheck); $rules[] = new PropertyTagTraitRule($propertyTagCheck, $reflectionProvider); $rules[] = new PropertyTagTraitUseRule($propertyTagCheck); $rules[] = new MixinRule($mixinCheck); $rules[] = new MixinTraitRule($mixinCheck, $reflectionProvider); $rules[] = new MixinTraitUseRule($mixinCheck); $rules[] = new LocalTypeTraitUseAliasesRule($localTypeAliasesCheck); $rules[] = new MethodTagTemplateTypeTraitRule($methodTagTemplateTypeCheck, $reflectionProvider); } return new DirectRuleRegistry($rules); } private function getCollectorRegistry(Container $container) : CollectorRegistry { return new CollectorRegistry([]); } } fileTypeMapper = $fileTypeMapper; $this->stubPhpDocProvider = $stubPhpDocProvider; } public function resolvePhpDocForProperty(?string $docComment, ClassReflection $classReflection, ?string $classReflectionFileName, ?string $declaringTraitName, string $propertyName) : \PHPStan\PhpDoc\ResolvedPhpDocBlock { $phpDocBlock = \PHPStan\PhpDoc\PhpDocBlock::resolvePhpDocBlockForProperty($docComment, $classReflection, null, $propertyName, $classReflectionFileName, null); return $this->docBlockTreeToResolvedDocBlock($phpDocBlock, $declaringTraitName, null, $propertyName, null); } public function resolvePhpDocForConstant(?string $docComment, ClassReflection $classReflection, ?string $classReflectionFileName, string $constantName) : \PHPStan\PhpDoc\ResolvedPhpDocBlock { $phpDocBlock = \PHPStan\PhpDoc\PhpDocBlock::resolvePhpDocBlockForConstant($docComment, $classReflection, $constantName, $classReflectionFileName, null); return $this->docBlockTreeToResolvedDocBlock($phpDocBlock, null, null, null, $constantName); } /** * @param array $positionalParameterNames */ public function resolvePhpDocForMethod(?string $docComment, ?string $fileName, ClassReflection $classReflection, ?string $declaringTraitName, string $methodName, array $positionalParameterNames) : \PHPStan\PhpDoc\ResolvedPhpDocBlock { $phpDocBlock = \PHPStan\PhpDoc\PhpDocBlock::resolvePhpDocBlockForMethod($docComment, $classReflection, $declaringTraitName, $methodName, $fileName, null, $positionalParameterNames, $positionalParameterNames); return $this->docBlockTreeToResolvedDocBlock($phpDocBlock, $phpDocBlock->getTrait(), $methodName, null, null); } private function docBlockTreeToResolvedDocBlock(\PHPStan\PhpDoc\PhpDocBlock $phpDocBlock, ?string $traitName, ?string $functionName, ?string $propertyName, ?string $constantName) : \PHPStan\PhpDoc\ResolvedPhpDocBlock { $parents = []; $parentPhpDocBlocks = []; foreach ($phpDocBlock->getParents() as $parentPhpDocBlock) { if ($functionName !== null && strtolower($functionName) === '__construct' && $parentPhpDocBlock->getClassReflection()->isBuiltin()) { continue; } $parents[] = $this->docBlockTreeToResolvedDocBlock($parentPhpDocBlock, $parentPhpDocBlock->getTrait(), $functionName, $propertyName, $constantName); $parentPhpDocBlocks[] = $parentPhpDocBlock; } $oneResolvedDockBlock = $this->docBlockToResolvedDocBlock($phpDocBlock, $traitName, $functionName, $propertyName, $constantName); return $oneResolvedDockBlock->merge($parents, $parentPhpDocBlocks); } private function docBlockToResolvedDocBlock(\PHPStan\PhpDoc\PhpDocBlock $phpDocBlock, ?string $traitName, ?string $functionName, ?string $propertyName, ?string $constantName) : \PHPStan\PhpDoc\ResolvedPhpDocBlock { $classReflection = $phpDocBlock->getClassReflection(); if ($functionName !== null && $classReflection->getNativeReflection()->hasMethod($functionName)) { $methodReflection = $classReflection->getNativeReflection()->getMethod($functionName); $stub = $this->stubPhpDocProvider->findMethodPhpDoc($classReflection->getName(), $classReflection->getName(), $functionName, array_map(static function (ReflectionParameter $parameter) : string { return $parameter->getName(); }, $methodReflection->getParameters())); if ($stub !== null) { return $stub; } } if ($propertyName !== null && $classReflection->getNativeReflection()->hasProperty($propertyName)) { $stub = $this->stubPhpDocProvider->findPropertyPhpDoc($classReflection->getName(), $propertyName); if ($stub === null) { $propertyReflection = $classReflection->getNativeReflection()->getProperty($propertyName); $propertyDeclaringClass = $propertyReflection->getBetterReflection()->getDeclaringClass(); if ($propertyDeclaringClass->isTrait() && (!$propertyReflection->getDeclaringClass()->isTrait() || $propertyReflection->getDeclaringClass()->getName() !== $propertyDeclaringClass->getName())) { $stub = $this->stubPhpDocProvider->findPropertyPhpDoc($propertyDeclaringClass->getName(), $propertyName); } } if ($stub !== null) { return $stub; } } if ($constantName !== null && $classReflection->getNativeReflection()->hasConstant($constantName)) { $stub = $this->stubPhpDocProvider->findClassConstantPhpDoc($classReflection->getName(), $constantName); if ($stub !== null) { return $stub; } } return $this->fileTypeMapper->getResolvedPhpDoc($phpDocBlock->getFile(), $classReflection->getName(), $traitName, $functionName, $phpDocBlock->getDocComment()); } } bleedingEdge = $bleedingEdge; } public function getFiles() : array { if ($this->bleedingEdge) { return [__DIR__ . '/../../stubs/bleedingEdge/Countable.stub']; } return [__DIR__ . '/../../stubs/Countable.stub']; } } extensions = $extensions; foreach ($extensions as $extension) { if (!$extension instanceof \PHPStan\PhpDoc\TypeNodeResolverAwareExtension) { continue; } $extension->setTypeNodeResolver($typeNodeResolver); } } /** * @return TypeNodeResolverExtension[] */ public function getExtensions() : array { return $this->extensions; } } reflectionProviderProvider = $reflectionProviderProvider; $this->initializerExprTypeResolver = $initializerExprTypeResolver; } public function resolve(ConstExprNode $node, NameScope $nameScope) : Type { if ($node instanceof ConstExprArrayNode) { return $this->resolveArrayNode($node, $nameScope); } if ($node instanceof ConstExprFalseNode) { return new ConstantBooleanType(\false); } if ($node instanceof ConstExprTrueNode) { return new ConstantBooleanType(\true); } if ($node instanceof ConstExprFloatNode) { return new ConstantFloatType((float) $node->value); } if ($node instanceof ConstExprIntegerNode) { return new ConstantIntegerType((int) $node->value); } if ($node instanceof ConstExprNullNode) { return new NullType(); } if ($node instanceof ConstExprStringNode) { return new ConstantStringType($node->value); } if ($node instanceof ConstFetchNode) { if ($nameScope->getClassName() !== null) { switch (strtolower($node->className)) { case 'static': case 'self': $className = $nameScope->getClassName(); break; case 'parent': if ($this->getReflectionProvider()->hasClass($nameScope->getClassName())) { $classReflection = $this->getReflectionProvider()->getClass($nameScope->getClassName()); if ($classReflection->getParentClass() === null) { return new ErrorType(); } $className = $classReflection->getParentClass()->getName(); } break; } } if (!isset($className)) { $className = $nameScope->resolveStringName($node->className); } if (!$this->getReflectionProvider()->hasClass($className)) { return new ErrorType(); } $classReflection = $this->getReflectionProvider()->getClass($className); if (!$classReflection->hasConstant($node->name)) { return new ErrorType(); } if ($classReflection->isEnum() && $classReflection->hasEnumCase($node->name)) { return new EnumCaseObjectType($classReflection->getName(), $node->name); } $reflectionConstant = $classReflection->getNativeReflection()->getReflectionConstant($node->name); if ($reflectionConstant === \false) { return new ErrorType(); } $declaringClass = $reflectionConstant->getDeclaringClass(); return $this->initializerExprTypeResolver->getType($reflectionConstant->getValueExpression(), InitializerExprContext::fromClass($declaringClass->getName(), $declaringClass->getFileName() ?: null)); } return new ErrorType(); } private function resolveArrayNode(ConstExprArrayNode $node, NameScope $nameScope) : Type { $arrayBuilder = ConstantArrayTypeBuilder::createEmpty(); foreach ($node->items as $item) { if ($item->key === null) { $key = null; } else { $key = $this->resolve($item->key, $nameScope); } $arrayBuilder->setOffsetValueType($key, $this->resolve($item->value, $nameScope)); } return $arrayBuilder->getArray(); } private function getReflectionProvider() : ReflectionProvider { return $this->reflectionProviderProvider->getReflectionProvider(); } } typeNodeResolver = $typeNodeResolver; $this->constExprNodeResolver = $constExprNodeResolver; $this->unresolvableTypeHelper = $unresolvableTypeHelper; } /** * @return array<(string|int), VarTag> */ public function resolveVarTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $resolved = []; $resolvedByTag = []; foreach (['@var', '@phan-var', '@psalm-var', '@phpstan-var'] as $tagName) { $tagResolved = []; foreach ($phpDocNode->getVarTagValues($tagName) as $tagValue) { $type = $this->typeNodeResolver->resolve($tagValue->type, $nameScope); if ($this->shouldSkipType($tagName, $type)) { continue; } if ($tagValue->variableName !== '') { $variableName = substr($tagValue->variableName, 1); $resolved[$variableName] = new VarTag($type, \true); } else { $varTag = new VarTag($type, \true); $tagResolved[] = $varTag; } } if (count($tagResolved) === 0) { continue; } $resolvedByTag[] = $tagResolved; } if (count($resolvedByTag) > 0) { return array_reverse($resolvedByTag)[0]; } return $resolved; } /** * @return array */ public function resolvePropertyTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $resolved = []; foreach (['@property', '@phpstan-property'] as $tagName) { foreach ($phpDocNode->getPropertyTagValues($tagName) as $tagValue) { $propertyName = substr($tagValue->propertyName, 1); $propertyType = $this->typeNodeResolver->resolve($tagValue->type, $nameScope); $resolved[$propertyName] = new PropertyTag($propertyType, $propertyType, $propertyType); } } foreach (['@property-read', '@phpstan-property-read'] as $tagName) { foreach ($phpDocNode->getPropertyReadTagValues($tagName) as $tagValue) { $propertyName = substr($tagValue->propertyName, 1); $propertyType = $this->typeNodeResolver->resolve($tagValue->type, $nameScope); $writableType = null; if (array_key_exists($propertyName, $resolved)) { $writableType = $resolved[$propertyName]->getWritableType(); } $resolved[$propertyName] = new PropertyTag($propertyType, $propertyType, $writableType); } } foreach (['@property-write', '@phpstan-property-write'] as $tagName) { foreach ($phpDocNode->getPropertyWriteTagValues($tagName) as $tagValue) { $propertyName = substr($tagValue->propertyName, 1); $propertyType = $this->typeNodeResolver->resolve($tagValue->type, $nameScope); $readableType = null; if (array_key_exists($propertyName, $resolved)) { $readableType = $resolved[$propertyName]->getReadableType(); } $resolved[$propertyName] = new PropertyTag($readableType ?? $propertyType, $readableType, $propertyType); } } return $resolved; } /** * @return array */ public function resolveMethodTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $resolved = []; $originalNameScope = $nameScope; foreach (['@method', '@phan-method', '@psalm-method', '@phpstan-method'] as $tagName) { foreach ($phpDocNode->getMethodTagValues($tagName) as $tagValue) { $nameScope = $originalNameScope; $templateTags = []; if (count($tagValue->templateTypes) > 0 && $nameScope->getClassName() !== null) { foreach ($tagValue->templateTypes as $templateType) { $templateTags[$templateType->name] = new TemplateTag($templateType->name, $templateType->bound !== null ? $this->typeNodeResolver->resolve($templateType->bound, $nameScope) : new MixedType(), $templateType->default !== null ? $this->typeNodeResolver->resolve($templateType->default, $nameScope) : null, TemplateTypeVariance::createInvariant()); } $templateTypeScope = TemplateTypeScope::createWithMethod($nameScope->getClassName(), $tagValue->methodName); $templateTypeMap = new TemplateTypeMap(array_map(static function (TemplateTag $tag) use($templateTypeScope) : Type { return TemplateTypeFactory::fromTemplateTag($templateTypeScope, $tag); }, $templateTags)); $nameScope = $nameScope->withTemplateTypeMap($templateTypeMap); } $parameters = []; foreach ($tagValue->parameters as $parameterNode) { $parameterName = substr($parameterNode->parameterName, 1); $type = $parameterNode->type !== null ? $this->typeNodeResolver->resolve($parameterNode->type, $nameScope) : new MixedType(); if ($parameterNode->defaultValue instanceof ConstExprNullNode) { $type = TypeCombinator::addNull($type); } $defaultValue = null; if ($parameterNode->defaultValue !== null) { $defaultValue = $this->constExprNodeResolver->resolve($parameterNode->defaultValue, $nameScope); } $parameters[$parameterName] = new MethodTagParameter($type, $parameterNode->isReference ? PassedByReference::createCreatesNewVariable() : PassedByReference::createNo(), $parameterNode->isVariadic || $parameterNode->defaultValue !== null, $parameterNode->isVariadic, $defaultValue); } $resolved[$tagValue->methodName] = new MethodTag($tagValue->returnType !== null ? $this->typeNodeResolver->resolve($tagValue->returnType, $nameScope) : new MixedType(), $tagValue->isStatic, $parameters, $templateTags); } } return $resolved; } /** * @return array */ public function resolveExtendsTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $resolved = []; foreach (['@extends', '@phan-extends', '@phan-inherits', '@template-extends', '@phpstan-extends'] as $tagName) { foreach ($phpDocNode->getExtendsTagValues($tagName) as $tagValue) { $resolved[$nameScope->resolveStringName($tagValue->type->type->name)] = new ExtendsTag($this->typeNodeResolver->resolve($tagValue->type, $nameScope)); } } return $resolved; } /** * @return array */ public function resolveImplementsTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $resolved = []; foreach (['@implements', '@template-implements', '@phpstan-implements'] as $tagName) { foreach ($phpDocNode->getImplementsTagValues($tagName) as $tagValue) { $resolved[$nameScope->resolveStringName($tagValue->type->type->name)] = new ImplementsTag($this->typeNodeResolver->resolve($tagValue->type, $nameScope)); } } return $resolved; } /** * @return array */ public function resolveUsesTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $resolved = []; foreach (['@use', '@template-use', '@phpstan-use'] as $tagName) { foreach ($phpDocNode->getUsesTagValues($tagName) as $tagValue) { $resolved[$nameScope->resolveStringName($tagValue->type->type->name)] = new UsesTag($this->typeNodeResolver->resolve($tagValue->type, $nameScope)); } } return $resolved; } /** * @return array */ public function resolveTemplateTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $resolved = []; $resolvedPrefix = []; $prefixPriority = ['' => 0, 'phan' => 1, 'psalm' => 2, 'phpstan' => 3]; foreach ($phpDocNode->getTags() as $phpDocTagNode) { $valueNode = $phpDocTagNode->value; if (!$valueNode instanceof TemplateTagValueNode) { continue; } $tagName = $phpDocTagNode->name; if (in_array($tagName, ['@template', '@phan-template', '@psalm-template', '@phpstan-template'], \true)) { $variance = TemplateTypeVariance::createInvariant(); } elseif (in_array($tagName, ['@template-covariant', '@psalm-template-covariant', '@phpstan-template-covariant'], \true)) { $variance = TemplateTypeVariance::createCovariant(); } elseif (in_array($tagName, ['@template-contravariant', '@psalm-template-contravariant', '@phpstan-template-contravariant'], \true)) { $variance = TemplateTypeVariance::createContravariant(); } else { continue; } if (str_starts_with($tagName, '@phan-')) { $prefix = 'phan'; } elseif (str_starts_with($tagName, '@psalm-')) { $prefix = 'psalm'; } elseif (str_starts_with($tagName, '@phpstan-')) { $prefix = 'phpstan'; } else { $prefix = ''; } if (isset($resolved[$valueNode->name])) { $setPrefix = $resolvedPrefix[$valueNode->name]; if ($prefixPriority[$prefix] <= $prefixPriority[$setPrefix]) { continue; } } $nameScopeWithoutCurrent = $nameScope->unsetTemplateType($valueNode->name); $resolved[$valueNode->name] = new TemplateTag($valueNode->name, $valueNode->bound !== null ? $this->typeNodeResolver->resolve($valueNode->bound, $nameScopeWithoutCurrent) : new MixedType(\true), $valueNode->default !== null ? $this->typeNodeResolver->resolve($valueNode->default, $nameScopeWithoutCurrent) : null, $variance); $resolvedPrefix[$valueNode->name] = $prefix; } return $resolved; } /** * @return array */ public function resolveParamTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $resolved = []; foreach (['@param', '@phan-param', '@psalm-param', '@phpstan-param'] as $tagName) { foreach ($phpDocNode->getParamTagValues($tagName) as $tagValue) { $parameterName = substr($tagValue->parameterName, 1); $parameterType = $this->typeNodeResolver->resolve($tagValue->type, $nameScope); if ($this->shouldSkipType($tagName, $parameterType)) { continue; } $resolved[$parameterName] = new ParamTag($parameterType, $tagValue->isVariadic); } } return $resolved; } /** * @return array */ public function resolveParamOutTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { if (!method_exists($phpDocNode, 'getParamOutTypeTagValues')) { return []; } $resolved = []; foreach (['@param-out', '@psalm-param-out', '@phpstan-param-out'] as $tagName) { foreach ($phpDocNode->getParamOutTypeTagValues($tagName) as $tagValue) { $parameterName = substr($tagValue->parameterName, 1); $parameterType = $this->typeNodeResolver->resolve($tagValue->type, $nameScope); if ($this->shouldSkipType($tagName, $parameterType)) { continue; } $resolved[$parameterName] = new ParamOutTag($parameterType); } } return $resolved; } /** * @return array */ public function resolveParamImmediatelyInvokedCallable(PhpDocNode $phpDocNode) : array { $parameters = []; foreach (['@param-immediately-invoked-callable', '@phpstan-param-immediately-invoked-callable'] as $tagName) { foreach ($phpDocNode->getParamImmediatelyInvokedCallableTagValues($tagName) as $tagValue) { $parameterName = substr($tagValue->parameterName, 1); $parameters[$parameterName] = \true; } } foreach (['@param-later-invoked-callable', '@phpstan-param-later-invoked-callable'] as $tagName) { foreach ($phpDocNode->getParamLaterInvokedCallableTagValues($tagName) as $tagValue) { $parameterName = substr($tagValue->parameterName, 1); $parameters[$parameterName] = \false; } } return $parameters; } /** * @return array */ public function resolveParamClosureThisTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $closureThisTypes = []; foreach (['@param-closure-this', '@phpstan-param-closure-this'] as $tagName) { foreach ($phpDocNode->getParamClosureThisTagValues($tagName) as $tagValue) { $parameterName = substr($tagValue->parameterName, 1); $closureThisTypes[$parameterName] = new ParamClosureThisTag(TypeCombinator::intersect($this->typeNodeResolver->resolve($tagValue->type, $nameScope), new ObjectWithoutClassType())); } } return $closureThisTypes; } public function resolveReturnTag(PhpDocNode $phpDocNode, NameScope $nameScope) : ?ReturnTag { $resolved = null; foreach (['@return', '@phan-return', '@phan-real-return', '@psalm-return', '@phpstan-return'] as $tagName) { foreach ($phpDocNode->getReturnTagValues($tagName) as $tagValue) { $type = $this->typeNodeResolver->resolve($tagValue->type, $nameScope); if ($this->shouldSkipType($tagName, $type)) { continue; } $resolved = new ReturnTag($type, \true); } } return $resolved; } public function resolveThrowsTags(PhpDocNode $phpDocNode, NameScope $nameScope) : ?ThrowsTag { foreach (['@phpstan-throws', '@throws'] as $tagName) { $types = []; foreach ($phpDocNode->getThrowsTagValues($tagName) as $tagValue) { $type = $this->typeNodeResolver->resolve($tagValue->type, $nameScope); if ($this->shouldSkipType($tagName, $type)) { continue; } $types[] = $type; } if (count($types) > 0) { return new ThrowsTag(TypeCombinator::union(...$types)); } } return null; } /** * @return array */ public function resolveMixinTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { return array_map(function (MixinTagValueNode $mixinTagValueNode) use($nameScope) : MixinTag { return new MixinTag($this->typeNodeResolver->resolve($mixinTagValueNode->type, $nameScope)); }, $phpDocNode->getMixinTagValues()); } /** * @return array */ public function resolveRequireExtendsTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $resolved = []; foreach (['@psalm-require-extends', '@phpstan-require-extends'] as $tagName) { foreach ($phpDocNode->getRequireExtendsTagValues($tagName) as $tagValue) { $resolved[] = new RequireExtendsTag($this->typeNodeResolver->resolve($tagValue->type, $nameScope)); } } return $resolved; } /** * @return array */ public function resolveRequireImplementsTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $resolved = []; foreach (['@psalm-require-implements', '@phpstan-require-implements'] as $tagName) { foreach ($phpDocNode->getRequireImplementsTagValues($tagName) as $tagValue) { $resolved[] = new RequireImplementsTag($this->typeNodeResolver->resolve($tagValue->type, $nameScope)); } } return $resolved; } /** * @return array */ public function resolveTypeAliasTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $resolved = []; foreach (['@phan-type', '@psalm-type', '@phpstan-type'] as $tagName) { foreach ($phpDocNode->getTypeAliasTagValues($tagName) as $typeAliasTagValue) { $alias = $typeAliasTagValue->alias; $typeNode = $typeAliasTagValue->type; $resolved[$alias] = new TypeAliasTag($alias, $typeNode, $nameScope); } } return $resolved; } /** * @return array */ public function resolveTypeAliasImportTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { $resolved = []; foreach (['@psalm-import-type', '@phpstan-import-type'] as $tagName) { foreach ($phpDocNode->getTypeAliasImportTagValues($tagName) as $typeAliasImportTagValue) { $importedAlias = $typeAliasImportTagValue->importedAlias; $importedFrom = $nameScope->resolveStringName($typeAliasImportTagValue->importedFrom->name); $importedAs = $typeAliasImportTagValue->importedAs; $resolved[$importedAs ?? $importedAlias] = new TypeAliasImportTag($importedAlias, $importedFrom, $importedAs); } } return $resolved; } /** * @return AssertTag[] */ public function resolveAssertTags(PhpDocNode $phpDocNode, NameScope $nameScope) : array { foreach (['@phpstan', '@psalm', '@phan'] as $prefix) { $resolved = array_merge($this->resolveAssertTagsFor($phpDocNode, $nameScope, $prefix . '-assert', AssertTag::NULL), $this->resolveAssertTagsFor($phpDocNode, $nameScope, $prefix . '-assert-if-true', AssertTag::IF_TRUE), $this->resolveAssertTagsFor($phpDocNode, $nameScope, $prefix . '-assert-if-false', AssertTag::IF_FALSE)); if (count($resolved) > 0) { return $resolved; } } return []; } /** * @param AssertTag::NULL|AssertTag::IF_TRUE|AssertTag::IF_FALSE $if * @return AssertTag[] */ private function resolveAssertTagsFor(PhpDocNode $phpDocNode, NameScope $nameScope, string $tagName, string $if) : array { $resolved = []; foreach ($phpDocNode->getAssertTagValues($tagName) as $assertTagValue) { $type = $this->typeNodeResolver->resolve($assertTagValue->type, $nameScope); $parameter = new AssertTagParameter($assertTagValue->parameter, null, null); $resolved[] = new AssertTag($if, $type, $parameter, $assertTagValue->isNegated, $assertTagValue->isEquality ?? \false, \true); } foreach ($phpDocNode->getAssertPropertyTagValues($tagName) as $assertTagValue) { $type = $this->typeNodeResolver->resolve($assertTagValue->type, $nameScope); $parameter = new AssertTagParameter($assertTagValue->parameter, $assertTagValue->property, null); $resolved[] = new AssertTag($if, $type, $parameter, $assertTagValue->isNegated, $assertTagValue->isEquality ?? \false, \true); } foreach ($phpDocNode->getAssertMethodTagValues($tagName) as $assertTagValue) { $type = $this->typeNodeResolver->resolve($assertTagValue->type, $nameScope); $parameter = new AssertTagParameter($assertTagValue->parameter, null, $assertTagValue->method); $resolved[] = new AssertTag($if, $type, $parameter, $assertTagValue->isNegated, $assertTagValue->isEquality ?? \false, \true); } return $resolved; } public function resolveSelfOutTypeTag(PhpDocNode $phpDocNode, NameScope $nameScope) : ?SelfOutTypeTag { if (!method_exists($phpDocNode, 'getSelfOutTypeTagValues')) { return null; } foreach (['@phpstan-this-out', '@phpstan-self-out', '@psalm-this-out', '@psalm-self-out'] as $tagName) { foreach ($phpDocNode->getSelfOutTypeTagValues($tagName) as $selfOutTypeTagValue) { $type = $this->typeNodeResolver->resolve($selfOutTypeTagValue->type, $nameScope); return new SelfOutTypeTag($type); } } return null; } public function resolveDeprecatedTag(PhpDocNode $phpDocNode, NameScope $nameScope) : ?DeprecatedTag { foreach ($phpDocNode->getDeprecatedTagValues() as $deprecatedTagValue) { $description = (string) $deprecatedTagValue; return new DeprecatedTag($description === '' ? null : $description); } return null; } public function resolveIsDeprecated(PhpDocNode $phpDocNode) : bool { $deprecatedTags = $phpDocNode->getTagsByName('@deprecated'); return count($deprecatedTags) > 0; } public function resolveIsNotDeprecated(PhpDocNode $phpDocNode) : bool { $notDeprecatedTags = $phpDocNode->getTagsByName('@not-deprecated'); return count($notDeprecatedTags) > 0; } public function resolveIsInternal(PhpDocNode $phpDocNode) : bool { $internalTags = $phpDocNode->getTagsByName('@internal'); return count($internalTags) > 0; } public function resolveIsFinal(PhpDocNode $phpDocNode) : bool { $finalTags = $phpDocNode->getTagsByName('@final'); return count($finalTags) > 0; } public function resolveIsPure(PhpDocNode $phpDocNode) : bool { foreach ($phpDocNode->getTags() as $phpDocTagNode) { if (in_array($phpDocTagNode->name, ['@pure', '@phan-pure', '@phan-side-effect-free', '@psalm-pure', '@phpstan-pure'], \true)) { return \true; } } return \false; } public function resolveIsImpure(PhpDocNode $phpDocNode) : bool { foreach ($phpDocNode->getTags() as $phpDocTagNode) { if (in_array($phpDocTagNode->name, ['@impure', '@phpstan-impure'], \true)) { return \true; } } return \false; } public function resolveIsReadOnly(PhpDocNode $phpDocNode) : bool { foreach (['@readonly', '@phan-read-only', '@psalm-readonly', '@phpstan-readonly', '@phpstan-readonly-allow-private-mutation', '@psalm-readonly-allow-private-mutation'] as $tagName) { $tags = $phpDocNode->getTagsByName($tagName); if (count($tags) > 0) { return \true; } } return \false; } public function resolveIsImmutable(PhpDocNode $phpDocNode) : bool { foreach (['@immutable', '@phan-immutable', '@psalm-immutable', '@phpstan-immutable'] as $tagName) { $tags = $phpDocNode->getTagsByName($tagName); if (count($tags) > 0) { return \true; } } return \false; } public function resolveHasConsistentConstructor(PhpDocNode $phpDocNode) : bool { foreach (['@consistent-constructor', '@phpstan-consistent-constructor', '@psalm-consistent-constructor'] as $tagName) { $tags = $phpDocNode->getTagsByName($tagName); if (count($tags) > 0) { return \true; } } return \false; } public function resolveAcceptsNamedArguments(PhpDocNode $phpDocNode) : bool { return count($phpDocNode->getTagsByName('@no-named-arguments')) === 0; } private function shouldSkipType(string $tagName, Type $type) : bool { if (!str_starts_with($tagName, '@psalm-')) { return \false; } return $this->unresolvableTypeHelper->containsUnresolvableType($type); } public function resolveAllowPrivateMutation(PhpDocNode $phpDocNode) : bool { foreach (['@phpstan-readonly-allow-private-mutation', '@phpstan-allow-private-mutation', '@psalm-readonly-allow-private-mutation', '@psalm-allow-private-mutation'] as $tagName) { $tags = $phpDocNode->getTagsByName($tagName); if (count($tags) > 0) { return \true; } } return \false; } } phpVersion = $phpVersion; } public function getFiles() : array { if ($this->phpVersion->getVersionId() >= 80000) { return [__DIR__ . '/../../stubs/socket_select_php8.stub']; } return [__DIR__ . '/../../stubs/socket_select.stub']; } } $arrays * @return iterable */ public static function combinations(array $arrays) : iterable { // from https://stackoverflow.com/a/70800936/565782 by Arnaud Le Blanc if ($arrays === []) { (yield []); return; } $head = array_shift($arrays); foreach ($head as $elem) { foreach (self::combinations($arrays) as $combination) { $comb = [$elem]; foreach ($combination as $c) { $comb[] = $c; } (yield $comb); } } } } getName(), ['getByType'], \true); } public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : Type { if (count($methodCall->getArgs()) === 0) { return ParametersAcceptorSelector::selectFromArgs($scope, $methodCall->getArgs(), $methodReflection->getVariants())->getReturnType(); } $argType = $scope->getType($methodCall->getArgs()[0]->value); if (!$argType instanceof ConstantStringType) { return ParametersAcceptorSelector::selectFromArgs($scope, $methodCall->getArgs(), $methodReflection->getVariants())->getReturnType(); } $type = new ObjectType($argType->getValue()); if ($methodReflection->getName() === 'getByType' && count($methodCall->getArgs()) >= 2) { $argType = $scope->getType($methodCall->getArgs()[1]->value); if ($argType->isTrue()->yes()) { $type = TypeCombinator::addNull($type); } } return $type; } } |null */ public static function getComposerConfig(string $root) : ?array { $composerJsonPath = self::getComposerJsonPath($root); if (!is_file($composerJsonPath)) { return null; } try { $composerJsonContents = FileReader::read($composerJsonPath); return Json::decode($composerJsonContents, Json::FORCE_ARRAY); } catch (CouldNotReadFileException|JsonException $e) { return null; } } private static function getComposerJsonPath(string $root) : string { $envComposer = getenv('COMPOSER'); $fileName = is_string($envComposer) ? $envComposer : 'composer.json'; $fileName = basename(trim($fileName)); return $root . '/' . $fileName; } /** * @param array $composerConfig */ public static function getVendorDirFromComposerConfig(string $root, array $composerConfig) : string { $vendorDirectory = $composerConfig['config']['vendor-dir'] ?? 'vendor'; return $root . '/' . trim($vendorDirectory, '/'); } /** * @param array $composerConfig */ public static function getBinDirFromComposerConfig(string $root, array $composerConfig) : string { $vendorDirectory = $composerConfig['config']['bin-dir'] ?? 'vendor/bin'; return $root . '/' . trim($vendorDirectory, '/'); } public static function getPhpStanVersion() : string { if (self::$phpstanVersion !== null) { return self::$phpstanVersion; } $installed = (require __DIR__ . '/../../vendor/composer/installed.php'); $rootPackage = $installed['root'] ?? null; if ($rootPackage === null) { return self::$phpstanVersion = self::UNKNOWN_VERSION; } if (preg_match('/[^v\\d.]/', $rootPackage['pretty_version']) === 0) { // Handles tagged versions, see https://github.com/Jean85/pretty-package-versions/blob/2.0.5/src/Version.php#L31 return self::$phpstanVersion = $rootPackage['pretty_version']; } return self::$phpstanVersion = $rootPackage['pretty_version'] . '@' . substr((string) $rootPackage['reference'], 0, 7); } } directory = $directory; $error = error_get_last(); parent::__construct(sprintf('Failed to create directory "%s" (%s).', $directory, is_null($error) ? 'unknown cause' : $error['message'])); } } body = $body; $this->conditions = $conditions; $this->line = $line; } public function getBody() : \PHPStan\Node\MatchExpressionArmBody { return $this->body; } /** * @return MatchExpressionArmCondition[] */ public function getConditions() : array { return $this->conditions; } public function getLine() : int { return $this->line; } } */ private $propertyUsages; /** * @var array */ private $methodCalls; /** * @var array */ private $returnStatementNodes; /** * @var list */ private $propertyAssigns; /** * @var ClassReflection */ private $classReflection; /** * @param ClassPropertyNode[] $properties * @param array $propertyUsages * @param array $methodCalls * @param array $returnStatementNodes * @param list $propertyAssigns */ public function __construct(ClassLike $class, ReadWritePropertiesExtensionProvider $readWritePropertiesExtensionProvider, array $properties, array $propertyUsages, array $methodCalls, array $returnStatementNodes, array $propertyAssigns, ClassReflection $classReflection) { $this->class = $class; $this->readWritePropertiesExtensionProvider = $readWritePropertiesExtensionProvider; $this->properties = $properties; $this->propertyUsages = $propertyUsages; $this->methodCalls = $methodCalls; $this->returnStatementNodes = $returnStatementNodes; $this->propertyAssigns = $propertyAssigns; $this->classReflection = $classReflection; parent::__construct($class->getAttributes()); } public function getClass() : ClassLike { return $this->class; } /** * @return ClassPropertyNode[] */ public function getProperties() : array { return $this->properties; } /** * @return array */ public function getPropertyUsages() : array { return $this->propertyUsages; } public function getType() : string { return 'PHPStan_Node_ClassPropertiesNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } public function getClassReflection() : ClassReflection { return $this->classReflection; } /** * @param string[] $constructors * @param ReadWritePropertiesExtension[]|null $extensions * @return array{array, array, array} */ public function getUninitializedProperties(Scope $scope, array $constructors, ?array $extensions = null) : array { if (!$this->getClass() instanceof Class_) { return [[], [], []]; } $classReflection = $this->getClassReflection(); $uninitializedProperties = []; $originalProperties = []; $initialInitializedProperties = []; $initializedProperties = []; if ($extensions === null) { $extensions = $this->readWritePropertiesExtensionProvider->getExtensions(); } $initializedViaExtension = []; foreach ($this->getProperties() as $property) { if ($property->isStatic()) { continue; } if ($property->getNativeType() === null) { continue; } if ($property->getDefault() !== null) { continue; } $originalProperties[$property->getName()] = $property; $is = TrinaryLogic::createFromBoolean($property->isPromoted() && !$property->isPromotedFromTrait()); if (!$is->yes() && $classReflection->hasNativeProperty($property->getName())) { $propertyReflection = $classReflection->getNativeProperty($property->getName()); foreach ($extensions as $extension) { if (!$extension->isInitialized($propertyReflection, $property->getName())) { continue; } $is = TrinaryLogic::createYes(); $initializedViaExtension[$property->getName()] = \true; break; } } $initialInitializedProperties[$property->getName()] = $is; foreach ($constructors as $constructor) { $initializedProperties[$constructor][$property->getName()] = $is; } if ($is->yes()) { continue; } $uninitializedProperties[$property->getName()] = $property; } if ($constructors === []) { return [$uninitializedProperties, [], []]; } $initializedInConstructor = []; if ($classReflection->hasConstructor()) { $initializedInConstructor = array_diff_key($uninitializedProperties, $this->collectUninitializedProperties([$classReflection->getConstructor()->getName()], $uninitializedProperties)); } $methodsCalledFromConstructor = $this->getMethodsCalledFromConstructor($classReflection, $initialInitializedProperties, $initializedProperties, $constructors, $initializedInConstructor); $prematureAccess = []; $additionalAssigns = []; foreach ($this->getPropertyUsages() as $usage) { $fetch = $usage->getFetch(); if (!$fetch instanceof PropertyFetch) { continue; } $usageScope = $usage->getScope(); if ($usageScope->getFunction() === null) { continue; } $function = $usageScope->getFunction(); if (!$function instanceof MethodReflection) { continue; } if ($function->getDeclaringClass()->getName() !== $classReflection->getName()) { continue; } if (!array_key_exists($function->getName(), $methodsCalledFromConstructor)) { continue; } $initializedPropertiesMap = $methodsCalledFromConstructor[$function->getName()]; if (!$fetch->name instanceof Identifier) { continue; } $propertyName = $fetch->name->toString(); $fetchedOnType = $usageScope->getType($fetch->var); if (TypeUtils::findThisType($fetchedOnType) === null) { continue; } $propertyReflection = $usageScope->getPropertyReflection($fetchedOnType, $propertyName); if ($propertyReflection === null) { continue; } if ($propertyReflection->getDeclaringClass()->getName() !== $classReflection->getName()) { continue; } if ($usage instanceof PropertyWrite) { if (array_key_exists($propertyName, $initializedPropertiesMap)) { $hasInitialization = $initializedPropertiesMap[$propertyName]->or($usageScope->hasExpressionType(new PropertyInitializationExpr($propertyName))); if (!$hasInitialization->no() && !$usage->isPromotedPropertyWrite() && !array_key_exists($propertyName, $initializedViaExtension)) { $additionalAssigns[] = [$propertyName, $fetch->getStartLine(), $originalProperties[$propertyName]]; } } } elseif (array_key_exists($propertyName, $initializedPropertiesMap)) { if (strtolower($function->getName()) !== '__construct' && array_key_exists($propertyName, $initializedInConstructor) && in_array($function->getName(), $constructors, \true)) { continue; } $hasInitialization = $initializedPropertiesMap[$propertyName]->or($usageScope->hasExpressionType(new PropertyInitializationExpr($propertyName))); if (!$hasInitialization->yes() && $usageScope->isInAnonymousFunction() && $usageScope->getParentScope() !== null) { $hasInitialization = $hasInitialization->or($usageScope->getParentScope()->hasExpressionType(new PropertyInitializationExpr($propertyName))); } if (!$hasInitialization->yes()) { $prematureAccess[] = [$propertyName, $fetch->getStartLine(), $originalProperties[$propertyName], $usageScope->getFile(), $usageScope->getFileDescription()]; } } } return [$this->collectUninitializedProperties(array_keys($methodsCalledFromConstructor), $uninitializedProperties), $prematureAccess, $additionalAssigns]; } /** * @param list $constructors * @param array $uninitializedProperties * @return array */ private function collectUninitializedProperties(array $constructors, array $uninitializedProperties) : array { foreach ($constructors as $constructor) { $lowerConstructorName = strtolower($constructor); if (!array_key_exists($lowerConstructorName, $this->returnStatementNodes)) { continue; } $returnStatementsNode = $this->returnStatementNodes[$lowerConstructorName]; $methodScope = null; foreach ($returnStatementsNode->getExecutionEnds() as $executionEnd) { $statementResult = $executionEnd->getStatementResult(); $endNode = $executionEnd->getNode(); if ($statementResult->isAlwaysTerminating()) { if ($endNode instanceof Node\Stmt\Throw_) { continue; } if ($endNode instanceof Node\Stmt\Expression) { $exprType = $statementResult->getScope()->getType($endNode->expr); if ($exprType instanceof NeverType && $exprType->isExplicit()) { continue; } } } if ($methodScope === null) { $methodScope = $statementResult->getScope(); continue; } $methodScope = $methodScope->mergeWith($statementResult->getScope()); } foreach ($returnStatementsNode->getReturnStatements() as $returnStatement) { if ($methodScope === null) { $methodScope = $returnStatement->getScope(); continue; } $methodScope = $methodScope->mergeWith($returnStatement->getScope()); } if ($methodScope === null) { continue; } foreach (array_keys($uninitializedProperties) as $propertyName) { if (!$methodScope->hasExpressionType(new PropertyInitializationExpr($propertyName))->yes()) { continue; } unset($uninitializedProperties[$propertyName]); } } return $uninitializedProperties; } /** * @param string[] $methods * @param array $initialInitializedProperties * @param array> $initializedProperties * @param array $initializedInConstructorProperties * * @return array> */ private function getMethodsCalledFromConstructor(ClassReflection $classReflection, array $initialInitializedProperties, array $initializedProperties, array $methods, array $initializedInConstructorProperties) : array { $originalMap = $initializedProperties; $originalMethods = $methods; foreach ($this->methodCalls as $methodCall) { $methodCallNode = $methodCall->getNode(); if ($methodCallNode instanceof Array_) { continue; } if (!$methodCallNode->name instanceof Identifier) { continue; } $callScope = $methodCall->getScope(); if ($methodCallNode instanceof Node\Expr\MethodCall) { $calledOnType = $callScope->getType($methodCallNode->var); } else { if (!$methodCallNode->class instanceof Name) { continue; } $calledOnType = $callScope->resolveTypeByName($methodCallNode->class); } if (TypeUtils::findThisType($calledOnType) === null) { continue; } $inMethod = $callScope->getFunction(); if (!$inMethod instanceof MethodReflection) { continue; } if (!in_array($inMethod->getName(), $methods, \true)) { continue; } if ($inMethod->getName() !== '__construct') { foreach ($initializedInConstructorProperties as $propertyName => $propertyNode) { $initializedProperties[$inMethod->getName()][$propertyName] = TrinaryLogic::createYes(); } } $methodName = $methodCallNode->name->toString(); if (array_key_exists($methodName, $initializedProperties)) { foreach ($this->getInitializedProperties($callScope, $initializedProperties[$inMethod->getName()] ?? $initialInitializedProperties) as $propertyName => $isInitialized) { $initializedProperties[$methodName][$propertyName] = $initializedProperties[$methodName][$propertyName]->and($isInitialized); } continue; } $methodReflection = $callScope->getMethodReflection($calledOnType, $methodName); if ($methodReflection === null) { continue; } if ($methodReflection->getDeclaringClass()->getName() !== $classReflection->getName()) { continue; } $initializedProperties[$methodName] = $this->getInitializedProperties($callScope, $initializedProperties[$inMethod->getName()] ?? $initialInitializedProperties); $methods[] = $methodName; } if ($originalMap === $initializedProperties && $originalMethods === $methods) { return $initializedProperties; } return $this->getMethodsCalledFromConstructor($classReflection, $initialInitializedProperties, $initializedProperties, $methods, $initializedInConstructorProperties); } /** * @param array $initialInitializedProperties * @return array */ private function getInitializedProperties(Scope $scope, array $initialInitializedProperties) : array { foreach ($initialInitializedProperties as $propertyName => $isInitialized) { $initialInitializedProperties[$propertyName] = $isInitialized->or($scope->hasExpressionType(new PropertyInitializationExpr($propertyName))); } return $initialInitializedProperties; } /** * @return list */ public function getPropertyAssigns() : array { return $this->propertyAssigns; } } class = $class; $this->originalNode = $originalNode; parent::__construct($this->originalNode->getAttributes()); } /** * @return Expr|Name */ public function getClass() { return $this->class; } public function getOriginalNode() : Expr\New_ { return $this->originalNode; } public function getType() : string { return 'PHPStan_Node_InstantiationCallableNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } functionReflection = $functionReflection; $this->originalNode = $originalNode; parent::__construct($originalNode->getAttributes()); } public function getFunctionReflection() : PhpFunctionFromParserNodeReflection { return $this->functionReflection; } public function getOriginalNode() : Node\Stmt\Function_ { return $this->originalNode; } public function getType() : string { return 'PHPStan_Stmt_InFunctionNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } originalNode = $originalNode; $this->caughtType = $caughtType; $this->originalCaughtType = $originalCaughtType; parent::__construct($originalNode->getAttributes()); } public function getOriginalNode() : Catch_ { return $this->originalNode; } public function getCaughtType() : Type { return $this->caughtType; } public function getOriginalCaughtType() : Type { return $this->originalCaughtType; } public function getType() : string { return 'PHPStan_Node_CatchWithUnthrownExceptionNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } scope = $scope; $this->body = $body; } public function getScope() : Scope { return $this->scope; } public function getBody() : Expr { return $this->body; } } collectedData = $collectedData; $this->onlyFiles = $onlyFiles; parent::__construct([]); } /** * @template TCollector of Collector * @template TValue * @param class-string $collectorType * @return array> */ public function get(string $collectorType) : array { $result = []; foreach ($this->collectedData as $collectedData) { if ($collectedData->getCollectorType() !== $collectorType) { continue; } $filePath = $collectedData->getFilePath(); if (!array_key_exists($filePath, $result)) { $result[$filePath] = []; } $result[$filePath][] = $collectedData->getData(); } return $result; } /** * Indicates that only files were passed to the analyser, not directory paths. * * True being returned strongly suggests that it's a partial analysis, not full project analysis. */ public function isOnlyFilesAnalysis() : bool { return $this->onlyFiles; } public function getType() : string { return 'PHPStan_Node_CollectedDataNode'; } /** * @return array{} */ public function getSubNodeNames() : array { return []; } } node = $node; $this->scope = $scope; } public function getNode() : ClassConstFetch { return $this->node; } public function getScope() : Scope { return $this->scope; } } isDeclaredInTrait = $isDeclaredInTrait; parent::__construct($node->name, ['flags' => $node->flags, 'byRef' => $node->byRef, 'params' => $node->params, 'returnType' => $node->returnType, 'stmts' => $node->stmts, 'attrGroups' => $node->attrGroups], $node->attributes); } public function getNode() : PhpParserClassMethod { return $this; } public function isDeclaredInTrait() : bool { return $this->isDeclaredInTrait; } } name = $name; $this->flags = $flags; $this->type = $type; $this->default = $default; $this->phpDoc = $phpDoc; $this->phpDocType = $phpDocType; $this->isPromoted = $isPromoted; $this->isPromotedFromTrait = $isPromotedFromTrait; $this->isReadonlyByPhpDoc = $isReadonlyByPhpDoc; $this->isDeclaredInTrait = $isDeclaredInTrait; $this->isReadonlyClass = $isReadonlyClass; $this->isAllowedPrivateMutation = $isAllowedPrivateMutation; $this->classReflection = $classReflection; parent::__construct($originalNode->getAttributes()); } public function getName() : string { return $this->name; } public function getFlags() : int { return $this->flags; } public function getDefault() : ?Expr { return $this->default; } public function isPromoted() : bool { return $this->isPromoted; } public function isPromotedFromTrait() : bool { return $this->isPromotedFromTrait; } public function getPhpDoc() : ?string { return $this->phpDoc; } public function getPhpDocType() : ?Type { return $this->phpDocType; } public function isPublic() : bool { return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; } public function isProtected() : bool { return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); } public function isPrivate() : bool { return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); } public function isStatic() : bool { return (bool) ($this->flags & Class_::MODIFIER_STATIC); } public function isReadOnly() : bool { return (bool) ($this->flags & Class_::MODIFIER_READONLY) || $this->isReadonlyClass; } public function isReadOnlyByPhpDoc() : bool { return $this->isReadonlyByPhpDoc; } public function isDeclaredInTrait() : bool { return $this->isDeclaredInTrait; } public function isAllowedPrivateMutation() : bool { return $this->isAllowedPrivateMutation; } /** * @return Identifier|Name|Node\ComplexType|null */ public function getNativeType() { return $this->type; } public function getClassReflection() : ClassReflection { return $this->classReflection; } public function getType() : string { return 'PHPStan_Node_ClassPropertyNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } node = $node; $this->statementResult = $statementResult; $this->hasNativeReturnTypehint = $hasNativeReturnTypehint; parent::__construct($node->getAttributes()); } public function getNode() : Node\Stmt { return $this->node; } public function getStatementResult() : StatementResult { return $this->statementResult; } public function hasNativeReturnTypehint() : bool { return $this->hasNativeReturnTypehint; } public function getType() : string { return 'PHPStan_Node_ExecutionEndNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } assign = $assign; $this->scope = $scope; } public function getAssign() : PropertyAssignNode { return $this->assign; } public function getScope() : Scope { return $this->scope; } } fetch = $fetch; $this->scope = $scope; $this->promotedPropertyWrite = $promotedPropertyWrite; } /** * @return PropertyFetch|StaticPropertyFetch */ public function getFetch() { return $this->fetch; } public function getScope() : Scope { return $this->scope; } public function isPromotedPropertyWrite() : bool { return $this->promotedPropertyWrite; } } fetch = $fetch; $this->scope = $scope; } /** * @return PropertyFetch|StaticPropertyFetch */ public function getFetch() { return $this->fetch; } public function getScope() : Scope { return $this->scope; } } class = $class; $this->name = $name; $this->originalNode = $originalNode; parent::__construct($originalNode->getAttributes()); } /** * @return Expr|Name */ public function getClass() { return $this->class; } /** * @return Identifier|Expr */ public function getName() { return $this->name; } public function getOriginalNode() : Expr\StaticCall { return $this->originalNode; } public function getType() : string { return 'PHPStan_Node_StaticMethodCallableNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } getSubNodeNames() as $subNodeName) { $subNodes[$subNodeName] = $node->{$subNodeName}; } return new \PHPStan\Node\AnonymousClassNode($node->name, $subNodes, $node->getAttributes()); } public function isAnonymous() : bool { return \true; } } expr = $expr; parent::__construct($expr->getAttributes()); } public function getExpr() : Expr { return $this->expr; } public function getType() : string { return 'PHPStan_Node_InvalidateExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } closureType = $closureType; parent::__construct($originalNode->getAttributes()); $this->originalNode = $originalNode; } public function getClosureType() : ClosureType { return $this->closureType; } public function getOriginalNode() : Node\Expr\ArrowFunction { return $this->originalNode; } public function getType() : string { return 'PHPStan_Node_InArrowFunctionNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } scope = $scope; $this->arrayItem = $arrayItem; } public function getScope() : Scope { return $this->scope; } public function getArrayItem() : ?ArrayItem { return $this->arrayItem; } } */ private $returnStatements; /** * @var list */ private $yieldStatements; /** * @var StatementResult */ private $statementResult; /** * @var list */ private $executionEnds; /** * @var ImpurePoint[] */ private $impurePoints; /** * @var PhpFunctionFromParserNodeReflection */ private $functionReflection; /** * @param list $returnStatements * @param list $yieldStatements * @param list $executionEnds * @param ImpurePoint[] $impurePoints */ public function __construct(Function_ $function, array $returnStatements, array $yieldStatements, StatementResult $statementResult, array $executionEnds, array $impurePoints, PhpFunctionFromParserNodeReflection $functionReflection) { $this->function = $function; $this->returnStatements = $returnStatements; $this->yieldStatements = $yieldStatements; $this->statementResult = $statementResult; $this->executionEnds = $executionEnds; $this->impurePoints = $impurePoints; $this->functionReflection = $functionReflection; parent::__construct($function->getAttributes()); } public function getReturnStatements() : array { return $this->returnStatements; } public function getStatementResult() : StatementResult { return $this->statementResult; } public function getExecutionEnds() : array { return $this->executionEnds; } public function getImpurePoints() : array { return $this->impurePoints; } public function returnsByRef() : bool { return $this->function->byRef; } public function hasNativeReturnTypehint() : bool { return $this->function->returnType !== null; } public function getYieldStatements() : array { return $this->yieldStatements; } public function isGenerator() : bool { return count($this->yieldStatements) > 0; } public function getType() : string { return 'PHPStan_Node_FunctionReturnStatementsNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } public function getFunctionReflection() : PhpFunctionFromParserNodeReflection { return $this->functionReflection; } /** * @return Stmt[] */ public function getStatements() : array { return $this->function->getStmts(); } } classReflection = $classReflection; $this->methodReflection = $methodReflection; $this->originalNode = $originalNode; parent::__construct($originalNode->getAttributes()); } public function getClassReflection() : ClassReflection { return $this->classReflection; } public function getMethodReflection() : PhpMethodFromParserNodeReflection { return $this->methodReflection; } public function getOriginalNode() : Node\Stmt\ClassMethod { return $this->originalNode; } public function getType() : string { return 'PHPStan_Stmt_InClassMethodNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } originalExpr = $originalExpr; $this->hasAssign = $hasAssign; parent::__construct($this->originalExpr->getAttributes()); } public function getOriginalExpr() : Expr { return $this->originalExpr; } public function hasAssign() : bool { return $this->hasAssign; } public function getType() : string { return 'PHPStan_Node_NoopExpressionNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } condition = $condition; $this->scope = $scope; $this->line = $line; } public function getCondition() : Expr { return $this->condition; } public function getScope() : Scope { return $this->scope; } public function getLine() : int { return $this->line; } } propertyFetch = $propertyFetch; $this->assignedExpr = $assignedExpr; $this->assignOp = $assignOp; parent::__construct($propertyFetch->getAttributes()); } /** * @return Expr\PropertyFetch|Expr\StaticPropertyFetch */ public function getPropertyFetch() { return $this->propertyFetch; } public function getAssignedExpr() : Expr { return $this->assignedExpr; } public function isAssignOp() : bool { return $this->assignOp; } public function getType() : string { return 'PHPStan_Node_PropertyAssignNodeNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } */ private $returnStatements; /** * @var list */ private $yieldStatements; /** * @var StatementResult */ private $statementResult; /** * @var list */ private $executionEnds; /** * @var ImpurePoint[] */ private $impurePoints; /** * @var ClassReflection */ private $classReflection; /** * @var PhpMethodFromParserNodeReflection */ private $methodReflection; /** * @var ClassMethod */ private $classMethod; /** * @param list $returnStatements * @param list $yieldStatements * @param list $executionEnds * @param ImpurePoint[] $impurePoints */ public function __construct(ClassMethod $method, array $returnStatements, array $yieldStatements, StatementResult $statementResult, array $executionEnds, array $impurePoints, ClassReflection $classReflection, PhpMethodFromParserNodeReflection $methodReflection) { $this->returnStatements = $returnStatements; $this->yieldStatements = $yieldStatements; $this->statementResult = $statementResult; $this->executionEnds = $executionEnds; $this->impurePoints = $impurePoints; $this->classReflection = $classReflection; $this->methodReflection = $methodReflection; parent::__construct($method->getAttributes()); $this->classMethod = $method; } public function getReturnStatements() : array { return $this->returnStatements; } public function getStatementResult() : StatementResult { return $this->statementResult; } public function getExecutionEnds() : array { return $this->executionEnds; } public function getImpurePoints() : array { return $this->impurePoints; } public function returnsByRef() : bool { return $this->classMethod->byRef; } public function hasNativeReturnTypehint() : bool { return $this->classMethod->returnType !== null; } public function getMethodName() : string { return $this->classMethod->name->toString(); } public function getYieldStatements() : array { return $this->yieldStatements; } public function getClassReflection() : ClassReflection { return $this->classReflection; } public function getMethodReflection() : PhpMethodFromParserNodeReflection { return $this->methodReflection; } /** * @return Stmt[] */ public function getStatements() : array { $stmts = $this->classMethod->getStmts(); if ($stmts === null) { return []; } return $stmts; } public function isGenerator() : bool { return count($this->yieldStatements) > 0; } public function getType() : string { return 'PHPStan_Node_MethodReturnStatementsNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } originalNode = $originalNode; parent::__construct($originalNode->getAttributes()); } public function getOriginalNode() : Foreach_ { return $this->originalNode; } public function getType() : string { return 'PHPStan_Node_InForeachNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } expr = $expr; parent::__construct([]); } public function getExpr() : Expr { return $this->expr; } public function getType() : string { return 'PHPStan_Node_IssetExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } originalNode = $originalNode; $this->classReflection = $classReflection; parent::__construct($originalNode->getAttributes()); } public function getOriginalNode() : ClassLike { return $this->originalNode; } public function getClassReflection() : ClassReflection { return $this->classReflection; } public function getType() : string { return 'PHPStan_Stmt_InClassNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } name = $name; $this->originalNode = $originalNode; parent::__construct($this->originalNode->getAttributes()); } /** * @return Expr|Name */ public function getName() { return $this->name; } public function getOriginalNode() : Expr\FuncCall { return $this->originalNode; } public function getType() : string { return 'PHPStan_Node_FunctionCallableNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } cond = $cond; $this->exitPoints = $exitPoints; parent::__construct($cond->getAttributes()); } public function getCond() : Expr { return $this->cond; } /** * @return StatementExitPoint[] */ public function getExitPoints() : array { return $this->exitPoints; } public function getType() : string { return 'PHPStan_Node_ClosureReturnStatementsNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } node = $node; $this->scope = $scope; } /** * @return Node\Expr\MethodCall|StaticCall|Array_ */ public function getNode() { return $this->node; } public function getScope() : Scope { return $this->scope; } } */ public function getReturnStatements() : array; public function getStatementResult() : StatementResult; /** * @return list */ public function getExecutionEnds() : array; /** * @return ImpurePoint[] */ public function getImpurePoints() : array; public function returnsByRef() : bool; public function hasNativeReturnTypehint() : bool; /** * @return list */ public function getYieldStatements() : array; public function isGenerator() : bool; } */ private $methodCalls; /** * @var ClassReflection */ private $classReflection; /** * @param ClassMethod[] $methods * @param array $methodCalls */ public function __construct(ClassLike $class, array $methods, array $methodCalls, ClassReflection $classReflection) { $this->class = $class; $this->methods = $methods; $this->methodCalls = $methodCalls; $this->classReflection = $classReflection; parent::__construct($class->getAttributes()); } public function getClass() : ClassLike { return $this->class; } /** * @return ClassMethod[] */ public function getMethods() : array { return $this->methods; } /** * @return array */ public function getMethodCalls() : array { return $this->methodCalls; } public function getType() : string { return 'PHPStan_Node_ClassMethodsNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } public function getClassReflection() : ClassReflection { return $this->classReflection; } } originalNode = $originalNode; $this->exitPoints = $exitPoints; parent::__construct($originalNode->getAttributes()); } public function getOriginalNode() : While_ { return $this->originalNode; } /** * @return StatementExitPoint[] */ public function getExitPoints() : array { return $this->exitPoints; } public function getType() : string { return 'PHPStan_Node_BreaklessWhileLoop'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } var = $var; $this->name = $name; $this->originalNode = $originalNode; parent::__construct($originalNode->getAttributes()); } public function getVar() : Expr { return $this->var; } /** * @return Expr|Identifier */ public function getName() { return $this->name; } public function getOriginalNode() : Expr\MethodCall { return $this->originalNode; } public function getType() : string { return 'PHPStan_Node_MethodCallableNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } closureType = $closureType; parent::__construct($originalNode->getAttributes()); $this->originalNode = $originalNode; } public function getClosureType() : ClosureType { return $this->closureType; } public function getOriginalNode() : Closure { return $this->originalNode; } public function getType() : string { return 'PHPStan_Node_InClosureNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } condition = $condition; $this->arms = $arms; $this->endScope = $endScope; parent::__construct($originalNode->getAttributes()); } public function getCondition() : Expr { return $this->condition; } /** * @return MatchExpressionArm[] */ public function getArms() : array { return $this->arms; } public function getEndScope() : Scope { return $this->endScope; } public function getType() : string { return 'PHPStan_Node_MatchExpression'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } nodes = $nodes; $firstNode = $nodes[0] ?? null; parent::__construct($firstNode !== null ? $firstNode->getAttributes() : []); } /** * @return Node[] */ public function getNodes() : array { return $this->nodes; } public function getType() : string { return 'PHPStan_Node_FileNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } originalNode = $originalNode; $this->rightScope = $rightScope; parent::__construct($originalNode->getAttributes()); } /** * @return BooleanAnd|LogicalAnd */ public function getOriginalNode() { return $this->originalNode; } public function getRightScope() : Scope { return $this->rightScope; } public function getType() : string { return 'PHPStan_Node_BooleanAndNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } */ private $propertyUsages = []; /** @var Node\Stmt\ClassConst[] */ private $constants = []; /** @var ClassConstantFetch[] */ private $constantFetches = []; /** @var array */ private $returnStatementNodes = []; /** @var list */ private $propertyAssigns = []; /** * @param callable(Node $node, Scope $scope): void $nodeCallback */ public function __construct(ClassReflection $classReflection, callable $nodeCallback) { $this->classReflection = $classReflection; $this->nodeCallback = $nodeCallback; } /** * @return ClassPropertyNode[] */ public function getProperties() : array { return $this->properties; } /** * @return ClassMethod[] */ public function getMethods() : array { return $this->methods; } /** * @return Method\MethodCall[] */ public function getMethodCalls() : array { return $this->methodCalls; } /** * @return array */ public function getPropertyUsages() : array { return $this->propertyUsages; } /** * @return Node\Stmt\ClassConst[] */ public function getConstants() : array { return $this->constants; } /** * @return ClassConstantFetch[] */ public function getConstantFetches() : array { return $this->constantFetches; } /** * @return array */ public function getReturnStatementsNodes() : array { return $this->returnStatementNodes; } /** * @return list */ public function getPropertyAssigns() : array { return $this->propertyAssigns; } public function __invoke(Node $node, Scope $scope) : void { $nodeCallback = $this->nodeCallback; $nodeCallback($node, $scope); $this->gatherNodes($node, $scope); } private function gatherNodes(Node $node, Scope $scope) : void { if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } if ($scope->getClassReflection()->getName() !== $this->classReflection->getName()) { return; } if ($node instanceof \PHPStan\Node\ClassPropertyNode) { $this->properties[] = $node; if ($node->isPromoted()) { $this->propertyUsages[] = new PropertyWrite(new PropertyFetch(new Expr\Variable('this'), new Identifier($node->getName())), $scope, \true); } return; } if ($node instanceof Node\Stmt\ClassMethod) { $this->methods[] = new \PHPStan\Node\ClassMethod($node, $scope->isInTrait()); return; } if ($node instanceof Node\Stmt\ClassConst) { $this->constants[] = $node; return; } if ($node instanceof MethodCall || $node instanceof StaticCall) { $this->methodCalls[] = new \PHPStan\Node\Method\MethodCall($node, $scope); if ($node instanceof StaticCall && $node->name instanceof Identifier && $node->name->toLowerString() === '__construct') { $this->tryToApplyPropertyWritesFromAncestorConstructor($node, $scope); } return; } if ($node instanceof \PHPStan\Node\MethodCallableNode || $node instanceof \PHPStan\Node\StaticMethodCallableNode) { $this->methodCalls[] = new \PHPStan\Node\Method\MethodCall($node->getOriginalNode(), $scope); return; } if ($node instanceof \PHPStan\Node\MethodReturnStatementsNode) { $this->returnStatementNodes[strtolower($node->getMethodName())] = $node; return; } if ($node instanceof Expr\FuncCall && $node->name instanceof Node\Name && in_array($node->name->toLowerString(), self::PROPERTY_ENUMERATING_FUNCTIONS, \true)) { $this->tryToApplyPropertyReads($node, $scope); return; } if ($node instanceof Array_ && count($node->items) === 2) { $this->methodCalls[] = new \PHPStan\Node\Method\MethodCall($node, $scope); return; } if ($node instanceof Expr\ClassConstFetch) { $this->constantFetches[] = new ClassConstantFetch($node, $scope); return; } if ($node instanceof \PHPStan\Node\PropertyAssignNode) { $this->propertyUsages[] = new PropertyWrite($node->getPropertyFetch(), $scope, \false); $this->propertyAssigns[] = new PropertyAssign($node, $scope); return; } if (!$node instanceof Expr) { return; } if ($node instanceof Expr\AssignOp\Coalesce) { $this->gatherNodes($node->var, $scope); return; } if ($node instanceof Expr\AssignRef) { if (!$node->expr instanceof PropertyFetch && !$node->expr instanceof StaticPropertyFetch) { $this->gatherNodes($node->expr, $scope); return; } $this->propertyUsages[] = new PropertyRead($node->expr, $scope); $this->propertyUsages[] = new PropertyWrite($node->expr, $scope, \false); return; } if ($node instanceof Node\Scalar\EncapsedStringPart) { return; } if ($node instanceof \PHPStan\Node\FunctionCallableNode) { $node = $node->getOriginalNode(); } elseif ($node instanceof \PHPStan\Node\InstantiationCallableNode) { $node = $node->getOriginalNode(); } $inAssign = $scope->isInExpressionAssign($node); if ($inAssign) { return; } while ($node instanceof ArrayDimFetch) { $node = $node->var; } if (!$node instanceof PropertyFetch && !$node instanceof StaticPropertyFetch) { return; } $this->propertyUsages[] = new PropertyRead($node, $scope); } private function tryToApplyPropertyReads(Expr\FuncCall $node, Scope $scope) : void { $args = $node->getArgs(); if (count($args) === 0) { return; } $firstArgValue = $args[0]->value; if (TypeUtils::findThisType($scope->getType($firstArgValue)) === null) { return; } $classProperties = $this->classReflection->getNativeReflection()->getProperties(); foreach ($classProperties as $property) { if ($property->isStatic()) { continue; } $this->propertyUsages[] = new PropertyRead(new PropertyFetch(new Expr\Variable('this'), new Identifier($property->getName())), $scope); } } private function tryToApplyPropertyWritesFromAncestorConstructor(StaticCall $ancestorConstructorCall, Scope $scope) : void { if (!$ancestorConstructorCall->class instanceof Node\Name) { return; } $calledOnType = $scope->resolveTypeByName($ancestorConstructorCall->class); if ($calledOnType->getClassReflection() === null || TypeUtils::findThisType($calledOnType) === null) { return; } $classReflection = $calledOnType->getClassReflection()->getNativeReflection(); foreach ($classReflection->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED) as $property) { if (!$property->isPromoted() || $property->getDeclaringClass()->getName() !== $classReflection->getName()) { continue; } $this->propertyUsages[] = new PropertyWrite(new PropertyFetch(new Expr\Variable('this'), new Identifier($property->getName()), $ancestorConstructorCall->getAttributes()), $scope, \false); } } } */ private $returnStatements; /** * @var list */ private $yieldStatements; /** * @var StatementResult */ private $statementResult; /** * @var list */ private $executionEnds; /** * @var ImpurePoint[] */ private $impurePoints; /** * @var Node\Expr\Closure */ private $closureExpr; /** * @param list $returnStatements * @param list $yieldStatements * @param list $executionEnds * @param ImpurePoint[] $impurePoints */ public function __construct(Closure $closureExpr, array $returnStatements, array $yieldStatements, StatementResult $statementResult, array $executionEnds, array $impurePoints) { $this->returnStatements = $returnStatements; $this->yieldStatements = $yieldStatements; $this->statementResult = $statementResult; $this->executionEnds = $executionEnds; $this->impurePoints = $impurePoints; parent::__construct($closureExpr->getAttributes()); $this->closureExpr = $closureExpr; } public function getClosureExpr() : Closure { return $this->closureExpr; } public function hasNativeReturnTypehint() : bool { return $this->closureExpr->returnType !== null; } public function getReturnStatements() : array { return $this->returnStatements; } public function getExecutionEnds() : array { return $this->executionEnds; } public function getImpurePoints() : array { return $this->impurePoints; } public function getYieldStatements() : array { return $this->yieldStatements; } public function isGenerator() : bool { return count($this->yieldStatements) > 0; } public function getStatementResult() : StatementResult { return $this->statementResult; } public function returnsByRef() : bool { return $this->closureExpr->byRef; } public function getType() : string { return 'PHPStan_Node_ClosureReturnStatementsNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } varTag = $varTag; $this->expr = $expr; parent::__construct($expr->getAttributes()); } public function getVarTag() : VarTag { return $this->varTag; } public function getExpr() : Expr { return $this->expr; } public function getType() : string { return 'PHPStan_Node_VarTagChangedExpressionType'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } originalStatement = $originalStatement; parent::__construct($originalStatement->getAttributes()); } public function getOriginalStatement() : Stmt { return $this->originalStatement; } public function getType() : string { return 'PHPStan_Stmt_UnreachableStatementNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } originalNode = $originalNode; $this->rightScope = $rightScope; parent::__construct($originalNode->getAttributes()); } /** * @return BooleanOr|LogicalOr */ public function getOriginalNode() { return $this->originalNode; } public function getRightScope() : Scope { return $this->rightScope; } public function getType() : string { return 'PHPStan_Node_BooleanOrNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } itemNodes = $itemNodes; parent::__construct($originalNode->getAttributes()); } /** * @return LiteralArrayItem[] */ public function getItemNodes() : array { return $this->itemNodes; } public function getType() : string { return 'PHPStan_Node_LiteralArray'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } var = $var; $this->dim = $dim; parent::__construct([]); } public function getVar() : Expr { return $this->var; } public function getDim() : Expr { return $this->dim; } public function getType() : string { return 'PHPStan_Node_UnsetOffsetExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } var = $var; $this->dim = $dim; $this->value = $value; parent::__construct([]); } public function getVar() : Expr { return $this->var; } public function getDim() : Expr { return $this->dim; } public function getValue() : Expr { return $this->value; } public function getType() : string { return 'PHPStan_Node_SetExistingOffsetValueTypeExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } var = $var; $this->dim = $dim; parent::__construct([]); } public function getVar() : Expr { return $this->var; } public function getDim() : Expr { return $this->dim; } public function getType() : string { return 'PHPStan_Node_ExistingArrayDimFetch'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } expr = $expr; $this->type = $type; $this->nativeType = $nativeType; parent::__construct([]); } public function getExpr() : Expr { return $this->expr; } public function getExprType() : Type { return $this->type; } public function getNativeExprType() : Type { return $this->nativeType; } public function getType() : string { return 'PHPStan_Node_AlwaysRememberedExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return ['expr']; } } exprType = $exprType; parent::__construct(); } public function getExprType() : Type { return $this->exprType; } public function getType() : string { return 'PHPStan_Node_TypeExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } var = $var; $this->dim = $dim; parent::__construct([]); } public function getVar() : Expr { return $this->var; } public function getDim() : Expr { return $this->dim; } public function getType() : string { return 'PHPStan_Node_GetOffsetValueTypeExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } propertyName = $propertyName; parent::__construct([]); } public function getPropertyName() : string { return $this->propertyName; } public function getType() : string { return 'PHPStan_Node_PropertyInitializationExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } variableName = $variableName; parent::__construct([]); } public function getVariableName() : string { return $this->variableName; } public function getType() : string { return 'PHPStan_Node_ParameterVariableOriginalValueExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } var = $var; $this->dim = $dim; $this->value = $value; parent::__construct([]); } public function getVar() : Expr { return $this->var; } public function getDim() : ?Expr { return $this->dim; } public function getValue() : Expr { return $this->value; } public function getType() : string { return 'PHPStan_Node_SetOffsetValueTypeExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } expr = $expr; parent::__construct([]); } public function getExpr() : Expr { return $this->expr; } public function getType() : string { return 'PHPStan_Node_GetIterableValueTypeExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } expr = $expr; parent::__construct([]); } public function getExpr() : Expr { return $this->expr; } public function getType() : string { return 'PHPStan_Node_GetIterableKeyTypeExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } propertyFetch = $propertyFetch; parent::__construct([]); } /** * @return Expr\PropertyFetch|Expr\StaticPropertyFetch */ public function getPropertyFetch() { return $this->propertyFetch; } public function getType() : string { return 'PHPStan_Node_OriginalPropertyTypeExpr'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } finallyExitPoints = $finallyExitPoints; $this->tryCatchExitPoints = $tryCatchExitPoints; parent::__construct([]); } /** * @return StatementExitPoint[] */ public function getFinallyExitPoints() : array { return $this->finallyExitPoints; } /** * @return StatementExitPoint[] */ public function getTryCatchExitPoints() : array { return $this->tryCatchExitPoints; } public function getType() : string { return 'PHPStan_Node_FinallyExitPointsNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } scope = $scope; $this->returnNode = $returnNode; } public function getScope() : Scope { return $this->scope; } public function getReturnNode() : Return_ { return $this->returnNode; } } class = $class; $this->constants = $constants; $this->fetches = $fetches; $this->classReflection = $classReflection; parent::__construct($class->getAttributes()); } public function getClass() : ClassLike { return $this->class; } /** * @return ClassConst[] */ public function getConstants() : array { return $this->constants; } /** * @return ClassConstantFetch[] */ public function getFetches() : array { return $this->fetches; } public function getType() : string { return 'PHPStan_Node_ClassConstantsNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } public function getClassReflection() : ClassReflection { return $this->classReflection; } } originalNode = $originalNode; $this->traitReflection = $traitReflection; $this->implementingClassReflection = $implementingClassReflection; parent::__construct($originalNode->getAttributes()); } public function getOriginalNode() : Node\Stmt\Trait_ { return $this->originalNode; } public function getTraitReflection() : ClassReflection { return $this->traitReflection; } public function getImplementingClassReflection() : ClassReflection { return $this->implementingClassReflection; } public function getType() : string { return 'PHPStan_Stmt_InTraitNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } variable = $variable; $this->assignedExpr = $assignedExpr; $this->assignOp = $assignOp; parent::__construct($variable->getAttributes()); } public function getVariable() : Expr\Variable { return $this->variable; } public function getAssignedExpr() : Expr { return $this->assignedExpr; } public function isAssignOp() : bool { return $this->assignOp; } public function getType() : string { return 'PHPStan_Node_VariableAssignNodeNode'; } /** * @return string[] */ public function getSubNodeNames() : array { return []; } } \true]); } protected function pPHPStan_Node_TypeExpr(TypeExpr $expr) : string { return sprintf('__phpstanType(%s)', $expr->getExprType()->describe(VerbosityLevel::precise())); } protected function pPHPStan_Node_GetOffsetValueTypeExpr(GetOffsetValueTypeExpr $expr) : string { return sprintf('__phpstanGetOffsetValueType(%s, %s)', $this->p($expr->getVar()), $this->p($expr->getDim())); } protected function pPHPStan_Node_UnsetOffsetExpr(UnsetOffsetExpr $expr) : string { return sprintf('__phpstanUnsetOffset(%s, %s)', $this->p($expr->getVar()), $this->p($expr->getDim())); } protected function pPHPStan_Node_GetIterableValueTypeExpr(GetIterableValueTypeExpr $expr) : string { return sprintf('__phpstanGetIterableValueType(%s)', $this->p($expr->getExpr())); } protected function pPHPStan_Node_GetIterableKeyTypeExpr(GetIterableKeyTypeExpr $expr) : string { return sprintf('__phpstanGetIterableKeyType(%s)', $this->p($expr->getExpr())); } protected function pPHPStan_Node_ExistingArrayDimFetch(ExistingArrayDimFetch $expr) : string { return sprintf('__phpstanExistingArrayDimFetch(%s, %s)', $this->p($expr->getVar()), $this->p($expr->getDim())); } protected function pPHPStan_Node_OriginalPropertyTypeExpr(OriginalPropertyTypeExpr $expr) : string { return sprintf('__phpstanOriginalPropertyType(%s)', $this->p($expr->getPropertyFetch())); } protected function pPHPStan_Node_SetOffsetValueTypeExpr(SetOffsetValueTypeExpr $expr) : string { return sprintf('__phpstanSetOffsetValueType(%s, %s, %s)', $this->p($expr->getVar()), $expr->getDim() !== null ? $this->p($expr->getDim()) : 'null', $this->p($expr->getValue())); } protected function pPHPStan_Node_SetExistingOffsetValueTypeExpr(SetExistingOffsetValueTypeExpr $expr) : string { return sprintf('__phpstanSetExistingOffsetValueType(%s, %s, %s)', $this->p($expr->getVar()), $this->p($expr->getDim()), $this->p($expr->getValue())); } protected function pPHPStan_Node_AlwaysRememberedExpr(AlwaysRememberedExpr $expr) : string { return sprintf('__phpstanRembered(%s)', $this->p($expr->getExpr())); } protected function pPHPStan_Node_PropertyInitializationExpr(PropertyInitializationExpr $expr) : string { return sprintf('__phpstanPropertyInitialization(%s)', $expr->getPropertyName()); } protected function pPHPStan_Node_ParameterVariableOriginalValueExpr(ParameterVariableOriginalValueExpr $expr) : string { return sprintf('__phpstanParameterVariableOriginalValue(%s)', $expr->getVariableName()); } protected function pPHPStan_Node_IssetExpr(IssetExpr $expr) : string { return sprintf('__phpstanIssetExpr(%s)', $this->p($expr->getExpr())); } } printer = $printer; } public function printExpr(Expr $expr) : string { /** @var string|null $exprString */ $exprString = $expr->getAttribute('phpstan_cache_printer'); if ($exprString === null) { $exprString = $this->printer->prettyPrintExpr($expr); $expr->setAttribute('phpstan_cache_printer', $exprString); } return $exprString; } } type); } if ($type instanceof Node\UnionType) { return implode('|', array_map(static function ($innerType) : string { $printedType = self::printType($innerType); if ($printedType === null) { throw new ShouldNotHappenException(); } return $printedType; }, $type->types)); } if ($type instanceof Node\IntersectionType) { return implode('&', array_map(static function ($innerType) : string { $printedType = self::printType($innerType); if ($printedType === null) { throw new ShouldNotHappenException(); } return $printedType; }, $type->types)); } if ($type instanceof Node\Identifier || $type instanceof Node\Name) { return $type->toString(); } throw new ShouldNotHappenException(); } } count !== null) { return $this->count; } try { $this->count = (new FidryCpuCoreCounter())->getCount(); } catch (NumberOfCpuCoreNotFound $e) { $this->count = 1; } return $this->count; } } getOption('memory-limit') === null) { $processCommandArray[] = '-d'; $processCommandArray[] = 'memory_limit=' . ini_get('memory_limit'); } foreach ([$mainScript, $commandName] as $arg) { $processCommandArray[] = escapeshellarg($arg); } if ($projectConfigFile !== null) { $processCommandArray[] = '--configuration'; $processCommandArray[] = escapeshellarg($projectConfigFile); } $options = [AnalyseCommand::OPTION_LEVEL, 'autoload-file', 'memory-limit', 'xdebug', 'verbose']; foreach ($options as $optionName) { /** @var bool|string|null $optionValue */ $optionValue = $input->getOption($optionName); if (is_bool($optionValue)) { if ($optionValue === \true) { $processCommandArray[] = sprintf('--%s', $optionName); } continue; } if ($optionValue === null) { continue; } $processCommandArray[] = sprintf('--%s=%s', $optionName, escapeshellarg($optionValue)); } $processCommandArray = array_merge($processCommandArray, $additionalItems); $processCommandArray[] = '--'; /** @var string[] $paths */ $paths = $input->getArgument('paths'); foreach ($paths as $path) { $processCommandArray[] = escapeshellarg($path); } return implode(' ', $processCommandArray); } } */ private $deferred; /** * @var ?Process */ private $process = null; /** * @var bool */ private $canceled = \false; public function __construct(LoopInterface $loop, string $name, string $command) { $this->loop = $loop; $this->name = $name; $this->command = $command; $this->deferred = new Deferred(); } public function getName() : string { return $this->name; } /** * @return PromiseInterface */ public function run() : PromiseInterface { $tmpStdOutResource = tmpfile(); if ($tmpStdOutResource === \false) { throw new ShouldNotHappenException('Failed creating temp file for stdout.'); } $tmpStdErrResource = tmpfile(); if ($tmpStdErrResource === \false) { throw new ShouldNotHappenException('Failed creating temp file for stderr.'); } $this->process = new Process($this->command, null, null, [1 => $tmpStdOutResource, 2 => $tmpStdErrResource]); $this->process->start($this->loop); $this->process->on('exit', function ($exitCode) use($tmpStdOutResource, $tmpStdErrResource) : void { if ($this->canceled) { fclose($tmpStdOutResource); fclose($tmpStdErrResource); return; } rewind($tmpStdOutResource); $stdOut = stream_get_contents($tmpStdOutResource); fclose($tmpStdOutResource); rewind($tmpStdErrResource); $stdErr = stream_get_contents($tmpStdErrResource); fclose($tmpStdErrResource); if ($exitCode === null) { $this->deferred->reject(new \PHPStan\Process\ProcessCrashedException($stdOut . $stdErr)); return; } if ($exitCode === 0) { if ($stdOut === \false) { $stdOut = ''; } $this->deferred->resolve($stdOut); return; } $this->deferred->reject(new \PHPStan\Process\ProcessCrashedException($stdOut . $stdErr)); }); return $this->deferred->promise(); } public function cancel() : void { if ($this->process === null) { throw new ShouldNotHappenException('Cancelling process before running'); } $this->canceled = \true; $this->process->terminate(); $this->deferred->reject(new \PHPStan\Process\ProcessCanceledException()); } } */ public function getClassPrefixes() : array; } reflectionProvider = $reflectionProvider; $this->functionCallParametersCheck = $functionCallParametersCheck; $this->classCheck = $classCheck; $this->deprecationRulesInstalled = $deprecationRulesInstalled; } /** * @param AttributeGroup[] $attrGroups * @param int-mask-of $requiredTarget * @return list */ public function check(Scope $scope, array $attrGroups, int $requiredTarget, string $targetName) : array { $errors = []; $alreadyPresent = []; foreach ($attrGroups as $attrGroup) { foreach ($attrGroup->attrs as $attribute) { $name = $attribute->name->toString(); if (!$this->reflectionProvider->hasClass($name)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Attribute class %s does not exist.', $name))->line($attribute->getStartLine())->identifier('attribute.notFound')->build(); continue; } $attributeClass = $this->reflectionProvider->getClass($name); if (!$attributeClass->isAttributeClass()) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('%s %s is not an Attribute class.', $attributeClass->getClassTypeDescription(), $attributeClass->getDisplayName()))->identifier('attribute.notAttribute')->line($attribute->getStartLine())->build(); continue; } if ($attributeClass->isAbstract()) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Attribute class %s is abstract.', $name))->identifier('attribute.abstract')->line($attribute->getStartLine())->build(); } foreach ($this->classCheck->checkClassNames([new \PHPStan\Rules\ClassNameNodePair($name, $attribute)]) as $caseSensitivityError) { $errors[] = $caseSensitivityError; } $flags = $attributeClass->getAttributeClassFlags(); if (($flags & $requiredTarget) === 0) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Attribute class %s does not have the %s target.', $name, $targetName))->identifier('attribute.target')->line($attribute->getStartLine())->build(); } if (($flags & Attribute::IS_REPEATABLE) === 0) { $loweredName = strtolower($name); if (array_key_exists($loweredName, $alreadyPresent)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Attribute class %s is not repeatable but is already present above the %s.', $name, $targetName))->identifier('attribute.nonRepeatable')->line($attribute->getStartLine())->build(); } $alreadyPresent[$loweredName] = \true; } if ($this->deprecationRulesInstalled && $attributeClass->isDeprecated()) { if ($attributeClass->getDeprecatedDescription() !== null) { $deprecatedError = sprintf('Attribute class %s is deprecated: %s', $name, $attributeClass->getDeprecatedDescription()); } else { $deprecatedError = sprintf('Attribute class %s is deprecated.', $name); } $errors[] = \PHPStan\Rules\RuleErrorBuilder::message($deprecatedError)->identifier('attribute.deprecated')->line($attribute->getStartLine())->build(); } if (!$attributeClass->hasConstructor()) { if (count($attribute->args) > 0) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Attribute class %s does not have a constructor and must be instantiated without any parameters.', $name))->identifier('attribute.noConstructor')->line($attribute->getStartLine())->build(); } continue; } $attributeConstructor = $attributeClass->getConstructor(); if (!$attributeConstructor->isPublic()) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Constructor of attribute class %s is not public.', $name))->identifier('attribute.constructorNotPublic')->line($attribute->getStartLine())->build(); } $attributeClassName = SprintfHelper::escapeFormatString($attributeClass->getDisplayName()); $nodeAttributes = $attribute->getAttributes(); $nodeAttributes['isAttribute'] = \true; $parameterErrors = $this->functionCallParametersCheck->check(ParametersAcceptorSelector::selectFromArgs($scope, $attribute->args, $attributeConstructor->getVariants(), $attributeConstructor->getNamedArgumentsVariants()), $scope, $attributeConstructor->getDeclaringClass()->isBuiltin(), new New_($attribute->name, $attribute->args, $nodeAttributes), [ 'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameter, %d required.', 'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameters, %d required.', 'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameter, at least %d required.', 'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameters, at least %d required.', 'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameter, %d-%d required.', 'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameters, %d-%d required.', 'Parameter %s of attribute class ' . $attributeClassName . ' constructor expects %s, %s given.', '', // constructor does not have a return type 'Parameter %s of attribute class ' . $attributeClassName . ' constructor is passed by reference, so it expects variables only', 'Unable to resolve the template type %s in instantiation of attribute class ' . $attributeClassName, 'Missing parameter $%s in call to ' . $attributeClassName . ' constructor.', 'Unknown parameter $%s in call to ' . $attributeClassName . ' constructor.', 'Return type of call to ' . $attributeClassName . ' constructor contains unresolvable type.', 'Parameter %s of attribute class ' . $attributeClassName . ' constructor contains unresolvable type.', 'Attribute class ' . $attributeClassName . ' constructor invoked with %s, but it\'s not allowed because of @no-named-arguments.', ], 'attribute', $attributeConstructor->acceptsNamedArguments()); foreach ($parameterErrors as $error) { $errors[] = $error; } } } return $errors; } } */ final class ApiInterfaceExtendsRule implements Rule { /** * @var ApiRuleHelper */ private $apiRuleHelper; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Api\ApiRuleHelper $apiRuleHelper, ReflectionProvider $reflectionProvider) { $this->apiRuleHelper = $apiRuleHelper; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Interface_::class; } public function processNode(Node $node, Scope $scope) : array { $errors = []; foreach ($node->extends as $extends) { $errors = array_merge($errors, $this->checkName($scope, $extends)); } return $errors; } /** * @return list */ private function checkName(Scope $scope, Node\Name $name) : array { $extendedInterface = (string) $name; if (!$this->reflectionProvider->hasClass($extendedInterface)) { return []; } $extendedInterfaceReflection = $this->reflectionProvider->getClass($extendedInterface); if (!$this->apiRuleHelper->isPhpStanCode($scope, $extendedInterfaceReflection->getName(), $extendedInterfaceReflection->getFileName())) { return []; } $ruleError = RuleErrorBuilder::message(sprintf('Extending %s is not covered by backward compatibility promise. The interface might change in a minor PHPStan version.', $extendedInterfaceReflection->getDisplayName()))->identifier('phpstanApi.interface')->tip(sprintf("If you think it should be covered by backward compatibility promise, open a discussion:\n %s\n\n See also:\n https://phpstan.org/developing-extensions/backward-compatibility-promise", 'https://github.com/phpstan/phpstan/discussions'))->build(); if (in_array($extendedInterfaceReflection->getName(), \PHPStan\Rules\Api\BcUncoveredInterface::CLASSES, \true)) { return [$ruleError]; } $docBlock = $extendedInterfaceReflection->getResolvedPhpDoc(); if ($docBlock === null) { return [$ruleError]; } foreach ($docBlock->getPhpDocNodes() as $phpDocNode) { $apiTags = $phpDocNode->getTagsByName('@api'); if (count($apiTags) > 0) { return []; } } return [$ruleError]; } } */ final class ApiClassExtendsRule implements Rule { /** * @var ApiRuleHelper */ private $apiRuleHelper; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Api\ApiRuleHelper $apiRuleHelper, ReflectionProvider $reflectionProvider) { $this->apiRuleHelper = $apiRuleHelper; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Class_::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->extends === null) { return []; } $extendedClassName = (string) $node->extends; if (!$this->reflectionProvider->hasClass($extendedClassName)) { return []; } $extendedClassReflection = $this->reflectionProvider->getClass($extendedClassName); if (!$this->apiRuleHelper->isPhpStanCode($scope, $extendedClassReflection->getName(), $extendedClassReflection->getFileName())) { return []; } if ($extendedClassReflection->getName() === MutatingScope::class) { return []; } $ruleError = RuleErrorBuilder::message(sprintf('Extending %s is not covered by backward compatibility promise. The class might change in a minor PHPStan version.', $extendedClassReflection->getDisplayName()))->identifier('phpstanApi.class')->tip(sprintf("If you think it should be covered by backward compatibility promise, open a discussion:\n %s\n\n See also:\n https://phpstan.org/developing-extensions/backward-compatibility-promise", 'https://github.com/phpstan/phpstan/discussions'))->build(); $docBlock = $extendedClassReflection->getResolvedPhpDoc(); if ($docBlock === null) { return [$ruleError]; } foreach ($docBlock->getPhpDocNodes() as $phpDocNode) { $apiTags = $phpDocNode->getTagsByName('@api'); if (count($apiTags) > 0) { return []; } } return [$ruleError]; } } */ final class RuntimeReflectionInstantiationRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ReflectionProvider $reflectionProvider) { $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Expr\New_::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->class instanceof Node\Name) { return []; } $className = $scope->resolveName($node->class); if (!$this->reflectionProvider->hasClass($className)) { return []; } $classReflection = $this->reflectionProvider->getClass($className); if (!in_array($classReflection->getName(), [ReflectionMethod::class, ReflectionClass::class, ReflectionClassConstant::class, 'ReflectionEnum', 'ReflectionEnumBackedCase', ReflectionZendExtension::class, ReflectionExtension::class, ReflectionFunction::class, ReflectionObject::class, ReflectionParameter::class, ReflectionProperty::class, ReflectionGenerator::class, 'ReflectionFiber'], \true)) { return []; } if (!$scope->isInClass()) { return []; } $scopeClassReflection = $scope->getClassReflection(); $hasPhpStanInterface = \false; foreach (array_keys($scopeClassReflection->getInterfaces()) as $interfaceName) { if (!str_starts_with($interfaceName, 'PHPStan\\')) { continue; } $hasPhpStanInterface = \true; } if (!$hasPhpStanInterface) { return []; } return [RuleErrorBuilder::message(sprintf('Creating new %s is a runtime reflection concept that might not work in PHPStan because it uses fully static reflection engine. Use objects retrieved from ReflectionProvider instead.', $classReflection->getName()))->identifier('phpstanApi.runtimeReflection')->build()]; } } */ final class ApiClassConstFetchRule implements Rule { /** * @var ApiRuleHelper */ private $apiRuleHelper; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Api\ApiRuleHelper $apiRuleHelper, ReflectionProvider $reflectionProvider) { $this->apiRuleHelper = $apiRuleHelper; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Expr\ClassConstFetch::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier) { return []; } if (!$node->class instanceof Node\Name) { return []; } $className = $scope->resolveName($node->class); if (!$this->reflectionProvider->hasClass($className)) { return []; } $classReflection = $this->reflectionProvider->getClass($className); if (!$this->apiRuleHelper->isPhpStanCode($scope, $classReflection->getName(), $classReflection->getFileName())) { return []; } $ruleError = RuleErrorBuilder::message(sprintf('Accessing %s::%s is not covered by backward compatibility promise. The class might change in a minor PHPStan version.', $classReflection->getDisplayName(), $node->name->toString()))->identifier('phpstanApi.classConstant')->tip(sprintf("If you think it should be covered by backward compatibility promise, open a discussion:\n %s\n\n See also:\n https://phpstan.org/developing-extensions/backward-compatibility-promise", 'https://github.com/phpstan/phpstan/discussions'))->build(); $docBlock = $classReflection->getResolvedPhpDoc(); if ($docBlock !== null) { foreach ($docBlock->getPhpDocNodes() as $phpDocNode) { $apiTags = $phpDocNode->getTagsByName('@api'); if (count($apiTags) > 0) { return []; } } } if ($node->name->toLowerString() === 'class') { foreach ($classReflection->getNativeReflection()->getMethods() as $methodReflection) { $methodDocComment = $methodReflection->getDocComment(); if ($methodDocComment === \false) { continue; } if (!str_contains($methodDocComment, '@api')) { continue; } return []; } } return [$ruleError]; } } */ final class ApiTraitUseRule implements Rule { /** * @var ApiRuleHelper */ private $apiRuleHelper; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Api\ApiRuleHelper $apiRuleHelper, ReflectionProvider $reflectionProvider) { $this->apiRuleHelper = $apiRuleHelper; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Stmt\TraitUse::class; } public function processNode(Node $node, Scope $scope) : array { $errors = []; $tip = sprintf("If you think it should be covered by backward compatibility promise, open a discussion:\n %s\n\n See also:\n https://phpstan.org/developing-extensions/backward-compatibility-promise", 'https://github.com/phpstan/phpstan/discussions'); foreach ($node->traits as $traitName) { $traitName = $traitName->toString(); if (!$this->reflectionProvider->hasClass($traitName)) { continue; } $traitReflection = $this->reflectionProvider->getClass($traitName); if (!$this->apiRuleHelper->isPhpStanCode($scope, $traitReflection->getName(), $traitReflection->getFileName())) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Using %s is not covered by backward compatibility promise. The trait might change in a minor PHPStan version.', $traitReflection->getDisplayName()))->identifier('phpstanApi.trait')->tip($tip)->build(); } return $errors; } } */ final class NodeConnectingVisitorAttributesRule implements Rule { /** * @var Container */ private $container; public function __construct(Container $container) { $this->container = $container; } public function getNodeType() : string { return MethodCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier) { return []; } if ($node->name->toLowerString() !== 'getattribute') { return []; } $calledOnType = $scope->getType($node->var); if (!(new ObjectType(Node::class))->isSuperTypeOf($calledOnType)->yes()) { return []; } $args = $node->getArgs(); if (!isset($args[0])) { return []; } $argType = $scope->getType($args[0]->value); if (!$argType instanceof ConstantStringType) { return []; } if (!in_array($argType->getValue(), ['parent', 'previous', 'next'], \true)) { return []; } if (!$scope->isInClass()) { return []; } $classReflection = $scope->getClassReflection(); $hasPhpStanInterface = \false; foreach (array_keys($classReflection->getInterfaces()) as $interfaceName) { if (!str_starts_with($interfaceName, 'PHPStan\\')) { continue; } $hasPhpStanInterface = \true; } if (!$hasPhpStanInterface) { return []; } $isVisitorRegistered = \false; foreach ($this->container->getServicesByTag(RichParser::VISITOR_SERVICE_TAG) as $service) { if (get_class($service) !== NodeConnectingVisitor::class) { continue; } $isVisitorRegistered = \true; break; } if ($isVisitorRegistered) { return []; } return [RuleErrorBuilder::message(sprintf('Node attribute \'%s\' is no longer available.', $argType->getValue()))->identifier('phpParser.nodeConnectingAttribute')->tip('See: https://phpstan.org/blog/preprocessing-ast-for-custom-rules')->build()]; } } */ final class PhpStanNamespaceIn3rdPartyPackageRule implements Rule { /** * @var ApiRuleHelper */ private $apiRuleHelper; public function __construct(\PHPStan\Rules\Api\ApiRuleHelper $apiRuleHelper) { $this->apiRuleHelper = $apiRuleHelper; } public function getNodeType() : string { return Node\Stmt\Namespace_::class; } public function processNode(Node $node, Scope $scope) : array { $namespace = null; if ($node->name !== null) { $namespace = $node->name->toString(); } if ($namespace === null || !$this->apiRuleHelper->isPhpStanName($namespace)) { return []; } $composerJson = $this->findComposerJsonContents(dirname($scope->getFile())); if ($composerJson === null) { return []; } $packageName = $composerJson['name'] ?? null; if ($packageName !== null && str_starts_with($packageName, 'phpstan/')) { return []; } return [RuleErrorBuilder::message('Declaring PHPStan namespace is not allowed in 3rd party packages.')->identifier('phpstanApi.phpstanNamespace')->tip("See:\n https://phpstan.org/developing-extensions/backward-compatibility-promise")->build()]; } /** * @return mixed[]|null */ private function findComposerJsonContents(string $fromDirectory) : ?array { if (!is_dir($fromDirectory)) { return null; } $composerJsonPath = $fromDirectory . '/composer.json'; if (!is_file($composerJsonPath)) { $dirName = dirname($fromDirectory); if ($dirName !== $fromDirectory) { return $this->findComposerJsonContents($dirName); } return null; } try { return Json::decode(FileReader::read($composerJsonPath), Json::FORCE_ARRAY); } catch (JsonException $e) { return null; } catch (CouldNotReadFileException $e) { return null; } } } */ final class ApiMethodCallRule implements Rule { /** * @var ApiRuleHelper */ private $apiRuleHelper; public function __construct(\PHPStan\Rules\Api\ApiRuleHelper $apiRuleHelper) { $this->apiRuleHelper = $apiRuleHelper; } public function getNodeType() : string { return Node\Expr\MethodCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier) { return []; } $methodReflection = $scope->getMethodReflection($scope->getType($node->var), $node->name->toString()); if ($methodReflection === null) { return []; } $declaringClass = $methodReflection->getDeclaringClass(); if (!$this->apiRuleHelper->isPhpStanCode($scope, $declaringClass->getName(), $declaringClass->getFileName())) { return []; } if ($this->isCovered($methodReflection)) { return []; } $ruleError = RuleErrorBuilder::message(sprintf('Calling %s::%s() is not covered by backward compatibility promise. The method might change in a minor PHPStan version.', $declaringClass->getDisplayName(), $methodReflection->getName()))->identifier('phpstanApi.method')->tip(sprintf("If you think it should be covered by backward compatibility promise, open a discussion:\n %s\n\n See also:\n https://phpstan.org/developing-extensions/backward-compatibility-promise", 'https://github.com/phpstan/phpstan/discussions'))->build(); return [$ruleError]; } private function isCovered(MethodReflection $methodReflection) : bool { $declaringClass = $methodReflection->getDeclaringClass(); $classDocBlock = $declaringClass->getResolvedPhpDoc(); if ($classDocBlock !== null) { foreach ($classDocBlock->getPhpDocNodes() as $phpDocNode) { $apiTags = $phpDocNode->getTagsByName('@api'); if (count($apiTags) > 0) { return \true; } } } $methodDocComment = $methodReflection->getDocComment(); if ($methodDocComment === null) { return \false; } return str_contains($methodDocComment, '@api'); } } */ final class ApiStaticCallRule implements Rule { /** * @var ApiRuleHelper */ private $apiRuleHelper; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Api\ApiRuleHelper $apiRuleHelper, ReflectionProvider $reflectionProvider) { $this->apiRuleHelper = $apiRuleHelper; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Expr\StaticCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier) { return []; } if (!$node->class instanceof Node\Name) { return []; } $className = $scope->resolveName($node->class); if (!$this->reflectionProvider->hasClass($className)) { return []; } $classReflection = $this->reflectionProvider->getClass($className); $methodName = $node->name->toString(); if (!$classReflection->hasNativeMethod($methodName)) { return []; } $methodReflection = $classReflection->getNativeMethod($methodName); $declaringClass = $methodReflection->getDeclaringClass(); if (!$this->apiRuleHelper->isPhpStanCode($scope, $declaringClass->getName(), $declaringClass->getFileName())) { return []; } if ($this->isCovered($methodReflection)) { return []; } $ruleError = RuleErrorBuilder::message(sprintf('Calling %s::%s() is not covered by backward compatibility promise. The method might change in a minor PHPStan version.', $declaringClass->getDisplayName(), $methodReflection->getName()))->identifier('phpstanApi.method')->tip(sprintf("If you think it should be covered by backward compatibility promise, open a discussion:\n %s\n\n See also:\n https://phpstan.org/developing-extensions/backward-compatibility-promise", 'https://github.com/phpstan/phpstan/discussions'))->build(); return [$ruleError]; } private function isCovered(MethodReflection $methodReflection) : bool { $declaringClass = $methodReflection->getDeclaringClass(); $classDocBlock = $declaringClass->getResolvedPhpDoc(); if ($methodReflection->getName() !== '__construct' && $classDocBlock !== null) { foreach ($classDocBlock->getPhpDocNodes() as $phpDocNode) { $apiTags = $phpDocNode->getTagsByName('@api'); if (count($apiTags) > 0) { return \true; } } } $methodDocComment = $methodReflection->getDocComment(); if ($methodDocComment === null) { return \false; } return str_contains($methodDocComment, '@api'); } } */ final class ApiClassImplementsRule implements Rule { /** * @var ApiRuleHelper */ private $apiRuleHelper; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Api\ApiRuleHelper $apiRuleHelper, ReflectionProvider $reflectionProvider) { $this->apiRuleHelper = $apiRuleHelper; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Class_::class; } public function processNode(Node $node, Scope $scope) : array { $errors = []; foreach ($node->implements as $implements) { $errors = array_merge($errors, $this->checkName($scope, $implements)); } return $errors; } /** * @return list */ private function checkName(Scope $scope, Node\Name $name) : array { $implementedClassName = (string) $name; if (!$this->reflectionProvider->hasClass($implementedClassName)) { return []; } $implementedClassReflection = $this->reflectionProvider->getClass($implementedClassName); if (!$this->apiRuleHelper->isPhpStanCode($scope, $implementedClassReflection->getName(), $implementedClassReflection->getFileName())) { return []; } $ruleError = RuleErrorBuilder::message(sprintf('Implementing %s is not covered by backward compatibility promise. The interface might change in a minor PHPStan version.', $implementedClassReflection->getDisplayName()))->identifier('phpstanApi.interface')->tip(sprintf("If you think it should be covered by backward compatibility promise, open a discussion:\n %s\n\n See also:\n https://phpstan.org/developing-extensions/backward-compatibility-promise", 'https://github.com/phpstan/phpstan/discussions'))->build(); if (in_array($implementedClassReflection->getName(), \PHPStan\Rules\Api\BcUncoveredInterface::CLASSES, \true)) { return [$ruleError]; } $docBlock = $implementedClassReflection->getResolvedPhpDoc(); if ($docBlock === null) { return [$ruleError]; } foreach ($docBlock->getPhpDocNodes() as $phpDocNode) { $apiTags = $phpDocNode->getTagsByName('@api'); if (count($apiTags) > 0) { return []; } } return [$ruleError]; } } */ final class RuntimeReflectionFunctionRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ReflectionProvider $reflectionProvider) { $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Expr\FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } $functionReflection = $this->reflectionProvider->getFunction($node->name, $scope); if (!in_array($functionReflection->getName(), ['is_a', 'is_subclass_of', 'class_parents', 'class_implements', 'class_uses'], \true)) { return []; } if (!$scope->isInClass()) { return []; } $classReflection = $scope->getClassReflection(); $hasPhpStanInterface = \false; foreach (array_keys($classReflection->getInterfaces()) as $interfaceName) { if (!str_starts_with($interfaceName, 'PHPStan\\')) { continue; } $hasPhpStanInterface = \true; } if (!$hasPhpStanInterface) { return []; } return [RuleErrorBuilder::message(sprintf('Function %s() is a runtime reflection concept that might not work in PHPStan because it uses fully static reflection engine. Use objects retrieved from ReflectionProvider instead.', $functionReflection->getName()))->identifier('phpstanApi.runtimeReflection')->build()]; } } getNamespace(); if ($scopeNamespace === null) { return $this->isPhpStanName($namespace); } if ($this->isPhpStanName($scopeNamespace)) { if (!$this->isPhpStanName($namespace)) { return \false; } if ($declaringFile !== null) { $scopeFile = $scope->getFile(); $dir = dirname($scopeFile); $helper = new ParentDirectoryRelativePathHelper($dir); $pathParts = $helper->getFilenameParts($declaringFile); $directories = $this->createAbsoluteDirectories($dir, $pathParts); foreach ($directories as $directory) { if (pathinfo($directory, PATHINFO_BASENAME) === 'vendor') { return \true; } } } return \false; } return $this->isPhpStanName($namespace); } /** * @param string[] $parts * @return string[] */ private function createAbsoluteDirectories(string $currentDirectory, array $parts) : array { $directories = []; foreach ($parts as $part) { if ($part === '..') { $currentDirectory = dirname($currentDirectory); $directories[] = $currentDirectory; continue; } $currentDirectory .= '/' . $part; $directories[] = $currentDirectory; } return $directories; } public function isPhpStanName(string $namespace) : bool { if (strtolower($namespace) === 'phpstan') { return \true; } if (str_starts_with($namespace, 'PHPStan\\PhpDocParser\\')) { return \false; } if (str_starts_with($namespace, 'PHPStan\\BetterReflection\\')) { return \false; } return stripos($namespace, 'PHPStan\\') === 0; } } */ final class ApiInstanceofTypeRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var bool */ private $enabled; /** * @var bool */ private $deprecationRulesInstalled; private const MAP = [ TypeWithClassName::class => 'Type::getObjectClassNames() or Type::getObjectClassReflections()', EnumCaseObjectType::class => 'Type::getEnumCases()', ConstantArrayType::class => 'Type::getConstantArrays()', ArrayType::class => 'Type::isArray() or Type::getArrays()', ConstantStringType::class => 'Type::getConstantStrings()', StringType::class => 'Type::isString()', ClassStringType::class => 'Type::isClassStringType()', IntegerType::class => 'Type::isInteger()', FloatType::class => 'Type::isFloat()', NullType::class => 'Type::isNull()', VoidType::class => 'Type::isVoid()', BooleanType::class => 'Type::isBoolean()', ConstantBooleanType::class => 'Type::isTrue() or Type::isFalse()', CallableType::class => 'Type::isCallable() and Type::getCallableParametersAcceptors()', IterableType::class => 'Type::isIterable()', ObjectWithoutClassType::class => 'Type::isObject()', ObjectType::class => 'Type::isObject() or Type::getObjectClassNames()', GenericClassStringType::class => 'Type::isClassStringType() and Type::getClassStringObjectType()', GenericObjectType::class => null, IntersectionType::class => null, ConstantType::class => 'Type::isConstantValue() or Type::generalize()', ConstantScalarType::class => 'Type::isConstantScalarValue() or Type::getConstantScalarTypes() or Type::getConstantScalarValues()', ObjectShapeType::class => 'Type::isObject() and Type::hasProperty()', // accessory types NonEmptyArrayType::class => 'Type::isIterableAtLeastOnce()', OversizedArrayType::class => 'Type::isOversizedArray()', AccessoryArrayListType::class => 'Type::isList()', AccessoryNumericStringType::class => 'Type::isNumericString()', AccessoryLiteralStringType::class => 'Type::isLiteralString()', AccessoryLowercaseStringType::class => 'Type::isLowercaseString()', AccessoryUppercaseStringType::class => 'Type::isUppercaseString()', AccessoryNonEmptyStringType::class => 'Type::isNonEmptyString()', AccessoryNonFalsyStringType::class => 'Type::isNonFalsyString()', HasMethodType::class => 'Type::hasMethod()', HasPropertyType::class => 'Type::hasProperty()', HasOffsetType::class => 'Type::hasOffsetValueType()', AccessoryType::class => 'methods on PHPStan\\Type\\Type', ]; public function __construct(ReflectionProvider $reflectionProvider, bool $enabled, bool $deprecationRulesInstalled) { $this->reflectionProvider = $reflectionProvider; $this->enabled = $enabled; $this->deprecationRulesInstalled = $deprecationRulesInstalled; } public function getNodeType() : string { return Instanceof_::class; } public function processNode(Node $node, Scope $scope) : array { if (!$this->enabled && !$this->deprecationRulesInstalled) { return []; } if (!$node->class instanceof Node\Name) { return []; } if ($node->getAttribute(TypeTraverserInstanceofVisitor::ATTRIBUTE_NAME, \false) === \true) { return []; } $lowerMap = []; foreach (self::MAP as $className => $method) { $lowerMap[strtolower($className)] = $method; } $className = $scope->resolveName($node->class); $lowerClassName = strtolower($className); if (!array_key_exists($lowerClassName, $lowerMap)) { return []; } if ($this->reflectionProvider->hasClass($className)) { $classReflection = $this->reflectionProvider->getClass($className); if ($classReflection->isSubclassOf(AccessoryType::class)) { if ($className === $classReflection->getName()) { return []; } } } $tip = 'Learn more: https://phpstan.org/blog/why-is-instanceof-type-wrong-and-getting-deprecated'; if ($lowerMap[$lowerClassName] === null) { return [RuleErrorBuilder::message(sprintf('Doing instanceof %s is error-prone and deprecated.', $className))->identifier('phpstanApi.instanceofType')->tip($tip)->build()]; } return [RuleErrorBuilder::message(sprintf('Doing instanceof %s is error-prone and deprecated. Use %s instead.', $className, $lowerMap[$lowerClassName]))->identifier('phpstanApi.instanceofType')->tip($tip)->build()]; } } */ final class ApiInstantiationRule implements Rule { /** * @var ApiRuleHelper */ private $apiRuleHelper; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Api\ApiRuleHelper $apiRuleHelper, ReflectionProvider $reflectionProvider) { $this->apiRuleHelper = $apiRuleHelper; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Expr\New_::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->class instanceof Node\Name) { return []; } $className = $scope->resolveName($node->class); if (!$this->reflectionProvider->hasClass($className)) { return []; } $classReflection = $this->reflectionProvider->getClass($className); if (!$this->apiRuleHelper->isPhpStanCode($scope, $classReflection->getName(), $classReflection->getFileName())) { return []; } $ruleError = RuleErrorBuilder::message(sprintf('Creating new %s is not covered by backward compatibility promise. The class might change in a minor PHPStan version.', $classReflection->getDisplayName()))->identifier('phpstanApi.constructor')->tip(sprintf("If you think it should be covered by backward compatibility promise, open a discussion:\n %s\n\n See also:\n https://phpstan.org/developing-extensions/backward-compatibility-promise", 'https://github.com/phpstan/phpstan/discussions'))->build(); if (!$classReflection->hasConstructor()) { return [$ruleError]; } $constructor = $classReflection->getConstructor(); $docComment = $constructor->getDocComment(); if ($docComment === null) { return [$ruleError]; } if (!str_contains($docComment, '@api')) { return [$ruleError]; } if ($constructor->getDeclaringClass()->getName() !== $classReflection->getName()) { return [$ruleError]; } return []; } } */ final class ApiInstanceofRule implements Rule { /** * @var ApiRuleHelper */ private $apiRuleHelper; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Api\ApiRuleHelper $apiRuleHelper, ReflectionProvider $reflectionProvider) { $this->apiRuleHelper = $apiRuleHelper; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Expr\Instanceof_::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->class instanceof Node\Name) { return []; } $className = $scope->resolveName($node->class); if (!$this->reflectionProvider->hasClass($className)) { return []; } $classReflection = $this->reflectionProvider->getClass($className); if (!$this->apiRuleHelper->isPhpStanCode($scope, $classReflection->getName(), $classReflection->getFileName())) { return []; } $ruleError = RuleErrorBuilder::message(sprintf('Asking about instanceof %s is not covered by backward compatibility promise. The %s might change in a minor PHPStan version.', $classReflection->getDisplayName(), strtolower($classReflection->getClassTypeDescription())))->identifier(sprintf('phpstanApi.%s', strtolower($classReflection->getClassTypeDescription())))->tip(sprintf("If you think it should be covered by backward compatibility promise, open a discussion:\n %s\n\n See also:\n https://phpstan.org/developing-extensions/backward-compatibility-promise", 'https://github.com/phpstan/phpstan/discussions'))->build(); $docBlock = $classReflection->getResolvedPhpDoc(); if ($docBlock === null) { return [$ruleError]; } foreach ($docBlock->getPhpDocNodes() as $phpDocNode) { $apiTags = $phpDocNode->getTagsByName('@api'); if (count($apiTags) > 0) { return $this->processCoveredClass($node, $scope, $classReflection); } } return [$ruleError]; } /** * @return list */ private function processCoveredClass(Node\Expr\Instanceof_ $node, Scope $scope, ClassReflection $classReflection) : array { if ($classReflection->getName() === Type::class || $classReflection->isSubclassOf(Type::class)) { return []; } if ($classReflection->isInterface()) { return []; } $instanceofType = $scope->getType($node); if ($instanceofType->isTrue()->or($instanceofType->isFalse())->yes()) { return []; } $classType = new ObjectType($classReflection->getName(), null, $classReflection); $exprType = $scope->getType($node->expr); if ($exprType instanceof UnionType) { foreach ($exprType->getTypes() as $innerType) { if ($innerType->getObjectClassNames() !== [] && $classType->isSuperTypeOf($innerType)->yes()) { return []; } } } return [RuleErrorBuilder::message(sprintf('Although %s is covered by backward compatibility promise, this instanceof assumption might break because it\'s not guaranteed to always stay the same.', $classReflection->getDisplayName()))->identifier('phpstanApi.instanceofAssumption')->tip(sprintf("In case of questions how to solve this correctly, open a discussion:\n %s\n\n See also:\n https://phpstan.org/developing-extensions/backward-compatibility-promise", 'https://github.com/phpstan/phpstan/discussions'))->build()]; } } */ final class GetTemplateTypeRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ReflectionProvider $reflectionProvider) { $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return MethodCall::class; } public function processNode(Node $node, Scope $scope) : array { $args = $node->getArgs(); if (count($args) < 2) { return []; } if (!$node->name instanceof Node\Identifier) { return []; } if ($node->name->toLowerString() !== 'gettemplatetype') { return []; } $calledOnType = $scope->getType($node->var); $methodReflection = $scope->getMethodReflection($calledOnType, $node->name->toString()); if ($methodReflection === null) { return []; } if (!$methodReflection->getDeclaringClass()->is(Type::class)) { return []; } $classType = $scope->getType($args[0]->value); $templateType = $scope->getType($args[1]->value); $errors = []; foreach ($classType->getConstantStrings() as $classNameType) { if (!$this->reflectionProvider->hasClass($classNameType->getValue())) { continue; } $classReflection = $this->reflectionProvider->getClass($classNameType->getValue()); $templateTypeMap = $classReflection->getTemplateTypeMap(); foreach ($templateType->getConstantStrings() as $templateTypeName) { if ($templateTypeMap->hasType($templateTypeName->getValue())) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Call to %s::%s() references unknown template type %s on class %s.', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName(), $templateTypeName->getValue(), $classReflection->getDisplayName()))->identifier('phpstanApi.getTemplateType')->build(); } } return $errors; } } */ final class IgnoreParseErrorRule implements Rule { public function getNodeType() : string { return FileNode::class; } public function processNode(Node $node, Scope $scope) : array { $nodes = $node->getNodes(); if (count($nodes) === 0) { return []; } $firstNode = $nodes[0]; $parseErrors = $firstNode->getAttribute('linesToIgnoreParseErrors', []); $errors = []; foreach ($parseErrors as $line => $lineParseErrors) { foreach ($lineParseErrors as $parseError) { $errors[] = RuleErrorBuilder::message(sprintf('Parse error in @phpstan-ignore: %s', $parseError))->line($line)->identifier('ignore.parseError')->nonIgnorable()->build(); } } return $errors; } } rules[$rule->getNodeType()][] = $rule; } } /** * @template TNodeType of Node * @param class-string $nodeType * @return array> */ public function getRules(string $nodeType) : array { if (!isset($this->cache[$nodeType])) { $parentNodeTypes = [$nodeType] + class_parents($nodeType) + class_implements($nodeType); $rules = []; foreach ($parentNodeTypes as $parentNodeType) { foreach ($this->rules[$parentNodeType] ?? [] as $rule) { $rules[] = $rule; } } $this->cache[$nodeType] = $rules; } /** * @var array> $selectedRules */ $selectedRules = $this->cache[$nodeType]; return $selectedRules; } } */ final class TypesAssignedToPropertiesRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var PropertyReflectionFinder */ private $propertyReflectionFinder; public function __construct(RuleLevelHelper $ruleLevelHelper, \PHPStan\Rules\Properties\PropertyReflectionFinder $propertyReflectionFinder) { $this->ruleLevelHelper = $ruleLevelHelper; $this->propertyReflectionFinder = $propertyReflectionFinder; } public function getNodeType() : string { return PropertyAssignNode::class; } public function processNode(Node $node, Scope $scope) : array { $propertyReflections = $this->propertyReflectionFinder->findPropertyReflectionsFromNode($node->getPropertyFetch(), $scope); $errors = []; foreach ($propertyReflections as $propertyReflection) { $errors = array_merge($errors, $this->processSingleProperty($propertyReflection, $node->getAssignedExpr())); } return $errors; } /** * @return list */ private function processSingleProperty(\PHPStan\Rules\Properties\FoundPropertyReflection $propertyReflection, Node\Expr $assignedExpr) : array { if (!$propertyReflection->isWritable()) { return []; } $propertyType = $propertyReflection->getWritableType(); $scope = $propertyReflection->getScope(); $assignedValueType = $scope->getType($assignedExpr); $accepts = $this->ruleLevelHelper->acceptsWithReason($propertyType, $assignedValueType, $scope->isDeclareStrictTypes()); if (!$accepts->result) { $propertyDescription = $this->describePropertyByName($propertyReflection, $propertyReflection->getName()); $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($propertyType, $assignedValueType); return [RuleErrorBuilder::message(sprintf('%s (%s) does not accept %s.', $propertyDescription, $propertyType->describe($verbosityLevel), $assignedValueType->describe($verbosityLevel)))->identifier('assign.propertyType')->acceptsReasonsTip($accepts->reasons)->build()]; } return []; } private function describePropertyByName(PropertyReflection $property, string $propertyName) : string { if (!$property->isStatic()) { return sprintf('Property %s::$%s', $property->getDeclaringClass()->getDisplayName(), $propertyName); } return sprintf('Static property %s::$%s', $property->getDeclaringClass()->getDisplayName(), $propertyName); } } name instanceof Node\Identifier) { $names = [$propertyFetch->name->name]; } else { $names = array_map(static function (ConstantStringType $name) : string { return $name->getValue(); }, $scope->getType($propertyFetch->name)->getConstantStrings()); } $reflections = []; $propertyHolderType = $scope->getType($propertyFetch->var); foreach ($names as $name) { $reflection = $this->findPropertyReflection($propertyHolderType, $name, $propertyFetch->name instanceof Expr ? $scope->filterByTruthyValue(new Expr\BinaryOp\Identical($propertyFetch->name, new String_($name))) : $scope); if ($reflection === null) { continue; } $reflections[] = $reflection; } return $reflections; } if ($propertyFetch->class instanceof Node\Name) { $propertyHolderType = $scope->resolveTypeByName($propertyFetch->class); } else { $propertyHolderType = $scope->getType($propertyFetch->class); } if ($propertyFetch->name instanceof VarLikeIdentifier) { $names = [$propertyFetch->name->name]; } else { $names = array_map(static function (ConstantStringType $name) : string { return $name->getValue(); }, $scope->getType($propertyFetch->name)->getConstantStrings()); } $reflections = []; foreach ($names as $name) { $reflection = $this->findPropertyReflection($propertyHolderType, $name, $propertyFetch->name instanceof Expr ? $scope->filterByTruthyValue(new Expr\BinaryOp\Identical($propertyFetch->name, new String_($name))) : $scope); if ($reflection === null) { continue; } $reflections[] = $reflection; } return $reflections; } /** * @param Node\Expr\PropertyFetch|Node\Expr\StaticPropertyFetch $propertyFetch */ public function findPropertyReflectionFromNode($propertyFetch, Scope $scope) : ?\PHPStan\Rules\Properties\FoundPropertyReflection { if ($propertyFetch instanceof Node\Expr\PropertyFetch) { if (!$propertyFetch->name instanceof Node\Identifier) { return null; } $propertyHolderType = $scope->getType($propertyFetch->var); return $this->findPropertyReflection($propertyHolderType, $propertyFetch->name->name, $scope); } if (!$propertyFetch->name instanceof Node\Identifier) { return null; } if ($propertyFetch->class instanceof Node\Name) { $propertyHolderType = $scope->resolveTypeByName($propertyFetch->class); } else { $propertyHolderType = $scope->getType($propertyFetch->class); } return $this->findPropertyReflection($propertyHolderType, $propertyFetch->name->name, $scope); } private function findPropertyReflection(Type $propertyHolderType, string $propertyName, Scope $scope) : ?\PHPStan\Rules\Properties\FoundPropertyReflection { if (!$propertyHolderType->hasProperty($propertyName)->yes()) { return null; } $originalProperty = $propertyHolderType->getProperty($propertyName, $scope); return new \PHPStan\Rules\Properties\FoundPropertyReflection($originalProperty, $scope, $propertyName, $originalProperty->getReadableType(), $originalProperty->getWritableType()); } } originalPropertyReflection = $originalPropertyReflection; $this->scope = $scope; $this->propertyName = $propertyName; $this->readableType = $readableType; $this->writableType = $writableType; } public function getScope() : Scope { return $this->scope; } public function getDeclaringClass() : ClassReflection { return $this->originalPropertyReflection->getDeclaringClass(); } public function getName() : string { return $this->propertyName; } public function isStatic() : bool { return $this->originalPropertyReflection->isStatic(); } public function isPrivate() : bool { return $this->originalPropertyReflection->isPrivate(); } public function isPublic() : bool { return $this->originalPropertyReflection->isPublic(); } public function getDocComment() : ?string { return $this->originalPropertyReflection->getDocComment(); } public function getReadableType() : Type { return $this->readableType; } public function getWritableType() : Type { return $this->writableType; } public function canChangeTypeAfterAssignment() : bool { return $this->originalPropertyReflection->canChangeTypeAfterAssignment(); } public function isReadable() : bool { return $this->originalPropertyReflection->isReadable(); } public function isWritable() : bool { return $this->originalPropertyReflection->isWritable(); } public function isDeprecated() : TrinaryLogic { return $this->originalPropertyReflection->isDeprecated(); } public function getDeprecatedDescription() : ?string { return $this->originalPropertyReflection->getDeprecatedDescription(); } public function isInternal() : TrinaryLogic { return $this->originalPropertyReflection->isInternal(); } public function isNative() : bool { return $this->getNativeReflection() !== null; } public function getNativeType() : ?Type { $reflection = $this->getNativeReflection(); if ($reflection === null) { return null; } return $reflection->getNativeType(); } public function getNativeReflection() : ?PhpPropertyReflection { $reflection = $this->originalPropertyReflection; while ($reflection instanceof WrapperPropertyReflection) { $reflection = $reflection->getOriginalReflection(); } if (!$reflection instanceof PhpPropertyReflection) { return null; } return $reflection; } } */ final class ReadOnlyByPhpDocPropertyAssignRule implements Rule { /** * @var PropertyReflectionFinder */ private $propertyReflectionFinder; /** * @var ConstructorsHelper */ private $constructorsHelper; public function __construct(\PHPStan\Rules\Properties\PropertyReflectionFinder $propertyReflectionFinder, ConstructorsHelper $constructorsHelper) { $this->propertyReflectionFinder = $propertyReflectionFinder; $this->constructorsHelper = $constructorsHelper; } public function getNodeType() : string { return PropertyAssignNode::class; } public function processNode(Node $node, Scope $scope) : array { $propertyFetch = $node->getPropertyFetch(); if (!$propertyFetch instanceof Node\Expr\PropertyFetch) { return []; } $errors = []; $reflections = $this->propertyReflectionFinder->findPropertyReflectionsFromNode($propertyFetch, $scope); foreach ($reflections as $propertyReflection) { $nativeReflection = $propertyReflection->getNativeReflection(); if ($nativeReflection === null) { continue; } if (!$scope->canAccessProperty($propertyReflection)) { continue; } if (!$nativeReflection->isReadOnlyByPhpDoc() || $nativeReflection->isReadOnly()) { continue; } $declaringClass = $nativeReflection->getDeclaringClass(); if (!$scope->isInClass()) { $errors[] = RuleErrorBuilder::message(sprintf('@readonly property %s::$%s is assigned outside of its declaring class.', $declaringClass->getDisplayName(), $propertyReflection->getName()))->identifier('property.readOnlyByPhpDocAssignOutOfClass')->build(); continue; } $scopeClassReflection = $scope->getClassReflection(); if ($scopeClassReflection->getName() !== $declaringClass->getName()) { $errors[] = RuleErrorBuilder::message(sprintf('@readonly property %s::$%s is assigned outside of its declaring class.', $declaringClass->getDisplayName(), $propertyReflection->getName()))->identifier('property.readOnlyByPhpDocAssignOutOfClass')->build(); continue; } $scopeMethod = $scope->getFunction(); if (!$scopeMethod instanceof MethodReflection) { throw new ShouldNotHappenException(); } if (in_array($scopeMethod->getName(), $this->constructorsHelper->getConstructors($scopeClassReflection), \true) || strtolower($scopeMethod->getName()) === '__unserialize') { if (TypeUtils::findThisType($scope->getType($propertyFetch->var)) === null) { $errors[] = RuleErrorBuilder::message(sprintf('@readonly property %s::$%s is not assigned on $this.', $declaringClass->getDisplayName(), $propertyReflection->getName()))->identifier('property.readOnlyByPhpDocAssignNotOnThis')->build(); } continue; } if ($nativeReflection->isAllowedPrivateMutation()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('@readonly property %s::$%s is assigned outside of the constructor.', $declaringClass->getDisplayName(), $propertyReflection->getName()))->identifier('property.readOnlyByPhpDocAssignNotInConstructor')->build(); } return $errors; } } container = $container; } public function getExtensions() : array { if ($this->extensions === null) { $this->extensions = $this->container->getServicesByTag(\PHPStan\Rules\Properties\ReadWritePropertiesExtensionProvider::EXTENSION_TAG); } return $this->extensions; } } */ final class MissingReadOnlyPropertyAssignRule implements Rule { /** * @var ConstructorsHelper */ private $constructorsHelper; public function __construct(ConstructorsHelper $constructorsHelper) { $this->constructorsHelper = $constructorsHelper; } public function getNodeType() : string { return ClassPropertiesNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); [$properties, $prematureAccess, $additionalAssigns] = $node->getUninitializedProperties($scope, $this->constructorsHelper->getConstructors($classReflection)); $errors = []; foreach ($properties as $propertyName => $propertyNode) { if (!$propertyNode->isReadOnly()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Class %s has an uninitialized readonly property $%s. Assign it in the constructor.', $classReflection->getDisplayName(), $propertyName))->line($propertyNode->getStartLine())->identifier('property.uninitializedReadonly')->build(); } foreach ($prematureAccess as [$propertyName, $line, $propertyNode, $file, $fileDescription]) { if (!$propertyNode->isReadOnly()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Access to an uninitialized readonly property %s::$%s.', $classReflection->getDisplayName(), $propertyName))->line($line)->file($file, $fileDescription)->identifier('property.uninitializedReadonly')->build(); } foreach ($additionalAssigns as [$propertyName, $line, $propertyNode]) { if (!$propertyNode->isReadOnly()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Readonly property %s::$%s is already assigned.', $classReflection->getDisplayName(), $propertyName))->line($line)->identifier('assign.readOnlyProperty')->build(); } return $errors; } } */ final class ExistingClassesInPropertiesRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var ClassNameCheck */ private $classCheck; /** * @var UnresolvableTypeHelper */ private $unresolvableTypeHelper; /** * @var PhpVersion */ private $phpVersion; /** * @var bool */ private $checkClassCaseSensitivity; /** * @var bool */ private $checkThisOnly; public function __construct(ReflectionProvider $reflectionProvider, ClassNameCheck $classCheck, UnresolvableTypeHelper $unresolvableTypeHelper, PhpVersion $phpVersion, bool $checkClassCaseSensitivity, bool $checkThisOnly) { $this->reflectionProvider = $reflectionProvider; $this->classCheck = $classCheck; $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->phpVersion = $phpVersion; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; $this->checkThisOnly = $checkThisOnly; } public function getNodeType() : string { return ClassPropertyNode::class; } public function processNode(Node $node, Scope $scope) : array { $propertyReflection = $node->getClassReflection()->getNativeProperty($node->getName()); if ($this->checkThisOnly) { $referencedClasses = $propertyReflection->getNativeType()->getReferencedClasses(); } else { $referencedClasses = array_merge($propertyReflection->getNativeType()->getReferencedClasses(), $propertyReflection->getPhpDocType()->getReferencedClasses()); } $errors = []; foreach ($referencedClasses as $referencedClass) { if ($this->reflectionProvider->hasClass($referencedClass)) { if ($this->reflectionProvider->getClass($referencedClass)->isTrait()) { $errors[] = RuleErrorBuilder::message(sprintf('Property %s::$%s has invalid type %s.', $propertyReflection->getDeclaringClass()->getDisplayName(), $node->getName(), $referencedClass))->identifier('property.trait')->build(); } continue; } $errors[] = RuleErrorBuilder::message(sprintf('Property %s::$%s has unknown class %s as its type.', $propertyReflection->getDeclaringClass()->getDisplayName(), $node->getName(), $referencedClass))->identifier('class.notFound')->discoveringSymbolsTip()->build(); } $errors = array_merge($errors, $this->classCheck->checkClassNames(array_map(static function (string $class) use($node) : ClassNameNodePair { return new ClassNameNodePair($class, $node); }, $referencedClasses), $this->checkClassCaseSensitivity)); if ($this->phpVersion->supportsPureIntersectionTypes() && $this->unresolvableTypeHelper->containsUnresolvableType($propertyReflection->getNativeType())) { $errors[] = RuleErrorBuilder::message(sprintf('Property %s::$%s has unresolvable native type.', $propertyReflection->getDeclaringClass()->getDisplayName(), $node->getName()))->identifier('property.unresolvableNativeType')->build(); } return $errors; } } */ final class UninitializedPropertyRule implements Rule { /** * @var ConstructorsHelper */ private $constructorsHelper; public function __construct(ConstructorsHelper $constructorsHelper) { $this->constructorsHelper = $constructorsHelper; } public function getNodeType() : string { return ClassPropertiesNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); [$properties, $prematureAccess] = $node->getUninitializedProperties($scope, $this->constructorsHelper->getConstructors($classReflection)); $errors = []; foreach ($properties as $propertyName => $propertyNode) { if ($propertyNode->isReadOnly() || $propertyNode->isReadOnlyByPhpDoc()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Class %s has an uninitialized property $%s. Give it default value or assign it in the constructor.', $classReflection->getDisplayName(), $propertyName))->line($propertyNode->getStartLine())->identifier('property.uninitialized')->build(); } foreach ($prematureAccess as [$propertyName, $line, $propertyNode, $file, $fileDescription]) { if ($propertyNode->isReadOnly() || $propertyNode->isReadOnlyByPhpDoc()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Access to an uninitialized property %s::$%s.', $classReflection->getDisplayName(), $propertyName))->line($line)->file($file, $fileDescription)->identifier('property.uninitialized')->build(); } return $errors; } } */ final class NullsafePropertyFetchRule implements Rule { public function __construct() { } public function getNodeType() : string { return Node\Expr\NullsafePropertyFetch::class; } public function processNode(Node $node, Scope $scope) : array { $calledOnType = $scope->getType($node->var); if (!$calledOnType->isNull()->no()) { return []; } if ($scope->isUndefinedExpressionAllowed($node)) { return []; } return [RuleErrorBuilder::message(sprintf('Using nullsafe property access on non-nullable type %s. Use -> instead.', $calledOnType->describe(VerbosityLevel::typeOnly())))->identifier('nullsafe.neverNull')->build()]; } } */ final class AccessPropertiesRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var bool */ private $reportMagicProperties; /** * @var bool */ private $checkDynamicProperties; public function __construct(ReflectionProvider $reflectionProvider, RuleLevelHelper $ruleLevelHelper, bool $reportMagicProperties, bool $checkDynamicProperties) { $this->reflectionProvider = $reflectionProvider; $this->ruleLevelHelper = $ruleLevelHelper; $this->reportMagicProperties = $reportMagicProperties; $this->checkDynamicProperties = $checkDynamicProperties; } public function getNodeType() : string { return PropertyFetch::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->name instanceof Identifier) { $names = [$node->name->name]; } else { $names = array_map(static function (ConstantStringType $type) : string { return $type->getValue(); }, $scope->getType($node->name)->getConstantStrings()); } $errors = []; foreach ($names as $name) { $errors = array_merge($errors, $this->processSingleProperty($scope, $node, $name)); } return $errors; } /** * @return list */ private function processSingleProperty(Scope $scope, PropertyFetch $node, string $name) : array { $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $node->var), sprintf('Access to property $%s on an unknown class %%s.', SprintfHelper::escapeFormatString($name)), static function (Type $type) use($name) : bool { return $type->canAccessProperties()->yes() && $type->hasProperty($name)->yes(); }); $type = $typeResult->getType(); if ($type instanceof ErrorType) { return $typeResult->getUnknownClassErrors(); } if ($scope->isInExpressionAssign($node)) { return []; } $typeForDescribe = $type; if ($type instanceof StaticType) { $typeForDescribe = $type->getStaticObjectType(); } if ($type->canAccessProperties()->no() || $type->canAccessProperties()->maybe() && !$scope->isUndefinedExpressionAllowed($node)) { return [RuleErrorBuilder::message(sprintf('Cannot access property $%s on %s.', $name, $typeForDescribe->describe(VerbosityLevel::typeOnly())))->identifier('property.nonObject')->build()]; } $has = $type->hasProperty($name); if (!$has->no() && $this->canAccessUndefinedProperties($scope, $node)) { return []; } if (!$has->yes()) { if ($scope->hasExpressionType($node)->yes()) { return []; } $classNames = $type->getObjectClassNames(); if (!$this->reportMagicProperties) { foreach ($classNames as $className) { if (!$this->reflectionProvider->hasClass($className)) { continue; } $classReflection = $this->reflectionProvider->getClass($className); if ($classReflection->hasNativeMethod('__get') || $classReflection->hasNativeMethod('__set')) { return []; } } } if (count($classNames) === 1) { $propertyClassReflection = $this->reflectionProvider->getClass($classNames[0]); $parentClassReflection = $propertyClassReflection->getParentClass(); while ($parentClassReflection !== null) { if ($parentClassReflection->hasProperty($name)) { if ($scope->canAccessProperty($parentClassReflection->getProperty($name, $scope))) { return []; } return [RuleErrorBuilder::message(sprintf('Access to private property $%s of parent class %s.', $name, $parentClassReflection->getDisplayName()))->identifier('property.private')->build()]; } $parentClassReflection = $parentClassReflection->getParentClass(); } } $ruleErrorBuilder = RuleErrorBuilder::message(sprintf('Access to an undefined property %s::$%s.', $typeForDescribe->describe(VerbosityLevel::typeOnly()), $name))->identifier('property.notFound'); if ($typeResult->getTip() !== null) { $ruleErrorBuilder->tip($typeResult->getTip()); } else { $ruleErrorBuilder->tip('Learn more: https://phpstan.org/blog/solving-phpstan-access-to-undefined-property'); } return [$ruleErrorBuilder->build()]; } $propertyReflection = $type->getProperty($name, $scope); if (!$scope->canAccessProperty($propertyReflection)) { return [RuleErrorBuilder::message(sprintf('Access to %s property %s::$%s.', $propertyReflection->isPrivate() ? 'private' : 'protected', $type->describe(VerbosityLevel::typeOnly()), $name))->identifier(sprintf('property.%s', $propertyReflection->isPrivate() ? 'private' : 'protected'))->build()]; } return []; } private function canAccessUndefinedProperties(Scope $scope, Node\Expr $node) : bool { return $scope->isUndefinedExpressionAllowed($node) && !$this->checkDynamicProperties; } } */ final class ReadOnlyPropertyAssignRefRule implements Rule { /** * @var PropertyReflectionFinder */ private $propertyReflectionFinder; public function __construct(\PHPStan\Rules\Properties\PropertyReflectionFinder $propertyReflectionFinder) { $this->propertyReflectionFinder = $propertyReflectionFinder; } public function getNodeType() : string { return Node\Expr\AssignRef::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->expr instanceof Node\Expr\PropertyFetch && !$node->expr instanceof Node\Expr\StaticPropertyFetch) { return []; } $propertyFetch = $node->expr; $errors = []; $reflections = $this->propertyReflectionFinder->findPropertyReflectionsFromNode($propertyFetch, $scope); foreach ($reflections as $propertyReflection) { $nativeReflection = $propertyReflection->getNativeReflection(); if ($nativeReflection === null) { continue; } if (!$scope->canAccessProperty($propertyReflection)) { continue; } if (!$nativeReflection->isReadOnly()) { continue; } $declaringClass = $nativeReflection->getDeclaringClass(); $errors[] = RuleErrorBuilder::message(sprintf('Readonly property %s::$%s is assigned by reference.', $declaringClass->getDisplayName(), $propertyReflection->getName()))->identifier('property.readOnlyAssignByRef')->build(); } return $errors; } } */ final class DefaultValueTypesAssignedToPropertiesRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return ClassPropertyNode::class; } public function processNode(Node $node, Scope $scope) : array { $default = $node->getDefault(); if ($default === null) { return []; } $classReflection = $node->getClassReflection(); $propertyReflection = $classReflection->getNativeProperty($node->getName()); $propertyType = $propertyReflection->getWritableType(); if ($propertyReflection->getNativeType() instanceof MixedType) { if ($default instanceof Node\Expr\ConstFetch && $default->name->toLowerString() === 'null') { return []; } } $defaultValueType = $scope->getType($default); $accepts = $this->ruleLevelHelper->acceptsWithReason($propertyType, $defaultValueType, \true); if ($accepts->result) { return []; } $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($propertyType, $defaultValueType); return [RuleErrorBuilder::message(sprintf('%s %s::$%s (%s) does not accept default value of type %s.', $node->isStatic() ? 'Static property' : 'Property', $classReflection->getDisplayName(), $node->getName(), $propertyType->describe($verbosityLevel), $defaultValueType->describe($verbosityLevel)))->identifier('property.defaultValue')->acceptsReasonsTip($accepts->reasons)->build()]; } } */ final class ReadOnlyPropertyRule implements Rule { /** * @var PhpVersion */ private $phpVersion; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function getNodeType() : string { return ClassPropertyNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->isReadOnly()) { return []; } $errors = []; if (!$this->phpVersion->supportsReadOnlyProperties()) { $errors[] = RuleErrorBuilder::message('Readonly properties are supported only on PHP 8.1 and later.')->nonIgnorable()->identifier('property.readOnlyNotSupported')->build(); } if ($node->getNativeType() === null) { $errors[] = RuleErrorBuilder::message('Readonly property must have a native type.')->identifier('property.readOnlyNoNativeType')->nonIgnorable()->build(); } if ($node->getDefault() !== null) { $errors[] = RuleErrorBuilder::message('Readonly property cannot have a default value.')->nonIgnorable()->identifier('property.readOnlyDefaultValue')->build(); } if ($node->isStatic()) { $errors[] = RuleErrorBuilder::message('Readonly property cannot be static.')->nonIgnorable()->identifier('property.readOnlyStatic')->build(); } return $errors; } } */ final class MissingPropertyTypehintRule implements Rule { /** * @var MissingTypehintCheck */ private $missingTypehintCheck; public function __construct(MissingTypehintCheck $missingTypehintCheck) { $this->missingTypehintCheck = $missingTypehintCheck; } public function getNodeType() : string { return ClassPropertyNode::class; } public function processNode(Node $node, Scope $scope) : array { $propertyReflection = $node->getClassReflection()->getNativeProperty($node->getName()); if ($propertyReflection->isPromoted()) { return []; } $propertyType = $propertyReflection->getReadableType(); if ($propertyType instanceof MixedType && !$propertyType->isExplicitMixed()) { return [RuleErrorBuilder::message(sprintf('Property %s::$%s has no type specified.', $propertyReflection->getDeclaringClass()->getDisplayName(), $node->getName()))->identifier('missingType.property')->build()]; } $messages = []; foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($propertyType) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $messages[] = RuleErrorBuilder::message(sprintf('Property %s::$%s type has no value type specified in iterable type %s.', $propertyReflection->getDeclaringClass()->getDisplayName(), $node->getName(), $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($propertyType) as [$name, $genericTypeNames]) { $messages[] = RuleErrorBuilder::message(sprintf('Property %s::$%s with generic %s does not specify its types: %s', $propertyReflection->getDeclaringClass()->getDisplayName(), $node->getName(), $name, $genericTypeNames))->identifier('missingType.generics')->build(); } foreach ($this->missingTypehintCheck->getCallablesWithMissingSignature($propertyType) as $callableType) { $messages[] = RuleErrorBuilder::message(sprintf('Property %s::$%s type has no signature specified for %s.', $propertyReflection->getDeclaringClass()->getDisplayName(), $node->getName(), $callableType->describe(VerbosityLevel::typeOnly())))->identifier('missingType.callable')->build(); } return $messages; } } */ final class AccessStaticPropertiesInAssignRule implements Rule { /** * @var AccessStaticPropertiesRule */ private $accessStaticPropertiesRule; public function __construct(\PHPStan\Rules\Properties\AccessStaticPropertiesRule $accessStaticPropertiesRule) { $this->accessStaticPropertiesRule = $accessStaticPropertiesRule; } public function getNodeType() : string { return PropertyAssignNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->getPropertyFetch() instanceof Node\Expr\StaticPropertyFetch) { return []; } if ($node->isAssignOp()) { return []; } return $this->accessStaticPropertiesRule->processNode($node->getPropertyFetch(), $scope); } } */ final class ReadOnlyByPhpDocPropertyRule implements Rule { public function getNodeType() : string { return ClassPropertyNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!($node->isReadOnlyByPhpDoc() && !$node->isAllowedPrivateMutation()) || $node->isReadOnly()) { return []; } $errors = []; if ($node->getDefault() !== null) { $errors[] = RuleErrorBuilder::message('@readonly property cannot have a default value.')->identifier('property.readOnlyByPhpDocDefaultValue')->build(); } return $errors; } } */ final class ReadOnlyPropertyAssignRule implements Rule { /** * @var PropertyReflectionFinder */ private $propertyReflectionFinder; /** * @var ConstructorsHelper */ private $constructorsHelper; public function __construct(\PHPStan\Rules\Properties\PropertyReflectionFinder $propertyReflectionFinder, ConstructorsHelper $constructorsHelper) { $this->propertyReflectionFinder = $propertyReflectionFinder; $this->constructorsHelper = $constructorsHelper; } public function getNodeType() : string { return PropertyAssignNode::class; } public function processNode(Node $node, Scope $scope) : array { $propertyFetch = $node->getPropertyFetch(); if (!$propertyFetch instanceof Node\Expr\PropertyFetch) { return []; } $errors = []; $reflections = $this->propertyReflectionFinder->findPropertyReflectionsFromNode($propertyFetch, $scope); foreach ($reflections as $propertyReflection) { $nativeReflection = $propertyReflection->getNativeReflection(); if ($nativeReflection === null) { continue; } if (!$scope->canAccessProperty($propertyReflection)) { continue; } if (!$nativeReflection->isReadOnly()) { continue; } $declaringClass = $nativeReflection->getDeclaringClass(); if (!$scope->isInClass()) { $errors[] = RuleErrorBuilder::message(sprintf('Readonly property %s::$%s is assigned outside of its declaring class.', $declaringClass->getDisplayName(), $propertyReflection->getName()))->identifier('property.readOnlyAssignOutOfClass')->build(); continue; } $scopeClassReflection = $scope->getClassReflection(); if ($scopeClassReflection->getName() !== $declaringClass->getName()) { $errors[] = RuleErrorBuilder::message(sprintf('Readonly property %s::$%s is assigned outside of its declaring class.', $declaringClass->getDisplayName(), $propertyReflection->getName()))->identifier('property.readOnlyAssignOutOfClass')->build(); continue; } $scopeMethod = $scope->getFunction(); if (!$scopeMethod instanceof MethodReflection) { throw new ShouldNotHappenException(); } if (in_array($scopeMethod->getName(), $this->constructorsHelper->getConstructors($scopeClassReflection), \true) || strtolower($scopeMethod->getName()) === '__unserialize') { if (TypeUtils::findThisType($scope->getType($propertyFetch->var)) === null) { $errors[] = RuleErrorBuilder::message(sprintf('Readonly property %s::$%s is not assigned on $this.', $declaringClass->getDisplayName(), $propertyReflection->getName()))->identifier('property.readOnlyAssignNotOnThis')->build(); } continue; } $errors[] = RuleErrorBuilder::message(sprintf('Readonly property %s::$%s is assigned outside of the constructor.', $declaringClass->getDisplayName(), $propertyReflection->getName()))->identifier('property.readOnlyAssignNotInConstructor')->build(); } return $errors; } } */ final class AccessPropertiesInAssignRule implements Rule { /** * @var AccessPropertiesRule */ private $accessPropertiesRule; public function __construct(\PHPStan\Rules\Properties\AccessPropertiesRule $accessPropertiesRule) { $this->accessPropertiesRule = $accessPropertiesRule; } public function getNodeType() : string { return PropertyAssignNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->getPropertyFetch() instanceof Node\Expr\PropertyFetch) { return []; } if ($node->isAssignOp()) { return []; } return $this->accessPropertiesRule->processNode($node->getPropertyFetch(), $scope); } } */ final class MissingReadOnlyByPhpDocPropertyAssignRule implements Rule { /** * @var ConstructorsHelper */ private $constructorsHelper; public function __construct(ConstructorsHelper $constructorsHelper) { $this->constructorsHelper = $constructorsHelper; } public function getNodeType() : string { return ClassPropertiesNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); [$properties, $prematureAccess, $additionalAssigns] = $node->getUninitializedProperties($scope, $this->constructorsHelper->getConstructors($classReflection)); $errors = []; foreach ($properties as $propertyName => $propertyNode) { if (!$propertyNode->isReadOnlyByPhpDoc() || $propertyNode->isReadOnly()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Class %s has an uninitialized @readonly property $%s. Assign it in the constructor.', $classReflection->getDisplayName(), $propertyName))->line($propertyNode->getStartLine())->identifier('property.uninitializedReadonlyByPhpDoc')->build(); } foreach ($prematureAccess as [$propertyName, $line, $propertyNode, $file, $fileDescription]) { if (!$propertyNode->isReadOnlyByPhpDoc() || $propertyNode->isReadOnly()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Access to an uninitialized @readonly property %s::$%s.', $classReflection->getDisplayName(), $propertyName))->identifier('property.uninitializedReadonlyByPhpDoc')->line($line)->file($file, $fileDescription)->build(); } foreach ($additionalAssigns as [$propertyName, $line, $propertyNode]) { if (!$propertyNode->isReadOnlyByPhpDoc() || $propertyNode->isReadOnly()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('@readonly property %s::$%s is already assigned.', $classReflection->getDisplayName(), $propertyName))->identifier('assign.readOnlyPropertyByPhpDoc')->line($line)->build(); } return $errors; } } */ final class PropertyAttributesRule implements Rule { /** * @var AttributesCheck */ private $attributesCheck; public function __construct(AttributesCheck $attributesCheck) { $this->attributesCheck = $attributesCheck; } public function getNodeType() : string { return Node\Stmt\Property::class; } public function processNode(Node $node, Scope $scope) : array { return $this->attributesCheck->check($scope, $node->attrGroups, Attribute::TARGET_PROPERTY, 'property'); } } */ final class InvalidCallablePropertyTypeRule implements Rule { public function getNodeType() : string { return ClassPropertyNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); $propertyReflection = $classReflection->getNativeProperty($node->getName()); if (!$propertyReflection->hasNativeType()) { return []; } $nativeType = $propertyReflection->getNativeType(); $callableTypes = []; TypeTraverser::map($nativeType, static function (Type $type, callable $traverse) use(&$callableTypes) : Type { if ($type instanceof UnionType || $type instanceof IntersectionType) { return $traverse($type); } if ($type instanceof CallableType) { $callableTypes[] = $type; } return $type; }); if ($callableTypes === []) { return []; } return [RuleErrorBuilder::message(sprintf('Property %s::$%s cannot have callable in its type declaration.', $classReflection->getDisplayName(), $node->getName()))->identifier('property.callableType')->nonIgnorable()->build()]; } } */ final class OverridingPropertyRule implements Rule { /** * @var bool */ private $checkPhpDocMethodSignatures; /** * @var bool */ private $reportMaybes; public function __construct(bool $checkPhpDocMethodSignatures, bool $reportMaybes) { $this->checkPhpDocMethodSignatures = $checkPhpDocMethodSignatures; $this->reportMaybes = $reportMaybes; } public function getNodeType() : string { return ClassPropertyNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); $prototype = $this->findPrototype($classReflection, $node->getName()); if ($prototype === null) { return []; } $errors = []; if ($prototype->isStatic()) { if (!$node->isStatic()) { $errors[] = RuleErrorBuilder::message(sprintf('Non-static property %s::$%s overrides static property %s::$%s.', $classReflection->getDisplayName(), $node->getName(), $prototype->getDeclaringClass()->getDisplayName(), $node->getName()))->identifier('property.nonStatic')->nonIgnorable()->build(); } } elseif ($node->isStatic()) { $errors[] = RuleErrorBuilder::message(sprintf('Static property %s::$%s overrides non-static property %s::$%s.', $classReflection->getDisplayName(), $node->getName(), $prototype->getDeclaringClass()->getDisplayName(), $node->getName()))->identifier('property.static')->nonIgnorable()->build(); } if ($prototype->isReadOnly()) { if (!$node->isReadOnly()) { $errors[] = RuleErrorBuilder::message(sprintf('Readwrite property %s::$%s overrides readonly property %s::$%s.', $classReflection->getDisplayName(), $node->getName(), $prototype->getDeclaringClass()->getDisplayName(), $node->getName()))->identifier('property.readWrite')->nonIgnorable()->build(); } } elseif ($node->isReadOnly()) { $errors[] = RuleErrorBuilder::message(sprintf('Readonly property %s::$%s overrides readwrite property %s::$%s.', $classReflection->getDisplayName(), $node->getName(), $prototype->getDeclaringClass()->getDisplayName(), $node->getName()))->identifier('property.readOnly')->nonIgnorable()->build(); } if ($prototype->isPublic()) { if (!$node->isPublic()) { $errors[] = RuleErrorBuilder::message(sprintf('%s property %s::$%s overriding public property %s::$%s should also be public.', $node->isPrivate() ? 'Private' : 'Protected', $classReflection->getDisplayName(), $node->getName(), $prototype->getDeclaringClass()->getDisplayName(), $node->getName()))->identifier('property.visibility')->nonIgnorable()->build(); } } elseif ($node->isPrivate()) { $errors[] = RuleErrorBuilder::message(sprintf('Private property %s::$%s overriding protected property %s::$%s should be protected or public.', $classReflection->getDisplayName(), $node->getName(), $prototype->getDeclaringClass()->getDisplayName(), $node->getName()))->identifier('property.visibility')->nonIgnorable()->build(); } $typeErrors = []; if ($prototype->hasNativeType()) { if ($node->getNativeType() === null) { $typeErrors[] = RuleErrorBuilder::message(sprintf('Property %s::$%s overriding property %s::$%s (%s) should also have native type %s.', $classReflection->getDisplayName(), $node->getName(), $prototype->getDeclaringClass()->getDisplayName(), $node->getName(), $prototype->getNativeType()->describe(VerbosityLevel::typeOnly()), $prototype->getNativeType()->describe(VerbosityLevel::typeOnly())))->identifier('property.missingNativeType')->nonIgnorable()->build(); } else { $nativeType = ParserNodeTypeToPHPStanType::resolve($node->getNativeType(), $classReflection); if (!$prototype->getNativeType()->equals($nativeType)) { $typeErrors[] = RuleErrorBuilder::message(sprintf('Type %s of property %s::$%s is not the same as type %s of overridden property %s::$%s.', $nativeType->describe(VerbosityLevel::typeOnly()), $classReflection->getDisplayName(), $node->getName(), $prototype->getNativeType()->describe(VerbosityLevel::typeOnly()), $prototype->getDeclaringClass()->getDisplayName(), $node->getName()))->identifier('property.nativeType')->nonIgnorable()->build(); } } } elseif ($node->getNativeType() !== null) { $typeErrors[] = RuleErrorBuilder::message(sprintf('Property %s::$%s (%s) overriding property %s::$%s should not have a native type.', $classReflection->getDisplayName(), $node->getName(), ParserNodeTypeToPHPStanType::resolve($node->getNativeType(), $classReflection)->describe(VerbosityLevel::typeOnly()), $prototype->getDeclaringClass()->getDisplayName(), $node->getName()))->identifier('property.extraNativeType')->nonIgnorable()->build(); } $errors = array_merge($errors, $typeErrors); if (!$this->checkPhpDocMethodSignatures) { return $errors; } if (count($typeErrors) > 0) { return $errors; } $propertyReflection = $classReflection->getNativeProperty($node->getName()); if ($prototype->getReadableType()->equals($propertyReflection->getReadableType())) { return $errors; } $verbosity = VerbosityLevel::getRecommendedLevelByType($prototype->getReadableType(), $propertyReflection->getReadableType()); $isSuperType = $prototype->getReadableType()->isSuperTypeOf($propertyReflection->getReadableType()); $canBeTurnedOffError = RuleErrorBuilder::message(sprintf('PHPDoc type %s of property %s::$%s is not the same as PHPDoc type %s of overridden property %s::$%s.', $propertyReflection->getReadableType()->describe($verbosity), $classReflection->getDisplayName(), $node->getName(), $prototype->getReadableType()->describe($verbosity), $prototype->getDeclaringClass()->getDisplayName(), $node->getName()))->identifier('property.phpDocType')->tip(sprintf("You can fix 3rd party PHPDoc types with stub files:\n %s\n This error can be turned off by setting\n %s", 'https://phpstan.org/user-guide/stub-files', 'reportMaybesInPropertyPhpDocTypes: false in your %configurationFile%.'))->build(); $cannotBeTurnedOffError = RuleErrorBuilder::message(sprintf('PHPDoc type %s of property %s::$%s is %s PHPDoc type %s of overridden property %s::$%s.', $propertyReflection->getReadableType()->describe($verbosity), $classReflection->getDisplayName(), $node->getName(), $this->reportMaybes ? 'not the same as' : 'not covariant with', $prototype->getReadableType()->describe($verbosity), $prototype->getDeclaringClass()->getDisplayName(), $node->getName()))->identifier('property.phpDocType')->tip(sprintf("You can fix 3rd party PHPDoc types with stub files:\n %s", 'https://phpstan.org/user-guide/stub-files'))->build(); if ($this->reportMaybes) { if (!$isSuperType->yes()) { $errors[] = $cannotBeTurnedOffError; } else { $errors[] = $canBeTurnedOffError; } } else { if (!$isSuperType->yes()) { $errors[] = $cannotBeTurnedOffError; } } return $errors; } private function findPrototype(ClassReflection $classReflection, string $propertyName) : ?PhpPropertyReflection { $parentClass = $classReflection->getParentClass(); if ($parentClass === null) { return null; } if (!$parentClass->hasNativeProperty($propertyName)) { return null; } $property = $parentClass->getNativeProperty($propertyName); if ($property->isPrivate()) { return null; } return $property; } } getType($propertyFetch->var); $declaringClassType = new ObjectType($property->getDeclaringClass()->getName()); if ($declaringClassType->isSuperTypeOf($fetchedOnType)->yes()) { $classDescription = $property->getDeclaringClass()->getDisplayName(); } else { $classDescription = $fetchedOnType->describe(VerbosityLevel::typeOnly()); } } else { $classDescription = $property->getDeclaringClass()->getDisplayName(); } /** @var Node\Identifier $name */ $name = $propertyFetch->name; if (!$property->isStatic()) { return sprintf('Property %s::$%s', $classDescription, $name->name); } return sprintf('Static property %s::$%s', $classDescription, $name->name); } } */ final class PropertiesInInterfaceRule implements Rule { public function getNodeType() : string { return ClassPropertyNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->getClassReflection()->isInterface()) { return []; } return [RuleErrorBuilder::message('Interfaces may not include properties.')->nonIgnorable()->identifier('property.inInterface')->build()]; } } */ final class WritingToReadOnlyPropertiesRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var PropertyDescriptor */ private $propertyDescriptor; /** * @var PropertyReflectionFinder */ private $propertyReflectionFinder; /** * @var bool */ private $checkThisOnly; public function __construct(RuleLevelHelper $ruleLevelHelper, \PHPStan\Rules\Properties\PropertyDescriptor $propertyDescriptor, \PHPStan\Rules\Properties\PropertyReflectionFinder $propertyReflectionFinder, bool $checkThisOnly) { $this->ruleLevelHelper = $ruleLevelHelper; $this->propertyDescriptor = $propertyDescriptor; $this->propertyReflectionFinder = $propertyReflectionFinder; $this->checkThisOnly = $checkThisOnly; } public function getNodeType() : string { return PropertyAssignNode::class; } public function processNode(Node $node, Scope $scope) : array { $propertyFetch = $node->getPropertyFetch(); if ($propertyFetch instanceof Node\Expr\PropertyFetch && $this->checkThisOnly && !$this->ruleLevelHelper->isThis($propertyFetch->var)) { return []; } $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($propertyFetch, $scope); if ($propertyReflection === null) { return []; } if (!$scope->canAccessProperty($propertyReflection)) { return []; } if (!$propertyReflection->isWritable()) { $propertyDescription = $this->propertyDescriptor->describeProperty($propertyReflection, $scope, $propertyFetch); return [RuleErrorBuilder::message(sprintf('%s is not writable.', $propertyDescription))->identifier('assign.propertyReadOnly')->build()]; } return []; } } */ final class AccessStaticPropertiesRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var ClassNameCheck */ private $classCheck; public function __construct(ReflectionProvider $reflectionProvider, RuleLevelHelper $ruleLevelHelper, ClassNameCheck $classCheck) { $this->reflectionProvider = $reflectionProvider; $this->ruleLevelHelper = $ruleLevelHelper; $this->classCheck = $classCheck; } public function getNodeType() : string { return StaticPropertyFetch::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->name instanceof Node\VarLikeIdentifier) { $names = [$node->name->name]; } else { $names = array_map(static function (ConstantStringType $type) : string { return $type->getValue(); }, $scope->getType($node->name)->getConstantStrings()); } $errors = []; foreach ($names as $name) { $errors = array_merge($errors, $this->processSingleProperty($scope, $node, $name)); } return $errors; } /** * @return list */ private function processSingleProperty(Scope $scope, StaticPropertyFetch $node, string $name) : array { $messages = []; if ($node->class instanceof Name) { $class = (string) $node->class; $lowercasedClass = strtolower($class); if (in_array($lowercasedClass, ['self', 'static'], \true)) { if (!$scope->isInClass()) { return [RuleErrorBuilder::message(sprintf('Accessing %s::$%s outside of class scope.', $class, $name))->identifier(sprintf('outOfClass.%s', $lowercasedClass))->build()]; } $classType = $scope->resolveTypeByName($node->class); } elseif ($lowercasedClass === 'parent') { if (!$scope->isInClass()) { return [RuleErrorBuilder::message(sprintf('Accessing %s::$%s outside of class scope.', $class, $name))->identifier('outOfClass.parent')->build()]; } if ($scope->getClassReflection()->getParentClass() === null) { return [RuleErrorBuilder::message(sprintf('%s::%s() accesses parent::$%s but %s does not extend any class.', $scope->getClassReflection()->getDisplayName(), $scope->getFunctionName(), $name, $scope->getClassReflection()->getDisplayName()))->identifier('class.noParent')->build()]; } if ($scope->getFunctionName() === null) { throw new ShouldNotHappenException(); } $currentMethodReflection = $scope->getClassReflection()->getNativeMethod($scope->getFunctionName()); if (!$currentMethodReflection->isStatic()) { // calling parent::method() from instance method return []; } $classType = $scope->resolveTypeByName($node->class); } else { if (!$this->reflectionProvider->hasClass($class)) { if ($scope->isInClassExists($class)) { return []; } return [RuleErrorBuilder::message(sprintf('Access to static property $%s on an unknown class %s.', $name, $class))->discoveringSymbolsTip()->identifier('class.notFound')->build()]; } $messages = $this->classCheck->checkClassNames([new ClassNameNodePair($class, $node->class)]); $classType = $scope->resolveTypeByName($node->class); } } else { $classTypeResult = $this->ruleLevelHelper->findTypeToCheck($scope, NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $node->class), sprintf('Access to static property $%s on an unknown class %%s.', SprintfHelper::escapeFormatString($name)), static function (Type $type) use($name) : bool { return $type->canAccessProperties()->yes() && $type->hasProperty($name)->yes(); }); $classType = $classTypeResult->getType(); if ($classType instanceof ErrorType) { return $classTypeResult->getUnknownClassErrors(); } } if ($classType->isString()->yes()) { return []; } $typeForDescribe = $classType; if ($classType instanceof ThisType) { $typeForDescribe = $classType->getStaticObjectType(); } $classType = TypeCombinator::remove($classType, new StringType()); if ($scope->isInExpressionAssign($node)) { return []; } if ($classType->canAccessProperties()->no() || $classType->canAccessProperties()->maybe() && !$scope->isUndefinedExpressionAllowed($node)) { return array_merge($messages, [RuleErrorBuilder::message(sprintf('Cannot access static property $%s on %s.', $name, $typeForDescribe->describe(VerbosityLevel::typeOnly())))->identifier('staticProperty.nonObject')->build()]); } $has = $classType->hasProperty($name); if (!$has->no() && $scope->isUndefinedExpressionAllowed($node)) { return []; } if (!$has->yes()) { if ($scope->hasExpressionType($node)->yes()) { return $messages; } $classNames = $classType->getObjectClassNames(); if (count($classNames) === 1) { $propertyClassReflection = $this->reflectionProvider->getClass($classNames[0]); $parentClassReflection = $propertyClassReflection->getParentClass(); while ($parentClassReflection !== null) { if ($parentClassReflection->hasProperty($name)) { if ($scope->canAccessProperty($parentClassReflection->getProperty($name, $scope))) { return []; } return [RuleErrorBuilder::message(sprintf('Access to private static property $%s of parent class %s.', $name, $parentClassReflection->getDisplayName()))->identifier('staticProperty.private')->build()]; } $parentClassReflection = $parentClassReflection->getParentClass(); } } return array_merge($messages, [RuleErrorBuilder::message(sprintf('Access to an undefined static property %s::$%s.', $typeForDescribe->describe(VerbosityLevel::typeOnly()), $name))->identifier('staticProperty.notFound')->build()]); } $property = $classType->getProperty($name, $scope); if (!$property->isStatic()) { $hasPropertyTypes = TypeUtils::getHasPropertyTypes($classType); foreach ($hasPropertyTypes as $hasPropertyType) { if ($hasPropertyType->getPropertyName() === $name) { return []; } } return array_merge($messages, [RuleErrorBuilder::message(sprintf('Static access to instance property %s::$%s.', $property->getDeclaringClass()->getDisplayName(), $name))->identifier('property.staticAccess')->build()]); } if (!$scope->canAccessProperty($property)) { return array_merge($messages, [RuleErrorBuilder::message(sprintf('Access to %s property $%s of class %s.', $property->isPrivate() ? 'private' : 'protected', $name, $property->getDeclaringClass()->getDisplayName()))->identifier(sprintf('staticProperty.%s', $property->isPrivate() ? 'private' : 'protected'))->build()]); } return $messages; } } */ final class ReadingWriteOnlyPropertiesRule implements Rule { /** * @var PropertyDescriptor */ private $propertyDescriptor; /** * @var PropertyReflectionFinder */ private $propertyReflectionFinder; /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var bool */ private $checkThisOnly; public function __construct(\PHPStan\Rules\Properties\PropertyDescriptor $propertyDescriptor, \PHPStan\Rules\Properties\PropertyReflectionFinder $propertyReflectionFinder, RuleLevelHelper $ruleLevelHelper, bool $checkThisOnly) { $this->propertyDescriptor = $propertyDescriptor; $this->propertyReflectionFinder = $propertyReflectionFinder; $this->ruleLevelHelper = $ruleLevelHelper; $this->checkThisOnly = $checkThisOnly; } public function getNodeType() : string { return Node\Expr::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof Node\Expr\PropertyFetch && !$node instanceof Node\Expr\StaticPropertyFetch) { return []; } if ($node instanceof Node\Expr\PropertyFetch && $this->checkThisOnly && !$this->ruleLevelHelper->isThis($node->var)) { return []; } if ($scope->isInExpressionAssign($node)) { return []; } $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node, $scope); if ($propertyReflection === null) { return []; } if (!$scope->canAccessProperty($propertyReflection)) { return []; } if (!$propertyReflection->isReadable()) { $propertyDescription = $this->propertyDescriptor->describeProperty($propertyReflection, $scope, $node); return [RuleErrorBuilder::message(sprintf('%s is not readable.', $propertyDescription))->identifier('property.writeOnly')->build()]; } return []; } } extensions = $extensions; } /** * @return ReadWritePropertiesExtension[] */ public function getExtensions() : array { return $this->extensions; } } */ final class ReadOnlyByPhpDocPropertyAssignRefRule implements Rule { /** * @var PropertyReflectionFinder */ private $propertyReflectionFinder; public function __construct(\PHPStan\Rules\Properties\PropertyReflectionFinder $propertyReflectionFinder) { $this->propertyReflectionFinder = $propertyReflectionFinder; } public function getNodeType() : string { return Node\Expr\AssignRef::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->expr instanceof Node\Expr\PropertyFetch && !$node->expr instanceof Node\Expr\StaticPropertyFetch) { return []; } $propertyFetch = $node->expr; $errors = []; $reflections = $this->propertyReflectionFinder->findPropertyReflectionsFromNode($propertyFetch, $scope); foreach ($reflections as $propertyReflection) { $nativeReflection = $propertyReflection->getNativeReflection(); if ($nativeReflection === null) { continue; } if (!$scope->canAccessProperty($propertyReflection)) { continue; } if (!$nativeReflection->isReadOnlyByPhpDoc() || $nativeReflection->isReadOnly()) { continue; } $declaringClass = $nativeReflection->getDeclaringClass(); $errors[] = RuleErrorBuilder::message(sprintf('@readonly property %s::$%s is assigned by reference.', $declaringClass->getDisplayName(), $propertyReflection->getName()))->identifier('property.readOnlyByPhpDocAssignByRef')->build(); } return $errors; } } */ final class AccessPrivatePropertyThroughStaticRule implements Rule { public function getNodeType() : string { return Node\Expr\StaticPropertyFetch::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\VarLikeIdentifier) { return []; } if (!$node->class instanceof Name) { return []; } $propertyName = $node->name->name; $className = $node->class; if ($className->toLowerString() !== 'static') { return []; } $classType = $scope->resolveTypeByName($className); if (!$classType->hasProperty($propertyName)->yes()) { return []; } $property = $classType->getProperty($propertyName, $scope); if (!$property->isPrivate()) { return []; } if (!$property->isStatic()) { return []; } if ($scope->isInClass() && $scope->getClassReflection()->isFinal()) { return []; } return [RuleErrorBuilder::message(sprintf('Unsafe access to private property %s::$%s through static::.', $property->getDeclaringClass()->getDisplayName(), $propertyName))->identifier('staticClassAccess.privateProperty')->build()]; } } classCheck = $classCheck; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; } /** * @param array $extendsTags * @return list */ public function checkExtendsTags(Node $node, array $extendsTags) : array { $errors = []; if (count($extendsTags) > 1) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-extends can only be used once.'))->identifier('requireExtends.duplicate')->build(); } foreach ($extendsTags as $extendsTag) { $type = $extendsTag->getType(); if (!$type instanceof ObjectType) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-extends contains non-object type %s.', $type->describe(VerbosityLevel::typeOnly())))->identifier('requireExtends.nonObject')->build(); continue; } $class = $type->getClassName(); $referencedClassReflection = $type->getClassReflection(); if ($referencedClassReflection === null) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-extends contains unknown class %s.', $class))->discoveringSymbolsTip()->identifier('class.notFound')->build(); continue; } if (!$referencedClassReflection->isClass()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-extends cannot contain non-class type %s.', $class))->identifier(sprintf('requireExtends.%s', strtolower($referencedClassReflection->getClassTypeDescription())))->build(); } elseif ($referencedClassReflection->isFinal()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-extends cannot contain final class %s.', $class))->identifier('requireExtends.finalClass')->build(); } else { $errors = array_merge($errors, $this->classCheck->checkClassNames([new ClassNameNodePair($class, $node)], $this->checkClassCaseSensitivity)); } } return $errors; } } */ final class InvalidPhpDocTagValueRule implements Rule { /** * @var Lexer */ private $phpDocLexer; /** * @var PhpDocParser */ private $phpDocParser; /** * @var bool */ private $checkAllInvalidPhpDocs; /** * @var bool */ private $invalidPhpDocTagLine; public function __construct(Lexer $phpDocLexer, PhpDocParser $phpDocParser, bool $checkAllInvalidPhpDocs, bool $invalidPhpDocTagLine) { $this->phpDocLexer = $phpDocLexer; $this->phpDocParser = $phpDocParser; $this->checkAllInvalidPhpDocs = $checkAllInvalidPhpDocs; $this->invalidPhpDocTagLine = $invalidPhpDocTagLine; } public function getNodeType() : string { return Node::class; } public function processNode(Node $node, Scope $scope) : array { if (!$this->checkAllInvalidPhpDocs) { if (!$node instanceof Node\Stmt\ClassLike && !$node instanceof Node\FunctionLike && !$node instanceof Node\Stmt\Foreach_ && !$node instanceof Node\Stmt\Property && !$node instanceof Node\Expr\Assign && !$node instanceof Node\Expr\AssignRef && !$node instanceof Node\Stmt\ClassConst) { return []; } } else { // mirrored with InvalidPHPStanDocTagRule if ($node instanceof VirtualNode) { return []; } if ($node instanceof Node\Stmt\Expression) { return []; } if ($node instanceof Node\Expr && !$node instanceof Node\Expr\Assign && !$node instanceof Node\Expr\AssignRef) { return []; } } $docComment = $node->getDocComment(); if ($docComment === null) { return []; } $phpDocString = $docComment->getText(); $tokens = new TokenIterator($this->phpDocLexer->tokenize($phpDocString)); $phpDocNode = $this->phpDocParser->parse($tokens); $errors = []; foreach ($phpDocNode->getTags() as $phpDocTag) { if (str_starts_with($phpDocTag->name, '@phan-') || str_starts_with($phpDocTag->name, '@psalm-')) { continue; } if ($phpDocTag->value instanceof TypeAliasTagValueNode) { if (!$phpDocTag->value->type instanceof InvalidTypeNode) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s %s has invalid value: %s', $phpDocTag->name, $phpDocTag->value->alias, $this->trimExceptionMessage($phpDocTag->value->type->getException()->getMessage())))->line(\PHPStan\Rules\PhpDoc\PhpDocLineHelper::detectLine($node, $phpDocTag))->identifier('phpDoc.parseError')->build(); continue; } elseif (!$phpDocTag->value instanceof InvalidTagValueNode) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s has invalid value (%s): %s', $phpDocTag->name, $phpDocTag->value->value, $this->trimExceptionMessage($phpDocTag->value->exception->getMessage())))->line(\PHPStan\Rules\PhpDoc\PhpDocLineHelper::detectLine($node, $phpDocTag))->identifier('phpDoc.parseError')->build(); } return $errors; } private function trimExceptionMessage(string $message) : string { if ($this->invalidPhpDocTagLine) { return $message; } return Strings::replace($message, '~( on line \\d+)$~', ''); } } */ final class IncompatiblePhpDocTypeRule implements Rule { /** * @var FileTypeMapper */ private $fileTypeMapper; /** * @var GenericObjectTypeCheck */ private $genericObjectTypeCheck; /** * @var UnresolvableTypeHelper */ private $unresolvableTypeHelper; /** * @var GenericCallableRuleHelper */ private $genericCallableRuleHelper; public function __construct(FileTypeMapper $fileTypeMapper, GenericObjectTypeCheck $genericObjectTypeCheck, \PHPStan\Rules\PhpDoc\UnresolvableTypeHelper $unresolvableTypeHelper, \PHPStan\Rules\PhpDoc\GenericCallableRuleHelper $genericCallableRuleHelper) { $this->fileTypeMapper = $fileTypeMapper; $this->genericObjectTypeCheck = $genericObjectTypeCheck; $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->genericCallableRuleHelper = $genericCallableRuleHelper; } public function getNodeType() : string { return Node\FunctionLike::class; } public function processNode(Node $node, Scope $scope) : array { if ($node instanceof Node\Stmt\ClassMethod) { $functionName = $node->name->name; } elseif ($node instanceof Node\Stmt\Function_) { $functionName = trim($scope->getNamespace() . '\\' . $node->name->name, '\\'); } else { return []; } $docComment = $node->getDocComment(); if ($docComment === null) { return []; } $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $scope->isInClass() ? $scope->getClassReflection()->getName() : null, $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $functionName, $docComment->getText()); $nativeParameterTypes = $this->getNativeParameterTypes($node, $scope); $byRefParameters = $this->getByRefParameters($node); $errors = []; foreach (['@param' => $resolvedPhpDoc->getParamTags(), '@param-out' => $resolvedPhpDoc->getParamOutTags(), '@param-closure-this' => $resolvedPhpDoc->getParamClosureThisTags()] as $tagName => $parameters) { foreach ($parameters as $parameterName => $phpDocParamTag) { $phpDocParamType = $phpDocParamTag->getType(); if (!isset($nativeParameterTypes[$parameterName])) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s references unknown parameter: $%s', $tagName, $parameterName))->identifier('parameter.notFound')->build(); } elseif ($this->unresolvableTypeHelper->containsUnresolvableType($phpDocParamType)) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for parameter $%s contains unresolvable type.', $tagName, $parameterName))->identifier('parameter.unresolvableType')->build(); } else { $nativeParamType = $nativeParameterTypes[$parameterName]; if ($phpDocParamTag instanceof ParamTag && $phpDocParamTag->isVariadic() && $phpDocParamType->isArray()->yes() && $nativeParamType->isArray()->no()) { $phpDocParamType = $phpDocParamType->getIterableValueType(); } $escapedParameterName = SprintfHelper::escapeFormatString($parameterName); $escapedTagName = SprintfHelper::escapeFormatString($tagName); $errors = array_merge($errors, $this->genericObjectTypeCheck->check($phpDocParamType, sprintf('PHPDoc tag %s for parameter $%s contains generic type %%s but %%s %%s is not generic.', $escapedTagName, $escapedParameterName), sprintf('Generic type %%s in PHPDoc tag %s for parameter $%s does not specify all template types of %%s %%s: %%s', $escapedTagName, $escapedParameterName), sprintf('Generic type %%s in PHPDoc tag %s for parameter $%s specifies %%d template types, but %%s %%s supports only %%d: %%s', $escapedTagName, $escapedParameterName), sprintf('Type %%s in generic type %%s in PHPDoc tag %s for parameter $%s is not subtype of template type %%s of %%s %%s.', $escapedTagName, $escapedParameterName), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag %s for parameter $%s is in conflict with %%s template type %%s of %%s %%s.', $escapedTagName, $escapedParameterName), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag %s for parameter $%s is redundant, template type %%s of %%s %%s has the same variance.', $escapedTagName, $escapedParameterName))); $errors = array_merge($errors, $this->genericCallableRuleHelper->check($node, $scope, sprintf('%s for parameter $%s', $escapedTagName, $escapedParameterName), $phpDocParamType, $functionName, $resolvedPhpDoc->getTemplateTags(), $scope->isInClass() ? $scope->getClassReflection() : null)); if ($phpDocParamTag instanceof ParamOutTag) { if (!$byRefParameters[$parameterName]) { $errors[] = RuleErrorBuilder::message(sprintf('Parameter $%s for PHPDoc tag %s is not passed by reference.', $parameterName, $tagName))->identifier('parameter.notByRef')->build(); } continue; } if (in_array($tagName, ['@param', '@param-out'], \true)) { $isParamSuperType = $nativeParamType->isSuperTypeOf($phpDocParamType); if ($isParamSuperType->no()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for parameter $%s with type %s is incompatible with native type %s.', $tagName, $parameterName, $phpDocParamType->describe(VerbosityLevel::typeOnly()), $nativeParamType->describe(VerbosityLevel::typeOnly())))->identifier('parameter.phpDocType')->build(); } elseif ($isParamSuperType->maybe()) { $errorBuilder = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for parameter $%s with type %s is not subtype of native type %s.', $tagName, $parameterName, $phpDocParamType->describe(VerbosityLevel::typeOnly()), $nativeParamType->describe(VerbosityLevel::typeOnly())))->identifier('parameter.phpDocType'); if ($phpDocParamType instanceof TemplateType) { $errorBuilder->tip(sprintf('Write @template %s of %s to fix this.', $phpDocParamType->getName(), $nativeParamType->describe(VerbosityLevel::typeOnly()))); } $errors[] = $errorBuilder->build(); } } if ($tagName === '@param-closure-this') { $isNonClosure = (new ClosureType())->isSuperTypeOf($nativeParamType)->no(); if ($isNonClosure) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s is for parameter $%s with non-Closure type %s.', $tagName, $parameterName, $nativeParamType->describe(VerbosityLevel::typeOnly())))->identifier('paramClosureThis.nonClosure')->build(); } } } } } if ($resolvedPhpDoc->getReturnTag() !== null) { $phpDocReturnType = $resolvedPhpDoc->getReturnTag()->getType(); if ($this->unresolvableTypeHelper->containsUnresolvableType($phpDocReturnType)) { $errors[] = RuleErrorBuilder::message('PHPDoc tag @return contains unresolvable type.')->identifier('return.unresolvableType')->build(); } else { $nativeReturnType = $this->getNativeReturnType($node, $scope); $isReturnSuperType = $nativeReturnType->isSuperTypeOf($phpDocReturnType); $errors = array_merge($errors, $this->genericObjectTypeCheck->check($phpDocReturnType, 'PHPDoc tag @return contains generic type %s but %s %s is not generic.', 'Generic type %s in PHPDoc tag @return does not specify all template types of %s %s: %s', 'Generic type %s in PHPDoc tag @return specifies %d template types, but %s %s supports only %d: %s', 'Type %s in generic type %s in PHPDoc tag @return is not subtype of template type %s of %s %s.', 'Call-site variance of %s in generic type %s in PHPDoc tag @return is in conflict with %s template type %s of %s %s.', 'Call-site variance of %s in generic type %s in PHPDoc tag @return is redundant, template type %s of %s %s has the same variance.')); if ($isReturnSuperType->no()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @return with type %s is incompatible with native type %s.', $phpDocReturnType->describe(VerbosityLevel::typeOnly()), $nativeReturnType->describe(VerbosityLevel::typeOnly())))->identifier('return.phpDocType')->build(); } elseif ($isReturnSuperType->maybe()) { $errorBuilder = RuleErrorBuilder::message(sprintf('PHPDoc tag @return with type %s is not subtype of native type %s.', $phpDocReturnType->describe(VerbosityLevel::typeOnly()), $nativeReturnType->describe(VerbosityLevel::typeOnly())))->identifier('return.phpDocType'); if ($phpDocReturnType instanceof TemplateType) { $errorBuilder->tip(sprintf('Write @template %s of %s to fix this.', $phpDocReturnType->getName(), $nativeReturnType->describe(VerbosityLevel::typeOnly()))); } $errors[] = $errorBuilder->build(); } $errors = array_merge($errors, $this->genericCallableRuleHelper->check($node, $scope, '@return', $phpDocReturnType, $functionName, $resolvedPhpDoc->getTemplateTags(), $scope->isInClass() ? $scope->getClassReflection() : null)); } } return $errors; } /** * @return Type[] */ private function getNativeParameterTypes(Node\FunctionLike $node, Scope $scope) : array { $nativeParameterTypes = []; foreach ($node->getParams() as $parameter) { $isNullable = $scope->isParameterValueNullable($parameter); if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { throw new ShouldNotHappenException(); } $nativeParameterTypes[$parameter->var->name] = $scope->getFunctionType($parameter->type, $isNullable, \false); } return $nativeParameterTypes; } /** * @return array */ private function getByRefParameters(Node\FunctionLike $node) : array { $nativeParameterTypes = []; foreach ($node->getParams() as $parameter) { if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { throw new ShouldNotHappenException(); } $nativeParameterTypes[$parameter->var->name] = $parameter->byRef; } return $nativeParameterTypes; } private function getNativeReturnType(Node\FunctionLike $node, Scope $scope) : Type { return $scope->getFunctionType($node->getReturnType(), \false, \false); } } */ final class RequireImplementsDefinitionTraitRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var ClassNameCheck */ private $classCheck; /** * @var bool */ private $checkClassCaseSensitivity; public function __construct(ReflectionProvider $reflectionProvider, ClassNameCheck $classCheck, bool $checkClassCaseSensitivity) { $this->reflectionProvider = $reflectionProvider; $this->classCheck = $classCheck; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; } public function getNodeType() : string { return Node\Stmt\Trait_::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->namespacedName === null || !$this->reflectionProvider->hasClass($node->namespacedName->toString())) { return []; } $traitReflection = $this->reflectionProvider->getClass($node->namespacedName->toString()); $implementsTags = $traitReflection->getRequireImplementsTags(); $errors = []; foreach ($implementsTags as $implementsTag) { $type = $implementsTag->getType(); if (!$type instanceof ObjectType) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-implements contains non-object type %s.', $type->describe(VerbosityLevel::typeOnly())))->identifier('requireImplements.nonObject')->build(); continue; } $class = $type->getClassName(); $referencedClassReflection = $type->getClassReflection(); if ($referencedClassReflection === null) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-implements contains unknown class %s.', $class))->discoveringSymbolsTip()->identifier('class.notFound')->build(); continue; } if (!$referencedClassReflection->isInterface()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-implements cannot contain non-interface type %s.', $class))->identifier(sprintf('requireImplements.%s', strtolower($referencedClassReflection->getClassTypeDescription())))->build(); } else { $errors = array_merge($errors, $this->classCheck->checkClassNames([new ClassNameNodePair($class, $node)], $this->checkClassCaseSensitivity)); } } return $errors; } } */ final class IncompatibleClassConstantPhpDocTypeRule implements Rule { /** * @var GenericObjectTypeCheck */ private $genericObjectTypeCheck; /** * @var UnresolvableTypeHelper */ private $unresolvableTypeHelper; public function __construct(GenericObjectTypeCheck $genericObjectTypeCheck, \PHPStan\Rules\PhpDoc\UnresolvableTypeHelper $unresolvableTypeHelper) { $this->genericObjectTypeCheck = $genericObjectTypeCheck; $this->unresolvableTypeHelper = $unresolvableTypeHelper; } public function getNodeType() : string { return Node\Stmt\ClassConst::class; } public function processNode(Node $node, Scope $scope) : array { if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } $nativeType = null; if ($node->type !== null) { $nativeType = ParserNodeTypeToPHPStanType::resolve($node->type, $scope->getClassReflection()); } $errors = []; foreach ($node->consts as $const) { $constantName = $const->name->toString(); $errors = array_merge($errors, $this->processSingleConstant($scope->getClassReflection(), $nativeType, $constantName)); } return $errors; } /** * @return list */ private function processSingleConstant(ClassReflection $classReflection, ?Type $nativeType, string $constantName) : array { $constantReflection = $classReflection->getConstant($constantName); $phpDocType = $constantReflection->getPhpDocType(); if ($phpDocType === null) { return []; } $errors = []; if ($this->unresolvableTypeHelper->containsUnresolvableType($phpDocType)) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @var for constant %s::%s contains unresolvable type.', $constantReflection->getDeclaringClass()->getName(), $constantName))->identifier('classConstant.unresolvableType')->build(); } elseif ($nativeType !== null) { $isSuperType = $nativeType->isSuperTypeOf($phpDocType); if ($isSuperType->no()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @var for constant %s::%s with type %s is incompatible with native type %s.', $constantReflection->getDeclaringClass()->getDisplayName(), $constantName, $phpDocType->describe(VerbosityLevel::typeOnly()), $nativeType->describe(VerbosityLevel::typeOnly())))->identifier('classConstant.phpDocType')->build(); } elseif ($isSuperType->maybe()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @var for constant %s::%s with type %s is not subtype of native type %s.', $constantReflection->getDeclaringClass()->getDisplayName(), $constantName, $phpDocType->describe(VerbosityLevel::typeOnly()), $nativeType->describe(VerbosityLevel::typeOnly())))->identifier('classConstant.phpDocType')->build(); } } $className = SprintfHelper::escapeFormatString($constantReflection->getDeclaringClass()->getDisplayName()); $escapedConstantName = SprintfHelper::escapeFormatString($constantName); return array_merge($errors, $this->genericObjectTypeCheck->check($phpDocType, sprintf('PHPDoc tag @var for constant %s::%s contains generic type %%s but %%s %%s is not generic.', $className, $escapedConstantName), sprintf('Generic type %%s in PHPDoc tag @var for constant %s::%s does not specify all template types of %%s %%s: %%s', $className, $escapedConstantName), sprintf('Generic type %%s in PHPDoc tag @var for constant %s::%s specifies %%d template types, but %%s %%s supports only %%d: %%s', $className, $escapedConstantName), sprintf('Type %%s in generic type %%s in PHPDoc tag @var for constant %s::%s is not subtype of template type %%s of %%s %%s.', $className, $escapedConstantName), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag @var for constant %s::%s is in conflict with %%s template type %%s of %%s %%s.', $className, $escapedConstantName), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag @var for constant %s::%s is redundant, template type %%s of %%s %%s has the same variance.', $className, $escapedConstantName))); } } */ final class FunctionConditionalReturnTypeRule implements Rule { /** * @var ConditionalReturnTypeRuleHelper */ private $helper; public function __construct(\PHPStan\Rules\PhpDoc\ConditionalReturnTypeRuleHelper $helper) { $this->helper = $helper; } public function getNodeType() : string { return InFunctionNode::class; } public function processNode(Node $node, Scope $scope) : array { $function = $node->getFunctionReflection(); $variants = $function->getVariants(); if (count($variants) !== 1) { return []; } return $this->helper->check($variants[0]); } } */ final class RequireImplementsDefinitionClassRule implements Rule { public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); $implementsTags = $classReflection->getRequireImplementsTags(); if (count($implementsTags) === 0) { return []; } return [RuleErrorBuilder::message('PHPDoc tag @phpstan-require-implements is only valid on trait.')->identifier(sprintf('requireImplements.on%s', $classReflection->getClassTypeDescription()))->build()]; } } typeNodeResolver = $typeNodeResolver; $this->fileTypeMapper = $fileTypeMapper; $this->checkTypeAgainstPhpDocType = $checkTypeAgainstPhpDocType; $this->strictWideningCheck = $strictWideningCheck; } /** * @param VarTag[] $varTags * @param string[] $assignedVariables * @return list */ public function checkVarType(Scope $scope, Node\Expr $var, Node\Expr $expr, array $varTags, array $assignedVariables) : array { $errors = []; if ($var instanceof Expr\Variable && is_string($var->name)) { if (array_key_exists($var->name, $varTags)) { $varTagType = $varTags[$var->name]->getType(); } elseif (count($assignedVariables) === 1 && array_key_exists(0, $varTags)) { $varTagType = $varTags[0]->getType(); } else { return []; } return $this->checkExprType($scope, $expr, $varTagType); } elseif ($var instanceof Expr\List_ || $var instanceof Expr\Array_) { foreach ($var->items as $i => $arrayItem) { if ($arrayItem === null) { continue; } if ($arrayItem->key === null) { $dimExpr = new Node\Scalar\LNumber($i); } else { $dimExpr = $arrayItem->key; } $itemErrors = $this->checkVarType($scope, $arrayItem->value, new GetOffsetValueTypeExpr($expr, $dimExpr), $varTags, $assignedVariables); foreach ($itemErrors as $error) { $errors[] = $error; } } } return $errors; } /** * @return list */ public function checkExprType(Scope $scope, Node\Expr $expr, Type $varTagType) : array { $errors = []; $exprNativeType = $scope->getNativeType($expr); $containsPhpStanType = $this->containsPhpStanType($varTagType); if ($this->shouldVarTagTypeBeReported($scope, $expr, $exprNativeType, $varTagType)) { $verbosity = VerbosityLevel::getRecommendedLevelByType($exprNativeType, $varTagType); $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @var with type %s is not subtype of native type %s.', $varTagType->describe($verbosity), $exprNativeType->describe($verbosity)))->identifier('varTag.nativeType')->build(); } else { $exprType = $scope->getType($expr); if ($this->shouldVarTagTypeBeReported($scope, $expr, $exprType, $varTagType) && ($this->checkTypeAgainstPhpDocType || $containsPhpStanType)) { $verbosity = VerbosityLevel::getRecommendedLevelByType($exprType, $varTagType); $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @var with type %s is not subtype of type %s.', $varTagType->describe($verbosity), $exprType->describe($verbosity)))->identifier('varTag.type')->build(); } } if (count($errors) === 0 && $containsPhpStanType) { $exprType = $scope->getType($expr); if (!$exprType->equals($varTagType)) { $verbosity = VerbosityLevel::getRecommendedLevelByType($exprType, $varTagType); $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @var assumes the expression with type %s is always %s but it\'s error-prone and dangerous.', $exprType->describe($verbosity), $varTagType->describe($verbosity)))->identifier('phpstanApi.varTagAssumption')->build(); } } return $errors; } private function containsPhpStanType(Type $type) : bool { $classReflections = TypeUtils::toBenevolentUnion($type)->getObjectClassReflections(); foreach ($classReflections as $classReflection) { if (!$classReflection->isSubclassOf(Type::class)) { continue; } return \true; } return \false; } private function shouldVarTagTypeBeReported(Scope $scope, Node\Expr $expr, Type $type, Type $varTagType) : bool { if ($expr instanceof Expr\Array_) { if ($expr->items === []) { $type = new ArrayType(new MixedType(), new MixedType()); } return !$this->isAtLeastMaybeSuperTypeOfVarType($scope, $type, $varTagType); } if ($expr instanceof Expr\ConstFetch) { return !$this->isAtLeastMaybeSuperTypeOfVarType($scope, $type, $varTagType); } if ($expr instanceof Node\Scalar) { return !$this->isAtLeastMaybeSuperTypeOfVarType($scope, $type, $varTagType); } if ($expr instanceof Expr\New_) { if ($type instanceof GenericObjectType) { $type = new ObjectType($type->getClassName()); } } return $this->checkType($scope, $type, $varTagType); } private function checkType(Scope $scope, Type $type, Type $varTagType, int $depth = 0) : bool { if ($this->strictWideningCheck) { return !$this->isSuperTypeOfVarType($scope, $type, $varTagType); } if ($type->isConstantArray()->yes()) { if ($type->isIterableAtLeastOnce()->no()) { $type = new ArrayType(new MixedType(), new MixedType()); return !$this->isAtLeastMaybeSuperTypeOfVarType($scope, $type, $varTagType); } } if ($type->isIterable()->yes() && $varTagType->isIterable()->yes()) { if (!$this->isAtLeastMaybeSuperTypeOfVarType($scope, $type, $varTagType)) { return \true; } $innerType = $type->getIterableValueType(); $innerVarTagType = $varTagType->getIterableValueType(); if ($type->equals($innerType) || $varTagType->equals($innerVarTagType)) { return !$this->isSuperTypeOfVarType($scope, $innerType, $innerVarTagType); } return $this->checkType($scope, $innerType, $innerVarTagType, $depth + 1); } if ($depth === 0 && $type->isConstantValue()->yes()) { return !$this->isAtLeastMaybeSuperTypeOfVarType($scope, $type, $varTagType); } return !$this->isSuperTypeOfVarType($scope, $type, $varTagType); } private function isSuperTypeOfVarType(Scope $scope, Type $type, Type $varTagType) : bool { if ($type->isSuperTypeOf($varTagType)->yes()) { return \true; } try { $type = $this->typeNodeResolver->resolve($type->toPhpDocNode(), $this->createNameScope($scope)); } catch (NameScopeAlreadyBeingCreatedException $e) { return \true; } return $type->isSuperTypeOf($varTagType)->yes(); } private function isAtLeastMaybeSuperTypeOfVarType(Scope $scope, Type $type, Type $varTagType) : bool { if (!$type->isSuperTypeOf($varTagType)->no()) { return \true; } try { $type = $this->typeNodeResolver->resolve($type->toPhpDocNode(), $this->createNameScope($scope)); } catch (NameScopeAlreadyBeingCreatedException $e) { return \true; } return !$type->isSuperTypeOf($varTagType)->no(); } /** * @throws NameScopeAlreadyBeingCreatedException */ private function createNameScope(Scope $scope) : NameScope { $function = $scope->getFunction(); return $this->fileTypeMapper->getNameScope($scope->getFile(), $scope->isInClass() ? $scope->getClassReflection()->getName() : null, $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $function !== null ? $function->getName() : null)->withoutNamespaceAndUses(); } } */ public function check(ParametersAcceptorWithPhpDocs $acceptor) : array { $conditionalTypes = []; $parametersByName = []; foreach ($acceptor->getParameters() as $parameter) { TypeTraverser::map($parameter->getType(), static function (Type $type, callable $traverse) use(&$conditionalTypes) : Type { if ($type instanceof ConditionalType || $type instanceof ConditionalTypeForParameter) { $conditionalTypes[] = $type; } return $traverse($type); }); if ($parameter->getOutType() !== null) { TypeTraverser::map($parameter->getOutType(), static function (Type $type, callable $traverse) use(&$conditionalTypes) : Type { if ($type instanceof ConditionalType || $type instanceof ConditionalTypeForParameter) { $conditionalTypes[] = $type; } return $traverse($type); }); } if ($parameter->getClosureThisType() !== null) { TypeTraverser::map($parameter->getClosureThisType(), static function (Type $type, callable $traverse) use(&$conditionalTypes) : Type { if ($type instanceof ConditionalType || $type instanceof ConditionalTypeForParameter) { $conditionalTypes[] = $type; } return $traverse($type); }); } $parametersByName[$parameter->getName()] = $parameter; } TypeTraverser::map($acceptor->getReturnType(), static function (Type $type, callable $traverse) use(&$conditionalTypes) : Type { if ($type instanceof ConditionalType || $type instanceof ConditionalTypeForParameter) { $conditionalTypes[] = $type; } return $traverse($type); }); $errors = []; foreach ($conditionalTypes as $conditionalType) { if ($conditionalType instanceof ConditionalType) { $subjectType = $conditionalType->getSubject(); if ($subjectType instanceof StaticType) { continue; } $templateTypes = []; TypeTraverser::map($subjectType, static function (Type $type, callable $traverse) use(&$templateTypes) : Type { if ($type instanceof TemplateType) { $templateTypes[] = $type; return $type; } return $traverse($type); }); if (count($templateTypes) === 0) { $errors[] = RuleErrorBuilder::message(sprintf('Conditional return type uses subject type %s which is not part of PHPDoc @template tags.', $subjectType->describe(VerbosityLevel::typeOnly())))->identifier('conditionalType.subjectNotFound')->build(); continue; } } else { $parameterName = substr($conditionalType->getParameterName(), 1); if (!array_key_exists($parameterName, $parametersByName)) { $errors[] = RuleErrorBuilder::message(sprintf('Conditional return type references unknown parameter $%s.', $parameterName))->identifier('parameter.notFound')->build(); continue; } $subjectType = $parametersByName[$parameterName]->getType(); } $targetType = $conditionalType->getTarget(); $isTargetSuperType = $targetType->isSuperTypeOf($subjectType); if ($isTargetSuperType->maybe()) { continue; } $verbosity = VerbosityLevel::getRecommendedLevelByType($subjectType, $targetType); $errors[] = RuleErrorBuilder::message(sprintf('Condition "%s" in conditional return type is always %s.', sprintf('%s %s %s', $subjectType->describe($verbosity), $conditionalType->isNegated() ? 'is not' : 'is', $targetType->describe($verbosity)), $conditionalType->isNegated() ? $isTargetSuperType->yes() ? 'false' : 'true' : ($isTargetSuperType->yes() ? 'true' : 'false')))->identifier(sprintf('conditionalType.always%s', $conditionalType->isNegated() ? $isTargetSuperType->yes() ? 'False' : 'True' : ($isTargetSuperType->yes() ? 'True' : 'False')))->build(); } return $errors; } } */ final class RequireExtendsDefinitionTraitRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var RequireExtendsCheck */ private $requireExtendsCheck; public function __construct(ReflectionProvider $reflectionProvider, \PHPStan\Rules\PhpDoc\RequireExtendsCheck $requireExtendsCheck) { $this->reflectionProvider = $reflectionProvider; $this->requireExtendsCheck = $requireExtendsCheck; } public function getNodeType() : string { return Node\Stmt\Trait_::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->namespacedName === null || !$this->reflectionProvider->hasClass($node->namespacedName->toString())) { return []; } $traitReflection = $this->reflectionProvider->getClass($node->namespacedName->toString()); $extendsTags = $traitReflection->getRequireExtendsTags(); return $this->requireExtendsCheck->checkExtendsTags($node, $extendsTags); } } templateTypeCheck = $templateTypeCheck; } /** * @param array $functionTemplateTags * * @return list */ public function check(Node $node, Scope $scope, string $location, Type $callableType, ?string $functionName, array $functionTemplateTags, ?ClassReflection $classReflection) : array { $errors = []; TypeTraverser::map($callableType, function (Type $type, callable $traverse) use(&$errors, $node, $scope, $location, $functionName, $functionTemplateTags, $classReflection) { if (!($type instanceof CallableType || $type instanceof ClosureType)) { return $traverse($type); } $typeDescription = $type->describe(VerbosityLevel::precise()); $errors = $this->templateTypeCheck->check($scope, $node, TemplateTypeScope::createWithAnonymousFunction(), $type->getTemplateTags(), sprintf('PHPDoc tag %s template of %s cannot have existing class %%s as its name.', $location, $typeDescription), sprintf('PHPDoc tag %s template of %s cannot have existing type alias %%s as its name.', $location, $typeDescription), sprintf('PHPDoc tag %s template %%s of %s has invalid bound type %%s.', $location, $typeDescription), sprintf('PHPDoc tag %s template %%s of %s with bound type %%s is not supported.', $location, $typeDescription), sprintf('PHPDoc tag %s template %%s of %s has invalid default type %%s.', $location, $typeDescription), sprintf('Default type %%s in PHPDoc tag %s template %%s of %s is not subtype of bound type %%s.', $location, $typeDescription), sprintf('PHPDoc tag %s template %%s of %s does not have a default type but follows an optional template %%s.', $location, $typeDescription)); $templateTags = $type->getTemplateTags(); $classDescription = null; if ($classReflection !== null) { $classDescription = $classReflection->getDisplayName(); } if ($functionName !== null) { $functionDescription = sprintf('function %s', $functionName); if ($classReflection !== null) { $functionDescription = sprintf('method %s::%s', $classDescription, $functionName); } foreach (array_keys($functionTemplateTags) as $name) { if (!isset($templateTags[$name])) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s template %s of %s shadows @template %s for %s.', $location, $name, $typeDescription, $name, $functionDescription))->identifier('callable.shadowTemplate')->build(); } } if ($classReflection !== null) { foreach (array_keys($classReflection->getTemplateTags()) as $name) { if (!isset($templateTags[$name])) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s template %s of %s shadows @template %s for class %s.', $location, $name, $typeDescription, $name, $classDescription))->identifier('callable.shadowTemplate')->build(); } } return $traverse($type); }); return $errors; } } */ final class InvalidPHPStanDocTagRule implements Rule { /** * @var Lexer */ private $phpDocLexer; /** * @var PhpDocParser */ private $phpDocParser; /** * @var bool */ private $checkAllInvalidPhpDocs; private const POSSIBLE_PHPSTAN_TAGS = ['@phpstan-param', '@phpstan-param-out', '@phpstan-var', '@phpstan-extends', '@phpstan-implements', '@phpstan-use', '@phpstan-template', '@phpstan-template-contravariant', '@phpstan-template-covariant', '@phpstan-return', '@phpstan-throws', '@phpstan-ignore', '@phpstan-ignore-next-line', '@phpstan-ignore-line', '@phpstan-method', '@phpstan-pure', '@phpstan-impure', '@phpstan-immutable', '@phpstan-type', '@phpstan-import-type', '@phpstan-property', '@phpstan-property-read', '@phpstan-property-write', '@phpstan-consistent-constructor', '@phpstan-assert', '@phpstan-assert-if-true', '@phpstan-assert-if-false', '@phpstan-self-out', '@phpstan-this-out', '@phpstan-allow-private-mutation', '@phpstan-readonly', '@phpstan-readonly-allow-private-mutation', '@phpstan-require-extends', '@phpstan-require-implements', '@phpstan-param-immediately-invoked-callable', '@phpstan-param-later-invoked-callable', '@phpstan-param-closure-this']; public function __construct(Lexer $phpDocLexer, PhpDocParser $phpDocParser, bool $checkAllInvalidPhpDocs) { $this->phpDocLexer = $phpDocLexer; $this->phpDocParser = $phpDocParser; $this->checkAllInvalidPhpDocs = $checkAllInvalidPhpDocs; } public function getNodeType() : string { return Node::class; } public function processNode(Node $node, Scope $scope) : array { if (!$this->checkAllInvalidPhpDocs) { if (!$node instanceof Node\Stmt\ClassLike && !$node instanceof Node\FunctionLike && !$node instanceof Node\Stmt\Foreach_ && !$node instanceof Node\Stmt\Property && !$node instanceof Node\Expr\Assign && !$node instanceof Node\Expr\AssignRef && !$node instanceof Node\Stmt\ClassConst) { return []; } } else { // mirrored with InvalidPhpDocTagValueRule if ($node instanceof VirtualNode) { return []; } if ($node instanceof Node\Stmt\Expression) { return []; } if ($node instanceof Node\Expr && !$node instanceof Node\Expr\Assign && !$node instanceof Node\Expr\AssignRef) { return []; } } $docComment = $node->getDocComment(); if ($docComment === null) { return []; } $phpDocString = $docComment->getText(); $tokens = new TokenIterator($this->phpDocLexer->tokenize($phpDocString)); $phpDocNode = $this->phpDocParser->parse($tokens); $errors = []; foreach ($phpDocNode->getTags() as $phpDocTag) { if (!str_starts_with($phpDocTag->name, '@phpstan-') || in_array($phpDocTag->name, self::POSSIBLE_PHPSTAN_TAGS, \true)) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Unknown PHPDoc tag: %s', $phpDocTag->name))->line(\PHPStan\Rules\PhpDoc\PhpDocLineHelper::detectLine($node, $phpDocTag))->identifier('phpDoc.phpstanTag')->build(); } return $errors; } } */ final class RequireExtendsDefinitionClassRule implements Rule { /** * @var RequireExtendsCheck */ private $requireExtendsCheck; public function __construct(\PHPStan\Rules\PhpDoc\RequireExtendsCheck $requireExtendsCheck) { $this->requireExtendsCheck = $requireExtendsCheck; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); $extendsTags = $classReflection->getRequireExtendsTags(); if (count($extendsTags) === 0) { return []; } if (!$classReflection->isInterface()) { return [RuleErrorBuilder::message('PHPDoc tag @phpstan-require-extends is only valid on trait or interface.')->identifier(sprintf('requireExtends.on%s', $classReflection->getClassTypeDescription()))->build()]; } return $this->requireExtendsCheck->checkExtendsTags($node, $extendsTags); } } */ final class InvalidThrowsPhpDocValueRule implements Rule { /** * @var FileTypeMapper */ private $fileTypeMapper; public function __construct(FileTypeMapper $fileTypeMapper) { $this->fileTypeMapper = $fileTypeMapper; } public function getNodeType() : string { return Node\Stmt::class; } public function processNode(Node $node, Scope $scope) : array { if ($node instanceof Node\Stmt\Function_ || $node instanceof Node\Stmt\ClassMethod) { return []; // is handled by virtual nodes } $docComment = $node->getDocComment(); if ($docComment === null) { return []; } $functionName = null; if ($scope->getFunction() !== null) { $functionName = $scope->getFunction()->getName(); } $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $scope->isInClass() ? $scope->getClassReflection()->getName() : null, $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $functionName, $docComment->getText()); if ($resolvedPhpDoc->getThrowsTag() === null) { return []; } $phpDocThrowsType = $resolvedPhpDoc->getThrowsTag()->getType(); if ($phpDocThrowsType->isVoid()->yes()) { return []; } if ($this->isThrowsValid($phpDocThrowsType)) { return []; } return [RuleErrorBuilder::message(sprintf('PHPDoc tag @throws with type %s is not subtype of Throwable', $phpDocThrowsType->describe(VerbosityLevel::typeOnly())))->identifier('throws.notThrowable')->build()]; } private function isThrowsValid(Type $phpDocThrowsType) : bool { $throwType = new ObjectType(Throwable::class); if ($phpDocThrowsType instanceof UnionType) { foreach ($phpDocThrowsType->getTypes() as $innerType) { if (!$this->isThrowsValid($innerType)) { return \false; } } return \true; } $toIntersectWith = []; foreach ($phpDocThrowsType->getObjectClassReflections() as $classReflection) { if (!$classReflection->isInterface()) { continue; } foreach ($classReflection->getRequireExtendsTags() as $requireExtendsTag) { $toIntersectWith[] = $requireExtendsTag->getType(); } } return $throwType->isSuperTypeOf(TypeCombinator::intersect($phpDocThrowsType, ...$toIntersectWith))->yes(); } } isExplicit()) { $containsUnresolvable = \true; return $type; } return $traverse($type); }); return $containsUnresolvable; } } getAttribute('startLine'); $phpDoc = $node->getDocComment(); if ($phpDocTagLine === null || $phpDoc === null) { return $node->getLine(); } return $phpDoc->getStartLine() + $phpDocTagLine - 1; } } */ final class VarTagChangedExpressionTypeRule implements Rule { /** * @var VarTagTypeRuleHelper */ private $varTagTypeRuleHelper; public function __construct(\PHPStan\Rules\PhpDoc\VarTagTypeRuleHelper $varTagTypeRuleHelper) { $this->varTagTypeRuleHelper = $varTagTypeRuleHelper; } public function getNodeType() : string { return VarTagChangedExpressionTypeNode::class; } public function processNode(Node $node, Scope $scope) : array { return $this->varTagTypeRuleHelper->checkExprType($scope, $node->getExpr(), $node->getVarTag()->getType()); } } */ final class IncompatibleSelfOutTypeRule implements Rule { /** * @var UnresolvableTypeHelper */ private $unresolvableTypeHelper; /** * @var GenericObjectTypeCheck */ private $genericObjectTypeCheck; public function __construct(\PHPStan\Rules\PhpDoc\UnresolvableTypeHelper $unresolvableTypeHelper, GenericObjectTypeCheck $genericObjectTypeCheck) { $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->genericObjectTypeCheck = $genericObjectTypeCheck; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); $selfOutType = $method->getSelfOutType(); if ($selfOutType === null) { return []; } $classReflection = $method->getDeclaringClass(); $classType = new ObjectType($classReflection->getName(), null, $classReflection); $errors = []; if (!$classType->isSuperTypeOf($selfOutType)->yes()) { $errors[] = RuleErrorBuilder::message(sprintf('Self-out type %s of method %s::%s is not subtype of %s.', $selfOutType->describe(VerbosityLevel::precise()), $classReflection->getDisplayName(), $method->getName(), $classType->describe(VerbosityLevel::precise())))->identifier('selfOut.type')->build(); } if ($method->isStatic()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-self-out is not supported above static method %s::%s().', $classReflection->getName(), $method->getName()))->identifier('selfOut.static')->build(); } if ($this->unresolvableTypeHelper->containsUnresolvableType($selfOutType)) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-self-out for method %s::%s() contains unresolvable type.', $classReflection->getDisplayName(), $method->getName()))->identifier('selfOut.unresolvableType')->build(); } $escapedTagName = SprintfHelper::escapeFormatString('@phpstan-self-out'); return array_merge($errors, $this->genericObjectTypeCheck->check($selfOutType, sprintf('PHPDoc tag %s contains generic type %%s but %%s %%s is not generic.', $escapedTagName), sprintf('Generic type %%s in PHPDoc tag %s does not specify all template types of %%s %%s: %%s', $escapedTagName), sprintf('Generic type %%s in PHPDoc tag %s specifies %%d template types, but %%s %%s supports only %%d: %%s', $escapedTagName), sprintf('Type %%s in generic type %%s in PHPDoc tag %s is not subtype of template type %%s of %%s %%s.', $escapedTagName), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag %s is in conflict with %%s template type %%s of %%s %%s.', $escapedTagName), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag %s is redundant, template type %%s of %%s %%s has the same variance.', $escapedTagName))); } } */ final class FunctionAssertRule implements Rule { /** * @var AssertRuleHelper */ private $helper; public function __construct(\PHPStan\Rules\PhpDoc\AssertRuleHelper $helper) { $this->helper = $helper; } public function getNodeType() : string { return InFunctionNode::class; } public function processNode(Node $node, Scope $scope) : array { $function = $node->getFunctionReflection(); $variants = $function->getVariants(); if (count($variants) !== 1) { return []; } return $this->helper->check($node->getOriginalNode(), $function, $variants[0]); } } */ final class InvalidPhpDocVarTagTypeRule implements Rule { /** * @var FileTypeMapper */ private $fileTypeMapper; /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var ClassNameCheck */ private $classCheck; /** * @var GenericObjectTypeCheck */ private $genericObjectTypeCheck; /** * @var MissingTypehintCheck */ private $missingTypehintCheck; /** * @var UnresolvableTypeHelper */ private $unresolvableTypeHelper; /** * @var bool */ private $checkClassCaseSensitivity; /** * @var bool */ private $checkMissingVarTagTypehint; public function __construct(FileTypeMapper $fileTypeMapper, ReflectionProvider $reflectionProvider, ClassNameCheck $classCheck, GenericObjectTypeCheck $genericObjectTypeCheck, MissingTypehintCheck $missingTypehintCheck, \PHPStan\Rules\PhpDoc\UnresolvableTypeHelper $unresolvableTypeHelper, bool $checkClassCaseSensitivity, bool $checkMissingVarTagTypehint) { $this->fileTypeMapper = $fileTypeMapper; $this->reflectionProvider = $reflectionProvider; $this->classCheck = $classCheck; $this->genericObjectTypeCheck = $genericObjectTypeCheck; $this->missingTypehintCheck = $missingTypehintCheck; $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; $this->checkMissingVarTagTypehint = $checkMissingVarTagTypehint; } public function getNodeType() : string { return Node\Stmt::class; } public function processNode(Node $node, Scope $scope) : array { if ($node instanceof Node\Stmt\Property || $node instanceof Node\Stmt\PropertyProperty || $node instanceof Node\Stmt\ClassConst || $node instanceof Node\Stmt\Const_) { return []; } $docComment = $node->getDocComment(); if ($docComment === null) { return []; } $function = $scope->getFunction(); $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $scope->isInClass() ? $scope->getClassReflection()->getName() : null, $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $function !== null ? $function->getName() : null, $docComment->getText()); $errors = []; foreach ($resolvedPhpDoc->getVarTags() as $name => $varTag) { $varTagType = $varTag->getType(); $identifier = 'PHPDoc tag @var'; if (is_string($name)) { $identifier .= sprintf(' for variable $%s', $name); } if ($this->unresolvableTypeHelper->containsUnresolvableType($varTagType)) { $errors[] = RuleErrorBuilder::message(sprintf('%s contains unresolvable type.', $identifier))->line($docComment->getStartLine())->identifier('varTag.unresolvableType')->build(); continue; } if ($this->checkMissingVarTagTypehint) { foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($varTagType) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $errors[] = RuleErrorBuilder::message(sprintf('%s has no value type specified in iterable type %s.', $identifier, $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } } $escapedIdentifier = SprintfHelper::escapeFormatString($identifier); $errors = array_merge($errors, $this->genericObjectTypeCheck->check($varTagType, sprintf('%s contains generic type %%s but %%s %%s is not generic.', $escapedIdentifier), sprintf('Generic type %%s in %s does not specify all template types of %%s %%s: %%s', $escapedIdentifier), sprintf('Generic type %%s in %s specifies %%d template types, but %%s %%s supports only %%d: %%s', $escapedIdentifier), sprintf('Type %%s in generic type %%s in %s is not subtype of template type %%s of %%s %%s.', $escapedIdentifier), sprintf('Call-site variance of %%s in generic type %%s in %s is in conflict with %%s template type %%s of %%s %%s.', $escapedIdentifier), sprintf('Call-site variance of %%s in generic type %%s in %s is redundant, template type %%s of %%s %%s has the same variance.', $escapedIdentifier))); foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($varTagType) as [$innerName, $genericTypeNames]) { $errors[] = RuleErrorBuilder::message(sprintf('%s contains generic %s but does not specify its types: %s', $identifier, $innerName, $genericTypeNames))->identifier('missingType.generics')->build(); } $referencedClasses = $varTagType->getReferencedClasses(); foreach ($referencedClasses as $referencedClass) { if ($this->reflectionProvider->hasClass($referencedClass)) { if ($this->reflectionProvider->getClass($referencedClass)->isTrait()) { $errors[] = RuleErrorBuilder::message(sprintf(sprintf('%s has invalid type %%s.', $identifier), $referencedClass))->identifier('varTag.trait')->build(); } continue; } if ($scope->isInClassExists($referencedClass)) { continue; } $errors[] = RuleErrorBuilder::message(sprintf(sprintf('%s contains unknown class %%s.', $identifier), $referencedClass))->identifier('class.notFound')->discoveringSymbolsTip()->build(); } $errors = array_merge($errors, $this->classCheck->checkClassNames(array_map(static function (string $class) use($node) : ClassNameNodePair { return new ClassNameNodePair($class, $node); }, $referencedClasses), $this->checkClassCaseSensitivity)); } return $errors; } } */ final class WrongVariableNameInVarTagRule implements Rule { /** * @var FileTypeMapper */ private $fileTypeMapper; /** * @var VarTagTypeRuleHelper */ private $varTagTypeRuleHelper; /** * @var bool */ private $checkTypeAgainstNativeType; public function __construct(FileTypeMapper $fileTypeMapper, \PHPStan\Rules\PhpDoc\VarTagTypeRuleHelper $varTagTypeRuleHelper, bool $checkTypeAgainstNativeType) { $this->fileTypeMapper = $fileTypeMapper; $this->varTagTypeRuleHelper = $varTagTypeRuleHelper; $this->checkTypeAgainstNativeType = $checkTypeAgainstNativeType; } public function getNodeType() : string { return Node\Stmt::class; } public function processNode(Node $node, Scope $scope) : array { if ($node instanceof Node\Stmt\Property || $node instanceof Node\Stmt\PropertyProperty || $node instanceof Node\Stmt\ClassConst || $node instanceof Node\Stmt\Const_ || $node instanceof VirtualNode && !$node instanceof InFunctionNode && !$node instanceof InClassMethodNode && !$node instanceof InClassNode) { return []; } $varTags = []; $function = $scope->getFunction(); foreach ($node->getComments() as $comment) { if (!$comment instanceof Doc) { continue; } $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $scope->isInClass() ? $scope->getClassReflection()->getName() : null, $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $function !== null ? $function->getName() : null, $comment->getText()); foreach ($resolvedPhpDoc->getVarTags() as $key => $varTag) { $varTags[$key] = $varTag; } } if (count($varTags) === 0) { return []; } if ($node instanceof Node\Stmt\Foreach_) { return $this->processForeach($scope, $node->expr, $node->keyVar, $node->valueVar, $varTags); } if ($node instanceof Node\Stmt\Static_) { return $this->processStatic($scope, $node->vars, $varTags); } if ($node instanceof Node\Stmt\Expression) { return $this->processExpression($scope, $node->expr, $varTags); } if ($node instanceof Node\Stmt\Throw_ || $node instanceof Node\Stmt\Return_) { return $this->processStmt($scope, $varTags, $node->expr); } if ($node instanceof Node\Stmt\Global_) { return $this->processGlobal($scope, $node, $varTags); } if ($node instanceof InClassNode || $node instanceof InClassMethodNode || $node instanceof InFunctionNode) { $description = 'a function'; $originalNode = $node->getOriginalNode(); if ($originalNode instanceof Node\Stmt\Interface_) { $description = 'an interface'; } elseif ($originalNode instanceof Node\Stmt\Class_) { $description = 'a class'; } elseif ($originalNode instanceof Node\Stmt\Enum_) { $description = 'an enum'; } elseif ($originalNode instanceof Node\Stmt\Trait_) { throw new ShouldNotHappenException(); } elseif ($originalNode instanceof Node\Stmt\ClassMethod) { $description = 'a method'; } return [RuleErrorBuilder::message(sprintf('PHPDoc tag @var above %s has no effect.', $description))->identifier('varTag.misplaced')->build()]; } return $this->processStmt($scope, $varTags, null); } /** * @param VarTag[] $varTags * @return list */ private function processAssign(Scope $scope, Node\Expr $var, Node\Expr $expr, array $varTags) : array { $errors = []; $hasMultipleMessage = \false; $assignedVariables = $this->getAssignedVariables($var); if ($this->checkTypeAgainstNativeType) { foreach ($this->varTagTypeRuleHelper->checkVarType($scope, $var, $expr, $varTags, $assignedVariables) as $error) { $errors[] = $error; } } foreach (array_keys($varTags) as $key) { if (is_int($key)) { if (count($varTags) !== 1) { if (!$hasMultipleMessage) { $errors[] = RuleErrorBuilder::message('Multiple PHPDoc @var tags above single variable assignment are not supported.')->identifier('varTag.multipleTags')->build(); $hasMultipleMessage = \true; } } elseif (count($assignedVariables) !== 1) { $errors[] = RuleErrorBuilder::message('PHPDoc tag @var above assignment does not specify variable name.')->identifier('varTag.noVariable')->build(); } continue; } if (!$scope->hasVariableType($key)->no()) { continue; } if (in_array($key, $assignedVariables, \true)) { continue; } if (count($assignedVariables) === 1 && count($varTags) === 1) { $errors[] = RuleErrorBuilder::message(sprintf('Variable $%s in PHPDoc tag @var does not match assigned variable $%s.', $key, $assignedVariables[0]))->identifier('varTag.differentVariable')->build(); } else { $errors[] = RuleErrorBuilder::message(sprintf('Variable $%s in PHPDoc tag @var does not exist.', $key))->identifier('varTag.variableNotFound')->build(); } } return $errors; } /** * @return string[] */ private function getAssignedVariables(Expr $expr) : array { if ($expr instanceof Expr\Variable) { if (is_string($expr->name)) { return [$expr->name]; } return []; } if ($expr instanceof Expr\List_ || $expr instanceof Expr\Array_) { $names = []; foreach ($expr->items as $item) { if ($item === null) { continue; } $names = array_merge($names, $this->getAssignedVariables($item->value)); } return $names; } return []; } /** * @param VarTag[] $varTags * @return list */ private function processForeach(Scope $scope, Node\Expr $iterateeExpr, ?Node\Expr $keyVar, Node\Expr $valueVar, array $varTags) : array { $variableNames = []; if ($iterateeExpr instanceof Node\Expr\Variable && is_string($iterateeExpr->name)) { $variableNames[] = $iterateeExpr->name; } if ($keyVar instanceof Node\Expr\Variable && is_string($keyVar->name)) { $variableNames[] = $keyVar->name; } $variableNames = array_merge($variableNames, $this->getAssignedVariables($valueVar)); $errors = []; foreach (array_keys($varTags) as $name) { if (is_int($name)) { if (count($variableNames) === 1) { continue; } $errors[] = RuleErrorBuilder::message('PHPDoc tag @var above foreach loop does not specify variable name.')->identifier('varTag.noVariable')->build(); continue; } if (in_array($name, $variableNames, \true)) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Variable $%s in PHPDoc tag @var does not match any variable in the foreach loop: %s', $name, implode(', ', array_map(static function (string $name) : string { return sprintf('$%s', $name); }, $variableNames))))->identifier('varTag.differentVariable')->build(); } if ($this->checkTypeAgainstNativeType) { foreach ($this->varTagTypeRuleHelper->checkVarType($scope, $iterateeExpr, $iterateeExpr, $varTags, $variableNames) as $error) { $errors[] = $error; } if ($keyVar !== null) { foreach ($this->varTagTypeRuleHelper->checkVarType($scope, $keyVar, new GetIterableKeyTypeExpr($iterateeExpr), $varTags, $variableNames) as $error) { $errors[] = $error; } } foreach ($this->varTagTypeRuleHelper->checkVarType($scope, $valueVar, new GetIterableValueTypeExpr($iterateeExpr), $varTags, $variableNames) as $error) { $errors[] = $error; } } return $errors; } /** * @param VarTag[] $varTags * @return list */ private function processExpression(Scope $scope, Expr $expr, array $varTags) : array { if ($expr instanceof Node\Expr\Assign || $expr instanceof Node\Expr\AssignRef) { return $this->processAssign($scope, $expr->var, $expr->expr, $varTags); } return $this->processStmt($scope, $varTags, null); } /** * @param Node\Stmt\StaticVar[] $vars * @param VarTag[] $varTags * @return list */ private function processStatic(Scope $scope, array $vars, array $varTags) : array { $variableNames = []; foreach ($vars as $var) { if (!is_string($var->var->name)) { continue; } $variableNames[] = $var->var->name; } $errors = []; foreach (array_keys($varTags) as $name) { if (is_int($name)) { if (count($vars) === 1) { continue; } $errors[] = RuleErrorBuilder::message('PHPDoc tag @var above multiple static variables does not specify variable name.')->identifier('varTag.noVariable')->build(); continue; } if (in_array($name, $variableNames, \true)) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Variable $%s in PHPDoc tag @var does not match any static variable: %s', $name, implode(', ', array_map(static function (string $name) : string { return sprintf('$%s', $name); }, $variableNames))))->identifier('varTag.differentVariable')->build(); } if ($this->checkTypeAgainstNativeType) { foreach ($vars as $var) { if ($var->default === null) { continue; } foreach ($this->varTagTypeRuleHelper->checkVarType($scope, $var->var, $var->default, $varTags, $variableNames) as $error) { $errors[] = $error; } } } return $errors; } /** * @param VarTag[] $varTags * @return list */ private function processStmt(Scope $scope, array $varTags, ?Expr $defaultExpr) : array { $errors = []; $variableLessVarTags = []; foreach ($varTags as $name => $varTag) { if (is_int($name)) { $variableLessVarTags[] = $varTag; continue; } if (!$scope->hasVariableType($name)->no()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Variable $%s in PHPDoc tag @var does not exist.', $name))->identifier('varTag.variableNotFound')->build(); } if (count($variableLessVarTags) !== 1 || $defaultExpr === null) { if (count($variableLessVarTags) > 0) { $errors[] = RuleErrorBuilder::message('PHPDoc tag @var does not specify variable name.')->identifier('varTag.noVariable')->build(); } } return $errors; } /** * @param VarTag[] $varTags * @return list */ private function processGlobal(Scope $scope, Node\Stmt\Global_ $node, array $varTags) : array { $variableNames = []; foreach ($node->vars as $var) { if (!$var instanceof Expr\Variable) { continue; } if (!is_string($var->name)) { continue; } $variableNames[$var->name] = \true; } $errors = []; foreach (array_keys($varTags) as $name) { if (is_int($name)) { if (count($variableNames) === 1) { continue; } $errors[] = RuleErrorBuilder::message('PHPDoc tag @var above multiple global variables does not specify variable name.')->identifier('varTag.noVariable')->build(); continue; } if (isset($variableNames[$name])) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Variable $%s in PHPDoc tag @var does not match any global variable: %s', $name, implode(', ', array_map(static function (string $name) : string { return sprintf('$%s', $name); }, array_keys($variableNames)))))->identifier('varTag.differentVariable')->build(); } return $errors; } } */ final class IncompatibleParamImmediatelyInvokedCallableRule implements Rule { /** * @var FileTypeMapper */ private $fileTypeMapper; public function __construct(FileTypeMapper $fileTypeMapper) { $this->fileTypeMapper = $fileTypeMapper; } public function getNodeType() : string { return FunctionLike::class; } public function processNode(Node $node, Scope $scope) : array { if ($node instanceof Node\Stmt\ClassMethod) { $functionName = $node->name->name; } elseif ($node instanceof Node\Stmt\Function_) { $functionName = trim($scope->getNamespace() . '\\' . $node->name->name, '\\'); } else { return []; } $docComment = $node->getDocComment(); if ($docComment === null) { return []; } $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $scope->isInClass() ? $scope->getClassReflection()->getName() : null, $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $functionName, $docComment->getText()); $nativeParameterTypes = []; foreach ($node->getParams() as $parameter) { if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { throw new ShouldNotHappenException(); } $nativeParameterTypes[$parameter->var->name] = $scope->getFunctionType($parameter->type, $scope->isParameterValueNullable($parameter), \false); } $errors = []; foreach ($resolvedPhpDoc->getParamsImmediatelyInvokedCallable() as $parameterName => $immediately) { $tagName = $immediately ? '@param-immediately-invoked-callable' : '@param-later-invoked-callable'; if (!isset($nativeParameterTypes[$parameterName])) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s references unknown parameter: $%s', $tagName, $parameterName))->identifier('parameter.notFound')->build(); } elseif ($nativeParameterTypes[$parameterName]->isCallable()->no()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s is for parameter $%s with non-callable type %s.', $tagName, $parameterName, $nativeParameterTypes[$parameterName]->describe(VerbosityLevel::typeOnly())))->identifier(sprintf('%s.nonCallable', $immediately ? 'paramImmediatelyInvokedCallable' : 'paramLaterInvokedCallable'))->build(); } } return $errors; } } initializerExprTypeResolver = $initializerExprTypeResolver; $this->reflectionProvider = $reflectionProvider; $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->classCheck = $classCheck; $this->missingTypehintCheck = $missingTypehintCheck; $this->genericObjectTypeCheck = $genericObjectTypeCheck; $this->absentTypeChecks = $absentTypeChecks; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; $this->checkMissingTypehints = $checkMissingTypehints; } /** * @return list * @param Function_|ClassMethod $node * @param ExtendedMethodReflection|FunctionReflection $reflection */ public function check($node, $reflection, ParametersAcceptor $acceptor) : array { $parametersByName = []; foreach ($acceptor->getParameters() as $parameter) { $parametersByName[$parameter->getName()] = $parameter->getType(); } if ($reflection instanceof ExtendedMethodReflection && !$reflection->isStatic()) { $class = $reflection->getDeclaringClass(); $parametersByName['this'] = new ObjectType($class->getName(), null, $class); } $context = InitializerExprContext::createEmpty(); $errors = []; foreach ($reflection->getAsserts()->getAll() as $assert) { $parameterName = substr($assert->getParameter()->getParameterName(), 1); if (!array_key_exists($parameterName, $parametersByName)) { $errors[] = RuleErrorBuilder::message(sprintf('Assert references unknown parameter $%s.', $parameterName))->identifier('parameter.notFound')->build(); continue; } if (!$assert->isExplicit()) { continue; } $assertedExpr = $assert->getParameter()->getExpr(new TypeExpr($parametersByName[$parameterName])); $assertedExprType = $this->initializerExprTypeResolver->getType($assertedExpr, $context); $assertedExprString = $assert->getParameter()->describe(); if ($assertedExprType instanceof ErrorType) { if ($this->absentTypeChecks) { $errors[] = RuleErrorBuilder::message(sprintf('Assert references unknown %s.', $assertedExprString))->identifier('assert.unknownExpr')->build(); } continue; } $assertedType = $assert->getType(); $tagName = [AssertTag::NULL => '@phpstan-assert', AssertTag::IF_TRUE => '@phpstan-assert-if-true', AssertTag::IF_FALSE => '@phpstan-assert-if-false'][$assert->getIf()]; if ($this->absentTypeChecks) { if ($this->unresolvableTypeHelper->containsUnresolvableType($assertedType)) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for %s contains unresolvable type.', $tagName, $assertedExprString))->identifier('assert.unresolvableType')->build(); continue; } } $isSuperType = $assertedType->isSuperTypeOf($assertedExprType); if (!$isSuperType->maybe()) { if ($assert->isNegated() ? $isSuperType->yes() : $isSuperType->no()) { $errors[] = RuleErrorBuilder::message(sprintf('Asserted %stype %s for %s with type %s can never happen.', $assert->isNegated() ? 'negated ' : '', $assertedType->describe(VerbosityLevel::precise()), $assertedExprString, $assertedExprType->describe(VerbosityLevel::precise())))->identifier('assert.impossibleType')->build(); } elseif ($assert->isNegated() ? $isSuperType->no() : $isSuperType->yes()) { $errors[] = RuleErrorBuilder::message(sprintf('Asserted %stype %s for %s with type %s does not narrow down the type.', $assert->isNegated() ? 'negated ' : '', $assertedType->describe(VerbosityLevel::precise()), $assertedExprString, $assertedExprType->describe(VerbosityLevel::precise())))->identifier('assert.alreadyNarrowedType')->build(); } } if (!$this->absentTypeChecks) { continue; } foreach ($assertedType->getReferencedClasses() as $class) { if (!$this->reflectionProvider->hasClass($class)) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for %s contains unknown class %s.', $tagName, $assertedExprString, $class))->identifier('class.notFound')->build(); continue; } $classReflection = $this->reflectionProvider->getClass($class); if ($classReflection->isTrait()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for %s contains invalid type %s.', $tagName, $assertedExprString, $class))->identifier('assert.trait')->build(); continue; } $errors = array_merge($errors, $this->classCheck->checkClassNames([new ClassNameNodePair($class, $node)], $this->checkClassCaseSensitivity)); } $errors = array_merge($errors, $this->genericObjectTypeCheck->check($assertedType, sprintf('PHPDoc tag %s for %s contains generic type %%s but %%s %%s is not generic.', $tagName, $assertedExprString), sprintf('Generic type %%s in PHPDoc tag %s for %s does not specify all template types of %%s %%s: %%s', $tagName, $assertedExprString), sprintf('Generic type %%s in PHPDoc tag %s for %s specifies %%d template types, but %%s %%s supports only %%d: %%s', $tagName, $assertedExprString), sprintf('Type %%s in generic type %%s in PHPDoc tag %s for %s is not subtype of template type %%s of %%s %%s.', $tagName, $assertedExprString), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag %s for %s is in conflict with %%s template type %%s of %%s %%s.', $tagName, $assertedExprString), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag %s for %s is redundant, template type %%s of %%s %%s has the same variance.', $tagName, $assertedExprString))); if (!$this->checkMissingTypehints) { continue; } foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($assertedType) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for %s has no value type specified in iterable type %s.', $tagName, $assertedExprString, $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($assertedType) as [$innerName, $genericTypeNames]) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for %s contains generic %s but does not specify its types: %s', $tagName, $assertedExprString, $innerName, $genericTypeNames))->identifier('missingType.generics')->build(); } foreach ($this->missingTypehintCheck->getCallablesWithMissingSignature($assertedType) as $callableType) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for %s has no signature specified for %s.', $tagName, $assertedExprString, $callableType->describe(VerbosityLevel::typeOnly())))->identifier('missingType.callable')->build(); } } return $errors; } } */ final class MethodAssertRule implements Rule { /** * @var AssertRuleHelper */ private $helper; public function __construct(\PHPStan\Rules\PhpDoc\AssertRuleHelper $helper) { $this->helper = $helper; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); $variants = $method->getVariants(); if (count($variants) !== 1) { return []; } return $this->helper->check($node->getOriginalNode(), $method, $variants[0]); } } */ final class MethodConditionalReturnTypeRule implements Rule { /** * @var ConditionalReturnTypeRuleHelper */ private $helper; public function __construct(\PHPStan\Rules\PhpDoc\ConditionalReturnTypeRuleHelper $helper) { $this->helper = $helper; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); $variants = $method->getVariants(); if (count($variants) !== 1) { return []; } return $this->helper->check($variants[0]); } } */ final class IncompatiblePropertyPhpDocTypeRule implements Rule { /** * @var GenericObjectTypeCheck */ private $genericObjectTypeCheck; /** * @var UnresolvableTypeHelper */ private $unresolvableTypeHelper; /** * @var GenericCallableRuleHelper */ private $genericCallableRuleHelper; public function __construct(GenericObjectTypeCheck $genericObjectTypeCheck, \PHPStan\Rules\PhpDoc\UnresolvableTypeHelper $unresolvableTypeHelper, \PHPStan\Rules\PhpDoc\GenericCallableRuleHelper $genericCallableRuleHelper) { $this->genericObjectTypeCheck = $genericObjectTypeCheck; $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->genericCallableRuleHelper = $genericCallableRuleHelper; } public function getNodeType() : string { return ClassPropertyNode::class; } public function processNode(Node $node, Scope $scope) : array { $phpDocType = $node->getPhpDocType(); if ($phpDocType === null) { return []; } $propertyName = $node->getName(); $description = 'PHPDoc tag @var'; if ($node->isPromoted()) { $description = 'PHPDoc type'; } $classReflection = $node->getClassReflection(); $messages = []; if ($this->unresolvableTypeHelper->containsUnresolvableType($phpDocType)) { $messages[] = RuleErrorBuilder::message(sprintf('%s for property %s::$%s contains unresolvable type.', $description, $classReflection->getDisplayName(), $propertyName))->identifier('property.unresolvableType')->build(); } $nativeType = ParserNodeTypeToPHPStanType::resolve($node->getNativeType(), $classReflection); $isSuperType = $nativeType->isSuperTypeOf($phpDocType); if ($isSuperType->no()) { $messages[] = RuleErrorBuilder::message(sprintf('%s for property %s::$%s with type %s is incompatible with native type %s.', $description, $classReflection->getDisplayName(), $propertyName, $phpDocType->describe(VerbosityLevel::typeOnly()), $nativeType->describe(VerbosityLevel::typeOnly())))->identifier('property.phpDocType')->build(); } elseif ($isSuperType->maybe()) { $errorBuilder = RuleErrorBuilder::message(sprintf('%s for property %s::$%s with type %s is not subtype of native type %s.', $description, $classReflection->getDisplayName(), $propertyName, $phpDocType->describe(VerbosityLevel::typeOnly()), $nativeType->describe(VerbosityLevel::typeOnly())))->identifier('property.phpDocType'); if ($phpDocType instanceof TemplateType) { $errorBuilder->tip(sprintf('Write @template %s of %s to fix this.', $phpDocType->getName(), $nativeType->describe(VerbosityLevel::typeOnly()))); } $messages[] = $errorBuilder->build(); } $className = SprintfHelper::escapeFormatString($classReflection->getDisplayName()); $escapedPropertyName = SprintfHelper::escapeFormatString($propertyName); if ($node->isPromoted() === \false) { $messages = array_merge($messages, $this->genericCallableRuleHelper->check($node, $scope, '@var', $phpDocType, null, [], $classReflection)); } $messages = array_merge($messages, $this->genericObjectTypeCheck->check($phpDocType, sprintf('%s for property %s::$%s contains generic type %%s but %%s %%s is not generic.', $description, $className, $escapedPropertyName), sprintf('Generic type %%s in %s for property %s::$%s does not specify all template types of %%s %%s: %%s', $description, $className, $escapedPropertyName), sprintf('Generic type %%s in %s for property %s::$%s specifies %%d template types, but %%s %%s supports only %%d: %%s', $description, $className, $escapedPropertyName), sprintf('Type %%s in generic type %%s in %s for property %s::$%s is not subtype of template type %%s of %%s %%s.', $description, $className, $escapedPropertyName), sprintf('Call-site variance of %%s in generic type %%s in %s for property %s::$%s is in conflict with %%s template type %%s of %%s %%s.', $description, $className, $escapedPropertyName), sprintf('Call-site variance of %%s in generic type %%s in %s for property %s::$%s is redundant, template type %%s of %%s %%s has the same variance.', $description, $className, $escapedPropertyName))); return $messages; } } message; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } } message; } public function getLine() : int { return $this->line; } public function getTip() : string { return $this->tip; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } } message; } public function getLine() : int { return $this->line; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getTip() : string { return $this->tip; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getTip() : string { return $this->tip; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getTip() : string { return $this->tip; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } } message; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } } message; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getLine() : int { return $this->line; } } message; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } } message; } public function getLine() : int { return $this->line; } public function getTip() : string { return $this->tip; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getLine() : int { return $this->line; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } } message; } public function getLine() : int { return $this->line; } public function getTip() : string { return $this->tip; } } message; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getIdentifier() : string { return $this->identifier; } } message; } public function getLine() : int { return $this->line; } public function getTip() : string { return $this->tip; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getIdentifier() : string { return $this->identifier; } } message; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getLine() : int { return $this->line; } public function getTip() : string { return $this->tip; } public function getIdentifier() : string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } } message; } public function getTip() : string { return $this->tip; } } message; } public function getFile() : string { return $this->file; } public function getFileDescription() : string { return $this->fileDescription; } public function getTip() : string { return $this->tip; } } message; } public function getIdentifier() : string { return $this->identifier; } } */ public function getNodeType() : string; /** * @param TNodeType $node * @return (string|RuleError)[] errors */ public function processNode(Node $node, Scope $scope) : array; } */ final class EnumCaseAttributesRule implements Rule { /** * @var AttributesCheck */ private $attributesCheck; public function __construct(AttributesCheck $attributesCheck) { $this->attributesCheck = $attributesCheck; } public function getNodeType() : string { return Node\Stmt\EnumCase::class; } public function processNode(Node $node, Scope $scope) : array { return $this->attributesCheck->check($scope, $node->attrGroups, Attribute::TARGET_CLASS_CONSTANT, 'class constant'); } } */ final class AllowedSubTypesRule implements Rule { public function getNodeType() : string { return InClassNode::class; } /** * @param InClassNode $node */ public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); $className = $classReflection->getName(); $parents = array_values($classReflection->getImmediateInterfaces()); $parentClass = $classReflection->getParentClass(); if ($parentClass !== null) { $parents[] = $parentClass; } $messages = []; foreach ($parents as $parentReflection) { $allowedSubTypes = $parentReflection->getAllowedSubTypes(); if ($allowedSubTypes === null) { continue; } foreach ($allowedSubTypes as $allowedSubType) { if (!$allowedSubType->isObject()->yes()) { continue; } if ($allowedSubType->getObjectClassNames() === [$className]) { continue 2; } } $identifierType = strtolower($classReflection->getClassTypeDescription()); $messages[] = RuleErrorBuilder::message(sprintf('Type %s is not allowed to be a subtype of %s.', $className, $parentReflection->getName()))->identifier(sprintf('%s.disallowedSubtype', $identifierType))->build(); } return $messages; } } */ final class DuplicateClassDeclarationRule implements Rule { /** * @var Reflector */ private $reflector; /** * @var RelativePathHelper */ private $relativePathHelper; public function __construct(Reflector $reflector, RelativePathHelper $relativePathHelper) { $this->reflector = $reflector; $this->relativePathHelper = $relativePathHelper; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $thisClass = $node->getClassReflection(); $className = $thisClass->getName(); $allClasses = $this->reflector->reflectAllClasses(); $filteredClasses = []; foreach ($allClasses as $reflectionClass) { if ($reflectionClass->getName() !== $className) { continue; } $filteredClasses[] = $reflectionClass; } if (count($filteredClasses) < 2) { return []; } $filteredClasses = array_filter($filteredClasses, static function (ReflectionClass $class) use($thisClass) { return $class->getStartLine() !== $thisClass->getNativeReflection()->getStartLine(); }); $identifierType = strtolower($thisClass->getClassTypeDescription()); return [RuleErrorBuilder::message(sprintf("Class %s declared multiple times:\n%s", $thisClass->getDisplayName(), implode("\n", array_map(function (ReflectionClass $class) { return sprintf('- %s:%d', $this->relativePathHelper->getRelativePath($class->getFileName() ?? 'unknown'), $class->getStartLine()); }, $filteredClasses))))->identifier(sprintf('%s.duplicate', $identifierType))->build()]; } } */ final class ExistingClassesInInterfaceExtendsRule implements Rule { /** * @var ClassNameCheck */ private $classCheck; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ClassNameCheck $classCheck, ReflectionProvider $reflectionProvider) { $this->classCheck = $classCheck; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Stmt\Interface_::class; } public function processNode(Node $node, Scope $scope) : array { $messages = $this->classCheck->checkClassNames(array_map(static function (Node\Name $interfaceName) : ClassNameNodePair { return new ClassNameNodePair((string) $interfaceName, $interfaceName); }, $node->extends)); $currentInterfaceName = (string) $node->namespacedName; foreach ($node->extends as $extends) { $extendedInterfaceName = (string) $extends; if (!$this->reflectionProvider->hasClass($extendedInterfaceName)) { if (!$scope->isInClassExists($extendedInterfaceName)) { $messages[] = RuleErrorBuilder::message(sprintf('Interface %s extends unknown interface %s.', $currentInterfaceName, $extendedInterfaceName))->identifier('interface.notFound')->nonIgnorable()->discoveringSymbolsTip()->build(); } } else { $reflection = $this->reflectionProvider->getClass($extendedInterfaceName); if ($reflection->isClass()) { $messages[] = RuleErrorBuilder::message(sprintf('Interface %s extends class %s.', $currentInterfaceName, $reflection->getDisplayName()))->identifier('interfaceExtends.class')->nonIgnorable()->build(); } elseif ($reflection->isTrait()) { $messages[] = RuleErrorBuilder::message(sprintf('Interface %s extends trait %s.', $currentInterfaceName, $reflection->getDisplayName()))->identifier('interfaceExtends.trait')->nonIgnorable()->build(); } elseif ($reflection->isEnum()) { $messages[] = RuleErrorBuilder::message(sprintf('Interface %s extends enum %s.', $currentInterfaceName, $reflection->getDisplayName()))->identifier('interfaceExtends.enum')->nonIgnorable()->build(); } } return $messages; } return $messages; } } */ final class NewStaticRule implements Rule { public function getNodeType() : string { return Node\Expr\New_::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->class instanceof Node\Name) { return []; } if (!$scope->isInClass()) { return []; } if (strtolower($node->class->toString()) !== 'static') { return []; } $classReflection = $scope->getClassReflection(); if ($classReflection->isFinal()) { return []; } $messages = [RuleErrorBuilder::message('Unsafe usage of new static().')->identifier('new.static')->tip('See: https://phpstan.org/blog/solving-phpstan-error-unsafe-usage-of-new-static')->build()]; if (!$classReflection->hasConstructor()) { return $messages; } $constructor = $classReflection->getConstructor(); if ($constructor->getPrototype()->getDeclaringClass()->isInterface()) { return []; } if ($constructor->getDeclaringClass()->hasConsistentConstructor()) { return []; } foreach ($classReflection->getImmediateInterfaces() as $interface) { if ($interface->hasConstructor()) { return []; } } if ($constructor instanceof PhpMethodReflection) { if ($constructor->isFinal()->yes()) { return []; } $prototype = $constructor->getPrototype(); if ($prototype->isAbstract()) { return []; } } return $messages; } } */ final class PropertyTagRule implements Rule { /** * @var PropertyTagCheck */ private $check; public function __construct(\PHPStan\Rules\Classes\PropertyTagCheck $check) { $this->check = $check; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { return $this->check->check($node->getClassReflection(), $node->getOriginalNode()); } } reflectionProvider = $reflectionProvider; $this->classCheck = $classCheck; $this->genericObjectTypeCheck = $genericObjectTypeCheck; $this->missingTypehintCheck = $missingTypehintCheck; $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; $this->checkMissingTypehints = $checkMissingTypehints; } /** * @return list */ public function check(ClassReflection $classReflection, ClassLike $node) : array { $errors = []; foreach ($classReflection->getPropertyTags() as $propertyName => $propertyTag) { [$types, $tagName] = $this->getTypesAndTagName($propertyTag); foreach ($types as $type) { foreach ($this->checkPropertyTypeInTraitDefinitionContext($classReflection, $propertyName, $tagName, $type) as $error) { $errors[] = $error; } foreach ($this->checkPropertyTypeInTraitUseContext($classReflection, $propertyName, $tagName, $type, $node) as $error) { $errors[] = $error; } } } return $errors; } /** * @return list */ public function checkInTraitDefinitionContext(ClassReflection $classReflection) : array { $errors = []; foreach ($classReflection->getPropertyTags() as $propertyName => $propertyTag) { [$types, $tagName] = $this->getTypesAndTagName($propertyTag); foreach ($types as $type) { foreach ($this->checkPropertyTypeInTraitDefinitionContext($classReflection, $propertyName, $tagName, $type) as $error) { $errors[] = $error; } } } return $errors; } /** * @return list */ public function checkInTraitUseContext(ClassReflection $classReflection, ClassReflection $implementingClass, ClassLike $node) : array { $phpDoc = $classReflection->getTraitContextResolvedPhpDoc($implementingClass); if ($phpDoc === null) { return []; } $errors = []; foreach ($phpDoc->getPropertyTags() as $propertyName => $propertyTag) { [$types, $tagName] = $this->getTypesAndTagName($propertyTag); foreach ($types as $type) { foreach ($this->checkPropertyTypeInTraitUseContext($classReflection, $propertyName, $tagName, $type, $node) as $error) { $errors[] = $error; } } } return $errors; } /** * @return array{list, string} */ private function getTypesAndTagName(PropertyTag $propertyTag) : array { $readableType = $propertyTag->getReadableType(); $writableType = $propertyTag->getWritableType(); $types = []; $tagName = '@property'; if ($readableType !== null) { if ($writableType !== null) { if ($writableType->equals($readableType)) { $types[] = $readableType; } else { $types[] = $readableType; $types[] = $writableType; } } else { $tagName = '@property-read'; $types[] = $readableType; } } elseif ($writableType !== null) { $tagName = '@property-write'; $types[] = $writableType; } else { throw new ShouldNotHappenException(); } return [$types, $tagName]; } /** * @return list */ private function checkPropertyTypeInTraitDefinitionContext(ClassReflection $classReflection, string $propertyName, string $tagName, Type $type) : array { if (!$this->checkMissingTypehints) { return []; } $errors = []; foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($type) as [$innerName, $genericTypeNames]) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for property %s::$%s contains generic %s but does not specify its types: %s', $tagName, $classReflection->getDisplayName(), $propertyName, $innerName, $genericTypeNames))->identifier('missingType.generics')->build(); } foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($type) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $errors[] = RuleErrorBuilder::message(sprintf('%s %s has PHPDoc tag %s for property $%s with no value type specified in iterable type %s.', $classReflection->getClassTypeDescription(), $classReflection->getDisplayName(), $tagName, $propertyName, $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } foreach ($this->missingTypehintCheck->getCallablesWithMissingSignature($type) as $callableType) { $errors[] = RuleErrorBuilder::message(sprintf('%s %s has PHPDoc tag %s for property $%s with no signature specified for %s.', $classReflection->getClassTypeDescription(), $classReflection->getDisplayName(), $tagName, $propertyName, $callableType->describe(VerbosityLevel::typeOnly())))->identifier('missingType.callable')->build(); } return $errors; } /** * @return list */ private function checkPropertyTypeInTraitUseContext(ClassReflection $classReflection, string $propertyName, string $tagName, Type $type, ClassLike $node) : array { $errors = []; foreach ($type->getReferencedClasses() as $class) { if (!$this->reflectionProvider->hasClass($class)) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for property %s::$%s contains unknown class %s.', $tagName, $classReflection->getDisplayName(), $propertyName, $class))->identifier('class.notFound')->discoveringSymbolsTip()->build(); } elseif ($this->reflectionProvider->getClass($class)->isTrait()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for property %s::$%s contains invalid type %s.', $tagName, $classReflection->getDisplayName(), $propertyName, $class))->identifier('propertyTag.trait')->build(); } else { $errors = array_merge($errors, $this->classCheck->checkClassNames([new ClassNameNodePair($class, $node)], $this->checkClassCaseSensitivity)); } } if ($this->unresolvableTypeHelper->containsUnresolvableType($type)) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag %s for property %s::$%s contains unresolvable type.', $tagName, $classReflection->getDisplayName(), $propertyName))->identifier('propertyTag.unresolvableType')->build(); } $escapedClassName = SprintfHelper::escapeFormatString($classReflection->getDisplayName()); $escapedPropertyName = SprintfHelper::escapeFormatString($propertyName); $escapedTagName = SprintfHelper::escapeFormatString($tagName); return array_merge($errors, $this->genericObjectTypeCheck->check($type, sprintf('PHPDoc tag %s for property %s::$%s contains generic type %%s but %%s %%s is not generic.', $escapedTagName, $escapedClassName, $escapedPropertyName), sprintf('Generic type %%s in PHPDoc tag %s for property %s::$%s does not specify all template types of %%s %%s: %%s', $escapedTagName, $escapedClassName, $escapedPropertyName), sprintf('Generic type %%s in PHPDoc tag %s for property %s::$%s specifies %%d template types, but %%s %%s supports only %%d: %%s', $escapedTagName, $escapedClassName, $escapedPropertyName), sprintf('Type %%s in generic type %%s in PHPDoc tag %s for property %s::$%s is not subtype of template type %%s of %%s %%s.', $escapedTagName, $escapedClassName, $escapedPropertyName), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag %s for property %s::$%s is in conflict with %%s template type %%s of %%s %%s.', $escapedTagName, $escapedClassName, $escapedPropertyName), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag %s for property %s::$%s is redundant, template type %%s of %%s %%s has the same variance.', $escapedTagName, $escapedClassName, $escapedPropertyName))); } } */ final class MixinTraitRule implements Rule { /** * @var MixinCheck */ private $check; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Classes\MixinCheck $check, ReflectionProvider $reflectionProvider) { $this->check = $check; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Stmt\Trait_::class; } public function processNode(Node $node, Scope $scope) : array { $traitName = $node->namespacedName; if ($traitName === null) { return []; } if (!$this->reflectionProvider->hasClass($traitName->toString())) { return []; } return $this->check->checkInTraitDefinitionContext($this->reflectionProvider->getClass($traitName->toString())); } } */ final class UnusedConstructorParametersRule implements Rule { /** * @var UnusedFunctionParametersCheck */ private $check; public function __construct(UnusedFunctionParametersCheck $check) { $this->check = $check; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); $originalNode = $node->getOriginalNode(); if (strtolower($method->getName()) !== '__construct' || $originalNode->stmts === null) { return []; } if (count($originalNode->params) === 0) { return []; } $message = sprintf('Constructor of class %s has an unused parameter $%%s.', SprintfHelper::escapeFormatString($node->getClassReflection()->getDisplayName())); if ($node->getClassReflection()->isAnonymous()) { $message = 'Constructor of an anonymous class has an unused parameter $%s.'; } return $this->check->getUnusedParameters($scope, array_map(static function (Param $parameter) : string { if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { throw new ShouldNotHappenException(); } return $parameter->var->name; }, array_values(array_filter($originalNode->params, static function (Param $parameter) : bool { return $parameter->flags === 0; }))), $originalNode->stmts, $message, 'constructor.unusedParameter'); } } reflectionProvider = $reflectionProvider; $this->classCheck = $classCheck; $this->genericObjectTypeCheck = $genericObjectTypeCheck; $this->missingTypehintCheck = $missingTypehintCheck; $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; $this->absentTypeChecks = $absentTypeChecks; $this->checkMissingTypehints = $checkMissingTypehints; } /** * @return list */ public function check(ClassReflection $classReflection, ClassLike $node) : array { $errors = []; foreach ($this->checkInTraitDefinitionContext($classReflection) as $error) { $errors[] = $error; } foreach ($this->checkInTraitUseContext($classReflection, $classReflection, $node) as $error) { $errors[] = $error; } return $errors; } /** * @return list */ public function checkInTraitDefinitionContext(ClassReflection $classReflection) : array { $errors = []; foreach ($classReflection->getMixinTags() as $mixinTag) { $type = $mixinTag->getType(); if (!$type->canCallMethods()->yes() || !$type->canAccessProperties()->yes()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @mixin contains non-object type %s.', $type->describe(VerbosityLevel::typeOnly())))->identifier('mixin.nonObject')->build(); continue; } if (!$this->absentTypeChecks) { continue; } if (!$this->checkMissingTypehints) { continue; } foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($type) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $errors[] = RuleErrorBuilder::message(sprintf('%s %s has PHPDoc tag @mixin with no value type specified in iterable type %s.', $classReflection->getClassTypeDescription(), $classReflection->getDisplayName(), $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($type) as [$innerName, $genericTypeNames]) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @mixin contains generic %s but does not specify its types: %s', $innerName, $genericTypeNames))->identifier('missingType.generics')->build(); } foreach ($this->missingTypehintCheck->getCallablesWithMissingSignature($type) as $callableType) { $errors[] = RuleErrorBuilder::message(sprintf('%s %s has PHPDoc tag @mixin with no signature specified for %s.', $classReflection->getClassTypeDescription(), $classReflection->getDisplayName(), $callableType->describe(VerbosityLevel::typeOnly())))->identifier('missingType.callable')->build(); } } return $errors; } /** * @return list */ public function checkInTraitUseContext(ClassReflection $reflection, ClassReflection $implementingClassReflection, ClassLike $node) : array { if ($reflection->getNativeReflection()->getName() === $implementingClassReflection->getName()) { $phpDoc = $reflection->getResolvedPhpDoc(); } else { $phpDoc = $reflection->getTraitContextResolvedPhpDoc($implementingClassReflection); } if ($phpDoc === null) { return []; } $errors = []; foreach ($phpDoc->getMixinTags() as $mixinTag) { $type = $mixinTag->getType(); if ($this->unresolvableTypeHelper->containsUnresolvableType($type)) { $errors[] = RuleErrorBuilder::message('PHPDoc tag @mixin contains unresolvable type.')->identifier('mixin.unresolvableType')->build(); continue; } $errors = array_merge($errors, $this->genericObjectTypeCheck->check($type, 'PHPDoc tag @mixin contains generic type %s but %s %s is not generic.', 'Generic type %s in PHPDoc tag @mixin does not specify all template types of %s %s: %s', 'Generic type %s in PHPDoc tag @mixin specifies %d template types, but %s %s supports only %d: %s', 'Type %s in generic type %s in PHPDoc tag @mixin is not subtype of template type %s of %s %s.', 'Call-site variance of %s in generic type %s in PHPDoc tag @mixin is in conflict with %s template type %s of %s %s.', 'Call-site variance of %s in generic type %s in PHPDoc tag @mixin is redundant, template type %s of %s %s has the same variance.')); foreach ($type->getReferencedClasses() as $class) { if (!$this->reflectionProvider->hasClass($class)) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @mixin contains unknown class %s.', $class))->identifier('class.notFound')->discoveringSymbolsTip()->build(); } elseif ($this->reflectionProvider->getClass($class)->isTrait()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @mixin contains invalid type %s.', $class))->identifier('mixin.trait')->build(); } else { $errors = array_merge($errors, $this->classCheck->checkClassNames([new ClassNameNodePair($class, $node)], $this->checkClassCaseSensitivity)); } } } return $errors; } } */ final class ImpossibleInstanceOfRule implements Rule { /** * @var bool */ private $checkAlwaysTrueInstanceof; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $reportAlwaysTrueInLastCondition; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(bool $checkAlwaysTrueInstanceof, bool $treatPhpDocTypesAsCertain, bool $reportAlwaysTrueInLastCondition, bool $treatPhpDocTypesAsCertainTip) { $this->checkAlwaysTrueInstanceof = $checkAlwaysTrueInstanceof; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->reportAlwaysTrueInLastCondition = $reportAlwaysTrueInLastCondition; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return Node\Expr\Instanceof_::class; } public function processNode(Node $node, Scope $scope) : array { $instanceofType = $this->treatPhpDocTypesAsCertain ? $scope->getType($node) : $scope->getNativeType($node); if (!$instanceofType instanceof ConstantBooleanType) { return []; } if ($node->class instanceof Node\Name) { $className = $scope->resolveName($node->class); $classType = new ObjectType($className); } else { $classType = $this->treatPhpDocTypesAsCertain ? $scope->getType($node->class) : $scope->getNativeType($node->class); $allowed = TypeCombinator::union(new StringType(), new ObjectWithoutClassType()); if (!$allowed->isSuperTypeOf($classType)->yes()) { return [RuleErrorBuilder::message(sprintf('Instanceof between %s and %s results in an error.', $scope->getType($node->expr)->describe(VerbosityLevel::typeOnly()), $classType->describe(VerbosityLevel::typeOnly())))->identifier('instanceof.invalidExprType')->build()]; } } $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $instanceofTypeWithoutPhpDocs = $scope->getNativeType($node); if ($instanceofTypeWithoutPhpDocs instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; if (!$instanceofType->getValue()) { $exprType = $this->treatPhpDocTypesAsCertain ? $scope->getType($node->expr) : $scope->getNativeType($node->expr); return [$addTip(RuleErrorBuilder::message(sprintf('Instanceof between %s and %s will always evaluate to false.', $exprType->describe(VerbosityLevel::typeOnly()), $classType->describe(VerbosityLevel::getRecommendedLevelByType($classType)))))->identifier('instanceof.alwaysFalse')->build()]; } elseif ($this->checkAlwaysTrueInstanceof) { $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if ($isLast === \true && !$this->reportAlwaysTrueInLastCondition) { return []; } $exprType = $this->treatPhpDocTypesAsCertain ? $scope->getType($node->expr) : $scope->getNativeType($node->expr); $errorBuilder = $addTip(RuleErrorBuilder::message(sprintf('Instanceof between %s and %s will always evaluate to true.', $exprType->describe(VerbosityLevel::typeOnly()), $classType->describe(VerbosityLevel::getRecommendedLevelByType($classType))))); if ($isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errorBuilder->identifier('instanceof.alwaysTrue'); return [$errorBuilder->build()]; } return []; } } */ final class ExistingClassInInstanceOfRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var ClassNameCheck */ private $classCheck; /** * @var bool */ private $checkClassCaseSensitivity; public function __construct(ReflectionProvider $reflectionProvider, ClassNameCheck $classCheck, bool $checkClassCaseSensitivity) { $this->reflectionProvider = $reflectionProvider; $this->classCheck = $classCheck; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; } public function getNodeType() : string { return Instanceof_::class; } public function processNode(Node $node, Scope $scope) : array { $class = $node->class; if (!$class instanceof Node\Name) { return []; } $name = (string) $class; $lowercaseName = strtolower($name); if (in_array($lowercaseName, ['self', 'static', 'parent'], \true)) { if (!$scope->isInClass()) { return [RuleErrorBuilder::message(sprintf('Using %s outside of class scope.', $lowercaseName))->identifier(sprintf('outOfClass.%s', $lowercaseName))->line($class->getStartLine())->build()]; } return []; } $errors = []; if (!$this->reflectionProvider->hasClass($name)) { if ($scope->isInClassExists($name)) { return []; } return [RuleErrorBuilder::message(sprintf('Class %s not found.', $name))->identifier('class.notFound')->line($class->getStartLine())->discoveringSymbolsTip()->build()]; } $errors = array_merge($errors, $this->classCheck->checkClassNames([new ClassNameNodePair($name, $class)], $this->checkClassCaseSensitivity)); $classReflection = $this->reflectionProvider->getClass($name); if ($classReflection->isTrait()) { $expressionType = $scope->getType($node->expr); $errors[] = RuleErrorBuilder::message(sprintf('Instanceof between %s and trait %s will always evaluate to false.', $expressionType->describe(VerbosityLevel::typeOnly()), $name))->identifier('instanceof.trait')->build(); } return $errors; } } */ final class ClassConstantRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var ClassNameCheck */ private $classCheck; /** * @var PhpVersion */ private $phpVersion; public function __construct(ReflectionProvider $reflectionProvider, RuleLevelHelper $ruleLevelHelper, ClassNameCheck $classCheck, PhpVersion $phpVersion) { $this->reflectionProvider = $reflectionProvider; $this->ruleLevelHelper = $ruleLevelHelper; $this->classCheck = $classCheck; $this->phpVersion = $phpVersion; } public function getNodeType() : string { return ClassConstFetch::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier) { return []; } $constantName = $node->name->name; $class = $node->class; $messages = []; if ($class instanceof Node\Name) { $className = (string) $class; $lowercasedClassName = strtolower($className); if (in_array($lowercasedClassName, ['self', 'static'], \true)) { if (!$scope->isInClass()) { return [RuleErrorBuilder::message(sprintf('Using %s outside of class scope.', $className))->identifier(sprintf('outOfClass.%s', $lowercasedClassName))->build()]; } $classType = $scope->resolveTypeByName($class); } elseif ($lowercasedClassName === 'parent') { if (!$scope->isInClass()) { return [RuleErrorBuilder::message(sprintf('Using %s outside of class scope.', $className))->identifier(sprintf('outOfClass.%s', $lowercasedClassName))->build()]; } $currentClassReflection = $scope->getClassReflection(); if ($currentClassReflection->getParentClass() === null) { return [RuleErrorBuilder::message(sprintf('Access to parent::%s but %s does not extend any class.', $constantName, $currentClassReflection->getDisplayName()))->identifier('class.noParent')->build()]; } $classType = $scope->resolveTypeByName($class); } else { if (!$this->reflectionProvider->hasClass($className)) { if ($scope->isInClassExists($className)) { return []; } if (strtolower($constantName) === 'class') { return [RuleErrorBuilder::message(sprintf('Class %s not found.', $className))->identifier('class.notFound')->discoveringSymbolsTip()->build()]; } return [RuleErrorBuilder::message(sprintf('Access to constant %s on an unknown class %s.', $constantName, $className))->identifier('class.notFound')->discoveringSymbolsTip()->build()]; } $messages = $this->classCheck->checkClassNames([new ClassNameNodePair($className, $class)]); $classType = $scope->resolveTypeByName($class); } if (strtolower($constantName) === 'class') { return $messages; } } else { $classTypeResult = $this->ruleLevelHelper->findTypeToCheck($scope, NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $class), sprintf('Access to constant %s on an unknown class %%s.', SprintfHelper::escapeFormatString($constantName)), static function (Type $type) use($constantName) : bool { return $type->canAccessConstants()->yes() && $type->hasConstant($constantName)->yes(); }); $classType = $classTypeResult->getType(); if ($classType instanceof ErrorType) { return $classTypeResult->getUnknownClassErrors(); } if (strtolower($constantName) === 'class') { if (!$this->phpVersion->supportsClassConstantOnExpression()) { return [RuleErrorBuilder::message('Accessing ::class constant on an expression is supported only on PHP 8.0 and later.')->identifier('classConstant.notSupported')->nonIgnorable()->build()]; } if (!$class instanceof Node\Scalar\String_ && $classType->isString()->yes()) { return [RuleErrorBuilder::message('Accessing ::class constant on a dynamic string is not supported in PHP.')->identifier('classConstant.dynamicString')->nonIgnorable()->build()]; } } } if ($classType->isString()->yes()) { return $messages; } $typeForDescribe = $classType; if ($classType instanceof ThisType) { $typeForDescribe = $classType->getStaticObjectType(); } $classType = TypeCombinator::remove($classType, new StringType()); if (!$classType->canAccessConstants()->yes()) { return array_merge($messages, [RuleErrorBuilder::message(sprintf('Cannot access constant %s on %s.', $constantName, $typeForDescribe->describe(VerbosityLevel::typeOnly())))->identifier('classConstant.nonObject')->build()]); } if (strtolower($constantName) === 'class' || $scope->hasExpressionType($node)->yes()) { return $messages; } if (!$classType->hasConstant($constantName)->yes()) { return array_merge($messages, [RuleErrorBuilder::message(sprintf('Access to undefined constant %s::%s.', $typeForDescribe->describe(VerbosityLevel::typeOnly()), $constantName))->identifier('classConstant.notFound')->build()]); } $constantReflection = $classType->getConstant($constantName); if (!$scope->canAccessConstant($constantReflection)) { return array_merge($messages, [RuleErrorBuilder::message(sprintf('Access to %s constant %s of class %s.', $constantReflection->isPrivate() ? 'private' : 'protected', $constantName, $constantReflection->getDeclaringClass()->getDisplayName()))->identifier(sprintf('classConstant.%s', $constantReflection->isPrivate() ? 'private' : 'protected'))->build()]); } return $messages; } } */ final class PropertyTagTraitRule implements Rule { /** * @var PropertyTagCheck */ private $check; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Classes\PropertyTagCheck $check, ReflectionProvider $reflectionProvider) { $this->check = $check; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Stmt\Trait_::class; } public function processNode(Node $node, Scope $scope) : array { $traitName = $node->namespacedName; if ($traitName === null) { return []; } if (!$this->reflectionProvider->hasClass($traitName->toString())) { return []; } return $this->check->checkInTraitDefinitionContext($this->reflectionProvider->getClass($traitName->toString())); } } */ final class ReadOnlyClassRule implements Rule { /** * @var PhpVersion */ private $phpVersion; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); if (!$classReflection->isReadOnly()) { return []; } if ($classReflection->isAnonymous()) { if ($this->phpVersion->supportsReadOnlyAnonymousClasses()) { return []; } return [RuleErrorBuilder::message('Anonymous readonly classes are supported only on PHP 8.3 and later.')->identifier('classConstant.nativeTypeNotSupported')->nonIgnorable()->build()]; } if ($this->phpVersion->supportsReadOnlyClasses()) { return []; } return [RuleErrorBuilder::message('Readonly classes are supported only on PHP 8.2 and later.')->identifier('classConstant.nativeTypeNotSupported')->nonIgnorable()->build()]; } } */ final class PropertyTagTraitUseRule implements Rule { /** * @var PropertyTagCheck */ private $check; public function __construct(\PHPStan\Rules\Classes\PropertyTagCheck $check) { $this->check = $check; } public function getNodeType() : string { return InTraitNode::class; } public function processNode(Node $node, Scope $scope) : array { return $this->check->checkInTraitUseContext($node->getTraitReflection(), $node->getImplementingClassReflection(), $node->getOriginalNode()); } } */ final class MethodTagTraitRule implements Rule { /** * @var MethodTagCheck */ private $check; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Classes\MethodTagCheck $check, ReflectionProvider $reflectionProvider) { $this->check = $check; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Stmt\Trait_::class; } public function processNode(Node $node, Scope $scope) : array { $traitName = $node->namespacedName; if ($traitName === null) { return []; } if (!$this->reflectionProvider->hasClass($traitName->toString())) { return []; } return $this->check->checkInTraitDefinitionContext($this->reflectionProvider->getClass($traitName->toString())); } } */ final class LocalTypeTraitUseAliasesRule implements Rule { /** * @var LocalTypeAliasesCheck */ private $check; public function __construct(\PHPStan\Rules\Classes\LocalTypeAliasesCheck $check) { $this->check = $check; } public function getNodeType() : string { return InTraitNode::class; } public function processNode(Node $node, Scope $scope) : array { return $this->check->checkInTraitUseContext($node->getTraitReflection(), $node->getImplementingClassReflection(), $node->getOriginalNode()); } } */ final class AccessPrivateConstantThroughStaticRule implements Rule { public function getNodeType() : string { return Node\Expr\ClassConstFetch::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier) { return []; } if (!$node->class instanceof Name) { return []; } $constantName = $node->name->name; $className = $node->class; if ($className->toLowerString() !== 'static') { return []; } $classType = $scope->resolveTypeByName($className); if (!$classType->hasConstant($constantName)->yes()) { return []; } $constant = $classType->getConstant($constantName); if (!$constant->isPrivate()) { return []; } if ($scope->isInClass() && $scope->getClassReflection()->isFinal()) { return []; } return [RuleErrorBuilder::message(sprintf('Unsafe access to private constant %s::%s through static::.', $constant->getDeclaringClass()->getDisplayName(), $constantName))->identifier('staticClassAccess.privateConstant')->build()]; } } */ final class ClassConstantAttributesRule implements Rule { /** * @var AttributesCheck */ private $attributesCheck; public function __construct(AttributesCheck $attributesCheck) { $this->attributesCheck = $attributesCheck; } public function getNodeType() : string { return Node\Stmt\ClassConst::class; } public function processNode(Node $node, Scope $scope) : array { return $this->attributesCheck->check($scope, $node->attrGroups, Attribute::TARGET_CLASS_CONSTANT, 'class constant'); } } */ final class NonClassAttributeClassRule implements Rule { public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $originalNode = $node->getOriginalNode(); foreach ($originalNode->attrGroups as $attrGroup) { foreach ($attrGroup->attrs as $attr) { $name = $attr->name->toLowerString(); if ($name === 'attribute') { return $this->check($scope); } } } return []; } /** * @return list */ private function check(Scope $scope) : array { if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } $classReflection = $scope->getClassReflection(); if (!$classReflection->isClass()) { return [RuleErrorBuilder::message(sprintf('%s cannot be an Attribute class.', $classReflection->getClassTypeDescription()))->identifier(sprintf('attribute.%s', strtolower($classReflection->getClassTypeDescription())))->build()]; } if ($classReflection->isAbstract()) { return [RuleErrorBuilder::message(sprintf('Abstract class %s cannot be an Attribute class.', $classReflection->getDisplayName()))->identifier('attribute.abstract')->build()]; } if (!$classReflection->hasConstructor()) { return []; } if (!$classReflection->getConstructor()->isPublic()) { return [RuleErrorBuilder::message(sprintf('Attribute class %s constructor must be public.', $classReflection->getDisplayName()))->identifier('attribute.constructorNotPublic')->build()]; } return []; } } */ final class MethodTagRule implements Rule { /** * @var MethodTagCheck */ private $check; public function __construct(\PHPStan\Rules\Classes\MethodTagCheck $check) { $this->check = $check; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { return $this->check->check($node->getClassReflection(), $node->getOriginalNode()); } } */ final class ClassAttributesRule implements Rule { /** * @var AttributesCheck */ private $attributesCheck; public function __construct(AttributesCheck $attributesCheck) { $this->attributesCheck = $attributesCheck; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classLikeNode = $node->getOriginalNode(); return $this->attributesCheck->check($scope, $classLikeNode->attrGroups, Attribute::TARGET_CLASS, 'class'); } } */ final class TraitAttributeClassRule implements Rule { public function getNodeType() : string { return Node\Stmt\Trait_::class; } public function processNode(Node $node, Scope $scope) : array { foreach ($node->attrGroups as $attrGroup) { foreach ($attrGroup->attrs as $attr) { $name = $attr->name->toLowerString(); if ($name === 'attribute') { return [RuleErrorBuilder::message('Trait cannot be an Attribute class.')->identifier('attribute.trait')->build()]; } } } return []; } } reflectionProvider = $reflectionProvider; $this->classCheck = $classCheck; $this->genericObjectTypeCheck = $genericObjectTypeCheck; $this->missingTypehintCheck = $missingTypehintCheck; $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; $this->checkMissingTypehints = $checkMissingTypehints; } /** * @return list */ public function check(ClassReflection $classReflection, ClassLike $node) : array { $errors = []; foreach ($classReflection->getMethodTags() as $methodName => $methodTag) { $i = 0; foreach ($methodTag->getParameters() as $parameterName => $parameterTag) { $i++; $parameterDescription = sprintf('parameter #%d $%s', $i, $parameterName); foreach ($this->checkMethodTypeInTraitDefinitionContext($classReflection, $methodName, $parameterDescription, $parameterTag->getType()) as $error) { $errors[] = $error; } foreach ($this->checkMethodTypeInTraitUseContext($classReflection, $methodName, $parameterDescription, $parameterTag->getType(), $node) as $error) { $errors[] = $error; } if ($parameterTag->getDefaultValue() === null) { continue; } $defaultValueDescription = sprintf('%s default value', $parameterDescription); foreach ($this->checkMethodTypeInTraitDefinitionContext($classReflection, $methodName, $defaultValueDescription, $parameterTag->getDefaultValue()) as $error) { $errors[] = $error; } foreach ($this->checkMethodTypeInTraitUseContext($classReflection, $methodName, $defaultValueDescription, $parameterTag->getDefaultValue(), $node) as $error) { $errors[] = $error; } } $returnTypeDescription = 'return type'; foreach ($this->checkMethodTypeInTraitDefinitionContext($classReflection, $methodName, $returnTypeDescription, $methodTag->getReturnType()) as $error) { $errors[] = $error; } foreach ($this->checkMethodTypeInTraitUseContext($classReflection, $methodName, $returnTypeDescription, $methodTag->getReturnType(), $node) as $error) { $errors[] = $error; } } return $errors; } /** * @return list */ public function checkInTraitDefinitionContext(ClassReflection $classReflection) : array { $errors = []; foreach ($classReflection->getMethodTags() as $methodName => $methodTag) { $i = 0; foreach ($methodTag->getParameters() as $parameterName => $parameterTag) { $i++; $parameterDescription = sprintf('parameter #%d $%s', $i, $parameterName); foreach ($this->checkMethodTypeInTraitDefinitionContext($classReflection, $methodName, $parameterDescription, $parameterTag->getType()) as $error) { $errors[] = $error; } if ($parameterTag->getDefaultValue() === null) { continue; } $defaultValueDescription = sprintf('%s default value', $parameterDescription); foreach ($this->checkMethodTypeInTraitDefinitionContext($classReflection, $methodName, $defaultValueDescription, $parameterTag->getDefaultValue()) as $error) { $errors[] = $error; } } $returnTypeDescription = 'return type'; foreach ($this->checkMethodTypeInTraitDefinitionContext($classReflection, $methodName, $returnTypeDescription, $methodTag->getReturnType()) as $error) { $errors[] = $error; } } return $errors; } /** * @return list */ public function checkInTraitUseContext(ClassReflection $classReflection, ClassReflection $implementingClass, ClassLike $node) : array { $phpDoc = $classReflection->getTraitContextResolvedPhpDoc($implementingClass); if ($phpDoc === null) { return []; } $errors = []; foreach ($phpDoc->getMethodTags() as $methodName => $methodTag) { $i = 0; foreach ($methodTag->getParameters() as $parameterName => $parameterTag) { $i++; $parameterDescription = sprintf('parameter #%d $%s', $i, $parameterName); foreach ($this->checkMethodTypeInTraitUseContext($classReflection, $methodName, $parameterDescription, $parameterTag->getType(), $node) as $error) { $errors[] = $error; } if ($parameterTag->getDefaultValue() === null) { continue; } $defaultValueDescription = sprintf('%s default value', $parameterDescription); foreach ($this->checkMethodTypeInTraitUseContext($classReflection, $methodName, $defaultValueDescription, $parameterTag->getDefaultValue(), $node) as $error) { $errors[] = $error; } } $returnTypeDescription = 'return type'; foreach ($this->checkMethodTypeInTraitUseContext($classReflection, $methodName, $returnTypeDescription, $methodTag->getReturnType(), $node) as $error) { $errors[] = $error; } } return $errors; } /** * @return list */ private function checkMethodTypeInTraitDefinitionContext(ClassReflection $classReflection, string $methodName, string $description, Type $type) : array { if (!$this->checkMissingTypehints) { return []; } $errors = []; foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($type) as [$innerName, $genericTypeNames]) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @method for method %s::%s() %s contains generic %s but does not specify its types: %s', $classReflection->getDisplayName(), $methodName, $description, $innerName, $genericTypeNames))->identifier('missingType.generics')->build(); } foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($type) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $errors[] = RuleErrorBuilder::message(sprintf('%s %s has PHPDoc tag @method for method %s() %s with no value type specified in iterable type %s.', $classReflection->getClassTypeDescription(), $classReflection->getDisplayName(), $methodName, $description, $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } foreach ($this->missingTypehintCheck->getCallablesWithMissingSignature($type) as $callableType) { $errors[] = RuleErrorBuilder::message(sprintf('%s %s has PHPDoc tag @method for method %s() %s with no signature specified for %s.', $classReflection->getClassTypeDescription(), $classReflection->getDisplayName(), $methodName, $description, $callableType->describe(VerbosityLevel::typeOnly())))->identifier('missingType.callable')->build(); } return $errors; } /** * @return list */ private function checkMethodTypeInTraitUseContext(ClassReflection $classReflection, string $methodName, string $description, Type $type, ClassLike $node) : array { $errors = []; foreach ($type->getReferencedClasses() as $class) { if (!$this->reflectionProvider->hasClass($class)) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @method for method %s::%s() %s contains unknown class %s.', $classReflection->getDisplayName(), $methodName, $description, $class))->identifier('class.notFound')->discoveringSymbolsTip()->build(); } elseif ($this->reflectionProvider->getClass($class)->isTrait()) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @method for method %s::%s() %s contains invalid type %s.', $classReflection->getDisplayName(), $methodName, $description, $class))->identifier('methodTag.trait')->build(); } else { $errors = array_merge($errors, $this->classCheck->checkClassNames([new ClassNameNodePair($class, $node)], $this->checkClassCaseSensitivity)); } } if ($this->unresolvableTypeHelper->containsUnresolvableType($type)) { $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @method for method %s::%s() %s contains unresolvable type.', $classReflection->getDisplayName(), $methodName, $description))->identifier('methodTag.unresolvableType')->build(); } $escapedClassName = SprintfHelper::escapeFormatString($classReflection->getDisplayName()); $escapedMethodName = SprintfHelper::escapeFormatString($methodName); $escapedDescription = SprintfHelper::escapeFormatString($description); return array_merge($errors, $this->genericObjectTypeCheck->check($type, sprintf('PHPDoc tag @method for method %s::%s() %s contains generic type %%s but %%s %%s is not generic.', $escapedClassName, $escapedMethodName, $escapedDescription), sprintf('Generic type %%s in PHPDoc tag @method for method %s::%s() %s does not specify all template types of %%s %%s: %%s', $escapedClassName, $escapedMethodName, $escapedDescription), sprintf('Generic type %%s in PHPDoc tag @method for method %s::%s() %s specifies %%d template types, but %%s %%s supports only %%d: %%s', $escapedClassName, $escapedMethodName, $escapedDescription), sprintf('Type %%s in generic type %%s in PHPDoc tag @method for method %s::%s() %s is not subtype of template type %%s of %%s %%s.', $escapedClassName, $escapedMethodName, $escapedDescription), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag @method for method %s::%s() %s is in conflict with %%s template type %%s of %%s %%s.', $escapedClassName, $escapedMethodName, $escapedDescription), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag @method for method %s::%s() %s is redundant, template type %%s of %%s %%s has the same variance.', $escapedClassName, $escapedMethodName, $escapedDescription))); } } */ final class RequireExtendsRule implements Rule { public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); if ($classReflection->isInterface()) { return []; } $errors = []; foreach ($classReflection->getInterfaces() as $interface) { $extendsTags = $interface->getRequireExtendsTags(); foreach ($extendsTags as $extendsTag) { $type = $extendsTag->getType(); if (!$type instanceof ObjectType) { continue; } if ($classReflection->is($type->getClassName())) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Interface %s requires implementing class to extend %s, but %s does not.', $interface->getDisplayName(), $type->describe(VerbosityLevel::typeOnly()), $classReflection->getDisplayName()))->identifier('class.missingExtends')->build(); } } foreach ($classReflection->getTraits(\true) as $trait) { $extendsTags = $trait->getRequireExtendsTags(); foreach ($extendsTags as $extendsTag) { $type = $extendsTag->getType(); if (!$type instanceof ObjectType) { continue; } if ($classReflection->is($type->getClassName())) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Trait %s requires using class to extend %s, but %s does not.', $trait->getDisplayName(), $type->describe(VerbosityLevel::typeOnly()), $classReflection->getDisplayName()))->identifier('class.missingExtends')->build(); } } return $errors; } } */ final class InstantiationCallableRule implements Rule { public function getNodeType() : string { return InstantiationCallableNode::class; } public function processNode(Node $node, Scope $scope) : array { return [RuleErrorBuilder::message('Cannot create callable from the new operator.')->identifier('callable.notSupported')->nonIgnorable()->build()]; } } */ final class InvalidPromotedPropertiesRule implements Rule { /** * @var PhpVersion */ private $phpVersion; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function getNodeType() : string { return Node\FunctionLike::class; } public function processNode(Node $node, Scope $scope) : array { $hasPromotedProperties = \false; foreach ($node->getParams() as $param) { if ($param->flags === 0) { continue; } $hasPromotedProperties = \true; break; } if (!$hasPromotedProperties) { return []; } if (!$this->phpVersion->supportsPromotedProperties()) { return [RuleErrorBuilder::message('Promoted properties are supported only on PHP 8.0 and later.')->identifier('property.promotedNotSupported')->nonIgnorable()->build()]; } if (!$node instanceof Node\Stmt\ClassMethod || $node->name->toLowerString() !== '__construct' && $node->getAttribute('originalTraitMethodName') !== '__construct') { return [RuleErrorBuilder::message('Promoted properties can be in constructor only.')->identifier('property.invalidPromoted')->nonIgnorable()->build()]; } if ($node->getStmts() === null) { return [RuleErrorBuilder::message('Promoted properties are not allowed in abstract constructors.')->identifier('property.invalidPromoted')->nonIgnorable()->build()]; } $errors = []; foreach ($node->getParams() as $param) { if ($param->flags === 0) { continue; } if (!$param->var instanceof Node\Expr\Variable || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } if (!$param->variadic) { continue; } $propertyName = $param->var->name; $errors[] = RuleErrorBuilder::message(sprintf('Promoted property parameter $%s can not be variadic.', $propertyName))->identifier('property.invalidPromoted')->nonIgnorable()->line($param->getStartLine())->build(); } return $errors; } } */ final class InstantiationRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var FunctionCallParametersCheck */ private $check; /** * @var ClassNameCheck */ private $classCheck; public function __construct(ReflectionProvider $reflectionProvider, FunctionCallParametersCheck $check, ClassNameCheck $classCheck) { $this->reflectionProvider = $reflectionProvider; $this->check = $check; $this->classCheck = $classCheck; } public function getNodeType() : string { return New_::class; } public function processNode(Node $node, Scope $scope) : array { $errors = []; foreach ($this->getClassNames($node, $scope) as [$class, $isName]) { $errors = array_merge($errors, $this->checkClassName($class, $isName, $node, $scope)); } return $errors; } /** * @param Node\Expr\New_ $node * @return list */ private function checkClassName(string $class, bool $isName, Node $node, Scope $scope) : array { $lowercasedClass = strtolower($class); $messages = []; $isStatic = \false; if ($lowercasedClass === 'static') { if (!$scope->isInClass()) { return [RuleErrorBuilder::message(sprintf('Using %s outside of class scope.', $class))->identifier('outOfClass.static')->build()]; } $isStatic = \true; $classReflection = $scope->getClassReflection(); if (!$classReflection->isFinal()) { if (!$classReflection->hasConstructor()) { return []; } $constructor = $classReflection->getConstructor(); if (!$constructor->getPrototype()->getDeclaringClass()->isInterface() && $constructor instanceof PhpMethodReflection && !$constructor->isFinal()->yes() && !$constructor->getPrototype()->isAbstract()) { return []; } } } elseif ($lowercasedClass === 'self') { if (!$scope->isInClass()) { return [RuleErrorBuilder::message(sprintf('Using %s outside of class scope.', $class))->identifier('outOfClass.self')->build()]; } $classReflection = $scope->getClassReflection(); } elseif ($lowercasedClass === 'parent') { if (!$scope->isInClass()) { return [RuleErrorBuilder::message(sprintf('Using %s outside of class scope.', $class))->identifier('outOfClass.parent')->build()]; } if ($scope->getClassReflection()->getParentClass() === null) { return [RuleErrorBuilder::message(sprintf('%s::%s() calls new parent but %s does not extend any class.', $scope->getClassReflection()->getDisplayName(), $scope->getFunctionName(), $scope->getClassReflection()->getDisplayName()))->identifier('class.noParent')->build()]; } $classReflection = $scope->getClassReflection()->getParentClass(); } else { if (!$this->reflectionProvider->hasClass($class)) { if ($scope->isInClassExists($class)) { return []; } return [RuleErrorBuilder::message(sprintf('Instantiated class %s not found.', $class))->identifier('class.notFound')->discoveringSymbolsTip()->build()]; } $messages = $this->classCheck->checkClassNames([new ClassNameNodePair($class, $node->class)]); $classReflection = $this->reflectionProvider->getClass($class); } if ($classReflection->isEnum() && $isName) { return [RuleErrorBuilder::message(sprintf('Cannot instantiate enum %s.', $classReflection->getDisplayName()))->identifier('new.enum')->build()]; } if (!$isStatic && $classReflection->isInterface() && $isName) { return [RuleErrorBuilder::message(sprintf('Cannot instantiate interface %s.', $classReflection->getDisplayName()))->identifier('new.interface')->build()]; } if (!$isStatic && $classReflection->isAbstract() && $isName) { return [RuleErrorBuilder::message(sprintf('Instantiated class %s is abstract.', $classReflection->getDisplayName()))->identifier('new.abstract')->build()]; } if (!$isName) { return []; } if (!$classReflection->hasConstructor()) { if (count($node->getArgs()) > 0) { return array_merge($messages, [RuleErrorBuilder::message(sprintf('Class %s does not have a constructor and must be instantiated without any parameters.', $classReflection->getDisplayName()))->identifier('new.noConstructor')->build()]); } return $messages; } $constructorReflection = $classReflection->getConstructor(); if (!$scope->canCallMethod($constructorReflection)) { $messages[] = RuleErrorBuilder::message(sprintf('Cannot instantiate class %s via %s constructor %s::%s().', $classReflection->getDisplayName(), $constructorReflection->isPrivate() ? 'private' : 'protected', $constructorReflection->getDeclaringClass()->getDisplayName(), $constructorReflection->getName()))->identifier(sprintf('new.%sConstructor', $constructorReflection->isPrivate() ? 'private' : 'protected'))->build(); } $classDisplayName = SprintfHelper::escapeFormatString($classReflection->getDisplayName()); return array_merge($messages, $this->check->check(ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $constructorReflection->getVariants(), $constructorReflection->getNamedArgumentsVariants()), $scope, $constructorReflection->getDeclaringClass()->isBuiltin(), $node, [ 'Class ' . $classDisplayName . ' constructor invoked with %d parameter, %d required.', 'Class ' . $classDisplayName . ' constructor invoked with %d parameters, %d required.', 'Class ' . $classDisplayName . ' constructor invoked with %d parameter, at least %d required.', 'Class ' . $classDisplayName . ' constructor invoked with %d parameters, at least %d required.', 'Class ' . $classDisplayName . ' constructor invoked with %d parameter, %d-%d required.', 'Class ' . $classDisplayName . ' constructor invoked with %d parameters, %d-%d required.', 'Parameter %s of class ' . $classDisplayName . ' constructor expects %s, %s given.', '', // constructor does not have a return type 'Parameter %s of class ' . $classDisplayName . ' constructor is passed by reference, so it expects variables only', 'Unable to resolve the template type %s in instantiation of class ' . $classDisplayName, 'Missing parameter $%s in call to ' . $classDisplayName . ' constructor.', 'Unknown parameter $%s in call to ' . $classDisplayName . ' constructor.', 'Return type of call to ' . $classDisplayName . ' constructor contains unresolvable type.', 'Parameter %s of class ' . $classDisplayName . ' constructor contains unresolvable type.', 'Class ' . $classDisplayName . ' constructor invoked with %s, but it\'s not allowed because of @no-named-arguments.', ], 'new', $constructorReflection->acceptsNamedArguments())); } /** * @param Node\Expr\New_ $node * @return array */ private function getClassNames(Node $node, Scope $scope) : array { if ($node->class instanceof Node\Name) { return [[(string) $node->class, \true]]; } if ($node->class instanceof Node\Stmt\Class_) { $classNames = $scope->getType($node)->getObjectClassNames(); if ($classNames === []) { throw new ShouldNotHappenException(); } return array_map(static function (string $className) { return [$className, \true]; }, $classNames); } $type = $scope->getType($node->class); return array_merge(array_map(static function (ConstantStringType $type) : array { return [$type->getValue(), \true]; }, $type->getConstantStrings()), array_map(static function (string $name) : array { return [$name, \false]; }, $type->getObjectClassNames())); } } */ final class ExistingClassesInClassImplementsRule implements Rule { /** * @var ClassNameCheck */ private $classCheck; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ClassNameCheck $classCheck, ReflectionProvider $reflectionProvider) { $this->classCheck = $classCheck; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Stmt\Class_::class; } public function processNode(Node $node, Scope $scope) : array { $messages = $this->classCheck->checkClassNames(array_map(static function (Node\Name $interfaceName) : ClassNameNodePair { return new ClassNameNodePair((string) $interfaceName, $interfaceName); }, $node->implements)); $currentClassName = null; if (isset($node->namespacedName)) { $currentClassName = (string) $node->namespacedName; } foreach ($node->implements as $implements) { $implementedClassName = (string) $implements; if (!$this->reflectionProvider->hasClass($implementedClassName)) { if (!$scope->isInClassExists($implementedClassName)) { $messages[] = RuleErrorBuilder::message(sprintf('%s implements unknown interface %s.', $currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class', $implementedClassName))->identifier('interface.notFound')->nonIgnorable()->discoveringSymbolsTip()->build(); } } else { $reflection = $this->reflectionProvider->getClass($implementedClassName); if ($reflection->isClass()) { $messages[] = RuleErrorBuilder::message(sprintf('%s implements class %s.', $currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class', $reflection->getDisplayName()))->identifier('classImplements.class')->nonIgnorable()->build(); } elseif ($reflection->isTrait()) { $messages[] = RuleErrorBuilder::message(sprintf('%s implements trait %s.', $currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class', $reflection->getDisplayName()))->identifier('classImplements.trait')->nonIgnorable()->build(); } elseif ($reflection->isEnum()) { $messages[] = RuleErrorBuilder::message(sprintf('%s implements enum %s.', $currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class', $reflection->getDisplayName()))->identifier('classImplements.enum')->nonIgnorable()->build(); } } } return $messages; } } */ final class RequireImplementsRule implements Rule { public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); $errors = []; foreach ($classReflection->getTraits(\true) as $trait) { $implementsTags = $trait->getRequireImplementsTags(); foreach ($implementsTags as $implementsTag) { $type = $implementsTag->getType(); if (!$type instanceof ObjectType) { continue; } if ($classReflection->implementsInterface($type->getClassName())) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Trait %s requires using class to implement %s, but %s does not.', $trait->getDisplayName(), $type->describe(VerbosityLevel::typeOnly()), $classReflection->getDisplayName()))->identifier('class.missingImplements')->build(); } } return $errors; } } */ final class ExistingClassesInEnumImplementsRule implements Rule { /** * @var ClassNameCheck */ private $classCheck; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ClassNameCheck $classCheck, ReflectionProvider $reflectionProvider) { $this->classCheck = $classCheck; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Stmt\Enum_::class; } public function processNode(Node $node, Scope $scope) : array { $messages = $this->classCheck->checkClassNames(array_map(static function (Node\Name $interfaceName) : ClassNameNodePair { return new ClassNameNodePair((string) $interfaceName, $interfaceName); }, $node->implements)); $currentEnumName = (string) $node->namespacedName; foreach ($node->implements as $implements) { $implementedClassName = (string) $implements; if (!$this->reflectionProvider->hasClass($implementedClassName)) { if (!$scope->isInClassExists($implementedClassName)) { $messages[] = RuleErrorBuilder::message(sprintf('Enum %s implements unknown interface %s.', $currentEnumName, $implementedClassName))->identifier('interface.notFound')->nonIgnorable()->discoveringSymbolsTip()->build(); } } else { $reflection = $this->reflectionProvider->getClass($implementedClassName); if ($reflection->isClass()) { $messages[] = RuleErrorBuilder::message(sprintf('Enum %s implements class %s.', $currentEnumName, $reflection->getDisplayName()))->identifier('enumImplements.class')->nonIgnorable()->build(); } elseif ($reflection->isTrait()) { $messages[] = RuleErrorBuilder::message(sprintf('Enum %s implements trait %s.', $currentEnumName, $reflection->getDisplayName()))->identifier('enumImplements.trait')->nonIgnorable()->build(); } elseif ($reflection->isEnum()) { $messages[] = RuleErrorBuilder::message(sprintf('Enum %s implements enum %s.', $currentEnumName, $reflection->getDisplayName()))->identifier('enumImplements.enum')->nonIgnorable()->build(); } } } return $messages; } } */ final class LocalTypeAliasesRule implements Rule { /** * @var LocalTypeAliasesCheck */ private $check; public function __construct(\PHPStan\Rules\Classes\LocalTypeAliasesCheck $check) { $this->check = $check; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { return $this->check->check($node->getClassReflection(), $node->getOriginalNode()); } } */ final class DuplicateDeclarationRule implements Rule { public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); $identifierType = strtolower($classReflection->getClassTypeDescription()); $errors = []; $declaredClassConstantsOrEnumCases = []; foreach ($node->getOriginalNode()->stmts as $stmtNode) { if ($stmtNode instanceof EnumCase) { if (array_key_exists($stmtNode->name->name, $declaredClassConstantsOrEnumCases)) { $errors[] = RuleErrorBuilder::message(sprintf('Cannot redeclare enum case %s::%s.', $classReflection->getDisplayName(), $stmtNode->name->name))->identifier(sprintf('%s.duplicateEnumCase', $identifierType))->line($stmtNode->getStartLine())->nonIgnorable()->build(); } else { $declaredClassConstantsOrEnumCases[$stmtNode->name->name] = \true; } } elseif ($stmtNode instanceof ClassConst) { foreach ($stmtNode->consts as $classConstNode) { if (array_key_exists($classConstNode->name->name, $declaredClassConstantsOrEnumCases)) { $errors[] = RuleErrorBuilder::message(sprintf('Cannot redeclare constant %s::%s.', $classReflection->getDisplayName(), $classConstNode->name->name))->identifier(sprintf('%s.duplicateConstant', $identifierType))->line($classConstNode->getStartLine())->nonIgnorable()->build(); } else { $declaredClassConstantsOrEnumCases[$classConstNode->name->name] = \true; } } } } $declaredProperties = []; foreach ($node->getOriginalNode()->getProperties() as $propertyDecl) { foreach ($propertyDecl->props as $property) { if (array_key_exists($property->name->name, $declaredProperties)) { $errors[] = RuleErrorBuilder::message(sprintf('Cannot redeclare property %s::$%s.', $classReflection->getDisplayName(), $property->name->name))->identifier(sprintf('%s.duplicateProperty', $identifierType))->line($property->getStartLine())->nonIgnorable()->build(); } else { $declaredProperties[$property->name->name] = \true; } } } $declaredFunctions = []; foreach ($node->getOriginalNode()->getMethods() as $method) { if ($method->name->toLowerString() === '__construct') { foreach ($method->params as $param) { if ($param->flags === 0) { continue; } if (!$param->var instanceof Node\Expr\Variable || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } $propertyName = $param->var->name; if (array_key_exists($propertyName, $declaredProperties)) { $errors[] = RuleErrorBuilder::message(sprintf('Cannot redeclare property %s::$%s.', $classReflection->getDisplayName(), $propertyName))->identifier(sprintf('%s.duplicateProperty', $identifierType))->line($param->getStartLine())->nonIgnorable()->build(); } else { $declaredProperties[$propertyName] = \true; } } } if (array_key_exists(strtolower($method->name->name), $declaredFunctions)) { $errors[] = RuleErrorBuilder::message(sprintf('Cannot redeclare method %s::%s().', $classReflection->getDisplayName(), $method->name->name))->identifier(sprintf('%s.duplicateMethod', $identifierType))->line($method->getStartLine())->nonIgnorable()->build(); } else { $declaredFunctions[strtolower($method->name->name)] = \true; } } return $errors; } } */ final class ExistingClassInTraitUseRule implements Rule { /** * @var ClassNameCheck */ private $classCheck; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ClassNameCheck $classCheck, ReflectionProvider $reflectionProvider) { $this->classCheck = $classCheck; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Stmt\TraitUse::class; } public function processNode(Node $node, Scope $scope) : array { $messages = $this->classCheck->checkClassNames(array_map(static function (Node\Name $traitName) : ClassNameNodePair { return new ClassNameNodePair((string) $traitName, $traitName); }, $node->traits)); if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } $classReflection = $scope->getClassReflection(); if ($classReflection->isInterface()) { if (!$scope->isInTrait()) { foreach ($node->traits as $trait) { $messages[] = RuleErrorBuilder::message(sprintf('Interface %s uses trait %s.', $classReflection->getName(), (string) $trait))->identifier('interface.traitUse')->nonIgnorable()->build(); } } } else { if ($scope->isInTrait()) { $currentName = sprintf('Trait %s', $scope->getTraitReflection()->getName()); } else { if ($classReflection->isAnonymous()) { $currentName = 'Anonymous class'; } else { $currentName = sprintf('Class %s', $classReflection->getName()); } } foreach ($node->traits as $trait) { $traitName = (string) $trait; if (!$this->reflectionProvider->hasClass($traitName)) { $messages[] = RuleErrorBuilder::message(sprintf('%s uses unknown trait %s.', $currentName, $traitName))->identifier('trait.notFound')->nonIgnorable()->discoveringSymbolsTip()->build(); } else { $reflection = $this->reflectionProvider->getClass($traitName); if ($reflection->isClass()) { $messages[] = RuleErrorBuilder::message(sprintf('%s uses class %s.', $currentName, $reflection->getDisplayName()))->identifier('traitUse.class')->nonIgnorable()->build(); } elseif ($reflection->isInterface()) { $messages[] = RuleErrorBuilder::message(sprintf('%s uses interface %s.', $currentName, $reflection->getDisplayName()))->identifier('traitUse.interface')->nonIgnorable()->build(); } elseif ($reflection->isEnum()) { $messages[] = RuleErrorBuilder::message(sprintf('%s uses enum %s.', $currentName, $reflection->getDisplayName()))->identifier('traitUse.enum')->nonIgnorable()->build(); } } } } return $messages; } } */ final class EnumSanityRule implements Rule { private const ALLOWED_MAGIC_METHODS = ['__call' => \true, '__callstatic' => \true, '__invoke' => \true]; public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); if (!$classReflection->isEnum()) { return []; } /** @var Node\Stmt\Enum_ $enumNode */ $enumNode = $node->getOriginalNode(); $errors = []; foreach ($enumNode->getMethods() as $methodNode) { $lowercasedMethodName = $methodNode->name->toLowerString(); if ($methodNode->isMagic()) { if ($lowercasedMethodName === '__construct') { $errors[] = RuleErrorBuilder::message(sprintf('Enum %s contains constructor.', $classReflection->getDisplayName()))->identifier('enum.constructor')->line($methodNode->getStartLine())->nonIgnorable()->build(); } elseif ($lowercasedMethodName === '__destruct') { $errors[] = RuleErrorBuilder::message(sprintf('Enum %s contains destructor.', $classReflection->getDisplayName()))->identifier('enum.destructor')->line($methodNode->getStartLine())->nonIgnorable()->build(); } elseif (!array_key_exists($lowercasedMethodName, self::ALLOWED_MAGIC_METHODS)) { $errors[] = RuleErrorBuilder::message(sprintf('Enum %s contains magic method %s().', $classReflection->getDisplayName(), $methodNode->name->name))->identifier('enum.magicMethod')->line($methodNode->getStartLine())->nonIgnorable()->build(); } } if ($lowercasedMethodName === 'cases') { $errors[] = RuleErrorBuilder::message(sprintf('Enum %s cannot redeclare native method %s().', $classReflection->getDisplayName(), $methodNode->name->name))->identifier('enum.methodRedeclaration')->line($methodNode->getStartLine())->nonIgnorable()->build(); } if ($enumNode->scalarType === null) { continue; } if (!in_array($lowercasedMethodName, ['from', 'tryfrom'], \true)) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Enum %s cannot redeclare native method %s().', $classReflection->getDisplayName(), $methodNode->name->name))->identifier('enum.methodRedeclaration')->line($methodNode->getStartLine())->nonIgnorable()->build(); } if ($enumNode->scalarType !== null && !in_array($enumNode->scalarType->name, ['int', 'string'], \true)) { $errors[] = RuleErrorBuilder::message(sprintf('Backed enum %s can have only "int" or "string" type.', $classReflection->getDisplayName()))->identifier('enum.backingType')->line($enumNode->scalarType->getStartLine())->nonIgnorable()->build(); } if ($classReflection->implementsInterface(Serializable::class)) { $errors[] = RuleErrorBuilder::message(sprintf('Enum %s cannot implement the Serializable interface.', $classReflection->getDisplayName()))->identifier('enum.serializable')->line($enumNode->getStartLine())->nonIgnorable()->build(); } $enumCases = []; foreach ($enumNode->stmts as $stmt) { if (!$stmt instanceof Node\Stmt\EnumCase) { continue; } $caseName = $stmt->name->name; if ($stmt->expr instanceof Node\Scalar\LNumber || $stmt->expr instanceof Node\Scalar\String_) { if ($enumNode->scalarType === null) { $errors[] = RuleErrorBuilder::message(sprintf('Enum %s is not backed, but case %s has value %s.', $classReflection->getDisplayName(), $caseName, $stmt->expr->value))->identifier('enum.caseWithValue')->line($stmt->getStartLine())->nonIgnorable()->build(); } else { $caseValue = $stmt->expr->value; if (!isset($enumCases[$caseValue])) { $enumCases[$caseValue] = []; } $enumCases[$caseValue][] = $caseName; } } if ($enumNode->scalarType === null) { continue; } if ($stmt->expr === null) { $errors[] = RuleErrorBuilder::message(sprintf('Enum case %s::%s does not have a value but the enum is backed with the "%s" type.', $classReflection->getDisplayName(), $caseName, $enumNode->scalarType->name))->identifier('enum.missingCase')->line($stmt->getStartLine())->nonIgnorable()->build(); continue; } $exprType = $scope->getType($stmt->expr); $scalarType = $enumNode->scalarType->toLowerString() === 'int' ? new IntegerType() : new StringType(); if ($scalarType->isSuperTypeOf($exprType)->yes()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Enum case %s::%s value %s does not match the "%s" type.', $classReflection->getDisplayName(), $caseName, $exprType->describe(VerbosityLevel::value()), $scalarType->describe(VerbosityLevel::typeOnly())))->identifier('enum.caseType')->line($stmt->getStartLine())->nonIgnorable()->build(); } foreach ($enumCases as $caseValue => $caseNames) { if (count($caseNames) <= 1) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Enum %s has duplicate value %s for cases %s.', $classReflection->getDisplayName(), $caseValue, implode(', ', $caseNames)))->identifier('enum.duplicateValue')->line($enumNode->getStartLine())->nonIgnorable()->build(); } return $errors; } } */ final class ExistingClassInClassExtendsRule implements Rule { /** * @var ClassNameCheck */ private $classCheck; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ClassNameCheck $classCheck, ReflectionProvider $reflectionProvider) { $this->classCheck = $classCheck; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Stmt\Class_::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->extends === null) { return []; } $extendedClassName = (string) $node->extends; $messages = $this->classCheck->checkClassNames([new ClassNameNodePair($extendedClassName, $node->extends)]); $currentClassName = null; if (isset($node->namespacedName)) { $currentClassName = (string) $node->namespacedName; } if (!$this->reflectionProvider->hasClass($extendedClassName)) { if (!$scope->isInClassExists($extendedClassName)) { $messages[] = RuleErrorBuilder::message(sprintf('%s extends unknown class %s.', $currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class', $extendedClassName))->identifier('class.notFound')->nonIgnorable()->discoveringSymbolsTip()->build(); } } else { $reflection = $this->reflectionProvider->getClass($extendedClassName); if ($reflection->isInterface()) { $messages[] = RuleErrorBuilder::message(sprintf('%s extends interface %s.', $currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class', $reflection->getDisplayName()))->identifier('class.extendsInterface')->nonIgnorable()->build(); } elseif ($reflection->isTrait()) { $messages[] = RuleErrorBuilder::message(sprintf('%s extends trait %s.', $currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class', $reflection->getDisplayName()))->identifier('class.extendsTrait')->nonIgnorable()->build(); } elseif ($reflection->isEnum()) { $messages[] = RuleErrorBuilder::message(sprintf('%s extends enum %s.', $currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class', $reflection->getDisplayName()))->identifier('class.extendsEnum')->nonIgnorable()->build(); } elseif ($reflection->isFinalByKeyword()) { $messages[] = RuleErrorBuilder::message(sprintf('%s extends final class %s.', $currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class', $reflection->getDisplayName()))->identifier('class.extendsFinal')->nonIgnorable()->build(); } elseif ($reflection->isFinal()) { $messages[] = RuleErrorBuilder::message(sprintf('%s extends @final class %s.', $currentClassName !== null ? sprintf('Class %s', $currentClassName) : 'Anonymous class', $reflection->getDisplayName()))->identifier('class.extendsFinalByPhpDoc')->build(); } if ($reflection->isClass()) { if ($node->isReadonly()) { if (!$reflection->isReadOnly()) { $messages[] = RuleErrorBuilder::message(sprintf('%s extends non-readonly class %s.', $currentClassName !== null ? sprintf('Readonly class %s', $currentClassName) : 'Anonymous readonly class', $reflection->getDisplayName()))->identifier('class.readOnly')->nonIgnorable()->build(); } } elseif ($reflection->isReadOnly()) { $messages[] = RuleErrorBuilder::message(sprintf('%s extends readonly class %s.', $currentClassName !== null ? sprintf('Non-readonly class %s', $currentClassName) : 'Anonymous non-readonly class', $reflection->getDisplayName()))->identifier('class.nonReadOnly')->nonIgnorable()->build(); } } } return $messages; } } */ final class MethodTagTraitUseRule implements Rule { /** * @var MethodTagCheck */ private $check; public function __construct(\PHPStan\Rules\Classes\MethodTagCheck $check) { $this->check = $check; } public function getNodeType() : string { return InTraitNode::class; } public function processNode(Node $node, Scope $scope) : array { return $this->check->checkInTraitUseContext($node->getTraitReflection(), $node->getImplementingClassReflection(), $node->getOriginalNode()); } } */ final class MixinTraitUseRule implements Rule { /** * @var MixinCheck */ private $check; public function __construct(\PHPStan\Rules\Classes\MixinCheck $check) { $this->check = $check; } public function getNodeType() : string { return InTraitNode::class; } public function processNode(Node $node, Scope $scope) : array { return $this->check->checkInTraitUseContext($node->getTraitReflection(), $node->getImplementingClassReflection(), $node->getOriginalNode()); } } */ private $globalTypeAliases; /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var TypeNodeResolver */ private $typeNodeResolver; /** * @var MissingTypehintCheck */ private $missingTypehintCheck; /** * @var ClassNameCheck */ private $classCheck; /** * @var UnresolvableTypeHelper */ private $unresolvableTypeHelper; /** * @var GenericObjectTypeCheck */ private $genericObjectTypeCheck; /** * @var bool */ private $checkMissingTypehints; /** * @var bool */ private $checkClassCaseSensitivity; /** * @var bool */ private $absentTypeChecks; /** * @param array $globalTypeAliases */ public function __construct(array $globalTypeAliases, ReflectionProvider $reflectionProvider, TypeNodeResolver $typeNodeResolver, MissingTypehintCheck $missingTypehintCheck, ClassNameCheck $classCheck, UnresolvableTypeHelper $unresolvableTypeHelper, GenericObjectTypeCheck $genericObjectTypeCheck, bool $checkMissingTypehints, bool $checkClassCaseSensitivity, bool $absentTypeChecks) { $this->globalTypeAliases = $globalTypeAliases; $this->reflectionProvider = $reflectionProvider; $this->typeNodeResolver = $typeNodeResolver; $this->missingTypehintCheck = $missingTypehintCheck; $this->classCheck = $classCheck; $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->genericObjectTypeCheck = $genericObjectTypeCheck; $this->checkMissingTypehints = $checkMissingTypehints; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; $this->absentTypeChecks = $absentTypeChecks; } /** * @return list */ public function check(ClassReflection $reflection, ClassLike $node) : array { $errors = []; foreach ($this->checkInTraitDefinitionContext($reflection) as $error) { $errors[] = $error; } foreach ($this->checkInTraitUseContext($reflection, $reflection, $node) as $error) { $errors[] = $error; } return $errors; } /** * @return list */ public function checkInTraitDefinitionContext(ClassReflection $reflection) : array { $phpDoc = $reflection->getResolvedPhpDoc(); if ($phpDoc === null) { return []; } $nameScope = $phpDoc->getNullableNameScope(); $resolveName = static function (string $name) use($nameScope) : string { if ($nameScope === null) { return $name; } return $nameScope->resolveStringName($name); }; $errors = []; $className = $reflection->getDisplayName(); $importedAliases = []; foreach ($phpDoc->getTypeAliasImportTags() as $typeAliasImportTag) { $aliasName = $typeAliasImportTag->getImportedAs() ?? $typeAliasImportTag->getImportedAlias(); $importedAlias = $typeAliasImportTag->getImportedAlias(); $importedFromClassName = $typeAliasImportTag->getImportedFrom(); if (!$this->reflectionProvider->hasClass($importedFromClassName)) { $errors[] = RuleErrorBuilder::message(sprintf('Cannot import type alias %s: class %s does not exist.', $importedAlias, $importedFromClassName))->identifier('class.notFound')->build(); continue; } $importedFromReflection = $this->reflectionProvider->getClass($importedFromClassName); $typeAliases = $importedFromReflection->getTypeAliases(); if (!array_key_exists($importedAlias, $typeAliases)) { $errors[] = RuleErrorBuilder::message(sprintf('Cannot import type alias %s: type alias does not exist in %s.', $importedAlias, $importedFromClassName))->identifier('typeAlias.notFound')->build(); continue; } $resolvedName = $resolveName($aliasName); if ($this->reflectionProvider->hasClass($resolveName($aliasName))) { $classReflection = $this->reflectionProvider->getClass($resolvedName); $classLikeDescription = 'a class'; if ($classReflection->isInterface()) { $classLikeDescription = 'an interface'; } elseif ($classReflection->isTrait()) { $classLikeDescription = 'a trait'; } elseif ($classReflection->isEnum()) { $classLikeDescription = 'an enum'; } $errors[] = RuleErrorBuilder::message(sprintf('Type alias %s already exists as %s in scope of %s.', $aliasName, $classLikeDescription, $className))->identifier('typeAlias.duplicate')->build(); continue; } if (array_key_exists($aliasName, $this->globalTypeAliases)) { $errors[] = RuleErrorBuilder::message(sprintf('Type alias %s already exists as a global type alias.', $aliasName))->identifier('typeAlias.duplicate')->build(); continue; } $importedAs = $typeAliasImportTag->getImportedAs(); if ($importedAs !== null && !$this->isAliasNameValid($importedAs, $nameScope)) { $errors[] = RuleErrorBuilder::message(sprintf('Imported type alias %s has an invalid name: %s.', $importedAlias, $importedAs))->identifier('typeAlias.invalidName')->build(); continue; } $importedAliases[] = $aliasName; } foreach ($phpDoc->getTypeAliasTags() as $typeAliasTag) { $aliasName = $typeAliasTag->getAliasName(); if (in_array($aliasName, $importedAliases, \true)) { $errors[] = RuleErrorBuilder::message(sprintf('Type alias %s overwrites an imported type alias of the same name.', $aliasName))->identifier('typeAlias.duplicate')->build(); continue; } $resolvedName = $resolveName($aliasName); if ($this->reflectionProvider->hasClass($resolvedName)) { $classReflection = $this->reflectionProvider->getClass($resolvedName); $classLikeDescription = 'a class'; if ($classReflection->isInterface()) { $classLikeDescription = 'an interface'; } elseif ($classReflection->isTrait()) { $classLikeDescription = 'a trait'; } elseif ($classReflection->isEnum()) { $classLikeDescription = 'an enum'; } $errors[] = RuleErrorBuilder::message(sprintf('Type alias %s already exists as %s in scope of %s.', $aliasName, $classLikeDescription, $className))->identifier('typeAlias.duplicate')->build(); continue; } if (array_key_exists($aliasName, $this->globalTypeAliases)) { $errors[] = RuleErrorBuilder::message(sprintf('Type alias %s already exists as a global type alias.', $aliasName))->identifier('typeAlias.duplicate')->build(); continue; } if (!$this->isAliasNameValid($aliasName, $nameScope)) { $errors[] = RuleErrorBuilder::message(sprintf('Type alias has an invalid name: %s.', $aliasName))->identifier('typeAlias.invalidName')->build(); continue; } $resolvedType = $typeAliasTag->getTypeAlias()->resolve($this->typeNodeResolver); if ($this->hasErrorType($resolvedType, $aliasName, $errors)) { continue; } if (!$this->absentTypeChecks) { continue; } if (!$this->checkMissingTypehints) { continue; } foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($resolvedType) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $errors[] = RuleErrorBuilder::message(sprintf('%s %s has type alias %s with no value type specified in iterable type %s.', $reflection->getClassTypeDescription(), $reflection->getDisplayName(), $aliasName, $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($resolvedType) as [$name, $genericTypeNames]) { $errors[] = RuleErrorBuilder::message(sprintf('%s %s has type alias %s with generic %s but does not specify its types: %s', $reflection->getClassTypeDescription(), $reflection->getDisplayName(), $aliasName, $name, $genericTypeNames))->identifier('missingType.generics')->build(); } foreach ($this->missingTypehintCheck->getCallablesWithMissingSignature($resolvedType) as $callableType) { $errors[] = RuleErrorBuilder::message(sprintf('%s %s has type alias %s with no signature specified for %s.', $reflection->getClassTypeDescription(), $reflection->getDisplayName(), $aliasName, $callableType->describe(VerbosityLevel::typeOnly())))->identifier('missingType.callable')->build(); } } return $errors; } /** * @return list */ public function checkInTraitUseContext(ClassReflection $reflection, ClassReflection $implementingClassReflection, ClassLike $node) : array { if ($reflection->getNativeReflection()->getName() === $implementingClassReflection->getName()) { $phpDoc = $reflection->getResolvedPhpDoc(); } else { $phpDoc = $reflection->getTraitContextResolvedPhpDoc($implementingClassReflection); } if ($phpDoc === null) { return []; } $errors = []; foreach ($phpDoc->getTypeAliasTags() as $typeAliasTag) { $aliasName = $typeAliasTag->getAliasName(); $resolvedType = $typeAliasTag->getTypeAlias()->resolve($this->typeNodeResolver); $throwawayErrors = []; if ($this->hasErrorType($resolvedType, $aliasName, $throwawayErrors)) { continue; } foreach ($resolvedType->getReferencedClasses() as $class) { if (!$this->reflectionProvider->hasClass($class)) { $errors[] = RuleErrorBuilder::message(sprintf('Type alias %s contains unknown class %s.', $aliasName, $class))->identifier('class.notFound')->discoveringSymbolsTip()->build(); } elseif ($this->reflectionProvider->getClass($class)->isTrait()) { $errors[] = RuleErrorBuilder::message(sprintf('Type alias %s contains invalid type %s.', $aliasName, $class))->identifier('typeAlias.trait')->build(); } else { $errors = array_merge($errors, $this->classCheck->checkClassNames([new ClassNameNodePair($class, $node)], $this->checkClassCaseSensitivity)); } } if ($this->unresolvableTypeHelper->containsUnresolvableType($resolvedType)) { $errors[] = RuleErrorBuilder::message(sprintf('Type alias %s contains unresolvable type.', $aliasName))->identifier('typeAlias.unresolvableType')->build(); } $escapedTypeAlias = SprintfHelper::escapeFormatString($aliasName); $errors = array_merge($errors, $this->genericObjectTypeCheck->check($resolvedType, sprintf('Type alias %s contains generic type %%s but %%s %%s is not generic.', $escapedTypeAlias), sprintf('Generic type %%s in type alias %s does not specify all template types of %%s %%s: %%s', $escapedTypeAlias), sprintf('Generic type %%s in type alias %s specifies %%d template types, but %%s %%s supports only %%d: %%s', $escapedTypeAlias), sprintf('Type %%s in generic type %%s in type alias %s is not subtype of template type %%s of %%s %%s.', $escapedTypeAlias), sprintf('Call-site variance of %%s in generic type %%s in type alias %s is in conflict with %%s template type %%s of %%s %%s.', $escapedTypeAlias), sprintf('Call-site variance of %%s in generic type %%s in type alias %s is redundant, template type %%s of %%s %%s has the same variance.', $escapedTypeAlias))); } return $errors; } private function isAliasNameValid(string $aliasName, ?NameScope $nameScope) : bool { if ($nameScope === null) { return \true; } $aliasNameResolvedType = $this->typeNodeResolver->resolve(new IdentifierTypeNode($aliasName), $nameScope->bypassTypeAliases()); return $aliasNameResolvedType->isObject()->yes() && !in_array($aliasName, ['self', 'parent'], \true) || $aliasNameResolvedType instanceof TemplateType; // aliases take precedence over type parameters, this is reported by other rules using TemplateTypeCheck } /** * @param list $errors * @param-out list $errors */ private function hasErrorType(Type $type, string $aliasName, array &$errors) : bool { $foundError = \false; TypeTraverser::map($type, static function (Type $type, callable $traverse) use(&$errors, &$foundError, $aliasName) : Type { if ($foundError) { return $type; } if ($type instanceof CircularTypeAliasErrorType) { $errors[] = RuleErrorBuilder::message(sprintf('Circular definition detected in type alias %s.', $aliasName))->identifier('typeAlias.circular')->build(); $foundError = \true; return $type; } if ($type instanceof ErrorType) { $errors[] = RuleErrorBuilder::message(sprintf('Invalid type definition detected in type alias %s.', $aliasName))->identifier('typeAlias.invalidType')->build(); $foundError = \true; return $type; } return $traverse($type); }); return $foundError; } } */ final class MixinRule implements Rule { /** * @var MixinCheck */ private $check; public function __construct(\PHPStan\Rules\Classes\MixinCheck $check) { $this->check = $check; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { return $this->check->check($node->getClassReflection(), $node->getOriginalNode()); } } */ final class LocalTypeTraitAliasesRule implements Rule { /** * @var LocalTypeAliasesCheck */ private $check; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Classes\LocalTypeAliasesCheck $check, ReflectionProvider $reflectionProvider) { $this->check = $check; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Stmt\Trait_::class; } public function processNode(Node $node, Scope $scope) : array { $traitName = $node->namespacedName; if ($traitName === null) { return []; } if (!$this->reflectionProvider->hasClass($traitName->toString())) { return []; } return $this->check->checkInTraitDefinitionContext($this->reflectionProvider->getClass($traitName->toString())); } } */ final class InvalidTypesInUnionRule implements Rule { private const ONLY_STANDALONE_TYPES = ['mixed', 'never', 'void']; public function getNodeType() : string { return Node::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof Node\FunctionLike && !$node instanceof ClassPropertyNode) { return []; } if ($node instanceof Node\FunctionLike) { return $this->processFunctionLikeNode($node); } return $this->processClassPropertyNode($node); } /** * @return list */ private function processFunctionLikeNode(Node\FunctionLike $functionLike) : array { $errors = []; foreach ($functionLike->getParams() as $param) { if (!$param->type instanceof Node\ComplexType) { continue; } $errors = array_merge($errors, $this->processComplexType($param->type)); } if ($functionLike->getReturnType() instanceof Node\ComplexType) { $errors = array_merge($errors, $this->processComplexType($functionLike->getReturnType())); } return $errors; } /** * @return list */ private function processClassPropertyNode(ClassPropertyNode $classPropertyNode) : array { if (!$classPropertyNode->getNativeType() instanceof Node\ComplexType) { return []; } return $this->processComplexType($classPropertyNode->getNativeType()); } /** * @return list */ private function processComplexType(Node\ComplexType $complexType) : array { if (!$complexType instanceof Node\UnionType && !$complexType instanceof Node\NullableType) { return []; } if ($complexType instanceof Node\UnionType) { foreach ($complexType->types as $type) { if (!$type instanceof Node\Identifier) { continue; } $typeString = $type->toLowerString(); if (in_array($typeString, self::ONLY_STANDALONE_TYPES, \true)) { return [RuleErrorBuilder::message(sprintf('Type %s cannot be part of a union type declaration.', $type->toString()))->line($complexType->getStartLine())->identifier(sprintf('unionType.%s', $typeString))->nonIgnorable()->build()]; } } return []; } if ($complexType->type instanceof Node\Identifier) { $complexTypeString = $complexType->type->toLowerString(); if (in_array($complexTypeString, self::ONLY_STANDALONE_TYPES, \true)) { return [RuleErrorBuilder::message(sprintf('Type %s cannot be part of a nullable type declaration.', $complexType->type->toString()))->line($complexType->getStartLine())->identifier(sprintf('nullableType.%s', $complexTypeString))->nonIgnorable()->build()]; } } return []; } } */ final class YieldFromTypeRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var bool */ private $reportMaybes; public function __construct(RuleLevelHelper $ruleLevelHelper, bool $reportMaybes) { $this->ruleLevelHelper = $ruleLevelHelper; $this->reportMaybes = $reportMaybes; } public function getNodeType() : string { return YieldFrom::class; } public function processNode(Node $node, Scope $scope) : array { $exprType = $scope->getType($node->expr); $isIterable = $exprType->isIterable(); $messagePattern = 'Argument of an invalid type %s passed to yield from, only iterables are supported.'; if ($isIterable->no()) { return [RuleErrorBuilder::message(sprintf($messagePattern, $exprType->describe(VerbosityLevel::typeOnly())))->line($node->expr->getStartLine())->identifier('generator.nonIterable')->build()]; } elseif (!$exprType instanceof MixedType && $this->reportMaybes && $isIterable->maybe()) { return [RuleErrorBuilder::message(sprintf($messagePattern, $exprType->describe(VerbosityLevel::typeOnly())))->line($node->expr->getStartLine())->identifier('generator.nonIterable')->build()]; } $anonymousFunctionReturnType = $scope->getAnonymousFunctionReturnType(); $scopeFunction = $scope->getFunction(); if ($anonymousFunctionReturnType !== null) { $returnType = $anonymousFunctionReturnType; } elseif ($scopeFunction !== null) { $returnType = $scopeFunction->getReturnType(); } else { return []; // already reported by YieldInGeneratorRule } if ($returnType instanceof MixedType) { return []; } $messages = []; $acceptsKey = $this->ruleLevelHelper->acceptsWithReason($returnType->getIterableKeyType(), $exprType->getIterableKeyType(), $scope->isDeclareStrictTypes()); if (!$acceptsKey->result) { $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($returnType->getIterableKeyType(), $exprType->getIterableKeyType()); $messages[] = RuleErrorBuilder::message(sprintf('Generator expects key type %s, %s given.', $returnType->getIterableKeyType()->describe($verbosityLevel), $exprType->getIterableKeyType()->describe($verbosityLevel)))->line($node->expr->getStartLine())->identifier('generator.keyType')->acceptsReasonsTip($acceptsKey->reasons)->build(); } $acceptsValue = $this->ruleLevelHelper->acceptsWithReason($returnType->getIterableValueType(), $exprType->getIterableValueType(), $scope->isDeclareStrictTypes()); if (!$acceptsValue->result) { $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($returnType->getIterableValueType(), $exprType->getIterableValueType()); $messages[] = RuleErrorBuilder::message(sprintf('Generator expects value type %s, %s given.', $returnType->getIterableValueType()->describe($verbosityLevel), $exprType->getIterableValueType()->describe($verbosityLevel)))->line($node->expr->getStartLine())->identifier('generator.valueType')->acceptsReasonsTip($acceptsValue->reasons)->build(); } $scopeFunction = $scope->getFunction(); if ($scopeFunction === null) { return $messages; } $currentReturnType = $scopeFunction->getReturnType(); $exprSendType = $exprType->getTemplateType(Generator::class, 'TSend'); $thisSendType = $currentReturnType->getTemplateType(Generator::class, 'TSend'); if ($exprSendType instanceof ErrorType || $thisSendType instanceof ErrorType) { return $messages; } $isSuperType = $exprSendType->isSuperTypeOf($thisSendType); if ($isSuperType->no()) { $messages[] = RuleErrorBuilder::message(sprintf('Generator expects delegated TSend type %s, %s given.', $exprSendType->describe(VerbosityLevel::typeOnly()), $thisSendType->describe(VerbosityLevel::typeOnly())))->identifier('generator.sendType')->build(); } elseif ($this->reportMaybes && !$isSuperType->yes()) { $messages[] = RuleErrorBuilder::message(sprintf('Generator expects delegated TSend type %s, %s given.', $exprSendType->describe(VerbosityLevel::typeOnly()), $thisSendType->describe(VerbosityLevel::typeOnly())))->identifier('generator.sendType')->build(); } if (!$scope->isInFirstLevelStatement() && $scope->getType($node)->isVoid()->yes()) { $messages[] = RuleErrorBuilder::message('Result of yield from (void) is used.')->identifier('generator.void')->build(); } return $messages; } } */ final class YieldTypeRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Node\Expr\Yield_::class; } public function processNode(Node $node, Scope $scope) : array { $anonymousFunctionReturnType = $scope->getAnonymousFunctionReturnType(); $scopeFunction = $scope->getFunction(); if ($anonymousFunctionReturnType !== null) { $returnType = $anonymousFunctionReturnType; } elseif ($scopeFunction !== null) { $returnType = $scopeFunction->getReturnType(); } else { return []; // already reported by YieldInGeneratorRule } if ($returnType instanceof MixedType) { return []; } if ($node->key === null) { $keyType = new IntegerType(); } else { $keyType = $scope->getType($node->key); } $messages = []; $acceptsKey = $this->ruleLevelHelper->acceptsWithReason($returnType->getIterableKeyType(), $keyType, $scope->isDeclareStrictTypes()); if (!$acceptsKey->result) { $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($returnType->getIterableKeyType(), $keyType); $messages[] = RuleErrorBuilder::message(sprintf('Generator expects key type %s, %s given.', $returnType->getIterableKeyType()->describe($verbosityLevel), $keyType->describe($verbosityLevel)))->acceptsReasonsTip($acceptsKey->reasons)->identifier('generator.keyType')->build(); } if ($node->value === null) { $valueType = new NullType(); } else { $valueType = $scope->getType($node->value); } $acceptsValue = $this->ruleLevelHelper->acceptsWithReason($returnType->getIterableValueType(), $valueType, $scope->isDeclareStrictTypes()); if (!$acceptsValue->result) { $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($returnType->getIterableValueType(), $valueType); $messages[] = RuleErrorBuilder::message(sprintf('Generator expects value type %s, %s given.', $returnType->getIterableValueType()->describe($verbosityLevel), $valueType->describe($verbosityLevel)))->acceptsReasonsTip($acceptsValue->reasons)->identifier('generator.valueType')->build(); } if (!$scope->isInFirstLevelStatement() && $scope->getType($node)->isVoid()->yes()) { $messages[] = RuleErrorBuilder::message('Result of yield (void) is used.')->identifier('generator.void')->build(); } return $messages; } } */ final class YieldInGeneratorRule implements Rule { /** * @var bool */ private $reportMaybes; public function __construct(bool $reportMaybes) { $this->reportMaybes = $reportMaybes; } public function getNodeType() : string { return Node\Expr::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof Node\Expr\Yield_ && !$node instanceof Node\Expr\YieldFrom) { return []; } $anonymousFunctionReturnType = $scope->getAnonymousFunctionReturnType(); $scopeFunction = $scope->getFunction(); if ($anonymousFunctionReturnType !== null) { $returnType = $anonymousFunctionReturnType; } elseif ($scopeFunction !== null) { $returnType = $scopeFunction->getReturnType(); } else { return [RuleErrorBuilder::message('Yield can be used only inside a function.')->identifier('generator.outOfFunction')->nonIgnorable()->build()]; } if ($returnType instanceof MixedType) { return []; } if ($returnType instanceof NeverType && $returnType->isExplicit()) { $isSuperType = TrinaryLogic::createNo(); } else { $isSuperType = $returnType->isIterable()->and(TrinaryLogic::createFromBoolean(!$returnType->isArray()->yes())); } if ($isSuperType->yes()) { return []; } if ($isSuperType->maybe() && !$this->reportMaybes) { return []; } return [RuleErrorBuilder::message(sprintf('Yield can be used only with these return types: %s.', 'Generator, Iterator, Traversable, iterable'))->identifier('generator.returnType')->build()]; } } */ final class FinalPrivateMethodRule implements Rule { /** * @var PhpVersion */ private $phpVersion; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); if (!$this->phpVersion->producesWarningForFinalPrivateMethods()) { return []; } if ($method->getName() === '__construct') { return []; } if (!$method->isFinal()->yes() || !$method->isPrivate()) { return []; } return [RuleErrorBuilder::message(sprintf('Private method %s::%s() cannot be final as it is never overridden by other classes.', $method->getDeclaringClass()->getDisplayName(), $method->getName()))->identifier('method.finalPrivate')->build()]; } } container = $container; } public function getExtensions() : array { return $this->extensions = $this->extensions ?? $this->container->getServicesByTag(static::EXTENSION_TAG); } } extensions = $extensions; } public function getExtensions() : array { return $this->extensions; } } */ final class ConstructorReturnTypeRule implements Rule { public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); $methodNode = $node->getOriginalNode(); if ($scope->isInTrait()) { $originalMethodName = $methodNode->getAttribute('originalTraitMethodName'); if ($originalMethodName === '__construct' && $methodNode->returnType !== null) { return [RuleErrorBuilder::message(sprintf('Original constructor of trait %s has a return type.', $scope->getTraitReflection()->getDisplayName()))->identifier('constructor.returnType')->nonIgnorable()->build()]; } } if (!$classReflection->hasConstructor()) { return []; } $constructorReflection = $classReflection->getConstructor(); $methodReflection = $node->getMethodReflection(); if ($methodReflection->getName() !== $constructorReflection->getName()) { return []; } if ($methodNode->returnType === null) { return []; } return [RuleErrorBuilder::message(sprintf('Constructor of class %s has a return type.', $classReflection->getDisplayName()))->identifier('constructor.returnType')->nonIgnorable()->build()]; } } */ final class IllegalConstructorMethodCallRule implements Rule { public function getNodeType() : string { return Node\Expr\MethodCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier || $node->name->toLowerString() !== '__construct') { return []; } return [RuleErrorBuilder::message('Call to __construct() on an existing object is not allowed.')->identifier('constructor.call')->build()]; } } */ final class ConsistentConstructorRule implements Rule { /** * @var MethodParameterComparisonHelper */ private $methodParameterComparisonHelper; public function __construct(\PHPStan\Rules\Methods\MethodParameterComparisonHelper $methodParameterComparisonHelper) { $this->methodParameterComparisonHelper = $methodParameterComparisonHelper; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); if (strtolower($method->getName()) !== '__construct') { return []; } $parent = $method->getDeclaringClass()->getParentClass(); if ($parent === null) { return []; } if ($parent->hasConstructor()) { $parentConstructor = $parent->getConstructor(); } else { $parentConstructor = new DummyConstructorReflection($parent); } if (!$parentConstructor->getDeclaringClass()->hasConsistentConstructor()) { return []; } return $this->methodParameterComparisonHelper->compare($parentConstructor, $parentConstructor->getDeclaringClass(), $method, \true); } } */ final class StaticMethodCallableRule implements Rule { /** * @var StaticMethodCallCheck */ private $methodCallCheck; /** * @var PhpVersion */ private $phpVersion; public function __construct(\PHPStan\Rules\Methods\StaticMethodCallCheck $methodCallCheck, PhpVersion $phpVersion) { $this->methodCallCheck = $methodCallCheck; $this->phpVersion = $phpVersion; } public function getNodeType() : string { return StaticMethodCallableNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$this->phpVersion->supportsFirstClassCallables()) { return [RuleErrorBuilder::message('First-class callables are supported only on PHP 8.1 and later.')->nonIgnorable()->identifier('callable.notSupported')->build()]; } $methodName = $node->getName(); if (!$methodName instanceof Node\Identifier) { return []; } $methodNameName = $methodName->toString(); [$errors, $methodReflection] = $this->methodCallCheck->check($scope, $methodNameName, $node->getClass()); if ($methodReflection === null) { return $errors; } $declaringClass = $methodReflection->getDeclaringClass(); if ($declaringClass->hasNativeMethod($methodNameName)) { return $errors; } $messagesMethodName = SprintfHelper::escapeFormatString($declaringClass->getDisplayName() . '::' . $methodReflection->getName() . '()'); $errors[] = RuleErrorBuilder::message(sprintf('Creating callable from a non-native static method %s.', $messagesMethodName))->identifier('callable.nonNativeMethod')->build(); return $errors; } } */ final class NullsafeMethodCallRule implements Rule { public function getNodeType() : string { return Node\Expr\NullsafeMethodCall::class; } public function processNode(Node $node, Scope $scope) : array { $calledOnType = $scope->getType($node->var); if (!$calledOnType->isNull()->no()) { return []; } return [RuleErrorBuilder::message(sprintf('Using nullsafe method call on non-nullable type %s. Use -> instead.', $calledOnType->describe(VerbosityLevel::typeOnly())))->identifier('nullsafe.neverNull')->build()]; } } */ final class MissingMagicSerializationMethodsRule implements Rule { /** * @var PhpVersion */ private $phpversion; public function __construct(PhpVersion $phpversion) { $this->phpversion = $phpversion; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); if (!$this->phpversion->serializableRequiresMagicMethods()) { return []; } if (!$classReflection->implementsInterface(Serializable::class)) { return []; } if ($classReflection->isAbstract() || $classReflection->isInterface() || $classReflection->isEnum()) { return []; } $messages = []; try { $nativeMethods = $classReflection->getNativeReflection()->getMethods(); } catch (IdentifierNotFound $e) { return []; } $missingMagicSerialize = \true; $missingMagicUnserialize = \true; foreach ($nativeMethods as $method) { if (strtolower($method->getName()) === '__serialize') { $missingMagicSerialize = \false; } if (strtolower($method->getName()) !== '__unserialize') { continue; } $missingMagicUnserialize = \false; } if ($missingMagicSerialize) { $messages[] = RuleErrorBuilder::message(sprintf('Non-abstract class %s implements the Serializable interface, but does not implement __serialize().', $classReflection->getDisplayName()))->tip('See https://wiki.php.net/rfc/phase_out_serializable')->identifier('class.serializable')->build(); } if ($missingMagicUnserialize) { $messages[] = RuleErrorBuilder::message(sprintf('Non-abstract class %s implements the Serializable interface, but does not implement __unserialize().', $classReflection->getDisplayName()))->tip('See https://wiki.php.net/rfc/phase_out_serializable')->identifier('class.serializable')->build(); } return $messages; } } */ final class CallToConstructorStatementWithoutSideEffectsRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var bool */ private $reportNoConstructor; public function __construct(ReflectionProvider $reflectionProvider, bool $reportNoConstructor) { $this->reflectionProvider = $reflectionProvider; $this->reportNoConstructor = $reportNoConstructor; } public function getNodeType() : string { return NoopExpressionNode::class; } public function processNode(Node $node, Scope $scope) : array { $instantiation = $node->getOriginalExpr(); if (!$instantiation instanceof Node\Expr\New_) { return []; } if (!$instantiation->class instanceof Node\Name) { return []; } $className = $scope->resolveName($instantiation->class); if (!$this->reflectionProvider->hasClass($className)) { return []; } $classReflection = $this->reflectionProvider->getClass($className); if (!$classReflection->hasConstructor()) { if ($this->reportNoConstructor) { return [RuleErrorBuilder::message(sprintf('Call to new %s() on a separate line has no effect.', $classReflection->getDisplayName()))->identifier('new.resultUnused')->build()]; } return []; } $constructor = $classReflection->getConstructor(); $methodResult = $scope->getType($instantiation); if ($methodResult instanceof NeverType && $methodResult->isExplicit()) { return []; } return [RuleErrorBuilder::message(sprintf('Call to %s::%s() on a separate line has no effect.', $classReflection->getDisplayName(), $constructor->getName()))->identifier('new.resultUnused')->build()]; } } */ final class CallPrivateMethodThroughStaticRule implements Rule { public function getNodeType() : string { return StaticCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier) { return []; } if (!$node->class instanceof Name) { return []; } $methodName = $node->name->name; $className = $node->class; if ($className->toLowerString() !== 'static') { return []; } $classType = $scope->resolveTypeByName($className); if (!$classType->hasMethod($methodName)->yes()) { return []; } $method = $classType->getMethod($methodName, $scope); if (!$method->isPrivate()) { return []; } if ($scope->isInClass() && $scope->getClassReflection()->isFinal()) { return []; } return [RuleErrorBuilder::message(sprintf('Unsafe call to private method %s::%s() through static::.', $method->getDeclaringClass()->getDisplayName(), $method->getName()))->identifier('staticClassAccess.privateMethod')->build()]; } } */ final class ReturnTypeRule implements Rule { /** * @var FunctionReturnTypeCheck */ private $returnTypeCheck; public function __construct(FunctionReturnTypeCheck $returnTypeCheck) { $this->returnTypeCheck = $returnTypeCheck; } public function getNodeType() : string { return Return_::class; } public function processNode(Node $node, Scope $scope) : array { if ($scope->getFunction() === null) { return []; } if ($scope->isInAnonymousFunction()) { return []; } $method = $scope->getFunction(); if (!$method instanceof PhpMethodFromParserNodeReflection) { return []; } $returnType = $method->getReturnType(); $errors = $this->returnTypeCheck->checkReturnType($scope, $returnType, $node->expr, $node, sprintf('Method %s::%s() should return %%s but empty return statement found.', $method->getDeclaringClass()->getDisplayName(), $method->getName()), sprintf('Method %s::%s() with return type void returns %%s but should not return anything.', $method->getDeclaringClass()->getDisplayName(), $method->getName()), sprintf('Method %s::%s() should return %%s but returns %%s.', $method->getDeclaringClass()->getDisplayName(), $method->getName()), sprintf('Method %s::%s() should never return but return statement found.', $method->getDeclaringClass()->getDisplayName(), $method->getName()), $method->isGenerator()); if (count($errors) === 1 && $errors[0]->getIdentifier() === 'return.type' && !$errors[0] instanceof TipRuleError && $errors[0] instanceof LineRuleError && $method->getDeclaringClass()->isSubclassOf(Rule::class) && strtolower($method->getName()) === 'processnode' && $node->expr !== null) { $ruleErrorType = new ObjectType(RuleError::class); $identifierRuleErrorType = new ObjectType(IdentifierRuleError::class); $listOfIdentifierRuleErrors = new IntersectionType([new ArrayType(IntegerRangeType::fromInterval(0, null), $identifierRuleErrorType), new AccessoryArrayListType()]); if (!$listOfIdentifierRuleErrors->isSuperTypeOf($returnType)->yes()) { return $errors; } $returnValueType = $scope->getType($node->expr)->getIterableValueType(); $builder = RuleErrorBuilder::message($errors[0]->getMessage())->line($errors[0]->getLine())->identifier($errors[0]->getIdentifier()); if (!$returnValueType->isString()->no()) { $builder->tip('Rules can no longer return plain strings. See: https://phpstan.org/blog/using-rule-error-builder'); } elseif ($ruleErrorType->isSuperTypeOf($returnValueType)->yes() && !$identifierRuleErrorType->isSuperTypeOf($returnValueType)->yes()) { $builder->tip('Error is missing an identifier. See: https://phpstan.org/blog/using-rule-error-builder'); } $errors = [$builder->build()]; } return $errors; } } */ final class MethodAttributesRule implements Rule { /** * @var AttributesCheck */ private $attributesCheck; public function __construct(AttributesCheck $attributesCheck) { $this->attributesCheck = $attributesCheck; } public function getNodeType() : string { return Node\Stmt\ClassMethod::class; } public function processNode(Node $node, Scope $scope) : array { return $this->attributesCheck->check($scope, $node->attrGroups, Attribute::TARGET_METHOD, 'method'); } } */ final class MissingMethodReturnTypehintRule implements Rule { /** * @var MissingTypehintCheck */ private $missingTypehintCheck; public function __construct(MissingTypehintCheck $missingTypehintCheck) { $this->missingTypehintCheck = $missingTypehintCheck; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $methodReflection = $node->getMethodReflection(); if ($scope->isInTrait()) { $methodNode = $node->getOriginalNode(); $originalMethodName = $methodNode->getAttribute('originalTraitMethodName'); if ($originalMethodName === '__construct') { return []; } } $returnType = $methodReflection->getReturnType(); if ($returnType instanceof MixedType && !$returnType->isExplicitMixed()) { return [RuleErrorBuilder::message(sprintf('Method %s::%s() has no return type specified.', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName()))->identifier('missingType.return')->build()]; } $messages = []; foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($returnType) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() return type has no value type specified in iterable type %s.', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName(), $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($returnType) as [$name, $genericTypeNames]) { $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() return type with generic %s does not specify its types: %s', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName(), $name, $genericTypeNames))->identifier('missingType.generics')->build(); } foreach ($this->missingTypehintCheck->getCallablesWithMissingSignature($returnType) as $callableType) { $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() return type has no signature specified for %s.', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName(), $callableType->describe(VerbosityLevel::typeOnly())))->identifier('missingType.callable')->build(); } return $messages; } } */ final class CallToStaticMethodStatementWithoutSideEffectsRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(RuleLevelHelper $ruleLevelHelper, ReflectionProvider $reflectionProvider) { $this->ruleLevelHelper = $ruleLevelHelper; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return NoopExpressionNode::class; } public function processNode(Node $node, Scope $scope) : array { $staticCall = $node->getOriginalExpr(); if (!$staticCall instanceof Node\Expr\StaticCall) { return []; } if (!$staticCall->name instanceof Node\Identifier) { return []; } $methodName = $staticCall->name->toString(); if ($staticCall->class instanceof Node\Name) { $className = $scope->resolveName($staticCall->class); if (!$this->reflectionProvider->hasClass($className)) { return []; } $calledOnType = new ObjectType($className); } else { $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $staticCall->class), '', static function (Type $type) use($methodName) : bool { return $type->canCallMethods()->yes() && $type->hasMethod($methodName)->yes(); }); $calledOnType = $typeResult->getType(); if ($calledOnType instanceof ErrorType) { return []; } } if (!$calledOnType->canCallMethods()->yes()) { return []; } if (!$calledOnType->hasMethod($methodName)->yes()) { return []; } $method = $calledOnType->getMethod($methodName, $scope); if (strtolower($method->getName()) === '__construct' || strtolower($method->getName()) === strtolower($method->getDeclaringClass()->getName())) { return []; } $methodResult = $scope->getType($staticCall); if ($methodResult instanceof NeverType && $methodResult->isExplicit()) { return []; } return [RuleErrorBuilder::message(sprintf('Call to %s %s::%s() on a separate line has no effect.', $method->isStatic() ? 'static method' : 'method', $method->getDeclaringClass()->getDisplayName(), $method->getName()))->identifier('staticMethod.resultUnused')->build()]; } } */ final class CallStaticMethodsRule implements Rule { /** * @var StaticMethodCallCheck */ private $methodCallCheck; /** * @var FunctionCallParametersCheck */ private $parametersCheck; public function __construct(\PHPStan\Rules\Methods\StaticMethodCallCheck $methodCallCheck, FunctionCallParametersCheck $parametersCheck) { $this->methodCallCheck = $methodCallCheck; $this->parametersCheck = $parametersCheck; } public function getNodeType() : string { return StaticCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier) { return []; } $methodName = $node->name->name; [$errors, $method] = $this->methodCallCheck->check($scope, $methodName, $node->class); if ($method === null) { return $errors; } $displayMethodName = SprintfHelper::escapeFormatString(sprintf('%s %s', $method->isStatic() ? 'Static method' : 'Method', $method->getDeclaringClass()->getDisplayName() . '::' . $method->getName() . '()')); $lowercasedMethodName = SprintfHelper::escapeFormatString(sprintf('%s %s', $method->isStatic() ? 'static method' : 'method', $method->getDeclaringClass()->getDisplayName() . '::' . $method->getName() . '()')); $errors = array_merge($errors, $this->parametersCheck->check(ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $method->getVariants(), $method->getNamedArgumentsVariants()), $scope, $method->getDeclaringClass()->isBuiltin(), $node, [$displayMethodName . ' invoked with %d parameter, %d required.', $displayMethodName . ' invoked with %d parameters, %d required.', $displayMethodName . ' invoked with %d parameter, at least %d required.', $displayMethodName . ' invoked with %d parameters, at least %d required.', $displayMethodName . ' invoked with %d parameter, %d-%d required.', $displayMethodName . ' invoked with %d parameters, %d-%d required.', 'Parameter %s of ' . $lowercasedMethodName . ' expects %s, %s given.', 'Result of ' . $lowercasedMethodName . ' (void) is used.', 'Parameter %s of ' . $lowercasedMethodName . ' is passed by reference, so it expects variables only.', 'Unable to resolve the template type %s in call to method ' . $lowercasedMethodName, 'Missing parameter $%s in call to ' . $lowercasedMethodName . '.', 'Unknown parameter $%s in call to ' . $lowercasedMethodName . '.', 'Return type of call to ' . $lowercasedMethodName . ' contains unresolvable type.', 'Parameter %s of ' . $lowercasedMethodName . ' contains unresolvable type.', $displayMethodName . ' invoked with %s, but it\'s not allowed because of @no-named-arguments.'], 'staticMethod', $method->acceptsNamedArguments())); return $errors; } } */ final class MissingMethodImplementationRule implements Rule { public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); if ($classReflection->isInterface()) { return []; } if ($classReflection->isAbstract()) { return []; } $messages = []; try { $nativeMethods = $classReflection->getNativeReflection()->getMethods(); } catch (IdentifierNotFound $e) { return []; } foreach ($nativeMethods as $method) { if (!$method->isAbstract()) { continue; } $declaringClass = $method->getDeclaringClass(); $classLikeDescription = 'Non-abstract class'; if ($classReflection->isEnum()) { $classLikeDescription = 'Enum'; } $messages[] = RuleErrorBuilder::message(sprintf('%s %s contains abstract method %s() from %s %s.', $classLikeDescription, $classReflection->getDisplayName(), $method->getName(), $declaringClass->isInterface() ? 'interface' : 'class', $declaringClass->getName()))->nonIgnorable()->identifier('method.abstract')->build(); } return $messages; } } */ final class MethodSignatureRule implements Rule { /** * @var PhpClassReflectionExtension */ private $phpClassReflectionExtension; /** * @var bool */ private $reportMaybes; /** * @var bool */ private $reportStatic; /** * @var bool */ private $abstractTraitMethod; public function __construct(PhpClassReflectionExtension $phpClassReflectionExtension, bool $reportMaybes, bool $reportStatic, bool $abstractTraitMethod) { $this->phpClassReflectionExtension = $phpClassReflectionExtension; $this->reportMaybes = $reportMaybes; $this->reportStatic = $reportStatic; $this->abstractTraitMethod = $abstractTraitMethod; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); $methodName = $method->getName(); if ($methodName === '__construct') { return []; } if (!$this->reportStatic && $method->isStatic()) { return []; } if ($method->isPrivate()) { return []; } $errors = []; $declaringClass = $method->getDeclaringClass(); foreach ($this->collectParentMethods($methodName, $method->getDeclaringClass()) as [$parentMethod, $parentMethodDeclaringClass]) { $parentVariants = $parentMethod->getVariants(); if (count($parentVariants) !== 1) { continue; } $parentVariant = $parentVariants[0]; [$returnTypeCompatibility, $returnType, $parentReturnType] = $this->checkReturnTypeCompatibility($declaringClass, $method, $parentVariant); if ($returnTypeCompatibility->no() || !$returnTypeCompatibility->yes() && $this->reportMaybes) { $builder = RuleErrorBuilder::message(sprintf('Return type (%s) of method %s::%s() should be %s with return type (%s) of method %s::%s()', $returnType->describe(VerbosityLevel::value()), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $returnTypeCompatibility->no() ? 'compatible' : 'covariant', $parentReturnType->describe(VerbosityLevel::value()), $parentMethodDeclaringClass->getDisplayName(), $parentMethod->getName()))->identifier('method.childReturnType'); if ($parentMethod->getDeclaringClass()->getName() === Rule::class && strtolower($methodName) === 'processnode') { $ruleErrorType = new ObjectType(RuleError::class); $identifierRuleErrorType = new ObjectType(IdentifierRuleError::class); $listOfIdentifierRuleErrors = new IntersectionType([new ArrayType(IntegerRangeType::fromInterval(0, null), $identifierRuleErrorType), new AccessoryArrayListType()]); if ($listOfIdentifierRuleErrors->isSuperTypeOf($parentReturnType)->yes()) { $returnValueType = $returnType->getIterableValueType(); if (!$returnValueType->isString()->no()) { $builder->tip('Rules can no longer return plain strings. See: https://phpstan.org/blog/using-rule-error-builder'); } elseif ($ruleErrorType->isSuperTypeOf($returnValueType)->yes() && !$identifierRuleErrorType->isSuperTypeOf($returnValueType)->yes()) { $builder->tip('Errors are missing identifiers. See: https://phpstan.org/blog/using-rule-error-builder'); } elseif (!$returnType->isList()->yes()) { $builder->tip('Return type must be a list. See: https://phpstan.org/blog/using-rule-error-builder'); } } } $errors[] = $builder->build(); } $parameterResults = $this->checkParameterTypeCompatibility($declaringClass, $method->getParameters(), $parentVariant->getParameters()); foreach ($parameterResults as $parameterIndex => [$parameterResult, $parameterType, $parentParameterType]) { if ($parameterResult->yes()) { continue; } if (!$parameterResult->no() && !$this->reportMaybes) { continue; } $parameter = $method->getParameters()[$parameterIndex]; $parentParameter = $parentVariant->getParameters()[$parameterIndex]; $errors[] = RuleErrorBuilder::message(sprintf('Parameter #%d $%s (%s) of method %s::%s() should be %s with parameter $%s (%s) of method %s::%s()', $parameterIndex + 1, $parameter->getName(), $parameterType->describe(VerbosityLevel::value()), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $parameterResult->no() ? 'compatible' : 'contravariant', $parentParameter->getName(), $parentParameterType->describe(VerbosityLevel::value()), $parentMethodDeclaringClass->getDisplayName(), $parentMethod->getName()))->identifier('method.childParameterType')->build(); } } return $errors; } /** * @return list */ private function collectParentMethods(string $methodName, ClassReflection $class) : array { $parentMethods = []; $parentClass = $class->getParentClass(); if ($parentClass !== null && $parentClass->hasNativeMethod($methodName)) { $parentMethod = $parentClass->getNativeMethod($methodName); if (!$parentMethod->isPrivate()) { $parentMethods[] = [$parentMethod, $parentMethod->getDeclaringClass()]; } } foreach ($class->getInterfaces() as $interface) { if (!$interface->hasNativeMethod($methodName)) { continue; } $method = $interface->getNativeMethod($methodName); $parentMethods[] = [$method, $method->getDeclaringClass()]; } if ($this->abstractTraitMethod) { foreach ($class->getTraits(\true) as $trait) { $nativeTraitReflection = $trait->getNativeReflection(); if (!$nativeTraitReflection->hasMethod($methodName)) { continue; } $methodReflection = $nativeTraitReflection->getMethod($methodName); $isAbstract = $methodReflection->isAbstract(); if (!$isAbstract) { continue; } $declaringTrait = $trait->getNativeMethod($methodName)->getDeclaringClass(); $parentMethods[] = [$this->phpClassReflectionExtension->createUserlandMethodReflection($trait, $class, new NativeBuiltinMethodReflection($methodReflection), $declaringTrait->getName()), $declaringTrait]; } } return $parentMethods; } /** * @return array{TrinaryLogic, Type, Type} */ private function checkReturnTypeCompatibility(ClassReflection $declaringClass, ParametersAcceptorWithPhpDocs $currentVariant, ParametersAcceptorWithPhpDocs $parentVariant) : array { $returnType = TypehintHelper::decideType($currentVariant->getNativeReturnType(), TemplateTypeHelper::resolveToBounds($currentVariant->getPhpDocReturnType())); $originalParentReturnType = TypehintHelper::decideType($parentVariant->getNativeReturnType(), TemplateTypeHelper::resolveToBounds($parentVariant->getPhpDocReturnType())); $parentReturnType = $this->transformStaticType($declaringClass, $originalParentReturnType); // Allow adding `void` return type hints when the parent defines no return type if ($returnType->isVoid()->yes() && $parentReturnType instanceof MixedType) { return [TrinaryLogic::createYes(), $returnType, $parentReturnType]; } // We can return anything if ($parentReturnType->isVoid()->yes()) { return [TrinaryLogic::createYes(), $returnType, $parentReturnType]; } return [$parentReturnType->isSuperTypeOf($returnType), TypehintHelper::decideType($currentVariant->getNativeReturnType(), $currentVariant->getPhpDocReturnType()), $originalParentReturnType]; } /** * @param ParameterReflectionWithPhpDocs[] $parameters * @param ParameterReflectionWithPhpDocs[] $parentParameters * @return array */ private function checkParameterTypeCompatibility(ClassReflection $declaringClass, array $parameters, array $parentParameters) : array { $parameterResults = []; $numberOfParameters = min(count($parameters), count($parentParameters)); for ($i = 0; $i < $numberOfParameters; $i++) { $parameter = $parameters[$i]; $parentParameter = $parentParameters[$i]; $parameterType = TypehintHelper::decideType($parameter->getNativeType(), TemplateTypeHelper::resolveToBounds($parameter->getPhpDocType())); $originalParameterType = TypehintHelper::decideType($parentParameter->getNativeType(), TemplateTypeHelper::resolveToBounds($parentParameter->getPhpDocType())); $parentParameterType = $this->transformStaticType($declaringClass, $originalParameterType); $parameterResults[] = [$parameterType->isSuperTypeOf($parentParameterType), TypehintHelper::decideType($parameter->getNativeType(), $parameter->getPhpDocType()), $originalParameterType]; } return $parameterResults; } private function transformStaticType(ClassReflection $declaringClass, Type $type) : Type { return TypeTraverser::map($type, static function (Type $type, callable $traverse) use($declaringClass) : Type { if ($type instanceof GenericStaticType) { if ($declaringClass->isFinal()) { $changedType = $type->changeBaseClass($declaringClass)->getStaticObjectType(); } else { $changedType = $type->changeBaseClass($declaringClass); } return $traverse($changedType); } if ($type instanceof StaticType) { if ($declaringClass->isFinal()) { $changedType = new ObjectType($declaringClass->getName()); } else { $changedType = $type->changeBaseClass($declaringClass); } return $traverse($changedType); } return $traverse($type); }); } } */ final class MissingMethodSelfOutTypeRule implements Rule { /** * @var MissingTypehintCheck */ private $missingTypehintCheck; public function __construct(MissingTypehintCheck $missingTypehintCheck) { $this->missingTypehintCheck = $missingTypehintCheck; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $methodReflection = $node->getMethodReflection(); $selfOutType = $methodReflection->getSelfOutType(); if ($selfOutType === null) { return []; } $classReflection = $methodReflection->getDeclaringClass(); $phpDocTagMessage = 'PHPDoc tag @phpstan-self-out'; $messages = []; foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($selfOutType) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() has %s with no value type specified in iterable type %s.', $classReflection->getDisplayName(), $methodReflection->getName(), $phpDocTagMessage, $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($selfOutType) as [$name, $genericTypeNames]) { $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() has %s with generic %s but does not specify its types: %s', $classReflection->getDisplayName(), $methodReflection->getName(), $phpDocTagMessage, $name, $genericTypeNames))->identifier('missingType.generics')->build(); } foreach ($this->missingTypehintCheck->getCallablesWithMissingSignature($selfOutType) as $callableType) { $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() has %s with no signature specified for %s.', $classReflection->getDisplayName(), $methodReflection->getName(), $phpDocTagMessage, $callableType->describe(VerbosityLevel::typeOnly())))->identifier('missingType.callable')->build(); } return $messages; } } */ final class ExistingClassesInTypehintsRule implements Rule { /** * @var FunctionDefinitionCheck */ private $check; public function __construct(FunctionDefinitionCheck $check) { $this->check = $check; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $methodReflection = $node->getMethodReflection(); $className = SprintfHelper::escapeFormatString($node->getClassReflection()->getDisplayName()); $methodName = SprintfHelper::escapeFormatString($methodReflection->getName()); return $this->check->checkClassMethod($methodReflection, $node->getOriginalNode(), sprintf('Parameter $%%s of method %s::%s() has invalid type %%s.', $className, $methodName), sprintf('Method %s::%s() has invalid return type %%s.', $className, $methodName), sprintf('Method %s::%s() uses native union types but they\'re supported only on PHP 8.0 and later.', $className, $methodName), sprintf('Template type %%s of method %s::%s() is not referenced in a parameter.', $className, $methodName), sprintf('Parameter $%%s of method %s::%s() has unresolvable native type.', $className, $methodName), sprintf('Method %s::%s() has unresolvable native return type.', $className, $methodName), sprintf('Method %s::%s() has invalid @phpstan-self-out type %%s.', $className, $methodName)); } } */ final class MethodCallableRule implements Rule { /** * @var MethodCallCheck */ private $methodCallCheck; /** * @var PhpVersion */ private $phpVersion; public function __construct(\PHPStan\Rules\Methods\MethodCallCheck $methodCallCheck, PhpVersion $phpVersion) { $this->methodCallCheck = $methodCallCheck; $this->phpVersion = $phpVersion; } public function getNodeType() : string { return MethodCallableNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$this->phpVersion->supportsFirstClassCallables()) { return [RuleErrorBuilder::message('First-class callables are supported only on PHP 8.1 and later.')->nonIgnorable()->identifier('callable.notSupported')->build()]; } $methodName = $node->getName(); if (!$methodName instanceof Node\Identifier) { return []; } $methodNameName = $methodName->toString(); [$errors, $methodReflection] = $this->methodCallCheck->check($scope, $methodNameName, $node->getVar()); if ($methodReflection === null) { return $errors; } $declaringClass = $methodReflection->getDeclaringClass(); if ($declaringClass->hasNativeMethod($methodNameName)) { return $errors; } $messagesMethodName = SprintfHelper::escapeFormatString($declaringClass->getDisplayName() . '::' . $methodReflection->getName() . '()'); $errors[] = RuleErrorBuilder::message(sprintf('Creating callable from a non-native method %s.', $messagesMethodName))->identifier('callable.nonNativeMethod')->build(); return $errors; } } */ final class MethodVisibilityInInterfaceRule implements Rule { public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); if ($method->isPublic()) { return []; } $classReflection = $scope->getClassReflection(); if ($classReflection === null) { return []; } if (!$classReflection->isInterface()) { return []; } return [RuleErrorBuilder::message(sprintf('Method %s::%s() cannot use non-public visibility in interface.', $method->getDeclaringClass()->getDisplayName(), $method->getName()))->identifier('method.visibility')->nonIgnorable()->build()]; } } */ final class AbstractPrivateMethodRule implements Rule { public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); if (!$method->isPrivate()) { return []; } if (!$method->isAbstract()->yes()) { return []; } if ($scope->isInTrait()) { return []; } $classReflection = $scope->getClassReflection(); if ($classReflection === null) { return []; } if (!$classReflection->isAbstract() && !$classReflection->isInterface()) { return []; } return [RuleErrorBuilder::message(sprintf('Private method %s::%s() cannot be abstract.', $method->getDeclaringClass()->getDisplayName(), $method->getName()))->identifier('method.abstractPrivate')->nonIgnorable()->build()]; } } */ final class OverridingMethodRule implements Rule { /** * @var PhpVersion */ private $phpVersion; /** * @var MethodSignatureRule */ private $methodSignatureRule; /** * @var bool */ private $checkPhpDocMethodSignatures; /** * @var MethodParameterComparisonHelper */ private $methodParameterComparisonHelper; /** * @var PhpClassReflectionExtension */ private $phpClassReflectionExtension; /** * @var bool */ private $genericPrototypeMessage; /** * @var bool */ private $finalByPhpDoc; /** * @var bool */ private $checkMissingOverrideMethodAttribute; public function __construct(PhpVersion $phpVersion, \PHPStan\Rules\Methods\MethodSignatureRule $methodSignatureRule, bool $checkPhpDocMethodSignatures, \PHPStan\Rules\Methods\MethodParameterComparisonHelper $methodParameterComparisonHelper, PhpClassReflectionExtension $phpClassReflectionExtension, bool $genericPrototypeMessage, bool $finalByPhpDoc, bool $checkMissingOverrideMethodAttribute) { $this->phpVersion = $phpVersion; $this->methodSignatureRule = $methodSignatureRule; $this->checkPhpDocMethodSignatures = $checkPhpDocMethodSignatures; $this->methodParameterComparisonHelper = $methodParameterComparisonHelper; $this->phpClassReflectionExtension = $phpClassReflectionExtension; $this->genericPrototypeMessage = $genericPrototypeMessage; $this->finalByPhpDoc = $finalByPhpDoc; $this->checkMissingOverrideMethodAttribute = $checkMissingOverrideMethodAttribute; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); $prototypeData = $this->findPrototype($node->getClassReflection(), $method->getName()); if ($prototypeData === null) { if (strtolower($method->getName()) === '__construct') { $parent = $method->getDeclaringClass()->getParentClass(); if ($parent !== null && $parent->hasConstructor()) { $parentConstructor = $parent->getConstructor(); if ($parentConstructor->isFinalByKeyword()->yes()) { return $this->addErrors([RuleErrorBuilder::message(sprintf('Method %s::%s() overrides final method %s::%s().', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $parent->getDisplayName($this->genericPrototypeMessage), $parentConstructor->getName()))->nonIgnorable()->identifier('method.parentMethodFinal')->build()], $node, $scope); } if ($parentConstructor->isFinal()->yes() && $this->finalByPhpDoc) { return $this->addErrors([RuleErrorBuilder::message(sprintf('Method %s::%s() overrides @final method %s::%s().', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $parent->getDisplayName($this->genericPrototypeMessage), $parentConstructor->getName()))->identifier('method.parentMethodFinalByPhpDoc')->build()], $node, $scope); } } } if ($this->phpVersion->supportsOverrideAttribute() && $this->hasOverrideAttribute($node->getOriginalNode())) { return [RuleErrorBuilder::message(sprintf('Method %s::%s() has #[\\Override] attribute but does not override any method.', $method->getDeclaringClass()->getDisplayName(), $method->getName()))->nonIgnorable()->identifier('method.override')->build()]; } return []; } [$prototype, $prototypeDeclaringClass, $checkVisibility] = $prototypeData; $messages = []; if ($this->phpVersion->supportsOverrideAttribute() && $this->checkMissingOverrideMethodAttribute && !$scope->isInTrait() && !$this->hasOverrideAttribute($node->getOriginalNode())) { $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() overrides method %s::%s() but is missing the #[\\Override] attribute.', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->identifier('method.missingOverride')->build(); } if ($prototype->isFinalByKeyword()->yes()) { $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() overrides final method %s::%s().', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->nonIgnorable()->identifier('method.parentMethodFinal')->build(); } elseif ($prototype->isFinal()->yes() && $this->finalByPhpDoc) { $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() overrides @final method %s::%s().', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->identifier('method.parentMethodFinalByPhpDoc')->build(); } if ($prototype->isStatic()) { if (!$method->isStatic()) { $messages[] = RuleErrorBuilder::message(sprintf('Non-static method %s::%s() overrides static method %s::%s().', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->nonIgnorable()->identifier('method.nonStatic')->build(); } } elseif ($method->isStatic()) { $messages[] = RuleErrorBuilder::message(sprintf('Static method %s::%s() overrides non-static method %s::%s().', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->nonIgnorable()->identifier('method.static')->build(); } if ($checkVisibility) { if ($prototype->isPublic()) { if (!$method->isPublic()) { $messages[] = RuleErrorBuilder::message(sprintf('%s method %s::%s() overriding public method %s::%s() should also be public.', $method->isPrivate() ? 'Private' : 'Protected', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->nonIgnorable()->identifier('method.visibility')->build(); } } elseif ($method->isPrivate()) { $messages[] = RuleErrorBuilder::message(sprintf('Private method %s::%s() overriding protected method %s::%s() should be protected or public.', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->nonIgnorable()->identifier('method.visibility')->build(); } } $prototypeVariants = $prototype->getVariants(); if (count($prototypeVariants) !== 1) { return $this->addErrors($messages, $node, $scope); } $prototypeVariant = $prototypeVariants[0]; $methodReturnType = $method->getNativeReturnType(); $realPrototype = $method->getPrototype(); if ($realPrototype instanceof MethodPrototypeReflection && $this->phpVersion->hasTentativeReturnTypes() && $realPrototype->getTentativeReturnType() !== null && !$this->hasReturnTypeWillChangeAttribute($node->getOriginalNode()) && count($prototypeDeclaringClass->getNativeReflection()->getMethod($prototype->getName())->getAttributes('ReturnTypeWillChange')) === 0) { if (!$this->methodParameterComparisonHelper->isReturnTypeCompatible($realPrototype->getTentativeReturnType(), $method->getNativeReturnType(), \true)) { $messages[] = RuleErrorBuilder::message(sprintf('Return type %s of method %s::%s() is not covariant with tentative return type %s of method %s::%s().', $methodReturnType->describe(VerbosityLevel::typeOnly()), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $realPrototype->getTentativeReturnType()->describe(VerbosityLevel::typeOnly()), $realPrototype->getDeclaringClass()->getDisplayName($this->genericPrototypeMessage), $realPrototype->getName()))->tip('Make it covariant, or use the #[\\ReturnTypeWillChange] attribute to temporarily suppress the error.')->nonIgnorable()->identifier('method.tentativeReturnType')->build(); } } $messages = array_merge($messages, $this->methodParameterComparisonHelper->compare($prototype, $prototypeDeclaringClass, $method)); if (!$prototypeVariant instanceof FunctionVariantWithPhpDocs) { return $this->addErrors($messages, $node, $scope); } $prototypeReturnType = $prototypeVariant->getNativeReturnType(); $reportReturnType = \true; if ($this->phpVersion->hasTentativeReturnTypes()) { $reportReturnType = !$realPrototype instanceof MethodPrototypeReflection || $realPrototype->getTentativeReturnType() === null || $prototype->isInternal()->no(); } else { if ($realPrototype instanceof MethodPrototypeReflection && $realPrototype->isInternal()) { if ($prototype->isInternal()->yes() && $prototypeDeclaringClass->getName() !== $realPrototype->getDeclaringClass()->getName()) { $realPrototypeVariant = $realPrototype->getVariants()[0]; if ($prototypeReturnType instanceof MixedType && !$prototypeReturnType->isExplicitMixed() && (!$realPrototypeVariant->getReturnType() instanceof MixedType || $realPrototypeVariant->getReturnType()->isExplicitMixed())) { $reportReturnType = \false; } } if ($reportReturnType && $prototype->isInternal()->yes()) { $reportReturnType = !$this->hasReturnTypeWillChangeAttribute($node->getOriginalNode()); } } } if ($reportReturnType && !$this->methodParameterComparisonHelper->isReturnTypeCompatible($prototypeReturnType, $methodReturnType, $this->phpVersion->supportsReturnCovariance())) { if ($this->phpVersion->supportsReturnCovariance()) { $messages[] = RuleErrorBuilder::message(sprintf('Return type %s of method %s::%s() is not covariant with return type %s of method %s::%s().', $methodReturnType->describe(VerbosityLevel::typeOnly()), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $prototypeReturnType->describe(VerbosityLevel::typeOnly()), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->nonIgnorable()->identifier('method.childReturnType')->build(); } else { $messages[] = RuleErrorBuilder::message(sprintf('Return type %s of method %s::%s() is not compatible with return type %s of method %s::%s().', $methodReturnType->describe(VerbosityLevel::typeOnly()), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $prototypeReturnType->describe(VerbosityLevel::typeOnly()), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->nonIgnorable()->identifier('method.childReturnType')->build(); } } return $this->addErrors($messages, $node, $scope); } /** * @param list $errors * @return list */ private function addErrors(array $errors, InClassMethodNode $classMethod, Scope $scope) : array { if (count($errors) > 0) { return $errors; } if (!$this->checkPhpDocMethodSignatures) { return $errors; } return $this->methodSignatureRule->processNode($classMethod, $scope); } private function hasReturnTypeWillChangeAttribute(Node\Stmt\ClassMethod $method) : bool { foreach ($method->attrGroups as $attrGroup) { foreach ($attrGroup->attrs as $attr) { if ($attr->name->toLowerString() === 'returntypewillchange') { return \true; } } } return \false; } private function hasOverrideAttribute(Node\Stmt\ClassMethod $method) : bool { foreach ($method->attrGroups as $attrGroup) { foreach ($attrGroup->attrs as $attr) { if ($attr->name->toLowerString() === 'override') { return \true; } } } return \false; } /** * @return array{ExtendedMethodReflection, ClassReflection, bool}|null */ private function findPrototype(ClassReflection $classReflection, string $methodName) : ?array { foreach ($classReflection->getImmediateInterfaces() as $immediateInterface) { if ($immediateInterface->hasNativeMethod($methodName)) { $method = $immediateInterface->getNativeMethod($methodName); return [$method, $method->getDeclaringClass(), \true]; } } if ($this->phpVersion->supportsAbstractTraitMethods()) { foreach ($classReflection->getTraits(\true) as $trait) { $nativeTraitReflection = $trait->getNativeReflection(); if (!$nativeTraitReflection->hasMethod($methodName)) { continue; } $methodReflection = $nativeTraitReflection->getMethod($methodName); $isAbstract = $methodReflection->isAbstract(); if ($isAbstract) { $declaringTrait = $trait->getNativeMethod($methodName)->getDeclaringClass(); return [$this->phpClassReflectionExtension->createUserlandMethodReflection($trait, $classReflection, new NativeBuiltinMethodReflection($methodReflection), $declaringTrait->getName()), $declaringTrait, \false]; } } } $parentClass = $classReflection->getParentClass(); if ($parentClass === null) { return null; } if (!$parentClass->hasNativeMethod($methodName)) { return null; } $method = $parentClass->getNativeMethod($methodName); if ($method->isPrivate()) { return null; } $declaringClass = $method->getDeclaringClass(); if ($declaringClass->hasConstructor()) { if ($method->getName() === $declaringClass->getConstructor()->getName()) { $prototype = $method->getPrototype(); if ($prototype instanceof PhpMethodReflection || $prototype instanceof MethodPrototypeReflection || $prototype instanceof NativeMethodReflection) { $abstract = $prototype->isAbstract(); if (is_bool($abstract)) { if (!$abstract) { return null; } } elseif (!$abstract->yes()) { return null; } } } elseif (strtolower($methodName) === '__construct') { return null; } } return [$method, $method->getDeclaringClass(), \true]; } } reflectionProvider = $reflectionProvider; $this->ruleLevelHelper = $ruleLevelHelper; $this->checkFunctionNameCase = $checkFunctionNameCase; $this->reportMagicMethods = $reportMagicMethods; } /** * @return array{list, ExtendedMethodReflection|null} */ public function check(Scope $scope, string $methodName, Expr $var) : array { $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $var), sprintf('Call to method %s() on an unknown class %%s.', SprintfHelper::escapeFormatString($methodName)), static function (Type $type) use($methodName) : bool { return $type->canCallMethods()->yes() && $type->hasMethod($methodName)->yes(); }); $type = $typeResult->getType(); if ($type instanceof ErrorType) { return [$typeResult->getUnknownClassErrors(), null]; } $typeForDescribe = $type; if ($type instanceof StaticType) { $typeForDescribe = $type->getStaticObjectType(); } if (!$type->canCallMethods()->yes() || $type->isClassStringType()->yes()) { return [[RuleErrorBuilder::message(sprintf('Cannot call method %s() on %s.', $methodName, $typeForDescribe->describe(VerbosityLevel::typeOnly())))->identifier('method.nonObject')->build()], null]; } if (!$type->hasMethod($methodName)->yes()) { $directClassNames = $typeResult->getReferencedClasses(); if (!$this->reportMagicMethods) { foreach ($directClassNames as $className) { if (!$this->reflectionProvider->hasClass($className)) { continue; } $classReflection = $this->reflectionProvider->getClass($className); if ($classReflection->hasNativeMethod('__call')) { return [[], null]; } } } if (count($directClassNames) === 1) { $referencedClass = $directClassNames[0]; $methodClassReflection = $this->reflectionProvider->getClass($referencedClass); $parentClassReflection = $methodClassReflection->getParentClass(); while ($parentClassReflection !== null) { if ($parentClassReflection->hasMethod($methodName)) { $methodReflection = $parentClassReflection->getMethod($methodName, $scope); return [[RuleErrorBuilder::message(sprintf('Call to private method %s() of parent class %s.', $methodReflection->getName(), $parentClassReflection->getDisplayName()))->identifier('method.private')->build()], $methodReflection]; } $parentClassReflection = $parentClassReflection->getParentClass(); } } return [[RuleErrorBuilder::message(sprintf('Call to an undefined method %s::%s().', $typeForDescribe->describe(VerbosityLevel::typeOnly()), $methodName))->identifier('method.notFound')->build()], null]; } $methodReflection = $type->getMethod($methodName, $scope); $declaringClass = $methodReflection->getDeclaringClass(); $messagesMethodName = SprintfHelper::escapeFormatString($declaringClass->getDisplayName() . '::' . $methodReflection->getName() . '()'); $errors = []; if (!$scope->canCallMethod($methodReflection)) { $errors[] = RuleErrorBuilder::message(sprintf('Call to %s method %s() of class %s.', $methodReflection->isPrivate() ? 'private' : 'protected', $methodReflection->getName(), $declaringClass->getDisplayName()))->identifier(sprintf('method.%s', $methodReflection->isPrivate() ? 'private' : 'protected'))->build(); } if ($this->checkFunctionNameCase && strtolower($methodReflection->getName()) === strtolower($methodName) && $methodReflection->getName() !== $methodName) { $errors[] = RuleErrorBuilder::message(sprintf('Call to method %s with incorrect case: %s', $messagesMethodName, $methodName))->identifier('method.nameCase')->build(); } return [$errors, $methodReflection]; } } */ final class AbstractMethodInNonAbstractClassRule implements Rule { public function getNodeType() : string { return Node\Stmt\ClassMethod::class; } public function processNode(Node $node, Scope $scope) : array { if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } $class = $scope->getClassReflection(); if (!$class->isAbstract() && $node->isAbstract()) { if ($class->isEnum()) { $lowercasedMethodName = $node->name->toLowerString(); if ($lowercasedMethodName === 'cases') { return []; } if ($class->isBackedEnum()) { if (in_array($lowercasedMethodName, ['from', 'tryfrom'], \true)) { return []; } } } $description = $class->getClassTypeDescription(); return [RuleErrorBuilder::message(sprintf('%s %s contains abstract method %s().', $description === 'Class' ? 'Non-abstract class' : $description, $class->getDisplayName(), $node->name->toString()))->nonIgnorable()->identifier('method.abstract')->build()]; } if (!$class->isAbstract() && !$class->isInterface() && $node->getStmts() === null) { return [RuleErrorBuilder::message(sprintf('Non-abstract method %s::%s() must contain a body.', $class->getDisplayName(), $node->name->toString()))->nonIgnorable()->identifier('method.nonAbstract')->build()]; } return []; } } */ final class CallToMethodStatementWithoutSideEffectsRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return NoopExpressionNode::class; } public function processNode(Node $node, Scope $scope) : array { $methodCall = $node->getOriginalExpr(); if ($methodCall instanceof Node\Expr\NullsafeMethodCall) { $scope = $scope->filterByTruthyValue(new Node\Expr\BinaryOp\NotIdentical($methodCall->var, new Node\Expr\ConstFetch(new Node\Name('null')))); } elseif (!$methodCall instanceof Node\Expr\MethodCall) { return []; } if (!$methodCall->name instanceof Node\Identifier) { return []; } $methodName = $methodCall->name->toString(); $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $methodCall->var), '', static function (Type $type) use($methodName) : bool { return $type->canCallMethods()->yes() && $type->hasMethod($methodName)->yes(); }); $calledOnType = $typeResult->getType(); if ($calledOnType instanceof ErrorType) { return []; } if (!$calledOnType->canCallMethods()->yes()) { return []; } if (!$calledOnType->hasMethod($methodName)->yes()) { return []; } $methodResult = $scope->getType($methodCall); if ($methodResult instanceof NeverType && $methodResult->isExplicit()) { return []; } $method = $calledOnType->getMethod($methodName, $scope); return [RuleErrorBuilder::message(sprintf('Call to %s %s::%s() on a separate line has no effect.', $method->isStatic() ? 'static method' : 'method', $method->getDeclaringClass()->getDisplayName(), $method->getName()))->identifier('method.resultUnused')->build()]; } } reflectionProvider = $reflectionProvider; $this->ruleLevelHelper = $ruleLevelHelper; $this->classCheck = $classCheck; $this->checkFunctionNameCase = $checkFunctionNameCase; $this->reportMagicMethods = $reportMagicMethods; } /** * @param Name|Expr $class * @return array{list, ExtendedMethodReflection|null} */ public function check(Scope $scope, string $methodName, $class) : array { $errors = []; $isAbstract = \false; if ($class instanceof Name) { $classStringType = $scope->getType(new Expr\ClassConstFetch($class, 'class')); if ($classStringType->hasMethod($methodName)->yes()) { return [[], null]; } $className = (string) $class; $lowercasedClassName = strtolower($className); if (in_array($lowercasedClassName, ['self', 'static'], \true)) { if (!$scope->isInClass()) { return [[RuleErrorBuilder::message(sprintf('Calling %s::%s() outside of class scope.', $className, $methodName))->identifier(sprintf('outOfClass.%s', $lowercasedClassName))->build()], null]; } $classType = $scope->resolveTypeByName($class); } elseif ($lowercasedClassName === 'parent') { if (!$scope->isInClass()) { return [[RuleErrorBuilder::message(sprintf('Calling %s::%s() outside of class scope.', $className, $methodName))->identifier(sprintf('outOfClass.parent'))->build()], null]; } $currentClassReflection = $scope->getClassReflection(); if ($currentClassReflection->getParentClass() === null) { return [[RuleErrorBuilder::message(sprintf('%s::%s() calls parent::%s() but %s does not extend any class.', $scope->getClassReflection()->getDisplayName(), $scope->getFunctionName(), $methodName, $scope->getClassReflection()->getDisplayName()))->identifier('class.noParent')->build()], null]; } if ($scope->getFunctionName() === null) { throw new ShouldNotHappenException(); } $classType = $scope->resolveTypeByName($class); } else { if (!$this->reflectionProvider->hasClass($className)) { if ($scope->isInClassExists($className)) { return [[], null]; } return [[RuleErrorBuilder::message(sprintf('Call to static method %s() on an unknown class %s.', $methodName, $className))->identifier('class.notFound')->discoveringSymbolsTip()->build()], null]; } $errors = $this->classCheck->checkClassNames([new ClassNameNodePair($className, $class)]); $classType = $scope->resolveTypeByName($class); } $classReflection = $classType->getClassReflection(); if ($classReflection !== null && $classReflection->hasNativeMethod($methodName) && $lowercasedClassName !== 'static') { $nativeMethodReflection = $classReflection->getNativeMethod($methodName); if ($nativeMethodReflection instanceof PhpMethodReflection || $nativeMethodReflection instanceof NativeMethodReflection) { $isAbstract = $nativeMethodReflection->isAbstract(); if ($isAbstract instanceof TrinaryLogic) { $isAbstract = $isAbstract->yes(); } } } } else { $classTypeResult = $this->ruleLevelHelper->findTypeToCheck($scope, NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $class), sprintf('Call to static method %s() on an unknown class %%s.', SprintfHelper::escapeFormatString($methodName)), static function (Type $type) use($methodName) : bool { return $type->canCallMethods()->yes() && $type->hasMethod($methodName)->yes(); }); $classType = $classTypeResult->getType(); if ($classType instanceof ErrorType) { return [$classTypeResult->getUnknownClassErrors(), null]; } } if ($classType instanceof GenericClassStringType) { $classType = $classType->getGenericType(); if (!$classType->isObject()->yes()) { return [[], null]; } } elseif ($classType->isString()->yes()) { return [[], null]; } $typeForDescribe = $classType; if ($classType instanceof StaticType) { $typeForDescribe = $classType->getStaticObjectType(); } $classType = TypeCombinator::remove($classType, new StringType()); if (!$classType->canCallMethods()->yes()) { return [array_merge($errors, [RuleErrorBuilder::message(sprintf('Cannot call static method %s() on %s.', $methodName, $typeForDescribe->describe(VerbosityLevel::typeOnly())))->identifier('staticMethod.nonObject')->build()]), null]; } if (!$classType->hasMethod($methodName)->yes()) { if (!$this->reportMagicMethods) { foreach ($classType->getObjectClassNames() as $className) { if (!$this->reflectionProvider->hasClass($className)) { continue; } $classReflection = $this->reflectionProvider->getClass($className); if ($classReflection->hasNativeMethod('__callStatic')) { return [[], null]; } } } return [array_merge($errors, [RuleErrorBuilder::message(sprintf('Call to an undefined static method %s::%s().', $typeForDescribe->describe(VerbosityLevel::typeOnly()), $methodName))->identifier('staticMethod.notFound')->build()]), null]; } $method = $classType->getMethod($methodName, $scope); if (!$method->isStatic()) { $function = $scope->getFunction(); $scopeIsInMethodClassOrSubClass = TrinaryLogic::createFromBoolean($scope->isInClass())->lazyAnd($classType->getObjectClassNames(), static function (string $objectClassName) use($scope) { return TrinaryLogic::createFromBoolean($scope->isInClass() && ($scope->getClassReflection()->getName() === $objectClassName || $scope->getClassReflection()->isSubclassOf($objectClassName))); }); if (!$function instanceof MethodReflection || $function->isStatic() || $scopeIsInMethodClassOrSubClass->no()) { // per php-src docs, this method can be called statically, even if declared non-static if (strtolower($method->getName()) === 'loadhtml' && $method->getDeclaringClass()->getName() === DOMDocument::class) { return [[], null]; } return [array_merge($errors, [RuleErrorBuilder::message(sprintf('Static call to instance method %s::%s().', $method->getDeclaringClass()->getDisplayName(), $method->getName()))->identifier('method.staticCall')->build()]), $method]; } } if (!$scope->canCallMethod($method)) { $errors = array_merge($errors, [RuleErrorBuilder::message(sprintf('Call to %s %s %s() of class %s.', $method->isPrivate() ? 'private' : 'protected', $method->isStatic() ? 'static method' : 'method', $method->getName(), $method->getDeclaringClass()->getDisplayName()))->identifier(sprintf('staticMethod.%s', $method->isPrivate() ? 'private' : 'protected'))->build()]); } if ($isAbstract) { return [[RuleErrorBuilder::message(sprintf('Cannot call abstract%s method %s::%s().', $method->isStatic() ? ' static' : '', $method->getDeclaringClass()->getDisplayName(), $method->getName()))->identifier(sprintf('%s.callToAbstract', $method->isStatic() ? 'staticMethod' : 'method'))->build()], $method]; } $lowercasedMethodName = SprintfHelper::escapeFormatString(sprintf('%s %s', $method->isStatic() ? 'static method' : 'method', $method->getDeclaringClass()->getDisplayName() . '::' . $method->getName() . '()')); if ($this->checkFunctionNameCase && $method->getName() !== $methodName) { $errors[] = RuleErrorBuilder::message(sprintf('Call to %s with incorrect case: %s', $lowercasedMethodName, $methodName))->identifier('staticMethod.nameCase')->build(); } return [$errors, $method]; } } phpVersion = $phpVersion; $this->genericPrototypeMessage = $genericPrototypeMessage; } /** * @return list */ public function compare(ExtendedMethodReflection $prototype, ClassReflection $prototypeDeclaringClass, PhpMethodFromParserNodeReflection $method, bool $ignorable = \false) : array { /** @var list $messages */ $messages = []; $prototypeVariant = $prototype->getVariants()[0]; $methodParameters = $method->getParameters(); $prototypeAfterVariadic = \false; foreach ($prototypeVariant->getParameters() as $i => $prototypeParameter) { if (!array_key_exists($i, $methodParameters)) { $error = RuleErrorBuilder::message(sprintf('Method %s::%s() overrides method %s::%s() but misses parameter #%d $%s.', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName(), $i + 1, $prototypeParameter->getName()))->identifier('parameter.missing'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); continue; } $methodParameter = $methodParameters[$i]; if ($prototypeParameter->passedByReference()->no()) { if (!$methodParameter->passedByReference()->no()) { $error = RuleErrorBuilder::message(sprintf('Parameter #%d $%s of method %s::%s() is passed by reference but parameter #%d $%s of method %s::%s() is not passed by reference.', $i + 1, $methodParameter->getName(), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $i + 1, $prototypeParameter->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->identifier('parameter.byRef'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); } } elseif ($methodParameter->passedByReference()->no()) { $error = RuleErrorBuilder::message(sprintf('Parameter #%d $%s of method %s::%s() is not passed by reference but parameter #%d $%s of method %s::%s() is passed by reference.', $i + 1, $methodParameter->getName(), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $i + 1, $prototypeParameter->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->identifier('parameter.notByRef'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); } if ($prototypeParameter->isVariadic()) { $prototypeAfterVariadic = \true; if (!$methodParameter->isVariadic()) { if (!$methodParameter->isOptional()) { if (count($methodParameters) !== $i + 1) { $error = RuleErrorBuilder::message(sprintf('Parameter #%d $%s of method %s::%s() is not optional.', $i + 1, $methodParameter->getName(), $method->getDeclaringClass()->getDisplayName(), $method->getName()))->identifier('parameter.notOptional'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); continue; } $error = RuleErrorBuilder::message(sprintf('Parameter #%d $%s of method %s::%s() is not variadic but parameter #%d $%s of method %s::%s() is variadic.', $i + 1, $methodParameter->getName(), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $i + 1, $prototypeParameter->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->identifier('parameter.notVariadic'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); continue; } elseif (count($methodParameters) === $i + 1) { $error = RuleErrorBuilder::message(sprintf('Parameter #%d $%s of method %s::%s() is not variadic.', $i + 1, $methodParameter->getName(), $method->getDeclaringClass()->getDisplayName(), $method->getName()))->identifier('parameter.notVariadic'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); } } } elseif ($methodParameter->isVariadic()) { if ($this->phpVersion->supportsLessOverridenParametersWithVariadic()) { $remainingPrototypeParameters = array_slice($prototypeVariant->getParameters(), $i); foreach ($remainingPrototypeParameters as $j => $remainingPrototypeParameter) { if ($methodParameter->getNativeType()->isSuperTypeOf($remainingPrototypeParameter->getNativeType())->yes()) { continue; } $error = RuleErrorBuilder::message(sprintf('Parameter #%d ...$%s (%s) of method %s::%s() is not contravariant with parameter #%d $%s (%s) of method %s::%s().', $i + 1, $methodParameter->getName(), $methodParameter->getNativeType()->describe(VerbosityLevel::typeOnly()), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $i + $j + 1, $remainingPrototypeParameter->getName(), $remainingPrototypeParameter->getNativeType()->describe(VerbosityLevel::typeOnly()), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->identifier('method.childParameterType'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); } break; } $error = RuleErrorBuilder::message(sprintf('Parameter #%d $%s of method %s::%s() is variadic but parameter #%d $%s of method %s::%s() is not variadic.', $i + 1, $methodParameter->getName(), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $i + 1, $prototypeParameter->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->identifier('parameter.variadic'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); continue; } if ($prototypeParameter->isOptional() && !$methodParameter->isOptional()) { $error = RuleErrorBuilder::message(sprintf('Parameter #%d $%s of method %s::%s() is required but parameter #%d $%s of method %s::%s() is optional.', $i + 1, $methodParameter->getName(), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $i + 1, $prototypeParameter->getName(), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->identifier('parameter.notOptional'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); } $methodParameterType = $methodParameter->getNativeType(); $prototypeParameterType = $prototypeParameter->getNativeType(); if (!$this->phpVersion->supportsParameterTypeWidening()) { if (!$methodParameterType->equals($prototypeParameterType)) { $error = RuleErrorBuilder::message(sprintf('Parameter #%d $%s (%s) of method %s::%s() does not match parameter #%d $%s (%s) of method %s::%s().', $i + 1, $methodParameter->getName(), $methodParameterType->describe(VerbosityLevel::typeOnly()), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $i + 1, $prototypeParameter->getName(), $prototypeParameterType->describe(VerbosityLevel::typeOnly()), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->identifier('method.childParameterType'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); } continue; } if ($this->isParameterTypeCompatible($methodParameterType, $prototypeParameterType, $this->phpVersion->supportsParameterContravariance())) { continue; } if ($this->phpVersion->supportsParameterContravariance()) { $error = RuleErrorBuilder::message(sprintf('Parameter #%d $%s (%s) of method %s::%s() is not contravariant with parameter #%d $%s (%s) of method %s::%s().', $i + 1, $methodParameter->getName(), $methodParameterType->describe(VerbosityLevel::typeOnly()), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $i + 1, $prototypeParameter->getName(), $prototypeParameterType->describe(VerbosityLevel::typeOnly()), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->identifier('method.childParameterType'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); } else { $error = RuleErrorBuilder::message(sprintf('Parameter #%d $%s (%s) of method %s::%s() is not compatible with parameter #%d $%s (%s) of method %s::%s().', $i + 1, $methodParameter->getName(), $methodParameterType->describe(VerbosityLevel::typeOnly()), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $i + 1, $prototypeParameter->getName(), $prototypeParameterType->describe(VerbosityLevel::typeOnly()), $prototypeDeclaringClass->getDisplayName($this->genericPrototypeMessage), $prototype->getName()))->identifier('method.childParameterType'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); } } if (!isset($i)) { $i = -1; } foreach ($methodParameters as $j => $methodParameter) { if ($j <= $i) { continue; } if ($j === count($methodParameters) - 1 && $prototypeAfterVariadic && !$methodParameter->isVariadic()) { $error = RuleErrorBuilder::message(sprintf('Parameter #%d $%s of method %s::%s() is not variadic.', $j + 1, $methodParameter->getName(), $method->getDeclaringClass()->getDisplayName(), $method->getName()))->identifier('parameter.notVariadic'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); continue; } if ($methodParameter->isOptional()) { continue; } $error = RuleErrorBuilder::message(sprintf('Parameter #%d $%s of method %s::%s() is not optional.', $j + 1, $methodParameter->getName(), $method->getDeclaringClass()->getDisplayName(), $method->getName()))->identifier('parameter.notOptional'); if (!$ignorable) { $error->nonIgnorable(); } $messages[] = $error->build(); continue; } return $messages; } public function isParameterTypeCompatible(Type $methodParameterType, Type $prototypeParameterType, bool $supportsContravariance) : bool { return $this->isTypeCompatible($methodParameterType, $prototypeParameterType, $supportsContravariance, \false); } public function isReturnTypeCompatible(Type $methodParameterType, Type $prototypeParameterType, bool $supportsCovariance) : bool { return $this->isTypeCompatible($methodParameterType, $prototypeParameterType, $supportsCovariance, \true); } private function isTypeCompatible(Type $methodParameterType, Type $prototypeParameterType, bool $supportsContravariance, bool $considerMixedExplicitness) : bool { if ($methodParameterType instanceof MixedType) { if ($considerMixedExplicitness && $prototypeParameterType instanceof MixedType) { return !$methodParameterType->isExplicitMixed() || $prototypeParameterType->isExplicitMixed(); } return \true; } if (!$supportsContravariance) { if (TypeCombinator::containsNull($methodParameterType)) { $prototypeParameterType = TypeCombinator::removeNull($prototypeParameterType); } $methodParameterType = TypeCombinator::removeNull($methodParameterType); if ($methodParameterType->equals($prototypeParameterType)) { return \true; } if ($methodParameterType instanceof IterableType) { if ($prototypeParameterType instanceof ArrayType) { return \true; } if ($prototypeParameterType->isObject()->yes() && $prototypeParameterType->getObjectClassNames() === [Traversable::class]) { return \true; } } return \false; } return $methodParameterType->isSuperTypeOf($prototypeParameterType)->yes(); } } */ final class IncompatibleDefaultParameterTypeRule implements Rule { public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); $errors = []; foreach ($node->getOriginalNode()->getParams() as $paramI => $param) { if ($param->default === null) { continue; } if ($param->var instanceof Node\Expr\Error || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } $defaultValueType = $scope->getType($param->default); $parameter = $method->getParameters()[$paramI]; $parameterType = $parameter->getType(); $parameterType = TemplateTypeHelper::resolveToBounds($parameterType); $accepts = $parameterType->acceptsWithReason($defaultValueType, \true); if ($accepts->yes()) { continue; } $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($parameterType, $defaultValueType); $errors[] = RuleErrorBuilder::message(sprintf('Default value of the parameter #%d $%s (%s) of method %s::%s() is incompatible with type %s.', $paramI + 1, $param->var->name, $defaultValueType->describe($verbosityLevel), $method->getDeclaringClass()->getDisplayName(), $method->getName(), $parameterType->describe($verbosityLevel)))->line($param->getStartLine())->identifier('parameter.defaultValue')->acceptsReasonsTip($accepts->reasons)->build(); } return $errors; } } */ final class CallMethodsRule implements Rule { /** * @var MethodCallCheck */ private $methodCallCheck; /** * @var FunctionCallParametersCheck */ private $parametersCheck; public function __construct(\PHPStan\Rules\Methods\MethodCallCheck $methodCallCheck, FunctionCallParametersCheck $parametersCheck) { $this->methodCallCheck = $methodCallCheck; $this->parametersCheck = $parametersCheck; } public function getNodeType() : string { return MethodCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier) { return []; } $methodName = $node->name->name; [$errors, $methodReflection] = $this->methodCallCheck->check($scope, $methodName, $node->var); if ($methodReflection === null) { return $errors; } $declaringClass = $methodReflection->getDeclaringClass(); $messagesMethodName = SprintfHelper::escapeFormatString($declaringClass->getDisplayName() . '::' . $methodReflection->getName() . '()'); return array_merge($errors, $this->parametersCheck->check(ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $methodReflection->getVariants(), $methodReflection->getNamedArgumentsVariants()), $scope, $declaringClass->isBuiltin(), $node, ['Method ' . $messagesMethodName . ' invoked with %d parameter, %d required.', 'Method ' . $messagesMethodName . ' invoked with %d parameters, %d required.', 'Method ' . $messagesMethodName . ' invoked with %d parameter, at least %d required.', 'Method ' . $messagesMethodName . ' invoked with %d parameters, at least %d required.', 'Method ' . $messagesMethodName . ' invoked with %d parameter, %d-%d required.', 'Method ' . $messagesMethodName . ' invoked with %d parameters, %d-%d required.', 'Parameter %s of method ' . $messagesMethodName . ' expects %s, %s given.', 'Result of method ' . $messagesMethodName . ' (void) is used.', 'Parameter %s of method ' . $messagesMethodName . ' is passed by reference, so it expects variables only.', 'Unable to resolve the template type %s in call to method ' . $messagesMethodName, 'Missing parameter $%s in call to method ' . $messagesMethodName . '.', 'Unknown parameter $%s in call to method ' . $messagesMethodName . '.', 'Return type of call to method ' . $messagesMethodName . ' contains unresolvable type.', 'Parameter %s of method ' . $messagesMethodName . ' contains unresolvable type.', 'Method ' . $messagesMethodName . ' invoked with %s, but it\'s not allowed because of @no-named-arguments.'], 'method', $methodReflection->acceptsNamedArguments())); } } */ final class MissingMethodParameterTypehintRule implements Rule { /** * @var MissingTypehintCheck */ private $missingTypehintCheck; /** * @var bool */ private $paramOut; public function __construct(MissingTypehintCheck $missingTypehintCheck, bool $paramOut) { $this->missingTypehintCheck = $missingTypehintCheck; $this->paramOut = $paramOut; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $methodReflection = $node->getMethodReflection(); $messages = []; foreach ($methodReflection->getParameters() as $parameterReflection) { foreach ($this->checkMethodParameter($methodReflection, sprintf('parameter $%s', $parameterReflection->getName()), $parameterReflection->getType()) as $parameterMessage) { $messages[] = $parameterMessage; } if ($parameterReflection->getClosureThisType() !== null) { foreach ($this->checkMethodParameter($methodReflection, sprintf('@param-closure-this PHPDoc tag for parameter $%s', $parameterReflection->getName()), $parameterReflection->getClosureThisType()) as $parameterMessage) { $messages[] = $parameterMessage; } } if (!$this->paramOut) { continue; } if ($parameterReflection->getOutType() === null) { continue; } foreach ($this->checkMethodParameter($methodReflection, sprintf('@param-out PHPDoc tag for parameter $%s', $parameterReflection->getName()), $parameterReflection->getOutType()) as $parameterMessage) { $messages[] = $parameterMessage; } } return $messages; } /** * @return list */ private function checkMethodParameter(MethodReflection $methodReflection, string $parameterMessage, Type $parameterType) : array { if ($parameterType instanceof MixedType && !$parameterType->isExplicitMixed()) { return [RuleErrorBuilder::message(sprintf('Method %s::%s() has %s with no type specified.', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName(), $parameterMessage))->identifier('missingType.parameter')->build()]; } $messages = []; foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($parameterType) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() has %s with no value type specified in iterable type %s.', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName(), $parameterMessage, $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($parameterType) as [$name, $genericTypeNames]) { $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() has %s with generic %s but does not specify its types: %s', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName(), $parameterMessage, $name, $genericTypeNames))->identifier('missingType.generics')->build(); } foreach ($this->missingTypehintCheck->getCallablesWithMissingSignature($parameterType) as $callableType) { $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() has %s with no signature specified for %s.', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName(), $parameterMessage, $callableType->describe(VerbosityLevel::typeOnly())))->identifier('missingType.callable')->build(); } return $messages; } } */ final class IllegalConstructorStaticCallRule implements Rule { public function getNodeType() : string { return Node\Expr\StaticCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier || $node->name->toLowerString() !== '__construct') { return []; } if ($this->isCollectCallingConstructor($node, $scope)) { return []; } return [RuleErrorBuilder::message('Static call to __construct() is only allowed on a parent class in the constructor.')->identifier('constructor.call')->build()]; } private function isCollectCallingConstructor(Node\Expr\StaticCall $node, Scope $scope) : bool { // __construct should be called from inside constructor if ($scope->getFunction() === null) { return \false; } if ($scope->getFunction()->getName() !== '__construct') { if (!$this->isInRenamedTraitConstructor($scope)) { return \false; } } if (!$scope->isInClass()) { return \false; } if (!$node->class instanceof Node\Name) { return \false; } $parentClasses = array_map(static function (string $name) { return strtolower($name); }, $scope->getClassReflection()->getParentClassesNames()); return in_array(strtolower($scope->resolveName($node->class)), $parentClasses, \true); } private function isInRenamedTraitConstructor(Scope $scope) : bool { if (!$scope->isInClass()) { return \false; } if (!$scope->isInTrait()) { return \false; } if ($scope->getFunction() === null) { return \false; } $traitAliases = $scope->getClassReflection()->getNativeReflection()->getTraitAliases(); $functionName = $scope->getFunction()->getName(); if (!array_key_exists($functionName, $traitAliases)) { return \false; } return $traitAliases[$functionName] === sprintf('%s::%s', $scope->getTraitReflection()->getName(), '__construct'); } } reflectionProvider = $reflectionProvider; $this->classCheck = $classCheck; $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->phpVersion = $phpVersion; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; $this->checkThisOnly = $checkThisOnly; $this->absentTypeChecks = $absentTypeChecks; } /** * @return list */ public function checkFunction(Function_ $function, PhpFunctionFromParserNodeReflection $functionReflection, string $parameterMessage, string $returnMessage, string $unionTypesMessage, string $templateTypeMissingInParameterMessage, string $unresolvableParameterTypeMessage, string $unresolvableReturnTypeMessage) : array { return $this->checkParametersAcceptor($functionReflection, $function, $parameterMessage, $returnMessage, $unionTypesMessage, $templateTypeMissingInParameterMessage, $unresolvableParameterTypeMessage, $unresolvableReturnTypeMessage); } /** * @param Node\Param[] $parameters * @param Node\Identifier|Node\Name|Node\ComplexType|null $returnTypeNode * @return list */ public function checkAnonymousFunction(Scope $scope, array $parameters, $returnTypeNode, string $parameterMessage, string $returnMessage, string $unionTypesMessage, string $unresolvableParameterTypeMessage, string $unresolvableReturnTypeMessage) : array { $errors = []; $unionTypeReported = \false; foreach ($parameters as $i => $param) { if ($param->type === null) { continue; } if (!$unionTypeReported && $param->type instanceof UnionType && !$this->phpVersion->supportsNativeUnionTypes()) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message($unionTypesMessage)->line($param->getStartLine())->identifier('parameter.unionTypeNotSupported')->nonIgnorable()->build(); $unionTypeReported = \true; } if (!$param->var instanceof Variable || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } $implicitlyNullableTypeError = $this->checkImplicitlyNullableType($param->type, $param->default, $i + 1, $param->getStartLine(), $param->var->name); if ($implicitlyNullableTypeError !== null) { $errors[] = $implicitlyNullableTypeError; } $type = $scope->getFunctionType($param->type, \false, \false); if ($type->isVoid()->yes()) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($parameterMessage, $param->var->name, 'void'))->line($param->type->getStartLine())->identifier('parameter.void')->nonIgnorable()->build(); } if ($this->phpVersion->supportsPureIntersectionTypes() && $this->unresolvableTypeHelper->containsUnresolvableType($type)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($unresolvableParameterTypeMessage, $param->var->name))->line($param->type->getStartLine())->identifier('parameter.unresolvableNativeType')->nonIgnorable()->build(); } foreach ($type->getReferencedClasses() as $class) { if (!$this->reflectionProvider->hasClass($class)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($parameterMessage, $param->var->name, $class))->line($param->type->getStartLine())->identifier('class.notFound')->build(); continue; } $classReflection = $this->reflectionProvider->getClass($class); if ($classReflection->isTrait()) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($parameterMessage, $param->var->name, $class))->line($param->type->getStartLine())->identifier('parameter.trait')->build(); continue; } $errors = array_merge($errors, $this->classCheck->checkClassNames([new \PHPStan\Rules\ClassNameNodePair($class, $param->type)], $this->checkClassCaseSensitivity)); } } if ($this->phpVersion->deprecatesRequiredParameterAfterOptional()) { $errors = array_merge($errors, $this->checkRequiredParameterAfterOptional($parameters)); } if ($returnTypeNode === null) { return $errors; } if (!$unionTypeReported && $returnTypeNode instanceof UnionType && !$this->phpVersion->supportsNativeUnionTypes()) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message($unionTypesMessage)->line($returnTypeNode->getStartLine())->identifier('return.unionTypeNotSupported')->nonIgnorable()->build(); } $returnType = $scope->getFunctionType($returnTypeNode, \false, \false); if ($this->phpVersion->supportsPureIntersectionTypes() && $this->unresolvableTypeHelper->containsUnresolvableType($returnType)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message($unresolvableReturnTypeMessage)->line($returnTypeNode->getStartLine())->identifier('return.unresolvableNativeType')->nonIgnorable()->build(); } foreach ($returnType->getReferencedClasses() as $returnTypeClass) { if (!$this->reflectionProvider->hasClass($returnTypeClass)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($returnMessage, $returnTypeClass))->line($returnTypeNode->getLine())->identifier('class.notFound')->build(); continue; } if ($this->reflectionProvider->getClass($returnTypeClass)->isTrait()) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($returnMessage, $returnTypeClass))->line($returnTypeNode->getStartLine())->identifier('return.trait')->build(); continue; } $errors = array_merge($errors, $this->classCheck->checkClassNames([new \PHPStan\Rules\ClassNameNodePair($returnTypeClass, $returnTypeNode)], $this->checkClassCaseSensitivity)); } return $errors; } /** * @return list */ public function checkClassMethod(PhpMethodFromParserNodeReflection $methodReflection, ClassMethod $methodNode, string $parameterMessage, string $returnMessage, string $unionTypesMessage, string $templateTypeMissingInParameterMessage, string $unresolvableParameterTypeMessage, string $unresolvableReturnTypeMessage, string $selfOutMessage) : array { $errors = $this->checkParametersAcceptor($methodReflection, $methodNode, $parameterMessage, $returnMessage, $unionTypesMessage, $templateTypeMissingInParameterMessage, $unresolvableParameterTypeMessage, $unresolvableReturnTypeMessage); $selfOutType = $methodReflection->getSelfOutType(); if ($selfOutType !== null && $this->absentTypeChecks) { $selfOutTypeReferencedClasses = $selfOutType->getReferencedClasses(); foreach ($selfOutTypeReferencedClasses as $class) { if (!$this->reflectionProvider->hasClass($class)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($selfOutMessage, $class))->line($methodNode->getStartLine())->identifier('class.notFound')->build(); continue; } if (!$this->reflectionProvider->getClass($class)->isTrait()) { continue; } $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($selfOutMessage, $class))->line($methodNode->getStartLine())->identifier('selfOut.trait')->build(); } $errors = array_merge($errors, $this->classCheck->checkClassNames(array_map(static function (string $class) use($methodNode) : \PHPStan\Rules\ClassNameNodePair { return new \PHPStan\Rules\ClassNameNodePair($class, $methodNode); }, $selfOutTypeReferencedClasses), $this->checkClassCaseSensitivity)); } return $errors; } /** * @return list */ private function checkParametersAcceptor(ParametersAcceptor $parametersAcceptor, FunctionLike $functionNode, string $parameterMessage, string $returnMessage, string $unionTypesMessage, string $templateTypeMissingInParameterMessage, string $unresolvableParameterTypeMessage, string $unresolvableReturnTypeMessage) : array { $errors = []; $parameterNodes = $functionNode->getParams(); if (!$this->phpVersion->supportsNativeUnionTypes()) { $unionTypeReported = \false; foreach ($parameterNodes as $parameterNode) { if (!$parameterNode->type instanceof UnionType) { continue; } $errors[] = \PHPStan\Rules\RuleErrorBuilder::message($unionTypesMessage)->line($parameterNode->getStartLine())->identifier('parameter.unionTypeNotSupported')->nonIgnorable()->build(); $unionTypeReported = \true; break; } if (!$unionTypeReported && $functionNode->getReturnType() instanceof UnionType) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message($unionTypesMessage)->line($functionNode->getReturnType()->getStartLine())->identifier('return.unionTypeNotSupported')->nonIgnorable()->build(); } } foreach ($parameterNodes as $i => $parameterNode) { if (!$parameterNode->var instanceof Variable || !is_string($parameterNode->var->name)) { throw new ShouldNotHappenException(); } $implicitlyNullableTypeError = $this->checkImplicitlyNullableType($parameterNode->type, $parameterNode->default, $i + 1, $parameterNode->getStartLine(), $parameterNode->var->name); if ($implicitlyNullableTypeError === null) { continue; } $errors[] = $implicitlyNullableTypeError; } if ($this->phpVersion->deprecatesRequiredParameterAfterOptional()) { $errors = array_merge($errors, $this->checkRequiredParameterAfterOptional($parameterNodes)); } $returnTypeNode = $functionNode->getReturnType() ?? $functionNode; foreach ($parametersAcceptor->getParameters() as $parameter) { $referencedClasses = $this->getParameterReferencedClasses($parameter); $parameterNode = null; $parameterNodeCallback = function () use($parameter, $parameterNodes, &$parameterNode) : Param { if ($parameterNode === null) { $parameterNode = $this->getParameterNode($parameter->getName(), $parameterNodes); } return $parameterNode; }; if ($parameter instanceof ParameterReflectionWithPhpDocs) { $parameterVar = $parameterNodeCallback()->var; if (!$parameterVar instanceof Variable || !is_string($parameterVar->name)) { throw new ShouldNotHappenException(); } if ($parameter->getNativeType()->isVoid()->yes()) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($parameterMessage, $parameterVar->name, 'void'))->line($parameterNodeCallback()->getStartLine())->identifier('parameter.void')->nonIgnorable()->build(); } if ($this->phpVersion->supportsPureIntersectionTypes() && $this->unresolvableTypeHelper->containsUnresolvableType($parameter->getNativeType())) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($unresolvableParameterTypeMessage, $parameterVar->name))->line($parameterNodeCallback()->getStartLine())->identifier('parameter.unresolvableNativeType')->nonIgnorable()->build(); } } foreach ($referencedClasses as $class) { if (!$this->reflectionProvider->hasClass($class)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($parameterMessage, $parameter->getName(), $class))->line($parameterNodeCallback()->getStartLine())->identifier('class.notFound')->build(); continue; } if (!$this->reflectionProvider->getClass($class)->isTrait()) { continue; } $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($parameterMessage, $parameter->getName(), $class))->line($parameterNodeCallback()->getStartLine())->identifier('parameter.trait')->build(); } $errors = array_merge($errors, $this->classCheck->checkClassNames(array_map(static function (string $class) use($parameterNodeCallback) : \PHPStan\Rules\ClassNameNodePair { return new \PHPStan\Rules\ClassNameNodePair($class, $parameterNodeCallback()); }, $referencedClasses), $this->checkClassCaseSensitivity)); if (!$parameter->getType() instanceof NonexistentParentClassType) { continue; } $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($parameterMessage, $parameter->getName(), $parameter->getType()->describe(VerbosityLevel::typeOnly())))->line($parameterNodeCallback()->getStartLine())->identifier('parameter.noParent')->build(); } if ($this->phpVersion->supportsPureIntersectionTypes() && $functionNode->getReturnType() !== null) { $nativeReturnType = ParserNodeTypeToPHPStanType::resolve($functionNode->getReturnType(), null); if ($this->unresolvableTypeHelper->containsUnresolvableType($nativeReturnType)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message($unresolvableReturnTypeMessage)->nonIgnorable()->line($returnTypeNode->getStartLine())->identifier('return.unresolvableNativeType')->build(); } } $returnTypeReferencedClasses = $this->getReturnTypeReferencedClasses($parametersAcceptor); foreach ($returnTypeReferencedClasses as $class) { if (!$this->reflectionProvider->hasClass($class)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($returnMessage, $class))->line($returnTypeNode->getStartLine())->identifier('class.notFound')->build(); continue; } if (!$this->reflectionProvider->getClass($class)->isTrait()) { continue; } $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($returnMessage, $class))->line($returnTypeNode->getStartLine())->identifier('return.trait')->build(); } $errors = array_merge($errors, $this->classCheck->checkClassNames(array_map(static function (string $class) use($returnTypeNode) : \PHPStan\Rules\ClassNameNodePair { return new \PHPStan\Rules\ClassNameNodePair($class, $returnTypeNode); }, $returnTypeReferencedClasses), $this->checkClassCaseSensitivity)); if ($parametersAcceptor->getReturnType() instanceof NonexistentParentClassType) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($returnMessage, $parametersAcceptor->getReturnType()->describe(VerbosityLevel::typeOnly())))->line($returnTypeNode->getStartLine())->identifier('return.noParent')->build(); } $templateTypeMap = $parametersAcceptor->getTemplateTypeMap(); $templateTypes = $templateTypeMap->getTypes(); if (count($templateTypes) > 0) { foreach ($parametersAcceptor->getParameters() as $parameter) { TypeTraverser::map($parameter->getType(), static function (Type $type, callable $traverse) use(&$templateTypes) : Type { if ($type instanceof TemplateType) { unset($templateTypes[$type->getName()]); return $traverse($type); } return $traverse($type); }); } $returnType = $parametersAcceptor->getReturnType(); if ($returnType instanceof ConditionalTypeForParameter && !$returnType->isNegated()) { TypeTraverser::map($returnType, static function (Type $type, callable $traverse) use(&$templateTypes) : Type { if ($type instanceof TemplateType) { unset($templateTypes[$type->getName()]); return $traverse($type); } return $traverse($type); }); } foreach (array_keys($templateTypes) as $templateTypeName) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($templateTypeMissingInParameterMessage, $templateTypeName))->identifier('method.templateTypeNotInParameter')->build(); } } return $errors; } /** * @param Param[] $parameterNodes * @return list */ private function checkRequiredParameterAfterOptional(array $parameterNodes) : array { /** @var string|null $optionalParameter */ $optionalParameter = null; $errors = []; $targetPhpVersion = null; foreach ($parameterNodes as $parameterNode) { if (!$parameterNode->var instanceof Variable) { throw new ShouldNotHappenException(); } if (!is_string($parameterNode->var->name)) { throw new ShouldNotHappenException(); } $parameterName = $parameterNode->var->name; if ($optionalParameter !== null && $parameterNode->default === null && !$parameterNode->variadic) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Deprecated in PHP %s: Required parameter $%s follows optional parameter $%s.', $targetPhpVersion ?? '8.0', $parameterName, $optionalParameter))->line($parameterNode->getStartLine())->identifier('parameter.requiredAfterOptional')->build(); $targetPhpVersion = null; continue; } if ($parameterNode->default === null) { continue; } if ($parameterNode->type === null) { $optionalParameter = $parameterName; continue; } $defaultValue = $parameterNode->default; if (!$defaultValue instanceof ConstFetch) { $optionalParameter = $parameterName; continue; } $constantName = $defaultValue->name->toLowerString(); if ($constantName === 'null') { if (!$this->phpVersion->deprecatesRequiredParameterAfterOptionalNullableAndDefaultNull()) { continue; } $parameterNodeType = $parameterNode->type; if ($parameterNodeType instanceof NullableType) { $targetPhpVersion = '8.1'; } if ($this->phpVersion->deprecatesRequiredParameterAfterOptionalUnionOrMixed()) { $types = []; if ($parameterNodeType instanceof UnionType) { $types = $parameterNodeType->types; } elseif ($parameterNodeType instanceof Identifier) { $types = [$parameterNodeType]; } $nullOrMixed = array_filter($types, static function ($type) : bool { return $type instanceof Identifier && in_array($type->name, ['null', 'mixed'], \true); }); if (0 < count($nullOrMixed)) { $targetPhpVersion = '8.3'; } } if ($targetPhpVersion === null) { continue; } } $optionalParameter = $parameterName; } return $errors; } /** * @param Param[] $parameterNodes */ private function getParameterNode(string $parameterName, array $parameterNodes) : Param { foreach ($parameterNodes as $param) { if ($param->var instanceof Node\Expr\Error) { continue; } if (!is_string($param->var->name)) { continue; } if ($param->var->name === $parameterName) { return $param; } } throw new ShouldNotHappenException(sprintf('Parameter %s not found.', $parameterName)); } /** * @return string[] */ private function getParameterReferencedClasses(ParameterReflection $parameter) : array { if (!$parameter instanceof ParameterReflectionWithPhpDocs) { return $parameter->getType()->getReferencedClasses(); } if ($this->checkThisOnly) { return $parameter->getNativeType()->getReferencedClasses(); } $moreClasses = []; if ($this->absentTypeChecks) { if ($parameter->getOutType() !== null) { $moreClasses = array_merge($moreClasses, $parameter->getOutType()->getReferencedClasses()); } if ($parameter->getClosureThisType() !== null) { $moreClasses = array_merge($moreClasses, $parameter->getClosureThisType()->getReferencedClasses()); } } return array_merge($parameter->getNativeType()->getReferencedClasses(), $parameter->getPhpDocType()->getReferencedClasses(), $moreClasses); } /** * @return string[] */ private function getReturnTypeReferencedClasses(ParametersAcceptor $parametersAcceptor) : array { if (!$parametersAcceptor instanceof ParametersAcceptorWithPhpDocs) { return $parametersAcceptor->getReturnType()->getReferencedClasses(); } if ($this->checkThisOnly) { return $parametersAcceptor->getNativeReturnType()->getReferencedClasses(); } return array_merge($parametersAcceptor->getNativeReturnType()->getReferencedClasses(), $parametersAcceptor->getPhpDocReturnType()->getReferencedClasses()); } /** * @param Identifier|Name|ComplexType|null $type */ private function checkImplicitlyNullableType($type, ?Node\Expr $default, int $order, int $line, string $name) : ?\PHPStan\Rules\IdentifierRuleError { if (!$default instanceof ConstFetch) { return null; } if ($default->name->toLowerString() !== 'null') { return null; } if ($type === null) { return null; } if ($type instanceof NullableType || $type instanceof IntersectionType) { return null; } if (!$this->phpVersion->deprecatesImplicitlyNullableParameterTypes()) { return null; } if ($type instanceof Identifier && strtolower($type->name) === 'mixed') { return null; } if ($type instanceof Name && $type->toLowerString() === 'mixed') { return null; } if ($type instanceof Identifier && strtolower($type->name) === 'null') { return null; } if ($type instanceof Name && $type->toLowerString() === 'null') { return null; } if ($type instanceof UnionType) { foreach ($type->types as $innerType) { if ($innerType instanceof Identifier && strtolower($innerType->name) === 'null') { return null; } if ($innerType instanceof Name && $innerType->toLowerString() === 'null') { return null; } } } return \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Deprecated in PHP 8.4: Parameter #%d $%s (%s) is implicitly nullable via default value null.', $order, $name, NodeTypePrinter::printType($type)))->line($line)->identifier('parameter.implicitlyNullable')->build(); } } container = $container; } /** * @template TNodeType of Node * @param class-string $nodeType * @return array> */ public function getRules(string $nodeType) : array { if (!isset($this->cache[$nodeType])) { $parentNodeTypes = [$nodeType] + class_parents($nodeType) + class_implements($nodeType); $rules = []; $rulesFromContainer = $this->getRulesFromContainer(); foreach ($parentNodeTypes as $parentNodeType) { foreach ($rulesFromContainer[$parentNodeType] ?? [] as $rule) { $rules[] = $rule; } } $this->cache[$nodeType] = $rules; } /** * @var array> $selectedRules */ $selectedRules = $this->cache[$nodeType]; return $selectedRules; } /** * @return Rule[][] */ private function getRulesFromContainer() : array { if ($this->rules !== null) { return $this->rules; } $rules = []; foreach ($this->container->getServicesByTag(self::RULE_TAG) as $rule) { $rules[$rule->getNodeType()][] = $rule; } return $this->rules = $rules; } } */ final class InterfaceTemplateTypeRule implements Rule { /** * @var TemplateTypeCheck */ private $templateTypeCheck; public function __construct(\PHPStan\Rules\Generics\TemplateTypeCheck $templateTypeCheck) { $this->templateTypeCheck = $templateTypeCheck; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); if (!$classReflection->isInterface()) { return []; } $interfaceName = $classReflection->getName(); $escapadInterfaceName = SprintfHelper::escapeFormatString($interfaceName); return $this->templateTypeCheck->check($scope, $node, TemplateTypeScope::createWithClass($interfaceName), $classReflection->getTemplateTags(), sprintf('PHPDoc tag @template for interface %s cannot have existing class %%s as its name.', $escapadInterfaceName), sprintf('PHPDoc tag @template for interface %s cannot have existing type alias %%s as its name.', $escapadInterfaceName), sprintf('PHPDoc tag @template %%s for interface %s has invalid bound type %%s.', $escapadInterfaceName), sprintf('PHPDoc tag @template %%s for interface %s with bound type %%s is not supported.', $escapadInterfaceName), sprintf('PHPDoc tag @template %%s for interface %s has invalid default type %%s.', $escapadInterfaceName), sprintf('Default type %%s in PHPDoc tag @template %%s for interface %s is not subtype of bound type %%s.', $escapadInterfaceName), sprintf('PHPDoc tag @template %%s for interface %s does not have a default type but follows an optional @template %%s.', $escapadInterfaceName)); } } reflectionProvider = $reflectionProvider; $this->classCheck = $classCheck; $this->genericObjectTypeCheck = $genericObjectTypeCheck; $this->typeAliasResolver = $typeAliasResolver; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; } /** * @param array $templateTags * @return list */ public function check(Scope $scope, Node $node, TemplateTypeScope $templateTypeScope, array $templateTags, string $sameTemplateTypeNameAsClassMessage, string $sameTemplateTypeNameAsTypeMessage, string $invalidBoundTypeMessage, string $notSupportedBoundMessage, string $invalidDefaultTypeMessage, string $defaultNotSubtypeOfBoundMessage, string $requiredTypeAfterOptionalMessage) : array { $messages = []; $templateTagWithDefaultType = null; foreach ($templateTags as $templateTag) { $templateTagName = $scope->resolveName(new Node\Name($templateTag->getName())); if ($this->reflectionProvider->hasClass($templateTagName)) { $messages[] = RuleErrorBuilder::message(sprintf($sameTemplateTypeNameAsClassMessage, $templateTagName))->identifier('generics.existingClass')->build(); } if ($this->typeAliasResolver->hasTypeAlias($templateTagName, $templateTypeScope->getClassName())) { $messages[] = RuleErrorBuilder::message(sprintf($sameTemplateTypeNameAsTypeMessage, $templateTagName))->identifier('generics.existingTypeAlias')->build(); } $boundType = $templateTag->getBound(); foreach ($boundType->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { $messages[] = RuleErrorBuilder::message(sprintf($invalidBoundTypeMessage, $templateTagName, $referencedClass))->identifier('class.notFound')->build(); continue; } if (!$this->reflectionProvider->getClass($referencedClass)->isTrait()) { continue; } $messages[] = RuleErrorBuilder::message(sprintf($invalidBoundTypeMessage, $templateTagName, $referencedClass))->identifier('generics.traitBound')->build(); } $classNameNodePairs = array_map(static function (string $referencedClass) use($node) : ClassNameNodePair { return new ClassNameNodePair($referencedClass, $node); }, $boundType->getReferencedClasses()); $messages = array_merge($messages, $this->classCheck->checkClassNames($classNameNodePairs, $this->checkClassCaseSensitivity)); $boundTypeClass = get_class($boundType); if ($boundTypeClass !== MixedType::class && $boundTypeClass !== ConstantArrayType::class && $boundTypeClass !== ArrayType::class && $boundTypeClass !== ConstantStringType::class && $boundTypeClass !== StringType::class && $boundTypeClass !== ConstantIntegerType::class && $boundTypeClass !== IntegerType::class && $boundTypeClass !== FloatType::class && $boundTypeClass !== BooleanType::class && $boundTypeClass !== ObjectWithoutClassType::class && $boundTypeClass !== ObjectType::class && $boundTypeClass !== ObjectShapeType::class && $boundTypeClass !== GenericObjectType::class && $boundTypeClass !== KeyOfType::class && $boundTypeClass !== IterableType::class && !$boundType instanceof UnionType && !$boundType instanceof IntersectionType && !$boundType instanceof TemplateType) { $messages[] = RuleErrorBuilder::message(sprintf($notSupportedBoundMessage, $templateTagName, $boundType->describe(VerbosityLevel::typeOnly())))->identifier('generics.notSupportedBound')->build(); } $escapedTemplateTagName = SprintfHelper::escapeFormatString($templateTagName); $genericObjectErrors = $this->genericObjectTypeCheck->check($boundType, sprintf('PHPDoc tag @template %s bound contains generic type %%s but %%s %%s is not generic.', $escapedTemplateTagName), sprintf('PHPDoc tag @template %s bound has type %%s which does not specify all template types of %%s %%s: %%s', $escapedTemplateTagName), sprintf('PHPDoc tag @template %s bound has type %%s which specifies %%d template types, but %%s %%s supports only %%d: %%s', $escapedTemplateTagName), sprintf('Type %%s in generic type %%s in PHPDoc tag @template %s is not subtype of template type %%s of %%s %%s.', $escapedTemplateTagName), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag @template %s is in conflict with %%s template type %%s of %%s %%s.', $escapedTemplateTagName), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag @template %s is redundant, template type %%s of %%s %%s has the same variance.', $escapedTemplateTagName)); foreach ($genericObjectErrors as $genericObjectError) { $messages[] = $genericObjectError; } $defaultType = $templateTag->getDefault(); if ($defaultType === null) { if ($templateTagWithDefaultType !== null) { $messages[] = RuleErrorBuilder::message(sprintf($requiredTypeAfterOptionalMessage, $templateTagName, $templateTagWithDefaultType))->identifier('generics.requiredTypeAfterOptional')->build(); } continue; } $templateTagWithDefaultType = $templateTagName; foreach ($defaultType->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { $messages[] = RuleErrorBuilder::message(sprintf($invalidDefaultTypeMessage, $templateTagName, $referencedClass))->identifier('class.notFound')->build(); continue; } if (!$this->reflectionProvider->getClass($referencedClass)->isTrait()) { continue; } $messages[] = RuleErrorBuilder::message(sprintf($invalidDefaultTypeMessage, $templateTagName, $referencedClass))->identifier('generics.traitBound')->build(); } $classNameNodePairs = array_map(static function (string $referencedClass) use($node) : ClassNameNodePair { return new ClassNameNodePair($referencedClass, $node); }, $defaultType->getReferencedClasses()); $messages = array_merge($messages, $this->classCheck->checkClassNames($classNameNodePairs, $this->checkClassCaseSensitivity)); $genericDefaultErrors = $this->genericObjectTypeCheck->check($defaultType, sprintf('PHPDoc tag @template %s default contains generic type %%s but class %%s is not generic.', $escapedTemplateTagName), sprintf('PHPDoc tag @template %s default has type %%s which does not specify all template types of class %%s: %%s', $escapedTemplateTagName), sprintf('PHPDoc tag @template %s default has type %%s which specifies %%d template types, but class %%s supports only %%d: %%s', $escapedTemplateTagName), sprintf('Type %%s in generic type %%s in PHPDoc tag @template %s default is not subtype of template type %%s of class %%s.', $escapedTemplateTagName), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag @template %s default is in conflict with %%s template type %%s of %%s %%s.', $escapedTemplateTagName), sprintf('Call-site variance of %%s in generic type %%s in PHPDoc tag @template %s default is redundant, template type %%s of %%s %%s has the same variance.', $escapedTemplateTagName)); foreach ($genericDefaultErrors as $genericDefaultError) { $messages[] = $genericDefaultError; } if (!$boundType->accepts($defaultType, $scope->isDeclareStrictTypes())->no()) { continue; } $messages[] = RuleErrorBuilder::message(sprintf($defaultNotSubtypeOfBoundMessage, $defaultType->describe(VerbosityLevel::typeOnly()), $templateTagName, $boundType->describe(VerbosityLevel::typeOnly())))->identifier('generics.templateDefaultOutOfBounds')->build(); } return $messages; } } */ final class ClassTemplateTypeRule implements Rule { /** * @var TemplateTypeCheck */ private $templateTypeCheck; public function __construct(\PHPStan\Rules\Generics\TemplateTypeCheck $templateTypeCheck) { $this->templateTypeCheck = $templateTypeCheck; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); if (!$classReflection->isClass()) { return []; } $className = $classReflection->getName(); if ($classReflection->isAnonymous()) { $displayName = 'anonymous class'; } else { $displayName = 'class ' . SprintfHelper::escapeFormatString($classReflection->getDisplayName()); } return $this->templateTypeCheck->check($scope, $node, TemplateTypeScope::createWithClass($className), $classReflection->getTemplateTags(), sprintf('PHPDoc tag @template for %s cannot have existing class %%s as its name.', $displayName), sprintf('PHPDoc tag @template for %s cannot have existing type alias %%s as its name.', $displayName), sprintf('PHPDoc tag @template %%s for %s has invalid bound type %%s.', $displayName), sprintf('PHPDoc tag @template %%s for %s with bound type %%s is not supported.', $displayName), sprintf('PHPDoc tag @template %%s for %s has invalid default type %%s.', $displayName), sprintf('Default type %%s in PHPDoc tag @template %%s for %s is not subtype of bound type %%s.', $displayName), sprintf('PHPDoc tag @template %%s for %s does not have a default type but follows an optional @template %%s.', $displayName)); } } */ final class FunctionSignatureVarianceRule implements Rule { /** * @var VarianceCheck */ private $varianceCheck; public function __construct(\PHPStan\Rules\Generics\VarianceCheck $varianceCheck) { $this->varianceCheck = $varianceCheck; } public function getNodeType() : string { return InFunctionNode::class; } public function processNode(Node $node, Scope $scope) : array { $functionReflection = $node->getFunctionReflection(); $functionName = $functionReflection->getName(); return $this->varianceCheck->checkParametersAcceptor($functionReflection, sprintf('in parameter %%s of function %s()', SprintfHelper::escapeFormatString($functionName)), sprintf('in param-out type of parameter %%s of function %s()', SprintfHelper::escapeFormatString($functionName)), sprintf('in return type of function %s()', $functionName), sprintf('in function %s()', $functionName), \false, \false, 'function'); } } */ final class PropertyVarianceRule implements Rule { /** * @var VarianceCheck */ private $varianceCheck; /** * @var bool */ private $readOnlyByPhpDoc; public function __construct(\PHPStan\Rules\Generics\VarianceCheck $varianceCheck, bool $readOnlyByPhpDoc) { $this->varianceCheck = $varianceCheck; $this->readOnlyByPhpDoc = $readOnlyByPhpDoc; } public function getNodeType() : string { return ClassPropertyNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); if (!$classReflection->hasNativeProperty($node->getName())) { return []; } $propertyReflection = $classReflection->getNativeProperty($node->getName()); if ($propertyReflection->isPrivate()) { return []; } $variance = $node->isReadOnly() || $this->readOnlyByPhpDoc && $node->isReadOnlyByPhpDoc() ? TemplateTypeVariance::createCovariant() : TemplateTypeVariance::createInvariant(); return $this->varianceCheck->check($variance, $propertyReflection->getReadableType(), sprintf('in property %s::$%s', SprintfHelper::escapeFormatString($classReflection->getDisplayName()), SprintfHelper::escapeFormatString($node->getName()))); } } reflectionProvider = $reflectionProvider; $this->genericObjectTypeCheck = $genericObjectTypeCheck; $this->varianceCheck = $varianceCheck; $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->checkGenericClassInNonGenericObjectType = $checkGenericClassInNonGenericObjectType; $this->skipCheckGenericClasses = $skipCheckGenericClasses; $this->absentTypeChecks = $absentTypeChecks; } /** * @param array $nameNodes * @param array $ancestorTypes * @return list */ public function check(array $nameNodes, array $ancestorTypes, string $incompatibleTypeMessage, string $unresolvableTypeMessage, string $noNamesMessage, string $noRelatedNameMessage, string $classNotGenericMessage, string $notEnoughTypesMessage, string $extraTypesMessage, string $typeIsNotSubtypeMessage, string $typeProjectionIsNotAllowedMessage, string $invalidTypeMessage, string $genericClassInNonGenericObjectType, string $invalidVarianceMessage) : array { $names = array_fill_keys(array_map(static function (Name $nameNode) : string { return $nameNode->toString(); }, $nameNodes), \true); $unusedNames = $names; $messages = []; foreach ($ancestorTypes as $ancestorType) { if (!$ancestorType instanceof GenericObjectType) { $messages[] = RuleErrorBuilder::message(sprintf($incompatibleTypeMessage, $ancestorType->describe(VerbosityLevel::typeOnly())))->identifier('generics.notCompatible')->build(); continue; } $ancestorTypeClassName = $ancestorType->getClassName(); if (!isset($names[$ancestorTypeClassName])) { if (count($names) === 0) { $messages[] = RuleErrorBuilder::message($noNamesMessage)->identifier('generics.noParent')->build(); } else { $messages[] = RuleErrorBuilder::message(sprintf($noRelatedNameMessage, $ancestorTypeClassName, implode(', ', array_keys($names))))->identifier('generics.wrongParent')->build(); } continue; } unset($unusedNames[$ancestorTypeClassName]); $genericObjectTypeCheckMessages = $this->genericObjectTypeCheck->check($ancestorType, $classNotGenericMessage, $notEnoughTypesMessage, $extraTypesMessage, $typeIsNotSubtypeMessage, '', ''); $messages = array_merge($messages, $genericObjectTypeCheckMessages); if ($this->absentTypeChecks) { if ($this->unresolvableTypeHelper->containsUnresolvableType($ancestorType)) { $messages[] = RuleErrorBuilder::message($unresolvableTypeMessage)->identifier('generics.unresolvable')->build(); } } foreach ($ancestorType->getReferencedClasses() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { $messages[] = RuleErrorBuilder::message(sprintf($invalidTypeMessage, $referencedClass))->identifier('class.notFound')->build(); continue; } if (!$this->absentTypeChecks) { continue; } if ($referencedClass === $ancestorType->getClassName()) { continue; } $classReflection = $this->reflectionProvider->getClass($referencedClass); if (!$classReflection->isTrait()) { continue; } $messages[] = RuleErrorBuilder::message(sprintf($invalidTypeMessage, $referencedClass))->identifier('generics.trait')->build(); } $variance = TemplateTypeVariance::createStatic(); $messageContext = sprintf($invalidVarianceMessage, $ancestorType->describe(VerbosityLevel::typeOnly())); foreach ($this->varianceCheck->check($variance, $ancestorType, $messageContext) as $message) { $messages[] = $message; } foreach ($ancestorType->getVariances() as $index => $typeVariance) { if ($typeVariance->invariant()) { continue; } $messages[] = RuleErrorBuilder::message(sprintf($typeProjectionIsNotAllowedMessage, TypeProjectionHelper::describe($ancestorType->getTypes()[$index], $typeVariance, VerbosityLevel::typeOnly()), $ancestorType->describe(VerbosityLevel::typeOnly())))->identifier('generics.callSiteVarianceNotAllowed')->build(); } } if ($this->checkGenericClassInNonGenericObjectType) { foreach (array_keys($unusedNames) as $unusedName) { if (!$this->reflectionProvider->hasClass($unusedName)) { continue; } $unusedNameClassReflection = $this->reflectionProvider->getClass($unusedName); if (in_array($unusedNameClassReflection->getName(), $this->skipCheckGenericClasses, \true)) { continue; } if (!$unusedNameClassReflection->isGeneric()) { continue; } $templateTypes = $unusedNameClassReflection->getTemplateTypeMap()->getTypes(); $templateTypesCount = count($templateTypes); $requiredTemplateTypesCount = count(array_filter($templateTypes, static function (Type $type) { return $type instanceof TemplateType && $type->getDefault() === null; })); if ($requiredTemplateTypesCount === 0) { continue; } $templateTypesList = implode(', ', array_keys($templateTypes)); if ($requiredTemplateTypesCount !== $templateTypesCount) { $templateTypesList .= sprintf(' (%d-%d required)', $requiredTemplateTypesCount, $templateTypesCount); } $messages[] = RuleErrorBuilder::message(sprintf($genericClassInNonGenericObjectType, $unusedName, $templateTypesList))->identifier('missingType.generics')->build(); } } return $messages; } } */ final class FunctionTemplateTypeRule implements Rule { /** * @var FileTypeMapper */ private $fileTypeMapper; /** * @var TemplateTypeCheck */ private $templateTypeCheck; public function __construct(FileTypeMapper $fileTypeMapper, \PHPStan\Rules\Generics\TemplateTypeCheck $templateTypeCheck) { $this->fileTypeMapper = $fileTypeMapper; $this->templateTypeCheck = $templateTypeCheck; } public function getNodeType() : string { return Node\Stmt\Function_::class; } public function processNode(Node $node, Scope $scope) : array { $docComment = $node->getDocComment(); if ($docComment === null) { return []; } if (!isset($node->namespacedName)) { throw new ShouldNotHappenException(); } $functionName = (string) $node->namespacedName; $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), null, null, $functionName, $docComment->getText()); $escapedFunctionName = SprintfHelper::escapeFormatString($functionName); return $this->templateTypeCheck->check($scope, $node, TemplateTypeScope::createWithFunction($functionName), $resolvedPhpDoc->getTemplateTags(), sprintf('PHPDoc tag @template for function %s() cannot have existing class %%s as its name.', $escapedFunctionName), sprintf('PHPDoc tag @template for function %s() cannot have existing type alias %%s as its name.', $escapedFunctionName), sprintf('PHPDoc tag @template %%s for function %s() has invalid bound type %%s.', $escapedFunctionName), sprintf('PHPDoc tag @template %%s for function %s() with bound type %%s is not supported.', $escapedFunctionName), sprintf('PHPDoc tag @template %%s for function %s() has invalid default type %%s.', $escapedFunctionName), sprintf('Default type %%s in PHPDoc tag @template %%s for function %s() is not subtype of bound type %%s.', $escapedFunctionName), sprintf('PHPDoc tag @template %%s for function %s() does not have a default type but follows an optional @template %%s.', $escapedFunctionName)); } } */ public function check(ClassReflection $classReflection) : array { $interfaceTemplateTypeMaps = []; $errors = []; $check = static function (ClassReflection $classReflection, bool $first) use(&$interfaceTemplateTypeMaps, &$check, &$errors) : void { foreach ($classReflection->getInterfaces() as $interface) { if (!$interface->isGeneric()) { continue; } if (array_key_exists($interface->getName(), $interfaceTemplateTypeMaps)) { $otherMap = $interfaceTemplateTypeMaps[$interface->getName()]; foreach ($interface->getActiveTemplateTypeMap()->getTypes() as $name => $type) { $otherType = $otherMap->getType($name); if ($otherType === null) { continue; } if ($type->equals($otherType)) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('%s specifies template type %s of interface %s as %s but it\'s already specified as %s.', $classReflection->isInterface() ? sprintf('Interface %s', $classReflection->getName()) : sprintf('Class %s', $classReflection->getName()), $name, $interface->getName(), $type->describe(VerbosityLevel::value()), $otherType->describe(VerbosityLevel::value())))->identifier('generics.interfaceConflict')->build(); } continue; } $interfaceTemplateTypeMaps[$interface->getName()] = $interface->getActiveTemplateTypeMap(); } $parent = $classReflection->getParentClass(); $checkParents = \true; if ($first && $parent !== null) { $extendsTags = $classReflection->getExtendsTags(); if (!array_key_exists($parent->getName(), $extendsTags)) { $checkParents = \false; } } if ($checkParents) { while ($parent !== null) { $check($parent, \false); $parent = $parent->getParentClass(); } } $interfaceTags = []; if ($first) { if ($classReflection->isInterface()) { $interfaceTags = $classReflection->getExtendsTags(); } else { $interfaceTags = $classReflection->getImplementsTags(); } } foreach ($classReflection->getInterfaces() as $interface) { if ($first) { if (!array_key_exists($interface->getName(), $interfaceTags)) { continue; } } $check($interface, \false); } }; $check($classReflection, \true); return $errors; } } */ final class InterfaceAncestorsRule implements Rule { /** * @var GenericAncestorsCheck */ private $genericAncestorsCheck; /** * @var CrossCheckInterfacesHelper */ private $crossCheckInterfacesHelper; public function __construct(\PHPStan\Rules\Generics\GenericAncestorsCheck $genericAncestorsCheck, \PHPStan\Rules\Generics\CrossCheckInterfacesHelper $crossCheckInterfacesHelper) { $this->genericAncestorsCheck = $genericAncestorsCheck; $this->crossCheckInterfacesHelper = $crossCheckInterfacesHelper; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $originalNode = $node->getOriginalNode(); if (!$originalNode instanceof Node\Stmt\Interface_) { return []; } $classReflection = $node->getClassReflection(); $interfaceName = $classReflection->getName(); $escapedInterfaceName = SprintfHelper::escapeFormatString($interfaceName); $extendsErrors = $this->genericAncestorsCheck->check($originalNode->extends, array_map(static function (ExtendsTag $tag) : Type { return $tag->getType(); }, $classReflection->getExtendsTags()), sprintf('Interface %s @extends tag contains incompatible type %%s.', $escapedInterfaceName), sprintf('Interface %s @extends tag contains unresolvable type.', $interfaceName), sprintf('Interface %s has @extends tag, but does not extend any interface.', $escapedInterfaceName), sprintf('The @extends tag of interface %s describes %%s but the interface extends: %%s', $escapedInterfaceName), 'PHPDoc tag @extends contains generic type %s but %s %s is not generic.', 'Generic type %s in PHPDoc tag @extends does not specify all template types of %s %s: %s', 'Generic type %s in PHPDoc tag @extends specifies %d template types, but %s %s supports only %d: %s', 'Type %s in generic type %s in PHPDoc tag @extends is not subtype of template type %s of %s %s.', 'Call-site variance annotation of %s in generic type %s in PHPDoc tag @extends is not allowed.', 'PHPDoc tag @extends has invalid type %s.', sprintf('Interface %s extends generic interface %%s but does not specify its types: %%s', $escapedInterfaceName), sprintf('in extended type %%s of interface %s', $escapedInterfaceName)); $implementsErrors = $this->genericAncestorsCheck->check([], array_map(static function (ImplementsTag $tag) : Type { return $tag->getType(); }, $classReflection->getImplementsTags()), sprintf('Interface %s @implements tag contains incompatible type %%s.', $escapedInterfaceName), sprintf('Interface %s @implements tag contains unresolvable type.', $interfaceName), sprintf('Interface %s has @implements tag, but can not implement any interface, must extend from it.', $escapedInterfaceName), '', '', '', '', '', '', '', '', ''); foreach ($this->crossCheckInterfacesHelper->check($classReflection) as $error) { $implementsErrors[] = $error; } return array_merge($extendsErrors, $implementsErrors); } } */ final class UsedTraitsRule implements Rule { /** * @var FileTypeMapper */ private $fileTypeMapper; /** * @var GenericAncestorsCheck */ private $genericAncestorsCheck; public function __construct(FileTypeMapper $fileTypeMapper, \PHPStan\Rules\Generics\GenericAncestorsCheck $genericAncestorsCheck) { $this->fileTypeMapper = $fileTypeMapper; $this->genericAncestorsCheck = $genericAncestorsCheck; } public function getNodeType() : string { return Node\Stmt\TraitUse::class; } public function processNode(Node $node, Scope $scope) : array { if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } $className = $scope->getClassReflection()->getName(); $traitName = null; if ($scope->isInTrait()) { $traitName = $scope->getTraitReflection()->getName(); } $useTags = []; $docComment = $node->getDocComment(); if ($docComment !== null) { $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $className, $traitName, null, $docComment->getText()); $useTags = $resolvedPhpDoc->getUsesTags(); } $typeDescription = strtolower($scope->getClassReflection()->getClassTypeDescription()); $description = sprintf('%s %s', $typeDescription, SprintfHelper::escapeFormatString($className)); if ($traitName !== null) { $typeDescription = 'trait'; $description = sprintf('%s %s', $typeDescription, SprintfHelper::escapeFormatString($traitName)); } $escapedDescription = SprintfHelper::escapeFormatString($description); $upperCaseDescription = ucfirst($description); $escapedUpperCaseDescription = SprintfHelper::escapeFormatString($upperCaseDescription); return $this->genericAncestorsCheck->check($node->traits, array_map(static function (UsesTag $tag) : Type { return $tag->getType(); }, $useTags), sprintf('%s @use tag contains incompatible type %%s.', $escapedUpperCaseDescription), sprintf('%s @use tag contains unresolvable type.', $upperCaseDescription), sprintf('%s has @use tag, but does not use any trait.', $upperCaseDescription), sprintf('The @use tag of %s describes %%s but the %s uses %%s.', $escapedDescription, $typeDescription), 'PHPDoc tag @use contains generic type %s but %s %s is not generic.', 'Generic type %s in PHPDoc tag @use does not specify all template types of %s %s: %s', 'Generic type %s in PHPDoc tag @use specifies %d template types, but %s %s supports only %d: %s', 'Type %s in generic type %s in PHPDoc tag @use is not subtype of template type %s of %s %s.', 'Call-site variance annotation of %s in generic type %s in PHPDoc tag @use is not allowed.', 'PHPDoc tag @use has invalid type %s.', sprintf('%s uses generic trait %%s but does not specify its types: %%s', $escapedUpperCaseDescription), sprintf('in used type %%s of %s', $escapedDescription)); } } */ final class TraitTemplateTypeRule implements Rule { /** * @var FileTypeMapper */ private $fileTypeMapper; /** * @var TemplateTypeCheck */ private $templateTypeCheck; public function __construct(FileTypeMapper $fileTypeMapper, \PHPStan\Rules\Generics\TemplateTypeCheck $templateTypeCheck) { $this->fileTypeMapper = $fileTypeMapper; $this->templateTypeCheck = $templateTypeCheck; } public function getNodeType() : string { return Node\Stmt\Trait_::class; } public function processNode(Node $node, Scope $scope) : array { $docComment = $node->getDocComment(); if ($docComment === null) { return []; } if (!isset($node->namespacedName)) { throw new ShouldNotHappenException(); } $traitName = (string) $node->namespacedName; $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $traitName, null, null, $docComment->getText()); $escapedTraitName = SprintfHelper::escapeFormatString($traitName); return $this->templateTypeCheck->check($scope, $node, TemplateTypeScope::createWithClass($traitName), $resolvedPhpDoc->getTemplateTags(), sprintf('PHPDoc tag @template for trait %s cannot have existing class %%s as its name.', $escapedTraitName), sprintf('PHPDoc tag @template for trait %s cannot have existing type alias %%s as its name.', $escapedTraitName), sprintf('PHPDoc tag @template %%s for trait %s has invalid bound type %%s.', $escapedTraitName), sprintf('PHPDoc tag @template %%s for trait %s with bound type %%s is not supported.', $escapedTraitName), sprintf('PHPDoc tag @template %%s for trait %s has invalid default type %%s.', $escapedTraitName), sprintf('Default type %%s in PHPDoc tag @template %%s for trait %s is not subtype of bound type %%s.', $escapedTraitName), sprintf('PHPDoc tag @template %%s for trait %s does not have a default type but follows an optional @template %%s.', $escapedTraitName)); } } */ final class MethodTemplateTypeRule implements Rule { /** * @var FileTypeMapper */ private $fileTypeMapper; /** * @var TemplateTypeCheck */ private $templateTypeCheck; public function __construct(FileTypeMapper $fileTypeMapper, \PHPStan\Rules\Generics\TemplateTypeCheck $templateTypeCheck) { $this->fileTypeMapper = $fileTypeMapper; $this->templateTypeCheck = $templateTypeCheck; } public function getNodeType() : string { return Node\Stmt\ClassMethod::class; } public function processNode(Node $node, Scope $scope) : array { $docComment = $node->getDocComment(); if ($docComment === null) { return []; } if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } $classReflection = $scope->getClassReflection(); $className = $classReflection->getDisplayName(); $methodName = $node->name->toString(); $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $classReflection->getName(), $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $methodName, $docComment->getText()); $methodTemplateTags = $resolvedPhpDoc->getTemplateTags(); $escapedClassName = SprintfHelper::escapeFormatString($className); $escapedMethodName = SprintfHelper::escapeFormatString($methodName); $messages = $this->templateTypeCheck->check($scope, $node, TemplateTypeScope::createWithMethod($className, $methodName), $methodTemplateTags, sprintf('PHPDoc tag @template for method %s::%s() cannot have existing class %%s as its name.', $escapedClassName, $escapedMethodName), sprintf('PHPDoc tag @template for method %s::%s() cannot have existing type alias %%s as its name.', $escapedClassName, $escapedMethodName), sprintf('PHPDoc tag @template %%s for method %s::%s() has invalid bound type %%s.', $escapedClassName, $escapedMethodName), sprintf('PHPDoc tag @template %%s for method %s::%s() with bound type %%s is not supported.', $escapedClassName, $escapedMethodName), sprintf('PHPDoc tag @template %%s for method %s::%s() has invalid default type %%s.', $escapedClassName, $escapedMethodName), sprintf('Default type %%s in PHPDoc tag @template %%s for method %s::%s() is not subtype of bound type %%s.', $escapedClassName, $escapedMethodName), sprintf('PHPDoc tag @template %%s for method %s::%s() does not have a default type but follows an optional @template %%s.', $escapedClassName, $escapedMethodName)); $classTemplateTypes = $classReflection->getTemplateTypeMap()->getTypes(); foreach (array_keys($methodTemplateTags) as $name) { if (!isset($classTemplateTypes[$name])) { continue; } $messages[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @template %s for method %s::%s() shadows @template %s for class %s.', $name, $className, $methodName, $classTemplateTypes[$name]->describe(VerbosityLevel::typeOnly()), $classReflection->getDisplayName(\false)))->identifier('method.shadowTemplate')->build(); } return $messages; } } */ final class ClassAncestorsRule implements Rule { /** * @var GenericAncestorsCheck */ private $genericAncestorsCheck; /** * @var CrossCheckInterfacesHelper */ private $crossCheckInterfacesHelper; public function __construct(\PHPStan\Rules\Generics\GenericAncestorsCheck $genericAncestorsCheck, \PHPStan\Rules\Generics\CrossCheckInterfacesHelper $crossCheckInterfacesHelper) { $this->genericAncestorsCheck = $genericAncestorsCheck; $this->crossCheckInterfacesHelper = $crossCheckInterfacesHelper; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $originalNode = $node->getOriginalNode(); if (!$originalNode instanceof Node\Stmt\Class_) { return []; } $classReflection = $node->getClassReflection(); if ($classReflection->isAnonymous()) { return []; } $className = $classReflection->getName(); $escapedClassName = SprintfHelper::escapeFormatString($className); $extendsErrors = $this->genericAncestorsCheck->check($originalNode->extends !== null ? [$originalNode->extends] : [], array_map(static function (ExtendsTag $tag) : Type { return $tag->getType(); }, $classReflection->getExtendsTags()), sprintf('Class %s @extends tag contains incompatible type %%s.', $escapedClassName), sprintf('Class %s @extends tag contains unresolvable type.', $className), sprintf('Class %s has @extends tag, but does not extend any class.', $escapedClassName), sprintf('The @extends tag of class %s describes %%s but the class extends %%s.', $escapedClassName), 'PHPDoc tag @extends contains generic type %s but %s %s is not generic.', 'Generic type %s in PHPDoc tag @extends does not specify all template types of %s %s: %s', 'Generic type %s in PHPDoc tag @extends specifies %d template types, but %s %s supports only %d: %s', 'Type %s in generic type %s in PHPDoc tag @extends is not subtype of template type %s of %s %s.', 'Call-site variance annotation of %s in generic type %s in PHPDoc tag @extends is not allowed.', 'PHPDoc tag @extends has invalid type %s.', sprintf('Class %s extends generic class %%s but does not specify its types: %%s', $escapedClassName), sprintf('in extended type %%s of class %s', $escapedClassName)); $implementsErrors = $this->genericAncestorsCheck->check($originalNode->implements, array_map(static function (ImplementsTag $tag) : Type { return $tag->getType(); }, $classReflection->getImplementsTags()), sprintf('Class %s @implements tag contains incompatible type %%s.', $escapedClassName), sprintf('Class %s @implements tag contains unresolvable type.', $className), sprintf('Class %s has @implements tag, but does not implement any interface.', $escapedClassName), sprintf('The @implements tag of class %s describes %%s but the class implements: %%s', $escapedClassName), 'PHPDoc tag @implements contains generic type %s but %s %s is not generic.', 'Generic type %s in PHPDoc tag @implements does not specify all template types of %s %s: %s', 'Generic type %s in PHPDoc tag @implements specifies %d template types, but %s %s supports only %d: %s', 'Type %s in generic type %s in PHPDoc tag @implements is not subtype of template type %s of %s %s.', 'Call-site variance annotation of %s in generic type %s in PHPDoc tag @implements is not allowed.', 'PHPDoc tag @implements has invalid type %s.', sprintf('Class %s implements generic interface %%s but does not specify its types: %%s', $escapedClassName), sprintf('in implemented type %%s of class %s', $escapedClassName)); foreach ($this->crossCheckInterfacesHelper->check($classReflection) as $error) { $implementsErrors[] = $error; } return array_merge($extendsErrors, $implementsErrors); } } */ public function check(Type $phpDocType, string $classNotGenericMessage, string $notEnoughTypesMessage, string $extraTypesMessage, string $typeIsNotSubtypeMessage, string $typeProjectionHasConflictingVarianceMessage, string $typeProjectionIsRedundantMessage) : array { $genericTypes = $this->getGenericTypes($phpDocType); $messages = []; foreach ($genericTypes as $genericType) { $classReflection = $genericType->getClassReflection(); if ($classReflection === null) { continue; } $classLikeDescription = strtolower($classReflection->getClassTypeDescription()); if (!$classReflection->isGeneric()) { $messages[] = RuleErrorBuilder::message(sprintf($classNotGenericMessage, $genericType->describe(VerbosityLevel::typeOnly()), $classLikeDescription, $classReflection->getDisplayName()))->identifier('generics.notGeneric')->build(); continue; } $templateTypes = array_values($classReflection->getTemplateTypeMap()->getTypes()); $genericTypeTypes = $genericType->getTypes(); $genericTypeVariances = $genericType->getVariances(); $templateTypesCount = count($templateTypes); $genericTypeTypesCount = count($genericTypeTypes); $requiredTemplateTypesCount = count(array_filter($templateTypes, static function (Type $type) { return $type instanceof TemplateType && $type->getDefault() === null; })); if ($requiredTemplateTypesCount > $genericTypeTypesCount) { $templateTypesList = implode(', ', array_keys($classReflection->getTemplateTypeMap()->getTypes())); if ($requiredTemplateTypesCount !== $templateTypesCount) { $templateTypesList .= sprintf(' (%d-%d required).', $requiredTemplateTypesCount, $templateTypesCount); } $messages[] = RuleErrorBuilder::message(sprintf($notEnoughTypesMessage, $genericType->describe(VerbosityLevel::typeOnly()), $classLikeDescription, $classReflection->getDisplayName(\false), $templateTypesList))->identifier('generics.lessTypes')->build(); } elseif ($templateTypesCount < $genericTypeTypesCount) { $templateTypesList = implode(', ', array_keys($classReflection->getTemplateTypeMap()->getTypes())); if ($requiredTemplateTypesCount !== $templateTypesCount) { $templateTypesList .= sprintf(' (%d-%d required)', $requiredTemplateTypesCount, $templateTypesCount); } $messages[] = RuleErrorBuilder::message(sprintf($extraTypesMessage, $genericType->describe(VerbosityLevel::typeOnly()), $genericTypeTypesCount, $classLikeDescription, $classReflection->getDisplayName(\false), $templateTypesCount, $templateTypesList))->identifier('generics.moreTypes')->build(); } for ($i = 0; $i < $templateTypesCount; $i++) { if (!isset($genericTypeTypes[$i])) { continue; } $templateType = $templateTypes[$i]; $genericTypeType = $genericTypeTypes[$i]; $genericTypeVariance = $genericTypeVariances[$i] ?? TemplateTypeVariance::createInvariant(); if ($templateType instanceof TemplateType && !$genericTypeVariance->invariant()) { if ($genericTypeVariance->equals($templateType->getVariance())) { $messages[] = RuleErrorBuilder::message(sprintf($typeProjectionIsRedundantMessage, TypeProjectionHelper::describe($genericTypeType, $genericTypeVariance, VerbosityLevel::typeOnly()), $genericType->describe(VerbosityLevel::typeOnly()), $templateType->describe(VerbosityLevel::typeOnly()), $classLikeDescription, $classReflection->getDisplayName(\false)))->identifier('generics.callSiteVarianceRedundant')->tip('You can safely remove the call-site variance annotation.')->build(); } elseif (!$genericTypeVariance->validPosition($templateType->getVariance())) { $messages[] = RuleErrorBuilder::message(sprintf($typeProjectionHasConflictingVarianceMessage, TypeProjectionHelper::describe($genericTypeType, $genericTypeVariance, VerbosityLevel::typeOnly()), $genericType->describe(VerbosityLevel::typeOnly()), $templateType->getVariance()->describe(), $templateType->describe(VerbosityLevel::typeOnly()), $classLikeDescription, $classReflection->getDisplayName(\false)))->identifier('generics.callSiteVarianceConflict')->build(); } } $boundType = TemplateTypeHelper::resolveToBounds($templateType); if ($boundType->isSuperTypeOf($genericTypeType)->yes()) { if (!$templateType instanceof TemplateType) { continue; } $map = $templateType->inferTemplateTypes($genericTypeType); for ($j = 0; $j < $templateTypesCount; $j++) { if ($i === $j) { continue; } $templateTypes[$j] = TemplateTypeHelper::resolveTemplateTypes($templateTypes[$j], $map, TemplateTypeVarianceMap::createEmpty(), TemplateTypeVariance::createStatic()); } continue; } if ($genericTypeVariance->bivariant()) { continue; } $messages[] = RuleErrorBuilder::message(sprintf($typeIsNotSubtypeMessage, $genericTypeType->describe(VerbosityLevel::typeOnly()), $genericType->describe(VerbosityLevel::typeOnly()), $templateType->describe(VerbosityLevel::typeOnly()), $classLikeDescription, $classReflection->getDisplayName(\false)))->identifier('generics.notSubtype')->build(); } } return $messages; } /** * @return list */ private function getGenericTypes(Type $phpDocType) : array { $genericObjectTypes = []; TypeTraverser::map($phpDocType, static function (Type $type, callable $traverse) use(&$genericObjectTypes) : Type { if ($type instanceof GenericObjectType || $type instanceof GenericStaticType) { $resolvedType = TemplateTypeHelper::resolveToBounds($type); if (!$resolvedType instanceof GenericObjectType && !$resolvedType instanceof GenericStaticType) { throw new ShouldNotHappenException(); } $genericObjectTypes[] = $resolvedType; $traverse($type); return $type; } $traverse($type); return $type; }); return $genericObjectTypes; } } checkParamOutVariance = $checkParamOutVariance; $this->strictStaticVariance = $strictStaticVariance; } /** * @param 'function'|'method' $identifier * @return list */ public function checkParametersAcceptor(ParametersAcceptorWithPhpDocs $parametersAcceptor, string $parameterTypeMessage, string $parameterOutTypeMessage, string $returnTypeMessage, string $generalMessage, bool $isStatic, bool $isPrivate, string $identifier) : array { $errors = []; foreach ($parametersAcceptor->getTemplateTypeMap()->getTypes() as $templateType) { if (!$templateType instanceof TemplateType || $templateType->getScope()->getFunctionName() === null || $templateType->getVariance()->invariant()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Variance annotation is only allowed for type parameters of classes and interfaces, but occurs in template type %s in %s.', $templateType->getName(), $generalMessage))->identifier(sprintf('%s.variance', $identifier))->build(); } if ($isPrivate) { return $errors; } $covariant = TemplateTypeVariance::createCovariant(); $parameterVariance = $isStatic && !$this->strictStaticVariance ? TemplateTypeVariance::createStatic() : TemplateTypeVariance::createContravariant(); foreach ($parametersAcceptor->getParameters() as $parameterReflection) { $type = $parameterReflection->getType(); $message = sprintf($parameterTypeMessage, $parameterReflection->getName()); foreach ($this->check($parameterVariance, $type, $message) as $error) { $errors[] = $error; } if (!$this->checkParamOutVariance) { continue; } $paramOutType = $parameterReflection->getOutType(); if ($paramOutType === null) { continue; } $outMessage = sprintf($parameterOutTypeMessage, $parameterReflection->getName()); foreach ($this->check($covariant, $paramOutType, $outMessage) as $error) { $errors[] = $error; } } $type = $parametersAcceptor->getReturnType(); foreach ($this->check($covariant, $type, $returnTypeMessage) as $error) { $errors[] = $error; } return $errors; } /** @return list */ public function check(TemplateTypeVariance $positionVariance, Type $type, string $messageContext) : array { $errors = []; foreach ($type->getReferencedTemplateTypes($positionVariance) as $reference) { $referredType = $reference->getType(); if ($referredType->getScope()->getFunctionName() !== null && !$referredType->getVariance()->invariant() || $this->isTemplateTypeVarianceValid($reference->getPositionVariance(), $referredType)) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Template type %s is declared as %s, but occurs in %s position %s.', $referredType->getName(), $referredType->getVariance()->describe(), $reference->getPositionVariance()->describe(), $messageContext))->identifier('generics.variance')->build(); } return $errors; } private function isTemplateTypeVarianceValid(TemplateTypeVariance $positionVariance, TemplateType $type) : bool { return $positionVariance->validPosition($type->getVariance()); } } fileTypeMapper = $fileTypeMapper; $this->templateTypeCheck = $templateTypeCheck; } /** * @return list */ public function check(ClassReflection $classReflection, Scope $scope, ClassLike $node, string $docComment) : array { $className = $classReflection->getDisplayName(); $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $classReflection->getName(), $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, null, $docComment); $messages = []; $escapedClassName = SprintfHelper::escapeFormatString($className); $classTemplateTypes = $classReflection->getTemplateTypeMap()->getTypes(); foreach ($resolvedPhpDoc->getMethodTags() as $methodName => $methodTag) { $methodTemplateTags = $methodTag->getTemplateTags(); $escapedMethodName = SprintfHelper::escapeFormatString($methodName); $messages = array_merge($messages, $this->templateTypeCheck->check($scope, $node, TemplateTypeScope::createWithMethod($className, $methodName), $methodTemplateTags, sprintf('PHPDoc tag @method template for method %s::%s() cannot have existing class %%s as its name.', $escapedClassName, $escapedMethodName), sprintf('PHPDoc tag @method template for method %s::%s() cannot have existing type alias %%s as its name.', $escapedClassName, $escapedMethodName), sprintf('PHPDoc tag @method template %%s for method %s::%s() has invalid bound type %%s.', $escapedClassName, $escapedMethodName), sprintf('PHPDoc tag @method template %%s for method %s::%s() with bound type %%s is not supported.', $escapedClassName, $escapedMethodName), sprintf('PHPDoc tag @method template %%s for method %s::%s() has invalid default type %%s', $escapedClassName, $escapedMethodName), sprintf('Default type %%s in PHPDoc tag @method template %%s for method %s::%s() is not subtype of bound type %%s', $escapedClassName, $escapedMethodName), sprintf('PHPDoc tag @template %%s for method %s::%s() does not have a default type but follows an optional @template %%s.', $escapedClassName, $escapedMethodName))); foreach (array_keys($methodTemplateTags) as $name) { if (!isset($classTemplateTypes[$name])) { continue; } $messages[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @method template %s for method %s::%s() shadows @template %s for class %s.', $name, $className, $methodName, $classTemplateTypes[$name]->describe(VerbosityLevel::typeOnly()), $classReflection->getDisplayName(\false)))->identifier('methodTag.shadowTemplate')->build(); } } return $messages; } } */ final class MethodTagTemplateTypeRule implements Rule { /** * @var MethodTagTemplateTypeCheck */ private $check; public function __construct(\PHPStan\Rules\Generics\MethodTagTemplateTypeCheck $check) { $this->check = $check; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $docComment = $node->getDocComment(); if ($docComment === null) { return []; } return $this->check->check($node->getClassReflection(), $scope, $node->getOriginalNode(), $docComment->getText()); } } */ final class EnumTemplateTypeRule implements Rule { public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $classReflection = $node->getClassReflection(); if (!$classReflection->isEnum()) { return []; } $templateTagsCount = count($classReflection->getTemplateTags()); if ($templateTagsCount === 0) { return []; } $className = $classReflection->getDisplayName(); return [RuleErrorBuilder::message(sprintf('Enum %s has PHPDoc @template tag%s but enums cannot be generic.', $className, $templateTagsCount === 1 ? '' : 's'))->identifier('enum.generic')->build()]; } } */ final class MethodTagTemplateTypeTraitRule implements Rule { /** * @var MethodTagTemplateTypeCheck */ private $check; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Generics\MethodTagTemplateTypeCheck $check, ReflectionProvider $reflectionProvider) { $this->check = $check; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Stmt\Trait_::class; } public function processNode(Node $node, Scope $scope) : array { $docComment = $node->getDocComment(); if ($docComment === null) { return []; } $traitName = $node->namespacedName; if ($traitName === null) { return []; } if (!$this->reflectionProvider->hasClass($traitName->toString())) { return []; } return $this->check->check($this->reflectionProvider->getClass($traitName->toString()), $scope, $node, $docComment->getText()); } } */ final class EnumAncestorsRule implements Rule { /** * @var GenericAncestorsCheck */ private $genericAncestorsCheck; /** * @var CrossCheckInterfacesHelper */ private $crossCheckInterfacesHelper; public function __construct(\PHPStan\Rules\Generics\GenericAncestorsCheck $genericAncestorsCheck, \PHPStan\Rules\Generics\CrossCheckInterfacesHelper $crossCheckInterfacesHelper) { $this->genericAncestorsCheck = $genericAncestorsCheck; $this->crossCheckInterfacesHelper = $crossCheckInterfacesHelper; } public function getNodeType() : string { return InClassNode::class; } public function processNode(Node $node, Scope $scope) : array { $originalNode = $node->getOriginalNode(); if (!$originalNode instanceof Node\Stmt\Enum_) { return []; } $classReflection = $node->getClassReflection(); $enumName = $classReflection->getName(); $escapedEnumName = SprintfHelper::escapeFormatString($enumName); $extendsErrors = $this->genericAncestorsCheck->check([], array_map(static function (ExtendsTag $tag) : Type { return $tag->getType(); }, $classReflection->getExtendsTags()), sprintf('Enum %s @extends tag contains incompatible type %%s.', $escapedEnumName), sprintf('Enum %s @extends tag contains unresolvable type.', $enumName), sprintf('Enum %s has @extends tag, but cannot extend anything.', $escapedEnumName), '', '', '', '', '', '', '', '', ''); $implementsErrors = $this->genericAncestorsCheck->check($originalNode->implements, array_map(static function (ImplementsTag $tag) : Type { return $tag->getType(); }, $classReflection->getImplementsTags()), sprintf('Enum %s @implements tag contains incompatible type %%s.', $escapedEnumName), sprintf('Enum %s @implements tag contains unresolvable type.', $enumName), sprintf('Enum %s has @implements tag, but does not implement any interface.', $escapedEnumName), sprintf('The @implements tag of eunm %s describes %%s but the enum implements: %%s', $escapedEnumName), 'PHPDoc tag @implements contains generic type %s but %s %s is not generic.', 'Generic type %s in PHPDoc tag @implements does not specify all template types of %s %s: %s', 'Generic type %s in PHPDoc tag @implements specifies %d template types, but %s %s supports only %d: %s', 'Type %s in generic type %s in PHPDoc tag @implements is not subtype of template type %s of %s %s.', 'Call-site variance annotation of %s in generic type %s in PHPDoc tag @implements is not allowed.', 'PHPDoc tag @implements has invalid type %s.', sprintf('Enum %s implements generic interface %%s but does not specify its types: %%s', $escapedEnumName), sprintf('in implemented type %%s of enum %s', $escapedEnumName)); foreach ($this->crossCheckInterfacesHelper->check($classReflection) as $error) { $implementsErrors[] = $error; } return array_merge($extendsErrors, $implementsErrors); } } */ final class MethodSignatureVarianceRule implements Rule { /** * @var VarianceCheck */ private $varianceCheck; public function __construct(\PHPStan\Rules\Generics\VarianceCheck $varianceCheck) { $this->varianceCheck = $varianceCheck; } public function getNodeType() : string { return InClassMethodNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); return $this->varianceCheck->checkParametersAcceptor($method, sprintf('in parameter %%s of method %s::%s()', SprintfHelper::escapeFormatString($method->getDeclaringClass()->getDisplayName()), SprintfHelper::escapeFormatString($method->getName())), sprintf('in param-out type of parameter %%s of method %s::%s()', SprintfHelper::escapeFormatString($method->getDeclaringClass()->getDisplayName()), SprintfHelper::escapeFormatString($method->getName())), sprintf('in return type of method %s::%s()', $method->getDeclaringClass()->getDisplayName(), $method->getName()), sprintf('in method %s::%s()', $method->getDeclaringClass()->getDisplayName(), $method->getName()), $method->isStatic(), $method->isPrivate() || $method->getName() === '__construct', 'method'); } } */ final class DumpPhpDocTypeRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var Printer */ private $printer; public function __construct(ReflectionProvider $reflectionProvider, Printer $printer) { $this->reflectionProvider = $reflectionProvider; $this->printer = $printer; } public function getNodeType() : string { return Node\Expr\FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } $functionName = $this->reflectionProvider->resolveFunctionName($node->name, $scope); if ($functionName === null) { return []; } if (strtolower($functionName) !== 'phpstan\\dumpphpdoctype') { return []; } if (count($node->getArgs()) === 0) { return []; } return [RuleErrorBuilder::message(sprintf('Dumped type: %s', $this->printer->print($scope->getType($node->getArgs()[0]->value)->toPhpDocNode())))->nonIgnorable()->identifier('phpstan.dumpPhpDocType')->build()]; } } */ final class DebugScopeRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ReflectionProvider $reflectionProvider) { $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Expr\FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } $functionName = $this->reflectionProvider->resolveFunctionName($node->name, $scope); if ($functionName === null) { return []; } if (strtolower($functionName) !== 'phpstan\\debugscope') { return []; } if (!$scope instanceof MutatingScope) { return []; } $parts = []; foreach ($scope->debug() as $key => $row) { $parts[] = sprintf('%s: %s', $key, $row); } if (count($parts) === 0) { $parts[] = 'Scope is empty'; } return [RuleErrorBuilder::message(implode("\n", $parts))->nonIgnorable()->identifier('phpstan.debugScope')->build()]; } } */ final class DumpTypeRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ReflectionProvider $reflectionProvider) { $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Expr\FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } $functionName = $this->reflectionProvider->resolveFunctionName($node->name, $scope); if ($functionName === null) { return []; } if (strtolower($functionName) !== 'phpstan\\dumptype') { return []; } if (count($node->getArgs()) === 0) { return []; } return [RuleErrorBuilder::message(sprintf('Dumped type: %s', $scope->getType($node->getArgs()[0]->value)->describe(VerbosityLevel::precise())))->nonIgnorable()->identifier('phpstan.dumpType')->build()]; } } */ final class FileAssertRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ReflectionProvider $reflectionProvider) { $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Expr\FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } $function = $this->reflectionProvider->getFunction($node->name, $scope); if ($function->getName() === 'PHPStan\\Testing\\assertType') { return $this->processAssertType($node->getArgs(), $scope); } if ($function->getName() === 'PHPStan\\Testing\\assertNativeType') { return $this->processAssertNativeType($node->getArgs(), $scope); } if ($function->getName() === 'PHPStan\\Testing\\assertVariableCertainty') { return $this->processAssertVariableCertainty($node->getArgs(), $scope); } return []; } /** * @param Node\Arg[] $args * @return list */ private function processAssertType(array $args, Scope $scope) : array { if (count($args) !== 2) { return []; } $expectedTypeStrings = $scope->getType($args[0]->value)->getConstantStrings(); if (count($expectedTypeStrings) !== 1) { return [RuleErrorBuilder::message('Expected type must be a literal string.')->nonIgnorable()->identifier('phpstan.unknownExpectation')->build()]; } $expressionType = $scope->getType($args[1]->value)->describe(VerbosityLevel::precise()); if ($expectedTypeStrings[0]->getValue() === $expressionType) { return []; } return [RuleErrorBuilder::message(sprintf('Expected type %s, actual: %s', $expectedTypeStrings[0]->getValue(), $expressionType))->nonIgnorable()->identifier('phpstan.type')->build()]; } /** * @param Node\Arg[] $args * @return list */ private function processAssertNativeType(array $args, Scope $scope) : array { if (count($args) !== 2) { return []; } $expectedTypeStrings = $scope->getNativeType($args[0]->value)->getConstantStrings(); if (count($expectedTypeStrings) !== 1) { return [RuleErrorBuilder::message('Expected native type must be a literal string.')->nonIgnorable()->identifier('phpstan.unknownExpectation')->build()]; } $expressionType = $scope->getNativeType($args[1]->value)->describe(VerbosityLevel::precise()); if ($expectedTypeStrings[0]->getValue() === $expressionType) { return []; } return [RuleErrorBuilder::message(sprintf('Expected native type %s, actual: %s', $expectedTypeStrings[0]->getValue(), $expressionType))->nonIgnorable()->identifier('phpstan.nativeType')->build()]; } /** * @param Node\Arg[] $args * @return list */ private function processAssertVariableCertainty(array $args, Scope $scope) : array { if (count($args) !== 2) { return []; } $certainty = $args[0]->value; if (!$certainty instanceof StaticCall) { return [RuleErrorBuilder::message('First argument of %s() must be TrinaryLogic call')->nonIgnorable()->identifier('phpstan.unknownExpectation')->build()]; } if (!$certainty->class instanceof Node\Name) { return [RuleErrorBuilder::message('Invalid TrinaryLogic call.')->nonIgnorable()->identifier('phpstan.unknownExpectation')->build()]; } if ($certainty->class->toString() !== 'PHPStan\\TrinaryLogic') { return [RuleErrorBuilder::message('Invalid TrinaryLogic call.')->nonIgnorable()->identifier('phpstan.unknownExpectation')->build()]; } if (!$certainty->name instanceof Node\Identifier) { return [RuleErrorBuilder::message('Invalid TrinaryLogic call.')->nonIgnorable()->identifier('phpstan.unknownExpectation')->build()]; } // @phpstan-ignore staticMethod.dynamicName $expectedCertaintyValue = TrinaryLogic::{$certainty->name->toString()}(); $variable = $args[1]->value; if ($variable instanceof Node\Expr\Variable && is_string($variable->name)) { $actualCertaintyValue = $scope->hasVariableType($variable->name); $variableDescription = sprintf('variable $%s', $variable->name); } elseif ($variable instanceof Node\Expr\ArrayDimFetch && $variable->dim !== null) { $offset = $scope->getType($variable->dim); $actualCertaintyValue = $scope->getType($variable->var)->hasOffsetValueType($offset); $variableDescription = sprintf('offset %s', $offset->describe(VerbosityLevel::precise())); } else { return [RuleErrorBuilder::message('Invalid assertVariableCertainty call.')->nonIgnorable()->identifier('phpstan.unknownExpectation')->build()]; } if ($expectedCertaintyValue->equals($actualCertaintyValue)) { return []; } return [RuleErrorBuilder::message(sprintf('Expected %s certainty %s, actual: %s', $variableDescription, $expectedCertaintyValue->describe(), $actualCertaintyValue->describe()))->nonIgnorable()->identifier('phpstan.variable')->build()]; } } propertyDescriptor = $propertyDescriptor; $this->propertyReflectionFinder = $propertyReflectionFinder; $this->checkAdvancedIsset = $checkAdvancedIsset; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->strictUnnecessaryNullsafePropertyFetch = $strictUnnecessaryNullsafePropertyFetch; } /** * @param ErrorIdentifier $identifier * @param callable(Type): ?string $typeMessageCallback */ public function check(Expr $expr, Scope $scope, string $operatorDescription, string $identifier, callable $typeMessageCallback, ?\PHPStan\Rules\IdentifierRuleError $error = null) : ?\PHPStan\Rules\IdentifierRuleError { // mirrored in PHPStan\Analyser\MutatingScope::issetCheck() if ($expr instanceof Node\Expr\Variable && is_string($expr->name)) { $hasVariable = $scope->hasVariableType($expr->name); if ($hasVariable->maybe()) { return null; } if ($error === null) { if ($hasVariable->yes()) { if ($expr->name === '_SESSION') { return null; } $type = $this->treatPhpDocTypesAsCertain ? $scope->getType($expr) : $scope->getNativeType($expr); if (!$type instanceof NeverType) { return $this->generateError($type, sprintf('Variable $%s %s always exists and', $expr->name, $operatorDescription), $typeMessageCallback, $identifier, 'variable'); } } return \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Variable $%s %s is never defined.', $expr->name, $operatorDescription))->identifier(sprintf('%s.variable', $identifier))->build(); } return $error; } elseif ($expr instanceof Node\Expr\ArrayDimFetch && $expr->dim !== null) { $type = $this->treatPhpDocTypesAsCertain ? $scope->getType($expr->var) : $scope->getNativeType($expr->var); if (!$type->isOffsetAccessible()->yes()) { return $error ?? $this->checkUndefined($expr->var, $scope, $operatorDescription, $identifier); } $dimType = $this->treatPhpDocTypesAsCertain ? $scope->getType($expr->dim) : $scope->getNativeType($expr->dim); $hasOffsetValue = $type->hasOffsetValueType($dimType); if ($hasOffsetValue->no()) { if (!$this->checkAdvancedIsset) { return null; } return \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Offset %s on %s %s does not exist.', $dimType->describe(VerbosityLevel::value()), $type->describe(VerbosityLevel::value()), $operatorDescription))->identifier(sprintf('%s.offset', $identifier))->build(); } // If offset cannot be null, store this error message and see if one of the earlier offsets is. // E.g. $array['a']['b']['c'] ?? null; is a valid coalesce if a OR b or C might be null. if ($hasOffsetValue->yes() || $scope->hasExpressionType($expr)->yes()) { if (!$this->checkAdvancedIsset) { return null; } $error = $error ?? $this->generateError($type->getOffsetValueType($dimType), sprintf('Offset %s on %s %s always exists and', $dimType->describe(VerbosityLevel::value()), $type->describe(VerbosityLevel::value()), $operatorDescription), $typeMessageCallback, $identifier, 'offset'); if ($error !== null) { return $this->check($expr->var, $scope, $operatorDescription, $identifier, $typeMessageCallback, $error); } } // Has offset, it is nullable return null; } elseif ($expr instanceof Node\Expr\PropertyFetch || $expr instanceof Node\Expr\StaticPropertyFetch) { $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($expr, $scope); if ($propertyReflection === null) { if ($expr instanceof Node\Expr\PropertyFetch) { return $this->checkUndefined($expr->var, $scope, $operatorDescription, $identifier); } if ($expr->class instanceof Expr) { return $this->checkUndefined($expr->class, $scope, $operatorDescription, $identifier); } return null; } if (!$propertyReflection->isNative()) { if ($expr instanceof Node\Expr\PropertyFetch) { return $this->checkUndefined($expr->var, $scope, $operatorDescription, $identifier); } if ($expr->class instanceof Expr) { return $this->checkUndefined($expr->class, $scope, $operatorDescription, $identifier); } return null; } $nativeType = $propertyReflection->getNativeType(); if (!$nativeType instanceof MixedType) { if (!$scope->hasExpressionType($expr)->yes()) { if ($expr instanceof Node\Expr\PropertyFetch) { return $this->checkUndefined($expr->var, $scope, $operatorDescription, $identifier); } if ($expr->class instanceof Expr) { return $this->checkUndefined($expr->class, $scope, $operatorDescription, $identifier); } return null; } } $propertyDescription = $this->propertyDescriptor->describeProperty($propertyReflection, $scope, $expr); $propertyType = $propertyReflection->getWritableType(); if ($error !== null) { return $error; } if (!$this->checkAdvancedIsset) { if ($expr instanceof Node\Expr\PropertyFetch) { return $this->checkUndefined($expr->var, $scope, $operatorDescription, $identifier); } if ($expr->class instanceof Expr) { return $this->checkUndefined($expr->class, $scope, $operatorDescription, $identifier); } return null; } $error = $this->generateError($propertyReflection->getWritableType(), sprintf('%s (%s) %s', $propertyDescription, $propertyType->describe(VerbosityLevel::typeOnly()), $operatorDescription), $typeMessageCallback, $identifier, 'property'); if ($error !== null) { if ($expr instanceof Node\Expr\PropertyFetch) { return $this->check($expr->var, $scope, $operatorDescription, $identifier, $typeMessageCallback, $error); } if ($expr->class instanceof Expr) { return $this->check($expr->class, $scope, $operatorDescription, $identifier, $typeMessageCallback, $error); } } return $error; } if ($error !== null) { return $error; } if (!$this->checkAdvancedIsset) { return null; } $error = $this->generateError($this->treatPhpDocTypesAsCertain ? $scope->getType($expr) : $scope->getNativeType($expr), sprintf('Expression %s', $operatorDescription), $typeMessageCallback, $identifier, 'expr'); if ($error !== null) { return $error; } if ($expr instanceof Expr\NullsafePropertyFetch) { if (!$this->strictUnnecessaryNullsafePropertyFetch) { return null; } if ($expr->name instanceof Node\Identifier) { return \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Using nullsafe property access "?->%s" %s is unnecessary. Use -> instead.', $expr->name->name, $operatorDescription))->identifier('nullsafe.neverNull')->build(); } return \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Using nullsafe property access "?->(Expression)" %s is unnecessary. Use -> instead.', $operatorDescription))->identifier('nullsafe.neverNull')->build(); } return null; } /** * @param ErrorIdentifier $identifier */ private function checkUndefined(Expr $expr, Scope $scope, string $operatorDescription, string $identifier) : ?\PHPStan\Rules\IdentifierRuleError { if ($expr instanceof Node\Expr\Variable && is_string($expr->name)) { $hasVariable = $scope->hasVariableType($expr->name); if (!$hasVariable->no()) { return null; } return \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Variable $%s %s is never defined.', $expr->name, $operatorDescription))->identifier(sprintf('%s.variable', $identifier))->build(); } if ($expr instanceof Node\Expr\ArrayDimFetch && $expr->dim !== null) { $type = $this->treatPhpDocTypesAsCertain ? $scope->getType($expr->var) : $scope->getNativeType($expr->var); $dimType = $this->treatPhpDocTypesAsCertain ? $scope->getType($expr->dim) : $scope->getNativeType($expr->dim); $hasOffsetValue = $type->hasOffsetValueType($dimType); if (!$type->isOffsetAccessible()->yes()) { return $this->checkUndefined($expr->var, $scope, $operatorDescription, $identifier); } if (!$hasOffsetValue->no()) { return $this->checkUndefined($expr->var, $scope, $operatorDescription, $identifier); } return \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Offset %s on %s %s does not exist.', $dimType->describe(VerbosityLevel::value()), $type->describe(VerbosityLevel::value()), $operatorDescription))->identifier(sprintf('%s.offset', $identifier))->build(); } if ($expr instanceof Expr\PropertyFetch) { return $this->checkUndefined($expr->var, $scope, $operatorDescription, $identifier); } if ($expr instanceof Expr\StaticPropertyFetch && $expr->class instanceof Expr) { return $this->checkUndefined($expr->class, $scope, $operatorDescription, $identifier); } return null; } /** * @param callable(Type): ?string $typeMessageCallback * @param ErrorIdentifier $identifier * @param 'variable'|'offset'|'property'|'expr' $identifierSecondPart */ private function generateError(Type $type, string $message, callable $typeMessageCallback, string $identifier, string $identifierSecondPart) : ?\PHPStan\Rules\IdentifierRuleError { $typeMessage = $typeMessageCallback($type); if ($typeMessage === null) { return null; } return \PHPStan\Rules\RuleErrorBuilder::message(sprintf('%s %s.', $message, $typeMessage))->identifier(sprintf('%s.%s', $identifier, $identifierSecondPart))->build(); } } */ final class RegularExpressionPatternRule implements Rule { /** * @var RegexExpressionHelper */ private $regexExpressionHelper; public function __construct(RegexExpressionHelper $regexExpressionHelper) { $this->regexExpressionHelper = $regexExpressionHelper; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { $patterns = $this->extractPatterns($node, $scope); $errors = []; foreach ($patterns as $pattern) { $errorMessage = $this->validatePattern($pattern); if ($errorMessage === null) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Regex pattern is invalid: %s', $errorMessage))->identifier('regexp.pattern')->build(); } return $errors; } /** * @return string[] */ private function extractPatterns(FuncCall $functionCall, Scope $scope) : array { if (!$functionCall->name instanceof Node\Name) { return []; } $functionName = strtolower((string) $functionCall->name); if (!str_starts_with($functionName, 'preg_')) { return []; } if (!isset($functionCall->getArgs()[0])) { return []; } $patternNode = $functionCall->getArgs()[0]->value; $patternType = $scope->getType($patternNode); $patternStrings = []; if (in_array($functionName, ['preg_match', 'preg_match_all', 'preg_split', 'preg_grep', 'preg_replace', 'preg_replace_callback', 'preg_filter'], \true)) { if ($patternNode instanceof Node\Expr\BinaryOp\Concat) { $patternType = $this->regexExpressionHelper->resolvePatternConcat($patternNode, $scope); } foreach ($patternType->getConstantStrings() as $constantStringType) { $patternStrings[] = $constantStringType->getValue(); } } if (in_array($functionName, ['preg_replace', 'preg_replace_callback', 'preg_filter'], \true)) { foreach ($patternType->getConstantArrays() as $constantArrayType) { foreach ($constantArrayType->getValueTypes() as $arrayKeyType) { foreach ($arrayKeyType->getConstantStrings() as $constantString) { $patternStrings[] = $constantString->getValue(); } } } } if ($functionName === 'preg_replace_callback_array') { foreach ($patternType->getConstantArrays() as $constantArrayType) { foreach ($constantArrayType->getKeyTypes() as $arrayKeyType) { foreach ($arrayKeyType->getConstantStrings() as $constantString) { $patternStrings[] = $constantString->getValue(); } } } } return $patternStrings; } private function validatePattern(string $pattern) : ?string { try { Strings::match('', $pattern); } catch (RegexpException $e) { return $e->getMessage(); } return null; } } */ final class RegularExpressionQuotingRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var RegexExpressionHelper */ private $regexExpressionHelper; public function __construct(ReflectionProvider $reflectionProvider, RegexExpressionHelper $regexExpressionHelper) { $this->reflectionProvider = $reflectionProvider; $this->regexExpressionHelper = $regexExpressionHelper; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } $functionReflection = $this->reflectionProvider->getFunction($node->name, $scope); if (!in_array($functionReflection->getName(), ['preg_match', 'preg_match_all', 'preg_filter', 'preg_grep', 'preg_replace', 'preg_replace_callback', 'preg_split'], \true)) { return []; } $normalizedArgs = $this->getNormalizedArgs($node, $scope, $functionReflection); if ($normalizedArgs === null) { return []; } if (!isset($normalizedArgs[0])) { return []; } if (!$normalizedArgs[0]->value instanceof Concat) { return []; } $patternDelimiters = $this->regexExpressionHelper->getPatternDelimiters($normalizedArgs[0]->value, $scope); return $this->validateQuoteDelimiters($normalizedArgs[0]->value, $scope, $patternDelimiters); } /** * @param string[] $patternDelimiters * * @return list */ private function validateQuoteDelimiters(Concat $concat, Scope $scope, array $patternDelimiters) : array { if ($patternDelimiters === []) { return []; } $errors = []; if ($concat->left instanceof FuncCall && $concat->left->name instanceof Name && $concat->left->name->toLowerString() === 'preg_quote') { $pregError = $this->validatePregQuote($concat->left, $scope, $patternDelimiters); if ($pregError !== null) { $errors[] = $pregError; } } elseif ($concat->left instanceof Concat) { $errors = array_merge($errors, $this->validateQuoteDelimiters($concat->left, $scope, $patternDelimiters)); } if ($concat->right instanceof FuncCall && $concat->right->name instanceof Name && $concat->right->name->toLowerString() === 'preg_quote') { $pregError = $this->validatePregQuote($concat->right, $scope, $patternDelimiters); if ($pregError !== null) { $errors[] = $pregError; } } elseif ($concat->right instanceof Concat) { $errors = array_merge($errors, $this->validateQuoteDelimiters($concat->right, $scope, $patternDelimiters)); } return $errors; } /** * @param string[] $patternDelimiters */ private function validatePregQuote(FuncCall $pregQuote, Scope $scope, array $patternDelimiters) : ?IdentifierRuleError { if (!$pregQuote->name instanceof Node\Name) { return null; } if (!$this->reflectionProvider->hasFunction($pregQuote->name, $scope)) { return null; } $functionReflection = $this->reflectionProvider->getFunction($pregQuote->name, $scope); $args = $this->getNormalizedArgs($pregQuote, $scope, $functionReflection); if ($args === null) { return null; } $patternDelimiters = $this->removeDefaultEscapedDelimiters($patternDelimiters); if ($patternDelimiters === []) { return null; } if (count($args) === 1) { if (count($patternDelimiters) === 1) { return RuleErrorBuilder::message(sprintf('Call to preg_quote() is missing delimiter %s to be effective.', $patternDelimiters[0]))->line($pregQuote->getStartLine())->identifier('argument.invalidPregQuote')->build(); } return RuleErrorBuilder::message('Call to preg_quote() is missing delimiter parameter to be effective.')->line($pregQuote->getStartLine())->identifier('argument.invalidPregQuote')->build(); } if (count($args) >= 2) { foreach ($scope->getType($args[1]->value)->getConstantStrings() as $quoteDelimiterType) { $quoteDelimiter = $quoteDelimiterType->getValue(); $quoteDelimiters = $this->removeDefaultEscapedDelimiters([$quoteDelimiter]); if ($quoteDelimiters === []) { continue; } if (count($quoteDelimiters) !== 1) { throw new ShouldNotHappenException(); } $quoteDelimiter = $quoteDelimiters[0]; if (!in_array($quoteDelimiter, $patternDelimiters, \true)) { if (count($patternDelimiters) === 1) { return RuleErrorBuilder::message(sprintf('Call to preg_quote() uses invalid delimiter %s while pattern uses %s.', $quoteDelimiter, $patternDelimiters[0]))->line($pregQuote->getStartLine())->identifier('argument.invalidPregQuote')->build(); } return RuleErrorBuilder::message(sprintf('Call to preg_quote() uses invalid delimiter %s.', $quoteDelimiter))->line($pregQuote->getStartLine())->identifier('argument.invalidPregQuote')->build(); } } } return null; } /** * @param string[] $delimiters * * @return list */ private function removeDefaultEscapedDelimiters(array $delimiters) : array { return array_values(array_filter($delimiters, function (string $delimiter) : bool { return !$this->isDefaultEscaped($delimiter); })); } private function isDefaultEscaped(string $delimiter) : bool { if (strlen($delimiter) !== 1) { return \false; } return in_array( $delimiter, // these delimiters are escaped, no matter what preg_quote() 2nd arg looks like ['.', '\\', '+', '*', '?', '[', '^', ']', '$', '(', ')', '{', '}', '=', '!', '<', '>', '|', ':', '-', '#'], \true ); } /** * @return Node\Arg[]|null */ private function getNormalizedArgs(FuncCall $functionCall, Scope $scope, FunctionReflection $functionReflection) : ?array { $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->getArgs(), $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants()); $normalizedFuncCall = ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $functionCall); if ($normalizedFuncCall === null) { return null; } return $normalizedFuncCall->getArgs(); } } */ final class ExistingNamesInGroupUseRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var ClassNameCheck */ private $classCheck; /** * @var bool */ private $checkFunctionNameCase; public function __construct(ReflectionProvider $reflectionProvider, ClassNameCheck $classCheck, bool $checkFunctionNameCase) { $this->reflectionProvider = $reflectionProvider; $this->classCheck = $classCheck; $this->checkFunctionNameCase = $checkFunctionNameCase; } public function getNodeType() : string { return Node\Stmt\GroupUse::class; } public function processNode(Node $node, Scope $scope) : array { $errors = []; foreach ($node->uses as $use) { $error = null; /** @var Node\Name $name */ $name = Node\Name::concat($node->prefix, $use->name, ['startLine' => $use->getStartLine()]); if ($node->type === Use_::TYPE_CONSTANT || $use->type === Use_::TYPE_CONSTANT) { $error = $this->checkConstant($name); } elseif ($node->type === Use_::TYPE_FUNCTION || $use->type === Use_::TYPE_FUNCTION) { $error = $this->checkFunction($name); } elseif ($use->type === Use_::TYPE_NORMAL) { $error = $this->checkClass($name); } else { throw new ShouldNotHappenException(); } if ($error === null) { continue; } $errors[] = $error; } return $errors; } private function checkConstant(Node\Name $name) : ?IdentifierRuleError { if (!$this->reflectionProvider->hasConstant($name, null)) { return RuleErrorBuilder::message(sprintf('Used constant %s not found.', (string) $name))->discoveringSymbolsTip()->line($name->getStartLine())->identifier('constant.notFound')->build(); } return null; } private function checkFunction(Node\Name $name) : ?IdentifierRuleError { if (!$this->reflectionProvider->hasFunction($name, null)) { return RuleErrorBuilder::message(sprintf('Used function %s not found.', (string) $name))->discoveringSymbolsTip()->line($name->getStartLine())->identifier('function.notFound')->build(); } if ($this->checkFunctionNameCase) { $functionReflection = $this->reflectionProvider->getFunction($name, null); $realName = $functionReflection->getName(); $usedName = (string) $name; if (strtolower($realName) === strtolower($usedName) && $realName !== $usedName) { return RuleErrorBuilder::message(sprintf('Function %s used with incorrect case: %s.', $realName, $usedName))->line($name->getStartLine())->identifier('function.nameCase')->build(); } } return null; } private function checkClass(Node\Name $name) : ?IdentifierRuleError { $errors = $this->classCheck->checkClassNames([new ClassNameNodePair((string) $name, $name)]); if (count($errors) === 0) { return null; } elseif (count($errors) === 1) { return $errors[0]; } throw new ShouldNotHappenException(); } } */ final class ExistingNamesInUseRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var ClassNameCheck */ private $classCheck; /** * @var bool */ private $checkFunctionNameCase; public function __construct(ReflectionProvider $reflectionProvider, ClassNameCheck $classCheck, bool $checkFunctionNameCase) { $this->reflectionProvider = $reflectionProvider; $this->classCheck = $classCheck; $this->checkFunctionNameCase = $checkFunctionNameCase; } public function getNodeType() : string { return Node\Stmt\Use_::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->type === Node\Stmt\Use_::TYPE_UNKNOWN) { throw new ShouldNotHappenException(); } foreach ($node->uses as $use) { if ($use->type !== Node\Stmt\Use_::TYPE_UNKNOWN) { throw new ShouldNotHappenException(); } } if ($node->type === Node\Stmt\Use_::TYPE_CONSTANT) { return $this->checkConstants($node->uses); } if ($node->type === Node\Stmt\Use_::TYPE_FUNCTION) { return $this->checkFunctions($node->uses); } return $this->checkClasses($node->uses); } /** * @param Node\Stmt\UseUse[] $uses * @return list */ private function checkConstants(array $uses) : array { $errors = []; foreach ($uses as $use) { if ($this->reflectionProvider->hasConstant($use->name, null)) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Used constant %s not found.', (string) $use->name))->line($use->name->getStartLine())->identifier('constant.notFound')->discoveringSymbolsTip()->build(); } return $errors; } /** * @param Node\Stmt\UseUse[] $uses * @return list */ private function checkFunctions(array $uses) : array { $errors = []; foreach ($uses as $use) { if (!$this->reflectionProvider->hasFunction($use->name, null)) { $errors[] = RuleErrorBuilder::message(sprintf('Used function %s not found.', (string) $use->name))->line($use->name->getStartLine())->identifier('function.notFound')->discoveringSymbolsTip()->build(); } elseif ($this->checkFunctionNameCase) { $functionReflection = $this->reflectionProvider->getFunction($use->name, null); $realName = $functionReflection->getName(); $usedName = (string) $use->name; if (strtolower($realName) === strtolower($usedName) && $realName !== $usedName) { $errors[] = RuleErrorBuilder::message(sprintf('Function %s used with incorrect case: %s.', $realName, $usedName))->line($use->name->getStartLine())->identifier('function.nameCase')->build(); } } } return $errors; } /** * @param Node\Stmt\UseUse[] $uses * @return list */ private function checkClasses(array $uses) : array { return $this->classCheck->checkClassNames(array_map(static function (Node\Stmt\UseUse $use) : ClassNameNodePair { return new ClassNameNodePair((string) $use->name, $use->name); }, $uses)); } } */ final class MissingReturnRule implements Rule { /** * @var bool */ private $checkExplicitMixedMissingReturn; /** * @var bool */ private $checkPhpDocMissingReturn; public function __construct(bool $checkExplicitMixedMissingReturn, bool $checkPhpDocMissingReturn) { $this->checkExplicitMixedMissingReturn = $checkExplicitMixedMissingReturn; $this->checkPhpDocMissingReturn = $checkPhpDocMissingReturn; } public function getNodeType() : string { return ExecutionEndNode::class; } public function processNode(Node $node, Scope $scope) : array { $statementResult = $node->getStatementResult(); if ($statementResult->isAlwaysTerminating()) { return []; } $anonymousFunctionReturnType = $scope->getAnonymousFunctionReturnType(); $scopeFunction = $scope->getFunction(); if ($anonymousFunctionReturnType !== null) { $returnType = $anonymousFunctionReturnType; $description = 'Anonymous function'; if (!$node->hasNativeReturnTypehint()) { return []; } } elseif ($scopeFunction !== null) { $returnType = $scopeFunction->getReturnType(); if ($scopeFunction instanceof MethodReflection) { $description = sprintf('Method %s::%s()', $scopeFunction->getDeclaringClass()->getDisplayName(), $scopeFunction->getName()); } else { $description = sprintf('Function %s()', $scopeFunction->getName()); } } else { throw new ShouldNotHappenException(); } $returnType = TypeUtils::resolveLateResolvableTypes($returnType); $isVoidSuperType = $returnType->isSuperTypeOf(new VoidType()); if ($isVoidSuperType->yes() && !$returnType instanceof MixedType) { return []; } if ($statementResult->hasYield()) { if ($this->checkPhpDocMissingReturn) { $generatorReturnType = $returnType->getTemplateType(Generator::class, 'TReturn'); if (!$generatorReturnType instanceof ErrorType) { $returnType = $generatorReturnType; if ($returnType->isVoid()->yes()) { return []; } if (!$returnType instanceof MixedType) { return [RuleErrorBuilder::message(sprintf('%s should return %s but return statement is missing.', $description, $returnType->describe(VerbosityLevel::typeOnly())))->line($node->getNode()->getStartLine())->identifier('return.missing')->build()]; } } } return []; } if (!$node->hasNativeReturnTypehint() && !$this->checkPhpDocMissingReturn && TypeCombinator::containsNull($returnType)) { return []; } if ($returnType instanceof NeverType && $returnType->isExplicit()) { $errorBuilder = RuleErrorBuilder::message(sprintf('%s should always throw an exception or terminate script execution but doesn\'t do that.', $description))->line($node->getNode()->getStartLine()); if ($node->hasNativeReturnTypehint()) { $errorBuilder->nonIgnorable(); } $errorBuilder->identifier('return.never'); return [$errorBuilder->build()]; } if ($returnType instanceof MixedType && !$returnType instanceof TemplateMixedType && !$node->hasNativeReturnTypehint() && (!$returnType->isExplicitMixed() || !$this->checkExplicitMixedMissingReturn)) { return []; } $errorBuilder = RuleErrorBuilder::message(sprintf('%s should return %s but return statement is missing.', $description, $returnType->describe(VerbosityLevel::typeOnly())))->line($node->getNode()->getStartLine()); if ($node->hasNativeReturnTypehint()) { $errorBuilder->nonIgnorable(); } $errorBuilder->identifier('return.missing'); return [$errorBuilder->build()]; } } */ final class FileWhitespaceRule implements Rule { public function getNodeType() : string { return FileNode::class; } public function processNode(Node $node, Scope $scope) : array { $nodes = $node->getNodes(); if (count($nodes) === 0) { return []; } $firstNode = $nodes[0]; $messages = []; if ($firstNode instanceof Node\Stmt\InlineHTML && $firstNode->value === "") { $messages[] = RuleErrorBuilder::message('File begins with UTF-8 BOM character. This may cause problems when running the code in the web browser.')->identifier('whitespace.bom')->build(); } $nodeTraverser = new NodeTraverser(); $visitor = new class extends NodeVisitorAbstract { /** @var Node[] */ private $lastNodes = []; /** * @return int|null */ public function enterNode(Node $node) { if ($node instanceof Node\Stmt\Declare_) { if ($node->stmts !== null && count($node->stmts) > 0) { $this->lastNodes[] = $node->stmts[count($node->stmts) - 1]; } return null; } if ($node instanceof Node\Stmt\Namespace_) { if (count($node->stmts) > 0) { $this->lastNodes[] = $node->stmts[count($node->stmts) - 1]; } return null; } return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN; } /** * @return Node[] */ public function getLastNodes() : array { return $this->lastNodes; } }; $nodeTraverser->addVisitor($visitor); $nodeTraverser->traverse($nodes); $lastNodes = $visitor->getLastNodes(); $lastNodes[] = $nodes[count($nodes) - 1]; foreach ($lastNodes as $lastNode) { if (!$lastNode instanceof Node\Stmt\InlineHTML || Strings::match($lastNode->value, '#^(\\s+)$#') === null) { continue; } $messages[] = RuleErrorBuilder::message('File ends with a trailing whitespace. This may cause problems when running the code in the web browser. Remove the closing ?> mark or remove the whitespace.')->line($lastNode->getStartLine())->identifier('whitespace.fileEnd')->build(); } return $messages; } } */ final class CallToFunctionStatementWithoutImpurePointsRule implements Rule { public function getNodeType() : string { return CollectedDataNode::class; } public function processNode(Node $node, Scope $scope) : array { $functions = []; foreach ($node->get(\PHPStan\Rules\DeadCode\FunctionWithoutImpurePointsCollector::class) as [$functionName]) { $functions[strtolower($functionName)] = $functionName; } $errors = []; foreach ($node->get(\PHPStan\Rules\DeadCode\PossiblyPureFuncCallCollector::class) as $filePath => $data) { foreach ($data as [$func, $line]) { $lowerFunc = strtolower($func); if (!array_key_exists($lowerFunc, $functions)) { continue; } $originalFunctionName = $functions[$lowerFunc]; $errors[] = RuleErrorBuilder::message(sprintf('Call to function %s() on a separate line has no effect.', $originalFunctionName))->file($filePath)->line($line)->identifier('function.resultUnused')->build(); } } return $errors; } } */ final class UnreachableStatementRule implements Rule { public function getNodeType() : string { return UnreachableStatementNode::class; } public function processNode(Node $node, Scope $scope) : array { return [RuleErrorBuilder::message('Unreachable statement - code above always terminates.')->identifier('deadCode.unreachable')->build()]; } } */ final class UnusedPrivateConstantRule implements Rule { /** * @var AlwaysUsedClassConstantsExtensionProvider */ private $extensionProvider; public function __construct(AlwaysUsedClassConstantsExtensionProvider $extensionProvider) { $this->extensionProvider = $extensionProvider; } public function getNodeType() : string { return ClassConstantsNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->getClass() instanceof Node\Stmt\Class_ && !$node->getClass() instanceof Node\Stmt\Enum_) { return []; } $classReflection = $node->getClassReflection(); $classType = new ObjectType($classReflection->getName(), null, $classReflection); $constants = []; foreach ($node->getConstants() as $constant) { if (!$constant->isPrivate()) { continue; } foreach ($constant->consts as $const) { $constantName = $const->name->toString(); $constantReflection = $classReflection->getConstant($constantName); foreach ($this->extensionProvider->getExtensions() as $extension) { if ($extension->isAlwaysUsed($constantReflection)) { continue 2; } } $constants[$constantName] = $const; } } foreach ($node->getFetches() as $fetch) { $fetchNode = $fetch->getNode(); $fetchScope = $fetch->getScope(); if ($fetchNode->class instanceof Node\Name) { $fetchedOnClass = $fetchScope->resolveTypeByName($fetchNode->class); } else { $fetchedOnClass = $fetchScope->getType($fetchNode->class); } if (!$fetchNode->name instanceof Node\Identifier) { if (!$classType->isSuperTypeOf($fetchedOnClass)->no()) { $constants = []; break; } continue; } $constantReflection = $fetchScope->getConstantReflection($fetchedOnClass, $fetchNode->name->toString()); if ($constantReflection === null) { if (!$classType->isSuperTypeOf($fetchedOnClass)->no()) { unset($constants[$fetchNode->name->toString()]); } continue; } if ($constantReflection->getDeclaringClass()->getName() !== $classReflection->getName()) { if (!$classType->isSuperTypeOf($fetchedOnClass)->no()) { unset($constants[$fetchNode->name->toString()]); } continue; } unset($constants[$fetchNode->name->toString()]); } $errors = []; foreach ($constants as $constantName => $constantNode) { $errors[] = RuleErrorBuilder::message(sprintf('Constant %s::%s is unused.', $classReflection->getDisplayName(), $constantName))->line($constantNode->getStartLine())->identifier('classConstant.unused')->tip(sprintf('See: %s', 'https://phpstan.org/developing-extensions/always-used-class-constants'))->build(); } return $errors; } } */ final class CallToConstructorStatementWithoutImpurePointsRule implements Rule { public function getNodeType() : string { return CollectedDataNode::class; } public function processNode(Node $node, Scope $scope) : array { $classesWithConstructors = []; foreach ($node->get(\PHPStan\Rules\DeadCode\ConstructorWithoutImpurePointsCollector::class) as [$class]) { $classesWithConstructors[strtolower($class)] = $class; } $errors = []; foreach ($node->get(\PHPStan\Rules\DeadCode\PossiblyPureNewCollector::class) as $filePath => $data) { foreach ($data as [$class, $line]) { $lowerClass = strtolower($class); if (!array_key_exists($lowerClass, $classesWithConstructors)) { continue; } $originalClassName = $classesWithConstructors[$lowerClass]; $errors[] = RuleErrorBuilder::message(sprintf('Call to new %s() on a separate line has no effect.', $originalClassName))->file($filePath)->line($line)->identifier('new.resultUnused')->build(); } } return $errors; } } */ final class NoopRule implements Rule { /** * @var ExprPrinter */ private $exprPrinter; /** * @var bool */ private $better; public function __construct(ExprPrinter $exprPrinter, bool $better) { $this->exprPrinter = $exprPrinter; $this->better = $better; } public function getNodeType() : string { return Node\Stmt\Expression::class; } public function processNode(Node $node, Scope $scope) : array { if ($this->better) { // disabled in bleeding edge return []; } $originalExpr = $node->expr; $expr = $originalExpr; if ($expr instanceof Node\Expr\Cast || $expr instanceof Node\Expr\UnaryMinus || $expr instanceof Node\Expr\UnaryPlus || $expr instanceof Node\Expr\ErrorSuppress) { $expr = $expr->expr; } if (!$this->isNoopExpr($expr)) { return []; } return [RuleErrorBuilder::message(sprintf('Expression "%s" on a separate line does not do anything.', $this->exprPrinter->printExpr($originalExpr)))->line($expr->getStartLine())->identifier('expr.resultUnused')->build()]; } public function isNoopExpr(Node\Expr $expr) : bool { return $expr instanceof Node\Expr\Variable || $expr instanceof Node\Expr\PropertyFetch || $expr instanceof Node\Expr\StaticPropertyFetch || $expr instanceof Node\Expr\NullsafePropertyFetch || $expr instanceof Node\Expr\ArrayDimFetch || $expr instanceof Node\Scalar || $expr instanceof Node\Expr\Isset_ || $expr instanceof Node\Expr\Empty_ || $expr instanceof Node\Expr\ConstFetch || $expr instanceof Node\Expr\ClassConstFetch; } } */ final class PossiblyPureStaticCallCollector implements Collector { public function __construct() { } public function getNodeType() : string { return Expression::class; } public function processNode(Node $node, Scope $scope) { if (!$node->expr instanceof Node\Expr\StaticCall) { return null; } if (!$node->expr->name instanceof Node\Identifier) { return null; } if (!$node->expr->class instanceof Node\Name) { return null; } $methodName = $node->expr->name->toString(); $calledOnType = $scope->resolveTypeByName($node->expr->class); $methodReflection = $scope->getMethodReflection($calledOnType, $methodName); if ($methodReflection === null) { return null; } if (!$methodReflection->isPure()->maybe()) { return null; } if (!$methodReflection->hasSideEffects()->maybe()) { return null; } return [$methodReflection->getDeclaringClass()->getName(), $methodReflection->getName(), $node->getStartLine()]; } } */ final class PossiblyPureNewCollector implements Collector { /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ReflectionProvider $reflectionProvider) { $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Expression::class; } public function processNode(Node $node, Scope $scope) { if (!$node->expr instanceof Node\Expr\New_) { return null; } if (!$node->expr->class instanceof Node\Name) { return null; } $className = $node->expr->class->toString(); if (!$this->reflectionProvider->hasClass($className)) { return null; } $classReflection = $this->reflectionProvider->getClass($className); if (!$classReflection->hasConstructor()) { return null; } $constructor = $classReflection->getConstructor(); if (strtolower($constructor->getName()) !== '__construct') { return null; } if (!$constructor->isPure()->maybe()) { return null; } return [$constructor->getDeclaringClass()->getName(), $node->getStartLine()]; } } */ final class UnusedPrivatePropertyRule implements Rule { /** * @var ReadWritePropertiesExtensionProvider */ private $extensionProvider; /** * @var string[] */ private $alwaysWrittenTags; /** * @var string[] */ private $alwaysReadTags; /** * @var bool */ private $checkUninitializedProperties; /** * @param string[] $alwaysWrittenTags * @param string[] $alwaysReadTags */ public function __construct(ReadWritePropertiesExtensionProvider $extensionProvider, array $alwaysWrittenTags, array $alwaysReadTags, bool $checkUninitializedProperties) { $this->extensionProvider = $extensionProvider; $this->alwaysWrittenTags = $alwaysWrittenTags; $this->alwaysReadTags = $alwaysReadTags; $this->checkUninitializedProperties = $checkUninitializedProperties; } public function getNodeType() : string { return ClassPropertiesNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->getClass() instanceof Node\Stmt\Class_) { return []; } $classReflection = $node->getClassReflection(); $classType = new ObjectType($classReflection->getName(), null, $classReflection); $properties = []; foreach ($node->getProperties() as $property) { if (!$property->isPrivate()) { continue; } if ($property->isDeclaredInTrait()) { continue; } $alwaysRead = \false; $alwaysWritten = \false; if ($property->getPhpDoc() !== null) { $text = $property->getPhpDoc(); foreach ($this->alwaysReadTags as $tag) { if (!str_contains($text, $tag)) { continue; } $alwaysRead = \true; break; } foreach ($this->alwaysWrittenTags as $tag) { if (!str_contains($text, $tag)) { continue; } $alwaysWritten = \true; break; } } $propertyName = $property->getName(); if (!$alwaysRead || !$alwaysWritten) { if (!$classReflection->hasNativeProperty($propertyName)) { continue; } $propertyReflection = $classReflection->getNativeProperty($propertyName); foreach ($this->extensionProvider->getExtensions() as $extension) { if ($alwaysRead && $alwaysWritten) { break; } if (!$alwaysRead && $extension->isAlwaysRead($propertyReflection, $propertyName)) { $alwaysRead = \true; } if ($alwaysWritten || !$extension->isAlwaysWritten($propertyReflection, $propertyName)) { continue; } $alwaysWritten = \true; } } $read = $alwaysRead; $written = $alwaysWritten || $property->getDefault() !== null; $properties[$propertyName] = ['read' => $read, 'written' => $written, 'node' => $property]; } foreach ($node->getPropertyUsages() as $usage) { $fetch = $usage->getFetch(); if ($fetch->name instanceof Node\Identifier) { $propertyNames = [$fetch->name->toString()]; } else { $propertyNameType = $usage->getScope()->getType($fetch->name); $strings = $propertyNameType->getConstantStrings(); if (count($strings) === 0) { // handle subtractions of a dynamic property fetch foreach ($properties as $propertyName => $data) { if ((new ConstantStringType($propertyName))->isSuperTypeOf($propertyNameType)->no()) { continue; } unset($properties[$propertyName]); } continue; } $propertyNames = array_map(static function (ConstantStringType $type) : string { return $type->getValue(); }, $strings); } if ($fetch instanceof Node\Expr\PropertyFetch) { $fetchedOnType = $usage->getScope()->getType($fetch->var); } else { if ($fetch->class instanceof Node\Name) { $fetchedOnType = $usage->getScope()->resolveTypeByName($fetch->class); } else { $fetchedOnType = $usage->getScope()->getType($fetch->class); } } foreach ($propertyNames as $propertyName) { if (!array_key_exists($propertyName, $properties)) { continue; } $propertyReflection = $usage->getScope()->getPropertyReflection($fetchedOnType, $propertyName); if ($propertyReflection === null) { if (!$classType->isSuperTypeOf($fetchedOnType)->no()) { if ($usage instanceof PropertyRead) { $properties[$propertyName]['read'] = \true; } else { $properties[$propertyName]['written'] = \true; } } continue; } if ($propertyReflection->getDeclaringClass()->getName() !== $classReflection->getName()) { if (!$classType->isSuperTypeOf($fetchedOnType)->no()) { if ($usage instanceof PropertyRead) { $properties[$propertyName]['read'] = \true; } else { $properties[$propertyName]['written'] = \true; } } continue; } if ($usage instanceof PropertyRead) { $properties[$propertyName]['read'] = \true; } else { $properties[$propertyName]['written'] = \true; } } } [$uninitializedProperties] = $node->getUninitializedProperties($scope, []); $errors = []; foreach ($properties as $name => $data) { $propertyNode = $data['node']; if ($propertyNode->isStatic()) { $propertyName = sprintf('Static property %s::$%s', $classReflection->getDisplayName(), $name); } else { $propertyName = sprintf('Property %s::$%s', $classReflection->getDisplayName(), $name); } $tip = sprintf('See: %s', 'https://phpstan.org/developing-extensions/always-read-written-properties'); if (!$data['read']) { if (!$data['written']) { $errors[] = RuleErrorBuilder::message(sprintf('%s is unused.', $propertyName))->line($propertyNode->getStartLine())->tip($tip)->identifier('property.unused')->build(); } else { $errors[] = RuleErrorBuilder::message(sprintf('%s is never read, only written.', $propertyName))->line($propertyNode->getStartLine())->identifier('property.onlyWritten')->tip($tip)->build(); } } elseif (!$data['written'] && (!array_key_exists($name, $uninitializedProperties) || !$this->checkUninitializedProperties)) { $errors[] = RuleErrorBuilder::message(sprintf('%s is never written, only read.', $propertyName))->line($propertyNode->getStartLine())->identifier('property.onlyRead')->tip($tip)->build(); } } return $errors; } } */ final class UnusedPrivateMethodRule implements Rule { /** * @var AlwaysUsedMethodExtensionProvider */ private $extensionProvider; public function __construct(AlwaysUsedMethodExtensionProvider $extensionProvider) { $this->extensionProvider = $extensionProvider; } public function getNodeType() : string { return ClassMethodsNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->getClass() instanceof Node\Stmt\Class_ && !$node->getClass() instanceof Node\Stmt\Enum_) { return []; } $classReflection = $node->getClassReflection(); $classType = new ObjectType($classReflection->getName(), null, $classReflection); $constructor = null; if ($classReflection->hasConstructor()) { $constructor = $classReflection->getConstructor(); } $methods = []; foreach ($node->getMethods() as $method) { if (!$method->getNode()->isPrivate()) { continue; } if ($method->isDeclaredInTrait()) { continue; } $methodName = $method->getNode()->name->toString(); if ($constructor !== null && $constructor->getName() === $methodName) { continue; } if (strtolower($methodName) === '__clone') { continue; } $methodReflection = $classReflection->getNativeMethod($methodName); foreach ($this->extensionProvider->getExtensions() as $extension) { if ($extension->isAlwaysUsed($methodReflection)) { continue 2; } } $methods[strtolower($methodName)] = $method; } $arrayCalls = []; foreach ($node->getMethodCalls() as $methodCall) { $methodCallNode = $methodCall->getNode(); if ($methodCallNode instanceof Node\Expr\Array_) { $arrayCalls[] = $methodCall; continue; } $callScope = $methodCall->getScope(); if ($methodCallNode->name instanceof Identifier) { $methodNames = [$methodCallNode->name->toString()]; } else { $methodNameType = $callScope->getType($methodCallNode->name); $strings = $methodNameType->getConstantStrings(); if (count($strings) === 0) { // handle subtractions of a dynamic method call foreach ($methods as $lowerMethodName => $method) { if ((new ConstantStringType($method->getNode()->name->toString()))->isSuperTypeOf($methodNameType)->no()) { continue; } unset($methods[$lowerMethodName]); } continue; } $methodNames = array_map(static function (ConstantStringType $type) : string { return $type->getValue(); }, $strings); } if ($methodCallNode instanceof Node\Expr\MethodCall) { $calledOnType = $callScope->getType($methodCallNode->var); } else { if ($methodCallNode->class instanceof Node\Name) { $calledOnType = $callScope->resolveTypeByName($methodCallNode->class); } else { $calledOnType = $callScope->getType($methodCallNode->class); } } $inMethod = $callScope->getFunction(); if (!$inMethod instanceof MethodReflection) { continue; } foreach ($methodNames as $methodName) { $methodReflection = $callScope->getMethodReflection($calledOnType, $methodName); if ($methodReflection === null) { if (!$classType->isSuperTypeOf($calledOnType)->no()) { unset($methods[strtolower($methodName)]); } continue; } if ($methodReflection->getDeclaringClass()->getName() !== $classReflection->getName()) { if (!$classType->isSuperTypeOf($calledOnType)->no()) { unset($methods[strtolower($methodName)]); } continue; } if ($inMethod->getName() === $methodName) { continue; } unset($methods[strtolower($methodName)]); } } if (count($methods) > 0) { foreach ($arrayCalls as $arrayCall) { /** @var Node\Expr\Array_ $array */ $array = $arrayCall->getNode(); $arrayScope = $arrayCall->getScope(); $arrayType = $arrayScope->getType($array); if (!$arrayType->isCallable()->yes()) { continue; } foreach ($arrayType->getConstantArrays() as $constantArray) { foreach ($constantArray->findTypeAndMethodNames() as $typeAndMethod) { if ($typeAndMethod->isUnknown()) { return []; } if (!$typeAndMethod->getCertainty()->yes()) { return []; } $calledOnType = $typeAndMethod->getType(); $methodReflection = $arrayScope->getMethodReflection($calledOnType, $typeAndMethod->getMethod()); if ($methodReflection === null) { continue; } if ($methodReflection->getDeclaringClass()->getName() !== $classReflection->getName()) { continue; } $inMethod = $arrayScope->getFunction(); if (!$inMethod instanceof MethodReflection) { continue; } if ($inMethod->getName() === $typeAndMethod->getMethod()) { continue; } unset($methods[strtolower($typeAndMethod->getMethod())]); } } } } $errors = []; foreach ($methods as $method) { $originalMethodName = $method->getNode()->name->toString(); $methodType = 'Method'; if ($method->getNode()->isStatic()) { $methodType = 'Static method'; } $errors[] = RuleErrorBuilder::message(sprintf('%s %s::%s() is unused.', $methodType, $classReflection->getDisplayName(), $originalMethodName))->line($method->getNode()->getStartLine())->identifier('method.unused')->build(); } return $errors; } } */ final class ConstructorWithoutImpurePointsCollector implements Collector { public function getNodeType() : string { return MethodReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) { $method = $node->getMethodReflection(); if (!$method->isConstructor()) { return null; } if (!$method->isPure()->maybe()) { return null; } if (count($node->getImpurePoints()) !== 0) { return null; } if (count($node->getStatementResult()->getThrowPoints()) !== 0) { return null; } foreach ($method->getParameters() as $parameter) { if (!$parameter->passedByReference()->createsNewVariable()) { continue; } return null; } if (count($method->getAsserts()->getAll()) !== 0) { return null; } return $method->getDeclaringClass()->getName(); } } */ final class FunctionWithoutImpurePointsCollector implements Collector { public function getNodeType() : string { return FunctionReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) { $function = $node->getFunctionReflection(); if (!$function->isPure()->maybe()) { return null; } if (!$function->hasSideEffects()->maybe()) { return null; } if (count($node->getImpurePoints()) !== 0) { return null; } if (count($node->getStatementResult()->getThrowPoints()) !== 0) { return null; } foreach ($function->getParameters() as $parameter) { if (!$parameter->passedByReference()->createsNewVariable()) { continue; } return null; } if (count($function->getAsserts()->getAll()) !== 0) { return null; } return $function->getName(); } } */ final class CallToStaticMethodStatementWithoutImpurePointsRule implements Rule { public function getNodeType() : string { return CollectedDataNode::class; } public function processNode(Node $node, Scope $scope) : array { $methods = []; foreach ($node->get(\PHPStan\Rules\DeadCode\MethodWithoutImpurePointsCollector::class) as $collected) { foreach ($collected as [$className, $methodName, $classDisplayName]) { $lowerClassName = strtolower($className); if (!array_key_exists($lowerClassName, $methods)) { $methods[$lowerClassName] = []; } $methods[$lowerClassName][strtolower($methodName)] = $classDisplayName . '::' . $methodName; } } $errors = []; foreach ($node->get(\PHPStan\Rules\DeadCode\PossiblyPureStaticCallCollector::class) as $filePath => $data) { foreach ($data as [$className, $method, $line]) { $lowerClassName = strtolower($className); if (!array_key_exists($lowerClassName, $methods)) { continue; } $lowerMethod = strtolower($method); if (!array_key_exists($lowerMethod, $methods[$lowerClassName])) { continue; } $originalMethodName = $methods[$lowerClassName][$lowerMethod]; $errors[] = RuleErrorBuilder::message(sprintf('Call to %s() on a separate line has no effect.', $originalMethodName))->file($filePath)->line($line)->identifier('staticMethod.resultUnused')->build(); } } return $errors; } } */ final class MethodWithoutImpurePointsCollector implements Collector { public function getNodeType() : string { return MethodReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) { $method = $node->getMethodReflection(); if (!$method->isPure()->maybe()) { return null; } if (!$method->hasSideEffects()->maybe()) { return null; } if (count($node->getImpurePoints()) !== 0) { return null; } if (count($node->getStatementResult()->getThrowPoints()) !== 0) { return null; } foreach ($method->getParameters() as $parameter) { if (!$parameter->passedByReference()->createsNewVariable()) { continue; } return null; } if (count($method->getAsserts()->getAll()) !== 0) { return null; } if ($method->isConstructor()) { return null; } return [$method->getDeclaringClass()->getName(), $method->getName(), $method->getDeclaringClass()->getDisplayName()]; } } */ final class CallToMethodStatementWithoutImpurePointsRule implements Rule { public function getNodeType() : string { return CollectedDataNode::class; } public function processNode(Node $node, Scope $scope) : array { $methods = []; foreach ($node->get(\PHPStan\Rules\DeadCode\MethodWithoutImpurePointsCollector::class) as $collected) { foreach ($collected as [$className, $methodName, $classDisplayName]) { $className = strtolower($className); if (!array_key_exists($className, $methods)) { $methods[$className] = []; } $methods[$className][strtolower($methodName)] = $classDisplayName . '::' . $methodName; } } $errors = []; foreach ($node->get(\PHPStan\Rules\DeadCode\PossiblyPureMethodCallCollector::class) as $filePath => $data) { foreach ($data as [$classNames, $method, $line]) { $originalMethodName = null; foreach ($classNames as $className) { $className = strtolower($className); if (!array_key_exists($className, $methods)) { continue 2; } $lowerMethod = strtolower($method); if (!array_key_exists($lowerMethod, $methods[$className])) { continue 2; } $originalMethodName = $methods[$className][$lowerMethod]; } $errors[] = RuleErrorBuilder::message(sprintf('Call to method %s() on a separate line has no effect.', $originalMethodName))->file($filePath)->line($line)->identifier('method.resultUnused')->build(); } } return $errors; } } */ final class BetterNoopRule implements Rule { /** * @var ExprPrinter */ private $exprPrinter; public function __construct(ExprPrinter $exprPrinter) { $this->exprPrinter = $exprPrinter; } public function getNodeType() : string { return NoopExpressionNode::class; } public function processNode(Node $node, Scope $scope) : array { $expr = $node->getOriginalExpr(); if ($expr instanceof Node\Expr\BinaryOp\LogicalXor) { return [RuleErrorBuilder::message('Unused result of "xor" operator.')->line($expr->getStartLine())->tip('This operator has unexpected precedence, try disambiguating the logic with parentheses ().')->identifier('logicalXor.resultUnused')->build()]; } if ($expr instanceof Node\Expr\BinaryOp\LogicalAnd || $expr instanceof Node\Expr\BinaryOp\LogicalOr) { $identifierType = $expr instanceof Node\Expr\BinaryOp\LogicalAnd ? 'logicalAnd' : 'logicalOr'; return [RuleErrorBuilder::message(sprintf('Unused result of "%s" operator.', $expr->getOperatorSigil()))->line($expr->getStartLine())->tip('This operator has unexpected precedence, try disambiguating the logic with parentheses ().')->identifier(sprintf('%s.resultUnused', $identifierType))->build()]; } if ($node->hasAssign()) { return []; } if ($expr instanceof Node\Expr\BinaryOp\BooleanAnd || $expr instanceof Node\Expr\BinaryOp\BooleanOr) { $identifierType = $expr instanceof Node\Expr\BinaryOp\BooleanAnd ? 'booleanAnd' : 'booleanOr'; return [RuleErrorBuilder::message(sprintf('Unused result of "%s" operator.', $expr->getOperatorSigil()))->line($expr->getStartLine())->identifier(sprintf('%s.resultUnused', $identifierType))->build()]; } if ($expr instanceof Node\Expr\Ternary) { return [RuleErrorBuilder::message('Unused result of ternary operator.')->line($expr->getStartLine())->identifier('ternary.resultUnused')->build()]; } if ($expr instanceof Node\Expr\FuncCall) { if ($expr->name instanceof Node\Name) { // handled by CallToFunctionStatementWithoutSideEffectsRule return []; } $nameType = $scope->getType($expr->name); if (!$nameType->isCallable()->yes()) { return []; } } if ($expr instanceof Node\Expr\New_ && $expr->class instanceof Node\Name) { // handled by CallToConstructorStatementWithoutSideEffectsRule return []; } if ($expr instanceof Node\Expr\NullsafeMethodCall || $expr instanceof Node\Expr\MethodCall || $expr instanceof Node\Expr\StaticCall) { // handled by *WithoutSideEffectsRule rules return []; } if ($expr instanceof Node\Expr\Assign || $expr instanceof Node\Expr\AssignOp || $expr instanceof Node\Expr\AssignRef) { return []; } if ($expr instanceof Node\Expr\Closure) { return []; } $exprString = $this->exprPrinter->printExpr($expr); $exprStringLines = preg_split('~\\R~', $exprString, 2); if ($exprStringLines !== \false && count($exprStringLines) > 1) { $exprString = $exprStringLines[0] . '…'; } return [RuleErrorBuilder::message(sprintf('Expression "%s" on a separate line does not do anything.', $exprString))->line($expr->getStartLine())->identifier('expr.resultUnused')->build()]; } } , string, int}> */ final class PossiblyPureMethodCallCollector implements Collector { public function __construct() { } public function getNodeType() : string { return Expression::class; } public function processNode(Node $node, Scope $scope) { if (!$node->expr instanceof Node\Expr\MethodCall) { return null; } if (!$node->expr->name instanceof Node\Identifier) { return null; } $methodName = $node->expr->name->toString(); $calledOnType = $scope->getType($node->expr->var); if (!$calledOnType->hasMethod($methodName)->yes()) { return null; } $classNames = []; $methodReflection = null; foreach ($calledOnType->getObjectClassReflections() as $classReflection) { if (!$classReflection->hasMethod($methodName)) { return null; } $methodReflection = $classReflection->getMethod($methodName, $scope); if (!$methodReflection->isPrivate() && !$methodReflection->isFinal()->yes() && !$methodReflection->getDeclaringClass()->isFinal()) { if (!$classReflection->isFinal()) { return null; } } if (!$methodReflection->isPure()->maybe()) { return null; } if (!$methodReflection->hasSideEffects()->maybe()) { return null; } $classNames[] = $methodReflection->getDeclaringClass()->getName(); } if ($methodReflection === null) { return null; } return [$classNames, $methodReflection->getName(), $node->getStartLine()]; } } */ final class PossiblyPureFuncCallCollector implements Collector { /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(ReflectionProvider $reflectionProvider) { $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Expression::class; } public function processNode(Node $node, Scope $scope) { if (!$node->expr instanceof Node\Expr\FuncCall) { return null; } if (!$node->expr->name instanceof Node\Name) { return null; } if (!$this->reflectionProvider->hasFunction($node->expr->name, $scope)) { return null; } $functionReflection = $this->reflectionProvider->getFunction($node->expr->name, $scope); if (!$functionReflection->isPure()->maybe()) { return null; } if (!$functionReflection->hasSideEffects()->maybe()) { return null; } return [$functionReflection->getName(), $node->getStartLine()]; } } */ final class TooWideFunctionReturnTypehintRule implements Rule { public function getNodeType() : string { return FunctionReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { $function = $node->getFunctionReflection(); $functionReturnType = $function->getReturnType(); $functionReturnType = TypeUtils::resolveLateResolvableTypes($functionReturnType); if (!$functionReturnType instanceof UnionType) { return []; } $statementResult = $node->getStatementResult(); if ($statementResult->hasYield()) { return []; } $returnStatements = $node->getReturnStatements(); if (count($returnStatements) === 0) { return []; } $returnTypes = []; foreach ($returnStatements as $returnStatement) { $returnNode = $returnStatement->getReturnNode(); if ($returnNode->expr === null) { $returnTypes[] = new VoidType(); continue; } $returnTypes[] = $returnStatement->getScope()->getType($returnNode->expr); } if (!$statementResult->isAlwaysTerminating()) { $returnTypes[] = new VoidType(); } $returnType = TypeCombinator::union(...$returnTypes); $messages = []; foreach ($functionReturnType->getTypes() as $type) { if (!$type->isSuperTypeOf($returnType)->no()) { continue; } if ($type->isNull()->yes() && !$node->hasNativeReturnTypehint()) { foreach ($node->getExecutionEnds() as $executionEnd) { if ($executionEnd->getStatementResult()->isAlwaysTerminating()) { continue; } continue 2; } } $messages[] = RuleErrorBuilder::message(sprintf('Function %s() never returns %s so it can be removed from the return type.', $function->getName(), $type->describe(VerbosityLevel::getRecommendedLevelByType($type))))->identifier('return.unusedType')->build(); } return $messages; } } */ final class TooWideMethodReturnTypehintRule implements Rule { /** * @var bool */ private $checkProtectedAndPublicMethods; /** * @var bool */ private $alwaysCheckFinal; public function __construct(bool $checkProtectedAndPublicMethods, bool $alwaysCheckFinal) { $this->checkProtectedAndPublicMethods = $checkProtectedAndPublicMethods; $this->alwaysCheckFinal = $alwaysCheckFinal; } public function getNodeType() : string { return MethodReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { if ($scope->isInTrait()) { return []; } $method = $node->getMethodReflection(); $isFirstDeclaration = $method->getPrototype()->getDeclaringClass() === $method->getDeclaringClass(); if (!$method->isPrivate()) { if ($this->alwaysCheckFinal) { if (!$method->getDeclaringClass()->isFinal() && !$method->isFinal()->yes()) { if (!$this->checkProtectedAndPublicMethods) { return []; } if ($isFirstDeclaration) { return []; } } } elseif (!$this->checkProtectedAndPublicMethods) { return []; } elseif ($isFirstDeclaration && !$method->getDeclaringClass()->isFinal() && !$method->isFinal()->yes()) { return []; } } $methodReturnType = $method->getReturnType(); $methodReturnType = TypeUtils::resolveLateResolvableTypes($methodReturnType); if (!$methodReturnType instanceof UnionType) { return []; } $statementResult = $node->getStatementResult(); if ($statementResult->hasYield()) { return []; } $returnStatements = $node->getReturnStatements(); if (count($returnStatements) === 0) { return []; } $returnTypes = []; foreach ($returnStatements as $returnStatement) { $returnNode = $returnStatement->getReturnNode(); if ($returnNode->expr === null) { $returnTypes[] = new VoidType(); continue; } $returnTypes[] = $returnStatement->getScope()->getType($returnNode->expr); } if (!$statementResult->isAlwaysTerminating()) { $returnTypes[] = new VoidType(); } $returnType = TypeCombinator::union(...$returnTypes); if (!$method->isPrivate() && ($returnType->isNull()->yes() || $returnType instanceof ConstantBooleanType) && !$isFirstDeclaration) { return []; } $messages = []; foreach ($methodReturnType->getTypes() as $type) { if (!$type->isSuperTypeOf($returnType)->no()) { continue; } if ($type->isNull()->yes() && !$node->hasNativeReturnTypehint()) { foreach ($node->getExecutionEnds() as $executionEnd) { if ($executionEnd->getStatementResult()->isAlwaysTerminating()) { continue; } continue 2; } } $messages[] = RuleErrorBuilder::message(sprintf('Method %s::%s() never returns %s so it can be removed from the return type.', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $type->describe(VerbosityLevel::getRecommendedLevelByType($type))))->identifier('return.unusedType')->build(); } return $messages; } } */ final class TooWideArrowFunctionReturnTypehintRule implements Rule { public function getNodeType() : string { return InArrowFunctionNode::class; } public function processNode(Node $node, Scope $scope) : array { $arrowFunction = $node->getOriginalNode(); if ($arrowFunction->returnType === null) { return []; } $expr = $arrowFunction->expr; if ($expr instanceof Node\Expr\YieldFrom || $expr instanceof Node\Expr\Yield_) { return []; } $functionReturnType = $scope->getFunctionType($arrowFunction->returnType, \false, \false); if (!$functionReturnType instanceof UnionType) { return []; } $returnType = $scope->getType($expr); if ($returnType->isNull()->yes()) { return []; } $messages = []; foreach ($functionReturnType->getTypes() as $type) { if (!$type->isSuperTypeOf($returnType)->no()) { continue; } $messages[] = RuleErrorBuilder::message(sprintf('Anonymous function never returns %s so it can be removed from the return type.', $type->describe(VerbosityLevel::getRecommendedLevelByType($type))))->identifier('return.unusedType')->build(); } return $messages; } } */ final class TooWideFunctionParameterOutTypeRule implements Rule { /** * @var TooWideParameterOutTypeCheck */ private $check; public function __construct(\PHPStan\Rules\TooWideTypehints\TooWideParameterOutTypeCheck $check) { $this->check = $check; } public function getNodeType() : string { return FunctionReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { $inFunction = $node->getFunctionReflection(); return $this->check->check($node->getExecutionEnds(), $node->getReturnStatements(), $inFunction->getParameters(), sprintf('Function %s()', $inFunction->getName())); } } $executionEnds * @param list $returnStatements * @param ParameterReflectionWithPhpDocs[] $parameters * @return list */ public function check(array $executionEnds, array $returnStatements, array $parameters, string $functionDescription) : array { $finalScope = null; foreach ($executionEnds as $executionEnd) { $endScope = $executionEnd->getStatementResult()->getScope(); if ($finalScope === null) { $finalScope = $endScope; continue; } $finalScope = $finalScope->mergeWith($endScope); } foreach ($returnStatements as $statement) { if ($finalScope === null) { $finalScope = $statement->getScope(); continue; } $finalScope = $finalScope->mergeWith($statement->getScope()); } if ($finalScope === null) { return []; } $errors = []; foreach ($parameters as $parameter) { if (!$parameter->passedByReference()->createsNewVariable()) { continue; } foreach ($this->processSingleParameter($finalScope, $functionDescription, $parameter) as $error) { $errors[] = $error; } } return $errors; } /** * @return list */ private function processSingleParameter(Scope $scope, string $functionDescription, ParameterReflectionWithPhpDocs $parameter) : array { $isParamOutType = \true; $outType = $parameter->getOutType(); if ($outType === null) { $isParamOutType = \false; $outType = $parameter->getType(); } $outType = TypeUtils::resolveLateResolvableTypes($outType); if (!$outType instanceof UnionType) { return []; } $variableExpr = new Variable($parameter->getName()); $variableType = $scope->getType($variableExpr); $messages = []; foreach ($outType->getTypes() as $type) { if (!$type->isSuperTypeOf($variableType)->no()) { continue; } $errorBuilder = RuleErrorBuilder::message(sprintf('%s never assigns %s to &$%s so it can be removed from the %s.', $functionDescription, $type->describe(VerbosityLevel::getRecommendedLevelByType($type)), $parameter->getName(), $isParamOutType ? '@param-out type' : 'by-ref type'))->identifier(sprintf('%s.unusedType', $isParamOutType ? 'paramOut' : 'parameterByRef')); if (!$isParamOutType) { $errorBuilder->tip('You can narrow the parameter out type with @param-out PHPDoc tag.'); } $messages[] = $errorBuilder->build(); } return $messages; } } */ final class TooWideClosureReturnTypehintRule implements Rule { public function getNodeType() : string { return ClosureReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { $closureExpr = $node->getClosureExpr(); if ($closureExpr->returnType === null) { return []; } $statementResult = $node->getStatementResult(); if ($statementResult->hasYield()) { return []; } $returnStatements = $node->getReturnStatements(); if (count($returnStatements) === 0) { return []; } $closureReturnType = $scope->getFunctionType($closureExpr->returnType, \false, \false); if (!$closureReturnType instanceof UnionType) { return []; } $returnTypes = []; foreach ($returnStatements as $returnStatement) { $returnNode = $returnStatement->getReturnNode(); if ($returnNode->expr === null) { continue; } $returnTypes[] = $returnStatement->getScope()->getType($returnNode->expr); } if (count($returnTypes) === 0) { return []; } $returnType = TypeCombinator::union(...$returnTypes); if ($returnType->isNull()->yes()) { return []; } $messages = []; foreach ($closureReturnType->getTypes() as $type) { if (!$type->isSuperTypeOf($returnType)->no()) { continue; } $messages[] = RuleErrorBuilder::message(sprintf('Anonymous function never returns %s so it can be removed from the return type.', $type->describe(VerbosityLevel::getRecommendedLevelByType($type))))->identifier('return.unusedType')->build(); } return $messages; } } */ final class TooWideMethodParameterOutTypeRule implements Rule { /** * @var TooWideParameterOutTypeCheck */ private $check; public function __construct(\PHPStan\Rules\TooWideTypehints\TooWideParameterOutTypeCheck $check) { $this->check = $check; } public function getNodeType() : string { return MethodReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { $inMethod = $node->getMethodReflection(); return $this->check->check($node->getExecutionEnds(), $node->getReturnStatements(), $inMethod->getParameters(), sprintf('Method %s::%s()', $inMethod->getDeclaringClass()->getDisplayName(), $inMethod->getName())); } } */ final class TooWidePropertyTypeRule implements Rule { /** * @var ReadWritePropertiesExtensionProvider */ private $extensionProvider; /** * @var PropertyReflectionFinder */ private $propertyReflectionFinder; public function __construct(ReadWritePropertiesExtensionProvider $extensionProvider, PropertyReflectionFinder $propertyReflectionFinder) { $this->extensionProvider = $extensionProvider; $this->propertyReflectionFinder = $propertyReflectionFinder; } public function getNodeType() : string { return ClassPropertiesNode::class; } public function processNode(Node $node, Scope $scope) : array { $errors = []; $classReflection = $node->getClassReflection(); foreach ($node->getProperties() as $property) { if (!$property->isPrivate()) { continue; } if ($property->isDeclaredInTrait()) { continue; } if ($property->isPromoted()) { continue; } $propertyName = $property->getName(); if (!$classReflection->hasNativeProperty($propertyName)) { continue; } $propertyReflection = $classReflection->getNativeProperty($propertyName); $propertyType = $propertyReflection->getWritableType(); if (!$propertyType instanceof UnionType) { continue; } foreach ($this->extensionProvider->getExtensions() as $extension) { if ($extension->isAlwaysRead($propertyReflection, $propertyName)) { continue 2; } if ($extension->isAlwaysWritten($propertyReflection, $propertyName)) { continue 2; } if ($extension->isInitialized($propertyReflection, $propertyName)) { continue 2; } } $assignedTypes = []; foreach ($node->getPropertyAssigns() as $assign) { $assignNode = $assign->getAssign(); $assignPropertyReflections = $this->propertyReflectionFinder->findPropertyReflectionsFromNode($assignNode->getPropertyFetch(), $assign->getScope()); foreach ($assignPropertyReflections as $assignPropertyReflection) { if ($propertyName !== $assignPropertyReflection->getName()) { continue; } if ($propertyReflection->getDeclaringClass()->getName() !== $assignPropertyReflection->getDeclaringClass()->getName()) { continue; } $assignedTypes[] = $assignPropertyReflection->getScope()->getType($assignNode->getAssignedExpr()); } } if ($property->getDefault() !== null) { $assignedTypes[] = $scope->getType($property->getDefault()); } if (count($assignedTypes) === 0) { continue; } $assignedType = TypeCombinator::union(...$assignedTypes); $propertyDescription = $this->describePropertyByName($propertyReflection, $propertyName); $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($propertyType, $assignedType); foreach ($propertyType->getTypes() as $type) { if (!$type->isSuperTypeOf($assignedType)->no()) { continue; } if ($property->getNativeType() === null && (new NullType())->isSuperTypeOf($type)->yes()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('%s (%s) is never assigned %s so it can be removed from the property type.', $propertyDescription, $propertyType->describe($verbosityLevel), $type->describe($verbosityLevel)))->identifier('property.unusedType')->line($property->getStartLine())->build(); } } return $errors; } private function describePropertyByName(PropertyReflection $property, string $propertyName) : string { if (!$property->isStatic()) { return sprintf('Property %s::$%s', $property->getDeclaringClass()->getDisplayName(), $propertyName); } return sprintf('Static property %s::$%s', $property->getDeclaringClass()->getDisplayName(), $propertyName); } } */ final class InvalidComparisonOperationRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Node\Expr\BinaryOp::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof Node\Expr\BinaryOp\Equal && !$node instanceof Node\Expr\BinaryOp\NotEqual && !$node instanceof Node\Expr\BinaryOp\Smaller && !$node instanceof Node\Expr\BinaryOp\SmallerOrEqual && !$node instanceof Node\Expr\BinaryOp\Greater && !$node instanceof Node\Expr\BinaryOp\GreaterOrEqual && !$node instanceof Node\Expr\BinaryOp\Spaceship) { return []; } if ($this->isNumberType($scope, $node->left) && $this->isNumberType($scope, $node->right)) { return []; } if ($this->isNumberType($scope, $node->left) && ($this->isPossiblyNullableObjectType($scope, $node->right) || $this->isPossiblyNullableArrayType($scope, $node->right)) || $this->isNumberType($scope, $node->right) && ($this->isPossiblyNullableObjectType($scope, $node->left) || $this->isPossiblyNullableArrayType($scope, $node->left))) { switch (get_class($node)) { case Node\Expr\BinaryOp\Equal::class: $nodeType = 'equal'; break; case Node\Expr\BinaryOp\NotEqual::class: $nodeType = 'notEqual'; break; case Node\Expr\BinaryOp\Greater::class: $nodeType = 'greater'; break; case Node\Expr\BinaryOp\GreaterOrEqual::class: $nodeType = 'greaterOrEqual'; break; case Node\Expr\BinaryOp\Smaller::class: $nodeType = 'smaller'; break; case Node\Expr\BinaryOp\SmallerOrEqual::class: $nodeType = 'smallerOrEqual'; break; case Node\Expr\BinaryOp\Spaceship::class: $nodeType = 'spaceship'; break; default: throw new ShouldNotHappenException(); } return [RuleErrorBuilder::message(sprintf('Comparison operation "%s" between %s and %s results in an error.', $node->getOperatorSigil(), $scope->getType($node->left)->describe(VerbosityLevel::value()), $scope->getType($node->right)->describe(VerbosityLevel::value())))->line($node->left->getStartLine())->identifier(sprintf('%s.invalid', $nodeType))->build()]; } return []; } private function isNumberType(Scope $scope, Node\Expr $expr) : bool { $acceptedType = new UnionType([new IntegerType(), new FloatType()]); $onlyNumber = static function (Type $type) use($acceptedType) : bool { return $acceptedType->isSuperTypeOf($type)->yes(); }; $type = $this->ruleLevelHelper->findTypeToCheck($scope, $expr, '', $onlyNumber)->getType(); if ($type instanceof ErrorType || !$type->equals($scope->getType($expr))) { return \false; } // SimpleXMLElement can be cast to number union type return !$acceptedType->isSuperTypeOf($type)->no() || $acceptedType->equals($type->toNumber()); } private function isPossiblyNullableObjectType(Scope $scope, Node\Expr $expr) : bool { $acceptedType = new ObjectWithoutClassType(); $type = $this->ruleLevelHelper->findTypeToCheck($scope, $expr, '', static function (Type $type) use($acceptedType) : bool { return $acceptedType->isSuperTypeOf($type)->yes(); })->getType(); if ($type instanceof ErrorType) { return \false; } if (TypeCombinator::containsNull($type) && !$type->isNull()->yes()) { $type = TypeCombinator::removeNull($type); } $isSuperType = $acceptedType->isSuperTypeOf($type); if ($type instanceof BenevolentUnionType) { return !$isSuperType->no(); } return $isSuperType->yes(); } private function isPossiblyNullableArrayType(Scope $scope, Node\Expr $expr) : bool { $type = $this->ruleLevelHelper->findTypeToCheck($scope, $expr, '', static function (Type $type) : bool { return $type->isArray()->yes(); })->getType(); if (TypeCombinator::containsNull($type) && !$type->isNull()->yes()) { $type = TypeCombinator::removeNull($type); } return !$type instanceof ErrorType && $type->isArray()->yes(); } } */ final class InvalidUnaryOperationRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var bool */ private $bleedingEdge; public function __construct(RuleLevelHelper $ruleLevelHelper, bool $bleedingEdge) { $this->ruleLevelHelper = $ruleLevelHelper; $this->bleedingEdge = $bleedingEdge; } public function getNodeType() : string { return Node\Expr::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof Node\Expr\UnaryPlus && !$node instanceof Node\Expr\UnaryMinus && !$node instanceof Node\Expr\BitwiseNot) { return []; } if ($this->bleedingEdge) { $varName = '__PHPSTAN__LEFT__'; $variable = new Node\Expr\Variable($varName); $newNode = clone $node; $newNode->setAttribute('phpstan_cache_printer', null); $newNode->expr = $variable; if ($node instanceof Node\Expr\BitwiseNot) { $callback = static function (Type $type) : bool { return $type->isString()->yes() || $type->isInteger()->yes() || $type->isFloat()->yes(); }; } else { $callback = static function (Type $type) : bool { return !$type->toNumber() instanceof ErrorType; }; } $exprType = $this->ruleLevelHelper->findTypeToCheck($scope, $node->expr, '', $callback)->getType(); if ($exprType instanceof ErrorType) { return []; } if (!$scope instanceof MutatingScope) { throw new ShouldNotHappenException(); } $scope = $scope->assignVariable($varName, $exprType, $exprType); if (!$scope->getType($newNode) instanceof ErrorType) { return []; } } elseif (!$scope->getType($node) instanceof ErrorType) { return []; } if ($node instanceof Node\Expr\UnaryPlus) { $operator = '+'; } elseif ($node instanceof Node\Expr\UnaryMinus) { $operator = '-'; } else { $operator = '~'; } return [RuleErrorBuilder::message(sprintf('Unary operation "%s" on %s results in an error.', $operator, $scope->getType($node->expr)->describe(VerbosityLevel::value())))->line($node->expr->getStartLine())->identifier('unaryOp.invalid')->build()]; } } */ final class InvalidAssignVarRule implements Rule { /** * @var NullsafeCheck */ private $nullsafeCheck; public function __construct(NullsafeCheck $nullsafeCheck) { $this->nullsafeCheck = $nullsafeCheck; } public function getNodeType() : string { return Expr::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof Assign && !$node instanceof AssignOp && !$node instanceof AssignRef) { return []; } if ($this->nullsafeCheck->containsNullSafe($node->var)) { return [RuleErrorBuilder::message('Nullsafe operator cannot be on left side of assignment.')->identifier('nullsafe.assign')->nonIgnorable()->build()]; } if ($node instanceof AssignRef && $this->nullsafeCheck->containsNullSafe($node->expr)) { return [RuleErrorBuilder::message('Nullsafe operator cannot be on right side of assignment by reference.')->identifier('nullsafe.byRef')->nonIgnorable()->build()]; } if ($this->containsNonAssignableExpression($node->var)) { return [RuleErrorBuilder::message('Expression on left side of assignment is not assignable.')->identifier('assign.invalidExpr')->nonIgnorable()->build()]; } return []; } private function containsNonAssignableExpression(Expr $expr) : bool { if ($expr instanceof Expr\Variable) { return \false; } if ($expr instanceof Expr\PropertyFetch) { return \false; } if ($expr instanceof Expr\ArrayDimFetch) { return \false; } if ($expr instanceof Expr\StaticPropertyFetch) { return \false; } if ($expr instanceof Expr\List_ || $expr instanceof Expr\Array_) { foreach ($expr->items as $item) { if ($item === null) { continue; } if (!$this->containsNonAssignableExpression($item->value)) { continue; } return \true; } return \false; } return \true; } } */ final class InvalidBinaryOperationRule implements Rule { /** * @var ExprPrinter */ private $exprPrinter; /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var bool */ private $bleedingEdge; public function __construct(ExprPrinter $exprPrinter, RuleLevelHelper $ruleLevelHelper, bool $bleedingEdge) { $this->exprPrinter = $exprPrinter; $this->ruleLevelHelper = $ruleLevelHelper; $this->bleedingEdge = $bleedingEdge; } public function getNodeType() : string { return Node\Expr::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof Node\Expr\BinaryOp && !$node instanceof Node\Expr\AssignOp) { return []; } if (!$scope->getType($node) instanceof ErrorType && !$this->bleedingEdge) { return []; } $leftName = '__PHPSTAN__LEFT__'; $rightName = '__PHPSTAN__RIGHT__'; $leftVariable = new Node\Expr\Variable($leftName); $rightVariable = new Node\Expr\Variable($rightName); if ($node instanceof Node\Expr\AssignOp) { $identifier = 'assignOp'; $newNode = clone $node; $newNode->setAttribute('phpstan_cache_printer', null); $left = $node->var; $right = $node->expr; $newNode->var = $leftVariable; $newNode->expr = $rightVariable; } else { $identifier = 'binaryOp'; $newNode = clone $node; $newNode->setAttribute('phpstan_cache_printer', null); $left = $node->left; $right = $node->right; $newNode->left = $leftVariable; $newNode->right = $rightVariable; } if ($node instanceof Node\Expr\AssignOp\Concat || $node instanceof Node\Expr\BinaryOp\Concat) { $callback = static function (Type $type) : bool { return !$type->toString() instanceof ErrorType; }; } elseif ($node instanceof Node\Expr\AssignOp\Plus || $node instanceof Node\Expr\BinaryOp\Plus) { $callback = static function (Type $type) : bool { return !$type->toNumber() instanceof ErrorType || $type->isArray()->yes(); }; } else { $callback = static function (Type $type) : bool { return !$type->toNumber() instanceof ErrorType; }; } $leftType = $this->ruleLevelHelper->findTypeToCheck($scope, $left, '', $callback)->getType(); if ($leftType instanceof ErrorType) { return []; } $rightType = $this->ruleLevelHelper->findTypeToCheck($scope, $right, '', $callback)->getType(); if ($rightType instanceof ErrorType) { return []; } if (!$scope instanceof MutatingScope) { throw new ShouldNotHappenException(); } $scope = $scope->assignVariable($leftName, $leftType, $leftType)->assignVariable($rightName, $rightType, $rightType); if (!$scope->getType($newNode) instanceof ErrorType) { return []; } return [RuleErrorBuilder::message(sprintf('Binary operation "%s" between %s and %s results in an error.', substr(substr($this->exprPrinter->printExpr($newNode), strlen($leftName) + 2), 0, -(strlen($rightName) + 2)), $scope->getType($left)->describe(VerbosityLevel::value()), $scope->getType($right)->describe(VerbosityLevel::value())))->line($left->getStartLine())->identifier(sprintf('%s.invalid', $identifier))->build()]; } } */ final class InvalidIncDecOperationRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var bool */ private $bleedingEdge; /** * @var bool */ private $checkThisOnly; public function __construct(RuleLevelHelper $ruleLevelHelper, bool $bleedingEdge, bool $checkThisOnly) { $this->ruleLevelHelper = $ruleLevelHelper; $this->bleedingEdge = $bleedingEdge; $this->checkThisOnly = $checkThisOnly; } public function getNodeType() : string { return Node\Expr::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof Node\Expr\PreInc && !$node instanceof Node\Expr\PostInc && !$node instanceof Node\Expr\PreDec && !$node instanceof Node\Expr\PostDec) { return []; } switch (get_class($node)) { case Node\Expr\PreInc::class: $nodeType = 'preInc'; break; case Node\Expr\PostInc::class: $nodeType = 'postInc'; break; case Node\Expr\PreDec::class: $nodeType = 'preDec'; break; case Node\Expr\PostDec::class: $nodeType = 'postDec'; break; default: throw new ShouldNotHappenException(); } $operatorString = $node instanceof Node\Expr\PreInc || $node instanceof Node\Expr\PostInc ? '++' : '--'; if (!$node->var instanceof Node\Expr\Variable && !$node->var instanceof Node\Expr\ArrayDimFetch && !$node->var instanceof Node\Expr\PropertyFetch && !$node->var instanceof Node\Expr\StaticPropertyFetch) { return [RuleErrorBuilder::message(sprintf('Cannot use %s on a non-variable.', $operatorString))->line($node->var->getStartLine())->identifier(sprintf('%s.expr', $nodeType))->build()]; } if (!$this->bleedingEdge) { if ($this->checkThisOnly) { return []; } $varType = $scope->getType($node->var); if (!$varType->toString() instanceof ErrorType) { return []; } if (!$varType->toNumber() instanceof ErrorType) { return []; } } else { $allowedTypes = new UnionType([new BooleanType(), new FloatType(), new IntegerType(), new StringType(), new NullType(), new ObjectType('SimpleXMLElement')]); $varType = $this->ruleLevelHelper->findTypeToCheck($scope, $node->var, '', static function (Type $type) use($allowedTypes) : bool { return $allowedTypes->isSuperTypeOf($type)->yes(); })->getType(); if ($varType instanceof ErrorType || $allowedTypes->isSuperTypeOf($varType)->yes()) { return []; } } return [RuleErrorBuilder::message(sprintf('Cannot use %s on %s.', $operatorString, $varType->describe(VerbosityLevel::value())))->line($node->var->getStartLine())->identifier(sprintf('%s.type', $nodeType))->build()]; } } ruleLevelHelper = $ruleLevelHelper; } /** @param callable(Type): Type $castFn */ public function checkParameter(Arg $parameter, Scope $scope, string $errorMessageTemplate, callable $castFn, string $functionName, string $parameterName) : ?\PHPStan\Rules\IdentifierRuleError { if ($parameter->unpack) { return null; } $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $parameter->value, '', static function (Type $type) use($castFn) : bool { return !$castFn($type->getIterableValueType()) instanceof ErrorType; }); if ($typeResult->getType() instanceof ErrorType || !$castFn($typeResult->getType()->getIterableValueType()) instanceof ErrorType) { return null; } return \PHPStan\Rules\RuleErrorBuilder::message(sprintf($errorMessageTemplate, $parameterName, $functionName, $typeResult->getType()->describe(VerbosityLevel::typeOnly())))->identifier('argument.type')->build(); } public function getParameterName(Arg $parameter, int $parameterIdx, ?ParameterReflection $parameterReflection) : string { if ($parameterReflection === null) { return sprintf('#%d', $parameterIdx + 1); } $paramName = $parameterReflection->getName(); $origParameter = $parameter->getAttributes()[ArgumentsNormalizer::ORIGINAL_ARG_ATTRIBUTE] ?? null; if (!$origParameter instanceof Arg) { $origParameter = $parameter; } return $origParameter->name !== null ? sprintf('$%s', $paramName) : sprintf('#%d $%s', $parameterIdx + 1, $paramName); } } containsNullSafe($expr->var); } if ($expr instanceof Expr\PropertyFetch) { return $this->containsNullSafe($expr->var); } if ($expr instanceof Expr\StaticPropertyFetch && $expr->class instanceof Expr) { return $this->containsNullSafe($expr->class); } if ($expr instanceof Expr\MethodCall) { return $this->containsNullSafe($expr->var); } if ($expr instanceof Expr\StaticCall && $expr->class instanceof Expr) { return $this->containsNullSafe($expr->class); } if ($expr instanceof Expr\List_ || $expr instanceof Expr\Array_) { foreach ($expr->items as $item) { if ($item === null) { continue; } if ($item->key !== null && $this->containsNullSafe($item->key)) { return \true; } if ($this->containsNullSafe($item->value)) { return \true; } } } return \false; } } classCaseSensitivityCheck = $classCaseSensitivityCheck; $this->classForbiddenNameCheck = $classForbiddenNameCheck; } /** * @param ClassNameNodePair[] $pairs * @return list */ public function checkClassNames(array $pairs, bool $checkClassCaseSensitivity = \true) : array { $errors = []; if ($checkClassCaseSensitivity) { foreach ($this->classCaseSensitivityCheck->checkClassNames($pairs) as $error) { $errors[] = $error; } } foreach ($this->classForbiddenNameCheck->checkClassNames($pairs) as $error) { $errors[] = $error; } return $errors; } } $nodeType * @return array> */ public function getRules(string $nodeType) : array; } */ public $reasons; /** * @param list $reasons */ public function __construct(bool $result, array $reasons) { $this->result = $result; $this->reasons = $reasons; } public function and(self $other) : self { return new self($this->result && $other->result, array_merge($this->reasons, $other->reasons)); } /** * @param callable(string): string $cb */ public function decorateReasons(callable $cb) : self { $reasons = []; foreach ($this->reasons as $reason) { $reasons[] = $cb($reason); } return new self($this->result, $reasons); } } */ final class MissingCheckedExceptionInMethodThrowsRule implements Rule { /** * @var MissingCheckedExceptionInThrowsCheck */ private $check; public function __construct(\PHPStan\Rules\Exceptions\MissingCheckedExceptionInThrowsCheck $check) { $this->check = $check; } public function getNodeType() : string { return MethodReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { $statementResult = $node->getStatementResult(); $methodReflection = $node->getMethodReflection(); $errors = []; foreach ($this->check->check($methodReflection->getThrowType(), $statementResult->getThrowPoints()) as [$className, $throwPointNode]) { $errors[] = RuleErrorBuilder::message(sprintf('Method %s::%s() throws checked exception %s but it\'s missing from the PHPDoc @throws tag.', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName(), $className))->line($throwPointNode->getStartLine())->identifier('missingType.checkedException')->build(); } return $errors; } } isVoid()->yes()) { return []; } $throwPointType = TypeCombinator::union(...array_map(static function (ThrowPoint $throwPoint) : Type { if (!$throwPoint->isExplicit()) { return new NeverType(); } return $throwPoint->getType(); }, $throwPoints)); $throwClasses = []; foreach (TypeUtils::flattenTypes($throwType) as $type) { if (!$throwPointType instanceof NeverType && !$type->isSuperTypeOf($throwPointType)->no()) { continue; } $throwClasses[] = $type->describe(VerbosityLevel::typeOnly()); } return $throwClasses; } } */ final class ThrowExpressionRule implements Rule { /** * @var PhpVersion */ private $phpVersion; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function getNodeType() : string { return Node\Expr\Throw_::class; } public function processNode(Node $node, Scope $scope) : array { if ($this->phpVersion->supportsThrowExpression()) { return []; } return [RuleErrorBuilder::message('Throw expression is supported only on PHP 8.0 and later.')->nonIgnorable()->identifier('throw.notSupported')->build()]; } } reflectionProvider = $reflectionProvider; $this->uncheckedExceptionRegexes = $uncheckedExceptionRegexes; $this->uncheckedExceptionClasses = $uncheckedExceptionClasses; $this->checkedExceptionRegexes = $checkedExceptionRegexes; $this->checkedExceptionClasses = $checkedExceptionClasses; } public function isCheckedException(string $className, Scope $scope) : bool { foreach ($this->uncheckedExceptionRegexes as $regex) { if (Strings::match($className, $regex) !== null) { return \false; } } foreach ($this->uncheckedExceptionClasses as $uncheckedExceptionClass) { if ($className === $uncheckedExceptionClass) { return \false; } } if (!$this->reflectionProvider->hasClass($className)) { return $this->isCheckedExceptionInternal($className); } $classReflection = $this->reflectionProvider->getClass($className); foreach ($this->uncheckedExceptionClasses as $uncheckedExceptionClass) { if ($classReflection->getName() === $uncheckedExceptionClass) { return \false; } if (!$classReflection->isSubclassOf($uncheckedExceptionClass)) { continue; } return \false; } return $this->isCheckedExceptionInternal($className); } private function isCheckedExceptionInternal(string $className) : bool { foreach ($this->checkedExceptionRegexes as $regex) { if (Strings::match($className, $regex) !== null) { return \true; } } foreach ($this->checkedExceptionClasses as $checkedExceptionClass) { if ($className === $checkedExceptionClass) { return \true; } } if (!$this->reflectionProvider->hasClass($className)) { return count($this->checkedExceptionRegexes) === 0 && count($this->checkedExceptionClasses) === 0; } $classReflection = $this->reflectionProvider->getClass($className); foreach ($this->checkedExceptionClasses as $checkedExceptionClass) { if ($classReflection->getName() === $checkedExceptionClass) { return \true; } if (!$classReflection->isSubclassOf($checkedExceptionClass)) { continue; } return \true; } return count($this->checkedExceptionRegexes) === 0 && count($this->checkedExceptionClasses) === 0; } } */ final class CaughtExceptionExistenceRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var ClassNameCheck */ private $classCheck; /** * @var bool */ private $checkClassCaseSensitivity; public function __construct(ReflectionProvider $reflectionProvider, ClassNameCheck $classCheck, bool $checkClassCaseSensitivity) { $this->reflectionProvider = $reflectionProvider; $this->classCheck = $classCheck; $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; } public function getNodeType() : string { return Catch_::class; } public function processNode(Node $node, Scope $scope) : array { $errors = []; foreach ($node->types as $class) { $className = (string) $class; if (!$this->reflectionProvider->hasClass($className)) { if ($scope->isInClassExists($className)) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Caught class %s not found.', $className))->line($class->getStartLine())->identifier('class.notFound')->discoveringSymbolsTip()->build(); continue; } $classReflection = $this->reflectionProvider->getClass($className); if (!$classReflection->isInterface() && !$classReflection->implementsInterface(Throwable::class)) { $errors[] = RuleErrorBuilder::message(sprintf('Caught class %s is not an exception.', $classReflection->getDisplayName()))->line($class->getStartLine())->identifier('catch.notThrowable')->build(); } $errors = array_merge($errors, $this->classCheck->checkClassNames([new ClassNameNodePair($className, $class)], $this->checkClassCaseSensitivity)); } return $errors; } } exceptionTypeResolver = $exceptionTypeResolver; } /** * @param ThrowPoint[] $throwPoints * @return array */ public function check(?Type $throwType, array $throwPoints) : array { if ($throwType === null) { $throwType = new NeverType(); } $classes = []; foreach ($throwPoints as $throwPoint) { if (!$throwPoint->isExplicit()) { continue; } foreach (TypeUtils::flattenTypes($throwPoint->getType()) as $throwPointType) { if ($throwPointType->isSuperTypeOf(new ObjectType(Throwable::class))->yes()) { continue; } if ($throwType->isSuperTypeOf($throwPointType)->yes()) { continue; } $isCheckedException = TrinaryLogic::createNo()->lazyOr($throwPointType->getObjectClassNames(), function (string $objectClassName) use($throwPoint) { return TrinaryLogic::createFromBoolean($this->exceptionTypeResolver->isCheckedException($objectClassName, $throwPoint->getScope())); }); if ($isCheckedException->no()) { continue; } $classes[] = [$throwPointType->describe(VerbosityLevel::typeOnly()), $throwPoint->getNode()]; } } return $classes; } } */ final class MissingCheckedExceptionInFunctionThrowsRule implements Rule { /** * @var MissingCheckedExceptionInThrowsCheck */ private $check; public function __construct(\PHPStan\Rules\Exceptions\MissingCheckedExceptionInThrowsCheck $check) { $this->check = $check; } public function getNodeType() : string { return FunctionReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { $statementResult = $node->getStatementResult(); $functionReflection = $node->getFunctionReflection(); $errors = []; foreach ($this->check->check($functionReflection->getThrowType(), $statementResult->getThrowPoints()) as [$className, $throwPointNode]) { $errors[] = RuleErrorBuilder::message(sprintf('Function %s() throws checked exception %s but it\'s missing from the PHPDoc @throws tag.', $functionReflection->getName(), $className))->line($throwPointNode->getStartLine())->identifier('missingType.checkedException')->build(); } return $errors; } } */ final class ThrowExprTypeRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Node\Expr\Throw_::class; } public function processNode(Node $node, Scope $scope) : array { $throwableType = new ObjectType(Throwable::class); $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $node->expr, 'Throwing object of an unknown class %s.', static function (Type $type) use($throwableType) : bool { return $throwableType->isSuperTypeOf($type)->yes(); }); $foundType = $typeResult->getType(); if ($foundType instanceof ErrorType) { return $typeResult->getUnknownClassErrors(); } $isSuperType = $throwableType->isSuperTypeOf($foundType); if ($isSuperType->yes()) { return []; } return [RuleErrorBuilder::message(sprintf('Invalid type %s to throw.', $foundType->describe(VerbosityLevel::typeOnly())))->identifier('throw.notThrowable')->build()]; } } */ final class NoncapturingCatchRule implements Rule { /** * @var PhpVersion */ private $phpVersion; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function getNodeType() : string { return Node\Stmt\Catch_::class; } /** * @param Node\Stmt\Catch_ $node */ public function processNode(Node $node, Scope $scope) : array { if ($this->phpVersion->supportsNoncapturingCatches()) { return []; } if ($node->var !== null) { return []; } return [RuleErrorBuilder::message('Non-capturing catch is supported only on PHP 8.0 and later.')->nonIgnorable()->identifier('catch.nonCapturingNotSupported')->build()]; } } */ final class TooWideFunctionThrowTypeRule implements Rule { /** * @var TooWideThrowTypeCheck */ private $check; public function __construct(\PHPStan\Rules\Exceptions\TooWideThrowTypeCheck $check) { $this->check = $check; } public function getNodeType() : string { return FunctionReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { $statementResult = $node->getStatementResult(); $functionReflection = $node->getFunctionReflection(); $throwType = $functionReflection->getThrowType(); if ($throwType === null) { return []; } $errors = []; foreach ($this->check->check($throwType, $statementResult->getThrowPoints()) as $throwClass) { $errors[] = RuleErrorBuilder::message(sprintf('Function %s() has %s in PHPDoc @throws tag but it\'s not thrown.', $functionReflection->getName(), $throwClass))->identifier('throws.unusedType')->build(); } return $errors; } } */ final class CatchWithUnthrownExceptionRule implements Rule { /** * @var ExceptionTypeResolver */ private $exceptionTypeResolver; /** * @var bool */ private $reportUncheckedExceptionDeadCatch; public function __construct(\PHPStan\Rules\Exceptions\ExceptionTypeResolver $exceptionTypeResolver, bool $reportUncheckedExceptionDeadCatch) { $this->exceptionTypeResolver = $exceptionTypeResolver; $this->reportUncheckedExceptionDeadCatch = $reportUncheckedExceptionDeadCatch; } public function getNodeType() : string { return CatchWithUnthrownExceptionNode::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->getCaughtType() instanceof NeverType) { return [RuleErrorBuilder::message(sprintf('Dead catch - %s is already caught above.', $node->getOriginalCaughtType()->describe(VerbosityLevel::typeOnly())))->line($node->getStartLine())->identifier('catch.alreadyCaught')->build()]; } if (!$this->reportUncheckedExceptionDeadCatch) { $isCheckedException = \false; foreach ($node->getCaughtType()->getObjectClassNames() as $objectClassName) { if ($this->exceptionTypeResolver->isCheckedException($objectClassName, $scope)) { $isCheckedException = \true; break; } } if (!$isCheckedException) { return []; } } return [RuleErrorBuilder::message(sprintf('Dead catch - %s is never thrown in the try block.', $node->getCaughtType()->describe(VerbosityLevel::typeOnly())))->line($node->getStartLine())->identifier('catch.neverThrown')->build()]; } } */ final class OverwrittenExitPointByFinallyRule implements Rule { public function getNodeType() : string { return FinallyExitPointsNode::class; } public function processNode(Node $node, Scope $scope) : array { if (count($node->getTryCatchExitPoints()) === 0) { return []; } $errors = []; foreach ($node->getTryCatchExitPoints() as $exitPoint) { $errors[] = RuleErrorBuilder::message(sprintf('This %s is overwritten by a different one in the finally block below.', $this->describeExitPoint($exitPoint->getStatement())))->line($exitPoint->getStatement()->getStartLine())->identifier('finally.exitPoint')->build(); } foreach ($node->getFinallyExitPoints() as $exitPoint) { $errors[] = RuleErrorBuilder::message(sprintf('The overwriting %s is on this line.', $this->describeExitPoint($exitPoint->getStatement())))->line($exitPoint->getStatement()->getStartLine())->identifier('finally.exitPoint')->build(); } return $errors; } private function describeExitPoint(Node\Stmt $stmt) : string { if ($stmt instanceof Node\Stmt\Return_) { return 'return'; } if ($stmt instanceof Node\Stmt\Throw_) { return 'throw'; } if ($stmt instanceof Node\Stmt\Continue_) { return 'continue'; } if ($stmt instanceof Node\Stmt\Break_) { return 'break'; } return 'exit point'; } } */ final class ThrowsVoidFunctionWithExplicitThrowPointRule implements Rule { /** * @var ExceptionTypeResolver */ private $exceptionTypeResolver; /** * @var bool */ private $missingCheckedExceptionInThrows; public function __construct(\PHPStan\Rules\Exceptions\ExceptionTypeResolver $exceptionTypeResolver, bool $missingCheckedExceptionInThrows) { $this->exceptionTypeResolver = $exceptionTypeResolver; $this->missingCheckedExceptionInThrows = $missingCheckedExceptionInThrows; } public function getNodeType() : string { return FunctionReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { $statementResult = $node->getStatementResult(); $functionReflection = $node->getFunctionReflection(); if ($functionReflection->getThrowType() === null || !$functionReflection->getThrowType()->isVoid()->yes()) { return []; } $errors = []; foreach ($statementResult->getThrowPoints() as $throwPoint) { if (!$throwPoint->isExplicit()) { continue; } foreach (TypeUtils::flattenTypes($throwPoint->getType()) as $throwPointType) { $isCheckedException = TrinaryLogic::createFromBoolean($this->missingCheckedExceptionInThrows)->lazyAnd($throwPointType->getObjectClassNames(), function (string $objectClassName) use($throwPoint) { return TrinaryLogic::createFromBoolean($this->exceptionTypeResolver->isCheckedException($objectClassName, $throwPoint->getScope())); }); if ($isCheckedException->yes()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Function %s() throws exception %s but the PHPDoc contains @throws void.', $functionReflection->getName(), $throwPointType->describe(VerbosityLevel::typeOnly())))->line($throwPoint->getNode()->getStartLine())->identifier('throws.void')->build(); } } return $errors; } } */ final class ThrowsVoidMethodWithExplicitThrowPointRule implements Rule { /** * @var ExceptionTypeResolver */ private $exceptionTypeResolver; /** * @var bool */ private $missingCheckedExceptionInThrows; public function __construct(\PHPStan\Rules\Exceptions\ExceptionTypeResolver $exceptionTypeResolver, bool $missingCheckedExceptionInThrows) { $this->exceptionTypeResolver = $exceptionTypeResolver; $this->missingCheckedExceptionInThrows = $missingCheckedExceptionInThrows; } public function getNodeType() : string { return MethodReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { $statementResult = $node->getStatementResult(); $methodReflection = $node->getMethodReflection(); if ($methodReflection->getThrowType() === null || !$methodReflection->getThrowType()->isVoid()->yes()) { return []; } $errors = []; foreach ($statementResult->getThrowPoints() as $throwPoint) { if (!$throwPoint->isExplicit()) { continue; } foreach (TypeUtils::flattenTypes($throwPoint->getType()) as $throwPointType) { $isCheckedException = TrinaryLogic::createFromBoolean($this->missingCheckedExceptionInThrows)->lazyAnd($throwPointType->getObjectClassNames(), function (string $objectClassName) use($throwPoint) { return TrinaryLogic::createFromBoolean($this->exceptionTypeResolver->isCheckedException($objectClassName, $throwPoint->getScope())); }); if ($isCheckedException->yes()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Method %s::%s() throws exception %s but the PHPDoc contains @throws void.', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName(), $throwPointType->describe(VerbosityLevel::typeOnly())))->line($throwPoint->getNode()->getStartLine())->identifier('throws.void')->build(); } } return $errors; } } */ final class TooWideMethodThrowTypeRule implements Rule { /** * @var FileTypeMapper */ private $fileTypeMapper; /** * @var TooWideThrowTypeCheck */ private $check; public function __construct(FileTypeMapper $fileTypeMapper, \PHPStan\Rules\Exceptions\TooWideThrowTypeCheck $check) { $this->fileTypeMapper = $fileTypeMapper; $this->check = $check; } public function getNodeType() : string { return MethodReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { $docComment = $node->getDocComment(); if ($docComment === null) { return []; } $statementResult = $node->getStatementResult(); $methodReflection = $node->getMethodReflection(); $classReflection = $node->getClassReflection(); $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $classReflection->getName(), $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $methodReflection->getName(), $docComment->getText()); if ($resolvedPhpDoc->getThrowsTag() === null) { return []; } $throwType = $resolvedPhpDoc->getThrowsTag()->getType(); $errors = []; foreach ($this->check->check($throwType, $statementResult->getThrowPoints()) as $throwClass) { $errors[] = RuleErrorBuilder::message(sprintf('Method %s::%s() has %s in PHPDoc @throws tag but it\'s not thrown.', $methodReflection->getDeclaringClass()->getDisplayName(), $methodReflection->getName(), $throwClass))->identifier('throws.unusedType')->build(); } return $errors; } } */ final class RequireFileExistsRule implements Rule { /** * @var string */ private $currentWorkingDirectory; public function __construct(string $currentWorkingDirectory) { $this->currentWorkingDirectory = $currentWorkingDirectory; } public function getNodeType() : string { return Include_::class; } public function processNode(Node $node, Scope $scope) : array { $errors = []; $paths = $this->resolveFilePaths($node, $scope); foreach ($paths as $path) { if ($this->doesFileExist($path, $scope)) { continue; } $errors[] = $this->getErrorMessage($node, $path); } return $errors; } /** * We cannot use `stream_resolve_include_path` as it works based on the calling script. * This method simulates the behavior of `stream_resolve_include_path` but for the given scope. * The priority order is the following: * 1. The current working directory. * 2. The include path. * 3. The path of the script that is being executed. */ private function doesFileExist(string $path, Scope $scope) : bool { $directories = array_merge([$this->currentWorkingDirectory], explode(PATH_SEPARATOR, get_include_path()), [dirname($scope->getFile())]); foreach ($directories as $directory) { if ($this->doesFileExistForDirectory($path, $directory)) { return \true; } } return \false; } private function doesFileExistForDirectory(string $path, string $workingDirectory) : bool { $fileHelper = new FileHelper($workingDirectory); $absolutePath = $fileHelper->absolutizePath($path); return is_file($absolutePath); } private function getErrorMessage(Include_ $node, string $filePath) : IdentifierRuleError { $message = 'Path in %s() "%s" is not a file or it does not exist.'; switch ($node->type) { case Include_::TYPE_REQUIRE: $type = 'require'; $identifierType = 'require'; break; case Include_::TYPE_REQUIRE_ONCE: $type = 'require_once'; $identifierType = 'requireOnce'; break; case Include_::TYPE_INCLUDE: $type = 'include'; $identifierType = 'include'; break; case Include_::TYPE_INCLUDE_ONCE: $type = 'include_once'; $identifierType = 'includeOnce'; break; default: throw new ShouldNotHappenException('Rule should have already validated the node type.'); } $identifier = sprintf('%s.fileNotFound', $identifierType); return RuleErrorBuilder::message(sprintf($message, $type, $filePath))->identifier($identifier)->build(); } /** * @return array */ private function resolveFilePaths(Include_ $node, Scope $scope) : array { $paths = []; $type = $scope->getType($node->expr); $constantStrings = $type->getConstantStrings(); foreach ($constantStrings as $constantString) { $paths[] = $constantString->getValue(); } return $paths; } } */ final class ContinueBreakInLoopRule implements Rule { public function getNodeType() : string { return Stmt::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof Stmt\Continue_ && !$node instanceof Stmt\Break_) { return []; } if (!$node->num instanceof Node\Scalar\LNumber) { $value = 1; } else { $value = $node->num->value; } $parentStmtTypes = array_reverse($node->getAttribute(ParentStmtTypesVisitor::ATTRIBUTE_NAME)); foreach ($parentStmtTypes as $parentStmtType) { if ($parentStmtType === Stmt\Case_::class) { continue; } if ($parentStmtType === Stmt\Function_::class || $parentStmtType === Stmt\ClassMethod::class || $parentStmtType === Node\Expr\Closure::class) { return [RuleErrorBuilder::message(sprintf('Keyword %s used outside of a loop or a switch statement.', $node instanceof Stmt\Continue_ ? 'continue' : 'break'))->nonIgnorable()->identifier(sprintf('%s.outOfLoop', $node instanceof Stmt\Continue_ ? 'continue' : 'break'))->build()]; } if ($parentStmtType === Stmt\For_::class || $parentStmtType === Stmt\Foreach_::class || $parentStmtType === Stmt\Do_::class || $parentStmtType === Stmt\While_::class || $parentStmtType === Stmt\Switch_::class) { $value--; } if ($value === 0) { break; } } if ($value > 0) { return [RuleErrorBuilder::message(sprintf('Keyword %s used outside of a loop or a switch statement.', $node instanceof Stmt\Continue_ ? 'continue' : 'break'))->nonIgnorable()->identifier(sprintf('%s.outOfLoop', $node instanceof Stmt\Continue_ ? 'continue' : 'break'))->build()]; } return []; } } */ final class DeclareStrictTypesRule implements Rule { /** * @readonly * @var ExprPrinter */ private $exprPrinter; public function __construct(ExprPrinter $exprPrinter) { $this->exprPrinter = $exprPrinter; } public function getNodeType() : string { return Stmt\Declare_::class; } public function processNode(Node $node, Scope $scope) : array { $declaresStrictTypes = \false; foreach ($node->declares as $declare) { if ($declare->key->name !== 'strict_types') { continue; } if (!$declare->value instanceof Node\Scalar\LNumber || !in_array($declare->value->value, [0, 1], \true)) { return [RuleErrorBuilder::message(sprintf(sprintf('Declare strict_types must have 0 or 1 as its value, %s given.', $this->exprPrinter->printExpr($declare->value))))->identifier('declareStrictTypes.value')->nonIgnorable()->build()]; } $declaresStrictTypes = \true; break; } if ($declaresStrictTypes === \false) { return []; } if (!$node->hasAttribute(DeclarePositionVisitor::ATTRIBUTE_NAME)) { return []; } $isFirstStatement = (bool) $node->getAttribute(DeclarePositionVisitor::ATTRIBUTE_NAME); if ($isFirstStatement) { return []; } return [RuleErrorBuilder::message(sprintf('Declare strict_types must be the very first statement.'))->identifier('declareStrictTypes.notFirst')->nonIgnorable()->build()]; } } */ final class NoPhpCodeRule implements Rule { public function getNodeType() : string { return FileNode::class; } public function processNode(Node $node, Scope $scope) : array { if (count($node->getNodes()) !== 1) { return []; } $html = $node->getNodes()[0]; if (!$html instanceof Node\Stmt\InlineHTML) { return []; } return [RuleErrorBuilder::message('The example does not contain any PHP code. Did you forget the opening identifier('phpstanPlayground.noPhp')->build()]; } } */ final class NotAnalysedTraitRule implements Rule { public function getNodeType() : string { return CollectedDataNode::class; } public function processNode(Node $node, Scope $scope) : array { $traitDeclarationData = $node->get(TraitDeclarationCollector::class); $traitUseData = $node->get(TraitUseCollector::class); $declaredTraits = []; foreach ($traitDeclarationData as $file => $declaration) { foreach ($declaration as [$name, $line]) { $declaredTraits[strtolower($name)] = [$file, $name, $line]; } } foreach ($traitUseData as $usedNamesData) { foreach ($usedNamesData as $usedNames) { foreach ($usedNames as $usedName) { unset($declaredTraits[strtolower($usedName)]); } } } $errors = []; foreach ($declaredTraits as [$file, $name, $line]) { $errors[] = RuleErrorBuilder::message(sprintf('Trait %s is used zero times and is not analysed.', $name))->identifier('phpstanPlayground.traitUnused')->file($file)->line($line)->tip('See: https://phpstan.org/blog/how-phpstan-analyses-traits')->build(); } return $errors; } } */ final class FunctionNeverRule implements Rule { /** * @var NeverRuleHelper */ private $helper; public function __construct(\PHPStan\Rules\Playground\NeverRuleHelper $helper) { $this->helper = $helper; } public function getNodeType() : string { return FunctionReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { if (count($node->getReturnStatements()) > 0) { return []; } $function = $node->getFunctionReflection(); $returnType = $function->getReturnType(); $helperResult = $this->helper->shouldReturnNever($node, $returnType); if ($helperResult === \false) { return []; } return [RuleErrorBuilder::message(sprintf('Function %s() always %s, it should have return type "never".', $function->getName(), count($helperResult) === 0 ? 'throws an exception' : 'terminates script execution'))->identifier('phpstanPlayground.never')->build()]; } } |false */ public function shouldReturnNever(ReturnStatementsNode $node, Type $returnType) { if ($returnType instanceof NeverType && $returnType->isExplicit()) { return \false; } if ($node->isGenerator()) { return \false; } $other = []; foreach ($node->getExecutionEnds() as $executionEnd) { if ($executionEnd->getStatementResult()->isAlwaysTerminating()) { if (!$executionEnd->getNode() instanceof Node\Stmt\Throw_) { $other[] = $executionEnd->getNode(); } continue; } return \false; } return $other; } } */ final class MethodNeverRule implements Rule { /** * @var NeverRuleHelper */ private $helper; public function __construct(\PHPStan\Rules\Playground\NeverRuleHelper $helper) { $this->helper = $helper; } public function getNodeType() : string { return MethodReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { if (count($node->getReturnStatements()) > 0) { return []; } $method = $node->getMethodReflection(); $returnType = $method->getReturnType(); $helperResult = $this->helper->shouldReturnNever($node, $returnType); if ($helperResult === \false) { return []; } return [RuleErrorBuilder::message(sprintf('Method %s::%s() always %s, it should have return type "never".', $method->getDeclaringClass()->getDisplayName(), $method->getName(), count($helperResult) === 0 ? 'throws an exception' : 'terminates script execution'))->identifier('phpstanPlayground.never')->build()]; } } ruleLevelHelper = $ruleLevelHelper; } /** * @return list */ public function checkReturnType(Scope $scope, Type $returnType, ?Expr $returnValue, Node $returnNode, string $emptyReturnStatementMessage, string $voidMessage, string $typeMismatchMessage, string $neverMessage, bool $isGenerator) : array { $returnType = TypeUtils::resolveLateResolvableTypes($returnType); if ($returnType instanceof NeverType && $returnType->isExplicit()) { return [\PHPStan\Rules\RuleErrorBuilder::message($neverMessage)->line($returnNode->getStartLine())->identifier('return.never')->build()]; } if ($isGenerator) { $returnType = $returnType->getTemplateType(Generator::class, 'TReturn'); if ($returnType instanceof ErrorType) { return []; } } $isVoidSuperType = $returnType->isVoid(); $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($returnType, null); if ($returnValue === null) { if (!$isVoidSuperType->no()) { return []; } return [\PHPStan\Rules\RuleErrorBuilder::message(sprintf($emptyReturnStatementMessage, $returnType->describe($verbosityLevel)))->line($returnNode->getStartLine())->identifier('return.empty')->build()]; } if ($returnNode instanceof Expr\Yield_ || $returnNode instanceof Expr\YieldFrom) { return []; } $returnValueType = $scope->getType($returnValue); $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($returnType, $returnValueType); if ($isVoidSuperType->yes()) { return [\PHPStan\Rules\RuleErrorBuilder::message(sprintf($voidMessage, $returnValueType->describe($verbosityLevel)))->line($returnNode->getStartLine())->identifier('return.void')->build()]; } $accepts = $this->ruleLevelHelper->acceptsWithReason($returnType, $returnValueType, $scope->isDeclareStrictTypes()); if (!$accepts->result) { return [\PHPStan\Rules\RuleErrorBuilder::message(sprintf($typeMismatchMessage, $returnType->describe($verbosityLevel), $returnValueType->describe($verbosityLevel)))->line($returnNode->getStartLine())->identifier('return.type')->acceptsReasonsTip($accepts->reasons)->build()]; } return []; } } reflectionProvider = $reflectionProvider; $this->checkInternalClassCaseSensitivity = $checkInternalClassCaseSensitivity; } /** * @param ClassNameNodePair[] $pairs * @return list */ public function checkClassNames(array $pairs) : array { $errors = []; foreach ($pairs as $pair) { $className = $pair->getClassName(); if (!$this->reflectionProvider->hasClass($className)) { continue; } $classReflection = $this->reflectionProvider->getClass($className); if (!$this->checkInternalClassCaseSensitivity && $classReflection->isBuiltin()) { continue; // skip built-in classes } $realClassName = $classReflection->getName(); if (strtolower($realClassName) !== strtolower($className)) { continue; // skip class alias } if ($realClassName === $className) { continue; } $typeName = $classReflection->getClassTypeDescription(); $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('%s %s referenced with incorrect case: %s.', $typeName, $realClassName, $className))->identifier(sprintf('%s.nameCase', strtolower($typeName)))->line($pair->getNode()->getStartLine())->build(); } return $errors; } } '_PHPStan_', 'Rector' => 'RectorPrefix', 'PHP-Scoper' => '_PhpScoper', 'PHPUnit' => 'PHPUnitPHAR', 'Box' => '_HumbugBox']; public function __construct(Container $container) { $this->container = $container; } /** * @param ClassNameNodePair[] $pairs * @return list */ public function checkClassNames(array $pairs) : array { $extensions = $this->container->getServicesByTag(ForbiddenClassNameExtension::EXTENSION_TAG); $classPrefixes = array_merge(self::INTERNAL_CLASS_PREFIXES, ...array_map(static function (ForbiddenClassNameExtension $extension) : array { return $extension->getClassPrefixes(); }, $extensions)); $errors = []; foreach ($pairs as $pair) { $className = $pair->getClassName(); $projectName = null; $withoutPrefixClassName = null; foreach ($classPrefixes as $project => $prefix) { if (!str_starts_with($className, $prefix)) { continue; } $projectName = $project; $withoutPrefixClassName = substr($className, strlen($prefix)); if (strpos($withoutPrefixClassName, '\\') === \false) { continue; } $withoutPrefixClassName = substr($withoutPrefixClassName, strpos($withoutPrefixClassName, '\\')); } if ($projectName === null) { continue; } $error = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Referencing prefixed %s class: %s.', $projectName, $className))->line($pair->getNode()->getLine())->identifier('class.prefixed')->nonIgnorable(); if ($withoutPrefixClassName !== null) { $error->tip(sprintf('This is most likely unintentional. Did you mean to type %s?', $withoutPrefixClassName)); } $errors[] = $error->build(); } return $errors; } } ruleLevelHelper = $ruleLevelHelper; $this->reportMaybes = $reportMaybes; $this->bleedingEdge = $bleedingEdge; $this->reportPossiblyNonexistentGeneralArrayOffset = $reportPossiblyNonexistentGeneralArrayOffset; $this->reportPossiblyNonexistentConstantArrayOffset = $reportPossiblyNonexistentConstantArrayOffset; } /** * @return list */ public function check(Scope $scope, Expr $var, string $unknownClassPattern, Type $dimType) : array { $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $var), $unknownClassPattern, static function (Type $type) use($dimType) : bool { return $type->hasOffsetValueType($dimType)->yes(); }); $type = $typeResult->getType(); if ($type instanceof ErrorType) { return $typeResult->getUnknownClassErrors(); } if ($scope->isInExpressionAssign($var) || $scope->isUndefinedExpressionAllowed($var)) { return []; } if ($type->hasOffsetValueType($dimType)->no()) { return [RuleErrorBuilder::message(sprintf('Offset %s does not exist on %s.', $dimType->describe(VerbosityLevel::value()), $type->describe(VerbosityLevel::value())))->identifier('offsetAccess.notFound')->build()]; } if ($this->reportMaybes) { $report = \false; if ($type instanceof BenevolentUnionType) { $flattenedTypes = [$type]; } else { $flattenedTypes = TypeUtils::flattenTypes($type); } foreach ($flattenedTypes as $innerType) { if ($this->reportPossiblyNonexistentGeneralArrayOffset && $innerType->isArray()->yes() && !$innerType->isConstantArray()->yes() && !$innerType->hasOffsetValueType($dimType)->yes()) { $report = \true; break; } if ($this->reportPossiblyNonexistentConstantArrayOffset && $innerType->isConstantArray()->yes() && !$innerType->hasOffsetValueType($dimType)->yes()) { $report = \true; break; } if ($dimType instanceof UnionType) { if ($innerType->hasOffsetValueType($dimType)->no()) { $report = \true; break; } continue; } foreach (TypeUtils::flattenTypes($dimType) as $innerDimType) { if ($innerType->hasOffsetValueType($innerDimType)->no()) { $report = \true; break 2; } } } if ($report) { if ($this->bleedingEdge || $this->reportPossiblyNonexistentGeneralArrayOffset || $this->reportPossiblyNonexistentConstantArrayOffset) { return [RuleErrorBuilder::message(sprintf('Offset %s might not exist on %s.', $dimType->describe(VerbosityLevel::value()), $type->describe(VerbosityLevel::value())))->identifier('offsetAccess.notFound')->build()]; } return [RuleErrorBuilder::message(sprintf('Offset %s does not exist on %s.', $dimType->describe(VerbosityLevel::value()), $type->describe(VerbosityLevel::value())))->identifier('offsetAccess.notFound')->build()]; } } return []; } } */ final class InvalidKeyInArrayItemRule implements Rule { /** * @var bool */ private $reportMaybes; public function __construct(bool $reportMaybes) { $this->reportMaybes = $reportMaybes; } public function getNodeType() : string { return Node\Expr\ArrayItem::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->key === null) { return []; } $dimensionType = $scope->getType($node->key); $isSuperType = \PHPStan\Rules\Arrays\AllowedArrayKeysTypes::getType()->isSuperTypeOf($dimensionType); if ($isSuperType->no()) { return [RuleErrorBuilder::message(sprintf('Invalid array key type %s.', $dimensionType->describe(VerbosityLevel::typeOnly())))->identifier('array.invalidKey')->build()]; } elseif ($this->reportMaybes && $isSuperType->maybe() && !$dimensionType instanceof MixedType) { return [RuleErrorBuilder::message(sprintf('Possibly invalid array key type %s.', $dimensionType->describe(VerbosityLevel::typeOnly())))->identifier('array.invalidKey')->build()]; } return []; } } */ final class EmptyArrayItemRule implements Rule { public function getNodeType() : string { return LiteralArrayNode::class; } public function processNode(Node $node, Scope $scope) : array { foreach ($node->getItemNodes() as $itemNode) { $item = $itemNode->getArrayItem(); if ($item !== null) { continue; } return [RuleErrorBuilder::message('Literal array contains empty item.')->nonIgnorable()->identifier('array.emptyItem')->build()]; } return []; } } */ final class DuplicateKeysInLiteralArraysRule implements Rule { /** * @var ExprPrinter */ private $exprPrinter; public function __construct(ExprPrinter $exprPrinter) { $this->exprPrinter = $exprPrinter; } public function getNodeType() : string { return LiteralArrayNode::class; } public function processNode(Node $node, Scope $scope) : array { $values = []; $duplicateKeys = []; $printedValues = []; $valueLines = []; /** * @var int|false|null $autoGeneratedIndex * - An int value represent the biggest integer used as array key. * When no key is provided this value + 1 will be used. * - Null is used as initializer instead of 0 to avoid issue with negative keys. * - False means a non-scalar value was encountered and we cannot be sure of the next keys. */ $autoGeneratedIndex = null; foreach ($node->getItemNodes() as $itemNode) { $item = $itemNode->getArrayItem(); if ($item === null) { $autoGeneratedIndex = \false; continue; } $key = $item->key; if ($key === null) { if ($autoGeneratedIndex === \false) { continue; } if ($autoGeneratedIndex === null) { $autoGeneratedIndex = 0; $keyType = new ConstantIntegerType(0); } else { $keyType = new ConstantIntegerType(++$autoGeneratedIndex); } } else { $keyType = $itemNode->getScope()->getType($key); $arrayKeyValue = $keyType->toArrayKey(); if ($arrayKeyValue instanceof ConstantIntegerType) { $autoGeneratedIndex = $autoGeneratedIndex === null ? $arrayKeyValue->getValue() : max($autoGeneratedIndex, $arrayKeyValue->getValue()); } } if (!$keyType instanceof ConstantScalarType) { $autoGeneratedIndex = \false; continue; } $value = $keyType->getValue(); $printedValue = $key !== null ? $this->exprPrinter->printExpr($key) : $value; $printedValues[$value][] = $printedValue; if (!isset($valueLines[$value])) { $valueLines[$value] = $item->getStartLine(); } $previousCount = count($values); $values[$value] = $printedValue; if ($previousCount !== count($values)) { continue; } $duplicateKeys[$value] = \true; } $messages = []; foreach (array_keys($duplicateKeys) as $value) { $messages[] = RuleErrorBuilder::message(sprintf('Array has %d %s with value %s (%s).', count($printedValues[$value]), count($printedValues[$value]) === 1 ? 'duplicate key' : 'duplicate keys', var_export($value, \true), implode(', ', $printedValues[$value])))->identifier('array.duplicateKey')->line($valueLines[$value])->build(); } return $messages; } } */ final class OffsetAccessAssignOpRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Node\Expr\AssignOp::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->var instanceof ArrayDimFetch) { return []; } $arrayDimFetch = $node->var; $potentialDimType = null; if ($arrayDimFetch->dim !== null) { $potentialDimType = $scope->getType($arrayDimFetch->dim); } $varTypeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $arrayDimFetch->var, '', static function (Type $varType) use($potentialDimType) : bool { $arrayDimType = $varType->setOffsetValueType($potentialDimType, new MixedType()); return !$arrayDimType instanceof ErrorType; }); $varType = $varTypeResult->getType(); if ($arrayDimFetch->dim !== null) { $dimTypeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $arrayDimFetch->dim, '', static function (Type $dimType) use($varType) : bool { $arrayDimType = $varType->setOffsetValueType($dimType, new MixedType()); return !$arrayDimType instanceof ErrorType; }); $dimType = $dimTypeResult->getType(); if ($varType->hasOffsetValueType($dimType)->no()) { return []; } } else { $dimType = $potentialDimType; } $resultType = $varType->setOffsetValueType($dimType, new MixedType()); if (!$resultType instanceof ErrorType) { return []; } if ($dimType === null) { return [RuleErrorBuilder::message(sprintf('Cannot assign new offset to %s.', $varType->describe(VerbosityLevel::typeOnly())))->identifier('offsetAssign.dimType')->build()]; } return [RuleErrorBuilder::message(sprintf('Cannot assign offset %s to %s.', $dimType->describe(VerbosityLevel::value()), $varType->describe(VerbosityLevel::typeOnly())))->identifier('offsetAssign.dimType')->build()]; } } */ final class DeadForeachRule implements Rule { public function getNodeType() : string { return Node\Stmt\Foreach_::class; } public function processNode(Node $node, Scope $scope) : array { $iterableType = $scope->getType($node->expr); if ($iterableType->isIterable()->no()) { return []; } if (!$iterableType->isIterableAtLeastOnce()->no()) { return []; } return [RuleErrorBuilder::message('Empty array passed to foreach.')->identifier('foreach.emptyArray')->build()]; } } */ final class ArrayDestructuringRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var NonexistentOffsetInArrayDimFetchCheck */ private $nonexistentOffsetInArrayDimFetchCheck; public function __construct(RuleLevelHelper $ruleLevelHelper, \PHPStan\Rules\Arrays\NonexistentOffsetInArrayDimFetchCheck $nonexistentOffsetInArrayDimFetchCheck) { $this->ruleLevelHelper = $ruleLevelHelper; $this->nonexistentOffsetInArrayDimFetchCheck = $nonexistentOffsetInArrayDimFetchCheck; } public function getNodeType() : string { return Assign::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->var instanceof Node\Expr\List_ && !$node->var instanceof Node\Expr\Array_) { return []; } return $this->getErrors($scope, $node->var, $node->expr); } /** * @param Node\Expr\List_|Node\Expr\Array_ $var * @return list */ private function getErrors(Scope $scope, Expr $var, Expr $expr) : array { $exprTypeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $expr, '', static function (Type $varType) : bool { return $varType->isArray()->yes() || (new ObjectType(ArrayAccess::class))->isSuperTypeOf($varType)->yes(); }); $exprType = $exprTypeResult->getType(); if ($exprType instanceof ErrorType) { return []; } if (!$exprType->isArray()->yes() && !(new ObjectType(ArrayAccess::class))->isSuperTypeOf($exprType)->yes()) { return [RuleErrorBuilder::message(sprintf('Cannot use array destructuring on %s.', $exprType->describe(VerbosityLevel::typeOnly())))->identifier('offsetAccess.nonArray')->build()]; } $errors = []; $i = 0; foreach ($var->items as $item) { if ($item === null) { $i++; continue; } $keyExpr = null; if ($item->key === null) { $keyType = new ConstantIntegerType($i); $keyExpr = new Node\Scalar\LNumber($i); } else { $keyType = $scope->getType($item->key); $keyExpr = new TypeExpr($keyType); } $itemErrors = $this->nonexistentOffsetInArrayDimFetchCheck->check($scope, $expr, '', $keyType); $errors = array_merge($errors, $itemErrors); if (!$item->value instanceof Node\Expr\List_ && !$item->value instanceof Node\Expr\Array_) { $i++; continue; } $errors = array_merge($errors, $this->getErrors($scope, $item->value, new Expr\ArrayDimFetch($expr, $keyExpr))); } return $errors; } } */ final class IterableInForeachRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return InForeachNode::class; } public function processNode(Node $node, Scope $scope) : array { $originalNode = $node->getOriginalNode(); $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $originalNode->expr, 'Iterating over an object of an unknown class %s.', static function (Type $type) : bool { return $type->isIterable()->yes(); }); $type = $typeResult->getType(); if ($type instanceof ErrorType) { return $typeResult->getUnknownClassErrors(); } if ($type->isIterable()->yes()) { return []; } return [RuleErrorBuilder::message(sprintf('Argument of an invalid type %s supplied for foreach, only iterables are supported.', $type->describe(VerbosityLevel::typeOnly())))->identifier('foreach.nonIterable')->line($originalNode->expr->getStartLine())->build()]; } } */ final class NonexistentOffsetInArrayDimFetchRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var NonexistentOffsetInArrayDimFetchCheck */ private $nonexistentOffsetInArrayDimFetchCheck; /** * @var bool */ private $reportMaybes; public function __construct(RuleLevelHelper $ruleLevelHelper, \PHPStan\Rules\Arrays\NonexistentOffsetInArrayDimFetchCheck $nonexistentOffsetInArrayDimFetchCheck, bool $reportMaybes) { $this->ruleLevelHelper = $ruleLevelHelper; $this->nonexistentOffsetInArrayDimFetchCheck = $nonexistentOffsetInArrayDimFetchCheck; $this->reportMaybes = $reportMaybes; } public function getNodeType() : string { return Node\Expr\ArrayDimFetch::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->dim !== null) { $dimType = $scope->getType($node->dim); $unknownClassPattern = sprintf('Access to offset %s on an unknown class %%s.', SprintfHelper::escapeFormatString($dimType->describe(VerbosityLevel::value()))); } else { $dimType = null; $unknownClassPattern = 'Access to an offset on an unknown class %s.'; } $isOffsetAccessibleTypeResult = $this->ruleLevelHelper->findTypeToCheck($scope, NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $node->var), $unknownClassPattern, static function (Type $type) : bool { return $type->isOffsetAccessible()->yes(); }); $isOffsetAccessibleType = $isOffsetAccessibleTypeResult->getType(); if ($isOffsetAccessibleType instanceof ErrorType) { return $isOffsetAccessibleTypeResult->getUnknownClassErrors(); } if ($scope->hasExpressionType($node)->yes()) { return []; } $isOffsetAccessible = $isOffsetAccessibleType->isOffsetAccessible(); if ($scope->isInExpressionAssign($node) && $isOffsetAccessible->yes()) { return []; } if ($scope->isUndefinedExpressionAllowed($node) && $isOffsetAccessibleType->isOffsetAccessLegal()->yes()) { return []; } if (!$isOffsetAccessible->yes()) { if ($isOffsetAccessible->no() || $this->reportMaybes) { if ($dimType !== null) { return [RuleErrorBuilder::message(sprintf('Cannot access offset %s on %s.', $dimType->describe(VerbosityLevel::value()), $isOffsetAccessibleType->describe(VerbosityLevel::value())))->identifier('offsetAccess.nonOffsetAccessible')->build()]; } return [RuleErrorBuilder::message(sprintf('Cannot access an offset on %s.', $isOffsetAccessibleType->describe(VerbosityLevel::typeOnly())))->identifier('offsetAccess.nonOffsetAccessible')->build()]; } return []; } if ($dimType === null) { return []; } return $this->nonexistentOffsetInArrayDimFetchCheck->check($scope, $node->var, $unknownClassPattern, $dimType); } } isArray()->yes() || $varType->isIterableAtLeastOnce()->no()) { return null; } $varIterableKeyType = $varType->getIterableKeyType(); if ($varIterableKeyType->isConstantScalarValue()->yes()) { $narrowedKey = TypeCombinator::union($varIterableKeyType, TypeCombinator::remove($varIterableKeyType->toString(), new ConstantStringType(''))); if (!$varType->hasOffsetValueType(new ConstantIntegerType(0))->no()) { $narrowedKey = TypeCombinator::union($narrowedKey, new ConstantBooleanType(\false)); } if (!$varType->hasOffsetValueType(new ConstantIntegerType(1))->no()) { $narrowedKey = TypeCombinator::union($narrowedKey, new ConstantBooleanType(\true)); } if (!$varType->hasOffsetValueType(new ConstantStringType(''))->no()) { $narrowedKey = TypeCombinator::addNull($narrowedKey); } if (!$varIterableKeyType->isNumericString()->no() || !$varIterableKeyType->isInteger()->no()) { $narrowedKey = TypeCombinator::union($narrowedKey, new FloatType()); } return $narrowedKey; } elseif ($varIterableKeyType->isInteger()->yes() && $keyType->isString()->yes()) { return TypeCombinator::intersect($varIterableKeyType->toString(), $keyType); } return new MixedType(\false, new UnionType([new ArrayType(new MixedType(), new MixedType()), new ObjectWithoutClassType(), new ResourceType()])); } } */ final class UnpackIterableInArrayRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return LiteralArrayNode::class; } public function processNode(Node $node, Scope $scope) : array { $errors = []; foreach ($node->getItemNodes() as $itemNode) { $item = $itemNode->getArrayItem(); if ($item === null) { continue; } if (!$item->unpack) { continue; } $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $item->value, '', static function (Type $type) : bool { return $type->isIterable()->yes(); }); $type = $typeResult->getType(); if ($type instanceof ErrorType) { continue; } if ($type->isIterable()->yes()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Only iterables can be unpacked, %s given.', $type->describe(VerbosityLevel::typeOnly())))->identifier('arrayUnpacking.nonIterable')->line($item->getStartLine())->build(); } return $errors; } } */ final class AppendedArrayKeyTypeRule implements Rule { /** * @var PropertyReflectionFinder */ private $propertyReflectionFinder; /** * @var bool */ private $checkUnionTypes; public function __construct(PropertyReflectionFinder $propertyReflectionFinder, bool $checkUnionTypes) { $this->propertyReflectionFinder = $propertyReflectionFinder; $this->checkUnionTypes = $checkUnionTypes; } public function getNodeType() : string { return Assign::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->var instanceof ArrayDimFetch) { return []; } if (!$node->var->var instanceof Node\Expr\PropertyFetch && !$node->var->var instanceof Node\Expr\StaticPropertyFetch) { return []; } $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node->var->var, $scope); if ($propertyReflection === null) { return []; } $arrayType = $propertyReflection->getReadableType(); if (!$arrayType->isArray()->yes()) { return []; } if ($node->var->dim !== null) { $dimensionType = $scope->getType($node->var->dim); $isValidKey = \PHPStan\Rules\Arrays\AllowedArrayKeysTypes::getType()->isSuperTypeOf($dimensionType); if (!$isValidKey->yes()) { // already handled by InvalidKeyInArrayDimFetchRule return []; } $keyType = $dimensionType->toArrayKey(); if (!$this->checkUnionTypes && $keyType instanceof UnionType) { return []; } } else { $keyType = new IntegerType(); } if (!$arrayType->getIterableKeyType()->isSuperTypeOf($keyType)->yes()) { $verbosity = VerbosityLevel::getRecommendedLevelByType($arrayType->getIterableKeyType(), $keyType); return [RuleErrorBuilder::message(sprintf('Array (%s) does not accept key %s.', $arrayType->describe($verbosity), $keyType->describe(VerbosityLevel::value())))->identifier('array.keyType')->build()]; } return []; } } */ final class ArrayUnpackingRule implements Rule { /** * @var PhpVersion */ private $phpVersion; /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(PhpVersion $phpVersion, RuleLevelHelper $ruleLevelHelper) { $this->phpVersion = $phpVersion; $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return ArrayItem::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->unpack === \false || $this->phpVersion->supportsArrayUnpackingWithStringKeys()) { return []; } $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, new GetIterableKeyTypeExpr($node->value), '', static function (Type $type) : bool { return $type->isString()->no(); }); $keyType = $typeResult->getType(); if ($keyType instanceof ErrorType) { return $typeResult->getUnknownClassErrors(); } $isString = $keyType->isString(); if ($isString->no()) { return []; } return [RuleErrorBuilder::message(sprintf('Array unpacking cannot be used on an array with %sstring keys: %s', $isString->yes() ? '' : 'potential ', $scope->getType($node->value)->describe(VerbosityLevel::value())))->identifier('arrayUnpacking.stringOffset')->build()]; } } */ final class AppendedArrayItemTypeRule implements Rule { /** * @var PropertyReflectionFinder */ private $propertyReflectionFinder; /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(PropertyReflectionFinder $propertyReflectionFinder, RuleLevelHelper $ruleLevelHelper) { $this->propertyReflectionFinder = $propertyReflectionFinder; $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Node\Expr::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof Assign && !$node instanceof AssignOp && !$node instanceof AssignRef) { return []; } if (!$node->var instanceof ArrayDimFetch) { return []; } if (!$node->var->var instanceof Node\Expr\PropertyFetch && !$node->var->var instanceof Node\Expr\StaticPropertyFetch) { return []; } $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node->var->var, $scope); if ($propertyReflection === null) { return []; } $assignedToType = $propertyReflection->getWritableType(); if (!$assignedToType->isArray()->yes()) { return []; } if ($node instanceof Assign || $node instanceof AssignRef) { $assignedValueType = $scope->getType($node->expr); } else { $assignedValueType = $scope->getType($node); } $itemType = $assignedToType->getIterableValueType(); $accepts = $this->ruleLevelHelper->acceptsWithReason($itemType, $assignedValueType, $scope->isDeclareStrictTypes()); if (!$accepts->result) { $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($itemType, $assignedValueType); return [RuleErrorBuilder::message(sprintf('Array (%s) does not accept %s.', $assignedToType->describe($verbosityLevel), $assignedValueType->describe($verbosityLevel)))->acceptsReasonsTip($accepts->reasons)->identifier('array.valueType')->build()]; } return []; } } */ final class OffsetAccessValueAssignmentRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Expr::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof Assign && !$node instanceof AssignOp && !$node instanceof Expr\AssignRef) { return []; } if (!$node->var instanceof Expr\ArrayDimFetch) { return []; } $arrayDimFetch = $node->var; $varType = $scope->getType($arrayDimFetch->var); if ($varType->isObject()->no()) { return []; } if ($node instanceof Assign || $node instanceof Expr\AssignRef) { $assignedValueType = $scope->getType($node->expr); } else { $assignedValueType = $scope->getType($node); } $arrayTypeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $arrayDimFetch->var, '', static function (Type $varType) use($assignedValueType) : bool { $result = $varType->setOffsetValueType(new MixedType(), $assignedValueType); return !$result instanceof ErrorType; }); $arrayType = $arrayTypeResult->getType(); if ($arrayType instanceof ErrorType) { return []; } $isOffsetAccessible = $arrayType->isOffsetAccessible(); if (!$isOffsetAccessible->yes()) { return []; } $resultType = $arrayType->setOffsetValueType(new MixedType(), $assignedValueType); if (!$resultType instanceof ErrorType) { return []; } $originalArrayType = $scope->getType($arrayDimFetch->var); return [RuleErrorBuilder::message(sprintf('%s does not accept %s.', $originalArrayType->describe(VerbosityLevel::value()), $assignedValueType->describe(VerbosityLevel::typeOnly())))->identifier('offsetAssign.valueType')->build()]; } } */ final class OffsetAccessAssignmentRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Node\Expr\ArrayDimFetch::class; } public function processNode(Node $node, Scope $scope) : array { if (!$scope->isInExpressionAssign($node)) { return []; } $potentialDimType = null; if ($node->dim !== null) { $potentialDimType = $scope->getType($node->dim); } $varTypeResult = $this->ruleLevelHelper->findTypeToCheck($scope, NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $node->var), '', static function (Type $varType) use($potentialDimType) : bool { $arrayDimType = $varType->setOffsetValueType($potentialDimType, new MixedType()); return !$arrayDimType instanceof ErrorType; }); $varType = $varTypeResult->getType(); if ($varType instanceof ErrorType) { return []; } if (!$varType->isOffsetAccessible()->yes()) { return []; } if ($node->dim !== null) { $dimTypeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $node->dim, '', static function (Type $dimType) use($varType) : bool { $arrayDimType = $varType->setOffsetValueType($dimType, new MixedType()); return !$arrayDimType instanceof ErrorType; }); $dimType = $dimTypeResult->getType(); } else { $dimType = $potentialDimType; } $resultType = $varType->setOffsetValueType($dimType, new MixedType()); if (!$resultType instanceof ErrorType) { return []; } if ($dimType === null) { return [RuleErrorBuilder::message(sprintf('Cannot assign new offset to %s.', $varType->describe(VerbosityLevel::typeOnly())))->identifier('offsetAssign.dimType')->build()]; } return [RuleErrorBuilder::message(sprintf('Cannot assign offset %s to %s.', $dimType->describe(VerbosityLevel::value()), $varType->describe(VerbosityLevel::typeOnly())))->identifier('offsetAssign.dimType')->build()]; } } */ final class OffsetAccessWithoutDimForReadingRule implements Rule { public function getNodeType() : string { return Node\Expr\ArrayDimFetch::class; } public function processNode(Node $node, Scope $scope) : array { if ($scope->isInExpressionAssign($node)) { return []; } if ($node->dim !== null) { return []; } return [RuleErrorBuilder::message('Cannot use [] for reading.')->identifier('offsetAccess.noDim')->nonIgnorable()->build()]; } } */ final class InvalidKeyInArrayDimFetchRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var bool */ private $reportMaybes; public function __construct(RuleLevelHelper $ruleLevelHelper, bool $reportMaybes) { $this->ruleLevelHelper = $ruleLevelHelper; $this->reportMaybes = $reportMaybes; } public function getNodeType() : string { return Node\Expr\ArrayDimFetch::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->dim === null) { return []; } $dimensionType = $scope->getType($node->dim); if ($dimensionType instanceof MixedType) { return []; } $varType = $this->ruleLevelHelper->findTypeToCheck($scope, $node->var, '', static function (Type $varType) use($dimensionType) : bool { return $varType->isArray()->no() || \PHPStan\Rules\Arrays\AllowedArrayKeysTypes::getType()->isSuperTypeOf($dimensionType)->yes(); })->getType(); if ($varType instanceof ErrorType || $varType->isArray()->no()) { return []; } $isSuperType = \PHPStan\Rules\Arrays\AllowedArrayKeysTypes::getType()->isSuperTypeOf($dimensionType); if ($isSuperType->yes() || $isSuperType->maybe() && !$this->reportMaybes) { return []; } return [RuleErrorBuilder::message(sprintf('%s array key type %s.', $isSuperType->no() ? 'Invalid' : 'Possibly invalid', $dimensionType->describe(VerbosityLevel::typeOnly())))->identifier('offsetAccess.invalidOffset')->build()]; } } */ final class NumberComparisonOperatorsConstantConditionRule implements Rule { /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(bool $treatPhpDocTypesAsCertain, bool $treatPhpDocTypesAsCertainTip) { $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return BinaryOp::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof BinaryOp\Greater && !$node instanceof BinaryOp\GreaterOrEqual && !$node instanceof BinaryOp\Smaller && !$node instanceof BinaryOp\SmallerOrEqual) { return []; } $exprType = $this->treatPhpDocTypesAsCertain ? $scope->getType($node) : $scope->getNativeType($node); if ($exprType instanceof ConstantBooleanType) { $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $scope->getNativeType($node); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; switch (get_class($node)) { case BinaryOp\Greater::class: $nodeType = 'greater'; break; case BinaryOp\GreaterOrEqual::class: $nodeType = 'greaterOrEqual'; break; case BinaryOp\Smaller::class: $nodeType = 'smaller'; break; case BinaryOp\SmallerOrEqual::class: $nodeType = 'smallerOrEqual'; break; default: throw new ShouldNotHappenException(); } return [$addTip(RuleErrorBuilder::message(sprintf('Comparison operation "%s" between %s and %s is always %s.', $node->getOperatorSigil(), $scope->getType($node->left)->describe(VerbosityLevel::value()), $scope->getType($node->right)->describe(VerbosityLevel::value()), $exprType->getValue() ? 'true' : 'false')))->identifier(sprintf('%s.always%s', $nodeType, $exprType->getValue() ? 'True' : 'False'))->build()]; } return []; } } */ final class WhileLoopAlwaysTrueConditionRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $helper; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $helper, bool $treatPhpDocTypesAsCertain, bool $treatPhpDocTypesAsCertainTip) { $this->helper = $helper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return BreaklessWhileLoopNode::class; } public function processNode(Node $node, Scope $scope) : array { foreach ($node->getExitPoints() as $exitPoint) { $statement = $exitPoint->getStatement(); if ($statement instanceof Break_) { return []; } if (!$statement instanceof Continue_) { return []; } if ($statement->num === null) { continue; } if (!$statement->num instanceof LNumber) { continue; } $value = $statement->num->value; if ($value === 1) { continue; } if ($value > 1) { return []; } } $originalNode = $node->getOriginalNode(); $exprType = $this->helper->getBooleanType($scope, $originalNode->cond); if ($exprType->isTrue()->yes()) { $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $originalNode) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($scope, $originalNode->cond); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; return [$addTip(RuleErrorBuilder::message('While loop condition is always true.'))->line($originalNode->cond->getStartLine())->identifier('while.alwaysTrue')->build()]; } return []; } } */ final class TernaryOperatorConstantConditionRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $helper; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $helper, bool $treatPhpDocTypesAsCertain, bool $treatPhpDocTypesAsCertainTip) { $this->helper = $helper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return Node\Expr\Ternary::class; } public function processNode(Node $node, Scope $scope) : array { $exprType = $this->helper->getBooleanType($scope, $node->cond); if ($exprType instanceof ConstantBooleanType) { $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($scope, $node->cond); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; return [$addTip(RuleErrorBuilder::message(sprintf('Ternary operator condition is always %s.', $exprType->getValue() ? 'true' : 'false')))->identifier(sprintf('ternary.always%s', $exprType->getValue() ? 'True' : 'False'))->build()]; } return []; } } */ final class ImpossibleCheckTypeMethodCallRule implements Rule { /** * @var ImpossibleCheckTypeHelper */ private $impossibleCheckTypeHelper; /** * @var bool */ private $checkAlwaysTrueCheckTypeFunctionCall; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $reportAlwaysTrueInLastCondition; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ImpossibleCheckTypeHelper $impossibleCheckTypeHelper, bool $checkAlwaysTrueCheckTypeFunctionCall, bool $treatPhpDocTypesAsCertain, bool $reportAlwaysTrueInLastCondition, bool $treatPhpDocTypesAsCertainTip) { $this->impossibleCheckTypeHelper = $impossibleCheckTypeHelper; $this->checkAlwaysTrueCheckTypeFunctionCall = $checkAlwaysTrueCheckTypeFunctionCall; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->reportAlwaysTrueInLastCondition = $reportAlwaysTrueInLastCondition; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return Node\Expr\MethodCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier) { return []; } $isAlways = $this->impossibleCheckTypeHelper->findSpecifiedType($scope, $node); if ($isAlways === null) { return []; } $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $isAlways = $this->impossibleCheckTypeHelper->doNotTreatPhpDocTypesAsCertain()->findSpecifiedType($scope, $node); if ($isAlways !== null) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; if (!$isAlways) { $method = $this->getMethod($node->var, $node->name->name, $scope); return [$addTip(RuleErrorBuilder::message(sprintf('Call to method %s::%s()%s will always evaluate to false.', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $this->impossibleCheckTypeHelper->getArgumentsDescription($scope, $node->getArgs()))))->identifier('method.impossibleType')->build()]; } elseif ($this->checkAlwaysTrueCheckTypeFunctionCall) { $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if ($isLast === \true && !$this->reportAlwaysTrueInLastCondition) { return []; } $method = $this->getMethod($node->var, $node->name->name, $scope); $errorBuilder = $addTip(RuleErrorBuilder::message(sprintf('Call to method %s::%s()%s will always evaluate to true.', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $this->impossibleCheckTypeHelper->getArgumentsDescription($scope, $node->getArgs())))); if ($isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errorBuilder->identifier('method.alreadyNarrowedType'); return [$errorBuilder->build()]; } return []; } private function getMethod(Expr $var, string $methodName, Scope $scope) : MethodReflection { $calledOnType = $scope->getType($var); $method = $scope->getMethodReflection($calledOnType, $methodName); if ($method === null) { throw new ShouldNotHappenException(); } return $method; } } reflectionProvider = $reflectionProvider; $this->typeSpecifier = $typeSpecifier; $this->universalObjectCratesClasses = $universalObjectCratesClasses; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->nullContextForVoidReturningFunctions = $nullContextForVoidReturningFunctions; } public function findSpecifiedType(Scope $scope, Expr $node) : ?bool { if ($node instanceof FuncCall) { if ($node->isFirstClassCallable()) { return null; } $argsCount = count($node->getArgs()); if ($node->name instanceof Node\Name) { $functionName = strtolower((string) $node->name); if ($functionName === 'assert' && $argsCount >= 1) { $arg = $node->getArgs()[0]->value; $assertValue = ($this->treatPhpDocTypesAsCertain ? $scope->getType($arg) : $scope->getNativeType($arg))->toBoolean(); if (!$assertValue instanceof ConstantBooleanType) { return null; } return $assertValue->getValue(); } if (in_array($functionName, ['class_exists', 'interface_exists', 'trait_exists', 'enum_exists'], \true)) { return null; } if (in_array($functionName, ['count', 'sizeof'], \true)) { return null; } elseif ($functionName === 'defined') { return null; } elseif ($functionName === 'array_search') { return null; } elseif ($functionName === 'in_array' && $argsCount >= 2) { $haystackArg = $node->getArgs()[1]->value; $haystackType = $this->treatPhpDocTypesAsCertain ? $scope->getType($haystackArg) : $scope->getNativeType($haystackArg); if ($haystackType instanceof MixedType) { return null; } if (!$haystackType->isArray()->yes()) { return null; } $needleArg = $node->getArgs()[0]->value; $needleType = $this->treatPhpDocTypesAsCertain ? $scope->getType($needleArg) : $scope->getNativeType($needleArg); $isStrictComparison = \false; if ($argsCount >= 3) { $strictNodeType = $scope->getType($node->getArgs()[2]->value); $isStrictComparison = $strictNodeType->isTrue()->yes(); } $isStrictComparison = $isStrictComparison || $needleType->isEnum()->yes() || $haystackType->getIterableValueType()->isEnum()->yes(); if (!$isStrictComparison) { return null; } $valueType = $haystackType->getIterableValueType(); $constantNeedleTypesCount = count($needleType->getFiniteTypes()); $constantHaystackTypesCount = count($valueType->getFiniteTypes()); $isNeedleSupertype = $needleType->isSuperTypeOf($valueType); if ($haystackType->isConstantArray()->no()) { if ($haystackType->isIterableAtLeastOnce()->yes()) { // In this case the generic implementation via typeSpecifier fails, because the argument types cannot be narrowed down. if ($constantNeedleTypesCount === 1 && $constantHaystackTypesCount === 1) { if ($isNeedleSupertype->yes()) { return \true; } if ($isNeedleSupertype->no()) { return \false; } } return null; } } if (!$haystackType instanceof ConstantArrayType || count($haystackType->getValueTypes()) > 0) { $haystackArrayTypes = $haystackType->getArrays(); if (count($haystackArrayTypes) === 1 && $haystackArrayTypes[0]->getIterableValueType() instanceof NeverType) { return null; } if ($isNeedleSupertype->maybe() || $isNeedleSupertype->yes()) { foreach ($haystackArrayTypes as $haystackArrayType) { if ($haystackArrayType instanceof ConstantArrayType) { foreach ($haystackArrayType->getValueTypes() as $i => $haystackArrayValueType) { if ($haystackArrayType->isOptionalKey($i)) { continue; } foreach ($haystackArrayValueType->getConstantScalarTypes() as $constantScalarType) { if ($constantScalarType->isSuperTypeOf($needleType)->yes()) { continue 3; } } } } else { foreach ($haystackArrayType->getIterableValueType()->getConstantScalarTypes() as $constantScalarType) { if ($constantScalarType->isSuperTypeOf($needleType)->yes()) { continue 2; } } } return null; } } if ($isNeedleSupertype->yes()) { $hasConstantNeedleTypes = $constantNeedleTypesCount > 0; $hasConstantHaystackTypes = $constantHaystackTypesCount > 0; if (!$hasConstantNeedleTypes && !$hasConstantHaystackTypes || $hasConstantNeedleTypes !== $hasConstantHaystackTypes) { return null; } } } } elseif ($functionName === 'method_exists' && $argsCount >= 2) { $objectArg = $node->getArgs()[0]->value; $objectType = $this->treatPhpDocTypesAsCertain ? $scope->getType($objectArg) : $scope->getNativeType($objectArg); if ($objectType instanceof ConstantStringType && !$this->reflectionProvider->hasClass($objectType->getValue())) { return \false; } $methodArg = $node->getArgs()[1]->value; $methodType = $this->treatPhpDocTypesAsCertain ? $scope->getType($methodArg) : $scope->getNativeType($methodArg); if ($methodType instanceof ConstantStringType) { if ($objectType instanceof ConstantStringType) { $objectType = new ObjectType($objectType->getValue()); } if ($objectType->getObjectClassNames() !== []) { if ($objectType->hasMethod($methodType->getValue())->yes()) { return \true; } if ($objectType->hasMethod($methodType->getValue())->no()) { return \false; } } $genericType = TypeTraverser::map($objectType, static function (Type $type, callable $traverse) : Type { if ($type instanceof UnionType || $type instanceof IntersectionType) { return $traverse($type); } if ($type instanceof GenericClassStringType) { return $type->getGenericType(); } return new MixedType(); }); if ($genericType instanceof TypeWithClassName) { if ($genericType->hasMethod($methodType->getValue())->yes()) { return \true; } $classReflection = $genericType->getClassReflection(); if ($classReflection !== null && $classReflection->isFinal() && $genericType->hasMethod($methodType->getValue())->no()) { return \false; } } } } } } $typeSpecifierScope = $this->treatPhpDocTypesAsCertain ? $scope : $scope->doNotTreatPhpDocTypesAsCertain(); $specifiedTypes = $this->typeSpecifier->specifyTypesInCondition($typeSpecifierScope, $node, $this->determineContext($typeSpecifierScope, $node)); // don't validate types on overwrite if ($specifiedTypes->shouldOverwrite()) { return null; } $sureTypes = $specifiedTypes->getSureTypes(); $sureNotTypes = $specifiedTypes->getSureNotTypes(); $rootExpr = $specifiedTypes->getRootExpr(); if ($rootExpr !== null) { if (self::isSpecified($typeSpecifierScope, $node, $rootExpr)) { return null; } $rootExprType = $this->treatPhpDocTypesAsCertain ? $scope->getType($rootExpr) : $scope->getNativeType($rootExpr); if ($rootExprType instanceof ConstantBooleanType) { return $rootExprType->getValue(); } return null; } $results = []; foreach ($sureTypes as $sureType) { if (self::isSpecified($typeSpecifierScope, $node, $sureType[0])) { $results[] = TrinaryLogic::createMaybe(); continue; } if ($this->treatPhpDocTypesAsCertain) { $argumentType = $scope->getType($sureType[0]); } else { $argumentType = $scope->getNativeType($sureType[0]); } /** @var Type $resultType */ $resultType = $sureType[1]; $results[] = $resultType->isSuperTypeOf($argumentType); } foreach ($sureNotTypes as $sureNotType) { if (self::isSpecified($typeSpecifierScope, $node, $sureNotType[0])) { $results[] = TrinaryLogic::createMaybe(); continue; } if ($this->treatPhpDocTypesAsCertain) { $argumentType = $scope->getType($sureNotType[0]); } else { $argumentType = $scope->getNativeType($sureNotType[0]); } /** @var Type $resultType */ $resultType = $sureNotType[1]; $results[] = $resultType->isSuperTypeOf($argumentType)->negate(); } if (count($results) === 0) { return null; } $result = TrinaryLogic::createYes()->and(...$results); return $result->maybe() ? null : $result->yes(); } private static function isSpecified(Scope $scope, Expr $node, Expr $expr) : bool { if ($expr === $node) { return \true; } if ($expr instanceof Expr\Variable) { return is_string($expr->name) && !$scope->hasVariableType($expr->name)->yes(); } if ($expr instanceof Expr\BooleanNot) { return self::isSpecified($scope, $node, $expr->expr); } if ($expr instanceof Expr\BinaryOp) { return self::isSpecified($scope, $node, $expr->left) || self::isSpecified($scope, $node, $expr->right); } return ($node instanceof FuncCall || $node instanceof MethodCall || $node instanceof Expr\StaticCall) && $scope->hasExpressionType($expr)->yes(); } /** * @param Node\Arg[] $args */ public function getArgumentsDescription(Scope $scope, array $args) : string { if (count($args) === 0) { return ''; } $descriptions = array_map(function (Arg $arg) use($scope) : string { return ($this->treatPhpDocTypesAsCertain ? $scope->getType($arg->value) : $scope->getNativeType($arg->value))->describe(VerbosityLevel::value()); }, $args); if (count($descriptions) < 3) { return sprintf(' with %s', implode(' and ', $descriptions)); } $lastDescription = array_pop($descriptions); return sprintf(' with arguments %s and %s', implode(', ', $descriptions), $lastDescription); } public function doNotTreatPhpDocTypesAsCertain() : self { if (!$this->treatPhpDocTypesAsCertain) { return $this; } return new self($this->reflectionProvider, $this->typeSpecifier, $this->universalObjectCratesClasses, \false, $this->nullContextForVoidReturningFunctions); } private function determineContext(Scope $scope, Expr $node) : TypeSpecifierContext { if (!$this->nullContextForVoidReturningFunctions) { return TypeSpecifierContext::createTruthy(); } if ($node instanceof Expr\CallLike && $node->isFirstClassCallable()) { return TypeSpecifierContext::createTruthy(); } if ($node instanceof FuncCall && $node->name instanceof Node\Name) { if ($this->reflectionProvider->hasFunction($node->name, $scope)) { $functionReflection = $this->reflectionProvider->getFunction($node->name, $scope); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants()); $returnType = TypeUtils::resolveLateResolvableTypes($parametersAcceptor->getReturnType()); return $returnType->isVoid()->yes() ? TypeSpecifierContext::createNull() : TypeSpecifierContext::createTruthy(); } } elseif ($node instanceof MethodCall && $node->name instanceof Node\Identifier) { $methodCalledOnType = $scope->getType($node->var); $methodReflection = $scope->getMethodReflection($methodCalledOnType, $node->name->name); if ($methodReflection !== null) { $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $methodReflection->getVariants(), $methodReflection->getNamedArgumentsVariants()); $returnType = TypeUtils::resolveLateResolvableTypes($parametersAcceptor->getReturnType()); return $returnType->isVoid()->yes() ? TypeSpecifierContext::createNull() : TypeSpecifierContext::createTruthy(); } } elseif ($node instanceof StaticCall && $node->name instanceof Node\Identifier) { if ($node->class instanceof Node\Name) { $calleeType = $scope->resolveTypeByName($node->class); } else { $calleeType = $scope->getType($node->class); } $staticMethodReflection = $scope->getMethodReflection($calleeType, $node->name->name); if ($staticMethodReflection !== null) { $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $staticMethodReflection->getVariants(), $staticMethodReflection->getNamedArgumentsVariants()); $returnType = TypeUtils::resolveLateResolvableTypes($parametersAcceptor->getReturnType()); return $returnType->isVoid()->yes() ? TypeSpecifierContext::createNull() : TypeSpecifierContext::createTruthy(); } } return TypeSpecifierContext::createTruthy(); } } */ final class WhileLoopAlwaysFalseConditionRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $helper; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $helper, bool $treatPhpDocTypesAsCertain, bool $treatPhpDocTypesAsCertainTip) { $this->helper = $helper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return While_::class; } public function processNode(Node $node, Scope $scope) : array { $exprType = $this->helper->getBooleanType($scope, $node->cond); if ($exprType->isFalse()->yes()) { $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($scope, $node->cond); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; return [$addTip(RuleErrorBuilder::message('While loop condition is always false.'))->line($node->cond->getStartLine())->identifier('while.alwaysFalse')->build()]; } return []; } } */ final class LogicalXorConstantConditionRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $helper; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $reportAlwaysTrueInLastCondition; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $helper, bool $treatPhpDocTypesAsCertain, bool $reportAlwaysTrueInLastCondition, bool $treatPhpDocTypesAsCertainTip) { $this->helper = $helper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->reportAlwaysTrueInLastCondition = $reportAlwaysTrueInLastCondition; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return LogicalXor::class; } public function processNode(Node $node, Scope $scope) : array { $errors = []; $leftType = $this->helper->getBooleanType($scope, $node->left); if ($leftType instanceof ConstantBooleanType) { $addTipLeft = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($scope, $node->left); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if (!$leftType->getValue() || $isLast !== \true || $this->reportAlwaysTrueInLastCondition) { $errorBuilder = $addTipLeft(RuleErrorBuilder::message(sprintf('Left side of xor is always %s.', $leftType->getValue() ? 'true' : 'false')))->identifier(sprintf('logicalXor.leftAlways%s', $leftType->getValue() ? 'True' : 'False'))->line($node->left->getStartLine()); if ($leftType->getValue() && $isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errors[] = $errorBuilder->build(); } } $rightType = $this->helper->getBooleanType($scope, $node->right); if ($rightType instanceof ConstantBooleanType) { $addTipRight = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($scope, $node->right); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if (!$rightType->getValue() || $isLast !== \true || $this->reportAlwaysTrueInLastCondition) { $errorBuilder = $addTipRight(RuleErrorBuilder::message(sprintf('Right side of xor is always %s.', $rightType->getValue() ? 'true' : 'false')))->identifier(sprintf('logicalXor.rightAlways%s', $rightType->getValue() ? 'True' : 'False'))->line($node->right->getStartLine()); if ($rightType->getValue() && $isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errors[] = $errorBuilder->build(); } } return $errors; } } */ final class IfConstantConditionRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $helper; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $helper, bool $treatPhpDocTypesAsCertain, bool $treatPhpDocTypesAsCertainTip) { $this->helper = $helper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return Node\Stmt\If_::class; } public function processNode(Node $node, Scope $scope) : array { $exprType = $this->helper->getBooleanType($scope, $node->cond); if ($exprType instanceof ConstantBooleanType) { $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($scope, $node->cond); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; return [$addTip(RuleErrorBuilder::message(sprintf('If condition is always %s.', $exprType->getValue() ? 'true' : 'false')))->identifier(sprintf('if.always%s', $exprType->getValue() ? 'True' : 'False'))->line($node->cond->getStartLine())->build()]; } return []; } } */ final class ImpossibleCheckTypeStaticMethodCallRule implements Rule { /** * @var ImpossibleCheckTypeHelper */ private $impossibleCheckTypeHelper; /** * @var bool */ private $checkAlwaysTrueCheckTypeFunctionCall; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $reportAlwaysTrueInLastCondition; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ImpossibleCheckTypeHelper $impossibleCheckTypeHelper, bool $checkAlwaysTrueCheckTypeFunctionCall, bool $treatPhpDocTypesAsCertain, bool $reportAlwaysTrueInLastCondition, bool $treatPhpDocTypesAsCertainTip) { $this->impossibleCheckTypeHelper = $impossibleCheckTypeHelper; $this->checkAlwaysTrueCheckTypeFunctionCall = $checkAlwaysTrueCheckTypeFunctionCall; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->reportAlwaysTrueInLastCondition = $reportAlwaysTrueInLastCondition; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return Node\Expr\StaticCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Identifier) { return []; } $isAlways = $this->impossibleCheckTypeHelper->findSpecifiedType($scope, $node); if ($isAlways === null) { return []; } $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $isAlways = $this->impossibleCheckTypeHelper->doNotTreatPhpDocTypesAsCertain()->findSpecifiedType($scope, $node); if ($isAlways !== null) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; if (!$isAlways) { $method = $this->getMethod($node->class, $node->name->name, $scope); return [$addTip(RuleErrorBuilder::message(sprintf('Call to static method %s::%s()%s will always evaluate to false.', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $this->impossibleCheckTypeHelper->getArgumentsDescription($scope, $node->getArgs()))))->identifier('staticMethod.impossibleType')->build()]; } elseif ($this->checkAlwaysTrueCheckTypeFunctionCall) { $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if ($isLast === \true && !$this->reportAlwaysTrueInLastCondition) { return []; } $method = $this->getMethod($node->class, $node->name->name, $scope); $errorBuilder = $addTip(RuleErrorBuilder::message(sprintf('Call to static method %s::%s()%s will always evaluate to true.', $method->getDeclaringClass()->getDisplayName(), $method->getName(), $this->impossibleCheckTypeHelper->getArgumentsDescription($scope, $node->getArgs())))); if ($isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errorBuilder->identifier('staticMethod.alreadyNarrowedType'); return [$errorBuilder->build()]; } return []; } /** * @param Node\Name|Expr $class * @throws ShouldNotHappenException */ private function getMethod($class, string $methodName, Scope $scope) : MethodReflection { if ($class instanceof Node\Name) { $calledOnType = $scope->resolveTypeByName($class); } else { $calledOnType = $scope->getType($class); } $method = $scope->getMethodReflection($calledOnType, $methodName); if ($method === null) { throw new ShouldNotHappenException(); } return $method; } } */ final class StrictComparisonOfDifferentTypesRule implements Rule { /** * @var RicherScopeGetTypeHelper */ private $richerScopeGetTypeHelper; /** * @var bool */ private $checkAlwaysTrueStrictComparison; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $reportAlwaysTrueInLastCondition; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(RicherScopeGetTypeHelper $richerScopeGetTypeHelper, bool $checkAlwaysTrueStrictComparison, bool $treatPhpDocTypesAsCertain, bool $reportAlwaysTrueInLastCondition, bool $treatPhpDocTypesAsCertainTip) { $this->richerScopeGetTypeHelper = $richerScopeGetTypeHelper; $this->checkAlwaysTrueStrictComparison = $checkAlwaysTrueStrictComparison; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->reportAlwaysTrueInLastCondition = $reportAlwaysTrueInLastCondition; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return Node\Expr\BinaryOp::class; } public function processNode(Node $node, Scope $scope) : array { if ($node instanceof Node\Expr\BinaryOp\Identical) { $nodeTypeResult = $this->richerScopeGetTypeHelper->getIdenticalResult($this->treatPhpDocTypesAsCertain ? $scope : $scope->doNotTreatPhpDocTypesAsCertain(), $node); } elseif ($node instanceof Node\Expr\BinaryOp\NotIdentical) { $nodeTypeResult = $this->richerScopeGetTypeHelper->getNotIdenticalResult($this->treatPhpDocTypesAsCertain ? $scope : $scope->doNotTreatPhpDocTypesAsCertain(), $node); } else { return []; } $nodeType = $nodeTypeResult->type; if (!$nodeType instanceof ConstantBooleanType) { return []; } $leftType = $this->treatPhpDocTypesAsCertain ? $scope->getType($node->left) : $scope->getNativeType($node->left); $rightType = $this->treatPhpDocTypesAsCertain ? $scope->getType($node->right) : $scope->getNativeType($node->right); $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node, $nodeTypeResult) : RuleErrorBuilder { $reasons = $nodeTypeResult->reasons; if (count($reasons) > 0) { return $ruleErrorBuilder->acceptsReasonsTip($reasons); } if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $instanceofTypeWithoutPhpDocs = $scope->getNativeType($node); if ($instanceofTypeWithoutPhpDocs instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; $verbosity = VerbosityLevel::value(); if ($leftType->isConstantScalarValue()->yes() && !$leftType->isString()->no() && !$rightType->isConstantScalarValue()->yes() && !$rightType->isString()->no() && (TrinaryLogic::extremeIdentity($leftType->isLowercaseString(), $rightType->isLowercaseString())->maybe() || TrinaryLogic::extremeIdentity($leftType->isUppercaseString(), $rightType->isUppercaseString())->maybe()) || $rightType->isConstantScalarValue()->yes() && !$rightType->isString()->no() && !$leftType->isConstantScalarValue()->yes() && !$leftType->isString()->no() && (TrinaryLogic::extremeIdentity($leftType->isLowercaseString(), $rightType->isLowercaseString())->maybe() || TrinaryLogic::extremeIdentity($leftType->isUppercaseString(), $rightType->isUppercaseString())->maybe())) { $verbosity = VerbosityLevel::precise(); } if (!$nodeType->getValue()) { return [$addTip(RuleErrorBuilder::message(sprintf('Strict comparison using %s between %s and %s will always evaluate to false.', $node->getOperatorSigil(), $leftType->describe($verbosity), $rightType->describe($verbosity))))->identifier(sprintf('%s.alwaysFalse', $node instanceof Node\Expr\BinaryOp\Identical ? 'identical' : 'notIdentical'))->build()]; } elseif ($this->checkAlwaysTrueStrictComparison) { $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if ($isLast === \true && !$this->reportAlwaysTrueInLastCondition) { return []; } $errorBuilder = $addTip(RuleErrorBuilder::message(sprintf('Strict comparison using %s between %s and %s will always evaluate to true.', $node->getOperatorSigil(), $leftType->describe($verbosity), $rightType->describe($verbosity)))); if ($isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->addTip('Remove remaining cases below this one and this error will disappear too.'); } if ($leftType->isEnum()->yes() && $rightType->isEnum()->yes() && $node->getAttribute(LastConditionVisitor::ATTRIBUTE_IS_MATCH_NAME, \false) !== \true) { $errorBuilder->addTip('Use match expression instead. PHPStan will report unhandled enum cases.'); } $errorBuilder->identifier(sprintf('%s.alwaysTrue', $node instanceof Node\Expr\BinaryOp\Identical ? 'identical' : 'notIdentical')); return [$errorBuilder->build()]; } return []; } } */ final class DoWhileLoopConstantConditionRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $helper; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $helper, bool $treatPhpDocTypesAsCertain, bool $treatPhpDocTypesAsCertainTip) { $this->helper = $helper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return DoWhileLoopConditionNode::class; } public function processNode(Node $node, Scope $scope) : array { $exprType = $this->helper->getBooleanType($scope, $node->getCond()); if ($exprType instanceof ConstantBooleanType) { if ($exprType->getValue()) { foreach ($node->getExitPoints() as $exitPoint) { $statement = $exitPoint->getStatement(); if ($statement instanceof Break_) { return []; } if (!$statement instanceof Continue_) { return []; } if ($statement->num === null) { continue; } if (!$statement->num instanceof LNumber) { continue; } $value = $statement->num->value; if ($value === 1) { continue; } if ($value > 1) { return []; } } } $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($scope, $node->getCond()); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; return [$addTip(RuleErrorBuilder::message(sprintf('Do-while loop condition is always %s.', $exprType->getValue() ? 'true' : 'false')))->line($node->getCond()->getStartLine())->identifier(sprintf('doWhile.always%s', $exprType->getValue() ? 'True' : 'False'))->build()]; } return []; } } */ final class BooleanAndConstantConditionRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $helper; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $bleedingEdge; /** * @var bool */ private $reportAlwaysTrueInLastCondition; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $helper, bool $treatPhpDocTypesAsCertain, bool $bleedingEdge, bool $reportAlwaysTrueInLastCondition, bool $treatPhpDocTypesAsCertainTip) { $this->helper = $helper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->bleedingEdge = $bleedingEdge; $this->reportAlwaysTrueInLastCondition = $reportAlwaysTrueInLastCondition; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return BooleanAndNode::class; } public function processNode(Node $node, Scope $scope) : array { $errors = []; $originalNode = $node->getOriginalNode(); $nodeText = $this->bleedingEdge ? $originalNode->getOperatorSigil() : '&&'; $leftType = $this->helper->getBooleanType($scope, $originalNode->left); $identifierType = $originalNode instanceof Node\Expr\BinaryOp\BooleanAnd ? 'booleanAnd' : 'logicalAnd'; if ($leftType instanceof ConstantBooleanType) { $addTipLeft = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $originalNode) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($scope, $originalNode->left); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if (!$leftType->getValue() || $isLast !== \true || $this->reportAlwaysTrueInLastCondition) { $errorBuilder = $addTipLeft(RuleErrorBuilder::message(sprintf('Left side of %s is always %s.', $nodeText, $leftType->getValue() ? 'true' : 'false')))->identifier(sprintf('%s.leftAlways%s', $identifierType, $leftType->getValue() ? 'True' : 'False'))->line($originalNode->left->getStartLine()); if ($leftType->getValue() && $isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errors[] = $errorBuilder->build(); } } $rightScope = $node->getRightScope(); $rightType = $this->helper->getBooleanType($rightScope, $originalNode->right); if ($rightType instanceof ConstantBooleanType && !$scope->isInFirstLevelStatement()) { $addTipRight = function (RuleErrorBuilder $ruleErrorBuilder) use($rightScope, $originalNode) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($rightScope, $originalNode->right); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if (!$rightType->getValue() || $isLast !== \true || $this->reportAlwaysTrueInLastCondition) { $errorBuilder = $addTipRight(RuleErrorBuilder::message(sprintf('Right side of %s is always %s.', $nodeText, $rightType->getValue() ? 'true' : 'false')))->identifier(sprintf('%s.rightAlways%s', $identifierType, $rightType->getValue() ? 'True' : 'False'))->line($originalNode->right->getStartLine()); if ($rightType->getValue() && $isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errors[] = $errorBuilder->build(); } } if (count($errors) === 0 && !$scope->isInFirstLevelStatement()) { $nodeType = $this->treatPhpDocTypesAsCertain ? $scope->getType($originalNode) : $scope->getNativeType($originalNode); if ($nodeType instanceof ConstantBooleanType) { $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $originalNode) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $scope->getNativeType($originalNode); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if (!$nodeType->getValue() || $isLast !== \true || $this->reportAlwaysTrueInLastCondition) { $errorBuilder = $addTip(RuleErrorBuilder::message(sprintf('Result of %s is always %s.', $nodeText, $nodeType->getValue() ? 'true' : 'false'))); if ($nodeType->getValue() && $isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errorBuilder->identifier(sprintf('%s.always%s', $identifierType, $nodeType->getValue() ? 'True' : 'False')); $errors[] = $errorBuilder->build(); } } } return $errors; } } */ final class BooleanNotConstantConditionRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $helper; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $reportAlwaysTrueInLastCondition; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $helper, bool $treatPhpDocTypesAsCertain, bool $reportAlwaysTrueInLastCondition, bool $treatPhpDocTypesAsCertainTip) { $this->helper = $helper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->reportAlwaysTrueInLastCondition = $reportAlwaysTrueInLastCondition; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return Node\Expr\BooleanNot::class; } public function processNode(Node $node, Scope $scope) : array { $exprType = $this->helper->getBooleanType($scope, $node->expr); if ($exprType instanceof ConstantBooleanType) { $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($scope, $node->expr); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if ($exprType->getValue() || $isLast !== \true || $this->reportAlwaysTrueInLastCondition) { $errorBuilder = $addTip(RuleErrorBuilder::message(sprintf('Negated boolean expression is always %s.', $exprType->getValue() ? 'false' : 'true')))->line($node->expr->getStartLine()); if (!$exprType->getValue() && $isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errorBuilder->identifier(sprintf('booleanNot.always%s', $exprType->getValue() ? 'False' : 'True')); return [$errorBuilder->build()]; } } return []; } } */ final class UsageOfVoidMatchExpressionRule implements Rule { public function getNodeType() : string { return Node\Expr\Match_::class; } public function processNode(Node $node, Scope $scope) : array { if (!$scope->isInFirstLevelStatement()) { $matchResultType = $scope->getKeepVoidType($node); if ($matchResultType->isVoid()->yes()) { return [RuleErrorBuilder::message('Result of match expression (void) is used.')->identifier('match.void')->build()]; } } return []; } } */ final class ImpossibleCheckTypeFunctionCallRule implements Rule { /** * @var ImpossibleCheckTypeHelper */ private $impossibleCheckTypeHelper; /** * @var bool */ private $checkAlwaysTrueCheckTypeFunctionCall; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $reportAlwaysTrueInLastCondition; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ImpossibleCheckTypeHelper $impossibleCheckTypeHelper, bool $checkAlwaysTrueCheckTypeFunctionCall, bool $treatPhpDocTypesAsCertain, bool $reportAlwaysTrueInLastCondition, bool $treatPhpDocTypesAsCertainTip) { $this->impossibleCheckTypeHelper = $impossibleCheckTypeHelper; $this->checkAlwaysTrueCheckTypeFunctionCall = $checkAlwaysTrueCheckTypeFunctionCall; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->reportAlwaysTrueInLastCondition = $reportAlwaysTrueInLastCondition; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return Node\Expr\FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } $functionName = (string) $node->name; $isAlways = $this->impossibleCheckTypeHelper->findSpecifiedType($scope, $node); if ($isAlways === null) { return []; } $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $isAlways = $this->impossibleCheckTypeHelper->doNotTreatPhpDocTypesAsCertain()->findSpecifiedType($scope, $node); if ($isAlways !== null) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; if (!$isAlways) { return [$addTip(RuleErrorBuilder::message(sprintf('Call to function %s()%s will always evaluate to false.', $functionName, $this->impossibleCheckTypeHelper->getArgumentsDescription($scope, $node->getArgs()))))->identifier('function.impossibleType')->build()]; } elseif ($this->checkAlwaysTrueCheckTypeFunctionCall) { $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if ($isLast === \true && !$this->reportAlwaysTrueInLastCondition) { return []; } $errorBuilder = $addTip(RuleErrorBuilder::message(sprintf('Call to function %s()%s will always evaluate to true.', $functionName, $this->impossibleCheckTypeHelper->getArgumentsDescription($scope, $node->getArgs())))); if ($isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errorBuilder->identifier('function.alreadyNarrowedType'); return [$errorBuilder->build()]; } return []; } } */ final class ConstantLooseComparisonRule implements Rule { /** * @var bool */ private $checkAlwaysTrueLooseComparison; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $reportAlwaysTrueInLastCondition; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(bool $checkAlwaysTrueLooseComparison, bool $treatPhpDocTypesAsCertain, bool $reportAlwaysTrueInLastCondition, bool $treatPhpDocTypesAsCertainTip) { $this->checkAlwaysTrueLooseComparison = $checkAlwaysTrueLooseComparison; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->reportAlwaysTrueInLastCondition = $reportAlwaysTrueInLastCondition; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return Node\Expr\BinaryOp::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node instanceof Node\Expr\BinaryOp\Equal && !$node instanceof Node\Expr\BinaryOp\NotEqual) { return []; } $nodeType = $this->treatPhpDocTypesAsCertain ? $scope->getType($node) : $scope->getNativeType($node); if (!$nodeType instanceof ConstantBooleanType) { return []; } $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $instanceofTypeWithoutPhpDocs = $scope->getNativeType($node); if ($instanceofTypeWithoutPhpDocs instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; if (!$nodeType->getValue()) { return [$addTip(RuleErrorBuilder::message(sprintf('Loose comparison using %s between %s and %s will always evaluate to false.', $node->getOperatorSigil(), $scope->getType($node->left)->describe(VerbosityLevel::value()), $scope->getType($node->right)->describe(VerbosityLevel::value()))))->identifier(sprintf('%s.alwaysFalse', $node instanceof Node\Expr\BinaryOp\Equal ? 'equal' : 'notEqual'))->build()]; } elseif ($this->checkAlwaysTrueLooseComparison) { $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if ($isLast === \true && !$this->reportAlwaysTrueInLastCondition) { return []; } $errorBuilder = $addTip(RuleErrorBuilder::message(sprintf('Loose comparison using %s between %s and %s will always evaluate to true.', $node->getOperatorSigil(), $scope->getType($node->left)->describe(VerbosityLevel::value()), $scope->getType($node->right)->describe(VerbosityLevel::value())))); if ($isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errorBuilder->identifier(sprintf('%s.alwaysTrue', $node instanceof Node\Expr\BinaryOp\Equal ? 'equal' : 'notEqual')); return [$errorBuilder->build()]; } return []; } } */ final class UnreachableIfBranchesRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $helper; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $disable; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $helper, bool $treatPhpDocTypesAsCertain, bool $disable, bool $treatPhpDocTypesAsCertainTip) { $this->helper = $helper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->disable = $disable; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return Node\Stmt\If_::class; } public function processNode(Node $node, Scope $scope) : array { if ($this->disable) { return []; } $errors = []; $condition = $node->cond; $conditionType = $this->treatPhpDocTypesAsCertain ? $scope->getType($condition) : $scope->getNativeType($condition); $conditionBooleanType = $conditionType->toBoolean(); $nextBranchIsDead = $conditionBooleanType->isTrue()->yes() && $this->helper->shouldSkip($scope, $node->cond) && !$this->helper->shouldReportAlwaysTrueByDefault($node->cond); $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, &$condition) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $scope->getNativeType($condition)->toBoolean(); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; foreach ($node->elseifs as $elseif) { if ($nextBranchIsDead) { $errors[] = $addTip(RuleErrorBuilder::message('Elseif branch is unreachable because previous condition is always true.'))->identifier('elseif.unreachable')->line($elseif->getStartLine())->build(); continue; } $condition = $elseif->cond; $conditionType = $this->treatPhpDocTypesAsCertain ? $scope->getType($condition) : $scope->getNativeType($condition); $conditionBooleanType = $conditionType->toBoolean(); $nextBranchIsDead = $conditionBooleanType->isTrue()->yes() && $this->helper->shouldSkip($scope, $elseif->cond) && !$this->helper->shouldReportAlwaysTrueByDefault($elseif->cond); } if ($node->else !== null && $nextBranchIsDead) { $errors[] = $addTip(RuleErrorBuilder::message('Else branch is unreachable because previous condition is always true.'))->identifier('else.unreachable')->line($node->else->getStartLine())->build(); } return $errors; } } impossibleCheckTypeHelper = $impossibleCheckTypeHelper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->looseComparisonRuleEnabled = $looseComparisonRuleEnabled; } public function shouldReportAlwaysTrueByDefault(Expr $expr) : bool { return $expr instanceof Expr\BooleanNot || $expr instanceof Expr\BinaryOp\BooleanOr || $expr instanceof Expr\BinaryOp\BooleanAnd || $expr instanceof Expr\Ternary || $expr instanceof Expr\Isset_ || $expr instanceof Expr\Empty_; } public function shouldSkip(Scope $scope, Expr $expr) : bool { if ($this->looseComparisonRuleEnabled && ($expr instanceof Expr\BinaryOp\Equal || $expr instanceof Expr\BinaryOp\NotEqual)) { return \true; } if ($expr instanceof Expr\Instanceof_ || $expr instanceof Expr\BinaryOp\Identical || $expr instanceof Expr\BinaryOp\NotIdentical || $expr instanceof Expr\BooleanNot || $expr instanceof Expr\BinaryOp\BooleanOr || $expr instanceof Expr\BinaryOp\BooleanAnd || $expr instanceof Expr\Ternary || $expr instanceof Expr\Isset_ || $expr instanceof Expr\Empty_ || $expr instanceof Expr\BinaryOp\Greater || $expr instanceof Expr\BinaryOp\GreaterOrEqual || $expr instanceof Expr\BinaryOp\Smaller || $expr instanceof Expr\BinaryOp\SmallerOrEqual) { // already checked by different rules return \true; } if ($expr instanceof FuncCall || $expr instanceof MethodCall || $expr instanceof Expr\StaticCall) { $isAlways = $this->impossibleCheckTypeHelper->findSpecifiedType($scope, $expr); if ($isAlways !== null) { return \true; } } return \false; } public function getBooleanType(Scope $scope, Expr $expr) : BooleanType { if ($this->shouldSkip($scope, $expr)) { return new BooleanType(); } if ($this->treatPhpDocTypesAsCertain) { return $scope->getType($expr)->toBoolean(); } return $scope->getNativeType($expr)->toBoolean(); } public function getNativeBooleanType(Scope $scope, Expr $expr) : BooleanType { if ($this->shouldSkip($scope, $expr)) { return new BooleanType(); } return $scope->getNativeType($expr)->toBoolean(); } } */ final class BooleanOrConstantConditionRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $helper; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $bleedingEdge; /** * @var bool */ private $reportAlwaysTrueInLastCondition; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $helper, bool $treatPhpDocTypesAsCertain, bool $bleedingEdge, bool $reportAlwaysTrueInLastCondition, bool $treatPhpDocTypesAsCertainTip) { $this->helper = $helper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->bleedingEdge = $bleedingEdge; $this->reportAlwaysTrueInLastCondition = $reportAlwaysTrueInLastCondition; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return BooleanOrNode::class; } public function processNode(Node $node, Scope $scope) : array { $originalNode = $node->getOriginalNode(); $nodeText = $this->bleedingEdge ? $originalNode->getOperatorSigil() : '||'; $messages = []; $leftType = $this->helper->getBooleanType($scope, $originalNode->left); $identifierType = $originalNode instanceof Node\Expr\BinaryOp\BooleanOr ? 'booleanOr' : 'logicalOr'; if ($leftType instanceof ConstantBooleanType) { $addTipLeft = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $originalNode) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($scope, $originalNode->left); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if (!$leftType->getValue() || $isLast !== \true || $this->reportAlwaysTrueInLastCondition) { $errorBuilder = $addTipLeft(RuleErrorBuilder::message(sprintf('Left side of %s is always %s.', $nodeText, $leftType->getValue() ? 'true' : 'false')))->identifier(sprintf('%s.leftAlways%s', $identifierType, $leftType->getValue() ? 'True' : 'False'))->line($originalNode->left->getStartLine()); if ($leftType->getValue() && $isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $messages[] = $errorBuilder->build(); } } $rightScope = $node->getRightScope(); $rightType = $this->helper->getBooleanType($rightScope, $originalNode->right); if ($rightType instanceof ConstantBooleanType && !$scope->isInFirstLevelStatement()) { $addTipRight = function (RuleErrorBuilder $ruleErrorBuilder) use($rightScope, $originalNode) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($rightScope, $originalNode->right); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if (!$rightType->getValue() || $isLast !== \true || $this->reportAlwaysTrueInLastCondition) { $errorBuilder = $addTipRight(RuleErrorBuilder::message(sprintf('Right side of %s is always %s.', $nodeText, $rightType->getValue() ? 'true' : 'false')))->identifier(sprintf('%s.rightAlways%s', $identifierType, $rightType->getValue() ? 'True' : 'False'))->line($originalNode->right->getStartLine()); if ($rightType->getValue() && $isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $messages[] = $errorBuilder->build(); } } if (count($messages) === 0 && !$scope->isInFirstLevelStatement()) { $nodeType = $this->treatPhpDocTypesAsCertain ? $scope->getType($originalNode) : $scope->getNativeType($originalNode); if ($nodeType instanceof ConstantBooleanType) { $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $originalNode) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $scope->getNativeType($originalNode); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; $isLast = $node->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if (!$nodeType->getValue() || $isLast !== \true || $this->reportAlwaysTrueInLastCondition) { $errorBuilder = $addTip(RuleErrorBuilder::message(sprintf('Result of %s is always %s.', $nodeText, $nodeType->getValue() ? 'true' : 'false'))); if ($nodeType->getValue() && $isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errorBuilder->identifier(sprintf('%s.always%s', $identifierType, $nodeType->getValue() ? 'True' : 'False')); $messages[] = $errorBuilder->build(); } } } return $messages; } } */ final class ElseIfConstantConditionRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $helper; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $reportAlwaysTrueInLastCondition; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $helper, bool $treatPhpDocTypesAsCertain, bool $reportAlwaysTrueInLastCondition, bool $treatPhpDocTypesAsCertainTip) { $this->helper = $helper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->reportAlwaysTrueInLastCondition = $reportAlwaysTrueInLastCondition; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return Node\Stmt\ElseIf_::class; } public function processNode(Node $node, Scope $scope) : array { $exprType = $this->helper->getBooleanType($scope, $node->cond); if ($exprType instanceof ConstantBooleanType) { $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $this->helper->getNativeBooleanType($scope, $node->cond); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; $isLast = $node->cond->getAttribute(LastConditionVisitor::ATTRIBUTE_NAME); if (!$exprType->getValue() || $isLast !== \true || $this->reportAlwaysTrueInLastCondition) { $errorBuilder = $addTip(RuleErrorBuilder::message(sprintf('Elseif condition is always %s.', $exprType->getValue() ? 'true' : 'false')))->line($node->cond->getStartLine()); if ($exprType->getValue() && $isLast === \false && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errorBuilder->identifier(sprintf('elseif.always%s', $exprType->getValue() ? 'True' : 'False')); return [$errorBuilder->build()]; } } return []; } } */ final class UnreachableTernaryElseBranchRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $helper; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $disable; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $helper, bool $treatPhpDocTypesAsCertain, bool $disable, bool $treatPhpDocTypesAsCertainTip) { $this->helper = $helper; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->disable = $disable; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return Node\Expr\Ternary::class; } public function processNode(Node $node, Scope $scope) : array { if ($this->disable) { return []; } $conditionType = $this->treatPhpDocTypesAsCertain ? $scope->getType($node->cond) : $scope->getNativeType($node->cond); $conditionBooleanType = $conditionType->toBoolean(); if ($conditionBooleanType->isTrue()->yes() && $this->helper->shouldSkip($scope, $node->cond) && !$this->helper->shouldReportAlwaysTrueByDefault($node->cond)) { $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use($scope, $node) : RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; } $booleanNativeType = $scope->getNativeType($node->cond); if ($booleanNativeType instanceof ConstantBooleanType) { return $ruleErrorBuilder; } if (!$this->treatPhpDocTypesAsCertainTip) { return $ruleErrorBuilder; } return $ruleErrorBuilder->treatPhpDocTypesAsCertainTip(); }; return [$addTip(RuleErrorBuilder::message('Else branch is unreachable because ternary operator condition is always true.'))->identifier('ternary.elseUnreachable')->line($node->else->getStartLine())->build()]; } return []; } } */ final class MatchExpressionRule implements Rule { /** * @var ConstantConditionRuleHelper */ private $constantConditionRuleHelper; /** * @var bool */ private $checkAlwaysTrueStrictComparison; /** * @var bool */ private $disableUnreachable; /** * @var bool */ private $reportAlwaysTrueInLastCondition; /** * @var bool */ private $treatPhpDocTypesAsCertain; public function __construct(\PHPStan\Rules\Comparison\ConstantConditionRuleHelper $constantConditionRuleHelper, bool $checkAlwaysTrueStrictComparison, bool $disableUnreachable, bool $reportAlwaysTrueInLastCondition, bool $treatPhpDocTypesAsCertain) { $this->constantConditionRuleHelper = $constantConditionRuleHelper; $this->checkAlwaysTrueStrictComparison = $checkAlwaysTrueStrictComparison; $this->disableUnreachable = $disableUnreachable; $this->reportAlwaysTrueInLastCondition = $reportAlwaysTrueInLastCondition; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; } public function getNodeType() : string { return MatchExpressionNode::class; } public function processNode(Node $node, Scope $scope) : array { $matchCondition = $node->getCondition(); $matchConditionType = $scope->getType($matchCondition); $nextArmIsDeadForType = \false; $nextArmIsDeadForNativeType = \false; $errors = []; $armsCount = count($node->getArms()); $hasDefault = \false; foreach ($node->getArms() as $i => $arm) { if ($nextArmIsDeadForNativeType || $nextArmIsDeadForType && $this->treatPhpDocTypesAsCertain) { if (!$this->disableUnreachable) { $errors[] = RuleErrorBuilder::message('Match arm is unreachable because previous comparison is always true.')->identifier('match.unreachable')->line($arm->getLine())->build(); } continue; } $armConditions = $arm->getConditions(); if (count($armConditions) === 0) { $hasDefault = \true; } foreach ($armConditions as $armCondition) { $armConditionScope = $armCondition->getScope(); $armConditionExpr = new Node\Expr\BinaryOp\Identical($matchCondition, $armCondition->getCondition()); $armConditionResult = $armConditionScope->getType($armConditionExpr); if (!$armConditionResult instanceof ConstantBooleanType) { continue; } if ($armConditionResult->getValue()) { $nextArmIsDeadForType = \true; } if (!$this->treatPhpDocTypesAsCertain) { $armConditionNativeResult = $armConditionScope->getNativeType($armConditionExpr); if (!$armConditionNativeResult instanceof ConstantBooleanType) { continue; } if ($armConditionNativeResult->getValue()) { $nextArmIsDeadForNativeType = \true; } } if ($matchConditionType instanceof ConstantBooleanType) { $armConditionStandaloneResult = $this->constantConditionRuleHelper->getBooleanType($armConditionScope, $armCondition->getCondition()); if (!$armConditionStandaloneResult instanceof ConstantBooleanType) { continue; } } $armLine = $armCondition->getLine(); if (!$armConditionResult->getValue()) { $errors[] = RuleErrorBuilder::message(sprintf('Match arm comparison between %s and %s is always false.', $armConditionScope->getType($matchCondition)->describe(VerbosityLevel::value()), $armConditionScope->getType($armCondition->getCondition())->describe(VerbosityLevel::value())))->line($armLine)->identifier('match.alwaysFalse')->build(); } else { if ($this->checkAlwaysTrueStrictComparison) { if ($i === $armsCount - 1 && !$this->reportAlwaysTrueInLastCondition) { continue; } $errorBuilder = RuleErrorBuilder::message(sprintf('Match arm comparison between %s and %s is always true.', $armConditionScope->getType($matchCondition)->describe(VerbosityLevel::value()), $armConditionScope->getType($armCondition->getCondition())->describe(VerbosityLevel::value())))->line($armLine); if ($i !== $armsCount - 1 && !$this->reportAlwaysTrueInLastCondition) { $errorBuilder->tip('Remove remaining cases below this one and this error will disappear too.'); } $errorBuilder->identifier('match.alwaysTrue'); $errors[] = $errorBuilder->build(); } } } } if (!$hasDefault && !$nextArmIsDeadForType) { $remainingType = $node->getEndScope()->getType($matchCondition); $cases = $remainingType->getEnumCases(); $casesCount = count($cases); if ($casesCount > 1) { $remainingType = new UnionType($cases); } if ($casesCount === 1) { $remainingType = $cases[0]; } if (!$remainingType instanceof NeverType && !$this->isUnhandledMatchErrorCaught($node) && !$this->hasUnhandledMatchErrorThrowsTag($scope)) { $errors[] = RuleErrorBuilder::message(sprintf('Match expression does not handle remaining %s: %s', $remainingType instanceof UnionType ? 'values' : 'value', $remainingType->describe(VerbosityLevel::value())))->identifier('match.unhandled')->build(); } } return $errors; } private function isUnhandledMatchErrorCaught(Node $node) : bool { $tryCatchTypes = $node->getAttribute(TryCatchTypeVisitor::ATTRIBUTE_NAME); if ($tryCatchTypes === null) { return \false; } $tryCatchType = TypeCombinator::union(...array_map(static function (string $class) { return new ObjectType($class); }, $tryCatchTypes)); return $tryCatchType->isSuperTypeOf(new ObjectType(UnhandledMatchError::class))->yes(); } private function hasUnhandledMatchErrorThrowsTag(Scope $scope) : bool { $function = $scope->getFunction(); if ($function === null) { return \false; } $throwsType = $function->getThrowType(); if ($throwsType === null) { return \false; } return $throwsType->isSuperTypeOf(new ObjectType(UnhandledMatchError::class))->yes(); } } disableCheckMissingIterableValueType = $disableCheckMissingIterableValueType; $this->checkMissingIterableValueType = $checkMissingIterableValueType; $this->checkGenericClassInNonGenericObjectType = $checkGenericClassInNonGenericObjectType; $this->checkMissingCallableSignature = $checkMissingCallableSignature; $this->skipCheckGenericClasses = $skipCheckGenericClasses; } /** * @return Type[] */ public function getIterableTypesWithMissingValueTypehint(Type $type) : array { if (!$this->checkMissingIterableValueType) { if (!$this->disableCheckMissingIterableValueType) { return []; } } $iterablesWithMissingValueTypehint = []; TypeTraverser::map($type, function (Type $type, callable $traverse) use(&$iterablesWithMissingValueTypehint) : Type { if ($type instanceof TemplateType) { return $type; } if ($type instanceof AccessoryType) { return $type; } if ($type instanceof ConditionalType || $type instanceof ConditionalTypeForParameter) { $iterablesWithMissingValueTypehint = array_merge($iterablesWithMissingValueTypehint, $this->getIterableTypesWithMissingValueTypehint($type->getIf()), $this->getIterableTypesWithMissingValueTypehint($type->getElse())); return $type; } if ($type->isIterable()->yes()) { $iterableValue = $type->getIterableValueType(); if ($iterableValue instanceof MixedType && !$iterableValue->isExplicitMixed()) { $iterablesWithMissingValueTypehint[] = $type; } if ($type instanceof IntersectionType) { if ($type->isList()->yes()) { return $traverse($iterableValue); } return $type; } } return $traverse($type); }); return $iterablesWithMissingValueTypehint; } /** * @return array */ public function getNonGenericObjectTypesWithGenericClass(Type $type) : array { if (!$this->checkGenericClassInNonGenericObjectType) { return []; } $objectTypes = []; TypeTraverser::map($type, function (Type $type, callable $traverse) use(&$objectTypes) : Type { if ($type instanceof GenericObjectType || $type instanceof GenericStaticType) { $traverse($type); return $type; } if ($type instanceof TemplateType) { return $type; } if ($type instanceof ObjectType) { $classReflection = $type->getClassReflection(); if ($classReflection === null) { return $type; } if (in_array($classReflection->getName(), self::ITERABLE_GENERIC_CLASS_NAMES, \true)) { // checked by getIterableTypesWithMissingValueTypehint() already return $type; } if (in_array($classReflection->getName(), $this->skipCheckGenericClasses, \true)) { return $type; } if ($classReflection->isTrait()) { return $type; } if (!$classReflection->isGeneric()) { return $type; } $resolvedType = TemplateTypeHelper::resolveToBounds($type); if (!$resolvedType instanceof ObjectType) { throw new ShouldNotHappenException(); } $templateTypes = $classReflection->getTemplateTypeMap()->getTypes(); $templateTypesCount = count($templateTypes); $requiredTemplateTypesCount = count(array_filter($templateTypes, static function (Type $type) { return $type instanceof TemplateType && $type->getDefault() === null; })); if ($requiredTemplateTypesCount === 0) { return $type; } $templateTypesList = implode(', ', array_keys($templateTypes)); if ($requiredTemplateTypesCount !== $templateTypesCount) { $templateTypesList .= sprintf(' (%d-%d required)', $requiredTemplateTypesCount, $templateTypesCount); } $objectTypes[] = [sprintf('%s %s', strtolower($classReflection->getClassTypeDescription()), $classReflection->getDisplayName(\false)), $templateTypesList]; return $type; } return $traverse($type); }); return $objectTypes; } /** * @return Type[] */ public function getCallablesWithMissingSignature(Type $type) : array { if (!$this->checkMissingCallableSignature) { return []; } $result = []; TypeTraverser::map($type, static function (Type $type, callable $traverse) use(&$result) : Type { if ($type instanceof CallableType && $type->isCommonCallable() || $type instanceof ClosureType && $type->isCommonCallable() || $type instanceof ObjectType && $type->getClassName() === Closure::class) { $result[] = $type; } return $traverse($type); }); return $result; } } */ final class DateTimeInstantiationRule implements \PHPStan\Rules\Rule { public function getNodeType() : string { return New_::class; } /** * @param New_ $node */ public function processNode(Node $node, Scope $scope) : array { if (!$node->class instanceof Node\Name) { return []; } $lowerClassName = strtolower((string) $node->class); if (count($node->getArgs()) === 0 || !in_array($lowerClassName, ['datetime', 'datetimeimmutable'], \true)) { return []; } $arg = $scope->getType($node->getArgs()[0]->value); $errors = []; foreach ($arg->getConstantStrings() as $constantString) { $dateString = $constantString->getValue(); try { new DateTime($dateString); } catch (Throwable $e) { // an exception is thrown for errors only but we want to catch warnings too } $lastErrors = DateTime::getLastErrors(); if ($lastErrors === \false) { continue; } foreach ($lastErrors['errors'] as $error) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Instantiating %s with %s produces an error: %s', $lowerClassName === 'datetime' ? 'DateTime' : 'DateTimeImmutable', $dateString, $error))->identifier(sprintf('new.%s', $lowerClassName === 'datetime' ? 'dateTime' : 'dateTimeImmutable'))->build(); } } return $errors; } } */ final class PrintRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Node\Expr\Print_::class; } public function processNode(Node $node, Scope $scope) : array { $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $node->expr, '', static function (Type $type) : bool { return !$type->toString() instanceof ErrorType; }); if (!$typeResult->getType() instanceof ErrorType && $typeResult->getType()->toString() instanceof ErrorType) { return [RuleErrorBuilder::message(sprintf('Parameter %s of print cannot be converted to string.', $typeResult->getType()->describe(VerbosityLevel::value())))->identifier('print.nonString')->line($node->expr->getStartLine())->build()]; } return []; } } */ final class UnsetCastRule implements Rule { /** * @var PhpVersion */ private $phpVersion; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function getNodeType() : string { return Node\Expr\Cast\Unset_::class; } public function processNode(Node $node, Scope $scope) : array { if ($this->phpVersion->supportsUnsetCast()) { return []; } return [RuleErrorBuilder::message('The (unset) cast is no longer supported in PHP 8.0 and later.')->identifier('cast.unset')->nonIgnorable()->build()]; } } */ final class InvalidCastRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(ReflectionProvider $reflectionProvider, RuleLevelHelper $ruleLevelHelper) { $this->reflectionProvider = $reflectionProvider; $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Node\Expr\Cast::class; } public function processNode(Node $node, Scope $scope) : array { $castTypeCallback = static function (Type $type) use($node) : ?array { if ($node instanceof Node\Expr\Cast\Int_) { return [$type->toInteger(), 'int']; } elseif ($node instanceof Node\Expr\Cast\Bool_) { return [$type->toBoolean(), 'bool']; } elseif ($node instanceof Node\Expr\Cast\Double) { return [$type->toFloat(), 'double']; } elseif ($node instanceof Node\Expr\Cast\String_) { return [$type->toString(), 'string']; } return null; }; $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $node->expr, '', static function (Type $type) use($castTypeCallback) : bool { $castResult = $castTypeCallback($type); if ($castResult === null) { return \true; } [$castType] = $castResult; return !$castType instanceof ErrorType; }); $type = $typeResult->getType(); if ($type instanceof ErrorType) { return []; } $castResult = $castTypeCallback($type); if ($castResult === null) { return []; } [$castType, $castIdentifier] = $castResult; if ($castType instanceof ErrorType) { $classReflection = $this->reflectionProvider->getClass(get_class($node)); $shortName = $classReflection->getNativeReflection()->getShortName(); $shortName = strtolower($shortName); if ($shortName === 'double') { $shortName = 'float'; } else { $shortName = substr($shortName, 0, -1); } return [RuleErrorBuilder::message(sprintf('Cannot cast %s to %s.', $scope->getType($node->expr)->describe(VerbosityLevel::value()), $shortName))->identifier(sprintf('cast.%s', $castIdentifier))->line($node->getStartLine())->build()]; } return []; } } */ final class InvalidPartOfEncapsedStringRule implements Rule { /** * @var ExprPrinter */ private $exprPrinter; /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(ExprPrinter $exprPrinter, RuleLevelHelper $ruleLevelHelper) { $this->exprPrinter = $exprPrinter; $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Node\Scalar\Encapsed::class; } public function processNode(Node $node, Scope $scope) : array { $messages = []; foreach ($node->parts as $part) { if ($part instanceof Node\Scalar\EncapsedStringPart) { continue; } $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $part, '', static function (Type $type) : bool { return !$type->toString() instanceof ErrorType; }); $partType = $typeResult->getType(); if ($partType instanceof ErrorType) { continue; } $stringPartType = $partType->toString(); if (!$stringPartType instanceof ErrorType) { continue; } $messages[] = RuleErrorBuilder::message(sprintf('Part %s (%s) of encapsed string cannot be cast to string.', $this->exprPrinter->printExpr($part), $partType->describe(VerbosityLevel::value())))->identifier('encapsedStringPart.nonString')->line($part->getStartLine())->build(); } return $messages; } } */ final class EchoRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Node\Stmt\Echo_::class; } public function processNode(Node $node, Scope $scope) : array { $messages = []; foreach ($node->exprs as $key => $expr) { $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $expr, '', static function (Type $type) : bool { return !$type->toString() instanceof ErrorType; }); if ($typeResult->getType() instanceof ErrorType || !$typeResult->getType()->toString() instanceof ErrorType) { continue; } $messages[] = RuleErrorBuilder::message(sprintf('Parameter #%d (%s) of echo cannot be converted to string.', $key + 1, $typeResult->getType()->describe(VerbosityLevel::value())))->identifier('echo.nonString')->line($expr->getStartLine())->build(); } return $messages; } } */ final class ImplodeParameterCastableToStringRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var ParameterCastableToStringCheck */ private $parameterCastableToStringCheck; public function __construct(ReflectionProvider $reflectionProvider, ParameterCastableToStringCheck $parameterCastableToStringCheck) { $this->reflectionProvider = $reflectionProvider; $this->parameterCastableToStringCheck = $parameterCastableToStringCheck; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } $functionReflection = $this->reflectionProvider->getFunction($node->name, $scope); $functionName = $functionReflection->getName(); if (!in_array($functionName, ['implode', 'join'], \true)) { return []; } $origArgs = $node->getArgs(); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $origArgs, $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants()); $normalizedFuncCall = ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $node); if ($normalizedFuncCall === null) { return []; } $normalizedArgs = $normalizedFuncCall->getArgs(); $errorMessage = 'Parameter %s of function %s expects array, %s given.'; if (count($normalizedArgs) === 1) { $argsToCheck = [0 => $normalizedArgs[0]]; } elseif (count($normalizedArgs) === 2) { $argsToCheck = [1 => $normalizedArgs[1]]; } else { return []; } $origNamedArgs = []; foreach ($origArgs as $arg) { if ($arg->unpack || $arg->name === null) { continue; } $origNamedArgs[$arg->name->toString()] = $arg; } $errors = []; foreach ($argsToCheck as $argIdx => $arg) { // implode has weird variants, so $array has to be fixed. It's especially weird with named arguments. if (array_key_exists('array', $origNamedArgs)) { $argName = '$array'; } elseif (array_key_exists('separator', $origNamedArgs) && count($origArgs) === 1) { $argName = '$separator'; } else { $argName = sprintf('#%d $array', $argIdx + 1); } $error = $this->parameterCastableToStringCheck->checkParameter($arg, $scope, $errorMessage, static function (Type $t) { return $t->toString(); }, $functionName, $argName); if ($error === null) { continue; } $errors[] = $error; } return $errors; } } */ final class ArrowFunctionAttributesRule implements Rule { /** * @var AttributesCheck */ private $attributesCheck; public function __construct(AttributesCheck $attributesCheck) { $this->attributesCheck = $attributesCheck; } public function getNodeType() : string { return Node\Expr\ArrowFunction::class; } public function processNode(Node $node, Scope $scope) : array { return $this->attributesCheck->check($scope, $node->attrGroups, Attribute::TARGET_FUNCTION, 'function'); } } */ final class UnusedClosureUsesRule implements Rule { /** * @var UnusedFunctionParametersCheck */ private $check; public function __construct(UnusedFunctionParametersCheck $check) { $this->check = $check; } public function getNodeType() : string { return Node\Expr\Closure::class; } public function processNode(Node $node, Scope $scope) : array { if (count($node->uses) === 0) { return []; } return $this->check->getUnusedParameters($scope, array_map(static function (Node\Expr\ClosureUse $use) : string { if (!is_string($use->var->name)) { throw new ShouldNotHappenException(); } return $use->var->name; }, $node->uses), $node->stmts, 'Anonymous function has an unused use $%s.', 'closure.unusedUse'); } } */ final class MissingFunctionParameterTypehintRule implements Rule { /** * @var MissingTypehintCheck */ private $missingTypehintCheck; /** * @var bool */ private $paramOut; public function __construct(MissingTypehintCheck $missingTypehintCheck, bool $paramOut) { $this->missingTypehintCheck = $missingTypehintCheck; $this->paramOut = $paramOut; } public function getNodeType() : string { return InFunctionNode::class; } public function processNode(Node $node, Scope $scope) : array { $functionReflection = $node->getFunctionReflection(); $messages = []; foreach ($functionReflection->getParameters() as $parameterReflection) { foreach ($this->checkFunctionParameter($functionReflection, sprintf('parameter $%s', $parameterReflection->getName()), $parameterReflection->getType()) as $parameterMessage) { $messages[] = $parameterMessage; } if ($parameterReflection->getClosureThisType() !== null) { foreach ($this->checkFunctionParameter($functionReflection, sprintf('@param-closure-this PHPDoc tag for parameter $%s', $parameterReflection->getName()), $parameterReflection->getClosureThisType()) as $parameterMessage) { $messages[] = $parameterMessage; } } if (!$this->paramOut) { continue; } if ($parameterReflection->getOutType() === null) { continue; } foreach ($this->checkFunctionParameter($functionReflection, sprintf('@param-out PHPDoc tag for parameter $%s', $parameterReflection->getName()), $parameterReflection->getOutType()) as $parameterMessage) { $messages[] = $parameterMessage; } } return $messages; } /** * @return list */ private function checkFunctionParameter(FunctionReflection $functionReflection, string $parameterMessage, Type $parameterType) : array { if ($parameterType instanceof MixedType && !$parameterType->isExplicitMixed()) { return [RuleErrorBuilder::message(sprintf('Function %s() has %s with no type specified.', $functionReflection->getName(), $parameterMessage))->identifier('missingType.parameter')->build()]; } $messages = []; foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($parameterType) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $messages[] = RuleErrorBuilder::message(sprintf('Function %s() has %s with no value type specified in iterable type %s.', $functionReflection->getName(), $parameterMessage, $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($parameterType) as [$name, $genericTypeNames]) { $messages[] = RuleErrorBuilder::message(sprintf('Function %s() has %s with generic %s but does not specify its types: %s', $functionReflection->getName(), $parameterMessage, $name, $genericTypeNames))->identifier('missingType.generics')->build(); } foreach ($this->missingTypehintCheck->getCallablesWithMissingSignature($parameterType) as $callableType) { $messages[] = RuleErrorBuilder::message(sprintf('Function %s() has %s with no signature specified for %s.', $functionReflection->getName(), $parameterMessage, $callableType->describe(VerbosityLevel::typeOnly())))->identifier('missingType.callable')->build(); } return $messages; } } */ final class CallToFunctionStatementWithoutSideEffectsRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; private const SIDE_EFFECT_FLIP_PARAMETERS = [ // functionName => [name, pos, testName] 'print_r' => ['return', 1, 'isTruthy'], 'var_export' => ['return', 1, 'isTruthy'], 'highlight_string' => ['return', 1, 'isTruthy'], ]; public const PHPSTAN_TESTING_FUNCTIONS = ['PHPStan\\dumpType', 'PHPStan\\dumpPhpDocType', 'PHPStan\\debugScope', 'PHPStan\\Testing\\assertType', 'PHPStan\\Testing\\assertNativeType', 'PHPStan\\Testing\\assertVariableCertainty']; public function __construct(ReflectionProvider $reflectionProvider) { $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return Node\Stmt\Expression::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->expr instanceof Node\Expr\FuncCall) { return []; } $funcCall = $node->expr; if (!$funcCall->name instanceof Node\Name) { return []; } if (!$this->reflectionProvider->hasFunction($funcCall->name, $scope)) { return []; } $function = $this->reflectionProvider->getFunction($funcCall->name, $scope); $functionName = $function->getName(); $functionHasSideEffects = !$function->hasSideEffects()->no(); if (in_array($functionName, self::PHPSTAN_TESTING_FUNCTIONS, \true)) { return []; } if (isset(self::SIDE_EFFECT_FLIP_PARAMETERS[$functionName])) { [$flipParameterName, $flipParameterPosition, $testName] = self::SIDE_EFFECT_FLIP_PARAMETERS[$functionName]; $sideEffectFlipped = \false; $hasNamedParameter = \false; $checker = ['isNotNull' => static function (Type $type) { return $type->isNull()->no(); }, 'isTruthy' => static function (Type $type) { return $type->toBoolean()->isTrue()->yes(); }][$testName]; foreach ($funcCall->getRawArgs() as $i => $arg) { if (!$arg instanceof Arg) { return []; } $isFlipParameter = \false; if ($arg->name !== null) { $hasNamedParameter = \true; if ($arg->name->name === $flipParameterName) { $isFlipParameter = \true; } } if (!$hasNamedParameter && $i === $flipParameterPosition) { $isFlipParameter = \true; } if ($isFlipParameter) { $sideEffectFlipped = $checker($scope->getType($arg->value)); break; } } if (!$sideEffectFlipped) { return []; } $functionHasSideEffects = \false; } if (!$functionHasSideEffects || $node->expr->isFirstClassCallable()) { if (!$node->expr->isFirstClassCallable()) { $throwsType = $function->getThrowType(); if ($throwsType !== null && !$throwsType->isVoid()->yes()) { return []; } } $functionResult = $scope->getType($funcCall); if ($functionResult instanceof NeverType && $functionResult->isExplicit()) { return []; } return [RuleErrorBuilder::message(sprintf('Call to function %s() on a separate line has no effect.', $function->getName()))->identifier('function.resultUnused')->build()]; } return []; } } */ final class CallToNonExistentFunctionRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var bool */ private $checkFunctionNameCase; public function __construct(ReflectionProvider $reflectionProvider, bool $checkFunctionNameCase) { $this->reflectionProvider = $reflectionProvider; $this->checkFunctionNameCase = $checkFunctionNameCase; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { if ($scope->isInFunctionExists($node->name->toString())) { return []; } return [RuleErrorBuilder::message(sprintf('Function %s not found.', (string) $node->name))->identifier('function.notFound')->discoveringSymbolsTip()->build()]; } $function = $this->reflectionProvider->getFunction($node->name, $scope); $name = (string) $node->name; if ($this->checkFunctionNameCase) { /** @var string $calledFunctionName */ $calledFunctionName = $this->reflectionProvider->resolveFunctionName($node->name, $scope); if (strtolower($function->getName()) === strtolower($calledFunctionName) && $function->getName() !== $calledFunctionName) { return [RuleErrorBuilder::message(sprintf('Call to function %s() with incorrect case: %s', $function->getName(), $name))->identifier('function.nameCase')->build()]; } } return []; } } */ final class IncompatibleArrowFunctionDefaultParameterTypeRule implements Rule { public function getNodeType() : string { return InArrowFunctionNode::class; } public function processNode(Node $node, Scope $scope) : array { $parameters = $node->getClosureType()->getParameters(); $errors = []; foreach ($node->getOriginalNode()->getParams() as $paramI => $param) { if ($param->default === null) { continue; } if ($param->var instanceof Node\Expr\Error || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } $defaultValueType = $scope->getType($param->default); $parameterType = $parameters[$paramI]->getType(); $parameterType = TemplateTypeHelper::resolveToBounds($parameterType); $accepts = $parameterType->acceptsWithReason($defaultValueType, \true); if ($accepts->yes()) { continue; } $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($parameterType, $defaultValueType); $errors[] = RuleErrorBuilder::message(sprintf('Default value of the parameter #%d $%s (%s) of anonymous function is incompatible with type %s.', $paramI + 1, $param->var->name, $defaultValueType->describe($verbosityLevel), $parameterType->describe($verbosityLevel)))->line($param->getStartLine())->identifier('parameter.defaultValue')->acceptsReasonsTip($accepts->reasons)->build(); } return $errors; } } */ final class DefineParametersRule implements Rule { /** * @var PhpVersion */ private $phpVersion; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if ($this->phpVersion->supportsCaseInsensitiveConstantNames()) { return []; } $name = strtolower((string) $node->name); if ($name !== 'define') { return []; } $args = $node->getArgs(); $argsCount = count($args); // Expects 2 or 3, 1 arg is caught by CallToFunctionParametersRule if ($argsCount < 3) { return []; } return [RuleErrorBuilder::message('Argument #3 ($case_insensitive) is ignored since declaration of case-insensitive constants is no longer supported.')->line($node->getStartLine())->identifier('argument.unused')->build()]; } } */ final class UselessFunctionReturnValueRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; private const USELESS_FUNCTIONS = ['var_export' => 'null', 'print_r' => 'true', 'highlight_string' => 'true']; public function __construct(ReflectionProvider $reflectionProvider) { $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $funcCall, Scope $scope) : array { if (!$funcCall->name instanceof Node\Name || $scope->isInFirstLevelStatement()) { return []; } if (!$this->reflectionProvider->hasFunction($funcCall->name, $scope)) { return []; } $functionReflection = $this->reflectionProvider->getFunction($funcCall->name, $scope); if (!array_key_exists($functionReflection->getName(), self::USELESS_FUNCTIONS)) { return []; } $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $funcCall->getArgs(), $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants()); $reorderedFuncCall = ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $funcCall); if ($reorderedFuncCall === null) { return []; } $reorderedArgs = $reorderedFuncCall->getArgs(); if (count($reorderedArgs) === 1 || count($reorderedArgs) >= 2 && $scope->getType($reorderedArgs[1]->value)->isFalse()->yes()) { return [RuleErrorBuilder::message(sprintf('Return value of function %s() is always %s and the result is printed instead of being returned. Pass in true as parameter #%d $%s to return the output instead.', $functionReflection->getName(), self::USELESS_FUNCTIONS[$functionReflection->getName()], 2, $parametersAcceptor->getParameters()[1]->getName()))->identifier('function.uselessReturnValue')->line($funcCall->getStartLine())->build()]; } return []; } } */ final class MissingFunctionReturnTypehintRule implements Rule { /** * @var MissingTypehintCheck */ private $missingTypehintCheck; public function __construct(MissingTypehintCheck $missingTypehintCheck) { $this->missingTypehintCheck = $missingTypehintCheck; } public function getNodeType() : string { return InFunctionNode::class; } public function processNode(Node $node, Scope $scope) : array { $functionReflection = $node->getFunctionReflection(); $returnType = $functionReflection->getReturnType(); if ($returnType instanceof MixedType && !$returnType->isExplicitMixed()) { return [RuleErrorBuilder::message(sprintf('Function %s() has no return type specified.', $functionReflection->getName()))->identifier('missingType.return')->build()]; } $messages = []; foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($returnType) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $messages[] = RuleErrorBuilder::message(sprintf('Function %s() return type has no value type specified in iterable type %s.', $functionReflection->getName(), $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($returnType) as [$name, $genericTypeNames]) { $messages[] = RuleErrorBuilder::message(sprintf('Function %s() return type with generic %s does not specify its types: %s', $functionReflection->getName(), $name, $genericTypeNames))->identifier('missingType.generics')->build(); } foreach ($this->missingTypehintCheck->getCallablesWithMissingSignature($returnType) as $callableType) { $messages[] = RuleErrorBuilder::message(sprintf('Function %s() return type has no signature specified for %s.', $functionReflection->getName(), $callableType->describe(VerbosityLevel::typeOnly())))->identifier('missingType.callable')->build(); } return $messages; } } */ final class ParamAttributesRule implements Rule { /** * @var AttributesCheck */ private $attributesCheck; public function __construct(AttributesCheck $attributesCheck) { $this->attributesCheck = $attributesCheck; } public function getNodeType() : string { return Node\Param::class; } public function processNode(Node $node, Scope $scope) : array { $targetName = 'parameter'; $targetType = Attribute::TARGET_PARAMETER; if ($node->flags !== 0) { $targetName = 'parameter or property'; $targetType |= Attribute::TARGET_PROPERTY; } return $this->attributesCheck->check($scope, $node->attrGroups, $targetType, $targetName); } } */ final class ExistingClassesInArrowFunctionTypehintsRule implements Rule { /** * @var FunctionDefinitionCheck */ private $check; /** * @var PhpVersion */ private $phpVersion; public function __construct(FunctionDefinitionCheck $check, PhpVersion $phpVersion) { $this->check = $check; $this->phpVersion = $phpVersion; } public function getNodeType() : string { return Node\Expr\ArrowFunction::class; } public function processNode(Node $node, Scope $scope) : array { $messages = []; if ($node->returnType !== null && !$this->phpVersion->supportsNeverReturnTypeInArrowFunction()) { $returnType = ParserNodeTypeToPHPStanType::resolve($node->returnType, $scope->isInClass() ? $scope->getClassReflection() : null); if ($returnType instanceof NonAcceptingNeverType) { $messages[] = RuleErrorBuilder::message('Never return type in arrow function is supported only on PHP 8.2 and later.')->identifier('return.neverTypeNotSupported')->nonIgnorable()->build(); } } return array_merge($messages, $this->check->checkAnonymousFunction($scope, $node->getParams(), $node->getReturnType(), 'Parameter $%s of anonymous function has invalid type %s.', 'Anonymous function has invalid return type %s.', 'Anonymous function uses native union types but they\'re supported only on PHP 8.0 and later.', 'Parameter $%s of anonymous function has unresolvable native type.', 'Anonymous function has unresolvable native return type.')); } } phpVersion = $phpVersion; } public function getPrintfPlaceholdersCount(string $format) : int { return $this->getPlaceholdersCount('(?:[bs%s]|l?[cdeEgfFGouxX])', $format); } public function getScanfPlaceholdersCount(string $format) : int { return $this->getPlaceholdersCount('(?:[cdDeEfinosuxX%s]|\\[[^\\]]+\\])', $format); } private function getPlaceholdersCount(string $specifiersPattern, string $format) : int { $addSpecifier = ''; if ($this->phpVersion->supportsHhPrintfSpecifier()) { $addSpecifier .= 'hH'; } $specifiers = sprintf($specifiersPattern, $addSpecifier); $pattern = '~(?%*)%(?:(?\\d+)\\$)?[-+]?(?:[ 0]|(?:\'[^%]))?(?\\*)?-?\\d*(?:\\.(?:\\d+|(?\\*))?)?' . $specifiers . '~'; $matches = Strings::matchAll($format, $pattern, PREG_SET_ORDER); if (count($matches) === 0) { return 0; } $placeholders = array_filter($matches, static function (array $match) : bool { return strlen($match['before']) % 2 === 0; }); if (count($placeholders) === 0) { return 0; } $maxPositionedNumber = 0; $maxOrdinaryNumber = 0; foreach ($placeholders as $placeholder) { if (isset($placeholder['width']) && $placeholder['width'] !== '') { $maxOrdinaryNumber++; } if (isset($placeholder['precision']) && $placeholder['precision'] !== '') { $maxOrdinaryNumber++; } if (isset($placeholder['position']) && $placeholder['position'] !== '') { $maxPositionedNumber = max((int) $placeholder['position'], $maxPositionedNumber); } else { $maxOrdinaryNumber++; } } return max($maxPositionedNumber, $maxOrdinaryNumber); } } */ final class ParameterCastableToStringRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var ParameterCastableToStringCheck */ private $parameterCastableToStringCheck; public function __construct(ReflectionProvider $reflectionProvider, ParameterCastableToStringCheck $parameterCastableToStringCheck) { $this->reflectionProvider = $reflectionProvider; $this->parameterCastableToStringCheck = $parameterCastableToStringCheck; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } $functionReflection = $this->reflectionProvider->getFunction($node->name, $scope); $functionName = $functionReflection->getName(); $checkAllArgsFunctions = ['array_intersect', 'array_intersect_assoc', 'array_diff', 'array_diff_assoc']; $checkFirstArgFunctions = ['array_combine', 'natcasesort', 'natsort', 'array_count_values', 'array_fill_keys']; if (!in_array($functionName, $checkAllArgsFunctions, \true) && !in_array($functionName, $checkFirstArgFunctions, \true)) { return []; } $origArgs = $node->getArgs(); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $origArgs, $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants()); $errorMessage = 'Parameter %s of function %s expects an array of values castable to string, %s given.'; $functionParameters = $parametersAcceptor->getParameters(); if (in_array($functionName, $checkAllArgsFunctions, \true)) { $argsToCheck = $origArgs; } elseif (in_array($functionName, $checkFirstArgFunctions, \true)) { $normalizedFuncCall = ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $node); if ($normalizedFuncCall === null) { return []; } $normalizedArgs = $normalizedFuncCall->getArgs(); if (!array_key_exists(0, $normalizedArgs)) { return []; } $argsToCheck = [0 => $normalizedArgs[0]]; } else { return []; } $errors = []; foreach ($argsToCheck as $argIdx => $arg) { $error = $this->parameterCastableToStringCheck->checkParameter($arg, $scope, $errorMessage, static function (Type $t) { return $t->toString(); }, $functionName, $this->parameterCastableToStringCheck->getParameterName($arg, $argIdx, $functionParameters[$argIdx] ?? null)); if ($error === null) { continue; } $errors[] = $error; } return $errors; } } */ final class InnerFunctionRule implements Rule { public function getNodeType() : string { return Function_::class; } public function processNode(Node $node, Scope $scope) : array { if ($scope->getFunction() === null) { return []; } return [RuleErrorBuilder::message('Inner named functions are not supported by PHPStan. Consider refactoring to an anonymous function, class method, or a top-level-defined function. See issue #165 (https://github.com/phpstan/phpstan/issues/165) for more details.')->identifier('function.inner')->build()]; } } */ final class SortParameterCastableToStringRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var ParameterCastableToStringCheck */ private $parameterCastableToStringCheck; public function __construct(ReflectionProvider $reflectionProvider, ParameterCastableToStringCheck $parameterCastableToStringCheck) { $this->reflectionProvider = $reflectionProvider; $this->parameterCastableToStringCheck = $parameterCastableToStringCheck; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } $functionReflection = $this->reflectionProvider->getFunction($node->name, $scope); $functionName = $functionReflection->getName(); if (!in_array($functionName, ['array_unique', 'sort', 'rsort', 'asort', 'arsort'], \true)) { return []; } $origArgs = $node->getArgs(); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $origArgs, $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants()); $functionParameters = $parametersAcceptor->getParameters(); $normalizedFuncCall = ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $node); if ($normalizedFuncCall === null) { return []; } $normalizedArgs = $normalizedFuncCall->getArgs(); if (!array_key_exists(0, $normalizedArgs)) { return []; } $argsToCheck = [0 => $normalizedArgs[0]]; $flags = null; if (array_key_exists(1, $normalizedArgs)) { $flags = $scope->getType($normalizedArgs[1]->value); } elseif (array_key_exists(1, $functionParameters)) { $flags = $functionParameters[1]->getDefaultValue(); } if ($flags === null || $flags->equals(new ConstantIntegerType(SORT_REGULAR))) { return []; } $constantIntFlags = TypeUtils::getConstantIntegers($flags); $mustBeCastableToString = $mustBeCastableToFloat = $constantIntFlags === []; foreach ($constantIntFlags as $flag) { if ($flag->getValue() === SORT_NUMERIC) { $mustBeCastableToFloat = \true; } elseif (in_array($flag->getValue() & ~SORT_FLAG_CASE, [SORT_STRING, SORT_LOCALE_STRING, SORT_NATURAL], \true)) { $mustBeCastableToString = \true; } } if ($mustBeCastableToString && !$mustBeCastableToFloat) { $errorMessage = 'Parameter %s of function %s expects an array of values castable to string, %s given.'; $castFn = static function (Type $t) { return $t->toString(); }; } elseif ($mustBeCastableToString) { $errorMessage = 'Parameter %s of function %s expects an array of values castable to string and float, %s given.'; $castFn = static function (Type $t) : Type { $float = $t->toFloat(); return $float instanceof ErrorType ? $float : $t->toString(); }; } elseif ($mustBeCastableToFloat) { $errorMessage = 'Parameter %s of function %s expects an array of values castable to float, %s given.'; $castFn = static function (Type $t) { return $t->toFloat(); }; } else { return []; } $errors = []; foreach ($argsToCheck as $argIdx => $arg) { $error = $this->parameterCastableToStringCheck->checkParameter($arg, $scope, $errorMessage, $castFn, $functionName, $this->parameterCastableToStringCheck->getParameterName($arg, $argIdx, $functionParameters[$argIdx] ?? null)); if ($error === null) { continue; } $errors[] = $error; } return $errors; } } */ final class ReturnTypeRule implements Rule { /** * @var FunctionReturnTypeCheck */ private $returnTypeCheck; public function __construct(FunctionReturnTypeCheck $returnTypeCheck) { $this->returnTypeCheck = $returnTypeCheck; } public function getNodeType() : string { return Return_::class; } public function processNode(Node $node, Scope $scope) : array { if ($scope->getFunction() === null) { return []; } if ($scope->isInAnonymousFunction()) { return []; } $function = $scope->getFunction(); if ($function instanceof MethodReflection) { return []; } return $this->returnTypeCheck->checkReturnType($scope, $function->getReturnType(), $node->expr, $node, sprintf('Function %s() should return %%s but empty return statement found.', $function->getName()), sprintf('Function %s() with return type void returns %%s but should not return anything.', $function->getName()), sprintf('Function %s() should return %%s but returns %%s.', $function->getName()), sprintf('Function %s() should never return but return statement found.', $function->getName()), $function->isGenerator()); } } */ final class InvalidLexicalVariablesInClosureUseRule implements Rule { public function getNodeType() : string { return Node\Expr\Closure::class; } /** * @param Node\Expr\Closure $node */ public function processNode(Node $node, Scope $scope) : array { $errors = []; $params = array_filter(array_map(static function (Node\Param $param) { if (!$param->var instanceof Node\Expr\Variable) { return \false; } if (!is_string($param->var->name)) { return \false; } return $param->var->name; }, $node->getParams()), static function ($name) { return $name !== \false; }); foreach ($node->uses as $use) { if (!is_string($use->var->name)) { continue; } $var = $use->var->name; if ($var === 'this') { $errors[] = RuleErrorBuilder::message('Cannot use $this as lexical variable.')->line($use->getStartLine())->identifier('closure.useThis')->nonIgnorable()->build(); continue; } if (in_array($var, Scope::SUPERGLOBAL_VARIABLES, \true)) { $errors[] = RuleErrorBuilder::message(sprintf('Cannot use superglobal variable $%s as lexical variable.', $var))->line($use->getStartLine())->identifier('closure.useSuperGlobal')->nonIgnorable()->build(); continue; } if (!in_array($var, $params, \true)) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('Cannot use lexical variable $%s since a parameter with the same name already exists.', $var))->line($use->getStartLine())->identifier('closure.useDuplicate')->nonIgnorable()->build(); } return $errors; } } */ final class ArrowFunctionReturnNullsafeByRefRule implements Rule { /** * @var NullsafeCheck */ private $nullsafeCheck; public function __construct(NullsafeCheck $nullsafeCheck) { $this->nullsafeCheck = $nullsafeCheck; } public function getNodeType() : string { return Node\Expr\ArrowFunction::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->byRef) { return []; } if (!$this->nullsafeCheck->containsNullSafe($node->expr)) { return []; } return [RuleErrorBuilder::message('Nullsafe cannot be returned by reference.')->nonIgnorable()->identifier('nullsafe.byRef')->build()]; } } */ final class CallToFunctionParametersRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var FunctionCallParametersCheck */ private $check; public function __construct(ReflectionProvider $reflectionProvider, FunctionCallParametersCheck $check) { $this->reflectionProvider = $reflectionProvider; $this->check = $check; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } $function = $this->reflectionProvider->getFunction($node->name, $scope); $functionName = SprintfHelper::escapeFormatString($function->getName()); return $this->check->check(ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $function->getVariants(), $function->getNamedArgumentsVariants()), $scope, $function->isBuiltin(), $node, ['Function ' . $functionName . ' invoked with %d parameter, %d required.', 'Function ' . $functionName . ' invoked with %d parameters, %d required.', 'Function ' . $functionName . ' invoked with %d parameter, at least %d required.', 'Function ' . $functionName . ' invoked with %d parameters, at least %d required.', 'Function ' . $functionName . ' invoked with %d parameter, %d-%d required.', 'Function ' . $functionName . ' invoked with %d parameters, %d-%d required.', 'Parameter %s of function ' . $functionName . ' expects %s, %s given.', 'Result of function ' . $functionName . ' (void) is used.', 'Parameter %s of function ' . $functionName . ' is passed by reference, so it expects variables only.', 'Unable to resolve the template type %s in call to function ' . $functionName, 'Missing parameter $%s in call to function ' . $functionName . '.', 'Unknown parameter $%s in call to function ' . $functionName . '.', 'Return type of call to function ' . $functionName . ' contains unresolvable type.', 'Parameter %s of function ' . $functionName . ' contains unresolvable type.', 'Function ' . $functionName . ' invoked with %s, but it\'s not allowed because of @no-named-arguments.'], 'function', $function->acceptsNamedArguments()); } } */ final class ClosureReturnTypeRule implements Rule { /** * @var FunctionReturnTypeCheck */ private $returnTypeCheck; public function __construct(FunctionReturnTypeCheck $returnTypeCheck) { $this->returnTypeCheck = $returnTypeCheck; } public function getNodeType() : string { return ClosureReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$scope->isInAnonymousFunction()) { return []; } /** @var Type $returnType */ $returnType = $scope->getAnonymousFunctionReturnType(); $containsNull = TypeCombinator::containsNull($returnType); $hasNativeTypehint = $node->getClosureExpr()->returnType !== null; $messages = []; foreach ($node->getReturnStatements() as $returnStatement) { $returnNode = $returnStatement->getReturnNode(); $returnExpr = $returnNode->expr; if ($returnExpr === null && $containsNull && !$hasNativeTypehint) { $returnExpr = new Node\Expr\ConstFetch(new Node\Name\FullyQualified('null')); } $returnMessages = $this->returnTypeCheck->checkReturnType($returnStatement->getScope(), $returnType, $returnExpr, $returnNode, 'Anonymous function should return %s but empty return statement found.', 'Anonymous function with return type void returns %s but should not return anything.', 'Anonymous function should return %s but returns %s.', 'Anonymous function should never return but return statement found.', $node->isGenerator()); foreach ($returnMessages as $returnMessage) { $messages[] = $returnMessage; } } return $messages; } } */ final class CallCallablesRule implements Rule { /** * @var FunctionCallParametersCheck */ private $check; /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var bool */ private $reportMaybes; public function __construct(FunctionCallParametersCheck $check, RuleLevelHelper $ruleLevelHelper, bool $reportMaybes) { $this->check = $check; $this->ruleLevelHelper = $ruleLevelHelper; $this->reportMaybes = $reportMaybes; } public function getNodeType() : string { return Node\Expr\FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Expr) { return []; } $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $node->name), 'Invoking callable on an unknown class %s.', static function (Type $type) : bool { return $type->isCallable()->yes(); }); $type = $typeResult->getType(); if ($type instanceof ErrorType) { return $typeResult->getUnknownClassErrors(); } $isCallable = $type->isCallable(); if ($isCallable->no()) { return [RuleErrorBuilder::message(sprintf('Trying to invoke %s but it\'s not a callable.', $type->describe(VerbosityLevel::value())))->identifier('callable.nonCallable')->build()]; } if ($this->reportMaybes && $isCallable->maybe()) { return [RuleErrorBuilder::message(sprintf('Trying to invoke %s but it might not be a callable.', $type->describe(VerbosityLevel::value())))->identifier('callable.nonCallable')->build()]; } $parametersAcceptors = $type->getCallableParametersAcceptors($scope); $messages = []; $acceptsNamedArguments = \true; foreach ($parametersAcceptors as $parametersAcceptor) { $acceptsNamedArguments = $acceptsNamedArguments && $parametersAcceptor->acceptsNamedArguments(); } if (count($parametersAcceptors) === 1 && $parametersAcceptors[0] instanceof InaccessibleMethod) { $method = $parametersAcceptors[0]->getMethod(); $messages[] = RuleErrorBuilder::message(sprintf('Call to %s method %s() of class %s.', $method->isPrivate() ? 'private' : 'protected', $method->getName(), $method->getDeclaringClass()->getDisplayName()))->identifier('callable.inaccessibleMethod')->build(); } $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $parametersAcceptors, null); if ($type instanceof ClosureType) { $callableDescription = 'closure'; } else { $callableDescription = sprintf('callable %s', SprintfHelper::escapeFormatString($type->describe(VerbosityLevel::value()))); } return array_merge($messages, $this->check->check($parametersAcceptor, $scope, \false, $node, [ucfirst($callableDescription) . ' invoked with %d parameter, %d required.', ucfirst($callableDescription) . ' invoked with %d parameters, %d required.', ucfirst($callableDescription) . ' invoked with %d parameter, at least %d required.', ucfirst($callableDescription) . ' invoked with %d parameters, at least %d required.', ucfirst($callableDescription) . ' invoked with %d parameter, %d-%d required.', ucfirst($callableDescription) . ' invoked with %d parameters, %d-%d required.', 'Parameter %s of ' . $callableDescription . ' expects %s, %s given.', 'Result of ' . $callableDescription . ' (void) is used.', 'Parameter %s of ' . $callableDescription . ' is passed by reference, so it expects variables only.', 'Unable to resolve the template type %s in call to ' . $callableDescription, 'Missing parameter $%s in call to ' . $callableDescription . '.', 'Unknown parameter $%s in call to ' . $callableDescription . '.', 'Return type of call to ' . $callableDescription . ' contains unresolvable type.', 'Parameter %s of ' . $callableDescription . ' contains unresolvable type.', ucfirst($callableDescription) . ' invoked with %s, but it\'s not allowed because of @no-named-arguments.'], 'callable', $acceptsNamedArguments)); } } */ final class ReturnNullsafeByRefRule implements Rule { /** * @var NullsafeCheck */ private $nullsafeCheck; public function __construct(NullsafeCheck $nullsafeCheck) { $this->nullsafeCheck = $nullsafeCheck; } public function getNodeType() : string { return ReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->returnsByRef()) { return []; } $errors = []; foreach ($node->getReturnStatements() as $returnStatement) { $returnNode = $returnStatement->getReturnNode(); if ($returnNode->expr === null) { continue; } if (!$this->nullsafeCheck->containsNullSafe($returnNode->expr)) { continue; } $errors[] = RuleErrorBuilder::message('Nullsafe cannot be returned by reference.')->line($returnNode->getStartLine())->identifier('nullsafe.byRef')->nonIgnorable()->build(); } return $errors; } } */ final class ExistingClassesInTypehintsRule implements Rule { /** * @var FunctionDefinitionCheck */ private $check; public function __construct(FunctionDefinitionCheck $check) { $this->check = $check; } public function getNodeType() : string { return InFunctionNode::class; } public function processNode(Node $node, Scope $scope) : array { $functionName = SprintfHelper::escapeFormatString($node->getFunctionReflection()->getName()); return $this->check->checkFunction($node->getOriginalNode(), $node->getFunctionReflection(), sprintf('Parameter $%%s of function %s() has invalid type %%s.', $functionName), sprintf('Function %s() has invalid return type %%s.', $functionName), sprintf('Function %s() uses native union types but they\'re supported only on PHP 8.0 and later.', $functionName), sprintf('Template type %%s of function %s() is not referenced in a parameter.', $functionName), sprintf('Parameter $%%s of function %s() has unresolvable native type.', $functionName), sprintf('Function %s() has unresolvable native return type.', $functionName)); } } */ final class ClosureAttributesRule implements Rule { /** * @var AttributesCheck */ private $attributesCheck; public function __construct(AttributesCheck $attributesCheck) { $this->attributesCheck = $attributesCheck; } public function getNodeType() : string { return Node\Expr\Closure::class; } public function processNode(Node $node, Scope $scope) : array { return $this->attributesCheck->check($scope, $node->attrGroups, Attribute::TARGET_FUNCTION, 'function'); } } */ final class ArrowFunctionReturnTypeRule implements Rule { /** * @var FunctionReturnTypeCheck */ private $returnTypeCheck; public function __construct(FunctionReturnTypeCheck $returnTypeCheck) { $this->returnTypeCheck = $returnTypeCheck; } public function getNodeType() : string { return InArrowFunctionNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$scope->isInAnonymousFunction()) { throw new ShouldNotHappenException(); } /** @var Type $returnType */ $returnType = $scope->getAnonymousFunctionReturnType(); $generatorType = new ObjectType(Generator::class); $originalNode = $node->getOriginalNode(); $isVoidSuperType = $returnType->isVoid(); if ($originalNode->returnType === null && $isVoidSuperType->yes()) { return []; } $exprType = $scope->getType($originalNode->expr); if ($returnType instanceof NeverType && $returnType->isExplicit() && $exprType instanceof NeverType && $exprType->isExplicit()) { return []; } return $this->returnTypeCheck->checkReturnType($scope, $returnType, $originalNode->expr, $originalNode->expr, 'Anonymous function should return %s but empty return statement found.', 'Anonymous function with return type void returns %s but should not return anything.', 'Anonymous function should return %s but returns %s.', 'Anonymous function should never return but return statement found.', $generatorType->isSuperTypeOf($returnType)->yes()); } } */ final class IncompatibleClosureDefaultParameterTypeRule implements Rule { public function getNodeType() : string { return InClosureNode::class; } public function processNode(Node $node, Scope $scope) : array { $parameters = $node->getClosureType()->getParameters(); $errors = []; foreach ($node->getOriginalNode()->getParams() as $paramI => $param) { if ($param->default === null) { continue; } if ($param->var instanceof Node\Expr\Error || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } $defaultValueType = $scope->getType($param->default); $parameterType = $parameters[$paramI]->getType(); $parameterType = TemplateTypeHelper::resolveToBounds($parameterType); $accepts = $parameterType->acceptsWithReason($defaultValueType, \true); if ($accepts->yes()) { continue; } $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($parameterType, $defaultValueType); $errors[] = RuleErrorBuilder::message(sprintf('Default value of the parameter #%d $%s (%s) of anonymous function is incompatible with type %s.', $paramI + 1, $param->var->name, $defaultValueType->describe($verbosityLevel), $parameterType->describe($verbosityLevel)))->line($param->getStartLine())->identifier('parameter.defaultValue')->acceptsReasonsTip($accepts->reasons)->build(); } return $errors; } } */ final class DuplicateFunctionDeclarationRule implements Rule { /** * @var Reflector */ private $reflector; /** * @var RelativePathHelper */ private $relativePathHelper; public function __construct(Reflector $reflector, RelativePathHelper $relativePathHelper) { $this->reflector = $reflector; $this->relativePathHelper = $relativePathHelper; } public function getNodeType() : string { return InFunctionNode::class; } public function processNode(Node $node, Scope $scope) : array { $thisFunction = $node->getFunctionReflection(); $allFunctions = $this->reflector->reflectAllFunctions(); $filteredFunctions = []; foreach ($allFunctions as $reflectionFunction) { if ($reflectionFunction->getName() !== $thisFunction->getName()) { continue; } $filteredFunctions[] = $reflectionFunction; } if (count($filteredFunctions) < 2) { return []; } return [RuleErrorBuilder::message(sprintf("Function %s declared multiple times:\n%s", $thisFunction->getName(), implode("\n", array_map(function (ReflectionFunction $function) { return sprintf('- %s:%d', $this->relativePathHelper->getRelativePath($function->getFileName() ?? 'unknown'), $function->getStartLine()); }, $filteredFunctions))))->identifier('function.duplicate')->build()]; } } */ final class ArrayValuesRule implements Rule { /** * @readonly * @var ReflectionProvider */ private $reflectionProvider; /** * @readonly * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(ReflectionProvider $reflectionProvider, bool $treatPhpDocTypesAsCertain, bool $treatPhpDocTypesAsCertainTip) { $this->reflectionProvider = $reflectionProvider; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (AccessoryArrayListType::isListTypeEnabled() === \false) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } $functionReflection = $this->reflectionProvider->getFunction($node->name, $scope); if ($functionReflection->getName() !== 'array_values') { return []; } $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants()); $normalizedFuncCall = ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $node); if ($normalizedFuncCall === null) { return []; } $args = $normalizedFuncCall->getArgs(); if (count($args) === 0) { return []; } if ($this->treatPhpDocTypesAsCertain) { $arrayType = $scope->getType($args[0]->value); } else { $arrayType = $scope->getNativeType($args[0]->value); } if ($arrayType->isIterableAtLeastOnce()->no()) { $message = 'Parameter #1 $array (%s) to function array_values is empty, call has no effect.'; $errorBuilder = RuleErrorBuilder::message(sprintf($message, $arrayType->describe(VerbosityLevel::value())))->identifier('arrayValues.empty'); if ($this->treatPhpDocTypesAsCertain) { $nativeArrayType = $scope->getNativeType($args[0]->value); if ($this->treatPhpDocTypesAsCertainTip && !$nativeArrayType->isIterableAtLeastOnce()->no()) { $errorBuilder->treatPhpDocTypesAsCertainTip(); } } return [$errorBuilder->build()]; } if ($arrayType->isList()->yes()) { $message = 'Parameter #1 $array (%s) of array_values is already a list, call has no effect.'; $errorBuilder = RuleErrorBuilder::message(sprintf($message, $arrayType->describe(VerbosityLevel::value())))->identifier('arrayValues.list'); if ($this->treatPhpDocTypesAsCertain) { $nativeArrayType = $scope->getNativeType($args[0]->value); if ($this->treatPhpDocTypesAsCertainTip && !$nativeArrayType->isList()->yes()) { $errorBuilder->treatPhpDocTypesAsCertainTip(); } } return [$errorBuilder->build()]; } return []; } } */ final class ImplodeFunctionRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var bool */ private $disabled; public function __construct(ReflectionProvider $reflectionProvider, RuleLevelHelper $ruleLevelHelper, bool $disabled) { $this->reflectionProvider = $reflectionProvider; $this->ruleLevelHelper = $ruleLevelHelper; $this->disabled = $disabled; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if ($this->disabled) { return []; } if (!$node->name instanceof Node\Name) { return []; } $functionName = $this->reflectionProvider->resolveFunctionName($node->name, $scope); if (!in_array($functionName, ['implode', 'join'], \true)) { return []; } $args = $node->getArgs(); if (count($args) === 1) { $arrayArg = $args[0]->value; $paramNo = 1; } elseif (count($args) === 2) { $arrayArg = $args[1]->value; $paramNo = 2; } else { return []; } $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $arrayArg, '', static function (Type $type) : bool { return !$type->getIterableValueType()->toString() instanceof ErrorType; }); if ($typeResult->getType() instanceof ErrorType || !$typeResult->getType()->getIterableValueType()->toString() instanceof ErrorType) { return []; } return [RuleErrorBuilder::message(sprintf('Parameter #%d $array of function %s expects array, %s given.', $paramNo, $functionName, $typeResult->getType()->describe(VerbosityLevel::typeOnly())))->identifier('argument.type')->build()]; } } */ final class RedefinedParametersRule implements Rule { public function getNodeType() : string { return Node\FunctionLike::class; } public function processNode(Node $node, Scope $scope) : array { $params = $node->getParams(); if (count($params) <= 1) { return []; } $vars = []; $errors = []; foreach ($params as $param) { if (!$param->var instanceof Node\Expr\Variable) { continue; } if (!is_string($param->var->name)) { continue; } $var = $param->var->name; if (!isset($vars[$var])) { $vars[$var] = \true; continue; } $errors[] = RuleErrorBuilder::message(sprintf('Redefinition of parameter $%s.', $var))->identifier('parameter.duplicate')->nonIgnorable()->build(); } return $errors; } } */ final class CallUserFuncRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var FunctionCallParametersCheck */ private $check; public function __construct(ReflectionProvider $reflectionProvider, FunctionCallParametersCheck $check) { $this->reflectionProvider = $reflectionProvider; $this->check = $check; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (count($node->getArgs()) === 0) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } $functionReflection = $this->reflectionProvider->getFunction($node->name, $scope); if ($functionReflection->getName() !== 'call_user_func') { return []; } $result = ArgumentsNormalizer::reorderCallUserFuncArguments($node, $scope); if ($result === null) { return []; } [$parametersAcceptor, $funcCall, $acceptsNamedArguments] = $result; $callableDescription = 'callable passed to call_user_func()'; return $this->check->check($parametersAcceptor, $scope, \false, $funcCall, [ucfirst($callableDescription) . ' invoked with %d parameter, %d required.', ucfirst($callableDescription) . ' invoked with %d parameters, %d required.', ucfirst($callableDescription) . ' invoked with %d parameter, at least %d required.', ucfirst($callableDescription) . ' invoked with %d parameters, at least %d required.', ucfirst($callableDescription) . ' invoked with %d parameter, %d-%d required.', ucfirst($callableDescription) . ' invoked with %d parameters, %d-%d required.', 'Parameter %s of ' . $callableDescription . ' expects %s, %s given.', 'Result of ' . $callableDescription . ' (void) is used.', 'Parameter %s of ' . $callableDescription . ' is passed by reference, so it expects variables only.', 'Unable to resolve the template type %s in call to ' . $callableDescription, 'Missing parameter $%s in call to ' . $callableDescription . '.', 'Unknown parameter $%s in call to ' . $callableDescription . '.', 'Return type of call to ' . $callableDescription . ' contains unresolvable type.', 'Parameter %s of ' . $callableDescription . ' contains unresolvable type.', ucfirst($callableDescription) . ' invoked with %s, but it\'s not allowed because of @no-named-arguments.'], 'function', $acceptsNamedArguments); } } */ final class VariadicParametersDeclarationRule implements Rule { public function getNodeType() : string { return Node\FunctionLike::class; } public function processNode(Node $node, Scope $scope) : array { $parameters = $node->getParams(); $paramCount = count($parameters); if ($paramCount === 0) { return []; } $errors = []; foreach ($parameters as $index => $parameter) { if (!$parameter->variadic) { continue; } if ($paramCount - 1 === $index) { continue; } $errors[] = RuleErrorBuilder::message('Only the last parameter can be variadic.')->nonIgnorable()->identifier('parameter.variadicNotLast')->build(); } return $errors; } } */ final class FunctionAttributesRule implements Rule { /** * @var AttributesCheck */ private $attributesCheck; public function __construct(AttributesCheck $attributesCheck) { $this->attributesCheck = $attributesCheck; } public function getNodeType() : string { return Node\Stmt\Function_::class; } public function processNode(Node $node, Scope $scope) : array { return $this->attributesCheck->check($scope, $node->attrGroups, Attribute::TARGET_FUNCTION, 'function'); } } */ final class ArrayFilterRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var bool */ private $treatPhpDocTypesAsCertain; /** * @var bool */ private $treatPhpDocTypesAsCertainTip; public function __construct(ReflectionProvider $reflectionProvider, bool $treatPhpDocTypesAsCertain, bool $treatPhpDocTypesAsCertainTip) { $this->reflectionProvider = $reflectionProvider; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->treatPhpDocTypesAsCertainTip = $treatPhpDocTypesAsCertainTip; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } $functionReflection = $this->reflectionProvider->getFunction($node->name, $scope); if ($functionReflection->getName() !== 'array_filter') { return []; } $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants()); $normalizedFuncCall = ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $node); if ($normalizedFuncCall === null) { return []; } $args = $normalizedFuncCall->getArgs(); if (count($args) !== 1) { return []; } if ($this->treatPhpDocTypesAsCertain) { $arrayType = $scope->getType($args[0]->value); } else { $arrayType = $scope->getNativeType($args[0]->value); } if ($arrayType->isIterableAtLeastOnce()->no()) { $message = 'Parameter #1 $array (%s) to function array_filter is empty, call has no effect.'; $errorBuilder = RuleErrorBuilder::message(sprintf($message, $arrayType->describe(VerbosityLevel::value())))->identifier('arrayFilter.empty'); if ($this->treatPhpDocTypesAsCertain) { $nativeArrayType = $scope->getNativeType($args[0]->value); if ($this->treatPhpDocTypesAsCertainTip && !$nativeArrayType->isIterableAtLeastOnce()->no()) { $errorBuilder->treatPhpDocTypesAsCertainTip(); } } return [$errorBuilder->build()]; } $falsyType = StaticTypeFactory::falsey(); $isSuperType = $falsyType->isSuperTypeOf($arrayType->getIterableValueType()); if ($isSuperType->no()) { $message = 'Parameter #1 $array (%s) to function array_filter does not contain falsy values, the array will always stay the same.'; $errorBuilder = RuleErrorBuilder::message(sprintf($message, $arrayType->describe(VerbosityLevel::value())))->identifier('arrayFilter.same'); if ($this->treatPhpDocTypesAsCertain) { $nativeArrayType = $scope->getNativeType($args[0]->value); $isNativeSuperType = $falsyType->isSuperTypeOf($nativeArrayType->getIterableValueType()); if ($this->treatPhpDocTypesAsCertainTip && !$isNativeSuperType->no()) { $errorBuilder->treatPhpDocTypesAsCertainTip(); } } return [$errorBuilder->build()]; } if ($isSuperType->yes()) { $message = 'Parameter #1 $array (%s) to function array_filter contains falsy values only, the result will always be an empty array.'; $errorBuilder = RuleErrorBuilder::message(sprintf($message, $arrayType->describe(VerbosityLevel::value())))->identifier('arrayFilter.alwaysEmpty'); if ($this->treatPhpDocTypesAsCertain) { $nativeArrayType = $scope->getNativeType($args[0]->value); $isNativeSuperType = $falsyType->isSuperTypeOf($nativeArrayType->getIterableValueType()); if ($this->treatPhpDocTypesAsCertainTip && !$isNativeSuperType->yes()) { $errorBuilder->treatPhpDocTypesAsCertainTip(); } } return [$errorBuilder->build()]; } return []; } } */ final class FunctionCallableRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var RuleLevelHelper */ private $ruleLevelHelper; /** * @var PhpVersion */ private $phpVersion; /** * @var bool */ private $checkFunctionNameCase; /** * @var bool */ private $reportMaybes; public function __construct(ReflectionProvider $reflectionProvider, RuleLevelHelper $ruleLevelHelper, PhpVersion $phpVersion, bool $checkFunctionNameCase, bool $reportMaybes) { $this->reflectionProvider = $reflectionProvider; $this->ruleLevelHelper = $ruleLevelHelper; $this->phpVersion = $phpVersion; $this->checkFunctionNameCase = $checkFunctionNameCase; $this->reportMaybes = $reportMaybes; } public function getNodeType() : string { return FunctionCallableNode::class; } public function processNode(Node $node, Scope $scope) : array { if (!$this->phpVersion->supportsFirstClassCallables()) { return [RuleErrorBuilder::message('First-class callables are supported only on PHP 8.1 and later.')->nonIgnorable()->identifier('callable.notSupported')->build()]; } $functionName = $node->getName(); if ($functionName instanceof Node\Name) { $functionNameName = $functionName->toString(); if ($this->reflectionProvider->hasFunction($functionName, $scope)) { if ($this->checkFunctionNameCase) { $function = $this->reflectionProvider->getFunction($functionName, $scope); /** @var string $calledFunctionName */ $calledFunctionName = $this->reflectionProvider->resolveFunctionName($functionName, $scope); if (strtolower($function->getName()) === strtolower($calledFunctionName) && $function->getName() !== $calledFunctionName) { return [RuleErrorBuilder::message(sprintf('Call to function %s() with incorrect case: %s', $function->getName(), $functionNameName))->identifier('function.nameCase')->build()]; } } return []; } if ($scope->isInFunctionExists($functionNameName)) { return []; } return [RuleErrorBuilder::message(sprintf('Function %s not found.', $functionNameName))->identifier('function.notFound')->build()]; } $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $functionName), 'Creating callable from an unknown class %s.', static function (Type $type) : bool { return $type->isCallable()->yes(); }); $type = $typeResult->getType(); if ($type instanceof ErrorType) { return $typeResult->getUnknownClassErrors(); } $isCallable = $type->isCallable(); if ($isCallable->no()) { return [RuleErrorBuilder::message(sprintf('Creating callable from %s but it\'s not a callable.', $type->describe(VerbosityLevel::value())))->identifier('callable.nonCallable')->build()]; } if ($this->reportMaybes && $isCallable->maybe()) { return [RuleErrorBuilder::message(sprintf('Creating callable from %s but it might not be a callable.', $type->describe(VerbosityLevel::value())))->identifier('callable.nonCallable')->build()]; } return []; } } */ final class PrintfParametersRule implements Rule { /** * @var PrintfHelper */ private $printfHelper; /** * @var ReflectionProvider */ private $reflectionProvider; private const FORMAT_ARGUMENT_POSITIONS = ['printf' => 0, 'sprintf' => 0, 'sscanf' => 1, 'fscanf' => 1]; private const MINIMUM_NUMBER_OF_ARGUMENTS = ['printf' => 1, 'sprintf' => 1, 'sscanf' => 3, 'fscanf' => 3]; public function __construct(\PHPStan\Rules\Functions\PrintfHelper $printfHelper, ReflectionProvider $reflectionProvider) { $this->printfHelper = $printfHelper; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } $functionReflection = $this->reflectionProvider->getFunction($node->name, $scope); $name = $functionReflection->getName(); if (!array_key_exists($name, self::FORMAT_ARGUMENT_POSITIONS)) { return []; } $formatArgumentPosition = self::FORMAT_ARGUMENT_POSITIONS[$name]; $args = $node->getArgs(); foreach ($args as $arg) { if ($arg->unpack) { return []; } } $argsCount = count($args); if ($argsCount < self::MINIMUM_NUMBER_OF_ARGUMENTS[$name]) { return []; // caught by CallToFunctionParametersRule } $formatArgType = $scope->getType($args[$formatArgumentPosition]->value); $maxPlaceHoldersCount = null; foreach ($formatArgType->getConstantStrings() as $formatString) { $format = $formatString->getValue(); if (in_array($name, ['sprintf', 'printf'], \true)) { $tempPlaceHoldersCount = $this->printfHelper->getPrintfPlaceholdersCount($format); } else { $tempPlaceHoldersCount = $this->printfHelper->getScanfPlaceholdersCount($format); } if ($maxPlaceHoldersCount === null) { $maxPlaceHoldersCount = $tempPlaceHoldersCount; } elseif ($tempPlaceHoldersCount > $maxPlaceHoldersCount) { $maxPlaceHoldersCount = $tempPlaceHoldersCount; } } if ($maxPlaceHoldersCount === null) { return []; } $argsCount -= $formatArgumentPosition; if ($argsCount !== $maxPlaceHoldersCount + 1) { return [RuleErrorBuilder::message(sprintf(sprintf('%s, %s.', $maxPlaceHoldersCount === 1 ? 'Call to %s contains %d placeholder' : 'Call to %s contains %d placeholders', $argsCount - 1 === 1 ? '%d value given' : '%d values given'), $name, $maxPlaceHoldersCount, $argsCount - 1))->identifier(sprintf('argument.%s', $name))->build()]; } return []; } } */ final class ExistingClassesInClosureTypehintsRule implements Rule { /** * @var FunctionDefinitionCheck */ private $check; public function __construct(FunctionDefinitionCheck $check) { $this->check = $check; } public function getNodeType() : string { return Closure::class; } public function processNode(Node $node, Scope $scope) : array { return $this->check->checkAnonymousFunction($scope, $node->getParams(), $node->getReturnType(), 'Parameter $%s of anonymous function has invalid type %s.', 'Anonymous function has invalid return type %s.', 'Anonymous function uses native union types but they\'re supported only on PHP 8.0 and later.', 'Parameter $%s of anonymous function has unresolvable native type.', 'Anonymous function has unresolvable native return type.'); } } */ final class PrintfArrayParametersRule implements Rule { /** * @var PrintfHelper */ private $printfHelper; /** * @var ReflectionProvider */ private $reflectionProvider; public function __construct(\PHPStan\Rules\Functions\PrintfHelper $printfHelper, ReflectionProvider $reflectionProvider) { $this->printfHelper = $printfHelper; $this->reflectionProvider = $reflectionProvider; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } $functionReflection = $this->reflectionProvider->getFunction($node->name, $scope); $name = $functionReflection->getName(); if (!in_array($name, ['vprintf', 'vsprintf'], \true)) { return []; } $args = $node->getArgs(); $argsCount = count($args); if ($argsCount < 1) { return []; // caught by CallToFunctionParametersRule } $formatArgType = $scope->getType($args[0]->value); $placeHoldersCounts = []; foreach ($formatArgType->getConstantStrings() as $formatString) { $format = $formatString->getValue(); $placeHoldersCounts[] = $this->printfHelper->getPrintfPlaceholdersCount($format); } if ($placeHoldersCounts === []) { return []; } $minCount = min($placeHoldersCounts); $maxCount = max($placeHoldersCounts); if ($minCount === $maxCount) { $placeHoldersCount = new ConstantIntegerType($minCount); } else { $placeHoldersCount = IntegerRangeType::fromInterval($minCount, $maxCount); if (!$placeHoldersCount instanceof IntegerRangeType && !$placeHoldersCount instanceof ConstantIntegerType) { return []; } } $formatArgsCounts = []; if (isset($args[1])) { $formatArgsType = $scope->getType($args[1]->value); $constantArrays = $formatArgsType->getConstantArrays(); if ($constantArrays === []) { $formatArgsCounts[] = new IntegerType(); } foreach ($constantArrays as $constantArray) { $formatArgsCounts[] = $constantArray->getArraySize(); } } if ($formatArgsCounts === []) { $formatArgsCount = new ConstantIntegerType(0); } else { $formatArgsCount = TypeCombinator::union(...$formatArgsCounts); if (!$formatArgsCount instanceof IntegerRangeType && !$formatArgsCount instanceof ConstantIntegerType) { return []; } } if (!$this->placeholdersMatchesArgsCount($placeHoldersCount, $formatArgsCount)) { if ($placeHoldersCount instanceof IntegerRangeType) { $placeholders = $this->getIntegerRangeAsString($placeHoldersCount); $singlePlaceholder = \false; } else { $placeholders = $placeHoldersCount->getValue(); $singlePlaceholder = $placeholders === 1; } if ($formatArgsCount instanceof IntegerRangeType) { $values = $this->getIntegerRangeAsString($formatArgsCount); $singleValue = \false; } else { $values = $formatArgsCount->getValue(); $singleValue = $values === 1; } return [RuleErrorBuilder::message(sprintf(sprintf('%s, %s.', $singlePlaceholder ? 'Call to %s contains %d placeholder' : 'Call to %s contains %s placeholders', $singleValue ? '%d value given' : '%s values given'), $name, $placeholders, $values))->identifier(sprintf('argument.%s', $name))->build()]; } return []; } /** * @param ConstantIntegerType|IntegerRangeType $placeHoldersCount * @param ConstantIntegerType|IntegerRangeType $formatArgsCount */ private function placeholdersMatchesArgsCount($placeHoldersCount, $formatArgsCount) : bool { if ($placeHoldersCount instanceof ConstantIntegerType) { if ($formatArgsCount instanceof ConstantIntegerType) { return $placeHoldersCount->getValue() === $formatArgsCount->getValue(); } // Zero placeholders + array if ($placeHoldersCount->getValue() === 0) { return \true; } return \false; } if ($formatArgsCount instanceof IntegerRangeType && IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($placeHoldersCount)->yes()) { if ($formatArgsCount->getMin() !== null && $formatArgsCount->getMax() !== null) { // constant array return $placeHoldersCount->isSuperTypeOf($formatArgsCount)->yes(); } // general array return IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($formatArgsCount)->yes(); } return \false; } private function getIntegerRangeAsString(IntegerRangeType $range) : string { if ($range->getMin() !== null && $range->getMax() !== null) { return $range->getMin() . '-' . $range->getMax(); } elseif ($range->getMin() !== null) { return $range->getMin() . ' or more'; } elseif ($range->getMax() !== null) { return $range->getMax() . ' or less'; } throw new ShouldNotHappenException(); } } */ final class IncompatibleDefaultParameterTypeRule implements Rule { public function getNodeType() : string { return InFunctionNode::class; } public function processNode(Node $node, Scope $scope) : array { $function = $node->getFunctionReflection(); $errors = []; foreach ($node->getOriginalNode()->getParams() as $paramI => $param) { if ($param->default === null) { continue; } if ($param->var instanceof Node\Expr\Error || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } $defaultValueType = $scope->getType($param->default); $parameterType = $function->getParameters()[$paramI]->getType(); $parameterType = TemplateTypeHelper::resolveToBounds($parameterType); $accepts = $parameterType->acceptsWithReason($defaultValueType, \true); if ($accepts->yes()) { continue; } $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($parameterType, $defaultValueType); $errors[] = RuleErrorBuilder::message(sprintf('Default value of the parameter #%d $%s (%s) of function %s() is incompatible with type %s.', $paramI + 1, $param->var->name, $defaultValueType->describe($verbosityLevel), $function->getName(), $parameterType->describe($verbosityLevel)))->line($param->getStartLine())->identifier('parameter.defaultValue')->acceptsReasonsTip($accepts->reasons)->build(); } return $errors; } } */ final class RandomIntParametersRule implements Rule { /** * @var ReflectionProvider */ private $reflectionProvider; /** * @var bool */ private $reportMaybes; public function __construct(ReflectionProvider $reflectionProvider, bool $reportMaybes) { $this->reflectionProvider = $reflectionProvider; $this->reportMaybes = $reportMaybes; } public function getNodeType() : string { return FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Name) { return []; } if ($this->reflectionProvider->resolveFunctionName($node->name, $scope) !== 'random_int') { return []; } $args = array_values($node->getArgs()); if (count($args) < 2) { return []; } $minType = $scope->getType($args[0]->value)->toInteger(); $maxType = $scope->getType($args[1]->value)->toInteger(); if (!$minType instanceof ConstantIntegerType && !$minType instanceof IntegerRangeType || !$maxType instanceof ConstantIntegerType && !$maxType instanceof IntegerRangeType) { return []; } $isSmaller = $maxType->isSmallerThan($minType); if ($isSmaller->yes() || $isSmaller->maybe() && $this->reportMaybes) { $message = 'Parameter #1 $min (%s) of function random_int expects lower number than parameter #2 $max (%s).'; return [RuleErrorBuilder::message(sprintf($message, $minType->describe(VerbosityLevel::value()), $maxType->describe(VerbosityLevel::value())))->identifier('argument.type')->build()]; } return []; } } className = $className; $this->node = $node; } public function getClassName() : string { return $this->className; } public function getNode() : Node { return $this->node; } } */ private $unknownClassErrors; /** * @var ?string */ private $tip; /** * @param string[] $referencedClasses * @param list $unknownClassErrors */ public function __construct(Type $type, array $referencedClasses, array $unknownClassErrors, ?string $tip) { $this->type = $type; $this->referencedClasses = $referencedClasses; $this->unknownClassErrors = $unknownClassErrors; $this->tip = $tip; } public function getType() : Type { return $this->type; } /** * @return string[] */ public function getReferencedClasses() : array { return $this->referencedClasses; } /** * @return list */ public function getUnknownClassErrors() : array { return $this->unknownClassErrors; } public function getTip() : ?string { return $this->tip; } } */ private $tips = []; private function __construct(string $message) { $this->properties['message'] = $message; $this->type = self::TYPE_MESSAGE; } /** * @return array}> */ public static function getRuleErrorTypes() : array { return [self::TYPE_MESSAGE => [\PHPStan\Rules\RuleError::class, [['message', 'string', 'string']]], self::TYPE_LINE => [\PHPStan\Rules\LineRuleError::class, [['line', 'int', 'int']]], self::TYPE_FILE => [\PHPStan\Rules\FileRuleError::class, [['file', 'string', 'string'], ['fileDescription', 'string', 'string']]], self::TYPE_TIP => [\PHPStan\Rules\TipRuleError::class, [['tip', 'string', 'string']]], self::TYPE_IDENTIFIER => [\PHPStan\Rules\IdentifierRuleError::class, [['identifier', 'string', 'string']]], self::TYPE_METADATA => [\PHPStan\Rules\MetadataRuleError::class, [['metadata', 'array', 'mixed[]']]], self::TYPE_NON_IGNORABLE => [\PHPStan\Rules\NonIgnorableRuleError::class, []]]; } /** * @return self */ public static function message(string $message) : self { return new self($message); } /** * @phpstan-this-out self * @return self */ public function line(int $line) : self { $this->properties['line'] = $line; $this->type |= self::TYPE_LINE; return $this; } /** * @phpstan-this-out self * @return self */ public function file(string $file, ?string $fileDescription = null) : self { if (!is_file($file)) { throw new ShouldNotHappenException(sprintf('File %s does not exist.', $file)); } $this->properties['file'] = $file; $this->properties['fileDescription'] = $fileDescription ?? $file; $this->type |= self::TYPE_FILE; return $this; } /** * @phpstan-this-out self * @return self */ public function tip(string $tip) : self { $this->tips = [$tip]; $this->type |= self::TYPE_TIP; return $this; } /** * @phpstan-this-out self * @return self */ public function addTip(string $tip) : self { $this->tips[] = $tip; $this->type |= self::TYPE_TIP; return $this; } /** * @phpstan-this-out self * @return self */ public function discoveringSymbolsTip() : self { return $this->tip('Learn more at https://phpstan.org/user-guide/discovering-symbols'); } /** * @param list $reasons * @phpstan-this-out self * @return self */ public function acceptsReasonsTip(array $reasons) : self { foreach ($reasons as $reason) { $this->addTip($reason); } return $this; } /** * @phpstan-this-out self * @return self */ public function treatPhpDocTypesAsCertainTip() : self { return $this->tip('Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.'); } /** * Sets an error identifier. * * List of all current error identifiers in PHPStan: https://phpstan.org/error-identifiers * * @phpstan-this-out self * @return self */ public function identifier(string $identifier) : self { if (!Error::validateIdentifier($identifier)) { throw new ShouldNotHappenException(sprintf('Invalid identifier: %s, error identifiers must match /%s/', $identifier, Error::PATTERN_IDENTIFIER)); } $this->properties['identifier'] = $identifier; $this->type |= self::TYPE_IDENTIFIER; return $this; } /** * @param mixed[] $metadata * @phpstan-this-out self * @return self */ public function metadata(array $metadata) : self { $this->properties['metadata'] = $metadata; $this->type |= self::TYPE_METADATA; return $this; } /** * @phpstan-this-out self * @return self */ public function nonIgnorable() : self { $this->type |= self::TYPE_NON_IGNORABLE; return $this; } /** * @return T */ public function build() : \PHPStan\Rules\RuleError { /** @var class-string $className */ $className = sprintf('PHPStan\\Rules\\RuleErrors\\RuleError%d', $this->type); if (!class_exists($className)) { throw new ShouldNotHappenException(sprintf('Class %s does not exist.', $className)); } $ruleError = new $className(); foreach ($this->properties as $propertyName => $value) { $ruleError->{$propertyName} = $value; } if (count($this->tips) > 0) { if (count($this->tips) === 1) { $ruleError->tip = $this->tips[0]; } else { $ruleError->tip = implode("\n", array_map(static function (string $tip) { return sprintf('• %s', $tip); }, $this->tips)); } } return $ruleError; } } ruleLevelHelper = $ruleLevelHelper; $this->nullsafeCheck = $nullsafeCheck; $this->phpVersion = $phpVersion; $this->unresolvableTypeHelper = $unresolvableTypeHelper; $this->propertyReflectionFinder = $propertyReflectionFinder; $this->checkArgumentTypes = $checkArgumentTypes; $this->checkArgumentsPassedByReference = $checkArgumentsPassedByReference; $this->checkExtraArguments = $checkExtraArguments; $this->checkMissingTypehints = $checkMissingTypehints; $this->checkUnresolvableParameterTypes = $checkUnresolvableParameterTypes; } /** * @param Node\Expr\FuncCall|Node\Expr\MethodCall|Node\Expr\StaticCall|Node\Expr\New_ $funcCall * @param array{0: string, 1: string, 2: string, 3: string, 4: string, 5: string, 6: string, 7: string, 8: string, 9: string, 10: string, 11: string, 12: string, 13?: string, 14?: string} $messages * @param 'attribute'|'callable'|'method'|'staticMethod'|'function'|'new' $nodeType * @return list */ public function check(ParametersAcceptor $parametersAcceptor, Scope $scope, bool $isBuiltin, $funcCall, array $messages, string $nodeType = 'function', bool $acceptsNamedArguments = \true) : array { $functionParametersMinCount = 0; $functionParametersMaxCount = 0; foreach ($parametersAcceptor->getParameters() as $parameter) { if (!$parameter->isOptional()) { $functionParametersMinCount++; } $functionParametersMaxCount++; } if ($parametersAcceptor->isVariadic()) { $functionParametersMaxCount = -1; } /** @var array $arguments */ $arguments = []; /** @var array $args */ $args = $funcCall->getArgs(); $hasNamedArguments = \false; $hasUnpackedArgument = \false; $errors = []; foreach ($args as $arg) { if ($hasNamedArguments && $arg->unpack) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message('Named argument cannot be followed by an unpacked (...) argument.')->identifier('argument.unpackAfterNamed')->line($arg->getStartLine())->nonIgnorable()->build(); } if ($hasUnpackedArgument && !$arg->unpack) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message('Unpacked argument (...) cannot be followed by a non-unpacked argument.')->identifier('argument.nonUnpackAfterUnpacked')->line($arg->getStartLine())->nonIgnorable()->build(); } if ($arg->unpack) { $hasUnpackedArgument = \true; } $argumentName = null; if ($arg->name !== null) { $hasNamedArguments = \true; $argumentName = $arg->name->toString(); } if ($arg->unpack) { $type = $scope->getType($arg->value); $arrays = $type->getConstantArrays(); if (count($arrays) > 0) { $minKeys = null; foreach ($arrays as $array) { $countType = $array->getArraySize(); if ($countType instanceof ConstantIntegerType) { $keysCount = $countType->getValue(); } elseif ($countType instanceof IntegerRangeType) { $keysCount = $countType->getMin(); if ($keysCount === null) { throw new ShouldNotHappenException(); } } else { throw new ShouldNotHappenException(); } if ($minKeys !== null && $keysCount >= $minKeys) { continue; } $minKeys = $keysCount; } for ($j = 0; $j < $minKeys; $j++) { $types = []; $commonKey = null; foreach ($arrays as $constantArray) { $types[] = $constantArray->getValueTypes()[$j]; $keyType = $constantArray->getKeyTypes()[$j]; if ($commonKey === null) { $commonKey = $keyType->getValue(); } elseif ($commonKey !== $keyType->getValue()) { $commonKey = \false; } } $keyArgumentName = null; if (is_string($commonKey)) { $keyArgumentName = $commonKey; $hasNamedArguments = \true; } $arguments[] = [$arg->value, TypeCombinator::union(...$types), \false, $keyArgumentName, $arg->getStartLine()]; } } else { $arguments[] = [$arg->value, $type->getIterableValueType(), \true, null, $arg->getStartLine()]; } continue; } $arguments[] = [$arg->value, null, \false, $argumentName, $arg->getStartLine()]; } if ($hasNamedArguments && !$this->phpVersion->supportsNamedArguments() && !(bool) $funcCall->getAttribute('isAttribute', \false)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message('Named arguments are supported only on PHP 8.0 and later.')->identifier('argument.namedNotSupported')->line($funcCall->getStartLine())->nonIgnorable()->build(); } if (!$hasNamedArguments) { $invokedParametersCount = count($arguments); foreach ($arguments as [$argumentValue, $argumentValueType, $unpack, $argumentName]) { if ($unpack) { $invokedParametersCount = max($functionParametersMinCount, $functionParametersMaxCount); break; } } if ($invokedParametersCount < $functionParametersMinCount || $this->checkExtraArguments && $invokedParametersCount > $functionParametersMaxCount) { if ($functionParametersMinCount === $functionParametersMaxCount) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($invokedParametersCount === 1 ? $messages[0] : $messages[1], $invokedParametersCount, $functionParametersMinCount))->identifier('arguments.count')->line($funcCall->getStartLine())->build(); } elseif ($functionParametersMaxCount === -1 && $invokedParametersCount < $functionParametersMinCount) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($invokedParametersCount === 1 ? $messages[2] : $messages[3], $invokedParametersCount, $functionParametersMinCount))->identifier('arguments.count')->line($funcCall->getStartLine())->build(); } elseif ($functionParametersMaxCount !== -1) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($invokedParametersCount === 1 ? $messages[4] : $messages[5], $invokedParametersCount, $functionParametersMinCount, $functionParametersMaxCount))->identifier('arguments.count')->line($funcCall->getStartLine())->build(); } } } if (!$funcCall instanceof Node\Expr\New_ && !$scope->isInFirstLevelStatement() && $scope->getKeepVoidType($funcCall)->isVoid()->yes()) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message($messages[7])->identifier(sprintf('%s.void', $nodeType))->line($funcCall->getStartLine())->build(); } [$addedErrors, $argumentsWithParameters] = $this->processArguments($parametersAcceptor, $funcCall->getStartLine(), $isBuiltin, $arguments, $hasNamedArguments, $messages[10], $messages[11]); foreach ($addedErrors as $error) { $errors[] = $error; } if (!$this->checkArgumentTypes && !$this->checkArgumentsPassedByReference) { return $errors; } foreach ($argumentsWithParameters as $i => [$argumentValue, $argumentValueType, $unpack, $argumentName, $argumentLine, $parameter, $originalParameter]) { if ($this->checkArgumentTypes && $unpack) { $iterableTypeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $argumentValue, '', static function (Type $type) : bool { return $type->isIterable()->yes(); }); $iterableTypeResultType = $iterableTypeResult->getType(); if (!$iterableTypeResultType instanceof ErrorType && !$iterableTypeResultType->isIterable()->yes()) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Only iterables can be unpacked, %s given in argument #%d.', $iterableTypeResultType->describe(VerbosityLevel::typeOnly()), $i + 1))->identifier('argument.unpackNonIterable')->line($argumentLine)->build(); } } if ($parameter === null) { continue; } if ($argumentValueType === null) { if ($scope instanceof MutatingScope) { $scope = $scope->pushInFunctionCall(null, $parameter); } $argumentValueType = $scope->getType($argumentValue); if ($scope instanceof MutatingScope) { $scope = $scope->popInFunctionCall(); } } if (!$acceptsNamedArguments && $this->checkUnresolvableParameterTypes && isset($messages[14])) { if ($argumentName !== null) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($messages[14], sprintf('named argument $%s', $argumentName)))->identifier('argument.named')->line($argumentLine)->build(); } elseif ($unpack) { $unpackedArrayType = $scope->getType($argumentValue); $hasStringKey = $unpackedArrayType->getIterableKeyType()->isString(); if (!$hasStringKey->no()) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($messages[14], sprintf('unpacked array with %s', $hasStringKey->yes() ? 'string key' : 'possibly string key')))->identifier('argument.named')->line($argumentLine)->build(); } } } if ($this->checkArgumentTypes) { $parameterType = TypeUtils::resolveLateResolvableTypes($parameter->getType()); if (!$parameter->passedByReference()->createsNewVariable() || !$isBuiltin && $this->checkUnresolvableParameterTypes && !$argumentValueType instanceof ErrorType) { $accepts = $this->ruleLevelHelper->acceptsWithReason($parameterType, $argumentValueType, $scope->isDeclareStrictTypes()); if (!$accepts->result) { $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($parameterType, $argumentValueType); $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($messages[6], $this->describeParameter($parameter, $argumentName === null ? $i + 1 : null), $parameterType->describe($verbosityLevel), $argumentValueType->describe($verbosityLevel)))->identifier('argument.type')->line($argumentLine)->acceptsReasonsTip($accepts->reasons)->build(); } } if ($this->checkUnresolvableParameterTypes && $originalParameter !== null && isset($messages[13]) && !$this->unresolvableTypeHelper->containsUnresolvableType($originalParameter->getType()) && $this->unresolvableTypeHelper->containsUnresolvableType($parameterType)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($messages[13], $this->describeParameter($parameter, $argumentName === null ? $i + 1 : null)))->identifier('argument.unresolvableType')->line($argumentLine)->build(); } if ($parameter instanceof ParameterReflectionWithPhpDocs && $parameter->getClosureThisType() !== null && ($argumentValue instanceof Expr\Closure || $argumentValue instanceof Expr\ArrowFunction) && $argumentValue->static) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($messages[6], $this->describeParameter($parameter, $argumentName === null ? $i + 1 : null), 'bindable closure', 'static closure'))->identifier('argument.staticClosure')->line($argumentLine)->build(); } } if (!$this->checkArgumentsPassedByReference || !$parameter->passedByReference()->yes()) { continue; } if ($this->nullsafeCheck->containsNullSafe($argumentValue)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($messages[8], $this->describeParameter($parameter, $argumentName === null ? $i + 1 : null)))->identifier('argument.byRef')->line($argumentLine)->build(); continue; } if ($argumentValue instanceof Node\Expr\PropertyFetch || $argumentValue instanceof Node\Expr\StaticPropertyFetch) { $propertyReflections = $this->propertyReflectionFinder->findPropertyReflectionsFromNode($argumentValue, $scope); foreach ($propertyReflections as $propertyReflection) { $nativePropertyReflection = $propertyReflection->getNativeReflection(); if ($nativePropertyReflection === null) { continue; } if (!$nativePropertyReflection->isReadOnly()) { continue; } if ($nativePropertyReflection->isStatic()) { $propertyDescription = sprintf('static readonly property %s::$%s', $propertyReflection->getDeclaringClass()->getDisplayName(), $propertyReflection->getName()); } else { $propertyDescription = sprintf('readonly property %s::$%s', $propertyReflection->getDeclaringClass()->getDisplayName(), $propertyReflection->getName()); } $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Parameter %s is passed by reference so it does not accept %s.', $this->describeParameter($parameter, $argumentName === null ? $i + 1 : null), $propertyDescription))->identifier('argument.byRef')->line($argumentLine)->build(); } } if ($argumentValue instanceof Node\Expr\Variable || $argumentValue instanceof Node\Expr\ArrayDimFetch || $argumentValue instanceof Node\Expr\PropertyFetch || $argumentValue instanceof Node\Expr\StaticPropertyFetch) { continue; } $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($messages[8], $this->describeParameter($parameter, $argumentName === null ? $i + 1 : null)))->identifier('argument.byRef')->line($argumentLine)->build(); } if ($this->checkMissingTypehints && $parametersAcceptor instanceof ResolvedFunctionVariant) { $originalParametersAcceptor = $parametersAcceptor->getOriginalParametersAcceptor(); $resolvedTypes = $parametersAcceptor->getResolvedTemplateTypeMap()->getTypes(); if (count($resolvedTypes) > 0) { $returnTemplateTypes = []; TypeTraverser::map($parametersAcceptor->getReturnTypeWithUnresolvableTemplateTypes(), static function (Type $type, callable $traverse) use(&$returnTemplateTypes) : Type { while ($type instanceof ConditionalType && $type->isResolvable()) { $type = $type->resolve(); } if ($type instanceof TemplateType && $type->getDefault() === null) { $returnTemplateTypes[$type->getName()] = \true; return $type; } return $traverse($type); }); $parameterTemplateTypes = []; foreach ($originalParametersAcceptor->getParameters() as $parameter) { TypeTraverser::map($parameter->getType(), static function (Type $type, callable $traverse) use(&$parameterTemplateTypes) : Type { if ($type instanceof TemplateType && $type->getDefault() === null) { $parameterTemplateTypes[$type->getName()] = \true; return $type; } return $traverse($type); }); } foreach ($resolvedTypes as $name => $type) { if (!$type instanceof ErrorType && (!$type instanceof NeverType || $type->isExplicit())) { continue; } if (!array_key_exists($name, $returnTemplateTypes)) { continue; } if (!array_key_exists($name, $parameterTemplateTypes)) { continue; } $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($messages[9], $name))->identifier('argument.templateType')->line($funcCall->getStartLine())->tip('See: https://phpstan.org/blog/solving-phpstan-error-unable-to-resolve-template-type')->build(); } } if (!$this->unresolvableTypeHelper->containsUnresolvableType($originalParametersAcceptor->getReturnType()) && $this->unresolvableTypeHelper->containsUnresolvableType($parametersAcceptor->getReturnType())) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message($messages[12])->identifier(sprintf('%s.unresolvableReturnType', $nodeType))->line($funcCall->getStartLine())->build(); } } return $errors; } /** * @param array $arguments * @return array{list, array} */ private function processArguments(ParametersAcceptor $parametersAcceptor, int $line, bool $isBuiltin, array $arguments, bool $hasNamedArguments, string $missingParameterMessage, string $unknownParameterMessage) : array { $parameters = $parametersAcceptor->getParameters(); $originalParameters = $parametersAcceptor instanceof ResolvedFunctionVariant ? $parametersAcceptor->getOriginalParametersAcceptor()->getParameters() : array_fill(0, count($parameters), null); $parametersByName = []; $originalParametersByName = []; $unusedParametersByName = []; $errors = []; foreach ($parameters as $i => $parameter) { $parametersByName[$parameter->getName()] = $parameter; $originalParametersByName[$parameter->getName()] = $originalParameters[$i]; if ($parameter->isVariadic()) { continue; } $unusedParametersByName[$parameter->getName()] = $parameter; } $newArguments = []; $namedArgumentAlreadyOccurred = \false; foreach ($arguments as $i => [$argumentValue, $argumentValueType, $unpack, $argumentName, $argumentLine]) { if ($argumentName === null) { if (!isset($parameters[$i])) { if (!$parametersAcceptor->isVariadic() || count($parameters) === 0) { $newArguments[$i] = [$argumentValue, $argumentValueType, $unpack, $argumentName, $argumentLine, null, null]; break; } $parameter = $parameters[count($parameters) - 1]; $originalParameter = $originalParameters[count($originalParameters) - 1]; if (!$parameter->isVariadic()) { $newArguments[$i] = [$argumentValue, $argumentValueType, $unpack, $argumentName, $argumentLine, null, null]; break; // func_get_args } } else { $parameter = $parameters[$i]; $originalParameter = $originalParameters[$i]; } } elseif (array_key_exists($argumentName, $parametersByName)) { $namedArgumentAlreadyOccurred = \true; $parameter = $parametersByName[$argumentName]; $originalParameter = $originalParametersByName[$argumentName]; } else { $namedArgumentAlreadyOccurred = \true; $parametersCount = count($parameters); if (!$parametersAcceptor->isVariadic() || $parametersCount <= 0 || $isBuiltin) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($unknownParameterMessage, $argumentName))->identifier('argument.unknown')->line($argumentLine)->build(); $newArguments[$i] = [$argumentValue, $argumentValueType, $unpack, $argumentName, $argumentLine, null, null]; continue; } $parameter = $parameters[$parametersCount - 1]; $originalParameter = $originalParameters[$parametersCount - 1]; } if ($namedArgumentAlreadyOccurred && $argumentName === null && !$unpack) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message('Named argument cannot be followed by a positional argument.')->identifier('argument.positionalAfterNamed')->line($argumentLine)->nonIgnorable()->build(); $newArguments[$i] = [$argumentValue, $argumentValueType, $unpack, $argumentName, $argumentLine, null, null]; continue; } $newArguments[$i] = [$argumentValue, $argumentValueType, $unpack, $argumentName, $argumentLine, $parameter, $originalParameter]; if ($hasNamedArguments && !$parameter->isVariadic() && !array_key_exists($parameter->getName(), $unusedParametersByName)) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf('Argument for parameter $%s has already been passed.', $parameter->getName()))->identifier('argument.duplicate')->line($argumentLine)->build(); continue; } unset($unusedParametersByName[$parameter->getName()]); } if ($hasNamedArguments) { foreach ($unusedParametersByName as $parameter) { if ($parameter->isOptional()) { continue; } $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($missingParameterMessage, sprintf('%s (%s)', $parameter->getName(), $parameter->getType()->describe(VerbosityLevel::typeOnly()))))->identifier('argument.missing')->line($line)->build(); } } return [$errors, $newArguments]; } private function describeParameter(ParameterReflection $parameter, ?int $position) : string { $parts = []; if ($position !== null) { $parts[] = '#' . $position; } $name = $parameter->getName(); if ($name !== '') { $parts[] = ($parameter->isVariadic() ? '...$' : '$') . $name; } return implode(' ', $parts); } } */ final class PureFunctionRule implements Rule { /** * @var FunctionPurityCheck */ private $check; public function __construct(\PHPStan\Rules\Pure\FunctionPurityCheck $check) { $this->check = $check; } public function getNodeType() : string { return FunctionReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { $function = $node->getFunctionReflection(); return $this->check->check(sprintf('Function %s()', $function->getName()), 'Function', $function, $function->getParameters(), $function->getReturnType(), $node->getImpurePoints(), $node->getStatementResult()->getThrowPoints(), $node->getStatements(), \false); } } */ final class PureMethodRule implements Rule { /** * @var FunctionPurityCheck */ private $check; public function __construct(\PHPStan\Rules\Pure\FunctionPurityCheck $check) { $this->check = $check; } public function getNodeType() : string { return MethodReturnStatementsNode::class; } public function processNode(Node $node, Scope $scope) : array { $method = $node->getMethodReflection(); return $this->check->check(sprintf('Method %s::%s()', $method->getDeclaringClass()->getDisplayName(), $method->getName()), 'Method', $method, $method->getParameters(), $method->getReturnType(), $node->getImpurePoints(), $node->getStatementResult()->getThrowPoints(), $node->getStatements(), $method->isConstructor()); } } * @param FunctionReflection|ExtendedMethodReflection $functionReflection */ public function check(string $functionDescription, string $identifier, $functionReflection, array $parameters, Type $returnType, array $impurePoints, array $throwPoints, array $statements, bool $isConstructor) : array { $errors = []; $isPure = $functionReflection->isPure(); if ($isPure->yes()) { foreach ($parameters as $parameter) { if (!$parameter->passedByReference()->createsNewVariable()) { continue; } $errors[] = RuleErrorBuilder::message(sprintf('%s is marked as pure but parameter $%s is passed by reference.', $functionDescription, $parameter->getName()))->identifier(sprintf('pure%s.parameterByRef', $identifier))->build(); } if ($returnType->isVoid()->yes() && !$isConstructor) { $errors[] = RuleErrorBuilder::message(sprintf('%s is marked as pure but returns void.', $functionDescription))->identifier(sprintf('pure%s.void', $identifier))->build(); } foreach ($impurePoints as $impurePoint) { $errors[] = RuleErrorBuilder::message(sprintf('%s %s in pure %s.', $impurePoint->isCertain() ? 'Impure' : 'Possibly impure', $impurePoint->getDescription(), lcfirst($functionDescription)))->line($impurePoint->getNode()->getStartLine())->identifier(sprintf('%s.%s', $impurePoint->isCertain() ? 'impure' : 'possiblyImpure', $impurePoint->getIdentifier()))->build(); } } elseif ($isPure->no()) { if (count($throwPoints) === 0 && count($impurePoints) === 0 && count($functionReflection->getAsserts()->getAll()) === 0) { $errors[] = RuleErrorBuilder::message(sprintf('%s is marked as impure but does not have any side effects.', $functionDescription))->identifier(sprintf('impure%s.pure', $identifier))->build(); } } elseif ($returnType->isVoid()->yes()) { if (count($throwPoints) === 0 && count($impurePoints) === 0 && !$isConstructor && (!$functionReflection instanceof ExtendedMethodReflection || $functionReflection->isPrivate()) && count($functionReflection->getAsserts()->getAll()) === 0) { $hasByRef = \false; foreach ($parameters as $parameter) { if (!$parameter->passedByReference()->createsNewVariable()) { continue; } $hasByRef = \true; break; } $statements = array_filter($statements, static function (Stmt $stmt) : bool { if ($stmt instanceof Stmt\Nop) { return \false; } if (!$stmt instanceof Stmt\Expression) { return \true; } if (!$stmt->expr instanceof FuncCall) { return \true; } if (!$stmt->expr->name instanceof Name) { return \true; } return !in_array($stmt->expr->name->toString(), CallToFunctionStatementWithoutSideEffectsRule::PHPSTAN_TESTING_FUNCTIONS, \true); }); if (!$hasByRef && count($statements) > 0) { $errors[] = RuleErrorBuilder::message(sprintf('%s returns void but does not have any side effects.', $functionDescription))->identifier('void.pure')->build(); } } } return $errors; } } */ final class ParameterOutAssignedTypeRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return VariableAssignNode::class; } public function processNode(Node $node, Scope $scope) : array { $inFunction = $scope->getFunction(); if ($inFunction === null) { return []; } if ($scope->isInAnonymousFunction()) { return []; } $variable = $node->getVariable(); if (!is_string($variable->name)) { return []; } $parameters = $inFunction->getParameters(); $foundParameter = null; foreach ($parameters as $parameter) { if (!$parameter->passedByReference()->createsNewVariable()) { continue; } if ($parameter->getName() !== $variable->name) { continue; } $foundParameter = $parameter; break; } if ($foundParameter === null) { return []; } $isParamOutType = \true; $outType = $foundParameter->getOutType(); if ($outType === null) { $isParamOutType = \false; $outType = $foundParameter->getType(); } $outType = TypeUtils::resolveLateResolvableTypes($outType); $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $node->getAssignedExpr(), '', static function (Type $type) use($outType) : bool { return $outType->isSuperTypeOf($type)->yes(); }); $type = $typeResult->getType(); if ($type instanceof ErrorType) { return $typeResult->getUnknownClassErrors(); } $assignedExprType = $scope->getType($node->getAssignedExpr()); if ($outType->isSuperTypeOf($assignedExprType)->yes()) { return []; } if ($inFunction instanceof ExtendedMethodReflection) { $functionDescription = sprintf('method %s::%s()', $inFunction->getDeclaringClass()->getDisplayName(), $inFunction->getName()); } else { $functionDescription = sprintf('function %s()', $inFunction->getName()); } $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($outType, $assignedExprType); $errorBuilder = RuleErrorBuilder::message(sprintf('Parameter &$%s %s of %s expects %s, %s given.', $foundParameter->getName(), $isParamOutType ? '@param-out type' : 'by-ref type', $functionDescription, $outType->describe($verbosityLevel), $assignedExprType->describe($verbosityLevel)))->identifier(sprintf('%s.type', $isParamOutType ? 'paramOut' : 'parameterByRef')); if (!$isParamOutType) { $errorBuilder->tip('You can change the parameter out type with @param-out PHPDoc tag.'); } return [$errorBuilder->build()]; } } */ final class ThrowTypeRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Node\Stmt\Throw_::class; } public function processNode(Node $node, Scope $scope) : array { $throwableType = new ObjectType(Throwable::class); $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $node->expr, 'Throwing object of an unknown class %s.', static function (Type $type) use($throwableType) : bool { return $throwableType->isSuperTypeOf($type)->yes(); }); $foundType = $typeResult->getType(); if ($foundType instanceof ErrorType) { return $typeResult->getUnknownClassErrors(); } $isSuperType = $throwableType->isSuperTypeOf($foundType); if ($isSuperType->yes()) { return []; } return [RuleErrorBuilder::message(sprintf('Invalid type %s to throw.', $foundType->describe(VerbosityLevel::typeOnly())))->identifier('throw.notThrowable')->build()]; } } */ final class CompactVariablesRule implements Rule { /** * @var bool */ private $checkMaybeUndefinedVariables; public function __construct(bool $checkMaybeUndefinedVariables) { $this->checkMaybeUndefinedVariables = $checkMaybeUndefinedVariables; } public function getNodeType() : string { return Node\Expr\FuncCall::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->name instanceof Node\Expr) { return []; } $functionName = strtolower($node->name->toString()); if ($functionName !== 'compact') { return []; } $functionArguments = $node->getArgs(); $messages = []; foreach ($functionArguments as $argument) { $argumentType = $scope->getType($argument->value); $constantStrings = $this->findConstantStrings($argumentType); foreach ($constantStrings as $constantString) { $variableName = $constantString->getValue(); $scopeHasVariable = $scope->hasVariableType($variableName); if ($scopeHasVariable->no()) { $messages[] = RuleErrorBuilder::message(sprintf('Call to function compact() contains undefined variable $%s.', $variableName))->identifier('variable.undefined')->line($argument->getStartLine())->build(); } elseif ($this->checkMaybeUndefinedVariables && $scopeHasVariable->maybe()) { $messages[] = RuleErrorBuilder::message(sprintf('Call to function compact() contains possibly undefined variable $%s.', $variableName))->identifier('variable.undefined')->line($argument->getStartLine())->build(); } } } return $messages; } /** * @return array */ private function findConstantStrings(Type $type) : array { if ($type instanceof ConstantStringType) { return [$type]; } if ($type instanceof ConstantArrayType) { $result = []; foreach ($type->getValueTypes() as $valueType) { $constantStrings = $this->findConstantStrings($valueType); $result = array_merge($result, $constantStrings); } return $result; } return []; } } */ final class UnsetRule implements Rule { public function getNodeType() : string { return Node\Stmt\Unset_::class; } public function processNode(Node $node, Scope $scope) : array { $functionArguments = $node->vars; $errors = []; foreach ($functionArguments as $argument) { $error = $this->canBeUnset($argument, $scope); if ($error === null) { continue; } $errors[] = $error; } return $errors; } private function canBeUnset(Node $node, Scope $scope) : ?IdentifierRuleError { if ($node instanceof Node\Expr\Variable && is_string($node->name)) { $hasVariable = $scope->hasVariableType($node->name); if ($hasVariable->no()) { return RuleErrorBuilder::message(sprintf('Call to function unset() contains undefined variable $%s.', $node->name))->line($node->getStartLine())->identifier('unset.variable')->build(); } } elseif ($node instanceof Node\Expr\ArrayDimFetch && $node->dim !== null) { $type = $scope->getType($node->var); $dimType = $scope->getType($node->dim); if ($type->isOffsetAccessible()->no() || $type->hasOffsetValueType($dimType)->no()) { return RuleErrorBuilder::message(sprintf('Cannot unset offset %s on %s.', $dimType->describe(VerbosityLevel::value()), $type->describe(VerbosityLevel::value())))->line($node->getStartLine())->identifier('unset.offset')->build(); } return $this->canBeUnset($node->var, $scope); } return null; } } */ final class DefinedVariableRule implements Rule { /** * @var bool */ private $cliArgumentsVariablesRegistered; /** * @var bool */ private $checkMaybeUndefinedVariables; public function __construct(bool $cliArgumentsVariablesRegistered, bool $checkMaybeUndefinedVariables) { $this->cliArgumentsVariablesRegistered = $cliArgumentsVariablesRegistered; $this->checkMaybeUndefinedVariables = $checkMaybeUndefinedVariables; } public function getNodeType() : string { return Variable::class; } public function processNode(Node $node, Scope $scope) : array { if (!is_string($node->name)) { return []; } if ($this->cliArgumentsVariablesRegistered && in_array($node->name, ['argc', 'argv'], \true)) { $isInMain = !$scope->isInClass() && !$scope->isInAnonymousFunction() && $scope->getFunction() === null; if ($isInMain) { return []; } } if ($scope->isInExpressionAssign($node) || $scope->isUndefinedExpressionAllowed($node)) { return []; } if ($scope->hasVariableType($node->name)->no()) { return [RuleErrorBuilder::message(sprintf('Undefined variable: $%s', $node->name))->identifier('variable.undefined')->build()]; } elseif ($this->checkMaybeUndefinedVariables && !$scope->hasVariableType($node->name)->yes()) { return [RuleErrorBuilder::message(sprintf('Variable $%s might not be defined.', $node->name))->identifier('variable.undefined')->build()]; } return []; } } */ final class VariableCloningRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return Clone_::class; } public function processNode(Node $node, Scope $scope) : array { $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $node->expr, 'Cloning object of an unknown class %s.', static function (Type $type) : bool { return $type->isCloneable()->yes(); }); $type = $typeResult->getType(); if ($type instanceof ErrorType) { return $typeResult->getUnknownClassErrors(); } if ($type->isCloneable()->yes()) { return []; } if ($node->expr instanceof Variable && is_string($node->expr->name)) { return [RuleErrorBuilder::message(sprintf('Cannot clone non-object variable $%s of type %s.', $node->expr->name, $type->describe(VerbosityLevel::typeOnly())))->identifier('clone.nonObject')->build()]; } return [RuleErrorBuilder::message(sprintf('Cannot clone %s.', $type->describe(VerbosityLevel::typeOnly())))->identifier('clone.nonObject')->build()]; } } */ final class ParameterOutExecutionEndTypeRule implements Rule { /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(RuleLevelHelper $ruleLevelHelper) { $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return ExecutionEndNode::class; } public function processNode(Node $node, Scope $scope) : array { $inFunction = $scope->getFunction(); if ($inFunction === null) { return []; } if ($scope->isInAnonymousFunction()) { return []; } $endNode = $node->getNode(); if ($endNode instanceof Node\Stmt\Expression) { $endNodeExpr = $endNode->expr; $endNodeExprType = $scope->getType($endNodeExpr); if ($endNodeExprType instanceof NeverType && $endNodeExprType->isExplicit()) { return []; } } if ($endNode instanceof Node\Stmt\Throw_) { return []; } $parameters = $inFunction->getParameters(); $errors = []; foreach ($parameters as $parameter) { if (!$parameter->passedByReference()->createsNewVariable()) { continue; } foreach ($this->processSingleParameter($scope, $inFunction, $parameter) as $error) { $errors[] = $error; } } return $errors; } /** * @return list * @param FunctionReflection|ExtendedMethodReflection $inFunction */ private function processSingleParameter(Scope $scope, $inFunction, ParameterReflectionWithPhpDocs $parameter) : array { $outType = $parameter->getOutType(); if ($outType === null) { return []; } if ($scope->hasExpressionType(new ParameterVariableOriginalValueExpr($parameter->getName()))->no()) { return []; } $outType = TypeUtils::resolveLateResolvableTypes($outType); $variableExpr = new Node\Expr\Variable($parameter->getName()); $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $variableExpr, '', static function (Type $type) use($outType) : bool { return $outType->isSuperTypeOf($type)->yes(); }); $type = $typeResult->getType(); if ($type instanceof ErrorType) { return $typeResult->getUnknownClassErrors(); } $assignedExprType = $scope->getType($variableExpr); if ($outType->isSuperTypeOf($assignedExprType)->yes()) { return []; } if ($inFunction instanceof ExtendedMethodReflection) { $functionDescription = sprintf('method %s::%s()', $inFunction->getDeclaringClass()->getDisplayName(), $inFunction->getName()); } else { $functionDescription = sprintf('function %s()', $inFunction->getName()); } $verbosityLevel = VerbosityLevel::getRecommendedLevelByType($outType, $assignedExprType); $errorBuilder = RuleErrorBuilder::message(sprintf('Parameter &$%s @param-out type of %s expects %s, %s given.', $parameter->getName(), $functionDescription, $outType->describe($verbosityLevel), $assignedExprType->describe($verbosityLevel)))->identifier(sprintf('paramOut.type')); return [$errorBuilder->build()]; } } */ final class NullCoalesceRule implements Rule { /** * @var IssetCheck */ private $issetCheck; public function __construct(IssetCheck $issetCheck) { $this->issetCheck = $issetCheck; } public function getNodeType() : string { return Node\Expr::class; } public function processNode(Node $node, Scope $scope) : array { $typeMessageCallback = static function (Type $type) : ?string { $isNull = $type->isNull(); if ($isNull->maybe()) { return null; } if ($isNull->yes()) { return 'is always null'; } return 'is not nullable'; }; if ($node instanceof Node\Expr\BinaryOp\Coalesce) { $error = $this->issetCheck->check($node->left, $scope, 'on left side of ??', 'nullCoalesce', $typeMessageCallback); } elseif ($node instanceof Node\Expr\AssignOp\Coalesce) { $error = $this->issetCheck->check($node->var, $scope, 'on left side of ??=', 'nullCoalesce', $typeMessageCallback); } else { return []; } if ($error === null) { return []; } return [$error]; } } */ final class EmptyRule implements Rule { /** * @var IssetCheck */ private $issetCheck; public function __construct(IssetCheck $issetCheck) { $this->issetCheck = $issetCheck; } public function getNodeType() : string { return Node\Expr\Empty_::class; } public function processNode(Node $node, Scope $scope) : array { $error = $this->issetCheck->check($node->expr, $scope, 'in empty()', 'empty', static function (Type $type) : ?string { $isNull = $type->isNull(); if ($isNull->maybe()) { return null; } $isFalsey = $type->toBoolean()->isFalse(); if ($isFalsey->maybe()) { return null; } if ($isNull->yes()) { if ($isFalsey->yes()) { return 'is always falsy'; } if ($isFalsey->no()) { return 'is not falsy'; } return 'is always null'; } if ($isFalsey->yes()) { return 'is always falsy'; } if ($isFalsey->no()) { return 'is not falsy'; } return 'is not nullable'; }); if ($error === null) { return []; } return [$error]; } } */ final class IssetRule implements Rule { /** * @var IssetCheck */ private $issetCheck; public function __construct(IssetCheck $issetCheck) { $this->issetCheck = $issetCheck; } public function getNodeType() : string { return Node\Expr\Isset_::class; } public function processNode(Node $node, Scope $scope) : array { $messages = []; foreach ($node->vars as $var) { $error = $this->issetCheck->check($var, $scope, 'in isset()', 'isset', static function (Type $type) : ?string { $isNull = $type->isNull(); if ($isNull->maybe()) { return null; } if ($isNull->yes()) { return 'is always null'; } return 'is not nullable'; }); if ($error === null) { continue; } $messages[] = $error; } return $messages; } } */ final class UsedNamesRule implements Rule { public function getNodeType() : string { return FileNode::class; } /** * @param FileNode $node */ public function processNode(Node $node, Scope $scope) : array { $usedNames = []; $errors = []; foreach ($node->getNodes() as $oneNode) { if ($oneNode instanceof Namespace_) { $namespaceName = $oneNode->name !== null ? $oneNode->name->toString() : ''; foreach ($oneNode->stmts as $stmt) { foreach ($this->findErrorsForNode($stmt, $namespaceName, $usedNames) as $error) { $errors[] = $error; } } continue; } foreach ($this->findErrorsForNode($oneNode, '', $usedNames) as $error) { $errors[] = $error; } } return $errors; } /** * @param array $usedNames * @return list */ private function findErrorsForNode(Node $node, string $namespace, array &$usedNames) : array { $lowerNamespace = strtolower($namespace); if ($node instanceof Use_) { if ($this->shouldBeIgnored($node)) { return []; } return $this->findErrorsInUses($node->uses, '', $lowerNamespace, $usedNames); } if ($node instanceof GroupUse) { if ($this->shouldBeIgnored($node)) { return []; } $useGroupPrefix = $node->prefix->toString(); return $this->findErrorsInUses($node->uses, $useGroupPrefix, $lowerNamespace, $usedNames); } if ($node instanceof ClassLike) { if ($node->name === null) { return []; } $type = 'class'; if ($node instanceof Interface_) { $type = 'interface'; } elseif ($node instanceof Trait_) { $type = 'trait'; } elseif ($node instanceof Enum_) { $type = 'enum'; } $name = $node->name->toLowerString(); if (in_array($name, $usedNames[$lowerNamespace] ?? [], \true)) { return [RuleErrorBuilder::message(sprintf('Cannot declare %s %s because the name is already in use.', $type, $namespace !== '' ? $namespace . '\\' . $node->name->toString() : $node->name->toString()))->identifier(sprintf('%s.nameInUse', $type))->line($node->getLine())->nonIgnorable()->build()]; } $usedNames[$lowerNamespace][] = $name; return []; } return []; } /** * @param UseUse[] $uses * @param array $usedNames * @return list */ private function findErrorsInUses(array $uses, string $useGroupPrefix, string $lowerNamespace, array &$usedNames) : array { $errors = []; foreach ($uses as $use) { if ($this->shouldBeIgnored($use)) { continue; } $useAlias = $use->getAlias()->toLowerString(); if (in_array($useAlias, $usedNames[$lowerNamespace] ?? [], \true)) { $errors[] = RuleErrorBuilder::message(sprintf('Cannot use %s as %s because the name is already in use.', $useGroupPrefix !== '' ? $useGroupPrefix . '\\' . $use->name->toString() : $use->name->toString(), $use->getAlias()->toString()))->identifier('use.nameInUse')->line($use->getLine())->nonIgnorable()->build(); continue; } $usedNames[$lowerNamespace][] = $useAlias; } return $errors; } /** * @param Use_|GroupUse|UseUse $use */ private function shouldBeIgnored($use) : bool { return in_array($use->type, [Use_::TYPE_FUNCTION, Use_::TYPE_CONSTANT], \true); } } */ final class ClassAsClassConstantRule implements Rule { public function getNodeType() : string { return Node\Stmt\ClassConst::class; } public function processNode(Node $node, Scope $scope) : array { $errors = []; foreach ($node->consts as $const) { if ($const->name->toLowerString() !== 'class') { continue; } $errors[] = RuleErrorBuilder::message('A class constant must not be called \'class\'; it is reserved for class name fetching.')->line($const->getStartLine())->identifier('classConstant.class')->nonIgnorable()->build(); } return $errors; } } container = $container; } public function getExtensions() : array { if ($this->extensions === null) { $this->extensions = $this->container->getServicesByTag(\PHPStan\Rules\Constants\AlwaysUsedClassConstantsExtensionProvider::EXTENSION_TAG); } return $this->extensions; } } */ final class MagicConstantContextRule implements Rule { public function getNodeType() : string { return MagicConst::class; } public function processNode(Node $node, Scope $scope) : array { // test cases https://3v4l.org/ZUvvr if ($node instanceof MagicConst\Class_) { if ($scope->isInClass()) { return []; } return [RuleErrorBuilder::message(sprintf('Magic constant %s is always empty outside a class.', $node->getName()))->identifier('magicConstant.outOfClass')->build()]; } elseif ($node instanceof MagicConst\Trait_) { if ($scope->isInTrait()) { return []; } return [RuleErrorBuilder::message(sprintf('Magic constant %s is always empty outside a trait.', $node->getName()))->identifier('magicConstant.outOfTrait')->build()]; } elseif ($node instanceof MagicConst\Method || $node instanceof MagicConst\Function_) { if ($scope->getFunctionName() !== null) { return []; } if ($scope->isInAnonymousFunction()) { return []; } if ((bool) $node->getAttribute(MagicConstantParamDefaultVisitor::ATTRIBUTE_NAME)) { return []; } return [RuleErrorBuilder::message(sprintf('Magic constant %s is always empty outside a function.', $node->getName()))->identifier('magicConstant.outOfFunction')->build()]; } elseif ($node instanceof MagicConst\Namespace_) { if ($scope->getNamespace() === null) { return [RuleErrorBuilder::message(sprintf('Magic constant %s is always empty in global namespace.', $node->getName()))->identifier('magicConstant.outOfNamespace')->build()]; } } return []; } } */ final class DynamicClassConstantFetchRule implements Rule { /** * @var PhpVersion */ private $phpVersion; /** * @var RuleLevelHelper */ private $ruleLevelHelper; public function __construct(PhpVersion $phpVersion, RuleLevelHelper $ruleLevelHelper) { $this->phpVersion = $phpVersion; $this->ruleLevelHelper = $ruleLevelHelper; } public function getNodeType() : string { return ClassConstFetch::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->name instanceof Node\Expr) { return []; } if (!$this->phpVersion->supportsDynamicClassConstantFetch()) { return [RuleErrorBuilder::message('Fetching class constants with a dynamic name is supported only on PHP 8.3 and later.')->identifier('classConstant.dynamicFetch')->nonIgnorable()->build()]; } $typeResult = $this->ruleLevelHelper->findTypeToCheck($scope, $node->name, '', static function (Type $type) : bool { return $type->isString()->yes(); }); $type = $typeResult->getType(); if ($type instanceof ErrorType) { return []; } if ($type->isString()->yes()) { return []; } return [RuleErrorBuilder::message(sprintf('Class constant name in dynamic fetch can only be a string, %s given.', $type->describe(VerbosityLevel::typeOnly())))->identifier('classConstant.nameType')->build()]; } } */ final class ConstantRule implements Rule { public function getNodeType() : string { return Node\Expr\ConstFetch::class; } public function processNode(Node $node, Scope $scope) : array { if (!$scope->hasConstant($node->name)) { return [RuleErrorBuilder::message(sprintf('Constant %s not found.', (string) $node->name))->identifier('constant.notFound')->discoveringSymbolsTip()->build()]; } return []; } } */ final class ValueAssignedToClassConstantRule implements Rule { public function getNodeType() : string { return Node\Stmt\ClassConst::class; } public function processNode(Node $node, Scope $scope) : array { if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } $nativeType = null; if ($node->type !== null) { $nativeType = ParserNodeTypeToPHPStanType::resolve($node->type, $scope->getClassReflection()); } $errors = []; foreach ($node->consts as $const) { $constantName = $const->name->toString(); $errors = array_merge($errors, $this->processSingleConstant($scope->getClassReflection(), $constantName, $scope->getType($const->value), $nativeType)); } return $errors; } /** * @return list */ private function processSingleConstant(ClassReflection $classReflection, string $constantName, Type $valueExprType, ?Type $nativeType) : array { $constantReflection = $classReflection->getConstant($constantName); $phpDocType = $constantReflection->getPhpDocType(); if ($phpDocType === null) { if ($nativeType === null) { return []; } $accepts = $nativeType->acceptsWithReason($valueExprType, \true); if ($accepts->yes()) { return []; } return [RuleErrorBuilder::message(sprintf('Constant %s::%s (%s) does not accept value %s.', $constantReflection->getDeclaringClass()->getDisplayName(), $constantName, $nativeType->describe(VerbosityLevel::typeOnly()), $valueExprType->describe(VerbosityLevel::value())))->acceptsReasonsTip($accepts->reasons)->nonIgnorable()->identifier('classConstant.value')->build()]; } elseif ($nativeType === null) { $isSuperType = $phpDocType->isSuperTypeOf($valueExprType); $verbosity = VerbosityLevel::getRecommendedLevelByType($phpDocType, $valueExprType); if ($isSuperType->no()) { return [RuleErrorBuilder::message(sprintf('PHPDoc tag @var for constant %s::%s with type %s is incompatible with value %s.', $constantReflection->getDeclaringClass()->getDisplayName(), $constantName, $phpDocType->describe($verbosity), $valueExprType->describe(VerbosityLevel::value())))->identifier('classConstant.phpDocType')->build()]; } elseif ($isSuperType->maybe()) { return [RuleErrorBuilder::message(sprintf('PHPDoc tag @var for constant %s::%s with type %s is not subtype of value %s.', $constantReflection->getDeclaringClass()->getDisplayName(), $constantName, $phpDocType->describe($verbosity), $valueExprType->describe(VerbosityLevel::value())))->identifier('classConstant.phpDocType')->build()]; } return []; } $type = $constantReflection->getValueType(); $accepts = $type->acceptsWithReason($valueExprType, \true); if ($accepts->yes()) { return []; } $verbosity = VerbosityLevel::getRecommendedLevelByType($type, $valueExprType); return [RuleErrorBuilder::message(sprintf('Constant %s::%s (%s) does not accept value %s.', $constantReflection->getDeclaringClass()->getDisplayName(), $constantName, $type->describe(VerbosityLevel::typeOnly()), $valueExprType->describe($verbosity)))->acceptsReasonsTip($accepts->reasons)->identifier('classConstant.value')->build()]; } } */ final class NativeTypedClassConstantRule implements Rule { /** * @var PhpVersion */ private $phpVersion; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function getNodeType() : string { return Node\Stmt\ClassConst::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->type === null) { return []; } if ($this->phpVersion->supportsNativeTypesInClassConstants()) { return []; } return [RuleErrorBuilder::message('Class constants with native types are supported only on PHP 8.3 and later.')->identifier('classConstant.nativeTypeNotSupported')->nonIgnorable()->build()]; } } */ final class OverridingConstantRule implements Rule { /** * @var bool */ private $checkPhpDocMethodSignatures; public function __construct(bool $checkPhpDocMethodSignatures) { $this->checkPhpDocMethodSignatures = $checkPhpDocMethodSignatures; } public function getNodeType() : string { return Node\Stmt\ClassConst::class; } public function processNode(Node $node, Scope $scope) : array { if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } $errors = []; foreach ($node->consts as $const) { $constantName = $const->name->toString(); $errors = array_merge($errors, $this->processSingleConstant($scope->getClassReflection(), $constantName)); } return $errors; } /** * @return list */ private function processSingleConstant(ClassReflection $classReflection, string $constantName) : array { $prototype = $this->findPrototype($classReflection, $constantName); if (!$prototype instanceof ClassConstantReflection) { return []; } $constantReflection = $classReflection->getConstant($constantName); $errors = []; if ($prototype->isFinal()) { $errors[] = RuleErrorBuilder::message(sprintf('Constant %s::%s overrides final constant %s::%s.', $classReflection->getDisplayName(), $constantReflection->getName(), $prototype->getDeclaringClass()->getDisplayName(), $prototype->getName()))->identifier('classConstant.final')->nonIgnorable()->build(); } if ($prototype->isPublic()) { if (!$constantReflection->isPublic()) { $errors[] = RuleErrorBuilder::message(sprintf('%s constant %s::%s overriding public constant %s::%s should also be public.', $constantReflection->isPrivate() ? 'Private' : 'Protected', $constantReflection->getDeclaringClass()->getDisplayName(), $constantReflection->getName(), $prototype->getDeclaringClass()->getDisplayName(), $prototype->getName()))->identifier('classConstant.visibility')->nonIgnorable()->build(); } } elseif ($constantReflection->isPrivate()) { $errors[] = RuleErrorBuilder::message(sprintf('Private constant %s::%s overriding protected constant %s::%s should be protected or public.', $constantReflection->getDeclaringClass()->getDisplayName(), $constantReflection->getName(), $prototype->getDeclaringClass()->getDisplayName(), $prototype->getName()))->identifier('classConstant.visibility')->nonIgnorable()->build(); } if (!$this->checkPhpDocMethodSignatures) { return $errors; } $prototypeNativeType = $prototype->getNativeType(); $constantNativeType = $constantReflection->getNativeType(); if ($prototypeNativeType !== null) { if ($constantNativeType !== null) { if (!$prototypeNativeType->isSuperTypeOf($constantNativeType)->yes()) { $errors[] = RuleErrorBuilder::message(sprintf('Native type %s of constant %s::%s is not covariant with native type %s of constant %s::%s.', $constantNativeType->describe(VerbosityLevel::typeOnly()), $constantReflection->getDeclaringClass()->getDisplayName(), $constantReflection->getName(), $prototypeNativeType->describe(VerbosityLevel::typeOnly()), $prototype->getDeclaringClass()->getDisplayName(), $prototype->getName()))->identifier('classConstant.nativeType')->nonIgnorable()->build(); } } else { $errors[] = RuleErrorBuilder::message(sprintf('Constant %s::%s overriding constant %s::%s (%s) should also have native type %s.', $constantReflection->getDeclaringClass()->getDisplayName(), $constantReflection->getName(), $prototype->getDeclaringClass()->getDisplayName(), $prototype->getName(), $prototypeNativeType->describe(VerbosityLevel::typeOnly()), $prototypeNativeType->describe(VerbosityLevel::typeOnly())))->identifier('classConstant.missingNativeType')->nonIgnorable()->build(); } } if (!$prototype->hasPhpDocType()) { return $errors; } if (!$constantReflection->hasPhpDocType()) { return $errors; } if (!$prototype->getValueType()->isSuperTypeOf($constantReflection->getValueType())->yes()) { $errors[] = RuleErrorBuilder::message(sprintf('Type %s of constant %s::%s is not covariant with type %s of constant %s::%s.', $constantReflection->getValueType()->describe(VerbosityLevel::value()), $constantReflection->getDeclaringClass()->getDisplayName(), $constantReflection->getName(), $prototype->getValueType()->describe(VerbosityLevel::value()), $prototype->getDeclaringClass()->getDisplayName(), $prototype->getName()))->identifier('classConstant.type')->build(); } return $errors; } private function findPrototype(ClassReflection $classReflection, string $constantName) : ?ConstantReflection { foreach ($classReflection->getImmediateInterfaces() as $immediateInterface) { if ($immediateInterface->hasConstant($constantName)) { return $immediateInterface->getConstant($constantName); } } $parentClass = $classReflection->getParentClass(); if ($parentClass === null) { return null; } if (!$parentClass->hasConstant($constantName)) { return null; } $constant = $parentClass->getConstant($constantName); if ($constant->isPrivate()) { return null; } return $constant; } } */ final class FinalConstantRule implements Rule { /** * @var PhpVersion */ private $phpVersion; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function getNodeType() : string { return ClassConst::class; } public function processNode(Node $node, Scope $scope) : array { if (!$node->isFinal()) { return []; } if ($this->phpVersion->supportsFinalConstants()) { return []; } return [RuleErrorBuilder::message('Final class constants are supported only on PHP 8.1 and later.')->identifier('classConstant.finalNotSupported')->nonIgnorable()->build()]; } } */ final class MissingClassConstantTypehintRule implements Rule { /** * @var MissingTypehintCheck */ private $missingTypehintCheck; public function __construct(MissingTypehintCheck $missingTypehintCheck) { $this->missingTypehintCheck = $missingTypehintCheck; } public function getNodeType() : string { return Node\Stmt\ClassConst::class; } public function processNode(Node $node, Scope $scope) : array { if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } $errors = []; foreach ($node->consts as $const) { $constantName = $const->name->toString(); $errors = array_merge($errors, $this->processSingleConstant($scope->getClassReflection(), $constantName)); } return $errors; } /** * @return list */ private function processSingleConstant(ClassReflection $classReflection, string $constantName) : array { $constantReflection = $classReflection->getConstant($constantName); $constantType = $constantReflection->getPhpDocType(); if ($constantType === null) { return []; } $errors = []; foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($constantType) as $iterableType) { $iterableTypeDescription = $iterableType->describe(VerbosityLevel::typeOnly()); $errors[] = RuleErrorBuilder::message(sprintf('Constant %s::%s type has no value type specified in iterable type %s.', $constantReflection->getDeclaringClass()->getDisplayName(), $constantName, $iterableTypeDescription))->tip(MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP)->identifier('missingType.iterableValue')->build(); } foreach ($this->missingTypehintCheck->getNonGenericObjectTypesWithGenericClass($constantType) as [$name, $genericTypeNames]) { $errors[] = RuleErrorBuilder::message(sprintf('Constant %s::%s with generic %s does not specify its types: %s', $constantReflection->getDeclaringClass()->getDisplayName(), $constantName, $name, $genericTypeNames))->identifier('missingType.generics')->build(); } foreach ($this->missingTypehintCheck->getCallablesWithMissingSignature($constantType) as $callableType) { $errors[] = RuleErrorBuilder::message(sprintf('Constant %s::%s type has no signature specified for %s.', $constantReflection->getDeclaringClass()->getDisplayName(), $constantName, $callableType->describe(VerbosityLevel::typeOnly())))->identifier('missingType.callable')->build(); } return $errors; } } */ final class ConstantsInTraitsRule implements Rule { /** * @var PhpVersion */ private $phpVersion; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function getNodeType() : string { return Node\Stmt\ClassConst::class; } /** * @param Node\Stmt\ClassConst $node */ public function processNode(Node $node, Scope $scope) : array { if ($this->phpVersion->supportsConstantsInTraits()) { return []; } if (!$scope->isInTrait()) { return []; } return [RuleErrorBuilder::message('Constant is declared inside a trait but is only supported on PHP 8.2 and later.')->identifier('classConstant.inTrait')->nonIgnorable()->build()]; } } */ final class NotAnalysedTraitRule implements Rule { public function getNodeType() : string { return CollectedDataNode::class; } public function processNode(Node $node, Scope $scope) : array { if ($node->isOnlyFilesAnalysis()) { return []; } $traitDeclarationData = $node->get(\PHPStan\Rules\Traits\TraitDeclarationCollector::class); $traitUseData = $node->get(\PHPStan\Rules\Traits\TraitUseCollector::class); $declaredTraits = []; foreach ($traitDeclarationData as $file => $declaration) { foreach ($declaration as [$name, $line]) { $declaredTraits[strtolower($name)] = [$file, $name, $line]; } } foreach ($traitUseData as $usedNamesData) { foreach ($usedNamesData as $usedNames) { foreach ($usedNames as $usedName) { unset($declaredTraits[strtolower($usedName)]); } } } $errors = []; foreach ($declaredTraits as [$file, $name, $line]) { $errors[] = RuleErrorBuilder::message(sprintf('Trait %s is used zero times and is not analysed.', $name))->file($file)->line($line)->identifier('trait.unused')->tip('See: https://phpstan.org/blog/how-phpstan-analyses-traits')->build(); } return $errors; } } */ final class TraitDeclarationCollector implements Collector { public function getNodeType() : string { return Node\Stmt\Trait_::class; } public function processNode(Node $node, Scope $scope) { if ($node->namespacedName === null) { return null; } return [$node->namespacedName->toString(), $node->getStartLine()]; } } */ final class ConflictingTraitConstantsRule implements Rule { /** * @var InitializerExprTypeResolver */ private $initializerExprTypeResolver; public function __construct(InitializerExprTypeResolver $initializerExprTypeResolver) { $this->initializerExprTypeResolver = $initializerExprTypeResolver; } public function getNodeType() : string { return Node\Stmt\ClassConst::class; } public function processNode(Node $node, Scope $scope) : array { if (!$scope->isInClass()) { return []; } $classReflection = $scope->getClassReflection(); $traitConstants = []; foreach ($classReflection->getTraits(\true) as $trait) { foreach ($trait->getNativeReflection()->getReflectionConstants() as $constant) { $traitConstants[] = $constant; } } $errors = []; foreach ($node->consts as $const) { foreach ($traitConstants as $traitConstant) { if ($traitConstant->getName() !== $const->name->toString()) { continue; } foreach ($this->processSingleConstant($classReflection, $traitConstant, $node, $const->value) as $error) { $errors[] = $error; } } } return $errors; } /** * @return list */ private function processSingleConstant(ClassReflection $classReflection, ReflectionClassConstant $traitConstant, Node\Stmt\ClassConst $classConst, Node\Expr $valueExpr) : array { $errors = []; if ($traitConstant->isPublic()) { if ($classConst->isProtected()) { $errors[] = RuleErrorBuilder::message(sprintf('Protected constant %s::%s overriding public constant %s::%s should also be public.', $classReflection->getDisplayName(), $traitConstant->getName(), $traitConstant->getDeclaringClass()->getName(), $traitConstant->getName()))->nonIgnorable()->identifier('classConstant.visibility')->build(); } elseif ($classConst->isPrivate()) { $errors[] = RuleErrorBuilder::message(sprintf('Private constant %s::%s overriding public constant %s::%s should also be public.', $classReflection->getDisplayName(), $traitConstant->getName(), $traitConstant->getDeclaringClass()->getName(), $traitConstant->getName()))->nonIgnorable()->identifier('classConstant.visibility')->build(); } } elseif ($traitConstant->isProtected()) { if ($classConst->isPublic()) { $errors[] = RuleErrorBuilder::message(sprintf('Public constant %s::%s overriding protected constant %s::%s should also be protected.', $classReflection->getDisplayName(), $traitConstant->getName(), $traitConstant->getDeclaringClass()->getName(), $traitConstant->getName()))->nonIgnorable()->identifier('classConstant.visibility')->build(); } elseif ($classConst->isPrivate()) { $errors[] = RuleErrorBuilder::message(sprintf('Private constant %s::%s overriding protected constant %s::%s should also be protected.', $classReflection->getDisplayName(), $traitConstant->getName(), $traitConstant->getDeclaringClass()->getName(), $traitConstant->getName()))->nonIgnorable()->identifier('classConstant.visibility')->build(); } } elseif ($traitConstant->isPrivate()) { if ($classConst->isPublic()) { $errors[] = RuleErrorBuilder::message(sprintf('Public constant %s::%s overriding private constant %s::%s should also be private.', $classReflection->getDisplayName(), $traitConstant->getName(), $traitConstant->getDeclaringClass()->getName(), $traitConstant->getName()))->nonIgnorable()->identifier('classConstant.visibility')->build(); } elseif ($classConst->isProtected()) { $errors[] = RuleErrorBuilder::message(sprintf('Protected constant %s::%s overriding private constant %s::%s should also be private.', $classReflection->getDisplayName(), $traitConstant->getName(), $traitConstant->getDeclaringClass()->getName(), $traitConstant->getName()))->nonIgnorable()->identifier('classConstant.visibility')->build(); } } if ($traitConstant->isFinal()) { if (!$classConst->isFinal()) { $errors[] = RuleErrorBuilder::message(sprintf('Non-final constant %s::%s overriding final constant %s::%s should also be final.', $classReflection->getDisplayName(), $traitConstant->getName(), $traitConstant->getDeclaringClass()->getName(), $traitConstant->getName()))->nonIgnorable()->identifier('classConstant.nonFinal')->build(); } } elseif ($classConst->isFinal()) { $errors[] = RuleErrorBuilder::message(sprintf('Final constant %s::%s overriding non-final constant %s::%s should also be non-final.', $classReflection->getDisplayName(), $traitConstant->getName(), $traitConstant->getDeclaringClass()->getName(), $traitConstant->getName()))->nonIgnorable()->identifier('classConstant.final')->build(); } $traitNativeType = $traitConstant->getType(); $constantNativeType = $classConst->type; $traitDeclaringClass = $traitConstant->getDeclaringClass(); if ($traitNativeType === null) { if ($constantNativeType !== null) { $constantNativeTypeType = ParserNodeTypeToPHPStanType::resolve($constantNativeType, $classReflection); $errors[] = RuleErrorBuilder::message(sprintf('Constant %s::%s (%s) overriding constant %s::%s should not have a native type.', $classReflection->getDisplayName(), $traitConstant->getName(), $constantNativeTypeType->describe(VerbosityLevel::typeOnly()), $traitConstant->getDeclaringClass()->getName(), $traitConstant->getName()))->nonIgnorable()->identifier('classConstant.nativeType')->build(); } } elseif ($constantNativeType === null) { $traitNativeTypeType = TypehintHelper::decideTypeFromReflection($traitNativeType, null, $traitDeclaringClass->getName()); $errors[] = RuleErrorBuilder::message(sprintf('Constant %s::%s overriding constant %s::%s (%s) should also have native type %s.', $classReflection->getDisplayName(), $traitConstant->getName(), $traitConstant->getDeclaringClass()->getName(), $traitConstant->getName(), $traitNativeTypeType->describe(VerbosityLevel::typeOnly()), $traitNativeTypeType->describe(VerbosityLevel::typeOnly())))->nonIgnorable()->identifier('classConstant.missingNativeType')->build(); } else { $traitNativeTypeType = TypehintHelper::decideTypeFromReflection($traitNativeType, null, $traitDeclaringClass->getName()); $constantNativeTypeType = ParserNodeTypeToPHPStanType::resolve($constantNativeType, $classReflection); if (!$traitNativeTypeType->equals($constantNativeTypeType)) { $errors[] = RuleErrorBuilder::message(sprintf('Constant %s::%s (%s) overriding constant %s::%s (%s) should have the same native type %s.', $classReflection->getDisplayName(), $traitConstant->getName(), $constantNativeTypeType->describe(VerbosityLevel::typeOnly()), $traitConstant->getDeclaringClass()->getName(), $traitConstant->getName(), $traitNativeTypeType->describe(VerbosityLevel::typeOnly()), $traitNativeTypeType->describe(VerbosityLevel::typeOnly())))->nonIgnorable()->identifier('classConstant.nativeType')->build(); } } $classConstantValueType = $this->initializerExprTypeResolver->getType($valueExpr, InitializerExprContext::fromClassReflection($classReflection)); $traitConstantValueType = $this->initializerExprTypeResolver->getType($traitConstant->getValueExpression(), InitializerExprContext::fromClass($traitDeclaringClass->getName(), $traitDeclaringClass->getFileName() !== \false ? $traitDeclaringClass->getFileName() : null)); if (!$classConstantValueType->equals($traitConstantValueType)) { $errors[] = RuleErrorBuilder::message(sprintf('Constant %s::%s with value %s overriding constant %s::%s with different value %s should have the same value.', $classReflection->getDisplayName(), $traitConstant->getName(), $classConstantValueType->describe(VerbosityLevel::value()), $traitConstant->getDeclaringClass()->getName(), $traitConstant->getName(), $traitConstantValueType->describe(VerbosityLevel::value())))->nonIgnorable()->identifier('classConstant.value')->build(); } return $errors; } } > */ final class TraitUseCollector implements Collector { public function getNodeType() : string { return Node\Stmt\TraitUse::class; } /** * @return list */ public function processNode(Node $node, Scope $scope) : array { return array_values(array_map(static function (Node\Name $traitName) { return $traitName->toString(); }, $node->traits)); } } reflectionProvider = $reflectionProvider; } /** * @param string[] $parameterNames * @param Node[] $statements * @param 'constructor.unusedParameter'|'closure.unusedUse' $identifier * @return list */ public function getUnusedParameters(Scope $scope, array $parameterNames, array $statements, string $unusedParameterMessage, string $identifier) : array { $unusedParameters = array_fill_keys($parameterNames, \true); foreach ($this->getUsedVariables($scope, $statements) as $variableName) { if (!isset($unusedParameters[$variableName])) { continue; } unset($unusedParameters[$variableName]); } $errors = []; foreach (array_keys($unusedParameters) as $name) { $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($unusedParameterMessage, $name))->identifier($identifier)->build(); } return $errors; } /** * @param Node[]|Node|scalar|null $node * @return string[] */ private function getUsedVariables(Scope $scope, $node) : array { $variableNames = []; if ($node instanceof Node) { if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name) { $functionName = $this->reflectionProvider->resolveFunctionName($node->name, $scope); if ($functionName === 'func_get_args' || $functionName === 'get_defined_vars') { return $scope->getDefinedVariables(); } } if ($node instanceof Node\Expr\Variable && is_string($node->name) && $node->name !== 'this') { return [$node->name]; } if ($node instanceof Node\Expr\ClosureUse && is_string($node->var->name)) { return [$node->var->name]; } if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name && (string) $node->name === 'compact') { foreach ($node->getArgs() as $arg) { $argType = $scope->getType($arg->value); if (!$argType instanceof ConstantStringType) { continue; } $variableNames[] = $argType->getValue(); } } foreach ($node->getSubNodeNames() as $subNodeName) { if ($node instanceof Node\Expr\Closure && $subNodeName !== 'uses') { continue; } $subNode = $node->{$subNodeName}; $variableNames = array_merge($variableNames, $this->getUsedVariables($scope, $subNode)); } } elseif (is_array($node)) { foreach ($node as $subNode) { $variableNames = array_merge($variableNames, $this->getUsedVariables($scope, $subNode)); } } return $variableNames; } } reflectionProvider = $reflectionProvider; $this->checkNullables = $checkNullables; $this->checkThisOnly = $checkThisOnly; $this->checkUnionTypes = $checkUnionTypes; $this->checkExplicitMixed = $checkExplicitMixed; $this->checkImplicitMixed = $checkImplicitMixed; $this->newRuleLevelHelper = $newRuleLevelHelper; $this->checkBenevolentUnionTypes = $checkBenevolentUnionTypes; } /** @api */ public function isThis(Expr $expression) : bool { return $expression instanceof Expr\Variable && $expression->name === 'this'; } /** @api */ public function accepts(Type $acceptingType, Type $acceptedType, bool $strictTypes) : bool { return $this->acceptsWithReason($acceptingType, $acceptedType, $strictTypes)->result; } private function transformCommonType(Type $type) : Type { if (!$this->checkExplicitMixed && !$this->checkImplicitMixed) { return $type; } return TypeTraverser::map($type, function (Type $type, callable $traverse) { if ($type instanceof TemplateMixedType) { if (!$this->newRuleLevelHelper) { return $type->toStrictMixedType(); } if ($this->checkExplicitMixed) { return $type->toStrictMixedType(); } } if ($type instanceof MixedType && ($type->isExplicitMixed() && $this->checkExplicitMixed || !$type->isExplicitMixed() && $this->checkImplicitMixed)) { return new StrictMixedType(); } return $traverse($type); }); } /** * @return array{Type, bool} */ private function transformAcceptedType(Type $acceptingType, Type $acceptedType) : array { $checkForUnion = $this->checkUnionTypes; $acceptedType = TypeTraverser::map($acceptedType, function (Type $acceptedType, callable $traverse) use($acceptingType, &$checkForUnion) : Type { if ($acceptedType instanceof CallableType) { if ($acceptedType->isCommonCallable()) { return $acceptedType; } return new CallableType($acceptedType->getParameters(), $traverse($this->transformCommonType($acceptedType->getReturnType())), $acceptedType->isVariadic(), $acceptedType->getTemplateTypeMap(), $acceptedType->getResolvedTemplateTypeMap(), $acceptedType->getTemplateTags(), $acceptedType->isPure()); } if ($acceptedType instanceof ClosureType) { if ($acceptedType->isCommonCallable()) { return $acceptedType; } return new ClosureType($acceptedType->getParameters(), $traverse($this->transformCommonType($acceptedType->getReturnType())), $acceptedType->isVariadic(), $acceptedType->getTemplateTypeMap(), $acceptedType->getResolvedTemplateTypeMap(), $acceptedType->getCallSiteVarianceMap(), $acceptedType->getTemplateTags(), $acceptedType->getThrowPoints(), $acceptedType->getImpurePoints(), $acceptedType->getInvalidateExpressions(), $acceptedType->getUsedVariables(), $acceptedType->acceptsNamedArguments()); } if (!$this->checkNullables && !$acceptingType instanceof NullType && !$acceptedType instanceof NullType && !$acceptedType instanceof BenevolentUnionType) { return $traverse(TypeCombinator::removeNull($acceptedType)); } if ($this->checkBenevolentUnionTypes) { if ($acceptedType instanceof BenevolentUnionType) { $checkForUnion = \true; return $traverse(TypeUtils::toStrictUnion($acceptedType)); } } return $traverse($this->transformCommonType($acceptedType)); }); return [$acceptedType, $checkForUnion]; } public function acceptsWithReason(Type $acceptingType, Type $acceptedType, bool $strictTypes) : \PHPStan\Rules\RuleLevelHelperAcceptsResult { if ($this->newRuleLevelHelper) { [$acceptedType, $checkForUnion] = $this->transformAcceptedType($acceptingType, $acceptedType); $acceptingType = $this->transformCommonType($acceptingType); $accepts = $acceptingType->acceptsWithReason($acceptedType, $strictTypes); return new \PHPStan\Rules\RuleLevelHelperAcceptsResult($checkForUnion ? $accepts->yes() : !$accepts->no(), $accepts->reasons); } $checkForUnion = $this->checkUnionTypes; if ($this->checkBenevolentUnionTypes) { $traverse = static function (Type $type, callable $traverse) use(&$checkForUnion) : Type { if ($type instanceof BenevolentUnionType) { $checkForUnion = \true; return TypeUtils::toStrictUnion($type); } return $traverse($type); }; $acceptedType = TypeTraverser::map($acceptedType, $traverse); } if ($this->checkExplicitMixed) { $traverse = static function (Type $type, callable $traverse) : Type { if ($type instanceof TemplateMixedType) { return $type->toStrictMixedType(); } if ($type instanceof MixedType && $type->isExplicitMixed()) { return new StrictMixedType(); } return $traverse($type); }; $acceptingType = TypeTraverser::map($acceptingType, $traverse); $acceptedType = TypeTraverser::map($acceptedType, $traverse); } if ($this->checkImplicitMixed) { $traverse = static function (Type $type, callable $traverse) : Type { if ($type instanceof TemplateMixedType) { return $type->toStrictMixedType(); } if ($type instanceof MixedType && !$type->isExplicitMixed()) { return new StrictMixedType(); } return $traverse($type); }; $acceptingType = TypeTraverser::map($acceptingType, $traverse); $acceptedType = TypeTraverser::map($acceptedType, $traverse); } if (!$this->checkNullables && !$acceptingType instanceof NullType && !$acceptedType instanceof NullType && !$acceptedType instanceof BenevolentUnionType) { $acceptedType = TypeCombinator::removeNull($acceptedType); } $accepts = $acceptingType->acceptsWithReason($acceptedType, $strictTypes); if ($accepts->yes()) { return new \PHPStan\Rules\RuleLevelHelperAcceptsResult(\true, $accepts->reasons); } if ($acceptingType instanceof UnionType) { $reasons = []; foreach ($acceptingType->getTypes() as $innerType) { $accepts = self::acceptsWithReason($innerType, $acceptedType, $strictTypes); if ($accepts->result) { return $accepts; } $reasons = array_merge($reasons, $accepts->reasons); } return new \PHPStan\Rules\RuleLevelHelperAcceptsResult(\false, $reasons); } if ($acceptedType->isArray()->yes() && $acceptingType->isArray()->yes() && ($acceptedType->isConstantArray()->no() || !$acceptedType->isIterableAtLeastOnce()->no()) && $acceptingType->isConstantArray()->no()) { if ($acceptingType->isIterableAtLeastOnce()->yes() && !$acceptedType->isIterableAtLeastOnce()->yes()) { $verbosity = VerbosityLevel::getRecommendedLevelByType($acceptingType, $acceptedType); return new \PHPStan\Rules\RuleLevelHelperAcceptsResult(\false, [sprintf('%s %s empty.', $acceptedType->describe($verbosity), $acceptedType->isIterableAtLeastOnce()->no() ? 'is' : 'might be')]); } if ($acceptingType->isList()->yes() && !$acceptedType->isList()->yes()) { $report = $checkForUnion || $acceptedType->isList()->no(); if ($report) { $verbosity = VerbosityLevel::getRecommendedLevelByType($acceptingType, $acceptedType); return new \PHPStan\Rules\RuleLevelHelperAcceptsResult(\false, [sprintf('%s %s a list.', $acceptedType->describe($verbosity), $acceptedType->isList()->no() ? 'is not' : 'might not be')]); } } return self::acceptsWithReason($acceptingType->getIterableKeyType(), $acceptedType->getIterableKeyType(), $strictTypes)->and(self::acceptsWithReason($acceptingType->getIterableValueType(), $acceptedType->getIterableValueType(), $strictTypes)); } return new \PHPStan\Rules\RuleLevelHelperAcceptsResult($checkForUnion ? $accepts->yes() : !$accepts->no(), $accepts->reasons); } /** * @api * @param callable(Type $type): bool $unionTypeCriteriaCallback */ public function findTypeToCheck(Scope $scope, Expr $var, string $unknownClassErrorPattern, callable $unionTypeCriteriaCallback) : \PHPStan\Rules\FoundTypeResult { if ($this->checkThisOnly && !$this->isThis($var)) { return new \PHPStan\Rules\FoundTypeResult(new ErrorType(), [], [], null); } $type = $scope->getType($var); return $this->findTypeToCheckImplementation($scope, $var, $type, $unknownClassErrorPattern, $unionTypeCriteriaCallback, \true); } /** @param callable(Type $type): bool $unionTypeCriteriaCallback */ private function findTypeToCheckImplementation(Scope $scope, Expr $var, Type $type, string $unknownClassErrorPattern, callable $unionTypeCriteriaCallback, bool $isTopLevel = \false) : \PHPStan\Rules\FoundTypeResult { if (!$this->checkNullables && !$type->isNull()->yes()) { $type = TypeCombinator::removeNull($type); } if ($this->newRuleLevelHelper) { if (($this->checkExplicitMixed || $this->checkImplicitMixed) && $type instanceof MixedType && ($type->isExplicitMixed() ? $this->checkExplicitMixed : $this->checkImplicitMixed)) { return new \PHPStan\Rules\FoundTypeResult($type instanceof TemplateMixedType ? $type->toStrictMixedType() : new StrictMixedType(), [], [], null); } } else { if ($this->checkExplicitMixed && $type instanceof MixedType && !$type instanceof TemplateMixedType && $type->isExplicitMixed()) { return new \PHPStan\Rules\FoundTypeResult(new StrictMixedType(), [], [], null); } if ($this->checkImplicitMixed && $type instanceof MixedType && !$type instanceof TemplateMixedType && !$type->isExplicitMixed()) { return new \PHPStan\Rules\FoundTypeResult(new StrictMixedType(), [], [], null); } } if ($type instanceof MixedType || $type instanceof NeverType) { return new \PHPStan\Rules\FoundTypeResult(new ErrorType(), [], [], null); } if (!$this->newRuleLevelHelper) { if ($isTopLevel && $type instanceof StaticType) { $type = $type->getStaticObjectType(); } } $errors = []; $hasClassExistsClass = \false; $directClassNames = []; if ($isTopLevel) { $directClassNames = $type->getObjectClassNames(); foreach ($directClassNames as $referencedClass) { if ($this->reflectionProvider->hasClass($referencedClass)) { $classReflection = $this->reflectionProvider->getClass($referencedClass); if (!$classReflection->isTrait()) { continue; } } if ($scope->isInClassExists($referencedClass)) { $hasClassExistsClass = \true; continue; } $errors[] = \PHPStan\Rules\RuleErrorBuilder::message(sprintf($unknownClassErrorPattern, $referencedClass))->line($var->getStartLine())->identifier('class.notFound')->discoveringSymbolsTip()->build(); } } if (count($errors) > 0 || $hasClassExistsClass) { return new \PHPStan\Rules\FoundTypeResult(new ErrorType(), [], $errors, null); } if (!$this->checkUnionTypes && $type instanceof ObjectWithoutClassType) { return new \PHPStan\Rules\FoundTypeResult(new ErrorType(), [], [], null); } if ($this->newRuleLevelHelper) { if ($type instanceof UnionType) { $shouldFilterUnion = !$this->checkUnionTypes && !$type instanceof BenevolentUnionType || !$this->checkBenevolentUnionTypes && $type instanceof BenevolentUnionType; $newTypes = []; foreach ($type->getTypes() as $innerType) { if ($shouldFilterUnion && !$unionTypeCriteriaCallback($innerType)) { continue; } $newTypes[] = $this->findTypeToCheckImplementation($scope, $var, $innerType, $unknownClassErrorPattern, $unionTypeCriteriaCallback)->getType(); } if (count($newTypes) > 0) { $newUnion = TypeCombinator::union(...$newTypes); if (!$this->checkBenevolentUnionTypes && $type instanceof BenevolentUnionType) { $newUnion = TypeUtils::toBenevolentUnion($newUnion); } return new \PHPStan\Rules\FoundTypeResult($newUnion, $directClassNames, [], null); } } if ($type instanceof IntersectionType) { $newTypes = []; foreach ($type->getTypes() as $innerType) { $newTypes[] = $this->findTypeToCheckImplementation($scope, $var, $innerType, $unknownClassErrorPattern, $unionTypeCriteriaCallback)->getType(); } return new \PHPStan\Rules\FoundTypeResult(TypeCombinator::intersect(...$newTypes), $directClassNames, [], null); } } else { if (!$this->checkUnionTypes && $type instanceof UnionType && !$type instanceof BenevolentUnionType || !$this->checkBenevolentUnionTypes && $type instanceof BenevolentUnionType) { $newTypes = []; foreach ($type->getTypes() as $innerType) { if (!$unionTypeCriteriaCallback($innerType)) { continue; } $newTypes[] = $innerType; } if (count($newTypes) > 0) { return new \PHPStan\Rules\FoundTypeResult(TypeCombinator::union(...$newTypes), $directClassNames, [], null); } } } $tip = null; if ($type instanceof UnionType && count($type->getTypes()) === 2 && $type->getTypes()[0] instanceof ObjectType && $type->getTypes()[1] instanceof ObjectType && $type->getTypes()[0]->getClassName() === 'PhpParser\\Node\\Arg' && $type->getTypes()[1]->getClassName() === 'PhpParser\\Node\\VariadicPlaceholder' && !$unionTypeCriteriaCallback($type)) { $tip = 'Use ->getArgs() instead of ->args.'; } return new \PHPStan\Rules\FoundTypeResult($type, $directClassNames, [], $tip); } } container = $container; } public function create() : \PHPStan\Collectors\Registry { return new \PHPStan\Collectors\Registry($this->container->getServicesByTag(self::COLLECTOR_TAG)); } } collectors[$collector->getNodeType()][] = $collector; } } /** * @template TNodeType of Node * @param class-string $nodeType * @return array> */ public function getCollectors(string $nodeType) : array { if (!isset($this->cache[$nodeType])) { $parentNodeTypes = [$nodeType] + class_parents($nodeType) + class_implements($nodeType); $collectors = []; foreach ($parentNodeTypes as $parentNodeType) { foreach ($this->collectors[$parentNodeType] ?? [] as $collector) { $collectors[] = $collector; } } $this->cache[$nodeType] = $collectors; } /** * @var array> $selectedCollectors */ $selectedCollectors = $this->cache[$nodeType]; return $selectedCollectors; } } */ public function getNodeType() : string; /** * @param TNodeType $node * @return TValue|null Collected data */ public function processNode(Node $node, Scope $scope); } > */ private $collectorType; /** * @param mixed $data * @param class-string> $collectorType */ public function __construct($data, string $filePath, string $collectorType) { $this->data = $data; $this->filePath = $filePath; $this->collectorType = $collectorType; } /** * @return mixed */ public function getData() { return $this->data; } public function getFilePath() : string { return $this->filePath; } public function changeFilePath(string $newFilePath) : self { return new self($this->data, $newFilePath, $this->collectorType); } /** * @return class-string> */ public function getCollectorType() : string { return $this->collectorType; } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['data' => $this->data, 'filePath' => $this->filePath, 'collectorType' => $this->collectorType]; } /** * @param mixed[] $json */ public static function decode(array $json) : self { return new self($json['data'], $json['filePath'], $json['collectorType']); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self { return new self($properties['data'], $properties['filePath'], $properties['collectorType']); } } noImplicitWildcard = $noImplicitWildcard; foreach ($analyseExcludes as $exclude) { $len = strlen($exclude); $trailingDirSeparator = $len > 0 && in_array($exclude[$len - 1], ['\\', '/'], \true); $normalized = $fileHelper->normalizePath($exclude); if ($trailingDirSeparator) { $normalized .= DIRECTORY_SEPARATOR; } if (self::isFnmatchPattern($normalized)) { $this->fnmatchAnalyseExcludes[] = $normalized; } else { if ($this->noImplicitWildcard) { if (is_file($normalized)) { $this->literalAnalyseFilesExcludes[] = $normalized; } elseif (is_dir($normalized)) { if (!$trailingDirSeparator) { $normalized .= DIRECTORY_SEPARATOR; } $this->literalAnalyseDirectoryExcludes[] = $normalized; } } else { $this->literalAnalyseExcludes[] = $fileHelper->absolutizePath($normalized); } } } $isWindows = DIRECTORY_SEPARATOR === '\\'; if ($isWindows) { $this->fnmatchFlags = FNM_NOESCAPE | FNM_CASEFOLD; } else { $this->fnmatchFlags = 0; } } public function isExcludedFromAnalysing(string $file) : bool { foreach ($this->literalAnalyseExcludes as $exclude) { if (str_starts_with($file, $exclude)) { return \true; } } if ($this->noImplicitWildcard) { foreach ($this->literalAnalyseDirectoryExcludes as $exclude) { if (str_starts_with($file, $exclude)) { return \true; } } foreach ($this->literalAnalyseFilesExcludes as $exclude) { if ($file === $exclude) { return \true; } } } foreach ($this->fnmatchAnalyseExcludes as $exclude) { if (fnmatch($exclude, $file, $this->fnmatchFlags)) { return \true; } } return \false; } public static function isAbsolutePath(string $path) : bool { if (DIRECTORY_SEPARATOR === '/') { if (str_starts_with($path, '/')) { return \true; } } elseif (substr($path, 1, 1) === ':') { return \true; } return \false; } public static function isFnmatchPattern(string $path) : bool { return preg_match('~[*?[\\]]~', $path) > 0; } } files = $files; $this->onlyFiles = $onlyFiles; } /** * @return string[] */ public function getFiles() : array { return $this->files; } public function isOnlyFiles() : bool { return $this->onlyFiles; } } |null */ private $fileHashes = null; /** @var array|null */ private $filePaths = null; /** * @param string[] $analysedPaths * @param string[] $analysedPathsFromConfig * @param string[] $scanFiles * @param string[] $scanDirectories */ public function __construct(\PHPStan\File\FileFinder $analyseFileFinder, \PHPStan\File\FileFinder $scanFileFinder, array $analysedPaths, array $analysedPathsFromConfig, array $scanFiles, array $scanDirectories) { $this->analyseFileFinder = $analyseFileFinder; $this->scanFileFinder = $scanFileFinder; $this->analysedPaths = $analysedPaths; $this->analysedPathsFromConfig = $analysedPathsFromConfig; $this->scanFiles = $scanFiles; $this->scanDirectories = $scanDirectories; } /** * @param array $filePaths */ public function initialize(array $filePaths) : void { $finderResult = $this->analyseFileFinder->findFiles($this->analysedPaths); $fileHashes = []; foreach (array_unique(array_merge($finderResult->getFiles(), $filePaths, $this->getScannedFiles($finderResult->getFiles()))) as $filePath) { $fileHashes[$filePath] = $this->getFileHash($filePath); } $this->fileHashes = $fileHashes; $this->filePaths = $filePaths; } public function getChanges() : \PHPStan\File\FileMonitorResult { if ($this->fileHashes === null || $this->filePaths === null) { throw new ShouldNotHappenException(); } $finderResult = $this->analyseFileFinder->findFiles($this->analysedPaths); $oldFileHashes = $this->fileHashes; $fileHashes = []; $newFiles = []; $changedFiles = []; $deletedFiles = []; $filePaths = array_unique(array_merge($finderResult->getFiles(), $this->filePaths, $this->getScannedFiles($finderResult->getFiles()))); foreach ($filePaths as $filePath) { if (!array_key_exists($filePath, $oldFileHashes)) { $newFiles[] = $filePath; $fileHashes[$filePath] = $this->getFileHash($filePath); continue; } $oldHash = $oldFileHashes[$filePath]; unset($oldFileHashes[$filePath]); $newHash = $this->getFileHash($filePath); $fileHashes[$filePath] = $newHash; if ($oldHash === $newHash) { continue; } $changedFiles[] = $filePath; } $this->fileHashes = $fileHashes; foreach (array_keys($oldFileHashes) as $file) { $deletedFiles[] = $file; } return new \PHPStan\File\FileMonitorResult($newFiles, $changedFiles, $deletedFiles, count($fileHashes)); } private function getFileHash(string $filePath) : string { $hash = sha1_file($filePath); if ($hash === \false) { throw new \PHPStan\File\CouldNotReadFileException($filePath); } return $hash; } /** * @param string[] $allAnalysedFiles * @return array */ private function getScannedFiles(array $allAnalysedFiles) : array { $scannedFiles = $this->scanFiles; $analysedDirectories = []; foreach (array_merge($this->analysedPaths, $this->analysedPathsFromConfig) as $analysedPath) { if (is_file($analysedPath)) { continue; } if (!is_dir($analysedPath)) { continue; } $analysedDirectories[] = $analysedPath; } $directories = array_unique(array_merge($analysedDirectories, $this->scanDirectories)); foreach ($this->scanFileFinder->findFiles($directories)->getFiles() as $file) { $scannedFiles[] = $file; } return array_diff($scannedFiles, $allAnalysedFiles); } } fallbackRelativePathHelper = $fallbackRelativePathHelper; if ($directorySeparator === null) { $directorySeparator = DIRECTORY_SEPARATOR; } $this->directorySeparator = $directorySeparator; $pathBeginning = null; $pathToTrimArray = null; $trimBeginning = static function (string $path) : array { if (str_starts_with($path, '/')) { return ['/', substr($path, 1)]; } elseif (substr($path, 1, 1) === ':') { return [substr($path, 0, 3), substr($path, 3)]; } return ['', $path]; }; if (!in_array($currentWorkingDirectory, ['', '/'], \true) && !(strlen($currentWorkingDirectory) === 3 && substr($currentWorkingDirectory, 1, 1) === ':')) { [$pathBeginning, $currentWorkingDirectory] = $trimBeginning($currentWorkingDirectory); $pathToTrimArray = explode($directorySeparator, $currentWorkingDirectory); } foreach ($analysedPaths as $pathNumber => $path) { [$tempPathBeginning, $path] = $trimBeginning($path); $pathArray = explode($directorySeparator, $path); $pathTempParts = []; $pathArraySize = count($pathArray); foreach ($pathArray as $i => $pathPart) { if ($i === $pathArraySize - 1 && str_ends_with($pathPart, '.php')) { continue; } if (!isset($pathToTrimArray[$i])) { if ($pathNumber !== 0) { $pathToTrimArray = $pathTempParts; continue 2; } } elseif ($pathToTrimArray[$i] !== $pathPart) { $pathToTrimArray = $pathTempParts; continue 2; } $pathTempParts[] = $pathPart; } $pathBeginning = $tempPathBeginning; $pathToTrimArray = $pathTempParts; } if ($pathToTrimArray === null || count($pathToTrimArray) === 0) { return; } $pathToTrim = $pathBeginning . implode($directorySeparator, $pathToTrimArray); $realPathToTrim = realpath($pathToTrim); if ($realPathToTrim !== \false) { $pathToTrim = $realPathToTrim; } $this->pathToTrim = $pathToTrim; } public function getRelativePath(string $filename) : string { if ($this->pathToTrim !== null && str_starts_with($filename, $this->pathToTrim)) { return ltrim(substr($filename, strlen($this->pathToTrim)), $this->directorySeparator); } return $this->fallbackRelativePathHelper->getRelativePath($filename); } } parentDirectory = $parentDirectory; } public function getRelativePath(string $filename) : string { return implode('/', $this->getFilenameParts($filename)); } /** * @return string[] */ public function getFilenameParts(string $filename) : array { $schemePosition = strpos($filename, '://'); if ($schemePosition !== \false) { $filename = substr($filename, $schemePosition + 3); } $parentParts = explode('/', trim(str_replace('\\', '/', $this->parentDirectory), '/')); $parentPartsCount = count($parentParts); $filenameParts = explode('/', trim(str_replace('\\', '/', $filename), '/')); $filenamePartsCount = count($filenameParts); $i = 0; for (; $i < $filenamePartsCount; $i++) { if ($parentPartsCount < $i + 1) { break; } $parentPath = implode('/', array_slice($parentParts, 0, $i + 1)); $filenamePath = implode('/', array_slice($filenameParts, 0, $i + 1)); if ($parentPath !== $filenamePath) { break; } } if ($i === 0) { return [$filename]; } $dotsCount = $parentPartsCount - $i; if ($dotsCount < 0) { throw new ShouldNotHappenException(); } return array_merge(array_fill(0, $dotsCount, '..'), array_slice($filenameParts, $i)); } } fileHelper = $fileHelper; } public function getRelativePath(string $filename) : string { $cwd = $this->fileHelper->getWorkingDirectory(); if ($cwd !== '' && str_starts_with($filename, $cwd)) { return substr($filename, strlen($cwd) + 1); } return $filename; } } currentWorkingDirectory = $currentWorkingDirectory; } public function getRelativePath(string $filename) : string { if ($this->currentWorkingDirectory !== '' && str_starts_with($filename, $this->currentWorkingDirectory)) { return str_replace('\\', '/', substr($filename, strlen($this->currentWorkingDirectory) + 1)); } return str_replace('\\', '/', $filename); } } , analyseAndScan?: array}|null */ private $excludePaths; /** * @param string[] $obsoleteExcludesAnalyse * @param array{analyse?: array, analyseAndScan?: array}|null $excludePaths */ public function __construct(\PHPStan\File\FileExcluderRawFactory $fileExcluderRawFactory, array $obsoleteExcludesAnalyse, ?array $excludePaths) { $this->fileExcluderRawFactory = $fileExcluderRawFactory; $this->obsoleteExcludesAnalyse = $obsoleteExcludesAnalyse; $this->excludePaths = $excludePaths; } public function createAnalyseFileExcluder() : \PHPStan\File\FileExcluder { if ($this->excludePaths === null) { return $this->fileExcluderRawFactory->create($this->obsoleteExcludesAnalyse); } $paths = []; if (array_key_exists('analyse', $this->excludePaths)) { $paths = $this->excludePaths['analyse']; } if (array_key_exists('analyseAndScan', $this->excludePaths)) { $paths = array_merge($paths, $this->excludePaths['analyseAndScan']); } return $this->fileExcluderRawFactory->create(array_values(array_unique($paths))); } public function createScanFileExcluder() : \PHPStan\File\FileExcluder { if ($this->excludePaths === null) { return $this->fileExcluderRawFactory->create($this->obsoleteExcludesAnalyse); } $paths = []; if (array_key_exists('analyseAndScan', $this->excludePaths)) { $paths = $this->excludePaths['analyseAndScan']; } return $this->fileExcluderRawFactory->create(array_values(array_unique($paths))); } } newFiles = $newFiles; $this->changedFiles = $changedFiles; $this->deletedFiles = $deletedFiles; $this->totalFilesCount = $totalFilesCount; } /** * @return string[] */ public function getChangedFiles() : array { return $this->changedFiles; } public function hasAnyChanges() : bool { return count($this->newFiles) > 0 || count($this->changedFiles) > 0 || count($this->deletedFiles) > 0; } public function getTotalFilesCount() : int { return $this->totalFilesCount; } } fileExcluder = $fileExcluder; $this->fileHelper = $fileHelper; $this->fileExtensions = $fileExtensions; } /** * @param string[] $paths */ public function findFiles(array $paths) : \PHPStan\File\FileFinderResult { $onlyFiles = \true; $files = []; foreach ($paths as $path) { if (is_file($path)) { $files[] = $this->fileHelper->normalizePath($path); } elseif (!file_exists($path)) { throw new \PHPStan\File\PathNotFoundException($path); } else { $finder = new Finder(); $finder->followLinks(); foreach ($finder->files()->name('*.{' . implode(',', $this->fileExtensions) . '}')->in($path) as $fileInfo) { $files[] = $this->fileHelper->normalizePath($fileInfo->getPathname()); $onlyFiles = \false; } } } $files = array_values(array_unique(array_filter($files, function (string $file) : bool { return !$this->fileExcluder->isExcludedFromAnalysing($file); }))); return new \PHPStan\File\FileFinderResult($files, $onlyFiles); } } workingDirectory = $this->normalizePath($workingDirectory); } public function getWorkingDirectory() : string { return $this->workingDirectory; } /** @api */ public function absolutizePath(string $path) : string { if (DIRECTORY_SEPARATOR === '/') { if (str_starts_with($path, '/')) { return $path; } } elseif (substr($path, 1, 1) === ':') { return $path; } if (preg_match('~^[a-z0-9+\\-.]+://~i', $path) === 1) { return $path; } return rtrim($this->getWorkingDirectory(), '/\\') . DIRECTORY_SEPARATOR . ltrim($path, '/\\'); } /** @api */ public function normalizePath(string $originalPath, string $directorySeparator = DIRECTORY_SEPARATOR) : string { $isLocalPath = \false; if ($originalPath !== '') { if ($originalPath[0] === '/') { $isLocalPath = \true; } elseif (strlen($originalPath) >= 3 && $originalPath[1] === ':' && $originalPath[2] === '\\') { // e.g. C:\ $isLocalPath = \true; } } $matches = null; if (!$isLocalPath) { $matches = Strings::match($originalPath, '~^([a-z0-9+\\-.]+)://(.+)$~is'); } if ($matches !== null) { [, $scheme, $path] = $matches; $scheme = strtolower($scheme); } else { $scheme = null; $path = $originalPath; } $path = str_replace(['\\', '//', '///', '////'], '/', $path); $pathRoot = str_starts_with($path, '/') ? $directorySeparator : ''; $pathParts = explode('/', trim($path, '/')); $normalizedPathParts = []; foreach ($pathParts as $pathPart) { if ($pathPart === '.') { continue; } if ($pathPart === '..') { $removedPart = array_pop($normalizedPathParts); if ($scheme === 'phar' && $removedPart !== null && str_ends_with($removedPart, '.phar')) { $scheme = null; } } else { $normalizedPathParts[] = $pathPart; } } return ($scheme !== null ? $scheme . '://' : '') . $pathRoot . implode($directorySeparator, $normalizedPathParts); } } path = $path; parent::__construct(sprintf('Path %s does not exist', $path)); } public function getPath() : string { return $this->path; } } value = $value; } public static function createYes() : self { return self::$registry[self::YES] = self::$registry[self::YES] ?? new self(self::YES); } public static function createNo() : self { return self::$registry[self::NO] = self::$registry[self::NO] ?? new self(self::NO); } public static function createMaybe() : self { return self::$registry[self::MAYBE] = self::$registry[self::MAYBE] ?? new self(self::MAYBE); } public static function createFromBoolean(bool $value) : self { $yesNo = $value ? self::YES : self::NO; return self::$registry[$yesNo] = self::$registry[$yesNo] ?? new self($yesNo); } private static function create(int $value) : self { self::$registry[$value] = self::$registry[$value] ?? new self($value); return self::$registry[$value]; } public function yes() : bool { return $this->value === self::YES; } public function maybe() : bool { return $this->value === self::MAYBE; } public function no() : bool { return $this->value === self::NO; } public function toBooleanType() : BooleanType { if ($this->value === self::MAYBE) { return new BooleanType(); } return new ConstantBooleanType($this->value === self::YES); } public function and(self ...$operands) : self { $operandValues = array_column($operands, 'value'); $operandValues[] = $this->value; return self::create(min($operandValues)); } /** * @template T * @param T[] $objects * @param callable(T): self $callback */ public function lazyAnd(array $objects, callable $callback) : self { if ($this->no()) { return $this; } $results = []; foreach ($objects as $object) { $result = $callback($object); if ($result->no()) { return $result; } $results[] = $result; } return $this->and(...$results); } public function or(self ...$operands) : self { $operandValues = array_column($operands, 'value'); $operandValues[] = $this->value; return self::create(max($operandValues)); } /** * @template T * @param T[] $objects * @param callable(T): self $callback */ public function lazyOr(array $objects, callable $callback) : self { if ($this->yes()) { return $this; } $results = []; foreach ($objects as $object) { $result = $callback($object); if ($result->yes()) { return $result; } $results[] = $result; } return $this->or(...$results); } public static function extremeIdentity(self ...$operands) : self { if ($operands === []) { throw new \PHPStan\ShouldNotHappenException(); } $operandValues = array_column($operands, 'value'); $min = min($operandValues); $max = max($operandValues); return self::create($min === $max ? $min : self::MAYBE); } /** * @template T * @param T[] $objects * @param callable(T): self $callback */ public static function lazyExtremeIdentity(array $objects, callable $callback) : self { if ($objects === []) { throw new \PHPStan\ShouldNotHappenException(); } $lastResult = null; foreach ($objects as $object) { $result = $callback($object); if ($lastResult === null) { $lastResult = $result; continue; } if ($lastResult->equals($result)) { continue; } return self::createMaybe(); } return $lastResult; } public static function maxMin(self ...$operands) : self { if ($operands === []) { throw new \PHPStan\ShouldNotHappenException(); } $operandValues = array_column($operands, 'value'); return self::create(max($operandValues) > 0 ? 1 : min($operandValues)); } /** * @template T * @param T[] $objects * @param callable(T): self $callback */ public static function lazyMaxMin(array $objects, callable $callback) : self { $results = []; foreach ($objects as $object) { $result = $callback($object); if ($result->yes()) { return $result; } $results[] = $result; } return self::maxMin(...$results); } public function negate() : self { return self::create(-$this->value); } public function equals(self $other) : bool { return $this === $other; } public function compareTo(self $other) : ?self { if ($this->value > $other->value) { return $this; } elseif ($other->value > $this->value) { return $other; } return null; } public function describe() : string { static $labels = [self::NO => 'No', self::MAYBE => 'Maybe', self::YES => 'Yes']; return $labels[$this->value]; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self { return self::create($properties['value']); } } wrappedParser = $wrappedParser; $this->traverser = new NodeTraverser(); $this->traverser->addVisitor(new \PHPStan\Parser\CleaningVisitor()); $this->traverser->addVisitor(new \PHPStan\Parser\RemoveUnusedCodeByPhpVersionIdVisitor($phpVersion->getVersionString())); } public function parseFile(string $file) : array { return $this->clean($this->wrappedParser->parseFile($file)); } public function parseString(string $sourceCode) : array { return $this->clean($this->wrappedParser->parseString($sourceCode)); } /** * @param Stmt[] $ast * @return Stmt[] */ private function clean(array $ast) : array { /** @var Stmt[] */ return $this->traverser->traverse($ast); } } parser = $parser; $this->nameResolver = $nameResolver; } /** * @param string $file path to a file to parse * @return Node\Stmt[] */ public function parseFile(string $file) : array { try { return $this->parseString(FileReader::read($file)); } catch (\PHPStan\Parser\ParserErrorsException $e) { throw new \PHPStan\Parser\ParserErrorsException($e->getErrors(), $file); } } /** * @return Node\Stmt[] */ public function parseString(string $sourceCode) : array { $errorHandler = new Collecting(); $nodes = $this->parser->parse($sourceCode, $errorHandler); if ($errorHandler->hasErrors()) { throw new \PHPStan\Parser\ParserErrorsException($errorHandler->getErrors(), null); } if ($nodes === null) { throw new ShouldNotHappenException(); } $nodeTraverser = new NodeTraverser(); $nodeTraverser->addVisitor($this->nameResolver); /** @var array */ return $nodeTraverser->traverse($nodes); } } nodeFinder = new NodeFinder(); } public function enterNode(Node $node) : ?Node { if ($node instanceof Node\Stmt\Function_) { $node->stmts = $this->keepVariadicsAndYields($node->stmts); return $node; } if ($node instanceof Node\Stmt\ClassMethod && $node->stmts !== null) { $node->stmts = $this->keepVariadicsAndYields($node->stmts); return $node; } if ($node instanceof Node\Expr\Closure) { $node->stmts = $this->keepVariadicsAndYields($node->stmts); return $node; } return null; } /** * @param Node\Stmt[] $stmts * @return Node\Stmt[] */ private function keepVariadicsAndYields(array $stmts) : array { $results = $this->nodeFinder->find($stmts, static function (Node $node) : bool { if ($node instanceof Node\Expr\YieldFrom || $node instanceof Node\Expr\Yield_) { return \true; } if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name) { return in_array($node->name->toLowerString(), ParametersAcceptor::VARIADIC_FUNCTIONS, \true); } if ($node instanceof Node\Expr\Closure || $node instanceof Node\Expr\ArrowFunction) { return \true; } return \false; }); $newStmts = []; foreach ($results as $result) { if ($result instanceof Node\Expr\Yield_ || $result instanceof Node\Expr\YieldFrom || $result instanceof Node\Expr\Closure || $result instanceof Node\Expr\ArrowFunction) { $newStmts[] = new Node\Stmt\Expression($result); continue; } if (!$result instanceof Node\Expr\FuncCall) { continue; } $newStmts[] = new Node\Stmt\Expression(new Node\Expr\FuncCall(new Node\Name\FullyQualified('func_get_args'))); } return $newStmts; } } depth = 0; return null; } public function enterNode(Node $node) : ?Node { if ($node instanceof Node\Expr\Instanceof_ && $this->depth > 0) { $node->setAttribute(self::ATTRIBUTE_NAME, \true); return null; } if ($node instanceof Node\Expr\StaticCall && $node->class instanceof Node\Name && $node->class->toLowerString() === 'phpstan\\type\\typetraverser' && $node->name instanceof Node\Identifier && $node->name->toLowerString() === 'map') { $this->depth++; } return null; } public function leaveNode(Node $node) : ?Node { if ($node instanceof Node\Expr\StaticCall && $node->class instanceof Node\Name && $node->class->toLowerString() === 'phpstan\\type\\typetraverser' && $node->name instanceof Node\Identifier && $node->name->toLowerString() === 'map') { $this->depth--; } return null; } } name instanceof Node\Expr\Closure) { $node->name->setAttribute(self::ATTRIBUTE_NAME, \true); } return null; } } isFirstClassCallable()) { return null; } if ($node->name instanceof Node\Expr\Assign && $node->name->expr instanceof Node\Expr\Closure) { $closure = $node->name->expr; } elseif ($node->name instanceof Node\Expr\Closure) { $closure = $node->name; } else { return null; } $args = $node->getArgs(); if (count($args) > 0) { $closure->setAttribute(self::ATTRIBUTE_NAME, $args); } return null; } } */ public $traits = []; public function enterNode(Node $node) : ?Node { if (!$node instanceof Node\Stmt\Trait_) { return null; } $this->traits[] = $node; return null; } } errors = $errors; $this->parsedFile = $parsedFile; parent::__construct(implode(', ', array_map(static function (Error $error) : string { return $error->getRawMessage(); }, $errors))); if (count($errors) > 0) { $this->attributes = $errors[0]->getAttributes(); } else { $this->attributes = []; } } /** * @return Error[] */ public function getErrors() : array { return $this->errors; } public function getParsedFile() : ?string { return $this->parsedFile; } /** * @return mixed[] */ public function getAttributes() : array { return $this->attributes; } } |null> */ private $typeStack = []; public function beforeTraverse(array $nodes) : ?array { $this->typeStack = []; return null; } public function enterNode(Node $node) : ?Node { if ($node instanceof Node\Stmt || $node instanceof Node\Expr\Match_) { if (count($this->typeStack) > 0) { $node->setAttribute(self::ATTRIBUTE_NAME, $this->typeStack[count($this->typeStack) - 1]); } } if ($node instanceof Node\FunctionLike) { $this->typeStack[] = null; } if ($node instanceof Node\Stmt\TryCatch) { $types = []; foreach (array_reverse($this->typeStack) as $stackTypes) { if ($stackTypes === null) { break; } foreach ($stackTypes as $type) { $types[] = $type; } } foreach ($node->catches as $catch) { foreach ($catch->types as $type) { $types[] = $type->toString(); } } $this->typeStack[] = $types; } return null; } public function leaveNode(Node $node) : ?Node { if (!$node instanceof Node\Stmt\TryCatch && !$node instanceof Node\FunctionLike) { return null; } array_pop($this->typeStack); return null; } } > */ private $typeStack = []; public function beforeTraverse(array $nodes) : ?array { $this->typeStack = []; return null; } public function enterNode(Node $node) : ?Node { if (!$node instanceof Node\Stmt && !$node instanceof Node\Expr\Closure) { return null; } if (count($this->typeStack) > 0) { $node->setAttribute(self::ATTRIBUTE_NAME, $this->typeStack); } $this->typeStack[] = get_class($node); return null; } public function leaveNode(Node $node) : ?Node { if (!$node instanceof Node\Stmt && !$node instanceof Node\Expr\Closure) { return null; } array_pop($this->typeStack); return null; } } > */ private $nodesPerLine = []; public function beforeTraverse(array $nodes) : ?array { $this->nodesPerLine = []; return null; } public function enterNode(Node $node) : ?Node { if (!$node instanceof Node\Stmt\Class_ || !$node->isAnonymous()) { return null; } $node = AnonymousClassNode::createFromClassNode($node); $node->setAttribute('anonymousClass', \true); // We keep this for backward compatibility $this->nodesPerLine[$node->getStartLine()][] = $node; return $node; } public function afterTraverse(array $nodes) : ?array { foreach ($this->nodesPerLine as $nodesOnLine) { if (count($nodesOnLine) === 1) { continue; } for ($i = 0; $i < count($nodesOnLine); $i++) { $nodesOnLine[$i]->setAttribute(self::ATTRIBUTE_LINE_INDEX, $i + 1); } } $this->nodesPerLine = []; return null; } } var instanceof Node\Expr\PropertyFetch || $node->var instanceof Node\Expr\StaticPropertyFetch) && $node->expr instanceof Node\Expr\New_) { $node->expr->setAttribute(self::ATTRIBUTE_NAME, $node->var); } } return null; } } name instanceof Node\Name) { $functionName = $node->name->toLowerString(); if ($functionName === 'curl_setopt') { $args = $node->getRawArgs(); if (isset($args[0])) { $args[0]->setAttribute(self::ATTRIBUTE_NAME, \true); } } } return null; } } class instanceof Node\Name && $node->class->toLowerString() === 'closure' && $node->name instanceof Identifier && $node->name->toLowerString() === 'bind' && !$node->isFirstClassCallable()) { $args = $node->getArgs(); if (count($args) > 1) { $args[0]->setAttribute(self::ATTRIBUTE_NAME, \true); } } return null; } } */ private $cachedNodesByString = []; /** * @var int */ private $cachedNodesByStringCount = 0; /** @var array */ private $parsedByString = []; public function __construct(\PHPStan\Parser\Parser $originalParser, int $cachedNodesByStringCountMax) { $this->originalParser = $originalParser; $this->cachedNodesByStringCountMax = $cachedNodesByStringCountMax; } /** * @param string $file path to a file to parse * @return Node\Stmt[] */ public function parseFile(string $file) : array { if ($this->cachedNodesByStringCountMax !== 0 && $this->cachedNodesByStringCount >= $this->cachedNodesByStringCountMax) { $this->cachedNodesByString = array_slice($this->cachedNodesByString, 1, null, \true); --$this->cachedNodesByStringCount; } $sourceCode = FileReader::read($file); if (!isset($this->cachedNodesByString[$sourceCode]) || isset($this->parsedByString[$sourceCode])) { $this->cachedNodesByString[$sourceCode] = $this->originalParser->parseFile($file); $this->cachedNodesByStringCount++; unset($this->parsedByString[$sourceCode]); } return $this->cachedNodesByString[$sourceCode]; } /** * @return Node\Stmt[] */ public function parseString(string $sourceCode) : array { if ($this->cachedNodesByStringCountMax !== 0 && $this->cachedNodesByStringCount >= $this->cachedNodesByStringCountMax) { $this->cachedNodesByString = array_slice($this->cachedNodesByString, 1, null, \true); --$this->cachedNodesByStringCount; } if (!isset($this->cachedNodesByString[$sourceCode])) { $this->cachedNodesByString[$sourceCode] = $this->originalParser->parseString($sourceCode); $this->cachedNodesByStringCount++; $this->parsedByString[$sourceCode] = \true; } return $this->cachedNodesByString[$sourceCode]; } public function getCachedNodesByStringCount() : int { return $this->cachedNodesByStringCount; } public function getCachedNodesByStringCountMax() : int { return $this->cachedNodesByStringCountMax; } /** * @return array */ public function getCachedNodesByString() : array { return $this->cachedNodesByString; } } findFunctionCallInStatements($functionNames, $statement); if ($result !== null) { return $result; } } if (!$statement instanceof Node) { continue; } if ($statement instanceof FuncCall && $statement->name instanceof Name) { if (in_array((string) $statement->name, $functionNames, \true)) { return $statement; } } $result = $this->findFunctionCallInStatements($functionNames, $statement); if ($result !== null) { return $result; } } return null; } } isFirstStatement = \true; return null; } public function enterNode(Node $node) : ?Node { // ignore shebang if ($this->isFirstStatement && $node instanceof Node\Stmt\InlineHTML && str_starts_with($node->value, '#!')) { return null; } if ($node instanceof Node\Stmt) { if ($node instanceof Node\Stmt\Declare_) { $node->setAttribute(self::ATTRIBUTE_NAME, $this->isFirstStatement); } $this->isFirstStatement = \false; } return null; } } name instanceof Node\Name) { $functionName = $node->name->toLowerString(); if ($functionName === 'array_walk') { $args = $node->getRawArgs(); if (isset($args[0])) { $args[0]->setAttribute(self::ATTRIBUTE_NAME, \true); } } } return null; } } name instanceof Node\Name) { $functionName = $node->name->toLowerString(); if (in_array($functionName, ['array_all', 'array_any', 'array_find', 'array_find_key'], \true)) { $args = $node->getRawArgs(); if (isset($args[0])) { $args[0]->setAttribute(self::ATTRIBUTE_NAME, \true); } } } return null; } } wrappedParser = $wrappedParser; } /** * @return Node\Stmt[] */ public function parse(string $code, ?ErrorHandler $errorHandler = null) : array { try { return $this->wrappedParser->parseString($code); } catch (\PHPStan\Parser\ParserErrorsException $e) { $message = $e->getMessage(); if ($e->getParsedFile() !== null) { $message .= sprintf(' in file %s', $e->getParsedFile()); } throw new Error($message, $e->getAttributes()); } } } default instanceof Node\Scalar\MagicConst) { $node->default->setAttribute(self::ATTRIBUTE_NAME, \true); } return null; } } name instanceof Node\Name) { $functionName = $node->name->toLowerString(); if ($functionName === 'array_filter') { $args = $node->getRawArgs(); if (isset($args[0])) { $args[0]->setAttribute(self::ATTRIBUTE_NAME, \true); } } } return null; } } isFirstClassCallable()) { return null; } if ($node->name instanceof Node\Expr\Assign && $node->name->expr instanceof Node\Expr\ArrowFunction) { $arrow = $node->name->expr; } elseif ($node->name instanceof Node\Expr\ArrowFunction) { $arrow = $node->name; } else { return null; } $args = $node->getArgs(); if (count($args) > 0) { $arrow->setAttribute(self::ATTRIBUTE_NAME, $args); } return null; } } elseifs !== []) { $lastElseIf = count($node->elseifs) - 1; $elseIsMissingOrThrowing = $node->else === null || count($node->else->stmts) === 1 && $node->else->stmts[0] instanceof Node\Stmt\Throw_; foreach ($node->elseifs as $i => $elseif) { $isLast = $i === $lastElseIf && $elseIsMissingOrThrowing; $elseif->cond->setAttribute(self::ATTRIBUTE_NAME, $isLast); } } if ($node instanceof Node\Expr\Match_ && $node->arms !== []) { $lastArm = count($node->arms) - 1; foreach ($node->arms as $i => $arm) { if ($arm->conds === null || $arm->conds === []) { continue; } $isLast = $i === $lastArm; $index = count($arm->conds) - 1; $arm->conds[$index]->setAttribute(self::ATTRIBUTE_NAME, $isLast); $arm->conds[$index]->setAttribute(self::ATTRIBUTE_IS_MATCH_NAME, \true); } } if ($node instanceof Node\Stmt\Function_ || $node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Stmt\If_ || $node instanceof Node\Stmt\ElseIf_ || $node instanceof Node\Stmt\Else_ || $node instanceof Node\Stmt\Case_ || $node instanceof Node\Stmt\Catch_ || $node instanceof Node\Stmt\Do_ || $node instanceof Node\Stmt\Finally_ || $node instanceof Node\Stmt\For_ || $node instanceof Node\Stmt\Foreach_ || $node instanceof Node\Stmt\Namespace_ || $node instanceof Node\Stmt\TryCatch || $node instanceof Node\Stmt\While_) { $statements = $node->stmts ?? []; $statementCount = count($statements); if ($statementCount < 2) { return null; } if (!$statements[$statementCount - 1] instanceof Node\Stmt\Throw_) { return null; } if (!$statements[$statementCount - 2] instanceof Node\Stmt\If_ || $statements[$statementCount - 2]->else !== null) { return null; } $if = $statements[$statementCount - 2]; $cond = count($if->elseifs) > 0 ? $if->elseifs[count($if->elseifs) - 1]->cond : $if->cond; $cond->setAttribute(self::ATTRIBUTE_NAME, \true); } return null; } } parser = $parser; $this->lexer = $lexer; $this->nameResolver = $nameResolver; $this->container = $container; $this->ignoreLexer = $ignoreLexer; $this->enableIgnoreErrorsWithinPhpDocs = $enableIgnoreErrorsWithinPhpDocs; } /** * @param string $file path to a file to parse * @return Node\Stmt[] */ public function parseFile(string $file) : array { try { return $this->parseString(FileReader::read($file)); } catch (\PHPStan\Parser\ParserErrorsException $e) { throw new \PHPStan\Parser\ParserErrorsException($e->getErrors(), $file); } } /** * @return Node\Stmt[] */ public function parseString(string $sourceCode) : array { $errorHandler = new Collecting(); $nodes = $this->parser->parse($sourceCode, $errorHandler); /** @var list $tokens */ $tokens = $this->lexer->getTokens(); if ($errorHandler->hasErrors()) { throw new \PHPStan\Parser\ParserErrorsException($errorHandler->getErrors(), null); } if ($nodes === null) { throw new ShouldNotHappenException(); } $nodeTraverser = new NodeTraverser(); $nodeTraverser->addVisitor($this->nameResolver); $traitCollectingVisitor = new \PHPStan\Parser\TraitCollectingVisitor(); $nodeTraverser->addVisitor($traitCollectingVisitor); foreach ($this->container->getServicesByTag(self::VISITOR_SERVICE_TAG) as $visitor) { $nodeTraverser->addVisitor($visitor); } /** @var array */ $nodes = $nodeTraverser->traverse($nodes); ['lines' => $linesToIgnore, 'errors' => $ignoreParseErrors] = $this->getLinesToIgnore($tokens); if (isset($nodes[0])) { $nodes[0]->setAttribute('linesToIgnore', $linesToIgnore); if (count($ignoreParseErrors) > 0) { $nodes[0]->setAttribute('linesToIgnoreParseErrors', $ignoreParseErrors); } } foreach ($traitCollectingVisitor->traits as $trait) { $preexisting = $trait->getAttribute('linesToIgnore', []); $filteredLinesToIgnore = array_filter($linesToIgnore, static function (int $line) use($trait) : bool { return $line >= $trait->getStartLine() && $line <= $trait->getEndLine(); }, ARRAY_FILTER_USE_KEY); foreach ($preexisting as $line => $ignores) { $filteredLinesToIgnore[$line] = $ignores; } $trait->setAttribute('linesToIgnore', $filteredLinesToIgnore); } return $nodes; } /** * @param list $tokens * @return array{lines: array|null>, errors: array>} */ private function getLinesToIgnore(array $tokens) : array { $lines = []; $previousToken = null; $pendingToken = null; $errors = []; foreach ($tokens as $token) { if (is_string($token)) { continue; } $type = $token[0]; $line = $token[2]; if ($type !== T_COMMENT && $type !== T_DOC_COMMENT) { if ($type !== T_WHITESPACE) { if ($pendingToken !== null) { [$pendingText, $pendingIgnorePos, $tokenLine, $pendingLine] = $pendingToken; try { $identifiers = $this->parseIdentifiers($pendingText, $pendingIgnorePos); } catch (IgnoreParseException $e) { $errors[] = [$tokenLine + $e->getPhpDocLine(), $e->getMessage()]; $pendingToken = null; continue; } if ($line !== $pendingLine + 1) { $lineToAdd = $pendingLine; } else { $lineToAdd = $line; } foreach ($identifiers as $identifier) { $lines[$lineToAdd][] = $identifier; } $pendingToken = null; } $previousToken = $token; } continue; } $text = $token[1]; $isNextLine = str_contains($text, '@phpstan-ignore-next-line'); $isCurrentLine = str_contains($text, '@phpstan-ignore-line'); if ($this->enableIgnoreErrorsWithinPhpDocs && $type === T_DOC_COMMENT) { $lines += $this->getLinesToIgnoreForTokenByIgnoreComment($text, $line, '@phpstan-ignore-line'); if ($isNextLine) { $pattern = sprintf('~%s~si', implode('|', [self::PHPDOC_TAG_REGEX, self::PHPDOC_DOCTRINE_TAG_REGEX])); $r = preg_match_all($pattern, $text, $pregMatches, PREG_OFFSET_CAPTURE); if ($r !== \false) { $c = count($pregMatches[0]); if ($c > 0) { [$lastMatchTag, $lastMatchOffset] = $pregMatches[0][$c - 1]; if ($lastMatchTag === '@phpstan-ignore-next-line') { // this will let us ignore errors outside of PHPDoc // and also cut off the PHPDoc text before the last tag $lineToIgnore = $line + 1 + substr_count($text, "\n"); $lines[$lineToIgnore] = null; $text = substr($text, 0, $lastMatchOffset); } } } $lines += $this->getLinesToIgnoreForTokenByIgnoreComment($text, $line, '@phpstan-ignore-next-line', \true); } if ($isNextLine || $isCurrentLine) { continue; } } else { if ($isNextLine) { $line++; } if ($isNextLine || $isCurrentLine) { $line += substr_count($token[1], "\n"); $lines[$line] = null; continue; } } $ignorePos = strpos($text, '@phpstan-ignore'); if ($ignorePos === \false) { continue; } $ignoreLine = substr_count(substr($text, 0, $ignorePos), "\n") - 1; if ($previousToken !== null && $previousToken[2] === $line) { try { foreach ($this->parseIdentifiers($text, $ignorePos) as $identifier) { $lines[$line][] = $identifier; } } catch (IgnoreParseException $e) { $errors[] = [$token[2] + $e->getPhpDocLine() + $ignoreLine, $e->getMessage()]; } continue; } $line += substr_count($token[1], "\n"); $pendingToken = [$text, $ignorePos, $token[2] + $ignoreLine, $line]; } if ($pendingToken !== null) { [$pendingText, $pendingIgnorePos, $tokenLine, $pendingLine] = $pendingToken; try { foreach ($this->parseIdentifiers($pendingText, $pendingIgnorePos) as $identifier) { $lines[$pendingLine][] = $identifier; } } catch (IgnoreParseException $e) { $errors[] = [$tokenLine + $e->getPhpDocLine(), $e->getMessage()]; } } $processedErrors = []; foreach ($errors as [$line, $message]) { $processedErrors[$line][] = $message; } return ['lines' => $lines, 'errors' => $processedErrors]; } /** * @return array */ private function getLinesToIgnoreForTokenByIgnoreComment(string $tokenText, int $tokenLine, string $ignoreComment, bool $ignoreNextLine = \false) : array { $lines = []; $positionsOfIgnoreComment = []; $offset = 0; while (($pos = strpos($tokenText, $ignoreComment, $offset)) !== \false) { $positionsOfIgnoreComment[] = $pos; $offset = $pos + 1; } foreach ($positionsOfIgnoreComment as $pos) { $line = $tokenLine + substr_count(substr($tokenText, 0, $pos), "\n") + ($ignoreNextLine ? 1 : 0); $lines[$line] = null; } return $lines; } /** * @return non-empty-list * @throws IgnoreParseException */ private function parseIdentifiers(string $text, int $ignorePos) : array { $text = substr($text, $ignorePos + strlen('@phpstan-ignore')); $originalTokens = $this->ignoreLexer->tokenize($text); $tokens = []; foreach ($originalTokens as $originalToken) { if ($originalToken[IgnoreLexer::TYPE_OFFSET] === IgnoreLexer::TOKEN_WHITESPACE) { continue; } $tokens[] = $originalToken; } $c = count($tokens); $identifiers = []; $openParenthesisCount = 0; $expected = [IgnoreLexer::TOKEN_IDENTIFIER]; for ($i = 0; $i < $c; $i++) { $lastTokenTypeLabel = isset($tokenType) ? $this->ignoreLexer->getLabel($tokenType) : '@phpstan-ignore'; [IgnoreLexer::VALUE_OFFSET => $content, IgnoreLexer::TYPE_OFFSET => $tokenType, IgnoreLexer::LINE_OFFSET => $tokenLine] = $tokens[$i]; if ($expected !== null && !in_array($tokenType, $expected, \true)) { $tokenTypeLabel = $this->ignoreLexer->getLabel($tokenType); $otherTokenContent = $tokenType === IgnoreLexer::TOKEN_OTHER ? sprintf(" '%s'", $content) : ''; $expectedLabels = implode(' or ', array_map(function ($token) { return $this->ignoreLexer->getLabel($token); }, $expected)); throw new IgnoreParseException(sprintf('Unexpected %s%s after %s, expected %s', $tokenTypeLabel, $otherTokenContent, $lastTokenTypeLabel, $expectedLabels), $tokenLine); } if ($tokenType === IgnoreLexer::TOKEN_OPEN_PARENTHESIS) { $openParenthesisCount++; $expected = null; continue; } if ($tokenType === IgnoreLexer::TOKEN_CLOSE_PARENTHESIS) { $openParenthesisCount--; if ($openParenthesisCount === 0) { $expected = [IgnoreLexer::TOKEN_COMMA, IgnoreLexer::TOKEN_END]; } continue; } if ($openParenthesisCount > 0) { continue; // waiting for comment end } if ($tokenType === IgnoreLexer::TOKEN_IDENTIFIER) { $identifiers[] = $content; $expected = [IgnoreLexer::TOKEN_COMMA, IgnoreLexer::TOKEN_END, IgnoreLexer::TOKEN_OPEN_PARENTHESIS]; continue; } if ($tokenType === IgnoreLexer::TOKEN_COMMA) { $expected = [IgnoreLexer::TOKEN_IDENTIFIER]; continue; } } if ($openParenthesisCount > 0) { throw new IgnoreParseException('Unexpected end, unclosed opening parenthesis', $tokenLine ?? 1); } if (count($identifiers) === 0) { throw new IgnoreParseException('Missing identifier', 1); } return $identifiers; } } ['comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos', 'startFilePos', 'endFilePos']]; public function __construct(PhpVersion $phpVersion) { $this->phpVersion = $phpVersion; } public function create() : Lexer { $options = self::OPTIONS; if ($this->phpVersion->getVersionId() === PHP_VERSION_ID) { return new Lexer($options); } $options['phpVersion'] = $this->phpVersion->getVersionString(); return new Lexer\Emulative($options); } public function createEmulative() : Lexer\Emulative { return new Lexer\Emulative(self::OPTIONS); } } name instanceof Node\Name && !$node->isFirstClassCallable()) { $functionName = $node->name->toLowerString(); if ($functionName === 'array_map') { $args = $node->getArgs(); if (isset($args[0])) { $slicedArgs = array_slice($args, 1); if (count($slicedArgs) > 0) { $args[0]->value->setAttribute(self::ATTRIBUTE_NAME, $slicedArgs); } } } } return null; } } name instanceof Identifier && $node->name->toLowerString() === 'bindto' && !$node->isFirstClassCallable()) { $args = $node->getArgs(); if (isset($args[0])) { $args[0]->setAttribute(self::ATTRIBUTE_NAME, $node->var); } } return null; } } phpVersionString = $phpVersionString; } public function enterNode(Node $node) : ?Node { if (!$node instanceof Node\Stmt\If_) { return null; } if (count($node->elseifs) > 0) { return null; } if ($node->else === null) { return null; } $cond = $node->cond; if (!$cond instanceof Node\Expr\BinaryOp\Smaller && !$cond instanceof Node\Expr\BinaryOp\SmallerOrEqual && !$cond instanceof Node\Expr\BinaryOp\Greater && !$cond instanceof Node\Expr\BinaryOp\GreaterOrEqual && !$cond instanceof Node\Expr\BinaryOp\Equal && !$cond instanceof Node\Expr\BinaryOp\NotEqual && !$cond instanceof Node\Expr\BinaryOp\Identical && !$cond instanceof Node\Expr\BinaryOp\NotIdentical) { return null; } $operator = $cond->getOperatorSigil(); if ($operator === '===') { $operator = '=='; } elseif ($operator === '!==') { $operator = '!='; } $operands = $this->getOperands($cond->left, $cond->right); if ($operands === null) { return null; } $result = version_compare($operands[0], $operands[1], $operator); if ($result) { // remove else $node->cond = new Node\Expr\ConstFetch(new Node\Name('true')); $node->else = null; return $node; } // remove if $node->cond = new Node\Expr\ConstFetch(new Node\Name('false')); $node->stmts = []; return $node; } /** * @return array{string, string}|null */ private function getOperands(Node\Expr $left, Node\Expr $right) : ?array { if ($left instanceof Node\Scalar\LNumber && $right instanceof Node\Expr\ConstFetch && $right->name->toString() === 'PHP_VERSION_ID') { return [(new PhpVersion($left->value))->getVersionString(), $this->phpVersionString]; } if ($right instanceof Node\Scalar\LNumber && $left instanceof Node\Expr\ConstFetch && $left->name->toString() === 'PHP_VERSION_ID') { return [$this->phpVersionString, (new PhpVersion($right->value))->getVersionString()]; } return null; } } bool(true) */ private $analysedFiles = []; public function __construct(FileHelper $fileHelper, \PHPStan\Parser\Parser $currentPhpVersionRichParser, \PHPStan\Parser\Parser $currentPhpVersionSimpleParser, \PHPStan\Parser\Parser $php8Parser, ?string $singleReflectionFile) { $this->fileHelper = $fileHelper; $this->currentPhpVersionRichParser = $currentPhpVersionRichParser; $this->currentPhpVersionSimpleParser = $currentPhpVersionSimpleParser; $this->php8Parser = $php8Parser; $this->singleReflectionFile = $singleReflectionFile !== null ? $fileHelper->normalizePath($singleReflectionFile) : null; } /** * @param string[] $files */ public function setAnalysedFiles(array $files) : void { $this->analysedFiles = array_fill_keys($files, \true); } public function parseFile(string $file) : array { $normalizedPath = $this->fileHelper->normalizePath($file, '/'); if (str_contains($normalizedPath, 'vendor/jetbrains/phpstorm-stubs')) { return $this->php8Parser->parseFile($file); } if (str_contains($normalizedPath, 'vendor/phpstan/php-8-stubs/stubs')) { return $this->php8Parser->parseFile($file); } $file = $this->fileHelper->normalizePath($file); if (!isset($this->analysedFiles[$file]) && $file !== $this->singleReflectionFile) { // check symlinked file that still might be in analysedFiles $pathParts = explode(DIRECTORY_SEPARATOR, $file); for ($i = count($pathParts); $i > 1; $i--) { $joinedPartOfPath = implode(DIRECTORY_SEPARATOR, array_slice($pathParts, 0, $i)); if (!@is_link($joinedPartOfPath)) { continue; } $realFilePath = realpath($file); if ($realFilePath !== \false) { $normalizedRealFilePath = $this->fileHelper->normalizePath($realFilePath); if (isset($this->analysedFiles[$normalizedRealFilePath])) { return $this->currentPhpVersionRichParser->parseFile($file); } } break; } return $this->currentPhpVersionSimpleParser->parseFile($file); } return $this->currentPhpVersionRichParser->parseFile($file); } public function parseString(string $sourceCode) : array { return $this->currentPhpVersionSimpleParser->parseString($sourceCode); } } composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; $this->analysisStartTime = $analysisStartTime; parent::__construct(); } protected function configure() : void { $this->setName(self::NAME)->setDescription('Analyses source code')->setDefinition([new InputArgument('paths', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Paths with source code to run analysis on'), new InputOption('configuration', 'c', InputOption::VALUE_REQUIRED, 'Path to project configuration file'), new InputOption(self::OPTION_LEVEL, 'l', InputOption::VALUE_REQUIRED, 'Level of rule options - the higher the stricter'), new InputOption(\PHPStan\Command\ErrorsConsoleStyle::OPTION_NO_PROGRESS, null, InputOption::VALUE_NONE, 'Do not show progress bar, only results'), new InputOption('debug', null, InputOption::VALUE_NONE, 'Show debug information - which file is analysed, do not catch internal errors'), new InputOption('autoload-file', 'a', InputOption::VALUE_REQUIRED, 'Project\'s additional autoload file path'), new InputOption('error-format', null, InputOption::VALUE_REQUIRED, 'Format in which to print the result of the analysis', null), new InputOption('generate-baseline', 'b', InputOption::VALUE_OPTIONAL, 'Path to a file where the baseline should be saved', \false), new InputOption('allow-empty-baseline', null, InputOption::VALUE_NONE, 'Do not error out when the generated baseline is empty'), new InputOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Memory limit for analysis'), new InputOption('xdebug', null, InputOption::VALUE_NONE, 'Allow running with Xdebug for debugging purposes'), new InputOption('tmp-file', null, InputOption::VALUE_REQUIRED, '(Editor mode) Edited file used in place of --instead-of file'), new InputOption('instead-of', null, InputOption::VALUE_REQUIRED, '(Editor mode) File being replaced by --tmp-file'), new InputOption('fix', null, InputOption::VALUE_NONE, 'Launch PHPStan Pro'), new InputOption('watch', null, InputOption::VALUE_NONE, 'Launch PHPStan Pro'), new InputOption('pro', null, InputOption::VALUE_NONE, 'Launch PHPStan Pro'), new InputOption('fail-without-result-cache', null, InputOption::VALUE_NONE, 'Return non-zero exit code when result cache is not used')]); } /** * @return string[] */ public function getAliases() : array { return ['analyze']; } protected function initialize(InputInterface $input, OutputInterface $output) : void { if ((bool) $input->getOption('debug')) { $application = $this->getApplication(); if ($application === null) { return; } $application->setCatchExceptions(\false); return; } } protected function execute(InputInterface $input, OutputInterface $output) : int { if ($output instanceof ConsoleOutputInterface) { $errorOutput = $output->getErrorOutput(); $errorOutput->writeln(''); $errorOutput->writeln("⚠️ You're running an old version of PHPStan.️"); $errorOutput->writeln(''); $errorOutput->writeln('The last release in the 1.12.x series with new features'); $lastRelease = new DateTimeImmutable('2025-07-17 00:00:00'); $daysSince = (time() - $lastRelease->getTimestamp()) / 60 / 60 / 24; $errorOutput->writeln('and bugfixes was released on July 17th 2025,'); $errorOutput->writeln(sprintf('that\'s %d days ago.', (int) $daysSince)); $errorOutput->writeln(''); $errorOutput->writeln('Since then more than 65 new PHPStan versions were released'); $errorOutput->writeln('with hundreds of new features, bugfixes, and other'); $errorOutput->writeln('quality of life improvements.'); $errorOutput->writeln(''); $errorOutput->writeln("To learn about what you're missing out on, check out"); $errorOutput->writeln('this blog with articles about the latest major releases:'); $errorOutput->writeln('https://phpstan.org/blog'); $errorOutput->writeln(''); $errorOutput->writeln('Upgrade today to PHPStan 2.2 or newer by using'); $errorOutput->writeln('"phpstan/phpstan": "^2.2" in your composer.json.'); $errorOutput->writeln(''); } $paths = $input->getArgument('paths'); $memoryLimit = $input->getOption('memory-limit'); $autoloadFile = $input->getOption('autoload-file'); $configuration = $input->getOption('configuration'); $level = $input->getOption(self::OPTION_LEVEL); $allowXdebug = $input->getOption('xdebug'); $debugEnabled = (bool) $input->getOption('debug'); $fix = (bool) $input->getOption('fix') || (bool) $input->getOption('watch') || (bool) $input->getOption('pro'); $failWithoutResultCache = (bool) $input->getOption('fail-without-result-cache'); /** @var string|false|null $generateBaselineFile */ $generateBaselineFile = $input->getOption('generate-baseline'); if ($generateBaselineFile === \false) { $generateBaselineFile = null; } elseif ($generateBaselineFile === null) { $generateBaselineFile = 'phpstan-baseline.neon'; } $allowEmptyBaseline = (bool) $input->getOption('allow-empty-baseline'); $tmpFile = $input->getOption('tmp-file'); $insteadOfFile = $input->getOption('instead-of'); if (!is_array($paths) || !is_string($memoryLimit) && $memoryLimit !== null || !is_string($autoloadFile) && $autoloadFile !== null || !is_string($configuration) && $configuration !== null || !is_string($level) && $level !== null || !is_string($tmpFile) && $tmpFile !== null || !is_string($insteadOfFile) && $insteadOfFile !== null || !is_bool($allowXdebug)) { throw new ShouldNotHappenException(); } try { $inceptionResult = \PHPStan\Command\CommandHelper::begin($input, $output, $paths, $memoryLimit, $autoloadFile, $this->composerAutoloaderProjectPaths, $configuration, $generateBaselineFile, $level, $allowXdebug, $debugEnabled, $tmpFile, $insteadOfFile); } catch (\PHPStan\Command\InceptionNotSuccessfulException $e) { return 1; } if ($generateBaselineFile === null && $allowEmptyBaseline) { $inceptionResult->getStdOutput()->getStyle()->error('You must pass the --generate-baseline option alongside --allow-empty-baseline.'); return $inceptionResult->handleReturn(1, null, $this->analysisStartTime); } if ($inceptionResult->getEditorModeTmpFile() !== null) { if ($generateBaselineFile !== null) { $inceptionResult->getStdOutput()->getStyle()->error('Editor mode options --tmp-file and --instead-of cannot be used when generating the baseline.'); return $inceptionResult->handleReturn(1, null, $this->analysisStartTime); } if ($fix) { $inceptionResult->getStdOutput()->getStyle()->error('Editor mode options --tmp-file and --instead-of cannot be used with PHPStan Pro.'); return $inceptionResult->handleReturn(1, null, $this->analysisStartTime); } } $errorOutput = $inceptionResult->getErrorOutput(); $obsoleteDockerImage = $_SERVER['PHPSTAN_OBSOLETE_DOCKER_IMAGE'] ?? 'false'; if ($obsoleteDockerImage === 'true') { $errorOutput->writeLineFormatted('⚠️ You\'re using an obsolete PHPStan Docker image. ⚠️️'); $errorOutput->writeLineFormatted(' You can obtain the current one from ghcr.io/phpstan/phpstan.'); $errorOutput->writeLineFormatted(' Read more about it here:'); $errorOutput->writeLineFormatted(' https://phpstan.org/user-guide/docker'); $errorOutput->writeLineFormatted(''); } $errorFormat = $input->getOption('error-format'); if (!is_string($errorFormat) && $errorFormat !== null) { throw new ShouldNotHappenException(); } if ($errorFormat === null) { $errorFormat = $inceptionResult->getContainer()->getParameter('errorFormat'); } if ($errorFormat === null) { $errorFormat = 'table'; } $container = $inceptionResult->getContainer(); $errorFormatterServiceName = sprintf('errorFormatter.%s', $errorFormat); if (!$container->hasService($errorFormatterServiceName)) { $errorOutput->writeLineFormatted(sprintf('Error formatter "%s" not found. Available error formatters are: %s', $errorFormat, implode(', ', array_map(static function (string $name) : string { return substr($name, strlen('errorFormatter.')); }, $container->findServiceNamesByType(ErrorFormatter::class))))); return 1; } $generateBaselineFile = $inceptionResult->getGenerateBaselineFile(); if ($generateBaselineFile !== null) { $baselineExtension = pathinfo($generateBaselineFile, PATHINFO_EXTENSION); if ($baselineExtension === '') { $inceptionResult->getStdOutput()->getStyle()->error(sprintf('Baseline filename must have an extension, %s provided instead.', pathinfo($generateBaselineFile, PATHINFO_BASENAME))); return $inceptionResult->handleReturn(1, null, $this->analysisStartTime); } if (!in_array($baselineExtension, ['neon', 'php'], \true)) { $inceptionResult->getStdOutput()->getStyle()->error(sprintf('Baseline filename extension must be .neon or .php, .%s was used instead.', $baselineExtension)); return $inceptionResult->handleReturn(1, null, $this->analysisStartTime); } } try { [$files, $onlyFiles] = $inceptionResult->getFiles(); } catch (PathNotFoundException $e) { $this->runDiagnoseExtensions($container, $inceptionResult->getErrorOutput()); $inceptionResult->getErrorOutput()->writeLineFormatted(sprintf('%s', $e->getMessage())); return 1; } catch (\PHPStan\Command\InceptionNotSuccessfulException $e) { $this->runDiagnoseExtensions($container, $inceptionResult->getErrorOutput()); return 1; } if (count($files) === 0) { $bleedingEdge = (bool) $container->getParameter('featureToggles')['zeroFiles']; $this->runDiagnoseExtensions($container, $inceptionResult->getErrorOutput()); if (!$bleedingEdge) { $inceptionResult->getErrorOutput()->getStyle()->note('No files found to analyse.'); $inceptionResult->getErrorOutput()->getStyle()->warning('This will cause a non-zero exit code in PHPStan 2.0.'); return $inceptionResult->handleReturn(0, null, $this->analysisStartTime); } $inceptionResult->getErrorOutput()->getStyle()->error('No files found to analyse.'); return $inceptionResult->handleReturn(1, null, $this->analysisStartTime); } if ($inceptionResult->getEditorModeInsteadOfFile() !== null) { if (!in_array($inceptionResult->getEditorModeInsteadOfFile(), $files, \true)) { $inceptionResult->getStdOutput()->getStyle()->error(sprintf('File %s passed to --instead-of is not in analysed project files.', $inceptionResult->getEditorModeInsteadOfFile())); return $inceptionResult->handleReturn(1, null, $this->analysisStartTime); } } if ($inceptionResult->getEditorModeTmpFile() !== null) { if (in_array($inceptionResult->getEditorModeTmpFile(), $files, \true)) { $inceptionResult->getStdOutput()->getStyle()->error(sprintf('File %s passed to --tmp-file is already in analysed project files.', $inceptionResult->getEditorModeInsteadOfFile())); return $inceptionResult->handleReturn(1, null, $this->analysisStartTime); } } $analysedConfigFiles = array_intersect($files, $container->getParameter('allConfigFiles')); /** @var RelativePathHelper $relativePathHelper */ $relativePathHelper = $container->getService('relativePathHelper'); foreach ($analysedConfigFiles as $analysedConfigFile) { $fileSize = @filesize($analysedConfigFile); if ($fileSize === \false) { continue; } if ($fileSize <= 512 * 1024) { continue; } $inceptionResult->getErrorOutput()->getStyle()->warning(sprintf('Configuration file %s (%s) is too big and might slow down PHPStan. Consider adding it to excludePaths.', $relativePathHelper->getRelativePath($analysedConfigFile), BytesHelper::bytes($fileSize))); } if ($fix) { if ($generateBaselineFile !== null) { $inceptionResult->getStdOutput()->getStyle()->error('You cannot pass the --generate-baseline option when running PHPStan Pro.'); return $inceptionResult->handleReturn(1, null, $this->analysisStartTime); } return $this->runFixer($inceptionResult, $container, $onlyFiles, $input, $output, $files); } /** @var AnalyseApplication $application */ $application = $container->getByType(\PHPStan\Command\AnalyseApplication::class); $debug = $input->getOption('debug'); if (!is_bool($debug)) { throw new ShouldNotHappenException(); } try { $analysisResult = $application->analyse($files, $onlyFiles, $inceptionResult->getStdOutput(), $inceptionResult->getErrorOutput(), $inceptionResult->isDefaultLevelUsed(), $debug, $inceptionResult->getProjectConfigFile(), $inceptionResult->getProjectConfigArray(), $inceptionResult->getEditorModeTmpFile(), $inceptionResult->getEditorModeInsteadOfFile(), $input); } catch (Throwable $t) { if ($debug) { $stdOutput = $inceptionResult->getStdOutput(); $stdOutput->writeRaw(sprintf('Uncaught %s: %s in %s:%d', get_class($t), $t->getMessage(), $t->getFile(), $t->getLine())); $stdOutput->writeLineFormatted(''); $stdOutput->writeRaw($t->getTraceAsString()); $stdOutput->writeLineFormatted(''); $previous = $t->getPrevious(); while ($previous !== null) { $stdOutput->writeLineFormatted(''); $stdOutput->writeLineFormatted('Caused by:'); $stdOutput->writeRaw(sprintf('Uncaught %s: %s in %s:%d', get_class($previous), $previous->getMessage(), $previous->getFile(), $previous->getLine())); $stdOutput->writeRaw($previous->getTraceAsString()); $stdOutput->writeLineFormatted(''); $previous = $previous->getPrevious(); } return $inceptionResult->handleReturn(1, null, $this->analysisStartTime); } throw $t; } /** * Variable $internalErrorsTuples contains both "internal errors" * and "errors with non-ignorable exception" as InternalError objects. */ $internalErrorsTuples = []; $internalFileSpecificErrors = []; foreach ($analysisResult->getInternalErrorObjects() as $internalError) { $internalErrorsTuples[$internalError->getMessage()] = [new InternalError($internalError->getTraceAsString() !== null ? sprintf('Internal error: %s', $internalError->getMessage()) : $internalError->getMessage(), $internalError->getContextDescription(), $internalError->getTrace(), $internalError->getTraceAsString(), $internalError->shouldReportBug()), \false]; } foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { if (!$fileSpecificError->hasNonIgnorableException()) { continue; } $message = $fileSpecificError->getMessage(); $metadata = $fileSpecificError->getMetadata(); $hasStackTrace = \false; if ($fileSpecificError->getIdentifier() === 'phpstan.internal' && array_key_exists(InternalError::STACK_TRACE_AS_STRING_METADATA_KEY, $metadata)) { $message = sprintf('Internal error: %s', $message); $hasStackTrace = \true; } if (!$hasStackTrace) { if (!array_key_exists($fileSpecificError->getMessage(), $internalFileSpecificErrors)) { $internalFileSpecificErrors[$fileSpecificError->getMessage()] = $fileSpecificError; } } $internalErrorsTuples[$fileSpecificError->getMessage()] = [new InternalError($message, sprintf('analysing file %s', $fileSpecificError->getTraitFilePath() ?? $fileSpecificError->getFilePath()), $metadata[InternalError::STACK_TRACE_METADATA_KEY] ?? [], $metadata[InternalError::STACK_TRACE_AS_STRING_METADATA_KEY] ?? null, \true), !$hasStackTrace]; } $internalErrorsTuples = array_values($internalErrorsTuples); $fileHelper = $container->getByType(FileHelper::class); /** * Variable $internalErrors only contains non-file-specific "internal errors". */ $internalErrors = []; foreach ($internalErrorsTuples as [$internalError, $isInFileSpecificErrors]) { if ($isInFileSpecificErrors) { continue; } $internalErrors[] = new InternalError($this->getMessageFromInternalError($fileHelper, $internalError, $output->getVerbosity()), $internalError->getContextDescription(), $internalError->getTrace(), $internalError->getTraceAsString(), $internalError->shouldReportBug()); } if ($generateBaselineFile !== null) { $this->runDiagnoseExtensions($container, $inceptionResult->getErrorOutput()); if (count($internalErrorsTuples) > 0) { foreach ($internalErrorsTuples as [$internalError]) { $inceptionResult->getStdOutput()->writeLineFormatted($internalError->getMessage()); $inceptionResult->getStdOutput()->writeLineFormatted(''); } $inceptionResult->getStdOutput()->getStyle()->error(sprintf('%s occurred. Baseline could not be generated.', count($internalErrors) === 1 ? 'An internal error' : 'Internal errors')); return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes(), $this->analysisStartTime); } return $this->generateBaseline($generateBaselineFile, $inceptionResult, $analysisResult, $output, $allowEmptyBaseline, $baselineExtension, $failWithoutResultCache); } /** @var ErrorFormatter $errorFormatter */ $errorFormatter = $container->getService($errorFormatterServiceName); if (count($internalErrorsTuples) > 0) { $analysisResult = new \PHPStan\Command\AnalysisResult(array_values($internalFileSpecificErrors), array_map(static function (InternalError $internalError) { return $internalError->getMessage(); }, $internalErrors), [], [], [], $analysisResult->isDefaultLevelUsed(), $analysisResult->getProjectConfigFile(), $analysisResult->isResultCacheSaved(), $analysisResult->getPeakMemoryUsageBytes(), $analysisResult->isResultCacheUsed(), $analysisResult->getChangedProjectExtensionFilesOutsideOfAnalysedPaths()); $exitCode = $errorFormatter->formatErrors($analysisResult, $inceptionResult->getStdOutput()); $this->runDiagnoseExtensions($container, $inceptionResult->getErrorOutput()); $errorOutput->writeLineFormatted('⚠️ Result is incomplete because of severe errors. ⚠️'); $errorOutput->writeLineFormatted(' Fix these errors first and then re-run PHPStan'); $errorOutput->writeLineFormatted(' to get all reported errors.'); $errorOutput->writeLineFormatted(''); return $inceptionResult->handleReturn($exitCode, $analysisResult->getPeakMemoryUsageBytes(), $this->analysisStartTime); } $exitCode = $errorFormatter->formatErrors($analysisResult, $inceptionResult->getStdOutput()); if ($failWithoutResultCache && !$analysisResult->isResultCacheUsed()) { $exitCode = 2; } if ($analysisResult->isResultCacheUsed() && $analysisResult->isResultCacheSaved() && !$onlyFiles && $inceptionResult->getProjectConfigArray() !== null) { $projectServicesNotInAnalysedPaths = array_values(array_unique($analysisResult->getChangedProjectExtensionFilesOutsideOfAnalysedPaths())); $projectServiceFileNamesNotInAnalysedPaths = array_keys($analysisResult->getChangedProjectExtensionFilesOutsideOfAnalysedPaths()); if (count($projectServicesNotInAnalysedPaths) > 0) { $one = count($projectServicesNotInAnalysedPaths) === 1; $errorOutput->writeLineFormatted('Result cache might not behave correctly.'); $errorOutput->writeLineFormatted(sprintf('You\'re using custom %s in your project config', $one ? 'extension' : 'extensions')); $errorOutput->writeLineFormatted(sprintf('but %s not part of analysed paths:', $one ? 'this extension is' : 'these extensions are')); $errorOutput->writeLineFormatted(''); foreach ($projectServicesNotInAnalysedPaths as $service) { $errorOutput->writeLineFormatted(sprintf('- %s', $service)); } $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted('When you edit them and re-run PHPStan, the result cache will get stale.'); $directoriesToAdd = []; foreach ($projectServiceFileNamesNotInAnalysedPaths as $path) { $directoriesToAdd[] = dirname($relativePathHelper->getRelativePath($path)); } $directoriesToAdd = array_unique($directoriesToAdd); $oneDirectory = count($directoriesToAdd) === 1; $errorOutput->writeLineFormatted(sprintf('Add %s to your analysed paths to get rid of this problem:', $oneDirectory ? 'this directory' : 'these directories')); $errorOutput->writeLineFormatted(''); foreach ($directoriesToAdd as $directory) { $errorOutput->writeLineFormatted(sprintf('- %s', $directory)); } $errorOutput->writeLineFormatted(''); $bleedingEdge = (bool) $container->getParameter('featureToggles')['projectServicesNotInAnalysedPaths']; if ($bleedingEdge) { return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes(), $this->analysisStartTime); } $errorOutput->getStyle()->warning('This will cause a non-zero exit code in PHPStan 2.0.'); } } $this->runDiagnoseExtensions($container, $inceptionResult->getErrorOutput()); return $inceptionResult->handleReturn($exitCode, $analysisResult->getPeakMemoryUsageBytes(), $this->analysisStartTime); } private function createStreamOutput() : StreamOutput { $resource = fopen('php://memory', 'w', \false); if ($resource === \false) { throw new ShouldNotHappenException(); } return new StreamOutput($resource); } private function getMessageFromInternalError(FileHelper $fileHelper, InternalError $internalError, int $verbosity) : string { $message = sprintf('%s while %s', $internalError->getMessage(), $internalError->getContextDescription()); $hasLarastan = \false; $isLaravelLast = \false; foreach (array_reverse($internalError->getTrace()) as $traceItem) { if ($traceItem['file'] === null) { continue; } $file = $fileHelper->normalizePath($traceItem['file'], '/'); if (str_contains($file, '/larastan/')) { $hasLarastan = \true; $isLaravelLast = \false; continue; } if (!str_contains($file, '/laravel/framework/')) { continue; } $isLaravelLast = \true; } if ($hasLarastan) { if ($isLaravelLast) { $message .= "\n"; $message .= "\n" . 'This message is coming from Laravel Framework itself.'; $message .= "\n" . 'Larastan boots up your application in order to provide'; $message .= "\n" . 'smarter static analysis of your codebase.'; $message .= "\n"; $message .= "\n" . 'In order to do that, the environment you run PHPStan in'; $message .= "\n" . 'must match the environment you run your application in.'; $message .= "\n"; $message .= "\n" . 'Make sure you\'ve set your environment variables'; $message .= "\n" . 'or the .env file correctly.'; return $message; } $bugReportUrl = 'https://github.com/larastan/larastan/issues/new?template=bug-report.md'; } else { $bugReportUrl = 'https://github.com/phpstan/phpstan/issues/new?template=Bug_report.yaml'; } if ($internalError->getTraceAsString() !== null) { if (OutputInterface::VERBOSITY_VERBOSE <= $verbosity) { $firstTraceItem = $internalError->getTrace()[0] ?? null; $trace = ''; if ($firstTraceItem !== null && $firstTraceItem['file'] !== null && $firstTraceItem['line'] !== null) { $trace = sprintf('## %s(%d)%s', $firstTraceItem['file'], $firstTraceItem['line'], "\n"); } $trace .= $internalError->getTraceAsString(); if ($internalError->shouldReportBug()) { $message .= sprintf('%sPost the following stack trace to %s: %s%s', "\n", $bugReportUrl, "\n", $trace); } else { $message .= sprintf('%s%s', "\n\n", $trace); } } else { if ($internalError->shouldReportBug()) { $message .= sprintf('%sRun PHPStan with -v option and post the stack trace to:%s%s%s', "\n\n", "\n", $bugReportUrl, "\n"); } else { $message .= sprintf('%sRun PHPStan with -v option to see the stack trace', "\n"); } } } return $message; } private function generateBaseline(string $generateBaselineFile, \PHPStan\Command\InceptionResult $inceptionResult, \PHPStan\Command\AnalysisResult $analysisResult, OutputInterface $output, bool $allowEmptyBaseline, string $baselineExtension, bool $failWithoutResultCache) : int { if (!$allowEmptyBaseline && !$analysisResult->hasErrors()) { $inceptionResult->getStdOutput()->getStyle()->error('No errors were found during the analysis. Baseline could not be generated.'); $inceptionResult->getStdOutput()->writeLineFormatted('To allow generating empty baselines, pass --allow-empty-baseline option.'); return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes(), $this->analysisStartTime); } $streamOutput = $this->createStreamOutput(); $errorConsoleStyle = new \PHPStan\Command\ErrorsConsoleStyle(new StringInput(''), $streamOutput); $baselineOutput = new SymfonyOutput($streamOutput, new SymfonyStyle($errorConsoleStyle)); $baselineFileDirectory = dirname($generateBaselineFile); $baselinePathHelper = new ParentDirectoryRelativePathHelper($baselineFileDirectory); if ($baselineExtension === 'php') { $baselineErrorFormatter = new BaselinePhpErrorFormatter($baselinePathHelper); $baselineErrorFormatter->formatErrors($analysisResult, $baselineOutput); } else { $baselineErrorFormatter = new BaselineNeonErrorFormatter($baselinePathHelper); $existingBaselineContent = is_file($generateBaselineFile) ? FileReader::read($generateBaselineFile) : ''; $baselineErrorFormatter->formatErrors($analysisResult, $baselineOutput, $existingBaselineContent); } $stream = $streamOutput->getStream(); rewind($stream); $baselineContents = stream_get_contents($stream); if ($baselineContents === \false) { throw new ShouldNotHappenException(); } try { DirectoryCreator::ensureDirectoryExists($baselineFileDirectory, 0644); } catch (DirectoryCreatorException $e) { $inceptionResult->getStdOutput()->writeLineFormatted($e->getMessage()); return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes(), $this->analysisStartTime); } try { FileWriter::write($generateBaselineFile, $baselineContents); } catch (CouldNotWriteFileException $e) { $inceptionResult->getStdOutput()->writeLineFormatted($e->getMessage()); return $inceptionResult->handleReturn(1, $analysisResult->getPeakMemoryUsageBytes(), $this->analysisStartTime); } $errorsCount = 0; $unignorableCount = 0; foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { if (!$fileSpecificError->canBeIgnored()) { $unignorableCount++; if ($output->isVeryVerbose()) { $inceptionResult->getStdOutput()->writeLineFormatted('Unignorable errors could not be added to the baseline:'); $inceptionResult->getStdOutput()->writeLineFormatted($fileSpecificError->getMessage()); $inceptionResult->getStdOutput()->writeLineFormatted($fileSpecificError->getFile()); $inceptionResult->getStdOutput()->writeLineFormatted(''); } continue; } $errorsCount++; } $message = sprintf('Baseline generated with %d %s.', $errorsCount, $errorsCount === 1 ? 'error' : 'errors'); if ($unignorableCount === 0 && count($analysisResult->getNotFileSpecificErrors()) === 0) { $inceptionResult->getStdOutput()->getStyle()->success($message); } else { if ($output->isVeryVerbose()) { $inceptionResult->getStdOutput()->getStyle()->warning($message . "\nSome errors could not be put into baseline."); } else { $inceptionResult->getStdOutput()->getStyle()->warning($message . "\nSome errors could not be put into baseline. Re-run PHPStan with \"-vv\" and fix them."); } } $exitCode = 0; if ($failWithoutResultCache && !$analysisResult->isResultCacheUsed()) { $exitCode = 2; } return $inceptionResult->handleReturn($exitCode, $analysisResult->getPeakMemoryUsageBytes(), $this->analysisStartTime); } /** * @param string[] $files */ private function runFixer(\PHPStan\Command\InceptionResult $inceptionResult, Container $container, bool $onlyFiles, InputInterface $input, OutputInterface $output, array $files) : int { $ciDetector = new CiDetector(); if ($ciDetector->isCiDetected()) { $inceptionResult->getStdOutput()->writeLineFormatted('PHPStan Pro can\'t run in CI environment yet. Stay tuned!'); return $inceptionResult->handleReturn(1, null, $this->analysisStartTime); } /** @var FixerApplication $fixerApplication */ $fixerApplication = $container->getByType(\PHPStan\Command\FixerApplication::class); return $fixerApplication->run($inceptionResult->getProjectConfigFile(), $input, $output, count($files), $_SERVER['argv'][0]); } private function runDiagnoseExtensions(Container $container, \PHPStan\Command\Output $errorOutput) : void { if (!$errorOutput->isDebug()) { return; } /** @var PHPStanDiagnoseExtension $phpstanDiagnoseExtension */ $phpstanDiagnoseExtension = $container->getService('phpstanDiagnoseExtension'); // not using tag for this extension to make sure it's always first $phpstanDiagnoseExtension->print($errorOutput); /** @var DiagnoseExtension $extension */ foreach ($container->getServicesByTag(DiagnoseExtension::EXTENSION_TAG) as $extension) { $extension->print($errorOutput); } } } symfonyOutput = $symfonyOutput; $this->style = $style; } public function writeFormatted(string $message) : void { $this->symfonyOutput->write($message, \false, OutputInterface::OUTPUT_NORMAL); } public function writeLineFormatted(string $message) : void { $this->symfonyOutput->writeln($message, OutputInterface::OUTPUT_NORMAL); } public function writeRaw(string $message) : void { $this->symfonyOutput->write($message, \false, OutputInterface::OUTPUT_RAW); } public function getStyle() : OutputStyle { return $this->style; } public function isVerbose() : bool { return $this->symfonyOutput->isVerbose(); } public function isVeryVerbose() : bool { return $this->symfonyOutput->isVeryVerbose(); } public function isDebug() : bool { return $this->symfonyOutput->isDebug(); } public function isDecorated() : bool { return $this->symfonyOutput->isDecorated(); } } symfonyStyle = $symfonyStyle; } public function getSymfonyStyle() : StyleInterface { return $this->symfonyStyle; } public function title(string $message) : void { $this->symfonyStyle->title($message); } public function section(string $message) : void { $this->symfonyStyle->section($message); } public function listing(array $elements) : void { $this->symfonyStyle->listing($elements); } public function success(string $message) : void { $this->symfonyStyle->success($message); } public function error(string $message) : void { $this->symfonyStyle->error($message); } public function warning(string $message) : void { $this->symfonyStyle->warning($message); } public function note(string $message) : void { $this->symfonyStyle->note($message); } public function caution(string $message) : void { $this->symfonyStyle->caution($message); } public function table(array $headers, array $rows) : void { $this->symfonyStyle->table($headers, $rows); } public function newLine(int $count = 1) : void { $this->symfonyStyle->newLine($count); } public function progressStart(int $max = 0) : void { $this->symfonyStyle->progressStart($max); } public function progressAdvance(int $step = 1) : void { $this->symfonyStyle->progressAdvance($step); } public function progressFinish() : void { $this->symfonyStyle->progressFinish(); } } parser = $parser; $this->typeStringResolver = $typeStringResolver; } public function validate(string $regex) : \PHPStan\Command\IgnoredRegexValidatorResult { $regex = $this->removeDelimiters($regex); try { /** @var TreeNode $ast */ $ast = $this->parser->parse($regex); } catch (Exception $e) { return new \PHPStan\Command\IgnoredRegexValidatorResult([], \false, \false); } if (Strings::match($regex, '~(?getIgnoredTypes($ast), $this->hasAnchorsInTheMiddle($ast), \false); } /** * @return array */ private function getIgnoredTypes(TreeNode $ast) : array { /** @var TreeNode|null $alternation */ $alternation = $ast->getChild(0); if ($alternation === null) { return []; } if ($alternation->getId() !== '#alternation') { return []; } $types = []; foreach ($alternation->getChildren() as $child) { $text = $this->getText($child); if ($text === null) { continue; } $matches = Strings::match($text, '#^([a-zA-Z0-9]+)[,]?\\s*#'); if ($matches === null) { continue; } try { $type = $this->typeStringResolver->resolve($matches[1], null); } catch (ParserException $e) { continue; } if ($type instanceof ObjectType) { continue; } $typeDescription = $type->describe(VerbosityLevel::typeOnly()); if ($typeDescription !== $matches[1]) { continue; } $types[$typeDescription] = $text; } return $types; } private function removeDelimiters(string $regex) : string { $delimiter = substr($regex, 0, 1); $endDelimiterPosition = strrpos($regex, $delimiter); if ($endDelimiterPosition === \false) { throw new ShouldNotHappenException(); } return substr($regex, 1, $endDelimiterPosition - 1); } private function getText(TreeNode $treeNode) : ?string { if ($treeNode->getId() === 'token') { return $treeNode->getValueValue(); } if ($treeNode->getId() === '#concatenation') { $fullText = ''; foreach ($treeNode->getChildren() as $child) { $text = $this->getText($child); if ($text === null) { continue; } $fullText .= $text; } if ($fullText === '') { return null; } return $fullText; } return null; } private function hasAnchorsInTheMiddle(TreeNode $ast) : bool { if ($ast->getId() === 'token') { $valueArray = $ast->getValue(); return $valueArray['token'] === 'anchor' && $valueArray['value'] === '$'; } $childrenCount = count($ast->getChildren()); foreach ($ast->getChildren() as $i => $child) { $has = $this->hasAnchorsInTheMiddle($child); if ($has && ($ast->getId() !== '#concatenation' || $i !== $childrenCount - 1)) { return \true; } } return \false; } } composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; parent::__construct(); } protected function configure() : void { $this->setName(self::NAME)->setDescription('(Internal) Support for PHPStan Pro.')->setDefinition([new InputArgument('paths', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Paths with source code to run analysis on'), new InputOption('configuration', 'c', InputOption::VALUE_REQUIRED, 'Path to project configuration file'), new InputOption(\PHPStan\Command\AnalyseCommand::OPTION_LEVEL, 'l', InputOption::VALUE_REQUIRED, 'Level of rule options - the higher the stricter'), new InputOption('autoload-file', 'a', InputOption::VALUE_REQUIRED, 'Project\'s additional autoload file path'), new InputOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Memory limit for analysis'), new InputOption('xdebug', null, InputOption::VALUE_NONE, 'Allow running with Xdebug for debugging purposes'), new InputOption('server-port', null, InputOption::VALUE_REQUIRED, 'Server port for FixerApplication')])->setHidden(\true); } protected function execute(InputInterface $input, OutputInterface $output) : int { $paths = $input->getArgument('paths'); $memoryLimit = $input->getOption('memory-limit'); $autoloadFile = $input->getOption('autoload-file'); $configuration = $input->getOption('configuration'); $level = $input->getOption(\PHPStan\Command\AnalyseCommand::OPTION_LEVEL); $allowXdebug = $input->getOption('xdebug'); $serverPort = $input->getOption('server-port'); if (!is_array($paths) || !is_string($memoryLimit) && $memoryLimit !== null || !is_string($autoloadFile) && $autoloadFile !== null || !is_string($configuration) && $configuration !== null || !is_string($level) && $level !== null || !is_bool($allowXdebug) || !is_string($serverPort)) { throw new ShouldNotHappenException(); } try { $inceptionResult = \PHPStan\Command\CommandHelper::begin($input, $output, $paths, $memoryLimit, $autoloadFile, $this->composerAutoloaderProjectPaths, $configuration, null, $level, $allowXdebug, \false, null, null, \false); } catch (\PHPStan\Command\InceptionNotSuccessfulException $e) { return 1; } $container = $inceptionResult->getContainer(); /** @var IgnoredErrorHelper $ignoredErrorHelper */ $ignoredErrorHelper = $container->getByType(IgnoredErrorHelper::class); $ignoredErrorHelperResult = $ignoredErrorHelper->initialize(); if (count($ignoredErrorHelperResult->getErrors()) > 0) { throw new ShouldNotHappenException(); } $loop = new StreamSelectLoop(); $tcpConnector = new TcpConnector($loop); $tcpConnector->connect(sprintf('127.0.0.1:%d', $serverPort))->then(function (ConnectionInterface $connection) use($container, $inceptionResult, $configuration, $input, $ignoredErrorHelperResult, $loop) : void { // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly $jsonInvalidUtf8Ignore = \defined('JSON_INVALID_UTF8_IGNORE') ? JSON_INVALID_UTF8_IGNORE : 0; // phpcs:enable $out = new Encoder($connection, $jsonInvalidUtf8Ignore); //$in = new Decoder($connection, true, 512, $jsonInvalidUtf8Ignore, 128 * 1024 * 1024); /** @var ResultCacheManager $resultCacheManager */ $resultCacheManager = $container->getByType(ResultCacheManagerFactory::class)->create([]); $projectConfigArray = $inceptionResult->getProjectConfigArray(); /** @var AnalyserResultFinalizer $analyserResultFinalizer */ $analyserResultFinalizer = $container->getByType(AnalyserResultFinalizer::class); try { [$inceptionFiles, $isOnlyFiles] = $inceptionResult->getFiles(); } catch (PathNotFoundException|\PHPStan\Command\InceptionNotSuccessfulException $e) { throw new ShouldNotHappenException(); } $out->write(['action' => 'analysisStart', 'result' => ['analysedFiles' => $inceptionFiles]]); $resultCache = $resultCacheManager->restore($inceptionFiles, \false, \false, $projectConfigArray, $inceptionResult->getErrorOutput()); $errorsFromResultCacheTmp = $resultCache->getErrors(); $locallyIgnoredErrorsFromResultCacheTmp = $resultCache->getLocallyIgnoredErrors(); foreach ($resultCache->getFilesToAnalyse() as $fileToAnalyse) { unset($errorsFromResultCacheTmp[$fileToAnalyse]); unset($locallyIgnoredErrorsFromResultCacheTmp[$fileToAnalyse]); } $errorsFromResultCache = []; foreach ($errorsFromResultCacheTmp as $errorsByFile) { foreach ($errorsByFile as $error) { $errorsFromResultCache[] = $error; } } [$errorsFromResultCache, $ignoredErrorsFromResultCache] = $this->filterErrors($errorsFromResultCache, $ignoredErrorHelperResult, $isOnlyFiles, $inceptionFiles, \false); foreach ($locallyIgnoredErrorsFromResultCacheTmp as $locallyIgnoredErrors) { foreach ($locallyIgnoredErrors as $locallyIgnoredError) { $ignoredErrorsFromResultCache[] = [$locallyIgnoredError, null]; } } $out->write(['action' => 'analysisStream', 'result' => ['errors' => $errorsFromResultCache, 'ignoredErrors' => $ignoredErrorsFromResultCache, 'analysedFiles' => array_diff($inceptionFiles, $resultCache->getFilesToAnalyse())]]); $filesToAnalyse = $resultCache->getFilesToAnalyse(); usort($filesToAnalyse, static function (string $a, string $b) : int { $aTime = @filemtime($a); if ($aTime === \false) { return 1; } $bTime = @filemtime($b); if ($bTime === \false) { return -1; } // files are sorted from the oldest // because ParallelAnalyser reverses the scheduler jobs to do the smallest // jobs first return $aTime <=> $bTime; }); $this->runAnalyser($loop, $container, $filesToAnalyse, $configuration, $input, function (array $errors, array $locallyIgnoredErrors, array $analysedFiles) use($out, $ignoredErrorHelperResult, $isOnlyFiles, $inceptionFiles) : void { $internalErrors = []; foreach ($errors as $fileSpecificError) { if (!$fileSpecificError->hasNonIgnorableException()) { continue; } $internalErrors[] = $this->transformErrorIntoInternalError($fileSpecificError); } if (count($internalErrors) > 0) { $out->write(['action' => 'analysisCrash', 'data' => ['internalErrors' => $internalErrors]]); return; } [$errors, $ignoredErrors] = $this->filterErrors($errors, $ignoredErrorHelperResult, $isOnlyFiles, $inceptionFiles, \false); foreach ($locallyIgnoredErrors as $locallyIgnoredError) { $ignoredErrors[] = [$locallyIgnoredError, null]; } $out->write(['action' => 'analysisStream', 'result' => ['errors' => $errors, 'ignoredErrors' => $ignoredErrors, 'analysedFiles' => $analysedFiles]]); })->then(function (AnalyserResult $intermediateAnalyserResult) use($analyserResultFinalizer, $resultCacheManager, $resultCache, $inceptionResult, $isOnlyFiles, $ignoredErrorHelperResult, $inceptionFiles, $out) : void { $analyserResult = $resultCacheManager->process($intermediateAnalyserResult, $resultCache, $inceptionResult->getErrorOutput(), \false, \true)->getAnalyserResult(); $finalizerResult = $analyserResultFinalizer->finalize($analyserResult, $isOnlyFiles, \false); $internalErrors = []; foreach ($finalizerResult->getAnalyserResult()->getInternalErrors() as $internalError) { $internalErrors[] = new InternalError($internalError->getTraceAsString() !== null ? sprintf('Internal error: %s', $internalError->getMessage()) : $internalError->getMessage(), $internalError->getContextDescription(), $internalError->getTrace(), $internalError->getTraceAsString(), $internalError->shouldReportBug()); } foreach ($finalizerResult->getAnalyserResult()->getUnorderedErrors() as $fileSpecificError) { if (!$fileSpecificError->hasNonIgnorableException()) { continue; } $internalErrors[] = $this->transformErrorIntoInternalError($fileSpecificError); } $hasInternalErrors = count($internalErrors) > 0 || $finalizerResult->getAnalyserResult()->hasReachedInternalErrorsCountLimit(); if ($hasInternalErrors) { $out->write(['action' => 'analysisCrash', 'data' => ['internalErrors' => count($internalErrors) > 0 ? $internalErrors : [new InternalError('Internal error occurred', 'running analyser in PHPStan Pro worker', [], null, \false)]]]); } [$collectorErrors, $ignoredCollectorErrors] = $this->filterErrors($finalizerResult->getCollectorErrors(), $ignoredErrorHelperResult, $isOnlyFiles, $inceptionFiles, $hasInternalErrors); foreach ($finalizerResult->getLocallyIgnoredCollectorErrors() as $locallyIgnoredCollectorError) { $ignoredCollectorErrors[] = [$locallyIgnoredCollectorError, null]; } $out->write(['action' => 'analysisStream', 'result' => ['errors' => $collectorErrors, 'ignoredErrors' => $ignoredCollectorErrors, 'analysedFiles' => []]]); $ignoredErrorHelperProcessedResult = $ignoredErrorHelperResult->process($finalizerResult->getErrors(), $isOnlyFiles, $inceptionFiles, $hasInternalErrors); $ignoreFileErrors = []; foreach ($ignoredErrorHelperProcessedResult->getNotIgnoredErrors() as $error) { if ($error->getIdentifier() === null) { continue; } if (!in_array($error->getIdentifier(), ['ignore.count', 'ignore.unmatched', 'ignore.unmatchedLine', 'ignore.unmatchedIdentifier'], \true)) { continue; } $ignoreFileErrors[] = $error; } $out->end(['action' => 'analysisEnd', 'result' => ['ignoreFileErrors' => $ignoreFileErrors, 'ignoreNotFileErrors' => $ignoredErrorHelperProcessedResult->getOtherIgnoreMessages()]]); }); }); $loop->run(); return 0; } private function transformErrorIntoInternalError(Error $error) : InternalError { $message = $error->getMessage(); $metadata = $error->getMetadata(); if ($error->getIdentifier() === 'phpstan.internal' && array_key_exists(InternalError::STACK_TRACE_AS_STRING_METADATA_KEY, $metadata)) { $message = sprintf('Internal error: %s', $message); } return new InternalError($message, sprintf('analysing file %s', $error->getTraitFilePath() ?? $error->getFilePath()), $metadata[InternalError::STACK_TRACE_METADATA_KEY] ?? [], $metadata[InternalError::STACK_TRACE_AS_STRING_METADATA_KEY] ?? null, \true); } /** * @param string[] $inceptionFiles * @param array $errors * @return array{list, list} */ private function filterErrors(array $errors, IgnoredErrorHelperResult $ignoredErrorHelperResult, bool $onlyFiles, array $inceptionFiles, bool $hasInternalErrors) : array { $ignoredErrorHelperProcessedResult = $ignoredErrorHelperResult->process($errors, $onlyFiles, $inceptionFiles, $hasInternalErrors); $finalErrors = []; foreach ($ignoredErrorHelperProcessedResult->getNotIgnoredErrors() as $error) { if ($error->getIdentifier() === null) { $finalErrors[] = $error; continue; } if (in_array($error->getIdentifier(), ['ignore.count', 'ignore.unmatched'], \true)) { continue; } $finalErrors[] = $error; } return [$finalErrors, $ignoredErrorHelperProcessedResult->getIgnoredErrors()]; } /** * @param string[] $files * @param callable(list, list, string[]): void $onFileAnalysisHandler * @return PromiseInterface */ private function runAnalyser(LoopInterface $loop, Container $container, array $files, ?string $configuration, InputInterface $input, callable $onFileAnalysisHandler) : PromiseInterface { /** @var ParallelAnalyser $parallelAnalyser */ $parallelAnalyser = $container->getByType(ParallelAnalyser::class); $filesCount = count($files); if ($filesCount === 0) { return resolve(new AnalyserResult([], [], [], [], [], [], [], [], [], [], [], \false, memory_get_peak_usage(\true))); } /** @var Scheduler $scheduler */ $scheduler = $container->getByType(Scheduler::class); /** @var CpuCoreCounter $cpuCoreCounter */ $cpuCoreCounter = $container->getByType(CpuCoreCounter::class); $schedule = $scheduler->scheduleWork($cpuCoreCounter->getNumberOfCpuCores(), $files); $mainScript = null; if (isset($_SERVER['argv'][0]) && is_file($_SERVER['argv'][0])) { $mainScript = $_SERVER['argv'][0]; } return $parallelAnalyser->analyse($loop, $schedule, $mainScript, null, $configuration, null, null, $input, $onFileAnalysisHandler); } } scheduler = $scheduler; $this->analyser = $analyser; $this->parallelAnalyser = $parallelAnalyser; $this->cpuCoreCounter = $cpuCoreCounter; } /** * @param string[] $files * @param string[] $allAnalysedFiles * @param Closure(string $file): void|null $preFileCallback * @param Closure(int ): void|null $postFileCallback */ public function runAnalyser(array $files, array $allAnalysedFiles, ?Closure $preFileCallback, ?Closure $postFileCallback, bool $debug, bool $allowParallel, ?string $projectConfigFile, ?string $tmpFile, ?string $insteadOfFile, InputInterface $input) : AnalyserResult { $filesCount = count($files); if ($filesCount === 0) { return new AnalyserResult([], [], [], [], [], [], [], [], [], [], [], \false, memory_get_peak_usage(\true)); } $schedule = $this->scheduler->scheduleWork($this->cpuCoreCounter->getNumberOfCpuCores(), $files); $mainScript = null; if (isset($_SERVER['argv'][0]) && is_file($_SERVER['argv'][0])) { $mainScript = $_SERVER['argv'][0]; } if (!$debug && $allowParallel && function_exists('proc_open') && $mainScript !== null && $schedule->getNumberOfProcesses() > 0) { $loop = new StreamSelectLoop(); $result = null; $promise = $this->parallelAnalyser->analyse($loop, $schedule, $mainScript, $postFileCallback, $projectConfigFile, $tmpFile, $insteadOfFile, $input, null); $promise->then(static function (AnalyserResult $tmp) use(&$result) : void { $result = $tmp; }); $loop->run(); if ($result === null) { throw new ShouldNotHappenException(); } return $result; } return $this->analyser->analyse($this->switchTmpFile($files, $insteadOfFile, $tmpFile), $preFileCallback, $postFileCallback, $debug, $this->switchTmpFile($allAnalysedFiles, $insteadOfFile, $tmpFile)); } /** * @param string[] $analysedFiles * @return string[] */ private function switchTmpFile(array $analysedFiles, ?string $insteadOfFile, ?string $tmpFile) : array { if ($insteadOfFile === null) { return $analysedFiles; } $analysedFiles = array_values(array_filter($analysedFiles, static function (string $file) use($insteadOfFile) : bool { return $file !== $insteadOfFile; })); if ($tmpFile !== null) { array_unshift($analysedFiles, $tmpFile); } return $analysedFiles; } } */ private $ignoredTypes; /** * @var bool */ private $anchorsInTheMiddle; /** * @var bool */ private $allErrorsIgnored; /** * @var ?string */ private $wrongSequence; /** * @var ?string */ private $escapedWrongSequence; /** * @param array $ignoredTypes */ public function __construct(array $ignoredTypes, bool $anchorsInTheMiddle, bool $allErrorsIgnored, ?string $wrongSequence = null, ?string $escapedWrongSequence = null) { $this->ignoredTypes = $ignoredTypes; $this->anchorsInTheMiddle = $anchorsInTheMiddle; $this->allErrorsIgnored = $allErrorsIgnored; $this->wrongSequence = $wrongSequence; $this->escapedWrongSequence = $escapedWrongSequence; } /** * @return array */ public function getIgnoredTypes() : array { return $this->ignoredTypes; } public function hasAnchorsInTheMiddle() : bool { return $this->anchorsInTheMiddle; } public function areAllErrorsIgnored() : bool { return $this->allErrorsIgnored; } public function getWrongSequence() : ?string { return $this->wrongSequence; } public function getEscapedWrongSequence() : ?string { return $this->escapedWrongSequence; } } showProgress = $input->hasOption(self::OPTION_NO_PROGRESS) && !(bool) $input->getOption(self::OPTION_NO_PROGRESS); } private function isCiDetected() : bool { if ($this->isCiDetected === null) { $ciDetector = new CiDetector(); $this->isCiDetected = $ciDetector->isCiDetected(); } return $this->isCiDetected; } /** * @param string[] $headers * @param string[][] $rows */ public function table(array $headers, array $rows) : void { /** @var int $terminalWidth */ $terminalWidth = (new Terminal())->getWidth() - 2; $maxHeaderWidth = strlen($headers[0]); foreach ($rows as $row) { $length = strlen($row[0]); if ($maxHeaderWidth !== 0 && $length <= $maxHeaderWidth) { continue; } $maxHeaderWidth = $length; } // manual wrapping could be replaced with $table->setColumnMaxWidth() // but it's buggy for lines // https://github.com/symfony/symfony/issues/45520 // https://github.com/symfony/symfony/issues/45521 $headers = $this->wrap($headers, $terminalWidth, $maxHeaderWidth); foreach ($headers as $i => $header) { $newHeader = []; foreach (explode("\n", $header) as $h) { $newHeader[] = sprintf('%s', $h); } $headers[$i] = implode("\n", $newHeader); } foreach ($rows as $i => $row) { $rows[$i] = $this->wrap($row, $terminalWidth, $maxHeaderWidth); } $table = $this->createTable(); array_unshift($rows, $headers, new TableSeparator()); $table->setRows($rows); $table->render(); $this->newLine(); } /** * @param string[] $rows * @return string[] */ private function wrap(array $rows, int $terminalWidth, int $maxHeaderWidth) : array { foreach ($rows as $i => $column) { $columnRows = explode("\n", $column); foreach ($columnRows as $k => $columnRow) { if (str_starts_with($columnRow, '✏️')) { continue; } $wrapped = wordwrap($columnRow, $terminalWidth - $maxHeaderWidth - 5); if (str_starts_with($columnRow, '💡 ')) { $wrappedLines = explode("\n", $wrapped); $newWrappedLines = []; foreach ($wrappedLines as $l => $line) { if ($l === 0) { $newWrappedLines[] = $line; continue; } $newWrappedLines[] = ' ' . $line; } $columnRows[$k] = implode("\n", $newWrappedLines); } else { $columnRows[$k] = $wrapped; } } $rows[$i] = implode("\n", $columnRows); } return $rows; } public function createProgressBar(int $max = 0) : ProgressBar { $this->progressBar = parent::createProgressBar($max); $format = $this->getProgressBarFormat(); if ($format !== null) { $this->progressBar->setFormat($format); } $ci = $this->isCiDetected(); $this->progressBar->setOverwrite(!$ci); if ($ci) { $this->progressBar->minSecondsBetweenRedraws(15); $this->progressBar->maxSecondsBetweenRedraws(30); } elseif (DIRECTORY_SEPARATOR === '\\') { $this->progressBar->minSecondsBetweenRedraws(0.5); $this->progressBar->maxSecondsBetweenRedraws(2); } else { $this->progressBar->minSecondsBetweenRedraws(0.1); $this->progressBar->maxSecondsBetweenRedraws(0.5); } return $this->progressBar; } private function getProgressBarFormat() : ?string { switch ($this->getVerbosity()) { case OutputInterface::VERBOSITY_NORMAL: $formatName = ProgressBar::FORMAT_NORMAL; break; case OutputInterface::VERBOSITY_VERBOSE: $formatName = ProgressBar::FORMAT_VERBOSE; break; case OutputInterface::VERBOSITY_VERY_VERBOSE: case OutputInterface::VERBOSITY_DEBUG: $formatName = ProgressBar::FORMAT_VERY_VERBOSE; break; default: $formatName = null; break; } if ($formatName === null) { return null; } return ProgressBar::getFormatDefinition($formatName); } public function progressStart(int $max = 0) : void { if (!$this->showProgress) { return; } parent::progressStart($max); } public function progressAdvance(int $step = 1) : void { if (!$this->showProgress) { return; } parent::progressAdvance($step); } public function progressFinish() : void { if (!$this->showProgress) { return; } parent::progressFinish(); } } */ private $dnsServers; /** * @var string[] */ private $composerAutoloaderProjectPaths; /** * @var string[] */ private $allConfigFiles; /** * @var ?string */ private $cliAutoloadFile; /** * @var string[] */ private $bootstrapFiles; /** * @var ?string */ private $editorUrl; /** * @var string */ private $usedLevel; /** @var PromiseInterface|null */ private $processInProgress = null; /** * @var bool */ private $fileMonitorActive = \true; /** * @param string[] $analysedPaths * @param list $dnsServers * @param string[] $composerAutoloaderProjectPaths * @param string[] $allConfigFiles * @param string[] $bootstrapFiles */ public function __construct(FileMonitor $fileMonitor, IgnoredErrorHelper $ignoredErrorHelper, StubFilesProvider $stubFilesProvider, array $analysedPaths, string $currentWorkingDirectory, string $proTmpDir, array $dnsServers, array $composerAutoloaderProjectPaths, array $allConfigFiles, ?string $cliAutoloadFile, array $bootstrapFiles, ?string $editorUrl, string $usedLevel) { $this->fileMonitor = $fileMonitor; $this->ignoredErrorHelper = $ignoredErrorHelper; $this->stubFilesProvider = $stubFilesProvider; $this->analysedPaths = $analysedPaths; $this->currentWorkingDirectory = $currentWorkingDirectory; $this->proTmpDir = $proTmpDir; $this->dnsServers = $dnsServers; $this->composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; $this->allConfigFiles = $allConfigFiles; $this->cliAutoloadFile = $cliAutoloadFile; $this->bootstrapFiles = $bootstrapFiles; $this->editorUrl = $editorUrl; $this->usedLevel = $usedLevel; } public function run(?string $projectConfigFile, InputInterface $input, OutputInterface $output, int $filesCount, string $mainScript) : int { $loop = new StreamSelectLoop(); $server = new TcpServer('127.0.0.1:0', $loop); /** @var string $serverAddress */ $serverAddress = $server->getAddress(); /** @var int<0, 65535> $serverPort */ $serverPort = parse_url($serverAddress, PHP_URL_PORT); $server->on('connection', function (ConnectionInterface $connection) use($loop, $projectConfigFile, $input, $output, $mainScript, $filesCount) : void { // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly $jsonInvalidUtf8Ignore = defined('JSON_INVALID_UTF8_IGNORE') ? JSON_INVALID_UTF8_IGNORE : 0; // phpcs:enable $decoder = new Decoder($connection, \true, 512, $jsonInvalidUtf8Ignore, 128 * 1024 * 1024); $encoder = new Encoder($connection, $jsonInvalidUtf8Ignore); $encoder->write(['action' => 'initialData', 'data' => ['currentWorkingDirectory' => $this->currentWorkingDirectory, 'analysedPaths' => $this->analysedPaths, 'projectConfigFile' => $projectConfigFile, 'filesCount' => $filesCount, 'phpstanVersion' => ComposerHelper::getPhpStanVersion(), 'editorUrl' => $this->editorUrl, 'ruleLevel' => $this->usedLevel]]); $decoder->on('data', function (array $data) use($output) : void { if ($data['action'] === 'webPort') { $output->writeln(sprintf('Open your web browser at: http://127.0.0.1:%d', $data['data']['port'])); $output->writeln('Press [Ctrl-C] to quit.'); return; } if ($data['action'] === 'resumeFileMonitor') { $this->fileMonitorActive = \true; return; } if ($data['action'] === 'pauseFileMonitor') { $this->fileMonitorActive = \false; return; } }); $this->fileMonitor->initialize(array_merge($this->getComposerLocks(), $this->getComposerInstalled(), $this->getExecutedFiles(), $this->getStubFiles(), $this->allConfigFiles)); $this->analyse($loop, $mainScript, $projectConfigFile, $input, $output, $encoder); $this->monitorFileChanges($loop, function (FileMonitorResult $changes) use($loop, $mainScript, $projectConfigFile, $input, $encoder, $output) : void { if ($this->processInProgress !== null) { $this->processInProgress->cancel(); $this->processInProgress = null; } if (count($changes->getChangedFiles()) > 0) { $encoder->write(['action' => 'changedFiles', 'data' => ['paths' => $changes->getChangedFiles()]]); } $this->analyse($loop, $mainScript, $projectConfigFile, $input, $output, $encoder); }); }); try { $fixerProcess = $this->getFixerProcess($output, $serverPort); } catch (\PHPStan\Command\FixerProcessException $e) { return 1; } $fixerProcess->start($loop); $fixerProcess->on('exit', function ($exitCode) use($output, $loop) : void { $loop->stop(); if ($exitCode === null) { return; } if ($exitCode === 0) { return; } $output->writeln(sprintf('PHPStan Pro process exited with code %d.', $exitCode)); @unlink($this->proTmpDir . '/phar-info.json'); }); $loop->run(); return 0; } /** * @throws FixerProcessException */ private function getFixerProcess(OutputInterface $output, int $serverPort) : Process { try { DirectoryCreator::ensureDirectoryExists($this->proTmpDir, 0777); } catch (DirectoryCreatorException $e) { $output->writeln($e->getMessage()); throw new \PHPStan\Command\FixerProcessException(); } $pharPath = $this->proTmpDir . '/phpstan-fixer.phar'; $infoPath = $this->proTmpDir . '/phar-info.json'; try { $this->downloadPhar($output, $pharPath, $infoPath); } catch (RuntimeException $e) { if (!is_file($pharPath)) { $this->printDownloadError($output, $e); throw new \PHPStan\Command\FixerProcessException(); } } $pubKeyPath = $pharPath . '.pubkey'; FileWriter::write($pubKeyPath, FileReader::read(__DIR__ . '/fixer-phar.pubkey')); try { $phar = new Phar($pharPath); } catch (Throwable $e) { @unlink($pharPath); @unlink($infoPath); $output->writeln('PHPStan Pro PHAR signature is corrupted.'); $output->writeln(sprintf('%s: %s', get_class($e), $e->getMessage())); throw new \PHPStan\Command\FixerProcessException(); } if ($phar->getSignature()['hash_type'] !== 'OpenSSL') { @unlink($pharPath); @unlink($infoPath); $output->writeln('PHPStan Pro PHAR signature is corrupted.'); $output->writeln(sprintf('Wrong hash type: %s', $phar->getSignature()['hash_type'])); throw new \PHPStan\Command\FixerProcessException(); } $env = getenv(); $env['PHPSTAN_PRO_TMP_DIR'] = $this->proTmpDir; $forcedPort = $_SERVER['PHPSTAN_PRO_WEB_PORT'] ?? null; if ($forcedPort !== null) { $env['PHPSTAN_PRO_WEB_PORT'] = $_SERVER['PHPSTAN_PRO_WEB_PORT']; $isDocker = $this->isDockerRunning(); if ($isDocker) { $output->writeln('Running in Docker? Don\'t forget to do these steps:'); $output->writeln('1) Publish this port when running Docker:'); $output->writeln(sprintf(' -p 127.0.0.1:%d:%d', $_SERVER['PHPSTAN_PRO_WEB_PORT'], $_SERVER['PHPSTAN_PRO_WEB_PORT'])); $output->writeln('2) Map the temp directory to a persistent volume'); $output->writeln(' so that you don\'t have to log in every time:'); $output->writeln(sprintf(' -v ~/.phpstan-pro:%s', $this->proTmpDir)); $output->writeln(''); } } else { $isDocker = $this->isDockerRunning(); if ($isDocker) { $output->writeln('Running in Docker? You need to do these steps in order to launch PHPStan Pro:'); $output->writeln(''); $output->writeln('1) Set the PHPSTAN_PRO_WEB_PORT environment variable in the Dockerfile:'); $output->writeln(' ENV PHPSTAN_PRO_WEB_PORT=11111'); $output->writeln('2) Expose this port in the Dockerfile:'); $output->writeln(' EXPOSE 11111'); $output->writeln('3) Publish this port when running Docker:'); $output->writeln(' -p 127.0.0.1:11111:11111'); $output->writeln('4) Map the temp directory to a persistent volume'); $output->writeln(' so that you don\'t have to log in every time:'); $output->writeln(sprintf(' -v ~/phpstan-pro:%s', $this->proTmpDir)); $output->writeln(''); } } return new Process(sprintf('%s -d memory_limit=%s %s --port %d', escapeshellarg(PHP_BINARY), escapeshellarg(ini_get('memory_limit')), escapeshellarg($pharPath), $serverPort), null, $env, []); } private function downloadPhar(OutputInterface $output, string $pharPath, string $infoPath) : void { $currentVersion = null; $branch = '1.1.x'; if (is_file($pharPath) && is_file($infoPath)) { /** @var array{version: string, date: string, branch?: string} $currentInfo */ $currentInfo = Json::decode(FileReader::read($infoPath), Json::FORCE_ARRAY); $currentVersion = $currentInfo['version']; $currentBranch = $currentInfo['branch'] ?? 'master'; $currentDate = DateTime::createFromFormat(DateTime::ATOM, $currentInfo['date']); if ($currentDate === \false) { throw new ShouldNotHappenException(); } if ($currentBranch === $branch && new DateTimeImmutable('', new DateTimeZone('UTC')) <= $currentDate->modify('+24 hours')) { return; } $output->writeln('Checking if there\'s a new PHPStan Pro release...'); } $dnsConfig = new Config(); $dnsConfig->nameservers = $this->dnsServers; $client = new Browser(new Connector(['timeout' => 5, 'tls' => ['cafile' => CaBundle::getBundledCaBundlePath()], 'dns' => $dnsConfig])); /** * @var array{url: string, version: string} $latestInfo */ $latestInfo = Json::decode((string) await($client->get(sprintf('https://fixer-download-api.phpstan.com/latest?%s', http_build_query(['phpVersion' => PHP_VERSION_ID, 'branch' => $branch]))))->getBody(), Json::FORCE_ARRAY); if ($currentVersion !== null && $latestInfo['version'] === $currentVersion) { $this->writeInfoFile($infoPath, $latestInfo['version'], $branch); $output->writeln('You\'re running the latest PHPStan Pro!'); return; } $output->writeln('Downloading the latest PHPStan Pro...'); $pharPathResource = fopen($pharPath, 'w'); if ($pharPathResource === \false) { throw new ShouldNotHappenException(sprintf('Could not open file %s for writing.', $pharPath)); } $progressBar = new ProgressBar($output); $client->requestStreaming('GET', $latestInfo['url'])->then(static function (ResponseInterface $response) use($progressBar, $pharPathResource) : void { $body = $response->getBody(); if (!$body instanceof ReadableStreamInterface) { throw new ShouldNotHappenException(); } $totalSize = (int) $response->getHeaderLine('Content-Length'); $progressBar->setFormat('file_download'); $progressBar->setMessage(sprintf('%.2f MB', $totalSize / 1000000), 'fileSize'); $progressBar->start($totalSize); $bytes = 0; $body->on('data', static function ($chunk) use($pharPathResource, $progressBar, &$bytes) : void { $bytes += strlen($chunk); fwrite($pharPathResource, $chunk); $progressBar->setProgress($bytes); }); }, function (Throwable $e) use($output) : void { $this->printDownloadError($output, $e); }); Loop::run(); fclose($pharPathResource); $progressBar->finish(); $output->writeln(''); $output->writeln(''); $this->writeInfoFile($infoPath, $latestInfo['version'], $branch); } private function printDownloadError(OutputInterface $output, Throwable $e) : void { $output->writeln(sprintf('Could not download the PHPStan Pro executable: %s', $e->getMessage())); $output->writeln(''); $output->writeln('Try different DNS servers in your configuration file:'); $output->writeln(''); $output->writeln('parameters:'); $output->writeln("\tpro:"); $output->writeln("\t\tdnsServers!:"); $output->writeln("\t\t\t- '8.8.8.8'"); $output->writeln(''); } private function writeInfoFile(string $infoPath, string $version, string $branch) : void { FileWriter::write($infoPath, Json::encode(['version' => $version, 'branch' => $branch, 'date' => (new DateTimeImmutable('', new DateTimeZone('UTC')))->format(DateTime::ATOM)])); } /** * @param callable(FileMonitorResult): void $hasChangesCallback */ private function monitorFileChanges(LoopInterface $loop, callable $hasChangesCallback) : void { $callback = function () use(&$callback, $loop, $hasChangesCallback) : void { if (!$this->fileMonitorActive) { $loop->addTimer(1.0, $callback); return; } if ($this->processInProgress !== null) { $loop->addTimer(1.0, $callback); return; } $changes = $this->fileMonitor->getChanges(); if ($changes->hasAnyChanges()) { $hasChangesCallback($changes); } $loop->addTimer(1.0, $callback); }; $loop->addTimer(1.0, $callback); } private function analyse(LoopInterface $loop, string $mainScript, ?string $projectConfigFile, InputInterface $input, OutputInterface $output, Encoder $phpstanFixerEncoder) : void { $ignoredErrorHelperResult = $this->ignoredErrorHelper->initialize(); if (count($ignoredErrorHelperResult->getErrors()) > 0) { throw new ShouldNotHappenException(); } // TCP server for fixer:worker (TCP client) $server = new TcpServer('127.0.0.1:0', $loop); /** @var string $serverAddress */ $serverAddress = $server->getAddress(); /** @var int<0, 65535> $serverPort */ $serverPort = parse_url($serverAddress, PHP_URL_PORT); $server->on('connection', static function (ConnectionInterface $connection) use($phpstanFixerEncoder) : void { // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly $jsonInvalidUtf8Ignore = defined('JSON_INVALID_UTF8_IGNORE') ? JSON_INVALID_UTF8_IGNORE : 0; // phpcs:enable $decoder = new Decoder($connection, \true, 512, $jsonInvalidUtf8Ignore, 128 * 1024 * 1024); $decoder->on('data', static function (array $data) use($phpstanFixerEncoder) : void { $phpstanFixerEncoder->write($data); }); }); $process = new ProcessPromise($loop, 'changedFileAnalysis', ProcessHelper::getWorkerCommand($mainScript, 'fixer:worker', $projectConfigFile, ['--server-port', (string) $serverPort], $input)); $this->processInProgress = $process->run(); $this->processInProgress->then(function () use($server) : void { $this->processInProgress = null; $server->close(); }, function (Throwable $e) use($server, $phpstanFixerEncoder) : void { $this->processInProgress = null; $server->close(); if ($e instanceof ProcessCanceledException) { return; } if ($e instanceof ProcessCrashedException) { $message = 'Analysis crashed'; $traceAsString = $e->getMessage(); $trace = []; } else { $message = $e->getMessage(); $traceAsString = $e->getTraceAsString(); $trace = InternalError::prepareTrace($e); } $phpstanFixerEncoder->write(['action' => 'analysisCrash', 'data' => ['internalErrors' => [new InternalError($message, 'running PHPStan Pro worker', $trace, $traceAsString, \false)]]]); }); } private function isDockerRunning() : bool { return is_file('/.dockerenv'); } /** * @return list */ private function getComposerLocks() : array { $locks = []; foreach ($this->composerAutoloaderProjectPaths as $autoloadPath) { $lockPath = $autoloadPath . '/composer.lock'; if (!is_file($lockPath)) { continue; } $locks[] = $lockPath; } return $locks; } /** * @return list */ private function getComposerInstalled() : array { $files = []; foreach ($this->composerAutoloaderProjectPaths as $autoloadPath) { $composer = ComposerHelper::getComposerConfig($autoloadPath); if ($composer === null) { continue; } $filePath = ComposerHelper::getVendorDirFromComposerConfig($autoloadPath, $composer) . '/composer/installed.php'; if (!is_file($filePath)) { continue; } $files[] = $filePath; } return $files; } /** * @return list */ private function getExecutedFiles() : array { $files = []; if ($this->cliAutoloadFile !== null) { $files[] = $this->cliAutoloadFile; } foreach ($this->bootstrapFiles as $bootstrapFile) { $files[] = $bootstrapFile; } return $files; } /** * @return list */ private function getStubFiles() : array { $stubFiles = []; foreach ($this->stubFilesProvider->getProjectStubFiles() as $stubFile) { $stubFiles[] = $stubFile; } return $stubFiles; } } */ private $notFileSpecificErrors; /** * @var list */ private $internalErrors; /** * @var list */ private $warnings; /** * @var list */ private $collectedData; /** * @var bool */ private $defaultLevelUsed; /** * @var ?string */ private $projectConfigFile; /** * @var bool */ private $savedResultCache; /** * @var int */ private $peakMemoryUsageBytes; /** * @var bool */ private $isResultCacheUsed; /** * @var array */ private $changedProjectExtensionFilesOutsideOfAnalysedPaths; /** @var list sorted by their file name, line number and message */ private $fileSpecificErrors; /** * @param list $fileSpecificErrors * @param list $notFileSpecificErrors * @param list $internalErrors * @param list $warnings * @param list $collectedData * @param array $changedProjectExtensionFilesOutsideOfAnalysedPaths */ public function __construct(array $fileSpecificErrors, array $notFileSpecificErrors, array $internalErrors, array $warnings, array $collectedData, bool $defaultLevelUsed, ?string $projectConfigFile, bool $savedResultCache, int $peakMemoryUsageBytes, bool $isResultCacheUsed, array $changedProjectExtensionFilesOutsideOfAnalysedPaths) { $this->notFileSpecificErrors = $notFileSpecificErrors; $this->internalErrors = $internalErrors; $this->warnings = $warnings; $this->collectedData = $collectedData; $this->defaultLevelUsed = $defaultLevelUsed; $this->projectConfigFile = $projectConfigFile; $this->savedResultCache = $savedResultCache; $this->peakMemoryUsageBytes = $peakMemoryUsageBytes; $this->isResultCacheUsed = $isResultCacheUsed; $this->changedProjectExtensionFilesOutsideOfAnalysedPaths = $changedProjectExtensionFilesOutsideOfAnalysedPaths; usort($fileSpecificErrors, static function (Error $a, Error $b) : int { return [$a->getFile(), $a->getLine(), $a->getMessage()] <=> [$b->getFile(), $b->getLine(), $b->getMessage()]; }); $this->fileSpecificErrors = $fileSpecificErrors; } public function hasErrors() : bool { return $this->getTotalErrorsCount() > 0; } public function getTotalErrorsCount() : int { return count($this->fileSpecificErrors) + count($this->notFileSpecificErrors); } /** * @return list sorted by their file name, line number and message */ public function getFileSpecificErrors() : array { return $this->fileSpecificErrors; } /** * @return list */ public function getNotFileSpecificErrors() : array { return $this->notFileSpecificErrors; } /** * @deprecated Use getInternalErrorObjects * @return list */ public function getInternalErrors() : array { return array_map(static function (InternalError $internalError) { return $internalError->getMessage(); }, $this->internalErrors); } /** * @return list */ public function getInternalErrorObjects() : array { return $this->internalErrors; } /** * @return list */ public function getWarnings() : array { return $this->warnings; } public function hasWarnings() : bool { return count($this->warnings) > 0; } /** * @return list */ public function getCollectedData() : array { return $this->collectedData; } public function isDefaultLevelUsed() : bool { return $this->defaultLevelUsed; } public function getProjectConfigFile() : ?string { return $this->projectConfigFile; } public function hasInternalErrors() : bool { return count($this->internalErrors) > 0; } public function isResultCacheSaved() : bool { return $this->savedResultCache; } public function getPeakMemoryUsageBytes() : int { return $this->peakMemoryUsageBytes; } public function isResultCacheUsed() : bool { return $this->isResultCacheUsed; } /** * @return array */ public function getChangedProjectExtensionFilesOutsideOfAnalysedPaths() : array { return $this->changedProjectExtensionFilesOutsideOfAnalysedPaths; } } composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; parent::__construct(); } protected function configure() : void { $this->setName(self::NAME)->setDescription('(Internal) Support for parallel analysis.')->setDefinition([new InputArgument('paths', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Paths with source code to run analysis on'), new InputOption('configuration', 'c', InputOption::VALUE_REQUIRED, 'Path to project configuration file'), new InputOption(\PHPStan\Command\AnalyseCommand::OPTION_LEVEL, 'l', InputOption::VALUE_REQUIRED, 'Level of rule options - the higher the stricter'), new InputOption('autoload-file', 'a', InputOption::VALUE_REQUIRED, 'Project\'s additional autoload file path'), new InputOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Memory limit for analysis'), new InputOption('xdebug', null, InputOption::VALUE_NONE, 'Allow running with Xdebug for debugging purposes'), new InputOption('port', null, InputOption::VALUE_REQUIRED), new InputOption('identifier', null, InputOption::VALUE_REQUIRED), new InputOption('tmp-file', null, InputOption::VALUE_REQUIRED), new InputOption('instead-of', null, InputOption::VALUE_REQUIRED)])->setHidden(\true); } protected function execute(InputInterface $input, OutputInterface $output) : int { $paths = $input->getArgument('paths'); $memoryLimit = $input->getOption('memory-limit'); $autoloadFile = $input->getOption('autoload-file'); $configuration = $input->getOption('configuration'); $level = $input->getOption(\PHPStan\Command\AnalyseCommand::OPTION_LEVEL); $allowXdebug = $input->getOption('xdebug'); $port = $input->getOption('port'); $identifier = $input->getOption('identifier'); $tmpFile = $input->getOption('tmp-file'); $insteadOfFile = $input->getOption('instead-of'); if (!is_array($paths) || !is_string($memoryLimit) && $memoryLimit !== null || !is_string($autoloadFile) && $autoloadFile !== null || !is_string($configuration) && $configuration !== null || !is_string($level) && $level !== null || !is_bool($allowXdebug) || !is_string($port) || !is_string($identifier) || !is_string($tmpFile) && $tmpFile !== null || !is_string($insteadOfFile) && $insteadOfFile !== null) { throw new ShouldNotHappenException(); } try { $inceptionResult = \PHPStan\Command\CommandHelper::begin($input, $output, $paths, $memoryLimit, $autoloadFile, $this->composerAutoloaderProjectPaths, $configuration, null, $level, $allowXdebug, \false, $tmpFile, $insteadOfFile, \false); } catch (\PHPStan\Command\InceptionNotSuccessfulException $e) { return 1; } $loop = new StreamSelectLoop(); $container = $inceptionResult->getContainer(); try { [$analysedFiles] = $inceptionResult->getFiles(); $analysedFiles = $this->switchTmpFile($analysedFiles, $insteadOfFile, $tmpFile); } catch (PathNotFoundException $e) { $inceptionResult->getErrorOutput()->writeLineFormatted(sprintf('%s', $e->getMessage())); return 1; } catch (\PHPStan\Command\InceptionNotSuccessfulException $e) { return 1; } $nodeScopeResolver = $container->getByType(NodeScopeResolver::class); $nodeScopeResolver->setAnalysedFiles($analysedFiles); $analysedFiles = array_fill_keys($analysedFiles, \true); $tcpConnector = new TcpConnector($loop); $tcpConnector->connect(sprintf('127.0.0.1:%d', $port))->then(function (ConnectionInterface $connection) use($container, $identifier, $output, $analysedFiles, $tmpFile, $insteadOfFile) : void { // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly $jsonInvalidUtf8Ignore = defined('JSON_INVALID_UTF8_IGNORE') ? \JSON_INVALID_UTF8_IGNORE : 0; // phpcs:enable $out = new Encoder($connection, $jsonInvalidUtf8Ignore); $in = new Decoder($connection, \true, 512, $jsonInvalidUtf8Ignore, $container->getParameter('parallel')['buffer']); $out->write(['action' => 'hello', 'identifier' => $identifier]); $this->runWorker($container, $out, $in, $output, $analysedFiles, $tmpFile, $insteadOfFile); }); $loop->run(); if ($this->errorCount > 0) { return 1; } return 0; } /** * @param array $analysedFiles */ private function runWorker(Container $container, WritableStreamInterface $out, ReadableStreamInterface $in, OutputInterface $output, array $analysedFiles, ?string $tmpFile, ?string $insteadOfFile) : void { $handleError = function (Throwable $error) use($out, $output) : void { $this->errorCount++; $output->writeln(sprintf('Error: %s', $error->getMessage())); $out->write(['action' => 'result', 'result' => ['errors' => [], 'internalErrors' => [new InternalError($error->getMessage(), 'communicating with main process in parallel worker', InternalError::prepareTrace($error), $error->getTraceAsString(), \true)], 'filteredPhpErrors' => [], 'allPhpErrors' => [], 'locallyIgnoredErrors' => [], 'linesToIgnore' => [], 'unmatchedLineIgnores' => [], 'collectedData' => [], 'memoryUsage' => memory_get_peak_usage(\true), 'dependencies' => [], 'exportedNodes' => [], 'files' => [], 'internalErrorsCount' => 1]]); $out->end(); }; $out->on('error', $handleError); $fileAnalyser = $container->getByType(FileAnalyser::class); $ruleRegistry = $container->getByType(RuleRegistry::class); $collectorRegistry = $container->getByType(CollectorRegistry::class); $in->on('data', static function (array $json) use($fileAnalyser, $ruleRegistry, $collectorRegistry, $out, $analysedFiles, $tmpFile, $insteadOfFile) : void { $action = $json['action']; if ($action !== 'analyse') { return; } $internalErrorsCount = 0; $files = $json['files']; $errors = []; $internalErrors = []; $filteredPhpErrors = []; $allPhpErrors = []; $locallyIgnoredErrors = []; $linesToIgnore = []; $unmatchedLineIgnores = []; $collectedData = []; $dependencies = []; $usedTraitDependencies = []; $exportedNodes = []; foreach ($files as $file) { try { if ($file === $insteadOfFile) { $file = $tmpFile; } $fileAnalyserResult = $fileAnalyser->analyseFile($file, $analysedFiles, $ruleRegistry, $collectorRegistry, null); $fileErrors = $fileAnalyserResult->getErrors(); $filteredPhpErrors = array_merge($filteredPhpErrors, $fileAnalyserResult->getFilteredPhpErrors()); $allPhpErrors = array_merge($allPhpErrors, $fileAnalyserResult->getAllPhpErrors()); $linesToIgnore[$file] = $fileAnalyserResult->getLinesToIgnore(); $unmatchedLineIgnores[$file] = $fileAnalyserResult->getUnmatchedLineIgnores(); $dependencies[$file] = $fileAnalyserResult->getDependencies(); $usedTraitDependencies[$file] = $fileAnalyserResult->getUsedTraitDependencies(); $exportedNodes[$file] = $fileAnalyserResult->getExportedNodes(); foreach ($fileErrors as $fileError) { $errors[] = $fileError; } foreach ($fileAnalyserResult->getLocallyIgnoredErrors() as $locallyIgnoredError) { $locallyIgnoredErrors[] = $locallyIgnoredError; } foreach ($fileAnalyserResult->getCollectedData() as $data) { $collectedData[] = $data; } } catch (Throwable $t) { $internalErrorsCount++; $internalErrors[] = new InternalError($t->getMessage(), sprintf('analysing file %s', $file), InternalError::prepareTrace($t), $t->getTraceAsString(), \true); } } $out->write(['action' => 'result', 'result' => ['errors' => $errors, 'internalErrors' => $internalErrors, 'filteredPhpErrors' => $filteredPhpErrors, 'allPhpErrors' => $allPhpErrors, 'locallyIgnoredErrors' => $locallyIgnoredErrors, 'linesToIgnore' => $linesToIgnore, 'unmatchedLineIgnores' => $unmatchedLineIgnores, 'collectedData' => $collectedData, 'memoryUsage' => memory_get_peak_usage(\true), 'dependencies' => $dependencies, 'usedTraitDependencies' => $usedTraitDependencies, 'exportedNodes' => $exportedNodes, 'files' => $files, 'internalErrorsCount' => $internalErrorsCount]]); }); $in->on('error', $handleError); } /** * @param string[] $analysedFiles * @return string[] */ private function switchTmpFile(array $analysedFiles, ?string $insteadOfFile, ?string $tmpFile) : array { if ($insteadOfFile === null) { return $analysedFiles; } $analysedFiles = array_values(array_filter($analysedFiles, static function (string $file) use($insteadOfFile) : bool { return $file !== $insteadOfFile; })); if ($tmpFile !== null) { array_unshift($analysedFiles, $tmpFile); } return $analysedFiles; } } analyserRunner = $analyserRunner; $this->analyserResultFinalizer = $analyserResultFinalizer; $this->stubValidator = $stubValidator; $this->resultCacheManagerFactory = $resultCacheManagerFactory; $this->ignoredErrorHelper = $ignoredErrorHelper; $this->stubFilesProvider = $stubFilesProvider; } /** * @param string[] $files * @param mixed[]|null $projectConfigArray */ public function analyse(array $files, bool $onlyFiles, \PHPStan\Command\Output $stdOutput, \PHPStan\Command\Output $errorOutput, bool $defaultLevelUsed, bool $debug, ?string $projectConfigFile, ?array $projectConfigArray, ?string $tmpFile, ?string $insteadOfFile, InputInterface $input) : \PHPStan\Command\AnalysisResult { $isResultCacheUsed = \false; $fileReplacements = []; if ($tmpFile !== null && $insteadOfFile !== null) { $fileReplacements = [$insteadOfFile => $tmpFile]; } $resultCacheManager = $this->resultCacheManagerFactory->create($fileReplacements); $ignoredErrorHelperResult = $this->ignoredErrorHelper->initialize(); $fileSpecificErrors = []; if (count($ignoredErrorHelperResult->getErrors()) > 0) { $notFileSpecificErrors = $ignoredErrorHelperResult->getErrors(); $internalErrors = []; $collectedData = []; $savedResultCache = \false; $memoryUsageBytes = memory_get_peak_usage(\true); if ($errorOutput->isVeryVerbose()) { $errorOutput->writeLineFormatted('Result cache was not saved because of ignoredErrorHelperResult errors.'); } $changedProjectExtensionFilesOutsideOfAnalysedPaths = []; } else { $resultCache = $resultCacheManager->restore($files, $debug, $onlyFiles, $projectConfigArray, $errorOutput); $intermediateAnalyserResult = $this->runAnalyser($resultCache->getFilesToAnalyse(), $files, $debug, $projectConfigFile, $tmpFile, $insteadOfFile, $stdOutput, $errorOutput, $input); $projectStubFiles = $this->stubFilesProvider->getProjectStubFiles(); $forceValidateStubFiles = (bool) ($_SERVER['__PHPSTAN_FORCE_VALIDATE_STUB_FILES'] ?? \false); if ($resultCache->isFullAnalysis() && count($projectStubFiles) !== 0 && (!$onlyFiles || $forceValidateStubFiles)) { $stubErrors = $this->stubValidator->validate($projectStubFiles, $debug); $intermediateAnalyserResult = new AnalyserResult(array_merge($intermediateAnalyserResult->getUnorderedErrors(), $stubErrors), $intermediateAnalyserResult->getFilteredPhpErrors(), $intermediateAnalyserResult->getAllPhpErrors(), $intermediateAnalyserResult->getLocallyIgnoredErrors(), $intermediateAnalyserResult->getLinesToIgnore(), $intermediateAnalyserResult->getUnmatchedLineIgnores(), $intermediateAnalyserResult->getInternalErrors(), $intermediateAnalyserResult->getCollectedData(), $intermediateAnalyserResult->getDependencies(), $intermediateAnalyserResult->getUsedTraitDependencies(), $intermediateAnalyserResult->getExportedNodes(), $intermediateAnalyserResult->hasReachedInternalErrorsCountLimit(), $intermediateAnalyserResult->getPeakMemoryUsageBytes()); } $resultCacheResult = $resultCacheManager->process($intermediateAnalyserResult, $resultCache, $errorOutput, $onlyFiles, \true); $analyserResult = $this->analyserResultFinalizer->finalize($this->switchTmpFileInAnalyserResult($resultCacheResult->getAnalyserResult(), $insteadOfFile, $tmpFile), $onlyFiles, $debug)->getAnalyserResult(); $internalErrors = $analyserResult->getInternalErrors(); $errors = array_merge($analyserResult->getErrors(), $analyserResult->getFilteredPhpErrors()); $hasInternalErrors = count($internalErrors) > 0 || $analyserResult->hasReachedInternalErrorsCountLimit(); $memoryUsageBytes = $analyserResult->getPeakMemoryUsageBytes(); $isResultCacheUsed = !$resultCache->isFullAnalysis(); $changedProjectExtensionFilesOutsideOfAnalysedPaths = []; if ($isResultCacheUsed && $resultCacheResult->isSaved() && !$onlyFiles && $projectConfigArray !== null) { foreach ($resultCache->getProjectExtensionFiles() as $file => [$hash, $isAnalysed, $className]) { if ($isAnalysed) { continue; } if (!is_file($file)) { $changedProjectExtensionFilesOutsideOfAnalysedPaths[$file] = $className; continue; } $newHash = sha1_file($file); if ($newHash === $hash) { continue; } $changedProjectExtensionFilesOutsideOfAnalysedPaths[$file] = $className; } } $ignoredErrorHelperProcessedResult = $ignoredErrorHelperResult->process($errors, $onlyFiles, $files, $hasInternalErrors); $fileSpecificErrors = $ignoredErrorHelperProcessedResult->getNotIgnoredErrors(); $notFileSpecificErrors = $ignoredErrorHelperProcessedResult->getOtherIgnoreMessages(); $collectedData = $analyserResult->getCollectedData(); $savedResultCache = $resultCacheResult->isSaved(); } return new \PHPStan\Command\AnalysisResult($fileSpecificErrors, $notFileSpecificErrors, $internalErrors, [], $collectedData, $defaultLevelUsed, $projectConfigFile, $savedResultCache, $memoryUsageBytes, $isResultCacheUsed, $changedProjectExtensionFilesOutsideOfAnalysedPaths); } /** * @param string[] $files * @param string[] $allAnalysedFiles */ private function runAnalyser(array $files, array $allAnalysedFiles, bool $debug, ?string $projectConfigFile, ?string $tmpFile, ?string $insteadOfFile, \PHPStan\Command\Output $stdOutput, \PHPStan\Command\Output $errorOutput, InputInterface $input) : AnalyserResult { $filesCount = count($files); $allAnalysedFilesCount = count($allAnalysedFiles); if ($filesCount === 0) { $errorOutput->getStyle()->progressStart($allAnalysedFilesCount); $errorOutput->getStyle()->progressAdvance($allAnalysedFilesCount); $errorOutput->getStyle()->progressFinish(); return new AnalyserResult([], [], [], [], [], [], [], [], [], [], [], \false, memory_get_peak_usage(\true)); } if (!$debug) { $preFileCallback = null; $postFileCallback = static function (int $step) use($errorOutput) : void { $errorOutput->getStyle()->progressAdvance($step); }; $errorOutput->getStyle()->progressStart($allAnalysedFilesCount); $errorOutput->getStyle()->progressAdvance($allAnalysedFilesCount - $filesCount); } else { $startTime = null; $preFileCallback = static function (string $file) use($stdOutput, &$startTime) : void { $stdOutput->writeLineFormatted($file); $startTime = microtime(\true); }; $postFileCallback = null; if ($stdOutput->isDebug()) { $previousMemory = memory_get_peak_usage(\true); $postFileCallback = static function () use($stdOutput, &$previousMemory, &$startTime) : void { if ($startTime === null) { throw new ShouldNotHappenException(); } $currentTotalMemory = memory_get_peak_usage(\true); $elapsedTime = microtime(\true) - $startTime; $stdOutput->writeLineFormatted(sprintf('--- consumed %s, total %s, took %.2f s', BytesHelper::bytes($currentTotalMemory - $previousMemory), BytesHelper::bytes($currentTotalMemory), $elapsedTime)); $previousMemory = $currentTotalMemory; }; } } $analyserResult = $this->analyserRunner->runAnalyser($files, $allAnalysedFiles, $preFileCallback, $postFileCallback, $debug, \true, $projectConfigFile, $tmpFile, $insteadOfFile, $input); if (!$debug) { $errorOutput->getStyle()->progressFinish(); } return $analyserResult; } private function switchTmpFileInAnalyserResult(AnalyserResult $analyserResult, ?string $insteadOfFile, ?string $tmpFile) : AnalyserResult { if ($insteadOfFile === null || $tmpFile === null) { return $analyserResult; } $collectedData = []; foreach ($analyserResult->getCollectedData() as $data) { if ($data->getFilePath() === $tmpFile) { $data = $data->changeFilePath($insteadOfFile); } $collectedData[] = $data; } $dependencies = null; if ($analyserResult->getDependencies() !== null) { $dependencies = $this->switchTmpFileInDependencies($analyserResult->getDependencies(), $insteadOfFile, $tmpFile); } $usedTraitDependencies = null; if ($analyserResult->getUsedTraitDependencies() !== null) { $usedTraitDependencies = $this->switchTmpFileInDependencies($analyserResult->getUsedTraitDependencies(), $insteadOfFile, $tmpFile); } $exportedNodes = []; foreach ($analyserResult->getExportedNodes() as $file => $fileExportedNodes) { if ($file === $tmpFile) { $file = $insteadOfFile; } $exportedNodes[$file] = $fileExportedNodes; } return new AnalyserResult($this->switchTmpFileInErrors($analyserResult->getUnorderedErrors(), $insteadOfFile, $tmpFile), $this->switchTmpFileInErrors($analyserResult->getFilteredPhpErrors(), $insteadOfFile, $tmpFile), $this->switchTmpFileInErrors($analyserResult->getAllPhpErrors(), $insteadOfFile, $tmpFile), $this->switchTmpFileInErrors($analyserResult->getLocallyIgnoredErrors(), $insteadOfFile, $tmpFile), $this->swittchTmpFileInLinesToIgnore($analyserResult->getLinesToIgnore(), $insteadOfFile, $tmpFile), $this->swittchTmpFileInLinesToIgnore($analyserResult->getUnmatchedLineIgnores(), $insteadOfFile, $tmpFile), $analyserResult->getInternalErrors(), $collectedData, $dependencies, $usedTraitDependencies, $exportedNodes, $analyserResult->hasReachedInternalErrorsCountLimit(), $analyserResult->getPeakMemoryUsageBytes()); } /** * @param array> $dependencies * @return array> */ private function switchTmpFileInDependencies(array $dependencies, string $insteadOfFile, string $tmpFile) : array { $newDependencies = []; foreach ($dependencies as $dependencyFile => $dependentFiles) { $new = []; foreach ($dependentFiles as $file) { if ($file === $tmpFile) { $new[] = $insteadOfFile; continue; } $new[] = $file; } $key = $dependencyFile; if ($key === $tmpFile) { $key = $insteadOfFile; } $newDependencies[$key] = $new; } return $newDependencies; } /** * @param list $errors * @return list */ private function switchTmpFileInErrors(array $errors, string $insteadOfFile, string $tmpFile) : array { $newErrors = []; foreach ($errors as $error) { if ($error->getFilePath() === $tmpFile) { $error = $error->changeFilePath($insteadOfFile); } if ($error->getTraitFilePath() === $tmpFile) { $error = $error->changeTraitFilePath($insteadOfFile); } $newErrors[] = $error; } return $newErrors; } /** * @param array $linesToIgnore * @return array */ private function swittchTmpFileInLinesToIgnore(array $linesToIgnore, string $insteadOfFile, string $tmpFile) : array { $newLinesToIgnore = []; foreach ($linesToIgnore as $file => $lines) { if ($file === $tmpFile) { $file = $insteadOfFile; } $newLines = []; foreach ($lines as $f => $line) { if ($f === $tmpFile) { $f = $insteadOfFile; } $newLines[$f] = $line; } $newLinesToIgnore[$file] = $newLines; } return $newLinesToIgnore; } } composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; parent::__construct(); } protected function configure() : void { $this->setName(self::NAME)->setDescription('Dumps all parameters')->setDefinition([new InputOption('configuration', 'c', InputOption::VALUE_REQUIRED, 'Path to project configuration file'), new InputOption(\PHPStan\Command\AnalyseCommand::OPTION_LEVEL, 'l', InputOption::VALUE_REQUIRED, 'Level of rule options - the higher the stricter'), new InputOption('autoload-file', 'a', InputOption::VALUE_REQUIRED, 'Project\'s additional autoload file path'), new InputOption('debug', null, InputOption::VALUE_NONE, 'Show debug information - which file is analysed, do not catch internal errors'), new InputOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Memory limit for clearing result cache'), new InputOption('json', null, InputOption::VALUE_NONE, 'Dump parameters as JSON instead of NEON')]); } protected function initialize(InputInterface $input, OutputInterface $output) : void { if ((bool) $input->getOption('debug')) { $application = $this->getApplication(); if ($application === null) { throw new ShouldNotHappenException(); } $application->setCatchExceptions(\false); return; } } protected function execute(InputInterface $input, OutputInterface $output) : int { $memoryLimit = $input->getOption('memory-limit'); $autoloadFile = $input->getOption('autoload-file'); $configuration = $input->getOption('configuration'); $level = $input->getOption(\PHPStan\Command\AnalyseCommand::OPTION_LEVEL); $json = (bool) $input->getOption('json'); if (!is_string($memoryLimit) && $memoryLimit !== null || !is_string($autoloadFile) && $autoloadFile !== null || !is_string($configuration) && $configuration !== null || !is_string($level) && $level !== null) { throw new ShouldNotHappenException(); } try { $inceptionResult = \PHPStan\Command\CommandHelper::begin($input, $output, [], $memoryLimit, $autoloadFile, $this->composerAutoloaderProjectPaths, $configuration, null, $level, \false); } catch (\PHPStan\Command\InceptionNotSuccessfulException $e) { return 1; } $parameters = $inceptionResult->getContainer()->getParameters(); // always set to '.' unset($parameters['analysedPaths']); // irrelevant Nette parameters unset($parameters['debugMode']); unset($parameters['productionMode']); unset($parameters['tempDir']); unset($parameters['__validate']); // internal - editor mode unset($parameters['singleReflectionFile']); unset($parameters['singleReflectionInsteadOfFile']); if ($json) { $encoded = Json::encode($parameters, Json::PRETTY); } else { $encoded = Neon::encode($parameters, \true); } $output->writeln($encoded); return 0; } } composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; parent::__construct(); } protected function configure() : void { $this->setName(self::NAME)->setDescription('Shows diagnose information about PHPStan and extensions')->setDefinition([new InputOption('configuration', 'c', InputOption::VALUE_REQUIRED, 'Path to project configuration file'), new InputOption(\PHPStan\Command\AnalyseCommand::OPTION_LEVEL, 'l', InputOption::VALUE_REQUIRED, 'Level of rule options - the higher the stricter'), new InputOption('autoload-file', 'a', InputOption::VALUE_REQUIRED, 'Project\'s additional autoload file path'), new InputOption('debug', null, InputOption::VALUE_NONE, 'Show debug information - do not catch internal errors'), new InputOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Memory limit for clearing result cache')]); } protected function initialize(InputInterface $input, OutputInterface $output) : void { if ((bool) $input->getOption('debug')) { $application = $this->getApplication(); if ($application === null) { throw new ShouldNotHappenException(); } $application->setCatchExceptions(\false); return; } } protected function execute(InputInterface $input, OutputInterface $output) : int { $memoryLimit = $input->getOption('memory-limit'); $autoloadFile = $input->getOption('autoload-file'); $configuration = $input->getOption('configuration'); $level = $input->getOption(\PHPStan\Command\AnalyseCommand::OPTION_LEVEL); if (!is_string($memoryLimit) && $memoryLimit !== null || !is_string($autoloadFile) && $autoloadFile !== null || !is_string($configuration) && $configuration !== null || !is_string($level) && $level !== null) { throw new ShouldNotHappenException(); } try { $inceptionResult = \PHPStan\Command\CommandHelper::begin($input, $output, [], $memoryLimit, $autoloadFile, $this->composerAutoloaderProjectPaths, $configuration, null, $level, \false); } catch (\PHPStan\Command\InceptionNotSuccessfulException $e) { return 1; } $container = $inceptionResult->getContainer(); $output = $inceptionResult->getStdOutput(); /** @var PHPStanDiagnoseExtension $phpstanDiagnoseExtension */ $phpstanDiagnoseExtension = $container->getService('phpstanDiagnoseExtension'); // not using tag for this extension to make sure it's always first $phpstanDiagnoseExtension->print($output); /** @var DiagnoseExtension $extension */ foreach ($container->getServicesByTag(DiagnoseExtension::EXTENSION_TAG) as $extension) { $extension->print($output); } return 0; } } relativePathHelper = $relativePathHelper; } public function formatErrors(AnalysisResult $analysisResult, Output $output) : int { $output->writeRaw(''); $output->writeLineFormatted(''); $output->writeRaw(''); $output->writeLineFormatted(''); foreach ($this->groupByFile($analysisResult) as $relativeFilePath => $errors) { $output->writeRaw(sprintf('', $this->escape($relativeFilePath))); $output->writeLineFormatted(''); foreach ($errors as $error) { $output->writeRaw(sprintf(' ', $this->escape((string) $error->getLine()), $this->escape($error->getMessage()), $error->getIdentifier() !== null ? sprintf(' source="%s"', $this->escape($error->getIdentifier())) : '')); $output->writeLineFormatted(''); } $output->writeRaw(''); $output->writeLineFormatted(''); } $notFileSpecificErrors = $analysisResult->getNotFileSpecificErrors(); if (count($notFileSpecificErrors) > 0) { $output->writeRaw(''); $output->writeLineFormatted(''); foreach ($notFileSpecificErrors as $error) { $output->writeRaw(sprintf(' ', $this->escape($error))); $output->writeLineFormatted(''); } $output->writeRaw(''); $output->writeLineFormatted(''); } if ($analysisResult->hasWarnings()) { $output->writeRaw(''); $output->writeLineFormatted(''); foreach ($analysisResult->getWarnings() as $warning) { $output->writeRaw(sprintf(' ', $this->escape($warning))); $output->writeLineFormatted(''); } $output->writeRaw(''); $output->writeLineFormatted(''); } $output->writeRaw(''); $output->writeLineFormatted(''); return $analysisResult->hasErrors() ? 1 : 0; } /** * Escapes values for using in XML * */ private function escape(string $string) : string { return htmlspecialchars($string, ENT_XML1 | ENT_COMPAT, 'UTF-8'); } /** * Group errors by file * * @return array> Array that have as key the relative path of file * and as value an array with occurred errors. */ private function groupByFile(AnalysisResult $analysisResult) : array { $files = []; /** @var Error $fileSpecificError */ foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { $absolutePath = $fileSpecificError->getFilePath(); if ($fileSpecificError->getTraitFilePath() !== null) { $absolutePath = $fileSpecificError->getTraitFilePath(); } $relativeFilePath = $this->relativePathHelper->getRelativePath($absolutePath); $files[$relativeFilePath][] = $fileSpecificError; } return $files; } } relativePathHelper = $relativePathHelper; } public function formatErrors(AnalysisResult $analysisResult, Output $output, string $existingBaselineContent) : int { if (!$analysisResult->hasErrors()) { $output->writeRaw($this->getNeon([], $existingBaselineContent)); return 0; } $fileErrors = []; foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { if (!$fileSpecificError->canBeIgnored()) { continue; } $fileErrors[$this->relativePathHelper->getRelativePath($fileSpecificError->getFilePath())][] = $fileSpecificError->getMessage(); } ksort($fileErrors, SORT_STRING); $errorsToOutput = []; foreach ($fileErrors as $file => $errorMessages) { $fileErrorsCounts = []; foreach ($errorMessages as $errorMessage) { if (!isset($fileErrorsCounts[$errorMessage])) { $fileErrorsCounts[$errorMessage] = 1; continue; } $fileErrorsCounts[$errorMessage]++; } ksort($fileErrorsCounts, SORT_STRING); foreach ($fileErrorsCounts as $message => $count) { $errorsToOutput[] = ['message' => Helpers::escape('#^' . preg_quote($message, '#') . '$#'), 'count' => $count, 'path' => Helpers::escape($file)]; } } $output->writeRaw($this->getNeon($errorsToOutput, $existingBaselineContent)); return 1; } /** * @param array $ignoreErrors */ private function getNeon(array $ignoreErrors, string $existingBaselineContent) : string { $neon = Neon::encode(['parameters' => ['ignoreErrors' => $ignoreErrors]], Neon::BLOCK); if (substr($neon, -2) !== "\n\n") { throw new ShouldNotHappenException(); } if ($existingBaselineContent === '') { return substr($neon, 0, -1); } $existingBaselineContentEndOfFileNewlinesMatches = Strings::match($existingBaselineContent, "~(\n)+\$~"); $existingBaselineContentEndOfFileNewlines = $existingBaselineContentEndOfFileNewlinesMatches !== null ? $existingBaselineContentEndOfFileNewlinesMatches[0] : ''; return substr($neon, 0, -2) . $existingBaselineContentEndOfFileNewlines; } } relativePathHelper = $relativePathHelper; } public function formatErrors(AnalysisResult $analysisResult, Output $output) : int { foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { $metas = ['file' => $this->relativePathHelper->getRelativePath($fileSpecificError->getFile()), 'line' => $fileSpecificError->getLine(), 'col' => 0]; array_walk($metas, static function (&$value, string $key) : void { $value = sprintf('%s=%s', $key, (string) $value); }); $message = $fileSpecificError->getMessage(); // newlines need to be encoded // see https://github.com/actions/starter-workflows/issues/68#issuecomment-581479448 $message = str_replace("\n", '%0A', $message); $line = sprintf('::error %s::%s', implode(',', $metas), $message); $output->writeRaw($line); $output->writeLineFormatted(''); } foreach ($analysisResult->getNotFileSpecificErrors() as $notFileSpecificError) { // newlines need to be encoded // see https://github.com/actions/starter-workflows/issues/68#issuecomment-581479448 $notFileSpecificError = str_replace("\n", '%0A', $notFileSpecificError); $line = sprintf('::error ::%s', $notFileSpecificError); $output->writeRaw($line); $output->writeLineFormatted(''); } foreach ($analysisResult->getWarnings() as $warning) { // newlines need to be encoded // see https://github.com/actions/starter-workflows/issues/68#issuecomment-581479448 $warning = str_replace("\n", '%0A', $warning); $line = sprintf('::warning ::%s', $warning); $output->writeRaw($line); $output->writeLineFormatted(''); } return $analysisResult->hasErrors() ? 1 : 0; } } relativePathHelper = $relativePathHelper; } public function formatErrors(AnalysisResult $analysisResult, Output $output) : int { $result = ''; $fileSpecificErrors = $analysisResult->getFileSpecificErrors(); $notFileSpecificErrors = $analysisResult->getNotFileSpecificErrors(); $warnings = $analysisResult->getWarnings(); if (count($fileSpecificErrors) === 0 && count($notFileSpecificErrors) === 0 && count($warnings) === 0) { return 0; } $result .= $this->createTeamcityLine('inspectionType', ['id' => 'phpstan', 'name' => 'phpstan', 'category' => 'phpstan', 'description' => 'phpstan Inspection']); foreach ($fileSpecificErrors as $fileSpecificError) { $result .= $this->createTeamcityLine('inspection', [ 'typeId' => 'phpstan', 'message' => $fileSpecificError->getMessage(), 'file' => $this->relativePathHelper->getRelativePath($fileSpecificError->getFile()), 'line' => $fileSpecificError->getLine(), // additional attributes 'SEVERITY' => 'ERROR', 'ignorable' => $fileSpecificError->canBeIgnored(), 'tip' => $fileSpecificError->getTip(), ]); } foreach ($notFileSpecificErrors as $notFileSpecificError) { $result .= $this->createTeamcityLine('inspection', [ 'typeId' => 'phpstan', 'message' => $notFileSpecificError, // the file is required 'file' => $analysisResult->getProjectConfigFile() !== null ? $this->relativePathHelper->getRelativePath($analysisResult->getProjectConfigFile()) : '.', 'SEVERITY' => 'ERROR', ]); } foreach ($warnings as $warning) { $result .= $this->createTeamcityLine('inspection', [ 'typeId' => 'phpstan', 'message' => $warning, // the file is required 'file' => $analysisResult->getProjectConfigFile() !== null ? $this->relativePathHelper->getRelativePath($analysisResult->getProjectConfigFile()) : '.', 'SEVERITY' => 'WARNING', ]); } $output->writeRaw($result); return $analysisResult->hasErrors() ? 1 : 0; } /** * Creates a Teamcity report line * * @param string $messageName The message name * @param mixed[] $keyValuePairs The key=>value pairs * @return string The Teamcity report line */ private function createTeamcityLine(string $messageName, array $keyValuePairs) : string { $string = '##teamcity[' . $messageName; foreach ($keyValuePairs as $key => $value) { if (is_string($value)) { $value = $this->escape($value); } $string .= ' ' . $key . '=\'' . $value . '\''; } return $string . ']' . PHP_EOL; } /** * Escapes the given string for Teamcity output * * @param string $string The string to escape * @return string The escaped string */ private function escape(string $string) : string { $replacements = ['~\\n~' => '|n', '~\\r~' => '|r', '~([\'\\|\\[\\]])~' => '|$1']; return (string) preg_replace(array_keys($replacements), array_values($replacements), $string); } } relativePathHelper = $relativePathHelper; } public function formatErrors(AnalysisResult $analysisResult, Output $output) : int { if (!$analysisResult->hasErrors()) { $php = 'writeRaw($php); return 0; } $fileErrors = []; foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { if (!$fileSpecificError->canBeIgnored()) { continue; } $fileErrors['/' . $this->relativePathHelper->getRelativePath($fileSpecificError->getFilePath())][] = $fileSpecificError; } ksort($fileErrors, SORT_STRING); $php = ' $errors) { $fileErrorsByMessage = []; foreach ($errors as $error) { $errorMessage = $error->getMessage(); if (!isset($fileErrorsByMessage[$errorMessage])) { $fileErrorsByMessage[$errorMessage] = [1, $error->getIdentifier() !== null ? [$error->getIdentifier() => \true] : []]; continue; } $fileErrorsByMessage[$errorMessage][0]++; if ($error->getIdentifier() === null) { continue; } $fileErrorsByMessage[$errorMessage][1][$error->getIdentifier()] = \true; } ksort($fileErrorsByMessage, SORT_STRING); foreach ($fileErrorsByMessage as $message => [$count, $identifiersInKeys]) { $identifiers = array_keys($identifiersInKeys); sort($identifiers); $identifiersComment = ''; if (count($identifiers) > 0) { if (count($identifiers) === 1) { $identifiersComment = "\n\t// identifier: " . $identifiers[0]; } else { $identifiersComment = "\n\t// identifiers: " . implode(', ', $identifiers); } } $php .= sprintf("\$ignoreErrors[] = [%s\n\t'message' => %s,\n\t'count' => %d,\n\t'path' => __DIR__ . %s,\n];\n", $identifiersComment, var_export(Helpers::escape('#^' . preg_quote($message, '#') . '$#'), \true), var_export($count, \true), var_export(Helpers::escape($file), \true)); } } $php .= "\n"; $php .= 'return [\'parameters\' => [\'ignoreErrors\' => $ignoreErrors]];'; $php .= "\n"; $output->writeRaw($php); return 1; } } githubErrorFormatter = $githubErrorFormatter; $this->teamcityErrorFormatter = $teamcityErrorFormatter; } public function formatErrors(AnalysisResult $analysisResult, Output $output) : int { $ciDetector = new CiDetector(); try { $ci = $ciDetector->detect(); if ($ci->getCiName() === CiDetector::CI_GITHUB_ACTIONS) { return $this->githubErrorFormatter->formatErrors($analysisResult, $output); } elseif ($ci->getCiName() === CiDetector::CI_TEAMCITY) { return $this->teamcityErrorFormatter->formatErrors($analysisResult, $output); } } catch (CiNotDetectedException $e) { // pass } if (!$analysisResult->hasErrors() && !$analysisResult->hasWarnings()) { return 0; } return $analysisResult->getTotalErrorsCount() > 0 ? 1 : 0; } } getNotFileSpecificErrors() as $notFileSpecificError) { $output->writeRaw(sprintf('?:?:%s', $notFileSpecificError)); $output->writeLineFormatted(''); } $outputIdentifiers = $output->isVerbose(); foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { $identifier = ''; if ($outputIdentifiers && $fileSpecificError->getIdentifier() !== null) { $identifier = sprintf(' [identifier=%s]', $fileSpecificError->getIdentifier()); } $output->writeRaw(sprintf('%s:%d:%s%s', $fileSpecificError->getFile(), $fileSpecificError->getLine() ?? '?', $fileSpecificError->getMessage(), $identifier)); $output->writeLineFormatted(''); } foreach ($analysisResult->getWarnings() as $warning) { $output->writeRaw(sprintf('?:?:%s', $warning)); $output->writeLineFormatted(''); } return $analysisResult->hasErrors() ? 1 : 0; } } relativePathHelper = $relativePathHelper; } public function formatErrors(AnalysisResult $analysisResult, Output $output) : int { $totalFailuresCount = $analysisResult->getTotalErrorsCount(); $totalTestsCount = $analysisResult->hasErrors() ? $totalFailuresCount : 1; $result = ''; $result .= sprintf('', $totalFailuresCount, $totalTestsCount); foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { $fileName = $this->relativePathHelper->getRelativePath($fileSpecificError->getFile()); $result .= $this->createTestCase(sprintf('%s:%s', $fileName, (string) $fileSpecificError->getLine()), 'ERROR', $fileSpecificError->getMessage()); } foreach ($analysisResult->getNotFileSpecificErrors() as $notFileSpecificError) { $result .= $this->createTestCase('General error', 'ERROR', $notFileSpecificError); } foreach ($analysisResult->getWarnings() as $warning) { $result .= $this->createTestCase('Warning', 'WARNING', $warning); } if (!$analysisResult->hasErrors()) { $result .= $this->createTestCase('phpstan', ''); } $result .= ''; $output->writeRaw($result); return $analysisResult->hasErrors() ? 1 : 0; } /** * Format a single test case * * */ private function createTestCase(string $reference, string $type, ?string $message = null) : string { $result = sprintf('', $this->escape($reference)); if ($message !== null) { $result .= sprintf('', $this->escape($type), $this->escape($message)); } $result .= ''; return $result; } /** * Escapes values for using in XML * */ private function escape(string $string) : string { return htmlspecialchars($string, ENT_XML1 | ENT_COMPAT, 'UTF-8'); } } relativePathHelper = $relativePathHelper; } public function formatErrors(AnalysisResult $analysisResult, Output $output) : int { $errorsArray = []; foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { $error = ['description' => $fileSpecificError->getMessage(), 'fingerprint' => hash('sha256', implode([$fileSpecificError->getFile(), $fileSpecificError->getLine(), $fileSpecificError->getMessage()])), 'severity' => $fileSpecificError->canBeIgnored() ? 'major' : 'blocker', 'location' => ['path' => $this->relativePathHelper->getRelativePath($fileSpecificError->getFile()), 'lines' => ['begin' => $fileSpecificError->getLine() ?? 0]]]; $errorsArray[] = $error; } foreach ($analysisResult->getNotFileSpecificErrors() as $notFileSpecificError) { $errorsArray[] = ['description' => $notFileSpecificError, 'fingerprint' => hash('sha256', $notFileSpecificError), 'severity' => 'major', 'location' => ['path' => '', 'lines' => ['begin' => 0]]]; } $json = Json::encode($errorsArray, Json::PRETTY); $output->writeRaw($json); return $analysisResult->hasErrors() ? 1 : 0; } } pretty = $pretty; } public function formatErrors(AnalysisResult $analysisResult, Output $output) : int { $errorsArray = ['totals' => ['errors' => count($analysisResult->getNotFileSpecificErrors()), 'file_errors' => count($analysisResult->getFileSpecificErrors())], 'files' => [], 'errors' => []]; $tipFormatter = new OutputFormatter(\false); foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { $file = $fileSpecificError->getFile(); if (!array_key_exists($file, $errorsArray['files'])) { $errorsArray['files'][$file] = ['errors' => 0, 'messages' => []]; } $errorsArray['files'][$file]['errors']++; $message = ['message' => $fileSpecificError->getMessage(), 'line' => $fileSpecificError->getLine(), 'ignorable' => $fileSpecificError->canBeIgnored()]; if ($fileSpecificError->getTip() !== null) { $message['tip'] = $tipFormatter->format($fileSpecificError->getTip()); } if ($fileSpecificError->getIdentifier() !== null) { $message['identifier'] = $fileSpecificError->getIdentifier(); } $errorsArray['files'][$file]['messages'][] = $message; } foreach ($analysisResult->getNotFileSpecificErrors() as $notFileSpecificError) { $errorsArray['errors'][] = $notFileSpecificError; } $json = Json::encode($errorsArray, $this->pretty ? Json::PRETTY : 0); $output->writeRaw($json); return $analysisResult->hasErrors() ? 1 : 0; } } relativePathHelper = $relativePathHelper; $this->simpleRelativePathHelper = $simpleRelativePathHelper; $this->ciDetectedErrorFormatter = $ciDetectedErrorFormatter; $this->showTipsOfTheDay = $showTipsOfTheDay; $this->editorUrl = $editorUrl; $this->editorUrlTitle = $editorUrlTitle; } /** @api */ public function formatErrors(AnalysisResult $analysisResult, Output $output) : int { $this->ciDetectedErrorFormatter->formatErrors($analysisResult, $output); $projectConfigFile = 'phpstan.neon'; if ($analysisResult->getProjectConfigFile() !== null) { $projectConfigFile = $this->relativePathHelper->getRelativePath($analysisResult->getProjectConfigFile()); } $style = $output->getStyle(); if (!$analysisResult->hasErrors() && !$analysisResult->hasWarnings()) { $style->success('No errors'); if ($this->showTipsOfTheDay) { if ($analysisResult->isDefaultLevelUsed()) { $output->writeLineFormatted('💡 Tip of the Day:'); $output->writeLineFormatted(sprintf("PHPStan is performing only the most basic checks.\nYou can pass a higher rule level through the --%s option\n(the default and current level is %d) to analyse code more thoroughly.", AnalyseCommand::OPTION_LEVEL, AnalyseCommand::DEFAULT_LEVEL)); $output->writeLineFormatted(''); } } return 0; } /** @var array $fileErrors */ $fileErrors = []; $outputIdentifiers = $output->isVerbose(); $outputIdentifiersInFile = []; foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { if (!isset($fileErrors[$fileSpecificError->getFile()])) { $fileErrors[$fileSpecificError->getFile()] = []; } $fileErrors[$fileSpecificError->getFile()][] = $fileSpecificError; if ($outputIdentifiers) { continue; } $filePath = $fileSpecificError->getTraitFilePath() ?? $fileSpecificError->getFilePath(); if (array_key_exists($filePath, $outputIdentifiersInFile)) { continue; } if ($fileSpecificError->getIdentifier() === null) { continue; } if (!in_array($fileSpecificError->getIdentifier(), ['ignore.unmatchedIdentifier', 'ignore.parseError', 'ignore.unmatched'], \true)) { continue; } $outputIdentifiersInFile[$filePath] = \true; } foreach ($fileErrors as $file => $errors) { $rows = []; foreach ($errors as $error) { $message = $error->getMessage(); $filePath = $error->getTraitFilePath() ?? $error->getFilePath(); if (($outputIdentifiers || array_key_exists($filePath, $outputIdentifiersInFile)) && $error->getIdentifier() !== null && $error->canBeIgnored()) { $message .= "\n"; $message .= '🪪 ' . $error->getIdentifier(); } if ($error->getTip() !== null) { $tip = $error->getTip(); $tip = str_replace('%configurationFile%', $projectConfigFile, $tip); $message .= "\n"; if (str_contains($tip, "\n")) { $lines = explode("\n", $tip); foreach ($lines as $line) { $message .= '💡 ' . ltrim($line, ' •') . "\n"; } } else { $message .= '💡 ' . $tip; } } if (is_string($this->editorUrl)) { $url = str_replace(['%file%', '%relFile%', '%line%'], [$filePath, $this->simpleRelativePathHelper->getRelativePath($filePath), (string) $error->getLine()], $this->editorUrl); if (is_string($this->editorUrlTitle)) { $title = str_replace(['%file%', '%relFile%', '%line%'], [$filePath, $this->simpleRelativePathHelper->getRelativePath($filePath), (string) $error->getLine()], $this->editorUrlTitle); } else { $title = $this->relativePathHelper->getRelativePath($filePath); } $message .= "\n✏️ ' . $title . ''; } $rows[] = [$this->formatLineNumber($error->getLine()), $message]; } $style->table(['Line', $this->relativePathHelper->getRelativePath($file)], $rows); } if (count($analysisResult->getNotFileSpecificErrors()) > 0) { $style->table(['', 'Error'], array_map(static function (string $error) : array { return ['', OutputFormatter::escape($error)]; }, $analysisResult->getNotFileSpecificErrors())); } $warningsCount = count($analysisResult->getWarnings()); if ($warningsCount > 0) { $style->table(['', 'Warning'], array_map(static function (string $warning) : array { return ['', OutputFormatter::escape($warning)]; }, $analysisResult->getWarnings())); } $finalMessage = sprintf($analysisResult->getTotalErrorsCount() === 1 ? 'Found %d error' : 'Found %d errors', $analysisResult->getTotalErrorsCount()); if ($warningsCount > 0) { $finalMessage .= sprintf($warningsCount === 1 ? ' and %d warning' : ' and %d warnings', $warningsCount); } if ($analysisResult->getTotalErrorsCount() > 0) { $style->error($finalMessage); } else { $style->warning($finalMessage); } return $analysisResult->getTotalErrorsCount() > 0 ? 1 : 0; } private function formatLineNumber(?int $lineNumber) : string { if ($lineNumber === null) { return ''; } $isRunningInVSCodeTerminal = getenv('TERM_PROGRAM') === 'vscode'; if ($isRunningInVSCodeTerminal) { return ':' . $lineNumber; } return (string) $lineNumber; } } composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; parent::__construct(); } protected function configure() : void { $this->setName(self::NAME)->setDescription('Clears the result cache.')->setDefinition([new InputOption('configuration', 'c', InputOption::VALUE_REQUIRED, 'Path to project configuration file'), new InputOption('autoload-file', 'a', InputOption::VALUE_REQUIRED, 'Project\'s additional autoload file path'), new InputOption('debug', null, InputOption::VALUE_NONE, 'Show debug information - which file is analysed, do not catch internal errors'), new InputOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Memory limit for clearing result cache'), new InputOption('xdebug', null, InputOption::VALUE_NONE, 'Allow running with Xdebug for debugging purposes')]); } protected function initialize(InputInterface $input, OutputInterface $output) : void { if ((bool) $input->getOption('debug')) { $application = $this->getApplication(); if ($application === null) { throw new ShouldNotHappenException(); } $application->setCatchExceptions(\false); return; } } protected function execute(InputInterface $input, OutputInterface $output) : int { $autoloadFile = $input->getOption('autoload-file'); $configuration = $input->getOption('configuration'); $memoryLimit = $input->getOption('memory-limit'); $debugEnabled = (bool) $input->getOption('debug'); $allowXdebug = $input->getOption('xdebug'); if (!is_string($autoloadFile) && $autoloadFile !== null || !is_string($configuration) && $configuration !== null || !is_string($memoryLimit) && $memoryLimit !== null || !is_bool($allowXdebug)) { throw new ShouldNotHappenException(); } try { $inceptionResult = \PHPStan\Command\CommandHelper::begin($input, $output, [], $memoryLimit, $autoloadFile, $this->composerAutoloaderProjectPaths, $configuration, null, '0', $allowXdebug, $debugEnabled); } catch (\PHPStan\Command\InceptionNotSuccessfulException $e) { return 1; } $container = $inceptionResult->getContainer(); $resultCacheClearer = $container->getByType(ResultCacheClearer::class); $path = $resultCacheClearer->clear(); $output->writeln('Result cache cleared from directory:'); $output->writeln($path); return 0; } } getErrorOutput() : $output; return new SymfonyOutput($symfonyErrorOutput, new SymfonyStyle(new \PHPStan\Command\ErrorsConsoleStyle($input, $symfonyErrorOutput))); })(); if (!$allowXdebug) { $xdebug = new XdebugHandler('phpstan'); $xdebug->setPersistent(); $xdebug->check(); unset($xdebug); } if ($allowXdebug) { if (!XdebugHandler::isXdebugActive()) { $errorOutput->getStyle()->note('You are running with "--xdebug" enabled, but the Xdebug PHP extension is not active. The process will not halt at breakpoints.'); } else { $errorOutput->getStyle()->note("You are running with \"--xdebug\" enabled, and the Xdebug PHP extension is active.\nThe process will halt at breakpoints, but PHPStan will run much slower.\nUse this only if you are debugging PHPStan itself or your custom extensions."); } } elseif (XdebugHandler::isXdebugActive()) { $errorOutput->getStyle()->note('The Xdebug PHP extension is active, but "--xdebug" is not used. This may slow down performance and the process will not halt at breakpoints.'); } elseif ($debugEnabled) { $v = XdebugHandler::getSkippedVersion(); if ($v !== '') { $errorOutput->getStyle()->note("The Xdebug PHP extension is active, but \"--xdebug\" is not used.\n" . "The process was restarted and it will not halt at breakpoints.\n" . 'Use "--xdebug" if you want to halt at breakpoints.'); } } if ($memoryLimit !== null) { if (Strings::match($memoryLimit, '#^-?\\d+[kMG]?$#i') === null) { $errorOutput->writeLineFormatted(sprintf('Invalid memory limit format "%s".', $memoryLimit)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } if (ini_set('memory_limit', $memoryLimit) === \false) { $errorOutput->writeLineFormatted(sprintf('Memory limit "%s" cannot be set.', $memoryLimit)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } } self::$reservedMemory = str_repeat('PHPStan', 1463); // reserve 10 kB of space register_shutdown_function(static function () use($errorOutput) : void { self::$reservedMemory = null; $error = error_get_last(); if ($error === null) { return; } if ($error['type'] !== E_ERROR) { return; } if (!str_contains($error['message'], 'Allowed memory size')) { return; } $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted(sprintf('PHPStan process crashed because it reached configured PHP memory limit: %s', ini_get('memory_limit'))); $errorOutput->writeLineFormatted('Increase your memory limit in php.ini or run PHPStan with --memory-limit CLI option.'); }); $currentWorkingDirectory = getcwd(); if ($currentWorkingDirectory === \false) { throw new ShouldNotHappenException(); } $currentWorkingDirectoryFileHelper = new FileHelper($currentWorkingDirectory); $currentWorkingDirectory = $currentWorkingDirectoryFileHelper->getWorkingDirectory(); /** @var list|false $autoloadFunctionsBefore */ $autoloadFunctionsBefore = spl_autoload_functions(); if ($autoloadFile !== null) { $autoloadFile = $currentWorkingDirectoryFileHelper->absolutizePath($autoloadFile); if (!is_file($autoloadFile)) { $errorOutput->writeLineFormatted(sprintf('Autoload file "%s" not found.', $autoloadFile)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } (static function (string $file) : void { require_once $file; })($autoloadFile); } if ($projectConfigFile === null) { $discoverableConfigNames = ['.phpstan.neon', 'phpstan.neon', '.phpstan.neon.dist', 'phpstan.neon.dist', '.phpstan.dist.neon', 'phpstan.dist.neon']; foreach ($discoverableConfigNames as $discoverableConfigName) { $discoverableConfigFile = $currentWorkingDirectory . DIRECTORY_SEPARATOR . $discoverableConfigName; if (is_file($discoverableConfigFile)) { $projectConfigFile = $discoverableConfigFile; $errorOutput->writeLineFormatted(sprintf('Note: Using configuration file %s.', $projectConfigFile)); break; } } } else { $projectConfigFile = $currentWorkingDirectoryFileHelper->absolutizePath($projectConfigFile); } if ($generateBaselineFile !== null) { $generateBaselineFile = $currentWorkingDirectoryFileHelper->normalizePath($currentWorkingDirectoryFileHelper->absolutizePath($generateBaselineFile)); } if ($singleReflectionFile !== null) { $singleReflectionFile = $currentWorkingDirectoryFileHelper->normalizePath($currentWorkingDirectoryFileHelper->absolutizePath($singleReflectionFile)); if (!is_file($singleReflectionFile)) { $errorOutput->writeLineFormatted(sprintf('File passed to --tmp-file option does not exist: %s', $singleReflectionFile)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } if ($singleReflectionInsteadOfFile === null) { $errorOutput->writeLineFormatted('Both --tmp-file and --instead-of options must be passed at the same time for editor mode to work.'); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } } if ($singleReflectionInsteadOfFile !== null) { $singleReflectionInsteadOfFile = $currentWorkingDirectoryFileHelper->normalizePath($currentWorkingDirectoryFileHelper->absolutizePath($singleReflectionInsteadOfFile)); if (!is_file($singleReflectionInsteadOfFile)) { $errorOutput->writeLineFormatted(sprintf('File passed to --instead-of option does not exist: %s', $singleReflectionInsteadOfFile)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } if ($singleReflectionFile === null) { $errorOutput->writeLineFormatted('Both --tmp-file and --instead-of options must be passed at the same time for editor mode to work.'); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } } $defaultLevelUsed = \false; if ($projectConfigFile === null && $level === null) { $level = self::DEFAULT_LEVEL; $defaultLevelUsed = \true; } $paths = array_map(static function (string $path) use($currentWorkingDirectoryFileHelper) : string { return $currentWorkingDirectoryFileHelper->normalizePath($currentWorkingDirectoryFileHelper->absolutizePath($path)); }, $paths); $analysedPathsFromConfig = []; $containerFactory = new ContainerFactory($currentWorkingDirectory, \true); $projectConfig = null; if ($projectConfigFile !== null) { if (!is_file($projectConfigFile)) { $errorOutput->writeLineFormatted(sprintf('Project config file at path %s does not exist.', $projectConfigFile)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } $loader = (new LoaderFactory($currentWorkingDirectoryFileHelper, $containerFactory->getRootDirectory(), $containerFactory->getCurrentWorkingDirectory(), $generateBaselineFile))->createLoader(); try { $projectConfig = $loader->load($projectConfigFile, null); } catch (InvalidStateException|FileNotFoundException $e) { $errorOutput->writeLineFormatted($e->getMessage()); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } $defaultParameters = ['rootDir' => $containerFactory->getRootDirectory(), 'currentWorkingDirectory' => $containerFactory->getCurrentWorkingDirectory(), 'env' => getenv()]; if (isset($projectConfig['parameters']['tmpDir'])) { $tmpDir = Helpers::expand($projectConfig['parameters']['tmpDir'], $defaultParameters); } if ($level === null && isset($projectConfig['parameters']['level'])) { $level = (string) $projectConfig['parameters']['level']; } if (isset($projectConfig['parameters']['paths'])) { $analysedPathsFromConfig = Helpers::expand($projectConfig['parameters']['paths'], $defaultParameters); } if (count($paths) === 0) { $paths = $analysedPathsFromConfig; } } $additionalConfigFiles = []; if ($level !== null) { $levelConfigFile = sprintf('%s/config.level%s.neon', $containerFactory->getConfigDirectory(), $level); if (!is_file($levelConfigFile)) { $errorOutput->writeLineFormatted(sprintf('Level config file %s was not found.', $levelConfigFile)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } $additionalConfigFiles[] = $levelConfigFile; } if (class_exists('PHPStan\\ExtensionInstaller\\GeneratedConfig')) { $generatedConfigReflection = new ReflectionClass('PHPStan\\ExtensionInstaller\\GeneratedConfig'); $generatedConfigDirectory = dirname($generatedConfigReflection->getFileName()); foreach (GeneratedConfig::EXTENSIONS as $name => $extensionConfig) { foreach ($extensionConfig['extra']['includes'] ?? [] as $includedFile) { if (!is_string($includedFile)) { $errorOutput->writeLineFormatted(sprintf('Cannot include config from package %s, expecting string file path but got %s', $name, gettype($includedFile))); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } $includedFilePath = null; if (isset($extensionConfig['relative_install_path'])) { $includedFilePath = sprintf('%s/%s/%s', $generatedConfigDirectory, $extensionConfig['relative_install_path'], $includedFile); if (!is_file($includedFilePath) || !is_readable($includedFilePath)) { $includedFilePath = null; } } if ($includedFilePath === null) { $includedFilePath = sprintf('%s/%s', $extensionConfig['install_path'], $includedFile); } if (!is_file($includedFilePath) || !is_readable($includedFilePath)) { $errorOutput->writeLineFormatted(sprintf('Config file %s does not exist or isn\'t readable', $includedFilePath)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } $additionalConfigFiles[] = $includedFilePath; } } if (count($additionalConfigFiles) > 0 && $generatedConfigReflection->hasConstant('PHPSTAN_VERSION_CONSTRAINT')) { $generatedConfigPhpStanVersionConstraint = $generatedConfigReflection->getConstant('PHPSTAN_VERSION_CONSTRAINT'); if ($generatedConfigPhpStanVersionConstraint !== null) { $phpstanSemverVersion = ComposerHelper::getPhpStanVersion(); if ($phpstanSemverVersion !== ComposerHelper::UNKNOWN_VERSION && !str_contains($phpstanSemverVersion, '@') && !Semver::satisfies($phpstanSemverVersion, $generatedConfigPhpStanVersionConstraint)) { $errorOutput->writeLineFormatted('Running PHPStan with incompatible extensions'); $errorOutput->writeLineFormatted('You\'re running PHPStan from a different Composer project'); $errorOutput->writeLineFormatted('than the one where you installed extensions.'); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted(sprintf('Your PHPStan version is: %s', $phpstanSemverVersion)); $errorOutput->writeLineFormatted(sprintf('Installed PHPStan extensions support: %s', $generatedConfigPhpStanVersionConstraint)); $errorOutput->writeLineFormatted(''); if (isset($_SERVER['argv'][0]) && is_file($_SERVER['argv'][0])) { $mainScript = $_SERVER['argv'][0]; $errorOutput->writeLineFormatted(sprintf('PHPStan is running from: %s', $currentWorkingDirectoryFileHelper->absolutizePath(dirname($mainScript)))); } $errorOutput->writeLineFormatted(sprintf('Extensions were installed in: %s', dirname($generatedConfigDirectory, 3))); $errorOutput->writeLineFormatted(''); $simpleRelativePathHelper = new SimpleRelativePathHelper($currentWorkingDirectory); $errorOutput->writeLineFormatted(sprintf('Run PHPStan with %s to fix this problem.', $simpleRelativePathHelper->getRelativePath(dirname($generatedConfigDirectory, 3) . '/bin/phpstan'))); $errorOutput->writeLineFormatted(''); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } } } } if ($projectConfigFile !== null && $currentWorkingDirectoryFileHelper->normalizePath($projectConfigFile, '/') !== $currentWorkingDirectoryFileHelper->normalizePath(__DIR__ . '/../../conf/config.stubFiles.neon', '/')) { $additionalConfigFiles[] = $projectConfigFile; } $createDir = static function (string $path) use($errorOutput) : void { try { DirectoryCreator::ensureDirectoryExists($path, 0777); } catch (DirectoryCreatorException $e) { $errorOutput->writeLineFormatted($e->getMessage()); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } }; if (!isset($tmpDir)) { $tmpDir = sys_get_temp_dir() . '/phpstan'; $createDir($tmpDir); } try { $container = $containerFactory->create($tmpDir, $additionalConfigFiles, $paths, $composerAutoloaderProjectPaths, $analysedPathsFromConfig, $level ?? self::DEFAULT_LEVEL, $generateBaselineFile, $autoloadFile, $singleReflectionFile, $singleReflectionInsteadOfFile); } catch (InvalidConfigurationException|AssertionException $e) { $errorOutput->writeLineFormatted('Invalid configuration:'); $errorOutput->writeLineFormatted($e->getMessage()); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } catch (InvalidIgnoredErrorPatternsException $e) { $errorOutput->writeLineFormatted(sprintf('Invalid %s in ignoreErrors:', count($e->getErrors()) === 1 ? 'entry' : 'entries')); foreach ($e->getErrors() as $error) { $errorOutput->writeLineFormatted($error); $errorOutput->writeLineFormatted(''); } $errorOutput->writeLineFormatted('To ignore non-existent paths in ignoreErrors,'); $errorOutput->writeLineFormatted('set reportUnmatchedIgnoredErrors: false in your configuration file.'); $errorOutput->writeLineFormatted(''); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } catch (InvalidExcludePathsException $e) { $errorOutput->writeLineFormatted(sprintf('Invalid %s in excludePaths:', count($e->getErrors()) === 1 ? 'entry' : 'entries')); foreach ($e->getErrors() as $error) { $errorOutput->writeLineFormatted($error); $errorOutput->writeLineFormatted(''); } $errorOutput->writeLineFormatted('If the excluded path can sometimes exist, append (?)'); $errorOutput->writeLineFormatted('to its config entry to mark it as optional.'); $errorOutput->writeLineFormatted(''); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } catch (ValidationException $e) { foreach ($e->getMessages() as $message) { $errorOutput->writeLineFormatted('Invalid configuration:'); $errorOutput->writeLineFormatted($message); } throw new \PHPStan\Command\InceptionNotSuccessfulException(); } catch (ServiceCreationException $e) { $matches = Strings::match($e->getMessage(), '#Service of type (?[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\\\]*[a-zA-Z0-9_\\x7f-\\xff]): Service of type (?[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\\\]*[a-zA-Z0-9_\\x7f-\\xff]) needed by \\$(?[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*) in (?[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*)\\(\\)#'); if ($matches === null) { throw $e; } if ($matches['parserServiceType'] !== 'PHPStan\\Parser\\Parser') { throw $e; } if ($matches['methodName'] !== '__construct') { throw $e; } $errorOutput->writeLineFormatted('Invalid configuration:'); $errorOutput->writeLineFormatted(sprintf("Service of type %s is no longer autowired.\n", $matches['parserServiceType'])); $errorOutput->writeLineFormatted('You need to choose one of the following services'); $errorOutput->writeLineFormatted(sprintf('and use it in the %s argument of your service %s:', $matches['parameterName'], $matches['serviceType'])); $errorOutput->writeLineFormatted('* defaultAnalysisParser (if you\'re parsing files from analysed paths)'); $errorOutput->writeLineFormatted('* currentPhpVersionSimpleDirectParser (in most other situations)'); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted('After fixing this problem, your configuration will look something like this:'); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted('-'); $errorOutput->writeLineFormatted(sprintf("\tclass: %s", $matches['serviceType'])); $errorOutput->writeLineFormatted(sprintf("\targuments:")); $errorOutput->writeLineFormatted(sprintf("\t\t%s: @defaultAnalysisParser", $matches['parameterName'])); $errorOutput->writeLineFormatted(''); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } catch (DuplicateIncludedFilesException $e) { $format = "These files are included multiple times:\n- %s"; if (count($e->getFiles()) === 1) { $format = "This file is included multiple times:\n- %s"; } $errorOutput->writeLineFormatted(sprintf($format, implode("\n- ", $e->getFiles()))); if (class_exists('PHPStan\\ExtensionInstaller\\GeneratedConfig')) { $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted('It can lead to unexpected results. If you\'re using phpstan/extension-installer, make sure you have removed corresponding neon files from your project config file.'); } throw new \PHPStan\Command\InceptionNotSuccessfulException(); } if ($cleanupContainerCache) { $containerFactory->clearOldContainers($tmpDir); } /** @var bool|null $customRulesetUsed */ $customRulesetUsed = $container->getParameter('customRulesetUsed'); if ($customRulesetUsed === null) { $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted('No rules detected'); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted('You have the following choices:'); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted('* while running the analyse option, use the --level option to adjust your rule level - the higher the stricter'); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted(sprintf('* create your own custom ruleset by selecting which rules you want to check by copying the service definitions from the built-in config level files in %s.', $currentWorkingDirectoryFileHelper->normalizePath(__DIR__ . '/../../conf'))); $errorOutput->writeLineFormatted(' * in this case, don\'t forget to define parameter customRulesetUsed in your config file.'); $errorOutput->writeLineFormatted(''); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } elseif ($customRulesetUsed) { $defaultLevelUsed = \false; } foreach ($container->getParameter('bootstrapFiles') as $bootstrapFileFromArray) { self::executeBootstrapFile($bootstrapFileFromArray, $container, $errorOutput, $debugEnabled); } /** @var list|false $autoloadFunctionsAfter */ $autoloadFunctionsAfter = spl_autoload_functions(); if ($autoloadFunctionsBefore !== \false && $autoloadFunctionsAfter !== \false) { $newAutoloadFunctions = $GLOBALS['__phpstanAutoloadFunctions'] ?? []; foreach ($autoloadFunctionsAfter as $after) { foreach ($autoloadFunctionsBefore as $before) { if ($after === $before) { continue 2; } } $newAutoloadFunctions[] = $after; } $GLOBALS['__phpstanAutoloadFunctions'] = $newAutoloadFunctions; } if (PHP_VERSION_ID >= 80000) { require_once __DIR__ . '/../../stubs/runtime/Enum/UnitEnum.php'; require_once __DIR__ . '/../../stubs/runtime/Enum/BackedEnum.php'; require_once __DIR__ . '/../../stubs/runtime/Enum/ReflectionEnum.php'; require_once __DIR__ . '/../../stubs/runtime/Enum/ReflectionEnumUnitCase.php'; require_once __DIR__ . '/../../stubs/runtime/Enum/ReflectionEnumBackedCase.php'; } foreach ($container->getParameter('scanFiles') as $scannedFile) { if (is_file($scannedFile)) { continue; } $errorOutput->writeLineFormatted(sprintf('Scanned file %s does not exist.', $scannedFile)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } foreach ($container->getParameter('scanDirectories') as $scannedDirectory) { if (is_dir($scannedDirectory)) { continue; } $errorOutput->writeLineFormatted(sprintf('Scanned directory %s does not exist.', $scannedDirectory)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } $alreadyAddedStubFiles = []; foreach ($container->getParameter('stubFiles') as $stubFile) { if (array_key_exists($stubFile, $alreadyAddedStubFiles)) { $errorOutput->writeLineFormatted(sprintf('Stub file %s is added multiple times.', $stubFile)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } $alreadyAddedStubFiles[$stubFile] = \true; if (is_file($stubFile)) { continue; } $errorOutput->writeLineFormatted(sprintf('Stub file %s does not exist.', $stubFile)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } $excludesAnalyse = $container->getParameter('excludes_analyse'); $excludePaths = $container->getParameter('excludePaths'); if (count($excludesAnalyse) > 0 && $excludePaths !== null) { $errorOutput->writeLineFormatted(sprintf('Configuration parameters excludes_analyse and excludePaths cannot be used at the same time.')); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted(sprintf('Parameter excludes_analyse has been deprecated so use excludePaths only from now on.')); $errorOutput->writeLineFormatted(''); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } elseif (count($excludesAnalyse) > 0) { $errorOutput->writeLineFormatted('⚠️ You\'re using a deprecated config option excludes_analyse. ⚠️️'); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted(sprintf('Parameter excludes_analyse has been deprecated so use excludePaths only from now on.')); } if ($container->hasParameter('scopeClass') && $container->getParameter('scopeClass') !== MutatingScope::class) { $errorOutput->writeLineFormatted('⚠️ You\'re using a deprecated config option scopeClass. ⚠️️'); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted(sprintf('Please implement PHPStan\\Type\\ExpressionTypeResolverExtension interface instead and register it as a service.')); } if ($projectConfig !== null) { $parameters = $projectConfig['parameters'] ?? []; /** @var bool $checkMissingIterableValueType */ $checkMissingIterableValueType = $parameters['checkMissingIterableValueType'] ?? \true; if (!$checkMissingIterableValueType) { $errorOutput->writeLineFormatted('⚠️ You\'re using a deprecated config option checkMissingIterableValueType ⚠️️'); $errorOutput->writeLineFormatted(''); $featureToggles = $container->getParameter('featureToggles'); if (!(bool) $featureToggles['bleedingEdge']) { $errorOutput->writeLineFormatted('It\'s strongly recommended to remove it from your configuration file'); $errorOutput->writeLineFormatted('and add the missing array typehints.'); $errorOutput->writeLineFormatted(''); } $errorOutput->writeLineFormatted('If you want to continue ignoring missing typehints from arrays,'); $errorOutput->writeLineFormatted('add missingType.iterableValue error identifier to your ignoreErrors:'); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted('parameters:'); $errorOutput->writeLineFormatted("\tignoreErrors:"); $errorOutput->writeLineFormatted("\t\t-"); $errorOutput->writeLineFormatted("\t\t\tidentifier: missingType.iterableValue"); $errorOutput->writeLineFormatted(''); } /** @var bool $checkGenericClassInNonGenericObjectType */ $checkGenericClassInNonGenericObjectType = $parameters['checkGenericClassInNonGenericObjectType'] ?? \true; if (!$checkGenericClassInNonGenericObjectType) { $errorOutput->writeLineFormatted('⚠️ You\'re using a deprecated config option checkGenericClassInNonGenericObjectType ⚠️️'); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted('It\'s strongly recommended to remove it from your configuration file'); $errorOutput->writeLineFormatted('and add the missing generic typehints.'); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted('If you want to continue ignoring missing typehints from generics,'); $errorOutput->writeLineFormatted('add missingType.generics error identifier to your ignoreErrors:'); $errorOutput->writeLineFormatted(''); $errorOutput->writeLineFormatted('parameters:'); $errorOutput->writeLineFormatted("\tignoreErrors:"); $errorOutput->writeLineFormatted("\t\t-"); $errorOutput->writeLineFormatted("\t\t\tidentifier: missingType.generics"); $errorOutput->writeLineFormatted(''); } } $tempResultCachePath = $container->getParameter('tempResultCachePath'); $createDir($tempResultCachePath); /** @var FileFinder $fileFinder */ $fileFinder = $container->getService('fileFinderAnalyse'); $pathRoutingParser = $container->getService('pathRoutingParser'); $stubFilesProvider = $container->getByType(StubFilesProvider::class); $filesCallback = static function () use($currentWorkingDirectoryFileHelper, $stubFilesProvider, $fileFinder, $pathRoutingParser, $paths, $errorOutput) : array { if (count($paths) === 0) { $errorOutput->writeLineFormatted('At least one path must be specified to analyse.'); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } $fileFinderResult = $fileFinder->findFiles($paths); $files = $fileFinderResult->getFiles(); $pathRoutingParser->setAnalysedFiles($files); $stubFilesExcluder = new FileExcluder($currentWorkingDirectoryFileHelper, $stubFilesProvider->getProjectStubFiles(), \true); $files = array_values(array_filter($files, static function (string $file) use($stubFilesExcluder) { return !$stubFilesExcluder->isExcludedFromAnalysing($file); })); return [$files, $fileFinderResult->isOnlyFiles()]; }; return new \PHPStan\Command\InceptionResult($filesCallback, $stdOutput, $errorOutput, $container, $defaultLevelUsed, $projectConfigFile, $projectConfig, $generateBaselineFile, $singleReflectionFile, $singleReflectionInsteadOfFile); } /** * @throws InceptionNotSuccessfulException */ private static function executeBootstrapFile(string $file, Container $container, \PHPStan\Command\Output $errorOutput, bool $debugEnabled) : void { if (!is_file($file)) { $errorOutput->writeLineFormatted(sprintf('Bootstrap file %s does not exist.', $file)); throw new \PHPStan\Command\InceptionNotSuccessfulException(); } try { (static function (string $file) use($container) : void { require_once $file; })($file); } catch (Throwable $e) { $errorOutput->writeLineFormatted(sprintf('%s thrown in %s on line %d while loading bootstrap file %s: %s', get_class($e), $e->getFile(), $e->getLine(), $file, $e->getMessage())); if ($debugEnabled) { $errorOutput->writeLineFormatted($e->getTraceAsString()); } throw new \PHPStan\Command\InceptionNotSuccessfulException(); } } } -----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs+kHoHhs66QaDeVmF6zb kqgEafJTHVsKraOJp64zLlrIZhEiBjKnl5EwpIvvPOfgjjI9z9zm0Y8IoWMfNMf1 MN/9f7603vfJxTAdXVVPtTq4x3dKf1z8RdE9+04Nrfb/+OuAVCtDGCjKec9sRdce 4Ex499BfQx80njFoeC84eY39hNf82rhflW9OMCQeEZhv3durZV5q+tgp+2pdf0yw sdIc/NYebZB1C0Cj6AfqbT9WoMAojfG8R5tF+4S3mMiDHNXx6hNM4mJEpyODje1A qZW91T0x1rFWe25WWLtQG/VP1E+an03C8axn3Ag7+9gohE5hNRKfOWZLZsx+KivD sivJSiyZEP6h6Mxp3aVYk9fmxyJnn0+tvPGYm3wZlPYp0SQIMeYooPr1ddERwtxm 4TyoQ6v8tg+7hrPu4I5km7X8uUzKFtLWj5CB+DVQycjzSbA3Wrj7EcXbKlx8hoyl onQWCVNkSY75CuizY3YqGJr1lCYH7Gut/IAD+gT7CuqgU0PrsSE0c1yBI36Xz090 XZbT1h5UuhF1ezVv3GYSCSHuu3vHzoO4lrrIOmOdcPlSw+BuSy3WOpS9OIud4IwZ UFbzJNs6cOZbnwz7lwBzXFkm3PXPlwXmlGUPF9S4My+F4hYONE4zxI4IcmeF6U43 JUX0xbD+LXNnezCLkvkcVjMCAwEAAQ== -----END PUBLIC KEY----- stdOutput = $stdOutput; $this->errorOutput = $errorOutput; $this->container = $container; $this->isDefaultLevelUsed = $isDefaultLevelUsed; $this->projectConfigFile = $projectConfigFile; $this->projectConfigArray = $projectConfigArray; $this->generateBaselineFile = $generateBaselineFile; $this->editorModeTmpFile = $editorModeTmpFile; $this->editorModeInsteadOfFile = $editorModeInsteadOfFile; $this->filesCallback = $filesCallback; } /** * @throws InceptionNotSuccessfulException * @throws PathNotFoundException * @return array{string[], bool} */ public function getFiles() : array { $callback = $this->filesCallback; /** @throws InceptionNotSuccessfulException|PathNotFoundException */ return $callback(); } public function getStdOutput() : \PHPStan\Command\Output { return $this->stdOutput; } public function getErrorOutput() : \PHPStan\Command\Output { return $this->errorOutput; } public function getContainer() : Container { return $this->container; } public function isDefaultLevelUsed() : bool { return $this->isDefaultLevelUsed; } public function getProjectConfigFile() : ?string { return $this->projectConfigFile; } /** * @return mixed[]|null */ public function getProjectConfigArray() : ?array { return $this->projectConfigArray; } public function getGenerateBaselineFile() : ?string { return $this->generateBaselineFile; } public function getEditorModeTmpFile() : ?string { return $this->editorModeTmpFile; } public function getEditorModeInsteadOfFile() : ?string { return $this->editorModeInsteadOfFile; } public function handleReturn(int $exitCode, ?int $peakMemoryUsageBytes, float $analysisStartTime) : int { if ($this->getErrorOutput()->isVerbose()) { $elapsedTime = round(microtime(\true) - $analysisStartTime, 2); if ($elapsedTime < 10) { $elapsedTimeString = sprintf('%.2f seconds', $elapsedTime); } else { $elapsedTimeString = $this->formatDuration((int) $elapsedTime); } $this->getErrorOutput()->writeLineFormatted(sprintf('Elapsed time: %s', $elapsedTimeString)); } if ($peakMemoryUsageBytes !== null && $this->getErrorOutput()->isVerbose()) { $this->getErrorOutput()->writeLineFormatted(sprintf('Used memory: %s', BytesHelper::bytes(max(memory_get_peak_usage(\true), $peakMemoryUsageBytes)))); } return $exitCode; } private function formatDuration(int $seconds) : string { $minutes = (int) floor($seconds / 60); $remainingSeconds = $seconds % 60; $result = []; if ($minutes > 0) { $result[] = $minutes . ' minute' . ($minutes > 1 ? 's' : ''); } if ($remainingSeconds > 0) { $result[] = $remainingSeconds . ' second' . ($remainingSeconds > 1 ? 's' : ''); } return implode(' ', $result); } } */ private $processes = []; /** @var callable(): void */ private $onServerClose; /** * @param callable(): void $onServerClose */ public function __construct(TcpServer $server, callable $onServerClose) { $this->server = $server; $this->onServerClose = $onServerClose; } public function getProcess(string $identifier) : \PHPStan\Parallel\Process { if (!array_key_exists($identifier, $this->processes)) { throw new ShouldNotHappenException(sprintf('Process %s not found.', $identifier)); } return $this->processes[$identifier]; } public function attachProcess(string $identifier, \PHPStan\Parallel\Process $process) : void { $this->processes[$identifier] = $process; } public function tryQuitProcess(string $identifier) : void { if (!array_key_exists($identifier, $this->processes)) { return; } $this->quitProcess($identifier); } private function quitProcess(string $identifier) : void { $process = $this->getProcess($identifier); $process->quit(); unset($this->processes[$identifier]); if (count($this->processes) !== 0) { return; } $this->server->close(); $callback = $this->onServerClose; $callback(); } public function quitAll() : void { foreach (array_keys($this->processes) as $identifier) { $this->quitProcess($identifier); } } } > */ private $jobs; /** * @param array> $jobs */ public function __construct(int $numberOfProcesses, array $jobs) { $this->numberOfProcesses = $numberOfProcesses; $this->jobs = $jobs; } public function getNumberOfProcesses() : int { return $this->numberOfProcesses; } /** * @return array> */ public function getJobs() : array { return $this->jobs; } } jobSize = $jobSize; $this->maximumNumberOfProcesses = $maximumNumberOfProcesses; $this->minimumNumberOfJobsPerProcess = $minimumNumberOfJobsPerProcess; } /** * @param array $files */ public function scheduleWork(int $cpuCores, array $files) : \PHPStan\Parallel\Schedule { $jobs = array_chunk($files, $this->jobSize); $numberOfProcesses = min(max((int) floor(count($jobs) / $this->minimumNumberOfJobsPerProcess), 1), $cpuCores); $usedNumberOfProcesses = min($numberOfProcesses, $this->maximumNumberOfProcesses); $this->storedData = [$cpuCores, count($files), count($jobs), $usedNumberOfProcesses]; return new \PHPStan\Parallel\Schedule($usedNumberOfProcesses, $jobs); } public function print(Output $output) : void { if ($this->storedData === null) { return; } [$cpuCores, $filesCount, $jobsCount, $usedNumberOfProcesses] = $this->storedData; $output->writeLineFormatted('Parallel processing scheduler:'); $output->writeLineFormatted(sprintf('# of detected CPU %s: %s%d', $cpuCores === 1 ? 'core' : 'cores', $cpuCores === 1 ? '' : ' ', $cpuCores)); $output->writeLineFormatted(sprintf('# of analysed files: %d', $filesCount)); $output->writeLineFormatted(sprintf('# of jobs: %d', $jobsCount)); $output->writeLineFormatted(sprintf('# of spawned processes: %d', $usedNumberOfProcesses)); $output->writeLineFormatted(''); } } command = $command; $this->loop = $loop; $this->timeoutSeconds = $timeoutSeconds; } /** * @param callable(mixed[] $json) : void $onData * @param callable(Throwable $exception): void $onError * @param callable(?int $exitCode, string $output) : void $onExit */ public function start(callable $onData, callable $onError, callable $onExit) : void { $tmpStdOut = tmpfile(); if ($tmpStdOut === \false) { throw new ShouldNotHappenException('Failed creating temp file for stdout.'); } $tmpStdErr = tmpfile(); if ($tmpStdErr === \false) { throw new ShouldNotHappenException('Failed creating temp file for stderr.'); } $this->stdOut = $tmpStdOut; $this->stdErr = $tmpStdErr; $this->process = new \_PHPStan_c2fbb2235\React\ChildProcess\Process($this->command, null, null, [1 => $this->stdOut, 2 => $this->stdErr]); $this->process->start($this->loop); $this->onData = $onData; $this->onError = $onError; $this->process->on('exit', function ($exitCode) use($onExit) : void { $this->cancelTimer(); $output = ''; rewind($this->stdOut); $stdOut = stream_get_contents($this->stdOut); if (is_string($stdOut)) { $output .= $stdOut; } rewind($this->stdErr); $stdErr = stream_get_contents($this->stdErr); if (is_string($stdErr)) { $output .= $stdErr; } $onExit($exitCode, $output); fclose($this->stdOut); fclose($this->stdErr); }); } private function cancelTimer() : void { if ($this->timer === null) { return; } $this->loop->cancelTimer($this->timer); $this->timer = null; } /** * @param mixed[] $data */ public function request(array $data) : void { $this->cancelTimer(); if ($this->in === null) { throw new ShouldNotHappenException(); } $this->in->write($data); $this->timer = $this->loop->addTimer($this->timeoutSeconds, function () : void { $onError = $this->onError; $onError(new \PHPStan\Parallel\ProcessTimedOutException(sprintf('Child process timed out after %.1f seconds. Try making it longer with parallel.processTimeout setting.', $this->timeoutSeconds))); }); } public function quit() : void { $this->cancelTimer(); if (!$this->process->isRunning()) { return; } foreach ($this->process->pipes as $pipe) { $pipe->close(); } if ($this->in === null) { return; } $this->in->end(); } public function bindConnection(ReadableStreamInterface $out, WritableStreamInterface $in) : void { $out->on('data', function (array $json) : void { $this->cancelTimer(); if ($json['action'] !== 'result') { return; } $onData = $this->onData; $onData($json['result']); }); $this->in = $in; $out->on('error', function (Throwable $error) : void { $onError = $this->onError; $onError($error); }); $in->on('error', function (Throwable $error) : void { $onError = $this->onError; $onError($error); }); } } internalErrorsCountLimit = $internalErrorsCountLimit; $this->decoderBufferSize = $decoderBufferSize; $this->processTimeout = max($processTimeout, self::DEFAULT_TIMEOUT); } /** * @param Closure(int ): void|null $postFileCallback * @param (callable(list, list, string[]): void)|null $onFileAnalysisHandler * @return PromiseInterface */ public function analyse(LoopInterface $loop, \PHPStan\Parallel\Schedule $schedule, string $mainScript, ?Closure $postFileCallback, ?string $projectConfigFile, ?string $tmpFile, ?string $insteadOfFile, InputInterface $input, ?callable $onFileAnalysisHandler) : PromiseInterface { $jobs = array_reverse($schedule->getJobs()); $numberOfProcesses = $schedule->getNumberOfProcesses(); $someChildEnded = \false; $errors = []; $filteredPhpErrors = []; $allPhpErrors = []; $locallyIgnoredErrors = []; $linesToIgnore = []; $unmatchedLineIgnores = []; $peakMemoryUsages = []; $internalErrors = []; $internalErrorsCount = 0; $collectedData = []; $dependencies = []; $usedTraitDependencies = []; $reachedInternalErrorsCountLimit = \false; $exportedNodes = []; /** @var Deferred $deferred */ $deferred = new Deferred(); $server = new TcpServer('127.0.0.1:0', $loop); $this->processPool = new \PHPStan\Parallel\ProcessPool($server, static function () use($deferred, &$jobs, &$internalErrors, &$internalErrorsCount, &$reachedInternalErrorsCountLimit, &$errors, &$filteredPhpErrors, &$allPhpErrors, &$locallyIgnoredErrors, &$linesToIgnore, &$unmatchedLineIgnores, &$collectedData, &$dependencies, &$usedTraitDependencies, &$exportedNodes, &$peakMemoryUsages) : void { if (count($jobs) > 0 && $internalErrorsCount === 0) { $internalErrors[] = new InternalError('Some parallel worker jobs have not finished.', 'running parallel worker', [], null, \true); $internalErrorsCount++; } $deferred->resolve(new AnalyserResult($errors, $filteredPhpErrors, $allPhpErrors, $locallyIgnoredErrors, $linesToIgnore, $unmatchedLineIgnores, $internalErrors, $collectedData, $internalErrorsCount === 0 ? $dependencies : null, $internalErrorsCount === 0 ? $usedTraitDependencies : null, $exportedNodes, $reachedInternalErrorsCountLimit, array_sum($peakMemoryUsages))); }); $server->on('connection', function (ConnectionInterface $connection) use(&$jobs) : void { // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly $jsonInvalidUtf8Ignore = defined('JSON_INVALID_UTF8_IGNORE') ? \JSON_INVALID_UTF8_IGNORE : 0; // phpcs:enable $decoder = new Decoder($connection, \true, 512, $jsonInvalidUtf8Ignore, $this->decoderBufferSize); $encoder = new Encoder($connection, $jsonInvalidUtf8Ignore); $decoder->on('data', function (array $data) use(&$jobs, $decoder, $encoder) : void { if ($data['action'] !== 'hello') { return; } $identifier = $data['identifier']; $process = $this->processPool->getProcess($identifier); $process->bindConnection($decoder, $encoder); if (count($jobs) === 0) { $this->processPool->tryQuitProcess($identifier); return; } $job = array_pop($jobs); $process->request(['action' => 'analyse', 'files' => $job]); }); }); /** @var string $serverAddress */ $serverAddress = $server->getAddress(); /** @var int<0, 65535> $serverPort */ $serverPort = parse_url($serverAddress, PHP_URL_PORT); $handleError = function (Throwable $error) use(&$internalErrors, &$internalErrorsCount, &$reachedInternalErrorsCountLimit) : void { $internalErrors[] = new InternalError($error->getMessage(), 'communicating with parallel worker', InternalError::prepareTrace($error), $error->getTraceAsString(), !$error instanceof \PHPStan\Parallel\ProcessTimedOutException); $internalErrorsCount++; $reachedInternalErrorsCountLimit = \true; $this->processPool->quitAll(); }; for ($i = 0; $i < $numberOfProcesses; $i++) { if (count($jobs) === 0) { break; } $processIdentifier = Random::generate(); $commandOptions = ['--port', (string) $serverPort, '--identifier', $processIdentifier]; if ($tmpFile !== null && $insteadOfFile !== null) { $commandOptions[] = '--tmp-file'; $commandOptions[] = escapeshellarg($tmpFile); $commandOptions[] = '--instead-of'; $commandOptions[] = escapeshellarg($insteadOfFile); } $process = new \PHPStan\Parallel\Process(ProcessHelper::getWorkerCommand($mainScript, 'worker', $projectConfigFile, $commandOptions, $input), $loop, $this->processTimeout); $process->start(function (array $json) use($process, &$internalErrors, &$errors, &$filteredPhpErrors, &$allPhpErrors, &$locallyIgnoredErrors, &$linesToIgnore, &$unmatchedLineIgnores, &$collectedData, &$dependencies, &$usedTraitDependencies, &$exportedNodes, &$peakMemoryUsages, &$jobs, $postFileCallback, &$internalErrorsCount, &$reachedInternalErrorsCountLimit, $processIdentifier, $onFileAnalysisHandler) : void { $fileErrors = []; foreach ($json['errors'] as $jsonError) { $fileErrors[] = Error::decode($jsonError); } foreach ($json['internalErrors'] as $internalJsonError) { $internalErrors[] = InternalError::decode($internalJsonError); } foreach ($json['filteredPhpErrors'] as $filteredPhpError) { $filteredPhpErrors[] = Error::decode($filteredPhpError); } foreach ($json['allPhpErrors'] as $allPhpError) { $allPhpErrors[] = Error::decode($allPhpError); } $locallyIgnoredFileErrors = []; foreach ($json['locallyIgnoredErrors'] as $locallyIgnoredJsonError) { $locallyIgnoredFileErrors[] = Error::decode($locallyIgnoredJsonError); } if ($onFileAnalysisHandler !== null) { $onFileAnalysisHandler($fileErrors, $locallyIgnoredFileErrors, $json['files']); } foreach ($fileErrors as $fileError) { $errors[] = $fileError; } foreach ($locallyIgnoredFileErrors as $locallyIgnoredFileError) { $locallyIgnoredErrors[] = $locallyIgnoredFileError; } foreach ($json['collectedData'] as $jsonData) { $collectedData[] = CollectedData::decode($jsonData); } /** * @var string $file * @var array $fileDependencies */ foreach ($json['dependencies'] as $file => $fileDependencies) { $dependencies[$file] = $fileDependencies; } /** * @var string $file * @var array $fileUsedTraitDependencies */ foreach ($json['usedTraitDependencies'] as $file => $fileUsedTraitDependencies) { $usedTraitDependencies[$file] = $fileUsedTraitDependencies; } foreach ($json['linesToIgnore'] as $file => $fileLinesToIgnore) { if (count($fileLinesToIgnore) === 0) { continue; } $linesToIgnore[$file] = $fileLinesToIgnore; } foreach ($json['unmatchedLineIgnores'] as $file => $fileUnmatchedLineIgnores) { if (count($fileUnmatchedLineIgnores) === 0) { continue; } $unmatchedLineIgnores[$file] = $fileUnmatchedLineIgnores; } /** * @var string $file * @var array $fileExportedNodes */ foreach ($json['exportedNodes'] as $file => $fileExportedNodes) { if (count($fileExportedNodes) === 0) { continue; } $exportedNodes[$file] = array_map(static function (array $node) : RootExportedNode { $class = $node['type']; return $class::decode($node['data']); }, $fileExportedNodes); } if ($postFileCallback !== null) { $postFileCallback(count($json['files'])); } if (!isset($peakMemoryUsages[$processIdentifier]) || $peakMemoryUsages[$processIdentifier] < $json['memoryUsage']) { $peakMemoryUsages[$processIdentifier] = $json['memoryUsage']; } $internalErrorsCount += $json['internalErrorsCount']; if ($internalErrorsCount >= $this->internalErrorsCountLimit) { $reachedInternalErrorsCountLimit = \true; $this->processPool->quitAll(); } if (count($jobs) === 0) { $this->processPool->tryQuitProcess($processIdentifier); return; } $job = array_pop($jobs); $process->request(['action' => 'analyse', 'files' => $job]); }, $handleError, function ($exitCode, string $output) use(&$someChildEnded, &$peakMemoryUsages, &$internalErrors, &$internalErrorsCount, $processIdentifier) : void { if ($someChildEnded === \false) { $peakMemoryUsages['main'] = memory_get_usage(\true); } $someChildEnded = \true; if ($exitCode === 0) { $this->processPool->tryQuitProcess($processIdentifier); return; } if ($exitCode === null) { $this->processPool->tryQuitProcess($processIdentifier); return; } $memoryLimitMessage = 'PHPStan process crashed because it reached configured PHP memory limit'; if (str_contains($output, $memoryLimitMessage)) { foreach ($internalErrors as $internalError) { if (!str_contains($internalError->getMessage(), $memoryLimitMessage)) { continue; } $this->processPool->tryQuitProcess($processIdentifier); return; } $internalErrors[] = new InternalError(sprintf("Child process error: %s: %s\n%s\n", $memoryLimitMessage, ini_get('memory_limit'), 'Increase your memory limit in php.ini or run PHPStan with --memory-limit CLI option.'), 'running parallel worker', [], null, \false); $internalErrorsCount++; $this->processPool->tryQuitProcess($processIdentifier); return; } $internalErrors[] = new InternalError(sprintf('Child process error (exit code %d): %s', $exitCode, $output), 'running parallel worker', [], null, \true); $internalErrorsCount++; $this->processPool->tryQuitProcess($processIdentifier); }); $this->processPool->attachProcess($processIdentifier, $process); } return $deferred->promise(); } } typeStringResolver = $typeNodeResolver; } /** * @param mixed[] $map */ public function getFunctionSignature(array $map, ?string $className) : \PHPStan\Reflection\SignatureMap\FunctionSignature { $parameterSignatures = $this->getParameters(array_slice($map, 1)); $hasVariadic = \false; foreach ($parameterSignatures as $parameterSignature) { if ($parameterSignature->isVariadic()) { $hasVariadic = \true; break; } } return new \PHPStan\Reflection\SignatureMap\FunctionSignature($parameterSignatures, $this->getTypeFromString($map[0], $className), new MixedType(), $hasVariadic); } private function getTypeFromString(string $typeString, ?string $className) : Type { if ($typeString === '') { return new MixedType(\true); } return $this->typeStringResolver->resolve($typeString, new NameScope(null, [], $className)); } /** * @param array $parameterMap * @return array */ private function getParameters(array $parameterMap) : array { $parameterSignatures = []; foreach ($parameterMap as $parameterName => $typeString) { [$name, $isOptional, $passedByReference, $isVariadic] = $this->getParameterInfoFromName($parameterName); $parameterSignatures[] = new \PHPStan\Reflection\SignatureMap\ParameterSignature($name, $isOptional, $this->getTypeFromString($typeString, null), new MixedType(), $passedByReference, $isVariadic, null, null); } return $parameterSignatures; } /** * @return mixed[] */ private function getParameterInfoFromName(string $parameterNameString) : array { $matches = Strings::match($parameterNameString, '#^(?P&(?:\\.\\.\\.)?r?w?_?)?(?P\\.\\.\\.)?(?P[^=]+)?(?P=)?($)#'); if ($matches === null || !isset($matches['optional'])) { throw new ShouldNotHappenException(); } $isVariadic = $matches['variadic'] !== ''; $reference = $matches['reference']; if (str_starts_with($reference, '&...')) { $reference = '&' . substr($reference, 4); $isVariadic = \true; } if (str_starts_with($reference, '&rw')) { $passedByReference = PassedByReference::createReadsArgument(); } elseif (str_starts_with($reference, '&')) { $passedByReference = PassedByReference::createCreatesNewVariable(); } else { $passedByReference = PassedByReference::createNo(); } $isOptional = $isVariadic || $matches['optional'] !== ''; $name = $matches['name'] !== '' ? $matches['name'] : '...'; return [$name, $isOptional, $passedByReference, $isVariadic]; } } */ private static $signatureMaps = []; /** @var array|null */ private static $functionMetadata = null; public function __construct(\PHPStan\Reflection\SignatureMap\SignatureMapParser $parser, InitializerExprTypeResolver $initializerExprTypeResolver, PhpVersion $phpVersion, bool $stricterFunctionMap) { $this->parser = $parser; $this->initializerExprTypeResolver = $initializerExprTypeResolver; $this->phpVersion = $phpVersion; $this->stricterFunctionMap = $stricterFunctionMap; } public function hasMethodSignature(string $className, string $methodName) : bool { return $this->hasFunctionSignature(sprintf('%s::%s', $className, $methodName)); } public function hasFunctionSignature(string $name) : bool { return array_key_exists(strtolower($name), $this->getSignatureMap()); } public function getMethodSignatures(string $className, string $methodName, ?ReflectionMethod $reflectionMethod) : array { return $this->getFunctionSignatures(sprintf('%s::%s', $className, $methodName), $className, $reflectionMethod); } public function getFunctionSignatures(string $functionName, ?string $className, ?ReflectionFunctionAbstract $reflectionFunction) : array { $functionName = strtolower($functionName); $signatures = [$this->createSignature($functionName, $className, $reflectionFunction)]; $i = 1; $variantFunctionName = $functionName . '\'' . $i; while ($this->hasFunctionSignature($variantFunctionName)) { $signatures[] = $this->createSignature($variantFunctionName, $className, $reflectionFunction); $i++; $variantFunctionName = $functionName . '\'' . $i; } return ['positional' => $signatures, 'named' => null]; } private function createSignature(string $functionName, ?string $className, ?ReflectionFunctionAbstract $reflectionFunction) : \PHPStan\Reflection\SignatureMap\FunctionSignature { if (!$reflectionFunction instanceof ReflectionMethod && !$reflectionFunction instanceof ReflectionFunction && $reflectionFunction !== null) { throw new ShouldNotHappenException(); } $signatureMap = self::getSignatureMap(); $signature = $this->parser->getFunctionSignature($signatureMap[$functionName], $className); $parameters = []; foreach ($signature->getParameters() as $i => $parameter) { if ($reflectionFunction === null) { $parameters[] = $parameter; continue; } $nativeParameters = $reflectionFunction->getParameters(); if (!array_key_exists($i, $nativeParameters)) { $parameters[] = $parameter; continue; } $parameters[] = new \PHPStan\Reflection\SignatureMap\ParameterSignature($parameter->getName(), $parameter->isOptional(), $parameter->getType(), TypehintHelper::decideTypeFromReflection($nativeParameters[$i]->getType()), $parameter->passedByReference(), $parameter->isVariadic(), $nativeParameters[$i]->isDefaultValueAvailable() ? $this->initializerExprTypeResolver->getType($nativeParameters[$i]->getDefaultValueExpression(), InitializerExprContext::fromReflectionParameter($nativeParameters[$i])) : null, $parameter->getOutType()); } if ($reflectionFunction === null) { $nativeReturnType = new MixedType(); } else { $nativeReturnType = TypehintHelper::decideTypeFromReflection($reflectionFunction->getReturnType()); } return new \PHPStan\Reflection\SignatureMap\FunctionSignature($parameters, $signature->getReturnType(), $nativeReturnType, $signature->isVariadic()); } public function hasMethodMetadata(string $className, string $methodName) : bool { return $this->hasFunctionMetadata(sprintf('%s::%s', $className, $methodName)); } public function hasFunctionMetadata(string $name) : bool { $signatureMap = self::getFunctionMetadataMap(); return array_key_exists(strtolower($name), $signatureMap); } /** * @return array{hasSideEffects: bool} */ public function getMethodMetadata(string $className, string $methodName) : array { return $this->getFunctionMetadata(sprintf('%s::%s', $className, $methodName)); } /** * @return array{hasSideEffects: bool} */ public function getFunctionMetadata(string $functionName) : array { $functionName = strtolower($functionName); if (!$this->hasFunctionMetadata($functionName)) { throw new ShouldNotHappenException(); } return self::getFunctionMetadataMap()[$functionName]; } /** * @return array */ private static function getFunctionMetadataMap() : array { if (self::$functionMetadata === null) { /** @var array $metadata */ $metadata = (require __DIR__ . '/../../../resources/functionMetadata.php'); self::$functionMetadata = array_change_key_case($metadata, CASE_LOWER); } return self::$functionMetadata; } /** * @return mixed[] */ public function getSignatureMap() : array { $cacheKey = sprintf('%d-%d', $this->phpVersion->getVersionId(), $this->stricterFunctionMap ? 1 : 0); if (array_key_exists($cacheKey, self::$signatureMaps)) { return self::$signatureMaps[$cacheKey]; } $signatureMap = (require __DIR__ . '/../../../resources/functionMap.php'); if (!is_array($signatureMap)) { throw new ShouldNotHappenException('Signature map could not be loaded.'); } $signatureMap = array_change_key_case($signatureMap, CASE_LOWER); if ($this->stricterFunctionMap) { $signatureMap = $this->computeSignatureMapFile($signatureMap, __DIR__ . '/../../../resources/functionMap_bleedingEdge.php'); } if ($this->phpVersion->getVersionId() >= 70400) { $signatureMap = $this->computeSignatureMapFile($signatureMap, __DIR__ . '/../../../resources/functionMap_php74delta.php'); } if ($this->phpVersion->getVersionId() >= 80000) { $signatureMap = $this->computeSignatureMapFile($signatureMap, __DIR__ . '/../../../resources/functionMap_php80delta.php'); if ($this->stricterFunctionMap) { $signatureMap = $this->computeSignatureMapFile($signatureMap, __DIR__ . '/../../../resources/functionMap_php80delta_bleedingEdge.php'); } } if ($this->phpVersion->getVersionId() >= 80100) { $signatureMap = $this->computeSignatureMapFile($signatureMap, __DIR__ . '/../../../resources/functionMap_php81delta.php'); } if ($this->phpVersion->getVersionId() >= 80200) { $signatureMap = $this->computeSignatureMapFile($signatureMap, __DIR__ . '/../../../resources/functionMap_php82delta.php'); } if ($this->phpVersion->getVersionId() >= 80300) { $signatureMap = $this->computeSignatureMapFile($signatureMap, __DIR__ . '/../../../resources/functionMap_php83delta.php'); } if ($this->phpVersion->getVersionId() >= 80400) { $signatureMap = $this->computeSignatureMapFile($signatureMap, __DIR__ . '/../../../resources/functionMap_php84delta.php'); } return self::$signatureMaps[$cacheKey] = $signatureMap; } /** * @param array $signatureMap * @return array */ private function computeSignatureMapFile(array $signatureMap, string $file) : array { $signatureMapDelta = (include $file); if (!is_array($signatureMapDelta)) { throw new ShouldNotHappenException(sprintf('Signature map file "%s" could not be loaded.', $file)); } return $this->computeSignatureMap($signatureMap, $signatureMapDelta); } /** * @param array $signatureMap * @param array> $delta * @return array */ private function computeSignatureMap(array $signatureMap, array $delta) : array { foreach (array_keys($delta['old']) as $key) { unset($signatureMap[strtolower($key)]); } foreach ($delta['new'] as $key => $signature) { $signatureMap[strtolower($key)] = $signature; } return $signatureMap; } public function hasClassConstantMetadata(string $className, string $constantName) : bool { return \false; } public function getClassConstantMetadata(string $className, string $constantName) : array { throw new ShouldNotHappenException(); } } signatureMapProvider = $signatureMapProvider; $this->reflector = $reflector; $this->fileTypeMapper = $fileTypeMapper; $this->stubPhpDocProvider = $stubPhpDocProvider; } public function findFunctionReflection(string $functionName) : ?NativeFunctionReflection { $lowerCasedFunctionName = strtolower($functionName); $realFunctionName = $lowerCasedFunctionName; if (isset($this->functionMap[$lowerCasedFunctionName])) { return $this->functionMap[$lowerCasedFunctionName]; } if (!$this->signatureMapProvider->hasFunctionSignature($lowerCasedFunctionName)) { return null; } $throwType = null; $reflectionFunctionAdapter = null; $isDeprecated = \false; $phpDocReturnType = null; $asserts = Assertions::createEmpty(); $docComment = null; $returnsByReference = TrinaryLogic::createMaybe(); $acceptsNamedArguments = \true; try { $reflectionFunction = $this->reflector->reflectFunction($functionName); $reflectionFunctionAdapter = new ReflectionFunction($reflectionFunction); $returnsByReference = TrinaryLogic::createFromBoolean($reflectionFunctionAdapter->returnsReference()); $realFunctionName = $reflectionFunction->getName(); if ($reflectionFunction->getFileName() !== null) { $fileName = $reflectionFunction->getFileName(); $docComment = $reflectionFunction->getDocComment(); if ($docComment !== null) { $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($fileName, null, null, $reflectionFunction->getName(), $docComment); $throwsTag = $resolvedPhpDoc->getThrowsTag(); if ($throwsTag !== null) { $throwType = $throwsTag->getType(); } $isDeprecated = $reflectionFunction->isDeprecated(); } } } catch (IdentifierNotFound|InvalidIdentifierName $e) { // pass } $functionSignaturesResult = $this->signatureMapProvider->getFunctionSignatures($lowerCasedFunctionName, null, $reflectionFunctionAdapter); $phpDoc = $this->stubPhpDocProvider->findFunctionPhpDoc($lowerCasedFunctionName, array_map(static function (\PHPStan\Reflection\SignatureMap\ParameterSignature $parameter) : string { return $parameter->getName(); }, $functionSignaturesResult['positional'][0]->getParameters())); if ($phpDoc !== null) { if ($phpDoc->hasPhpDocString()) { $docComment = $phpDoc->getPhpDocString(); } if ($phpDoc->getThrowsTag() !== null) { $throwType = $phpDoc->getThrowsTag()->getType(); } $asserts = Assertions::createFromResolvedPhpDocBlock($phpDoc); $phpDocReturnType = $this->getReturnTypeFromPhpDoc($phpDoc); $acceptsNamedArguments = $phpDoc->acceptsNamedArguments(); } $variantsByType = ['positional' => []]; foreach ($functionSignaturesResult as $signatureType => $functionSignatures) { foreach ($functionSignatures ?? [] as $functionSignature) { $variantsByType[$signatureType][] = new FunctionVariantWithPhpDocs(TemplateTypeMap::createEmpty(), null, array_map(static function (\PHPStan\Reflection\SignatureMap\ParameterSignature $parameterSignature) use($phpDoc) : NativeParameterWithPhpDocsReflection { $type = $parameterSignature->getType(); $phpDocType = null; $immediatelyInvokedCallable = TrinaryLogic::createMaybe(); $closureThisType = null; if ($phpDoc !== null) { if (array_key_exists($parameterSignature->getName(), $phpDoc->getParamTags())) { $phpDocType = $phpDoc->getParamTags()[$parameterSignature->getName()]->getType(); } if (array_key_exists($parameterSignature->getName(), $phpDoc->getParamsImmediatelyInvokedCallable())) { $immediatelyInvokedCallable = TrinaryLogic::createFromBoolean($phpDoc->getParamsImmediatelyInvokedCallable()[$parameterSignature->getName()]); } if (array_key_exists($parameterSignature->getName(), $phpDoc->getParamClosureThisTags())) { $closureThisType = $phpDoc->getParamClosureThisTags()[$parameterSignature->getName()]->getType(); } } return new NativeParameterWithPhpDocsReflection($parameterSignature->getName(), $parameterSignature->isOptional(), TypehintHelper::decideType($type, $phpDocType), $phpDocType ?? new MixedType(), $type, $parameterSignature->passedByReference(), $parameterSignature->isVariadic(), $parameterSignature->getDefaultValue(), $phpDoc !== null ? \PHPStan\Reflection\SignatureMap\NativeFunctionReflectionProvider::getParamOutTypeFromPhpDoc($parameterSignature->getName(), $phpDoc) : null, $immediatelyInvokedCallable, $closureThisType); }, $functionSignature->getParameters()), $functionSignature->isVariadic(), TypehintHelper::decideType($functionSignature->getReturnType(), $phpDocReturnType), $phpDocReturnType ?? new MixedType(), $functionSignature->getReturnType()); } } if ($this->signatureMapProvider->hasFunctionMetadata($lowerCasedFunctionName)) { $hasSideEffects = TrinaryLogic::createFromBoolean($this->signatureMapProvider->getFunctionMetadata($lowerCasedFunctionName)['hasSideEffects']); } else { $hasSideEffects = TrinaryLogic::createMaybe(); } $functionReflection = new NativeFunctionReflection($realFunctionName, $variantsByType['positional'], $variantsByType['named'] ?? null, $throwType, $hasSideEffects, $isDeprecated, $asserts, $docComment, $returnsByReference, $acceptsNamedArguments); $this->functionMap[$lowerCasedFunctionName] = $functionReflection; return $functionReflection; } private function getReturnTypeFromPhpDoc(ResolvedPhpDocBlock $phpDoc) : ?Type { $returnTag = $phpDoc->getReturnTag(); if ($returnTag === null) { return null; } return $returnTag->getType(); } private static function getParamOutTypeFromPhpDoc(string $paramName, ResolvedPhpDocBlock $stubPhpDoc) : ?Type { $paramOutTags = $stubPhpDoc->getParamOutTags(); if (array_key_exists($paramName, $paramOutTags)) { return $paramOutTags[$paramName]->getType(); } return null; } } phpVersion = $phpVersion; $this->functionSignatureMapProvider = $functionSignatureMapProvider; $this->php8SignatureMapProvider = $php8SignatureMapProvider; } public function create() : \PHPStan\Reflection\SignatureMap\SignatureMapProvider { if ($this->phpVersion->getVersionId() < 80000) { return $this->functionSignatureMapProvider; } return $this->php8SignatureMapProvider; } } , named: ?array} */ public function getMethodSignatures(string $className, string $methodName, ?ReflectionMethod $reflectionMethod) : array; /** @return array{positional: array, named: ?array} */ public function getFunctionSignatures(string $functionName, ?string $className, ?ReflectionFunctionAbstract $reflectionFunction) : array; public function hasMethodMetadata(string $className, string $methodName) : bool; public function hasFunctionMetadata(string $name) : bool; /** * @return array{hasSideEffects: bool} */ public function getMethodMetadata(string $className, string $methodName) : array; /** * @return array{hasSideEffects: bool} */ public function getFunctionMetadata(string $functionName) : array; public function hasClassConstantMetadata(string $className, string $constantName) : bool; /** * @return array{nativeType: Type} */ public function getClassConstantMetadata(string $className, string $constantName) : array; } name = $name; $this->optional = $optional; $this->type = $type; $this->nativeType = $nativeType; $this->passedByReference = $passedByReference; $this->variadic = $variadic; $this->defaultValue = $defaultValue; $this->outType = $outType; } public function getName() : string { return $this->name; } public function isOptional() : bool { return $this->optional; } public function getType() : Type { return $this->type; } public function getNativeType() : Type { return $this->nativeType; } public function passedByReference() : PassedByReference { return $this->passedByReference; } public function isVariadic() : bool { return $this->variadic; } public function getDefaultValue() : ?Type { return $this->defaultValue; } public function getOutType() : ?Type { return $this->outType; } } > */ private $methodNodes = []; /** @var array> */ private $constantTypes = []; /** * @var Php8StubsMap */ private $map; public function __construct(\PHPStan\Reflection\SignatureMap\FunctionSignatureMapProvider $functionSignatureMapProvider, FileNodesFetcher $fileNodesFetcher, FileTypeMapper $fileTypeMapper, PhpVersion $phpVersion, InitializerExprTypeResolver $initializerExprTypeResolver, ReflectionProviderProvider $reflectionProviderProvider) { $this->functionSignatureMapProvider = $functionSignatureMapProvider; $this->fileNodesFetcher = $fileNodesFetcher; $this->fileTypeMapper = $fileTypeMapper; $this->phpVersion = $phpVersion; $this->initializerExprTypeResolver = $initializerExprTypeResolver; $this->reflectionProviderProvider = $reflectionProviderProvider; $this->map = new Php8StubsMap($phpVersion->getVersionId()); } public function hasMethodSignature(string $className, string $methodName) : bool { $lowerClassName = strtolower($className); if ($lowerClassName === 'backedenum') { return \false; } if (!array_key_exists($lowerClassName, $this->map->classes)) { return $this->functionSignatureMapProvider->hasMethodSignature($className, $methodName); } if ($this->findMethodNode($className, $methodName) === null) { return $this->functionSignatureMapProvider->hasMethodSignature($className, $methodName); } return \true; } /** * @return array{ClassMethod, string}|null */ private function findMethodNode(string $className, string $methodName) : ?array { $lowerClassName = strtolower($className); $lowerMethodName = strtolower($methodName); if (isset($this->methodNodes[$lowerClassName][$lowerMethodName])) { return $this->methodNodes[$lowerClassName][$lowerMethodName]; } $stubFile = self::DIRECTORY . '/' . $this->map->classes[$lowerClassName]; $nodes = $this->fileNodesFetcher->fetchNodes($stubFile); $classes = $nodes->getClassNodes(); if (count($classes) !== 1) { throw new ShouldNotHappenException(sprintf('Class %s stub not found in %s.', $className, $stubFile)); } $class = $classes[$lowerClassName]; if (count($class) !== 1) { throw new ShouldNotHappenException(sprintf('Class %s stub not found in %s.', $className, $stubFile)); } foreach ($class[0]->getNode()->stmts as $stmt) { if (!$stmt instanceof ClassMethod) { continue; } if ($stmt->name->toLowerString() === $lowerMethodName) { if (!$this->isForCurrentVersion($stmt->attrGroups)) { continue; } return $this->methodNodes[$lowerClassName][$lowerMethodName] = [$stmt, $stubFile]; } } return null; } /** * @param AttributeGroup[] $attrGroups */ private function isForCurrentVersion(array $attrGroups) : bool { foreach ($attrGroups as $attrGroup) { foreach ($attrGroup->attrs as $attr) { if ($attr->name->toString() === 'Until') { $arg = $attr->args[0]->value; if (!$arg instanceof String_) { throw new ShouldNotHappenException(); } $parts = explode('.', $arg->value); $versionId = (int) $parts[0] * 10000 + (int) ($parts[1] ?? 0) * 100 + (int) ($parts[2] ?? 0); if ($this->phpVersion->getVersionId() >= $versionId) { return \false; } } if ($attr->name->toString() !== 'Since') { continue; } $arg = $attr->args[0]->value; if (!$arg instanceof String_) { throw new ShouldNotHappenException(); } $parts = explode('.', $arg->value); $versionId = (int) $parts[0] * 10000 + (int) ($parts[1] ?? 0) * 100 + (int) ($parts[2] ?? 0); if ($this->phpVersion->getVersionId() < $versionId) { return \false; } } } return \true; } public function hasFunctionSignature(string $name) : bool { $lowerName = strtolower($name); if (!array_key_exists($lowerName, $this->map->functions)) { return $this->functionSignatureMapProvider->hasFunctionSignature($name); } return \true; } public function getMethodSignatures(string $className, string $methodName, ?ReflectionMethod $reflectionMethod) : array { $lowerClassName = strtolower($className); if (!array_key_exists($lowerClassName, $this->map->classes)) { return $this->functionSignatureMapProvider->getMethodSignatures($className, $methodName, $reflectionMethod); } $methodNode = $this->findMethodNode($className, $methodName); if ($methodNode === null) { return $this->functionSignatureMapProvider->getMethodSignatures($className, $methodName, $reflectionMethod); } [$methodNode, $stubFile] = $methodNode; $signature = $this->getSignature($methodNode, $className, $stubFile); if ($this->functionSignatureMapProvider->hasMethodSignature($className, $methodName)) { $functionMapSignatures = $this->functionSignatureMapProvider->getMethodSignatures($className, $methodName, $reflectionMethod); return $this->getMergedSignatures($signature, $functionMapSignatures); } return ['positional' => [$signature], 'named' => null]; } /** * @param ReflectionFunctionAbstract|null $reflectionFunction */ public function getFunctionSignatures(string $functionName, ?string $className, $reflectionFunction) : array { $lowerName = strtolower($functionName); if (!array_key_exists($lowerName, $this->map->functions)) { return $this->functionSignatureMapProvider->getFunctionSignatures($functionName, $className, $reflectionFunction); } $stubFile = self::DIRECTORY . '/' . $this->map->functions[$lowerName]; $nodes = $this->fileNodesFetcher->fetchNodes($stubFile); $functions = $nodes->getFunctionNodes(); if (!array_key_exists($lowerName, $functions)) { throw new ShouldNotHappenException(sprintf('Function %s stub not found in %s.', $functionName, $stubFile)); } foreach ($functions[$lowerName] as $functionNode) { if (!$this->isForCurrentVersion($functionNode->getNode()->getAttrGroups())) { continue; } $signature = $this->getSignature($functionNode->getNode(), null, $stubFile); if ($this->functionSignatureMapProvider->hasFunctionSignature($functionName)) { $functionMapSignatures = $this->functionSignatureMapProvider->getFunctionSignatures($functionName, $className, $reflectionFunction); return $this->getMergedSignatures($signature, $functionMapSignatures); } return ['positional' => [$signature], 'named' => null]; } throw new ShouldNotHappenException(sprintf('Function %s stub not found in %s.', $functionName, $stubFile)); } /** * @param array{positional: array, named: ?array} $functionMapSignatures * @return array{positional: array, named: ?array} */ private function getMergedSignatures(\PHPStan\Reflection\SignatureMap\FunctionSignature $nativeSignature, array $functionMapSignatures) : array { if (count($functionMapSignatures['positional']) === 1) { return ['positional' => [$this->mergeSignatures($nativeSignature, $functionMapSignatures['positional'][0])], 'named' => null]; } if (count($functionMapSignatures['positional']) === 0) { return ['positional' => [], 'named' => null]; } $nativeParams = $nativeSignature->getParameters(); $namedArgumentsVariants = []; $allParamNamesMatchNative = \true; foreach ($functionMapSignatures['positional'] as $functionMapSignature) { $isPrevParamVariadic = \false; $hasMiddleVariadicParam = \false; // avoid weird functions like array_diff_uassoc foreach ($functionMapSignature->getParameters() as $i => $functionParam) { $nativeParam = $nativeParams[$i] ?? null; $allParamNamesMatchNative = $allParamNamesMatchNative && $nativeParam !== null && $functionParam->getName() === $nativeParam->getName(); $hasMiddleVariadicParam = $hasMiddleVariadicParam || $isPrevParamVariadic; $isPrevParamVariadic = $functionParam->isVariadic() || ($nativeParam !== null ? $nativeParam->isVariadic() : \false); } if ($hasMiddleVariadicParam) { continue; } $parameters = []; foreach ($functionMapSignature->getParameters() as $i => $functionParam) { if (!array_key_exists($i, $nativeParams)) { continue 2; } // it seems that variadic parameters cannot be named in native functions/methods. $nativeParam = $nativeParams[$i]; if ($nativeParam->isVariadic()) { break; } $parameters[] = new \PHPStan\Reflection\SignatureMap\ParameterSignature($nativeParam->getName(), $functionParam->isOptional(), $functionParam->getType(), $functionParam->getNativeType(), $functionParam->passedByReference(), $functionParam->isVariadic(), $functionParam->getDefaultValue(), $functionParam->getOutType()); } $namedArgumentsVariants[] = new \PHPStan\Reflection\SignatureMap\FunctionSignature($parameters, $functionMapSignature->getReturnType(), $functionMapSignature->getNativeReturnType(), $functionMapSignature->isVariadic()); } if ($allParamNamesMatchNative || count($namedArgumentsVariants) === 0) { $namedArgumentsVariants = null; } return ['positional' => $functionMapSignatures['positional'], 'named' => $namedArgumentsVariants]; } private function mergeSignatures(\PHPStan\Reflection\SignatureMap\FunctionSignature $nativeSignature, \PHPStan\Reflection\SignatureMap\FunctionSignature $functionMapSignature) : \PHPStan\Reflection\SignatureMap\FunctionSignature { $parameters = []; foreach ($nativeSignature->getParameters() as $i => $nativeParameter) { if (!array_key_exists($i, $functionMapSignature->getParameters())) { $parameters[] = $nativeParameter; continue; } $functionMapParameter = $functionMapSignature->getParameters()[$i]; $nativeParameterType = $nativeParameter->getNativeType(); $parameters[] = new \PHPStan\Reflection\SignatureMap\ParameterSignature($nativeParameter->getName(), $nativeParameter->isOptional(), TypehintHelper::decideType($nativeParameterType, TypehintHelper::decideType($nativeParameter->getType(), $functionMapParameter->getType())), $nativeParameterType, $nativeParameter->passedByReference()->yes() ? $functionMapParameter->passedByReference() : $nativeParameter->passedByReference(), $nativeParameter->isVariadic(), $nativeParameter->getDefaultValue(), $nativeParameter->getOutType()); } $nativeReturnType = $nativeSignature->getNativeReturnType(); if ($nativeReturnType instanceof MixedType && !$nativeReturnType->isExplicitMixed()) { $returnType = $functionMapSignature->getReturnType(); } else { $returnType = TypehintHelper::decideType($nativeReturnType, TypehintHelper::decideType($nativeSignature->getReturnType(), $functionMapSignature->getReturnType())); } return new \PHPStan\Reflection\SignatureMap\FunctionSignature($parameters, $returnType, $nativeReturnType, $nativeSignature->isVariadic()); } public function hasMethodMetadata(string $className, string $methodName) : bool { return $this->functionSignatureMapProvider->hasMethodMetadata($className, $methodName); } public function hasFunctionMetadata(string $name) : bool { return $this->functionSignatureMapProvider->hasFunctionMetadata($name); } /** * @return array{hasSideEffects: bool} */ public function getMethodMetadata(string $className, string $methodName) : array { return $this->functionSignatureMapProvider->getMethodMetadata($className, $methodName); } /** * @return array{hasSideEffects: bool} */ public function getFunctionMetadata(string $functionName) : array { return $this->functionSignatureMapProvider->getFunctionMetadata($functionName); } /** * @param ClassMethod|Function_ $function */ private function getSignature($function, ?string $className, string $stubFile) : \PHPStan\Reflection\SignatureMap\FunctionSignature { $phpDocParameterTypes = null; $phpDocReturnType = null; if ($function->getDocComment() !== null) { if ($function instanceof ClassMethod) { $functionName = $function->name->toString(); } elseif ($function->namespacedName !== null) { $functionName = $function->namespacedName->toString(); } else { throw new ShouldNotHappenException(); } $phpDoc = $this->fileTypeMapper->getResolvedPhpDoc($stubFile, $className, null, $functionName, $function->getDocComment()->getText()); $phpDocParameterTypes = array_map(static function (ParamTag $param) : Type { return $param->getType(); }, $phpDoc->getParamTags()); if ($phpDoc->getReturnTag() !== null) { $phpDocReturnType = $phpDoc->getReturnTag()->getType(); } } $classReflection = null; if ($className !== null) { $reflectionProvider = $this->reflectionProviderProvider->getReflectionProvider(); $classReflection = $reflectionProvider->getClass($className); } $parameters = []; $variadic = \false; foreach ($function->getParams() as $param) { $name = $param->var; if (!$name instanceof Variable || !is_string($name->name)) { throw new ShouldNotHappenException(); } $parameterType = ParserNodeTypeToPHPStanType::resolve($param->type, $classReflection); $parameters[] = new \PHPStan\Reflection\SignatureMap\ParameterSignature($name->name, $param->default !== null || $param->variadic, TypehintHelper::decideType($parameterType, $phpDocParameterTypes[$name->name] ?? null), $parameterType, $param->byRef ? PassedByReference::createCreatesNewVariable() : PassedByReference::createNo(), $param->variadic, $param->default !== null ? $this->initializerExprTypeResolver->getType($param->default, InitializerExprContext::fromStubParameter($className, $stubFile, $function)) : null, null); $variadic = $variadic || $param->variadic; } $returnType = ParserNodeTypeToPHPStanType::resolve($function->getReturnType(), $classReflection); return new \PHPStan\Reflection\SignatureMap\FunctionSignature($parameters, TypehintHelper::decideType($returnType, $phpDocReturnType ?? null), $returnType, $variadic); } public function hasClassConstantMetadata(string $className, string $constantName) : bool { $lowerClassName = strtolower($className); if (!array_key_exists($lowerClassName, $this->map->classes)) { return \false; } return $this->findConstantType($className, $constantName) !== null; } public function getClassConstantMetadata(string $className, string $constantName) : array { $lowerClassName = strtolower($className); if (!array_key_exists($lowerClassName, $this->map->classes)) { throw new ShouldNotHappenException(); } $type = $this->findConstantType($className, $constantName); if ($type === null) { throw new ShouldNotHappenException(); } return ['nativeType' => $type]; } private function findConstantType(string $className, string $constantName) : ?Type { $lowerClassName = strtolower($className); $lowerConstantName = strtolower($constantName); if (isset($this->constantTypes[$lowerClassName][$lowerConstantName])) { return $this->constantTypes[$lowerClassName][$lowerConstantName]; } $stubFile = self::DIRECTORY . '/' . $this->map->classes[$lowerClassName]; $nodes = $this->fileNodesFetcher->fetchNodes($stubFile); $classes = $nodes->getClassNodes(); if (count($classes) !== 1) { throw new ShouldNotHappenException(sprintf('Class %s stub not found in %s.', $className, $stubFile)); } $class = $classes[$lowerClassName]; if (count($class) !== 1) { throw new ShouldNotHappenException(sprintf('Class %s stub not found in %s.', $className, $stubFile)); } foreach ($class[0]->getNode()->stmts as $stmt) { if (!$stmt instanceof ClassConst) { continue; } foreach ($stmt->consts as $const) { if ($const->name->toString() !== $constantName) { continue; } if (!$this->isForCurrentVersion($stmt->attrGroups)) { continue; } if ($stmt->type === null) { return null; } return $this->constantTypes[$lowerClassName][$lowerConstantName] = ParserNodeTypeToPHPStanType::resolve($stmt->type, null); } } return null; } } */ private $parameters; /** * @var Type */ private $returnType; /** * @var Type */ private $nativeReturnType; /** * @var bool */ private $variadic; /** * @param array $parameters */ public function __construct(array $parameters, Type $returnType, Type $nativeReturnType, bool $variadic) { $this->parameters = $parameters; $this->returnType = $returnType; $this->nativeReturnType = $nativeReturnType; $this->variadic = $variadic; } /** * @return array */ public function getParameters() : array { return $this->parameters; } public function getReturnType() : Type { return $this->returnType; } public function getNativeReturnType() : Type { return $this->nativeReturnType; } public function isVariadic() : bool { return $this->variadic; } } declaringEnum = $declaringEnum; $this->name = $name; $this->backingValueType = $backingValueType; } public function getDeclaringEnum() : \PHPStan\Reflection\ClassReflection { return $this->declaringEnum; } public function getName() : string { return $this->name; } public function getBackingValueType() : ?Type { return $this->backingValueType; } } methodName = $methodName; $this->methods = $methods; } public function getDeclaringClass() : ClassReflection { return $this->methods[0]->getDeclaringClass(); } public function isStatic() : bool { foreach ($this->methods as $method) { if ($method->isStatic()) { return \true; } } return \false; } public function isPrivate() : bool { foreach ($this->methods as $method) { if (!$method->isPrivate()) { return \false; } } return \true; } public function isPublic() : bool { foreach ($this->methods as $method) { if ($method->isPublic()) { return \true; } } return \false; } public function getName() : string { return $this->methodName; } public function getPrototype() : ClassMemberReflection { return $this; } public function getVariants() : array { $returnType = TypeCombinator::intersect(...array_map(static function (MethodReflection $method) : Type { return TypeCombinator::intersect(...array_map(static function (ParametersAcceptor $acceptor) : Type { return $acceptor->getReturnType(); }, $method->getVariants())); }, $this->methods)); $phpDocReturnType = TypeCombinator::intersect(...array_map(static function (MethodReflection $method) : Type { return TypeCombinator::intersect(...array_map(static function (ParametersAcceptor $acceptor) : Type { return $acceptor->getPhpDocReturnType(); }, $method->getVariants())); }, $this->methods)); $nativeReturnType = TypeCombinator::intersect(...array_map(static function (MethodReflection $method) : Type { return TypeCombinator::intersect(...array_map(static function (ParametersAcceptor $acceptor) : Type { return $acceptor->getNativeReturnType(); }, $method->getVariants())); }, $this->methods)); return array_map(static function (ParametersAcceptorWithPhpDocs $acceptor) use($returnType, $phpDocReturnType, $nativeReturnType) : ParametersAcceptorWithPhpDocs { return new FunctionVariantWithPhpDocs($acceptor->getTemplateTypeMap(), $acceptor->getResolvedTemplateTypeMap(), $acceptor->getParameters(), $acceptor->isVariadic(), $returnType, $phpDocReturnType, $nativeReturnType, $acceptor->getCallSiteVarianceMap()); }, $this->methods[0]->getVariants()); } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { $variants = $this->getVariants(); if (count($variants) !== 1) { throw new ShouldNotHappenException(); } return $variants[0]; } public function getNamedArgumentsVariants() : ?array { return null; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::lazyMaxMin($this->methods, static function (MethodReflection $method) : TrinaryLogic { return $method->isDeprecated(); }); } public function getDeprecatedDescription() : ?string { $descriptions = []; foreach ($this->methods as $method) { if (!$method->isDeprecated()->yes()) { continue; } $description = $method->getDeprecatedDescription(); if ($description === null) { continue; } $descriptions[] = $description; } if (count($descriptions) === 0) { return null; } return implode(' ', $descriptions); } public function isFinal() : TrinaryLogic { return TrinaryLogic::lazyMaxMin($this->methods, static function (MethodReflection $method) : TrinaryLogic { return $method->isFinal(); }); } public function isFinalByKeyword() : TrinaryLogic { return TrinaryLogic::lazyMaxMin($this->methods, static function (ExtendedMethodReflection $method) : TrinaryLogic { return $method->isFinalByKeyword(); }); } public function isInternal() : TrinaryLogic { return TrinaryLogic::lazyMaxMin($this->methods, static function (MethodReflection $method) : TrinaryLogic { return $method->isInternal(); }); } public function getThrowType() : ?Type { $types = []; foreach ($this->methods as $method) { $type = $method->getThrowType(); if ($type === null) { continue; } $types[] = $type; } if (count($types) === 0) { return null; } return TypeCombinator::intersect(...$types); } public function hasSideEffects() : TrinaryLogic { return TrinaryLogic::lazyMaxMin($this->methods, static function (MethodReflection $method) : TrinaryLogic { return $method->hasSideEffects(); }); } public function isPure() : TrinaryLogic { return TrinaryLogic::lazyMaxMin($this->methods, static function (ExtendedMethodReflection $method) : TrinaryLogic { return $method->isPure(); }); } public function getDocComment() : ?string { return null; } public function getAsserts() : Assertions { $assertions = Assertions::createEmpty(); foreach ($this->methods as $method) { $assertions = $assertions->intersectWith($method->getAsserts()); } return $assertions; } public function acceptsNamedArguments() : bool { $accepts = \true; foreach ($this->methods as $method) { $accepts = $accepts && $method->acceptsNamedArguments(); } return $accepts; } public function getSelfOutType() : ?Type { return null; } public function returnsByReference() : TrinaryLogic { return TrinaryLogic::lazyMaxMin($this->methods, static function (ExtendedMethodReflection $method) : TrinaryLogic { return $method->returnsByReference(); }); } public function isAbstract() : TrinaryLogic { return TrinaryLogic::lazyMaxMin($this->methods, static function (ExtendedMethodReflection $method) : TrinaryLogic { return is_bool($method->isAbstract()) ? TrinaryLogic::createFromBoolean($method->isAbstract()) : $method->isAbstract(); }); } } methodName = $methodName; $this->methodPrototypes = $methodPrototypes; } public function doNotResolveTemplateTypeMapToBounds() : \PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection { if ($this->cachedDoNotResolveTemplateTypeMapToBounds !== null) { return $this->cachedDoNotResolveTemplateTypeMapToBounds; } return $this->cachedDoNotResolveTemplateTypeMapToBounds = new self($this->methodName, array_map(static function (\PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection $prototype) : \PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection { return $prototype->doNotResolveTemplateTypeMapToBounds(); }, $this->methodPrototypes)); } public function getNakedMethod() : ExtendedMethodReflection { return $this->getTransformedMethod(); } public function getTransformedMethod() : ExtendedMethodReflection { if ($this->transformedMethod !== null) { return $this->transformedMethod; } $methods = array_map(static function (\PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection $prototype) : MethodReflection { return $prototype->getTransformedMethod(); }, $this->methodPrototypes); return $this->transformedMethod = new \PHPStan\Reflection\Type\UnionTypeMethodReflection($this->methodName, $methods); } public function withCalledOnType(Type $type) : \PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection { return new self($this->methodName, array_map(static function (\PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection $prototype) use($type) : \PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection { return $prototype->withCalledOnType($type); }, $this->methodPrototypes)); } } properties = $properties; } public function getDeclaringClass() : ClassReflection { return $this->properties[0]->getDeclaringClass(); } public function isStatic() : bool { return $this->computeResult(static function (PropertyReflection $property) { return $property->isStatic(); }); } public function isPrivate() : bool { return $this->computeResult(static function (PropertyReflection $property) { return $property->isPrivate(); }); } public function isPublic() : bool { return $this->computeResult(static function (PropertyReflection $property) { return $property->isPublic(); }); } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::lazyMaxMin($this->properties, static function (PropertyReflection $propertyReflection) : TrinaryLogic { return $propertyReflection->isDeprecated(); }); } public function getDeprecatedDescription() : ?string { $descriptions = []; foreach ($this->properties as $property) { if (!$property->isDeprecated()->yes()) { continue; } $description = $property->getDeprecatedDescription(); if ($description === null) { continue; } $descriptions[] = $description; } if (count($descriptions) === 0) { return null; } return implode(' ', $descriptions); } public function isInternal() : TrinaryLogic { return TrinaryLogic::lazyMaxMin($this->properties, static function (PropertyReflection $propertyReflection) : TrinaryLogic { return $propertyReflection->isInternal(); }); } public function getDocComment() : ?string { return null; } public function getReadableType() : Type { return TypeCombinator::intersect(...array_map(static function (PropertyReflection $property) : Type { return $property->getReadableType(); }, $this->properties)); } public function getWritableType() : Type { return TypeCombinator::intersect(...array_map(static function (PropertyReflection $property) : Type { return $property->getWritableType(); }, $this->properties)); } public function canChangeTypeAfterAssignment() : bool { return $this->computeResult(static function (PropertyReflection $property) { return $property->canChangeTypeAfterAssignment(); }); } public function isReadable() : bool { return $this->computeResult(static function (PropertyReflection $property) { return $property->isReadable(); }); } public function isWritable() : bool { return $this->computeResult(static function (PropertyReflection $property) { return $property->isWritable(); }); } /** * @param callable(PropertyReflection): bool $cb */ private function computeResult(callable $cb) : bool { $result = \false; foreach ($this->properties as $property) { $result = $result || $cb($property); } return $result; } } properties = $properties; } public function getDeclaringClass() : ClassReflection { return $this->properties[0]->getDeclaringClass(); } public function isStatic() : bool { return $this->computeResult(static function (PropertyReflection $property) { return $property->isStatic(); }); } public function isPrivate() : bool { return $this->computeResult(static function (PropertyReflection $property) { return $property->isPrivate(); }); } public function isPublic() : bool { return $this->computeResult(static function (PropertyReflection $property) { return $property->isPublic(); }); } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->properties, static function (PropertyReflection $propertyReflection) : TrinaryLogic { return $propertyReflection->isDeprecated(); }); } public function getDeprecatedDescription() : ?string { $descriptions = []; foreach ($this->properties as $property) { if (!$property->isDeprecated()->yes()) { continue; } $description = $property->getDeprecatedDescription(); if ($description === null) { continue; } $descriptions[] = $description; } if (count($descriptions) === 0) { return null; } return implode(' ', $descriptions); } public function isInternal() : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->properties, static function (PropertyReflection $propertyReflection) : TrinaryLogic { return $propertyReflection->isInternal(); }); } public function getDocComment() : ?string { return null; } public function getReadableType() : Type { return TypeCombinator::union(...array_map(static function (PropertyReflection $property) : Type { return $property->getReadableType(); }, $this->properties)); } public function getWritableType() : Type { return TypeCombinator::union(...array_map(static function (PropertyReflection $property) : Type { return $property->getWritableType(); }, $this->properties)); } public function canChangeTypeAfterAssignment() : bool { return $this->computeResult(static function (PropertyReflection $property) { return $property->canChangeTypeAfterAssignment(); }); } public function isReadable() : bool { return $this->computeResult(static function (PropertyReflection $property) { return $property->isReadable(); }); } public function isWritable() : bool { return $this->computeResult(static function (PropertyReflection $property) { return $property->isWritable(); }); } /** * @param callable(PropertyReflection): bool $cb */ private function computeResult(callable $cb) : bool { $result = \true; foreach ($this->properties as $property) { $result = $result && $cb($property); } return $result; } } methodName = $methodName; $this->methods = $methods; } public function getDeclaringClass() : ClassReflection { return $this->methods[0]->getDeclaringClass(); } public function isStatic() : bool { foreach ($this->methods as $method) { if (!$method->isStatic()) { return \false; } } return \true; } public function isPrivate() : bool { foreach ($this->methods as $method) { if ($method->isPrivate()) { return \true; } } return \false; } public function isPublic() : bool { foreach ($this->methods as $method) { if (!$method->isPublic()) { return \false; } } return \true; } public function getName() : string { return $this->methodName; } public function getPrototype() : ClassMemberReflection { return $this; } public function getVariants() : array { $variants = array_merge(...array_map(static function (MethodReflection $method) { return $method->getVariants(); }, $this->methods)); return [ParametersAcceptorSelector::combineAcceptors($variants)]; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { return $this->getVariants()[0]; } public function getNamedArgumentsVariants() : ?array { return null; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->methods, static function (MethodReflection $method) : TrinaryLogic { return $method->isDeprecated(); }); } public function getDeprecatedDescription() : ?string { $descriptions = []; foreach ($this->methods as $method) { if (!$method->isDeprecated()->yes()) { continue; } $description = $method->getDeprecatedDescription(); if ($description === null) { continue; } $descriptions[] = $description; } if (count($descriptions) === 0) { return null; } return implode(' ', $descriptions); } public function isFinal() : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->methods, static function (MethodReflection $method) : TrinaryLogic { return $method->isFinal(); }); } public function isFinalByKeyword() : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->methods, static function (ExtendedMethodReflection $method) : TrinaryLogic { return $method->isFinalByKeyword(); }); } public function isInternal() : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->methods, static function (MethodReflection $method) : TrinaryLogic { return $method->isInternal(); }); } public function getThrowType() : ?Type { $types = []; foreach ($this->methods as $method) { $type = $method->getThrowType(); if ($type === null) { continue; } $types[] = $type; } if (count($types) === 0) { return null; } return TypeCombinator::union(...$types); } public function hasSideEffects() : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->methods, static function (MethodReflection $method) : TrinaryLogic { return $method->hasSideEffects(); }); } public function isPure() : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->methods, static function (ExtendedMethodReflection $method) : TrinaryLogic { return $method->isPure(); }); } public function getDocComment() : ?string { return null; } public function getAsserts() : Assertions { return Assertions::createEmpty(); } public function acceptsNamedArguments() : bool { $accepts = \true; foreach ($this->methods as $method) { $accepts = $accepts && $method->acceptsNamedArguments(); } return $accepts; } public function getSelfOutType() : ?Type { return null; } public function returnsByReference() : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->methods, static function (ExtendedMethodReflection $method) : TrinaryLogic { return $method->returnsByReference(); }); } public function isAbstract() : TrinaryLogic { return TrinaryLogic::lazyExtremeIdentity($this->methods, static function (ExtendedMethodReflection $method) : TrinaryLogic { return is_bool($method->isAbstract()) ? TrinaryLogic::createFromBoolean($method->isAbstract()) : $method->isAbstract(); }); } } methodReflection = $methodReflection; $this->resolvedDeclaringClass = $resolvedDeclaringClass; $this->resolveTemplateTypeMapToBounds = $resolveTemplateTypeMapToBounds; $this->calledOnType = $calledOnType; } public function doNotResolveTemplateTypeMapToBounds() : \PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection { if ($this->cachedDoNotResolveTemplateTypeMapToBounds !== null) { return $this->cachedDoNotResolveTemplateTypeMapToBounds; } return $this->cachedDoNotResolveTemplateTypeMapToBounds = new self($this->methodReflection, $this->resolvedDeclaringClass, \false, $this->calledOnType); } public function getNakedMethod() : ExtendedMethodReflection { return $this->methodReflection; } public function getTransformedMethod() : ExtendedMethodReflection { if ($this->transformedMethod !== null) { return $this->transformedMethod; } $templateTypeMap = $this->resolvedDeclaringClass->getActiveTemplateTypeMap(); $callSiteVarianceMap = $this->resolvedDeclaringClass->getCallSiteVarianceMap(); return $this->transformedMethod = new ResolvedMethodReflection($this->transformMethodWithStaticType($this->resolvedDeclaringClass, $this->methodReflection), $this->resolveTemplateTypeMapToBounds ? $templateTypeMap->resolveToBounds() : $templateTypeMap, $callSiteVarianceMap); } public function withCalledOnType(Type $type) : \PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection { return new self($this->methodReflection, $this->resolvedDeclaringClass, $this->resolveTemplateTypeMapToBounds, $type); } private function transformMethodWithStaticType(ClassReflection $declaringClass, ExtendedMethodReflection $method) : ExtendedMethodReflection { $variantFn = function (ParametersAcceptorWithPhpDocs $acceptor) : ParametersAcceptorWithPhpDocs { return new FunctionVariantWithPhpDocs($acceptor->getTemplateTypeMap(), $acceptor->getResolvedTemplateTypeMap(), array_map(function (ParameterReflectionWithPhpDocs $parameter) : ParameterReflectionWithPhpDocs { return new DummyParameterWithPhpDocs($parameter->getName(), $this->transformStaticType($parameter->getType()), $parameter->isOptional(), $parameter->passedByReference(), $parameter->isVariadic(), $parameter->getDefaultValue(), $parameter->getNativeType(), $this->transformStaticType($parameter->getPhpDocType()), $parameter->getOutType() !== null ? $this->transformStaticType($parameter->getOutType()) : null, $parameter->isImmediatelyInvokedCallable(), $parameter->getClosureThisType() !== null ? $this->transformStaticType($parameter->getClosureThisType()) : null); }, $acceptor->getParameters()), $acceptor->isVariadic(), $this->transformStaticType($acceptor->getReturnType()), $this->transformStaticType($acceptor->getPhpDocReturnType()), $this->transformStaticType($acceptor->getNativeReturnType()), $acceptor->getCallSiteVarianceMap()); }; $variants = array_map($variantFn, $method->getVariants()); $namedArgumentsVariants = $method->getNamedArgumentsVariants(); $namedArgumentsVariants = $namedArgumentsVariants !== null ? array_map($variantFn, $namedArgumentsVariants) : null; return new ChangedTypeMethodReflection($declaringClass, $method, $variants, $namedArgumentsVariants); } private function transformStaticType(Type $type) : Type { return TypeTraverser::map($type, function (Type $type, callable $traverse) : Type { if ($type instanceof GenericStaticType) { $calledOnTypeReflections = $this->calledOnType->getObjectClassReflections(); if (count($calledOnTypeReflections) === 1) { $calledOnTypeReflection = $calledOnTypeReflections[0]; return $traverse($type->changeBaseClass($calledOnTypeReflection)->getStaticObjectType()); } return $this->calledOnType; } if ($type instanceof StaticType) { return $this->calledOnType; } return $traverse($type); }); } } propertyReflection = $propertyReflection; $this->resolvedDeclaringClass = $resolvedDeclaringClass; $this->resolveTemplateTypeMapToBounds = $resolveTemplateTypeMapToBounds; $this->fetchedOnType = $fetchedOnType; } public function doNotResolveTemplateTypeMapToBounds() : \PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection { if ($this->cachedDoNotResolveTemplateTypeMapToBounds !== null) { return $this->cachedDoNotResolveTemplateTypeMapToBounds; } return $this->cachedDoNotResolveTemplateTypeMapToBounds = new self($this->propertyReflection, $this->resolvedDeclaringClass, \false, $this->fetchedOnType); } public function getNakedProperty() : ExtendedPropertyReflection { return $this->propertyReflection; } public function getTransformedProperty() : ExtendedPropertyReflection { if ($this->transformedProperty !== null) { return $this->transformedProperty; } $templateTypeMap = $this->resolvedDeclaringClass->getActiveTemplateTypeMap(); $callSiteVarianceMap = $this->resolvedDeclaringClass->getCallSiteVarianceMap(); return $this->transformedProperty = new ResolvedPropertyReflection($this->transformPropertyWithStaticType($this->resolvedDeclaringClass, $this->propertyReflection), $this->resolveTemplateTypeMapToBounds ? $templateTypeMap->resolveToBounds() : $templateTypeMap, $callSiteVarianceMap); } public function withFechedOnType(Type $type) : \PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection { return new self($this->propertyReflection, $this->resolvedDeclaringClass, $this->resolveTemplateTypeMapToBounds, $type); } private function transformPropertyWithStaticType(ClassReflection $declaringClass, ExtendedPropertyReflection $property) : ExtendedPropertyReflection { $readableType = $this->transformStaticType($property->getReadableType()); $writableType = $this->transformStaticType($property->getWritableType()); return new ChangedTypePropertyReflection($declaringClass, $property, $readableType, $writableType); } private function transformStaticType(Type $type) : Type { return TypeTraverser::map($type, function (Type $type, callable $traverse) : Type { if ($type instanceof StaticType) { return $this->fetchedOnType; } return $traverse($type); }); } } propertyReflection = $propertyReflection; $this->resolvedDeclaringClass = $resolvedDeclaringClass; $this->resolveTemplateTypeMapToBounds = $resolveTemplateTypeMapToBounds; $this->transformStaticTypeCallback = $transformStaticTypeCallback; } public function doNotResolveTemplateTypeMapToBounds() : \PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection { if ($this->cachedDoNotResolveTemplateTypeMapToBounds !== null) { return $this->cachedDoNotResolveTemplateTypeMapToBounds; } return $this->cachedDoNotResolveTemplateTypeMapToBounds = new self($this->propertyReflection, $this->resolvedDeclaringClass, \false, $this->transformStaticTypeCallback); } public function getNakedProperty() : ExtendedPropertyReflection { return $this->propertyReflection; } public function getTransformedProperty() : ExtendedPropertyReflection { if ($this->transformedProperty !== null) { return $this->transformedProperty; } $templateTypeMap = $this->resolvedDeclaringClass->getActiveTemplateTypeMap(); $callSiteVarianceMap = $this->resolvedDeclaringClass->getCallSiteVarianceMap(); return $this->transformedProperty = new ResolvedPropertyReflection($this->transformPropertyWithStaticType($this->resolvedDeclaringClass, $this->propertyReflection), $this->resolveTemplateTypeMapToBounds ? $templateTypeMap->resolveToBounds() : $templateTypeMap, $callSiteVarianceMap); } public function withFechedOnType(Type $type) : \PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection { return new \PHPStan\Reflection\Type\CalledOnTypeUnresolvedPropertyPrototypeReflection($this->propertyReflection, $this->resolvedDeclaringClass, $this->resolveTemplateTypeMapToBounds, $type); } private function transformPropertyWithStaticType(ClassReflection $declaringClass, ExtendedPropertyReflection $property) : ExtendedPropertyReflection { $readableType = $this->transformStaticType($property->getReadableType()); $writableType = $this->transformStaticType($property->getWritableType()); return new ChangedTypePropertyReflection($declaringClass, $property, $readableType, $writableType); } private function transformStaticType(Type $type) : Type { $callback = $this->transformStaticTypeCallback; return $callback($type); } } methodName = $methodName; $this->methodPrototypes = $methodPrototypes; } public function doNotResolveTemplateTypeMapToBounds() : \PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection { if ($this->cachedDoNotResolveTemplateTypeMapToBounds !== null) { return $this->cachedDoNotResolveTemplateTypeMapToBounds; } return $this->cachedDoNotResolveTemplateTypeMapToBounds = new self($this->methodName, array_map(static function (\PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection $prototype) : \PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection { return $prototype->doNotResolveTemplateTypeMapToBounds(); }, $this->methodPrototypes)); } public function getNakedMethod() : ExtendedMethodReflection { return $this->getTransformedMethod(); } public function getTransformedMethod() : ExtendedMethodReflection { if ($this->transformedMethod !== null) { return $this->transformedMethod; } $methods = array_map(static function (\PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection $prototype) : MethodReflection { return $prototype->getTransformedMethod(); }, $this->methodPrototypes); return $this->transformedMethod = new \PHPStan\Reflection\Type\IntersectionTypeMethodReflection($this->methodName, $methods); } public function withCalledOnType(Type $type) : \PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection { return new self($this->methodName, array_map(static function (\PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection $prototype) use($type) : \PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection { return $prototype->withCalledOnType($type); }, $this->methodPrototypes)); } } propertyName = $propertyName; $this->propertyPrototypes = $propertyPrototypes; } public function doNotResolveTemplateTypeMapToBounds() : \PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection { if ($this->cachedDoNotResolveTemplateTypeMapToBounds !== null) { return $this->cachedDoNotResolveTemplateTypeMapToBounds; } return $this->cachedDoNotResolveTemplateTypeMapToBounds = new self($this->propertyName, array_map(static function (\PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection $prototype) : \PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection { return $prototype->doNotResolveTemplateTypeMapToBounds(); }, $this->propertyPrototypes)); } public function getNakedProperty() : ExtendedPropertyReflection { return $this->getTransformedProperty(); } public function getTransformedProperty() : ExtendedPropertyReflection { if ($this->transformedProperty !== null) { return $this->transformedProperty; } $properties = array_map(static function (\PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection $prototype) : PropertyReflection { return $prototype->getTransformedProperty(); }, $this->propertyPrototypes); return $this->transformedProperty = new \PHPStan\Reflection\Type\IntersectionTypePropertyReflection($properties); } public function withFechedOnType(Type $type) : \PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection { return new self($this->propertyName, array_map(static function (\PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection $prototype) use($type) : \PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection { return $prototype->withFechedOnType($type); }, $this->propertyPrototypes)); } } propertyName = $propertyName; $this->propertyPrototypes = $propertyPrototypes; } public function doNotResolveTemplateTypeMapToBounds() : \PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection { if ($this->cachedDoNotResolveTemplateTypeMapToBounds !== null) { return $this->cachedDoNotResolveTemplateTypeMapToBounds; } return $this->cachedDoNotResolveTemplateTypeMapToBounds = new self($this->propertyName, array_map(static function (\PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection $prototype) : \PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection { return $prototype->doNotResolveTemplateTypeMapToBounds(); }, $this->propertyPrototypes)); } public function getNakedProperty() : ExtendedPropertyReflection { return $this->getTransformedProperty(); } public function getTransformedProperty() : ExtendedPropertyReflection { if ($this->transformedProperty !== null) { return $this->transformedProperty; } $methods = array_map(static function (\PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection $prototype) : PropertyReflection { return $prototype->getTransformedProperty(); }, $this->propertyPrototypes); return $this->transformedProperty = new \PHPStan\Reflection\Type\UnionTypePropertyReflection($methods); } public function withFechedOnType(Type $type) : \PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection { return new self($this->propertyName, array_map(static function (\PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection $prototype) use($type) : \PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection { return $prototype->withFechedOnType($type); }, $this->propertyPrototypes)); } } methodReflection = $methodReflection; $this->resolvedDeclaringClass = $resolvedDeclaringClass; $this->resolveTemplateTypeMapToBounds = $resolveTemplateTypeMapToBounds; $this->transformStaticTypeCallback = $transformStaticTypeCallback; } public function doNotResolveTemplateTypeMapToBounds() : \PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection { if ($this->cachedDoNotResolveTemplateTypeMapToBounds !== null) { return $this->cachedDoNotResolveTemplateTypeMapToBounds; } return $this->cachedDoNotResolveTemplateTypeMapToBounds = new self($this->methodReflection, $this->resolvedDeclaringClass, \false, $this->transformStaticTypeCallback); } public function getNakedMethod() : ExtendedMethodReflection { return $this->methodReflection; } public function getTransformedMethod() : ExtendedMethodReflection { if ($this->transformedMethod !== null) { return $this->transformedMethod; } $templateTypeMap = $this->resolvedDeclaringClass->getActiveTemplateTypeMap(); $callSiteVarianceMap = $this->resolvedDeclaringClass->getCallSiteVarianceMap(); return $this->transformedMethod = new ResolvedMethodReflection($this->transformMethodWithStaticType($this->resolvedDeclaringClass, $this->methodReflection), $this->resolveTemplateTypeMapToBounds ? $templateTypeMap->resolveToBounds() : $templateTypeMap, $callSiteVarianceMap); } public function withCalledOnType(Type $type) : \PHPStan\Reflection\Type\UnresolvedMethodPrototypeReflection { return new \PHPStan\Reflection\Type\CalledOnTypeUnresolvedMethodPrototypeReflection($this->methodReflection, $this->resolvedDeclaringClass, $this->resolveTemplateTypeMapToBounds, $type); } private function transformMethodWithStaticType(ClassReflection $declaringClass, ExtendedMethodReflection $method) : ExtendedMethodReflection { $variantFn = function (ParametersAcceptorWithPhpDocs $acceptor) : ParametersAcceptorWithPhpDocs { return new FunctionVariantWithPhpDocs($acceptor->getTemplateTypeMap(), $acceptor->getResolvedTemplateTypeMap(), array_map(function (ParameterReflectionWithPhpDocs $parameter) : ParameterReflectionWithPhpDocs { return new DummyParameterWithPhpDocs($parameter->getName(), $this->transformStaticType($parameter->getType()), $parameter->isOptional(), $parameter->passedByReference(), $parameter->isVariadic(), $parameter->getDefaultValue(), $parameter->getNativeType(), $this->transformStaticType($parameter->getPhpDocType()), $parameter->getOutType() !== null ? $this->transformStaticType($parameter->getOutType()) : null, $parameter->isImmediatelyInvokedCallable(), $parameter->getClosureThisType() !== null ? $this->transformStaticType($parameter->getClosureThisType()) : null); }, $acceptor->getParameters()), $acceptor->isVariadic(), $this->transformStaticType($acceptor->getReturnType()), $this->transformStaticType($acceptor->getPhpDocReturnType()), $this->transformStaticType($acceptor->getNativeReturnType()), $acceptor->getCallSiteVarianceMap()); }; $variants = array_map($variantFn, $method->getVariants()); $namedArgumentVariants = $method->getNamedArgumentsVariants(); $namedArgumentVariants = $namedArgumentVariants !== null ? array_map($variantFn, $namedArgumentVariants) : null; return new ChangedTypeMethodReflection($declaringClass, $method, $variants, $namedArgumentVariants); } private function transformStaticType(Type $type) : Type { $callback = $this->transformStaticTypeCallback; return $callback($type); } } */ public function getParameters() : array; public function getPhpDocReturnType() : Type; public function getNativeReturnType() : Type; public function getCallSiteVarianceMap() : TemplateTypeVarianceMap; } $parameters * @param SimpleThrowPoint[] $throwPoints * @param SimpleImpurePoint[] $impurePoints * @param InvalidateExprNode[] $invalidateExpressions * @param string[] $usedVariables */ public function __construct(TemplateTypeMap $templateTypeMap, ?TemplateTypeMap $resolvedTemplateTypeMap, array $parameters, bool $isVariadic, Type $returnType, Type $phpDocReturnType, Type $nativeReturnType, ?TemplateTypeVarianceMap $callSiteVarianceMap, array $throwPoints, TrinaryLogic $isPure, array $impurePoints, array $invalidateExpressions, array $usedVariables, bool $acceptsNamedArguments) { $this->throwPoints = $throwPoints; $this->isPure = $isPure; $this->impurePoints = $impurePoints; $this->invalidateExpressions = $invalidateExpressions; $this->usedVariables = $usedVariables; $this->acceptsNamedArguments = $acceptsNamedArguments; parent::__construct($templateTypeMap, $resolvedTemplateTypeMap, $parameters, $isVariadic, $returnType, $phpDocReturnType, $nativeReturnType, $callSiteVarianceMap); } public function getThrowPoints() : array { return $this->throwPoints; } public function isPure() : TrinaryLogic { return $this->isPure; } public function getImpurePoints() : array { return $this->impurePoints; } public function getInvalidateExpressions() : array { return $this->invalidateExpressions; } public function getUsedVariables() : array { return $this->usedVariables; } public function acceptsNamedArguments() : bool { return $this->acceptsNamedArguments; } } getClass(stdClass::class); } public function isStatic() : bool { return \false; } public function isPrivate() : bool { return \false; } public function isPublic() : bool { return \true; } public function getReadableType() : Type { return new MixedType(); } public function getWritableType() : Type { return new MixedType(); } public function canChangeTypeAfterAssignment() : bool { return \true; } public function isReadable() : bool { return \true; } public function isWritable() : bool { return \true; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getDeprecatedDescription() : ?string { return null; } public function isInternal() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getDocComment() : ?string { return null; } } declaringClass = $declaringClass; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function isStatic() : bool { return \false; } public function isPrivate() : bool { return \false; } public function isPublic() : bool { return \true; } public function getName() : string { return '__construct'; } public function getPrototype() : ClassMemberReflection { return $this; } public function getVariants() : array { return [new FunctionVariantWithPhpDocs(TemplateTypeMap::createEmpty(), null, [], \false, new VoidType(), new MixedType(), new MixedType(), null)]; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { return $this->getVariants()[0]; } public function getNamedArgumentsVariants() : ?array { return null; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getDeprecatedDescription() : ?string { return null; } public function isFinal() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isInternal() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getThrowType() : ?Type { return null; } public function hasSideEffects() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDocComment() : ?string { return null; } public function getAsserts() : Assertions { return Assertions::createEmpty(); } public function acceptsNamedArguments() : bool { return $this->declaringClass->acceptsNamedArguments(); } public function getSelfOutType() : ?Type { return null; } public function returnsByReference() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFinalByKeyword() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isAbstract() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isPure() : TrinaryLogic { return TrinaryLogic::createYes(); } } name = $name; } public function getDeclaringClass() : ClassReflection { $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); return $reflectionProvider->getClass(stdClass::class); } public function isStatic() : bool { return \false; } public function isPrivate() : bool { return \false; } public function isPublic() : bool { return \true; } public function getName() : string { return $this->name; } public function getPrototype() : ClassMemberReflection { return $this; } public function getVariants() : array { return [new TrivialParametersAcceptor()]; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { return $this->getVariants()[0]; } public function getNamedArgumentsVariants() : ?array { return null; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getDeprecatedDescription() : ?string { return null; } public function isFinal() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isFinalByKeyword() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isInternal() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getThrowType() : ?Type { return null; } public function hasSideEffects() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getDocComment() : ?string { return null; } public function getAsserts() : Assertions { return Assertions::createEmpty(); } public function acceptsNamedArguments() : bool { return \true; } public function getSelfOutType() : ?Type { return null; } public function returnsByReference() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isAbstract() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isPure() : TrinaryLogic { return TrinaryLogic::createMaybe(); } } name = $name; } public function getDeclaringClass() : ClassReflection { $reflectionProvider = ReflectionProviderStaticAccessor::getInstance(); return $reflectionProvider->getClass(stdClass::class); } public function getFileName() : ?string { return null; } public function isStatic() : bool { return \true; } public function isPrivate() : bool { return \false; } public function isPublic() : bool { return \true; } public function getName() : string { return $this->name; } /** * @deprecated * @return mixed */ public function getValue() { // so that Scope::getTypeFromValue() returns mixed return new stdClass(); } public function getValueType() : Type { return new MixedType(); } public function getValueExpr() : Expr { return new TypeExpr(new MixedType()); } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getDeprecatedDescription() : ?string { return null; } public function isInternal() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getDocComment() : ?string { return null; } } declaringClass = $declaringClass; $this->reflection = $reflection; $this->readableType = $readableType; $this->writableType = $writableType; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function isStatic() : bool { return $this->reflection->isStatic(); } public function isPrivate() : bool { return $this->reflection->isPrivate(); } public function isPublic() : bool { return $this->reflection->isPublic(); } public function getDocComment() : ?string { return $this->reflection->getDocComment(); } public function getReadableType() : Type { return $this->readableType; } public function getWritableType() : Type { return $this->writableType; } public function canChangeTypeAfterAssignment() : bool { return $this->reflection->canChangeTypeAfterAssignment(); } public function isReadable() : bool { return $this->reflection->isReadable(); } public function isWritable() : bool { return $this->reflection->isWritable(); } public function isDeprecated() : TrinaryLogic { return $this->reflection->isDeprecated(); } public function getDeprecatedDescription() : ?string { return $this->reflection->getDeprecatedDescription(); } public function isInternal() : TrinaryLogic { return $this->reflection->isInternal(); } public function getOriginalReflection() : ExtendedPropertyReflection { return $this->reflection; } } declaringClass = $declaringClass; $this->reflection = $reflection; $this->variants = $variants; $this->namedArgumentsVariants = $namedArgumentsVariants; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function isStatic() : bool { return $this->reflection->isStatic(); } public function isPrivate() : bool { return $this->reflection->isPrivate(); } public function isPublic() : bool { return $this->reflection->isPublic(); } public function getDocComment() : ?string { return $this->reflection->getDocComment(); } public function getName() : string { return $this->reflection->getName(); } public function getPrototype() : ClassMemberReflection { return $this->reflection->getPrototype(); } public function getVariants() : array { return $this->variants; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { $variants = $this->getVariants(); if (count($variants) !== 1) { throw new ShouldNotHappenException(); } return $variants[0]; } public function getNamedArgumentsVariants() : ?array { return $this->namedArgumentsVariants; } public function isDeprecated() : TrinaryLogic { return $this->reflection->isDeprecated(); } public function getDeprecatedDescription() : ?string { return $this->reflection->getDeprecatedDescription(); } public function isFinal() : TrinaryLogic { return $this->reflection->isFinal(); } public function isFinalByKeyword() : TrinaryLogic { return $this->reflection->isFinalByKeyword(); } public function isInternal() : TrinaryLogic { return $this->reflection->isInternal(); } public function getThrowType() : ?Type { return $this->reflection->getThrowType(); } public function hasSideEffects() : TrinaryLogic { return $this->reflection->hasSideEffects(); } public function getAsserts() : Assertions { return $this->reflection->getAsserts(); } public function acceptsNamedArguments() : bool { return $this->reflection->acceptsNamedArguments(); } public function getSelfOutType() : ?Type { return $this->reflection->getSelfOutType(); } public function returnsByReference() : TrinaryLogic { return $this->reflection->returnsByReference(); } public function isAbstract() : TrinaryLogic { $abstract = $this->reflection->isAbstract(); if (is_bool($abstract)) { return TrinaryLogic::createFromBoolean($abstract); } return $abstract; } public function isPure() : TrinaryLogic { return $this->reflection->isPure(); } } reflection = $reflection; $this->templateTypeMap = $templateTypeMap; $this->callSiteVarianceMap = $callSiteVarianceMap; } public function getOriginalReflection() : \PHPStan\Reflection\ExtendedPropertyReflection { return $this->reflection; } public function getDeclaringClass() : \PHPStan\Reflection\ClassReflection { return $this->reflection->getDeclaringClass(); } public function getDeclaringTrait() : ?\PHPStan\Reflection\ClassReflection { if ($this->reflection instanceof PhpPropertyReflection) { return $this->reflection->getDeclaringTrait(); } return null; } public function isStatic() : bool { return $this->reflection->isStatic(); } public function isPrivate() : bool { return $this->reflection->isPrivate(); } public function isPublic() : bool { return $this->reflection->isPublic(); } public function getReadableType() : Type { $type = $this->readableType; if ($type !== null) { return $type; } $type = TemplateTypeHelper::resolveTemplateTypes($this->reflection->getReadableType(), $this->templateTypeMap, $this->callSiteVarianceMap, TemplateTypeVariance::createCovariant()); $type = TemplateTypeHelper::resolveTemplateTypes($type, $this->templateTypeMap, $this->callSiteVarianceMap, TemplateTypeVariance::createCovariant()); $this->readableType = $type; return $type; } public function getWritableType() : Type { $type = $this->writableType; if ($type !== null) { return $type; } $type = TemplateTypeHelper::resolveTemplateTypes($this->reflection->getWritableType(), $this->templateTypeMap, $this->callSiteVarianceMap, TemplateTypeVariance::createContravariant()); $type = TemplateTypeHelper::resolveTemplateTypes($type, $this->templateTypeMap, $this->callSiteVarianceMap, TemplateTypeVariance::createContravariant()); $this->writableType = $type; return $type; } public function canChangeTypeAfterAssignment() : bool { return $this->reflection->canChangeTypeAfterAssignment(); } public function isReadable() : bool { return $this->reflection->isReadable(); } public function isWritable() : bool { return $this->reflection->isWritable(); } public function getDocComment() : ?string { return $this->reflection->getDocComment(); } public function isDeprecated() : TrinaryLogic { return $this->reflection->isDeprecated(); } public function getDeprecatedDescription() : ?string { return $this->reflection->getDeprecatedDescription(); } public function isInternal() : TrinaryLogic { return $this->reflection->isInternal(); } } name = $name; $this->valueType = $valueType; $this->fileName = $fileName; $this->isDeprecated = $isDeprecated; $this->deprecatedDescription = $deprecatedDescription; } public function getName() : string { return $this->name; } public function getValueType() : Type { return $this->valueType; } public function getFileName() : ?string { return $this->fileName; } public function isDeprecated() : TrinaryLogic { return $this->isDeprecated; } public function getDeprecatedDescription() : ?string { return $this->deprecatedDescription; } public function isInternal() : TrinaryLogic { return TrinaryLogic::createNo(); } } callableName = $callableName; } public function getTemplateTypeMap() : TemplateTypeMap { return TemplateTypeMap::createEmpty(); } public function getResolvedTemplateTypeMap() : TemplateTypeMap { return TemplateTypeMap::createEmpty(); } public function getCallSiteVarianceMap() : TemplateTypeVarianceMap { return TemplateTypeVarianceMap::createEmpty(); } public function getParameters() : array { return []; } public function isVariadic() : bool { return \true; } public function getReturnType() : Type { return new MixedType(); } public function getPhpDocReturnType() : Type { return new MixedType(); } public function getNativeReturnType() : Type { return new MixedType(); } public function getThrowPoints() : array { return []; } public function isPure() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getImpurePoints() : array { return [new SimpleImpurePoint('functionCall', sprintf('call to a %s', $this->callableName), \false)]; } public function getInvalidateExpressions() : array { return []; } public function getUsedVariables() : array { return []; } public function acceptsNamedArguments() : bool { return \true; } } */ private $parameters; /** * @var bool */ private $isVariadic; /** * @var Type */ private $returnType; /** * @var TemplateTypeVarianceMap */ private $callSiteVarianceMap; /** * @api * @param array $parameters */ public function __construct(TemplateTypeMap $templateTypeMap, ?TemplateTypeMap $resolvedTemplateTypeMap, array $parameters, bool $isVariadic, Type $returnType, ?TemplateTypeVarianceMap $callSiteVarianceMap = null) { $this->templateTypeMap = $templateTypeMap; $this->resolvedTemplateTypeMap = $resolvedTemplateTypeMap; $this->parameters = $parameters; $this->isVariadic = $isVariadic; $this->returnType = $returnType; $this->callSiteVarianceMap = $callSiteVarianceMap ?? TemplateTypeVarianceMap::createEmpty(); } public function getTemplateTypeMap() : TemplateTypeMap { return $this->templateTypeMap; } public function getResolvedTemplateTypeMap() : TemplateTypeMap { return $this->resolvedTemplateTypeMap ?? TemplateTypeMap::createEmpty(); } public function getCallSiteVarianceMap() : TemplateTypeVarianceMap { return $this->callSiteVarianceMap; } /** * @return array */ public function getParameters() : array { return $this->parameters; } public function isVariadic() : bool { return $this->isVariadic; } public function getReturnType() : Type { return $this->returnType; } } method = $method; } public function getDeclaringClass() : \PHPStan\Reflection\ClassReflection { return $this->method->getDeclaringClass(); } public function isStatic() : bool { return $this->method->isStatic(); } public function isPrivate() : bool { return $this->method->isPrivate(); } public function isPublic() : bool { return $this->method->isPublic(); } public function getDocComment() : ?string { return $this->method->getDocComment(); } public function getName() : string { return $this->method->getName(); } public function getPrototype() : \PHPStan\Reflection\ClassMemberReflection { return $this->method->getPrototype(); } public function getVariants() : array { $variants = []; foreach ($this->method->getVariants() as $variant) { if ($variant instanceof \PHPStan\Reflection\ParametersAcceptorWithPhpDocs) { $variants[] = $variant; continue; } $variants[] = new \PHPStan\Reflection\FunctionVariantWithPhpDocs($variant->getTemplateTypeMap(), $variant->getResolvedTemplateTypeMap(), array_map(static function (\PHPStan\Reflection\ParameterReflection $parameter) : \PHPStan\Reflection\ParameterReflectionWithPhpDocs { return $parameter instanceof \PHPStan\Reflection\ParameterReflectionWithPhpDocs ? $parameter : new DummyParameterWithPhpDocs($parameter->getName(), $parameter->getType(), $parameter->isOptional(), $parameter->passedByReference(), $parameter->isVariadic(), $parameter->getDefaultValue(), new MixedType(), $parameter->getType(), null, TrinaryLogic::createMaybe(), null); }, $variant->getParameters()), $variant->isVariadic(), $variant->getReturnType(), $variant->getReturnType(), new MixedType(), TemplateTypeVarianceMap::createEmpty()); } return $variants; } public function getOnlyVariant() : \PHPStan\Reflection\ParametersAcceptorWithPhpDocs { return $this->getVariants()[0]; } public function getNamedArgumentsVariants() : ?array { return null; } public function isDeprecated() : TrinaryLogic { return $this->method->isDeprecated(); } public function getDeprecatedDescription() : ?string { return $this->method->getDeprecatedDescription(); } public function isFinal() : TrinaryLogic { return $this->method->isFinal(); } public function isFinalByKeyword() : TrinaryLogic { return $this->isFinal(); } public function isInternal() : TrinaryLogic { return $this->method->isInternal(); } public function getThrowType() : ?Type { return $this->method->getThrowType(); } public function hasSideEffects() : TrinaryLogic { return $this->method->hasSideEffects(); } public function isPure() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getAsserts() : \PHPStan\Reflection\Assertions { return \PHPStan\Reflection\Assertions::createEmpty(); } public function acceptsNamedArguments() : bool { return $this->getDeclaringClass()->acceptsNamedArguments(); } public function getSelfOutType() : ?Type { return null; } public function returnsByReference() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isAbstract() : TrinaryLogic { return TrinaryLogic::createNo(); } } methods[$classReflection->getCacheKey()][$methodName])) { $method = $this->findClassReflectionWithMethod($classReflection, $classReflection, $methodName); if ($method === null) { return \false; } $this->methods[$classReflection->getCacheKey()][$methodName] = $method; } return isset($this->methods[$classReflection->getCacheKey()][$methodName]); } /** * @return ExtendedMethodReflection */ public function getMethod(ClassReflection $classReflection, string $methodName) : MethodReflection { return $this->methods[$classReflection->getCacheKey()][$methodName]; } private function findClassReflectionWithMethod(ClassReflection $classReflection, ClassReflection $declaringClass, string $methodName) : ?ExtendedMethodReflection { $methodTags = $classReflection->getMethodTags(); if (isset($methodTags[$methodName])) { $parameters = []; foreach ($methodTags[$methodName]->getParameters() as $parameterName => $parameterTag) { $parameters[] = new \PHPStan\Reflection\Annotations\AnnotationsMethodParameterReflection($parameterName, $parameterTag->getType(), $parameterTag->passedByReference(), $parameterTag->isOptional(), $parameterTag->isVariadic(), $parameterTag->getDefaultValue()); } $templateTypeScope = TemplateTypeScope::createWithClass($classReflection->getName()); $templateTypeMap = new TemplateTypeMap(array_map(static function (TemplateTag $tag) use($templateTypeScope) : Type { return TemplateTypeFactory::fromTemplateTag($templateTypeScope, $tag); }, $methodTags[$methodName]->getTemplateTags())); $isStatic = $methodTags[$methodName]->isStatic(); $nativeCallMethodName = $isStatic ? '__callStatic' : '__call'; return new \PHPStan\Reflection\Annotations\AnnotationMethodReflection($methodName, $declaringClass, TemplateTypeHelper::resolveTemplateTypes($methodTags[$methodName]->getReturnType(), $classReflection->getActiveTemplateTypeMap(), $classReflection->getCallSiteVarianceMap(), TemplateTypeVariance::createCovariant()), $parameters, $isStatic, $this->detectMethodVariadic($parameters), $classReflection->hasNativeMethod($nativeCallMethodName) ? $classReflection->getNativeMethod($nativeCallMethodName)->getThrowType() : null, $templateTypeMap); } foreach ($classReflection->getTraits() as $traitClass) { $methodWithDeclaringClass = $this->findClassReflectionWithMethod($traitClass, $classReflection, $methodName); if ($methodWithDeclaringClass === null) { continue; } return $methodWithDeclaringClass; } $parentClass = $classReflection->getParentClass(); while ($parentClass !== null) { $methodWithDeclaringClass = $this->findClassReflectionWithMethod($parentClass, $parentClass, $methodName); if ($methodWithDeclaringClass !== null) { return $methodWithDeclaringClass; } $parentClass = $parentClass->getParentClass(); } foreach ($classReflection->getInterfaces() as $interfaceClass) { $methodWithDeclaringClass = $this->findClassReflectionWithMethod($interfaceClass, $interfaceClass, $methodName); if ($methodWithDeclaringClass === null) { continue; } return $methodWithDeclaringClass; } return null; } /** * @param AnnotationsMethodParameterReflection[] $parameters */ private function detectMethodVariadic(array $parameters) : bool { if ($parameters === []) { return \false; } $possibleVariadicParameterIndex = count($parameters) - 1; $possibleVariadicParameter = $parameters[$possibleVariadicParameterIndex]; return $possibleVariadicParameter->isVariadic(); } } name = $name; $this->declaringClass = $declaringClass; $this->returnType = $returnType; $this->parameters = $parameters; $this->isStatic = $isStatic; $this->isVariadic = $isVariadic; $this->throwType = $throwType; $this->templateTypeMap = $templateTypeMap; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function getPrototype() : ClassMemberReflection { return $this; } public function isStatic() : bool { return $this->isStatic; } public function isPrivate() : bool { return \false; } public function isPublic() : bool { return \true; } public function getName() : string { return $this->name; } public function getVariants() : array { if ($this->variants === null) { $this->variants = [new FunctionVariantWithPhpDocs($this->templateTypeMap, null, $this->parameters, $this->isVariadic, $this->returnType, $this->returnType, new MixedType())]; } return $this->variants; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { return $this->getVariants()[0]; } public function getNamedArgumentsVariants() : ?array { return null; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDeprecatedDescription() : ?string { return null; } public function isFinal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFinalByKeyword() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInternal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getThrowType() : ?Type { return $this->throwType; } public function hasSideEffects() : TrinaryLogic { if ($this->returnType->isVoid()->yes()) { return TrinaryLogic::createYes(); } if ((new ThisType($this->declaringClass))->isSuperTypeOf($this->returnType)->yes()) { return TrinaryLogic::createYes(); } return TrinaryLogic::createMaybe(); } public function getDocComment() : ?string { return null; } public function getAsserts() : Assertions { return Assertions::createEmpty(); } public function acceptsNamedArguments() : bool { return $this->declaringClass->acceptsNamedArguments(); } public function getSelfOutType() : ?Type { return null; } public function returnsByReference() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function isAbstract() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isPure() : TrinaryLogic { if ($this->hasSideEffects()->yes()) { return TrinaryLogic::createNo(); } return TrinaryLogic::createMaybe(); } } declaringClass = $declaringClass; $this->readableType = $readableType; $this->writableType = $writableType; $this->readable = $readable; $this->writable = $writable; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function isStatic() : bool { return \false; } public function isPrivate() : bool { return \false; } public function isPublic() : bool { return \true; } public function getReadableType() : Type { return $this->readableType; } public function getWritableType() : Type { return $this->writableType; } public function canChangeTypeAfterAssignment() : bool { return $this->readableType->equals($this->writableType); } public function isReadable() : bool { return $this->readable; } public function isWritable() : bool { return $this->writable; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDeprecatedDescription() : ?string { return null; } public function isInternal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDocComment() : ?string { return null; } } properties[$classReflection->getCacheKey()][$propertyName])) { $property = $this->findClassReflectionWithProperty($classReflection, $classReflection, $propertyName); if ($property === null) { return \false; } $this->properties[$classReflection->getCacheKey()][$propertyName] = $property; } return isset($this->properties[$classReflection->getCacheKey()][$propertyName]); } /** * @return ExtendedPropertyReflection */ public function getProperty(ClassReflection $classReflection, string $propertyName) : PropertyReflection { return $this->properties[$classReflection->getCacheKey()][$propertyName]; } private function findClassReflectionWithProperty(ClassReflection $classReflection, ClassReflection $declaringClass, string $propertyName) : ?ExtendedPropertyReflection { $propertyTags = $classReflection->getPropertyTags(); if (isset($propertyTags[$propertyName])) { $propertyTag = $propertyTags[$propertyName]; $isReadable = $propertyTags[$propertyName]->isReadable(); $isWritable = $propertyTags[$propertyName]->isWritable(); if ($classReflection->hasNativeProperty($propertyName)) { $nativeProperty = $classReflection->getNativeProperty($propertyName); $isReadable = $isReadable || $nativeProperty->isReadable(); $isWritable = $isWritable || $nativeProperty->isWritable(); } return new \PHPStan\Reflection\Annotations\AnnotationPropertyReflection($declaringClass, TemplateTypeHelper::resolveTemplateTypes($propertyTag->getReadableType() ?? new NeverType(), $classReflection->getActiveTemplateTypeMap(), $classReflection->getCallSiteVarianceMap(), TemplateTypeVariance::createCovariant()), TemplateTypeHelper::resolveTemplateTypes($propertyTag->getWritableType() ?? new NeverType(), $classReflection->getActiveTemplateTypeMap(), $classReflection->getCallSiteVarianceMap(), TemplateTypeVariance::createContravariant()), $isReadable, $isWritable); } foreach ($classReflection->getTraits() as $traitClass) { $methodWithDeclaringClass = $this->findClassReflectionWithProperty($traitClass, $classReflection, $propertyName); if ($methodWithDeclaringClass === null) { continue; } return $methodWithDeclaringClass; } $parentClass = $classReflection->getParentClass(); while ($parentClass !== null) { $methodWithDeclaringClass = $this->findClassReflectionWithProperty($parentClass, $parentClass, $propertyName); if ($methodWithDeclaringClass !== null) { return $methodWithDeclaringClass; } $parentClass = $parentClass->getParentClass(); } foreach ($classReflection->getInterfaces() as $interfaceClass) { $methodWithDeclaringClass = $this->findClassReflectionWithProperty($interfaceClass, $interfaceClass, $propertyName); if ($methodWithDeclaringClass === null) { continue; } return $methodWithDeclaringClass; } return null; } } name = $name; $this->type = $type; $this->passedByReference = $passedByReference; $this->isOptional = $isOptional; $this->isVariadic = $isVariadic; $this->defaultValue = $defaultValue; } public function getName() : string { return $this->name; } public function isOptional() : bool { return $this->isOptional; } public function getType() : Type { return $this->type; } public function getPhpDocType() : Type { return $this->type; } public function getNativeType() : Type { return new MixedType(); } public function getOutType() : ?Type { return null; } public function isImmediatelyInvokedCallable() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getClosureThisType() : ?Type { return null; } public function passedByReference() : PassedByReference { return $this->passedByReference; } public function isVariadic() : bool { return $this->isVariadic; } public function getDefaultValue() : ?Type { return $this->defaultValue; } } propertiesClassReflectionExtensions = $propertiesClassReflectionExtensions; $this->methodsClassReflectionExtensions = $methodsClassReflectionExtensions; $this->allowedSubTypesClassReflectionExtensions = $allowedSubTypesClassReflectionExtensions; $this->requireExtendsPropertiesClassReflectionExtension = $requireExtendsPropertiesClassReflectionExtension; $this->requireExtendsMethodsClassReflectionExtension = $requireExtendsMethodsClassReflectionExtension; foreach (array_merge($propertiesClassReflectionExtensions, $methodsClassReflectionExtensions, $allowedSubTypesClassReflectionExtensions) as $extension) { if (!$extension instanceof \PHPStan\Reflection\BrokerAwareExtension) { continue; } $extension->setBroker($broker); } } /** * @return PropertiesClassReflectionExtension[] */ public function getPropertiesClassReflectionExtensions() : array { return $this->propertiesClassReflectionExtensions; } /** * @return MethodsClassReflectionExtension[] */ public function getMethodsClassReflectionExtensions() : array { return $this->methodsClassReflectionExtensions; } /** * @return AllowedSubTypesClassReflectionExtension[] */ public function getAllowedSubTypesClassReflectionExtensions() : array { return $this->allowedSubTypesClassReflectionExtensions; } public function getRequireExtendsPropertyClassReflectionExtension() : RequireExtendsPropertiesClassReflectionExtension { return $this->requireExtendsPropertiesClassReflectionExtension; } public function getRequireExtendsMethodsClassReflectionExtension() : RequireExtendsMethodsClassReflectionExtension { return $this->requireExtendsMethodsClassReflectionExtension; } } property = $property; } public function getDeclaringClass() : \PHPStan\Reflection\ClassReflection { return $this->property->getDeclaringClass(); } public function isStatic() : bool { return $this->property->isStatic(); } public function isPrivate() : bool { return $this->property->isPrivate(); } public function isPublic() : bool { return $this->property->isPublic(); } public function getDocComment() : ?string { return $this->property->getDocComment(); } public function getReadableType() : Type { return $this->property->getReadableType(); } public function getWritableType() : Type { return $this->property->getWritableType(); } public function canChangeTypeAfterAssignment() : bool { return $this->property->canChangeTypeAfterAssignment(); } public function isReadable() : bool { return $this->property->isReadable(); } public function isWritable() : bool { return $this->property->isWritable(); } public function isDeprecated() : TrinaryLogic { return $this->property->isDeprecated(); } public function getDeprecatedDescription() : ?string { return $this->property->getDeprecatedDescription(); } public function isInternal() : TrinaryLogic { return $this->property->isInternal(); } } phpVersion = $phpVersion; $this->className = $className; $this->methodName = $methodName; } public function getClass() : string { return $this->className; } public function isMethodSupported(MethodReflection $methodReflection) : bool { return $methodReflection->getName() === $this->methodName; } public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope) : ?Type { if ($this->phpVersion->getVersionId() >= 80000) { return null; } return new ObjectType(ReflectionClass::class); } } parametersAcceptor = $parametersAcceptor; $this->throwPoints = $throwPoints; $this->isPure = $isPure; $this->impurePoints = $impurePoints; $this->invalidateExpressions = $invalidateExpressions; $this->usedVariables = $usedVariables; $this->acceptsNamedArguments = $acceptsNamedArguments; } public function getOriginalParametersAcceptor() : \PHPStan\Reflection\ParametersAcceptor { return $this->parametersAcceptor->getOriginalParametersAcceptor(); } public function getTemplateTypeMap() : TemplateTypeMap { return $this->parametersAcceptor->getTemplateTypeMap(); } public function getResolvedTemplateTypeMap() : TemplateTypeMap { return $this->parametersAcceptor->getResolvedTemplateTypeMap(); } public function getCallSiteVarianceMap() : TemplateTypeVarianceMap { return $this->parametersAcceptor->getCallSiteVarianceMap(); } public function getParameters() : array { return $this->parametersAcceptor->getParameters(); } public function isVariadic() : bool { return $this->parametersAcceptor->isVariadic(); } public function getReturnTypeWithUnresolvableTemplateTypes() : Type { return $this->parametersAcceptor->getReturnTypeWithUnresolvableTemplateTypes(); } public function getPhpDocReturnTypeWithUnresolvableTemplateTypes() : Type { return $this->parametersAcceptor->getPhpDocReturnTypeWithUnresolvableTemplateTypes(); } public function getReturnType() : Type { return $this->parametersAcceptor->getReturnType(); } public function getPhpDocReturnType() : Type { return $this->parametersAcceptor->getPhpDocReturnType(); } public function getNativeReturnType() : Type { return $this->parametersAcceptor->getNativeReturnType(); } public function getThrowPoints() : array { return $this->throwPoints; } public function isPure() : TrinaryLogic { return $this->isPure; } public function getImpurePoints() : array { return $this->impurePoints; } public function getInvalidateExpressions() : array { return $this->invalidateExpressions; } public function getUsedVariables() : array { return $this->usedVariables; } public function acceptsNamedArguments() : bool { return $this->acceptsNamedArguments; } } methodReflection = $methodReflection; } public function getMethod() : \PHPStan\Reflection\ExtendedMethodReflection { return $this->methodReflection; } public function getTemplateTypeMap() : TemplateTypeMap { return TemplateTypeMap::createEmpty(); } public function getResolvedTemplateTypeMap() : TemplateTypeMap { return TemplateTypeMap::createEmpty(); } public function getCallSiteVarianceMap() : TemplateTypeVarianceMap { return TemplateTypeVarianceMap::createEmpty(); } /** * @return array */ public function getParameters() : array { return []; } public function isVariadic() : bool { return \true; } public function getReturnType() : Type { return new MixedType(); } public function getThrowPoints() : array { return []; } public function isPure() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getImpurePoints() : array { return [new SimpleImpurePoint('methodCall', 'call to unknown method', \false)]; } public function getInvalidateExpressions() : array { return []; } public function getUsedVariables() : array { return []; } public function acceptsNamedArguments() : bool { return $this->methodReflection->acceptsNamedArguments(); } } >> */ private $classNodes; /** * @var array>> */ private $functionNodes; /** * @var array>> */ private $constantNodes; /** * @param array>> $classNodes * @param array>> $functionNodes * @param array>> $constantNodes */ public function __construct(array $classNodes, array $functionNodes, array $constantNodes) { $this->classNodes = $classNodes; $this->functionNodes = $functionNodes; $this->constantNodes = $constantNodes; } /** * @return array>> */ public function getClassNodes() : array { return $this->classNodes; } /** * @return array>> */ public function getFunctionNodes() : array { return $this->functionNodes; } /** * @return array>> */ public function getConstantNodes() : array { return $this->constantNodes; } } */ private $locators = []; public function __construct(PsrAutoloaderMapping $mapping, \PHPStan\Reflection\BetterReflection\SourceLocator\OptimizedSingleFileSourceLocatorRepository $optimizedSingleFileSourceLocatorRepository) { $this->mapping = $mapping; $this->optimizedSingleFileSourceLocatorRepository = $optimizedSingleFileSourceLocatorRepository; } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?Reflection { foreach ($this->locators as $locator) { $reflection = $locator->locateIdentifier($reflector, $identifier); if ($reflection === null) { continue; } return $reflection; } foreach ($this->mapping->resolvePossibleFilePaths($identifier) as $file) { if (!is_file($file)) { continue; } $locator = $this->optimizedSingleFileSourceLocatorRepository->getOrCreate($file); $reflection = $locator->locateIdentifier($reflector, $identifier); if ($reflection === null) { continue; } $this->locators[$file] = $locator; return $reflection; } return null; } /** * @return list */ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return []; } } |null */ private $classToFile = null; /** @var array|null */ private $constantToFile = null; /** @var array>|null */ private $functionToFiles = null; /** * @param string[] $files */ public function __construct(\PHPStan\Reflection\BetterReflection\SourceLocator\FileNodesFetcher $fileNodesFetcher, PhpVersion $phpVersion, array $files) { $this->fileNodesFetcher = $fileNodesFetcher; $this->phpVersion = $phpVersion; $this->files = $files; $this->extraTypes = $this->phpVersion->supportsEnums() ? '|enum' : ''; $this->cleaner = new \PHPStan\Reflection\BetterReflection\SourceLocator\PhpFileCleaner(); } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?Reflection { if ($identifier->isClass()) { $className = strtolower($identifier->getName()); $file = $this->findFileByClass($className); if ($file === null) { return null; } $fetchedClassNodes = $this->fileNodesFetcher->fetchNodes($file)->getClassNodes(); if (!array_key_exists($className, $fetchedClassNodes)) { return null; } /** @var FetchedNode $fetchedClassNode */ $fetchedClassNode = current($fetchedClassNodes[$className]); return $this->nodeToReflection($reflector, $fetchedClassNode); } if ($identifier->isFunction()) { $functionName = strtolower($identifier->getName()); $files = $this->findFilesByFunction($functionName); $fetchedFunctionNode = null; foreach ($files as $file) { $fetchedFunctionNodes = $this->fileNodesFetcher->fetchNodes($file)->getFunctionNodes(); if (!array_key_exists($functionName, $fetchedFunctionNodes)) { continue; } /** @var FetchedNode $fetchedFunctionNode */ $fetchedFunctionNode = current($fetchedFunctionNodes[$functionName]); } if ($fetchedFunctionNode === null) { return null; } return $this->nodeToReflection($reflector, $fetchedFunctionNode); } if ($identifier->isConstant()) { $constantName = ConstantNameHelper::normalize($identifier->getName()); $file = $this->findFileByConstant($constantName); if ($file === null) { return null; } $fetchedConstantNodes = $this->fileNodesFetcher->fetchNodes($file)->getConstantNodes(); if (!array_key_exists($constantName, $fetchedConstantNodes)) { return null; } /** @var FetchedNode $fetchedConstantNode */ $fetchedConstantNode = current($fetchedConstantNodes[$constantName]); return $this->nodeToReflection($reflector, $fetchedConstantNode, $this->findConstantPositionInConstNode($fetchedConstantNode->getNode(), $constantName)); } return null; } /** * @param FetchedNode|FetchedNode|FetchedNode $fetchedNode */ private function nodeToReflection(Reflector $reflector, \PHPStan\Reflection\BetterReflection\SourceLocator\FetchedNode $fetchedNode, ?int $positionInNode = null) : Reflection { $nodeToReflection = new NodeToReflection(); return $nodeToReflection->__invoke($reflector, $fetchedNode->getNode(), $fetchedNode->getLocatedSource(), $fetchedNode->getNamespace(), $positionInNode); } private function findFileByClass(string $className) : ?string { if ($this->classToFile === null) { $this->init(); if ($this->classToFile === null) { throw new ShouldNotHappenException(); } } if (!array_key_exists($className, $this->classToFile)) { return null; } return $this->classToFile[$className]; } private function findFileByConstant(string $constantName) : ?string { if ($this->constantToFile === null) { $this->init(); if ($this->constantToFile === null) { throw new ShouldNotHappenException(); } } if (!array_key_exists($constantName, $this->constantToFile)) { return null; } return $this->constantToFile[$constantName]; } /** * @return string[] */ private function findFilesByFunction(string $functionName) : array { if ($this->functionToFiles === null) { $this->init(); if ($this->functionToFiles === null) { throw new ShouldNotHappenException(); } } if (!array_key_exists($functionName, $this->functionToFiles)) { return []; } return $this->functionToFiles[$functionName]; } private function init() : void { $classToFile = []; $constantToFile = []; $functionToFiles = []; foreach ($this->files as $file) { $symbols = $this->findSymbols($file); foreach ($symbols['classes'] as $classInFile) { $classToFile[$classInFile] = $file; } foreach ($symbols['constants'] as $constantInFile) { $constantToFile[$constantInFile] = $file; } foreach ($symbols['functions'] as $functionInFile) { if (!array_key_exists($functionInFile, $functionToFiles)) { $functionToFiles[$functionInFile] = []; } $functionToFiles[$functionInFile][] = $file; } } $this->classToFile = $classToFile; $this->functionToFiles = $functionToFiles; $this->constantToFile = $constantToFile; } /** * Inspired by Composer\Autoload\ClassMapGenerator::findClasses() * @link https://github.com/composer/composer/blob/45d3e133a4691eccb12e9cd6f9dfd76eddc1906d/src/Composer/Autoload/ClassMapGenerator.php#L216 * * @return array{classes: string[], functions: string[], constants: string[]} */ private function findSymbols(string $file) : array { $contents = @php_strip_whitespace($file); if ($contents === '') { return ['classes' => [], 'functions' => [], 'constants' => []]; } $matchResults = (bool) preg_match_all(sprintf('{\\b(?:(?:class|interface|trait|const|function%s)\\s)|(?:define\\s*\\()}i', $this->extraTypes), $contents, $matches); if (!$matchResults) { return ['classes' => [], 'functions' => [], 'constants' => []]; } $contents = $this->cleaner->clean($contents, count($matches[0])); preg_match_all(sprintf('{ (?: \\b(?])(?: (?: (?Pclass|interface|trait%s) \\s++ (?P[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\-]*+) ) | (?: (?Pfunction) \\s++ (?:&\\s*)? (?P[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\-]*+) \\s*+ [&\\(] ) | (?: (?Pconst) \\s++ (?P[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\-]*+) \\s*+ [^;] ) | (?: (?:\\\\)? (?Pdefine) \\s*+ \\( \\s*+ [\'"] (?P[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+(?:[\\\\]{1,2}[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+)*+) ) | (?: (?Pnamespace) (?P\\s++[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+(?:\\s*+\\\\\\s*+[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+)*+)? \\s*+ [\\{;] ) ) ) }ix', $this->extraTypes), $contents, $matches); $classes = []; $functions = []; $constants = []; $namespace = ''; for ($i = 0, $len = count($matches['type']); $i < $len; $i++) { if (isset($matches['ns'][$i]) && $matches['ns'][$i] !== '') { $namespace = preg_replace('~\\s+~', '', strtolower($matches['nsname'][$i])) . '\\'; continue; } if ($matches['function'][$i] !== '') { $functions[] = strtolower(ltrim($namespace . $matches['fname'][$i], '\\')); continue; } if ($matches['constant'][$i] !== '') { $constants[] = ConstantNameHelper::normalize(ltrim($namespace . $matches['cname'][$i], '\\')); } if ($matches['define'][$i] !== '') { $constants[] = ConstantNameHelper::normalize($matches['dname'][$i]); continue; } $name = $matches['name'][$i]; // skip anon classes extending/implementing if (in_array($name, ['extends', 'implements'], \true)) { continue; } $classes[] = strtolower(ltrim($namespace . $name, '\\')); } return ['classes' => $classes, 'functions' => $functions, 'constants' => $constants]; } /** * @return list */ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { if ($this->classToFile === null || $this->functionToFiles === null || $this->constantToFile === null) { $this->init(); if ($this->classToFile === null || $this->functionToFiles === null || $this->constantToFile === null) { throw new ShouldNotHappenException(); } } $reflections = []; if ($identifierType->isClass()) { foreach ($this->classToFile as $file) { $fetchedNodesResult = $this->fileNodesFetcher->fetchNodes($file); foreach ($fetchedNodesResult->getClassNodes() as $identifierName => $fetchedClassNodes) { foreach ($fetchedClassNodes as $fetchedClassNode) { $reflections[$identifierName] = $this->nodeToReflection($reflector, $fetchedClassNode); } } } } elseif ($identifierType->isFunction()) { foreach ($this->functionToFiles as $files) { foreach ($files as $file) { $fetchedNodesResult = $this->fileNodesFetcher->fetchNodes($file); foreach ($fetchedNodesResult->getFunctionNodes() as $identifierName => $fetchedFunctionNodes) { foreach ($fetchedFunctionNodes as $fetchedFunctionNode) { $reflections[$identifierName] = $this->nodeToReflection($reflector, $fetchedFunctionNode); continue 2; } } } } } elseif ($identifierType->isConstant()) { foreach ($this->constantToFile as $file) { $fetchedNodesResult = $this->fileNodesFetcher->fetchNodes($file); foreach ($fetchedNodesResult->getConstantNodes() as $identifierName => $fetchedConstantNodes) { foreach ($fetchedConstantNodes as $fetchedConstantNode) { $reflections[$identifierName] = $this->nodeToReflection($reflector, $fetchedConstantNode, $this->findConstantPositionInConstNode($fetchedConstantNode->getNode(), $identifierName)); } } } } return array_values($reflections); } /** * @param Node\Stmt\Const_|Node\Expr\FuncCall $constantNode */ private function findConstantPositionInConstNode($constantNode, string $constantName) : ?int { if ($constantNode instanceof Node\Expr\FuncCall) { return null; } /** @var int $position */ foreach ($constantNode->consts as $position => $const) { if ($const->namespacedName === null) { throw new ShouldNotHappenException(); } if (ConstantNameHelper::normalize($const->namespacedName->toString()) === $constantName) { return $position; } } throw new ShouldNotHappenException(); } } cachingVisitor = $cachingVisitor; $this->parser = $parser; } public function fetchNodes(string $fileName) : \PHPStan\Reflection\BetterReflection\SourceLocator\FetchedNodesResult { $nodeTraverser = new NodeTraverser(); $nodeTraverser->addVisitor($this->cachingVisitor); $contents = FileReader::read($fileName); try { $ast = $this->parser->parseFile($fileName); } catch (ParserErrorsException $e) { return new \PHPStan\Reflection\BetterReflection\SourceLocator\FetchedNodesResult([], [], []); } $this->cachingVisitor->reset($fileName, $contents); $nodeTraverser->traverse($ast); $result = new \PHPStan\Reflection\BetterReflection\SourceLocator\FetchedNodesResult($this->cachingVisitor->getClassNodes(), $this->cachingVisitor->getFunctionNodes(), $this->cachingVisitor->getConstantNodes()); $this->cachingVisitor->reset($fileName, $contents); return $result; } } fileNodesFetcher = $fileNodesFetcher; $this->fileFinder = $fileFinder; $this->phpVersion = $phpVersion; $this->cache = $cache; $this->extraTypes = $this->phpVersion->supportsEnums() ? '|enum' : ''; $this->cleaner = new \PHPStan\Reflection\BetterReflection\SourceLocator\PhpFileCleaner(); } public function createByDirectory(string $directory) : \PHPStan\Reflection\BetterReflection\SourceLocator\NewOptimizedDirectorySourceLocator { $files = $this->fileFinder->findFiles([$directory])->getFiles(); $fileHashes = []; foreach ($files as $file) { $hash = sha1_file($file); if ($hash === \false) { continue; } $fileHashes[$file] = $hash; } $cacheKey = sprintf('odsl-%s', $directory); $variableCacheKey = 'v1'; /** @var array|null $cached */ $cached = $this->cache->load($cacheKey, $variableCacheKey); if ($cached !== null) { foreach ($cached as $file => [$hash, $classes, $functions, $constants]) { if (!array_key_exists($file, $fileHashes)) { unset($cached[$file]); continue; } $newHash = $fileHashes[$file]; unset($fileHashes[$file]); if ($hash === $newHash) { continue; } [$newClasses, $newFunctions, $newConstants] = $this->findSymbols($file); $cached[$file] = [$newHash, $newClasses, $newFunctions, $newConstants]; } } else { $cached = []; } foreach ($fileHashes as $file => $newHash) { [$newClasses, $newFunctions, $newConstants] = $this->findSymbols($file); $cached[$file] = [$newHash, $newClasses, $newFunctions, $newConstants]; } $this->cache->save($cacheKey, $variableCacheKey, $cached); [$classToFile, $functionToFiles, $constantToFile] = $this->changeStructure($cached); return new \PHPStan\Reflection\BetterReflection\SourceLocator\NewOptimizedDirectorySourceLocator($this->fileNodesFetcher, $classToFile, $functionToFiles, $constantToFile); } /** * @param string[] $files */ public function createByFiles(array $files) : \PHPStan\Reflection\BetterReflection\SourceLocator\NewOptimizedDirectorySourceLocator { $symbols = []; foreach ($files as $file) { [$newClasses, $newFunctions, $newConstants] = $this->findSymbols($file); $symbols[$file] = ['', $newClasses, $newFunctions, $newConstants]; } [$classToFile, $functionToFiles, $constantToFile] = $this->changeStructure($symbols); return new \PHPStan\Reflection\BetterReflection\SourceLocator\NewOptimizedDirectorySourceLocator($this->fileNodesFetcher, $classToFile, $functionToFiles, $constantToFile); } /** * @param array $symbols * @return array{array, array>, array} */ private function changeStructure(array $symbols) : array { $classToFile = []; $constantToFile = []; $functionToFiles = []; foreach ($symbols as $file => [, $classes, $functions, $constants]) { foreach ($classes as $classInFile) { $classToFile[$classInFile] = $file; } foreach ($functions as $functionInFile) { if (!array_key_exists($functionInFile, $functionToFiles)) { $functionToFiles[$functionInFile] = []; } $functionToFiles[$functionInFile][] = $file; } foreach ($constants as $constantInFile) { $constantToFile[$constantInFile] = $file; } } return [$classToFile, $functionToFiles, $constantToFile]; } /** * Inspired by Composer\Autoload\ClassMapGenerator::findClasses() * @link https://github.com/composer/composer/blob/45d3e133a4691eccb12e9cd6f9dfd76eddc1906d/src/Composer/Autoload/ClassMapGenerator.php#L216 * * @return array{string[], string[], string[]} */ private function findSymbols(string $file) : array { $contents = @php_strip_whitespace($file); if ($contents === '') { return [[], [], []]; } $matchResults = (bool) preg_match_all(sprintf('{\\b(?:(?:class|interface|trait|const|function%s)\\s)|(?:define\\s*\\()}i', $this->extraTypes), $contents, $matches); if (!$matchResults) { return [[], [], []]; } $contents = $this->cleaner->clean($contents, count($matches[0])); preg_match_all(sprintf('{ (?: \\b(?])(?: (?: (?Pclass|interface|trait%s) \\s++ (?P[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\-]*+) ) | (?: (?Pfunction) \\s++ (?:&\\s*)? (?P[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\-]*+) \\s*+ [&\\(] ) | (?: (?Pconst) \\s++ (?P[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\-]*+) \\s*+ [^;] ) | (?: (?:\\\\)? (?Pdefine) \\s*+ \\( \\s*+ [\'"] (?P[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+(?:[\\\\]{1,2}[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+)*+) ) | (?: (?Pnamespace) (?P\\s++[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+(?:\\s*+\\\\\\s*+[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+)*+)? \\s*+ [\\{;] ) ) ) }ix', $this->extraTypes), $contents, $matches); $classes = []; $functions = []; $constants = []; $namespace = ''; for ($i = 0, $len = count($matches['type']); $i < $len; $i++) { if (isset($matches['ns'][$i]) && $matches['ns'][$i] !== '') { $namespace = preg_replace('~\\s+~', '', strtolower($matches['nsname'][$i])) . '\\'; continue; } if ($matches['function'][$i] !== '') { $functions[] = strtolower(ltrim($namespace . $matches['fname'][$i], '\\')); continue; } if ($matches['constant'][$i] !== '') { $constants[] = ConstantNameHelper::normalize(ltrim($namespace . $matches['cname'][$i], '\\')); } if ($matches['define'][$i] !== '') { $constants[] = ConstantNameHelper::normalize($matches['dname'][$i]); continue; } $name = $matches['name'][$i]; // skip anon classes extending/implementing if (in_array($name, ['extends', 'implements'], \true)) { continue; } $classes[] = strtolower(ltrim($namespace . $name, '\\')); } return [$classes, $functions, $constants]; } } , functions: array, constants: array} */ private $presentSymbols = ['classes' => [], 'functions' => [], 'constants' => []]; /** @var array */ private $scannedFiles = []; /** @var array */ private $startLineByClass = []; public function __construct(\PHPStan\Reflection\BetterReflection\SourceLocator\FileNodesFetcher $fileNodesFetcher, bool $executeAutoloadersInFileReadTrap) { $this->fileNodesFetcher = $fileNodesFetcher; $this->executeAutoloadersInFileReadTrap = $executeAutoloadersInFileReadTrap; } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?Reflection { if ($identifier->isFunction()) { $functionName = $identifier->getName(); $loweredFunctionName = strtolower($functionName); if (array_key_exists($loweredFunctionName, $this->presentSymbols['functions'])) { return $this->findReflection($reflector, $this->presentSymbols['functions'][$loweredFunctionName], $identifier, null); } if (!function_exists($functionName)) { return null; } $reflection = new ReflectionFunction($functionName); $reflectionFileName = $reflection->getFileName(); if (!is_string($reflectionFileName)) { return null; } if (!is_file($reflectionFileName)) { return null; } return $this->findReflection($reflector, $reflectionFileName, $identifier, null); } if ($identifier->isConstant()) { $constantName = ConstantNameHelper::normalize($identifier->getName()); if (array_key_exists($constantName, $this->presentSymbols['constants'])) { return $this->findReflection($reflector, $this->presentSymbols['constants'][$constantName], $identifier, null); } if (!defined($constantName)) { return null; } $constantValue = @constant($constantName); return ReflectionConstant::createFromNode($reflector, new FuncCall(new Name('define'), [new Arg(new String_($constantName)), new Arg(new TypeExpr(ConstantTypeHelper::getTypeFromValue($constantValue)))], ['startLine' => 1, 'endLine' => 1, 'startFilePos' => 1, 'endFilePos' => 4]), new LocatedSource('isClass()) { return null; } $loweredClassName = strtolower($identifier->getName()); if (array_key_exists($loweredClassName, $this->presentSymbols['classes'])) { $startLine = null; if (array_key_exists($loweredClassName, $this->startLineByClass)) { $startLine = $this->startLineByClass[$loweredClassName]; } else { $reflection = $this->getReflectionClass($identifier->getName()); if ($reflection !== null && $reflection->getStartLine() !== \false && is_string($reflection->getFileName()) && is_file($reflection->getFileName()) && $reflection->getFileName() === $this->presentSymbols['classes'][$loweredClassName]) { $startLine = $reflection->getStartLine(); } } return $this->findReflection($reflector, $this->presentSymbols['classes'][$loweredClassName], $identifier, $startLine); } $locateResult = $this->locateClassByName($identifier->getName()); if ($locateResult === null) { return null; } [$potentiallyLocatedFiles, $className, $startLine] = $locateResult; if ($startLine !== null) { $this->startLineByClass[strtolower($className)] = $startLine; } $newIdentifier = new Identifier($className, $identifier->getType()); foreach ($potentiallyLocatedFiles as $potentiallyLocatedFile) { $reflection = $this->findReflection($reflector, $potentiallyLocatedFile, $newIdentifier, $startLine); if ($reflection === null) { continue; } return $reflection; } return null; } private function findReflection(Reflector $reflector, string $file, Identifier $identifier, ?int $startLine) : ?Reflection { $result = $this->fileNodesFetcher->fetchNodes($file); if (!array_key_exists($file, $this->scannedFiles)) { foreach (array_keys($result->getClassNodes()) as $className) { if (array_key_exists($className, $this->presentSymbols['classes'])) { continue; } $this->presentSymbols['classes'][$className] = $file; } foreach (array_keys($result->getFunctionNodes()) as $functionName) { if (array_key_exists($functionName, $this->presentSymbols['functions'])) { continue; } $this->presentSymbols['functions'][$functionName] = $file; } foreach (array_keys($result->getConstantNodes()) as $constantName) { if (array_key_exists($constantName, $this->presentSymbols['constants'])) { continue; } $this->presentSymbols['constants'][$constantName] = $file; } $this->scannedFiles[$file] = \true; } $nodeToReflection = new NodeToReflection(); if ($identifier->isClass()) { $identifierName = strtolower($identifier->getName()); if (!array_key_exists($identifierName, $result->getClassNodes())) { return null; } $classNodesCount = count($result->getClassNodes()[$identifierName]); foreach ($result->getClassNodes()[$identifierName] as $classNode) { if ($classNodesCount > 1 && $startLine !== null) { if (count($classNode->getNode()->attrGroups) > 0 && PHP_VERSION_ID < 80000) { $startLine--; } if ($startLine !== $classNode->getNode()->getStartLine()) { continue; } } return $nodeToReflection->__invoke($reflector, $classNode->getNode(), $classNode->getLocatedSource(), $classNode->getNamespace()); } return null; } if ($identifier->isFunction()) { $identifierName = strtolower($identifier->getName()); if (!array_key_exists($identifierName, $result->getFunctionNodes())) { return null; } foreach ($result->getFunctionNodes()[$identifierName] as $functionNode) { return $nodeToReflection->__invoke($reflector, $functionNode->getNode(), $functionNode->getLocatedSource(), $functionNode->getNamespace()); } } if ($identifier->isConstant()) { $identifierName = ConstantNameHelper::normalize($identifier->getName()); $constantNodes = $result->getConstantNodes(); if (!array_key_exists($identifierName, $constantNodes)) { return null; } foreach ($constantNodes[$identifierName] as $fetchedConstantNode) { $constantNode = $fetchedConstantNode->getNode(); $positionInNode = null; if ($constantNode instanceof Const_) { foreach ($constantNode->consts as $constPosition => $const) { if ($const->namespacedName === null) { throw new ShouldNotHappenException(); } if (ConstantNameHelper::normalize($const->namespacedName->toString()) === $identifierName) { /** @var int $positionInNode */ $positionInNode = $constPosition; break; } } if ($positionInNode === null) { throw new ShouldNotHappenException(); } } return $nodeToReflection->__invoke($reflector, $constantNode, $fetchedConstantNode->getLocatedSource(), $fetchedConstantNode->getNamespace(), $positionInNode); } } return null; } public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return []; } /** * @return ReflectionClass|null */ private function getReflectionClass(string $className) : ?ReflectionClass { if (class_exists($className, \false) || interface_exists($className, \false) || trait_exists($className, \false)) { return new ReflectionClass($className); } return null; } /** * Attempt to locate a class by name. * * If class already exists, simply use internal reflection API to get the * filename and store it. * * If class does not exist, we make an assumption that whatever autoloaders * that are registered will be loading a file. We then override the file:// * protocol stream wrapper to "capture" the filename we expect the class to * be in, and then restore it. Note that class_exists will cause an error * that it cannot find the file, so we squelch the errors by overriding the * error handler temporarily. * * @return array{string[], string, int|null}|null */ private function locateClassByName(string $className) : ?array { $reflection = $this->getReflectionClass($className); if ($reflection !== null) { $filename = $reflection->getFileName(); if (!is_string($filename)) { return null; } if (!is_file($filename)) { return null; } return [[$filename], $reflection->getName(), $reflection->getStartLine() !== \false ? $reflection->getStartLine() : null]; } if (!$this->executeAutoloadersInFileReadTrap) { return null; } $this->silenceErrors(); try { $result = \PHPStan\Reflection\BetterReflection\SourceLocator\FileReadTrapStreamWrapper::withStreamWrapperOverride(static function () use($className) : ?array { $functions = spl_autoload_functions(); if ($functions === \false) { return null; } foreach ($functions as $preExistingAutoloader) { $preExistingAutoloader($className); /** * This static variable is populated by the side-effect of the stream wrapper * trying to read the file path when `include()` is used by an autoloader. * * This will not be `null` when the autoloader tried to read a file. */ if (\PHPStan\Reflection\BetterReflection\SourceLocator\FileReadTrapStreamWrapper::$autoloadLocatedFiles !== []) { return [\PHPStan\Reflection\BetterReflection\SourceLocator\FileReadTrapStreamWrapper::$autoloadLocatedFiles, $className, null]; } } return null; }); if ($result === null) { return null; } if (!function_exists('opcache_invalidate')) { return $result; } foreach ($result[0] as $file) { opcache_invalidate($file, \true); } return $result; } finally { restore_error_handler(); } } private function silenceErrors() : void { set_error_handler(static function () : bool { return \true; }); } } */ private $classToFile; /** * @var array> */ private $functionToFiles; /** * @var array */ private $constantToFile; /** * @param array $classToFile * @param array> $functionToFiles * @param array $constantToFile */ public function __construct(\PHPStan\Reflection\BetterReflection\SourceLocator\FileNodesFetcher $fileNodesFetcher, array $classToFile, array $functionToFiles, array $constantToFile) { $this->fileNodesFetcher = $fileNodesFetcher; $this->classToFile = $classToFile; $this->functionToFiles = $functionToFiles; $this->constantToFile = $constantToFile; } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?Reflection { if ($identifier->isClass()) { $className = strtolower($identifier->getName()); $file = $this->findFileByClass($className); if ($file === null) { return null; } $fetchedClassNodes = $this->fileNodesFetcher->fetchNodes($file)->getClassNodes(); if (!array_key_exists($className, $fetchedClassNodes)) { return null; } /** @var FetchedNode $fetchedClassNode */ $fetchedClassNode = current($fetchedClassNodes[$className]); return $this->nodeToReflection($reflector, $fetchedClassNode); } if ($identifier->isFunction()) { $functionName = strtolower($identifier->getName()); $files = $this->findFilesByFunction($functionName); $fetchedFunctionNode = null; foreach ($files as $file) { $fetchedFunctionNodes = $this->fileNodesFetcher->fetchNodes($file)->getFunctionNodes(); if (!array_key_exists($functionName, $fetchedFunctionNodes)) { continue; } /** @var FetchedNode $fetchedFunctionNode */ $fetchedFunctionNode = current($fetchedFunctionNodes[$functionName]); } if ($fetchedFunctionNode === null) { return null; } return $this->nodeToReflection($reflector, $fetchedFunctionNode); } if ($identifier->isConstant()) { $constantName = ConstantNameHelper::normalize($identifier->getName()); $file = $this->findFileByConstant($constantName); if ($file === null) { return null; } $fetchedConstantNodes = $this->fileNodesFetcher->fetchNodes($file)->getConstantNodes(); if (!array_key_exists($constantName, $fetchedConstantNodes)) { return null; } /** @var FetchedNode $fetchedConstantNode */ $fetchedConstantNode = current($fetchedConstantNodes[$constantName]); return $this->nodeToReflection($reflector, $fetchedConstantNode, $this->findConstantPositionInConstNode($fetchedConstantNode->getNode(), $constantName)); } return null; } /** * @param FetchedNode|FetchedNode|FetchedNode $fetchedNode */ private function nodeToReflection(Reflector $reflector, \PHPStan\Reflection\BetterReflection\SourceLocator\FetchedNode $fetchedNode, ?int $positionInNode = null) : Reflection { $nodeToReflection = new NodeToReflection(); return $nodeToReflection->__invoke($reflector, $fetchedNode->getNode(), $fetchedNode->getLocatedSource(), $fetchedNode->getNamespace(), $positionInNode); } private function findFileByClass(string $className) : ?string { if (!array_key_exists($className, $this->classToFile)) { return null; } return $this->classToFile[$className]; } private function findFileByConstant(string $constantName) : ?string { if (!array_key_exists($constantName, $this->constantToFile)) { return null; } return $this->constantToFile[$constantName]; } /** * @return string[] */ private function findFilesByFunction(string $functionName) : array { if (!array_key_exists($functionName, $this->functionToFiles)) { return []; } return $this->functionToFiles[$functionName]; } /** * @return list */ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { $reflections = []; if ($identifierType->isClass()) { foreach ($this->classToFile as $file) { $fetchedNodesResult = $this->fileNodesFetcher->fetchNodes($file); foreach ($fetchedNodesResult->getClassNodes() as $identifierName => $fetchedClassNodes) { foreach ($fetchedClassNodes as $fetchedClassNode) { $reflections[$identifierName] = $this->nodeToReflection($reflector, $fetchedClassNode); } } } } elseif ($identifierType->isFunction()) { foreach ($this->functionToFiles as $files) { foreach ($files as $file) { $fetchedNodesResult = $this->fileNodesFetcher->fetchNodes($file); foreach ($fetchedNodesResult->getFunctionNodes() as $identifierName => $fetchedFunctionNodes) { foreach ($fetchedFunctionNodes as $fetchedFunctionNode) { $reflections[$identifierName] = $this->nodeToReflection($reflector, $fetchedFunctionNode); continue 2; } } } } } elseif ($identifierType->isConstant()) { foreach ($this->constantToFile as $file) { $fetchedNodesResult = $this->fileNodesFetcher->fetchNodes($file); foreach ($fetchedNodesResult->getConstantNodes() as $identifierName => $fetchedConstantNodes) { foreach ($fetchedConstantNodes as $fetchedConstantNode) { $reflections[$identifierName] = $this->nodeToReflection($reflector, $fetchedConstantNode, $this->findConstantPositionInConstNode($fetchedConstantNode->getNode(), $identifierName)); } } } } return array_values($reflections); } /** * @param Node\Stmt\Const_|Node\Expr\FuncCall $constantNode */ private function findConstantPositionInConstNode($constantNode, string $constantName) : ?int { if ($constantNode instanceof Node\Expr\FuncCall) { return null; } /** @var int $position */ foreach ($constantNode->consts as $position => $const) { if ($const->namespacedName === null) { throw new ShouldNotHappenException(); } if (ConstantNameHelper::normalize($const->namespacedName->toString()) === $constantName) { return $position; } } throw new ShouldNotHappenException(); } } node = $node; $this->namespace = $namespace; $this->locatedSource = $locatedSource; } /** * @return T */ public function getNode() : Node { return $this->node; } public function getNamespace() : ?Node\Stmt\Namespace_ { return $this->namespace; } public function getLocatedSource() : LocatedSource { return $this->locatedSource; } } autoloadSourceLocator = $autoloadSourceLocator; $this->reflectionClassSourceLocator = $reflectionClassSourceLocator; } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?Reflection { if (!$identifier->isClass()) { return null; } $className = $identifier->getName(); if (class_exists($className, \false) || interface_exists($className, \false) || trait_exists($className, \false)) { return null; } $autoloadFunctions = autoloadFunctions(); foreach ($autoloadFunctions as $autoloadFunction) { $autoloadFunction($className); $reflection = $this->autoloadSourceLocator->locateIdentifier($reflector, $identifier); if ($reflection !== null) { return $reflection; } $reflection = $this->reflectionClassSourceLocator->locateIdentifier($reflector, $identifier); if ($reflection !== null) { return $reflection; } } return null; } public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return []; } } sourceLocator = $sourceLocator; $this->phpStormStubsSourceStubber = $phpStormStubsSourceStubber; } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?Reflection { if ($identifier->isClass()) { if ($this->phpStormStubsSourceStubber->isPresentClass($identifier->getName()) === \false) { return null; } } if ($identifier->isFunction()) { if ($this->phpStormStubsSourceStubber->isPresentFunction($identifier->getName()) === \false) { return null; } } return $this->sourceLocator->locateIdentifier($reflector, $identifier); } public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return $this->sourceLocator->locateIdentifiersByType($reflector, $identifierType); } } >> */ private $classNodes; /** @var array>> */ private $functionNodes; /** @var array>> */ private $constantNodes; /** * @var ?Node\Stmt\Namespace_ */ private $currentNamespaceNode = null; public function enterNode(Node $node) : ?int { if ($node instanceof Namespace_) { $this->currentNamespaceNode = $node; return null; } if ($node instanceof Node\Stmt\ClassLike) { if ($node->name !== null) { $fullClassName = $node->name->toString(); if ($this->currentNamespaceNode !== null && $this->currentNamespaceNode->name !== null) { $fullClassName = $this->currentNamespaceNode->name . '\\' . $fullClassName; } $this->classNodes[strtolower($fullClassName)][] = new \PHPStan\Reflection\BetterReflection\SourceLocator\FetchedNode($node, $this->currentNamespaceNode, new LocatedSource($this->contents, $fullClassName, $this->fileName)); } return NodeTraverser::DONT_TRAVERSE_CHILDREN; } if ($node instanceof Node\Stmt\Function_) { if ($node->namespacedName !== null) { $functionName = $node->namespacedName->toString(); $this->functionNodes[strtolower($functionName)][] = new \PHPStan\Reflection\BetterReflection\SourceLocator\FetchedNode($node, $this->currentNamespaceNode, new LocatedSource($this->contents, $functionName, $this->fileName)); } return NodeTraverser::DONT_TRAVERSE_CHILDREN; } if ($node instanceof Node\Stmt\Const_) { foreach ($node->consts as $const) { if ($const->namespacedName === null) { continue; } $this->constantNodes[ConstantNameHelper::normalize($const->namespacedName->toString())][] = new \PHPStan\Reflection\BetterReflection\SourceLocator\FetchedNode($node, $this->currentNamespaceNode, new LocatedSource($this->contents, null, $this->fileName)); } return NodeTraverser::DONT_TRAVERSE_CHILDREN; } if ($node instanceof Node\Expr\FuncCall) { try { ConstantNodeChecker::assertValidDefineFunctionCall($node); } catch (InvalidConstantNode $e) { return null; } /** @var Node\Scalar\String_ $nameNode */ $nameNode = $node->getArgs()[0]->value; $constantName = $nameNode->value; $constantNode = new \PHPStan\Reflection\BetterReflection\SourceLocator\FetchedNode($node, $this->currentNamespaceNode, new LocatedSource($this->contents, $constantName, $this->fileName)); $this->constantNodes[ConstantNameHelper::normalize($constantName)][] = $constantNode; return NodeTraverser::DONT_TRAVERSE_CHILDREN; } return null; } /** * @return null */ public function leaveNode(Node $node) { if (!$node instanceof Namespace_) { return null; } $this->currentNamespaceNode = null; return null; } /** * @return array>> */ public function getClassNodes() : array { return $this->classNodes; } /** * @return array>> */ public function getFunctionNodes() : array { return $this->functionNodes; } /** * @return array>> */ public function getConstantNodes() : array { return $this->constantNodes; } public function reset(string $fileName, string $contents) : void { $this->classNodes = []; $this->functionNodes = []; $this->constantNodes = []; $this->fileName = $fileName; $this->contents = $contents; } } sourceLocator = $sourceLocator; } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?Reflection { if ($identifier->isClass()) { $className = $identifier->getName(); if (!class_exists($className, \false)) { return $this->sourceLocator->locateIdentifier($reflector, $identifier); } $reflection = new ReflectionClass($className); if ($reflection->getName() === 'ReturnTypeWillChange') { return $this->sourceLocator->locateIdentifier($reflector, $identifier); } if ($reflection->getFileName() === \false) { return $this->sourceLocator->locateIdentifier($reflector, $identifier); } return null; } return $this->sourceLocator->locateIdentifier($reflector, $identifier); } public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return $this->sourceLocator->locateIdentifiersByType($reflector, $identifierType); } } optimizedDirectorySourceLocatorRepository = $optimizedDirectorySourceLocatorRepository; $this->optimizedPsrAutoloaderLocatorFactory = $optimizedPsrAutoloaderLocatorFactory; $this->optimizedDirectorySourceLocatorFactory = $optimizedDirectorySourceLocatorFactory; $this->phpVersion = $phpVersion; } public function create(string $projectInstallationPath) : ?SourceLocator { $composer = ComposerHelper::getComposerConfig($projectInstallationPath); if ($composer === null) { return null; } $vendorDirectory = ComposerHelper::getVendorDirFromComposerConfig($projectInstallationPath, $composer); $installedJsonPath = $vendorDirectory . '/composer/installed.json'; if (!is_file($installedJsonPath)) { return null; } $installedJsonDirectoryPath = dirname($installedJsonPath); try { $installedJsonContents = FileReader::read($installedJsonPath); $installedJson = Json::decode($installedJsonContents, Json::FORCE_ARRAY); } catch (CouldNotReadFileException|JsonException $e) { return null; } $installed = $installedJson['packages'] ?? $installedJson; $dev = (bool) ($installedJson['dev'] ?? \true); $classMapPaths = array_merge($this->prefixPaths($this->packageToClassMapPaths($composer), $projectInstallationPath . '/'), $dev ? $this->prefixPaths($this->packageToClassMapPaths($composer, 'autoload-dev'), $projectInstallationPath . '/') : [], ...array_map(function (array $package) use($installedJsonDirectoryPath, $vendorDirectory) : array { return $this->prefixPaths($this->packageToClassMapPaths($package), $this->packagePrefixPath($installedJsonDirectoryPath, $package, $vendorDirectory)); }, $installed)); $filePaths = array_merge($this->prefixPaths($this->packageToFilePaths($composer), $projectInstallationPath . '/'), $dev ? $this->prefixPaths($this->packageToFilePaths($composer, 'autoload-dev'), $projectInstallationPath . '/') : [], ...array_map(function (array $package) use($installedJsonDirectoryPath, $vendorDirectory) : array { return $this->prefixPaths($this->packageToFilePaths($package), $this->packagePrefixPath($installedJsonDirectoryPath, $package, $vendorDirectory)); }, $installed)); $locators = []; $locators[] = $this->optimizedPsrAutoloaderLocatorFactory->create(Psr4Mapping::fromArrayMappings(array_merge_recursive($this->prefixWithInstallationPath($this->packageToPsr4AutoloadNamespaces($composer), $projectInstallationPath), $dev ? $this->prefixWithInstallationPath($this->packageToPsr4AutoloadNamespaces($composer, 'autoload-dev'), $projectInstallationPath) : [], ...array_map(function (array $package) use($installedJsonDirectoryPath, $vendorDirectory) : array { return $this->prefixWithPackagePath($this->packageToPsr4AutoloadNamespaces($package), $installedJsonDirectoryPath, $package, $vendorDirectory); }, $installed)))); $locators[] = $this->optimizedPsrAutoloaderLocatorFactory->create(Psr0Mapping::fromArrayMappings(array_merge_recursive($this->prefixWithInstallationPath($this->packageToPsr0AutoloadNamespaces($composer), $projectInstallationPath), $dev ? $this->prefixWithInstallationPath($this->packageToPsr0AutoloadNamespaces($composer, 'autoload-dev'), $projectInstallationPath) : [], ...array_map(function (array $package) use($installedJsonDirectoryPath, $vendorDirectory) : array { return $this->prefixWithPackagePath($this->packageToPsr0AutoloadNamespaces($package), $installedJsonDirectoryPath, $package, $vendorDirectory); }, $installed)))); $files = []; foreach ($classMapPaths as $classMapPath) { if (is_dir($classMapPath)) { $locators[] = $this->optimizedDirectorySourceLocatorRepository->getOrCreate($classMapPath); continue; } if (!is_file($classMapPath)) { continue; } $files[] = $classMapPath; } foreach ($filePaths as $file) { if (!is_file($file)) { continue; } $files[] = $file; } if (count($files) > 0) { $locators[] = $this->optimizedDirectorySourceLocatorFactory->createByFiles($files); } $binDir = ComposerHelper::getBinDirFromComposerConfig($projectInstallationPath, $composer); $phpunitBridgeDir = $binDir . '/.phpunit'; if (!is_dir($vendorDirectory . '/phpunit/phpunit') && is_dir($phpunitBridgeDir)) { // from https://github.com/composer/composer/blob/8ff237afb61b8766efa576b8ae1cc8560c8aed96/phpstan/locate-phpunit-autoloader.php $bestDirFound = null; $phpunitBridgeDirectories = glob($phpunitBridgeDir . '/phpunit-*', GLOB_ONLYDIR); if ($phpunitBridgeDirectories !== \false) { foreach (array_reverse($phpunitBridgeDirectories) as $dir) { $bestDirFound = $dir; if ($this->phpVersion->getVersionId() >= 80100 && str_contains($dir, 'phpunit-10')) { break; } if ($this->phpVersion->getVersionId() >= 80000) { if (str_contains($dir, 'phpunit-9')) { break; } continue; } if (str_contains($dir, 'phpunit-8') || str_contains($dir, 'phpunit-7')) { break; } } if ($bestDirFound !== null) { $phpunitBridgeLocator = $this->create($bestDirFound); if ($phpunitBridgeLocator !== null) { $locators[] = $phpunitBridgeLocator; } } } } return new AggregateSourceLocator($locators); } /** * @param mixed[] $package * * @return array> */ private function packageToPsr4AutoloadNamespaces(array $package, string $autoloadSection = 'autoload') : array { return array_map(static function ($namespacePaths) : array { return (array) $namespacePaths; }, $package[$autoloadSection]['psr-4'] ?? []); } /** * @param mixed[] $package * * @return array> */ private function packageToPsr0AutoloadNamespaces(array $package, string $autoloadSection = 'autoload') : array { return array_map(static function ($namespacePaths) : array { return (array) $namespacePaths; }, $package[$autoloadSection]['psr-0'] ?? []); } /** * @param mixed[] $package * * @return array */ private function packageToClassMapPaths(array $package, string $autoloadSection = 'autoload') : array { return $package[$autoloadSection]['classmap'] ?? []; } /** * @param mixed[] $package * * @return array */ private function packageToFilePaths(array $package, string $autoloadSection = 'autoload') : array { return $package[$autoloadSection]['files'] ?? []; } /** * @param mixed[] $package */ private function packagePrefixPath(string $installedJsonDirectoryPath, array $package, string $vendorDirectory) : string { if (array_key_exists('install-path', $package)) { return $installedJsonDirectoryPath . '/' . $package['install-path'] . '/'; } return $vendorDirectory . '/' . $package['name'] . '/'; } /** * @param array> $paths * @param array> $package * * @return array> */ private function prefixWithPackagePath(array $paths, string $installedJsonDirectoryPath, array $package, string $vendorDirectory) : array { $prefix = $this->packagePrefixPath($installedJsonDirectoryPath, $package, $vendorDirectory); return array_map(function (array $paths) use($prefix) : array { return $this->prefixPaths($paths, $prefix); }, $paths); } /** * @param array> $paths * * @return array> */ private function prefixWithInstallationPath(array $paths, string $trimmedInstallationPath) : array { return array_map(function (array $paths) use($trimmedInstallationPath) : array { return $this->prefixPaths($paths, $trimmedInstallationPath . '/'); }, $paths); } /** * @param array $paths * * @return array */ private function prefixPaths(array $paths, string $prefix) : array { return array_map(static function (string $path) use($prefix) : string { return $prefix . $path; }, $paths); } } */ private $locators = []; public function __construct(\PHPStan\Reflection\BetterReflection\SourceLocator\OptimizedDirectorySourceLocatorFactory $factory) { $this->factory = $factory; } public function getOrCreate(string $directory) : \PHPStan\Reflection\BetterReflection\SourceLocator\NewOptimizedDirectorySourceLocator { if (array_key_exists($directory, $this->locators)) { return $this->locators[$directory]; } $this->locators[$directory] = $this->factory->createByDirectory($directory); return $this->locators[$directory]; } } * @see https://github.com/composer/composer/pull/10107 */ final class PhpFileCleaner { /** @var array */ private $typeConfig = []; /** * @var string */ private $restPattern; /** * @var string */ private $contents = ''; /** * @var int */ private $len = 0; /** * @var int */ private $index = 0; public function __construct() { foreach (['class', 'interface', 'trait', 'enum'] as $type) { $this->typeConfig[$type[0]] = ['name' => $type, 'length' => strlen($type), 'pattern' => '{.\\b(?])' . $type . '\\s++[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\-]*+}Ais']; } $this->restPattern = '{[^{}?"\'typeConfig)) . ']+}A'; } public function clean(string $contents, int $maxMatches) : string { $this->contents = $contents; $this->len = strlen($contents); $this->index = 0; $inType = \false; $typeLevel = 0; $inDefine = \false; $clean = ''; while ($this->index < $this->len) { $this->skipToPhp(); $clean .= 'index < $this->len) { $char = $this->contents[$this->index]; if ($char === '?' && $this->peek('>')) { $clean .= '?>'; $this->index += 2; continue 2; } if (in_array($char, ['"', "'"], \true)) { if ($inDefine) { $clean .= $char . $this->consumeString($char); $inDefine = \false; } else { $this->skipString($char); $clean .= 'null'; } continue; } if ($char === '{') { if ($inType) { $typeLevel++; } $clean .= $char; $this->index++; continue; } if ($char === '}') { if ($inType) { $typeLevel--; if ($typeLevel === 0) { $inType = \false; } } $clean .= $char; $this->index++; continue; } if ($char === '<' && $this->peek('<') && $this->match('{<<<[ \\t]*+([\'"]?)([a-zA-Z_\\x80-\\xff][a-zA-Z0-9_\\x80-\\xff]*+)\\1(?:\\r\\n|\\n|\\r)}A', $match)) { $this->index += strlen($match[0]); $this->skipHeredoc($match[2]); $clean .= 'null'; continue; } if ($char === '/') { if ($this->peek('/')) { $this->skipToNewline(); continue; } if ($this->peek('*')) { $this->skipComment(); continue; } } if ($inType && $char === 'c' && $this->match('~.\\b(?])const(\\s++[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\-]*+)~Ais', $match, $this->index - 1)) { // It's invalid PHP but it does not matter $clean .= 'class_const' . $match[1]; $this->index += strlen($match[0]) - 1; continue; } if ($char === 'd' && $this->match('~.\\b(?])define\\s*+\\(~Ais', $match, $this->index - 1)) { $inDefine = \true; $clean .= $match[0]; $this->index += strlen($match[0]) - 1; continue; } if (isset($this->typeConfig[$char])) { $type = $this->typeConfig[$char]; if (substr($this->contents, $this->index, $type['length']) === $type['name']) { if ($maxMatches === 1 && $this->match($type['pattern'], $match, $this->index - 1)) { return $clean . $match[0]; } $inType = \true; } } $this->index += 1; if ($this->match($this->restPattern, $match)) { $clean .= $char . $match[0]; $this->index += strlen($match[0]); } else { $clean .= $char; } } } return $clean; } private function skipToPhp() : void { while ($this->index < $this->len) { if ($this->contents[$this->index] === '<' && $this->peek('?')) { $this->index += 2; break; } $this->index += 1; } } private function consumeString(string $delimiter) : string { $string = ''; $this->index += 1; while ($this->index < $this->len) { if ($this->contents[$this->index] === '\\' && ($this->peek('\\') || $this->peek($delimiter))) { $string .= $this->contents[$this->index]; $string .= $this->contents[$this->index + 1]; $this->index += 2; continue; } if ($this->contents[$this->index] === $delimiter) { $string .= $delimiter; $this->index += 1; break; } $string .= $this->contents[$this->index]; $this->index += 1; } return $string; } private function skipString(string $delimiter) : void { $this->index += 1; while ($this->index < $this->len) { if ($this->contents[$this->index] === '\\' && ($this->peek('\\') || $this->peek($delimiter))) { $this->index += 2; continue; } if ($this->contents[$this->index] === $delimiter) { $this->index += 1; break; } $this->index += 1; } } private function skipComment() : void { $this->index += 2; while ($this->index < $this->len) { if ($this->contents[$this->index] === '*' && $this->peek('/')) { $this->index += 2; break; } $this->index += 1; } } private function skipToNewline() : void { while ($this->index < $this->len) { if (in_array($this->contents[$this->index], ["\r", "\n"], \true)) { return; } $this->index += 1; } } private function skipHeredoc(string $delimiter) : void { $firstDelimiterChar = $delimiter[0]; $delimiterLength = strlen($delimiter); $delimiterPattern = '{' . preg_quote($delimiter) . '(?![a-zA-Z0-9_\\x80-\\xff])}A'; while ($this->index < $this->len) { // check if we find the delimiter after some spaces/tabs switch ($this->contents[$this->index]) { case "\t": case ' ': $this->index += 1; continue 2; case $firstDelimiterChar: if (substr($this->contents, $this->index, $delimiterLength) === $delimiter && $this->match($delimiterPattern)) { $this->index += $delimiterLength; return; } break; } // skip the rest of the line while ($this->index < $this->len) { $this->skipToNewline(); // skip newlines while ($this->index < $this->len && ($this->contents[$this->index] === "\r" || $this->contents[$this->index] === "\n")) { $this->index += 1; } break; } } } private function peek(string $char) : bool { return $this->index + 1 < $this->len && $this->contents[$this->index + 1] === $char; } /** * @param string[]|null $match * @param-out string[] $match */ private function match(string $regex, ?array &$match = null, ?int $offset = null) : bool { return preg_match($regex, $this->contents, $match, 0, $offset ?? $this->index) === 1; } } astLocator = $astLocator; $this->reflectionSourceStubber = $reflectionSourceStubber; } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?Reflection { if (!$identifier->isClass()) { return null; } /** @var class-string $className */ $className = $identifier->getName(); $stub = $this->reflectionSourceStubber->generateClassStub($className); if ($stub === null) { return null; } $reflection = new ReflectionClass($className); return $this->astLocator->findReflection($reflector, new LocatedSource($stub->getStub(), $reflection->getName(), null), new Identifier($reflection->getName(), new IdentifierType(IdentifierType::IDENTIFIER_CLASS))); } public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return []; } } */ private $locators = []; public function __construct(\PHPStan\Reflection\BetterReflection\SourceLocator\OptimizedSingleFileSourceLocatorFactory $factory) { $this->factory = $factory; } public function getOrCreate(string $fileName) : \PHPStan\Reflection\BetterReflection\SourceLocator\OptimizedSingleFileSourceLocator { if (array_key_exists($fileName, $this->locators)) { return $this->locators[$fileName]; } $this->locators[$fileName] = $this->factory->create($fileName); return $this->locators[$fileName]; } } originalSourceLocator = $originalSourceLocator; } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?Reflection { if (!$identifier->isClass()) { return $this->originalSourceLocator->locateIdentifier($reflector, $identifier); } if (class_exists($identifier->getName(), \false) || interface_exists($identifier->getName(), \false) || trait_exists($identifier->getName(), \false)) { $classReflection = new CoreReflectionClass($identifier->getName()); return $this->originalSourceLocator->locateIdentifier($reflector, new Identifier($classReflection->getName(), $identifier->getType())); } return $this->originalSourceLocator->locateIdentifier($reflector, $identifier); } public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return $this->originalSourceLocator->locateIdentifiersByType($reflector, $identifierType); } } readFromFile = \false; $this->seekPosition = 0; return $exists; } /** * Since we allow our wrapper's stream_open() to succeed, we need to * simulate a successful read so autoloaders with require() don't explode. * * @param int $count * */ public function stream_read($count) : string { $this->readFromFile = \true; // Dummy return value that is also valid PHP for require(). We'll read // and process the file elsewhere, so it's OK to provide dummy data for // this read. return ''; } /** * Since we allowed the open to succeed, we should allow the close to occur * as well. * */ public function stream_close() : void { // no op } /** * Required for `require_once` and `include_once` to work per PHP.net * comment referenced below. We delegate to url_stat(). * * @see https://www.php.net/manual/en/function.stream-wrapper-register.php#51855 * * @return mixed[]|bool */ public function stream_stat() { if (self::$autoloadLocatedFiles === []) { return \false; } return $this->url_stat(self::$autoloadLocatedFiles[0], STREAM_URL_STAT_QUIET); } /** * url_stat is triggered by calls like "file_exists". The call to "file_exists" must not be overloaded. * This function restores the original "file" stream, issues a call to "stat" to get the real results, * and then re-registers the AutoloadSourceLocator stream wrapper. * * @internal do not call this method directly! This is stream wrapper * voodoo logic that you **DO NOT** want to touch! * * @see https://php.net/manual/en/class.streamwrapper.php * @see https://php.net/manual/en/streamwrapper.url-stat.php * * @param string $path * @param int $flags * * @return mixed[]|bool */ public function url_stat($path, $flags) { return $this->invokeWithRealFileStreamWrapper(static function ($path, $flags) { if (($flags & STREAM_URL_STAT_QUIET) !== 0) { return @stat($path); } return stat($path); }, [$path, $flags]); } /** * @param mixed[] $args * @return mixed */ private function invokeWithRealFileStreamWrapper(callable $cb, array $args) { if (self::$registeredStreamWrapperProtocols === null) { throw new ShouldNotHappenException(self::class . ' not registered: cannot operate. Do not call this method directly.'); } foreach (self::$registeredStreamWrapperProtocols as $protocol) { stream_wrapper_restore($protocol); } $result = $cb(...$args); foreach (self::$registeredStreamWrapperProtocols as $protocol) { stream_wrapper_unregister($protocol); stream_wrapper_register($protocol, self::class); } return $result; } /** * Simulates behavior of reading from an empty file. * */ public function stream_eof() : bool { return $this->readFromFile; } public function stream_flush() : bool { return \true; } public function stream_tell() : int { return $this->seekPosition; } /** * @param int $offset * @param int $whence */ public function stream_seek($offset, $whence) : bool { switch ($whence) { // Behavior is the same for a zero-length file case SEEK_SET: case SEEK_END: if ($offset < 0) { return \false; } $this->seekPosition = $offset; return \true; case SEEK_CUR: if ($offset < 0) { return \false; } $this->seekPosition += $offset; return \true; default: return \false; } } /** * @param int $option * @param int $arg1 * @param int $arg2 */ public function stream_set_option($option, $arg1, $arg2) : bool { return \false; } public function dir_opendir(string $path, int $options) : bool { return is_dir($path); } public function dir_readdir() : string { return ''; } } , functions: array, constants: array}|null */ private $presentSymbols = null; public function __construct(\PHPStan\Reflection\BetterReflection\SourceLocator\FileNodesFetcher $fileNodesFetcher, string $fileName) { $this->fileNodesFetcher = $fileNodesFetcher; $this->fileName = $fileName; } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?Reflection { if ($this->presentSymbols !== null) { if ($identifier->isClass()) { $className = strtolower($identifier->getName()); if (!array_key_exists($className, $this->presentSymbols['classes'])) { return null; } } if ($identifier->isFunction()) { $className = strtolower($identifier->getName()); if (!array_key_exists($className, $this->presentSymbols['functions'])) { return null; } } if ($identifier->isConstant()) { $constantName = ConstantNameHelper::normalize($identifier->getName()); if (!array_key_exists($constantName, $this->presentSymbols['constants'])) { return null; } } } $fetchedNodesResult = $this->fileNodesFetcher->fetchNodes($this->fileName); if ($this->presentSymbols === null) { $presentSymbols = ['classes' => [], 'functions' => [], 'constants' => []]; foreach (array_keys($fetchedNodesResult->getClassNodes()) as $className) { $presentSymbols['classes'][$className] = \true; } foreach (array_keys($fetchedNodesResult->getFunctionNodes()) as $functionName) { $presentSymbols['functions'][$functionName] = \true; } foreach (array_keys($fetchedNodesResult->getConstantNodes()) as $constantName) { $presentSymbols['constants'][$constantName] = \true; } $this->presentSymbols = $presentSymbols; } $nodeToReflection = new NodeToReflection(); if ($identifier->isClass()) { $classNodes = $fetchedNodesResult->getClassNodes(); $className = strtolower($identifier->getName()); if (!array_key_exists($className, $classNodes)) { return null; } foreach ($classNodes[$className] as $classNode) { $classReflection = $nodeToReflection->__invoke($reflector, $classNode->getNode(), $classNode->getLocatedSource(), $classNode->getNamespace()); if (!$classReflection instanceof ReflectionClass) { throw new ShouldNotHappenException(); } return $classReflection; } } if ($identifier->isFunction()) { $functionNodes = $fetchedNodesResult->getFunctionNodes(); $functionName = strtolower($identifier->getName()); if (!array_key_exists($functionName, $functionNodes)) { return null; } foreach ($functionNodes[$functionName] as $functionNode) { $functionReflection = $nodeToReflection->__invoke($reflector, $functionNode->getNode(), $functionNode->getLocatedSource(), $functionNode->getNamespace()); if (!$functionReflection instanceof ReflectionFunction) { throw new ShouldNotHappenException(); } return $functionReflection; } } if ($identifier->isConstant()) { $constantNodes = $fetchedNodesResult->getConstantNodes(); $constantName = ConstantNameHelper::normalize($identifier->getName()); if (!array_key_exists($constantName, $constantNodes)) { return null; } foreach ($constantNodes[$constantName] as $fetchedConstantNode) { $constantNode = $fetchedConstantNode->getNode(); $positionInNode = null; if ($constantNode instanceof Const_) { foreach ($constantNode->consts as $constPosition => $const) { if ($const->namespacedName === null) { throw new ShouldNotHappenException(); } if (ConstantNameHelper::normalize($const->namespacedName->toString()) === $constantName) { /** @var int $positionInNode */ $positionInNode = $constPosition; break; } } if ($positionInNode === null) { throw new ShouldNotHappenException(); } } $constantReflection = $nodeToReflection->__invoke($reflector, $fetchedConstantNode->getNode(), $fetchedConstantNode->getLocatedSource(), $fetchedConstantNode->getNamespace(), $positionInNode); if (!$constantReflection instanceof ReflectionConstant) { throw new ShouldNotHappenException(); } return $constantReflection; } return null; } throw new ShouldNotHappenException(); } public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { $fetchedNodesResult = $this->fileNodesFetcher->fetchNodes($this->fileName); $nodeToReflection = new NodeToReflection(); $reflections = []; if ($identifierType->isClass()) { $classNodes = $fetchedNodesResult->getClassNodes(); foreach ($classNodes as $classNodesArray) { foreach ($classNodesArray as $classNode) { $classReflection = $nodeToReflection->__invoke($reflector, $classNode->getNode(), $classNode->getLocatedSource(), $classNode->getNamespace()); if (!$classReflection instanceof ReflectionClass) { throw new ShouldNotHappenException(); } $reflections[] = $classReflection; } } } if ($identifierType->isFunction()) { $functionNodes = $fetchedNodesResult->getFunctionNodes(); foreach ($functionNodes as $functionNodesArray) { foreach ($functionNodesArray as $functionNode) { $functionReflection = $nodeToReflection->__invoke($reflector, $functionNode->getNode(), $functionNode->getLocatedSource(), $functionNode->getNamespace()); $reflections[] = $functionReflection; } } } if ($identifierType->isConstant()) { $constantNodes = $fetchedNodesResult->getConstantNodes(); foreach ($constantNodes as $constantNodesArray) { foreach ($constantNodesArray as $fetchedConstantNode) { $constantNode = $fetchedConstantNode->getNode(); if ($constantNode instanceof Const_) { foreach ($constantNode->consts as $constPosition => $const) { if ($const->namespacedName === null) { throw new ShouldNotHappenException(); } $constantReflection = $nodeToReflection->__invoke($reflector, $constantNode, $fetchedConstantNode->getLocatedSource(), $fetchedConstantNode->getNamespace(), $constPosition); if (!$constantReflection instanceof ReflectionConstant) { throw new ShouldNotHappenException(); } $reflections[] = $constantReflection; } continue; } $constantReflection = $nodeToReflection->__invoke($reflector, $constantNode, $fetchedConstantNode->getLocatedSource(), $fetchedConstantNode->getNamespace()); if (!$constantReflection instanceof ReflectionConstant) { throw new ShouldNotHappenException(); } $reflections[] = $constantReflection; } } } return $reflections; } } parser = $parser; $this->php8Parser = $php8Parser; $this->phpstormStubsSourceStubber = $phpstormStubsSourceStubber; $this->reflectionSourceStubber = $reflectionSourceStubber; $this->optimizedSingleFileSourceLocatorRepository = $optimizedSingleFileSourceLocatorRepository; $this->optimizedDirectorySourceLocatorRepository = $optimizedDirectorySourceLocatorRepository; $this->composerJsonAndInstalledJsonSourceLocatorMaker = $composerJsonAndInstalledJsonSourceLocatorMaker; $this->optimizedPsrAutoloaderLocatorFactory = $optimizedPsrAutoloaderLocatorFactory; $this->fileNodesFetcher = $fileNodesFetcher; $this->scanFiles = $scanFiles; $this->scanDirectories = $scanDirectories; $this->analysedPaths = $analysedPaths; $this->composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; $this->analysedPathsFromConfig = $analysedPathsFromConfig; $this->playgroundMode = $playgroundMode; $this->singleReflectionFile = $singleReflectionFile; } public function create() : SourceLocator { $locators = []; if ($this->singleReflectionFile !== null) { $locators[] = $this->optimizedSingleFileSourceLocatorRepository->getOrCreate($this->singleReflectionFile); } $astLocator = new Locator($this->parser); $locators[] = new AutoloadFunctionsSourceLocator(new AutoloadSourceLocator($this->fileNodesFetcher, \false), new ReflectionClassSourceLocator($astLocator, $this->reflectionSourceStubber)); $analysedDirectories = []; $analysedFiles = []; foreach (array_merge($this->analysedPaths, $this->analysedPathsFromConfig) as $analysedPath) { if (is_file($analysedPath)) { $analysedFiles[] = $analysedPath; continue; } if (!is_dir($analysedPath)) { continue; } $analysedDirectories[] = $analysedPath; } $fileLocators = []; $analysedFiles = array_unique(array_merge($analysedFiles, $this->scanFiles)); foreach ($analysedFiles as $analysedFile) { $fileLocators[] = $this->optimizedSingleFileSourceLocatorRepository->getOrCreate($analysedFile); } $directories = array_unique(array_merge($analysedDirectories, $this->scanDirectories)); foreach ($directories as $directory) { $fileLocators[] = $this->optimizedDirectorySourceLocatorRepository->getOrCreate($directory); } $astPhp8Locator = new Locator($this->php8Parser); foreach ($this->composerAutoloaderProjectPaths as $composerAutoloaderProjectPath) { $locator = $this->composerJsonAndInstalledJsonSourceLocatorMaker->create($composerAutoloaderProjectPath); if ($locator === null) { continue; } $fileLocators[] = $locator; } if (extension_loaded('phar')) { $pharProtocolPath = Phar::running(); if ($pharProtocolPath !== '') { $mappings = ['PHPStan\\BetterReflection\\' => [$pharProtocolPath . '/vendor/ondrejmirtes/better-reflection/src/']]; if ($this->playgroundMode) { $mappings['PHPStan\\'] = [$pharProtocolPath . '/src/']; } else { $mappings['PHPStan\\Testing\\'] = [$pharProtocolPath . '/src/Testing/']; } $fileLocators[] = $this->optimizedPsrAutoloaderLocatorFactory->create(Psr4Mapping::fromArrayMappings($mappings)); } } $locators[] = new RewriteClassAliasSourceLocator(new AggregateSourceLocator($fileLocators)); $locators[] = new SkipClassAliasSourceLocator(new PhpInternalSourceLocator($astPhp8Locator, $this->phpstormStubsSourceStubber)); $locators[] = new AutoloadSourceLocator($this->fileNodesFetcher, \true); $locators[] = new PhpVersionBlacklistSourceLocator(new PhpInternalSourceLocator($astLocator, $this->reflectionSourceStubber), $this->phpstormStubsSourceStubber); $locators[] = new PhpVersionBlacklistSourceLocator(new EvaledCodeSourceLocator($astLocator, $this->reflectionSourceStubber), $this->phpstormStubsSourceStubber); return new MemoizingSourceLocator(new AggregateSourceLocator($locators)); } } */ private $cachedConstants = []; /** * @param string[] $universalObjectCratesClasses */ public function __construct(ReflectionProvider\ReflectionProviderProvider $reflectionProviderProvider, InitializerExprTypeResolver $initializerExprTypeResolver, ClassReflectionExtensionRegistryProvider $classReflectionExtensionRegistryProvider, Reflector $reflector, FileTypeMapper $fileTypeMapper, PhpDocInheritanceResolver $phpDocInheritanceResolver, PhpVersion $phpVersion, NativeFunctionReflectionProvider $nativeFunctionReflectionProvider, StubPhpDocProvider $stubPhpDocProvider, FunctionReflectionFactory $functionReflectionFactory, RelativePathHelper $relativePathHelper, AnonymousClassNameHelper $anonymousClassNameHelper, FileHelper $fileHelper, PhpStormStubsSourceStubber $phpstormStubsSourceStubber, SignatureMapProvider $signatureMapProvider, array $universalObjectCratesClasses) { $this->reflectionProviderProvider = $reflectionProviderProvider; $this->initializerExprTypeResolver = $initializerExprTypeResolver; $this->classReflectionExtensionRegistryProvider = $classReflectionExtensionRegistryProvider; $this->reflector = $reflector; $this->fileTypeMapper = $fileTypeMapper; $this->phpDocInheritanceResolver = $phpDocInheritanceResolver; $this->phpVersion = $phpVersion; $this->nativeFunctionReflectionProvider = $nativeFunctionReflectionProvider; $this->stubPhpDocProvider = $stubPhpDocProvider; $this->functionReflectionFactory = $functionReflectionFactory; $this->relativePathHelper = $relativePathHelper; $this->anonymousClassNameHelper = $anonymousClassNameHelper; $this->fileHelper = $fileHelper; $this->phpstormStubsSourceStubber = $phpstormStubsSourceStubber; $this->signatureMapProvider = $signatureMapProvider; $this->universalObjectCratesClasses = $universalObjectCratesClasses; } public function hasClass(string $className) : bool { if (isset(self::$anonymousClasses[$className])) { return \true; } if (!ClassNameHelper::isValidClassName($className)) { return \false; } try { $this->reflector->reflectClass($className); return \true; } catch (IdentifierNotFound $e) { return \false; } catch (InvalidIdentifierName $e) { return \false; } } public function getClass(string $className) : ClassReflection { if (isset(self::$anonymousClasses[$className])) { return self::$anonymousClasses[$className]; } try { $reflectionClass = $this->reflector->reflectClass($className); } catch (IdentifierNotFound|InvalidIdentifierName $e) { throw new ClassNotFoundException($className); } $reflectionClassName = strtolower($reflectionClass->getName()); if (array_key_exists($reflectionClassName, $this->classReflections)) { return $this->classReflections[$reflectionClassName]; } $enumAdapter = base64_decode('UEhQU3RhblxCZXR0ZXJSZWZsZWN0aW9uXFJlZmxlY3Rpb25cQWRhcHRlclxSZWZsZWN0aW9uRW51bQ==', \true); $classReflection = new ClassReflection($this->reflectionProviderProvider->getReflectionProvider(), $this->initializerExprTypeResolver, $this->fileTypeMapper, $this->stubPhpDocProvider, $this->phpDocInheritanceResolver, $this->phpVersion, $this->signatureMapProvider, $this->classReflectionExtensionRegistryProvider->getRegistry()->getPropertiesClassReflectionExtensions(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getMethodsClassReflectionExtensions(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getAllowedSubTypesClassReflectionExtensions(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getRequireExtendsPropertyClassReflectionExtension(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getRequireExtendsMethodsClassReflectionExtension(), $reflectionClass->getName(), $reflectionClass instanceof ReflectionEnum && PHP_VERSION_ID >= 80000 ? new $enumAdapter($reflectionClass) : new ReflectionClass($reflectionClass), null, null, $this->stubPhpDocProvider->findClassPhpDoc($reflectionClass->getName()), $this->universalObjectCratesClasses); $this->classReflections[$reflectionClassName] = $classReflection; return $classReflection; } public function getClassName(string $className) : string { if (!$this->hasClass($className)) { throw new ClassNotFoundException($className); } if (isset(self::$anonymousClasses[$className])) { return self::$anonymousClasses[$className]->getDisplayName(); } $reflectionClass = $this->reflector->reflectClass($className); return $reflectionClass->getName(); } public function supportsAnonymousClasses() : bool { return \true; } public function getAnonymousClassReflection(Node\Stmt\Class_ $classNode, Scope $scope) : ClassReflection { if (isset($classNode->namespacedName)) { throw new ShouldNotHappenException(); } if (!$scope->isInTrait()) { $scopeFile = $scope->getFile(); } else { $scopeFile = $scope->getTraitReflection()->getFileName(); if ($scopeFile === null) { $scopeFile = $scope->getFile(); } } $filename = $this->fileHelper->normalizePath($this->relativePathHelper->getRelativePath($scopeFile), '/'); $className = $this->anonymousClassNameHelper->getAnonymousClassName($classNode, $scopeFile); $classNode->name = new Node\Identifier($className); if (isset(self::$anonymousClasses[$className])) { return self::$anonymousClasses[$className]; } $reflectionClass = \PHPStan\BetterReflection\Reflection\ReflectionClass::createFromNode($this->reflector, $classNode, new LocatedSource(FileReader::read($scopeFile), $className, $scopeFile), null); /** @var int|null $classLineIndex */ $classLineIndex = $classNode->getAttribute(AnonymousClassVisitor::ATTRIBUTE_LINE_INDEX); if ($classLineIndex === null) { $displayName = sprintf('class@anonymous/%s:%s', $filename, $classNode->getStartLine()); } else { $displayName = sprintf('class@anonymous/%s:%s:%d', $filename, $classNode->getStartLine(), $classLineIndex); } self::$anonymousClasses[$className] = new ClassReflection($this->reflectionProviderProvider->getReflectionProvider(), $this->initializerExprTypeResolver, $this->fileTypeMapper, $this->stubPhpDocProvider, $this->phpDocInheritanceResolver, $this->phpVersion, $this->signatureMapProvider, $this->classReflectionExtensionRegistryProvider->getRegistry()->getPropertiesClassReflectionExtensions(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getMethodsClassReflectionExtensions(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getAllowedSubTypesClassReflectionExtensions(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getRequireExtendsPropertyClassReflectionExtension(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getRequireExtendsMethodsClassReflectionExtension(), $displayName, new ReflectionClass($reflectionClass), $scopeFile, null, $this->stubPhpDocProvider->findClassPhpDoc($className), $this->universalObjectCratesClasses); $this->classReflections[$className] = self::$anonymousClasses[$className]; return self::$anonymousClasses[$className]; } public function hasFunction(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : bool { return $this->resolveFunctionName($nameNode, $namespaceAnswerer) !== null; } public function getFunction(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : FunctionReflection { $functionName = $this->resolveFunctionName($nameNode, $namespaceAnswerer); if ($functionName === null) { throw new FunctionNotFoundException((string) $nameNode); } $lowerCasedFunctionName = strtolower($functionName); if (isset($this->functionReflections[$lowerCasedFunctionName])) { return $this->functionReflections[$lowerCasedFunctionName]; } if (in_array($lowerCasedFunctionName, ['exit', 'die'], \true)) { return $this->functionReflections[$lowerCasedFunctionName] = new ExitFunctionReflection($lowerCasedFunctionName); } $nativeFunctionReflection = $this->nativeFunctionReflectionProvider->findFunctionReflection($lowerCasedFunctionName); if ($nativeFunctionReflection !== null) { $this->functionReflections[$lowerCasedFunctionName] = $nativeFunctionReflection; return $nativeFunctionReflection; } $this->functionReflections[$lowerCasedFunctionName] = $this->getCustomFunction($functionName); return $this->functionReflections[$lowerCasedFunctionName]; } private function getCustomFunction(string $functionName) : PhpFunctionReflection { $reflectionFunction = new ReflectionFunction($this->reflector->reflectFunction($functionName)); $templateTypeMap = TemplateTypeMap::createEmpty(); $phpDocParameterTypes = []; $phpDocReturnTag = null; $phpDocThrowsTag = null; $deprecatedTag = null; $isDeprecated = \false; $isInternal = \false; $isFinal = \false; $isPure = null; $asserts = Assertions::createEmpty(); $acceptsNamedArguments = \true; $phpDocComment = null; $phpDocParameterOutTags = []; $phpDocParameterImmediatelyInvokedCallable = []; $phpDocParameterClosureThisTypeTags = []; $resolvedPhpDoc = $this->stubPhpDocProvider->findFunctionPhpDoc($reflectionFunction->getName(), array_map(static function (ReflectionParameter $parameter) : string { return $parameter->getName(); }, $reflectionFunction->getParameters())); if ($resolvedPhpDoc === null && $reflectionFunction->getFileName() !== \false && $reflectionFunction->getDocComment() !== \false) { $docComment = $reflectionFunction->getDocComment(); $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($reflectionFunction->getFileName(), null, null, $reflectionFunction->getName(), $docComment); } if ($resolvedPhpDoc !== null) { $templateTypeMap = $resolvedPhpDoc->getTemplateTypeMap(); $phpDocParameterTypes = array_map(static function ($tag) { return $tag->getType(); }, $resolvedPhpDoc->getParamTags()); $phpDocReturnTag = $resolvedPhpDoc->getReturnTag(); $phpDocThrowsTag = $resolvedPhpDoc->getThrowsTag(); $deprecatedTag = $resolvedPhpDoc->getDeprecatedTag(); $isDeprecated = $resolvedPhpDoc->isDeprecated(); $isInternal = $resolvedPhpDoc->isInternal(); $isFinal = $resolvedPhpDoc->isFinal(); $isPure = $resolvedPhpDoc->isPure(); $asserts = Assertions::createFromResolvedPhpDocBlock($resolvedPhpDoc); if ($resolvedPhpDoc->hasPhpDocString()) { $phpDocComment = $resolvedPhpDoc->getPhpDocString(); } $acceptsNamedArguments = $resolvedPhpDoc->acceptsNamedArguments(); $phpDocParameterOutTags = $resolvedPhpDoc->getParamOutTags(); $phpDocParameterImmediatelyInvokedCallable = $resolvedPhpDoc->getParamsImmediatelyInvokedCallable(); $phpDocParameterClosureThisTypeTags = $resolvedPhpDoc->getParamClosureThisTags(); } return $this->functionReflectionFactory->create($reflectionFunction, $templateTypeMap, $phpDocParameterTypes, $phpDocReturnTag !== null ? $phpDocReturnTag->getType() : null, $phpDocThrowsTag !== null ? $phpDocThrowsTag->getType() : null, $deprecatedTag !== null ? $deprecatedTag->getMessage() : null, $isDeprecated, $isInternal, $isFinal, $reflectionFunction->getFileName() !== \false ? $reflectionFunction->getFileName() : null, $isPure, $asserts, $acceptsNamedArguments, $phpDocComment, array_map(static function (ParamOutTag $paramOutTag) : Type { return $paramOutTag->getType(); }, $phpDocParameterOutTags), $phpDocParameterImmediatelyInvokedCallable, array_map(static function (ParamClosureThisTag $tag) : Type { return $tag->getType(); }, $phpDocParameterClosureThisTypeTags)); } public function resolveFunctionName(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : ?string { $name = $nameNode->toLowerString(); if (in_array($name, ['exit', 'die'], \true)) { return $name; } return $this->resolveName($nameNode, function (string $name) : bool { try { $this->reflector->reflectFunction($name); return \true; } catch (IdentifierNotFound $e) { // pass } catch (InvalidIdentifierName $e) { // pass } if ($this->nativeFunctionReflectionProvider->findFunctionReflection($name) !== null) { return $this->phpstormStubsSourceStubber->isPresentFunction($name) !== \false; } return \false; }, $namespaceAnswerer); } public function hasConstant(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : bool { return $this->resolveConstantName($nameNode, $namespaceAnswerer) !== null; } public function getConstant(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : GlobalConstantReflection { $constantName = $this->resolveConstantName($nameNode, $namespaceAnswerer); if ($constantName === null) { throw new ConstantNotFoundException((string) $nameNode); } if (array_key_exists($constantName, $this->cachedConstants)) { return $this->cachedConstants[$constantName]; } $constantReflection = $this->reflector->reflectConstant($constantName); $fileName = $constantReflection->getFileName(); $constantValueType = $this->initializerExprTypeResolver->getType($constantReflection->getValueExpression(), InitializerExprContext::fromGlobalConstant($constantReflection)); $docComment = $constantReflection->getDocComment(); $isDeprecated = TrinaryLogic::createNo(); $deprecatedDescription = null; if ($docComment !== null) { $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($fileName, null, null, null, $docComment); $isDeprecated = TrinaryLogic::createFromBoolean($resolvedPhpDoc->isDeprecated()); if ($resolvedPhpDoc->isDeprecated() && $resolvedPhpDoc->getDeprecatedTag() !== null) { $deprecatedMessage = $resolvedPhpDoc->getDeprecatedTag()->getMessage(); $matches = Strings::match($deprecatedMessage ?? '', '#^(\\d+)\\.(\\d+)(?:\\.(\\d+))?$#'); if ($matches !== null) { $major = $matches[1]; $minor = $matches[2]; $patch = $matches[3] ?? 0; $versionId = sprintf('%d%02d%02d', $major, $minor, $patch); $isDeprecated = TrinaryLogic::createFromBoolean($this->phpVersion->getVersionId() >= $versionId); } else { // filter raw version number messages like in // https://github.com/JetBrains/phpstorm-stubs/blob/9608c953230b08f07b703ecfe459cc58d5421437/filter/filter.php#L478 $deprecatedDescription = $deprecatedMessage; } } } return $this->cachedConstants[$constantName] = new RuntimeConstantReflection($constantName, $constantValueType, $fileName, $isDeprecated, $deprecatedDescription); } public function resolveConstantName(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : ?string { return $this->resolveName($nameNode, function (string $name) : bool { try { $this->reflector->reflectConstant($name); return \true; } catch (IdentifierNotFound $e) { // pass } catch (InvalidIdentifierName $e) { // pass } catch (UnableToCompileNode $e) { // pass } return \false; }, $namespaceAnswerer); } /** * @param Closure(string $name): bool $existsCallback */ private function resolveName(Node\Name $nameNode, Closure $existsCallback, ?NamespaceAnswerer $namespaceAnswerer) : ?string { $name = (string) $nameNode; if ($namespaceAnswerer !== null && $namespaceAnswerer->getNamespace() !== null && !$nameNode->isFullyQualified()) { $namespacedName = sprintf('%s\\%s', $namespaceAnswerer->getNamespace(), $name); if ($existsCallback($namespacedName)) { return $namespacedName; } } if ($existsCallback($name)) { return $name; } return null; } } */ private $classReflections = []; /** @var array */ private $constantReflections = []; /** @var array */ private $functionReflections = []; public function __construct(Reflector $reflector) { $this->reflector = $reflector; } public function reflectClass(string $className) : ReflectionClass { $lowerClassName = strtolower($className); if (array_key_exists($lowerClassName, $this->classReflections) && $this->classReflections[$lowerClassName] !== null) { return $this->classReflections[$lowerClassName]; } if (array_key_exists($className, $this->classReflections)) { $classReflection = $this->classReflections[$className]; if ($classReflection === null) { throw IdentifierNotFound::fromIdentifier(new Identifier($className, new IdentifierType(IdentifierType::IDENTIFIER_CLASS))); } return $classReflection; } try { return $this->classReflections[$lowerClassName] = $this->reflector->reflectClass($className); } catch (IdentifierNotFound $e) { $this->classReflections[$className] = null; throw $e; } } public function reflectConstant(string $constantName) : ReflectionConstant { if (array_key_exists($constantName, $this->constantReflections)) { $constantReflection = $this->constantReflections[$constantName]; if ($constantReflection === null) { throw IdentifierNotFound::fromIdentifier(new Identifier($constantName, new IdentifierType(IdentifierType::IDENTIFIER_CONSTANT))); } return $constantReflection; } try { return $this->constantReflections[$constantName] = $this->reflector->reflectConstant($constantName); } catch (IdentifierNotFound $e) { $this->constantReflections[$constantName] = null; throw $e; } } public function reflectFunction(string $functionName) : ReflectionFunction { $lowerFunctionName = strtolower($functionName); if (array_key_exists($lowerFunctionName, $this->functionReflections)) { $functionReflection = $this->functionReflections[$lowerFunctionName]; if ($functionReflection === null) { throw IdentifierNotFound::fromIdentifier(new Identifier($functionName, new IdentifierType(IdentifierType::IDENTIFIER_FUNCTION))); } return $functionReflection; } try { return $this->functionReflections[$lowerFunctionName] = $this->reflector->reflectFunction($functionName); } catch (IdentifierNotFound $e) { $this->functionReflections[$lowerFunctionName] = null; throw $e; } } public function reflectAllClasses() : iterable { return $this->reflector->reflectAllClasses(); } public function reflectAllFunctions() : iterable { return $this->reflector->reflectAllFunctions(); } public function reflectAllConstants() : iterable { return $this->reflector->reflectAllConstants(); } } phpParser = $phpParser; $this->printer = $printer; $this->phpVersion = $phpVersion; } public function create() : PhpStormStubsSourceStubber { return new PhpStormStubsSourceStubber($this->phpParser, $this->printer, $this->phpVersion->getVersionId()); } } printer = $printer; $this->phpVersion = $phpVersion; } public function create() : ReflectionSourceStubber { return new ReflectionSourceStubber($this->printer, $this->phpVersion->getVersionId()); } } */ private $passedArgs; /** @var ParameterReflectionWithPhpDocs[]|null */ private $parameters = null; /** * @var ?Type */ private $returnTypeWithUnresolvableTemplateTypes = null; /** * @var ?Type */ private $phpDocReturnTypeWithUnresolvableTemplateTypes = null; /** * @var ?Type */ private $returnType = null; /** * @var ?Type */ private $phpDocReturnType = null; /** * @param array $passedArgs */ public function __construct(\PHPStan\Reflection\ParametersAcceptorWithPhpDocs $parametersAcceptor, TemplateTypeMap $resolvedTemplateTypeMap, TemplateTypeVarianceMap $callSiteVarianceMap, array $passedArgs) { $this->parametersAcceptor = $parametersAcceptor; $this->resolvedTemplateTypeMap = $resolvedTemplateTypeMap; $this->callSiteVarianceMap = $callSiteVarianceMap; $this->passedArgs = $passedArgs; } public function getOriginalParametersAcceptor() : \PHPStan\Reflection\ParametersAcceptor { return $this->parametersAcceptor; } public function getTemplateTypeMap() : TemplateTypeMap { return $this->parametersAcceptor->getTemplateTypeMap(); } public function getResolvedTemplateTypeMap() : TemplateTypeMap { return $this->resolvedTemplateTypeMap; } public function getCallSiteVarianceMap() : TemplateTypeVarianceMap { return $this->callSiteVarianceMap; } public function getParameters() : array { $parameters = $this->parameters; if ($parameters === null) { $parameters = array_map(function (\PHPStan\Reflection\ParameterReflectionWithPhpDocs $param) : \PHPStan\Reflection\ParameterReflectionWithPhpDocs { $paramType = TypeUtils::resolveLateResolvableTypes(TemplateTypeHelper::resolveTemplateTypes($this->resolveConditionalTypesForParameter($param->getType()), $this->resolvedTemplateTypeMap, $this->callSiteVarianceMap, TemplateTypeVariance::createContravariant()), \false); $paramOutType = $param->getOutType(); if ($paramOutType !== null) { $paramOutType = TypeUtils::resolveLateResolvableTypes(TemplateTypeHelper::resolveTemplateTypes($this->resolveConditionalTypesForParameter($paramOutType), $this->resolvedTemplateTypeMap, $this->callSiteVarianceMap, TemplateTypeVariance::createCovariant()), \false); } $closureThisType = $param->getClosureThisType(); if ($closureThisType !== null) { $closureThisType = TypeUtils::resolveLateResolvableTypes(TemplateTypeHelper::resolveTemplateTypes($this->resolveConditionalTypesForParameter($closureThisType), $this->resolvedTemplateTypeMap, $this->callSiteVarianceMap, TemplateTypeVariance::createCovariant()), \false); } return new DummyParameterWithPhpDocs($param->getName(), $paramType, $param->isOptional(), $param->passedByReference(), $param->isVariadic(), $param->getDefaultValue(), $param->getNativeType(), $param->getPhpDocType(), $paramOutType, $param->isImmediatelyInvokedCallable(), $closureThisType); }, $this->parametersAcceptor->getParameters()); $this->parameters = $parameters; } return $parameters; } public function isVariadic() : bool { return $this->parametersAcceptor->isVariadic(); } public function getReturnTypeWithUnresolvableTemplateTypes() : Type { return $this->returnTypeWithUnresolvableTemplateTypes = $this->returnTypeWithUnresolvableTemplateTypes ?? $this->resolveConditionalTypesForParameter($this->resolveResolvableTemplateTypes($this->parametersAcceptor->getReturnType(), TemplateTypeVariance::createCovariant())); } public function getPhpDocReturnTypeWithUnresolvableTemplateTypes() : Type { return $this->phpDocReturnTypeWithUnresolvableTemplateTypes = $this->phpDocReturnTypeWithUnresolvableTemplateTypes ?? $this->resolveConditionalTypesForParameter($this->resolveResolvableTemplateTypes($this->parametersAcceptor->getPhpDocReturnType(), TemplateTypeVariance::createCovariant())); } public function getReturnType() : Type { $type = $this->returnType; if ($type === null) { $type = TypeUtils::resolveLateResolvableTypes(TemplateTypeHelper::resolveTemplateTypes($this->getReturnTypeWithUnresolvableTemplateTypes(), $this->resolvedTemplateTypeMap, $this->callSiteVarianceMap, TemplateTypeVariance::createCovariant()), \false); $this->returnType = $type; } return $type; } public function getPhpDocReturnType() : Type { $type = $this->phpDocReturnType; if ($type === null) { $type = TypeUtils::resolveLateResolvableTypes(TemplateTypeHelper::resolveTemplateTypes($this->getPhpDocReturnTypeWithUnresolvableTemplateTypes(), $this->resolvedTemplateTypeMap, $this->callSiteVarianceMap, TemplateTypeVariance::createCovariant()), \false); $this->phpDocReturnType = $type; } return $type; } public function getNativeReturnType() : Type { return $this->parametersAcceptor->getNativeReturnType(); } private function resolveResolvableTemplateTypes(Type $type, TemplateTypeVariance $positionVariance) : Type { $references = $type->getReferencedTemplateTypes($positionVariance); $objectCb = function (Type $type, callable $traverse) use($references) : Type { if ($type instanceof TemplateType && !$type->isArgument() && $type->getScope()->getFunctionName() !== null) { $newType = $this->resolvedTemplateTypeMap->getType($type->getName()); if ($newType === null || $newType instanceof ErrorType) { return $traverse($type); } $newType = TemplateTypeHelper::generalizeInferredTemplateType($type, $newType); $variance = TemplateTypeVariance::createInvariant(); foreach ($references as $reference) { // this uses identity to distinguish between different occurrences of the same template type // see https://github.com/phpstan/phpstan-src/pull/2485#discussion_r1328555397 for details if ($reference->getType() === $type) { $variance = $reference->getPositionVariance(); break; } } $callSiteVariance = $this->callSiteVarianceMap->getVariance($type->getName()); if ($callSiteVariance === null || $callSiteVariance->invariant()) { return $newType; } if (!$callSiteVariance->covariant() && $variance->covariant()) { return $traverse($type->getBound()); } if (!$callSiteVariance->contravariant() && $variance->contravariant()) { return new NonAcceptingNeverType(); } return $newType; } return $traverse($type); }; return TypeTraverser::map($type, function (Type $type, callable $traverse) use($references, $objectCb) : Type { if (BleedingEdgeToggle::isBleedingEdge() && ($type instanceof GenericObjectType || $type instanceof GenericStaticType)) { return TypeTraverser::map($type, $objectCb); } if ($type instanceof TemplateType && !$type->isArgument()) { $newType = $this->resolvedTemplateTypeMap->getType($type->getName()); if ($newType === null || $newType instanceof ErrorType) { return $traverse($type); } $variance = TemplateTypeVariance::createInvariant(); foreach ($references as $reference) { // this uses identity to distinguish between different occurrences of the same template type // see https://github.com/phpstan/phpstan-src/pull/2485#discussion_r1328555397 for details if ($reference->getType() === $type) { $variance = $reference->getPositionVariance(); break; } } $callSiteVariance = $this->callSiteVarianceMap->getVariance($type->getName()); if ($callSiteVariance === null || $callSiteVariance->invariant()) { return $newType; } if (!$callSiteVariance->covariant() && $variance->covariant()) { return $traverse($type->getBound()); } if (!$callSiteVariance->contravariant() && $variance->contravariant()) { return new NonAcceptingNeverType(); } return $newType; } return $traverse($type); }); } private function resolveConditionalTypesForParameter(Type $type) : Type { return TypeTraverser::map($type, function (Type $type, callable $traverse) : Type { if ($type instanceof ConditionalTypeForParameter && array_key_exists($type->getParameterName(), $this->passedArgs)) { $type = $type->toConditional($this->passedArgs[$type->getParameterName()]); } return $traverse($type); }); } } */ public function getAllowedSubTypes(\PHPStan\Reflection\ClassReflection $classReflection) : array; } > */ private $inProcess = []; /** * @param string[] $mixinExcludeClasses */ public function __construct(array $mixinExcludeClasses) { $this->mixinExcludeClasses = $mixinExcludeClasses; } public function hasMethod(ClassReflection $classReflection, string $methodName) : bool { return $this->findMethod($classReflection, $methodName) !== null; } public function getMethod(ClassReflection $classReflection, string $methodName) : MethodReflection { $method = $this->findMethod($classReflection, $methodName); if ($method === null) { throw new ShouldNotHappenException(); } return $method; } private function findMethod(ClassReflection $classReflection, string $methodName) : ?MethodReflection { $mixinTypes = $classReflection->getResolvedMixinTypes(); foreach ($mixinTypes as $type) { if (count(array_intersect($type->getObjectClassNames(), $this->mixinExcludeClasses)) > 0) { continue; } $typeDescription = $type->describe(VerbosityLevel::typeOnly()); if (isset($this->inProcess[$typeDescription][$methodName])) { continue; } $this->inProcess[$typeDescription][$methodName] = \true; if (!$type->hasMethod($methodName)->yes()) { unset($this->inProcess[$typeDescription][$methodName]); continue; } $method = $type->getMethod($methodName, new OutOfClassScope()); unset($this->inProcess[$typeDescription][$methodName]); $static = $method->isStatic(); if (!$static && $classReflection->hasNativeMethod('__callStatic')) { $static = \true; } return new \PHPStan\Reflection\Mixin\MixinMethodReflection($method, $static); } foreach ($classReflection->getTraits() as $traitClass) { $methodWithDeclaringClass = $this->findMethod($traitClass, $methodName); if ($methodWithDeclaringClass === null) { continue; } return $methodWithDeclaringClass; } $parentClass = $classReflection->getParentClass(); while ($parentClass !== null) { $method = $this->findMethod($parentClass, $methodName); if ($method !== null) { return $method; } $parentClass = $parentClass->getParentClass(); } return null; } } > */ private $inProcess = []; /** * @param string[] $mixinExcludeClasses */ public function __construct(array $mixinExcludeClasses) { $this->mixinExcludeClasses = $mixinExcludeClasses; } public function hasProperty(ClassReflection $classReflection, string $propertyName) : bool { return $this->findProperty($classReflection, $propertyName) !== null; } public function getProperty(ClassReflection $classReflection, string $propertyName) : PropertyReflection { $property = $this->findProperty($classReflection, $propertyName); if ($property === null) { throw new ShouldNotHappenException(); } return $property; } private function findProperty(ClassReflection $classReflection, string $propertyName) : ?PropertyReflection { $mixinTypes = $classReflection->getResolvedMixinTypes(); foreach ($mixinTypes as $type) { if (count(array_intersect($type->getObjectClassNames(), $this->mixinExcludeClasses)) > 0) { continue; } $typeDescription = $type->describe(VerbosityLevel::typeOnly()); if (isset($this->inProcess[$typeDescription][$propertyName])) { continue; } $this->inProcess[$typeDescription][$propertyName] = \true; if (!$type->hasProperty($propertyName)->yes()) { unset($this->inProcess[$typeDescription][$propertyName]); continue; } $property = $type->getProperty($propertyName, new OutOfClassScope()); unset($this->inProcess[$typeDescription][$propertyName]); return $property; } foreach ($classReflection->getTraits() as $traitClass) { $methodWithDeclaringClass = $this->findProperty($traitClass, $propertyName); if ($methodWithDeclaringClass === null) { continue; } return $methodWithDeclaringClass; } $parentClass = $classReflection->getParentClass(); while ($parentClass !== null) { $property = $this->findProperty($parentClass, $propertyName); if ($property !== null) { return $property; } $parentClass = $parentClass->getParentClass(); } return null; } } reflection = $reflection; $this->static = $static; } public function getDeclaringClass() : ClassReflection { return $this->reflection->getDeclaringClass(); } public function isStatic() : bool { return $this->static; } public function isPrivate() : bool { return $this->reflection->isPrivate(); } public function isPublic() : bool { return $this->reflection->isPublic(); } public function getDocComment() : ?string { return $this->reflection->getDocComment(); } public function getName() : string { return $this->reflection->getName(); } public function getPrototype() : ClassMemberReflection { return $this->reflection->getPrototype(); } public function getVariants() : array { return $this->reflection->getVariants(); } public function isDeprecated() : TrinaryLogic { return $this->reflection->isDeprecated(); } public function getDeprecatedDescription() : ?string { return $this->reflection->getDeprecatedDescription(); } public function isFinal() : TrinaryLogic { return $this->reflection->isFinal(); } public function isInternal() : TrinaryLogic { return $this->reflection->isInternal(); } public function getThrowType() : ?Type { return $this->reflection->getThrowType(); } public function hasSideEffects() : TrinaryLogic { return $this->reflection->hasSideEffects(); } } value = $value; } private static function create(int $value) : self { if (!array_key_exists($value, self::$registry)) { self::$registry[$value] = new self($value); } return self::$registry[$value]; } public static function createNo() : self { return self::create(self::NO); } public static function createCreatesNewVariable() : self { return self::create(self::CREATES_NEW_VARIABLE); } public static function createReadsArgument() : self { return self::create(self::READS_ARGUMENT); } public function no() : bool { return $this->value === self::NO; } public function yes() : bool { return !$this->no(); } public function equals(self $other) : bool { return $this->value === $other->value; } public function createsNewVariable() : bool { return $this->value === self::CREATES_NEW_VARIABLE; } public function combine(self $other) : self { if ($this->value > $other->value) { return $this; } elseif ($this->value < $other->value) { return $other; } return $this; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self { return new self($properties['value']); } } initializerExprTypeResolver = $initializerExprTypeResolver; $this->declaringClass = $declaringClass; $this->reflection = $reflection; $this->nativeType = $nativeType; $this->phpDocType = $phpDocType; $this->deprecatedDescription = $deprecatedDescription; $this->isDeprecated = $isDeprecated; $this->isInternal = $isInternal; $this->isFinal = $isFinal; } public function getName() : string { return $this->reflection->getName(); } public function getFileName() : ?string { return $this->declaringClass->getFileName(); } /** * @deprecated Use getValueExpr() * @return mixed */ public function getValue() { try { return $this->reflection->getValue(); } catch (UnableToCompileNode $e) { return NAN; } } public function getValueExpr() : Expr { return $this->reflection->getValueExpression(); } public function hasPhpDocType() : bool { return $this->phpDocType !== null; } public function getPhpDocType() : ?Type { return $this->phpDocType; } public function hasNativeType() : bool { return $this->nativeType !== null; } public function getNativeType() : ?Type { return $this->nativeType; } public function getValueType() : Type { if ($this->valueType === null) { if ($this->phpDocType !== null) { if ($this->nativeType !== null) { return $this->valueType = TypehintHelper::decideType($this->nativeType, $this->phpDocType); } return $this->phpDocType; } elseif ($this->nativeType !== null) { return $this->nativeType; } $this->valueType = $this->initializerExprTypeResolver->getType($this->getValueExpr(), \PHPStan\Reflection\InitializerExprContext::fromClassReflection($this->declaringClass)); } return $this->valueType; } public function getDeclaringClass() : \PHPStan\Reflection\ClassReflection { return $this->declaringClass; } public function isStatic() : bool { return \true; } public function isPrivate() : bool { return $this->reflection->isPrivate(); } public function isPublic() : bool { return $this->reflection->isPublic(); } public function isFinal() : bool { return $this->isFinal || $this->reflection->isFinal(); } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->isDeprecated); } public function getDeprecatedDescription() : ?string { if ($this->isDeprecated) { return $this->deprecatedDescription; } return null; } public function isInternal() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->isInternal); } public function getDocComment() : ?string { $docComment = $this->reflection->getDocComment(); if ($docComment === \false) { return null; } return $docComment; } } reflection = $reflection; $this->resolvedTemplateTypeMap = $resolvedTemplateTypeMap; $this->callSiteVarianceMap = $callSiteVarianceMap; } public function getName() : string { return $this->reflection->getName(); } public function getPrototype() : \PHPStan\Reflection\ClassMemberReflection { return $this->reflection->getPrototype(); } public function getVariants() : array { $variants = $this->variants; if ($variants !== null) { return $variants; } return $this->variants = $this->resolveVariants($this->reflection->getVariants()); } public function getOnlyVariant() : \PHPStan\Reflection\ParametersAcceptorWithPhpDocs { return $this->getVariants()[0]; } public function getNamedArgumentsVariants() : ?array { $variants = $this->namedArgumentVariants; if ($variants !== null) { return $variants; } $innerVariants = $this->reflection->getNamedArgumentsVariants(); if ($innerVariants === null) { return null; } return $this->namedArgumentVariants = $this->resolveVariants($innerVariants); } /** * @param ParametersAcceptorWithPhpDocs[] $variants * @return ResolvedFunctionVariant[] */ private function resolveVariants(array $variants) : array { $result = []; foreach ($variants as $variant) { $result[] = new \PHPStan\Reflection\ResolvedFunctionVariantWithOriginal($variant, $this->resolvedTemplateTypeMap, $this->callSiteVarianceMap, []); } return $result; } public function getDeclaringClass() : \PHPStan\Reflection\ClassReflection { return $this->reflection->getDeclaringClass(); } public function getDeclaringTrait() : ?\PHPStan\Reflection\ClassReflection { if ($this->reflection instanceof PhpMethodReflection) { return $this->reflection->getDeclaringTrait(); } return null; } public function isStatic() : bool { return $this->reflection->isStatic(); } public function isPrivate() : bool { return $this->reflection->isPrivate(); } public function isPublic() : bool { return $this->reflection->isPublic(); } public function getDocComment() : ?string { return $this->reflection->getDocComment(); } public function isDeprecated() : TrinaryLogic { return $this->reflection->isDeprecated(); } public function getDeprecatedDescription() : ?string { return $this->reflection->getDeprecatedDescription(); } public function isFinal() : TrinaryLogic { return $this->reflection->isFinal(); } public function isFinalByKeyword() : TrinaryLogic { return $this->reflection->isFinalByKeyword(); } public function isInternal() : TrinaryLogic { return $this->reflection->isInternal(); } public function getThrowType() : ?Type { return $this->reflection->getThrowType(); } public function hasSideEffects() : TrinaryLogic { return $this->reflection->hasSideEffects(); } public function isPure() : TrinaryLogic { return $this->reflection->isPure(); } public function getAsserts() : \PHPStan\Reflection\Assertions { return $this->asserts = $this->asserts ?? $this->reflection->getAsserts()->mapTypes(function (Type $type) { return TemplateTypeHelper::resolveTemplateTypes($type, $this->resolvedTemplateTypeMap, $this->callSiteVarianceMap, TemplateTypeVariance::createInvariant()); }); } public function acceptsNamedArguments() : bool { return $this->reflection->acceptsNamedArguments(); } public function getSelfOutType() : ?Type { if ($this->selfOutType === \false) { $selfOutType = $this->reflection->getSelfOutType(); if ($selfOutType !== null) { $selfOutType = TemplateTypeHelper::resolveTemplateTypes($selfOutType, $this->resolvedTemplateTypeMap, $this->callSiteVarianceMap, TemplateTypeVariance::createInvariant()); } $this->selfOutType = $selfOutType; } return $this->selfOutType; } public function returnsByReference() : TrinaryLogic { return $this->reflection->returnsByReference(); } public function isAbstract() : TrinaryLogic { $abstract = $this->reflection->isAbstract(); if (is_bool($abstract)) { return TrinaryLogic::createFromBoolean($abstract); } return $abstract; } } 0 && count($parametersAcceptors) > 0) { $arrayMapArgs = $args[0]->value->getAttribute(ArrayMapArgVisitor::ATTRIBUTE_NAME); if ($arrayMapArgs !== null) { $acceptor = $parametersAcceptors[0]; $parameters = $acceptor->getParameters(); $callbackParameters = []; foreach ($arrayMapArgs as $arg) { $argType = $scope->getType($arg->value); if ($arg->unpack) { $constantArrays = $argType->getConstantArrays(); if (count($constantArrays) > 0) { foreach ($constantArrays as $constantArray) { $valueTypes = $constantArray->getValueTypes(); foreach ($valueTypes as $valueType) { $callbackParameters[] = new DummyParameter('item', $scope->getIterableValueType($valueType), \false, \PHPStan\Reflection\PassedByReference::createNo(), \false, null); } } } } else { $callbackParameters[] = new DummyParameter('item', $scope->getIterableValueType($argType), \false, \PHPStan\Reflection\PassedByReference::createNo(), \false, null); } } $parameters[0] = new NativeParameterReflection($parameters[0]->getName(), $parameters[0]->isOptional(), new UnionType([new CallableType($callbackParameters, new MixedType(), \false), new NullType()]), $parameters[0]->passedByReference(), $parameters[0]->isVariadic(), $parameters[0]->getDefaultValue()); $parametersAcceptors = [new \PHPStan\Reflection\FunctionVariant($acceptor->getTemplateTypeMap(), $acceptor->getResolvedTemplateTypeMap(), $parameters, $acceptor->isVariadic(), $acceptor->getReturnType(), $acceptor instanceof \PHPStan\Reflection\ParametersAcceptorWithPhpDocs ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty())]; } if (count($args) >= 3 && (bool) $args[0]->getAttribute(CurlSetOptArgVisitor::ATTRIBUTE_NAME)) { $optType = $scope->getType($args[1]->value); if ($optType instanceof ConstantIntegerType) { $optValueType = self::getCurlOptValueType($optType->getValue()); if ($optValueType !== null) { $acceptor = $parametersAcceptors[0]; $parameters = $acceptor->getParameters(); $parameters[2] = new NativeParameterReflection($parameters[2]->getName(), $parameters[2]->isOptional(), $optValueType, $parameters[2]->passedByReference(), $parameters[2]->isVariadic(), $parameters[2]->getDefaultValue()); $parametersAcceptors = [new \PHPStan\Reflection\FunctionVariant($acceptor->getTemplateTypeMap(), $acceptor->getResolvedTemplateTypeMap(), $parameters, $acceptor->isVariadic(), $acceptor->getReturnType(), $acceptor instanceof \PHPStan\Reflection\ParametersAcceptorWithPhpDocs ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty())]; } } } if (isset($args[0]) && (bool) $args[0]->getAttribute(ArrayFilterArgVisitor::ATTRIBUTE_NAME)) { if (isset($args[2])) { $mode = $scope->getType($args[2]->value); if ($mode instanceof ConstantIntegerType) { if ($mode->getValue() === ARRAY_FILTER_USE_KEY) { $arrayFilterParameters = [new DummyParameter('key', $scope->getIterableKeyType($scope->getType($args[0]->value)), \false, \PHPStan\Reflection\PassedByReference::createNo(), \false, null)]; } elseif ($mode->getValue() === ARRAY_FILTER_USE_BOTH) { $arrayFilterParameters = [new DummyParameter('item', $scope->getIterableValueType($scope->getType($args[0]->value)), \false, \PHPStan\Reflection\PassedByReference::createNo(), \false, null), new DummyParameter('key', $scope->getIterableKeyType($scope->getType($args[0]->value)), \false, \PHPStan\Reflection\PassedByReference::createNo(), \false, null)]; } } } $acceptor = $parametersAcceptors[0]; $parameters = $acceptor->getParameters(); $parameters[1] = new NativeParameterReflection($parameters[1]->getName(), $parameters[1]->isOptional(), new UnionType([new CallableType($arrayFilterParameters ?? [new DummyParameter('item', $scope->getIterableValueType($scope->getType($args[0]->value)), \false, \PHPStan\Reflection\PassedByReference::createNo(), \false, null)], new BooleanType(), \false), new NullType()]), $parameters[1]->passedByReference(), $parameters[1]->isVariadic(), $parameters[1]->getDefaultValue()); $parametersAcceptors = [new \PHPStan\Reflection\FunctionVariant($acceptor->getTemplateTypeMap(), $acceptor->getResolvedTemplateTypeMap(), $parameters, $acceptor->isVariadic(), $acceptor->getReturnType(), $acceptor instanceof \PHPStan\Reflection\ParametersAcceptorWithPhpDocs ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty())]; } if (isset($args[0]) && (bool) $args[0]->getAttribute(ArrayWalkArgVisitor::ATTRIBUTE_NAME)) { $arrayWalkParameters = [new DummyParameter('item', $scope->getIterableValueType($scope->getType($args[0]->value)), \false, \PHPStan\Reflection\PassedByReference::createReadsArgument(), \false, null), new DummyParameter('key', $scope->getIterableKeyType($scope->getType($args[0]->value)), \false, \PHPStan\Reflection\PassedByReference::createNo(), \false, null)]; if (isset($args[2])) { $arrayWalkParameters[] = new DummyParameter('arg', $scope->getType($args[2]->value), \false, \PHPStan\Reflection\PassedByReference::createNo(), \false, null); } $acceptor = $parametersAcceptors[0]; $parameters = $acceptor->getParameters(); $parameters[1] = new NativeParameterReflection($parameters[1]->getName(), $parameters[1]->isOptional(), new CallableType($arrayWalkParameters, new MixedType(), \false), $parameters[1]->passedByReference(), $parameters[1]->isVariadic(), $parameters[1]->getDefaultValue()); $parametersAcceptors = [new \PHPStan\Reflection\FunctionVariant($acceptor->getTemplateTypeMap(), $acceptor->getResolvedTemplateTypeMap(), $parameters, $acceptor->isVariadic(), $acceptor->getReturnType(), $acceptor instanceof \PHPStan\Reflection\ParametersAcceptorWithPhpDocs ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty())]; } if (isset($args[0]) && (bool) $args[0]->getAttribute(ArrayFindArgVisitor::ATTRIBUTE_NAME)) { $acceptor = $parametersAcceptors[0]; $parameters = $acceptor->getParameters(); $argType = $scope->getType($args[0]->value); $parameters[1] = new NativeParameterReflection($parameters[1]->getName(), $parameters[1]->isOptional(), new CallableType([new DummyParameter('value', $scope->getIterableValueType($argType), \false, \PHPStan\Reflection\PassedByReference::createNo(), \false, null), new DummyParameter('key', $scope->getIterableKeyType($argType), \false, \PHPStan\Reflection\PassedByReference::createNo(), \false, null)], new BooleanType(), \false), $parameters[1]->passedByReference(), $parameters[1]->isVariadic(), $parameters[1]->getDefaultValue()); $parametersAcceptors = [new \PHPStan\Reflection\FunctionVariant($acceptor->getTemplateTypeMap(), $acceptor->getResolvedTemplateTypeMap(), $parameters, $acceptor->isVariadic(), $acceptor->getReturnType(), $acceptor instanceof \PHPStan\Reflection\ParametersAcceptorWithPhpDocs ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty())]; } if (isset($args[0])) { $closureBindToVar = $args[0]->getAttribute(ClosureBindToVarVisitor::ATTRIBUTE_NAME); if ($closureBindToVar !== null && $closureBindToVar instanceof Node\Expr\Variable && is_string($closureBindToVar->name)) { $varType = $scope->getType($closureBindToVar); if ((new ObjectType(Closure::class))->isSuperTypeOf($varType)->yes()) { $inFunction = $scope->getFunction(); if ($inFunction !== null) { $closureThisParameters = []; foreach ($inFunction->getParameters() as $parameter) { if ($parameter->getClosureThisType() === null) { continue; } $closureThisParameters[$parameter->getName()] = $parameter->getClosureThisType(); } if (array_key_exists($closureBindToVar->name, $closureThisParameters)) { if ($scope->hasExpressionType(new ParameterVariableOriginalValueExpr($closureBindToVar->name))->yes()) { $acceptor = $parametersAcceptors[0]; $parameters = $acceptor->getParameters(); $parameters[0] = new NativeParameterReflection($parameters[0]->getName(), $parameters[0]->isOptional(), $closureThisParameters[$closureBindToVar->name], $parameters[0]->passedByReference(), $parameters[0]->isVariadic(), $parameters[0]->getDefaultValue()); $parametersAcceptors = [new \PHPStan\Reflection\FunctionVariant($acceptor->getTemplateTypeMap(), $acceptor->getResolvedTemplateTypeMap(), $parameters, $acceptor->isVariadic(), $acceptor->getReturnType(), $acceptor instanceof \PHPStan\Reflection\ParametersAcceptorWithPhpDocs ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty())]; } } } } } if ($args[0]->getAttribute(ClosureBindArgVisitor::ATTRIBUTE_NAME) !== null && $args[0]->value instanceof Node\Expr\Variable && is_string($args[0]->value->name)) { $closureVarName = $args[0]->value->name; $inFunction = $scope->getFunction(); if ($inFunction !== null) { $closureThisParameters = []; foreach ($inFunction->getParameters() as $parameter) { if ($parameter->getClosureThisType() === null) { continue; } $closureThisParameters[$parameter->getName()] = $parameter->getClosureThisType(); } if (array_key_exists($closureVarName, $closureThisParameters)) { if ($scope->hasExpressionType(new ParameterVariableOriginalValueExpr($closureVarName))->yes()) { $acceptor = $parametersAcceptors[0]; $parameters = $acceptor->getParameters(); $parameters[1] = new NativeParameterReflection($parameters[1]->getName(), $parameters[1]->isOptional(), $closureThisParameters[$closureVarName], $parameters[1]->passedByReference(), $parameters[1]->isVariadic(), $parameters[1]->getDefaultValue()); $parametersAcceptors = [new \PHPStan\Reflection\FunctionVariant($acceptor->getTemplateTypeMap(), $acceptor->getResolvedTemplateTypeMap(), $parameters, $acceptor->isVariadic(), $acceptor->getReturnType(), $acceptor instanceof \PHPStan\Reflection\ParametersAcceptorWithPhpDocs ? $acceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty())]; } } } } } } if (count($parametersAcceptors) === 1) { $acceptor = $parametersAcceptors[0]; if (!self::hasAcceptorTemplateOrLateResolvableType($acceptor)) { return $acceptor; } } $reorderedArgs = $args; $parameters = null; $singleParametersAcceptor = null; if (count($parametersAcceptors) === 1) { $reorderedArgs = ArgumentsNormalizer::reorderArgs($parametersAcceptors[0], $args); $singleParametersAcceptor = $parametersAcceptors[0]; } $hasName = \false; foreach ($reorderedArgs ?? $args as $i => $arg) { $originalArg = $arg->getAttribute(ArgumentsNormalizer::ORIGINAL_ARG_ATTRIBUTE) ?? $arg; $parameter = null; if ($singleParametersAcceptor !== null) { $parameters = $singleParametersAcceptor->getParameters(); if (isset($parameters[$i])) { $parameter = $parameters[$i]; } elseif (count($parameters) > 0 && $singleParametersAcceptor->isVariadic()) { $parameter = $parameters[count($parameters) - 1]; } } if ($parameter !== null && $scope instanceof MutatingScope) { $scope = $scope->pushInFunctionCall(null, $parameter); } $type = $scope->getType($originalArg->value); if ($parameter !== null && $scope instanceof MutatingScope) { $scope = $scope->popInFunctionCall(); } if ($originalArg->name !== null) { $index = $originalArg->name->toString(); $hasName = \true; } else { $index = $i; } if ($originalArg->unpack) { $unpack = \true; $types[$index] = $type->getIterableValueType(); } else { $types[$index] = $type; } } if ($hasName && $namedArgumentsVariants !== null) { return self::selectFromTypes($types, $namedArgumentsVariants, $unpack); } return self::selectFromTypes($types, $parametersAcceptors, $unpack); } private static function hasAcceptorTemplateOrLateResolvableType(\PHPStan\Reflection\ParametersAcceptor $acceptor) : bool { if (self::hasTemplateOrLateResolvableType($acceptor->getReturnType())) { return \true; } foreach ($acceptor->getParameters() as $parameter) { if ($parameter instanceof \PHPStan\Reflection\ParameterReflectionWithPhpDocs && $parameter->getOutType() !== null && self::hasTemplateOrLateResolvableType($parameter->getOutType())) { return \true; } if ($parameter instanceof \PHPStan\Reflection\ParameterReflectionWithPhpDocs && $parameter->getClosureThisType() !== null && self::hasTemplateOrLateResolvableType($parameter->getClosureThisType())) { return \true; } if (!self::hasTemplateOrLateResolvableType($parameter->getType())) { continue; } return \true; } return \false; } private static function hasTemplateOrLateResolvableType(Type $type) : bool { $has = \false; TypeTraverser::map($type, static function (Type $type, callable $traverse) use(&$has) : Type { if ($type instanceof TemplateType || $type instanceof LateResolvableType) { $has = \true; return $type; } return $traverse($type); }); return $has; } /** * @param array $types * @param ParametersAcceptor[] $parametersAcceptors */ public static function selectFromTypes(array $types, array $parametersAcceptors, bool $unpack) : \PHPStan\Reflection\ParametersAcceptor { if (count($parametersAcceptors) === 1) { return \PHPStan\Reflection\GenericParametersAcceptorResolver::resolve($types, $parametersAcceptors[0]); } if (count($parametersAcceptors) === 0) { throw new ShouldNotHappenException('getVariants() must return at least one variant.'); } $typesCount = count($types); $acceptableAcceptors = []; foreach ($parametersAcceptors as $parametersAcceptor) { if ($unpack) { $acceptableAcceptors[] = $parametersAcceptor; continue; } $functionParametersMinCount = 0; $functionParametersMaxCount = 0; foreach ($parametersAcceptor->getParameters() as $parameter) { if (!$parameter->isOptional()) { $functionParametersMinCount++; } $functionParametersMaxCount++; } if ($typesCount < $functionParametersMinCount) { continue; } if (!$parametersAcceptor->isVariadic() && $typesCount > $functionParametersMaxCount) { continue; } $acceptableAcceptors[] = $parametersAcceptor; } if (count($acceptableAcceptors) === 0) { return \PHPStan\Reflection\GenericParametersAcceptorResolver::resolve($types, self::combineAcceptors($parametersAcceptors)); } if (count($acceptableAcceptors) === 1) { return \PHPStan\Reflection\GenericParametersAcceptorResolver::resolve($types, $acceptableAcceptors[0]); } $winningAcceptors = []; $winningCertainty = null; foreach ($acceptableAcceptors as $acceptableAcceptor) { $isSuperType = TrinaryLogic::createYes(); $acceptableAcceptor = \PHPStan\Reflection\GenericParametersAcceptorResolver::resolve($types, $acceptableAcceptor); foreach ($acceptableAcceptor->getParameters() as $i => $parameter) { if (!isset($types[$i])) { if (!$unpack || count($types) <= 0) { break; } $type = $types[array_key_last($types)]; } else { $type = $types[$i]; } if ($parameter->getType() instanceof MixedType) { $isSuperType = $isSuperType->and(TrinaryLogic::createMaybe()); } else { $isSuperType = $isSuperType->and($parameter->getType()->isSuperTypeOf($type)); } } if ($isSuperType->no()) { continue; } if ($winningCertainty === null) { $winningAcceptors[] = $acceptableAcceptor; $winningCertainty = $isSuperType; } else { $comparison = $winningCertainty->compareTo($isSuperType); if ($comparison === $isSuperType) { $winningAcceptors = [$acceptableAcceptor]; $winningCertainty = $isSuperType; } elseif ($comparison === null) { $winningAcceptors[] = $acceptableAcceptor; } } } if (count($winningAcceptors) === 0) { return \PHPStan\Reflection\GenericParametersAcceptorResolver::resolve($types, self::combineAcceptors($acceptableAcceptors)); } return \PHPStan\Reflection\GenericParametersAcceptorResolver::resolve($types, self::combineAcceptors($winningAcceptors)); } /** * @param ParametersAcceptor[] $acceptors */ public static function combineAcceptors(array $acceptors) : \PHPStan\Reflection\ParametersAcceptorWithPhpDocs { if (count($acceptors) === 0) { throw new ShouldNotHappenException('getVariants() must return at least one variant.'); } if (count($acceptors) === 1) { return self::wrapAcceptor($acceptors[0]); } $minimumNumberOfParameters = null; foreach ($acceptors as $acceptor) { $acceptorParametersMinCount = 0; foreach ($acceptor->getParameters() as $parameter) { if ($parameter->isOptional()) { continue; } $acceptorParametersMinCount++; } if ($minimumNumberOfParameters !== null && $minimumNumberOfParameters <= $acceptorParametersMinCount) { continue; } $minimumNumberOfParameters = $acceptorParametersMinCount; } $parameters = []; $isVariadic = \false; $returnTypes = []; $phpDocReturnTypes = []; $nativeReturnTypes = []; $callableOccurred = \false; $throwPoints = []; $isPure = TrinaryLogic::createNo(); $impurePoints = []; $invalidateExpressions = []; $usedVariables = []; $acceptsNamedArguments = \false; foreach ($acceptors as $acceptor) { $returnTypes[] = $acceptor->getReturnType(); if ($acceptor instanceof \PHPStan\Reflection\ParametersAcceptorWithPhpDocs) { $phpDocReturnTypes[] = $acceptor->getPhpDocReturnType(); $nativeReturnTypes[] = $acceptor->getNativeReturnType(); } if ($acceptor instanceof CallableParametersAcceptor) { $callableOccurred = \true; $throwPoints = array_merge($throwPoints, $acceptor->getThrowPoints()); $isPure = $isPure->or($acceptor->isPure()); $impurePoints = array_merge($impurePoints, $acceptor->getImpurePoints()); $invalidateExpressions = array_merge($invalidateExpressions, $acceptor->getInvalidateExpressions()); $usedVariables = array_merge($usedVariables, $acceptor->getUsedVariables()); $acceptsNamedArguments = $acceptsNamedArguments || $acceptor->acceptsNamedArguments(); } $isVariadic = $isVariadic || $acceptor->isVariadic(); foreach ($acceptor->getParameters() as $i => $parameter) { if (!isset($parameters[$i])) { $parameters[$i] = new DummyParameterWithPhpDocs($parameter->getName(), $parameter->getType(), $i + 1 > $minimumNumberOfParameters, $parameter->passedByReference(), $parameter->isVariadic(), $parameter->getDefaultValue(), $parameter instanceof \PHPStan\Reflection\ParameterReflectionWithPhpDocs ? $parameter->getNativeType() : new MixedType(), $parameter instanceof \PHPStan\Reflection\ParameterReflectionWithPhpDocs ? $parameter->getPhpDocType() : new MixedType(), $parameter instanceof \PHPStan\Reflection\ParameterReflectionWithPhpDocs ? $parameter->getOutType() : null, $parameter instanceof \PHPStan\Reflection\ParameterReflectionWithPhpDocs ? $parameter->isImmediatelyInvokedCallable() : TrinaryLogic::createMaybe(), $parameter instanceof \PHPStan\Reflection\ParameterReflectionWithPhpDocs ? $parameter->getClosureThisType() : null); continue; } $isVariadic = $parameters[$i]->isVariadic() || $parameter->isVariadic(); $defaultValueLeft = $parameters[$i]->getDefaultValue(); $defaultValueRight = $parameter->getDefaultValue(); if ($defaultValueLeft !== null && $defaultValueRight !== null) { $defaultValue = TypeCombinator::union($defaultValueLeft, $defaultValueRight); } else { $defaultValue = null; } $type = TypeCombinator::union($parameters[$i]->getType(), $parameter->getType()); $nativeType = $parameters[$i]->getNativeType(); $phpDocType = $parameters[$i]->getPhpDocType(); $outType = $parameters[$i]->getOutType(); $immediatelyInvokedCallable = $parameters[$i]->isImmediatelyInvokedCallable(); $closureThisType = $parameters[$i]->getClosureThisType(); if ($parameter instanceof \PHPStan\Reflection\ParameterReflectionWithPhpDocs) { $nativeType = TypeCombinator::union($nativeType, $parameter->getNativeType()); $phpDocType = TypeCombinator::union($phpDocType, $parameter->getPhpDocType()); if ($parameter->getOutType() !== null) { $outType = $outType === null ? null : TypeCombinator::union($outType, $parameter->getOutType()); } else { $outType = null; } if ($parameter->getClosureThisType() !== null && $closureThisType !== null) { $closureThisType = TypeCombinator::union($closureThisType, $parameter->getClosureThisType()); } else { $closureThisType = null; } $immediatelyInvokedCallable = $parameter->isImmediatelyInvokedCallable()->or($immediatelyInvokedCallable); } else { $nativeType = new MixedType(); $phpDocType = $type; $outType = null; $immediatelyInvokedCallable = TrinaryLogic::createMaybe(); $closureThisType = null; } $parameters[$i] = new DummyParameterWithPhpDocs($parameters[$i]->getName() !== $parameter->getName() ? sprintf('%s|%s', $parameters[$i]->getName(), $parameter->getName()) : $parameter->getName(), $type, $i + 1 > $minimumNumberOfParameters, $parameters[$i]->passedByReference()->combine($parameter->passedByReference()), $isVariadic, $defaultValue, $nativeType, $phpDocType, $outType, $immediatelyInvokedCallable, $closureThisType); if ($isVariadic) { $parameters = array_slice($parameters, 0, $i + 1); break; } } } $returnType = TypeCombinator::union(...$returnTypes); $phpDocReturnType = $phpDocReturnTypes === [] ? null : TypeCombinator::union(...$phpDocReturnTypes); $nativeReturnType = $nativeReturnTypes === [] ? null : TypeCombinator::union(...$nativeReturnTypes); if ($callableOccurred) { return new \PHPStan\Reflection\CallableFunctionVariantWithPhpDocs(TemplateTypeMap::createEmpty(), null, $parameters, $isVariadic, $returnType, $phpDocReturnType ?? $returnType, $nativeReturnType ?? new MixedType(), null, $throwPoints, $isPure, $impurePoints, $invalidateExpressions, $usedVariables, $acceptsNamedArguments); } return new \PHPStan\Reflection\FunctionVariantWithPhpDocs(TemplateTypeMap::createEmpty(), null, $parameters, $isVariadic, $returnType, $phpDocReturnType ?? $returnType, $nativeReturnType ?? new MixedType()); } private static function wrapAcceptor(\PHPStan\Reflection\ParametersAcceptor $acceptor) : \PHPStan\Reflection\ParametersAcceptorWithPhpDocs { if ($acceptor instanceof \PHPStan\Reflection\ParametersAcceptorWithPhpDocs) { return $acceptor; } if ($acceptor instanceof CallableParametersAcceptor) { return new \PHPStan\Reflection\CallableFunctionVariantWithPhpDocs($acceptor->getTemplateTypeMap(), $acceptor->getResolvedTemplateTypeMap(), array_map(static function (\PHPStan\Reflection\ParameterReflection $parameter) : \PHPStan\Reflection\ParameterReflectionWithPhpDocs { return self::wrapParameter($parameter); }, $acceptor->getParameters()), $acceptor->isVariadic(), $acceptor->getReturnType(), $acceptor->getReturnType(), new MixedType(), TemplateTypeVarianceMap::createEmpty(), $acceptor->getThrowPoints(), $acceptor->isPure(), $acceptor->getImpurePoints(), $acceptor->getInvalidateExpressions(), $acceptor->getUsedVariables(), $acceptor->acceptsNamedArguments()); } return new \PHPStan\Reflection\FunctionVariantWithPhpDocs($acceptor->getTemplateTypeMap(), $acceptor->getResolvedTemplateTypeMap(), array_map(static function (\PHPStan\Reflection\ParameterReflection $parameter) : \PHPStan\Reflection\ParameterReflectionWithPhpDocs { return self::wrapParameter($parameter); }, $acceptor->getParameters()), $acceptor->isVariadic(), $acceptor->getReturnType(), $acceptor->getReturnType(), new MixedType(), TemplateTypeVarianceMap::createEmpty()); } private static function wrapParameter(\PHPStan\Reflection\ParameterReflection $parameter) : \PHPStan\Reflection\ParameterReflectionWithPhpDocs { return $parameter instanceof \PHPStan\Reflection\ParameterReflectionWithPhpDocs ? $parameter : new DummyParameterWithPhpDocs($parameter->getName(), $parameter->getType(), $parameter->isOptional(), $parameter->passedByReference(), $parameter->isVariadic(), $parameter->getDefaultValue(), new MixedType(), $parameter->getType(), null, TrinaryLogic::createMaybe(), null); } private static function getCurlOptValueType(int $curlOpt) : ?Type { if (defined('CURLOPT_SSL_VERIFYHOST') && $curlOpt === CURLOPT_SSL_VERIFYHOST) { return new UnionType([new ConstantIntegerType(0), new ConstantIntegerType(2)]); } $boolConstants = ['CURLOPT_AUTOREFERER', 'CURLOPT_COOKIESESSION', 'CURLOPT_CERTINFO', 'CURLOPT_CONNECT_ONLY', 'CURLOPT_CRLF', 'CURLOPT_DISALLOW_USERNAME_IN_URL', 'CURLOPT_DNS_SHUFFLE_ADDRESSES', 'CURLOPT_HAPROXYPROTOCOL', 'CURLOPT_SSH_COMPRESSION', 'CURLOPT_DNS_USE_GLOBAL_CACHE', 'CURLOPT_FAILONERROR', 'CURLOPT_SSL_FALSESTART', 'CURLOPT_FILETIME', 'CURLOPT_FOLLOWLOCATION', 'CURLOPT_FORBID_REUSE', 'CURLOPT_FRESH_CONNECT', 'CURLOPT_FTP_USE_EPRT', 'CURLOPT_FTP_USE_EPSV', 'CURLOPT_FTP_CREATE_MISSING_DIRS', 'CURLOPT_FTPAPPEND', 'CURLOPT_TCP_NODELAY', 'CURLOPT_FTPASCII', 'CURLOPT_FTPLISTONLY', 'CURLOPT_HEADER', 'CURLOPT_HTTP09_ALLOWED', 'CURLOPT_HTTPGET', 'CURLOPT_HTTPPROXYTUNNEL', 'CURLOPT_HTTP_CONTENT_DECODING', 'CURLOPT_KEEP_SENDING_ON_ERROR', 'CURLOPT_MUTE', 'CURLOPT_NETRC', 'CURLOPT_NOBODY', 'CURLOPT_NOPROGRESS', 'CURLOPT_NOSIGNAL', 'CURLOPT_PATH_AS_IS', 'CURLOPT_PIPEWAIT', 'CURLOPT_POST', 'CURLOPT_PUT', 'CURLOPT_RETURNTRANSFER', 'CURLOPT_SASL_IR', 'CURLOPT_SSL_ENABLE_ALPN', 'CURLOPT_SSL_ENABLE_NPN', 'CURLOPT_SSL_VERIFYPEER', 'CURLOPT_SSL_VERIFYSTATUS', 'CURLOPT_PROXY_SSL_VERIFYPEER', 'CURLOPT_SUPPRESS_CONNECT_HEADERS', 'CURLOPT_TCP_FASTOPEN', 'CURLOPT_TFTP_NO_OPTIONS', 'CURLOPT_TRANSFERTEXT', 'CURLOPT_UNRESTRICTED_AUTH', 'CURLOPT_UPLOAD', 'CURLOPT_VERBOSE']; foreach ($boolConstants as $constName) { if (defined($constName) && constant($constName) === $curlOpt) { return new BooleanType(); } } $intConstants = ['CURLOPT_BUFFERSIZE', 'CURLOPT_CONNECTTIMEOUT', 'CURLOPT_CONNECTTIMEOUT_MS', 'CURLOPT_DNS_CACHE_TIMEOUT', 'CURLOPT_EXPECT_100_TIMEOUT_MS', 'CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS', 'CURLOPT_FTPSSLAUTH', 'CURLOPT_HEADEROPT', 'CURLOPT_HTTP_VERSION', 'CURLOPT_HTTPAUTH', 'CURLOPT_INFILESIZE', 'CURLOPT_LOW_SPEED_LIMIT', 'CURLOPT_LOW_SPEED_TIME', 'CURLOPT_MAXCONNECTS', 'CURLOPT_MAXREDIRS', 'CURLOPT_PORT', 'CURLOPT_POSTREDIR', 'CURLOPT_PROTOCOLS', 'CURLOPT_PROXYAUTH', 'CURLOPT_PROXYPORT', 'CURLOPT_PROXYTYPE', 'CURLOPT_REDIR_PROTOCOLS', 'CURLOPT_RESUME_FROM', 'CURLOPT_SOCKS5_AUTH', 'CURLOPT_SSL_OPTIONS', 'CURLOPT_SSL_VERIFYHOST', 'CURLOPT_SSLVERSION', 'CURLOPT_PROXY_SSL_OPTIONS', 'CURLOPT_PROXY_SSL_VERIFYHOST', 'CURLOPT_PROXY_SSLVERSION', 'CURLOPT_STREAM_WEIGHT', 'CURLOPT_TCP_KEEPALIVE', 'CURLOPT_TCP_KEEPIDLE', 'CURLOPT_TCP_KEEPINTVL', 'CURLOPT_TIMECONDITION', 'CURLOPT_TIMEOUT', 'CURLOPT_TIMEOUT_MS', 'CURLOPT_TIMEVALUE', 'CURLOPT_TIMEVALUE_LARGE', 'CURLOPT_MAX_RECV_SPEED_LARGE', 'CURLOPT_SSH_AUTH_TYPES', 'CURLOPT_IPRESOLVE', 'CURLOPT_FTP_FILEMETHOD']; foreach ($intConstants as $constName) { if (defined($constName) && constant($constName) === $curlOpt) { return new IntegerType(); } } $nonEmptyStringConstants = ['CURLOPT_ABSTRACT_UNIX_SOCKET', 'CURLOPT_CAINFO', 'CURLOPT_CAPATH', 'CURLOPT_COOKIE', 'CURLOPT_COOKIEJAR', 'CURLOPT_COOKIELIST', 'CURLOPT_CUSTOMREQUEST', 'CURLOPT_DEFAULT_PROTOCOL', 'CURLOPT_DNS_INTERFACE', 'CURLOPT_DNS_LOCAL_IP4', 'CURLOPT_DNS_LOCAL_IP6', 'CURLOPT_EGDSOCKET', 'CURLOPT_FTPPORT', 'CURLOPT_INTERFACE', 'CURLOPT_KEYPASSWD', 'CURLOPT_KRB4LEVEL', 'CURLOPT_LOGIN_OPTIONS', 'CURLOPT_PINNEDPUBLICKEY', 'CURLOPT_PROXY_SERVICE_NAME', 'CURLOPT_PROXY_CAINFO', 'CURLOPT_PROXY_CAPATH', 'CURLOPT_PROXY_CRLFILE', 'CURLOPT_PROXY_KEYPASSWD', 'CURLOPT_PROXY_PINNEDPUBLICKEY', 'CURLOPT_PROXY_SSLCERT', 'CURLOPT_PROXY_SSLCERTTYPE', 'CURLOPT_PROXY_SSL_CIPHER_LIST', 'CURLOPT_PROXY_TLS13_CIPHERS', 'CURLOPT_PROXY_SSLKEY', 'CURLOPT_PROXY_SSLKEYTYPE', 'CURLOPT_PROXY_TLSAUTH_PASSWORD', 'CURLOPT_PROXY_TLSAUTH_TYPE', 'CURLOPT_PROXY_TLSAUTH_USERNAME', 'CURLOPT_PROXYUSERPWD', 'CURLOPT_RANDOM_FILE', 'CURLOPT_RANGE', 'CURLOPT_REFERER', 'CURLOPT_SERVICE_NAME', 'CURLOPT_SSH_HOST_PUBLIC_KEY_MD5', 'CURLOPT_SSH_PUBLIC_KEYFILE', 'CURLOPT_SSH_PRIVATE_KEYFILE', 'CURLOPT_SSL_CIPHER_LIST', 'CURLOPT_SSLCERT', 'CURLOPT_SSLCERTPASSWD', 'CURLOPT_SSLCERTTYPE', 'CURLOPT_SSLENGINE', 'CURLOPT_SSLENGINE_DEFAULT', 'CURLOPT_SSLKEY', 'CURLOPT_SSLKEYPASSWD', 'CURLOPT_SSLKEYTYPE', 'CURLOPT_TLS13_CIPHERS', 'CURLOPT_UNIX_SOCKET_PATH', 'CURLOPT_URL', 'CURLOPT_USERAGENT', 'CURLOPT_USERNAME', 'CURLOPT_PASSWORD', 'CURLOPT_USERPWD', 'CURLOPT_XOAUTH2_BEARER']; foreach ($nonEmptyStringConstants as $constName) { if (defined($constName) && constant($constName) === $curlOpt) { return TypeCombinator::intersect(new StringType(), new AccessoryNonEmptyStringType()); } } $stringConstants = ['CURLOPT_COOKIEFILE', 'CURLOPT_ENCODING', 'CURLOPT_PRE_PROXY', 'CURLOPT_PRIVATE', 'CURLOPT_PROXY']; foreach ($stringConstants as $constName) { if (defined($constName) && constant($constName) === $curlOpt) { return new StringType(); } } $intArrayStringKeysConstants = ['CURLOPT_HTTPHEADER']; foreach ($intArrayStringKeysConstants as $constName) { if (defined($constName) && constant($constName) === $curlOpt) { return new ArrayType(new IntegerType(), new StringType()); } } $arrayConstants = ['CURLOPT_CONNECT_TO', 'CURLOPT_HTTP200ALIASES', 'CURLOPT_POSTQUOTE', 'CURLOPT_PROXYHEADER', 'CURLOPT_QUOTE', 'CURLOPT_RESOLVE']; foreach ($arrayConstants as $constName) { if (defined($constName) && constant($constName) === $curlOpt) { return new ArrayType(new MixedType(), new MixedType()); } } $arrayOrStringConstants = ['CURLOPT_POSTFIELDS']; foreach ($arrayOrStringConstants as $constName) { if (defined($constName) && constant($constName) === $curlOpt) { return new UnionType([new StringType(), new ArrayType(new MixedType(), new MixedType())]); } } $resourceConstants = ['CURLOPT_FILE', 'CURLOPT_INFILE', 'CURLOPT_STDERR', 'CURLOPT_WRITEHEADER']; foreach ($resourceConstants as $constName) { if (defined($constName) && constant($constName) === $curlOpt) { return new ResourceType(); } } // unknown constant return null; } } */ private $currentlyResolvingClassConstant = []; public function __construct(ConstantResolver $constantResolver, ReflectionProviderProvider $reflectionProviderProvider, PhpVersion $phpVersion, OperatorTypeSpecifyingExtensionRegistryProvider $operatorTypeSpecifyingExtensionRegistryProvider, OversizedArrayBuilder $oversizedArrayBuilder, bool $usePathConstantsAsConstantString = \false) { $this->constantResolver = $constantResolver; $this->reflectionProviderProvider = $reflectionProviderProvider; $this->phpVersion = $phpVersion; $this->operatorTypeSpecifyingExtensionRegistryProvider = $operatorTypeSpecifyingExtensionRegistryProvider; $this->oversizedArrayBuilder = $oversizedArrayBuilder; $this->usePathConstantsAsConstantString = $usePathConstantsAsConstantString; } /** @api */ public function getType(Expr $expr, \PHPStan\Reflection\InitializerExprContext $context) : Type { if ($expr instanceof TypeExpr) { return $expr->getExprType(); } if ($expr instanceof LNumber) { return new ConstantIntegerType($expr->value); } if ($expr instanceof DNumber) { return new ConstantFloatType($expr->value); } if ($expr instanceof String_) { return new ConstantStringType($expr->value); } if ($expr instanceof ConstFetch) { $constName = (string) $expr->name; $loweredConstName = strtolower($constName); if ($loweredConstName === 'true') { return new ConstantBooleanType(\true); } elseif ($loweredConstName === 'false') { return new ConstantBooleanType(\false); } elseif ($loweredConstName === 'null') { return new NullType(); } $constant = $this->constantResolver->resolveConstant($expr->name, $context); if ($constant !== null) { return $constant; } return new ErrorType(); } if ($expr instanceof File) { $file = $context->getFile(); if ($file === null) { return new StringType(); } $stringType = new ConstantStringType($file); return $this->usePathConstantsAsConstantString ? $stringType : $stringType->generalize(GeneralizePrecision::moreSpecific()); } if ($expr instanceof Dir) { $file = $context->getFile(); if ($file === null) { return new StringType(); } $stringType = new ConstantStringType(dirname($file)); return $this->usePathConstantsAsConstantString ? $stringType : $stringType->generalize(GeneralizePrecision::moreSpecific()); } if ($expr instanceof Line) { return new ConstantIntegerType($expr->getStartLine()); } if ($expr instanceof Expr\New_) { if ($expr->class instanceof Name) { return new ObjectType((string) $expr->class); } return new ObjectWithoutClassType(); } if ($expr instanceof Expr\Array_) { return $this->getArrayType($expr, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\ArrayDimFetch && $expr->dim !== null) { $var = $this->getType($expr->var, $context); $dim = $this->getType($expr->dim, $context); return $var->getOffsetValueType($dim); } if ($expr instanceof ClassConstFetch && $expr->name instanceof Identifier) { return $this->getClassConstFetchType($expr->class, $expr->name->toString(), $context->getClassName(), function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\UnaryPlus) { return $this->getType($expr->expr, $context)->toNumber(); } if ($expr instanceof Expr\UnaryMinus) { return $this->getUnaryMinusType($expr->expr, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\Coalesce) { $leftType = $this->getType($expr->left, $context); $rightType = $this->getType($expr->right, $context); return TypeCombinator::union(TypeCombinator::removeNull($leftType), $rightType); } if ($expr instanceof Expr\Ternary) { $condType = $this->getType($expr->cond, $context); $elseType = $this->getType($expr->else, $context); if ($expr->if === null) { return TypeCombinator::union(TypeCombinator::removeFalsey($condType), $elseType); } $ifType = $this->getType($expr->if, $context); return TypeCombinator::union(TypeCombinator::removeFalsey($ifType), $elseType); } if ($expr instanceof Expr\FuncCall && $expr->name instanceof Name && $expr->name->toLowerString() === 'constant') { $firstArg = $expr->args[0] ?? null; if ($firstArg instanceof Arg && $firstArg->value instanceof String_) { $constant = $this->constantResolver->resolvePredefinedConstant($firstArg->value->value); if ($constant !== null) { return $constant; } } } if ($expr instanceof Expr\BooleanNot) { $exprBooleanType = $this->getType($expr->expr, $context)->toBoolean(); if ($exprBooleanType instanceof ConstantBooleanType) { return new ConstantBooleanType(!$exprBooleanType->getValue()); } return new BooleanType(); } if ($expr instanceof Expr\BitwiseNot) { return $this->getBitwiseNotType($expr->expr, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\Concat) { return $this->getConcatType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\BitwiseAnd) { return $this->getBitwiseAndType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\BitwiseOr) { return $this->getBitwiseOrType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\BitwiseXor) { return $this->getBitwiseXorType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\Spaceship) { return $this->getSpaceshipType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\BooleanAnd || $expr instanceof Expr\BinaryOp\LogicalAnd || $expr instanceof Expr\BinaryOp\BooleanOr || $expr instanceof Expr\BinaryOp\LogicalOr) { return new BooleanType(); } if ($expr instanceof Expr\BinaryOp\Div) { return $this->getDivType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\Mod) { return $this->getModType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\Plus) { return $this->getPlusType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\Minus) { return $this->getMinusType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\Mul) { return $this->getMulType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\Pow) { return $this->getPowType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\ShiftLeft) { return $this->getShiftLeftType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof Expr\BinaryOp\ShiftRight) { return $this->getShiftRightType($expr->left, $expr->right, function (Expr $expr) use($context) : Type { return $this->getType($expr, $context); }); } if ($expr instanceof BinaryOp\Identical) { return $this->resolveIdenticalType($this->getType($expr->left, $context), $this->getType($expr->right, $context))->type; } if ($expr instanceof BinaryOp\NotIdentical) { return $this->getType(new Expr\BooleanNot(new BinaryOp\Identical($expr->left, $expr->right)), $context); } if ($expr instanceof BinaryOp\Equal) { return $this->resolveEqualType($this->getType($expr->left, $context), $this->getType($expr->right, $context))->type; } if ($expr instanceof BinaryOp\NotEqual) { return $this->getType(new Expr\BooleanNot(new BinaryOp\Equal($expr->left, $expr->right)), $context); } if ($expr instanceof Expr\BinaryOp\Smaller) { return $this->getType($expr->left, $context)->isSmallerThan($this->getType($expr->right, $context))->toBooleanType(); } if ($expr instanceof Expr\BinaryOp\SmallerOrEqual) { return $this->getType($expr->left, $context)->isSmallerThanOrEqual($this->getType($expr->right, $context))->toBooleanType(); } if ($expr instanceof Expr\BinaryOp\Greater) { return $this->getType($expr->right, $context)->isSmallerThan($this->getType($expr->left, $context))->toBooleanType(); } if ($expr instanceof Expr\BinaryOp\GreaterOrEqual) { return $this->getType($expr->right, $context)->isSmallerThanOrEqual($this->getType($expr->left, $context))->toBooleanType(); } if ($expr instanceof Expr\BinaryOp\LogicalXor) { $leftBooleanType = $this->getType($expr->left, $context)->toBoolean(); $rightBooleanType = $this->getType($expr->right, $context)->toBoolean(); if ($leftBooleanType instanceof ConstantBooleanType && $rightBooleanType instanceof ConstantBooleanType) { return new ConstantBooleanType($leftBooleanType->getValue() xor $rightBooleanType->getValue()); } return new BooleanType(); } if ($expr instanceof MagicConst\Class_) { if ($context->getTraitName() !== null) { return TypeCombinator::intersect(new ClassStringType(), new AccessoryLiteralStringType()); } if ($context->getClassName() === null) { return new ConstantStringType(''); } return new ConstantStringType($context->getClassName(), \true); } if ($expr instanceof MagicConst\Namespace_) { if ($context->getTraitName() !== null) { return TypeCombinator::intersect(new StringType(), new AccessoryLiteralStringType()); } return new ConstantStringType($context->getNamespace() ?? ''); } if ($expr instanceof MagicConst\Method) { return new ConstantStringType($context->getMethod() ?? ''); } if ($expr instanceof MagicConst\Function_) { return new ConstantStringType($context->getFunction() ?? ''); } if ($expr instanceof MagicConst\Trait_) { if ($context->getTraitName() === null) { return new ConstantStringType(''); } return new ConstantStringType($context->getTraitName(), \true); } if ($expr instanceof PropertyFetch && $expr->name instanceof Identifier) { $fetchedOnType = $this->getType($expr->var, $context); if (!$fetchedOnType->hasProperty($expr->name->name)->yes()) { return new ErrorType(); } return $fetchedOnType->getProperty($expr->name->name, new OutOfClassScope())->getReadableType(); } return new MixedType(); } /** * @param callable(Expr): Type $getTypeCallback */ public function getConcatType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $leftType = $getTypeCallback($left); $rightType = $getTypeCallback($right); return $this->resolveConcatType($leftType, $rightType); } public function resolveConcatType(Type $left, Type $right) : Type { $leftStringType = $left->toString(); $rightStringType = $right->toString(); if (TypeCombinator::union($leftStringType, $rightStringType) instanceof ErrorType) { return new ErrorType(); } if ($leftStringType instanceof ConstantStringType && $leftStringType->getValue() === '') { return $rightStringType; } if ($rightStringType instanceof ConstantStringType && $rightStringType->getValue() === '') { return $leftStringType; } if ($leftStringType instanceof ConstantStringType && $rightStringType instanceof ConstantStringType) { return $leftStringType->append($rightStringType); } $leftConstantStrings = $leftStringType->getConstantStrings(); $rightConstantStrings = $rightStringType->getConstantStrings(); $combinedConstantStringsCount = count($leftConstantStrings) * count($rightConstantStrings); // we limit the number of union-types for performance reasons if ($combinedConstantStringsCount > 0 && $combinedConstantStringsCount <= 16) { $strings = []; foreach ($leftConstantStrings as $leftConstantString) { if ($leftConstantString->getValue() === '') { $strings = array_merge($strings, $rightConstantStrings); continue; } foreach ($rightConstantStrings as $rightConstantString) { if ($rightConstantString->getValue() === '') { $strings[] = $leftConstantString; continue; } $strings[] = $leftConstantString->append($rightConstantString); } } if (count($strings) > 0) { return TypeCombinator::union(...$strings); } } $accessoryTypes = []; if ($leftStringType->isNonEmptyString()->and($rightStringType->isNonEmptyString())->yes()) { $accessoryTypes[] = new AccessoryNonFalsyStringType(); } elseif ($leftStringType->isNonFalsyString()->or($rightStringType->isNonFalsyString())->yes()) { $accessoryTypes[] = new AccessoryNonFalsyStringType(); } elseif ($leftStringType->isNonEmptyString()->or($rightStringType->isNonEmptyString())->yes()) { $accessoryTypes[] = new AccessoryNonEmptyStringType(); } if ($leftStringType->isLiteralString()->and($rightStringType->isLiteralString())->yes()) { $accessoryTypes[] = new AccessoryLiteralStringType(); } if ($leftStringType->isLowercaseString()->and($rightStringType->isLowercaseString())->yes()) { $accessoryTypes[] = new AccessoryLowercaseStringType(); } if ($leftStringType->isUppercaseString()->and($rightStringType->isUppercaseString())->yes()) { $accessoryTypes[] = new AccessoryUppercaseStringType(); } $leftNumericStringNonEmpty = TypeCombinator::remove($leftStringType, new ConstantStringType('')); if ($leftNumericStringNonEmpty->isNumericString()->yes()) { $allRightConstantsZeroOrMore = \false; foreach ($rightConstantStrings as $rightConstantString) { if ($rightConstantString->getValue() === '') { continue; } if (!is_numeric($rightConstantString->getValue()) || Strings::match($rightConstantString->getValue(), '#^[0-9]+$#') === null) { $allRightConstantsZeroOrMore = \false; break; } $allRightConstantsZeroOrMore = \true; } $zeroOrMoreInteger = IntegerRangeType::fromInterval(0, null); $nonNegativeRight = $allRightConstantsZeroOrMore || $zeroOrMoreInteger->isSuperTypeOf($right)->yes(); if ($nonNegativeRight) { $accessoryTypes[] = new AccessoryNumericStringType(); } } if (count($accessoryTypes) > 0) { $accessoryTypes[] = new StringType(); return new IntersectionType($accessoryTypes); } return new StringType(); } /** * @param callable(Expr): Type $getTypeCallback */ public function getArrayType(Expr\Array_ $expr, callable $getTypeCallback) : Type { if (count($expr->items) > ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) { return $this->oversizedArrayBuilder->build($expr, $getTypeCallback); } $arrayBuilder = ConstantArrayTypeBuilder::createEmpty(); $isList = null; foreach ($expr->items as $arrayItem) { if ($arrayItem === null) { continue; } $valueType = $getTypeCallback($arrayItem->value); if ($arrayItem->unpack) { $constantArrays = $valueType->getConstantArrays(); if (count($constantArrays) === 1) { $constantArrayType = $constantArrays[0]; $hasStringKey = \false; foreach ($constantArrayType->getKeyTypes() as $keyType) { if ($keyType->isString()->yes()) { $hasStringKey = \true; break; } } foreach ($constantArrayType->getValueTypes() as $i => $innerValueType) { if ($hasStringKey && $this->phpVersion->supportsArrayUnpackingWithStringKeys()) { $arrayBuilder->setOffsetValueType($constantArrayType->getKeyTypes()[$i], $innerValueType, $constantArrayType->isOptionalKey($i)); } else { $arrayBuilder->setOffsetValueType(null, $innerValueType, $constantArrayType->isOptionalKey($i)); } } } else { $arrayBuilder->degradeToGeneralArray(); if ($this->phpVersion->supportsArrayUnpackingWithStringKeys() && !$valueType->getIterableKeyType()->isString()->no()) { $isList = \false; $offsetType = $valueType->getIterableKeyType(); } else { $isList = $isList ?? $arrayBuilder->isList(); $offsetType = new IntegerType(); } $arrayBuilder->setOffsetValueType($offsetType, $valueType->getIterableValueType(), !$valueType->isIterableAtLeastOnce()->yes()); } } else { $arrayBuilder->setOffsetValueType($arrayItem->key !== null ? $getTypeCallback($arrayItem->key) : null, $valueType); } } $arrayType = $arrayBuilder->getArray(); if ($isList === \true) { return AccessoryArrayListType::intersectWith($arrayType); } return $arrayType; } /** * @param callable(Expr): Type $getTypeCallback */ public function getBitwiseAndType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $leftType = $getTypeCallback($left); $rightType = $getTypeCallback($right); if ($leftType instanceof NeverType || $rightType instanceof NeverType) { return $this->getNeverType($leftType, $rightType); } $leftTypes = $leftType->getConstantScalarTypes(); $rightTypes = $rightType->getConstantScalarTypes(); $leftTypesCount = count($leftTypes); $rightTypesCount = count($rightTypes); if ($leftTypesCount > 0 && $rightTypesCount > 0) { $resultTypes = []; $generalize = $leftTypesCount * $rightTypesCount > self::CALCULATE_SCALARS_LIMIT; if (!$generalize) { foreach ($leftTypes as $leftTypeInner) { foreach ($rightTypes as $rightTypeInner) { if ($leftTypeInner instanceof ConstantStringType && $rightTypeInner instanceof ConstantStringType) { $resultType = $this->getTypeFromValue($leftTypeInner->getValue() & $rightTypeInner->getValue()); } else { $leftNumberType = $leftTypeInner->toNumber(); $rightNumberType = $rightTypeInner->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } if (!$leftNumberType instanceof ConstantScalarType || !$rightNumberType instanceof ConstantScalarType) { throw new ShouldNotHappenException(); } $resultType = $this->getTypeFromValue($leftNumberType->getValue() & $rightNumberType->getValue()); } $resultTypes[] = $resultType; } } return TypeCombinator::union(...$resultTypes); } $leftType = $this->optimizeScalarType($leftType); $rightType = $this->optimizeScalarType($rightType); } if ($leftType->isString()->yes() && $rightType->isString()->yes()) { return new StringType(); } $leftNumberType = $leftType->toNumber(); $rightNumberType = $rightType->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } if ($rightNumberType instanceof ConstantIntegerType && $rightNumberType->getValue() >= 0) { return IntegerRangeType::fromInterval(0, $rightNumberType->getValue()); } if ($leftNumberType instanceof ConstantIntegerType && $leftNumberType->getValue() >= 0) { return IntegerRangeType::fromInterval(0, $leftNumberType->getValue()); } return new IntegerType(); } /** * @param callable(Expr): Type $getTypeCallback */ public function getBitwiseOrType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $leftType = $getTypeCallback($left); $rightType = $getTypeCallback($right); if ($leftType instanceof NeverType || $rightType instanceof NeverType) { return $this->getNeverType($leftType, $rightType); } $leftTypes = $leftType->getConstantScalarTypes(); $rightTypes = $rightType->getConstantScalarTypes(); $leftTypesCount = count($leftTypes); $rightTypesCount = count($rightTypes); if ($leftTypesCount > 0 && $rightTypesCount > 0) { $resultTypes = []; $generalize = $leftTypesCount * $rightTypesCount > self::CALCULATE_SCALARS_LIMIT; if (!$generalize) { foreach ($leftTypes as $leftTypeInner) { foreach ($rightTypes as $rightTypeInner) { if ($leftTypeInner instanceof ConstantStringType && $rightTypeInner instanceof ConstantStringType) { $resultType = $this->getTypeFromValue($leftTypeInner->getValue() | $rightTypeInner->getValue()); } else { $leftNumberType = $leftTypeInner->toNumber(); $rightNumberType = $rightTypeInner->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } if (!$leftNumberType instanceof ConstantScalarType || !$rightNumberType instanceof ConstantScalarType) { throw new ShouldNotHappenException(); } $resultType = $this->getTypeFromValue($leftNumberType->getValue() | $rightNumberType->getValue()); } $resultTypes[] = $resultType; } } return TypeCombinator::union(...$resultTypes); } $leftType = $this->optimizeScalarType($leftType); $rightType = $this->optimizeScalarType($rightType); } if ($leftType->isString()->yes() && $rightType->isString()->yes()) { return new StringType(); } if (TypeCombinator::union($leftType->toNumber(), $rightType->toNumber()) instanceof ErrorType) { return new ErrorType(); } return new IntegerType(); } /** * @param callable(Expr): Type $getTypeCallback */ public function getBitwiseXorType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $leftType = $getTypeCallback($left); $rightType = $getTypeCallback($right); if ($leftType instanceof NeverType || $rightType instanceof NeverType) { return $this->getNeverType($leftType, $rightType); } $leftTypes = $leftType->getConstantScalarTypes(); $rightTypes = $rightType->getConstantScalarTypes(); $leftTypesCount = count($leftTypes); $rightTypesCount = count($rightTypes); if ($leftTypesCount > 0 && $rightTypesCount > 0) { $resultTypes = []; $generalize = $leftTypesCount * $rightTypesCount > self::CALCULATE_SCALARS_LIMIT; if (!$generalize) { foreach ($leftTypes as $leftTypeInner) { foreach ($rightTypes as $rightTypeInner) { if ($leftTypeInner instanceof ConstantStringType && $rightTypeInner instanceof ConstantStringType) { $resultType = $this->getTypeFromValue($leftTypeInner->getValue() ^ $rightTypeInner->getValue()); } else { $leftNumberType = $leftTypeInner->toNumber(); $rightNumberType = $rightTypeInner->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } if (!$leftNumberType instanceof ConstantScalarType || !$rightNumberType instanceof ConstantScalarType) { throw new ShouldNotHappenException(); } $resultType = $this->getTypeFromValue($leftNumberType->getValue() ^ $rightNumberType->getValue()); } $resultTypes[] = $resultType; } } return TypeCombinator::union(...$resultTypes); } $leftType = $this->optimizeScalarType($leftType); $rightType = $this->optimizeScalarType($rightType); } if ($leftType->isString()->yes() && $rightType->isString()->yes()) { return new StringType(); } if (TypeCombinator::union($leftType->toNumber(), $rightType->toNumber()) instanceof ErrorType) { return new ErrorType(); } return new IntegerType(); } /** * @param callable(Expr): Type $getTypeCallback */ public function getSpaceshipType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $callbackLeftType = $getTypeCallback($left); $callbackRightType = $getTypeCallback($right); if ($callbackLeftType instanceof NeverType || $callbackRightType instanceof NeverType) { return $this->getNeverType($callbackLeftType, $callbackRightType); } $leftTypes = $callbackLeftType->getConstantScalarTypes(); $rightTypes = $callbackRightType->getConstantScalarTypes(); $leftTypesCount = count($leftTypes); $rightTypesCount = count($rightTypes); if ($leftTypesCount > 0 && $rightTypesCount > 0 && $leftTypesCount * $rightTypesCount <= self::CALCULATE_SCALARS_LIMIT) { $resultTypes = []; foreach ($leftTypes as $leftType) { foreach ($rightTypes as $rightType) { $leftValue = $leftType->getValue(); $rightValue = $rightType->getValue(); $resultType = $this->getTypeFromValue($leftValue <=> $rightValue); $resultTypes[] = $resultType; } } return TypeCombinator::union(...$resultTypes); } return IntegerRangeType::fromInterval(-1, 1); } /** * @param callable(Expr): Type $getTypeCallback */ public function getDivType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $leftType = $getTypeCallback($left); $rightType = $getTypeCallback($right); $leftTypes = $leftType->getConstantScalarTypes(); $rightTypes = $rightType->getConstantScalarTypes(); $leftTypesCount = count($leftTypes); $rightTypesCount = count($rightTypes); if ($leftTypesCount > 0 && $rightTypesCount > 0) { $resultTypes = []; $generalize = $leftTypesCount * $rightTypesCount > self::CALCULATE_SCALARS_LIMIT; if (!$generalize) { foreach ($leftTypes as $leftTypeInner) { foreach ($rightTypes as $rightTypeInner) { $leftNumberType = $leftTypeInner->toNumber(); $rightNumberType = $rightTypeInner->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } if (!$leftNumberType instanceof ConstantScalarType || !$rightNumberType instanceof ConstantScalarType) { throw new ShouldNotHappenException(); } if (in_array($rightNumberType->getValue(), [0, 0.0], \true)) { return new ErrorType(); } $resultType = $this->getTypeFromValue($leftNumberType->getValue() / $rightNumberType->getValue()); // @phpstan-ignore binaryOp.invalid $resultTypes[] = $resultType; } } return TypeCombinator::union(...$resultTypes); } $leftType = $this->optimizeScalarType($leftType); $rightType = $this->optimizeScalarType($rightType); } $rightScalarValues = $rightType->toNumber()->getConstantScalarValues(); foreach ($rightScalarValues as $scalarValue) { if ($scalarValue === 0 || $scalarValue === 0.0) { return new ErrorType(); } } return $this->resolveCommonMath(new BinaryOp\Div($left, $right), $leftType, $rightType); } /** * @param callable(Expr): Type $getTypeCallback */ public function getModType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $leftType = $getTypeCallback($left); $rightType = $getTypeCallback($right); if ($leftType instanceof NeverType || $rightType instanceof NeverType) { return $this->getNeverType($leftType, $rightType); } if ($leftType->toNumber() instanceof ErrorType || $rightType->toNumber() instanceof ErrorType) { return new ErrorType(); } $leftTypes = $leftType->getConstantScalarTypes(); $rightTypes = $rightType->getConstantScalarTypes(); $leftTypesCount = count($leftTypes); $rightTypesCount = count($rightTypes); if ($leftTypesCount > 0 && $rightTypesCount > 0) { $resultTypes = []; $generalize = $leftTypesCount * $rightTypesCount > self::CALCULATE_SCALARS_LIMIT; if (!$generalize) { foreach ($leftTypes as $leftTypeInner) { foreach ($rightTypes as $rightTypeInner) { $leftNumberType = $leftTypeInner->toNumber(); $rightNumberType = $rightTypeInner->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } if (!$leftNumberType instanceof ConstantScalarType || !$rightNumberType instanceof ConstantScalarType) { throw new ShouldNotHappenException(); } $rightIntegerValue = (int) $rightNumberType->getValue(); if ($rightIntegerValue === 0) { return new ErrorType(); } $resultType = $this->getTypeFromValue((int) $leftNumberType->getValue() % $rightIntegerValue); $resultTypes[] = $resultType; } } return TypeCombinator::union(...$resultTypes); } $leftType = $this->optimizeScalarType($leftType); $rightType = $this->optimizeScalarType($rightType); } $integerType = $rightType->toInteger(); if ($integerType instanceof ConstantIntegerType && $integerType->getValue() === 1) { return new ConstantIntegerType(0); } $rightScalarValues = $rightType->toNumber()->getConstantScalarValues(); foreach ($rightScalarValues as $scalarValue) { if ($scalarValue === 0 || $scalarValue === 0.0) { return new ErrorType(); } } $positiveInt = IntegerRangeType::fromInterval(0, null); if ($rightType->isInteger()->yes()) { $rangeMin = null; $rangeMax = null; if ($rightType instanceof IntegerRangeType) { $rangeMax = $rightType->getMax() !== null ? $rightType->getMax() - 1 : null; } elseif ($rightType instanceof ConstantIntegerType) { $rangeMax = $rightType->getValue() - 1; } elseif ($rightType instanceof UnionType) { foreach ($rightType->getTypes() as $type) { if ($type instanceof IntegerRangeType) { if ($type->getMax() === null) { $rangeMax = null; } else { $rangeMax = max($rangeMax, $type->getMax()); } } elseif ($type instanceof ConstantIntegerType) { $rangeMax = max($rangeMax, $type->getValue() - 1); } } } if ($positiveInt->isSuperTypeOf($leftType)->yes()) { $rangeMin = 0; } elseif ($rangeMax !== null) { $rangeMin = $rangeMax * -1; } return IntegerRangeType::fromInterval($rangeMin, $rangeMax); } elseif ($positiveInt->isSuperTypeOf($leftType)->yes()) { return IntegerRangeType::fromInterval(0, null); } return new IntegerType(); } /** * @param callable(Expr): Type $getTypeCallback */ public function getPlusType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $leftType = $getTypeCallback($left); $rightType = $getTypeCallback($right); if ($leftType instanceof NeverType || $rightType instanceof NeverType) { return $this->getNeverType($leftType, $rightType); } $leftTypes = $leftType->getConstantScalarTypes(); $rightTypes = $rightType->getConstantScalarTypes(); $leftTypesCount = count($leftTypes); $rightTypesCount = count($rightTypes); if ($leftTypesCount > 0 && $rightTypesCount > 0) { $resultTypes = []; $generalize = $leftTypesCount * $rightTypesCount > self::CALCULATE_SCALARS_LIMIT; if (!$generalize) { foreach ($leftTypes as $leftTypeInner) { foreach ($rightTypes as $rightTypeInner) { $leftNumberType = $leftTypeInner->toNumber(); $rightNumberType = $rightTypeInner->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } if (!$leftNumberType instanceof ConstantScalarType || !$rightNumberType instanceof ConstantScalarType) { throw new ShouldNotHappenException(); } $resultType = $this->getTypeFromValue($leftNumberType->getValue() + $rightNumberType->getValue()); $resultTypes[] = $resultType; } } return TypeCombinator::union(...$resultTypes); } $leftType = $this->optimizeScalarType($leftType); $rightType = $this->optimizeScalarType($rightType); } $leftConstantArrays = $leftType->getConstantArrays(); $rightConstantArrays = $rightType->getConstantArrays(); $leftCount = count($leftConstantArrays); $rightCount = count($rightConstantArrays); if ($leftCount > 0 && $rightCount > 0 && $leftCount + $rightCount < ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) { $resultTypes = []; foreach ($rightConstantArrays as $rightConstantArray) { foreach ($leftConstantArrays as $leftConstantArray) { $newArrayBuilder = ConstantArrayTypeBuilder::createFromConstantArray($rightConstantArray); foreach ($leftConstantArray->getKeyTypes() as $i => $leftKeyType) { $optional = $leftConstantArray->isOptionalKey($i); $valueType = $leftConstantArray->getOffsetValueType($leftKeyType); if (!$optional) { if ($rightConstantArray->hasOffsetValueType($leftKeyType)->maybe()) { $valueType = TypeCombinator::union($valueType, $rightConstantArray->getOffsetValueType($leftKeyType)); } } $newArrayBuilder->setOffsetValueType($leftKeyType, $valueType, $optional); } $resultTypes[] = $newArrayBuilder->getArray(); } } return TypeCombinator::union(...$resultTypes); } $leftIsArray = $leftType->isArray(); $rightIsArray = $rightType->isArray(); if ($leftIsArray->yes() && $rightIsArray->yes()) { if ($leftType->getIterableKeyType()->equals($rightType->getIterableKeyType())) { // to preserve BenevolentUnionType $keyType = $leftType->getIterableKeyType(); } else { $keyTypes = []; foreach ([$leftType->getIterableKeyType(), $rightType->getIterableKeyType()] as $keyType) { $keyTypes[] = $keyType; } $keyType = TypeCombinator::union(...$keyTypes); } $arrayType = new ArrayType($keyType, TypeCombinator::union($leftType->getIterableValueType(), $rightType->getIterableValueType())); if ($leftType->isIterableAtLeastOnce()->yes() || $rightType->isIterableAtLeastOnce()->yes()) { $arrayType = TypeCombinator::intersect($arrayType, new NonEmptyArrayType()); } if ($leftType->isList()->yes() && $rightType->isList()->yes()) { $arrayType = AccessoryArrayListType::intersectWith($arrayType); } return $arrayType; } if ($leftType instanceof MixedType && $rightType instanceof MixedType) { if ($leftIsArray->no() && $rightIsArray->no()) { return new BenevolentUnionType([new FloatType(), new IntegerType()]); } return new BenevolentUnionType([new FloatType(), new IntegerType(), new ArrayType(new MixedType(), new MixedType())]); } if ($leftIsArray->yes() && $rightIsArray->no() || $leftIsArray->no() && $rightIsArray->yes()) { return new ErrorType(); } if ($leftIsArray->yes() && $rightIsArray->maybe() || $leftIsArray->maybe() && $rightIsArray->yes()) { $resultType = new ArrayType(new MixedType(), new MixedType()); if ($leftType->isIterableAtLeastOnce()->yes() || $rightType->isIterableAtLeastOnce()->yes()) { return TypeCombinator::intersect($resultType, new NonEmptyArrayType()); } return $resultType; } if ($leftIsArray->maybe() && $rightIsArray->maybe()) { $plusable = new UnionType([new StringType(), new FloatType(), new IntegerType(), new ArrayType(new MixedType(), new MixedType()), new BooleanType()]); $plusableSuperTypeOfLeft = $plusable->isSuperTypeOf($leftType)->yes(); $plusableSuperTypeOfRight = $plusable->isSuperTypeOf($rightType)->yes(); if ($plusableSuperTypeOfLeft && $plusableSuperTypeOfRight) { return TypeCombinator::union($leftType, $rightType); } if ($plusableSuperTypeOfLeft && $rightType instanceof MixedType) { return $leftType; } if ($plusableSuperTypeOfRight && $leftType instanceof MixedType) { return $rightType; } } return $this->resolveCommonMath(new BinaryOp\Plus($left, $right), $leftType, $rightType); } /** * @param callable(Expr): Type $getTypeCallback */ public function getMinusType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $leftType = $getTypeCallback($left); $rightType = $getTypeCallback($right); $leftTypes = $leftType->getConstantScalarTypes(); $rightTypes = $rightType->getConstantScalarTypes(); $leftTypesCount = count($leftTypes); $rightTypesCount = count($rightTypes); if ($leftTypesCount > 0 && $rightTypesCount > 0) { $resultTypes = []; $generalize = $leftTypesCount * $rightTypesCount > self::CALCULATE_SCALARS_LIMIT; if (!$generalize) { foreach ($leftTypes as $leftTypeInner) { foreach ($rightTypes as $rightTypeInner) { $leftNumberType = $leftTypeInner->toNumber(); $rightNumberType = $rightTypeInner->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } if (!$leftNumberType instanceof ConstantScalarType || !$rightNumberType instanceof ConstantScalarType) { throw new ShouldNotHappenException(); } $resultType = $this->getTypeFromValue($leftNumberType->getValue() - $rightNumberType->getValue()); $resultTypes[] = $resultType; } } return TypeCombinator::union(...$resultTypes); } $leftType = $this->optimizeScalarType($leftType); $rightType = $this->optimizeScalarType($rightType); } return $this->resolveCommonMath(new BinaryOp\Minus($left, $right), $leftType, $rightType); } /** * @param callable(Expr): Type $getTypeCallback */ public function getMulType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $leftType = $getTypeCallback($left); $rightType = $getTypeCallback($right); $leftTypes = $leftType->getConstantScalarTypes(); $rightTypes = $rightType->getConstantScalarTypes(); $leftTypesCount = count($leftTypes); $rightTypesCount = count($rightTypes); if ($leftTypesCount > 0 && $rightTypesCount > 0) { $resultTypes = []; $generalize = $leftTypesCount * $rightTypesCount > self::CALCULATE_SCALARS_LIMIT; if (!$generalize) { foreach ($leftTypes as $leftTypeInner) { foreach ($rightTypes as $rightTypeInner) { $leftNumberType = $leftTypeInner->toNumber(); $rightNumberType = $rightTypeInner->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } if (!$leftNumberType instanceof ConstantScalarType || !$rightNumberType instanceof ConstantScalarType) { throw new ShouldNotHappenException(); } $resultType = $this->getTypeFromValue($leftNumberType->getValue() * $rightNumberType->getValue()); $resultTypes[] = $resultType; } } return TypeCombinator::union(...$resultTypes); } $leftType = $this->optimizeScalarType($leftType); $rightType = $this->optimizeScalarType($rightType); } $leftNumberType = $leftType->toNumber(); if ($leftNumberType instanceof ConstantIntegerType && $leftNumberType->getValue() === 0) { if ($rightType->isFloat()->yes()) { return new ConstantFloatType(0.0); } return new ConstantIntegerType(0); } $rightNumberType = $rightType->toNumber(); if ($rightNumberType instanceof ConstantIntegerType && $rightNumberType->getValue() === 0) { if ($leftType->isFloat()->yes()) { return new ConstantFloatType(0.0); } return new ConstantIntegerType(0); } return $this->resolveCommonMath(new BinaryOp\Mul($left, $right), $leftType, $rightType); } /** * @param callable(Expr): Type $getTypeCallback */ public function getPowType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $leftType = $getTypeCallback($left); $rightType = $getTypeCallback($right); $exponentiatedTyped = $leftType->exponentiate($rightType); if (!$exponentiatedTyped instanceof ErrorType) { return $exponentiatedTyped; } $extensionSpecified = $this->callOperatorTypeSpecifyingExtensions(new BinaryOp\Pow($left, $right), $leftType, $rightType); if ($extensionSpecified !== null) { return $extensionSpecified; } return new ErrorType(); } /** * @param callable(Expr): Type $getTypeCallback */ public function getShiftLeftType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $leftType = $getTypeCallback($left); $rightType = $getTypeCallback($right); if ($leftType instanceof NeverType || $rightType instanceof NeverType) { return $this->getNeverType($leftType, $rightType); } $leftTypes = $leftType->getConstantScalarTypes(); $rightTypes = $rightType->getConstantScalarTypes(); $leftTypesCount = count($leftTypes); $rightTypesCount = count($rightTypes); if ($leftTypesCount > 0 && $rightTypesCount > 0) { $resultTypes = []; $generalize = $leftTypesCount * $rightTypesCount > self::CALCULATE_SCALARS_LIMIT; if (!$generalize) { foreach ($leftTypes as $leftTypeInner) { foreach ($rightTypes as $rightTypeInner) { $leftNumberType = $leftTypeInner->toNumber(); $rightNumberType = $rightTypeInner->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } if (!$leftNumberType instanceof ConstantScalarType || !$rightNumberType instanceof ConstantScalarType) { throw new ShouldNotHappenException(); } if ($rightNumberType->getValue() < 0) { return new ErrorType(); } $resultType = $this->getTypeFromValue(intval($leftNumberType->getValue()) << intval($rightNumberType->getValue())); $resultTypes[] = $resultType; } } return TypeCombinator::union(...$resultTypes); } $leftType = $this->optimizeScalarType($leftType); $rightType = $this->optimizeScalarType($rightType); } $leftNumberType = $leftType->toNumber(); $rightNumberType = $rightType->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } return $this->resolveCommonMath(new Expr\BinaryOp\ShiftLeft($left, $right), $leftType, $rightType); } /** * @param callable(Expr): Type $getTypeCallback */ public function getShiftRightType(Expr $left, Expr $right, callable $getTypeCallback) : Type { $leftType = $getTypeCallback($left); $rightType = $getTypeCallback($right); if ($leftType instanceof NeverType || $rightType instanceof NeverType) { return $this->getNeverType($leftType, $rightType); } $leftTypes = $leftType->getConstantScalarTypes(); $rightTypes = $rightType->getConstantScalarTypes(); $leftTypesCount = count($leftTypes); $rightTypesCount = count($rightTypes); if ($leftTypesCount > 0 && $rightTypesCount > 0) { $resultTypes = []; $generalize = $leftTypesCount * $rightTypesCount > self::CALCULATE_SCALARS_LIMIT; if (!$generalize) { foreach ($leftTypes as $leftTypeInner) { foreach ($rightTypes as $rightTypeInner) { $leftNumberType = $leftTypeInner->toNumber(); $rightNumberType = $rightTypeInner->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } if (!$leftNumberType instanceof ConstantScalarType || !$rightNumberType instanceof ConstantScalarType) { throw new ShouldNotHappenException(); } if ($rightNumberType->getValue() < 0) { return new ErrorType(); } $resultType = $this->getTypeFromValue(intval($leftNumberType->getValue()) >> intval($rightNumberType->getValue())); $resultTypes[] = $resultType; } } return TypeCombinator::union(...$resultTypes); } $leftType = $this->optimizeScalarType($leftType); $rightType = $this->optimizeScalarType($rightType); } $leftNumberType = $leftType->toNumber(); $rightNumberType = $rightType->toNumber(); if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } return $this->resolveCommonMath(new Expr\BinaryOp\ShiftRight($left, $right), $leftType, $rightType); } private function optimizeScalarType(Type $type) : Type { $types = []; if ($type->isInteger()->yes()) { $types[] = new IntegerType(); } if ($type->isString()->yes()) { $types[] = new StringType(); } if ($type->isFloat()->yes()) { $types[] = new FloatType(); } if ($type->isNull()->yes()) { $types[] = new NullType(); } if (count($types) === 0) { return new ErrorType(); } if (count($types) === 1) { return $types[0]; } return new UnionType($types); } /** * @return TypeResult */ public function resolveIdenticalType(Type $leftType, Type $rightType) : TypeResult { if ($leftType instanceof NeverType || $rightType instanceof NeverType) { return new TypeResult(new ConstantBooleanType(\false), []); } if ($leftType instanceof ConstantScalarType && $rightType instanceof ConstantScalarType) { return new TypeResult(new ConstantBooleanType($leftType->getValue() === $rightType->getValue()), []); } $leftTypeFiniteTypes = $leftType->getFiniteTypes(); $rightTypeFiniteType = $rightType->getFiniteTypes(); if (count($leftTypeFiniteTypes) === 1 && count($rightTypeFiniteType) === 1) { return new TypeResult(new ConstantBooleanType($leftTypeFiniteTypes[0]->equals($rightTypeFiniteType[0])), []); } $leftIsSuperTypeOfRight = $leftType->isSuperTypeOfWithReason($rightType); $rightIsSuperTypeOfLeft = $rightType->isSuperTypeOfWithReason($leftType); if ($leftIsSuperTypeOfRight->no() && $rightIsSuperTypeOfLeft->no()) { return new TypeResult(new ConstantBooleanType(\false), array_merge($leftIsSuperTypeOfRight->reasons, $rightIsSuperTypeOfLeft->reasons)); } if ($leftType instanceof ConstantArrayType && $rightType instanceof ConstantArrayType) { return $this->resolveConstantArrayTypeComparison($leftType, $rightType, function ($leftValueType, $rightValueType) : TypeResult { return $this->resolveIdenticalType($leftValueType, $rightValueType); }); } return new TypeResult(new BooleanType(), []); } /** * @return TypeResult */ public function resolveEqualType(Type $leftType, Type $rightType) : TypeResult { if ($leftType->isEnum()->yes() && $rightType->isTrue()->no() || $rightType->isEnum()->yes() && $leftType->isTrue()->no()) { return $this->resolveIdenticalType($leftType, $rightType); } if ($leftType instanceof ConstantArrayType && $rightType instanceof ConstantArrayType) { return $this->resolveConstantArrayTypeComparison($leftType, $rightType, function ($leftValueType, $rightValueType) : TypeResult { return $this->resolveEqualType($leftValueType, $rightValueType); }); } return new TypeResult($leftType->looseCompare($rightType, $this->phpVersion), []); } /** * @param callable(Type, Type): TypeResult $valueComparisonCallback * @return TypeResult */ private function resolveConstantArrayTypeComparison(ConstantArrayType $leftType, ConstantArrayType $rightType, callable $valueComparisonCallback) : TypeResult { $leftKeyTypes = $leftType->getKeyTypes(); $rightKeyTypes = $rightType->getKeyTypes(); $leftValueTypes = $leftType->getValueTypes(); $rightValueTypes = $rightType->getValueTypes(); $resultType = new ConstantBooleanType(\true); foreach ($leftKeyTypes as $i => $leftKeyType) { $leftOptional = $leftType->isOptionalKey($i); if ($leftOptional) { $resultType = new BooleanType(); } if (count($rightKeyTypes) === 0) { if (!$leftOptional) { return new TypeResult(new ConstantBooleanType(\false), []); } continue; } $found = \false; foreach ($rightKeyTypes as $j => $rightKeyType) { unset($rightKeyTypes[$j]); if ($leftKeyType->equals($rightKeyType)) { $found = \true; break; } elseif (!$rightType->isOptionalKey($j)) { return new TypeResult(new ConstantBooleanType(\false), []); } } if (!$found) { if (!$leftOptional) { return new TypeResult(new ConstantBooleanType(\false), []); } continue; } if (!isset($j)) { throw new ShouldNotHappenException(); } $rightOptional = $rightType->isOptionalKey($j); if ($rightOptional) { $resultType = new BooleanType(); if ($leftOptional) { continue; } } $leftIdenticalToRightResult = $valueComparisonCallback($leftValueTypes[$i], $rightValueTypes[$j]); $leftIdenticalToRight = $leftIdenticalToRightResult->type; if ($leftIdenticalToRight->isFalse()->yes()) { return $leftIdenticalToRightResult; } $resultType = TypeCombinator::union($resultType, $leftIdenticalToRight); } foreach (array_keys($rightKeyTypes) as $j) { if (!$rightType->isOptionalKey($j)) { return new TypeResult(new ConstantBooleanType(\false), []); } $resultType = new BooleanType(); } return new TypeResult($resultType->toBoolean(), []); } private function callOperatorTypeSpecifyingExtensions(Expr\BinaryOp $expr, Type $leftType, Type $rightType) : ?Type { $operatorSigil = $expr->getOperatorSigil(); $operatorTypeSpecifyingExtensions = $this->operatorTypeSpecifyingExtensionRegistryProvider->getRegistry()->getOperatorTypeSpecifyingExtensions($operatorSigil, $leftType, $rightType); /** @var Type[] $extensionTypes */ $extensionTypes = []; foreach ($operatorTypeSpecifyingExtensions as $extension) { $extensionTypes[] = $extension->specifyType($operatorSigil, $leftType, $rightType); } if (count($extensionTypes) > 0) { return TypeCombinator::union(...$extensionTypes); } return null; } /** * @param BinaryOp\Plus|BinaryOp\Minus|BinaryOp\Mul|BinaryOp\Div|BinaryOp\ShiftLeft|BinaryOp\ShiftRight $expr */ private function resolveCommonMath(Expr\BinaryOp $expr, Type $leftType, Type $rightType) : Type { $types = TypeCombinator::union($leftType, $rightType); $leftNumberType = $leftType->toNumber(); $rightNumberType = $rightType->toNumber(); if (!$types instanceof MixedType && ($rightNumberType instanceof IntegerRangeType || $rightNumberType instanceof ConstantIntegerType || $rightNumberType instanceof UnionType)) { if ($leftNumberType instanceof IntegerRangeType || $leftNumberType instanceof ConstantIntegerType) { return $this->integerRangeMath($leftNumberType, $expr, $rightNumberType); } elseif ($leftNumberType instanceof UnionType) { $unionParts = []; foreach ($leftNumberType->getTypes() as $type) { $numberType = $type->toNumber(); if ($numberType instanceof IntegerRangeType || $numberType instanceof ConstantIntegerType) { $unionParts[] = $this->integerRangeMath($numberType, $expr, $rightNumberType); } else { $unionParts[] = $numberType; } } $union = TypeCombinator::union(...$unionParts); if ($leftNumberType instanceof BenevolentUnionType) { return TypeUtils::toBenevolentUnion($union)->toNumber(); } return $union->toNumber(); } } $specifiedTypes = $this->callOperatorTypeSpecifyingExtensions($expr, $leftType, $rightType); if ($specifiedTypes !== null) { return $specifiedTypes; } if ($leftType->isArray()->yes() || $rightType->isArray()->yes() || $types->isArray()->yes()) { return new ErrorType(); } if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) { return new ErrorType(); } if ($leftNumberType instanceof NeverType || $rightNumberType instanceof NeverType) { return $this->getNeverType($leftNumberType, $rightNumberType); } if ($leftNumberType->isFloat()->yes() || $rightNumberType->isFloat()->yes()) { if ($expr instanceof Expr\BinaryOp\ShiftLeft || $expr instanceof Expr\BinaryOp\ShiftRight) { return new IntegerType(); } return new FloatType(); } $resultType = TypeCombinator::union($leftNumberType, $rightNumberType); if ($expr instanceof Expr\BinaryOp\Div) { if ($types instanceof MixedType || $resultType->isInteger()->yes()) { return new BenevolentUnionType([new IntegerType(), new FloatType()]); } return new UnionType([new IntegerType(), new FloatType()]); } if ($types instanceof MixedType || $leftType instanceof BenevolentUnionType || $rightType instanceof BenevolentUnionType) { return TypeUtils::toBenevolentUnion($resultType); } return $resultType; } /** * @param ConstantIntegerType|IntegerRangeType $range * @param BinaryOp\Div|BinaryOp\Minus|BinaryOp\Mul|BinaryOp\Plus|BinaryOp\ShiftLeft|BinaryOp\ShiftRight $node */ private function integerRangeMath(Type $range, BinaryOp $node, Type $operand) : Type { if ($range instanceof IntegerRangeType) { $rangeMin = $range->getMin(); $rangeMax = $range->getMax(); } else { $rangeMin = $range->getValue(); $rangeMax = $rangeMin; } if ($operand instanceof UnionType) { $unionParts = []; foreach ($operand->getTypes() as $type) { $numberType = $type->toNumber(); if ($numberType instanceof IntegerRangeType || $numberType instanceof ConstantIntegerType) { $unionParts[] = $this->integerRangeMath($range, $node, $numberType); } else { $unionParts[] = $type->toNumber(); } } $union = TypeCombinator::union(...$unionParts); if ($operand instanceof BenevolentUnionType) { return TypeUtils::toBenevolentUnion($union)->toNumber(); } return $union->toNumber(); } $operand = $operand->toNumber(); if ($operand instanceof IntegerRangeType) { $operandMin = $operand->getMin(); $operandMax = $operand->getMax(); } elseif ($operand instanceof ConstantIntegerType) { $operandMin = $operand->getValue(); $operandMax = $operand->getValue(); } else { return $operand; } if ($node instanceof BinaryOp\Plus) { if ($operand instanceof ConstantIntegerType) { /** @var int|float|null $min */ $min = $rangeMin !== null ? $rangeMin + $operand->getValue() : null; /** @var int|float|null $max */ $max = $rangeMax !== null ? $rangeMax + $operand->getValue() : null; } else { /** @var int|float|null $min */ $min = $rangeMin !== null && $operand->getMin() !== null ? $rangeMin + $operand->getMin() : null; /** @var int|float|null $max */ $max = $rangeMax !== null && $operand->getMax() !== null ? $rangeMax + $operand->getMax() : null; } } elseif ($node instanceof BinaryOp\Minus) { if ($operand instanceof ConstantIntegerType) { /** @var int|float|null $min */ $min = $rangeMin !== null ? $rangeMin - $operand->getValue() : null; /** @var int|float|null $max */ $max = $rangeMax !== null ? $rangeMax - $operand->getValue() : null; } else { if ($rangeMin === $rangeMax && $rangeMin !== null && ($operand->getMin() === null || $operand->getMax() === null)) { $min = null; $max = $rangeMin; } else { if ($operand->getMin() === null) { $min = null; } elseif ($rangeMin !== null) { if ($operand->getMax() !== null) { /** @var int|float $min */ $min = $rangeMin - $operand->getMax(); } else { /** @var int|float $min */ $min = $rangeMin - $operand->getMin(); } } else { $min = null; } if ($operand->getMax() === null) { $min = null; $max = null; } elseif ($rangeMax !== null) { if ($rangeMin !== null && $operand->getMin() === null) { /** @var int|float $min */ $min = $rangeMin - $operand->getMax(); $max = null; } elseif ($operand->getMin() !== null) { /** @var int|float $max */ $max = $rangeMax - $operand->getMin(); } else { $max = null; } } else { $max = null; } if ($min !== null && $max !== null && $min > $max) { [$min, $max] = [$max, $min]; } } } } elseif ($node instanceof Expr\BinaryOp\Mul) { $min1 = $rangeMin === 0 || $operandMin === 0 ? 0 : ($rangeMin ?? -INF) * ($operandMin ?? -INF); $min2 = $rangeMin === 0 || $operandMax === 0 ? 0 : ($rangeMin ?? -INF) * ($operandMax ?? INF); $max1 = $rangeMax === 0 || $operandMin === 0 ? 0 : ($rangeMax ?? INF) * ($operandMin ?? -INF); $max2 = $rangeMax === 0 || $operandMax === 0 ? 0 : ($rangeMax ?? INF) * ($operandMax ?? INF); $min = min($min1, $min2, $max1, $max2); $max = max($min1, $min2, $max1, $max2); if (!is_finite($min)) { $min = null; } if (!is_finite($max)) { $max = null; } } elseif ($node instanceof Expr\BinaryOp\Div) { if ($operand instanceof ConstantIntegerType) { $min = $rangeMin !== null && $operand->getValue() !== 0 ? $rangeMin / $operand->getValue() : null; $max = $rangeMax !== null && $operand->getValue() !== 0 ? $rangeMax / $operand->getValue() : null; } else { // Avoid division by zero when looking for the min and the max by using the closest int $operandMin = $operandMin !== 0 ? $operandMin : 1; $operandMax = $operandMax !== 0 ? $operandMax : -1; if (($operandMin < 0 || $operandMin === null) && ($operandMax > 0 || $operandMax === null)) { $negativeOperand = IntegerRangeType::fromInterval($operandMin, 0); assert($negativeOperand instanceof IntegerRangeType); $positiveOperand = IntegerRangeType::fromInterval(0, $operandMax); assert($positiveOperand instanceof IntegerRangeType); $result = TypeCombinator::union($this->integerRangeMath($range, $node, $negativeOperand), $this->integerRangeMath($range, $node, $positiveOperand))->toNumber(); if ($result->equals(new UnionType([new IntegerType(), new FloatType()]))) { return new BenevolentUnionType([new IntegerType(), new FloatType()]); } return $result; } if (($rangeMin < 0 || $rangeMin === null) && ($rangeMax > 0 || $rangeMax === null)) { $negativeRange = IntegerRangeType::fromInterval($rangeMin, 0); assert($negativeRange instanceof IntegerRangeType); $positiveRange = IntegerRangeType::fromInterval(0, $rangeMax); assert($positiveRange instanceof IntegerRangeType); $result = TypeCombinator::union($this->integerRangeMath($negativeRange, $node, $operand), $this->integerRangeMath($positiveRange, $node, $operand))->toNumber(); if ($result->equals(new UnionType([new IntegerType(), new FloatType()]))) { return new BenevolentUnionType([new IntegerType(), new FloatType()]); } return $result; } $rangeMinSign = ($rangeMin ?? -INF) <=> 0; $rangeMaxSign = ($rangeMax ?? INF) <=> 0; $min1 = $operandMin !== null ? ($rangeMin ?? -INF) / $operandMin : $rangeMinSign * -0.1; $min2 = $operandMax !== null ? ($rangeMin ?? -INF) / $operandMax : $rangeMinSign * 0.1; $max1 = $operandMin !== null ? ($rangeMax ?? INF) / $operandMin : $rangeMaxSign * -0.1; $max2 = $operandMax !== null ? ($rangeMax ?? INF) / $operandMax : $rangeMaxSign * 0.1; $min = min($min1, $min2, $max1, $max2); $max = max($min1, $min2, $max1, $max2); if ($min === -INF) { $min = null; } if ($max === INF) { $max = null; } } if ($min !== null && $max !== null && $min > $max) { [$min, $max] = [$max, $min]; } if (is_float($min)) { $min = (int) ceil($min); } if (is_float($max)) { $max = (int) floor($max); } // invert maximas on division with negative constants if (($range instanceof ConstantIntegerType && $range->getValue() < 0 || $operand instanceof ConstantIntegerType && $operand->getValue() < 0) && ($min === null || $max === null)) { [$min, $max] = [$max, $min]; } if ($min === null && $max === null) { return new BenevolentUnionType([new IntegerType(), new FloatType()]); } return TypeCombinator::union(IntegerRangeType::fromInterval($min, $max), new FloatType()); } elseif ($node instanceof Expr\BinaryOp\ShiftLeft) { if (!$operand instanceof ConstantIntegerType) { return new IntegerType(); } if ($operand->getValue() < 0) { return new ErrorType(); } $min = $rangeMin !== null ? intval($rangeMin) << $operand->getValue() : null; $max = $rangeMax !== null ? intval($rangeMax) << $operand->getValue() : null; } elseif ($node instanceof Expr\BinaryOp\ShiftRight) { if (!$operand instanceof ConstantIntegerType) { return new IntegerType(); } if ($operand->getValue() < 0) { return new ErrorType(); } $min = $rangeMin !== null ? intval($rangeMin) >> $operand->getValue() : null; $max = $rangeMax !== null ? intval($rangeMax) >> $operand->getValue() : null; } else { throw new ShouldNotHappenException(); } if (is_float($min)) { $min = null; } if (is_float($max)) { $max = null; } return IntegerRangeType::fromInterval($min, $max); } /** * @param callable(Expr): Type $getTypeCallback * @param Name|Expr $class */ public function getClassConstFetchTypeByReflection($class, string $constantName, ?\PHPStan\Reflection\ClassReflection $classReflection, callable $getTypeCallback) : Type { $isObject = \false; if ($class instanceof Name) { $constantClass = (string) $class; $constantClassType = new ObjectType($constantClass); $namesToResolve = ['self', 'parent']; if ($classReflection !== null) { if ($classReflection->isFinal()) { $namesToResolve[] = 'static'; } elseif (strtolower($constantClass) === 'static') { if (strtolower($constantName) === 'class') { return new GenericClassStringType(new StaticType($classReflection)); } $namesToResolve[] = 'static'; $isObject = \true; } } if (in_array(strtolower($constantClass), $namesToResolve, \true)) { $resolvedName = $this->resolveName($class, $classReflection); if (strtolower($resolvedName) === 'parent' && strtolower($constantName) === 'class') { return new ClassStringType(); } $constantClassType = $this->resolveTypeByName($class, $classReflection); } if (strtolower($constantName) === 'class') { return new ConstantStringType($constantClassType->getClassName(), \true); } } elseif ($class instanceof String_ && strtolower($constantName) === 'class') { return new ConstantStringType($class->value, \true); } else { $constantClassType = $getTypeCallback($class); $isObject = \true; } if (strtolower($constantName) === 'class') { return TypeTraverser::map($constantClassType, function (Type $type, callable $traverse) : Type { if ($type instanceof UnionType || $type instanceof IntersectionType) { return $traverse($type); } if ($type instanceof NullType) { return $type; } if ($type instanceof EnumCaseObjectType) { return TypeCombinator::intersect(new GenericClassStringType(new ObjectType($type->getClassName())), new AccessoryLiteralStringType()); } $objectClassNames = $type->getObjectClassNames(); if (count($objectClassNames) > 1) { throw new ShouldNotHappenException(); } if ($type instanceof TemplateType && $objectClassNames === []) { return TypeCombinator::intersect(new GenericClassStringType($type), new AccessoryLiteralStringType()); } elseif ($objectClassNames !== [] && $this->getReflectionProvider()->hasClass($objectClassNames[0])) { $reflection = $this->getReflectionProvider()->getClass($objectClassNames[0]); if ($reflection->isFinalByKeyword()) { return new ConstantStringType($reflection->getName(), \true); } return TypeCombinator::intersect(new GenericClassStringType($type), new AccessoryLiteralStringType()); } elseif ($type->isObject()->yes()) { return TypeCombinator::intersect(new ClassStringType(), new AccessoryLiteralStringType()); } return new ErrorType(); }); } if ($constantClassType->isClassStringType()->yes()) { if ($constantClassType->isConstantScalarValue()->yes()) { $isObject = \false; } $constantClassType = $constantClassType->getClassStringObjectType(); } $types = []; foreach ($constantClassType->getObjectClassNames() as $referencedClass) { if (!$this->getReflectionProvider()->hasClass($referencedClass)) { continue; } $constantClassReflection = $this->getReflectionProvider()->getClass($referencedClass); if (!$constantClassReflection->hasConstant($constantName)) { continue; } if ($constantClassReflection->isEnum() && $constantClassReflection->hasEnumCase($constantName)) { $types[] = new EnumCaseObjectType($constantClassReflection->getName(), $constantName); continue; } $resolvingName = sprintf('%s::%s', $constantClassReflection->getName(), $constantName); if (array_key_exists($resolvingName, $this->currentlyResolvingClassConstant)) { $types[] = new MixedType(); continue; } $this->currentlyResolvingClassConstant[$resolvingName] = \true; if (!$isObject) { $reflectionConstant = $constantClassReflection->getNativeReflection()->getReflectionConstant($constantName); if ($reflectionConstant === \false) { unset($this->currentlyResolvingClassConstant[$resolvingName]); continue; } $reflectionConstantDeclaringClass = $reflectionConstant->getDeclaringClass(); $constantType = $this->getType($reflectionConstant->getValueExpression(), \PHPStan\Reflection\InitializerExprContext::fromClass($reflectionConstantDeclaringClass->getName(), $reflectionConstantDeclaringClass->getFileName() ?: null)); $nativeType = null; if ($reflectionConstant->getType() !== null) { $nativeType = TypehintHelper::decideTypeFromReflection($reflectionConstant->getType(), null, $constantClassReflection); } $types[] = $this->constantResolver->resolveClassConstantType($constantClassReflection->getName(), $constantName, $constantType, $nativeType); unset($this->currentlyResolvingClassConstant[$resolvingName]); continue; } $constantReflection = $constantClassReflection->getConstant($constantName); if (!$constantClassReflection->isFinal() && !$constantReflection->isFinal() && !$constantReflection->hasPhpDocType() && !$constantReflection->hasNativeType()) { unset($this->currentlyResolvingClassConstant[$resolvingName]); return new MixedType(); } if (!$constantClassReflection->isFinal()) { $constantType = $constantReflection->getValueType(); } else { $constantType = $this->getType($constantReflection->getValueExpr(), \PHPStan\Reflection\InitializerExprContext::fromClassReflection($constantReflection->getDeclaringClass())); } $nativeType = $constantReflection->getNativeType(); $constantType = $this->constantResolver->resolveClassConstantType($constantClassReflection->getName(), $constantName, $constantType, $nativeType); unset($this->currentlyResolvingClassConstant[$resolvingName]); $types[] = $constantType; } if (count($types) > 0) { return TypeCombinator::union(...$types); } if (!$constantClassType->hasConstant($constantName)->yes()) { return new ErrorType(); } return $constantClassType->getConstant($constantName)->getValueType(); } /** * @param callable(Expr): Type $getTypeCallback * @param Name|Expr $class */ public function getClassConstFetchType($class, string $constantName, ?string $className, callable $getTypeCallback) : Type { $classReflection = null; if ($className !== null && $this->getReflectionProvider()->hasClass($className)) { $classReflection = $this->getReflectionProvider()->getClass($className); } return $this->getClassConstFetchTypeByReflection($class, $constantName, $classReflection, $getTypeCallback); } /** * @param callable(Expr): Type $getTypeCallback */ public function getUnaryMinusType(Expr $expr, callable $getTypeCallback) : Type { $type = $getTypeCallback($expr)->toNumber(); $scalarValues = $type->getConstantScalarValues(); if (count($scalarValues) > 0) { $newTypes = []; foreach ($scalarValues as $scalarValue) { if (is_int($scalarValue)) { /** @var int|float $newValue */ $newValue = -$scalarValue; if (!is_int($newValue)) { return $type; } $newTypes[] = new ConstantIntegerType($newValue); } elseif (is_float($scalarValue)) { $newTypes[] = new ConstantFloatType(-$scalarValue); } } return TypeCombinator::union(...$newTypes); } if ($type instanceof IntegerRangeType) { return $getTypeCallback(new Expr\BinaryOp\Mul($expr, new LNumber(-1))); } return $type; } /** * @param callable(Expr): Type $getTypeCallback */ public function getBitwiseNotType(Expr $expr, callable $getTypeCallback) : Type { $exprType = $getTypeCallback($expr); return TypeTraverser::map($exprType, static function (Type $type, callable $traverse) : Type { if ($type instanceof UnionType || $type instanceof IntersectionType) { return $traverse($type); } if ($type instanceof ConstantStringType) { return new ConstantStringType(~$type->getValue()); } if ($type->isString()->yes()) { $accessories = [new StringType()]; if ($type->isNonEmptyString()->yes()) { $accessories[] = new AccessoryNonEmptyStringType(); } // it is not useful to apply numeric and literal strings here. // numeric string isn't certainly kept numeric: 3v4l.org/JERDB return TypeCombinator::intersect(...$accessories); } if ($type->isInteger()->yes() || $type->isFloat()->yes()) { return new IntegerType(); //no const types here, result depends on PHP_INT_SIZE } return new ErrorType(); }); } private function resolveName(Name $name, ?\PHPStan\Reflection\ClassReflection $classReflection) : string { $originalClass = (string) $name; if ($classReflection !== null) { $lowerClass = strtolower($originalClass); if (in_array($lowerClass, ['self', 'static'], \true)) { return $classReflection->getName(); } elseif ($lowerClass === 'parent') { if ($classReflection->getParentClass() !== null) { return $classReflection->getParentClass()->getName(); } } } return $originalClass; } private function resolveTypeByName(Name $name, ?\PHPStan\Reflection\ClassReflection $classReflection) : TypeWithClassName { if ($name->toLowerString() === 'static' && $classReflection !== null) { return new StaticType($classReflection); } $originalClass = $this->resolveName($name, $classReflection); if ($classReflection !== null) { $thisType = new ThisType($classReflection); $ancestor = $thisType->getAncestorWithClassName($originalClass); if ($ancestor !== null) { return $ancestor; } } return new ObjectType($originalClass); } /** * @param mixed $value */ private function getTypeFromValue($value) : Type { return ConstantTypeHelper::getTypeFromValue($value); } private function getReflectionProvider() : \PHPStan\Reflection\ReflectionProvider { return $this->reflectionProviderProvider->getReflectionProvider(); } private function getNeverType(Type $leftType, Type $rightType) : Type { // make sure we don't lose the explicit flag in the process if ($leftType instanceof NeverType && $leftType->isExplicit()) { return $leftType; } if ($rightType instanceof NeverType && $rightType->isExplicit()) { return $rightType; } return new NeverType(); } } getClassReflection() */ public function isInClass() : bool; public function getClassReflection() : ?\PHPStan\Reflection\ClassReflection; public function canAccessProperty(\PHPStan\Reflection\PropertyReflection $propertyReflection) : bool; public function canCallMethod(\PHPStan\Reflection\MethodReflection $methodReflection) : bool; public function canAccessConstant(\PHPStan\Reflection\ConstantReflection $constantReflection) : bool; } $argTypes */ public static function resolve(array $argTypes, \PHPStan\Reflection\ParametersAcceptor $parametersAcceptor) : \PHPStan\Reflection\ParametersAcceptorWithPhpDocs { $typeMap = TemplateTypeMap::createEmpty(); $passedArgs = []; $parameters = $parametersAcceptor->getParameters(); $namedArgTypes = []; foreach ($argTypes as $i => $argType) { if (is_int($i)) { if (isset($parameters[$i])) { $namedArgTypes[$parameters[$i]->getName()] = $argType; continue; } if (count($parameters) > 0) { $lastParameter = $parameters[count($parameters) - 1]; if ($lastParameter->isVariadic()) { $parameterName = $lastParameter->getName(); if (array_key_exists($parameterName, $namedArgTypes)) { $namedArgTypes[$parameterName] = TypeCombinator::union($namedArgTypes[$parameterName], $argType); continue; } $namedArgTypes[$parameterName] = $argType; } } continue; } $namedArgTypes[$i] = $argType; } foreach ($parametersAcceptor->getParameters() as $param) { if (isset($namedArgTypes[$param->getName()])) { $argType = $namedArgTypes[$param->getName()]; } elseif ($param->getDefaultValue() !== null) { $argType = $param->getDefaultValue(); } else { continue; } $paramType = $param->getType(); $typeMap = $typeMap->union($paramType->inferTemplateTypes($argType)); $passedArgs['$' . $param->getName()] = $argType; } $returnType = $parametersAcceptor->getReturnType(); if ($returnType instanceof ConditionalTypeForParameter && !$returnType->isNegated() && array_key_exists($returnType->getParameterName(), $passedArgs)) { $paramType = $returnType->getTarget(); $argType = $passedArgs[$returnType->getParameterName()]; $typeMap = $typeMap->union($paramType->inferTemplateTypes($argType)); } $resolvedTemplateTypeMap = new TemplateTypeMap(array_merge($parametersAcceptor->getTemplateTypeMap()->map(static function (string $name, Type $type) : Type { return new ErrorType(); })->getTypes(), $typeMap->getTypes())); $originalParametersAcceptor = $parametersAcceptor; if (!$parametersAcceptor instanceof \PHPStan\Reflection\ParametersAcceptorWithPhpDocs) { $parametersAcceptor = new \PHPStan\Reflection\FunctionVariantWithPhpDocs($parametersAcceptor->getTemplateTypeMap(), $parametersAcceptor->getResolvedTemplateTypeMap(), array_map(static function (\PHPStan\Reflection\ParameterReflection $parameter) : \PHPStan\Reflection\ParameterReflectionWithPhpDocs { return new DummyParameterWithPhpDocs($parameter->getName(), $parameter->getType(), $parameter->isOptional(), $parameter->passedByReference(), $parameter->isVariadic(), $parameter->getDefaultValue(), new MixedType(), $parameter->getType(), null, TrinaryLogic::createMaybe(), null); }, $parametersAcceptor->getParameters()), $parametersAcceptor->isVariadic(), $parametersAcceptor->getReturnType(), $parametersAcceptor->getReturnType(), new MixedType(), TemplateTypeVarianceMap::createEmpty()); } $result = new \PHPStan\Reflection\ResolvedFunctionVariantWithOriginal($parametersAcceptor, $resolvedTemplateTypeMap, $parametersAcceptor->getCallSiteVarianceMap(), $passedArgs); if ($originalParametersAcceptor instanceof CallableParametersAcceptor) { return new \PHPStan\Reflection\ResolvedFunctionVariantWithCallable($result, $originalParametersAcceptor->getThrowPoints(), $originalParametersAcceptor->isPure(), $originalParametersAcceptor->getImpurePoints(), $originalParametersAcceptor->getInvalidateExpressions(), $originalParametersAcceptor->getUsedVariables(), $originalParametersAcceptor->acceptsNamedArguments()); } return $result; } } */ private $additionalConstructors; /** @var array> */ private $additionalConstructorsCache = []; /** * @param list $additionalConstructors */ public function __construct(Container $container, array $additionalConstructors) { $this->container = $container; $this->additionalConstructors = $additionalConstructors; } /** * @return list */ public function getConstructors(\PHPStan\Reflection\ClassReflection $classReflection) : array { if (array_key_exists($classReflection->getName(), $this->additionalConstructorsCache)) { return $this->additionalConstructorsCache[$classReflection->getName()]; } $constructors = []; if ($classReflection->hasConstructor()) { $constructors[] = $classReflection->getConstructor()->getName(); } /** @var AdditionalConstructorsExtension[] $extensions */ $extensions = $this->container->getServicesByTag(\PHPStan\Reflection\AdditionalConstructorsExtension::EXTENSION_TAG); foreach ($extensions as $extension) { $extensionConstructors = $extension->getAdditionalConstructors($classReflection); foreach ($extensionConstructors as $extensionConstructor) { $constructors[] = $extensionConstructor; } } $nativeReflection = $classReflection->getNativeReflection(); foreach ($this->additionalConstructors as $additionalConstructor) { [$className, $methodName] = explode('::', $additionalConstructor); if (!$nativeReflection->hasMethod($methodName)) { continue; } $nativeMethod = $nativeReflection->getMethod($methodName); if ($nativeMethod->getDeclaringClass()->getName() !== $nativeReflection->getName()) { continue; } try { $prototype = $nativeMethod->getPrototype(); } catch (ReflectionException $e) { $prototype = $nativeMethod; } if ($prototype->getDeclaringClass()->getName() !== $className) { continue; } $constructors[] = $methodName; } $this->additionalConstructorsCache[$classReflection->getName()] = $constructors; return $constructors; } } |null */ private $ancestors = null; /** * @var ?string */ private $cacheKey = null; /** @var array */ private $subclasses = []; /** * @var string|false|null */ private $filename = \false; /** * @var string|false|null */ private $reflectionDocComment = \false; /** * @var false|ResolvedPhpDocBlock */ private $resolvedPhpDocBlock = \false; /** * @var false|ResolvedPhpDocBlock */ private $traitContextResolvedPhpDocBlock = \false; /** @var ClassReflection[]|null */ private $cachedInterfaces = null; /** * @var ClassReflection|false|null */ private $cachedParentClass = \false; /** @var array|null */ private $typeAliases = null; /** @var array */ private static $resolvingTypeAliasImports = []; /** @var array */ private $hasMethodCache = []; /** * @param PropertiesClassReflectionExtension[] $propertiesClassReflectionExtensions * @param MethodsClassReflectionExtension[] $methodsClassReflectionExtensions * @param AllowedSubTypesClassReflectionExtension[] $allowedSubTypesClassReflectionExtensions * @param string[] $universalObjectCratesClasses * @param ReflectionClass|ReflectionEnum $reflection */ public function __construct(\PHPStan\Reflection\ReflectionProvider $reflectionProvider, \PHPStan\Reflection\InitializerExprTypeResolver $initializerExprTypeResolver, FileTypeMapper $fileTypeMapper, StubPhpDocProvider $stubPhpDocProvider, PhpDocInheritanceResolver $phpDocInheritanceResolver, PhpVersion $phpVersion, SignatureMapProvider $signatureMapProvider, array $propertiesClassReflectionExtensions, array $methodsClassReflectionExtensions, array $allowedSubTypesClassReflectionExtensions, RequireExtendsPropertiesClassReflectionExtension $requireExtendsPropertiesClassReflectionExtension, RequireExtendsMethodsClassReflectionExtension $requireExtendsMethodsClassReflectionExtension, string $displayName, $reflection, ?string $anonymousFilename, ?TemplateTypeMap $resolvedTemplateTypeMap, ?ResolvedPhpDocBlock $stubPhpDocBlock, array $universalObjectCratesClasses, ?string $extraCacheKey = null, ?TemplateTypeVarianceMap $resolvedCallSiteVarianceMap = null) { $this->reflectionProvider = $reflectionProvider; $this->initializerExprTypeResolver = $initializerExprTypeResolver; $this->fileTypeMapper = $fileTypeMapper; $this->stubPhpDocProvider = $stubPhpDocProvider; $this->phpDocInheritanceResolver = $phpDocInheritanceResolver; $this->phpVersion = $phpVersion; $this->signatureMapProvider = $signatureMapProvider; $this->propertiesClassReflectionExtensions = $propertiesClassReflectionExtensions; $this->methodsClassReflectionExtensions = $methodsClassReflectionExtensions; $this->allowedSubTypesClassReflectionExtensions = $allowedSubTypesClassReflectionExtensions; $this->requireExtendsPropertiesClassReflectionExtension = $requireExtendsPropertiesClassReflectionExtension; $this->requireExtendsMethodsClassReflectionExtension = $requireExtendsMethodsClassReflectionExtension; $this->displayName = $displayName; $this->reflection = $reflection; $this->anonymousFilename = $anonymousFilename; $this->resolvedTemplateTypeMap = $resolvedTemplateTypeMap; $this->stubPhpDocBlock = $stubPhpDocBlock; $this->universalObjectCratesClasses = $universalObjectCratesClasses; $this->extraCacheKey = $extraCacheKey; $this->resolvedCallSiteVarianceMap = $resolvedCallSiteVarianceMap; } /** * @return ReflectionClass|ReflectionEnum */ public function getNativeReflection() { return $this->reflection; } public function getFileName() : ?string { if (!is_bool($this->filename)) { return $this->filename; } if ($this->anonymousFilename !== null) { return $this->filename = $this->anonymousFilename; } $fileName = $this->reflection->getFileName(); if ($fileName === \false) { return $this->filename = null; } if (!is_file($fileName)) { return $this->filename = null; } return $this->filename = $fileName; } /** * @deprecated Use getFileName() */ public function getFileNameWithPhpDocs() : ?string { return $this->getFileName(); } public function getParentClass() : ?\PHPStan\Reflection\ClassReflection { if (!is_bool($this->cachedParentClass)) { return $this->cachedParentClass; } $parentClass = $this->reflection->getParentClass(); if ($parentClass === \false) { return $this->cachedParentClass = null; } $extendsTag = $this->getFirstExtendsTag(); if ($extendsTag !== null && $this->isValidAncestorType($extendsTag->getType(), [$parentClass->getName()])) { $extendedType = $extendsTag->getType(); if ($this->isGeneric()) { $extendedType = TemplateTypeHelper::resolveTemplateTypes($extendedType, $this->getPossiblyIncompleteActiveTemplateTypeMap(), $this->getCallSiteVarianceMap(), TemplateTypeVariance::createStatic()); } if (!$extendedType instanceof GenericObjectType) { return $this->reflectionProvider->getClass($parentClass->getName()); } return $extendedType->getClassReflection() ?? $this->reflectionProvider->getClass($parentClass->getName()); } $parentReflection = $this->reflectionProvider->getClass($parentClass->getName()); if ($parentReflection->isGeneric()) { return $parentReflection->withTypes(array_values($parentReflection->getTemplateTypeMap()->map(static function () : Type { return new ErrorType(); })->getTypes())); } $this->cachedParentClass = $parentReflection; return $parentReflection; } /** * @return class-string */ public function getName() : string { return $this->reflection->getName(); } public function getDisplayName(bool $withTemplateTypes = \true) : string { if ($withTemplateTypes === \false || $this->resolvedTemplateTypeMap === null || count($this->resolvedTemplateTypeMap->getTypes()) === 0) { return $this->displayName; } $templateTypes = []; $variances = $this->getCallSiteVarianceMap()->getVariances(); foreach ($this->getActiveTemplateTypeMap()->getTypes() as $name => $templateType) { $variance = $variances[$name] ?? null; if ($variance === null) { continue; } $templateTypes[] = TypeProjectionHelper::describe($templateType, $variance, VerbosityLevel::typeOnly()); } return $this->displayName . '<' . implode(',', $templateTypes) . '>'; } public function getCacheKey() : string { $cacheKey = $this->cacheKey; if ($cacheKey !== null) { return $this->cacheKey; } $cacheKey = $this->displayName; if ($this->resolvedTemplateTypeMap !== null) { $templateTypes = []; $variances = $this->getCallSiteVarianceMap()->getVariances(); foreach ($this->getActiveTemplateTypeMap()->getTypes() as $name => $templateType) { $variance = $variances[$name] ?? null; if ($variance === null) { continue; } $templateTypes[] = TypeProjectionHelper::describe($templateType, $variance, VerbosityLevel::cache()); } $cacheKey .= '<' . implode(',', $templateTypes) . '>'; } if ($this->extraCacheKey !== null) { $cacheKey .= '-' . $this->extraCacheKey; } $this->cacheKey = $cacheKey; return $cacheKey; } /** * @return int[] */ public function getClassHierarchyDistances() : array { if ($this->classHierarchyDistances === null) { $distance = 0; $distances = [$this->getName() => $distance]; $currentClassReflection = $this->getNativeReflection(); foreach ($this->collectTraits($this->getNativeReflection()) as $trait) { $distance++; if (array_key_exists($trait->getName(), $distances)) { continue; } $distances[$trait->getName()] = $distance; } while ($currentClassReflection->getParentClass() !== \false) { $distance++; $parentClassName = $currentClassReflection->getParentClass()->getName(); if (!array_key_exists($parentClassName, $distances)) { $distances[$parentClassName] = $distance; } $currentClassReflection = $currentClassReflection->getParentClass(); foreach ($this->collectTraits($currentClassReflection) as $trait) { $distance++; if (array_key_exists($trait->getName(), $distances)) { continue; } $distances[$trait->getName()] = $distance; } } foreach ($this->getNativeReflection()->getInterfaces() as $interface) { $distance++; if (array_key_exists($interface->getName(), $distances)) { continue; } $distances[$interface->getName()] = $distance; } $this->classHierarchyDistances = $distances; } return $this->classHierarchyDistances; } /** * @return ReflectionClass[] * @param ReflectionClass|ReflectionEnum $class */ private function collectTraits($class) : array { $traits = []; $traitsLeftToAnalyze = $class->getTraits(); while (count($traitsLeftToAnalyze) !== 0) { $trait = reset($traitsLeftToAnalyze); $traits[] = $trait; foreach ($trait->getTraits() as $subTrait) { if (in_array($subTrait, $traits, \true)) { continue; } $traitsLeftToAnalyze[] = $subTrait; } array_shift($traitsLeftToAnalyze); } return $traits; } public function allowsDynamicProperties() : bool { if ($this->isEnum()) { return \false; } if (!$this->phpVersion->deprecatesDynamicProperties()) { return \true; } if ($this->isReadOnly()) { return \false; } if (UniversalObjectCratesClassReflectionExtension::isUniversalObjectCrate($this->reflectionProvider, $this->universalObjectCratesClasses, $this)) { return \true; } $class = $this; $attributes = $class->reflection->getAttributes('AllowDynamicProperties'); while (count($attributes) === 0 && $class->getParentClass() !== null) { $attributes = $class->getParentClass()->reflection->getAttributes('AllowDynamicProperties'); $class = $class->getParentClass(); } return count($attributes) > 0; } private function allowsDynamicPropertiesExtensions() : bool { if ($this->allowsDynamicProperties()) { return \true; } $hasMagicMethod = $this->hasNativeMethod('__get') || $this->hasNativeMethod('__set') || $this->hasNativeMethod('__isset'); if ($hasMagicMethod) { return \true; } foreach ($this->getRequireExtendsTags() as $extendsTag) { $type = $extendsTag->getType(); if (!$type instanceof ObjectType) { continue; } $reflection = $type->getClassReflection(); if ($reflection === null) { continue; } if (!$reflection->allowsDynamicPropertiesExtensions()) { continue; } return \true; } return \false; } public function hasProperty(string $propertyName) : bool { if ($this->isEnum()) { return $this->hasNativeProperty($propertyName); } foreach ($this->propertiesClassReflectionExtensions as $i => $extension) { if ($i > 0 && !$this->allowsDynamicPropertiesExtensions()) { break; } if ($extension->hasProperty($this, $propertyName)) { return \true; } } if ($this->requireExtendsPropertiesClassReflectionExtension->hasProperty($this, $propertyName)) { return \true; } return \false; } public function hasMethod(string $methodName) : bool { if (array_key_exists($methodName, $this->hasMethodCache)) { return $this->hasMethodCache[$methodName]; } foreach ($this->methodsClassReflectionExtensions as $extension) { if ($extension->hasMethod($this, $methodName)) { $this->hasMethodCache[$methodName] = \true; return \true; } } if ($this->requireExtendsMethodsClassReflectionExtension->hasMethod($this, $methodName)) { $this->hasMethodCache[$methodName] = \true; return \true; } $this->hasMethodCache[$methodName] = \false; return \false; } public function getMethod(string $methodName, \PHPStan\Reflection\ClassMemberAccessAnswerer $scope) : \PHPStan\Reflection\ExtendedMethodReflection { $key = $methodName; if ($scope->isInClass()) { $key = sprintf('%s-%s', $key, $scope->getClassReflection()->getCacheKey()); } if (!isset($this->methods[$key])) { foreach ($this->methodsClassReflectionExtensions as $extension) { if (!$extension->hasMethod($this, $methodName)) { continue; } $method = $this->wrapExtendedMethod($extension->getMethod($this, $methodName)); if ($scope->canCallMethod($method)) { return $this->methods[$key] = $method; } $this->methods[$key] = $method; } } if (!isset($this->methods[$key])) { if ($this->requireExtendsMethodsClassReflectionExtension->hasMethod($this, $methodName)) { $method = $this->requireExtendsMethodsClassReflectionExtension->getMethod($this, $methodName); $this->methods[$key] = $method; } } if (!isset($this->methods[$key])) { throw new \PHPStan\Reflection\MissingMethodFromReflectionException($this->getName(), $methodName); } return $this->methods[$key]; } private function wrapExtendedMethod(\PHPStan\Reflection\MethodReflection $method) : \PHPStan\Reflection\ExtendedMethodReflection { if ($method instanceof \PHPStan\Reflection\ExtendedMethodReflection) { return $method; } return new \PHPStan\Reflection\WrappedExtendedMethodReflection($method); } private function wrapExtendedProperty(\PHPStan\Reflection\PropertyReflection $method) : \PHPStan\Reflection\ExtendedPropertyReflection { if ($method instanceof \PHPStan\Reflection\ExtendedPropertyReflection) { return $method; } return new \PHPStan\Reflection\WrappedExtendedPropertyReflection($method); } public function hasNativeMethod(string $methodName) : bool { return $this->getPhpExtension()->hasNativeMethod($this, $methodName); } public function getNativeMethod(string $methodName) : \PHPStan\Reflection\ExtendedMethodReflection { if (!$this->hasNativeMethod($methodName)) { throw new \PHPStan\Reflection\MissingMethodFromReflectionException($this->getName(), $methodName); } return $this->getPhpExtension()->getNativeMethod($this, $methodName); } public function hasConstructor() : bool { return $this->findConstructor() !== null; } public function getConstructor() : \PHPStan\Reflection\ExtendedMethodReflection { $constructor = $this->findConstructor(); if ($constructor === null) { throw new ShouldNotHappenException(); } return $this->getNativeMethod($constructor->getName()); } private function findConstructor() : ?ReflectionMethod { $constructor = $this->reflection->getConstructor(); if ($constructor === null) { return null; } if ($this->phpVersion->supportsLegacyConstructor()) { return $constructor; } if (strtolower($constructor->getName()) !== '__construct') { return null; } return $constructor; } private function getPhpExtension() : PhpClassReflectionExtension { $extension = $this->methodsClassReflectionExtensions[0]; if (!$extension instanceof PhpClassReflectionExtension) { throw new ShouldNotHappenException(); } return $extension; } /** @internal */ public function evictPrivateSymbols() : void { foreach ($this->constants as $name => $constant) { if (!$constant->isPrivate()) { continue; } unset($this->constants[$name]); } foreach ($this->properties as $name => $property) { if (!$property->isPrivate()) { continue; } unset($this->properties[$name]); } foreach ($this->methods as $name => $method) { if (!$method->isPrivate()) { continue; } unset($this->methods[$name]); } $this->getPhpExtension()->evictPrivateSymbols($this->getCacheKey()); } public function getProperty(string $propertyName, \PHPStan\Reflection\ClassMemberAccessAnswerer $scope) : \PHPStan\Reflection\ExtendedPropertyReflection { if ($this->isEnum()) { return $this->getNativeProperty($propertyName); } $key = $propertyName; if ($scope->isInClass()) { $key = sprintf('%s-%s', $key, $scope->getClassReflection()->getCacheKey()); } if (!isset($this->properties[$key])) { foreach ($this->propertiesClassReflectionExtensions as $i => $extension) { if ($i > 0 && !$this->allowsDynamicPropertiesExtensions()) { break; } if (!$extension->hasProperty($this, $propertyName)) { continue; } $property = $this->wrapExtendedProperty($extension->getProperty($this, $propertyName)); if ($scope->canAccessProperty($property)) { return $this->properties[$key] = $property; } $this->properties[$key] = $property; } } if (!isset($this->properties[$key])) { if ($this->requireExtendsPropertiesClassReflectionExtension->hasProperty($this, $propertyName)) { $property = $this->requireExtendsPropertiesClassReflectionExtension->getProperty($this, $propertyName); $this->properties[$key] = $property; } } if (!isset($this->properties[$key])) { throw new \PHPStan\Reflection\MissingPropertyFromReflectionException($this->getName(), $propertyName); } return $this->properties[$key]; } public function hasNativeProperty(string $propertyName) : bool { return $this->getPhpExtension()->hasProperty($this, $propertyName); } public function getNativeProperty(string $propertyName) : PhpPropertyReflection { if (!$this->hasNativeProperty($propertyName)) { throw new \PHPStan\Reflection\MissingPropertyFromReflectionException($this->getName(), $propertyName); } return $this->getPhpExtension()->getNativeProperty($this, $propertyName); } public function isAbstract() : bool { return $this->reflection->isAbstract(); } public function isInterface() : bool { return $this->reflection->isInterface(); } public function isTrait() : bool { return $this->reflection->isTrait(); } /** * @phpstan-assert-if-true ReflectionEnum $this->reflection */ public function isEnum() : bool { return $this->reflection instanceof ReflectionEnum && $this->reflection->isEnum(); } /** * @return 'Interface'|'Trait'|'Enum'|'Class' */ public function getClassTypeDescription() : string { if ($this->isInterface()) { return 'Interface'; } elseif ($this->isTrait()) { return 'Trait'; } elseif ($this->isEnum()) { return 'Enum'; } return 'Class'; } public function isReadOnly() : bool { return $this->reflection->isReadOnly(); } public function isBackedEnum() : bool { if (!$this->reflection instanceof ReflectionEnum) { return \false; } return $this->reflection->isBacked(); } public function getBackedEnumType() : ?Type { if (!$this->reflection instanceof ReflectionEnum) { return null; } if (!$this->reflection->isBacked()) { return null; } return TypehintHelper::decideTypeFromReflection($this->reflection->getBackingType()); } public function hasEnumCase(string $name) : bool { if (!$this->isEnum()) { return \false; } return $this->reflection->hasCase($name); } /** * @return array */ public function getEnumCases() : array { if (!$this->isEnum()) { throw new ShouldNotHappenException(); } if ($this->enumCases !== null) { return $this->enumCases; } $cases = []; $initializerExprContext = \PHPStan\Reflection\InitializerExprContext::fromClassReflection($this); foreach ($this->reflection->getCases() as $case) { $valueType = null; if ($case instanceof ReflectionEnumBackedCase) { $valueType = $this->initializerExprTypeResolver->getType($case->getValueExpression(), $initializerExprContext); } /** @var string $caseName */ $caseName = $case->getName(); $cases[$caseName] = new \PHPStan\Reflection\EnumCaseReflection($this, $caseName, $valueType); } return $this->enumCases = $cases; } public function getEnumCase(string $name) : \PHPStan\Reflection\EnumCaseReflection { if (!$this->hasEnumCase($name)) { throw new ShouldNotHappenException(sprintf('Enum case %s::%s does not exist.', $this->getDisplayName(), $name)); } if (!$this->reflection instanceof ReflectionEnum) { throw new ShouldNotHappenException(); } if ($this->enumCases !== null && array_key_exists($name, $this->enumCases)) { return $this->enumCases[$name]; } $case = $this->reflection->getCase($name); $valueType = null; if ($case instanceof ReflectionEnumBackedCase) { $valueType = $this->initializerExprTypeResolver->getType($case->getValueExpression(), \PHPStan\Reflection\InitializerExprContext::fromClassReflection($this)); } return new \PHPStan\Reflection\EnumCaseReflection($this, $name, $valueType); } public function isClass() : bool { return !$this->isInterface() && !$this->isTrait() && !$this->isEnum(); } public function isAnonymous() : bool { return $this->anonymousFilename !== null; } public function is(string $className) : bool { return $this->getName() === $className || $this->isSubclassOf($className); } public function isSubclassOf(string $className) : bool { if (isset($this->subclasses[$className])) { return $this->subclasses[$className]; } if (!$this->reflectionProvider->hasClass($className)) { return $this->subclasses[$className] = \false; } try { return $this->subclasses[$className] = $this->reflection->isSubclassOf($className); } catch (ReflectionException $e) { return $this->subclasses[$className] = \false; } } public function implementsInterface(string $className) : bool { try { return $this->reflection->implementsInterface($className); } catch (ReflectionException $e) { return \false; } } /** * @return ClassReflection[] */ public function getParents() : array { $parents = []; $parent = $this->getParentClass(); while ($parent !== null) { $parents[] = $parent; $parent = $parent->getParentClass(); } return $parents; } /** * @return ClassReflection[] */ public function getInterfaces() : array { if ($this->cachedInterfaces !== null) { return $this->cachedInterfaces; } $interfaces = $this->getImmediateInterfaces(); $immediateInterfaces = $interfaces; $parent = $this->getParentClass(); while ($parent !== null) { foreach ($parent->getImmediateInterfaces() as $parentInterface) { $interfaces[$parentInterface->getName()] = $parentInterface; foreach ($this->collectInterfaces($parentInterface) as $parentInterfaceInterface) { $interfaces[$parentInterfaceInterface->getName()] = $parentInterfaceInterface; } } $parent = $parent->getParentClass(); } foreach ($immediateInterfaces as $immediateInterface) { foreach ($this->collectInterfaces($immediateInterface) as $interfaceInterface) { $interfaces[$interfaceInterface->getName()] = $interfaceInterface; } } $this->cachedInterfaces = $interfaces; return $interfaces; } /** * @return ClassReflection[] */ private function collectInterfaces(\PHPStan\Reflection\ClassReflection $interface) : array { $interfaces = []; foreach ($interface->getImmediateInterfaces() as $immediateInterface) { $interfaces[$immediateInterface->getName()] = $immediateInterface; foreach ($this->collectInterfaces($immediateInterface) as $immediateInterfaceInterface) { $interfaces[$immediateInterfaceInterface->getName()] = $immediateInterfaceInterface; } } return $interfaces; } /** * @return ClassReflection[] */ public function getImmediateInterfaces() : array { $indirectInterfaceNames = []; $parent = $this->getParentClass(); while ($parent !== null) { foreach ($parent->getNativeReflection()->getInterfaceNames() as $parentInterfaceName) { $indirectInterfaceNames[] = $parentInterfaceName; } $parent = $parent->getParentClass(); } foreach ($this->getNativeReflection()->getInterfaces() as $interfaceInterface) { foreach ($interfaceInterface->getInterfaceNames() as $interfaceInterfaceName) { $indirectInterfaceNames[] = $interfaceInterfaceName; } } if ($this->reflection->isInterface()) { $implementsTags = $this->getExtendsTags(); } else { $implementsTags = $this->getImplementsTags(); } $immediateInterfaceNames = array_diff($this->getNativeReflection()->getInterfaceNames(), $indirectInterfaceNames); $immediateInterfaces = []; foreach ($immediateInterfaceNames as $immediateInterfaceName) { if (!$this->reflectionProvider->hasClass($immediateInterfaceName)) { continue; } $immediateInterface = $this->reflectionProvider->getClass($immediateInterfaceName); if (array_key_exists($immediateInterface->getName(), $implementsTags)) { $implementsTag = $implementsTags[$immediateInterface->getName()]; $implementedType = $implementsTag->getType(); if ($this->isGeneric()) { $implementedType = TemplateTypeHelper::resolveTemplateTypes($implementedType, $this->getPossiblyIncompleteActiveTemplateTypeMap(), $this->getCallSiteVarianceMap(), TemplateTypeVariance::createStatic(), \true); } if ($implementedType instanceof GenericObjectType && $implementedType->getClassReflection() !== null) { $immediateInterfaces[$immediateInterface->getName()] = $implementedType->getClassReflection(); continue; } } if ($immediateInterface->isGeneric()) { $immediateInterfaces[$immediateInterface->getName()] = $immediateInterface->withTypes(array_values($immediateInterface->getTemplateTypeMap()->map(static function () : Type { return new ErrorType(); })->getTypes())); continue; } $immediateInterfaces[$immediateInterface->getName()] = $immediateInterface; } return $immediateInterfaces; } /** * @return array */ public function getTraits(bool $recursive = \false) : array { $traits = []; if ($recursive) { foreach ($this->collectTraits($this->getNativeReflection()) as $trait) { $traits[$trait->getName()] = $trait; } } else { $traits = $this->getNativeReflection()->getTraits(); } $traits = array_map(function (ReflectionClass $trait) : \PHPStan\Reflection\ClassReflection { return $this->reflectionProvider->getClass($trait->getName()); }, $traits); if ($recursive) { $parentClass = $this->getNativeReflection()->getParentClass(); if ($parentClass !== \false) { return array_merge($traits, $this->reflectionProvider->getClass($parentClass->getName())->getTraits(\true)); } } return $traits; } /** * @return list */ public function getParentClassesNames() : array { $parentNames = []; $parentClass = $this->getParentClass(); while ($parentClass !== null) { $parentNames[] = $parentClass->getName(); $parentClass = $parentClass->getParentClass(); } return $parentNames; } public function hasConstant(string $name) : bool { if (!$this->getNativeReflection()->hasConstant($name)) { return \false; } $reflectionConstant = $this->getNativeReflection()->getReflectionConstant($name); if ($reflectionConstant === \false) { return \false; } return $this->reflectionProvider->hasClass($reflectionConstant->getDeclaringClass()->getName()); } public function getConstant(string $name) : \PHPStan\Reflection\ClassConstantReflection { if (!isset($this->constants[$name])) { $reflectionConstant = $this->getNativeReflection()->getReflectionConstant($name); if ($reflectionConstant === \false) { throw new \PHPStan\Reflection\MissingConstantFromReflectionException($this->getName(), $name); } $declaringClass = $this->reflectionProvider->getClass($reflectionConstant->getDeclaringClass()->getName()); $fileName = $declaringClass->getFileName(); $phpDocType = null; $resolvedPhpDoc = $this->stubPhpDocProvider->findClassConstantPhpDoc($declaringClass->getName(), $name); if ($resolvedPhpDoc === null) { $docComment = null; if ($reflectionConstant->getDocComment() !== \false) { $docComment = $reflectionConstant->getDocComment(); } $resolvedPhpDoc = $this->phpDocInheritanceResolver->resolvePhpDocForConstant($docComment, $declaringClass, $fileName, $name); } $deprecatedDescription = $resolvedPhpDoc->getDeprecatedTag() !== null ? $resolvedPhpDoc->getDeprecatedTag()->getMessage() : null; $isDeprecated = $resolvedPhpDoc->isDeprecated(); $isInternal = $resolvedPhpDoc->isInternal(); $isFinal = $resolvedPhpDoc->isFinal(); $nativeType = null; if ($reflectionConstant->getType() !== null) { $nativeType = TypehintHelper::decideTypeFromReflection($reflectionConstant->getType(), null, $declaringClass); } elseif ($this->signatureMapProvider->hasClassConstantMetadata($declaringClass->getName(), $name)) { $nativeType = $this->signatureMapProvider->getClassConstantMetadata($declaringClass->getName(), $name)['nativeType']; } $varTags = $resolvedPhpDoc->getVarTags(); if (isset($varTags[0]) && count($varTags) === 1) { $varTag = $varTags[0]; if ($varTag->isExplicit() || $nativeType === null || $nativeType->isSuperTypeOf($varTag->getType())->yes()) { $phpDocType = $varTag->getType(); } } $this->constants[$name] = new \PHPStan\Reflection\ClassConstantReflection($this->initializerExprTypeResolver, $declaringClass, $reflectionConstant, $nativeType, $phpDocType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal); } return $this->constants[$name]; } public function hasTraitUse(string $traitName) : bool { return in_array($traitName, $this->getTraitNames(), \true); } /** * @return string[] */ private function getTraitNames() : array { $class = $this->reflection; $traitNames = array_map(static function (ReflectionClass $class) { return $class->getName(); }, $this->collectTraits($class)); while ($class->getParentClass() !== \false) { $traitNames = array_values(array_unique(array_merge($traitNames, $class->getParentClass()->getTraitNames()))); $class = $class->getParentClass(); } return $traitNames; } /** * @return array */ public function getTypeAliases() : array { if ($this->typeAliases === null) { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return $this->typeAliases = []; } $typeAliasImportTags = $resolvedPhpDoc->getTypeAliasImportTags(); $typeAliasTags = $resolvedPhpDoc->getTypeAliasTags(); // prevent circular imports if (array_key_exists($this->getName(), self::$resolvingTypeAliasImports)) { throw new CircularTypeAliasDefinitionException(); } self::$resolvingTypeAliasImports[$this->getName()] = \true; $importedAliases = array_map(function (TypeAliasImportTag $typeAliasImportTag) : ?TypeAlias { $importedAlias = $typeAliasImportTag->getImportedAlias(); $importedFromClassName = $typeAliasImportTag->getImportedFrom(); if (!$this->reflectionProvider->hasClass($importedFromClassName)) { return null; } $importedFromReflection = $this->reflectionProvider->getClass($importedFromClassName); try { $typeAliases = $importedFromReflection->getTypeAliases(); } catch (CircularTypeAliasDefinitionException $e) { return TypeAlias::invalid(); } if (!array_key_exists($importedAlias, $typeAliases)) { return null; } return $typeAliases[$importedAlias]; }, $typeAliasImportTags); unset(self::$resolvingTypeAliasImports[$this->getName()]); $localAliases = array_map(static function (TypeAliasTag $typeAliasTag) : TypeAlias { return $typeAliasTag->getTypeAlias(); }, $typeAliasTags); $this->typeAliases = array_filter(array_merge($importedAliases, $localAliases), static function (?TypeAlias $typeAlias) : bool { return $typeAlias !== null; }); } return $this->typeAliases; } public function getDeprecatedDescription() : ?string { if ($this->deprecatedDescription === null && $this->isDeprecated()) { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc !== null && $resolvedPhpDoc->getDeprecatedTag() !== null) { $this->deprecatedDescription = $resolvedPhpDoc->getDeprecatedTag()->getMessage(); } } return $this->deprecatedDescription; } public function isDeprecated() : bool { if ($this->isDeprecated === null) { $resolvedPhpDoc = $this->getResolvedPhpDoc(); $this->isDeprecated = $resolvedPhpDoc !== null && $resolvedPhpDoc->isDeprecated(); } return $this->isDeprecated; } public function isBuiltin() : bool { return $this->reflection->isInternal(); } public function isInternal() : bool { if ($this->isInternal === null) { $resolvedPhpDoc = $this->getResolvedPhpDoc(); $this->isInternal = $resolvedPhpDoc !== null && $resolvedPhpDoc->isInternal(); } return $this->isInternal; } public function isFinal() : bool { if ($this->isFinalByKeyword()) { return \true; } if ($this->isFinal === null) { $resolvedPhpDoc = $this->getResolvedPhpDoc(); $this->isFinal = $resolvedPhpDoc !== null && $resolvedPhpDoc->isFinal(); } return $this->isFinal; } public function isImmutable() : bool { if ($this->isImmutable === null) { $resolvedPhpDoc = $this->getResolvedPhpDoc(); $this->isImmutable = $resolvedPhpDoc !== null && ($resolvedPhpDoc->isImmutable() || $resolvedPhpDoc->isReadOnly()); $parentClass = $this->getParentClass(); if ($parentClass !== null && !$this->isImmutable) { $this->isImmutable = $parentClass->isImmutable(); } } return $this->isImmutable; } public function hasConsistentConstructor() : bool { if ($this->hasConsistentConstructor === null) { $resolvedPhpDoc = $this->getResolvedPhpDoc(); $this->hasConsistentConstructor = $resolvedPhpDoc !== null && $resolvedPhpDoc->hasConsistentConstructor(); } return $this->hasConsistentConstructor; } public function acceptsNamedArguments() : bool { if ($this->acceptsNamedArguments === null) { $resolvedPhpDoc = $this->getResolvedPhpDoc(); $this->acceptsNamedArguments = $resolvedPhpDoc === null || $resolvedPhpDoc->acceptsNamedArguments(); } return $this->acceptsNamedArguments; } public function isFinalByKeyword() : bool { if ($this->isAnonymous()) { return \true; } return $this->reflection->isFinal(); } public function isAttributeClass() : bool { return $this->findAttributeFlags() !== null; } private function findAttributeFlags() : ?int { if ($this->isInterface() || $this->isTrait() || $this->isEnum()) { return null; } $nativeAttributes = $this->reflection->getAttributes(Attribute::class); if (count($nativeAttributes) === 1) { if (!$this->reflectionProvider->hasClass(Attribute::class)) { return null; } $attributeClass = $this->reflectionProvider->getClass(Attribute::class); $arguments = []; foreach ($nativeAttributes[0]->getArgumentsExpressions() as $i => $expression) { $arguments[] = new Arg($expression, \false, \false, [], is_int($i) ? null : new Identifier($i)); } if (!$attributeClass->hasConstructor()) { return null; } $attributeConstructor = $attributeClass->getConstructor(); $attributeConstructorVariant = $attributeConstructor->getOnlyVariant(); if (count($arguments) === 0) { $flagType = $attributeConstructorVariant->getParameters()[0]->getDefaultValue(); } else { $staticCall = ArgumentsNormalizer::reorderStaticCallArguments($attributeConstructorVariant, new StaticCall(new FullyQualified(Attribute::class), $attributeConstructor->getName(), $arguments)); if ($staticCall === null) { return null; } $flagExpr = $staticCall->getArgs()[0]->value; $flagType = $this->initializerExprTypeResolver->getType($flagExpr, \PHPStan\Reflection\InitializerExprContext::fromClassReflection($this)); } if (!$flagType instanceof ConstantIntegerType) { return null; } return $flagType->getValue(); } return null; } public function getAttributeClassFlags() : int { $flags = $this->findAttributeFlags(); if ($flags === null) { throw new ShouldNotHappenException(); } return $flags; } public function getTemplateTypeMap() : TemplateTypeMap { if ($this->templateTypeMap !== null) { return $this->templateTypeMap; } $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { $this->templateTypeMap = TemplateTypeMap::createEmpty(); return $this->templateTypeMap; } $templateTypeScope = TemplateTypeScope::createWithClass($this->getName()); $templateTypeMap = new TemplateTypeMap(array_map(static function (TemplateTag $tag) use($templateTypeScope) : Type { return TemplateTypeFactory::fromTemplateTag($templateTypeScope, $tag); }, $this->getTemplateTags())); $this->templateTypeMap = $templateTypeMap; return $templateTypeMap; } public function getActiveTemplateTypeMap() : TemplateTypeMap { if ($this->activeTemplateTypeMap !== null) { return $this->activeTemplateTypeMap; } $resolved = $this->resolvedTemplateTypeMap; if ($resolved !== null) { $templateTypeMap = $this->getTemplateTypeMap(); return $this->activeTemplateTypeMap = $resolved->map(static function (string $name, Type $type) use($templateTypeMap) : Type { if ($type instanceof ErrorType) { $templateType = $templateTypeMap->getType($name); if ($templateType !== null) { return TemplateTypeHelper::resolveToDefaults($templateType); } } return $type; }); } return $this->activeTemplateTypeMap = $this->getTemplateTypeMap(); } public function getPossiblyIncompleteActiveTemplateTypeMap() : TemplateTypeMap { return $this->resolvedTemplateTypeMap ?? $this->getTemplateTypeMap(); } private function getDefaultCallSiteVarianceMap() : TemplateTypeVarianceMap { if ($this->defaultCallSiteVarianceMap !== null) { return $this->defaultCallSiteVarianceMap; } $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { $this->defaultCallSiteVarianceMap = TemplateTypeVarianceMap::createEmpty(); return $this->defaultCallSiteVarianceMap; } $map = []; foreach ($this->getTemplateTags() as $templateTag) { $map[$templateTag->getName()] = TemplateTypeVariance::createInvariant(); } $this->defaultCallSiteVarianceMap = new TemplateTypeVarianceMap($map); return $this->defaultCallSiteVarianceMap; } public function getCallSiteVarianceMap() : TemplateTypeVarianceMap { return $this->callSiteVarianceMap = $this->callSiteVarianceMap ?? $this->resolvedCallSiteVarianceMap ?? $this->getDefaultCallSiteVarianceMap(); } public function isGeneric() : bool { if ($this->isGeneric === null) { if ($this->isEnum()) { return $this->isGeneric = \false; } $this->isGeneric = count($this->getTemplateTags()) > 0; } return $this->isGeneric; } /** * @param array $types */ public function typeMapFromList(array $types) : TemplateTypeMap { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return TemplateTypeMap::createEmpty(); } $map = []; $i = 0; foreach ($resolvedPhpDoc->getTemplateTags() as $tag) { $map[$tag->getName()] = $types[$i] ?? $tag->getDefault() ?? $tag->getBound(); $i++; } return new TemplateTypeMap($map); } /** * @param array $variances */ public function varianceMapFromList(array $variances) : TemplateTypeVarianceMap { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return new TemplateTypeVarianceMap([]); } $map = []; $i = 0; foreach ($resolvedPhpDoc->getTemplateTags() as $tag) { $map[$tag->getName()] = $variances[$i] ?? TemplateTypeVariance::createInvariant(); $i++; } return new TemplateTypeVarianceMap($map); } /** @return array */ public function typeMapToList(TemplateTypeMap $typeMap) : array { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return []; } $list = []; foreach ($resolvedPhpDoc->getTemplateTags() as $tag) { $list[] = $typeMap->getType($tag->getName()) ?? $tag->getDefault() ?? $tag->getBound(); } return $list; } /** @return array */ public function varianceMapToList(TemplateTypeVarianceMap $varianceMap) : array { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return []; } $list = []; foreach ($resolvedPhpDoc->getTemplateTags() as $tag) { $list[] = $varianceMap->getVariance($tag->getName()) ?? TemplateTypeVariance::createInvariant(); } return $list; } /** * @param array $types */ public function withTypes(array $types) : self { return new self($this->reflectionProvider, $this->initializerExprTypeResolver, $this->fileTypeMapper, $this->stubPhpDocProvider, $this->phpDocInheritanceResolver, $this->phpVersion, $this->signatureMapProvider, $this->propertiesClassReflectionExtensions, $this->methodsClassReflectionExtensions, $this->allowedSubTypesClassReflectionExtensions, $this->requireExtendsPropertiesClassReflectionExtension, $this->requireExtendsMethodsClassReflectionExtension, $this->displayName, $this->reflection, $this->anonymousFilename, $this->typeMapFromList($types), $this->stubPhpDocBlock, $this->universalObjectCratesClasses, null, $this->resolvedCallSiteVarianceMap); } /** * @param array $variances */ public function withVariances(array $variances) : self { return new self($this->reflectionProvider, $this->initializerExprTypeResolver, $this->fileTypeMapper, $this->stubPhpDocProvider, $this->phpDocInheritanceResolver, $this->phpVersion, $this->signatureMapProvider, $this->propertiesClassReflectionExtensions, $this->methodsClassReflectionExtensions, $this->allowedSubTypesClassReflectionExtensions, $this->requireExtendsPropertiesClassReflectionExtension, $this->requireExtendsMethodsClassReflectionExtension, $this->displayName, $this->reflection, $this->anonymousFilename, $this->resolvedTemplateTypeMap, $this->stubPhpDocBlock, $this->universalObjectCratesClasses, null, $this->varianceMapFromList($variances)); } public function getResolvedPhpDoc() : ?ResolvedPhpDocBlock { if ($this->stubPhpDocBlock !== null) { return $this->stubPhpDocBlock; } $fileName = $this->getFileName(); if (is_bool($this->reflectionDocComment)) { $docComment = $this->reflection->getDocComment(); $this->reflectionDocComment = $docComment !== \false ? $docComment : null; } if ($this->reflectionDocComment === null) { return null; } if ($this->resolvedPhpDocBlock !== \false) { return $this->resolvedPhpDocBlock; } return $this->resolvedPhpDocBlock = $this->fileTypeMapper->getResolvedPhpDoc($fileName, $this->getName(), null, null, $this->reflectionDocComment); } public function getTraitContextResolvedPhpDoc(self $implementingClass) : ?ResolvedPhpDocBlock { if (!$this->isTrait()) { throw new ShouldNotHappenException(); } if ($implementingClass->isTrait()) { throw new ShouldNotHappenException(); } $fileName = $this->getFileName(); if (is_bool($this->reflectionDocComment)) { $docComment = $this->reflection->getDocComment(); $this->reflectionDocComment = $docComment !== \false ? $docComment : null; } if ($this->reflectionDocComment === null) { return null; } if ($this->traitContextResolvedPhpDocBlock !== \false) { return $this->traitContextResolvedPhpDocBlock; } return $this->traitContextResolvedPhpDocBlock = $this->fileTypeMapper->getResolvedPhpDoc($fileName, $implementingClass->getName(), $this->getName(), null, $this->reflectionDocComment); } private function getFirstExtendsTag() : ?ExtendsTag { foreach ($this->getExtendsTags() as $tag) { return $tag; } return null; } /** @return array */ public function getExtendsTags() : array { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return []; } return $resolvedPhpDoc->getExtendsTags(); } /** @return array */ public function getImplementsTags() : array { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return []; } return $resolvedPhpDoc->getImplementsTags(); } /** @return array */ public function getTemplateTags() : array { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return []; } return $resolvedPhpDoc->getTemplateTags(); } /** * @return array */ public function getAncestors() : array { $ancestors = $this->ancestors; if ($ancestors === null) { $ancestors = [$this->getName() => $this]; $addToAncestors = static function (string $name, \PHPStan\Reflection\ClassReflection $classReflection) use(&$ancestors) : void { if (array_key_exists($name, $ancestors)) { return; } $ancestors[$name] = $classReflection; }; foreach ($this->getInterfaces() as $interface) { $addToAncestors($interface->getName(), $interface); foreach ($interface->getAncestors() as $name => $ancestor) { $addToAncestors($name, $ancestor); } } foreach ($this->getTraits() as $trait) { $addToAncestors($trait->getName(), $trait); foreach ($trait->getAncestors() as $name => $ancestor) { $addToAncestors($name, $ancestor); } } $parent = $this->getParentClass(); if ($parent !== null) { $addToAncestors($parent->getName(), $parent); foreach ($parent->getAncestors() as $name => $ancestor) { $addToAncestors($name, $ancestor); } } $this->ancestors = $ancestors; } return $ancestors; } public function getAncestorWithClassName(string $className) : ?self { return $this->getAncestors()[$className] ?? null; } /** * @param string[] $ancestorClasses */ private function isValidAncestorType(Type $type, array $ancestorClasses) : bool { if (!$type instanceof GenericObjectType) { return \false; } $reflection = $type->getClassReflection(); if ($reflection === null) { return \false; } return in_array($reflection->getName(), $ancestorClasses, \true); } /** * @return array */ public function getMixinTags() : array { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return []; } return $resolvedPhpDoc->getMixinTags(); } /** * @return array */ public function getRequireExtendsTags() : array { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return []; } return $resolvedPhpDoc->getRequireExtendsTags(); } /** * @return array */ public function getRequireImplementsTags() : array { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return []; } return $resolvedPhpDoc->getRequireImplementsTags(); } /** * @return array */ public function getPropertyTags() : array { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return []; } return $resolvedPhpDoc->getPropertyTags(); } /** * @return array */ public function getMethodTags() : array { $resolvedPhpDoc = $this->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return []; } return $resolvedPhpDoc->getMethodTags(); } /** * @return array */ public function getResolvedMixinTypes() : array { $types = []; foreach ($this->getMixinTags() as $mixinTag) { if (!$this->isGeneric()) { $types[] = $mixinTag->getType(); continue; } $types[] = TemplateTypeHelper::resolveTemplateTypes($mixinTag->getType(), $this->getActiveTemplateTypeMap(), $this->getCallSiteVarianceMap(), TemplateTypeVariance::createStatic()); } return $types; } /** * @return array|null */ public function getAllowedSubTypes() : ?array { foreach ($this->allowedSubTypesClassReflectionExtensions as $allowedSubTypesClassReflectionExtension) { if ($allowedSubTypesClassReflectionExtension->supports($this)) { return $allowedSubTypesClassReflectionExtension->getAllowedSubTypes($this); } } return null; } } */ public function getParameters() : array; public function isVariadic() : bool; public function getReturnType() : Type; } getName() === 'SoapClient' || $classReflection->isSubclassOf('SoapClient'); } public function getMethod(ClassReflection $classReflection, string $methodName) : MethodReflection { return new \PHPStan\Reflection\Php\Soap\SoapClientMethodReflection($classReflection, $methodName); } } declaringClass = $declaringClass; $this->name = $name; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function isStatic() : bool { return \false; } public function isPrivate() : bool { return \false; } public function isPublic() : bool { return \true; } public function getDocComment() : ?string { return null; } public function getName() : string { return $this->name; } public function getPrototype() : ClassMemberReflection { return $this; } public function getVariants() : array { return [new FunctionVariant(TemplateTypeMap::createEmpty(), TemplateTypeMap::createEmpty(), [], \true, new MixedType(\true))]; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDeprecatedDescription() : ?string { return null; } public function isFinal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInternal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getThrowType() : Type { return new ObjectType('SoapFault'); } public function hasSideEffects() : TrinaryLogic { return TrinaryLogic::createYes(); } } */ private $immediatelyInvokedCallableParameters; /** * @var array */ private $phpDocClosureThisTypeParameters; /** @var Function_|ClassMethod */ private $functionLike; /** @var FunctionVariantWithPhpDocs[]|null */ private $variants = null; /** * @param Function_|ClassMethod $functionLike * @param Type[] $realParameterTypes * @param Type[] $phpDocParameterTypes * @param Type[] $realParameterDefaultValues * @param Type[] $parameterOutTypes * @param array $immediatelyInvokedCallableParameters * @param array $phpDocClosureThisTypeParameters */ public function __construct(FunctionLike $functionLike, string $fileName, TemplateTypeMap $templateTypeMap, array $realParameterTypes, array $phpDocParameterTypes, array $realParameterDefaultValues, Type $realReturnType, ?Type $phpDocReturnType, ?Type $throwType, ?string $deprecatedDescription, bool $isDeprecated, bool $isInternal, bool $isFinal, ?bool $isPure, bool $acceptsNamedArguments, Assertions $assertions, ?string $phpDocComment, array $parameterOutTypes, array $immediatelyInvokedCallableParameters, array $phpDocClosureThisTypeParameters) { $this->fileName = $fileName; $this->templateTypeMap = $templateTypeMap; $this->realParameterTypes = $realParameterTypes; $this->phpDocParameterTypes = $phpDocParameterTypes; $this->realParameterDefaultValues = $realParameterDefaultValues; $this->realReturnType = $realReturnType; $this->phpDocReturnType = $phpDocReturnType; $this->throwType = $throwType; $this->deprecatedDescription = $deprecatedDescription; $this->isDeprecated = $isDeprecated; $this->isInternal = $isInternal; $this->isFinal = $isFinal; $this->isPure = $isPure; $this->acceptsNamedArguments = $acceptsNamedArguments; $this->assertions = $assertions; $this->phpDocComment = $phpDocComment; $this->parameterOutTypes = $parameterOutTypes; $this->immediatelyInvokedCallableParameters = $immediatelyInvokedCallableParameters; $this->phpDocClosureThisTypeParameters = $phpDocClosureThisTypeParameters; $this->functionLike = $functionLike; } protected function getFunctionLike() : FunctionLike { return $this->functionLike; } public function getFileName() : string { return $this->fileName; } public function getName() : string { if ($this->functionLike instanceof ClassMethod) { return $this->functionLike->name->name; } if ($this->functionLike->namespacedName === null) { throw new ShouldNotHappenException(); } return (string) $this->functionLike->namespacedName; } /** * @return ParametersAcceptorWithPhpDocs[] */ public function getVariants() : array { if ($this->variants === null) { $this->variants = [new FunctionVariantWithPhpDocs($this->getTemplateTypeMap(), $this->getResolvedTemplateTypeMap(), $this->getParameters(), $this->isVariadic(), $this->getReturnType(), $this->getPhpDocReturnType(), $this->getNativeReturnType())]; } return $this->variants; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { return $this; } public function getNamedArgumentsVariants() : ?array { return null; } public function getTemplateTypeMap() : TemplateTypeMap { return $this->templateTypeMap; } public function getResolvedTemplateTypeMap() : TemplateTypeMap { return TemplateTypeMap::createEmpty(); } /** * @return array */ public function getParameters() : array { $parameters = []; $isOptional = \true; /** @var Node\Param $parameter */ foreach (array_reverse($this->functionLike->getParams()) as $parameter) { if ($parameter->default === null && !$parameter->variadic) { $isOptional = \false; } if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { throw new ShouldNotHappenException(); } if (isset($this->immediatelyInvokedCallableParameters[$parameter->var->name])) { $immediatelyInvokedCallable = TrinaryLogic::createFromBoolean($this->immediatelyInvokedCallableParameters[$parameter->var->name]); } else { $immediatelyInvokedCallable = TrinaryLogic::createMaybe(); } if (isset($this->phpDocClosureThisTypeParameters[$parameter->var->name])) { $closureThisType = $this->phpDocClosureThisTypeParameters[$parameter->var->name]; } else { $closureThisType = null; } $parameters[] = new \PHPStan\Reflection\Php\PhpParameterFromParserNodeReflection($parameter->var->name, $isOptional, $this->realParameterTypes[$parameter->var->name], $this->phpDocParameterTypes[$parameter->var->name] ?? null, $parameter->byRef ? PassedByReference::createCreatesNewVariable() : PassedByReference::createNo(), $this->realParameterDefaultValues[$parameter->var->name] ?? null, $parameter->variadic, $this->parameterOutTypes[$parameter->var->name] ?? null, $immediatelyInvokedCallable, $closureThisType); } return array_reverse($parameters); } public function isVariadic() : bool { foreach ($this->functionLike->getParams() as $parameter) { if ($parameter->variadic) { return \true; } } return \false; } public function getReturnType() : Type { return TypehintHelper::decideType($this->realReturnType, $this->phpDocReturnType); } public function getPhpDocReturnType() : Type { return $this->phpDocReturnType ?? new MixedType(); } public function getNativeReturnType() : Type { return $this->realReturnType; } public function getCallSiteVarianceMap() : TemplateTypeVarianceMap { return TemplateTypeVarianceMap::createEmpty(); } public function getDeprecatedDescription() : ?string { if ($this->isDeprecated) { return $this->deprecatedDescription; } return null; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->isDeprecated); } public function isInternal() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->isInternal); } public function isFinal() : TrinaryLogic { $finalMethod = \false; if ($this->functionLike instanceof ClassMethod) { $finalMethod = $this->functionLike->isFinal(); } return TrinaryLogic::createFromBoolean($finalMethod || $this->isFinal); } public function isFinalByKeyword() : TrinaryLogic { $finalMethod = \false; if ($this->functionLike instanceof ClassMethod) { $finalMethod = $this->functionLike->isFinal(); } return TrinaryLogic::createFromBoolean($finalMethod); } public function getThrowType() : ?Type { return $this->throwType; } public function hasSideEffects() : TrinaryLogic { if ($this->getReturnType()->isVoid()->yes()) { return TrinaryLogic::createYes(); } if ($this->isPure !== null) { return TrinaryLogic::createFromBoolean(!$this->isPure); } return TrinaryLogic::createMaybe(); } public function isBuiltin() : bool { return \false; } public function isGenerator() : bool { return $this->nodeIsOrContainsYield($this->functionLike); } public function acceptsNamedArguments() : bool { return $this->acceptsNamedArguments; } private function nodeIsOrContainsYield(Node $node) : bool { if ($node instanceof Node\Expr\Yield_) { return \true; } if ($node instanceof Node\Expr\YieldFrom) { return \true; } foreach ($node->getSubNodeNames() as $nodeName) { $nodeProperty = $node->{$nodeName}; if ($nodeProperty instanceof Node && $this->nodeIsOrContainsYield($nodeProperty)) { return \true; } if (!is_array($nodeProperty)) { continue; } foreach ($nodeProperty as $nodePropertyArrayItem) { if ($nodePropertyArrayItem instanceof Node && $this->nodeIsOrContainsYield($nodePropertyArrayItem)) { return \true; } } } return \false; } public function getAsserts() : Assertions { return $this->assertions; } public function getDocComment() : ?string { return $this->phpDocComment; } public function returnsByReference() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->functionLike->returnsByRef()); } public function isPure() : TrinaryLogic { if ($this->isPure === null) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createFromBoolean($this->isPure); } } > */ private $propertyTypesCache = []; /** @var array */ private $inferClassConstructorPropertyTypesInProcess = []; public function __construct(ScopeFactory $scopeFactory, NodeScopeResolver $nodeScopeResolver, \PHPStan\Reflection\Php\PhpMethodReflectionFactory $methodReflectionFactory, PhpDocInheritanceResolver $phpDocInheritanceResolver, AnnotationsMethodsClassReflectionExtension $annotationsMethodsClassReflectionExtension, AnnotationsPropertiesClassReflectionExtension $annotationsPropertiesClassReflectionExtension, SignatureMapProvider $signatureMapProvider, Parser $parser, StubPhpDocProvider $stubPhpDocProvider, ReflectionProvider\ReflectionProviderProvider $reflectionProviderProvider, FileTypeMapper $fileTypeMapper, bool $inferPrivatePropertyTypeFromConstructor) { $this->scopeFactory = $scopeFactory; $this->nodeScopeResolver = $nodeScopeResolver; $this->methodReflectionFactory = $methodReflectionFactory; $this->phpDocInheritanceResolver = $phpDocInheritanceResolver; $this->annotationsMethodsClassReflectionExtension = $annotationsMethodsClassReflectionExtension; $this->annotationsPropertiesClassReflectionExtension = $annotationsPropertiesClassReflectionExtension; $this->signatureMapProvider = $signatureMapProvider; $this->parser = $parser; $this->stubPhpDocProvider = $stubPhpDocProvider; $this->reflectionProviderProvider = $reflectionProviderProvider; $this->fileTypeMapper = $fileTypeMapper; $this->inferPrivatePropertyTypeFromConstructor = $inferPrivatePropertyTypeFromConstructor; } public function evictPrivateSymbols(string $classCacheKey) : void { foreach ($this->propertiesIncludingAnnotations as $key => $properties) { if ($key !== $classCacheKey) { continue; } foreach ($properties as $name => $property) { if (!$property->isPrivate()) { continue; } unset($this->propertiesIncludingAnnotations[$key][$name]); } } foreach ($this->nativeProperties as $key => $properties) { if ($key !== $classCacheKey) { continue; } foreach ($properties as $name => $property) { if (!$property->isPrivate()) { continue; } unset($this->nativeProperties[$key][$name]); } } foreach ($this->methodsIncludingAnnotations as $key => $methods) { if ($key !== $classCacheKey) { continue; } foreach ($methods as $name => $method) { if (!$method->isPrivate()) { continue; } unset($this->methodsIncludingAnnotations[$key][$name]); } } foreach ($this->nativeMethods as $key => $methods) { if ($key !== $classCacheKey) { continue; } foreach ($methods as $name => $method) { if (!$method->isPrivate()) { continue; } unset($this->nativeMethods[$key][$name]); } } } public function hasProperty(ClassReflection $classReflection, string $propertyName) : bool { return $classReflection->getNativeReflection()->hasProperty($propertyName); } /** * @return ExtendedPropertyReflection */ public function getProperty(ClassReflection $classReflection, string $propertyName) : PropertyReflection { if (!isset($this->propertiesIncludingAnnotations[$classReflection->getCacheKey()][$propertyName])) { $this->propertiesIncludingAnnotations[$classReflection->getCacheKey()][$propertyName] = $this->createProperty($classReflection, $propertyName, \true); } return $this->propertiesIncludingAnnotations[$classReflection->getCacheKey()][$propertyName]; } public function getNativeProperty(ClassReflection $classReflection, string $propertyName) : \PHPStan\Reflection\Php\PhpPropertyReflection { if (!isset($this->nativeProperties[$classReflection->getCacheKey()][$propertyName])) { /** @var PhpPropertyReflection $property */ $property = $this->createProperty($classReflection, $propertyName, \false); $this->nativeProperties[$classReflection->getCacheKey()][$propertyName] = $property; } return $this->nativeProperties[$classReflection->getCacheKey()][$propertyName]; } private function createProperty(ClassReflection $classReflection, string $propertyName, bool $includingAnnotations) : ExtendedPropertyReflection { $propertyReflection = $classReflection->getNativeReflection()->getProperty($propertyName); $propertyName = $propertyReflection->getName(); $declaringClassName = $propertyReflection->getDeclaringClass()->getName(); $declaringClassReflection = $classReflection->getAncestorWithClassName($declaringClassName); if ($declaringClassReflection === null) { throw new ShouldNotHappenException(sprintf('Internal error: Expected to find an ancestor with class name %s on %s, but none was found.', $declaringClassName, $classReflection->getName())); } if ($declaringClassReflection->isEnum()) { if ($propertyName === 'name' || $declaringClassReflection->isBackedEnum() && $propertyName === 'value') { $types = []; foreach (array_keys($classReflection->getEnumCases()) as $name) { if ($propertyName === 'name') { $types[] = new ConstantStringType($name); continue; } $case = $classReflection->getEnumCase($name); $value = $case->getBackingValueType(); if ($value === null) { throw new ShouldNotHappenException(); } $types[] = $value; } return new \PHPStan\Reflection\Php\PhpPropertyReflection($declaringClassReflection, null, null, TypeCombinator::union(...$types), $classReflection->getNativeReflection()->getProperty($propertyName), null, \false, \false, \false, \false); } } $deprecatedDescription = null; $isDeprecated = \false; $isInternal = \false; $isReadOnlyByPhpDoc = $classReflection->isImmutable(); $isAllowedPrivateMutation = \false; if ($includingAnnotations && !$declaringClassReflection->isEnum() && $this->annotationsPropertiesClassReflectionExtension->hasProperty($classReflection, $propertyName)) { $hierarchyDistances = $classReflection->getClassHierarchyDistances(); $annotationProperty = $this->annotationsPropertiesClassReflectionExtension->getProperty($classReflection, $propertyName); if (!isset($hierarchyDistances[$annotationProperty->getDeclaringClass()->getName()])) { throw new ShouldNotHappenException(); } $distanceDeclaringClass = $propertyReflection->getDeclaringClass()->getName(); $propertyTrait = $this->findPropertyTrait($propertyReflection); if ($propertyTrait !== null) { $distanceDeclaringClass = $propertyTrait; } if (!isset($hierarchyDistances[$distanceDeclaringClass])) { throw new ShouldNotHappenException(); } if ($hierarchyDistances[$annotationProperty->getDeclaringClass()->getName()] <= $hierarchyDistances[$distanceDeclaringClass]) { return $annotationProperty; } } $docComment = $propertyReflection->getDocComment() !== \false ? $propertyReflection->getDocComment() : null; $phpDocType = null; $resolvedPhpDoc = null; $declaringTraitName = $this->findPropertyTrait($propertyReflection); $constructorName = null; if ($propertyReflection->isPromoted()) { if ($declaringClassReflection->hasConstructor()) { $constructorName = $declaringClassReflection->getConstructor()->getName(); } } if ($constructorName === null) { $resolvedPhpDoc = $this->phpDocInheritanceResolver->resolvePhpDocForProperty($docComment, $declaringClassReflection, $declaringClassReflection->getFileName(), $declaringTraitName, $propertyName); } elseif ($docComment !== null) { $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($declaringClassReflection->getFileName(), $declaringClassName, $declaringTraitName, $constructorName, $docComment); } $phpDocBlockClassReflection = $declaringClassReflection; if ($resolvedPhpDoc !== null) { $varTags = $resolvedPhpDoc->getVarTags(); if (isset($varTags[0]) && count($varTags) === 1) { $phpDocType = $varTags[0]->getType(); } elseif (isset($varTags[$propertyName])) { $phpDocType = $varTags[$propertyName]->getType(); } $phpDocType = $phpDocType !== null ? TemplateTypeHelper::resolveTemplateTypes($phpDocType, $phpDocBlockClassReflection->getActiveTemplateTypeMap(), $phpDocBlockClassReflection->getCallSiteVarianceMap(), TemplateTypeVariance::createInvariant()) : null; $deprecatedDescription = $resolvedPhpDoc->getDeprecatedTag() !== null ? $resolvedPhpDoc->getDeprecatedTag()->getMessage() : null; $isDeprecated = $resolvedPhpDoc->isDeprecated(); $isInternal = $resolvedPhpDoc->isInternal(); $isReadOnlyByPhpDoc = $isReadOnlyByPhpDoc || $resolvedPhpDoc->isReadOnly(); $isAllowedPrivateMutation = $resolvedPhpDoc->isAllowedPrivateMutation(); } if ($phpDocType === null) { if (isset($constructorName)) { $constructorDocComment = $declaringClassReflection->getConstructor()->getDocComment(); $nativeClassReflection = $declaringClassReflection->getNativeReflection(); $positionalParameterNames = []; if ($nativeClassReflection->getConstructor() !== null) { $positionalParameterNames = array_map(static function (ReflectionParameter $parameter) : string { return $parameter->getName(); }, $nativeClassReflection->getConstructor()->getParameters()); } $resolvedConstructorPhpDoc = $this->phpDocInheritanceResolver->resolvePhpDocForMethod($constructorDocComment, $declaringClassReflection->getFileName(), $declaringClassReflection, $declaringTraitName, $constructorName, $positionalParameterNames); $paramTags = $resolvedConstructorPhpDoc->getParamTags(); if (isset($paramTags[$propertyReflection->getName()])) { $phpDocType = $paramTags[$propertyReflection->getName()]->getType(); } } } if ($phpDocType === null && $this->inferPrivatePropertyTypeFromConstructor && $declaringClassReflection->getFileName() !== null && $propertyReflection->isPrivate() && !$propertyReflection->isPromoted() && !$propertyReflection->hasType() && $declaringClassReflection->hasConstructor() && $declaringClassReflection->getConstructor()->getDeclaringClass()->getName() === $declaringClassReflection->getName()) { $phpDocType = $this->inferPrivatePropertyType($propertyReflection->getName(), $declaringClassReflection->getConstructor()); } $nativeType = null; if ($propertyReflection->getType() !== null) { $nativeType = $propertyReflection->getType(); } $declaringTrait = null; $reflectionProvider = $this->reflectionProviderProvider->getReflectionProvider(); if ($declaringTraitName !== null && $reflectionProvider->hasClass($declaringTraitName)) { $declaringTrait = $reflectionProvider->getClass($declaringTraitName); } return new \PHPStan\Reflection\Php\PhpPropertyReflection($declaringClassReflection, $declaringTrait, $nativeType, $phpDocType, $propertyReflection, $deprecatedDescription, $isDeprecated, $isInternal, $isReadOnlyByPhpDoc, $isAllowedPrivateMutation); } public function hasMethod(ClassReflection $classReflection, string $methodName) : bool { return $classReflection->getNativeReflection()->hasMethod($methodName); } /** * @return ExtendedMethodReflection */ public function getMethod(ClassReflection $classReflection, string $methodName) : MethodReflection { if (isset($this->methodsIncludingAnnotations[$classReflection->getCacheKey()][$methodName])) { return $this->methodsIncludingAnnotations[$classReflection->getCacheKey()][$methodName]; } $nativeMethodReflection = new \PHPStan\Reflection\Php\NativeBuiltinMethodReflection($classReflection->getNativeReflection()->getMethod($methodName)); if (!isset($this->methodsIncludingAnnotations[$classReflection->getCacheKey()][$nativeMethodReflection->getName()])) { $method = $this->createMethod($classReflection, $nativeMethodReflection, \true); $this->methodsIncludingAnnotations[$classReflection->getCacheKey()][$nativeMethodReflection->getName()] = $method; if ($nativeMethodReflection->getName() !== $methodName) { $this->methodsIncludingAnnotations[$classReflection->getCacheKey()][$methodName] = $method; } } return $this->methodsIncludingAnnotations[$classReflection->getCacheKey()][$nativeMethodReflection->getName()]; } public function hasNativeMethod(ClassReflection $classReflection, string $methodName) : bool { return $this->hasMethod($classReflection, $methodName); } public function getNativeMethod(ClassReflection $classReflection, string $methodName) : ExtendedMethodReflection { if (isset($this->nativeMethods[$classReflection->getCacheKey()][$methodName])) { return $this->nativeMethods[$classReflection->getCacheKey()][$methodName]; } if (!$classReflection->getNativeReflection()->hasMethod($methodName)) { throw new ShouldNotHappenException(); } $reflectionMethod = $classReflection->getNativeReflection()->getMethod($methodName); $nativeMethodReflection = new \PHPStan\Reflection\Php\NativeBuiltinMethodReflection($reflectionMethod); if (!isset($this->nativeMethods[$classReflection->getCacheKey()][$nativeMethodReflection->getName()])) { $method = $this->createMethod($classReflection, $nativeMethodReflection, \false); $this->nativeMethods[$classReflection->getCacheKey()][$nativeMethodReflection->getName()] = $method; } return $this->nativeMethods[$classReflection->getCacheKey()][$nativeMethodReflection->getName()]; } private function createMethod(ClassReflection $classReflection, \PHPStan\Reflection\Php\BuiltinMethodReflection $methodReflection, bool $includingAnnotations) : ExtendedMethodReflection { if ($includingAnnotations && $this->annotationsMethodsClassReflectionExtension->hasMethod($classReflection, $methodReflection->getName())) { $hierarchyDistances = $classReflection->getClassHierarchyDistances(); $annotationMethod = $this->annotationsMethodsClassReflectionExtension->getMethod($classReflection, $methodReflection->getName()); if (!isset($hierarchyDistances[$annotationMethod->getDeclaringClass()->getName()])) { throw new ShouldNotHappenException(); } $distanceDeclaringClass = $methodReflection->getDeclaringClass()->getName(); $methodTrait = $this->findMethodTrait($methodReflection); if ($methodTrait !== null) { $distanceDeclaringClass = $methodTrait; } if (!isset($hierarchyDistances[$distanceDeclaringClass])) { throw new ShouldNotHappenException(); } if ($hierarchyDistances[$annotationMethod->getDeclaringClass()->getName()] <= $hierarchyDistances[$distanceDeclaringClass]) { return $annotationMethod; } } $declaringClassName = $methodReflection->getDeclaringClass()->getName(); $declaringClass = $classReflection->getAncestorWithClassName($declaringClassName); if ($declaringClass === null) { throw new ShouldNotHappenException(sprintf('Internal error: Expected to find an ancestor with class name %s on %s, but none was found.', $declaringClassName, $classReflection->getName())); } if ($declaringClass->isEnum() && $declaringClass->getName() !== 'UnitEnum' && strtolower($methodReflection->getName()) === 'cases') { $arrayBuilder = ConstantArrayTypeBuilder::createEmpty(); foreach (array_keys($classReflection->getEnumCases()) as $name) { $arrayBuilder->setOffsetValueType(null, new EnumCaseObjectType($classReflection->getName(), $name)); } return new \PHPStan\Reflection\Php\EnumCasesMethodReflection($declaringClass, $arrayBuilder->getArray()); } if ($this->signatureMapProvider->hasMethodSignature($declaringClassName, $methodReflection->getName())) { $variantsByType = ['positional' => []]; $reflectionMethod = null; $throwType = null; $asserts = Assertions::createEmpty(); $acceptsNamedArguments = \true; $selfOutType = null; $phpDocComment = null; if ($classReflection->getNativeReflection()->hasMethod($methodReflection->getName())) { $reflectionMethod = $classReflection->getNativeReflection()->getMethod($methodReflection->getName()); } $methodSignaturesResult = $this->signatureMapProvider->getMethodSignatures($declaringClassName, $methodReflection->getName(), $reflectionMethod); foreach ($methodSignaturesResult as $signatureType => $methodSignatures) { if ($methodSignatures === null) { continue; } foreach ($methodSignatures as $methodSignature) { $phpDocParameterNameMapping = []; foreach ($methodSignature->getParameters() as $parameter) { $phpDocParameterNameMapping[$parameter->getName()] = $parameter->getName(); } $stubPhpDocReturnType = null; $stubPhpDocParameterTypes = []; $stubPhpDocParameterVariadicity = []; $phpDocParameterTypes = []; $phpDocReturnType = null; $stubPhpDocPair = null; $stubPhpParameterOutTypes = []; $phpDocParameterOutTypes = []; $immediatelyInvokedCallableParameters = []; $closureThisParameters = []; $stubImmediatelyInvokedCallableParameters = []; $stubClosureThisParameters = []; if (count($methodSignatures) === 1) { $stubPhpDocPair = $this->findMethodPhpDocIncludingAncestors($declaringClass, $declaringClass, $methodReflection->getName(), array_map(static function (ParameterSignature $parameterSignature) : string { return $parameterSignature->getName(); }, $methodSignature->getParameters())); if ($stubPhpDocPair !== null) { [$stubPhpDoc, $stubDeclaringClass] = $stubPhpDocPair; $templateTypeMap = $stubDeclaringClass->getActiveTemplateTypeMap(); $callSiteVarianceMap = $stubDeclaringClass->getCallSiteVarianceMap(); $returnTag = $stubPhpDoc->getReturnTag(); $stubImmediatelyInvokedCallableParameters = array_map(static function (bool $immediate) { return TrinaryLogic::createFromBoolean($immediate); }, $stubPhpDoc->getParamsImmediatelyInvokedCallable()); if ($returnTag !== null) { $stubPhpDocReturnType = TemplateTypeHelper::resolveTemplateTypes($returnTag->getType(), $templateTypeMap, $callSiteVarianceMap, TemplateTypeVariance::createCovariant()); } $stubClosureThisParameters = array_map(static function ($tag) { return $tag->getType(); }, $stubPhpDoc->getParamClosureThisTags()); foreach ($stubPhpDoc->getParamTags() as $name => $paramTag) { $stubPhpDocParameterTypes[$name] = TemplateTypeHelper::resolveTemplateTypes($paramTag->getType(), $templateTypeMap, $callSiteVarianceMap, TemplateTypeVariance::createContravariant()); $stubPhpDocParameterVariadicity[$name] = $paramTag->isVariadic(); } $throwsTag = $stubPhpDoc->getThrowsTag(); if ($throwsTag !== null) { $throwType = $throwsTag->getType(); } $asserts = Assertions::createFromResolvedPhpDocBlock($stubPhpDoc); $acceptsNamedArguments = $stubPhpDoc->acceptsNamedArguments(); $selfOutTypeTag = $stubPhpDoc->getSelfOutTag(); if ($selfOutTypeTag !== null) { $selfOutType = $selfOutTypeTag->getType(); } foreach ($stubPhpDoc->getParamOutTags() as $name => $paramOutTag) { $stubPhpParameterOutTypes[$name] = TemplateTypeHelper::resolveTemplateTypes($paramOutTag->getType(), $templateTypeMap, $callSiteVarianceMap, TemplateTypeVariance::createCovariant()); } if ($declaringClassName === $stubDeclaringClass->getName() && $stubPhpDoc->hasPhpDocString()) { $phpDocComment = $stubPhpDoc->getPhpDocString(); } } } if ($stubPhpDocPair === null && $reflectionMethod !== null && $reflectionMethod->getDocComment() !== \false) { $filename = $reflectionMethod->getFileName(); if ($filename !== \false) { $phpDocBlock = $this->fileTypeMapper->getResolvedPhpDoc($filename, $declaringClassName, null, $reflectionMethod->getName(), $reflectionMethod->getDocComment()); $throwsTag = $phpDocBlock->getThrowsTag(); if ($throwsTag !== null) { $throwType = $throwsTag->getType(); } $returnTag = $phpDocBlock->getReturnTag(); if ($returnTag !== null && count($methodSignatures) === 1) { $phpDocReturnType = $returnTag->getType(); } $immediatelyInvokedCallableParameters = array_map(static function ($immediate) { return TrinaryLogic::createFromBoolean($immediate); }, $phpDocBlock->getParamsImmediatelyInvokedCallable()); $closureThisParameters = array_map(static function ($tag) { return $tag->getType(); }, $phpDocBlock->getParamClosureThisTags()); foreach ($phpDocBlock->getParamTags() as $name => $paramTag) { $phpDocParameterTypes[$name] = $paramTag->getType(); } $asserts = Assertions::createFromResolvedPhpDocBlock($phpDocBlock); $acceptsNamedArguments = $phpDocBlock->acceptsNamedArguments(); $selfOutTypeTag = $phpDocBlock->getSelfOutTag(); if ($selfOutTypeTag !== null) { $selfOutType = $selfOutTypeTag->getType(); } if ($phpDocBlock->hasPhpDocString()) { $phpDocComment = $phpDocBlock->getPhpDocString(); } foreach ($phpDocBlock->getParamOutTags() as $name => $paramOutTag) { $phpDocParameterOutTypes[$name] = $paramOutTag->getType(); } $signatureParameters = $methodSignature->getParameters(); foreach ($reflectionMethod->getParameters() as $paramI => $reflectionParameter) { if (!array_key_exists($paramI, $signatureParameters)) { continue; } $phpDocParameterNameMapping[$signatureParameters[$paramI]->getName()] = $reflectionParameter->getName(); } } } $variantsByType[$signatureType][] = $this->createNativeMethodVariant($methodSignature, $stubPhpDocParameterTypes, $stubPhpDocParameterVariadicity, $stubPhpDocReturnType, $phpDocParameterTypes, $phpDocReturnType, $phpDocParameterNameMapping, $stubPhpParameterOutTypes, $phpDocParameterOutTypes, $stubImmediatelyInvokedCallableParameters, $immediatelyInvokedCallableParameters, $stubClosureThisParameters, $closureThisParameters, $signatureType !== 'named'); } } if ($this->signatureMapProvider->hasMethodMetadata($declaringClassName, $methodReflection->getName())) { $hasSideEffects = TrinaryLogic::createFromBoolean($this->signatureMapProvider->getMethodMetadata($declaringClassName, $methodReflection->getName())['hasSideEffects']); } else { $hasSideEffects = TrinaryLogic::createMaybe(); } return new NativeMethodReflection($this->reflectionProviderProvider->getReflectionProvider(), $declaringClass, $methodReflection, $variantsByType['positional'], $variantsByType['named'] ?? null, $hasSideEffects, $throwType, $asserts, $acceptsNamedArguments, $selfOutType, $phpDocComment); } return $this->createUserlandMethodReflection($declaringClass, $declaringClass, $methodReflection, $this->findMethodTrait($methodReflection)); } public function createUserlandMethodReflection(ClassReflection $fileDeclaringClass, ClassReflection $actualDeclaringClass, \PHPStan\Reflection\Php\BuiltinMethodReflection $methodReflection, ?string $declaringTraitName) : \PHPStan\Reflection\Php\PhpMethodReflection { $resolvedPhpDoc = null; $stubPhpDocPair = $this->findMethodPhpDocIncludingAncestors($fileDeclaringClass, $fileDeclaringClass, $methodReflection->getName(), array_map(static function (ReflectionParameter $parameter) : string { return $parameter->getName(); }, $methodReflection->getParameters())); $phpDocBlockClassReflection = $fileDeclaringClass; if ($methodReflection->getReflection() !== null) { $methodDeclaringClass = $methodReflection->getReflection()->getBetterReflection()->getDeclaringClass(); if ($stubPhpDocPair === null && $methodDeclaringClass->isTrait()) { if (!$methodReflection->getDeclaringClass()->isTrait() || $methodDeclaringClass->getName() !== $methodReflection->getDeclaringClass()->getName()) { $stubPhpDocPair = $this->findMethodPhpDocIncludingAncestors($this->reflectionProviderProvider->getReflectionProvider()->getClass($methodDeclaringClass->getName()), $this->reflectionProviderProvider->getReflectionProvider()->getClass($methodReflection->getDeclaringClass()->getName()), $methodReflection->getName(), array_map(static function (ReflectionParameter $parameter) : string { return $parameter->getName(); }, $methodReflection->getParameters())); } } } if ($stubPhpDocPair !== null) { [$resolvedPhpDoc, $phpDocBlockClassReflection] = $stubPhpDocPair; } if ($resolvedPhpDoc === null) { $docComment = $methodReflection->getDocComment(); $positionalParameterNames = array_map(static function (ReflectionParameter $parameter) : string { return $parameter->getName(); }, $methodReflection->getParameters()); $resolvedPhpDoc = $this->phpDocInheritanceResolver->resolvePhpDocForMethod($docComment, $actualDeclaringClass->getFileName(), $actualDeclaringClass, $declaringTraitName, $methodReflection->getName(), $positionalParameterNames); $phpDocBlockClassReflection = $fileDeclaringClass; } $declaringTrait = null; $reflectionProvider = $this->reflectionProviderProvider->getReflectionProvider(); if ($declaringTraitName !== null && $reflectionProvider->hasClass($declaringTraitName)) { $declaringTrait = $reflectionProvider->getClass($declaringTraitName); } $phpDocParameterTypes = []; if ($methodReflection instanceof \PHPStan\Reflection\Php\NativeBuiltinMethodReflection && $methodReflection->isConstructor()) { foreach ($methodReflection->getParameters() as $parameter) { if (!$parameter->isPromoted()) { continue; } if (!$methodReflection->getDeclaringClass()->hasProperty($parameter->getName())) { continue; } $parameterProperty = $methodReflection->getDeclaringClass()->getProperty($parameter->getName()); if (!$parameterProperty->isPromoted()) { continue; } if ($parameterProperty->getDocComment() === \false) { continue; } $propertyDocblock = $this->fileTypeMapper->getResolvedPhpDoc($fileDeclaringClass->getFileName(), $fileDeclaringClass->getName(), $declaringTraitName, $methodReflection->getName(), $parameterProperty->getDocComment()); $varTags = $propertyDocblock->getVarTags(); if (isset($varTags[0]) && count($varTags) === 1) { $phpDocType = $varTags[0]->getType(); } elseif (isset($varTags[$parameter->getName()])) { $phpDocType = $varTags[$parameter->getName()]->getType(); } else { continue; } $phpDocParameterTypes[$parameter->getName()] = $phpDocType; } } $templateTypeMap = $resolvedPhpDoc->getTemplateTypeMap(); $immediatelyInvokedCallableParameters = array_map(static function (bool $immediate) { return TrinaryLogic::createFromBoolean($immediate); }, $resolvedPhpDoc->getParamsImmediatelyInvokedCallable()); $closureThisParameters = array_map(static function ($tag) { return $tag->getType(); }, $resolvedPhpDoc->getParamClosureThisTags()); foreach ($resolvedPhpDoc->getParamTags() as $paramName => $paramTag) { if (array_key_exists($paramName, $phpDocParameterTypes)) { continue; } $phpDocParameterTypes[$paramName] = $paramTag->getType(); } foreach ($phpDocParameterTypes as $paramName => $paramType) { $phpDocParameterTypes[$paramName] = TemplateTypeHelper::resolveTemplateTypes($paramType, $phpDocBlockClassReflection->getActiveTemplateTypeMap(), $phpDocBlockClassReflection->getCallSiteVarianceMap(), TemplateTypeVariance::createContravariant()); } $phpDocParameterOutTypes = []; foreach ($resolvedPhpDoc->getParamOutTags() as $paramName => $paramOutTag) { $phpDocParameterOutTypes[$paramName] = TemplateTypeHelper::resolveTemplateTypes($paramOutTag->getType(), $phpDocBlockClassReflection->getActiveTemplateTypeMap(), $phpDocBlockClassReflection->getCallSiteVarianceMap(), TemplateTypeVariance::createCovariant()); } $nativeReturnType = TypehintHelper::decideTypeFromReflection($methodReflection->getReturnType(), null, $actualDeclaringClass); $phpDocReturnType = $this->getPhpDocReturnType($phpDocBlockClassReflection, $resolvedPhpDoc, $nativeReturnType); $phpDocThrowType = $resolvedPhpDoc->getThrowsTag() !== null ? $resolvedPhpDoc->getThrowsTag()->getType() : null; $deprecatedDescription = $resolvedPhpDoc->getDeprecatedTag() !== null ? $resolvedPhpDoc->getDeprecatedTag()->getMessage() : null; $isDeprecated = $resolvedPhpDoc->isDeprecated(); $isInternal = $resolvedPhpDoc->isInternal(); $isFinal = $resolvedPhpDoc->isFinal(); $isPure = $resolvedPhpDoc->isPure(); $asserts = Assertions::createFromResolvedPhpDocBlock($resolvedPhpDoc); $acceptsNamedArguments = $resolvedPhpDoc->acceptsNamedArguments(); $selfOutType = $resolvedPhpDoc->getSelfOutTag() !== null ? $resolvedPhpDoc->getSelfOutTag()->getType() : null; $phpDocComment = null; if ($resolvedPhpDoc->hasPhpDocString()) { $phpDocComment = $resolvedPhpDoc->getPhpDocString(); } return $this->methodReflectionFactory->create($actualDeclaringClass, $declaringTrait, $methodReflection, $templateTypeMap, $phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal, $isPure, $asserts, $selfOutType, $phpDocComment, $phpDocParameterOutTypes, $immediatelyInvokedCallableParameters, $closureThisParameters, $acceptsNamedArguments); } /** * @param array $stubPhpDocParameterTypes * @param array $stubPhpDocParameterVariadicity * @param array $phpDocParameterTypes * @param array $phpDocParameterNameMapping * @param array $stubPhpDocParameterOutTypes * @param array $phpDocParameterOutTypes * @param array $stubImmediatelyInvokedCallableParameters * @param array $immediatelyInvokedCallableParameters * @param array $stubClosureThisParameters * @param array $closureThisParameters */ private function createNativeMethodVariant(FunctionSignature $methodSignature, array $stubPhpDocParameterTypes, array $stubPhpDocParameterVariadicity, ?Type $stubPhpDocReturnType, array $phpDocParameterTypes, ?Type $phpDocReturnType, array $phpDocParameterNameMapping, array $stubPhpDocParameterOutTypes, array $phpDocParameterOutTypes, array $stubImmediatelyInvokedCallableParameters, array $immediatelyInvokedCallableParameters, array $stubClosureThisParameters, array $closureThisParameters, bool $usePhpDocParameterNames) : FunctionVariantWithPhpDocs { $parameters = []; foreach ($methodSignature->getParameters() as $parameterSignature) { $type = null; $phpDocType = null; $parameterOutType = null; $phpDocParameterName = $phpDocParameterNameMapping[$parameterSignature->getName()] ?? $parameterSignature->getName(); if (isset($stubPhpDocParameterTypes[$parameterSignature->getName()])) { $type = $stubPhpDocParameterTypes[$parameterSignature->getName()]; $phpDocType = $stubPhpDocParameterTypes[$parameterSignature->getName()]; } elseif (isset($phpDocParameterTypes[$phpDocParameterName])) { $phpDocType = $phpDocParameterTypes[$phpDocParameterName]; } if (isset($stubPhpDocParameterOutTypes[$parameterSignature->getName()])) { $parameterOutType = $stubPhpDocParameterOutTypes[$parameterSignature->getName()]; } elseif (isset($phpDocParameterOutTypes[$phpDocParameterName])) { $parameterOutType = $phpDocParameterOutTypes[$phpDocParameterName]; } if (isset($stubImmediatelyInvokedCallableParameters[$parameterSignature->getName()])) { $immediatelyInvoked = $stubImmediatelyInvokedCallableParameters[$parameterSignature->getName()]; } elseif (isset($immediatelyInvokedCallableParameters[$phpDocParameterName])) { $immediatelyInvoked = $immediatelyInvokedCallableParameters[$phpDocParameterName]; } else { $immediatelyInvoked = TrinaryLogic::createMaybe(); } $closureThisType = null; if (isset($stubClosureThisParameters[$parameterSignature->getName()])) { $closureThisType = $stubClosureThisParameters[$parameterSignature->getName()]; } elseif (isset($closureThisParameters[$phpDocParameterName])) { $closureThisType = $closureThisParameters[$phpDocParameterName]; } $parameters[] = new NativeParameterWithPhpDocsReflection($usePhpDocParameterNames ? $phpDocParameterName : $parameterSignature->getName(), $parameterSignature->isOptional(), $type ?? $parameterSignature->getType(), $phpDocType ?? new MixedType(), $parameterSignature->getNativeType(), $parameterSignature->passedByReference(), $stubPhpDocParameterVariadicity[$parameterSignature->getName()] ?? $parameterSignature->isVariadic(), $parameterSignature->getDefaultValue(), $parameterOutType ?? $parameterSignature->getOutType(), $immediatelyInvoked, $closureThisType); } if ($stubPhpDocReturnType !== null) { $returnType = $stubPhpDocReturnType; $phpDocReturnType = $stubPhpDocReturnType; } else { $returnType = TypehintHelper::decideType($methodSignature->getReturnType(), $phpDocReturnType); } return new FunctionVariantWithPhpDocs(TemplateTypeMap::createEmpty(), null, $parameters, $methodSignature->isVariadic(), $returnType, $phpDocReturnType ?? new MixedType(), $methodSignature->getNativeReturnType()); } private function findPropertyTrait(ReflectionProperty $propertyReflection) : ?string { $declaringClass = $propertyReflection->getBetterReflection()->getDeclaringClass(); if ($declaringClass->isTrait()) { if ($propertyReflection->getDeclaringClass()->isTrait() && $propertyReflection->getDeclaringClass()->getName() === $declaringClass->getName()) { return null; } return $declaringClass->getName(); } return null; } private function findMethodTrait(\PHPStan\Reflection\Php\BuiltinMethodReflection $methodReflection) : ?string { if ($methodReflection->getReflection() === null) { return null; } $declaringClass = $methodReflection->getReflection()->getBetterReflection()->getDeclaringClass(); if ($declaringClass->isTrait()) { if ($methodReflection->getDeclaringClass()->isTrait() && $declaringClass->getName() === $methodReflection->getDeclaringClass()->getName()) { return null; } return $declaringClass->getName(); } return null; } private function inferPrivatePropertyType(string $propertyName, MethodReflection $constructor) : ?Type { $declaringClassName = $constructor->getDeclaringClass()->getName(); if (isset($this->inferClassConstructorPropertyTypesInProcess[$declaringClassName])) { return null; } $this->inferClassConstructorPropertyTypesInProcess[$declaringClassName] = \true; $propertyTypes = $this->inferAndCachePropertyTypes($constructor); unset($this->inferClassConstructorPropertyTypesInProcess[$declaringClassName]); if (array_key_exists($propertyName, $propertyTypes)) { return $propertyTypes[$propertyName]; } return null; } /** * @return array */ private function inferAndCachePropertyTypes(MethodReflection $constructor) : array { $declaringClass = $constructor->getDeclaringClass(); if (isset($this->propertyTypesCache[$declaringClass->getName()])) { return $this->propertyTypesCache[$declaringClass->getName()]; } if ($declaringClass->getFileName() === null) { return $this->propertyTypesCache[$declaringClass->getName()] = []; } $fileName = $declaringClass->getFileName(); $nodes = $this->parser->parseFile($fileName); $classNode = $this->findClassNode($declaringClass->getName(), $nodes); if ($classNode === null) { return $this->propertyTypesCache[$declaringClass->getName()] = []; } $methodNode = $this->findConstructorNode($constructor->getName(), $classNode->stmts); if ($methodNode === null || $methodNode->stmts === null || count($methodNode->stmts) === 0) { return $this->propertyTypesCache[$declaringClass->getName()] = []; } $classNameParts = explode('\\', $declaringClass->getName()); $namespace = null; if (count($classNameParts) > 1) { $namespace = implode('\\', array_slice($classNameParts, 0, -1)); } $classScope = $this->scopeFactory->create(ScopeContext::create($fileName)); if ($namespace !== null) { $classScope = $classScope->enterNamespace($namespace); } $classScope = $classScope->enterClass($declaringClass); [$templateTypeMap, $phpDocParameterTypes, $phpDocImmediatelyInvokedCallableParameters, $phpDocClosureThisTypeParameters, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal, $isPure, $acceptsNamedArguments, , $phpDocComment, $asserts, $selfOutType, $phpDocParameterOutTypes] = $this->nodeScopeResolver->getPhpDocs($classScope, $methodNode); $methodScope = $classScope->enterClassMethod($methodNode, $templateTypeMap, $phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal, $isPure, $acceptsNamedArguments, $asserts, $selfOutType, $phpDocComment, $phpDocParameterOutTypes, $phpDocImmediatelyInvokedCallableParameters, $phpDocClosureThisTypeParameters); $propertyTypes = []; foreach ($methodNode->stmts as $statement) { if (!$statement instanceof Node\Stmt\Expression) { continue; } $expr = $statement->expr; if (!$expr instanceof Node\Expr\Assign) { continue; } if (!$expr->var instanceof Node\Expr\PropertyFetch) { continue; } $propertyFetch = $expr->var; if (!$propertyFetch->var instanceof Node\Expr\Variable || $propertyFetch->var->name !== 'this' || !$propertyFetch->name instanceof Node\Identifier) { continue; } $propertyType = $methodScope->getType($expr->expr); if ($propertyType instanceof ErrorType || $propertyType instanceof NeverType) { continue; } $propertyType = $propertyType->generalize(GeneralizePrecision::lessSpecific()); if ($propertyType->isConstantArray()->yes()) { $propertyType = new ArrayType(new MixedType(\true), new MixedType(\true)); } $propertyTypes[$propertyFetch->name->toString()] = $propertyType; } return $this->propertyTypesCache[$declaringClass->getName()] = $propertyTypes; } /** * @param Node[] $nodes */ private function findClassNode(string $className, array $nodes) : ?Class_ { foreach ($nodes as $node) { if ($node instanceof Class_ && $node->namespacedName !== null && $node->namespacedName->toString() === $className) { return $node; } if (!$node instanceof Namespace_ && !$node instanceof Declare_) { continue; } $subNodeNames = $node->getSubNodeNames(); foreach ($subNodeNames as $subNodeName) { $subNode = $node->{$subNodeName}; if (!is_array($subNode)) { $subNode = [$subNode]; } $result = $this->findClassNode($className, $subNode); if ($result === null) { continue; } return $result; } } return null; } /** * @param Node\Stmt[] $classStatements */ private function findConstructorNode(string $methodName, array $classStatements) : ?ClassMethod { foreach ($classStatements as $statement) { if ($statement instanceof ClassMethod && $statement->name->toString() === $methodName) { return $statement; } } return null; } private function getPhpDocReturnType(ClassReflection $phpDocBlockClassReflection, ResolvedPhpDocBlock $resolvedPhpDoc, Type $nativeReturnType) : ?Type { $returnTag = $resolvedPhpDoc->getReturnTag(); if ($returnTag === null) { return null; } $phpDocReturnType = $returnTag->getType(); $phpDocReturnType = TemplateTypeHelper::resolveTemplateTypes($phpDocReturnType, $phpDocBlockClassReflection->getActiveTemplateTypeMap(), $phpDocBlockClassReflection->getCallSiteVarianceMap(), TemplateTypeVariance::createCovariant()); if ($returnTag->isExplicit() || $nativeReturnType->isSuperTypeOf($phpDocReturnType)->yes()) { return $phpDocReturnType; } return null; } /** * @param array $positionalParameterNames * @return array{ResolvedPhpDocBlock, ClassReflection}|null */ private function findMethodPhpDocIncludingAncestors(ClassReflection $declaringClass, ClassReflection $implementingClass, string $methodName, array $positionalParameterNames) : ?array { $declaringClassName = $declaringClass->getName(); $resolved = $this->stubPhpDocProvider->findMethodPhpDoc($declaringClassName, $implementingClass->getName(), $methodName, $positionalParameterNames); if ($resolved !== null) { return [$resolved, $declaringClass]; } if (!$this->stubPhpDocProvider->isKnownClass($declaringClassName)) { return null; } $ancestors = $declaringClass->getAncestors(); foreach ($ancestors as $ancestor) { if ($ancestor->getName() === $declaringClassName) { continue; } if (!$ancestor->hasNativeMethod($methodName)) { continue; } $resolved = $this->stubPhpDocProvider->findMethodPhpDoc($ancestor->getName(), $ancestor->getName(), $methodName, $positionalParameterNames); if ($resolved === null) { continue; } return [$resolved, $ancestor]; } return null; } } $immediatelyInvokedCallableParameters * @param array $phpDocClosureThisTypeParameters */ public function create(ClassReflection $declaringClass, ?ClassReflection $declaringTrait, \PHPStan\Reflection\Php\BuiltinMethodReflection $reflection, TemplateTypeMap $templateTypeMap, array $phpDocParameterTypes, ?Type $phpDocReturnType, ?Type $phpDocThrowType, ?string $deprecatedDescription, bool $isDeprecated, bool $isInternal, bool $isFinal, ?bool $isPure, Assertions $asserts, ?Type $selfOutType, ?string $phpDocComment, array $phpDocParameterOutTypes, array $immediatelyInvokedCallableParameters = [], array $phpDocClosureThisTypeParameters = [], bool $acceptsNamedArguments = \true) : \PHPStan\Reflection\Php\PhpMethodReflection; } $immediatelyInvokedCallableParameters * @param array $phpDocClosureThisTypeParameters */ public function __construct(ClassReflection $declaringClass, ClassMethod $classMethod, string $fileName, TemplateTypeMap $templateTypeMap, array $realParameterTypes, array $phpDocParameterTypes, array $realParameterDefaultValues, Type $realReturnType, ?Type $phpDocReturnType, ?Type $throwType, ?string $deprecatedDescription, bool $isDeprecated, bool $isInternal, bool $isFinal, ?bool $isPure, bool $acceptsNamedArguments, Assertions $assertions, ?Type $selfOutType, ?string $phpDocComment, array $parameterOutTypes, array $immediatelyInvokedCallableParameters, array $phpDocClosureThisTypeParameters, bool $isConstructor) { $this->declaringClass = $declaringClass; $this->selfOutType = $selfOutType; $this->isConstructor = $isConstructor; $name = strtolower($classMethod->name->name); if ($this->isConstructor) { $realReturnType = new VoidType(); } if (in_array($name, ['__destruct', '__unset', '__wakeup', '__clone'], \true)) { $realReturnType = new VoidType(); } if ($name === '__tostring') { $realReturnType = new StringType(); } if ($name === '__isset') { $realReturnType = new BooleanType(); } if ($name === '__sleep') { $realReturnType = new ArrayType(new IntegerType(), new StringType()); } if ($name === '__set_state') { $realReturnType = TypeCombinator::intersect(new ObjectWithoutClassType(), $realReturnType); } if ($name === '__set') { $realReturnType = new VoidType(); } if ($name === '__debuginfo') { $realReturnType = TypeCombinator::intersect(TypeCombinator::addNull(new ArrayType(new MixedType(\true), new MixedType(\true))), $realReturnType); } if ($name === '__unserialize') { $realReturnType = new VoidType(); } if ($name === '__serialize') { $realReturnType = new ArrayType(new MixedType(\true), new MixedType(\true)); } parent::__construct($classMethod, $fileName, $templateTypeMap, $realParameterTypes, $phpDocParameterTypes, $realParameterDefaultValues, $realReturnType, $phpDocReturnType, $throwType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal || $classMethod->isFinal(), $isPure, $acceptsNamedArguments, $assertions, $phpDocComment, $parameterOutTypes, $immediatelyInvokedCallableParameters, $phpDocClosureThisTypeParameters); } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function getPrototype() : ClassMemberReflection { try { return $this->declaringClass->getNativeMethod($this->getClassMethod()->name->name)->getPrototype(); } catch (MissingMethodFromReflectionException $e) { return $this; } } private function getClassMethod() : ClassMethod { /** @var Node\Stmt\ClassMethod $functionLike */ $functionLike = $this->getFunctionLike(); return $functionLike; } public function isStatic() : bool { return $this->getClassMethod()->isStatic(); } public function isPrivate() : bool { return $this->getClassMethod()->isPrivate(); } public function isPublic() : bool { return $this->getClassMethod()->isPublic(); } public function isBuiltin() : bool { return \false; } public function getSelfOutType() : ?Type { return $this->selfOutType; } public function returnsByReference() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->getClassMethod()->returnsByRef()); } public function isAbstract() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->getClassMethod()->isAbstract()); } public function isConstructor() : bool { return $this->isConstructor; } public function hasSideEffects() : TrinaryLogic { if (strtolower($this->getName()) !== '__construct' && $this->getReturnType()->isVoid()->yes()) { return TrinaryLogic::createYes(); } if ($this->isPure !== null) { return TrinaryLogic::createFromBoolean(!$this->isPure); } return TrinaryLogic::createMaybe(); } } nativeMethodReflection = $nativeMethodReflection; $this->closureType = $closureType; } public function getDeclaringClass() : ClassReflection { return $this->nativeMethodReflection->getDeclaringClass(); } public function isStatic() : bool { return $this->nativeMethodReflection->isStatic(); } public function isPrivate() : bool { return $this->nativeMethodReflection->isPrivate(); } public function isPublic() : bool { return $this->nativeMethodReflection->isPublic(); } public function getDocComment() : ?string { return $this->nativeMethodReflection->getDocComment(); } public function getName() : string { return $this->nativeMethodReflection->getName(); } public function getPrototype() : ClassMemberReflection { return $this->nativeMethodReflection->getPrototype(); } public function getVariants() : array { $parameters = $this->closureType->getParameters(); $newThis = new NativeParameterReflection('newThis', \false, new ObjectWithoutClassType(), PassedByReference::createNo(), \false, null); array_unshift($parameters, $newThis); return [new FunctionVariantWithPhpDocs($this->closureType->getTemplateTypeMap(), $this->closureType->getResolvedTemplateTypeMap(), array_map(static function (ParameterReflection $parameter) : ParameterReflectionWithPhpDocs { return new \PHPStan\Reflection\Php\DummyParameterWithPhpDocs($parameter->getName(), $parameter->getType(), $parameter->isOptional(), $parameter->passedByReference(), $parameter->isVariadic(), $parameter->getDefaultValue(), new MixedType(), $parameter->getType(), null, TrinaryLogic::createMaybe(), null); }, $parameters), $this->closureType->isVariadic(), $this->closureType->getReturnType(), $this->closureType->getReturnType(), new MixedType(), $this->closureType->getCallSiteVarianceMap())]; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { return $this->getVariants()[0]; } public function getNamedArgumentsVariants() : ?array { return null; } public function isDeprecated() : TrinaryLogic { return $this->nativeMethodReflection->isDeprecated(); } public function getDeprecatedDescription() : ?string { return $this->nativeMethodReflection->getDeprecatedDescription(); } public function isFinal() : TrinaryLogic { return $this->nativeMethodReflection->isFinal(); } public function isFinalByKeyword() : TrinaryLogic { return $this->nativeMethodReflection->isFinalByKeyword(); } public function isInternal() : TrinaryLogic { return $this->nativeMethodReflection->isInternal(); } public function getThrowType() : ?Type { return $this->nativeMethodReflection->getThrowType(); } public function hasSideEffects() : TrinaryLogic { return $this->nativeMethodReflection->hasSideEffects(); } public function getAsserts() : Assertions { return $this->nativeMethodReflection->getAsserts(); } public function acceptsNamedArguments() : bool { return $this->nativeMethodReflection->acceptsNamedArguments(); } public function getSelfOutType() : ?Type { return $this->nativeMethodReflection->getSelfOutType(); } public function returnsByReference() : TrinaryLogic { return $this->nativeMethodReflection->returnsByReference(); } public function isAbstract() : TrinaryLogic { $abstract = $this->nativeMethodReflection->isAbstract(); if (is_bool($abstract)) { return TrinaryLogic::createFromBoolean($abstract); } return $abstract; } public function isPure() : TrinaryLogic { return $this->nativeMethodReflection->isPure(); } } initializerExprTypeResolver = $initializerExprTypeResolver; $this->reflection = $reflection; $this->phpDocType = $phpDocType; $this->declaringClassName = $declaringClassName; $this->outType = $outType; $this->immediatelyInvokedCallable = $immediatelyInvokedCallable; $this->closureThisType = $closureThisType; } public function isOptional() : bool { return $this->reflection->isOptional(); } public function getName() : string { return $this->reflection->getName(); } public function getType() : Type { if ($this->type === null) { $phpDocType = $this->phpDocType; if ($phpDocType !== null && $this->reflection->isDefaultValueAvailable()) { $defaultValueType = $this->initializerExprTypeResolver->getType($this->reflection->getDefaultValueExpression(), InitializerExprContext::fromReflectionParameter($this->reflection)); if ($defaultValueType->isNull()->yes()) { $phpDocType = TypeCombinator::addNull($phpDocType); } } $this->type = TypehintHelper::decideTypeFromReflection($this->reflection->getType(), $phpDocType, $this->declaringClassName, $this->isVariadic()); } return $this->type; } public function passedByReference() : PassedByReference { return $this->reflection->isPassedByReference() ? PassedByReference::createCreatesNewVariable() : PassedByReference::createNo(); } public function isVariadic() : bool { return $this->reflection->isVariadic(); } public function getPhpDocType() : Type { if ($this->phpDocType !== null) { return $this->phpDocType; } return new MixedType(); } public function getNativeType() : Type { if ($this->nativeType === null) { $this->nativeType = TypehintHelper::decideTypeFromReflection($this->reflection->getType(), null, $this->declaringClassName, $this->isVariadic()); } return $this->nativeType; } public function getDefaultValue() : ?Type { if ($this->reflection->isDefaultValueAvailable()) { return $this->initializerExprTypeResolver->getType($this->reflection->getDefaultValueExpression(), InitializerExprContext::fromReflectionParameter($this->reflection)); } return null; } public function getOutType() : ?Type { return $this->outType; } public function isImmediatelyInvokedCallable() : TrinaryLogic { return $this->immediatelyInvokedCallable; } public function getClosureThisType() : ?Type { return $this->closureThisType; } } */ private $immediatelyInvokedCallableParameters; /** * @var array */ private $phpDocClosureThisTypeParameters; /** @var PhpParameterReflection[]|null */ private $parameters = null; /** * @var ?Type */ private $returnType = null; /** * @var ?Type */ private $nativeReturnType = null; /** @var FunctionVariantWithPhpDocs[]|null */ private $variants = null; /** * @param Type[] $phpDocParameterTypes * @param Type[] $phpDocParameterOutTypes * @param array $immediatelyInvokedCallableParameters * @param array $phpDocClosureThisTypeParameters */ public function __construct(InitializerExprTypeResolver $initializerExprTypeResolver, ClassReflection $declaringClass, ?ClassReflection $declaringTrait, \PHPStan\Reflection\Php\BuiltinMethodReflection $reflection, ReflectionProvider $reflectionProvider, Parser $parser, FunctionCallStatementFinder $functionCallStatementFinder, Cache $cache, TemplateTypeMap $templateTypeMap, array $phpDocParameterTypes, ?Type $phpDocReturnType, ?Type $phpDocThrowType, ?string $deprecatedDescription, bool $isDeprecated, bool $isInternal, bool $isFinal, ?bool $isPure, Assertions $asserts, bool $acceptsNamedArguments, ?Type $selfOutType, ?string $phpDocComment, array $phpDocParameterOutTypes, array $immediatelyInvokedCallableParameters, array $phpDocClosureThisTypeParameters) { $this->initializerExprTypeResolver = $initializerExprTypeResolver; $this->declaringClass = $declaringClass; $this->declaringTrait = $declaringTrait; $this->reflection = $reflection; $this->reflectionProvider = $reflectionProvider; $this->parser = $parser; $this->functionCallStatementFinder = $functionCallStatementFinder; $this->cache = $cache; $this->templateTypeMap = $templateTypeMap; $this->phpDocParameterTypes = $phpDocParameterTypes; $this->phpDocReturnType = $phpDocReturnType; $this->phpDocThrowType = $phpDocThrowType; $this->deprecatedDescription = $deprecatedDescription; $this->isDeprecated = $isDeprecated; $this->isInternal = $isInternal; $this->isFinal = $isFinal; $this->isPure = $isPure; $this->asserts = $asserts; $this->acceptsNamedArguments = $acceptsNamedArguments; $this->selfOutType = $selfOutType; $this->phpDocComment = $phpDocComment; $this->phpDocParameterOutTypes = $phpDocParameterOutTypes; $this->immediatelyInvokedCallableParameters = $immediatelyInvokedCallableParameters; $this->phpDocClosureThisTypeParameters = $phpDocClosureThisTypeParameters; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function getDeclaringTrait() : ?ClassReflection { return $this->declaringTrait; } /** * @return self|MethodPrototypeReflection */ public function getPrototype() : ClassMemberReflection { try { $prototypeMethod = $this->reflection->getPrototype(); $prototypeDeclaringClass = $this->declaringClass->getAncestorWithClassName($prototypeMethod->getDeclaringClass()->getName()); if ($prototypeDeclaringClass === null) { $prototypeDeclaringClass = $this->reflectionProvider->getClass($prototypeMethod->getDeclaringClass()->getName()); } if (!$prototypeDeclaringClass->hasNativeMethod($prototypeMethod->getName())) { return $this; } $tentativeReturnType = null; if ($prototypeMethod->getTentativeReturnType() !== null) { $tentativeReturnType = TypehintHelper::decideTypeFromReflection($prototypeMethod->getTentativeReturnType()); } return new MethodPrototypeReflection($prototypeMethod->getName(), $prototypeDeclaringClass, $prototypeMethod->isStatic(), $prototypeMethod->isPrivate(), $prototypeMethod->isPublic(), $prototypeMethod->isAbstract(), $prototypeMethod->isFinal(), $prototypeMethod->isInternal(), $prototypeDeclaringClass->getNativeMethod($prototypeMethod->getName())->getVariants(), $tentativeReturnType); } catch (ReflectionException $e) { return $this; } } public function isStatic() : bool { return $this->reflection->isStatic(); } public function getName() : string { $name = $this->reflection->getName(); $lowercaseName = strtolower($name); if ($lowercaseName === $name) { if (PHP_VERSION_ID >= 80000) { return $name; } // fix for https://bugs.php.net/bug.php?id=74939 foreach ($this->getDeclaringClass()->getNativeReflection()->getTraitAliases() as $traitTarget) { $correctName = $this->getMethodNameWithCorrectCase($name, $traitTarget); if ($correctName !== null) { $name = $correctName; break; } } } return $name; } private function getMethodNameWithCorrectCase(string $lowercaseMethodName, string $traitTarget) : ?string { $trait = explode('::', $traitTarget)[0]; $traitReflection = $this->reflectionProvider->getClass($trait)->getNativeReflection(); foreach ($traitReflection->getTraitAliases() as $methodAlias => $aliasTraitTarget) { if ($lowercaseMethodName === strtolower($methodAlias)) { return $methodAlias; } $correctName = $this->getMethodNameWithCorrectCase($lowercaseMethodName, $aliasTraitTarget); if ($correctName !== null) { return $correctName; } } return null; } /** * @return ParametersAcceptorWithPhpDocs[] */ public function getVariants() : array { if ($this->variants === null) { $this->variants = [new FunctionVariantWithPhpDocs($this->templateTypeMap, null, $this->getParameters(), $this->isVariadic(), $this->getReturnType(), $this->getPhpDocReturnType(), $this->getNativeReturnType())]; } return $this->variants; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { return $this->getVariants()[0]; } public function getNamedArgumentsVariants() : ?array { return null; } /** * @return ParameterReflectionWithPhpDocs[] */ private function getParameters() : array { if ($this->parameters === null) { $this->parameters = array_map(function (ReflectionParameter $reflection) : \PHPStan\Reflection\Php\PhpParameterReflection { return new \PHPStan\Reflection\Php\PhpParameterReflection($this->initializerExprTypeResolver, $reflection, $this->phpDocParameterTypes[$reflection->getName()] ?? null, $this->getDeclaringClass()->getName(), $this->phpDocParameterOutTypes[$reflection->getName()] ?? null, $this->immediatelyInvokedCallableParameters[$reflection->getName()] ?? TrinaryLogic::createMaybe(), $this->phpDocClosureThisTypeParameters[$reflection->getName()] ?? null); }, $this->reflection->getParameters()); } return $this->parameters; } private function isVariadic() : bool { $isNativelyVariadic = $this->reflection->isVariadic(); $declaringClass = $this->declaringClass; $filename = $this->declaringClass->getFileName(); if ($this->declaringTrait !== null) { $declaringClass = $this->declaringTrait; $filename = $this->declaringTrait->getFileName(); } if (!$isNativelyVariadic && $filename !== null) { $modifiedTime = @filemtime($filename); if ($modifiedTime === \false) { $modifiedTime = time(); } $key = sprintf('variadic-method-%s-%s-%s', $declaringClass->getName(), $this->reflection->getName(), $filename); $variableCacheKey = sprintf('%d-v4', $modifiedTime); $cachedResult = $this->cache->load($key, $variableCacheKey); if ($cachedResult === null || !is_bool($cachedResult)) { $nodes = $this->parser->parseFile($filename); $result = $this->callsFuncGetArgs($declaringClass, $nodes); $this->cache->save($key, $variableCacheKey, $result); return $result; } return $cachedResult; } return $isNativelyVariadic; } /** * @param Node[] $nodes */ private function callsFuncGetArgs(ClassReflection $declaringClass, array $nodes) : bool { foreach ($nodes as $node) { if ($node instanceof Node\Stmt\ClassLike) { if (!isset($node->namespacedName)) { continue; } if ($declaringClass->getName() !== (string) $node->namespacedName) { continue; } if ($this->callsFuncGetArgs($declaringClass, $node->stmts)) { return \true; } continue; } if ($node instanceof ClassMethod) { if ($node->getStmts() === null) { continue; // interface } $methodName = $node->name->name; if ($methodName === $this->reflection->getName()) { return $this->functionCallStatementFinder->findFunctionCallInStatements(ParametersAcceptor::VARIADIC_FUNCTIONS, $node->getStmts()) !== null; } continue; } if ($node instanceof Function_) { continue; } if ($node instanceof Namespace_) { if ($this->callsFuncGetArgs($declaringClass, $node->stmts)) { return \true; } continue; } if (!$node instanceof Declare_ || $node->stmts === null) { continue; } if ($this->callsFuncGetArgs($declaringClass, $node->stmts)) { return \true; } } return \false; } public function isPrivate() : bool { return $this->reflection->isPrivate(); } public function isPublic() : bool { return $this->reflection->isPublic(); } private function getReturnType() : Type { if ($this->returnType === null) { $name = strtolower($this->getName()); $returnType = $this->reflection->getReturnType(); if ($returnType === null) { if (in_array($name, ['__construct', '__destruct', '__unset', '__wakeup', '__clone'], \true)) { return $this->returnType = TypehintHelper::decideType(new VoidType(), $this->phpDocReturnType); } if ($name === '__tostring') { return $this->returnType = TypehintHelper::decideType(new StringType(), $this->phpDocReturnType); } if ($name === '__isset') { return $this->returnType = TypehintHelper::decideType(new BooleanType(), $this->phpDocReturnType); } if ($name === '__sleep') { return $this->returnType = TypehintHelper::decideType(new ArrayType(new IntegerType(), new StringType()), $this->phpDocReturnType); } if ($name === '__set_state') { return $this->returnType = TypehintHelper::decideType(new ObjectWithoutClassType(), $this->phpDocReturnType); } } $this->returnType = TypehintHelper::decideTypeFromReflection($returnType, $this->phpDocReturnType, $this->declaringClass); } return $this->returnType; } private function getPhpDocReturnType() : Type { if ($this->phpDocReturnType !== null) { return $this->phpDocReturnType; } return new MixedType(); } private function getNativeReturnType() : Type { if ($this->nativeReturnType === null) { $this->nativeReturnType = TypehintHelper::decideTypeFromReflection($this->reflection->getReturnType(), null, $this->declaringClass); } return $this->nativeReturnType; } public function getDeprecatedDescription() : ?string { if ($this->isDeprecated) { return $this->deprecatedDescription; } return null; } public function isDeprecated() : TrinaryLogic { if ($this->isDeprecated) { return TrinaryLogic::createYes(); } return $this->reflection->isDeprecated(); } public function isInternal() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->isInternal || $this->reflection->isInternal()); } public function isFinal() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->isFinal || $this->reflection->isFinal()); } public function isFinalByKeyword() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->reflection->isFinal()); } public function isAbstract() : bool { return $this->reflection->isAbstract(); } public function getThrowType() : ?Type { return $this->phpDocThrowType; } public function hasSideEffects() : TrinaryLogic { if (strtolower($this->getName()) !== '__construct' && $this->getReturnType()->isVoid()->yes()) { return TrinaryLogic::createYes(); } if ($this->isPure !== null) { return TrinaryLogic::createFromBoolean(!$this->isPure); } if ((new ThisType($this->declaringClass))->isSuperTypeOf($this->getReturnType())->yes()) { return TrinaryLogic::createYes(); } return TrinaryLogic::createMaybe(); } public function getAsserts() : Assertions { return $this->asserts; } public function acceptsNamedArguments() : bool { return $this->declaringClass->acceptsNamedArguments() && $this->acceptsNamedArguments; } public function getSelfOutType() : ?Type { return $this->selfOutType; } public function getDocComment() : ?string { return $this->phpDocComment; } public function returnsByReference() : TrinaryLogic { return $this->reflection->returnsByReference(); } public function isPure() : TrinaryLogic { if ($this->isPure === null) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createFromBoolean($this->isPure); } } declaringClass = $declaringClass; $this->readableType = $readableType; $this->writableType = $writableType; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function isStatic() : bool { return \false; } public function isPrivate() : bool { return \false; } public function isPublic() : bool { return \true; } public function getReadableType() : Type { return $this->readableType; } public function getWritableType() : Type { return $this->writableType; } public function canChangeTypeAfterAssignment() : bool { return \true; } public function isReadable() : bool { return \true; } public function isWritable() : bool { return \true; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDeprecatedDescription() : ?string { return null; } public function isInternal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDocComment() : ?string { return null; } } declaringClass = $declaringClass; $this->type = $type; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function isStatic() : bool { return \false; } public function isPrivate() : bool { return \false; } public function isPublic() : bool { return \true; } public function getReadableType() : Type { return $this->type; } public function getWritableType() : Type { return TypeCombinator::union($this->type, new IntegerType(), new FloatType(), new StringType(), new BooleanType()); } public function isReadable() : bool { return \true; } public function isWritable() : bool { return \true; } public function canChangeTypeAfterAssignment() : bool { return \false; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDeprecatedDescription() : ?string { return null; } public function isInternal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDocComment() : ?string { return null; } } declaringClass = $declaringClass; $this->returnType = $returnType; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function isStatic() : bool { return \true; } public function isPrivate() : bool { return \false; } public function isPublic() : bool { return \true; } public function getDocComment() : ?string { return null; } public function getName() : string { return 'cases'; } public function getPrototype() : ClassMemberReflection { $unitEnum = $this->declaringClass->getAncestorWithClassName('UnitEnum'); if ($unitEnum === null) { throw new ShouldNotHappenException(); } return $unitEnum->getNativeMethod('cases'); } public function getVariants() : array { return [new FunctionVariantWithPhpDocs(TemplateTypeMap::createEmpty(), TemplateTypeMap::createEmpty(), [], \false, $this->returnType, new MixedType(), $this->returnType)]; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { return $this->getVariants()[0]; } public function getNamedArgumentsVariants() : ?array { return null; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDeprecatedDescription() : ?string { return null; } public function isFinal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isFinalByKeyword() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isInternal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getThrowType() : ?Type { return null; } public function hasSideEffects() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getAsserts() : Assertions { return Assertions::createEmpty(); } public function acceptsNamedArguments() : bool { return $this->declaringClass->acceptsNamedArguments(); } public function getSelfOutType() : ?Type { return null; } public function returnsByReference() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isAbstract() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isPure() : TrinaryLogic { return TrinaryLogic::createYes(); } } name = $name; } public function getName() : string { return $this->name; } public function getFileName() : ?string { return null; } public function getVariants() : array { $parameterType = new UnionType([new StringType(), new IntegerType()]); return [new FunctionVariantWithPhpDocs(TemplateTypeMap::createEmpty(), TemplateTypeMap::createEmpty(), [new \PHPStan\Reflection\Php\DummyParameterWithPhpDocs('status', $parameterType, \true, PassedByReference::createNo(), \false, new ConstantIntegerType(0), $parameterType, new MixedType(), null, TrinaryLogic::createNo(), null)], \false, new NeverType(\true), new MixedType(), new NeverType(\true), TemplateTypeVarianceMap::createEmpty())]; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { return $this->getVariants()[0]; } /** * @return ParametersAcceptorWithPhpDocs[] */ public function getNamedArgumentsVariants() : array { return $this->getVariants(); } public function acceptsNamedArguments() : bool { return \true; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDeprecatedDescription() : ?string { return null; } public function isFinal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isInternal() : TrinaryLogic { return TrinaryLogic::createYes(); } public function getThrowType() : ?Type { return null; } public function hasSideEffects() : TrinaryLogic { return TrinaryLogic::createYes(); } public function isBuiltin() : bool { return \true; } public function getAsserts() : Assertions { return Assertions::createEmpty(); } public function getDocComment() : ?string { return null; } public function returnsByReference() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isPure() : TrinaryLogic { return TrinaryLogic::createNo(); } } name = $name; $this->optional = $optional; $this->realType = $realType; $this->phpDocType = $phpDocType; $this->passedByReference = $passedByReference; $this->defaultValue = $defaultValue; $this->variadic = $variadic; $this->outType = $outType; $this->immediatelyInvokedCallable = $immediatelyInvokedCallable; $this->closureThisType = $closureThisType; } public function getName() : string { return $this->name; } public function isOptional() : bool { return $this->optional; } public function getType() : Type { if ($this->type === null) { $phpDocType = $this->phpDocType; if ($phpDocType !== null && $this->defaultValue !== null) { if ($this->defaultValue->isNull()->yes()) { $inferred = $phpDocType->inferTemplateTypes($this->defaultValue); if ($inferred->isEmpty()) { $phpDocType = TypeCombinator::addNull($phpDocType); } } } $this->type = TypehintHelper::decideType($this->realType, $phpDocType); } return $this->type; } public function getPhpDocType() : Type { return $this->phpDocType ?? new MixedType(); } public function getNativeType() : Type { return $this->realType; } public function passedByReference() : PassedByReference { return $this->passedByReference; } public function isVariadic() : bool { return $this->variadic; } public function getDefaultValue() : ?Type { return $this->defaultValue; } public function getOutType() : ?Type { return $this->outType; } public function isImmediatelyInvokedCallable() : TrinaryLogic { return $this->immediatelyInvokedCallable; } public function getClosureThisType() : ?Type { return $this->closureThisType; } } name = $name; $this->type = $type; $this->optional = $optional; $this->variadic = $variadic; $this->defaultValue = $defaultValue; $this->passedByReference = $passedByReference ?? PassedByReference::createNo(); } public function getName() : string { return $this->name; } public function isOptional() : bool { return $this->optional; } public function getType() : Type { return $this->type; } public function passedByReference() : PassedByReference { return $this->passedByReference; } public function isVariadic() : bool { return $this->variadic; } public function getDefaultValue() : ?Type { return $this->defaultValue; } } property = $property; } public function doNotResolveTemplateTypeMapToBounds() : UnresolvedPropertyPrototypeReflection { return $this; } public function getNakedProperty() : ExtendedPropertyReflection { return $this->property; } public function getTransformedProperty() : ExtendedPropertyReflection { return $this->property; } public function withFechedOnType(Type $type) : UnresolvedPropertyPrototypeReflection { return $this; } } nativeType = $nativeType; $this->phpDocType = $phpDocType; $this->outType = $outType; $this->immediatelyInvokedCallable = $immediatelyInvokedCallable; $this->closureThisType = $closureThisType; parent::__construct($name, $type, $optional, $passedByReference, $variadic, $defaultValue); } public function getPhpDocType() : Type { return $this->phpDocType; } public function getNativeType() : Type { return $this->nativeType; } public function getOutType() : ?Type { return $this->outType; } public function isImmediatelyInvokedCallable() : TrinaryLogic { return $this->immediatelyInvokedCallable; } public function getClosureThisType() : ?Type { return $this->closureThisType; } } reflectionProvider = $reflectionProvider; $this->classes = $classes; $this->annotationClassReflection = $annotationClassReflection; } public function hasProperty(ClassReflection $classReflection, string $propertyName) : bool { return self::isUniversalObjectCrate($this->reflectionProvider, $this->classes, $classReflection); } /** * @param string[] $classes */ public static function isUniversalObjectCrate(ReflectionProvider $reflectionProvider, array $classes, ClassReflection $classReflection) : bool { foreach ($classes as $className) { if (!$reflectionProvider->hasClass($className)) { continue; } if ($classReflection->getName() === $className || $classReflection->isSubclassOf($className)) { return \true; } } return \false; } public function getProperty(ClassReflection $classReflection, string $propertyName) : PropertyReflection { if ($this->annotationClassReflection->hasProperty($classReflection, $propertyName)) { return $this->annotationClassReflection->getProperty($classReflection, $propertyName); } if ($classReflection->hasNativeMethod('__get')) { $readableType = $classReflection->getNativeMethod('__get')->getOnlyVariant()->getReturnType(); } else { $readableType = new MixedType(); } if ($classReflection->hasNativeMethod('__set')) { $writableType = $classReflection->getNativeMethod('__set')->getOnlyVariant()->getParameters()[1]->getType(); } else { $writableType = new MixedType(); } return new \PHPStan\Reflection\Php\UniversalObjectCrateProperty($classReflection, $readableType, $writableType); } } */ private $phpDocParameterTypes; /** * @var ?Type */ private $phpDocReturnType; /** * @var ?Type */ private $phpDocThrowType; /** * @var ?string */ private $deprecatedDescription; /** * @var bool */ private $isDeprecated; /** * @var bool */ private $isInternal; /** * @var bool */ private $isFinal; /** * @var ?string */ private $filename; /** * @var ?bool */ private $isPure; /** * @var Assertions */ private $asserts; /** * @var bool */ private $acceptsNamedArguments; /** * @var ?string */ private $phpDocComment; /** * @var array */ private $phpDocParameterOutTypes; /** * @var array */ private $phpDocParameterImmediatelyInvokedCallable; /** * @var array */ private $phpDocParameterClosureThisTypes; /** @var FunctionVariantWithPhpDocs[]|null */ private $variants = null; /** * @param array $phpDocParameterTypes * @param array $phpDocParameterOutTypes * @param array $phpDocParameterImmediatelyInvokedCallable * @param array $phpDocParameterClosureThisTypes */ public function __construct(InitializerExprTypeResolver $initializerExprTypeResolver, ReflectionFunction $reflection, Parser $parser, FunctionCallStatementFinder $functionCallStatementFinder, Cache $cache, TemplateTypeMap $templateTypeMap, array $phpDocParameterTypes, ?Type $phpDocReturnType, ?Type $phpDocThrowType, ?string $deprecatedDescription, bool $isDeprecated, bool $isInternal, bool $isFinal, ?string $filename, ?bool $isPure, Assertions $asserts, bool $acceptsNamedArguments, ?string $phpDocComment, array $phpDocParameterOutTypes, array $phpDocParameterImmediatelyInvokedCallable, array $phpDocParameterClosureThisTypes) { $this->initializerExprTypeResolver = $initializerExprTypeResolver; $this->reflection = $reflection; $this->parser = $parser; $this->functionCallStatementFinder = $functionCallStatementFinder; $this->cache = $cache; $this->templateTypeMap = $templateTypeMap; $this->phpDocParameterTypes = $phpDocParameterTypes; $this->phpDocReturnType = $phpDocReturnType; $this->phpDocThrowType = $phpDocThrowType; $this->deprecatedDescription = $deprecatedDescription; $this->isDeprecated = $isDeprecated; $this->isInternal = $isInternal; $this->isFinal = $isFinal; $this->filename = $filename; $this->isPure = $isPure; $this->asserts = $asserts; $this->acceptsNamedArguments = $acceptsNamedArguments; $this->phpDocComment = $phpDocComment; $this->phpDocParameterOutTypes = $phpDocParameterOutTypes; $this->phpDocParameterImmediatelyInvokedCallable = $phpDocParameterImmediatelyInvokedCallable; $this->phpDocParameterClosureThisTypes = $phpDocParameterClosureThisTypes; } public function getName() : string { return $this->reflection->getName(); } public function getFileName() : ?string { if ($this->filename === null) { return null; } if (!is_file($this->filename)) { return null; } return $this->filename; } /** * @return ParametersAcceptorWithPhpDocs[] */ public function getVariants() : array { if ($this->variants === null) { $this->variants = [new FunctionVariantWithPhpDocs($this->templateTypeMap, null, $this->getParameters(), $this->isVariadic(), $this->getReturnType(), $this->getPhpDocReturnType(), $this->getNativeReturnType())]; } return $this->variants; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { return $this->getVariants()[0]; } public function getNamedArgumentsVariants() : ?array { return null; } /** * @return ParameterReflectionWithPhpDocs[] */ private function getParameters() : array { return array_map(function (ReflectionParameter $reflection) : \PHPStan\Reflection\Php\PhpParameterReflection { if (array_key_exists($reflection->getName(), $this->phpDocParameterImmediatelyInvokedCallable)) { $immediatelyInvokedCallable = TrinaryLogic::createFromBoolean($this->phpDocParameterImmediatelyInvokedCallable[$reflection->getName()]); } else { $immediatelyInvokedCallable = TrinaryLogic::createMaybe(); } return new \PHPStan\Reflection\Php\PhpParameterReflection($this->initializerExprTypeResolver, $reflection, $this->phpDocParameterTypes[$reflection->getName()] ?? null, null, $this->phpDocParameterOutTypes[$reflection->getName()] ?? null, $immediatelyInvokedCallable, $this->phpDocParameterClosureThisTypes[$reflection->getName()] ?? null); }, $this->reflection->getParameters()); } private function isVariadic() : bool { $isNativelyVariadic = $this->reflection->isVariadic(); if (!$isNativelyVariadic && $this->reflection->getFileName() !== \false) { $fileName = $this->reflection->getFileName(); if (is_file($fileName)) { $functionName = $this->reflection->getName(); $modifiedTime = filemtime($fileName); if ($modifiedTime === \false) { $modifiedTime = time(); } $variableCacheKey = sprintf('%d-v4', $modifiedTime); $key = sprintf('variadic-function-%s-%s', $functionName, $fileName); $cachedResult = $this->cache->load($key, $variableCacheKey); if ($cachedResult === null) { $nodes = $this->parser->parseFile($fileName); $result = !$this->containsVariadicFunction($nodes)->no(); $this->cache->save($key, $variableCacheKey, $result); return $result; } return $cachedResult; } } return $isNativelyVariadic; } /** * @param Node[]|scalar[]|Node $node */ private function containsVariadicFunction($node) : TrinaryLogic { $result = TrinaryLogic::createMaybe(); if ($node instanceof Node) { if ($node instanceof Function_) { $functionName = (string) $node->namespacedName; if ($functionName === $this->reflection->getName()) { return TrinaryLogic::createFromBoolean($this->isFunctionNodeVariadic($node)); } } foreach ($node->getSubNodeNames() as $subNodeName) { $innerNode = $node->{$subNodeName}; if (!$innerNode instanceof Node && !is_array($innerNode)) { continue; } $result = $result->and($this->containsVariadicFunction($innerNode)); } } elseif (is_array($node)) { foreach ($node as $subNode) { if (!$subNode instanceof Node) { continue; } $result = $result->and($this->containsVariadicFunction($subNode)); } } return $result; } private function getReturnType() : Type { return TypehintHelper::decideTypeFromReflection($this->reflection->getReturnType(), $this->phpDocReturnType); } private function getPhpDocReturnType() : Type { if ($this->phpDocReturnType !== null) { return $this->phpDocReturnType; } return new MixedType(); } private function getNativeReturnType() : Type { return TypehintHelper::decideTypeFromReflection($this->reflection->getReturnType()); } public function getDeprecatedDescription() : ?string { if ($this->isDeprecated) { return $this->deprecatedDescription; } return null; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->isDeprecated || $this->reflection->isDeprecated()); } public function isInternal() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->isInternal); } public function isFinal() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->isFinal); } public function getThrowType() : ?Type { return $this->phpDocThrowType; } public function hasSideEffects() : TrinaryLogic { if ($this->getReturnType()->isVoid()->yes()) { return TrinaryLogic::createYes(); } if ($this->isPure !== null) { return TrinaryLogic::createFromBoolean(!$this->isPure); } return TrinaryLogic::createMaybe(); } public function isPure() : TrinaryLogic { if ($this->isPure === null) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createFromBoolean($this->isPure); } public function isBuiltin() : bool { return $this->reflection->isInternal(); } public function getAsserts() : Assertions { return $this->asserts; } public function getDocComment() : ?string { return $this->phpDocComment; } public function returnsByReference() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->reflection->returnsReference()); } public function acceptsNamedArguments() : bool { return $this->acceptsNamedArguments; } private function isFunctionNodeVariadic(Function_ $node) : bool { foreach ($node->params as $parameter) { if ($parameter->variadic) { return \true; } } if ($this->functionCallStatementFinder->findFunctionCallInStatements(ParametersAcceptor::VARIADIC_FUNCTIONS, $node->getStmts()) !== null) { return \true; } return \false; } } declaringClass = $declaringClass; $this->declaringTrait = $declaringTrait; $this->nativeType = $nativeType; $this->phpDocType = $phpDocType; $this->reflection = $reflection; $this->deprecatedDescription = $deprecatedDescription; $this->isDeprecated = $isDeprecated; $this->isInternal = $isInternal; $this->isReadOnlyByPhpDoc = $isReadOnlyByPhpDoc; $this->isAllowedPrivateMutation = $isAllowedPrivateMutation; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function getDeclaringTrait() : ?ClassReflection { return $this->declaringTrait; } public function getDocComment() : ?string { $docComment = $this->reflection->getDocComment(); if ($docComment === \false) { return null; } return $docComment; } public function isStatic() : bool { return $this->reflection->isStatic(); } public function isPrivate() : bool { return $this->reflection->isPrivate(); } public function isPublic() : bool { return $this->reflection->isPublic(); } public function isReadOnly() : bool { return $this->reflection->isReadOnly(); } public function isReadOnlyByPhpDoc() : bool { return $this->isReadOnlyByPhpDoc; } public function getReadableType() : Type { if ($this->type === null) { $this->type = TypehintHelper::decideTypeFromReflection($this->nativeType, $this->phpDocType, $this->declaringClass); } return $this->type; } public function getWritableType() : Type { return $this->getReadableType(); } public function canChangeTypeAfterAssignment() : bool { return \true; } public function isPromoted() : bool { return $this->reflection->isPromoted(); } public function hasPhpDocType() : bool { return $this->phpDocType !== null; } public function getPhpDocType() : Type { if ($this->phpDocType !== null) { return $this->phpDocType; } return new MixedType(); } public function hasNativeType() : bool { return $this->nativeType !== null; } public function getNativeType() : Type { if ($this->finalNativeType === null) { $this->finalNativeType = TypehintHelper::decideTypeFromReflection($this->nativeType, null, $this->declaringClass); } return $this->finalNativeType; } public function isReadable() : bool { return \true; } public function isWritable() : bool { return \true; } public function getDeprecatedDescription() : ?string { if ($this->isDeprecated) { return $this->deprecatedDescription; } return null; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->isDeprecated); } public function isInternal() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->isInternal); } public function isAllowedPrivateMutation() : bool { return $this->isAllowedPrivateMutation; } public function getNativeReflection() : ReflectionProperty { return $this->reflection; } } reflection = $reflection; } public function getName() : string { return $this->reflection->getName(); } public function getReflection() : ReflectionMethod { return $this->reflection; } public function getFileName() : ?string { $fileName = $this->reflection->getFileName(); if ($fileName === \false) { return null; } return $fileName; } public function getDeclaringClass() : ReflectionClass { return $this->reflection->getDeclaringClass(); } public function getStartLine() : ?int { $line = $this->reflection->getStartLine(); if ($line === \false) { return null; } return $line; } public function getEndLine() : ?int { $line = $this->reflection->getEndLine(); if ($line === \false) { return null; } return $line; } public function getDocComment() : ?string { $docComment = $this->reflection->getDocComment(); if ($docComment === \false) { return null; } return $docComment; } public function isStatic() : bool { return $this->reflection->isStatic(); } public function isPrivate() : bool { return $this->reflection->isPrivate(); } public function isPublic() : bool { return $this->reflection->isPublic(); } public function isConstructor() : bool { return $this->reflection->isConstructor(); } public function getPrototype() : \PHPStan\Reflection\Php\BuiltinMethodReflection { return new self($this->reflection->getPrototype()); } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->reflection->isDeprecated()); } public function isFinal() : bool { return $this->reflection->isFinal(); } public function isInternal() : bool { return $this->reflection->isInternal(); } public function isAbstract() : bool { return $this->reflection->isAbstract(); } public function isVariadic() : bool { return $this->reflection->isVariadic(); } /** * @return ReflectionIntersectionType|ReflectionNamedType|ReflectionUnionType|null */ public function getReturnType() { return $this->reflection->getReturnType(); } /** * @return ReflectionIntersectionType|ReflectionNamedType|ReflectionUnionType|null */ public function getTentativeReturnType() { return $this->reflection->getTentativeReturnType(); } /** * @return ReflectionParameter[] */ public function getParameters() : array { return $this->reflection->getParameters(); } public function returnsByReference() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->reflection->returnsReference()); } } isEnum(); } public function getAllowedSubTypes(ClassReflection $classReflection) : array { $cases = []; foreach (array_keys($classReflection->getEnumCases()) as $name) { $cases[] = new EnumCaseObjectType($classReflection->getName(), $name); } return $cases; } } prototype = $prototype; $this->closure = $closure; } public function doNotResolveTemplateTypeMapToBounds() : UnresolvedMethodPrototypeReflection { return new self($this->prototype->doNotResolveTemplateTypeMapToBounds(), $this->closure); } public function getNakedMethod() : ExtendedMethodReflection { return $this->getTransformedMethod(); } public function getTransformedMethod() : ExtendedMethodReflection { return new \PHPStan\Reflection\Php\ClosureCallMethodReflection($this->prototype->getTransformedMethod(), $this->closure); } public function withCalledOnType(Type $type) : UnresolvedMethodPrototypeReflection { return new self($this->prototype->withCalledOnType($type), $this->closure); } } declaringClass = $declaringClass; $this->type = $type; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function isStatic() : bool { return \false; } public function isPrivate() : bool { return \false; } public function isPublic() : bool { return \true; } public function getDocComment() : ?string { return null; } public function getReadableType() : Type { return $this->type; } public function getWritableType() : Type { return $this->type; } public function canChangeTypeAfterAssignment() : bool { return \true; } public function isReadable() : bool { return \true; } public function isWritable() : bool { return \false; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createNo(); } public function getDeprecatedDescription() : ?string { return null; } public function isInternal() : TrinaryLogic { return TrinaryLogic::createNo(); } } file = $file; $this->namespace = $namespace; $this->className = $className; $this->traitName = $traitName; $this->function = $function; $this->method = $method; } public static function fromScope(Scope $scope) : self { return new self($scope->getFile(), $scope->getNamespace(), $scope->isInClass() ? $scope->getClassReflection()->getName() : null, $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $scope->isInAnonymousFunction() ? '{closure}' : ($scope->getFunction() !== null ? $scope->getFunction()->getName() : null), $scope->isInAnonymousFunction() ? '{closure}' : ($scope->getFunction() instanceof \PHPStan\Reflection\MethodReflection ? sprintf('%s::%s', $scope->getFunction()->getDeclaringClass()->getName(), $scope->getFunction()->getName()) : ($scope->getFunction() instanceof \PHPStan\Reflection\FunctionReflection ? $scope->getFunction()->getName() : null))); } /** * @return non-empty-string|null */ private static function parseNamespace(string $name) : ?string { $parts = explode('\\', $name); if (count($parts) > 1) { $ns = implode('\\', array_slice($parts, 0, -1)); if ($ns === '') { throw new ShouldNotHappenException('Namespace cannot be empty.'); } return $ns; } return null; } public static function fromClassReflection(\PHPStan\Reflection\ClassReflection $classReflection) : self { return self::fromClass($classReflection->getName(), $classReflection->getFileName()); } public static function fromClass(string $className, ?string $fileName) : self { return new self($fileName, self::parseNamespace($className), $className, null, null, null); } public static function fromReflectionParameter(ReflectionParameter $parameter) : self { $declaringFunction = $parameter->getDeclaringFunction(); if ($declaringFunction instanceof ReflectionFunction) { $file = $declaringFunction->getFileName(); return new self($file === \false ? null : $file, self::parseNamespace($declaringFunction->getName()), null, null, $declaringFunction->getName(), $declaringFunction->getName()); } $file = $declaringFunction->getFileName(); $betterReflection = $declaringFunction->getBetterReflection(); return new self($file === \false ? null : $file, self::parseNamespace($betterReflection->getDeclaringClass()->getName()), $declaringFunction->getDeclaringClass()->getName(), $betterReflection->getDeclaringClass()->isTrait() ? $betterReflection->getDeclaringClass()->getName() : null, $declaringFunction->getName(), sprintf('%s::%s', $declaringFunction->getDeclaringClass()->getName(), $declaringFunction->getName())); } /** * @param ClassMethod|Function_ $function */ public static function fromStubParameter(?string $className, string $stubFile, $function) : self { $namespace = null; if ($className !== null) { $namespace = self::parseNamespace($className); } else { if ($function instanceof Function_ && $function->namespacedName !== null) { $namespace = self::parseNamespace($function->namespacedName->toString()); } } return new self($stubFile, $namespace, $className, null, $function instanceof Function_ && $function->namespacedName !== null ? $function->namespacedName->toString() : ($function instanceof ClassMethod ? $function->name->toString() : null), $function instanceof ClassMethod && $className !== null ? sprintf('%s::%s', $className, $function->name->toString()) : ($function instanceof Function_ && $function->namespacedName !== null ? $function->namespacedName->toString() : null)); } public static function fromGlobalConstant(ReflectionConstant $constant) : self { return new self($constant->getFileName(), $constant->getNamespaceName(), null, null, null, null); } public static function createEmpty() : self { return new self(null, null, null, null, null, null); } public function getFile() : ?string { return $this->file; } public function getClassName() : ?string { return $this->className; } public function getNamespace() : ?string { return $this->namespace; } public function getTraitName() : ?string { return $this->traitName; } public function getFunction() : ?string { return $this->function; } public function getMethod() : ?string { return $this->method; } } $phpDocParameterTypes * @param array $phpDocParameterOutTypes * @param array $phpDocParameterImmediatelyInvokedCallable * @param array $phpDocParameterClosureThisTypes */ public function create(ReflectionFunction $reflection, TemplateTypeMap $templateTypeMap, array $phpDocParameterTypes, ?Type $phpDocReturnType, ?Type $phpDocThrowType, ?string $deprecatedDescription, bool $isDeprecated, bool $isInternal, bool $isFinal, ?string $filename, ?bool $isPure, \PHPStan\Reflection\Assertions $asserts, bool $acceptsNamedArguments, ?string $phpDocComment, array $phpDocParameterOutTypes, array $phpDocParameterImmediatelyInvokedCallable, array $phpDocParameterClosureThisTypes) : PhpFunctionReflection; } name = $name; $this->declaringClass = $declaringClass; $this->isStatic = $isStatic; $this->isPrivate = $isPrivate; $this->isPublic = $isPublic; $this->isAbstract = $isAbstract; $this->isFinal = $isFinal; $this->isInternal = $isInternal; $this->variants = $variants; $this->tentativeReturnType = $tentativeReturnType; } public function getName() : string { return $this->name; } public function getDeclaringClass() : \PHPStan\Reflection\ClassReflection { return $this->declaringClass; } public function isStatic() : bool { return $this->isStatic; } public function isPrivate() : bool { return $this->isPrivate; } public function isPublic() : bool { return $this->isPublic; } public function isAbstract() : bool { return $this->isAbstract; } public function isFinal() : bool { return $this->isFinal; } public function isInternal() : bool { return $this->isInternal; } public function getDocComment() : ?string { return null; } /** * @return ParametersAcceptor[] */ public function getVariants() : array { return $this->variants; } public function getTentativeReturnType() : ?Type { return $this->tentativeReturnType; } } staticReflectionProvider = $staticReflectionProvider; } public function create() : ReflectionProvider { return new \PHPStan\Reflection\ReflectionProvider\MemoizingReflectionProvider($this->staticReflectionProvider); } } reflectionProvider = $reflectionProvider; } public function getReflectionProvider() : ReflectionProvider { return $this->reflectionProvider; } } */ private $hasClasses = []; /** @var array */ private $classes = []; /** @var array */ private $classNames = []; public function __construct(ReflectionProvider $provider) { $this->provider = $provider; } public function hasClass(string $className) : bool { if (isset($this->hasClasses[$className])) { return $this->hasClasses[$className]; } return $this->hasClasses[$className] = $this->provider->hasClass($className); } public function getClass(string $className) : ClassReflection { $lowerClassName = strtolower($className); if (isset($this->classes[$lowerClassName])) { return $this->classes[$lowerClassName]; } return $this->classes[$lowerClassName] = $this->provider->getClass($className); } public function getClassName(string $className) : string { $lowerClassName = strtolower($className); if (isset($this->classNames[$lowerClassName])) { return $this->classNames[$lowerClassName]; } return $this->classNames[$lowerClassName] = $this->provider->getClassName($className); } public function supportsAnonymousClasses() : bool { return $this->provider->supportsAnonymousClasses(); } public function getAnonymousClassReflection(Node\Stmt\Class_ $classNode, Scope $scope) : ClassReflection { return $this->provider->getAnonymousClassReflection($classNode, $scope); } public function hasFunction(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : bool { return $this->provider->hasFunction($nameNode, $namespaceAnswerer); } public function getFunction(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : FunctionReflection { return $this->provider->getFunction($nameNode, $namespaceAnswerer); } public function resolveFunctionName(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : ?string { return $this->provider->resolveFunctionName($nameNode, $namespaceAnswerer); } public function hasConstant(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : bool { return $this->provider->hasConstant($nameNode, $namespaceAnswerer); } public function getConstant(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : GlobalConstantReflection { return $this->provider->getConstant($nameNode, $namespaceAnswerer); } public function resolveConstantName(Node\Name $nameNode, ?NamespaceAnswerer $namespaceAnswerer) : ?string { return $this->provider->resolveConstantName($nameNode, $namespaceAnswerer); } } container = $container; } public function getReflectionProvider() : ReflectionProvider { return $this->container->getByType(ReflectionProvider::class); } } reflectionProvider = $reflectionProvider; } public function getReflectionProvider() : ReflectionProvider { return $this->reflectionProvider; } } name = $name; $this->optional = $optional; $this->type = $type; $this->phpDocType = $phpDocType; $this->nativeType = $nativeType; $this->passedByReference = $passedByReference; $this->variadic = $variadic; $this->defaultValue = $defaultValue; $this->outType = $outType; $this->immediatelyInvokedCallable = $immediatelyInvokedCallable; $this->closureThisType = $closureThisType; } public function getName() : string { return $this->name; } public function isOptional() : bool { return $this->optional; } public function getType() : Type { return $this->type; } public function getPhpDocType() : Type { return $this->phpDocType; } public function getNativeType() : Type { return $this->nativeType; } public function passedByReference() : PassedByReference { return $this->passedByReference; } public function isVariadic() : bool { return $this->variadic; } public function getDefaultValue() : ?Type { return $this->defaultValue; } public function getOutType() : ?Type { return $this->outType; } public function isImmediatelyInvokedCallable() : TrinaryLogic { return $this->immediatelyInvokedCallable; } public function getClosureThisType() : ?Type { return $this->closureThisType; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self { return new self($properties['name'], $properties['optional'], $properties['type'], $properties['phpDocType'], $properties['nativeType'], $properties['passedByReference'], $properties['variadic'], $properties['defaultValue'], $properties['outType'], $properties['immediatelyInvokedCallable'], $properties['closureThisType']); } } name = $name; $this->variants = $variants; $this->namedArgumentsVariants = $namedArgumentsVariants; $this->throwType = $throwType; $this->hasSideEffects = $hasSideEffects; $this->isDeprecated = $isDeprecated; $this->phpDocComment = $phpDocComment; $this->acceptsNamedArguments = $acceptsNamedArguments; $this->assertions = $assertions ?? Assertions::createEmpty(); $this->returnsByReference = $returnsByReference ?? TrinaryLogic::createMaybe(); } public function getName() : string { return $this->name; } public function getFileName() : ?string { return null; } public function getVariants() : array { return $this->variants; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { $variants = $this->getVariants(); if (count($variants) !== 1) { throw new ShouldNotHappenException(); } return $variants[0]; } public function getNamedArgumentsVariants() : ?array { return $this->namedArgumentsVariants; } public function getThrowType() : ?Type { return $this->throwType; } public function getDeprecatedDescription() : ?string { return null; } public function isDeprecated() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->isDeprecated); } public function isInternal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function isFinal() : TrinaryLogic { return TrinaryLogic::createNo(); } public function hasSideEffects() : TrinaryLogic { if ($this->isVoid()) { return TrinaryLogic::createYes(); } return $this->hasSideEffects; } public function isPure() : TrinaryLogic { if ($this->hasSideEffects()->yes()) { return TrinaryLogic::createNo(); } return $this->hasSideEffects->negate(); } private function isVoid() : bool { foreach ($this->variants as $variant) { if (!$variant->getReturnType()->isVoid()->yes()) { return \false; } } return \true; } public function isBuiltin() : bool { return \true; } public function getAsserts() : Assertions { return $this->assertions; } public function getDocComment() : ?string { return $this->phpDocComment; } public function returnsByReference() : TrinaryLogic { return $this->returnsByReference; } public function acceptsNamedArguments() : bool { return $this->acceptsNamedArguments; } } name = $name; $this->optional = $optional; $this->type = $type; $this->passedByReference = $passedByReference; $this->variadic = $variadic; $this->defaultValue = $defaultValue; } public function getName() : string { return $this->name; } public function isOptional() : bool { return $this->optional; } public function getType() : Type { return $this->type; } public function passedByReference() : PassedByReference { return $this->passedByReference; } public function isVariadic() : bool { return $this->variadic; } public function getDefaultValue() : ?Type { return $this->defaultValue; } public function union(self $other) : self { return new self($this->name, $this->optional && $other->optional, TypeCombinator::union($this->type, $other->type), $this->passedByReference->combine($other->passedByReference), $this->variadic && $other->variadic, $this->optional && $other->optional ? $this->defaultValue : null); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self { return new self($properties['name'], $properties['optional'], $properties['type'], $properties['passedByReference'], $properties['variadic'], $properties['defaultValue']); } } reflectionProvider = $reflectionProvider; $this->declaringClass = $declaringClass; $this->reflection = $reflection; $this->variants = $variants; $this->namedArgumentsVariants = $namedArgumentsVariants; $this->hasSideEffects = $hasSideEffects; $this->throwType = $throwType; $this->assertions = $assertions; $this->acceptsNamedArguments = $acceptsNamedArguments; $this->selfOutType = $selfOutType; $this->phpDocComment = $phpDocComment; } public function getDeclaringClass() : ClassReflection { return $this->declaringClass; } public function isStatic() : bool { return $this->reflection->isStatic(); } public function isPrivate() : bool { return $this->reflection->isPrivate(); } public function isPublic() : bool { return $this->reflection->isPublic(); } public function isAbstract() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->reflection->isAbstract()); } public function getPrototype() : ClassMemberReflection { try { $prototypeMethod = $this->reflection->getPrototype(); $prototypeDeclaringClass = $this->declaringClass->getAncestorWithClassName($prototypeMethod->getDeclaringClass()->getName()); if ($prototypeDeclaringClass === null) { $prototypeDeclaringClass = $this->reflectionProvider->getClass($prototypeMethod->getDeclaringClass()->getName()); } if (!$prototypeDeclaringClass->hasNativeMethod($prototypeMethod->getName())) { return $this; } $tentativeReturnType = null; if ($prototypeMethod->getTentativeReturnType() !== null) { $tentativeReturnType = TypehintHelper::decideTypeFromReflection($prototypeMethod->getTentativeReturnType()); } return new MethodPrototypeReflection($prototypeMethod->getName(), $prototypeDeclaringClass, $prototypeMethod->isStatic(), $prototypeMethod->isPrivate(), $prototypeMethod->isPublic(), $prototypeMethod->isAbstract(), $prototypeMethod->isFinal(), $prototypeMethod->isInternal(), $prototypeDeclaringClass->getNativeMethod($prototypeMethod->getName())->getVariants(), $tentativeReturnType); } catch (ReflectionException $e) { return $this; } } public function getName() : string { return $this->reflection->getName(); } public function getVariants() : array { return $this->variants; } public function getOnlyVariant() : ParametersAcceptorWithPhpDocs { $variants = $this->getVariants(); if (count($variants) !== 1) { throw new ShouldNotHappenException(); } return $variants[0]; } public function getNamedArgumentsVariants() : ?array { return $this->namedArgumentsVariants; } public function getDeprecatedDescription() : ?string { return null; } public function isDeprecated() : TrinaryLogic { return $this->reflection->isDeprecated(); } public function isInternal() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->reflection->isInternal()); } public function isFinal() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->reflection->isFinal()); } public function isFinalByKeyword() : TrinaryLogic { return $this->isFinal(); } public function getThrowType() : ?Type { return $this->throwType; } public function hasSideEffects() : TrinaryLogic { $name = strtolower($this->getName()); $isVoid = $this->isVoid(); if ($name !== '__construct' && $isVoid) { return TrinaryLogic::createYes(); } return $this->hasSideEffects; } public function isPure() : TrinaryLogic { if ($this->hasSideEffects()->yes()) { return TrinaryLogic::createNo(); } return $this->hasSideEffects->negate(); } private function isVoid() : bool { foreach ($this->variants as $variant) { if (!$variant->getReturnType()->isVoid()->yes()) { return \false; } } return \true; } public function getDocComment() : ?string { return $this->phpDocComment; } public function getAsserts() : Assertions { return $this->assertions; } public function acceptsNamedArguments() : bool { return $this->declaringClass->acceptsNamedArguments() && $this->acceptsNamedArguments; } public function getSelfOutType() : ?Type { return $this->selfOutType; } public function returnsByReference() : TrinaryLogic { return $this->reflection->returnsByReference(); } } identifier = $identifier; $this->description = $description; $this->certain = $certain; } /** * @param FunctionReflection|ExtendedMethodReflection $function */ public static function createFromVariant($function, ?ParametersAcceptor $variant) : ?self { if (!$function->hasSideEffects()->no()) { $certain = $function->isPure()->no(); if ($variant !== null) { $certain = $certain || $variant->getReturnType()->isVoid()->yes(); } if ($function instanceof FunctionReflection) { return new \PHPStan\Reflection\Callables\SimpleImpurePoint('functionCall', sprintf('call to function %s()', $function->getName()), $certain); } return new \PHPStan\Reflection\Callables\SimpleImpurePoint('methodCall', sprintf('call to method %s::%s()', $function->getDeclaringClass()->getDisplayName(), $function->getName()), $certain); } return null; } /** * @return ImpurePointIdentifier */ public function getIdentifier() : string { return $this->identifier; } public function getDescription() : string { return $this->description; } public function isCertain() : bool { return $this->certain; } } type = $type; $this->explicit = $explicit; $this->canContainAnyThrowable = $canContainAnyThrowable; } public static function createExplicit(Type $type, bool $canContainAnyThrowable) : self { return new self($type, \true, $canContainAnyThrowable); } public static function createImplicit() : self { return new self(new ObjectType(Throwable::class), \false, \true); } public function getType() : Type { return $this->type; } public function isExplicit() : bool { return $this->explicit; } public function canContainAnyThrowable() : bool { return $this->canContainAnyThrowable; } } function = $function; $this->variant = $variant; } /** * @param ParametersAcceptorWithPhpDocs[] $variants * @return self[] * @param FunctionReflection|ExtendedMethodReflection $function */ public static function createFromVariants($function, array $variants) : array { return array_map(static function (ParametersAcceptorWithPhpDocs $variant) use($function) { return new self($function, $variant); }, $variants); } public function getTemplateTypeMap() : TemplateTypeMap { return $this->variant->getTemplateTypeMap(); } public function getResolvedTemplateTypeMap() : TemplateTypeMap { return $this->variant->getResolvedTemplateTypeMap(); } /** * @return array */ public function getParameters() : array { return $this->variant->getParameters(); } public function isVariadic() : bool { return $this->variant->isVariadic(); } public function getReturnType() : Type { return $this->variant->getReturnType(); } public function getPhpDocReturnType() : Type { return $this->variant->getPhpDocReturnType(); } public function getNativeReturnType() : Type { return $this->variant->getNativeReturnType(); } public function getCallSiteVarianceMap() : TemplateTypeVarianceMap { return $this->variant->getCallSiteVarianceMap(); } public function getThrowPoints() : array { if ($this->throwPoints !== null) { return $this->throwPoints; } if ($this->variant instanceof \PHPStan\Reflection\Callables\CallableParametersAcceptor) { return $this->throwPoints = $this->variant->getThrowPoints(); } $returnType = $this->variant->getReturnType(); $throwType = $this->function->getThrowType(); if ($throwType === null) { if ($returnType instanceof NeverType && $returnType->isExplicit()) { $throwType = new ObjectType(Throwable::class); } } $throwPoints = []; if ($throwType !== null) { if (!$throwType->isVoid()->yes()) { $throwPoints[] = \PHPStan\Reflection\Callables\SimpleThrowPoint::createExplicit($throwType, \true); } } else { if (!(new ObjectType(Throwable::class))->isSuperTypeOf($returnType)->yes()) { $throwPoints[] = \PHPStan\Reflection\Callables\SimpleThrowPoint::createImplicit(); } } return $this->throwPoints = $throwPoints; } public function isPure() : TrinaryLogic { $impurePoints = $this->getImpurePoints(); if (count($impurePoints) === 0) { return TrinaryLogic::createYes(); } $certainCount = 0; foreach ($impurePoints as $impurePoint) { if (!$impurePoint->isCertain()) { continue; } $certainCount++; } return $certainCount > 0 ? TrinaryLogic::createNo() : TrinaryLogic::createMaybe(); } public function getImpurePoints() : array { if ($this->impurePoints !== null) { return $this->impurePoints; } if ($this->variant instanceof \PHPStan\Reflection\Callables\CallableParametersAcceptor) { return $this->impurePoints = $this->variant->getImpurePoints(); } $impurePoint = \PHPStan\Reflection\Callables\SimpleImpurePoint::createFromVariant($this->function, $this->variant); if ($impurePoint === null) { return $this->impurePoints = []; } return $this->impurePoints = [$impurePoint]; } public function getInvalidateExpressions() : array { return []; } public function getUsedVariables() : array { return []; } public function acceptsNamedArguments() : bool { return $this->function->acceptsNamedArguments(); } } asserts = $asserts; } /** * @return AssertTag[] */ public function getAll() : array { return $this->asserts; } /** * @return AssertTag[] */ public function getAsserts() : array { return array_filter($this->asserts, static function (AssertTag $assert) { return $assert->getIf() === AssertTag::NULL; }); } /** * @return AssertTag[] */ public function getAssertsIfTrue() : array { return array_merge(array_filter($this->asserts, static function (AssertTag $assert) { return $assert->getIf() === AssertTag::IF_TRUE; }), array_map(static function (AssertTag $assert) { return $assert->negate(); }, array_filter($this->asserts, static function (AssertTag $assert) { return $assert->getIf() === AssertTag::IF_FALSE && !$assert->isEquality(); }))); } /** * @return AssertTag[] */ public function getAssertsIfFalse() : array { return array_merge(array_filter($this->asserts, static function (AssertTag $assert) { return $assert->getIf() === AssertTag::IF_FALSE; }), array_map(static function (AssertTag $assert) { return $assert->negate(); }, array_filter($this->asserts, static function (AssertTag $assert) { return $assert->getIf() === AssertTag::IF_TRUE && !$assert->isEquality(); }))); } /** * @param callable(Type): Type $callable */ public function mapTypes(callable $callable) : self { $assertTagsCallback = static function (AssertTag $tag) use($callable) : AssertTag { return $tag->withType($callable($tag->getType())); }; return new self(array_map($assertTagsCallback, $this->asserts)); } public function intersectWith(\PHPStan\Reflection\Assertions $other) : self { return new self(array_merge($this->getAll(), $other->getAll())); } public static function createEmpty() : self { $empty = self::$empty; if ($empty !== null) { return $empty; } $empty = new self([]); self::$empty = $empty; return $empty; } public static function createFromResolvedPhpDocBlock(ResolvedPhpDocBlock $phpDocBlock) : self { $tags = $phpDocBlock->getAssertTags(); if (count($tags) === 0) { return self::createEmpty(); } return new self($tags); } } findMethod($classReflection, $methodName) !== null; } /** * @return ExtendedMethodReflection */ public function getMethod(ClassReflection $classReflection, string $methodName) : MethodReflection { $method = $this->findMethod($classReflection, $methodName); if ($method === null) { throw new ShouldNotHappenException(); } return $method; } /** * @return ExtendedMethodReflection|null */ private function findMethod(ClassReflection $classReflection, string $methodName) : ?MethodReflection { if (!$classReflection->isInterface()) { return null; } $extendsTags = $classReflection->getRequireExtendsTags(); foreach ($extendsTags as $extendsTag) { $type = $extendsTag->getType(); if (!$type->hasMethod($methodName)->yes()) { continue; } return $type->getMethod($methodName, new OutOfClassScope()); } $interfaces = $classReflection->getInterfaces(); foreach ($interfaces as $interface) { $method = $this->findMethod($interface, $methodName); if ($method !== null) { return $method; } } return null; } } findProperty($classReflection, $propertyName) !== null; } /** * @return ExtendedPropertyReflection */ public function getProperty(ClassReflection $classReflection, string $propertyName) : PropertyReflection { $property = $this->findProperty($classReflection, $propertyName); if ($property === null) { throw new ShouldNotHappenException(); } return $property; } private function findProperty(ClassReflection $classReflection, string $propertyName) : ?ExtendedPropertyReflection { if (!$classReflection->isInterface()) { return null; } $requireExtendsTags = $classReflection->getRequireExtendsTags(); foreach ($requireExtendsTags as $requireExtendsTag) { $type = $requireExtendsTag->getType(); if (!$type->hasProperty($propertyName)->yes()) { continue; } return $type->getProperty($propertyName, new OutOfClassScope()); } $interfaces = $classReflection->getInterfaces(); foreach ($interfaces as $interface) { $property = $this->findProperty($interface, $propertyName); if ($property !== null) { return $property; } } return null; } } $parameters */ public function __construct(TemplateTypeMap $templateTypeMap, ?TemplateTypeMap $resolvedTemplateTypeMap, array $parameters, bool $isVariadic, Type $returnType, Type $phpDocReturnType, Type $nativeReturnType, ?TemplateTypeVarianceMap $callSiteVarianceMap = null) { $this->phpDocReturnType = $phpDocReturnType; $this->nativeReturnType = $nativeReturnType; parent::__construct($templateTypeMap, $resolvedTemplateTypeMap, $parameters, $isVariadic, $returnType, $callSiteVarianceMap); } /** * @return array */ public function getParameters() : array { /** @var array $parameters */ $parameters = parent::getParameters(); return $parameters; } public function getPhpDocReturnType() : Type { return $this->phpDocReturnType; } public function getNativeReturnType() : Type { return $this->nativeReturnType; } } */ function autoloadFunctions() : array { return $GLOBALS['__phpstanAutoloadFunctions'] ?? []; } phpVersion = $phpVersion; $this->fileHelper = $fileHelper; $this->composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; $this->allConfigFiles = $allConfigFiles; } public function print(Output $output) : void { $phpRuntimeVersion = new PhpVersion(PHP_VERSION_ID); $output->writeLineFormatted(sprintf('PHP runtime version: %s', $phpRuntimeVersion->getVersionString())); $output->writeLineFormatted(sprintf('PHP version for analysis: %s (from %s)', $this->phpVersion->getVersionString(), $this->phpVersion->getSourceLabel())); $output->writeLineFormatted(''); $output->writeLineFormatted(sprintf('PHPStan version: %s', ComposerHelper::getPhpStanVersion())); $output->writeLineFormatted('PHPStan running from:'); $pharRunning = Phar::running(\false); if ($pharRunning !== '') { $output->writeLineFormatted(dirname($pharRunning)); } else { if (isset($_SERVER['argv'][0]) && is_file($_SERVER['argv'][0])) { $output->writeLineFormatted($_SERVER['argv'][0]); } else { $output->writeLineFormatted('Unknown'); } } $output->writeLineFormatted(''); $configFilesFromExtensionInstaller = []; if (class_exists('PHPStan\\ExtensionInstaller\\GeneratedConfig')) { $output->writeLineFormatted('Extension installer:'); if (count(GeneratedConfig::EXTENSIONS) === 0) { $output->writeLineFormatted('No extensions installed'); } $generatedConfigReflection = new ReflectionClass('PHPStan\\ExtensionInstaller\\GeneratedConfig'); $generatedConfigDirectory = dirname($generatedConfigReflection->getFileName()); foreach (GeneratedConfig::EXTENSIONS as $name => $extensionConfig) { $output->writeLineFormatted(sprintf('%s: %s', $name, $extensionConfig['version'] ?? 'Unknown version')); foreach ($extensionConfig['extra']['includes'] ?? [] as $includedFile) { $includedFilePath = null; if (isset($extensionConfig['relative_install_path'])) { $includedFilePath = sprintf('%s/%s/%s', $generatedConfigDirectory, $extensionConfig['relative_install_path'], $includedFile); if (!is_file($includedFilePath) || !is_readable($includedFilePath)) { $includedFilePath = null; } } if ($includedFilePath === null) { $includedFilePath = sprintf('%s/%s', $extensionConfig['install_path'], $includedFile); } $configFilesFromExtensionInstaller[] = $this->fileHelper->normalizePath($includedFilePath, '/'); } } } else { $output->writeLineFormatted('Extension installer: Not installed'); } $output->writeLineFormatted(''); $thirdPartyIncludedConfigs = []; foreach ($this->allConfigFiles as $configFile) { $configFile = $this->fileHelper->normalizePath($configFile, '/'); if (in_array($configFile, $configFilesFromExtensionInstaller, \true)) { continue; } foreach ($this->composerAutoloaderProjectPaths as $composerAutoloaderProjectPath) { $composerConfig = ComposerHelper::getComposerConfig($composerAutoloaderProjectPath); if ($composerConfig === null) { continue; } $vendorDir = $this->fileHelper->normalizePath(ComposerHelper::getVendorDirFromComposerConfig($composerAutoloaderProjectPath, $composerConfig), '/'); if (!str_starts_with($configFile, $vendorDir)) { continue; } $installedPath = $vendorDir . '/composer/installed.php'; if (!is_file($installedPath)) { continue; } $installed = (require $installedPath); $trimmed = substr($configFile, strlen($vendorDir) + 1); $parts = explode('/', $trimmed); $package = implode('/', array_slice($parts, 0, 2)); $configPath = implode('/', array_slice($parts, 2)); if (!array_key_exists($package, $installed['versions'])) { continue; } $packageVersion = $installed['versions'][$package]['pretty_version'] ?? null; if ($packageVersion === null) { continue; } $thirdPartyIncludedConfigs[] = [$package, $packageVersion, $configPath]; } } if (count($thirdPartyIncludedConfigs) > 0) { $output->writeLineFormatted('Included configs from Composer packages:'); foreach ($thirdPartyIncludedConfigs as [$package, $packageVersion, $configPath]) { $output->writeLineFormatted(sprintf('%s (%s): %s', $package, $configPath, $packageVersion)); } $output->writeLineFormatted(''); } $composerAutoloaderProjectPathsCount = count($this->composerAutoloaderProjectPaths); $output->writeLineFormatted(sprintf('Discovered Composer project %s:', $composerAutoloaderProjectPathsCount === 1 ? 'root' : 'roots')); if ($composerAutoloaderProjectPathsCount === 0) { $output->writeLineFormatted('None'); } foreach ($this->composerAutoloaderProjectPaths as $composerAutoloaderProjectPath) { $output->writeLineFormatted($composerAutoloaderProjectPath); } $output->writeLineFormatted(''); } } expression = $expression; $this->originalType = $originalType; $this->originalNativeType = $originalNativeType; $this->certainty = $certainty; } public function getExpression() : Expr { return $this->expression; } public function getOriginalType() : Type { return $this->originalType; } public function getOriginalNativeType() : Type { return $this->originalNativeType; } public function getCertainty() : TrinaryLogic { return $this->certainty; } } scope = $scope; $this->throwPoints = $throwPoints; $this->impurePoints = $impurePoints; $this->invalidateExpressions = $invalidateExpressions; } public function getScope() : \PHPStan\Analyser\MutatingScope { return $this->scope; } /** * @return ThrowPoint[] */ public function getThrowPoints() : array { return $this->throwPoints; } /** * @return ImpurePoint[] */ public function getImpurePoints() : array { return $this->impurePoints; } /** * @return InvalidateExprNode[] */ public function getInvalidateExpressions() : array { return $this->invalidateExpressions; } } ruleRegistry = $ruleRegistry; $this->ruleErrorTransformer = $ruleErrorTransformer; $this->scopeFactory = $scopeFactory; $this->localIgnoresProcessor = $localIgnoresProcessor; $this->reportUnmatchedIgnoredErrors = $reportUnmatchedIgnoredErrors; } public function finalize(\PHPStan\Analyser\AnalyserResult $analyserResult, bool $onlyFiles, bool $debug) : \PHPStan\Analyser\FinalizerResult { if (count($analyserResult->getCollectedData()) === 0) { return $this->addUnmatchedIgnoredErrors($this->mergeFilteredPhpErrors($analyserResult), [], []); } $hasInternalErrors = count($analyserResult->getInternalErrors()) > 0 || $analyserResult->hasReachedInternalErrorsCountLimit(); if ($hasInternalErrors) { return $this->addUnmatchedIgnoredErrors($this->mergeFilteredPhpErrors($analyserResult), [], []); } $nodeType = CollectedDataNode::class; $node = new CollectedDataNode($analyserResult->getCollectedData(), $onlyFiles); $file = 'N/A'; $scope = $this->scopeFactory->create(\PHPStan\Analyser\ScopeContext::create($file)); $tempCollectorErrors = []; $internalErrors = $analyserResult->getInternalErrors(); foreach ($this->ruleRegistry->getRules($nodeType) as $rule) { try { $ruleErrors = $rule->processNode($node, $scope); } catch (AnalysedCodeException $e) { $tempCollectorErrors[] = (new \PHPStan\Analyser\Error($e->getMessage(), $file, $node->getStartLine(), $e, null, null, $e->getTip()))->withIdentifier('phpstan.internal')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($e), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); continue; } catch (IdentifierNotFound $e) { $tempCollectorErrors[] = (new \PHPStan\Analyser\Error(sprintf('Reflection error: %s not found.', $e->getIdentifier()->getName()), $file, $node->getStartLine(), $e, null, null, 'Learn more at https://phpstan.org/user-guide/discovering-symbols'))->withIdentifier('phpstan.reflection')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($e), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); continue; } catch (UnableToCompileNode|CircularReference $e) { $tempCollectorErrors[] = (new \PHPStan\Analyser\Error(sprintf('Reflection error: %s', $e->getMessage()), $file, $node->getStartLine(), $e))->withIdentifier('phpstan.reflection')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($e), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); continue; } catch (Throwable $t) { if ($debug) { throw $t; } $internalErrors[] = new \PHPStan\Analyser\InternalError($t->getMessage(), sprintf('running CollectedDataNode rule %s', get_class($rule)), \PHPStan\Analyser\InternalError::prepareTrace($t), $t->getTraceAsString(), \true); continue; } foreach ($ruleErrors as $ruleError) { $tempCollectorErrors[] = $this->ruleErrorTransformer->transform($ruleError, $scope, $nodeType, $node->getStartLine()); } } $errors = $analyserResult->getUnorderedErrors(); $locallyIgnoredErrors = $analyserResult->getLocallyIgnoredErrors(); $allLinesToIgnore = $analyserResult->getLinesToIgnore(); $allUnmatchedLineIgnores = $analyserResult->getUnmatchedLineIgnores(); $collectorErrors = []; $locallyIgnoredCollectorErrors = []; foreach ($tempCollectorErrors as $tempCollectorError) { $file = $tempCollectorError->getFilePath(); $linesToIgnore = $allLinesToIgnore[$file] ?? []; $unmatchedLineIgnores = $allUnmatchedLineIgnores[$file] ?? []; $localIgnoresProcessorResult = $this->localIgnoresProcessor->process([$tempCollectorError], $linesToIgnore, $unmatchedLineIgnores); foreach ($localIgnoresProcessorResult->getFileErrors() as $error) { $errors[] = $error; $collectorErrors[] = $error; } foreach ($localIgnoresProcessorResult->getLocallyIgnoredErrors() as $locallyIgnoredError) { $locallyIgnoredErrors[] = $locallyIgnoredError; $locallyIgnoredCollectorErrors[] = $locallyIgnoredError; } $allLinesToIgnore[$file] = $localIgnoresProcessorResult->getLinesToIgnore(); $allUnmatchedLineIgnores[$file] = $localIgnoresProcessorResult->getUnmatchedLineIgnores(); } return $this->addUnmatchedIgnoredErrors(new \PHPStan\Analyser\AnalyserResult(array_merge($errors, $analyserResult->getFilteredPhpErrors()), [], $analyserResult->getAllPhpErrors(), $locallyIgnoredErrors, $allLinesToIgnore, $allUnmatchedLineIgnores, $internalErrors, $analyserResult->getCollectedData(), $analyserResult->getDependencies(), $analyserResult->getUsedTraitDependencies(), $analyserResult->getExportedNodes(), $analyserResult->hasReachedInternalErrorsCountLimit(), $analyserResult->getPeakMemoryUsageBytes()), $collectorErrors, $locallyIgnoredCollectorErrors); } private function mergeFilteredPhpErrors(\PHPStan\Analyser\AnalyserResult $analyserResult) : \PHPStan\Analyser\AnalyserResult { return new \PHPStan\Analyser\AnalyserResult(array_merge($analyserResult->getUnorderedErrors(), $analyserResult->getFilteredPhpErrors()), [], $analyserResult->getAllPhpErrors(), $analyserResult->getLocallyIgnoredErrors(), $analyserResult->getLinesToIgnore(), $analyserResult->getUnmatchedLineIgnores(), $analyserResult->getInternalErrors(), $analyserResult->getCollectedData(), $analyserResult->getDependencies(), $analyserResult->getUsedTraitDependencies(), $analyserResult->getExportedNodes(), $analyserResult->hasReachedInternalErrorsCountLimit(), $analyserResult->getPeakMemoryUsageBytes()); } /** * @param list $collectorErrors * @param list $locallyIgnoredCollectorErrors */ private function addUnmatchedIgnoredErrors(\PHPStan\Analyser\AnalyserResult $analyserResult, array $collectorErrors, array $locallyIgnoredCollectorErrors) : \PHPStan\Analyser\FinalizerResult { if (!$this->reportUnmatchedIgnoredErrors) { return new \PHPStan\Analyser\FinalizerResult($analyserResult, $collectorErrors, $locallyIgnoredCollectorErrors); } $errors = $analyserResult->getUnorderedErrors(); foreach ($analyserResult->getUnmatchedLineIgnores() as $file => $data) { foreach ($data as $ignoredFile => $lines) { if ($ignoredFile !== $file) { continue; } foreach ($lines as $line => $identifiers) { if ($identifiers === null) { $errors[] = (new \PHPStan\Analyser\Error(sprintf('No error to ignore is reported on line %d.', $line), $file, $line, \false, $file))->withIdentifier('ignore.unmatchedLine'); continue; } foreach ($identifiers as $identifier) { $errors[] = (new \PHPStan\Analyser\Error(sprintf('No error with identifier %s is reported on line %d.', $identifier, $line), $file, $line, \false, $file))->withIdentifier('ignore.unmatchedIdentifier'); } } } } return new \PHPStan\Analyser\FinalizerResult(new \PHPStan\Analyser\AnalyserResult($errors, $analyserResult->getFilteredPhpErrors(), $analyserResult->getAllPhpErrors(), $analyserResult->getLocallyIgnoredErrors(), $analyserResult->getLinesToIgnore(), $analyserResult->getUnmatchedLineIgnores(), $analyserResult->getInternalErrors(), $analyserResult->getCollectedData(), $analyserResult->getDependencies(), $analyserResult->getUsedTraitDependencies(), $analyserResult->getExportedNodes(), $analyserResult->hasReachedInternalErrorsCountLimit(), $analyserResult->getPeakMemoryUsageBytes()), $collectorErrors, $locallyIgnoredCollectorErrors); } } */ private $errors; /** * @var array> */ private $otherIgnoreErrors; /** * @var array>> */ private $ignoreErrorsByFile; /** * @var (string|mixed[])[] */ private $ignoreErrors; /** * @var bool */ private $reportUnmatchedIgnoredErrors; /** * @param list $errors * @param array> $otherIgnoreErrors * @param array>> $ignoreErrorsByFile * @param (string|mixed[])[] $ignoreErrors */ public function __construct(FileHelper $fileHelper, array $errors, array $otherIgnoreErrors, array $ignoreErrorsByFile, array $ignoreErrors, bool $reportUnmatchedIgnoredErrors) { $this->fileHelper = $fileHelper; $this->errors = $errors; $this->otherIgnoreErrors = $otherIgnoreErrors; $this->ignoreErrorsByFile = $ignoreErrorsByFile; $this->ignoreErrors = $ignoreErrors; $this->reportUnmatchedIgnoredErrors = $reportUnmatchedIgnoredErrors; } /** * @return list */ public function getErrors() : array { return $this->errors; } /** * @param Error[] $errors * @param string[] $analysedFiles */ public function process(array $errors, bool $onlyFiles, array $analysedFiles, bool $hasInternalErrors) : \PHPStan\Analyser\Ignore\IgnoredErrorHelperProcessedResult { $unmatchedIgnoredErrors = $this->ignoreErrors; $stringErrors = []; $processIgnoreError = function (Error $error, int $i, $ignore) use(&$unmatchedIgnoredErrors, &$stringErrors) : bool { $shouldBeIgnored = \false; if (is_string($ignore)) { $shouldBeIgnored = \PHPStan\Analyser\Ignore\IgnoredError::shouldIgnore($this->fileHelper, $error, $ignore, null, null); if ($shouldBeIgnored) { unset($unmatchedIgnoredErrors[$i]); } } else { if (isset($ignore['path'])) { $shouldBeIgnored = \PHPStan\Analyser\Ignore\IgnoredError::shouldIgnore($this->fileHelper, $error, $ignore['message'] ?? null, $ignore['identifier'] ?? null, $ignore['path']); if ($shouldBeIgnored) { if (isset($ignore['count'])) { $realCount = $unmatchedIgnoredErrors[$i]['realCount'] ?? 0; $realCount++; $unmatchedIgnoredErrors[$i]['realCount'] = $realCount; if (!isset($unmatchedIgnoredErrors[$i]['file'])) { $unmatchedIgnoredErrors[$i]['file'] = $error->getFile(); $unmatchedIgnoredErrors[$i]['line'] = $error->getLine(); } if ($realCount > $ignore['count']) { $shouldBeIgnored = \false; } } else { unset($unmatchedIgnoredErrors[$i]); } } } elseif (isset($ignore['paths'])) { foreach ($ignore['paths'] as $j => $ignorePath) { $shouldBeIgnored = \PHPStan\Analyser\Ignore\IgnoredError::shouldIgnore($this->fileHelper, $error, $ignore['message'] ?? null, $ignore['identifier'] ?? null, $ignorePath); if (!$shouldBeIgnored) { continue; } if (isset($unmatchedIgnoredErrors[$i])) { if (!is_array($unmatchedIgnoredErrors[$i])) { throw new ShouldNotHappenException(); } unset($unmatchedIgnoredErrors[$i]['paths'][$j]); if (isset($unmatchedIgnoredErrors[$i]['paths']) && count($unmatchedIgnoredErrors[$i]['paths']) === 0) { unset($unmatchedIgnoredErrors[$i]); } } break; } } else { $shouldBeIgnored = \PHPStan\Analyser\Ignore\IgnoredError::shouldIgnore($this->fileHelper, $error, $ignore['message'] ?? null, $ignore['identifier'] ?? null, null); if ($shouldBeIgnored) { unset($unmatchedIgnoredErrors[$i]); } } } if ($shouldBeIgnored) { if (!$error->canBeIgnored()) { $stringErrors[] = sprintf('Error message "%s" cannot be ignored, use excludePaths instead.', $error->getMessage()); return \true; } return \false; } return \true; }; $ignoredErrors = []; foreach ($errors as $errorIndex => $error) { $filePath = $this->fileHelper->normalizePath($error->getFilePath()); if (isset($this->ignoreErrorsByFile[$filePath])) { foreach ($this->ignoreErrorsByFile[$filePath] as $ignoreError) { $i = $ignoreError['index']; $ignore = $ignoreError['ignoreError']; $result = $processIgnoreError($error, $i, $ignore); if (!$result) { unset($errors[$errorIndex]); $ignoredErrors[] = [$error, $ignore]; continue 2; } } } $traitFilePath = $error->getTraitFilePath(); if ($traitFilePath !== null) { $normalizedTraitFilePath = $this->fileHelper->normalizePath($traitFilePath); if (isset($this->ignoreErrorsByFile[$normalizedTraitFilePath])) { foreach ($this->ignoreErrorsByFile[$normalizedTraitFilePath] as $ignoreError) { $i = $ignoreError['index']; $ignore = $ignoreError['ignoreError']; $result = $processIgnoreError($error, $i, $ignore); if (!$result) { unset($errors[$errorIndex]); $ignoredErrors[] = [$error, $ignore]; continue 2; } } } } foreach ($this->otherIgnoreErrors as $ignoreError) { $i = $ignoreError['index']; $ignore = $ignoreError['ignoreError']; $result = $processIgnoreError($error, $i, $ignore); if (!$result) { unset($errors[$errorIndex]); $ignoredErrors[] = [$error, $ignore]; continue 2; } } } $errors = array_values($errors); foreach ($unmatchedIgnoredErrors as $unmatchedIgnoredError) { if (!isset($unmatchedIgnoredError['count']) || !isset($unmatchedIgnoredError['realCount'])) { continue; } if ($unmatchedIgnoredError['realCount'] <= $unmatchedIgnoredError['count']) { continue; } $errors[] = (new Error(sprintf('Ignored error pattern %s is expected to occur %d %s, but occurred %d %s.', \PHPStan\Analyser\Ignore\IgnoredError::stringifyPattern($unmatchedIgnoredError), $unmatchedIgnoredError['count'], $unmatchedIgnoredError['count'] === 1 ? 'time' : 'times', $unmatchedIgnoredError['realCount'], $unmatchedIgnoredError['realCount'] === 1 ? 'time' : 'times'), $unmatchedIgnoredError['file'], $unmatchedIgnoredError['line'], \false))->withIdentifier('ignore.count'); } $analysedFilesKeys = array_fill_keys($analysedFiles, \true); if (!$hasInternalErrors) { foreach ($unmatchedIgnoredErrors as $unmatchedIgnoredError) { $reportUnmatched = $unmatchedIgnoredError['reportUnmatched'] ?? $this->reportUnmatchedIgnoredErrors; if ($reportUnmatched === \false) { continue; } if (isset($unmatchedIgnoredError['count']) && isset($unmatchedIgnoredError['realCount']) && (isset($unmatchedIgnoredError['realPath']) || !$onlyFiles)) { if ($unmatchedIgnoredError['realCount'] < $unmatchedIgnoredError['count']) { $errors[] = (new Error(sprintf('Ignored error pattern %s is expected to occur %d %s, but occurred only %d %s.', \PHPStan\Analyser\Ignore\IgnoredError::stringifyPattern($unmatchedIgnoredError), $unmatchedIgnoredError['count'], $unmatchedIgnoredError['count'] === 1 ? 'time' : 'times', $unmatchedIgnoredError['realCount'], $unmatchedIgnoredError['realCount'] === 1 ? 'time' : 'times'), $unmatchedIgnoredError['file'], $unmatchedIgnoredError['line'], \false))->withIdentifier('ignore.count'); } } elseif (isset($unmatchedIgnoredError['realPath'])) { if (!array_key_exists($unmatchedIgnoredError['realPath'], $analysedFilesKeys)) { continue; } $errors[] = (new Error(sprintf('Ignored error pattern %s was not matched in reported errors.', \PHPStan\Analyser\Ignore\IgnoredError::stringifyPattern($unmatchedIgnoredError)), $unmatchedIgnoredError['realPath'], null, \false))->withIdentifier('ignore.unmatched'); } elseif (!$onlyFiles) { $stringErrors[] = sprintf('Ignored error pattern %s was not matched in reported errors.', \PHPStan\Analyser\Ignore\IgnoredError::stringifyPattern($unmatchedIgnoredError)); } } } return new \PHPStan\Analyser\Ignore\IgnoredErrorHelperProcessedResult($errors, $ignoredErrors, $stringErrors); } } 'T_WHITESPACE', self::TOKEN_END => 'end', self::TOKEN_IDENTIFIER => 'identifier', self::TOKEN_COMMA => 'comma (,)', self::TOKEN_OPEN_PARENTHESIS => 'T_OPEN_PARENTHESIS', self::TOKEN_CLOSE_PARENTHESIS => 'T_CLOSE_PARENTHESIS', self::TOKEN_OTHER => 'T_OTHER']; public const VALUE_OFFSET = 0; public const TYPE_OFFSET = 1; public const LINE_OFFSET = 2; /** * @var ?string */ private $regexp = null; /** * @return list */ public function tokenize(string $input) : array { if ($this->regexp === null) { $this->regexp = $this->generateRegexp(); } $matches = Strings::matchAll($input, $this->regexp, PREG_SET_ORDER); $tokens = []; $line = 1; foreach ($matches as $match) { /** @var self::TOKEN_* $type */ $type = (int) $match['MARK']; $tokens[] = [$match[0], $type, $line]; if ($type !== self::TOKEN_END) { continue; } $line++; } if (($type ?? null) !== self::TOKEN_END) { $tokens[] = ['', self::TOKEN_END, $line]; // ensure ending token is present } return $tokens; } /** * @param self::TOKEN_* $type */ public function getLabel(int $type) : string { return self::LABELS[$type]; } private function generateRegexp() : string { $patterns = [ self::TOKEN_WHITESPACE => '[\\x09\\x20]++', self::TOKEN_END => '(\\r?+\\n[\\x09\\x20]*+(?:\\*(?!/)\\x20?+)?|\\*/)', self::TOKEN_IDENTIFIER => Error::PATTERN_IDENTIFIER, self::TOKEN_COMMA => ',', self::TOKEN_OPEN_PARENTHESIS => '\\(', self::TOKEN_CLOSE_PARENTHESIS => '\\)', // everything except whitespaces and parentheses self::TOKEN_OTHER => '([^\\s\\)\\(])++', ]; foreach ($patterns as $type => &$pattern) { $pattern = '(?:' . $pattern . ')(*MARK:' . $type . ')'; } return '~' . implode('|', $patterns) . '~Asi'; } } phpDocLine = $phpDocLine; parent::__construct($message); } public function getPhpDocLine() : int { return $this->phpDocLine; } } */ private $notIgnoredErrors; /** * @var list */ private $ignoredErrors; /** * @var list */ private $otherIgnoreMessages; /** * @param list $notIgnoredErrors * @param list $ignoredErrors * @param list $otherIgnoreMessages */ public function __construct(array $notIgnoredErrors, array $ignoredErrors, array $otherIgnoreMessages) { $this->notIgnoredErrors = $notIgnoredErrors; $this->ignoredErrors = $ignoredErrors; $this->otherIgnoreMessages = $otherIgnoreMessages; } /** * @return list */ public function getNotIgnoredErrors() : array { return $this->notIgnoredErrors; } /** * @return list */ public function getIgnoredErrors() : array { return $this->ignoredErrors; } /** * @return list */ public function getOtherIgnoreMessages() : array { return $this->otherIgnoreMessages; } } getIdentifier() !== $identifier) { return \false; } } if ($ignoredErrorPattern !== null) { // normalize newlines to allow working with ignore-patterns independent of used OS newline-format $errorMessage = $error->getMessage(); $errorMessage = str_replace(['\\r\\n', '\\r'], '\\n', $errorMessage); $ignoredErrorPattern = str_replace([preg_quote('\\r\\n'), preg_quote('\\r')], preg_quote('\\n'), $ignoredErrorPattern); if (Strings::match($errorMessage, $ignoredErrorPattern) === null) { return \false; } } if ($path !== null) { $fileExcluder = new FileExcluder($fileHelper, [$path], BleedingEdgeToggle::isBleedingEdge()); $isExcluded = $fileExcluder->isExcludedFromAnalysing($error->getFilePath()); if (!$isExcluded && $error->getTraitFilePath() !== null) { return $fileExcluder->isExcludedFromAnalysing($error->getTraitFilePath()); } return $isExcluded; } return \true; } } fileHelper = $fileHelper; $this->ignoreErrors = $ignoreErrors; $this->reportUnmatchedIgnoredErrors = $reportUnmatchedIgnoredErrors; } public function initialize() : \PHPStan\Analyser\Ignore\IgnoredErrorHelperResult { $otherIgnoreErrors = []; $ignoreErrorsByFile = []; $errors = []; $expandedIgnoreErrors = []; foreach ($this->ignoreErrors as $ignoreError) { if (is_array($ignoreError)) { if (!isset($ignoreError['message']) && !isset($ignoreError['messages']) && !isset($ignoreError['identifier'])) { $errors[] = sprintf('Ignored error %s is missing a message or an identifier.', Json::encode($ignoreError)); continue; } if (isset($ignoreError['messages'])) { foreach ($ignoreError['messages'] as $message) { $expandedIgnoreError = $ignoreError; unset($expandedIgnoreError['messages']); $expandedIgnoreError['message'] = $message; $expandedIgnoreErrors[] = $expandedIgnoreError; } } else { $expandedIgnoreErrors[] = $ignoreError; } } else { $expandedIgnoreErrors[] = $ignoreError; } } $uniquedExpandedIgnoreErrors = []; foreach ($expandedIgnoreErrors as $ignoreError) { if (!isset($ignoreError['message']) && !isset($ignoreError['identifier'])) { $uniquedExpandedIgnoreErrors[] = $ignoreError; continue; } if (!isset($ignoreError['path'])) { $uniquedExpandedIgnoreErrors[] = $ignoreError; continue; } $key = $ignoreError['path']; if (isset($ignoreError['message'])) { $key = sprintf("%s\n%s", $key, $ignoreError['message']); } if (isset($ignoreError['identifier'])) { $key = sprintf("%s\n%s", $key, $ignoreError['identifier']); } if ($key === '') { throw new ShouldNotHappenException(); } if (!array_key_exists($key, $uniquedExpandedIgnoreErrors)) { $uniquedExpandedIgnoreErrors[$key] = $ignoreError; continue; } $uniquedExpandedIgnoreErrors[$key] = ['message' => $ignoreError['message'] ?? null, 'path' => $ignoreError['path'], 'identifier' => $ignoreError['identifier'] ?? null, 'count' => ($uniquedExpandedIgnoreErrors[$key]['count'] ?? 1) + ($ignoreError['count'] ?? 1), 'reportUnmatched' => ($uniquedExpandedIgnoreErrors[$key]['reportUnmatched'] ?? $this->reportUnmatchedIgnoredErrors) || ($ignoreError['reportUnmatched'] ?? $this->reportUnmatchedIgnoredErrors)]; } $expandedIgnoreErrors = array_values($uniquedExpandedIgnoreErrors); foreach ($expandedIgnoreErrors as $i => $ignoreError) { $ignoreErrorEntry = ['index' => $i, 'ignoreError' => $ignoreError]; try { if (is_array($ignoreError)) { if (!isset($ignoreError['message']) && !isset($ignoreError['identifier'])) { $errors[] = sprintf('Ignored error %s is missing a message or an identifier.', Json::encode($ignoreError)); continue; } if (!isset($ignoreError['path'])) { $otherIgnoreErrors[] = $ignoreErrorEntry; } elseif (@is_file($ignoreError['path'])) { $normalizedPath = $this->fileHelper->normalizePath($ignoreError['path']); $ignoreError['path'] = $normalizedPath; $ignoreErrorsByFile[$normalizedPath][] = $ignoreErrorEntry; $ignoreError['realPath'] = $normalizedPath; $expandedIgnoreErrors[$i] = $ignoreError; } else { $otherIgnoreErrors[] = $ignoreErrorEntry; } } else { $otherIgnoreErrors[] = $ignoreErrorEntry; } } catch (JsonException $e) { $errors[] = $e->getMessage(); } } return new \PHPStan\Analyser\Ignore\IgnoredErrorHelperResult($this->fileHelper, $errors, $otherIgnoreErrors, $ignoreErrorsByFile, $expandedIgnoreErrors, $this->reportUnmatchedIgnoredErrors); } } $fileReplacements */ public function create(array $fileReplacements) : \PHPStan\Analyser\ResultCache\ResultCacheManager; } */ private $fileReplacements; /** * @var bool */ private $checkDependenciesOfProjectExtensionFiles; private const CACHE_VERSION = 'v12-linesToIgnore'; /** @var array */ private $fileHashes = []; /** @var array */ private $alreadyProcessed = []; /** * @param string[] $analysedPaths * @param string[] $analysedPathsFromConfig * @param string[] $composerAutoloaderProjectPaths * @param string[] $bootstrapFiles * @param string[] $scanFiles * @param string[] $scanDirectories * @param array $fileReplacements */ public function __construct(ExportedNodeFetcher $exportedNodeFetcher, FileFinder $scanFileFinder, ReflectionProvider $reflectionProvider, StubFilesProvider $stubFilesProvider, FileHelper $fileHelper, string $cacheFilePath, array $analysedPaths, array $analysedPathsFromConfig, array $composerAutoloaderProjectPaths, string $usedLevel, ?string $cliAutoloadFile, array $bootstrapFiles, array $scanFiles, array $scanDirectories, array $fileReplacements, bool $checkDependenciesOfProjectExtensionFiles) { $this->exportedNodeFetcher = $exportedNodeFetcher; $this->scanFileFinder = $scanFileFinder; $this->reflectionProvider = $reflectionProvider; $this->stubFilesProvider = $stubFilesProvider; $this->fileHelper = $fileHelper; $this->cacheFilePath = $cacheFilePath; $this->analysedPaths = $analysedPaths; $this->analysedPathsFromConfig = $analysedPathsFromConfig; $this->composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; $this->usedLevel = $usedLevel; $this->cliAutoloadFile = $cliAutoloadFile; $this->bootstrapFiles = $bootstrapFiles; $this->scanFiles = $scanFiles; $this->scanDirectories = $scanDirectories; $this->fileReplacements = $fileReplacements; $this->checkDependenciesOfProjectExtensionFiles = $checkDependenciesOfProjectExtensionFiles; } /** * @param string[] $allAnalysedFiles * @param mixed[]|null $projectConfigArray */ public function restore(array $allAnalysedFiles, bool $debug, bool $onlyFiles, ?array $projectConfigArray, Output $output) : \PHPStan\Analyser\ResultCache\ResultCache { $startTime = microtime(\true); $currentFileHashes = []; foreach ($allAnalysedFiles as $analysedFile) { if (!is_file($analysedFile)) { continue; } $currentFileHashes[$analysedFile] = $this->getFileHash($analysedFile); } if ($debug) { if ($output->isVeryVerbose()) { $output->writeLineFormatted('Result cache not used because of debug mode.'); } return new \PHPStan\Analyser\ResultCache\ResultCache($allAnalysedFiles, \true, time(), $this->getMeta($allAnalysedFiles, $projectConfigArray), [], [], [], [], [], [], [], [], [], $currentFileHashes); } if ($onlyFiles) { if ($output->isVeryVerbose()) { $output->writeLineFormatted('Result cache not used because only files were passed as analysed paths.'); } return new \PHPStan\Analyser\ResultCache\ResultCache($allAnalysedFiles, \true, time(), $this->getMeta($allAnalysedFiles, $projectConfigArray), [], [], [], [], [], [], [], [], [], $currentFileHashes); } $cacheFilePath = $this->cacheFilePath; if (!is_file($cacheFilePath)) { if ($output->isVeryVerbose()) { $output->writeLineFormatted('Result cache not used because the cache file does not exist.'); } return new \PHPStan\Analyser\ResultCache\ResultCache($allAnalysedFiles, \true, time(), $this->getMeta($allAnalysedFiles, $projectConfigArray), [], [], [], [], [], [], [], [], [], $currentFileHashes); } try { $data = (require $cacheFilePath); } catch (Throwable $e) { if ($output->isVeryVerbose()) { $output->writeLineFormatted(sprintf('Result cache not used because an error occurred while loading the cache file: %s', $e->getMessage())); } @unlink($cacheFilePath); return new \PHPStan\Analyser\ResultCache\ResultCache($allAnalysedFiles, \true, time(), $this->getMeta($allAnalysedFiles, $projectConfigArray), [], [], [], [], [], [], [], [], [], $currentFileHashes); } if (!is_array($data)) { @unlink($cacheFilePath); if ($output->isVeryVerbose()) { $output->writeLineFormatted('Result cache not used because the cache file is corrupted.'); } return new \PHPStan\Analyser\ResultCache\ResultCache($allAnalysedFiles, \true, time(), $this->getMeta($allAnalysedFiles, $projectConfigArray), [], [], [], [], [], [], [], [], [], $currentFileHashes); } $meta = $this->getMeta($allAnalysedFiles, $projectConfigArray); if ($this->isMetaDifferent($data['meta'], $meta)) { if ($output->isVeryVerbose()) { $diffs = $this->getMetaKeyDifferences($data['meta'], $meta); $output->writeLineFormatted('Result cache not used because the metadata do not match: ' . implode(', ', $diffs)); } return new \PHPStan\Analyser\ResultCache\ResultCache($allAnalysedFiles, \true, time(), $meta, [], [], [], [], [], [], [], [], [], $currentFileHashes); } if (time() - $data['lastFullAnalysisTime'] >= 60 * 60 * 24 * 7) { if ($output->isVeryVerbose()) { $output->writeLineFormatted('Result cache not used because it\'s more than 7 days since last full analysis.'); } // run full analysis if the result cache is older than 7 days return new \PHPStan\Analyser\ResultCache\ResultCache($allAnalysedFiles, \true, time(), $meta, [], [], [], [], [], [], [], [], [], $currentFileHashes); } /** * @var string $fileHash * @var bool $isAnalysed */ foreach ($data['projectExtensionFiles'] as $extensionFile => [$fileHash, $isAnalysed]) { if (!$isAnalysed) { continue; } if (!is_file($extensionFile)) { if ($output->isVeryVerbose()) { $output->writeLineFormatted(sprintf('Result cache not used because extension file %s was not found.', $extensionFile)); } return new \PHPStan\Analyser\ResultCache\ResultCache($allAnalysedFiles, \true, time(), $meta, [], [], [], [], [], [], [], [], [], $currentFileHashes); } if ($this->getFileHash($extensionFile) === $fileHash) { continue; } if ($output->isVeryVerbose()) { $output->writeLineFormatted(sprintf('Result cache not used because extension file %s hash does not match.', $extensionFile)); } return new \PHPStan\Analyser\ResultCache\ResultCache($allAnalysedFiles, \true, time(), $meta, [], [], [], [], [], [], [], [], [], $currentFileHashes); } $invertedDependencies = $data['dependencies']; $deletedFiles = array_fill_keys(array_keys($invertedDependencies), \true); $filesToAnalyse = []; $invertedDependenciesToReturn = []; $invertedUsedTraitDependenciesToReturn = []; $errors = $data['errorsCallback'](); $locallyIgnoredErrors = $data['locallyIgnoredErrorsCallback'](); $linesToIgnore = $data['linesToIgnore']; $unmatchedLineIgnores = $data['unmatchedLineIgnores']; $collectedData = $data['collectedDataCallback'](); $exportedNodes = $data['exportedNodesCallback'](); $filteredErrors = []; $filteredLocallyIgnoredErrors = []; $filteredLinesToIgnore = []; $filteredUnmatchedLineIgnores = []; $filteredCollectedData = []; $filteredExportedNodes = []; $newFileAppeared = \false; foreach ($this->getStubFiles() as $stubFile) { if (!array_key_exists($stubFile, $errors)) { continue; } $filteredErrors[$stubFile] = $errors[$stubFile]; } foreach ($allAnalysedFiles as $analysedFile) { if (array_key_exists($analysedFile, $errors)) { $filteredErrors[$analysedFile] = $errors[$analysedFile]; } if (array_key_exists($analysedFile, $locallyIgnoredErrors)) { $filteredLocallyIgnoredErrors[$analysedFile] = $locallyIgnoredErrors[$analysedFile]; } if (array_key_exists($analysedFile, $linesToIgnore)) { $filteredLinesToIgnore[$analysedFile] = $linesToIgnore[$analysedFile]; } if (array_key_exists($analysedFile, $unmatchedLineIgnores)) { $filteredUnmatchedLineIgnores[$analysedFile] = $unmatchedLineIgnores[$analysedFile]; } if (array_key_exists($analysedFile, $collectedData)) { $filteredCollectedData[$analysedFile] = $collectedData[$analysedFile]; } if (array_key_exists($analysedFile, $exportedNodes)) { $filteredExportedNodes[$analysedFile] = $exportedNodes[$analysedFile]; } if (!array_key_exists($analysedFile, $invertedDependencies)) { // new file $filesToAnalyse[] = $analysedFile; $newFileAppeared = \true; continue; } unset($deletedFiles[$analysedFile]); $analysedFileData = $invertedDependencies[$analysedFile]; $cachedFileHash = $analysedFileData['fileHash']; $dependentFiles = $analysedFileData['dependentFiles']; $invertedDependenciesToReturn[$analysedFile] = $dependentFiles; $usedTraitDependentFiles = $analysedFileData['usedTraitDependentFiles'] ?? []; if (count($usedTraitDependentFiles) > 0) { $invertedUsedTraitDependenciesToReturn[$analysedFile] = $usedTraitDependentFiles; } $currentFileHash = $currentFileHashes[$analysedFile]; if ($cachedFileHash === $currentFileHash) { continue; } $filesToAnalyse[] = $analysedFile; if (!array_key_exists($analysedFile, $filteredExportedNodes)) { continue; } $cachedFileExportedNodes = $filteredExportedNodes[$analysedFile]; $exportedNodesChanged = $this->exportedNodesChanged($analysedFile, $cachedFileExportedNodes); if ($exportedNodesChanged === null) { if (count($cachedFileExportedNodes) === 0) { continue; } foreach ($cachedFileExportedNodes as $exportedNode) { if (!$exportedNode instanceof ExportedTraitNode) { continue 2; } } // if the file changed but no exported nodes changed and the only exported nodes are traits // reanalyse files with classes using those traits // but not other dependent files foreach ($usedTraitDependentFiles as $usedTraitDependentFile) { if (!is_file($usedTraitDependentFile)) { continue; } $filesToAnalyse[] = $usedTraitDependentFile; } continue; } if ($exportedNodesChanged) { $newFileAppeared = \true; } foreach ($dependentFiles as $dependentFile) { if (!is_file($dependentFile)) { continue; } $filesToAnalyse[] = $dependentFile; } } foreach (array_keys($deletedFiles) as $deletedFile) { if (!array_key_exists($deletedFile, $invertedDependencies)) { continue; } $deletedFileData = $invertedDependencies[$deletedFile]; $dependentFiles = $deletedFileData['dependentFiles']; foreach ($dependentFiles as $dependentFile) { if (!is_file($dependentFile)) { continue; } $filesToAnalyse[] = $dependentFile; } } if ($newFileAppeared) { foreach (array_keys($filteredErrors) as $fileWithError) { $filesToAnalyse[] = $fileWithError; } } $filesToAnalyse = array_unique($filesToAnalyse); $filesToAnalyseCount = count($filesToAnalyse); if ($output->isVeryVerbose()) { $elapsed = microtime(\true) - $startTime; $elapsedString = $elapsed > 5 ? sprintf(' in %f seconds', round($elapsed, 1)) : ''; $output->writeLineFormatted(sprintf('Result cache restored%s. %d %s will be reanalysed.', $elapsedString, $filesToAnalyseCount, $filesToAnalyseCount === 1 ? 'file' : 'files')); } return new \PHPStan\Analyser\ResultCache\ResultCache($filesToAnalyse, \false, $data['lastFullAnalysisTime'], $meta, $filteredErrors, $filteredLocallyIgnoredErrors, $filteredLinesToIgnore, $filteredUnmatchedLineIgnores, $filteredCollectedData, $invertedDependenciesToReturn, $invertedUsedTraitDependenciesToReturn, $filteredExportedNodes, $data['projectExtensionFiles'], $currentFileHashes); } /** * @param mixed[] $cachedMeta * @param mixed[] $currentMeta */ private function isMetaDifferent(array $cachedMeta, array $currentMeta) : bool { $projectConfig = $currentMeta['projectConfig']; if ($projectConfig !== null) { ksort($currentMeta['projectConfig']); $currentMeta['projectConfig'] = Neon::encode($currentMeta['projectConfig']); } return $cachedMeta !== $currentMeta; } /** * @param mixed[] $cachedMeta * @param mixed[] $currentMeta * * @return string[] */ private function getMetaKeyDifferences(array $cachedMeta, array $currentMeta) : array { $diffs = []; foreach ($cachedMeta as $key => $value) { if (!array_key_exists($key, $currentMeta)) { $diffs[] = $key; continue; } if ($value === $currentMeta[$key]) { continue; } $diffs[] = $key; } if ($diffs === []) { // when none of the keys is different, // the order of the keys is the problem $diffs[] = 'keyOrder'; } return $diffs; } /** * @param array $cachedFileExportedNodes * @return bool|null null means nothing changed, true means new root symbol appeared, false means nested node changed */ private function exportedNodesChanged(string $analysedFile, array $cachedFileExportedNodes) : ?bool { if (array_key_exists($analysedFile, $this->fileReplacements)) { $analysedFile = $this->fileReplacements[$analysedFile]; } $fileExportedNodes = $this->exportedNodeFetcher->fetchNodes($analysedFile); $cachedSymbols = []; foreach ($cachedFileExportedNodes as $cachedFileExportedNode) { $cachedSymbols[$cachedFileExportedNode->getType()][] = $cachedFileExportedNode->getName(); } $fileSymbols = []; foreach ($fileExportedNodes as $fileExportedNode) { $fileSymbols[$fileExportedNode->getType()][] = $fileExportedNode->getName(); } if ($cachedSymbols !== $fileSymbols) { return \true; } if (count($fileExportedNodes) !== count($cachedFileExportedNodes)) { return \true; } foreach ($fileExportedNodes as $i => $fileExportedNode) { $cachedExportedNode = $cachedFileExportedNodes[$i]; if (!$cachedExportedNode->equals($fileExportedNode)) { return \false; } } return null; } public function process(AnalyserResult $analyserResult, \PHPStan\Analyser\ResultCache\ResultCache $resultCache, Output $output, bool $onlyFiles, bool $save) : \PHPStan\Analyser\ResultCache\ResultCacheProcessResult { $internalErrors = $analyserResult->getInternalErrors(); $freshErrorsByFile = []; foreach ($analyserResult->getErrors() as $error) { $freshErrorsByFile[$error->getFilePath()][] = $error; } $freshLocallyIgnoredErrorsByFile = []; foreach ($analyserResult->getLocallyIgnoredErrors() as $error) { $freshLocallyIgnoredErrorsByFile[$error->getFilePath()][] = $error; } $freshCollectedDataByFile = []; foreach ($analyserResult->getCollectedData() as $collectedData) { $freshCollectedDataByFile[$collectedData->getFilePath()][] = $collectedData; } $meta = $resultCache->getMeta(); $projectConfigArray = $meta['projectConfig']; if ($projectConfigArray !== null) { $meta['projectConfig'] = Neon::encode($projectConfigArray); } $doSave = function (array $errorsByFile, $locallyIgnoredErrorsByFile, $linesToIgnore, $unmatchedLineIgnores, $collectedDataByFile, ?array $dependencies, ?array $usedTraitDependencies, array $exportedNodes, array $projectExtensionFiles) use($internalErrors, $resultCache, $output, $onlyFiles, $meta) : bool { if ($onlyFiles) { if ($output->isVeryVerbose()) { $output->writeLineFormatted('Result cache was not saved because only files were passed as analysed paths.'); } return \false; } if ($dependencies === null) { if ($output->isVeryVerbose()) { $output->writeLineFormatted('Result cache was not saved because of error in dependencies.'); } return \false; } if ($usedTraitDependencies === null) { if ($output->isVeryVerbose()) { $output->writeLineFormatted('Result cache was not saved because of error in used trait dependencies.'); } return \false; } if (count($internalErrors) > 0) { if ($output->isVeryVerbose()) { $output->writeLineFormatted('Result cache was not saved because of internal errors.'); } return \false; } if (count($this->fileReplacements) > 0) { if ($output->isVeryVerbose()) { $output->writeLineFormatted('Result cache was not saved because of --tmp-file and --instead-of CLI options passed (editor mode).'); } return \false; } foreach ($errorsByFile as $errors) { foreach ($errors as $error) { if (!$error->hasNonIgnorableException()) { continue; } if ($output->isVeryVerbose()) { $output->writeLineFormatted(sprintf('Result cache was not saved because of non-ignorable exception: %s', $error->getMessage())); } return \false; } } $this->save($resultCache->getLastFullAnalysisTime(), $errorsByFile, $locallyIgnoredErrorsByFile, $linesToIgnore, $unmatchedLineIgnores, $collectedDataByFile, $dependencies, $usedTraitDependencies, $exportedNodes, $projectExtensionFiles, $resultCache->getCurrentFileHashes(), $meta); if ($output->isVeryVerbose()) { $output->writeLineFormatted('Result cache is saved.'); } return \true; }; if ($resultCache->isFullAnalysis()) { $saved = \false; if ($save !== \false) { $projectExtensionFiles = []; if ($analyserResult->getDependencies() !== null) { $projectExtensionFiles = $this->getProjectExtensionFiles($projectConfigArray, $analyserResult->getDependencies()); } $saved = $doSave($freshErrorsByFile, $freshLocallyIgnoredErrorsByFile, $analyserResult->getLinesToIgnore(), $analyserResult->getUnmatchedLineIgnores(), $freshCollectedDataByFile, $analyserResult->getDependencies(), $analyserResult->getUsedTraitDependencies(), $analyserResult->getExportedNodes(), $projectExtensionFiles); } else { if ($output->isVeryVerbose()) { $output->writeLineFormatted('Result cache was not saved because it was not requested.'); } } return new \PHPStan\Analyser\ResultCache\ResultCacheProcessResult($analyserResult, $saved); } $errorsByFile = $this->mergeErrors($resultCache, $freshErrorsByFile); $locallyIgnoredErrorsByFile = $this->mergeLocallyIgnoredErrors($resultCache, $freshLocallyIgnoredErrorsByFile); $collectedDataByFile = $this->mergeCollectedData($resultCache, $freshCollectedDataByFile); $dependencies = $this->mergeDependencies($resultCache->getDependencies(), $resultCache->getFilesToAnalyse(), $analyserResult->getDependencies()); $usedTraitDependencies = $this->mergeDependencies($resultCache->getUsedTraitDependencies(), $resultCache->getFilesToAnalyse(), $analyserResult->getUsedTraitDependencies()); $exportedNodes = $this->mergeExportedNodes($resultCache, $analyserResult->getExportedNodes()); $linesToIgnore = $this->mergeLinesToIgnore($resultCache, $analyserResult->getLinesToIgnore()); $unmatchedLineIgnores = $this->mergeUnmatchedLineIgnores($resultCache, $analyserResult->getUnmatchedLineIgnores()); $saved = \false; if ($save !== \false) { $projectExtensionFiles = []; foreach ($resultCache->getProjectExtensionFiles() as $file => [$hash, $isAnalysed, $className]) { if ($isAnalysed) { continue; } // keep the same file hashes from the old run // so that the message "When you edit them and re-run PHPStan, the result cache will get stale." // keeps being shown on subsequent runs $projectExtensionFiles[$file] = [$hash, \false, $className]; } if ($dependencies !== null) { foreach ($this->getProjectExtensionFiles($projectConfigArray, $dependencies) as $file => [$hash, $isAnalysed, $className]) { if (!$isAnalysed) { continue; } $projectExtensionFiles[$file] = [$hash, \true, $className]; } } $saved = $doSave($errorsByFile, $locallyIgnoredErrorsByFile, $linesToIgnore, $unmatchedLineIgnores, $collectedDataByFile, $dependencies, $usedTraitDependencies, $exportedNodes, $projectExtensionFiles); } $flatErrors = []; foreach ($errorsByFile as $fileErrors) { foreach ($fileErrors as $fileError) { $flatErrors[] = $fileError; } } $flatLocallyIgnoredErrors = []; foreach ($locallyIgnoredErrorsByFile as $fileErrors) { foreach ($fileErrors as $fileError) { $flatLocallyIgnoredErrors[] = $fileError; } } $flatCollectedData = []; foreach ($collectedDataByFile as $fileCollectedData) { foreach ($fileCollectedData as $collectedData) { $flatCollectedData[] = $collectedData; } } return new \PHPStan\Analyser\ResultCache\ResultCacheProcessResult(new AnalyserResult($flatErrors, $analyserResult->getFilteredPhpErrors(), $analyserResult->getAllPhpErrors(), $flatLocallyIgnoredErrors, $linesToIgnore, $unmatchedLineIgnores, $internalErrors, $flatCollectedData, $dependencies, $usedTraitDependencies, $exportedNodes, $analyserResult->hasReachedInternalErrorsCountLimit(), $analyserResult->getPeakMemoryUsageBytes()), $saved); } /** * @param array> $freshErrorsByFile * @return array> */ private function mergeErrors(\PHPStan\Analyser\ResultCache\ResultCache $resultCache, array $freshErrorsByFile) : array { $errorsByFile = $resultCache->getErrors(); foreach ($resultCache->getFilesToAnalyse() as $file) { if (array_key_exists($file, $this->fileReplacements)) { unset($errorsByFile[$file]); $file = $this->fileReplacements[$file]; } if (!array_key_exists($file, $freshErrorsByFile)) { unset($errorsByFile[$file]); continue; } $errorsByFile[$file] = $freshErrorsByFile[$file]; } return $errorsByFile; } /** * @param array> $freshLocallyIgnoredErrorsByFile * @return array> */ private function mergeLocallyIgnoredErrors(\PHPStan\Analyser\ResultCache\ResultCache $resultCache, array $freshLocallyIgnoredErrorsByFile) : array { $errorsByFile = $resultCache->getLocallyIgnoredErrors(); foreach ($resultCache->getFilesToAnalyse() as $file) { if (array_key_exists($file, $this->fileReplacements)) { unset($errorsByFile[$file]); $file = $this->fileReplacements[$file]; } if (!array_key_exists($file, $freshLocallyIgnoredErrorsByFile)) { unset($errorsByFile[$file]); continue; } $errorsByFile[$file] = $freshLocallyIgnoredErrorsByFile[$file]; } return $errorsByFile; } /** * @param array> $freshCollectedDataByFile * @return array> */ private function mergeCollectedData(\PHPStan\Analyser\ResultCache\ResultCache $resultCache, array $freshCollectedDataByFile) : array { $collectedDataByFile = $resultCache->getCollectedData(); foreach ($resultCache->getFilesToAnalyse() as $file) { if (array_key_exists($file, $this->fileReplacements)) { unset($collectedDataByFile[$file]); $file = $this->fileReplacements[$file]; } if (!array_key_exists($file, $freshCollectedDataByFile)) { unset($collectedDataByFile[$file]); continue; } $collectedDataByFile[$file] = $freshCollectedDataByFile[$file]; } return $collectedDataByFile; } /** * @param array> $resultCacheDependencies * @param string[] $filesToAnalyse * @param array>|null $freshDependencies * @return array>|null */ private function mergeDependencies(array $resultCacheDependencies, array $filesToAnalyse, ?array $freshDependencies) : ?array { if ($freshDependencies === null) { return null; } $cachedDependencies = []; $filesNoOneIsDependingOn = array_fill_keys(array_keys($resultCacheDependencies), \true); foreach ($resultCacheDependencies as $file => $filesDependingOnFile) { foreach ($filesDependingOnFile as $fileDependingOnFile) { $cachedDependencies[$fileDependingOnFile][] = $file; unset($filesNoOneIsDependingOn[$fileDependingOnFile]); } } foreach (array_keys($filesNoOneIsDependingOn) as $file) { if (array_key_exists($file, $cachedDependencies)) { throw new ShouldNotHappenException(); } $cachedDependencies[$file] = []; } $newDependencies = $cachedDependencies; foreach ($filesToAnalyse as $file) { if (array_key_exists($file, $this->fileReplacements)) { unset($newDependencies[$file]); $file = $this->fileReplacements[$file]; } if (!array_key_exists($file, $freshDependencies)) { unset($newDependencies[$file]); continue; } $newDependencies[$file] = $freshDependencies[$file]; } return $newDependencies; } /** * @param array> $freshExportedNodes * @return array> */ private function mergeExportedNodes(\PHPStan\Analyser\ResultCache\ResultCache $resultCache, array $freshExportedNodes) : array { $newExportedNodes = $resultCache->getExportedNodes(); foreach ($resultCache->getFilesToAnalyse() as $file) { if (array_key_exists($file, $this->fileReplacements)) { unset($newExportedNodes[$file]); $file = $this->fileReplacements[$file]; } if (!array_key_exists($file, $freshExportedNodes)) { unset($newExportedNodes[$file]); continue; } $newExportedNodes[$file] = $freshExportedNodes[$file]; } return $newExportedNodes; } /** * @param array $freshLinesToIgnore * @return array */ private function mergeLinesToIgnore(\PHPStan\Analyser\ResultCache\ResultCache $resultCache, array $freshLinesToIgnore) : array { $newLinesToIgnore = $resultCache->getLinesToIgnore(); foreach ($resultCache->getFilesToAnalyse() as $file) { if (array_key_exists($file, $this->fileReplacements)) { unset($newLinesToIgnore[$file]); $file = $this->fileReplacements[$file]; } if (!array_key_exists($file, $freshLinesToIgnore)) { unset($newLinesToIgnore[$file]); continue; } $newLinesToIgnore[$file] = $freshLinesToIgnore[$file]; } return $newLinesToIgnore; } /** * @param array $freshUnmatchedLineIgnores * @return array */ private function mergeUnmatchedLineIgnores(\PHPStan\Analyser\ResultCache\ResultCache $resultCache, array $freshUnmatchedLineIgnores) : array { $newUnmatchedLineIgnores = $resultCache->getUnmatchedLineIgnores(); foreach ($resultCache->getFilesToAnalyse() as $file) { if (array_key_exists($file, $this->fileReplacements)) { unset($newUnmatchedLineIgnores[$file]); $file = $this->fileReplacements[$file]; } if (!array_key_exists($file, $freshUnmatchedLineIgnores)) { unset($newUnmatchedLineIgnores[$file]); continue; } $newUnmatchedLineIgnores[$file] = $freshUnmatchedLineIgnores[$file]; } return $newUnmatchedLineIgnores; } /** * @param array> $errors * @param array> $locallyIgnoredErrors * @param array $linesToIgnore * @param array $unmatchedLineIgnores * @param array> $collectedData * @param array> $dependencies * @param array> $usedTraitDependencies * @param array> $exportedNodes * @param array $projectExtensionFiles * @param array $currentFileHashes * @param mixed[] $meta */ private function save(int $lastFullAnalysisTime, array $errors, array $locallyIgnoredErrors, array $linesToIgnore, array $unmatchedLineIgnores, array $collectedData, array $dependencies, array $usedTraitDependencies, array $exportedNodes, array $projectExtensionFiles, array $currentFileHashes, array $meta) : void { $invertedDependencies = []; $filesNoOneIsDependingOn = array_fill_keys(array_keys($dependencies), \true); foreach ($dependencies as $file => $fileDependencies) { foreach ($fileDependencies as $fileDep) { if (!array_key_exists($fileDep, $invertedDependencies)) { $invertedDependencies[$fileDep] = ['fileHash' => $currentFileHashes[$fileDep] ?? $this->getFileHash($fileDep), 'dependentFiles' => []]; unset($filesNoOneIsDependingOn[$fileDep]); } $invertedDependencies[$fileDep]['dependentFiles'][] = $file; } } foreach ($usedTraitDependencies as $file => $fileUsedTraitDependencies) { foreach ($fileUsedTraitDependencies as $usedTraitFileDep) { if (!array_key_exists($usedTraitFileDep, $invertedDependencies)) { $invertedDependencies[$usedTraitFileDep] = ['fileHash' => $currentFileHashes[$usedTraitFileDep] ?? $this->getFileHash($usedTraitFileDep), 'dependentFiles' => [], 'usedTraitDependentFiles' => []]; unset($filesNoOneIsDependingOn[$usedTraitFileDep]); } $invertedDependencies[$usedTraitFileDep]['usedTraitDependentFiles'][] = $file; } } foreach (array_keys($filesNoOneIsDependingOn) as $file) { if (array_key_exists($file, $invertedDependencies)) { throw new ShouldNotHappenException(); } if (!is_file($file)) { continue; } $invertedDependencies[$file] = ['fileHash' => $currentFileHashes[$file] ?? $this->getFileHash($file), 'dependentFiles' => []]; } ksort($errors); ksort($locallyIgnoredErrors); ksort($linesToIgnore); ksort($unmatchedLineIgnores); ksort($collectedData); ksort($invertedDependencies); foreach ($invertedDependencies as $file => $fileData) { $dependentFiles = $fileData['dependentFiles']; sort($dependentFiles); $invertedDependencies[$file]['dependentFiles'] = $dependentFiles; $usedTraitDependentFiles = $fileData['usedTraitDependentFiles'] ?? []; if (count($usedTraitDependentFiles) === 0) { continue; } sort($usedTraitDependentFiles); $invertedDependencies[$file]['usedTraitDependentFiles'] = $usedTraitDependentFiles; } ksort($exportedNodes); $file = $this->cacheFilePath; FileWriter::write($file, " " . var_export($lastFullAnalysisTime, \true) . ",\n\t'meta' => " . var_export($meta, \true) . ",\n\t'projectExtensionFiles' => " . var_export($projectExtensionFiles, \true) . ",\n\t'errorsCallback' => static function (): array { return " . var_export($errors, \true) . "; },\n\t'locallyIgnoredErrorsCallback' => static function (): array { return " . var_export($locallyIgnoredErrors, \true) . "; },\n\t'linesToIgnore' => " . var_export($linesToIgnore, \true) . ",\n\t'unmatchedLineIgnores' => " . var_export($unmatchedLineIgnores, \true) . ",\n\t'collectedDataCallback' => static function (): array { return " . var_export($collectedData, \true) . "; },\n\t'dependencies' => " . var_export($invertedDependencies, \true) . ",\n\t'exportedNodesCallback' => static function (): array { return " . var_export($exportedNodes, \true) . '; }, ]; '); } /** * @param mixed[]|null $projectConfig * @param array $dependencies * @return array */ private function getProjectExtensionFiles(?array $projectConfig, array $dependencies) : array { $this->alreadyProcessed = []; $projectExtensionFiles = []; if ($projectConfig !== null) { $vendorDirs = []; foreach ($this->composerAutoloaderProjectPaths as $autoloaderProjectPath) { $composer = ComposerHelper::getComposerConfig($autoloaderProjectPath); if ($composer === null) { continue; } $vendorDirectory = ComposerHelper::getVendorDirFromComposerConfig($autoloaderProjectPath, $composer); $vendorDirs[] = $this->fileHelper->normalizePath($vendorDirectory); } $classes = ProjectConfigHelper::getServiceClassNames($projectConfig); foreach ($classes as $class) { if (!$this->reflectionProvider->hasClass($class)) { continue; } $classReflection = $this->reflectionProvider->getClass($class); $fileName = $classReflection->getFileName(); if ($fileName === null) { continue; } if (str_starts_with($fileName, 'phar://')) { continue; } $allServiceFiles = $this->getAllDependencies($fileName, $dependencies); if (count($allServiceFiles) === 0) { $normalizedFileName = $this->fileHelper->normalizePath($fileName); foreach ($vendorDirs as $vendorDir) { if (str_starts_with($normalizedFileName, $vendorDir)) { continue 2; } } $projectExtensionFiles[$fileName] = [$this->getFileHash($fileName), \false, $class]; continue; } foreach ($allServiceFiles as $serviceFile) { if (array_key_exists($serviceFile, $projectExtensionFiles)) { continue; } $projectExtensionFiles[$serviceFile] = [$this->getFileHash($serviceFile), \true, $class]; } } } return $projectExtensionFiles; } /** * @param array> $dependencies * @return array */ private function getAllDependencies(string $fileName, array $dependencies) : array { if (!array_key_exists($fileName, $dependencies)) { return []; } if (array_key_exists($fileName, $this->alreadyProcessed)) { return []; } $this->alreadyProcessed[$fileName] = \true; $files = [$fileName]; if ($this->checkDependenciesOfProjectExtensionFiles) { foreach ($dependencies[$fileName] as $fileDep) { foreach ($this->getAllDependencies($fileDep, $dependencies) as $fileDep2) { $files[] = $fileDep2; } } } return $files; } /** * @param string[] $allAnalysedFiles * @param mixed[]|null $projectConfigArray * @return mixed[] */ private function getMeta(array $allAnalysedFiles, ?array $projectConfigArray) : array { $extensions = array_values(array_filter(get_loaded_extensions(), static function (string $extension) : bool { return $extension !== 'xdebug'; })); sort($extensions); if ($projectConfigArray !== null) { unset($projectConfigArray['parameters']['editorUrl']); unset($projectConfigArray['parameters']['editorUrlTitle']); unset($projectConfigArray['parameters']['errorFormat']); unset($projectConfigArray['parameters']['ignoreErrors']); unset($projectConfigArray['parameters']['reportUnmatchedIgnoredErrors']); unset($projectConfigArray['parameters']['tipsOfTheDay']); unset($projectConfigArray['parameters']['parallel']); unset($projectConfigArray['parameters']['internalErrorsCountLimit']); unset($projectConfigArray['parameters']['cache']); unset($projectConfigArray['parameters']['memoryLimitFile']); unset($projectConfigArray['parameters']['pro']); unset($projectConfigArray['parametersSchema']); ksort($projectConfigArray); } return ['cacheVersion' => self::CACHE_VERSION, 'phpstanVersion' => ComposerHelper::getPhpStanVersion(), 'phpVersion' => PHP_VERSION_ID, 'projectConfig' => $projectConfigArray, 'analysedPaths' => $this->analysedPaths, 'scannedFiles' => $this->getScannedFiles($allAnalysedFiles), 'composerLocks' => $this->getComposerLocks(), 'composerInstalled' => $this->getComposerInstalled(), 'executedFilesHashes' => $this->getExecutedFileHashes(), 'phpExtensions' => $extensions, 'stubFiles' => $this->getStubFiles(), 'level' => $this->usedLevel]; } private function getFileHash(string $path) : string { if (array_key_exists($path, $this->fileReplacements)) { $path = $this->fileReplacements[$path]; } if (array_key_exists($path, $this->fileHashes)) { return $this->fileHashes[$path]; } $hash = sha1_file($path); if ($hash === \false) { throw new CouldNotReadFileException($path); } $this->fileHashes[$path] = $hash; return $hash; } /** * @param string[] $allAnalysedFiles * @return array */ private function getScannedFiles(array $allAnalysedFiles) : array { $scannedFiles = $this->scanFiles; $analysedDirectories = []; foreach (array_merge($this->analysedPaths, $this->analysedPathsFromConfig) as $analysedPath) { if (is_file($analysedPath)) { continue; } if (!is_dir($analysedPath)) { continue; } $analysedDirectories[] = $analysedPath; } $directories = array_unique(array_merge($analysedDirectories, $this->scanDirectories)); foreach ($this->scanFileFinder->findFiles($directories)->getFiles() as $file) { $scannedFiles[] = $file; } $hashes = []; foreach (array_diff($scannedFiles, $allAnalysedFiles) as $file) { $hashes[$file] = $this->getFileHash($file); } ksort($hashes); return $hashes; } /** * @return array */ private function getExecutedFileHashes() : array { $hashes = []; if ($this->cliAutoloadFile !== null) { $hashes[$this->cliAutoloadFile] = $this->getFileHash($this->cliAutoloadFile); } foreach ($this->bootstrapFiles as $bootstrapFile) { $hashes[$bootstrapFile] = $this->getFileHash($bootstrapFile); } ksort($hashes); return $hashes; } /** * @return array */ private function getComposerLocks() : array { $locks = []; foreach ($this->composerAutoloaderProjectPaths as $autoloadPath) { $lockPath = $autoloadPath . '/composer.lock'; if (!is_file($lockPath)) { continue; } $locks[$lockPath] = $this->getFileHash($lockPath); } return $locks; } /** * @return array */ private function getComposerInstalled() : array { $data = []; foreach ($this->composerAutoloaderProjectPaths as $autoloadPath) { $composer = ComposerHelper::getComposerConfig($autoloadPath); if ($composer === null) { continue; } $filePath = ComposerHelper::getVendorDirFromComposerConfig($autoloadPath, $composer) . '/composer/installed.php'; if (!is_file($filePath)) { continue; } $installed = (require $filePath); $rootName = $installed['root']['name']; unset($installed['root']); unset($installed['versions'][$rootName]); $data[$filePath] = $installed; } return $data; } /** * @return array */ private function getStubFiles() : array { $stubFiles = []; foreach ($this->stubFilesProvider->getProjectStubFiles() as $stubFile) { $stubFiles[$stubFile] = $this->getFileHash($stubFile); } ksort($stubFiles); return $stubFiles; } } cacheFilePath = $cacheFilePath; } public function clear() : string { $dir = dirname($this->cacheFilePath); if (!is_file($this->cacheFilePath)) { return $dir; } @unlink($this->cacheFilePath); return $dir; } } analyserResult = $analyserResult; $this->saved = $saved; } public function getAnalyserResult() : AnalyserResult { return $this->analyserResult; } public function isSaved() : bool { return $this->saved; } } > */ private $errors; /** * @var array> */ private $locallyIgnoredErrors; /** * @var array */ private $linesToIgnore; /** * @var array */ private $unmatchedLineIgnores; /** * @var array> */ private $collectedData; /** * @var array> */ private $dependencies; /** * @var array> */ private $usedTraitDependencies; /** * @var array> */ private $exportedNodes; /** * @var array */ private $projectExtensionFiles; /** * @var array */ private $currentFileHashes; /** * @param string[] $filesToAnalyse * @param mixed[] $meta * @param array> $errors * @param array> $locallyIgnoredErrors * @param array $linesToIgnore * @param array $unmatchedLineIgnores * @param array> $collectedData * @param array> $dependencies * @param array> $usedTraitDependencies * @param array> $exportedNodes * @param array $projectExtensionFiles * @param array $currentFileHashes */ public function __construct(array $filesToAnalyse, bool $fullAnalysis, int $lastFullAnalysisTime, array $meta, array $errors, array $locallyIgnoredErrors, array $linesToIgnore, array $unmatchedLineIgnores, array $collectedData, array $dependencies, array $usedTraitDependencies, array $exportedNodes, array $projectExtensionFiles, array $currentFileHashes) { $this->filesToAnalyse = $filesToAnalyse; $this->fullAnalysis = $fullAnalysis; $this->lastFullAnalysisTime = $lastFullAnalysisTime; $this->meta = $meta; $this->errors = $errors; $this->locallyIgnoredErrors = $locallyIgnoredErrors; $this->linesToIgnore = $linesToIgnore; $this->unmatchedLineIgnores = $unmatchedLineIgnores; $this->collectedData = $collectedData; $this->dependencies = $dependencies; $this->usedTraitDependencies = $usedTraitDependencies; $this->exportedNodes = $exportedNodes; $this->projectExtensionFiles = $projectExtensionFiles; $this->currentFileHashes = $currentFileHashes; } /** * @return string[] */ public function getFilesToAnalyse() : array { return $this->filesToAnalyse; } public function isFullAnalysis() : bool { return $this->fullAnalysis; } public function getLastFullAnalysisTime() : int { return $this->lastFullAnalysisTime; } /** * @return mixed[] */ public function getMeta() : array { return $this->meta; } /** * @return array> */ public function getErrors() : array { return $this->errors; } /** * @return array> */ public function getLocallyIgnoredErrors() : array { return $this->locallyIgnoredErrors; } /** * @return array */ public function getLinesToIgnore() : array { return $this->linesToIgnore; } /** * @return array */ public function getUnmatchedLineIgnores() : array { return $this->unmatchedLineIgnores; } /** * @return array> */ public function getCollectedData() : array { return $this->collectedData; } /** * @return array> */ public function getDependencies() : array { return $this->dependencies; } /** * @return array> */ public function getUsedTraitDependencies() : array { return $this->usedTraitDependencies; } /** * @return array> */ public function getExportedNodes() : array { return $this->exportedNodes; } /** * @return array */ public function getProjectExtensionFiles() : array { return $this->projectExtensionFiles; } /** * @return array */ public function getCurrentFileHashes() : array { return $this->currentFileHashes; } } exprPrinter = $exprPrinter; $this->reflectionProvider = $reflectionProvider; $this->functionTypeSpecifyingExtensions = $functionTypeSpecifyingExtensions; $this->methodTypeSpecifyingExtensions = $methodTypeSpecifyingExtensions; $this->staticMethodTypeSpecifyingExtensions = $staticMethodTypeSpecifyingExtensions; $this->rememberPossiblyImpureFunctionValues = $rememberPossiblyImpureFunctionValues; foreach (array_merge($functionTypeSpecifyingExtensions, $methodTypeSpecifyingExtensions, $staticMethodTypeSpecifyingExtensions) as $extension) { if (!$extension instanceof \PHPStan\Analyser\TypeSpecifierAwareExtension) { continue; } $extension->setTypeSpecifier($this); } } /** @api */ public function specifyTypesInCondition(\PHPStan\Analyser\Scope $scope, Expr $expr, \PHPStan\Analyser\TypeSpecifierContext $context, ?Expr $rootExpr = null) : \PHPStan\Analyser\SpecifiedTypes { $rootExpr = $rootExpr ?? $expr; if ($expr instanceof Expr\CallLike && $expr->isFirstClassCallable()) { return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } if ($expr instanceof Instanceof_) { $exprNode = $expr->expr; if ($expr->class instanceof Name) { $className = (string) $expr->class; $lowercasedClassName = strtolower($className); if ($lowercasedClassName === 'self' && $scope->isInClass()) { $type = new ObjectType($scope->getClassReflection()->getName()); } elseif ($lowercasedClassName === 'static' && $scope->isInClass()) { $type = new StaticType($scope->getClassReflection()); } elseif ($lowercasedClassName === 'parent') { if ($scope->isInClass() && $scope->getClassReflection()->getParentClass() !== null) { $type = new ObjectType($scope->getClassReflection()->getParentClass()->getName()); } else { $type = new NonexistentParentClassType(); } } else { $type = new ObjectType($className); } return $this->create($exprNode, $type, $context, \false, $scope, $rootExpr); } $classType = $scope->getType($expr->class); $uncertainty = \false; $type = TypeTraverser::map($classType, static function (Type $type, callable $traverse) use(&$uncertainty) : Type { if ($type instanceof UnionType || $type instanceof IntersectionType) { return $traverse($type); } if ($type->getObjectClassNames() !== []) { $uncertainty = \true; return $type; } if ($type instanceof GenericClassStringType) { $uncertainty = \true; return $type->getGenericType(); } if ($type instanceof ConstantStringType) { return new ObjectType($type->getValue()); } return new MixedType(); }); if (!$type->isSuperTypeOf(new MixedType())->yes()) { if ($context->true()) { $type = TypeCombinator::intersect($type, new ObjectWithoutClassType()); return $this->create($exprNode, $type, $context, \false, $scope, $rootExpr); } elseif ($context->false() && !$uncertainty) { $exprType = $scope->getType($expr->expr); if (!$type->isSuperTypeOf($exprType)->yes()) { return $this->create($exprNode, $type, $context, \false, $scope, $rootExpr); } } } if ($context->true()) { return $this->create($exprNode, new ObjectWithoutClassType(), $context, \false, $scope, $rootExpr); } } elseif ($expr instanceof Node\Expr\BinaryOp\Identical) { return $this->resolveIdentical($expr, $scope, $context, $rootExpr); } elseif ($expr instanceof Node\Expr\BinaryOp\NotIdentical) { return $this->specifyTypesInCondition($scope, new Node\Expr\BooleanNot(new Node\Expr\BinaryOp\Identical($expr->left, $expr->right)), $context, $rootExpr); } elseif ($expr instanceof Expr\Cast\Bool_) { return $this->specifyTypesInCondition($scope, new Node\Expr\BinaryOp\Equal($expr->expr, new ConstFetch(new Name\FullyQualified('true'))), $context, $rootExpr); } elseif ($expr instanceof Expr\Cast\String_) { return $this->specifyTypesInCondition($scope, new Node\Expr\BinaryOp\NotEqual($expr->expr, new Node\Scalar\String_('')), $context, $rootExpr); } elseif ($expr instanceof Expr\Cast\Int_) { return $this->specifyTypesInCondition($scope, new Node\Expr\BinaryOp\NotEqual($expr->expr, new Node\Scalar\LNumber(0)), $context, $rootExpr); } elseif ($expr instanceof Expr\Cast\Double) { return $this->specifyTypesInCondition($scope, new Node\Expr\BinaryOp\NotEqual($expr->expr, new Node\Scalar\DNumber(0.0)), $context, $rootExpr); } elseif ($expr instanceof Node\Expr\BinaryOp\Equal) { return $this->resolveEqual($expr, $scope, $context, $rootExpr); } elseif ($expr instanceof Node\Expr\BinaryOp\NotEqual) { return $this->specifyTypesInCondition($scope, new Node\Expr\BooleanNot(new Node\Expr\BinaryOp\Equal($expr->left, $expr->right)), $context, $rootExpr); } elseif ($expr instanceof Node\Expr\BinaryOp\Smaller || $expr instanceof Node\Expr\BinaryOp\SmallerOrEqual) { if ($expr->left instanceof FuncCall && count($expr->left->getArgs()) >= 1 && $expr->left->name instanceof Name && in_array(strtolower((string) $expr->left->name), ['count', 'sizeof', 'strlen', 'mb_strlen', 'preg_match'], \true) && (!$expr->right instanceof FuncCall || !$expr->right->name instanceof Name || !in_array(strtolower((string) $expr->right->name), ['count', 'sizeof', 'strlen', 'mb_strlen', 'preg_match'], \true))) { $inverseOperator = $expr instanceof Node\Expr\BinaryOp\Smaller ? new Node\Expr\BinaryOp\SmallerOrEqual($expr->right, $expr->left) : new Node\Expr\BinaryOp\Smaller($expr->right, $expr->left); return $this->specifyTypesInCondition($scope, new Node\Expr\BooleanNot($inverseOperator), $context, $rootExpr); } $orEqual = $expr instanceof Node\Expr\BinaryOp\SmallerOrEqual; $offset = $orEqual ? 0 : 1; $leftType = $scope->getType($expr->left); $result = new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); if (!$context->null() && $expr->right instanceof FuncCall && count($expr->right->getArgs()) >= 1 && $expr->right->name instanceof Name && in_array(strtolower((string) $expr->right->name), ['count', 'sizeof'], \true) && $leftType->isInteger()->yes()) { $argType = $scope->getType($expr->right->getArgs()[0]->value); if ($argType instanceof UnionType) { $sizeType = null; if ($leftType instanceof ConstantIntegerType) { if ($orEqual) { $sizeType = IntegerRangeType::createAllGreaterThanOrEqualTo($leftType->getValue()); } else { $sizeType = IntegerRangeType::createAllGreaterThan($leftType->getValue()); } } elseif ($leftType instanceof IntegerRangeType) { $sizeType = $leftType; } $narrowed = $this->narrowUnionByArraySize($expr->right, $argType, $sizeType, $context, $scope, $rootExpr); if ($narrowed !== null) { return $narrowed; } } if ($context->true() && IntegerRangeType::createAllGreaterThanOrEqualTo(1 - $offset)->isSuperTypeOf($leftType)->yes() || $context->false() && (new ConstantIntegerType(1 - $offset))->isSuperTypeOf($leftType)->yes()) { if ($context->truthy() && $argType->isArray()->maybe()) { $countables = []; if ($argType instanceof UnionType) { $countableInterface = new ObjectType(Countable::class); foreach ($argType->getTypes() as $innerType) { if ($innerType->isArray()->yes()) { $innerType = TypeCombinator::intersect(new NonEmptyArrayType(), $innerType); $countables[] = $innerType; } if (!$countableInterface->isSuperTypeOf($innerType)->yes()) { continue; } $countables[] = $innerType; } } if (count($countables) > 0) { $countableType = TypeCombinator::union(...$countables); return $this->create($expr->right->getArgs()[0]->value, $countableType, $context, \false, $scope, $rootExpr); } } if ($argType->isArray()->yes()) { $newType = new NonEmptyArrayType(); if ($context->true() && $argType->isList()->yes()) { $newType = AccessoryArrayListType::intersectWith($newType); } $result = $result->unionWith($this->create($expr->right->getArgs()[0]->value, $newType, $context, \false, $scope, $rootExpr)); } } } if (!$context->null() && $expr->right instanceof FuncCall && count($expr->right->getArgs()) >= 3 && $expr->right->name instanceof Name && in_array(strtolower((string) $expr->right->name), ['preg_match'], \true) && IntegerRangeType::fromInterval(0, null)->isSuperTypeOf($leftType)->yes()) { return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\NotIdentical($expr->right, new ConstFetch(new Name('false'))), $context, $rootExpr); } if (!$context->null() && $expr->right instanceof FuncCall && count($expr->right->getArgs()) === 1 && $expr->right->name instanceof Name && in_array(strtolower((string) $expr->right->name), ['strlen', 'mb_strlen'], \true) && $leftType->isInteger()->yes()) { if ($context->true() && IntegerRangeType::createAllGreaterThanOrEqualTo(1 - $offset)->isSuperTypeOf($leftType)->yes() || $context->false() && (new ConstantIntegerType(1 - $offset))->isSuperTypeOf($leftType)->yes()) { $argType = $scope->getType($expr->right->getArgs()[0]->value); if ($argType->isString()->yes()) { $accessory = new AccessoryNonEmptyStringType(); if (IntegerRangeType::createAllGreaterThanOrEqualTo(2 - $offset)->isSuperTypeOf($leftType)->yes()) { $accessory = new AccessoryNonFalsyStringType(); } $result = $result->unionWith($this->create($expr->right->getArgs()[0]->value, $accessory, $context, \false, $scope, $rootExpr)); } } } if ($leftType instanceof ConstantIntegerType) { if ($expr->right instanceof Expr\PostInc) { $result = $result->unionWith($this->createRangeTypes($rootExpr, $expr->right->var, IntegerRangeType::fromInterval($leftType->getValue(), null, $offset + 1), $context)); } elseif ($expr->right instanceof Expr\PostDec) { $result = $result->unionWith($this->createRangeTypes($rootExpr, $expr->right->var, IntegerRangeType::fromInterval($leftType->getValue(), null, $offset - 1), $context)); } elseif ($expr->right instanceof Expr\PreInc || $expr->right instanceof Expr\PreDec) { $result = $result->unionWith($this->createRangeTypes($rootExpr, $expr->right->var, IntegerRangeType::fromInterval($leftType->getValue(), null, $offset), $context)); } } $rightType = $scope->getType($expr->right); if ($rightType instanceof ConstantIntegerType) { if ($expr->left instanceof Expr\PostInc) { $result = $result->unionWith($this->createRangeTypes($rootExpr, $expr->left->var, IntegerRangeType::fromInterval(null, $rightType->getValue(), -$offset + 1), $context)); } elseif ($expr->left instanceof Expr\PostDec) { $result = $result->unionWith($this->createRangeTypes($rootExpr, $expr->left->var, IntegerRangeType::fromInterval(null, $rightType->getValue(), -$offset - 1), $context)); } elseif ($expr->left instanceof Expr\PreInc || $expr->left instanceof Expr\PreDec) { $result = $result->unionWith($this->createRangeTypes($rootExpr, $expr->left->var, IntegerRangeType::fromInterval(null, $rightType->getValue(), -$offset), $context)); } } if ($context->true()) { if (!$expr->left instanceof Node\Scalar) { $result = $result->unionWith($this->create($expr->left, $orEqual ? $rightType->getSmallerOrEqualType() : $rightType->getSmallerType(), \PHPStan\Analyser\TypeSpecifierContext::createTruthy(), \false, $scope, $rootExpr)); } if (!$expr->right instanceof Node\Scalar) { $result = $result->unionWith($this->create($expr->right, $orEqual ? $leftType->getGreaterOrEqualType() : $leftType->getGreaterType(), \PHPStan\Analyser\TypeSpecifierContext::createTruthy(), \false, $scope, $rootExpr)); } } elseif ($context->false()) { if (!$expr->left instanceof Node\Scalar) { $result = $result->unionWith($this->create($expr->left, $orEqual ? $rightType->getGreaterType() : $rightType->getGreaterOrEqualType(), \PHPStan\Analyser\TypeSpecifierContext::createTruthy(), \false, $scope, $rootExpr)); } if (!$expr->right instanceof Node\Scalar) { $result = $result->unionWith($this->create($expr->right, $orEqual ? $leftType->getSmallerType() : $leftType->getSmallerOrEqualType(), \PHPStan\Analyser\TypeSpecifierContext::createTruthy(), \false, $scope, $rootExpr)); } } return $result; } elseif ($expr instanceof Node\Expr\BinaryOp\Greater) { return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\Smaller($expr->right, $expr->left), $context, $rootExpr); } elseif ($expr instanceof Node\Expr\BinaryOp\GreaterOrEqual) { return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\SmallerOrEqual($expr->right, $expr->left), $context, $rootExpr); } elseif ($expr instanceof FuncCall && $expr->name instanceof Name) { if ($this->reflectionProvider->hasFunction($expr->name, $scope)) { $functionReflection = $this->reflectionProvider->getFunction($expr->name, $scope); foreach ($this->getFunctionTypeSpecifyingExtensions() as $extension) { if (!$extension->isFunctionSupported($functionReflection, $expr, $context)) { continue; } return $extension->specifyTypes($functionReflection, $expr, $scope, $context); } // lazy create parametersAcceptor, as creation can be expensive $parametersAcceptor = null; if (count($expr->getArgs()) > 0) { $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants()); $specifiedTypes = $this->specifyTypesFromConditionalReturnType($context, $expr, $parametersAcceptor, $scope); if ($specifiedTypes !== null) { return $specifiedTypes; } } $assertions = $functionReflection->getAsserts(); if ($assertions->getAll() !== []) { $parametersAcceptor = $parametersAcceptor ?? ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants()); $asserts = $assertions->mapTypes(static function (Type $type) use($parametersAcceptor) { return TemplateTypeHelper::resolveTemplateTypes($type, $parametersAcceptor->getResolvedTemplateTypeMap(), $parametersAcceptor instanceof ParametersAcceptorWithPhpDocs ? $parametersAcceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(), TemplateTypeVariance::createInvariant()); }); $specifiedTypes = $this->specifyTypesFromAsserts($context, $expr, $asserts, $parametersAcceptor, $scope); if ($specifiedTypes !== null) { return $specifiedTypes; } } } return $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope); } elseif ($expr instanceof MethodCall && $expr->name instanceof Node\Identifier) { $methodCalledOnType = $scope->getType($expr->var); $methodReflection = $scope->getMethodReflection($methodCalledOnType, $expr->name->name); if ($methodReflection !== null) { $referencedClasses = $methodCalledOnType->getObjectClassNames(); if (count($referencedClasses) === 1 && $this->reflectionProvider->hasClass($referencedClasses[0])) { $methodClassReflection = $this->reflectionProvider->getClass($referencedClasses[0]); foreach ($this->getMethodTypeSpecifyingExtensionsForClass($methodClassReflection->getName()) as $extension) { if (!$extension->isMethodSupported($methodReflection, $expr, $context)) { continue; } return $extension->specifyTypes($methodReflection, $expr, $scope, $context); } } // lazy create parametersAcceptor, as creation can be expensive $parametersAcceptor = null; if (count($expr->getArgs()) > 0) { $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $methodReflection->getVariants(), $methodReflection->getNamedArgumentsVariants()); $specifiedTypes = $this->specifyTypesFromConditionalReturnType($context, $expr, $parametersAcceptor, $scope); if ($specifiedTypes !== null) { return $specifiedTypes; } } $assertions = $methodReflection->getAsserts(); if ($assertions->getAll() !== []) { $parametersAcceptor = $parametersAcceptor ?? ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $methodReflection->getVariants(), $methodReflection->getNamedArgumentsVariants()); $asserts = $assertions->mapTypes(static function (Type $type) use($parametersAcceptor) { return TemplateTypeHelper::resolveTemplateTypes($type, $parametersAcceptor->getResolvedTemplateTypeMap(), $parametersAcceptor instanceof ParametersAcceptorWithPhpDocs ? $parametersAcceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(), TemplateTypeVariance::createInvariant()); }); $specifiedTypes = $this->specifyTypesFromAsserts($context, $expr, $asserts, $parametersAcceptor, $scope); if ($specifiedTypes !== null) { return $specifiedTypes; } } } return $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope); } elseif ($expr instanceof StaticCall && $expr->name instanceof Node\Identifier) { if ($expr->class instanceof Name) { $calleeType = $scope->resolveTypeByName($expr->class); } else { $calleeType = $scope->getType($expr->class); } $staticMethodReflection = $scope->getMethodReflection($calleeType, $expr->name->name); if ($staticMethodReflection !== null) { $referencedClasses = $calleeType->getObjectClassNames(); if (count($referencedClasses) === 1 && $this->reflectionProvider->hasClass($referencedClasses[0])) { $staticMethodClassReflection = $this->reflectionProvider->getClass($referencedClasses[0]); foreach ($this->getStaticMethodTypeSpecifyingExtensionsForClass($staticMethodClassReflection->getName()) as $extension) { if (!$extension->isStaticMethodSupported($staticMethodReflection, $expr, $context)) { continue; } return $extension->specifyTypes($staticMethodReflection, $expr, $scope, $context); } } // lazy create parametersAcceptor, as creation can be expensive $parametersAcceptor = null; if (count($expr->getArgs()) > 0) { $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $staticMethodReflection->getVariants(), $staticMethodReflection->getNamedArgumentsVariants()); $specifiedTypes = $this->specifyTypesFromConditionalReturnType($context, $expr, $parametersAcceptor, $scope); if ($specifiedTypes !== null) { return $specifiedTypes; } } $assertions = $staticMethodReflection->getAsserts(); if ($assertions->getAll() !== []) { $parametersAcceptor = $parametersAcceptor ?? ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $staticMethodReflection->getVariants(), $staticMethodReflection->getNamedArgumentsVariants()); $asserts = $assertions->mapTypes(static function (Type $type) use($parametersAcceptor) { return TemplateTypeHelper::resolveTemplateTypes($type, $parametersAcceptor->getResolvedTemplateTypeMap(), $parametersAcceptor instanceof ParametersAcceptorWithPhpDocs ? $parametersAcceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(), TemplateTypeVariance::createInvariant()); }); $specifiedTypes = $this->specifyTypesFromAsserts($context, $expr, $asserts, $parametersAcceptor, $scope); if ($specifiedTypes !== null) { return $specifiedTypes; } } } return $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope); } elseif ($expr instanceof BooleanAnd || $expr instanceof LogicalAnd) { if (!$scope instanceof \PHPStan\Analyser\MutatingScope) { throw new ShouldNotHappenException(); } $leftTypes = $this->specifyTypesInCondition($scope, $expr->left, $context, $rootExpr); $rightScope = $scope->filterByTruthyValue($expr->left); $rightTypes = $this->specifyTypesInCondition($rightScope, $expr->right, $context, $rootExpr); $types = $context->true() ? $leftTypes->unionWith($rightTypes) : $leftTypes->normalize($scope)->intersectWith($rightTypes->normalize($rightScope)); if ($context->false()) { return new \PHPStan\Analyser\SpecifiedTypes($types->getSureTypes(), $types->getSureNotTypes(), \false, array_merge($this->processBooleanNotSureConditionalTypes($scope, $leftTypes, $rightTypes), $this->processBooleanNotSureConditionalTypes($scope, $rightTypes, $leftTypes), $this->processBooleanSureConditionalTypes($scope, $leftTypes, $rightTypes), $this->processBooleanSureConditionalTypes($scope, $rightTypes, $leftTypes)), $rootExpr); } return $types; } elseif ($expr instanceof BooleanOr || $expr instanceof LogicalOr) { if (!$scope instanceof \PHPStan\Analyser\MutatingScope) { throw new ShouldNotHappenException(); } $leftTypes = $this->specifyTypesInCondition($scope, $expr->left, $context, $rootExpr); $rightScope = $scope->filterByFalseyValue($expr->left); $rightTypes = $this->specifyTypesInCondition($rightScope, $expr->right, $context, $rootExpr); $types = $context->true() ? $leftTypes->normalize($scope)->intersectWith($rightTypes->normalize($rightScope)) : $leftTypes->unionWith($rightTypes); if ($context->true()) { return new \PHPStan\Analyser\SpecifiedTypes($types->getSureTypes(), $types->getSureNotTypes(), \false, array_merge($this->processBooleanNotSureConditionalTypes($scope, $leftTypes, $rightTypes), $this->processBooleanNotSureConditionalTypes($scope, $rightTypes, $leftTypes), $this->processBooleanSureConditionalTypes($scope, $leftTypes, $rightTypes), $this->processBooleanSureConditionalTypes($scope, $rightTypes, $leftTypes)), $rootExpr); } return $types; } elseif ($expr instanceof Node\Expr\BooleanNot && !$context->null()) { return $this->specifyTypesInCondition($scope, $expr->expr, $context->negate(), $rootExpr); } elseif ($expr instanceof Node\Expr\Assign) { if (!$scope instanceof \PHPStan\Analyser\MutatingScope) { throw new ShouldNotHappenException(); } if ($context->null()) { return $this->specifyTypesInCondition($scope->exitFirstLevelStatements(), $expr->expr, $context, $rootExpr); } return $this->specifyTypesInCondition($scope->exitFirstLevelStatements(), $expr->var, $context, $rootExpr); } elseif ($expr instanceof Expr\Isset_ && count($expr->vars) > 0 && !$context->null()) { // rewrite multi param isset() to and-chained single param isset() if (count($expr->vars) > 1) { $issets = []; foreach ($expr->vars as $var) { $issets[] = new Expr\Isset_([$var], $expr->getAttributes()); } $first = array_shift($issets); $andChain = null; foreach ($issets as $isset) { if ($andChain === null) { $andChain = new BooleanAnd($first, $isset); continue; } $andChain = new BooleanAnd($andChain, $isset); } if ($andChain === null) { throw new ShouldNotHappenException(); } return $this->specifyTypesInCondition($scope, $andChain, $context, $rootExpr); } $issetExpr = $expr->vars[0]; if (!$context->true()) { if (!$scope instanceof \PHPStan\Analyser\MutatingScope) { throw new ShouldNotHappenException(); } $isset = $scope->issetCheck($issetExpr, static function () { return \true; }); if ($isset === \false) { return new \PHPStan\Analyser\SpecifiedTypes(); } $type = $scope->getType($issetExpr); $isNullable = !$type->isNull()->no(); $exprType = $this->create($issetExpr, new NullType(), $context->negate(), \false, $scope, $rootExpr); if ($issetExpr instanceof Expr\Variable && is_string($issetExpr->name)) { if ($isset === \true) { if ($isNullable) { return $exprType; } // variable cannot exist in !isset() return $exprType->unionWith($this->create(new IssetExpr($issetExpr), new NullType(), $context, \false, $scope, $rootExpr)); } if ($isNullable) { // reduces variable certainty to maybe return $exprType->unionWith($this->create(new IssetExpr($issetExpr), new NullType(), $context->negate(), \false, $scope, $rootExpr)); } // variable cannot exist in !isset() return $this->create(new IssetExpr($issetExpr), new NullType(), $context, \false, $scope, $rootExpr); } if ($isNullable && $isset === \true) { return $exprType; } return new \PHPStan\Analyser\SpecifiedTypes(); } $tmpVars = [$issetExpr]; while ($issetExpr instanceof ArrayDimFetch || $issetExpr instanceof PropertyFetch || $issetExpr instanceof StaticPropertyFetch && $issetExpr->class instanceof Expr) { if ($issetExpr instanceof StaticPropertyFetch) { /** @var Expr $issetExpr */ $issetExpr = $issetExpr->class; } else { $issetExpr = $issetExpr->var; } $tmpVars[] = $issetExpr; } $vars = array_reverse($tmpVars); $types = new \PHPStan\Analyser\SpecifiedTypes(); foreach ($vars as $var) { if ($var instanceof Expr\Variable && is_string($var->name)) { if ($scope->hasVariableType($var->name)->no()) { return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } } if ($var instanceof ArrayDimFetch && $var->dim !== null && !$scope->getType($var->var) instanceof MixedType) { $dimType = $scope->getType($var->dim); if ($dimType instanceof ConstantIntegerType || $dimType instanceof ConstantStringType) { $types = $types->unionWith($this->create($var->var, new HasOffsetType($dimType), $context, \false, $scope, $rootExpr)); } else { $varType = $scope->getType($var->var); $narrowedKey = AllowedArrayKeysTypes::narrowOffsetKeyType($varType, $dimType); if ($narrowedKey !== null) { $types = $types->unionWith($this->create($var->dim, $narrowedKey, $context, \false, $scope, $rootExpr)); } } } if ($var instanceof PropertyFetch && $var->name instanceof Node\Identifier) { $types = $types->unionWith($this->create($var->var, new IntersectionType([new ObjectWithoutClassType(), new HasPropertyType($var->name->toString())]), \PHPStan\Analyser\TypeSpecifierContext::createTruthy(), \false, $scope, $rootExpr)); } elseif ($var instanceof StaticPropertyFetch && $var->class instanceof Expr && $var->name instanceof Node\VarLikeIdentifier) { $types = $types->unionWith($this->create($var->class, new IntersectionType([new ObjectWithoutClassType(), new HasPropertyType($var->name->toString())]), \PHPStan\Analyser\TypeSpecifierContext::createTruthy(), \false, $scope, $rootExpr)); } $types = $types->unionWith($this->create($var, new NullType(), \PHPStan\Analyser\TypeSpecifierContext::createFalse(), \false, $scope, $rootExpr)); } return $types; } elseif ($expr instanceof Expr\BinaryOp\Coalesce && !$context->null()) { if (!$context->true()) { if (!$scope instanceof \PHPStan\Analyser\MutatingScope) { throw new ShouldNotHappenException(); } $isset = $scope->issetCheck($expr->left, static function () { return \true; }); if ($isset !== \true) { return new \PHPStan\Analyser\SpecifiedTypes(); } return $this->create($expr->left, new NullType(), $context->negate(), \false, $scope, $rootExpr); } if ((new ConstantBooleanType(\false))->isSuperTypeOf($scope->getType($expr->right)->toBoolean())->yes()) { return $this->create($expr->left, new NullType(), \PHPStan\Analyser\TypeSpecifierContext::createFalse(), \false, $scope, $rootExpr); } } elseif ($expr instanceof Expr\Empty_) { if (!$scope instanceof \PHPStan\Analyser\MutatingScope) { throw new ShouldNotHappenException(); } $isset = $scope->issetCheck($expr->expr, static function () { return \true; }); if ($isset === \false) { return new \PHPStan\Analyser\SpecifiedTypes(); } return $this->specifyTypesInCondition($scope, new BooleanOr(new Expr\BooleanNot(new Expr\Isset_([$expr->expr])), new Expr\BooleanNot($expr->expr)), $context, $rootExpr); } elseif ($expr instanceof Expr\ErrorSuppress) { return $this->specifyTypesInCondition($scope, $expr->expr, $context, $rootExpr); } elseif ($expr instanceof Expr\Ternary && !$context->null() && $scope->getType($expr->else)->isFalse()->yes()) { $conditionExpr = $expr->cond; if ($expr->if !== null) { $conditionExpr = new BooleanAnd($conditionExpr, $expr->if); } return $this->specifyTypesInCondition($scope, $conditionExpr, $context, $rootExpr); } elseif ($expr instanceof Expr\NullsafePropertyFetch && !$context->null()) { $types = $this->specifyTypesInCondition($scope, new BooleanAnd(new Expr\BinaryOp\NotIdentical($expr->var, new ConstFetch(new Name('null'))), new PropertyFetch($expr->var, $expr->name)), $context, $rootExpr); $nullSafeTypes = $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope); return $context->true() ? $types->unionWith($nullSafeTypes) : $types->normalize($scope)->intersectWith($nullSafeTypes->normalize($scope)); } elseif ($expr instanceof Expr\NullsafeMethodCall && !$context->null()) { $types = $this->specifyTypesInCondition($scope, new BooleanAnd(new Expr\BinaryOp\NotIdentical($expr->var, new ConstFetch(new Name('null'))), new MethodCall($expr->var, $expr->name, $expr->args)), $context, $rootExpr); $nullSafeTypes = $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope); return $context->true() ? $types->unionWith($nullSafeTypes) : $types->normalize($scope)->intersectWith($nullSafeTypes->normalize($scope)); } elseif ($expr instanceof Expr\New_ && $expr->class instanceof Name && $this->reflectionProvider->hasClass($expr->class->toString())) { $classReflection = $this->reflectionProvider->getClass($expr->class->toString()); if ($classReflection->hasConstructor()) { $methodReflection = $classReflection->getConstructor(); $asserts = $methodReflection->getAsserts(); if ($asserts->getAll() !== []) { $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $methodReflection->getVariants(), $methodReflection->getNamedArgumentsVariants()); $asserts = $asserts->mapTypes(static function (Type $type) use($parametersAcceptor) { return TemplateTypeHelper::resolveTemplateTypes($type, $parametersAcceptor->getResolvedTemplateTypeMap(), $parametersAcceptor instanceof ParametersAcceptorWithPhpDocs ? $parametersAcceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(), TemplateTypeVariance::createInvariant()); }); $specifiedTypes = $this->specifyTypesFromAsserts($context, $expr, $asserts, $parametersAcceptor, $scope); if ($specifiedTypes !== null) { return $specifiedTypes; } } } } elseif (!$context->null()) { return $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope); } return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } private function narrowUnionByArraySize(FuncCall $countFuncCall, UnionType $argType, ?Type $sizeType, \PHPStan\Analyser\TypeSpecifierContext $context, \PHPStan\Analyser\Scope $scope, ?Expr $rootExpr) : ?\PHPStan\Analyser\SpecifiedTypes { if ($sizeType === null) { return null; } if (count($countFuncCall->getArgs()) === 1) { $isNormalCount = TrinaryLogic::createYes(); } else { $mode = $scope->getType($countFuncCall->getArgs()[1]->value); $isNormalCount = (new ConstantIntegerType(COUNT_NORMAL))->isSuperTypeOf($mode)->or($argType->getIterableValueType()->isArray()->negate()); } if ($isNormalCount->yes() && $argType->isConstantArray()->yes()) { $result = []; foreach ($argType->getTypes() as $innerType) { $arraySize = $innerType->getArraySize(); $isSize = $sizeType->isSuperTypeOf($arraySize); if ($context->truthy()) { if ($isSize->no()) { continue; } $constArray = $this->turnListIntoConstantArray($countFuncCall, $innerType, $sizeType, $scope); if ($constArray !== null) { $innerType = $constArray; } } if ($context->falsey()) { if (!$isSize->yes()) { continue; } } $result[] = $innerType; } return $this->create($countFuncCall->getArgs()[0]->value, TypeCombinator::union(...$result), $context, \false, $scope, $rootExpr); } return null; } private function turnListIntoConstantArray(FuncCall $countFuncCall, Type $type, Type $sizeType, \PHPStan\Analyser\Scope $scope) : ?Type { $argType = $scope->getType($countFuncCall->getArgs()[0]->value); if (count($countFuncCall->getArgs()) === 1) { $isNormalCount = TrinaryLogic::createYes(); } else { $mode = $scope->getType($countFuncCall->getArgs()[1]->value); $isNormalCount = (new ConstantIntegerType(COUNT_NORMAL))->isSuperTypeOf($mode)->or($argType->getIterableValueType()->isArray()->negate()); } if ($isNormalCount->yes() && $type->isList()->yes() && $sizeType instanceof ConstantIntegerType && $sizeType->getValue() < ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) { // turn optional offsets non-optional $valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty(); for ($i = 0; $i < $sizeType->getValue(); $i++) { $offsetType = new ConstantIntegerType($i); $valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType)); } return $valueTypesBuilder->getArray(); } if ($isNormalCount->yes() && $type->isList()->yes() && $sizeType instanceof IntegerRangeType && $sizeType->getMin() !== null) { // turn optional offsets non-optional $valueTypesBuilder = ConstantArrayTypeBuilder::createEmpty(); for ($i = 0; $i < $sizeType->getMin(); $i++) { $offsetType = new ConstantIntegerType($i); $valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType)); } if ($sizeType->getMax() !== null) { for ($i = $sizeType->getMin(); $i < $sizeType->getMax(); $i++) { $offsetType = new ConstantIntegerType($i); $valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType), \true); } } elseif ($type->isConstantArray()->yes()) { for ($i = $sizeType->getMin();; $i++) { $offsetType = new ConstantIntegerType($i); $hasOffset = $type->hasOffsetValueType($offsetType); if ($hasOffset->no()) { break; } $valueTypesBuilder->setOffsetValueType($offsetType, $type->getOffsetValueType($offsetType), !$hasOffset->yes()); } } else { return null; } $arrayType = $valueTypesBuilder->getArray(); if ($arrayType->isIterableAtLeastOnce()->yes()) { return $arrayType; } } return null; } private function specifyTypesForConstantBinaryExpression(Expr $exprNode, Type $constantType, \PHPStan\Analyser\TypeSpecifierContext $context, \PHPStan\Analyser\Scope $scope, ?Expr $rootExpr) : ?\PHPStan\Analyser\SpecifiedTypes { if (!$context->null() && $constantType->isFalse()->yes()) { $types = $this->create($exprNode, $constantType, $context, \false, $scope, $rootExpr); if (!$context->true() && ($exprNode instanceof Expr\NullsafeMethodCall || $exprNode instanceof Expr\NullsafePropertyFetch)) { return $types; } return $types->unionWith($this->specifyTypesInCondition($scope, $exprNode, $context->true() ? \PHPStan\Analyser\TypeSpecifierContext::createFalse() : \PHPStan\Analyser\TypeSpecifierContext::createFalse()->negate(), $rootExpr)); } if (!$context->null() && $constantType->isTrue()->yes()) { $types = $this->create($exprNode, $constantType, $context, \false, $scope, $rootExpr); if (!$context->true() && ($exprNode instanceof Expr\NullsafeMethodCall || $exprNode instanceof Expr\NullsafePropertyFetch)) { return $types; } return $types->unionWith($this->specifyTypesInCondition($scope, $exprNode, $context->true() ? \PHPStan\Analyser\TypeSpecifierContext::createTrue() : \PHPStan\Analyser\TypeSpecifierContext::createTrue()->negate(), $rootExpr)); } return null; } private function specifyTypesForConstantStringBinaryExpression(Expr $exprNode, Type $constantType, \PHPStan\Analyser\TypeSpecifierContext $context, \PHPStan\Analyser\Scope $scope, ?Expr $rootExpr) : ?\PHPStan\Analyser\SpecifiedTypes { $scalarValues = $constantType->getConstantScalarValues(); if (count($scalarValues) !== 1 || !is_string($scalarValues[0])) { return null; } $constantStringValue = $scalarValues[0]; if ($exprNode instanceof FuncCall && $exprNode->name instanceof Name && strtolower($exprNode->name->toString()) === 'gettype' && isset($exprNode->getArgs()[0])) { $type = null; if ($constantStringValue === 'string') { $type = new StringType(); } if ($constantStringValue === 'array') { $type = new ArrayType(new MixedType(), new MixedType()); } if ($constantStringValue === 'boolean') { $type = new BooleanType(); } if (in_array($constantStringValue, ['resource', 'resource (closed)'], \true)) { $type = new ResourceType(); } if ($constantStringValue === 'integer') { $type = new IntegerType(); } if ($constantStringValue === 'double') { $type = new FloatType(); } if ($constantStringValue === 'NULL') { $type = new NullType(); } if ($constantStringValue === 'object') { $type = new ObjectWithoutClassType(); } if ($type !== null) { $callType = $this->create($exprNode, $constantType, $context, \false, $scope, $rootExpr); $argType = $this->create($exprNode->getArgs()[0]->value, $type, $context, \false, $scope, $rootExpr); return $callType->unionWith($argType); } } if ($context->true() && $exprNode instanceof FuncCall && $exprNode->name instanceof Name && strtolower((string) $exprNode->name) === 'get_parent_class' && isset($exprNode->getArgs()[0])) { $argType = $scope->getType($exprNode->getArgs()[0]->value); $objectType = new ObjectType($constantStringValue); $classStringType = new GenericClassStringType($objectType); if ($argType->isString()->yes()) { return $this->create($exprNode->getArgs()[0]->value, $classStringType, $context, \false, $scope); } if ($argType->isObject()->yes()) { return $this->create($exprNode->getArgs()[0]->value, $objectType, $context, \false, $scope); } return $this->create($exprNode->getArgs()[0]->value, TypeCombinator::union($objectType, $classStringType), $context, \false, $scope); } return null; } private function handleDefaultTruthyOrFalseyContext(\PHPStan\Analyser\TypeSpecifierContext $context, ?Expr $rootExpr, Expr $expr, \PHPStan\Analyser\Scope $scope) : \PHPStan\Analyser\SpecifiedTypes { if ($context->null()) { return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } if (!$context->truthy()) { $type = StaticTypeFactory::truthy(); return $this->create($expr, $type, \PHPStan\Analyser\TypeSpecifierContext::createFalse(), \false, $scope, $rootExpr); } elseif (!$context->falsey()) { $type = StaticTypeFactory::falsey(); return $this->create($expr, $type, \PHPStan\Analyser\TypeSpecifierContext::createFalse(), \false, $scope, $rootExpr); } return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } private function specifyTypesFromConditionalReturnType(\PHPStan\Analyser\TypeSpecifierContext $context, Expr\CallLike $call, ParametersAcceptor $parametersAcceptor, \PHPStan\Analyser\Scope $scope) : ?\PHPStan\Analyser\SpecifiedTypes { if (!$parametersAcceptor instanceof ResolvedFunctionVariant) { return null; } $returnType = $parametersAcceptor->getOriginalParametersAcceptor()->getReturnType(); if (!$returnType instanceof ConditionalTypeForParameter) { return null; } if ($context->true()) { $leftType = new ConstantBooleanType(\true); $rightType = new ConstantBooleanType(\false); } elseif ($context->false()) { $leftType = new ConstantBooleanType(\false); $rightType = new ConstantBooleanType(\true); } elseif ($context->null()) { $leftType = new MixedType(); $rightType = new NeverType(); } else { return null; } $argsMap = []; $parameters = $parametersAcceptor->getParameters(); foreach ($call->getArgs() as $i => $arg) { if ($arg->unpack) { continue; } if ($arg->name !== null) { $paramName = $arg->name->toString(); } elseif (isset($parameters[$i])) { $paramName = $parameters[$i]->getName(); } else { continue; } $argsMap['$' . $paramName] = $arg->value; } return $this->getConditionalSpecifiedTypes($returnType, $leftType, $rightType, $scope, $argsMap); } /** * @param array $argsMap */ public function getConditionalSpecifiedTypes(ConditionalTypeForParameter $conditionalType, Type $leftType, Type $rightType, \PHPStan\Analyser\Scope $scope, array $argsMap) : ?\PHPStan\Analyser\SpecifiedTypes { $parameterName = $conditionalType->getParameterName(); if (!array_key_exists($parameterName, $argsMap)) { return null; } $targetType = $conditionalType->getTarget(); $ifType = $conditionalType->getIf(); $elseType = $conditionalType->getElse(); if ($leftType->isSuperTypeOf($ifType)->yes() && $rightType->isSuperTypeOf($elseType)->yes()) { $context = $conditionalType->isNegated() ? \PHPStan\Analyser\TypeSpecifierContext::createFalse() : \PHPStan\Analyser\TypeSpecifierContext::createTrue(); } elseif ($leftType->isSuperTypeOf($elseType)->yes() && $rightType->isSuperTypeOf($ifType)->yes()) { $context = $conditionalType->isNegated() ? \PHPStan\Analyser\TypeSpecifierContext::createTrue() : \PHPStan\Analyser\TypeSpecifierContext::createFalse(); } else { return null; } $specifiedTypes = $this->create($argsMap[$parameterName], $targetType, $context, \false, $scope); if ($targetType instanceof ConstantBooleanType) { if (!$targetType->getValue()) { $context = $context->negate(); } $specifiedTypes = $specifiedTypes->unionWith($this->specifyTypesInCondition($scope, $argsMap[$parameterName], $context)); } return $specifiedTypes; } private function specifyTypesFromAsserts(\PHPStan\Analyser\TypeSpecifierContext $context, Expr\CallLike $call, Assertions $assertions, ParametersAcceptor $parametersAcceptor, \PHPStan\Analyser\Scope $scope) : ?\PHPStan\Analyser\SpecifiedTypes { if ($context->null()) { $asserts = $assertions->getAsserts(); } elseif ($context->true()) { $asserts = $assertions->getAssertsIfTrue(); } elseif ($context->false()) { $asserts = $assertions->getAssertsIfFalse(); } else { throw new ShouldNotHappenException(); } if (count($asserts) === 0) { return null; } $argsMap = []; $parameters = $parametersAcceptor->getParameters(); foreach ($call->getArgs() as $i => $arg) { if ($arg->unpack) { continue; } if ($arg->name !== null) { $paramName = $arg->name->toString(); } elseif (isset($parameters[$i])) { $paramName = $parameters[$i]->getName(); } elseif (count($parameters) > 0 && $parametersAcceptor->isVariadic()) { $lastParameter = $parameters[count($parameters) - 1]; $paramName = $lastParameter->getName(); } else { continue; } $argsMap[$paramName][] = $arg->value; } if ($call instanceof MethodCall) { $argsMap['this'] = [$call->var]; } /** @var SpecifiedTypes|null $types */ $types = null; foreach ($asserts as $assert) { foreach ($argsMap[substr($assert->getParameter()->getParameterName(), 1)] ?? [] as $parameterExpr) { $assertedType = TypeTraverser::map($assert->getType(), static function (Type $type, callable $traverse) use($argsMap, $scope) : Type { if ($type instanceof ConditionalTypeForParameter) { $parameterName = substr($type->getParameterName(), 1); if (array_key_exists($parameterName, $argsMap)) { $argType = TypeCombinator::union(...array_map(static function (Expr $expr) use($scope) { return $scope->getType($expr); }, $argsMap[$parameterName])); $type = $type->toConditional($argType); } } return $traverse($type); }); $assertExpr = $assert->getParameter()->getExpr($parameterExpr); $templateTypeMap = $parametersAcceptor->getResolvedTemplateTypeMap(); $containsUnresolvedTemplate = \false; TypeTraverser::map($assert->getOriginalType(), static function (Type $type, callable $traverse) use($templateTypeMap, &$containsUnresolvedTemplate) { if ($type instanceof TemplateType && $type->getScope()->getClassName() !== null) { $resolvedType = $templateTypeMap->getType($type->getName()); if ($resolvedType === null || $type->getBound()->equals($resolvedType)) { $containsUnresolvedTemplate = \true; return $type; } } return $traverse($type); }); $newTypes = $this->create($assertExpr, $assertedType, $assert->isNegated() ? \PHPStan\Analyser\TypeSpecifierContext::createFalse() : \PHPStan\Analyser\TypeSpecifierContext::createTrue(), \false, $scope, $containsUnresolvedTemplate || $assert->isEquality() ? $call : null); $types = $types !== null ? $types->unionWith($newTypes) : $newTypes; if (!$context->null() || !$assertedType instanceof ConstantBooleanType) { continue; } $subContext = $assertedType->getValue() ? \PHPStan\Analyser\TypeSpecifierContext::createTrue() : \PHPStan\Analyser\TypeSpecifierContext::createFalse(); if ($assert->isNegated()) { $subContext = $subContext->negate(); } $types = $types->unionWith($this->specifyTypesInCondition($scope, $assertExpr, $subContext)); } } return $types; } /** * @return array */ private function processBooleanSureConditionalTypes(\PHPStan\Analyser\Scope $scope, \PHPStan\Analyser\SpecifiedTypes $leftTypes, \PHPStan\Analyser\SpecifiedTypes $rightTypes) : array { $conditionExpressionTypes = []; foreach ($leftTypes->getSureTypes() as $exprString => [$expr, $type]) { if (!$expr instanceof Expr\Variable) { continue; } if (!is_string($expr->name)) { continue; } $conditionExpressionTypes[$exprString] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($expr, TypeCombinator::remove($scope->getType($expr), $type)); } if (count($conditionExpressionTypes) > 0) { $holders = []; foreach ($rightTypes->getSureTypes() as $exprString => [$expr, $type]) { if (!$expr instanceof Expr\Variable) { continue; } if (!is_string($expr->name)) { continue; } if (!isset($holders[$exprString])) { $holders[$exprString] = []; } $conditions = $conditionExpressionTypes; foreach ($conditions as $conditionExprString => $conditionExprTypeHolder) { $conditionExpr = $conditionExprTypeHolder->getExpr(); if (!$conditionExpr instanceof Expr\Variable) { continue; } if (!is_string($conditionExpr->name)) { continue; } if ($conditionExpr->name !== $expr->name) { continue; } unset($conditions[$conditionExprString]); } if (count($conditions) === 0) { continue; } $holder = new \PHPStan\Analyser\ConditionalExpressionHolder($conditions, new \PHPStan\Analyser\ExpressionTypeHolder($expr, TypeCombinator::intersect($scope->getType($expr), $type), TrinaryLogic::createYes())); $holders[$exprString][$holder->getKey()] = $holder; } return $holders; } return []; } /** * @return array */ private function processBooleanNotSureConditionalTypes(\PHPStan\Analyser\Scope $scope, \PHPStan\Analyser\SpecifiedTypes $leftTypes, \PHPStan\Analyser\SpecifiedTypes $rightTypes) : array { $conditionExpressionTypes = []; foreach ($leftTypes->getSureNotTypes() as $exprString => [$expr, $type]) { if (!$expr instanceof Expr\Variable) { continue; } if (!is_string($expr->name)) { continue; } $conditionExpressionTypes[$exprString] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($expr, TypeCombinator::intersect($scope->getType($expr), $type)); } if (count($conditionExpressionTypes) > 0) { $holders = []; foreach ($rightTypes->getSureNotTypes() as $exprString => [$expr, $type]) { if (!$expr instanceof Expr\Variable) { continue; } if (!is_string($expr->name)) { continue; } if (!isset($holders[$exprString])) { $holders[$exprString] = []; } $conditions = $conditionExpressionTypes; foreach ($conditions as $conditionExprString => $conditionExprTypeHolder) { $conditionExpr = $conditionExprTypeHolder->getExpr(); if (!$conditionExpr instanceof Expr\Variable) { continue; } if (!is_string($conditionExpr->name)) { continue; } if ($conditionExpr->name !== $expr->name) { continue; } unset($conditions[$conditionExprString]); } if (count($conditions) === 0) { continue; } $holder = new \PHPStan\Analyser\ConditionalExpressionHolder($conditions, new \PHPStan\Analyser\ExpressionTypeHolder($expr, TypeCombinator::remove($scope->getType($expr), $type), TrinaryLogic::createYes())); $holders[$exprString][$holder->getKey()] = $holder; } return $holders; } return []; } /** * @return array{Expr, ConstantScalarType, Type}|null */ private function findTypeExpressionsFromBinaryOperation(\PHPStan\Analyser\Scope $scope, Node\Expr\BinaryOp $binaryOperation) : ?array { $leftType = $scope->getType($binaryOperation->left); $rightType = $scope->getType($binaryOperation->right); $rightExpr = $binaryOperation->right; if ($rightExpr instanceof AlwaysRememberedExpr) { $rightExpr = $rightExpr->getExpr(); } $leftExpr = $binaryOperation->left; if ($leftExpr instanceof AlwaysRememberedExpr) { $leftExpr = $leftExpr->getExpr(); } if ($leftType instanceof ConstantScalarType && !$rightExpr instanceof ConstFetch && !$rightExpr instanceof ClassConstFetch) { return [$binaryOperation->right, $leftType, $rightType]; } elseif ($rightType instanceof ConstantScalarType && !$leftExpr instanceof ConstFetch && !$leftExpr instanceof ClassConstFetch) { return [$binaryOperation->left, $rightType, $leftType]; } return null; } /** @api */ public function create(Expr $expr, Type $type, \PHPStan\Analyser\TypeSpecifierContext $context, bool $overwrite = \false, ?\PHPStan\Analyser\Scope $scope = null, ?Expr $rootExpr = null) : \PHPStan\Analyser\SpecifiedTypes { if ($expr instanceof Instanceof_ || $expr instanceof Expr\List_) { return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } $specifiedExprs = []; if ($expr instanceof AlwaysRememberedExpr) { $specifiedExprs[] = $expr; $expr = $expr->expr; } if ($expr instanceof Expr\Assign) { $specifiedExprs[] = $expr->var; $specifiedExprs[] = $expr->expr; while ($expr->expr instanceof Expr\Assign) { $specifiedExprs[] = $expr->expr->var; $expr = $expr->expr; } } elseif ($expr instanceof Expr\AssignOp\Coalesce) { $specifiedExprs[] = $expr->var; } else { $specifiedExprs[] = $expr; } $types = null; foreach ($specifiedExprs as $specifiedExpr) { $newTypes = $this->createForExpr($specifiedExpr, $type, $context, $overwrite, $scope, $rootExpr); if ($types === null) { $types = $newTypes; } else { $types = $types->unionWith($newTypes); } } return $types; } private function createForExpr(Expr $expr, Type $type, \PHPStan\Analyser\TypeSpecifierContext $context, bool $overwrite = \false, ?\PHPStan\Analyser\Scope $scope = null, ?Expr $rootExpr = null) : \PHPStan\Analyser\SpecifiedTypes { if ($scope !== null) { if ($context->true()) { $containsNull = !$type->isNull()->no() && !$scope->getType($expr)->isNull()->no(); } elseif ($context->false()) { $containsNull = !TypeCombinator::containsNull($type) && !$scope->getType($expr)->isNull()->no(); } } $originalExpr = $expr; if (isset($containsNull) && !$containsNull) { $expr = \PHPStan\Analyser\NullsafeOperatorHelper::getNullsafeShortcircuitedExpr($expr); } if ($scope !== null && !$context->null() && $expr instanceof Expr\BinaryOp\Coalesce) { $rightIsSuperType = $type->isSuperTypeOf($scope->getType($expr->right)); if ($context->true() && $rightIsSuperType->no() || $context->false() && $rightIsSuperType->yes()) { $expr = $expr->left; } } if ($expr instanceof FuncCall && $expr->name instanceof Name) { $has = $this->reflectionProvider->hasFunction($expr->name, $scope); if (!$has) { // backwards compatibility with previous behaviour return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } $functionReflection = $this->reflectionProvider->getFunction($expr->name, $scope); $hasSideEffects = $functionReflection->hasSideEffects(); if ($hasSideEffects->yes()) { return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } if (!$this->rememberPossiblyImpureFunctionValues && !$hasSideEffects->no()) { return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } } if ($expr instanceof MethodCall && $expr->name instanceof Node\Identifier && $scope !== null) { $methodName = $expr->name->toString(); $calledOnType = $scope->getType($expr->var); $methodReflection = $scope->getMethodReflection($calledOnType, $methodName); if ($methodReflection === null || $methodReflection->hasSideEffects()->yes() || !$this->rememberPossiblyImpureFunctionValues && !$methodReflection->hasSideEffects()->no()) { if (isset($containsNull) && !$containsNull) { return $this->createNullsafeTypes($rootExpr, $originalExpr, $scope, $context, $overwrite, $type); } return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } } if ($expr instanceof StaticCall && $expr->name instanceof Node\Identifier && $scope !== null) { $methodName = $expr->name->toString(); if ($expr->class instanceof Name) { $calledOnType = $scope->resolveTypeByName($expr->class); } else { $calledOnType = $scope->getType($expr->class); } $methodReflection = $scope->getMethodReflection($calledOnType, $methodName); if ($methodReflection === null || $methodReflection->hasSideEffects()->yes() || !$this->rememberPossiblyImpureFunctionValues && !$methodReflection->hasSideEffects()->no()) { if (isset($containsNull) && !$containsNull) { return $this->createNullsafeTypes($rootExpr, $originalExpr, $scope, $context, $overwrite, $type); } return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } } $sureTypes = []; $sureNotTypes = []; $exprString = $this->exprPrinter->printExpr($expr); $originalExprString = $this->exprPrinter->printExpr($originalExpr); if ($context->false()) { $sureNotTypes[$exprString] = [$expr, $type]; if ($exprString !== $originalExprString) { $sureNotTypes[$originalExprString] = [$originalExpr, $type]; } } elseif ($context->true()) { $sureTypes[$exprString] = [$expr, $type]; if ($exprString !== $originalExprString) { $sureTypes[$originalExprString] = [$originalExpr, $type]; } } $types = new \PHPStan\Analyser\SpecifiedTypes($sureTypes, $sureNotTypes, $overwrite, [], $rootExpr); if ($scope !== null && isset($containsNull) && !$containsNull) { return $this->createNullsafeTypes($rootExpr, $originalExpr, $scope, $context, $overwrite, $type)->unionWith($types); } return $types; } private function createNullsafeTypes(?Expr $rootExpr, Expr $expr, \PHPStan\Analyser\Scope $scope, \PHPStan\Analyser\TypeSpecifierContext $context, bool $overwrite, ?Type $type) : \PHPStan\Analyser\SpecifiedTypes { if ($expr instanceof Expr\NullsafePropertyFetch) { if ($type !== null) { $propertyFetchTypes = $this->create(new PropertyFetch($expr->var, $expr->name), $type, $context, \false, $scope, $rootExpr); } else { $propertyFetchTypes = $this->create(new PropertyFetch($expr->var, $expr->name), new NullType(), \PHPStan\Analyser\TypeSpecifierContext::createFalse(), \false, $scope, $rootExpr); } return $propertyFetchTypes->unionWith($this->create($expr->var, new NullType(), \PHPStan\Analyser\TypeSpecifierContext::createFalse(), $overwrite, $scope, $rootExpr)); } if ($expr instanceof Expr\NullsafeMethodCall) { if ($type !== null) { $methodCallTypes = $this->create(new MethodCall($expr->var, $expr->name, $expr->args), $type, $context, $overwrite, $scope, $rootExpr); } else { $methodCallTypes = $this->create(new MethodCall($expr->var, $expr->name, $expr->args), new NullType(), \PHPStan\Analyser\TypeSpecifierContext::createFalse(), $overwrite, $scope, $rootExpr); } return $methodCallTypes->unionWith($this->create($expr->var, new NullType(), \PHPStan\Analyser\TypeSpecifierContext::createFalse(), $overwrite, $scope, $rootExpr)); } if ($expr instanceof Expr\PropertyFetch) { return $this->createNullsafeTypes($rootExpr, $expr->var, $scope, $context, $overwrite, null); } if ($expr instanceof Expr\MethodCall) { return $this->createNullsafeTypes($rootExpr, $expr->var, $scope, $context, $overwrite, null); } if ($expr instanceof Expr\ArrayDimFetch) { return $this->createNullsafeTypes($rootExpr, $expr->var, $scope, $context, $overwrite, null); } if ($expr instanceof Expr\StaticPropertyFetch && $expr->class instanceof Expr) { return $this->createNullsafeTypes($rootExpr, $expr->class, $scope, $context, $overwrite, null); } if ($expr instanceof Expr\StaticCall && $expr->class instanceof Expr) { return $this->createNullsafeTypes($rootExpr, $expr->class, $scope, $context, $overwrite, null); } return new \PHPStan\Analyser\SpecifiedTypes([], [], $overwrite, [], $rootExpr); } private function createRangeTypes(?Expr $rootExpr, Expr $expr, Type $type, \PHPStan\Analyser\TypeSpecifierContext $context) : \PHPStan\Analyser\SpecifiedTypes { $sureNotTypes = []; if ($type instanceof IntegerRangeType || $type instanceof ConstantIntegerType) { $exprString = $this->exprPrinter->printExpr($expr); if ($context->false()) { $sureNotTypes[$exprString] = [$expr, $type]; } elseif ($context->true()) { $inverted = TypeCombinator::remove(new IntegerType(), $type); $sureNotTypes[$exprString] = [$expr, $inverted]; } } return new \PHPStan\Analyser\SpecifiedTypes([], $sureNotTypes, \false, [], $rootExpr); } /** * @return FunctionTypeSpecifyingExtension[] */ private function getFunctionTypeSpecifyingExtensions() : array { return $this->functionTypeSpecifyingExtensions; } /** * @return MethodTypeSpecifyingExtension[] */ private function getMethodTypeSpecifyingExtensionsForClass(string $className) : array { if ($this->methodTypeSpecifyingExtensionsByClass === null) { $byClass = []; foreach ($this->methodTypeSpecifyingExtensions as $extension) { $byClass[$extension->getClass()][] = $extension; } $this->methodTypeSpecifyingExtensionsByClass = $byClass; } return $this->getTypeSpecifyingExtensionsForType($this->methodTypeSpecifyingExtensionsByClass, $className); } /** * @return StaticMethodTypeSpecifyingExtension[] */ private function getStaticMethodTypeSpecifyingExtensionsForClass(string $className) : array { if ($this->staticMethodTypeSpecifyingExtensionsByClass === null) { $byClass = []; foreach ($this->staticMethodTypeSpecifyingExtensions as $extension) { $byClass[$extension->getClass()][] = $extension; } $this->staticMethodTypeSpecifyingExtensionsByClass = $byClass; } return $this->getTypeSpecifyingExtensionsForType($this->staticMethodTypeSpecifyingExtensionsByClass, $className); } /** * @param MethodTypeSpecifyingExtension[][]|StaticMethodTypeSpecifyingExtension[][] $extensions * @return mixed[] */ private function getTypeSpecifyingExtensionsForType(array $extensions, string $className) : array { $extensionsForClass = [[]]; $class = $this->reflectionProvider->getClass($className); foreach (array_merge([$className], $class->getParentClassesNames(), $class->getNativeReflection()->getInterfaceNames()) as $extensionClassName) { if (!isset($extensions[$extensionClassName])) { continue; } $extensionsForClass[] = $extensions[$extensionClassName]; } return array_merge(...$extensionsForClass); } public function resolveEqual(Expr\BinaryOp\Equal $expr, \PHPStan\Analyser\Scope $scope, \PHPStan\Analyser\TypeSpecifierContext $context, ?Expr $rootExpr) : \PHPStan\Analyser\SpecifiedTypes { $expressions = $this->findTypeExpressionsFromBinaryOperation($scope, $expr); if ($expressions !== null) { $exprNode = $expressions[0]; $constantType = $expressions[1]; $otherType = $expressions[2]; if (!$context->null() && $constantType->getValue() === null) { $trueTypes = [new NullType(), new ConstantBooleanType(\false), new ConstantIntegerType(0), new ConstantFloatType(0.0), new ConstantStringType(''), new ConstantArrayType([], [])]; return $this->create($exprNode, new UnionType($trueTypes), $context, \false, $scope, $rootExpr); } if (!$context->null() && $constantType->getValue() === \false) { return $this->specifyTypesInCondition($scope, $exprNode, $context->true() ? \PHPStan\Analyser\TypeSpecifierContext::createFalsey() : \PHPStan\Analyser\TypeSpecifierContext::createFalsey()->negate(), $rootExpr); } if (!$context->null() && $constantType->getValue() === \true) { return $this->specifyTypesInCondition($scope, $exprNode, $context->true() ? \PHPStan\Analyser\TypeSpecifierContext::createTruthy() : \PHPStan\Analyser\TypeSpecifierContext::createTruthy()->negate(), $rootExpr); } if (!$context->null() && $constantType->getValue() === 0 && !$otherType->isInteger()->yes() && !$otherType->isBoolean()->yes()) { /* There is a difference between php 7.x and 8.x on the equality * behavior between zero and the empty string, so to be conservative * we leave it untouched regardless of the language version */ if ($context->true()) { $trueTypes = [new NullType(), new ConstantBooleanType(\false), new ConstantIntegerType(0), new ConstantFloatType(0.0), new StringType()]; } else { $trueTypes = [new NullType(), new ConstantBooleanType(\false), new ConstantIntegerType(0), new ConstantFloatType(0.0), new ConstantStringType('0')]; } return $this->create($exprNode, new UnionType($trueTypes), $context, \false, $scope, $rootExpr); } if (!$context->null() && $constantType->getValue() === '') { /* There is a difference between php 7.x and 8.x on the equality * behavior between zero and the empty string, so to be conservative * we leave it untouched regardless of the language version */ if ($context->true()) { $trueTypes = [new NullType(), new ConstantBooleanType(\false), new ConstantIntegerType(0), new ConstantFloatType(0.0), new ConstantStringType('')]; } else { $trueTypes = [new NullType(), new ConstantBooleanType(\false), new ConstantStringType('')]; } return $this->create($exprNode, new UnionType($trueTypes), $context, \false, $scope, $rootExpr); } if ($exprNode instanceof FuncCall && $exprNode->name instanceof Name && in_array(strtolower($exprNode->name->toString()), ['gettype', 'get_class', 'get_debug_type'], \true) && isset($exprNode->getArgs()[0]) && $constantType->isString()->yes()) { return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\Identical($expr->left, $expr->right), $context, $rootExpr); } if ($context->true() && $exprNode instanceof FuncCall && $exprNode->name instanceof Name && $exprNode->name->toLowerString() === 'preg_match' && (new ConstantIntegerType(1))->isSuperTypeOf($constantType)->yes()) { return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\Identical($expr->left, $expr->right), $context, $rootExpr); } } $leftType = $scope->getType($expr->left); $rightType = $scope->getType($expr->right); $leftBooleanType = $leftType->toBoolean(); if ($leftBooleanType instanceof ConstantBooleanType && $rightType->isBoolean()->yes()) { return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\Identical(new ConstFetch(new Name($leftBooleanType->getValue() ? 'true' : 'false')), $expr->right), $context, $rootExpr); } $rightBooleanType = $rightType->toBoolean(); if ($rightBooleanType instanceof ConstantBooleanType && $leftType->isBoolean()->yes()) { return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\Identical($expr->left, new ConstFetch(new Name($rightBooleanType->getValue() ? 'true' : 'false'))), $context, $rootExpr); } if (!$context->null() && $rightType->isArray()->yes() && $leftType->isConstantArray()->yes() && $leftType->isIterableAtLeastOnce()->no()) { return $this->create($expr->right, new NonEmptyArrayType(), $context->negate(), \false, $scope, $rootExpr); } if (!$context->null() && $leftType->isArray()->yes() && $rightType->isConstantArray()->yes() && $rightType->isIterableAtLeastOnce()->no()) { return $this->create($expr->left, new NonEmptyArrayType(), $context->negate(), \false, $scope, $rootExpr); } if ($leftType->isString()->yes() && $rightType->isString()->yes() || $leftType->isInteger()->yes() && $rightType->isInteger()->yes() || $leftType->isFloat()->yes() && $rightType->isFloat()->yes() || $leftType->isEnum()->yes() && $rightType->isEnum()->yes()) { return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\Identical($expr->left, $expr->right), $context, $rootExpr); } $leftExprString = $this->exprPrinter->printExpr($expr->left); $rightExprString = $this->exprPrinter->printExpr($expr->right); if ($leftExprString === $rightExprString) { if (!$expr->left instanceof Expr\Variable || !$expr->right instanceof Expr\Variable) { return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } } $leftTypes = $this->create($expr->left, $leftType, $context, \false, $scope, $rootExpr); $rightTypes = $this->create($expr->right, $rightType, $context, \false, $scope, $rootExpr); return $context->true() ? $leftTypes->unionWith($rightTypes) : $leftTypes->normalize($scope)->intersectWith($rightTypes->normalize($scope)); } public function resolveIdentical(Expr\BinaryOp\Identical $expr, \PHPStan\Analyser\Scope $scope, \PHPStan\Analyser\TypeSpecifierContext $context, ?Expr $rootExpr) : \PHPStan\Analyser\SpecifiedTypes { // Normalize to: fn() === expr $leftExpr = $expr->left; $rightExpr = $expr->right; if ($rightExpr instanceof FuncCall && !$leftExpr instanceof FuncCall) { [$leftExpr, $rightExpr] = [$rightExpr, $leftExpr]; } $unwrappedLeftExpr = $leftExpr; if ($leftExpr instanceof AlwaysRememberedExpr) { $unwrappedLeftExpr = $leftExpr->getExpr(); } $unwrappedRightExpr = $rightExpr; if ($rightExpr instanceof AlwaysRememberedExpr) { $unwrappedRightExpr = $rightExpr->getExpr(); } $rightType = $scope->getType($rightExpr); // (count($a) === $b) if (!$context->null() && $unwrappedLeftExpr instanceof FuncCall && count($unwrappedLeftExpr->getArgs()) >= 1 && $unwrappedLeftExpr->name instanceof Name && in_array(strtolower((string) $unwrappedLeftExpr->name), ['count', 'sizeof'], \true) && $rightType->isInteger()->yes()) { if (IntegerRangeType::fromInterval(null, -1)->isSuperTypeOf($rightType)->yes()) { return $this->create($unwrappedLeftExpr->getArgs()[0]->value, new NeverType(), $context, \false, $scope, $rootExpr); } $argType = $scope->getType($unwrappedLeftExpr->getArgs()[0]->value); $isZero = (new ConstantIntegerType(0))->isSuperTypeOf($rightType); if ($isZero->yes()) { $funcTypes = $this->create($unwrappedLeftExpr, $rightType, $context, \false, $scope, $rootExpr); if ($context->truthy() && !$argType->isArray()->yes()) { $newArgType = new UnionType([new ObjectType(Countable::class), new ConstantArrayType([], [])]); } else { $newArgType = new ConstantArrayType([], []); } return $funcTypes->unionWith($this->create($unwrappedLeftExpr->getArgs()[0]->value, $newArgType, $context, \false, $scope, $rootExpr)); } if ($argType instanceof UnionType) { $narrowed = $this->narrowUnionByArraySize($unwrappedLeftExpr, $argType, $rightType, $context, $scope, $rootExpr); if ($narrowed !== null) { return $narrowed; } } if ($context->truthy()) { if ($argType->isArray()->yes()) { if ($argType->isConstantArray()->yes() && $rightType->isSuperTypeOf($argType->getArraySize())->no()) { return $this->create($unwrappedLeftExpr->getArgs()[0]->value, new NeverType(), $context, \false, $scope, $rootExpr); } $funcTypes = $this->create($unwrappedLeftExpr, $rightType, $context, \false, $scope, $rootExpr); $constArray = $this->turnListIntoConstantArray($unwrappedLeftExpr, $argType, $rightType, $scope); if ($constArray !== null) { return $funcTypes->unionWith($this->create($unwrappedLeftExpr->getArgs()[0]->value, $constArray, $context, \false, $scope, $rootExpr)); } elseif (IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($rightType)->yes()) { return $funcTypes->unionWith($this->create($unwrappedLeftExpr->getArgs()[0]->value, new NonEmptyArrayType(), $context, \false, $scope, $rootExpr)); } return $funcTypes; } } } // strlen($a) === $b if (!$context->null() && $unwrappedLeftExpr instanceof FuncCall && count($unwrappedLeftExpr->getArgs()) === 1 && $unwrappedLeftExpr->name instanceof Name && in_array(strtolower((string) $unwrappedLeftExpr->name), ['strlen', 'mb_strlen'], \true) && $rightType->isInteger()->yes()) { if (IntegerRangeType::fromInterval(null, -1)->isSuperTypeOf($rightType)->yes()) { return $this->create($unwrappedLeftExpr->getArgs()[0]->value, new NeverType(), $context, \false, $scope, $rootExpr); } $isZero = (new ConstantIntegerType(0))->isSuperTypeOf($rightType); if ($isZero->yes()) { $funcTypes = $this->create($unwrappedLeftExpr, $rightType, $context, \false, $scope, $rootExpr); return $funcTypes->unionWith($this->create($unwrappedLeftExpr->getArgs()[0]->value, new ConstantStringType(''), $context, \false, $scope, $rootExpr)); } if ($context->truthy() && IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($rightType)->yes()) { $argType = $scope->getType($unwrappedLeftExpr->getArgs()[0]->value); if ($argType->isString()->yes()) { $funcTypes = $this->create($unwrappedLeftExpr, $rightType, $context, \false, $scope, $rootExpr); $accessory = new AccessoryNonEmptyStringType(); if (IntegerRangeType::fromInterval(2, null)->isSuperTypeOf($rightType)->yes()) { $accessory = new AccessoryNonFalsyStringType(); } $valueTypes = $this->create($unwrappedLeftExpr->getArgs()[0]->value, $accessory, $context, \false, $scope, $rootExpr); return $funcTypes->unionWith($valueTypes); } } } // preg_match($a) === $b if ($context->true() && $unwrappedLeftExpr instanceof FuncCall && $unwrappedLeftExpr->name instanceof Name && $unwrappedLeftExpr->name->toLowerString() === 'preg_match' && (new ConstantIntegerType(1))->isSuperTypeOf($rightType)->yes()) { return $this->specifyTypesInCondition($scope, $leftExpr, $context, $rootExpr); } // get_class($a) === 'Foo' if ($context->true() && $unwrappedLeftExpr instanceof FuncCall && $unwrappedLeftExpr->name instanceof Name && in_array(strtolower($unwrappedLeftExpr->name->toString()), ['get_class', 'get_debug_type'], \true) && isset($unwrappedLeftExpr->getArgs()[0])) { if ($rightType->getClassStringObjectType()->isObject()->yes()) { return $this->create($unwrappedLeftExpr->getArgs()[0]->value, $rightType->getClassStringObjectType(), $context, \false, $scope, $rootExpr)->unionWith($this->create($leftExpr, $rightType, $context, \false, $scope, $rootExpr)); } } // get_class($a) === 'Foo' if ($context->truthy() && $unwrappedLeftExpr instanceof FuncCall && $unwrappedLeftExpr->name instanceof Name && in_array(strtolower($unwrappedLeftExpr->name->toString()), ['substr', 'strstr', 'stristr', 'strchr', 'strrchr', 'strtolower', 'strtoupper', 'ucfirst', 'lcfirst', 'mb_substr', 'mb_strstr', 'mb_stristr', 'mb_strchr', 'mb_strrchr', 'mb_strtolower', 'mb_strtoupper', 'mb_ucfirst', 'mb_lcfirst', 'ucwords', 'mb_convert_case', 'mb_convert_kana'], \true) && isset($unwrappedLeftExpr->getArgs()[0]) && $rightType->isNonEmptyString()->yes()) { $argType = $scope->getType($unwrappedLeftExpr->getArgs()[0]->value); if ($argType->isString()->yes()) { if ($rightType->isNonFalsyString()->yes()) { return $this->create($unwrappedLeftExpr->getArgs()[0]->value, TypeCombinator::intersect($argType, new AccessoryNonFalsyStringType()), $context, \false, $scope); } return $this->create($unwrappedLeftExpr->getArgs()[0]->value, TypeCombinator::intersect($argType, new AccessoryNonEmptyStringType()), $context, \false, $scope); } } if ($rightType->isString()->yes()) { $types = null; foreach ($rightType->getConstantStrings() as $constantString) { $specifiedType = $this->specifyTypesForConstantStringBinaryExpression($unwrappedLeftExpr, $constantString, $context, $scope, $rootExpr); if ($specifiedType === null) { continue; } if ($types === null) { $types = $specifiedType; continue; } $types = $types->intersectWith($specifiedType); } if ($types !== null) { if ($leftExpr !== $unwrappedLeftExpr) { $types = $types->unionWith($this->create($leftExpr, $rightType, $context, \false, $scope, $rootExpr)); } return $types; } } $expressions = $this->findTypeExpressionsFromBinaryOperation($scope, $expr); if ($expressions !== null) { $exprNode = $expressions[0]; $constantType = $expressions[1]; $unwrappedExprNode = $exprNode; if ($exprNode instanceof AlwaysRememberedExpr) { $unwrappedExprNode = $exprNode->getExpr(); } $specifiedType = $this->specifyTypesForConstantBinaryExpression($unwrappedExprNode, $constantType, $context, $scope, $rootExpr); if ($specifiedType !== null) { if ($exprNode !== $unwrappedExprNode) { $specifiedType = $specifiedType->unionWith($this->create($exprNode, $constantType, $context, \false, $scope, $rootExpr)); } return $specifiedType; } } // $a::class === 'Foo' if ($context->true() && $unwrappedLeftExpr instanceof ClassConstFetch && $unwrappedLeftExpr->class instanceof Expr && $unwrappedLeftExpr->name instanceof Node\Identifier && $unwrappedRightExpr instanceof ClassConstFetch && $rightType instanceof ConstantStringType && $rightType->getValue() !== '' && strtolower($unwrappedLeftExpr->name->toString()) === 'class') { return $this->specifyTypesInCondition($scope, new Instanceof_($unwrappedLeftExpr->class, new Name($rightType->getValue())), $context, $rootExpr)->unionWith($this->create($leftExpr, $rightType, $context, \false, $scope, $rootExpr)); } $leftType = $scope->getType($leftExpr); // 'Foo' === $a::class if ($context->true() && $unwrappedRightExpr instanceof ClassConstFetch && $unwrappedRightExpr->class instanceof Expr && $unwrappedRightExpr->name instanceof Node\Identifier && $unwrappedLeftExpr instanceof ClassConstFetch && $leftType instanceof ConstantStringType && $leftType->getValue() !== '' && strtolower($unwrappedRightExpr->name->toString()) === 'class') { return $this->specifyTypesInCondition($scope, new Instanceof_($unwrappedRightExpr->class, new Name($leftType->getValue())), $context, $rootExpr)->unionWith($this->create($rightExpr, $leftType, $context, \false, $scope, $rootExpr)); } if ($context->false()) { $identicalType = $scope->getType($expr); if ($identicalType instanceof ConstantBooleanType) { $never = new NeverType(); $contextForTypes = $identicalType->getValue() ? $context->negate() : $context; $leftTypes = $this->create($leftExpr, $never, $contextForTypes, \false, $scope, $rootExpr); $rightTypes = $this->create($rightExpr, $never, $contextForTypes, \false, $scope, $rootExpr); if ($leftExpr instanceof AlwaysRememberedExpr) { $leftTypes = $leftTypes->unionWith($this->create($unwrappedLeftExpr, $never, $contextForTypes, \false, $scope, $rootExpr)); } if ($rightExpr instanceof AlwaysRememberedExpr) { $rightTypes = $rightTypes->unionWith($this->create($unwrappedRightExpr, $never, $contextForTypes, \false, $scope, $rootExpr)); } return $leftTypes->unionWith($rightTypes); } } $types = null; if (count($leftType->getFiniteTypes()) === 1 || $context->true() && $leftType->isConstantValue()->yes() && !$rightType->equals($leftType) && $rightType->isSuperTypeOf($leftType)->yes()) { $types = $this->create($rightExpr, $leftType, $context, \false, $scope, $rootExpr); if ($rightExpr instanceof AlwaysRememberedExpr) { $types = $types->unionWith($this->create($unwrappedRightExpr, $leftType, $context, \false, $scope, $rootExpr)); } } if (count($rightType->getFiniteTypes()) === 1 || $context->true() && $rightType->isConstantValue()->yes() && !$leftType->equals($rightType) && $leftType->isSuperTypeOf($rightType)->yes()) { $leftTypes = $this->create($leftExpr, $rightType, $context, \false, $scope, $rootExpr); if ($leftExpr instanceof AlwaysRememberedExpr) { $leftTypes = $leftTypes->unionWith($this->create($unwrappedLeftExpr, $rightType, $context, \false, $scope, $rootExpr)); } if ($types !== null) { $types = $types->unionWith($leftTypes); } else { $types = $leftTypes; } } if ($types !== null) { return $types; } $leftExprString = $this->exprPrinter->printExpr($unwrappedLeftExpr); $rightExprString = $this->exprPrinter->printExpr($unwrappedRightExpr); if ($leftExprString === $rightExprString) { if (!$unwrappedLeftExpr instanceof Expr\Variable || !$unwrappedRightExpr instanceof Expr\Variable) { return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } } if ($context->true()) { $leftTypes = $this->create($leftExpr, $rightType, $context, \false, $scope, $rootExpr); $rightTypes = $this->create($rightExpr, $leftType, $context, \false, $scope, $rootExpr); if ($leftExpr instanceof AlwaysRememberedExpr) { $leftTypes = $leftTypes->unionWith($this->create($unwrappedLeftExpr, $rightType, $context, \false, $scope, $rootExpr)); } if ($rightExpr instanceof AlwaysRememberedExpr) { $rightTypes = $rightTypes->unionWith($this->create($unwrappedRightExpr, $leftType, $context, \false, $scope, $rootExpr)); } return $leftTypes->unionWith($rightTypes); } elseif ($context->false()) { return $this->create($leftExpr, $leftType, $context, \false, $scope, $rootExpr)->normalize($scope)->intersectWith($this->create($rightExpr, $rightType, $context, \false, $scope, $rootExpr)->normalize($scope)); } return new \PHPStan\Analyser\SpecifiedTypes([], [], \false, [], $rootExpr); } } |null>> */ final class FileAnalyserResult { /** * @var list */ private $errors; /** * @var list */ private $filteredPhpErrors; /** * @var list */ private $allPhpErrors; /** * @var list */ private $locallyIgnoredErrors; /** * @var list */ private $collectedData; /** * @var list */ private $dependencies; /** * @var list */ private $usedTraitDependencies; /** * @var list */ private $exportedNodes; /** * @var LinesToIgnore */ private $linesToIgnore; /** * @var LinesToIgnore */ private $unmatchedLineIgnores; /** * @param list $errors * @param list $filteredPhpErrors * @param list $allPhpErrors * @param list $locallyIgnoredErrors * @param list $collectedData * @param list $dependencies * @param list $usedTraitDependencies * @param list $exportedNodes * @param LinesToIgnore $linesToIgnore * @param LinesToIgnore $unmatchedLineIgnores */ public function __construct(array $errors, array $filteredPhpErrors, array $allPhpErrors, array $locallyIgnoredErrors, array $collectedData, array $dependencies, array $usedTraitDependencies, array $exportedNodes, array $linesToIgnore, array $unmatchedLineIgnores) { $this->errors = $errors; $this->filteredPhpErrors = $filteredPhpErrors; $this->allPhpErrors = $allPhpErrors; $this->locallyIgnoredErrors = $locallyIgnoredErrors; $this->collectedData = $collectedData; $this->dependencies = $dependencies; $this->usedTraitDependencies = $usedTraitDependencies; $this->exportedNodes = $exportedNodes; $this->linesToIgnore = $linesToIgnore; $this->unmatchedLineIgnores = $unmatchedLineIgnores; } /** * @return list */ public function getErrors() : array { return $this->errors; } /** * @return list */ public function getFilteredPhpErrors() : array { return $this->filteredPhpErrors; } /** * @return list */ public function getAllPhpErrors() : array { return $this->allPhpErrors; } /** * @return list */ public function getLocallyIgnoredErrors() : array { return $this->locallyIgnoredErrors; } /** * @return list */ public function getCollectedData() : array { return $this->collectedData; } /** * @return list */ public function getDependencies() : array { return $this->dependencies; } /** * @return list */ public function getUsedTraitDependencies() : array { return $this->usedTraitDependencies; } /** * @return list */ public function getExportedNodes() : array { return $this->exportedNodes; } /** * @return LinesToIgnore */ public function getLinesToIgnore() : array { return $this->linesToIgnore; } /** * @return LinesToIgnore */ public function getUnmatchedLineIgnores() : array { return $this->unmatchedLineIgnores; } } value = $value; } private static function create(?int $value) : self { self::$registry[$value] = self::$registry[$value] ?? new self($value); return self::$registry[$value]; } public static function createTrue() : self { return self::create(self::CONTEXT_TRUE); } public static function createTruthy() : self { return self::create(self::CONTEXT_TRUTHY); } public static function createFalse() : self { return self::create(self::CONTEXT_FALSE); } public static function createFalsey() : self { return self::create(self::CONTEXT_FALSEY); } public static function createNull() : self { return self::create(null); } public function negate() : self { if ($this->value === null) { throw new ShouldNotHappenException(); } return self::create(~$this->value & self::CONTEXT_BITMASK); } public function true() : bool { return $this->value !== null && (bool) ($this->value & self::CONTEXT_TRUE); } public function truthy() : bool { return $this->value !== null && (bool) ($this->value & self::CONTEXT_TRUTHY); } public function false() : bool { return $this->value !== null && (bool) ($this->value & self::CONTEXT_FALSE); } public function falsey() : bool { return $this->value !== null && (bool) ($this->value & self::CONTEXT_FALSEY); } public function null() : bool { return $this->value === null; } } scope = $scope; $this->type = $type; $this->node = $node; $this->explicit = $explicit; $this->canContainAnyThrowable = $canContainAnyThrowable; } /** * @param Node\Expr|Node\Stmt $node */ public static function createExplicit(\PHPStan\Analyser\MutatingScope $scope, Type $type, Node $node, bool $canContainAnyThrowable) : self { return new self($scope, $type, $node, \true, $canContainAnyThrowable); } /** * @param Node\Expr|Node\Stmt $node */ public static function createImplicit(\PHPStan\Analyser\MutatingScope $scope, Node $node) : self { return new self($scope, new ObjectType(Throwable::class), $node, \false, \true); } public function getScope() : \PHPStan\Analyser\MutatingScope { return $this->scope; } public function getType() : Type { return $this->type; } /** * @return Node\Expr|Node\Stmt */ public function getNode() { return $this->node; } public function isExplicit() : bool { return $this->explicit; } public function canContainAnyThrowable() : bool { return $this->canContainAnyThrowable; } public function subtractCatchType(Type $catchType) : self { return new self($this->scope, TypeCombinator::remove($this->type, $catchType), $this->node, $this->explicit, $this->canContainAnyThrowable); } } scopeClass = $scopeClass; $this->reflectionProvider = $reflectionProvider; $this->initializerExprTypeResolver = $initializerExprTypeResolver; $this->dynamicReturnTypeExtensionRegistryProvider = $dynamicReturnTypeExtensionRegistryProvider; $this->expressionTypeResolverExtensionRegistryProvider = $expressionTypeResolverExtensionRegistryProvider; $this->exprPrinter = $exprPrinter; $this->typeSpecifier = $typeSpecifier; $this->propertyReflectionFinder = $propertyReflectionFinder; $this->parser = $parser; $this->nodeScopeResolver = $nodeScopeResolver; $this->richerScopeGetTypeHelper = $richerScopeGetTypeHelper; $this->phpVersion = $phpVersion; $this->explicitMixedInUnknownGenericNew = $explicitMixedInUnknownGenericNew; $this->explicitMixedForGlobalVariables = $explicitMixedForGlobalVariables; $this->constantResolver = $constantResolver; } /** * @param array $expressionTypes * @param array $nativeExpressionTypes * @param array $conditionalExpressions * @param list $inFunctionCallsStack * @param array $currentlyAssignedExpressions * @param array $currentlyAllowedUndefinedExpressions * @param FunctionReflection|MethodReflection|null $function */ public function create(\PHPStan\Analyser\ScopeContext $context, bool $declareStrictTypes = \false, $function = null, ?string $namespace = null, array $expressionTypes = [], array $nativeExpressionTypes = [], array $conditionalExpressions = [], array $inClosureBindScopeClasses = [], ?ParametersAcceptor $anonymousFunctionReflection = null, bool $inFirstLevelStatement = \true, array $currentlyAssignedExpressions = [], array $currentlyAllowedUndefinedExpressions = [], array $inFunctionCallsStack = [], bool $afterExtractCall = \false, ?\PHPStan\Analyser\Scope $parentScope = null, bool $nativeTypesPromoted = \false) : \PHPStan\Analyser\MutatingScope { $scopeClass = $this->scopeClass; if (!is_a($scopeClass, \PHPStan\Analyser\MutatingScope::class, \true)) { throw new ShouldNotHappenException(); } return new $scopeClass($this, $this->reflectionProvider, $this->initializerExprTypeResolver, $this->dynamicReturnTypeExtensionRegistryProvider->getRegistry(), $this->expressionTypeResolverExtensionRegistryProvider->getRegistry(), $this->exprPrinter, $this->typeSpecifier, $this->propertyReflectionFinder, $this->parser, $this->nodeScopeResolver, $this->richerScopeGetTypeHelper, $this->constantResolver, $context, $this->phpVersion, $declareStrictTypes, $function, $namespace, $expressionTypes, $nativeExpressionTypes, $conditionalExpressions, $inClosureBindScopeClasses, $anonymousFunctionReflection, $inFirstLevelStatement, $currentlyAssignedExpressions, $currentlyAllowedUndefinedExpressions, $inFunctionCallsStack, $afterExtractCall, $parentScope, $nativeTypesPromoted, $this->explicitMixedInUnknownGenericNew, $this->explicitMixedForGlobalVariables); } } */ private $allPhpErrors = []; /** @var list */ private $filteredPhpErrors = []; public function __construct(\PHPStan\Analyser\ScopeFactory $scopeFactory, \PHPStan\Analyser\NodeScopeResolver $nodeScopeResolver, Parser $parser, DependencyResolver $dependencyResolver, \PHPStan\Analyser\RuleErrorTransformer $ruleErrorTransformer, \PHPStan\Analyser\LocalIgnoresProcessor $localIgnoresProcessor) { $this->scopeFactory = $scopeFactory; $this->nodeScopeResolver = $nodeScopeResolver; $this->parser = $parser; $this->dependencyResolver = $dependencyResolver; $this->ruleErrorTransformer = $ruleErrorTransformer; $this->localIgnoresProcessor = $localIgnoresProcessor; } /** * @param array $analysedFiles * @param callable(Node $node, Scope $scope): void|null $outerNodeCallback */ public function analyseFile(string $file, array $analysedFiles, RuleRegistry $ruleRegistry, CollectorRegistry $collectorRegistry, ?callable $outerNodeCallback) : \PHPStan\Analyser\FileAnalyserResult { /** @var list $fileErrors */ $fileErrors = []; /** @var list $locallyIgnoredErrors */ $locallyIgnoredErrors = []; /** @var list $fileCollectedData */ $fileCollectedData = []; $fileDependencies = []; $usedTraitFileDependencies = []; $exportedNodes = []; $linesToIgnore = []; $unmatchedLineIgnores = []; if (is_file($file)) { try { $this->collectErrors($analysedFiles); $parserNodes = $this->parser->parseFile($file); $linesToIgnore = $unmatchedLineIgnores = [$file => $this->getLinesToIgnoreFromTokens($parserNodes)]; $temporaryFileErrors = []; $nodeCallback = function (Node $node, \PHPStan\Analyser\Scope $scope) use(&$fileErrors, &$fileCollectedData, &$fileDependencies, &$usedTraitFileDependencies, &$exportedNodes, $file, $ruleRegistry, $collectorRegistry, $outerNodeCallback, $analysedFiles, &$linesToIgnore, &$unmatchedLineIgnores, &$temporaryFileErrors) : void { if ($node instanceof Node\Stmt\Trait_) { foreach (array_keys($linesToIgnore[$file] ?? []) as $lineToIgnore) { if ($lineToIgnore < $node->getStartLine() || $lineToIgnore > $node->getEndLine()) { continue; } unset($unmatchedLineIgnores[$file][$lineToIgnore]); } } if ($node instanceof InTraitNode) { $traitNode = $node->getOriginalNode(); $linesToIgnore[$scope->getFileDescription()] = $this->getLinesToIgnoreFromTokens([$traitNode]); } if ($outerNodeCallback !== null) { $outerNodeCallback($node, $scope); } $uniquedAnalysedCodeExceptionMessages = []; $nodeType = get_class($node); foreach ($ruleRegistry->getRules($nodeType) as $rule) { try { $ruleErrors = $rule->processNode($node, $scope); } catch (AnalysedCodeException $e) { if (isset($uniquedAnalysedCodeExceptionMessages[$e->getMessage()])) { continue; } $uniquedAnalysedCodeExceptionMessages[$e->getMessage()] = \true; $fileErrors[] = (new \PHPStan\Analyser\Error($e->getMessage(), $file, $node->getStartLine(), $e, null, null, $e->getTip()))->withIdentifier('phpstan.internal')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($e), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); continue; } catch (IdentifierNotFound $e) { $fileErrors[] = (new \PHPStan\Analyser\Error(sprintf('Reflection error: %s not found.', $e->getIdentifier()->getName()), $file, $node->getStartLine(), $e, null, null, 'Learn more at https://phpstan.org/user-guide/discovering-symbols'))->withIdentifier('phpstan.reflection')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($e), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); continue; } catch (UnableToCompileNode|CircularReference $e) { $fileErrors[] = (new \PHPStan\Analyser\Error(sprintf('Reflection error: %s', $e->getMessage()), $file, $node->getStartLine(), $e))->withIdentifier('phpstan.reflection')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($e), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); continue; } foreach ($ruleErrors as $ruleError) { $temporaryFileErrors[] = $this->ruleErrorTransformer->transform($ruleError, $scope, $nodeType, $node->getStartLine()); } } foreach ($collectorRegistry->getCollectors($nodeType) as $collector) { try { $collectedData = $collector->processNode($node, $scope); } catch (AnalysedCodeException $e) { if (isset($uniquedAnalysedCodeExceptionMessages[$e->getMessage()])) { continue; } $uniquedAnalysedCodeExceptionMessages[$e->getMessage()] = \true; $fileErrors[] = (new \PHPStan\Analyser\Error($e->getMessage(), $file, $node->getStartLine(), $e, null, null, $e->getTip()))->withIdentifier('phpstan.internal')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($e), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); continue; } catch (IdentifierNotFound $e) { $fileErrors[] = (new \PHPStan\Analyser\Error(sprintf('Reflection error: %s not found.', $e->getIdentifier()->getName()), $file, $node->getStartLine(), $e, null, null, 'Learn more at https://phpstan.org/user-guide/discovering-symbols'))->withIdentifier('phpstan.reflection')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($e), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); continue; } catch (UnableToCompileNode|CircularReference $e) { $fileErrors[] = (new \PHPStan\Analyser\Error(sprintf('Reflection error: %s', $e->getMessage()), $file, $node->getStartLine(), $e))->withIdentifier('phpstan.reflection')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($e), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); continue; } if ($collectedData === null) { continue; } $fileCollectedData[] = new CollectedData($collectedData, $scope->getFile(), get_class($collector)); } try { $dependencies = $this->dependencyResolver->resolveDependencies($node, $scope); foreach ($dependencies->getFileDependencies($scope->getFile(), $analysedFiles) as $dependentFile) { $fileDependencies[] = $dependentFile; } if ($dependencies->getExportedNode() !== null) { $exportedNodes[] = $dependencies->getExportedNode(); } } catch (AnalysedCodeException $e) { // pass } catch (IdentifierNotFound $e) { // pass } catch (UnableToCompileNode $e) { // pass } if (!$node instanceof InClassNode) { return; } $usedTraitDependencies = $this->dependencyResolver->resolveUsedTraitDependencies($node); foreach ($usedTraitDependencies->getFileDependencies($scope->getFile(), $analysedFiles) as $dependentFile) { $usedTraitFileDependencies[] = $dependentFile; } }; $scope = $this->scopeFactory->create(\PHPStan\Analyser\ScopeContext::create($file)); $nodeCallback(new FileNode($parserNodes), $scope); $this->nodeScopeResolver->processNodes($parserNodes, $scope, $nodeCallback); $localIgnoresProcessorResult = $this->localIgnoresProcessor->process($temporaryFileErrors, $linesToIgnore, $unmatchedLineIgnores); foreach ($localIgnoresProcessorResult->getFileErrors() as $fileError) { $fileErrors[] = $fileError; } foreach ($localIgnoresProcessorResult->getLocallyIgnoredErrors() as $locallyIgnoredError) { $locallyIgnoredErrors[] = $locallyIgnoredError; } $linesToIgnore = $localIgnoresProcessorResult->getLinesToIgnore(); $unmatchedLineIgnores = $localIgnoresProcessorResult->getUnmatchedLineIgnores(); } catch (\PhpParser\Error $e) { $fileErrors[] = (new \PHPStan\Analyser\Error($e->getRawMessage(), $file, $e->getStartLine() !== -1 ? $e->getStartLine() : null, $e))->withIdentifier('phpstan.parse'); } catch (ParserErrorsException $e) { foreach ($e->getErrors() as $error) { $fileErrors[] = (new \PHPStan\Analyser\Error($error->getMessage(), $e->getParsedFile() ?? $file, $error->getLine() !== -1 ? $error->getStartLine() : null, $e))->withIdentifier('phpstan.parse'); } } catch (AnalysedCodeException $e) { $fileErrors[] = (new \PHPStan\Analyser\Error($e->getMessage(), $file, null, $e, null, null, $e->getTip()))->withIdentifier('phpstan.internal')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($e), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); } catch (IdentifierNotFound $e) { $fileErrors[] = (new \PHPStan\Analyser\Error(sprintf('Reflection error: %s not found.', $e->getIdentifier()->getName()), $file, null, $e, null, null, 'Learn more at https://phpstan.org/user-guide/discovering-symbols'))->withIdentifier('phpstan.reflection')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($e), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); } catch (UnableToCompileNode|CircularReference $e) { $fileErrors[] = (new \PHPStan\Analyser\Error(sprintf('Reflection error: %s', $e->getMessage()), $file, null, $e))->withIdentifier('phpstan.reflection')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($e), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString()]); } finally { $this->restoreCollectErrorsHandler(); } } elseif (is_dir($file)) { $fileErrors[] = (new \PHPStan\Analyser\Error(sprintf('File %s is a directory.', $file), $file, null, \false))->withIdentifier('phpstan.path'); } else { $fileErrors[] = (new \PHPStan\Analyser\Error(sprintf('File %s does not exist.', $file), $file, null, \false))->withIdentifier('phpstan.path'); } foreach ($linesToIgnore as $fileKey => $lines) { if (count($lines) > 0) { continue; } unset($linesToIgnore[$fileKey]); } foreach ($unmatchedLineIgnores as $fileKey => $lines) { if (count($lines) > 0) { continue; } unset($unmatchedLineIgnores[$fileKey]); } return new \PHPStan\Analyser\FileAnalyserResult($fileErrors, $this->filteredPhpErrors, $this->allPhpErrors, $locallyIgnoredErrors, $fileCollectedData, array_values(array_unique($fileDependencies)), array_values(array_unique($usedTraitFileDependencies)), $exportedNodes, $linesToIgnore, $unmatchedLineIgnores); } /** * @param Node[] $nodes * @return array|null> */ private function getLinesToIgnoreFromTokens(array $nodes) : array { if (!isset($nodes[0])) { return []; } /** @var array|null> */ return $nodes[0]->getAttribute('linesToIgnore', []); } /** * @param array $analysedFiles */ private function collectErrors(array $analysedFiles) : void { $this->filteredPhpErrors = []; $this->allPhpErrors = []; set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use($analysedFiles) : bool { if ((error_reporting() & $errno) === 0) { // silence @ operator return \true; } $errorMessage = sprintf('%s: %s', $this->getErrorLabel($errno), $errstr); $this->allPhpErrors[] = (new \PHPStan\Analyser\Error($errorMessage, $errfile, $errline, \true))->withIdentifier('phpstan.php'); if ($errno === E_DEPRECATED) { return \true; } if (!isset($analysedFiles[$errfile])) { return \true; } $this->filteredPhpErrors[] = (new \PHPStan\Analyser\Error($errorMessage, $errfile, $errline, \true))->withIdentifier('phpstan.php'); return \true; }); } private function restoreCollectErrorsHandler() : void { restore_error_handler(); } private function getErrorLabel(int $errno) : string { switch ($errno) { case E_ERROR: return 'Fatal error'; case E_WARNING: return 'Warning'; case E_PARSE: return 'Parse error'; case E_NOTICE: return 'Notice'; case E_USER_ERROR: return 'User error (E_USER_ERROR)'; case E_USER_WARNING: return 'User warning (E_USER_WARNING)'; case E_USER_NOTICE: return 'User notice (E_USER_NOTICE)'; case E_STRICT: return 'Strict error (E_STRICT)'; } return 'Unknown PHP error'; } } */ private $earlyTerminatingFunctionCalls; /** * @readonly * @var string[] */ private $universalObjectCratesClasses; /** * @readonly * @var bool */ private $implicitThrows; /** * @readonly * @var bool */ private $treatPhpDocTypesAsCertain; /** * @readonly * @var bool */ private $detectDeadTypeInMultiCatch; /** * @readonly * @var bool */ private $paramOutType; /** * @readonly * @var bool */ private $preciseMissingReturn; /** * @readonly * @var bool */ private $explicitThrow; private const LOOP_SCOPE_ITERATIONS = 3; private const GENERALIZE_AFTER_ITERATION = 1; /** @var bool[] filePath(string) => bool(true) */ private $analysedFiles = []; /** @var array */ private $earlyTerminatingMethodNames; /** @var array */ private $calledMethodStack = []; /** @var array */ private $calledMethodResults = []; /** * @param string[][] $earlyTerminatingMethodCalls className(string) => methods(string[]) * @param array $earlyTerminatingFunctionCalls * @param string[] $universalObjectCratesClasses */ public function __construct(ReflectionProvider $reflectionProvider, InitializerExprTypeResolver $initializerExprTypeResolver, Reflector $reflector, ClassReflectionExtensionRegistryProvider $classReflectionExtensionRegistryProvider, ParameterOutTypeExtensionProvider $parameterOutTypeExtensionProvider, Parser $parser, FileTypeMapper $fileTypeMapper, StubPhpDocProvider $stubPhpDocProvider, PhpVersion $phpVersion, SignatureMapProvider $signatureMapProvider, PhpDocInheritanceResolver $phpDocInheritanceResolver, FileHelper $fileHelper, \PHPStan\Analyser\TypeSpecifier $typeSpecifier, DynamicThrowTypeExtensionProvider $dynamicThrowTypeExtensionProvider, ReadWritePropertiesExtensionProvider $readWritePropertiesExtensionProvider, ParameterClosureTypeExtensionProvider $parameterClosureTypeExtensionProvider, \PHPStan\Analyser\ScopeFactory $scopeFactory, bool $polluteScopeWithLoopInitialAssignments, bool $polluteScopeWithAlwaysIterableForeach, array $earlyTerminatingMethodCalls, array $earlyTerminatingFunctionCalls, array $universalObjectCratesClasses, bool $implicitThrows, bool $treatPhpDocTypesAsCertain, bool $detectDeadTypeInMultiCatch, bool $paramOutType, bool $preciseMissingReturn, bool $explicitThrow) { $this->reflectionProvider = $reflectionProvider; $this->initializerExprTypeResolver = $initializerExprTypeResolver; $this->reflector = $reflector; $this->classReflectionExtensionRegistryProvider = $classReflectionExtensionRegistryProvider; $this->parameterOutTypeExtensionProvider = $parameterOutTypeExtensionProvider; $this->parser = $parser; $this->fileTypeMapper = $fileTypeMapper; $this->stubPhpDocProvider = $stubPhpDocProvider; $this->phpVersion = $phpVersion; $this->signatureMapProvider = $signatureMapProvider; $this->phpDocInheritanceResolver = $phpDocInheritanceResolver; $this->fileHelper = $fileHelper; $this->typeSpecifier = $typeSpecifier; $this->dynamicThrowTypeExtensionProvider = $dynamicThrowTypeExtensionProvider; $this->readWritePropertiesExtensionProvider = $readWritePropertiesExtensionProvider; $this->parameterClosureTypeExtensionProvider = $parameterClosureTypeExtensionProvider; $this->scopeFactory = $scopeFactory; $this->polluteScopeWithLoopInitialAssignments = $polluteScopeWithLoopInitialAssignments; $this->polluteScopeWithAlwaysIterableForeach = $polluteScopeWithAlwaysIterableForeach; $this->earlyTerminatingMethodCalls = $earlyTerminatingMethodCalls; $this->earlyTerminatingFunctionCalls = $earlyTerminatingFunctionCalls; $this->universalObjectCratesClasses = $universalObjectCratesClasses; $this->implicitThrows = $implicitThrows; $this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain; $this->detectDeadTypeInMultiCatch = $detectDeadTypeInMultiCatch; $this->paramOutType = $paramOutType; $this->preciseMissingReturn = $preciseMissingReturn; $this->explicitThrow = $explicitThrow; $earlyTerminatingMethodNames = []; foreach ($this->earlyTerminatingMethodCalls as $methodNames) { foreach ($methodNames as $methodName) { $earlyTerminatingMethodNames[strtolower($methodName)] = \true; } } $this->earlyTerminatingMethodNames = $earlyTerminatingMethodNames; } /** * @api * @param string[] $files */ public function setAnalysedFiles(array $files) : void { $this->analysedFiles = array_fill_keys($files, \true); } /** * @api * @param Node[] $nodes * @param callable(Node $node, Scope $scope): void $nodeCallback */ public function processNodes(array $nodes, \PHPStan\Analyser\MutatingScope $scope, callable $nodeCallback) : void { $alreadyTerminated = \false; foreach ($nodes as $i => $node) { if (!$node instanceof Node\Stmt || $alreadyTerminated && !($node instanceof Node\Stmt\Function_ || $node instanceof Node\Stmt\ClassLike)) { continue; } $statementResult = $this->processStmtNode($node, $scope, $nodeCallback, \PHPStan\Analyser\StatementContext::createTopLevel()); $scope = $statementResult->getScope(); if ($alreadyTerminated || !$statementResult->isAlwaysTerminating()) { continue; } $alreadyTerminated = \true; $nextStmt = $this->getFirstUnreachableNode(array_slice($nodes, $i + 1), \true); if (!$nextStmt instanceof Node\Stmt) { continue; } $nodeCallback(new UnreachableStatementNode($nextStmt), $scope); } } /** * @api * @param Node\Stmt[] $stmts * @param callable(Node $node, Scope $scope): void $nodeCallback */ public function processStmtNodes(Node $parentNode, array $stmts, \PHPStan\Analyser\MutatingScope $scope, callable $nodeCallback, ?\PHPStan\Analyser\StatementContext $context = null) : \PHPStan\Analyser\StatementResult { if ($context === null) { $context = \PHPStan\Analyser\StatementContext::createTopLevel(); } $exitPoints = []; $throwPoints = []; $impurePoints = []; $alreadyTerminated = \false; $hasYield = \false; $stmtCount = count($stmts); $shouldCheckLastStatement = $parentNode instanceof Node\Stmt\Function_ || $parentNode instanceof Node\Stmt\ClassMethod || $parentNode instanceof Expr\Closure; foreach ($stmts as $i => $stmt) { if ($alreadyTerminated && !($stmt instanceof Node\Stmt\Function_ || $stmt instanceof Node\Stmt\ClassLike)) { continue; } $isLast = $i === $stmtCount - 1; $statementResult = $this->processStmtNode($stmt, $scope, $nodeCallback, $context); $scope = $statementResult->getScope(); $hasYield = $hasYield || $statementResult->hasYield(); if ($shouldCheckLastStatement && $isLast) { /** @var Node\Stmt\Function_|Node\Stmt\ClassMethod|Expr\Closure $parentNode */ $parentNode = $parentNode; $endStatements = $statementResult->getEndStatements(); if ($this->preciseMissingReturn && count($endStatements) > 0) { foreach ($endStatements as $endStatement) { $endStatementResult = $endStatement->getResult(); $nodeCallback(new ExecutionEndNode($endStatement->getStatement(), new \PHPStan\Analyser\StatementResult($endStatementResult->getScope(), $hasYield, $endStatementResult->isAlwaysTerminating(), $endStatementResult->getExitPoints(), $endStatementResult->getThrowPoints(), $endStatementResult->getImpurePoints()), $parentNode->returnType !== null), $endStatementResult->getScope()); } } else { $nodeCallback(new ExecutionEndNode($stmt, new \PHPStan\Analyser\StatementResult($scope, $hasYield, $statementResult->isAlwaysTerminating(), $statementResult->getExitPoints(), $statementResult->getThrowPoints(), $statementResult->getImpurePoints()), $parentNode->returnType !== null), $scope); } } $exitPoints = array_merge($exitPoints, $statementResult->getExitPoints()); $throwPoints = array_merge($throwPoints, $statementResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $statementResult->getImpurePoints()); if ($alreadyTerminated || !$statementResult->isAlwaysTerminating()) { continue; } $alreadyTerminated = \true; $nextStmt = $this->getFirstUnreachableNode(array_slice($stmts, $i + 1), $parentNode instanceof Node\Stmt\Namespace_); if ($nextStmt === null) { continue; } $nodeCallback(new UnreachableStatementNode($nextStmt), $scope); } $statementResult = new \PHPStan\Analyser\StatementResult($scope, $hasYield, $alreadyTerminated, $exitPoints, $throwPoints, $impurePoints); if ($stmtCount === 0 && $shouldCheckLastStatement) { /** @var Node\Stmt\Function_|Node\Stmt\ClassMethod|Expr\Closure $parentNode */ $parentNode = $parentNode; $returnTypeNode = $parentNode->returnType; if ($parentNode instanceof Expr\Closure) { $parentNode = new Node\Stmt\Expression($parentNode, $parentNode->getAttributes()); } $nodeCallback(new ExecutionEndNode($parentNode, $statementResult, $returnTypeNode !== null), $scope); } return $statementResult; } /** * @param callable(Node $node, Scope $scope): void $nodeCallback */ private function processStmtNode(Node\Stmt $stmt, \PHPStan\Analyser\MutatingScope $scope, callable $nodeCallback, \PHPStan\Analyser\StatementContext $context) : \PHPStan\Analyser\StatementResult { if (!$stmt instanceof Static_ && !$stmt instanceof Foreach_ && !$stmt instanceof Node\Stmt\Global_ && !$stmt instanceof Node\Stmt\Property && !$stmt instanceof Node\Stmt\PropertyProperty && !$stmt instanceof Node\Stmt\ClassConst && !$stmt instanceof Node\Stmt\Const_) { $scope = $this->processStmtVarAnnotation($scope, $stmt, null, $nodeCallback); } if ($stmt instanceof Node\Stmt\ClassMethod) { if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } if ($scope->isInTrait() && $scope->getClassReflection()->hasNativeMethod($stmt->name->toString())) { $methodReflection = $scope->getClassReflection()->getNativeMethod($stmt->name->toString()); if ($methodReflection instanceof NativeMethodReflection) { return new \PHPStan\Analyser\StatementResult($scope, \false, \false, [], [], []); } if ($methodReflection instanceof PhpMethodReflection) { $declaringTrait = $methodReflection->getDeclaringTrait(); if ($declaringTrait === null || $declaringTrait->getName() !== $scope->getTraitReflection()->getName()) { return new \PHPStan\Analyser\StatementResult($scope, \false, \false, [], [], []); } } } } $stmtScope = $scope; if ($stmt instanceof Throw_ || $stmt instanceof Return_) { $stmtScope = $this->processStmtVarAnnotation($scope, $stmt, $stmt->expr, $nodeCallback); } $nodeCallback($stmt, $stmtScope); $overridingThrowPoints = $this->getOverridingThrowPoints($stmt, $scope); if ($stmt instanceof Node\Stmt\Declare_) { $hasYield = \false; $throwPoints = []; $impurePoints = []; $alwaysTerminating = \false; $exitPoints = []; foreach ($stmt->declares as $declare) { $nodeCallback($declare, $scope); $nodeCallback($declare->value, $scope); if ($declare->key->name !== 'strict_types' || !$declare->value instanceof Node\Scalar\LNumber || $declare->value->value !== 1) { continue; } $scope = $scope->enterDeclareStrictTypes(); } if ($stmt->stmts !== null) { $result = $this->processStmtNodes($stmt, $stmt->stmts, $scope, $nodeCallback, $context); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $alwaysTerminating = $result->isAlwaysTerminating(); $exitPoints = $result->getExitPoints(); } return new \PHPStan\Analyser\StatementResult($scope, $hasYield, $alwaysTerminating, $exitPoints, $throwPoints, $impurePoints); } elseif ($stmt instanceof Node\Stmt\Function_) { $hasYield = \false; $throwPoints = []; $impurePoints = []; $this->processAttributeGroups($stmt, $stmt->attrGroups, $scope, $nodeCallback); [$templateTypeMap, $phpDocParameterTypes, $phpDocImmediatelyInvokedCallableParameters, $phpDocClosureThisTypeParameters, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal, $isPure, $acceptsNamedArguments, , $phpDocComment, $asserts, , $phpDocParameterOutTypes] = $this->getPhpDocs($scope, $stmt); foreach ($stmt->params as $param) { $this->processParamNode($stmt, $param, $scope, $nodeCallback); } if ($stmt->returnType !== null) { $nodeCallback($stmt->returnType, $scope); } $functionScope = $scope->enterFunction($stmt, $templateTypeMap, $phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal, $isPure, $acceptsNamedArguments, $asserts, $phpDocComment, $phpDocParameterOutTypes, $phpDocImmediatelyInvokedCallableParameters, $phpDocClosureThisTypeParameters); $functionReflection = $functionScope->getFunction(); if (!$functionReflection instanceof PhpFunctionFromParserNodeReflection) { throw new ShouldNotHappenException(); } $nodeCallback(new InFunctionNode($functionReflection, $stmt), $functionScope); $gatheredReturnStatements = []; $gatheredYieldStatements = []; $executionEnds = []; $functionImpurePoints = []; $statementResult = $this->processStmtNodes($stmt, $stmt->stmts, $functionScope, static function (Node $node, \PHPStan\Analyser\Scope $scope) use($nodeCallback, $functionScope, &$gatheredReturnStatements, &$gatheredYieldStatements, &$executionEnds, &$functionImpurePoints) : void { $nodeCallback($node, $scope); if ($scope->getFunction() !== $functionScope->getFunction()) { return; } if ($scope->isInAnonymousFunction()) { return; } if ($node instanceof PropertyAssignNode) { $functionImpurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $node, 'propertyAssign', 'property assignment', \true); return; } if ($node instanceof ExecutionEndNode) { $executionEnds[] = $node; return; } if ($node instanceof Expr\Yield_ || $node instanceof Expr\YieldFrom) { $gatheredYieldStatements[] = $node; } if (!$node instanceof Return_) { return; } $gatheredReturnStatements[] = new ReturnStatement($scope, $node); }, \PHPStan\Analyser\StatementContext::createTopLevel()); $nodeCallback(new FunctionReturnStatementsNode($stmt, $gatheredReturnStatements, $gatheredYieldStatements, $statementResult, $executionEnds, array_merge($statementResult->getImpurePoints(), $functionImpurePoints), $functionReflection), $functionScope); } elseif ($stmt instanceof Node\Stmt\ClassMethod) { $hasYield = \false; $throwPoints = []; $impurePoints = []; $this->processAttributeGroups($stmt, $stmt->attrGroups, $scope, $nodeCallback); [$templateTypeMap, $phpDocParameterTypes, $phpDocImmediatelyInvokedCallableParameters, $phpDocClosureThisTypeParameters, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal, $isPure, $acceptsNamedArguments, , $phpDocComment, $asserts, $selfOutType, $phpDocParameterOutTypes] = $this->getPhpDocs($scope, $stmt); foreach ($stmt->params as $param) { $this->processParamNode($stmt, $param, $scope, $nodeCallback); } if ($stmt->returnType !== null) { $nodeCallback($stmt->returnType, $scope); } $isFromTrait = $stmt->getAttribute('originalTraitMethodName') === '__construct'; $isConstructor = $isFromTrait || $stmt->name->toLowerString() === '__construct'; $methodScope = $scope->enterClassMethod($stmt, $templateTypeMap, $phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal, $isPure, $acceptsNamedArguments, $asserts, $selfOutType, $phpDocComment, $phpDocParameterOutTypes, $phpDocImmediatelyInvokedCallableParameters, $phpDocClosureThisTypeParameters, $isConstructor); if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } if ($isConstructor) { foreach ($stmt->params as $param) { if ($param->flags === 0) { continue; } if (!$param->var instanceof Variable || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } $phpDoc = null; if ($param->getDocComment() !== null) { $phpDoc = $param->getDocComment()->getText(); } $nodeCallback(new ClassPropertyNode($param->var->name, $param->flags, $param->type, null, $phpDoc, $phpDocParameterTypes[$param->var->name] ?? null, \true, $isFromTrait, $param, \false, $scope->isInTrait(), $scope->getClassReflection()->isReadOnly(), \false, $scope->getClassReflection()), $methodScope); $methodScope = $methodScope->assignExpression(new PropertyInitializationExpr($param->var->name), new MixedType(), new MixedType()); } } if ($stmt->getAttribute('virtual', \false) === \false) { $methodReflection = $methodScope->getFunction(); if (!$methodReflection instanceof PhpMethodFromParserNodeReflection) { throw new ShouldNotHappenException(); } $nodeCallback(new InClassMethodNode($scope->getClassReflection(), $methodReflection, $stmt), $methodScope); } if ($stmt->stmts !== null) { $gatheredReturnStatements = []; $gatheredYieldStatements = []; $executionEnds = []; $methodImpurePoints = []; $statementResult = $this->processStmtNodes($stmt, $stmt->stmts, $methodScope, static function (Node $node, \PHPStan\Analyser\Scope $scope) use($nodeCallback, $methodScope, &$gatheredReturnStatements, &$gatheredYieldStatements, &$executionEnds, &$methodImpurePoints) : void { $nodeCallback($node, $scope); if ($scope->getFunction() !== $methodScope->getFunction()) { return; } if ($scope->isInAnonymousFunction()) { return; } if ($node instanceof PropertyAssignNode) { if ($node->getPropertyFetch() instanceof Expr\PropertyFetch && $scope->getFunction() instanceof PhpMethodFromParserNodeReflection && $scope->getFunction()->getDeclaringClass()->hasConstructor() && $scope->getFunction()->getDeclaringClass()->getConstructor()->getName() === $scope->getFunction()->getName() && TypeUtils::findThisType($scope->getType($node->getPropertyFetch()->var)) !== null) { return; } $methodImpurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $node, 'propertyAssign', 'property assignment', \true); return; } if ($node instanceof ExecutionEndNode) { $executionEnds[] = $node; return; } if ($node instanceof Expr\Yield_ || $node instanceof Expr\YieldFrom) { $gatheredYieldStatements[] = $node; } if (!$node instanceof Return_) { return; } $gatheredReturnStatements[] = new ReturnStatement($scope, $node); }, \PHPStan\Analyser\StatementContext::createTopLevel()); $classReflection = $scope->getClassReflection(); $methodReflection = $methodScope->getFunction(); if (!$methodReflection instanceof PhpMethodFromParserNodeReflection) { throw new ShouldNotHappenException(); } $nodeCallback(new MethodReturnStatementsNode($stmt, $gatheredReturnStatements, $gatheredYieldStatements, $statementResult, $executionEnds, array_merge($statementResult->getImpurePoints(), $methodImpurePoints), $classReflection, $methodReflection), $methodScope); } } elseif ($stmt instanceof Echo_) { $hasYield = \false; $throwPoints = []; foreach ($stmt->exprs as $echoExpr) { $result = $this->processExprNode($stmt, $echoExpr, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $scope = $result->getScope(); $hasYield = $hasYield || $result->hasYield(); } $throwPoints = $overridingThrowPoints ?? $throwPoints; $impurePoints = [new \PHPStan\Analyser\ImpurePoint($scope, $stmt, 'echo', 'echo', \true)]; } elseif ($stmt instanceof Return_) { if ($stmt->expr !== null) { $result = $this->processExprNode($stmt, $stmt->expr, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $scope = $result->getScope(); $hasYield = $result->hasYield(); } else { $hasYield = \false; $throwPoints = []; $impurePoints = []; } return new \PHPStan\Analyser\StatementResult($scope, $hasYield, \true, [new \PHPStan\Analyser\StatementExitPoint($stmt, $scope)], $overridingThrowPoints ?? $throwPoints, $impurePoints); } elseif ($stmt instanceof Continue_ || $stmt instanceof Break_) { if ($stmt->num !== null) { $result = $this->processExprNode($stmt, $stmt->num, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); } else { $hasYield = \false; $throwPoints = []; $impurePoints = []; } return new \PHPStan\Analyser\StatementResult($scope, $hasYield, \true, [new \PHPStan\Analyser\StatementExitPoint($stmt, $scope)], $overridingThrowPoints ?? $throwPoints, $impurePoints); } elseif ($stmt instanceof Node\Stmt\Expression) { $earlyTerminationExpr = $this->findEarlyTerminatingExpr($stmt->expr, $scope); $hasAssign = \false; $currentScope = $scope; $result = $this->processExprNode($stmt, $stmt->expr, $scope, static function (Node $node, \PHPStan\Analyser\Scope $scope) use($nodeCallback, $currentScope, &$hasAssign) : void { $nodeCallback($node, $scope); if ($scope->getAnonymousFunctionReflection() !== $currentScope->getAnonymousFunctionReflection()) { return; } if ($scope->getFunction() !== $currentScope->getFunction()) { return; } if (!$node instanceof VariableAssignNode && !$node instanceof PropertyAssignNode) { return; } $hasAssign = \true; }, \PHPStan\Analyser\ExpressionContext::createTopLevel()); $throwPoints = array_filter($result->getThrowPoints(), static function ($throwPoint) { return $throwPoint->isExplicit(); }); if (count($result->getImpurePoints()) === 0 && count($throwPoints) === 0 && !$stmt->expr instanceof Expr\PostInc && !$stmt->expr instanceof Expr\PreInc && !$stmt->expr instanceof Expr\PostDec && !$stmt->expr instanceof Expr\PreDec) { $nodeCallback(new NoopExpressionNode($stmt->expr, $hasAssign), $scope); } $scope = $result->getScope(); $scope = $scope->filterBySpecifiedTypes($this->typeSpecifier->specifyTypesInCondition($scope, $stmt->expr, \PHPStan\Analyser\TypeSpecifierContext::createNull())); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); if ($earlyTerminationExpr !== null) { return new \PHPStan\Analyser\StatementResult($scope, $hasYield, \true, [new \PHPStan\Analyser\StatementExitPoint($stmt, $scope)], $overridingThrowPoints ?? $throwPoints, $impurePoints); } return new \PHPStan\Analyser\StatementResult($scope, $hasYield, \false, [], $overridingThrowPoints ?? $throwPoints, $impurePoints); } elseif ($stmt instanceof Node\Stmt\Namespace_) { if ($stmt->name !== null) { $scope = $scope->enterNamespace($stmt->name->toString()); } $scope = $this->processStmtNodes($stmt, $stmt->stmts, $scope, $nodeCallback, $context)->getScope(); $hasYield = \false; $throwPoints = []; $impurePoints = []; } elseif ($stmt instanceof Node\Stmt\Trait_) { return new \PHPStan\Analyser\StatementResult($scope, \false, \false, [], [], []); } elseif ($stmt instanceof Node\Stmt\ClassLike) { if (!$context->isTopLevel()) { return new \PHPStan\Analyser\StatementResult($scope, \false, \false, [], [], []); } $hasYield = \false; $throwPoints = []; $impurePoints = []; if (isset($stmt->namespacedName)) { $classReflection = $this->getCurrentClassReflection($stmt, $stmt->namespacedName->toString(), $scope); $classScope = $scope->enterClass($classReflection); $nodeCallback(new InClassNode($stmt, $classReflection), $classScope); } elseif ($stmt instanceof Class_) { if ($stmt->name === null) { throw new ShouldNotHappenException(); } if (!$stmt->isAnonymous()) { $classReflection = $this->reflectionProvider->getClass($stmt->name->toString()); } else { $classReflection = $this->reflectionProvider->getAnonymousClassReflection($stmt, $scope); } $classScope = $scope->enterClass($classReflection); $nodeCallback(new InClassNode($stmt, $classReflection), $classScope); } else { throw new ShouldNotHappenException(); } $classStatementsGatherer = new ClassStatementsGatherer($classReflection, $nodeCallback); $this->processAttributeGroups($stmt, $stmt->attrGroups, $classScope, $classStatementsGatherer); $this->processStmtNodes($stmt, $stmt->stmts, $classScope, $classStatementsGatherer, $context); $nodeCallback(new ClassPropertiesNode($stmt, $this->readWritePropertiesExtensionProvider, $classStatementsGatherer->getProperties(), $classStatementsGatherer->getPropertyUsages(), $classStatementsGatherer->getMethodCalls(), $classStatementsGatherer->getReturnStatementsNodes(), $classStatementsGatherer->getPropertyAssigns(), $classReflection), $classScope); $nodeCallback(new ClassMethodsNode($stmt, $classStatementsGatherer->getMethods(), $classStatementsGatherer->getMethodCalls(), $classReflection), $classScope); $nodeCallback(new ClassConstantsNode($stmt, $classStatementsGatherer->getConstants(), $classStatementsGatherer->getConstantFetches(), $classReflection), $classScope); $classReflection->evictPrivateSymbols(); $this->calledMethodResults = []; } elseif ($stmt instanceof Node\Stmt\Property) { $hasYield = \false; $throwPoints = []; $impurePoints = []; $this->processAttributeGroups($stmt, $stmt->attrGroups, $scope, $nodeCallback); foreach ($stmt->props as $prop) { $nodeCallback($prop, $scope); if ($prop->default !== null) { $this->processExprNode($stmt, $prop->default, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); } [, , , , , , , , , , , , $isReadOnly, $docComment, , , , $varTags, $isAllowedPrivateMutation] = $this->getPhpDocs($scope, $stmt); if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } $propertyName = $prop->name->toString(); $phpDocType = null; if (isset($varTags[0]) && count($varTags) === 1) { $phpDocType = $varTags[0]->getType(); } elseif (isset($varTags[$propertyName])) { $phpDocType = $varTags[$propertyName]->getType(); } $nodeCallback(new ClassPropertyNode($propertyName, $stmt->flags, $stmt->type, $prop->default, $docComment, $phpDocType, \false, \false, $prop, $isReadOnly, $scope->isInTrait(), $scope->getClassReflection()->isReadOnly(), $isAllowedPrivateMutation, $scope->getClassReflection()), $scope); } if ($stmt->type !== null) { $nodeCallback($stmt->type, $scope); } } elseif ($stmt instanceof Throw_) { $result = $this->processExprNode($stmt, $stmt->expr, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $throwPoints = $result->getThrowPoints(); $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createExplicit($result->getScope(), $scope->getType($stmt->expr), $stmt, \false); $impurePoints = $result->getImpurePoints(); return new \PHPStan\Analyser\StatementResult($result->getScope(), $result->hasYield(), \true, [new \PHPStan\Analyser\StatementExitPoint($stmt, $scope)], $throwPoints, $impurePoints); } elseif ($stmt instanceof If_) { $conditionType = ($this->treatPhpDocTypesAsCertain ? $scope->getType($stmt->cond) : $scope->getNativeType($stmt->cond))->toBoolean(); $ifAlwaysTrue = $conditionType->isTrue()->yes(); $condResult = $this->processExprNode($stmt, $stmt->cond, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $exitPoints = []; $throwPoints = $overridingThrowPoints ?? $condResult->getThrowPoints(); $impurePoints = $condResult->getImpurePoints(); $endStatements = []; $finalScope = null; $alwaysTerminating = \true; $hasYield = $condResult->hasYield(); $branchScopeStatementResult = $this->processStmtNodes($stmt, $stmt->stmts, $condResult->getTruthyScope(), $nodeCallback, $context); if (!$conditionType instanceof ConstantBooleanType || $conditionType->getValue()) { $exitPoints = $branchScopeStatementResult->getExitPoints(); $throwPoints = array_merge($throwPoints, $branchScopeStatementResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $branchScopeStatementResult->getImpurePoints()); $branchScope = $branchScopeStatementResult->getScope(); $finalScope = $branchScopeStatementResult->isAlwaysTerminating() ? null : $branchScope; $alwaysTerminating = $branchScopeStatementResult->isAlwaysTerminating(); if (count($branchScopeStatementResult->getEndStatements()) > 0) { $endStatements = array_merge($endStatements, $branchScopeStatementResult->getEndStatements()); } elseif (count($stmt->stmts) > 0) { $endStatements[] = new \PHPStan\Analyser\EndStatementResult($stmt->stmts[count($stmt->stmts) - 1], $branchScopeStatementResult); } else { $endStatements[] = new \PHPStan\Analyser\EndStatementResult($stmt, $branchScopeStatementResult); } $hasYield = $branchScopeStatementResult->hasYield() || $hasYield; } $scope = $condResult->getFalseyScope(); $lastElseIfConditionIsTrue = \false; $condScope = $scope; foreach ($stmt->elseifs as $elseif) { $nodeCallback($elseif, $scope); $elseIfConditionType = ($this->treatPhpDocTypesAsCertain ? $condScope->getType($elseif->cond) : $scope->getNativeType($elseif->cond))->toBoolean(); $condResult = $this->processExprNode($stmt, $elseif->cond, $condScope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $throwPoints = array_merge($throwPoints, $condResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $condResult->getImpurePoints()); $condScope = $condResult->getScope(); $branchScopeStatementResult = $this->processStmtNodes($elseif, $elseif->stmts, $condResult->getTruthyScope(), $nodeCallback, $context); if (!$ifAlwaysTrue && (!$lastElseIfConditionIsTrue && (!$elseIfConditionType instanceof ConstantBooleanType || $elseIfConditionType->getValue()))) { $exitPoints = array_merge($exitPoints, $branchScopeStatementResult->getExitPoints()); $throwPoints = array_merge($throwPoints, $branchScopeStatementResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $branchScopeStatementResult->getImpurePoints()); $branchScope = $branchScopeStatementResult->getScope(); $finalScope = $branchScopeStatementResult->isAlwaysTerminating() ? $finalScope : $branchScope->mergeWith($finalScope); $alwaysTerminating = $alwaysTerminating && $branchScopeStatementResult->isAlwaysTerminating(); if (count($branchScopeStatementResult->getEndStatements()) > 0) { $endStatements = array_merge($endStatements, $branchScopeStatementResult->getEndStatements()); } elseif (count($elseif->stmts) > 0) { $endStatements[] = new \PHPStan\Analyser\EndStatementResult($elseif->stmts[count($elseif->stmts) - 1], $branchScopeStatementResult); } else { $endStatements[] = new \PHPStan\Analyser\EndStatementResult($elseif, $branchScopeStatementResult); } $hasYield = $hasYield || $branchScopeStatementResult->hasYield(); } if ($elseIfConditionType->isTrue()->yes()) { $lastElseIfConditionIsTrue = \true; } $condScope = $condScope->filterByFalseyValue($elseif->cond); $scope = $condScope; } if ($stmt->else === null) { if (!$ifAlwaysTrue && !$lastElseIfConditionIsTrue) { $finalScope = $scope->mergeWith($finalScope); $alwaysTerminating = \false; } } else { $nodeCallback($stmt->else, $scope); $branchScopeStatementResult = $this->processStmtNodes($stmt->else, $stmt->else->stmts, $scope, $nodeCallback, $context); if (!$ifAlwaysTrue && !$lastElseIfConditionIsTrue) { $exitPoints = array_merge($exitPoints, $branchScopeStatementResult->getExitPoints()); $throwPoints = array_merge($throwPoints, $branchScopeStatementResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $branchScopeStatementResult->getImpurePoints()); $branchScope = $branchScopeStatementResult->getScope(); $finalScope = $branchScopeStatementResult->isAlwaysTerminating() ? $finalScope : $branchScope->mergeWith($finalScope); $alwaysTerminating = $alwaysTerminating && $branchScopeStatementResult->isAlwaysTerminating(); if (count($branchScopeStatementResult->getEndStatements()) > 0) { $endStatements = array_merge($endStatements, $branchScopeStatementResult->getEndStatements()); } elseif (count($stmt->else->stmts) > 0) { $endStatements[] = new \PHPStan\Analyser\EndStatementResult($stmt->else->stmts[count($stmt->else->stmts) - 1], $branchScopeStatementResult); } else { $endStatements[] = new \PHPStan\Analyser\EndStatementResult($stmt->else, $branchScopeStatementResult); } $hasYield = $hasYield || $branchScopeStatementResult->hasYield(); } } if ($finalScope === null) { $finalScope = $scope; } if ($stmt->else === null && !$ifAlwaysTrue && !$lastElseIfConditionIsTrue) { $endStatements[] = new \PHPStan\Analyser\EndStatementResult($stmt, new \PHPStan\Analyser\StatementResult($finalScope, $hasYield, $alwaysTerminating, $exitPoints, $throwPoints, $impurePoints)); } return new \PHPStan\Analyser\StatementResult($finalScope, $hasYield, $alwaysTerminating, $exitPoints, $throwPoints, $impurePoints, $endStatements); } elseif ($stmt instanceof Node\Stmt\TraitUse) { $hasYield = \false; $throwPoints = []; $impurePoints = []; $this->processTraitUse($stmt, $scope, $nodeCallback); } elseif ($stmt instanceof Foreach_) { $condResult = $this->processExprNode($stmt, $stmt->expr, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $throwPoints = $overridingThrowPoints ?? $condResult->getThrowPoints(); $impurePoints = $condResult->getImpurePoints(); $scope = $condResult->getScope(); $arrayComparisonExpr = new BinaryOp\NotIdentical($stmt->expr, new Array_([])); if ($stmt->expr instanceof Variable && is_string($stmt->expr->name)) { $scope = $this->processVarAnnotation($scope, [$stmt->expr->name], $stmt); } $nodeCallback(new InForeachNode($stmt), $scope); $originalScope = $scope; $bodyScope = $scope; if ($context->isTopLevel()) { $originalScope = $this->polluteScopeWithAlwaysIterableForeach ? $scope->filterByTruthyValue($arrayComparisonExpr) : $scope; $bodyScope = $this->enterForeach($originalScope, $originalScope, $stmt); $count = 0; do { $prevScope = $bodyScope; $bodyScope = $bodyScope->mergeWith($this->polluteScopeWithAlwaysIterableForeach ? $scope->filterByTruthyValue($arrayComparisonExpr) : $scope); $bodyScope = $this->enterForeach($bodyScope, $originalScope, $stmt); $bodyScopeResult = $this->processStmtNodes($stmt, $stmt->stmts, $bodyScope, static function () : void { }, $context->enterDeep())->filterOutLoopExitPoints(); $bodyScope = $bodyScopeResult->getScope(); foreach ($bodyScopeResult->getExitPointsByType(Continue_::class) as $continueExitPoint) { $bodyScope = $bodyScope->mergeWith($continueExitPoint->getScope()); } if ($bodyScope->equals($prevScope)) { break; } if ($count >= self::GENERALIZE_AFTER_ITERATION) { $bodyScope = $prevScope->generalizeWith($bodyScope); } $count++; } while ($count < self::LOOP_SCOPE_ITERATIONS); } $bodyScope = $bodyScope->mergeWith($this->polluteScopeWithAlwaysIterableForeach ? $scope->filterByTruthyValue($arrayComparisonExpr) : $scope); $bodyScope = $this->enterForeach($bodyScope, $originalScope, $stmt); $finalScopeResult = $this->processStmtNodes($stmt, $stmt->stmts, $bodyScope, $nodeCallback, $context)->filterOutLoopExitPoints(); $finalScope = $finalScopeResult->getScope(); foreach ($finalScopeResult->getExitPointsByType(Continue_::class) as $continueExitPoint) { $finalScope = $continueExitPoint->getScope()->mergeWith($finalScope); } foreach ($finalScopeResult->getExitPointsByType(Break_::class) as $breakExitPoint) { $finalScope = $breakExitPoint->getScope()->mergeWith($finalScope); } $exprType = $scope->getType($stmt->expr); $isIterableAtLeastOnce = $exprType->isIterableAtLeastOnce(); if ($exprType->isIterable()->no() || $isIterableAtLeastOnce->maybe()) { $finalScope = $finalScope->mergeWith($scope->filterByTruthyValue(new BooleanOr(new BinaryOp\Identical($stmt->expr, new Array_([])), new FuncCall(new Name\FullyQualified('is_object'), [new Arg($stmt->expr)])))); } elseif ($isIterableAtLeastOnce->no() || $finalScopeResult->isAlwaysTerminating()) { $finalScope = $scope; } elseif (!$this->polluteScopeWithAlwaysIterableForeach) { $finalScope = $scope->processAlwaysIterableForeachScopeWithoutPollute($finalScope); // get types from finalScope, but don't create new variables } if (!$isIterableAtLeastOnce->no()) { $throwPoints = array_merge($throwPoints, $finalScopeResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $finalScopeResult->getImpurePoints()); } if (!(new ObjectType(Traversable::class))->isSuperTypeOf($scope->getType($stmt->expr))->no()) { $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $stmt->expr); } return new \PHPStan\Analyser\StatementResult($finalScope, $finalScopeResult->hasYield() || $condResult->hasYield(), $isIterableAtLeastOnce->yes() && $finalScopeResult->isAlwaysTerminating(), $finalScopeResult->getExitPointsForOuterLoop(), $throwPoints, $impurePoints); } elseif ($stmt instanceof While_) { $condResult = $this->processExprNode($stmt, $stmt->cond, $scope, static function () : void { }, \PHPStan\Analyser\ExpressionContext::createDeep()); $bodyScope = $condResult->getTruthyScope(); if ($context->isTopLevel()) { $count = 0; do { $prevScope = $bodyScope; $bodyScope = $bodyScope->mergeWith($scope); $bodyScope = $this->processExprNode($stmt, $stmt->cond, $bodyScope, static function () : void { }, \PHPStan\Analyser\ExpressionContext::createDeep())->getTruthyScope(); $bodyScopeResult = $this->processStmtNodes($stmt, $stmt->stmts, $bodyScope, static function () : void { }, $context->enterDeep())->filterOutLoopExitPoints(); $bodyScope = $bodyScopeResult->getScope(); foreach ($bodyScopeResult->getExitPointsByType(Continue_::class) as $continueExitPoint) { $bodyScope = $bodyScope->mergeWith($continueExitPoint->getScope()); } if ($bodyScope->equals($prevScope)) { break; } if ($count >= self::GENERALIZE_AFTER_ITERATION) { $bodyScope = $prevScope->generalizeWith($bodyScope); } $count++; } while ($count < self::LOOP_SCOPE_ITERATIONS); } $bodyScope = $bodyScope->mergeWith($scope); $bodyScopeMaybeRan = $bodyScope; $bodyScope = $this->processExprNode($stmt, $stmt->cond, $bodyScope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep())->getTruthyScope(); $finalScopeResult = $this->processStmtNodes($stmt, $stmt->stmts, $bodyScope, $nodeCallback, $context)->filterOutLoopExitPoints(); $finalScope = $finalScopeResult->getScope()->filterByFalseyValue($stmt->cond); $condBooleanType = ($this->treatPhpDocTypesAsCertain ? $bodyScopeMaybeRan->getType($stmt->cond) : $bodyScopeMaybeRan->getNativeType($stmt->cond))->toBoolean(); $alwaysIterates = $condBooleanType->isTrue()->yes() && $context->isTopLevel(); $neverIterates = $condBooleanType->isFalse()->yes() && $context->isTopLevel(); if (!$alwaysIterates) { foreach ($finalScopeResult->getExitPointsByType(Continue_::class) as $continueExitPoint) { $finalScope = $finalScope->mergeWith($continueExitPoint->getScope()); } } $breakExitPoints = $finalScopeResult->getExitPointsByType(Break_::class); foreach ($breakExitPoints as $breakExitPoint) { $finalScope = $finalScope->mergeWith($breakExitPoint->getScope()); } $beforeCondBooleanType = ($this->treatPhpDocTypesAsCertain ? $scope->getType($stmt->cond) : $scope->getNativeType($stmt->cond))->toBoolean(); $isIterableAtLeastOnce = $beforeCondBooleanType->isTrue()->yes(); $nodeCallback(new BreaklessWhileLoopNode($stmt, $finalScopeResult->getExitPoints()), $bodyScopeMaybeRan); if ($alwaysIterates) { $isAlwaysTerminating = count($finalScopeResult->getExitPointsByType(Break_::class)) === 0; } elseif ($isIterableAtLeastOnce) { $isAlwaysTerminating = $finalScopeResult->isAlwaysTerminating(); } else { $isAlwaysTerminating = \false; } $condScope = $condResult->getFalseyScope(); if (!$isIterableAtLeastOnce) { if (!$this->polluteScopeWithLoopInitialAssignments) { $condScope = $condScope->mergeWith($scope); } $finalScope = $finalScope->mergeWith($condScope); } $throwPoints = $overridingThrowPoints ?? $condResult->getThrowPoints(); $impurePoints = $condResult->getImpurePoints(); if (!$neverIterates) { $throwPoints = array_merge($throwPoints, $finalScopeResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $finalScopeResult->getImpurePoints()); } return new \PHPStan\Analyser\StatementResult($finalScope, $finalScopeResult->hasYield() || $condResult->hasYield(), $isAlwaysTerminating, $finalScopeResult->getExitPointsForOuterLoop(), $throwPoints, $impurePoints); } elseif ($stmt instanceof Do_) { $finalScope = null; $bodyScope = $scope; $count = 0; $hasYield = \false; $throwPoints = []; $impurePoints = []; if ($context->isTopLevel()) { do { $prevScope = $bodyScope; $bodyScope = $bodyScope->mergeWith($scope); $bodyScopeResult = $this->processStmtNodes($stmt, $stmt->stmts, $bodyScope, static function () : void { }, $context->enterDeep())->filterOutLoopExitPoints(); $alwaysTerminating = $bodyScopeResult->isAlwaysTerminating(); $bodyScope = $bodyScopeResult->getScope(); foreach ($bodyScopeResult->getExitPointsByType(Continue_::class) as $continueExitPoint) { $bodyScope = $bodyScope->mergeWith($continueExitPoint->getScope()); } $finalScope = $alwaysTerminating ? $finalScope : $bodyScope->mergeWith($finalScope); foreach ($bodyScopeResult->getExitPointsByType(Break_::class) as $breakExitPoint) { $finalScope = $breakExitPoint->getScope()->mergeWith($finalScope); } $bodyScope = $this->processExprNode($stmt, $stmt->cond, $bodyScope, static function () : void { }, \PHPStan\Analyser\ExpressionContext::createDeep())->getTruthyScope(); if ($bodyScope->equals($prevScope)) { break; } if ($count >= self::GENERALIZE_AFTER_ITERATION) { $bodyScope = $prevScope->generalizeWith($bodyScope); } $count++; } while ($count < self::LOOP_SCOPE_ITERATIONS); $bodyScope = $bodyScope->mergeWith($scope); } $bodyScopeResult = $this->processStmtNodes($stmt, $stmt->stmts, $bodyScope, $nodeCallback, $context)->filterOutLoopExitPoints(); $bodyScope = $bodyScopeResult->getScope(); foreach ($bodyScopeResult->getExitPointsByType(Continue_::class) as $continueExitPoint) { $bodyScope = $bodyScope->mergeWith($continueExitPoint->getScope()); } $condBooleanType = ($this->treatPhpDocTypesAsCertain ? $bodyScope->getType($stmt->cond) : $bodyScope->getNativeType($stmt->cond))->toBoolean(); $alwaysIterates = $condBooleanType->isTrue()->yes() && $context->isTopLevel(); $nodeCallback(new DoWhileLoopConditionNode($stmt->cond, $bodyScopeResult->getExitPoints()), $bodyScope); if ($alwaysIterates) { $alwaysTerminating = count($bodyScopeResult->getExitPointsByType(Break_::class)) === 0; } else { $alwaysTerminating = $bodyScopeResult->isAlwaysTerminating(); } $finalScope = $alwaysTerminating ? $finalScope : $bodyScope->mergeWith($finalScope); if ($finalScope === null) { $finalScope = $scope; } if (!$alwaysTerminating) { $condResult = $this->processExprNode($stmt, $stmt->cond, $bodyScope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $hasYield = $condResult->hasYield(); $throwPoints = $condResult->getThrowPoints(); $impurePoints = $condResult->getImpurePoints(); $finalScope = $condResult->getFalseyScope(); } else { $this->processExprNode($stmt, $stmt->cond, $bodyScope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); } foreach ($bodyScopeResult->getExitPointsByType(Break_::class) as $breakExitPoint) { $finalScope = $breakExitPoint->getScope()->mergeWith($finalScope); } return new \PHPStan\Analyser\StatementResult($finalScope, $bodyScopeResult->hasYield() || $hasYield, $alwaysTerminating, $bodyScopeResult->getExitPointsForOuterLoop(), array_merge($throwPoints, $bodyScopeResult->getThrowPoints()), array_merge($impurePoints, $bodyScopeResult->getImpurePoints())); } elseif ($stmt instanceof For_) { $initScope = $scope; $hasYield = \false; $throwPoints = []; $impurePoints = []; foreach ($stmt->init as $initExpr) { $initResult = $this->processExprNode($stmt, $initExpr, $initScope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createTopLevel()); $initScope = $initResult->getScope(); $hasYield = $hasYield || $initResult->hasYield(); $throwPoints = array_merge($throwPoints, $initResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $initResult->getImpurePoints()); } $bodyScope = $initScope; $isIterableAtLeastOnce = TrinaryLogic::createYes(); $lastCondExpr = $stmt->cond[count($stmt->cond) - 1] ?? null; foreach ($stmt->cond as $condExpr) { $condResult = $this->processExprNode($stmt, $condExpr, $bodyScope, static function () : void { }, \PHPStan\Analyser\ExpressionContext::createDeep()); $initScope = $condResult->getScope(); $condResultScope = $condResult->getScope(); if ($condExpr === $lastCondExpr) { $condTruthiness = ($this->treatPhpDocTypesAsCertain ? $condResultScope->getType($condExpr) : $condResultScope->getNativeType($condExpr))->toBoolean(); $isIterableAtLeastOnce = $isIterableAtLeastOnce->and($condTruthiness->isTrue()); } $hasYield = $hasYield || $condResult->hasYield(); $throwPoints = array_merge($throwPoints, $condResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $condResult->getImpurePoints()); $bodyScope = $condResult->getTruthyScope(); } if ($context->isTopLevel()) { $count = 0; do { $prevScope = $bodyScope; $bodyScope = $bodyScope->mergeWith($initScope); if ($lastCondExpr !== null) { $bodyScope = $this->processExprNode($stmt, $lastCondExpr, $bodyScope, static function () : void { }, \PHPStan\Analyser\ExpressionContext::createDeep())->getTruthyScope(); } $bodyScopeResult = $this->processStmtNodes($stmt, $stmt->stmts, $bodyScope, static function () : void { }, $context->enterDeep())->filterOutLoopExitPoints(); $bodyScope = $bodyScopeResult->getScope(); foreach ($bodyScopeResult->getExitPointsByType(Continue_::class) as $continueExitPoint) { $bodyScope = $bodyScope->mergeWith($continueExitPoint->getScope()); } foreach ($stmt->loop as $loopExpr) { $exprResult = $this->processExprNode($stmt, $loopExpr, $bodyScope, static function () : void { }, \PHPStan\Analyser\ExpressionContext::createTopLevel()); $bodyScope = $exprResult->getScope(); $hasYield = $hasYield || $exprResult->hasYield(); $throwPoints = array_merge($throwPoints, $exprResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $exprResult->getImpurePoints()); } if ($bodyScope->equals($prevScope)) { break; } if ($count >= self::GENERALIZE_AFTER_ITERATION) { $bodyScope = $prevScope->generalizeWith($bodyScope); } $count++; } while ($count < self::LOOP_SCOPE_ITERATIONS); } $bodyScope = $bodyScope->mergeWith($initScope); $alwaysIterates = TrinaryLogic::createFromBoolean($context->isTopLevel()); if ($lastCondExpr !== null) { $alwaysIterates = $alwaysIterates->and($bodyScope->getType($lastCondExpr)->toBoolean()->isTrue()); $bodyScope = $this->processExprNode($stmt, $lastCondExpr, $bodyScope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep())->getTruthyScope(); } $finalScopeResult = $this->processStmtNodes($stmt, $stmt->stmts, $bodyScope, $nodeCallback, $context)->filterOutLoopExitPoints(); $finalScope = $finalScopeResult->getScope(); foreach ($finalScopeResult->getExitPointsByType(Continue_::class) as $continueExitPoint) { $finalScope = $continueExitPoint->getScope()->mergeWith($finalScope); } $loopScope = $finalScope; foreach ($stmt->loop as $loopExpr) { $loopScope = $this->processExprNode($stmt, $loopExpr, $loopScope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createTopLevel())->getScope(); } $finalScope = $finalScope->generalizeWith($loopScope); if ($lastCondExpr !== null) { $finalScope = $finalScope->filterByFalseyValue($lastCondExpr); } foreach ($finalScopeResult->getExitPointsByType(Break_::class) as $breakExitPoint) { $finalScope = $breakExitPoint->getScope()->mergeWith($finalScope); } if ($isIterableAtLeastOnce->no() || $finalScopeResult->isAlwaysTerminating()) { if ($this->polluteScopeWithLoopInitialAssignments) { $finalScope = $initScope; } else { $finalScope = $scope; } } elseif ($isIterableAtLeastOnce->maybe()) { if ($this->polluteScopeWithLoopInitialAssignments) { $finalScope = $finalScope->mergeWith($initScope); } else { $finalScope = $finalScope->mergeWith($scope); } } else { if (!$this->polluteScopeWithLoopInitialAssignments) { $finalScope = $finalScope->mergeWith($scope); } } if ($alwaysIterates->yes()) { $isAlwaysTerminating = count($finalScopeResult->getExitPointsByType(Break_::class)) === 0; } elseif ($isIterableAtLeastOnce->yes()) { $isAlwaysTerminating = $finalScopeResult->isAlwaysTerminating(); } else { $isAlwaysTerminating = \false; } return new \PHPStan\Analyser\StatementResult($finalScope, $finalScopeResult->hasYield() || $hasYield, $isAlwaysTerminating, $finalScopeResult->getExitPointsForOuterLoop(), array_merge($throwPoints, $finalScopeResult->getThrowPoints()), array_merge($impurePoints, $finalScopeResult->getImpurePoints())); } elseif ($stmt instanceof Switch_) { $condResult = $this->processExprNode($stmt, $stmt->cond, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $scope = $condResult->getScope(); $scopeForBranches = $scope; $finalScope = null; $prevScope = null; $hasDefaultCase = \false; $alwaysTerminating = \true; $hasYield = $condResult->hasYield(); $exitPointsForOuterLoop = []; $throwPoints = $condResult->getThrowPoints(); $impurePoints = $condResult->getImpurePoints(); $fullCondExpr = null; foreach ($stmt->cases as $caseNode) { if ($caseNode->cond !== null) { $condExpr = new BinaryOp\Equal($stmt->cond, $caseNode->cond); $fullCondExpr = $fullCondExpr === null ? $condExpr : new BooleanOr($fullCondExpr, $condExpr); $caseResult = $this->processExprNode($stmt, $caseNode->cond, $scopeForBranches, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $scopeForBranches = $caseResult->getScope(); $hasYield = $hasYield || $caseResult->hasYield(); $throwPoints = array_merge($throwPoints, $caseResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $caseResult->getImpurePoints()); $branchScope = $caseResult->getTruthyScope()->filterByTruthyValue($condExpr); } else { $hasDefaultCase = \true; $fullCondExpr = null; $branchScope = $scopeForBranches; } $branchScope = $branchScope->mergeWith($prevScope); $branchScopeResult = $this->processStmtNodes($caseNode, $caseNode->stmts, $branchScope, $nodeCallback, $context); $branchScope = $branchScopeResult->getScope(); $branchFinalScopeResult = $branchScopeResult->filterOutLoopExitPoints(); $hasYield = $hasYield || $branchFinalScopeResult->hasYield(); foreach ($branchScopeResult->getExitPointsByType(Break_::class) as $breakExitPoint) { $alwaysTerminating = \false; $finalScope = $breakExitPoint->getScope()->mergeWith($finalScope); } foreach ($branchScopeResult->getExitPointsByType(Continue_::class) as $continueExitPoint) { $finalScope = $continueExitPoint->getScope()->mergeWith($finalScope); } $exitPointsForOuterLoop = array_merge($exitPointsForOuterLoop, $branchFinalScopeResult->getExitPointsForOuterLoop()); $throwPoints = array_merge($throwPoints, $branchFinalScopeResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $branchFinalScopeResult->getImpurePoints()); if ($branchScopeResult->isAlwaysTerminating()) { $alwaysTerminating = $alwaysTerminating && $branchFinalScopeResult->isAlwaysTerminating(); $prevScope = null; if (isset($fullCondExpr)) { $scopeForBranches = $scopeForBranches->filterByFalseyValue($fullCondExpr); $fullCondExpr = null; } if (!$branchFinalScopeResult->isAlwaysTerminating()) { $finalScope = $branchScope->mergeWith($finalScope); } } else { $prevScope = $branchScope; } } $exhaustive = $scopeForBranches->getType($stmt->cond) instanceof NeverType; if (!$hasDefaultCase && !$exhaustive) { $alwaysTerminating = \false; } if ($prevScope !== null && isset($branchFinalScopeResult)) { $finalScope = $prevScope->mergeWith($finalScope); $alwaysTerminating = $alwaysTerminating && $branchFinalScopeResult->isAlwaysTerminating(); } if (!$hasDefaultCase && !$exhaustive || $finalScope === null) { $finalScope = $scope->mergeWith($finalScope); } return new \PHPStan\Analyser\StatementResult($finalScope, $hasYield, $alwaysTerminating, $exitPointsForOuterLoop, $throwPoints, $impurePoints); } elseif ($stmt instanceof TryCatch) { $branchScopeResult = $this->processStmtNodes($stmt, $stmt->stmts, $scope, $nodeCallback, $context); $branchScope = $branchScopeResult->getScope(); $finalScope = $branchScopeResult->isAlwaysTerminating() ? null : $branchScope; $exitPoints = []; $finallyExitPoints = []; $alwaysTerminating = $branchScopeResult->isAlwaysTerminating(); $hasYield = $branchScopeResult->hasYield(); if ($stmt->finally !== null) { $finallyScope = $branchScope; } else { $finallyScope = null; } foreach ($branchScopeResult->getExitPoints() as $exitPoint) { $finallyExitPoints[] = $exitPoint; if ($exitPoint->getStatement() instanceof Throw_) { continue; } if ($finallyScope !== null) { $finallyScope = $finallyScope->mergeWith($exitPoint->getScope()); } $exitPoints[] = $exitPoint; } $throwPoints = $branchScopeResult->getThrowPoints(); $impurePoints = $branchScopeResult->getImpurePoints(); $throwPointsForLater = []; $pastCatchTypes = new NeverType(); foreach ($stmt->catches as $catchNode) { $nodeCallback($catchNode, $scope); $originalCatchTypes = array_map(static function (Name $name) : Type { return new ObjectType($name->toString()); }, $catchNode->types); $catchTypes = array_map(static function (Type $type) use($pastCatchTypes) : Type { return TypeCombinator::remove($type, $pastCatchTypes); }, $originalCatchTypes); $originalCatchType = TypeCombinator::union(...$originalCatchTypes); $catchType = TypeCombinator::union(...$catchTypes); $pastCatchTypes = TypeCombinator::union($pastCatchTypes, $originalCatchType); $matchingThrowPoints = []; $matchingCatchTypes = array_fill_keys(array_keys($originalCatchTypes), \false); // throwable matches all foreach ($originalCatchTypes as $catchTypeIndex => $catchTypeItem) { if (!$catchTypeItem->isSuperTypeOf(new ObjectType(Throwable::class))->yes()) { continue; } foreach ($throwPoints as $throwPointIndex => $throwPoint) { $matchingThrowPoints[$throwPointIndex] = $throwPoint; $matchingCatchTypes[$catchTypeIndex] = \true; } } // explicit only $onlyExplicitIsThrow = \true; if (count($matchingThrowPoints) === 0) { foreach ($throwPoints as $throwPointIndex => $throwPoint) { foreach ($catchTypes as $catchTypeIndex => $catchTypeItem) { if ($catchTypeItem->isSuperTypeOf($throwPoint->getType())->no()) { continue; } $matchingCatchTypes[$catchTypeIndex] = \true; if (!$throwPoint->isExplicit()) { continue; } $throwNode = $throwPoint->getNode(); if (!$throwNode instanceof Throw_ && !$throwNode instanceof Expr\Throw_ && !($throwNode instanceof Node\Stmt\Expression && $throwNode->expr instanceof Expr\Throw_)) { $onlyExplicitIsThrow = \false; } $matchingThrowPoints[$throwPointIndex] = $throwPoint; } } } // implicit only if (count($matchingThrowPoints) === 0 || $this->explicitThrow && $onlyExplicitIsThrow) { foreach ($throwPoints as $throwPointIndex => $throwPoint) { if ($throwPoint->isExplicit()) { continue; } foreach ($catchTypes as $catchTypeIndex => $catchTypeItem) { if ($catchTypeItem->isSuperTypeOf($throwPoint->getType())->no()) { continue; } $matchingThrowPoints[$throwPointIndex] = $throwPoint; } } } // include previously removed throw points if (count($matchingThrowPoints) === 0) { if ($originalCatchType->isSuperTypeOf(new ObjectType(Throwable::class))->yes()) { foreach ($branchScopeResult->getThrowPoints() as $originalThrowPoint) { if (!$originalThrowPoint->canContainAnyThrowable()) { continue; } $matchingThrowPoints[] = $originalThrowPoint; $matchingCatchTypes = array_fill_keys(array_keys($originalCatchTypes), \true); } } } // emit error if ($this->detectDeadTypeInMultiCatch) { foreach ($matchingCatchTypes as $catchTypeIndex => $matched) { if ($matched) { continue; } $nodeCallback(new CatchWithUnthrownExceptionNode($catchNode, $catchTypes[$catchTypeIndex], $originalCatchTypes[$catchTypeIndex]), $scope); } } if (count($matchingThrowPoints) === 0) { if (!$this->detectDeadTypeInMultiCatch) { $nodeCallback(new CatchWithUnthrownExceptionNode($catchNode, $catchType, $originalCatchType), $scope); } continue; } // recompute throw points $newThrowPoints = []; foreach ($throwPoints as $throwPoint) { $newThrowPoint = $throwPoint->subtractCatchType($originalCatchType); if ($newThrowPoint->getType() instanceof NeverType) { continue; } $newThrowPoints[] = $newThrowPoint; } $throwPoints = $newThrowPoints; $catchScope = null; foreach ($matchingThrowPoints as $matchingThrowPoint) { if ($catchScope === null) { $catchScope = $matchingThrowPoint->getScope(); } else { $catchScope = $catchScope->mergeWith($matchingThrowPoint->getScope()); } } $variableName = null; if ($catchNode->var !== null) { if (!is_string($catchNode->var->name)) { throw new ShouldNotHappenException(); } $variableName = $catchNode->var->name; } $catchScopeResult = $this->processStmtNodes($catchNode, $catchNode->stmts, $catchScope->enterCatchType($catchType, $variableName), $nodeCallback, $context); $catchScopeForFinally = $catchScopeResult->getScope(); $finalScope = $catchScopeResult->isAlwaysTerminating() ? $finalScope : $catchScopeResult->getScope()->mergeWith($finalScope); $alwaysTerminating = $alwaysTerminating && $catchScopeResult->isAlwaysTerminating(); $hasYield = $hasYield || $catchScopeResult->hasYield(); $catchThrowPoints = $catchScopeResult->getThrowPoints(); $impurePoints = array_merge($impurePoints, $catchScopeResult->getImpurePoints()); $throwPointsForLater = array_merge($throwPointsForLater, $catchThrowPoints); if ($finallyScope !== null) { $finallyScope = $finallyScope->mergeWith($catchScopeForFinally); } foreach ($catchScopeResult->getExitPoints() as $exitPoint) { $finallyExitPoints[] = $exitPoint; if ($exitPoint->getStatement() instanceof Throw_) { continue; } if ($finallyScope !== null) { $finallyScope = $finallyScope->mergeWith($exitPoint->getScope()); } $exitPoints[] = $exitPoint; } foreach ($catchThrowPoints as $catchThrowPoint) { if ($finallyScope === null) { continue; } $finallyScope = $finallyScope->mergeWith($catchThrowPoint->getScope()); } } if ($finalScope === null) { $finalScope = $scope; } foreach ($throwPoints as $throwPoint) { if ($finallyScope === null) { continue; } $finallyScope = $finallyScope->mergeWith($throwPoint->getScope()); } if ($finallyScope !== null && $stmt->finally !== null) { $originalFinallyScope = $finallyScope; $finallyResult = $this->processStmtNodes($stmt->finally, $stmt->finally->stmts, $finallyScope, $nodeCallback, $context); $alwaysTerminating = $alwaysTerminating || $finallyResult->isAlwaysTerminating(); $hasYield = $hasYield || $finallyResult->hasYield(); $throwPointsForLater = array_merge($throwPointsForLater, $finallyResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $finallyResult->getImpurePoints()); $finallyScope = $finallyResult->getScope(); $finalScope = $finallyResult->isAlwaysTerminating() ? $finalScope : $finalScope->processFinallyScope($finallyScope, $originalFinallyScope); if (count($finallyResult->getExitPoints()) > 0) { $nodeCallback(new FinallyExitPointsNode($finallyResult->getExitPoints(), $finallyExitPoints), $scope); } $exitPoints = array_merge($exitPoints, $finallyResult->getExitPoints()); } return new \PHPStan\Analyser\StatementResult($finalScope, $hasYield, $alwaysTerminating, $exitPoints, array_merge($throwPoints, $throwPointsForLater), $impurePoints); } elseif ($stmt instanceof Unset_) { $hasYield = \false; $throwPoints = []; $impurePoints = []; foreach ($stmt->vars as $var) { $scope = $this->lookForSetAllowedUndefinedExpressions($scope, $var); $exprResult = $this->processExprNode($stmt, $var, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $scope = $exprResult->getScope(); $scope = $this->lookForUnsetAllowedUndefinedExpressions($scope, $var); $hasYield = $hasYield || $exprResult->hasYield(); $throwPoints = array_merge($throwPoints, $exprResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $exprResult->getImpurePoints()); if ($var instanceof ArrayDimFetch && $var->dim !== null) { $cloningTraverser = new NodeTraverser(); $cloningTraverser->addVisitor(new CloningVisitor()); /** @var Expr $clonedVar */ [$clonedVar] = $cloningTraverser->traverse([$var->var]); $traverser = new NodeTraverser(); $traverser->addVisitor(new class extends NodeVisitorAbstract { public function leaveNode(Node $node) : ?ExistingArrayDimFetch { if (!$node instanceof ArrayDimFetch || $node->dim === null) { return null; } return new ExistingArrayDimFetch($node->var, $node->dim); } }); /** @var Expr $clonedVar */ [$clonedVar] = $traverser->traverse([$clonedVar]); $scope = $this->processAssignVar($scope, $stmt, $clonedVar, new UnsetOffsetExpr($var->var, $var->dim), static function (Node $node, \PHPStan\Analyser\Scope $scope) use($nodeCallback) : void { if (!$node instanceof PropertyAssignNode && !$node instanceof VariableAssignNode) { return; } $nodeCallback($node, $scope); }, \PHPStan\Analyser\ExpressionContext::createDeep(), static function (\PHPStan\Analyser\MutatingScope $scope) : \PHPStan\Analyser\ExpressionResult { return new \PHPStan\Analyser\ExpressionResult($scope, \false, [], []); }, \false)->getScope(); } elseif ($var instanceof PropertyFetch) { $scope = $scope->invalidateExpression($var); $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $var, 'propertyUnset', 'property unset', \true); } else { $scope = $scope->invalidateExpression($var); } } } elseif ($stmt instanceof Node\Stmt\Use_) { $hasYield = \false; $throwPoints = []; $impurePoints = []; foreach ($stmt->uses as $use) { $nodeCallback($use, $scope); } } elseif ($stmt instanceof Node\Stmt\Global_) { $hasYield = \false; $throwPoints = []; $impurePoints = [new \PHPStan\Analyser\ImpurePoint($scope, $stmt, 'global', 'global variable', \true)]; $vars = []; foreach ($stmt->vars as $var) { if (!$var instanceof Variable) { throw new ShouldNotHappenException(); } $scope = $this->lookForSetAllowedUndefinedExpressions($scope, $var); $varResult = $this->processExprNode($stmt, $var, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $impurePoints = array_merge($impurePoints, $varResult->getImpurePoints()); $scope = $this->lookForUnsetAllowedUndefinedExpressions($scope, $var); if (!is_string($var->name)) { continue; } $scope = $scope->assignVariable($var->name, new MixedType(), new MixedType()); $vars[] = $var->name; } $scope = $this->processVarAnnotation($scope, $vars, $stmt); } elseif ($stmt instanceof Static_) { $hasYield = \false; $throwPoints = []; $impurePoints = [new \PHPStan\Analyser\ImpurePoint($scope, $stmt, 'static', 'static variable', \true)]; $vars = []; foreach ($stmt->vars as $var) { if (!is_string($var->var->name)) { throw new ShouldNotHappenException(); } if ($var->default !== null) { $defaultExprResult = $this->processExprNode($stmt, $var->default, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $impurePoints = array_merge($impurePoints, $defaultExprResult->getImpurePoints()); } $scope = $scope->enterExpressionAssign($var->var); $varResult = $this->processExprNode($stmt, $var->var, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $impurePoints = array_merge($impurePoints, $varResult->getImpurePoints()); $scope = $scope->exitExpressionAssign($var->var); $scope = $scope->assignVariable($var->var->name, new MixedType(), new MixedType()); $vars[] = $var->var->name; } $scope = $this->processVarAnnotation($scope, $vars, $stmt); } elseif ($stmt instanceof Node\Stmt\Const_) { $hasYield = \false; $throwPoints = []; $impurePoints = []; foreach ($stmt->consts as $const) { $nodeCallback($const, $scope); $constResult = $this->processExprNode($stmt, $const->value, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $impurePoints = array_merge($impurePoints, $constResult->getImpurePoints()); if ($const->namespacedName !== null) { $constantName = new Name\FullyQualified($const->namespacedName->toString()); } else { if ($const->name->toString() === '') { throw new ShouldNotHappenException('Constant cannot have a empty name'); } $constantName = new Name\FullyQualified($const->name->toString()); } $scope = $scope->assignExpression(new ConstFetch($constantName), $scope->getType($const->value), $scope->getNativeType($const->value)); } } elseif ($stmt instanceof Node\Stmt\ClassConst) { $hasYield = \false; $throwPoints = []; $impurePoints = []; $this->processAttributeGroups($stmt, $stmt->attrGroups, $scope, $nodeCallback); foreach ($stmt->consts as $const) { $nodeCallback($const, $scope); $constResult = $this->processExprNode($stmt, $const->value, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $impurePoints = array_merge($impurePoints, $constResult->getImpurePoints()); if ($scope->getClassReflection() === null) { throw new ShouldNotHappenException(); } $scope = $scope->assignExpression(new Expr\ClassConstFetch(new Name\FullyQualified($scope->getClassReflection()->getName()), $const->name), $scope->getType($const->value), $scope->getNativeType($const->value)); } } elseif ($stmt instanceof Node\Stmt\EnumCase) { $hasYield = \false; $throwPoints = []; $this->processAttributeGroups($stmt, $stmt->attrGroups, $scope, $nodeCallback); $impurePoints = []; if ($stmt->expr !== null) { $exprResult = $this->processExprNode($stmt, $stmt->expr, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $impurePoints = $exprResult->getImpurePoints(); } } elseif ($stmt instanceof InlineHTML) { $hasYield = \false; $throwPoints = []; $impurePoints = [new \PHPStan\Analyser\ImpurePoint($scope, $stmt, 'betweenPhpTags', 'output between PHP opening and closing tags', \true)]; } elseif ($stmt instanceof Node\Stmt\Nop) { $hasYield = \false; $throwPoints = $overridingThrowPoints ?? []; $impurePoints = []; } elseif ($stmt instanceof Node\Stmt\GroupUse) { $hasYield = \false; $throwPoints = []; foreach ($stmt->uses as $use) { $nodeCallback($use, $scope); } $impurePoints = []; } else { $hasYield = \false; $throwPoints = $overridingThrowPoints ?? []; $impurePoints = []; } return new \PHPStan\Analyser\StatementResult($scope, $hasYield, \false, [], $throwPoints, $impurePoints); } /** * @return ThrowPoint[]|null */ private function getOverridingThrowPoints(Node\Stmt $statement, \PHPStan\Analyser\MutatingScope $scope) : ?array { foreach ($statement->getComments() as $comment) { if (!$comment instanceof Doc) { continue; } $function = $scope->getFunction(); $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $scope->isInClass() ? $scope->getClassReflection()->getName() : null, $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $function !== null ? $function->getName() : null, $comment->getText()); $throwsTag = $resolvedPhpDoc->getThrowsTag(); if ($throwsTag !== null) { $throwsType = $throwsTag->getType(); if ($throwsType->isVoid()->yes()) { return []; } return [\PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwsType, $statement, \false)]; } } return null; } private function getCurrentClassReflection(Node\Stmt\ClassLike $stmt, string $className, \PHPStan\Analyser\Scope $scope) : ClassReflection { if (!$this->reflectionProvider->hasClass($className)) { return $this->createAstClassReflection($stmt, $className, $scope); } $defaultClassReflection = $this->reflectionProvider->getClass($className); if ($defaultClassReflection->getFileName() !== $scope->getFile()) { return $this->createAstClassReflection($stmt, $className, $scope); } $startLine = $defaultClassReflection->getNativeReflection()->getStartLine(); if ($startLine !== $stmt->getStartLine()) { return $this->createAstClassReflection($stmt, $className, $scope); } return $defaultClassReflection; } private function createAstClassReflection(Node\Stmt\ClassLike $stmt, string $className, \PHPStan\Analyser\Scope $scope) : ClassReflection { $nodeToReflection = new NodeToReflection(); $betterReflectionClass = $nodeToReflection->__invoke($this->reflector, $stmt, new LocatedSource(FileReader::read($scope->getFile()), $className, $scope->getFile()), $scope->getNamespace() !== null ? new Node\Stmt\Namespace_(new Name($scope->getNamespace())) : null); if (!$betterReflectionClass instanceof \PHPStan\BetterReflection\Reflection\ReflectionClass) { throw new ShouldNotHappenException(); } $enumAdapter = base64_decode('UEhQU3RhblxCZXR0ZXJSZWZsZWN0aW9uXFJlZmxlY3Rpb25cQWRhcHRlclxSZWZsZWN0aW9uRW51bQ==', \true); return new ClassReflection($this->reflectionProvider, $this->initializerExprTypeResolver, $this->fileTypeMapper, $this->stubPhpDocProvider, $this->phpDocInheritanceResolver, $this->phpVersion, $this->signatureMapProvider, $this->classReflectionExtensionRegistryProvider->getRegistry()->getPropertiesClassReflectionExtensions(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getMethodsClassReflectionExtensions(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getAllowedSubTypesClassReflectionExtensions(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getRequireExtendsPropertyClassReflectionExtension(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getRequireExtendsMethodsClassReflectionExtension(), $betterReflectionClass->getName(), $betterReflectionClass instanceof ReflectionEnum && PHP_VERSION_ID >= 80000 ? new $enumAdapter($betterReflectionClass) : new ReflectionClass($betterReflectionClass), null, null, null, $this->universalObjectCratesClasses, sprintf('%s:%d', $scope->getFile(), $stmt->getStartLine())); } private function lookForSetAllowedUndefinedExpressions(\PHPStan\Analyser\MutatingScope $scope, Expr $expr) : \PHPStan\Analyser\MutatingScope { return $this->lookForExpressionCallback($scope, $expr, static function (\PHPStan\Analyser\MutatingScope $scope, Expr $expr) : \PHPStan\Analyser\MutatingScope { return $scope->setAllowedUndefinedExpression($expr); }); } private function lookForUnsetAllowedUndefinedExpressions(\PHPStan\Analyser\MutatingScope $scope, Expr $expr) : \PHPStan\Analyser\MutatingScope { return $this->lookForExpressionCallback($scope, $expr, static function (\PHPStan\Analyser\MutatingScope $scope, Expr $expr) : \PHPStan\Analyser\MutatingScope { return $scope->unsetAllowedUndefinedExpression($expr); }); } /** * @param Closure(MutatingScope $scope, Expr $expr): MutatingScope $callback */ private function lookForExpressionCallback(\PHPStan\Analyser\MutatingScope $scope, Expr $expr, Closure $callback) : \PHPStan\Analyser\MutatingScope { if (!$expr instanceof ArrayDimFetch || $expr->dim !== null) { $scope = $callback($scope, $expr); } if ($expr instanceof ArrayDimFetch) { $scope = $this->lookForExpressionCallback($scope, $expr->var, $callback); } elseif ($expr instanceof PropertyFetch || $expr instanceof Expr\NullsafePropertyFetch) { $scope = $this->lookForExpressionCallback($scope, $expr->var, $callback); } elseif ($expr instanceof StaticPropertyFetch && $expr->class instanceof Expr) { $scope = $this->lookForExpressionCallback($scope, $expr->class, $callback); } elseif ($expr instanceof Array_ || $expr instanceof List_) { foreach ($expr->items as $item) { if ($item === null) { continue; } $scope = $this->lookForExpressionCallback($scope, $item->value, $callback); } } return $scope; } private function ensureShallowNonNullability(\PHPStan\Analyser\MutatingScope $scope, \PHPStan\Analyser\Scope $originalScope, Expr $exprToSpecify) : \PHPStan\Analyser\EnsuredNonNullabilityResult { $exprType = $scope->getType($exprToSpecify); $isNull = $exprType->isNull(); if ($isNull->yes()) { return new \PHPStan\Analyser\EnsuredNonNullabilityResult($scope, []); } // keep certainty $certainty = TrinaryLogic::createYes(); $hasExpressionType = $originalScope->hasExpressionType($exprToSpecify); if (!$hasExpressionType->no()) { $certainty = $hasExpressionType; } $exprTypeWithoutNull = TypeCombinator::removeNull($exprType); if ($exprType->equals($exprTypeWithoutNull)) { $originalExprType = $originalScope->getType($exprToSpecify); if (!$originalExprType->equals($exprTypeWithoutNull)) { $originalNativeType = $originalScope->getNativeType($exprToSpecify); return new \PHPStan\Analyser\EnsuredNonNullabilityResult($scope, [new \PHPStan\Analyser\EnsuredNonNullabilityResultExpression($exprToSpecify, $originalExprType, $originalNativeType, $certainty)]); } return new \PHPStan\Analyser\EnsuredNonNullabilityResult($scope, []); } $nativeType = $scope->getNativeType($exprToSpecify); $scope = $scope->specifyExpressionType($exprToSpecify, $exprTypeWithoutNull, TypeCombinator::removeNull($nativeType)); return new \PHPStan\Analyser\EnsuredNonNullabilityResult($scope, [new \PHPStan\Analyser\EnsuredNonNullabilityResultExpression($exprToSpecify, $exprType, $nativeType, $certainty)]); } private function ensureNonNullability(\PHPStan\Analyser\MutatingScope $scope, Expr $expr) : \PHPStan\Analyser\EnsuredNonNullabilityResult { $specifiedExpressions = []; $originalScope = $scope; $scope = $this->lookForExpressionCallback($scope, $expr, function ($scope, $expr) use(&$specifiedExpressions, $originalScope) { $result = $this->ensureShallowNonNullability($scope, $originalScope, $expr); foreach ($result->getSpecifiedExpressions() as $specifiedExpression) { $specifiedExpressions[] = $specifiedExpression; } return $result->getScope(); }); return new \PHPStan\Analyser\EnsuredNonNullabilityResult($scope, $specifiedExpressions); } /** * @param EnsuredNonNullabilityResultExpression[] $specifiedExpressions */ private function revertNonNullability(\PHPStan\Analyser\MutatingScope $scope, array $specifiedExpressions) : \PHPStan\Analyser\MutatingScope { foreach ($specifiedExpressions as $specifiedExpressionResult) { $scope = $scope->specifyExpressionType($specifiedExpressionResult->getExpression(), $specifiedExpressionResult->getOriginalType(), $specifiedExpressionResult->getOriginalNativeType(), $specifiedExpressionResult->getCertainty()); } return $scope; } private function findEarlyTerminatingExpr(Expr $expr, \PHPStan\Analyser\Scope $scope) : ?Expr { if (($expr instanceof MethodCall || $expr instanceof Expr\StaticCall) && $expr->name instanceof Node\Identifier) { if (array_key_exists($expr->name->toLowerString(), $this->earlyTerminatingMethodNames)) { if ($expr instanceof MethodCall) { $methodCalledOnType = $scope->getType($expr->var); } else { if ($expr->class instanceof Name) { $methodCalledOnType = $scope->resolveTypeByName($expr->class); } else { $methodCalledOnType = $scope->getType($expr->class); } } foreach ($methodCalledOnType->getObjectClassNames() as $referencedClass) { if (!$this->reflectionProvider->hasClass($referencedClass)) { continue; } $classReflection = $this->reflectionProvider->getClass($referencedClass); foreach (array_merge([$referencedClass], $classReflection->getParentClassesNames(), $classReflection->getNativeReflection()->getInterfaceNames()) as $className) { if (!isset($this->earlyTerminatingMethodCalls[$className])) { continue; } if (in_array((string) $expr->name, $this->earlyTerminatingMethodCalls[$className], \true)) { return $expr; } } } } } if ($expr instanceof FuncCall && $expr->name instanceof Name) { if (in_array((string) $expr->name, $this->earlyTerminatingFunctionCalls, \true)) { return $expr; } } if ($expr instanceof Expr\Exit_ || $expr instanceof Expr\Throw_) { return $expr; } $exprType = $scope->getType($expr); if ($exprType instanceof NeverType && $exprType->isExplicit()) { return $expr; } return null; } /** * @param callable(Node $node, Scope $scope): void $nodeCallback */ public function processExprNode(Node\Stmt $stmt, Expr $expr, \PHPStan\Analyser\MutatingScope $scope, callable $nodeCallback, \PHPStan\Analyser\ExpressionContext $context) : \PHPStan\Analyser\ExpressionResult { if ($expr instanceof Expr\CallLike && $expr->isFirstClassCallable()) { if ($expr instanceof FuncCall) { $newExpr = new FunctionCallableNode($expr->name, $expr); } elseif ($expr instanceof MethodCall) { $newExpr = new MethodCallableNode($expr->var, $expr->name, $expr); } elseif ($expr instanceof StaticCall) { $newExpr = new StaticMethodCallableNode($expr->class, $expr->name, $expr); } elseif ($expr instanceof New_ && !$expr->class instanceof Class_) { $newExpr = new InstantiationCallableNode($expr->class, $expr); } else { throw new ShouldNotHappenException(); } return $this->processExprNode($stmt, $newExpr, $scope, $nodeCallback, $context); } $this->callNodeCallbackWithExpression($nodeCallback, $expr, $scope, $context); if ($expr instanceof Variable) { $hasYield = \false; $throwPoints = []; $impurePoints = []; if ($expr->name instanceof Expr) { return $this->processExprNode($stmt, $expr->name, $scope, $nodeCallback, $context->enterDeep()); } elseif (in_array($expr->name, \PHPStan\Analyser\Scope::SUPERGLOBAL_VARIABLES, \true)) { $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'superglobal', 'access to superglobal variable', \true); } } elseif ($expr instanceof Assign || $expr instanceof AssignRef) { $result = $this->processAssignVar($scope, $stmt, $expr->var, $expr->expr, $nodeCallback, $context, function (\PHPStan\Analyser\MutatingScope $scope) use($stmt, $expr, $nodeCallback, $context) : \PHPStan\Analyser\ExpressionResult { $impurePoints = []; if ($expr instanceof AssignRef) { $referencedExpr = $expr->expr; while ($referencedExpr instanceof ArrayDimFetch) { $referencedExpr = $referencedExpr->var; } if ($referencedExpr instanceof PropertyFetch || $referencedExpr instanceof StaticPropertyFetch) { $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'propertyAssignByRef', 'property assignment by reference', \false); } $scope = $scope->enterExpressionAssign($expr->expr); } if ($expr->var instanceof Variable && is_string($expr->var->name)) { $context = $context->enterRightSideAssign($expr->var->name, $scope->getType($expr->expr), $scope->getNativeType($expr->expr)); } $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); $scope = $result->getScope(); if ($expr instanceof AssignRef) { $scope = $scope->exitExpressionAssign($expr->expr); } return new \PHPStan\Analyser\ExpressionResult($scope, $hasYield, $throwPoints, $impurePoints); }, \true); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $vars = $this->getAssignedVariables($expr->var); if (count($vars) > 0) { $varChangedScope = \false; $scope = $this->processVarAnnotation($scope, $vars, $stmt, $varChangedScope); if (!$varChangedScope) { $scope = $this->processStmtVarAnnotation($scope, $stmt, null, $nodeCallback); } } } elseif ($expr instanceof Expr\AssignOp) { $result = $this->processAssignVar($scope, $stmt, $expr->var, $expr, $nodeCallback, $context, function (\PHPStan\Analyser\MutatingScope $scope) use($stmt, $expr, $nodeCallback, $context) : \PHPStan\Analyser\ExpressionResult { $originalScope = $scope; if ($expr instanceof Expr\AssignOp\Coalesce) { $scope = $scope->filterByFalseyValue(new BinaryOp\NotIdentical($expr->var, new ConstFetch(new Name('null')))); } $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context->enterDeep()); if ($expr instanceof Expr\AssignOp\Coalesce) { return new \PHPStan\Analyser\ExpressionResult($result->getScope()->mergeWith($originalScope), $result->hasYield(), $result->getThrowPoints(), $result->getImpurePoints()); } return $result; }, $expr instanceof Expr\AssignOp\Coalesce); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); if (($expr instanceof Expr\AssignOp\Div || $expr instanceof Expr\AssignOp\Mod) && !$scope->getType($expr->expr)->toNumber()->isSuperTypeOf(new ConstantIntegerType(0))->no()) { $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createExplicit($scope, new ObjectType(DivisionByZeroError::class), $expr, \false); } } elseif ($expr instanceof FuncCall) { $parametersAcceptor = null; $functionReflection = null; $throwPoints = []; $impurePoints = []; if ($expr->name instanceof Expr) { $nameType = $scope->getType($expr->name); if (!$nameType->isCallable()->no()) { $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $nameType->getCallableParametersAcceptors($scope), null); } $nameResult = $this->processExprNode($stmt, $expr->name, $scope, $nodeCallback, $context->enterDeep()); $scope = $nameResult->getScope(); $throwPoints = $nameResult->getThrowPoints(); $impurePoints = $nameResult->getImpurePoints(); if ($nameType->isObject()->yes() && $nameType->isCallable()->yes() && (new ObjectType(Closure::class))->isSuperTypeOf($nameType)->no()) { $invokeResult = $this->processExprNode($stmt, new MethodCall($expr->name, '__invoke', $expr->getArgs(), $expr->getAttributes()), $scope, static function () : void { }, $context->enterDeep()); $throwPoints = array_merge($throwPoints, $invokeResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $invokeResult->getImpurePoints()); } elseif ($parametersAcceptor instanceof CallableParametersAcceptor) { $callableThrowPoints = array_map(static function (SimpleThrowPoint $throwPoint) use($scope, $expr) { return $throwPoint->isExplicit() ? \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwPoint->getType(), $expr, $throwPoint->canContainAnyThrowable()) : \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $expr); }, $parametersAcceptor->getThrowPoints()); if (!$this->implicitThrows) { $callableThrowPoints = array_values(array_filter($callableThrowPoints, static function (\PHPStan\Analyser\ThrowPoint $throwPoint) { return $throwPoint->isExplicit(); })); } $throwPoints = array_merge($throwPoints, $callableThrowPoints); $impurePoints = array_merge($impurePoints, array_map(static function (SimpleImpurePoint $impurePoint) use($scope, $expr) { return new \PHPStan\Analyser\ImpurePoint($scope, $expr, $impurePoint->getIdentifier(), $impurePoint->getDescription(), $impurePoint->isCertain()); }, $parametersAcceptor->getImpurePoints())); $scope = $this->processImmediatelyCalledCallable($scope, $parametersAcceptor->getInvalidateExpressions(), $parametersAcceptor->getUsedVariables()); } } elseif ($this->reflectionProvider->hasFunction($expr->name, $scope)) { $functionReflection = $this->reflectionProvider->getFunction($expr->name, $scope); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants()); $impurePoint = SimpleImpurePoint::createFromVariant($functionReflection, $parametersAcceptor); if ($impurePoint !== null) { $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, $impurePoint->getIdentifier(), $impurePoint->getDescription(), $impurePoint->isCertain()); } } else { $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'functionCall', 'call to unknown function', \false); } if ($parametersAcceptor !== null) { $expr = \PHPStan\Analyser\ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $expr) ?? $expr; } $result = $this->processArgs($stmt, $functionReflection, null, $parametersAcceptor, $expr, $scope, $nodeCallback, $context); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); if ($functionReflection !== null) { $functionThrowPoint = $this->getFunctionThrowPoint($functionReflection, $parametersAcceptor, $expr, $scope); if ($functionThrowPoint !== null) { $throwPoints[] = $functionThrowPoint; } } else { $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $expr); } if ($functionReflection !== null && in_array($functionReflection->getName(), ['json_encode', 'json_decode'], \true)) { $scope = $scope->invalidateExpression(new FuncCall(new Name('json_last_error'), []))->invalidateExpression(new FuncCall(new Name\FullyQualified('json_last_error'), []))->invalidateExpression(new FuncCall(new Name('json_last_error_msg'), []))->invalidateExpression(new FuncCall(new Name\FullyQualified('json_last_error_msg'), [])); } if ($functionReflection !== null && $functionReflection->getName() === 'file_put_contents' && count($expr->getArgs()) > 0) { $scope = $scope->invalidateExpression(new FuncCall(new Name('file_get_contents'), [$expr->getArgs()[0]]))->invalidateExpression(new FuncCall(new Name\FullyQualified('file_get_contents'), [$expr->getArgs()[0]])); } if ($functionReflection !== null && in_array($functionReflection->getName(), ['array_pop', 'array_shift'], \true) && count($expr->getArgs()) >= 1) { $arrayArg = $expr->getArgs()[0]->value; $arrayArgType = $scope->getType($arrayArg); $arrayArgNativeType = $scope->getNativeType($arrayArg); $isArrayPop = $functionReflection->getName() === 'array_pop'; $scope = $scope->invalidateExpression($arrayArg)->assignExpression($arrayArg, $isArrayPop ? $arrayArgType->popArray() : $arrayArgType->shiftArray(), $isArrayPop ? $arrayArgNativeType->popArray() : $arrayArgNativeType->shiftArray()); } if ($functionReflection !== null && in_array($functionReflection->getName(), ['array_push', 'array_unshift'], \true) && count($expr->getArgs()) >= 2) { $arrayType = $this->getArrayFunctionAppendingType($functionReflection, $scope, $expr); $arrayNativeType = $this->getArrayFunctionAppendingType($functionReflection, $scope->doNotTreatPhpDocTypesAsCertain(), $expr); $arrayArg = $expr->getArgs()[0]->value; $scope = $scope->invalidateExpression($arrayArg)->assignExpression($arrayArg, $arrayType, $arrayNativeType); } if ($functionReflection !== null && in_array($functionReflection->getName(), ['fopen', 'file_get_contents'], \true)) { $scope = $scope->assignVariable('http_response_header', AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new StringType())), new ArrayType(new IntegerType(), new StringType())); } if ($functionReflection !== null && $functionReflection->getName() === 'shuffle') { $arrayArg = $expr->getArgs()[0]->value; $scope = $scope->assignExpression($arrayArg, $scope->getType($arrayArg)->shuffleArray(), $scope->getNativeType($arrayArg)->shuffleArray()); } if ($functionReflection !== null && $functionReflection->getName() === 'array_splice' && count($expr->getArgs()) >= 1) { $arrayArg = $expr->getArgs()[0]->value; $arrayArgType = $scope->getType($arrayArg); $valueType = $arrayArgType->getIterableValueType(); if (count($expr->getArgs()) >= 4) { $replacementType = $scope->getType($expr->getArgs()[3]->value)->toArray(); $valueType = TypeCombinator::union($valueType, $replacementType->getIterableValueType()); } $scope = $scope->invalidateExpression($arrayArg)->assignExpression($arrayArg, new ArrayType($arrayArgType->getIterableKeyType(), $valueType), new ArrayType($arrayArgType->getIterableKeyType(), $valueType)); } if ($functionReflection !== null && in_array($functionReflection->getName(), ['sort', 'rsort', 'usort'], \true) && count($expr->getArgs()) >= 1) { $arrayArg = $expr->getArgs()[0]->value; $scope = $scope->assignExpression($arrayArg, $this->getArraySortPreserveListFunctionType($scope->getType($arrayArg)), $this->getArraySortPreserveListFunctionType($scope->getNativeType($arrayArg))); } if ($functionReflection !== null && in_array($functionReflection->getName(), ['natcasesort', 'natsort', 'arsort', 'asort', 'ksort', 'krsort', 'uasort', 'uksort'], \true) && count($expr->getArgs()) >= 1) { $arrayArg = $expr->getArgs()[0]->value; $scope = $scope->assignExpression($arrayArg, $this->getArraySortDoNotPreserveListFunctionType($scope->getType($arrayArg)), $this->getArraySortDoNotPreserveListFunctionType($scope->getNativeType($arrayArg))); } if ($functionReflection !== null && $functionReflection->getName() === 'extract') { $extractedArg = $expr->getArgs()[0]->value; $extractedType = $scope->getType($extractedArg); $constantArrays = $extractedType->getConstantArrays(); if (count($constantArrays) > 0) { $properties = []; $optionalProperties = []; $refCount = []; foreach ($constantArrays as $constantArray) { foreach ($constantArray->getKeyTypes() as $i => $keyType) { if ($keyType->isString()->no()) { // integers as variable names not allowed continue; } $key = (string) $keyType->getValue(); $valueType = $constantArray->getValueTypes()[$i]; $optional = $constantArray->isOptionalKey($i); if ($optional) { $optionalProperties[] = $key; } if (isset($properties[$key])) { $properties[$key] = TypeCombinator::union($properties[$key], $valueType); $refCount[$key]++; } else { $properties[$key] = $valueType; $refCount[$key] = 1; } } } foreach ($properties as $name => $type) { $optional = in_array($name, $optionalProperties, \true) || $refCount[$name] < count($constantArrays); $scope = $scope->assignVariable($name, $type, $type, $optional ? TrinaryLogic::createMaybe() : TrinaryLogic::createYes()); } } else { $scope = $scope->afterExtractCall(); } } if ($functionReflection !== null && in_array($functionReflection->getName(), ['clearstatcache', 'unlink'], \true)) { $scope = $scope->afterClearstatcacheCall(); } if ($functionReflection !== null && str_starts_with($functionReflection->getName(), 'openssl')) { $scope = $scope->afterOpenSslCall($functionReflection->getName()); } } elseif ($expr instanceof MethodCall) { $originalScope = $scope; if (($expr->var instanceof Expr\Closure || $expr->var instanceof Expr\ArrowFunction) && $expr->name instanceof Node\Identifier && strtolower($expr->name->name) === 'call' && isset($expr->getArgs()[0])) { $closureCallScope = $scope->enterClosureCall($scope->getType($expr->getArgs()[0]->value), $scope->getNativeType($expr->getArgs()[0]->value)); } $result = $this->processExprNode($stmt, $expr->var, $closureCallScope ?? $scope, $nodeCallback, $context->enterDeep()); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $scope = $result->getScope(); if (isset($closureCallScope)) { $scope = $scope->restoreOriginalScopeAfterClosureBind($originalScope); } $parametersAcceptor = null; $methodReflection = null; $calledOnType = $scope->getType($expr->var); if ($expr->name instanceof Expr) { $methodNameResult = $this->processExprNode($stmt, $expr->name, $scope, $nodeCallback, $context->enterDeep()); $throwPoints = array_merge($throwPoints, $methodNameResult->getThrowPoints()); $scope = $methodNameResult->getScope(); } else { $methodName = $expr->name->name; $methodReflection = $scope->getMethodReflection($calledOnType, $methodName); if ($methodReflection !== null) { $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $methodReflection->getVariants(), $methodReflection->getNamedArgumentsVariants()); $methodThrowPoint = $this->getMethodThrowPoint($methodReflection, $parametersAcceptor, $expr, $scope); if ($methodThrowPoint !== null) { $throwPoints[] = $methodThrowPoint; } } } if ($methodReflection !== null) { $impurePoint = SimpleImpurePoint::createFromVariant($methodReflection, $parametersAcceptor); if ($impurePoint !== null) { $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, $impurePoint->getIdentifier(), $impurePoint->getDescription(), $impurePoint->isCertain()); } } else { $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'methodCall', 'call to unknown method', \false); } if ($parametersAcceptor !== null) { $expr = \PHPStan\Analyser\ArgumentsNormalizer::reorderMethodArguments($parametersAcceptor, $expr) ?? $expr; } $result = $this->processArgs($stmt, $methodReflection, $methodReflection !== null ? $scope->getNakedMethod($calledOnType, $methodReflection->getName()) : null, $parametersAcceptor, $expr, $scope, $nodeCallback, $context); $scope = $result->getScope(); if ($methodReflection !== null) { $hasSideEffects = $methodReflection->hasSideEffects(); if ($hasSideEffects->yes() || $methodReflection->getName() === '__construct') { $nodeCallback(new InvalidateExprNode($expr->var), $scope); $scope = $scope->invalidateExpression($expr->var, \true); } if ($parametersAcceptor !== null && !$methodReflection->isStatic()) { $selfOutType = $methodReflection->getSelfOutType(); if ($selfOutType !== null) { $scope = $scope->assignExpression($expr->var, TemplateTypeHelper::resolveTemplateTypes($selfOutType, $parametersAcceptor->getResolvedTemplateTypeMap(), $parametersAcceptor instanceof ParametersAcceptorWithPhpDocs ? $parametersAcceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(), TemplateTypeVariance::createCovariant()), $scope->getNativeType($expr->var)); } } if ($scope->isInClass() && $scope->getClassReflection()->getName() === $methodReflection->getDeclaringClass()->getName() && TypeUtils::findThisType($calledOnType) !== null) { $calledMethodScope = $this->processCalledMethod($methodReflection); if ($calledMethodScope !== null) { $scope = $scope->mergeInitializedProperties($calledMethodScope); } } } else { $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $expr); } $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); } elseif ($expr instanceof Expr\NullsafeMethodCall) { $nonNullabilityResult = $this->ensureShallowNonNullability($scope, $scope, $expr->var); $exprResult = $this->processExprNode($stmt, new MethodCall($expr->var, $expr->name, $expr->args, array_merge($expr->getAttributes(), ['virtualNullsafeMethodCall' => \true])), $nonNullabilityResult->getScope(), $nodeCallback, $context); $scope = $this->revertNonNullability($exprResult->getScope(), $nonNullabilityResult->getSpecifiedExpressions()); return new \PHPStan\Analyser\ExpressionResult($scope, $exprResult->hasYield(), $exprResult->getThrowPoints(), $exprResult->getImpurePoints(), static function () use($scope, $expr) : \PHPStan\Analyser\MutatingScope { return $scope->filterByTruthyValue($expr); }, static function () use($scope, $expr) : \PHPStan\Analyser\MutatingScope { return $scope->filterByFalseyValue($expr); }); } elseif ($expr instanceof StaticCall) { $hasYield = \false; $throwPoints = []; $impurePoints = []; if ($expr->class instanceof Expr) { $objectClasses = $scope->getType($expr->class)->getObjectClassNames(); if (count($objectClasses) !== 1) { $objectClasses = $scope->getType(new New_($expr->class))->getObjectClassNames(); } if (count($objectClasses) === 1) { $objectExprResult = $this->processExprNode($stmt, new StaticCall(new Name($objectClasses[0]), $expr->name, []), $scope, static function () : void { }, $context->enterDeep()); $additionalThrowPoints = $objectExprResult->getThrowPoints(); } else { $additionalThrowPoints = [\PHPStan\Analyser\ThrowPoint::createImplicit($scope, $expr)]; } $classResult = $this->processExprNode($stmt, $expr->class, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $classResult->hasYield(); $throwPoints = array_merge($throwPoints, $classResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $classResult->getImpurePoints()); foreach ($additionalThrowPoints as $throwPoint) { $throwPoints[] = $throwPoint; } $scope = $classResult->getScope(); } $parametersAcceptor = null; $methodReflection = null; if ($expr->name instanceof Expr) { $result = $this->processExprNode($stmt, $expr->name, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); $scope = $result->getScope(); } elseif ($expr->class instanceof Name) { $classType = $scope->resolveTypeByName($expr->class); $methodName = $expr->name->name; if ($classType->hasMethod($methodName)->yes()) { $methodReflection = $classType->getMethod($methodName, $scope); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $methodReflection->getVariants(), $methodReflection->getNamedArgumentsVariants()); $methodThrowPoint = $this->getStaticMethodThrowPoint($methodReflection, $parametersAcceptor, $expr, $scope); if ($methodThrowPoint !== null) { $throwPoints[] = $methodThrowPoint; } $declaringClass = $methodReflection->getDeclaringClass(); if ($declaringClass->getName() === 'Closure' && strtolower($methodName) === 'bind') { $thisType = null; $nativeThisType = null; if (isset($expr->getArgs()[1])) { $argType = $scope->getType($expr->getArgs()[1]->value); if ($argType->isNull()->yes()) { $thisType = null; } else { $thisType = $argType; } $nativeArgType = $scope->getNativeType($expr->getArgs()[1]->value); if ($nativeArgType->isNull()->yes()) { $nativeThisType = null; } else { $nativeThisType = $nativeArgType; } } $scopeClasses = ['static']; if (isset($expr->getArgs()[2])) { $argValue = $expr->getArgs()[2]->value; $argValueType = $scope->getType($argValue); $directClassNames = $argValueType->getObjectClassNames(); if (count($directClassNames) > 0) { $scopeClasses = $directClassNames; $thisTypes = []; foreach ($directClassNames as $directClassName) { $thisTypes[] = new ObjectType($directClassName); } $thisType = TypeCombinator::union(...$thisTypes); } else { $thisType = $argValueType->getClassStringObjectType(); $scopeClasses = $thisType->getObjectClassNames(); } } $closureBindScope = $scope->enterClosureBind($thisType, $nativeThisType, $scopeClasses); } } else { $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $expr); } } if ($methodReflection !== null) { $impurePoint = SimpleImpurePoint::createFromVariant($methodReflection, $parametersAcceptor); if ($impurePoint !== null) { $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, $impurePoint->getIdentifier(), $impurePoint->getDescription(), $impurePoint->isCertain()); } } else { $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'methodCall', 'call to unknown method', \false); } if ($parametersAcceptor !== null) { $expr = \PHPStan\Analyser\ArgumentsNormalizer::reorderStaticCallArguments($parametersAcceptor, $expr) ?? $expr; } $result = $this->processArgs($stmt, $methodReflection, null, $parametersAcceptor, $expr, $scope, $nodeCallback, $context, $closureBindScope ?? null); $scope = $result->getScope(); $scopeFunction = $scope->getFunction(); if ($methodReflection !== null && !$methodReflection->isStatic() && ($methodReflection->hasSideEffects()->yes() || $methodReflection->getName() === '__construct') && $scopeFunction instanceof MethodReflection && !$scopeFunction->isStatic() && $scope->isInClass() && ($scope->getClassReflection()->getName() === $methodReflection->getDeclaringClass()->getName() || $scope->getClassReflection()->isSubclassOf($methodReflection->getDeclaringClass()->getName()))) { $scope = $scope->invalidateExpression(new Variable('this'), \true); } if ($methodReflection !== null && !$methodReflection->isStatic() && $methodReflection->getName() === '__construct' && $scopeFunction instanceof MethodReflection && !$scopeFunction->isStatic() && $scope->isInClass() && $scope->getClassReflection()->isSubclassOf($methodReflection->getDeclaringClass()->getName())) { $thisType = $scope->getType(new Variable('this')); $methodClassReflection = $methodReflection->getDeclaringClass(); foreach ($methodClassReflection->getNativeReflection()->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED) as $property) { if (!$property->isPromoted() || $property->getDeclaringClass()->getName() !== $methodClassReflection->getName()) { continue; } $scope = $scope->assignInitializedProperty($thisType, $property->getName()); } } $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); } elseif ($expr instanceof PropertyFetch) { $result = $this->processExprNode($stmt, $expr->var, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $scope = $result->getScope(); if ($expr->name instanceof Expr) { $result = $this->processExprNode($stmt, $expr->name, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); $scope = $result->getScope(); } } elseif ($expr instanceof Expr\NullsafePropertyFetch) { $nonNullabilityResult = $this->ensureShallowNonNullability($scope, $scope, $expr->var); $exprResult = $this->processExprNode($stmt, new PropertyFetch($expr->var, $expr->name, array_merge($expr->getAttributes(), ['virtualNullsafePropertyFetch' => \true])), $nonNullabilityResult->getScope(), $nodeCallback, $context); $scope = $this->revertNonNullability($exprResult->getScope(), $nonNullabilityResult->getSpecifiedExpressions()); return new \PHPStan\Analyser\ExpressionResult($scope, $exprResult->hasYield(), $exprResult->getThrowPoints(), $exprResult->getImpurePoints(), static function () use($scope, $expr) : \PHPStan\Analyser\MutatingScope { return $scope->filterByTruthyValue($expr); }, static function () use($scope, $expr) : \PHPStan\Analyser\MutatingScope { return $scope->filterByFalseyValue($expr); }); } elseif ($expr instanceof StaticPropertyFetch) { $hasYield = \false; $throwPoints = []; $impurePoints = [new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'staticPropertyAccess', 'static property access', \true)]; if ($expr->class instanceof Expr) { $result = $this->processExprNode($stmt, $expr->class, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $scope = $result->getScope(); } if ($expr->name instanceof Expr) { $result = $this->processExprNode($stmt, $expr->name, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); $scope = $result->getScope(); } } elseif ($expr instanceof Expr\Closure) { $processClosureResult = $this->processClosureNode($stmt, $expr, $scope, $nodeCallback, $context, null); return new \PHPStan\Analyser\ExpressionResult($processClosureResult->getScope(), \false, [], []); } elseif ($expr instanceof Expr\ArrowFunction) { $result = $this->processArrowFunctionNode($stmt, $expr, $scope, $nodeCallback, null); return new \PHPStan\Analyser\ExpressionResult($result->getScope(), $result->hasYield(), [], []); } elseif ($expr instanceof ErrorSuppress) { $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $scope = $result->getScope(); } elseif ($expr instanceof Exit_) { $hasYield = \false; $throwPoints = []; $kind = $expr->getAttribute('kind', Exit_::KIND_EXIT); $identifier = $kind === Exit_::KIND_DIE ? 'die' : 'exit'; $impurePoints = [new \PHPStan\Analyser\ImpurePoint($scope, $expr, $identifier, $identifier, \true)]; if ($expr->expr !== null) { $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); $scope = $result->getScope(); } } elseif ($expr instanceof Node\Scalar\Encapsed) { $hasYield = \false; $throwPoints = []; $impurePoints = []; foreach ($expr->parts as $part) { $result = $this->processExprNode($stmt, $part, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); $scope = $result->getScope(); } } elseif ($expr instanceof ArrayDimFetch) { $hasYield = \false; $throwPoints = []; $impurePoints = []; if ($expr->dim !== null) { $result = $this->processExprNode($stmt, $expr->dim, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $scope = $result->getScope(); } $result = $this->processExprNode($stmt, $expr->var, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); $scope = $result->getScope(); } elseif ($expr instanceof Array_) { $itemNodes = []; $hasYield = \false; $throwPoints = []; $impurePoints = []; foreach ($expr->items as $arrayItem) { $itemNodes[] = new LiteralArrayItem($scope, $arrayItem); if ($arrayItem === null) { continue; } $nodeCallback($arrayItem, $scope); if ($arrayItem->key !== null) { $keyResult = $this->processExprNode($stmt, $arrayItem->key, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $hasYield || $keyResult->hasYield(); $throwPoints = array_merge($throwPoints, $keyResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $keyResult->getImpurePoints()); $scope = $keyResult->getScope(); } $valueResult = $this->processExprNode($stmt, $arrayItem->value, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $hasYield || $valueResult->hasYield(); $throwPoints = array_merge($throwPoints, $valueResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $valueResult->getImpurePoints()); $scope = $valueResult->getScope(); } $nodeCallback(new LiteralArrayNode($expr, $itemNodes), $scope); } elseif ($expr instanceof BooleanAnd || $expr instanceof BinaryOp\LogicalAnd) { $leftResult = $this->processExprNode($stmt, $expr->left, $scope, $nodeCallback, $context->enterDeep()); $rightResult = $this->processExprNode($stmt, $expr->right, $leftResult->getTruthyScope(), $nodeCallback, $context); $rightExprType = $rightResult->getScope()->getType($expr->right); if ($rightExprType instanceof NeverType && $rightExprType->isExplicit()) { $leftMergedWithRightScope = $leftResult->getFalseyScope(); } else { $leftMergedWithRightScope = $leftResult->getScope()->mergeWith($rightResult->getScope()); } $this->callNodeCallbackWithExpression($nodeCallback, new BooleanAndNode($expr, $leftResult->getTruthyScope()), $scope, $context); return new \PHPStan\Analyser\ExpressionResult($leftMergedWithRightScope, $leftResult->hasYield() || $rightResult->hasYield(), array_merge($leftResult->getThrowPoints(), $rightResult->getThrowPoints()), array_merge($leftResult->getImpurePoints(), $rightResult->getImpurePoints()), static function () use($rightResult, $expr) : \PHPStan\Analyser\MutatingScope { return $rightResult->getScope()->filterByTruthyValue($expr); }, static function () use($leftMergedWithRightScope, $expr) : \PHPStan\Analyser\MutatingScope { return $leftMergedWithRightScope->filterByFalseyValue($expr); }); } elseif ($expr instanceof BooleanOr || $expr instanceof BinaryOp\LogicalOr) { $leftResult = $this->processExprNode($stmt, $expr->left, $scope, $nodeCallback, $context->enterDeep()); $rightResult = $this->processExprNode($stmt, $expr->right, $leftResult->getFalseyScope(), $nodeCallback, $context); $rightExprType = $rightResult->getScope()->getType($expr->right); if ($rightExprType instanceof NeverType && $rightExprType->isExplicit()) { $leftMergedWithRightScope = $leftResult->getTruthyScope(); } else { $leftMergedWithRightScope = $leftResult->getScope()->mergeWith($rightResult->getScope()); } $this->callNodeCallbackWithExpression($nodeCallback, new BooleanOrNode($expr, $leftResult->getFalseyScope()), $scope, $context); return new \PHPStan\Analyser\ExpressionResult($leftMergedWithRightScope, $leftResult->hasYield() || $rightResult->hasYield(), array_merge($leftResult->getThrowPoints(), $rightResult->getThrowPoints()), array_merge($leftResult->getImpurePoints(), $rightResult->getImpurePoints()), static function () use($leftMergedWithRightScope, $expr) : \PHPStan\Analyser\MutatingScope { return $leftMergedWithRightScope->filterByTruthyValue($expr); }, static function () use($rightResult, $expr) : \PHPStan\Analyser\MutatingScope { return $rightResult->getScope()->filterByFalseyValue($expr); }); } elseif ($expr instanceof Coalesce) { $nonNullabilityResult = $this->ensureNonNullability($scope, $expr->left); $condScope = $this->lookForSetAllowedUndefinedExpressions($nonNullabilityResult->getScope(), $expr->left); $condResult = $this->processExprNode($stmt, $expr->left, $condScope, $nodeCallback, $context->enterDeep()); $scope = $this->revertNonNullability($condResult->getScope(), $nonNullabilityResult->getSpecifiedExpressions()); $scope = $this->lookForUnsetAllowedUndefinedExpressions($scope, $expr->left); $rightScope = $scope->filterByFalseyValue($expr); $rightResult = $this->processExprNode($stmt, $expr->right, $rightScope, $nodeCallback, $context->enterDeep()); $rightExprType = $scope->getType($expr->right); if ($rightExprType instanceof NeverType && $rightExprType->isExplicit()) { $scope = $scope->filterByTruthyValue(new Expr\Isset_([$expr->left])); } else { $scope = $scope->filterByTruthyValue(new Expr\Isset_([$expr->left]))->mergeWith($rightResult->getScope()); } $hasYield = $condResult->hasYield() || $rightResult->hasYield(); $throwPoints = array_merge($condResult->getThrowPoints(), $rightResult->getThrowPoints()); $impurePoints = array_merge($condResult->getImpurePoints(), $rightResult->getImpurePoints()); } elseif ($expr instanceof BinaryOp) { $result = $this->processExprNode($stmt, $expr->left, $scope, $nodeCallback, $context->enterDeep()); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $result = $this->processExprNode($stmt, $expr->right, $scope, $nodeCallback, $context->enterDeep()); if (($expr instanceof BinaryOp\Div || $expr instanceof BinaryOp\Mod) && !$scope->getType($expr->right)->toNumber()->isSuperTypeOf(new ConstantIntegerType(0))->no()) { $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createExplicit($scope, new ObjectType(DivisionByZeroError::class), $expr, \false); } $scope = $result->getScope(); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); } elseif ($expr instanceof Expr\Include_) { $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context->enterDeep()); $throwPoints = $result->getThrowPoints(); $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $expr); $impurePoints = $result->getImpurePoints(); $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, in_array($expr->type, [Expr\Include_::TYPE_INCLUDE, Expr\Include_::TYPE_INCLUDE_ONCE], \true) ? 'include' : 'require', in_array($expr->type, [Expr\Include_::TYPE_INCLUDE, Expr\Include_::TYPE_INCLUDE_ONCE], \true) ? 'include' : 'require', \true); $hasYield = $result->hasYield(); $scope = $result->getScope()->afterExtractCall(); } elseif ($expr instanceof Expr\Print_) { $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context->enterDeep()); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'print', 'print', \true); $hasYield = $result->hasYield(); $scope = $result->getScope(); } elseif ($expr instanceof Cast\String_) { $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context->enterDeep()); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $hasYield = $result->hasYield(); $exprType = $scope->getType($expr->expr); $toStringMethod = $scope->getMethodReflection($exprType, '__toString'); if ($toStringMethod !== null) { if (!$toStringMethod->hasSideEffects()->no()) { $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'methodCall', sprintf('call to method %s::%s()', $toStringMethod->getDeclaringClass()->getDisplayName(), $toStringMethod->getName()), $toStringMethod->isPure()->no()); } } $scope = $result->getScope(); } elseif ($expr instanceof Expr\BitwiseNot || $expr instanceof Cast || $expr instanceof Expr\Clone_ || $expr instanceof Expr\UnaryMinus || $expr instanceof Expr\UnaryPlus) { $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context->enterDeep()); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $hasYield = $result->hasYield(); $scope = $result->getScope(); } elseif ($expr instanceof Expr\Eval_) { $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context->enterDeep()); $throwPoints = $result->getThrowPoints(); $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $expr); $impurePoints = $result->getImpurePoints(); $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'eval', 'eval', \true); $hasYield = $result->hasYield(); $scope = $result->getScope(); } elseif ($expr instanceof Expr\YieldFrom) { $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context->enterDeep()); $throwPoints = $result->getThrowPoints(); $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $expr); $impurePoints = $result->getImpurePoints(); $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'yieldFrom', 'yield from', \true); $hasYield = \true; $scope = $result->getScope(); } elseif ($expr instanceof BooleanNot) { $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context->enterDeep()); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); } elseif ($expr instanceof Expr\ClassConstFetch) { if ($expr->class instanceof Expr) { $result = $this->processExprNode($stmt, $expr->class, $scope, $nodeCallback, $context->enterDeep()); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); } else { $hasYield = \false; $throwPoints = []; $impurePoints = []; $nodeCallback($expr->class, $scope); } if ($expr->name instanceof Expr) { $result = $this->processExprNode($stmt, $expr->name, $scope, $nodeCallback, $context->enterDeep()); $scope = $result->getScope(); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); } else { $nodeCallback($expr->name, $scope); } } elseif ($expr instanceof Expr\Empty_) { $nonNullabilityResult = $this->ensureNonNullability($scope, $expr->expr); $scope = $this->lookForSetAllowedUndefinedExpressions($nonNullabilityResult->getScope(), $expr->expr); $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context->enterDeep()); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $scope = $this->revertNonNullability($scope, $nonNullabilityResult->getSpecifiedExpressions()); $scope = $this->lookForUnsetAllowedUndefinedExpressions($scope, $expr->expr); } elseif ($expr instanceof Expr\Isset_) { $hasYield = \false; $throwPoints = []; $impurePoints = []; $nonNullabilityResults = []; foreach ($expr->vars as $var) { $nonNullabilityResult = $this->ensureNonNullability($scope, $var); $scope = $this->lookForSetAllowedUndefinedExpressions($nonNullabilityResult->getScope(), $var); $result = $this->processExprNode($stmt, $var, $scope, $nodeCallback, $context->enterDeep()); $scope = $result->getScope(); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); $nonNullabilityResults[] = $nonNullabilityResult; } foreach (array_reverse($expr->vars) as $var) { $scope = $this->lookForUnsetAllowedUndefinedExpressions($scope, $var); } foreach (array_reverse($nonNullabilityResults) as $nonNullabilityResult) { $scope = $this->revertNonNullability($scope, $nonNullabilityResult->getSpecifiedExpressions()); } } elseif ($expr instanceof Instanceof_) { $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, $context->enterDeep()); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); if ($expr->class instanceof Expr) { $result = $this->processExprNode($stmt, $expr->class, $scope, $nodeCallback, $context->enterDeep()); $scope = $result->getScope(); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); } } elseif ($expr instanceof List_) { // only in assign and foreach, processed elsewhere return new \PHPStan\Analyser\ExpressionResult($scope, \false, [], []); } elseif ($expr instanceof New_) { $parametersAcceptor = null; $constructorReflection = null; $hasYield = \false; $throwPoints = []; $impurePoints = []; $className = null; if ($expr->class instanceof Expr || $expr->class instanceof Name) { if ($expr->class instanceof Expr) { $objectClasses = $scope->getType($expr)->getObjectClassNames(); if (count($objectClasses) === 1) { $objectExprResult = $this->processExprNode($stmt, new New_(new Name($objectClasses[0])), $scope, static function () : void { }, $context->enterDeep()); $className = $objectClasses[0]; $additionalThrowPoints = $objectExprResult->getThrowPoints(); } else { $additionalThrowPoints = [\PHPStan\Analyser\ThrowPoint::createImplicit($scope, $expr)]; } $result = $this->processExprNode($stmt, $expr->class, $scope, $nodeCallback, $context->enterDeep()); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); foreach ($additionalThrowPoints as $throwPoint) { $throwPoints[] = $throwPoint; } } else { $className = $scope->resolveName($expr->class); } $classReflection = null; if ($className !== null && $this->reflectionProvider->hasClass($className)) { $classReflection = $this->reflectionProvider->getClass($className); if ($classReflection->hasConstructor()) { $constructorReflection = $classReflection->getConstructor(); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $constructorReflection->getVariants(), $constructorReflection->getNamedArgumentsVariants()); $constructorThrowPoint = $this->getConstructorThrowPoint($constructorReflection, $parametersAcceptor, $classReflection, $expr, new Name\FullyQualified($className), $expr->getArgs(), $scope); if ($constructorThrowPoint !== null) { $throwPoints[] = $constructorThrowPoint; } } } else { $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $expr); } if ($constructorReflection !== null) { if (!$constructorReflection->hasSideEffects()->no()) { $certain = $constructorReflection->isPure()->no(); $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'new', sprintf('instantiation of class %s', $constructorReflection->getDeclaringClass()->getDisplayName()), $certain); } } elseif ($classReflection === null) { $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'new', 'instantiation of unknown class', \false); } if ($parametersAcceptor !== null) { $expr = \PHPStan\Analyser\ArgumentsNormalizer::reorderNewArguments($parametersAcceptor, $expr) ?? $expr; } } else { $classReflection = $this->reflectionProvider->getAnonymousClassReflection($expr->class, $scope); // populates $expr->class->name $constructorResult = null; $this->processStmtNode($expr->class, $scope, static function (Node $node, \PHPStan\Analyser\Scope $scope) use($nodeCallback, $classReflection, &$constructorResult) : void { $nodeCallback($node, $scope); if (!$node instanceof MethodReturnStatementsNode) { return; } if ($constructorResult !== null) { return; } $currentClassReflection = $node->getClassReflection(); if ($currentClassReflection->getName() !== $classReflection->getName()) { return; } if (!$currentClassReflection->hasConstructor()) { return; } if ($currentClassReflection->getConstructor()->getName() !== $node->getMethodReflection()->getName()) { return; } $constructorResult = $node; }, \PHPStan\Analyser\StatementContext::createTopLevel()); if ($constructorResult !== null) { $throwPoints = array_merge($throwPoints, $constructorResult->getStatementResult()->getThrowPoints()); $impurePoints = array_merge($impurePoints, $constructorResult->getImpurePoints()); } if ($classReflection->hasConstructor()) { $constructorReflection = $classReflection->getConstructor(); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $constructorReflection->getVariants(), $constructorReflection->getNamedArgumentsVariants()); } } $result = $this->processArgs($stmt, $constructorReflection, null, $parametersAcceptor, $expr, $scope, $nodeCallback, $context); $scope = $result->getScope(); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); } elseif ($expr instanceof Expr\PreInc || $expr instanceof Expr\PostInc || $expr instanceof Expr\PreDec || $expr instanceof Expr\PostDec) { $result = $this->processExprNode($stmt, $expr->var, $scope, $nodeCallback, $context->enterDeep()); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $newExpr = $expr; if ($expr instanceof Expr\PostInc) { $newExpr = new Expr\PreInc($expr->var); } elseif ($expr instanceof Expr\PostDec) { $newExpr = new Expr\PreDec($expr->var); } $scope = $this->processAssignVar($scope, $stmt, $expr->var, $newExpr, static function (Node $node, \PHPStan\Analyser\Scope $scope) use($nodeCallback) : void { if (!$node instanceof PropertyAssignNode && !$node instanceof VariableAssignNode) { return; } $nodeCallback($node, $scope); }, $context, static function (\PHPStan\Analyser\MutatingScope $scope) : \PHPStan\Analyser\ExpressionResult { return new \PHPStan\Analyser\ExpressionResult($scope, \false, [], []); }, \false)->getScope(); } elseif ($expr instanceof Ternary) { $ternaryCondResult = $this->processExprNode($stmt, $expr->cond, $scope, $nodeCallback, $context->enterDeep()); $throwPoints = $ternaryCondResult->getThrowPoints(); $impurePoints = $ternaryCondResult->getImpurePoints(); $ifTrueScope = $ternaryCondResult->getTruthyScope(); $ifFalseScope = $ternaryCondResult->getFalseyScope(); $ifTrueType = null; if ($expr->if !== null) { $ifResult = $this->processExprNode($stmt, $expr->if, $ifTrueScope, $nodeCallback, $context); $throwPoints = array_merge($throwPoints, $ifResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $ifResult->getImpurePoints()); $ifTrueScope = $ifResult->getScope(); $ifTrueType = $ifTrueScope->getType($expr->if); } $elseResult = $this->processExprNode($stmt, $expr->else, $ifFalseScope, $nodeCallback, $context); $throwPoints = array_merge($throwPoints, $elseResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $elseResult->getImpurePoints()); $ifFalseScope = $elseResult->getScope(); $condType = $scope->getType($expr->cond); if ($condType->isTrue()->yes()) { $finalScope = $ifTrueScope; } elseif ($condType->isFalse()->yes()) { $finalScope = $ifFalseScope; } else { if ($ifTrueType instanceof NeverType && $ifTrueType->isExplicit()) { $finalScope = $ifFalseScope; } else { $ifFalseType = $ifFalseScope->getType($expr->else); if ($ifFalseType instanceof NeverType && $ifFalseType->isExplicit()) { $finalScope = $ifTrueScope; } else { $finalScope = $ifTrueScope->mergeWith($ifFalseScope); } } } return new \PHPStan\Analyser\ExpressionResult($finalScope, $ternaryCondResult->hasYield(), $throwPoints, $impurePoints, static function () use($finalScope, $expr) : \PHPStan\Analyser\MutatingScope { return $finalScope->filterByTruthyValue($expr); }, static function () use($finalScope, $expr) : \PHPStan\Analyser\MutatingScope { return $finalScope->filterByFalseyValue($expr); }); } elseif ($expr instanceof Expr\Yield_) { $throwPoints = [\PHPStan\Analyser\ThrowPoint::createImplicit($scope, $expr)]; $impurePoints = [new \PHPStan\Analyser\ImpurePoint($scope, $expr, 'yield', 'yield', \true)]; if ($expr->key !== null) { $keyResult = $this->processExprNode($stmt, $expr->key, $scope, $nodeCallback, $context->enterDeep()); $scope = $keyResult->getScope(); $throwPoints = $keyResult->getThrowPoints(); $impurePoints = array_merge($impurePoints, $keyResult->getImpurePoints()); } if ($expr->value !== null) { $valueResult = $this->processExprNode($stmt, $expr->value, $scope, $nodeCallback, $context->enterDeep()); $scope = $valueResult->getScope(); $throwPoints = array_merge($throwPoints, $valueResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $valueResult->getImpurePoints()); } $hasYield = \true; } elseif ($expr instanceof Expr\Match_) { $deepContext = $context->enterDeep(); $condType = $scope->getType($expr->cond); $condResult = $this->processExprNode($stmt, $expr->cond, $scope, $nodeCallback, $deepContext); $scope = $condResult->getScope(); $hasYield = $condResult->hasYield(); $throwPoints = $condResult->getThrowPoints(); $impurePoints = $condResult->getImpurePoints(); $matchScope = $scope->enterMatch($expr); $armNodes = []; $hasDefaultCond = \false; $hasAlwaysTrueCond = \false; $arms = $expr->arms; if ($condType->isEnum()->yes()) { // enum match analysis would work even without this if branch // but would be much slower // this avoids using ObjectType::$subtractedType which is slow for huge enums // because of repeated union type normalization $enumCases = $condType->getEnumCases(); if (count($enumCases) > 0) { $indexedEnumCases = []; foreach ($enumCases as $enumCase) { $indexedEnumCases[strtolower($enumCase->getClassName())][$enumCase->getEnumCaseName()] = $enumCase; } $unusedIndexedEnumCases = $indexedEnumCases; foreach ($arms as $i => $arm) { if ($arm->conds === null) { continue; } $condNodes = []; $conditionCases = []; foreach ($arm->conds as $cond) { if (!$cond instanceof Expr\ClassConstFetch) { continue 2; } if (!$cond->class instanceof Name) { continue 2; } if (!$cond->name instanceof Node\Identifier) { continue 2; } $fetchedClassName = $scope->resolveName($cond->class); $loweredFetchedClassName = strtolower($fetchedClassName); if (!array_key_exists($loweredFetchedClassName, $indexedEnumCases)) { continue 2; } if (!array_key_exists($loweredFetchedClassName, $unusedIndexedEnumCases)) { throw new ShouldNotHappenException(); } $caseName = $cond->name->toString(); if (!array_key_exists($caseName, $indexedEnumCases[$loweredFetchedClassName])) { continue 2; } $enumCase = $indexedEnumCases[$loweredFetchedClassName][$caseName]; $conditionCases[] = $enumCase; $armConditionScope = $matchScope; if (!array_key_exists($caseName, $unusedIndexedEnumCases[$loweredFetchedClassName])) { // force "always false" $armConditionScope = $armConditionScope->removeTypeFromExpression($expr->cond, $enumCase); } else { $unusedCasesCount = 0; foreach ($unusedIndexedEnumCases as $cases) { $unusedCasesCount += count($cases); } if ($unusedCasesCount === 1) { $hasAlwaysTrueCond = \true; // force "always true" $armConditionScope = $armConditionScope->addTypeToExpression($expr->cond, $enumCase); } } $this->processExprNode($stmt, $cond, $armConditionScope, $nodeCallback, $deepContext); $condNodes[] = new MatchExpressionArmCondition($cond, $armConditionScope, $cond->getStartLine()); unset($unusedIndexedEnumCases[$loweredFetchedClassName][$caseName]); } $conditionCasesCount = count($conditionCases); if ($conditionCasesCount === 0) { throw new ShouldNotHappenException(); } elseif ($conditionCasesCount === 1) { $conditionCaseType = $conditionCases[0]; } else { $conditionCaseType = new UnionType($conditionCases); } $matchArmBodyScope = $matchScope->addTypeToExpression($expr->cond, $conditionCaseType); $matchArmBody = new MatchExpressionArmBody($matchArmBodyScope, $arm->body); $armNodes[$i] = new MatchExpressionArm($matchArmBody, $condNodes, $arm->getStartLine()); $armResult = $this->processExprNode($stmt, $arm->body, $matchArmBodyScope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createTopLevel()); $armScope = $armResult->getScope(); $scope = $scope->mergeWith($armScope); $hasYield = $hasYield || $armResult->hasYield(); $throwPoints = array_merge($throwPoints, $armResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $armResult->getImpurePoints()); unset($arms[$i]); } $remainingCases = []; foreach ($unusedIndexedEnumCases as $cases) { foreach ($cases as $case) { $remainingCases[] = $case; } } $remainingCasesCount = count($remainingCases); if ($remainingCasesCount === 0) { $remainingType = new NeverType(); } elseif ($remainingCasesCount === 1) { $remainingType = $remainingCases[0]; } else { $remainingType = new UnionType($remainingCases); } $matchScope = $matchScope->addTypeToExpression($expr->cond, $remainingType); } } foreach ($arms as $i => $arm) { if ($arm->conds === null) { $hasDefaultCond = \true; $matchArmBody = new MatchExpressionArmBody($matchScope, $arm->body); $armNodes[$i] = new MatchExpressionArm($matchArmBody, [], $arm->getStartLine()); $armResult = $this->processExprNode($stmt, $arm->body, $matchScope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createTopLevel()); $matchScope = $armResult->getScope(); $hasYield = $hasYield || $armResult->hasYield(); $throwPoints = array_merge($throwPoints, $armResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $armResult->getImpurePoints()); $scope = $scope->mergeWith($matchScope); continue; } if (count($arm->conds) === 0) { throw new ShouldNotHappenException(); } $filteringExprs = []; $armCondScope = $matchScope; $condNodes = []; foreach ($arm->conds as $armCond) { $condNodes[] = new MatchExpressionArmCondition($armCond, $armCondScope, $armCond->getStartLine()); $armCondResult = $this->processExprNode($stmt, $armCond, $armCondScope, $nodeCallback, $deepContext); $hasYield = $hasYield || $armCondResult->hasYield(); $throwPoints = array_merge($throwPoints, $armCondResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $armCondResult->getImpurePoints()); $armCondExpr = new BinaryOp\Identical($expr->cond, $armCond); $armCondResultScope = $armCondResult->getScope(); $armCondType = $this->treatPhpDocTypesAsCertain ? $armCondResultScope->getType($armCondExpr) : $armCondResultScope->getNativeType($armCondExpr); if ($armCondType->isTrue()->yes()) { $hasAlwaysTrueCond = \true; } $armCondScope = $armCondResult->getScope()->filterByFalseyValue($armCondExpr); $filteringExprs[] = $armCond; } if (count($filteringExprs) === 1) { $filteringExpr = new BinaryOp\Identical($expr->cond, $filteringExprs[0]); } else { $items = []; foreach ($filteringExprs as $filteringExpr) { $items[] = new ArrayItem($filteringExpr); } $filteringExpr = new FuncCall(new Name\FullyQualified('in_array'), [new Arg($expr->cond), new Arg(new Array_($items)), new Arg(new ConstFetch(new Name\FullyQualified('true')))]); } $bodyScope = $this->processExprNode($stmt, $filteringExpr, $matchScope, static function () : void { }, $deepContext)->getTruthyScope(); $matchArmBody = new MatchExpressionArmBody($bodyScope, $arm->body); $armNodes[$i] = new MatchExpressionArm($matchArmBody, $condNodes, $arm->getStartLine()); $armResult = $this->processExprNode($stmt, $arm->body, $bodyScope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createTopLevel()); $armScope = $armResult->getScope(); $scope = $scope->mergeWith($armScope); $hasYield = $hasYield || $armResult->hasYield(); $throwPoints = array_merge($throwPoints, $armResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $armResult->getImpurePoints()); $matchScope = $matchScope->filterByFalseyValue($filteringExpr); } $remainingType = $matchScope->getType($expr->cond); if (!$hasDefaultCond && !$hasAlwaysTrueCond && !$remainingType instanceof NeverType) { $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createExplicit($scope, new ObjectType(UnhandledMatchError::class), $expr, \false); } ksort($armNodes, SORT_NUMERIC); $nodeCallback(new MatchExpressionNode($expr->cond, array_values($armNodes), $expr, $matchScope), $scope); } elseif ($expr instanceof AlwaysRememberedExpr) { $result = $this->processExprNode($stmt, $expr->getExpr(), $scope, $nodeCallback, $context); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $scope = $result->getScope(); } elseif ($expr instanceof Expr\Throw_) { $hasYield = \false; $result = $this->processExprNode($stmt, $expr->expr, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $scope->getType($expr->expr), $expr, \false); } elseif ($expr instanceof FunctionCallableNode) { $throwPoints = []; $impurePoints = []; $hasYield = \false; if ($expr->getName() instanceof Expr) { $result = $this->processExprNode($stmt, $expr->getName(), $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); } } elseif ($expr instanceof MethodCallableNode) { $result = $this->processExprNode($stmt, $expr->getVar(), $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $scope = $result->getScope(); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); if ($expr->getName() instanceof Expr) { $nameResult = $this->processExprNode($stmt, $expr->getVar(), $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $scope = $nameResult->getScope(); $hasYield = $hasYield || $nameResult->hasYield(); $throwPoints = array_merge($throwPoints, $nameResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $nameResult->getImpurePoints()); } } elseif ($expr instanceof StaticMethodCallableNode) { $throwPoints = []; $impurePoints = []; $hasYield = \false; if ($expr->getClass() instanceof Expr) { $classResult = $this->processExprNode($stmt, $expr->getClass(), $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $scope = $classResult->getScope(); $hasYield = $classResult->hasYield(); $throwPoints = $classResult->getThrowPoints(); $impurePoints = $classResult->getImpurePoints(); } if ($expr->getName() instanceof Expr) { $nameResult = $this->processExprNode($stmt, $expr->getName(), $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $scope = $nameResult->getScope(); $hasYield = $hasYield || $nameResult->hasYield(); $throwPoints = array_merge($throwPoints, $nameResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $nameResult->getImpurePoints()); } } elseif ($expr instanceof InstantiationCallableNode) { $throwPoints = []; $impurePoints = []; $hasYield = \false; if ($expr->getClass() instanceof Expr) { $classResult = $this->processExprNode($stmt, $expr->getClass(), $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $scope = $classResult->getScope(); $hasYield = $classResult->hasYield(); $throwPoints = $classResult->getThrowPoints(); $impurePoints = $classResult->getImpurePoints(); } } elseif ($expr instanceof Node\Scalar) { $hasYield = \false; $throwPoints = []; $impurePoints = []; } elseif ($expr instanceof ConstFetch) { $hasYield = \false; $throwPoints = []; $impurePoints = []; $nodeCallback($expr->name, $scope); } else { $hasYield = \false; $throwPoints = []; $impurePoints = []; } return new \PHPStan\Analyser\ExpressionResult($scope, $hasYield, $throwPoints, $impurePoints, static function () use($scope, $expr) : \PHPStan\Analyser\MutatingScope { return $scope->filterByTruthyValue($expr); }, static function () use($scope, $expr) : \PHPStan\Analyser\MutatingScope { return $scope->filterByFalseyValue($expr); }); } private function getArrayFunctionAppendingType(FunctionReflection $functionReflection, \PHPStan\Analyser\Scope $scope, FuncCall $expr) : Type { $arrayArg = $expr->getArgs()[0]->value; $arrayType = $scope->getType($arrayArg); $callArgs = array_slice($expr->getArgs(), 1); /** * @param Arg[] $callArgs * @param callable(?Type, Type, bool): void $setOffsetValueType */ $setOffsetValueTypes = static function (\PHPStan\Analyser\Scope $scope, array $callArgs, callable $setOffsetValueType, ?bool &$nonConstantArrayWasUnpacked = null) : void { foreach ($callArgs as $callArg) { $callArgType = $scope->getType($callArg->value); if ($callArg->unpack) { $constantArrays = $callArgType->getConstantArrays(); if (count($constantArrays) === 1) { $iterableValueTypes = $constantArrays[0]->getValueTypes(); } else { $iterableValueTypes = [$callArgType->getIterableValueType()]; $nonConstantArrayWasUnpacked = \true; } $isOptional = !$callArgType->isIterableAtLeastOnce()->yes(); foreach ($iterableValueTypes as $iterableValueType) { if ($iterableValueType instanceof UnionType) { foreach ($iterableValueType->getTypes() as $innerType) { $setOffsetValueType(null, $innerType, $isOptional); } } else { $setOffsetValueType(null, $iterableValueType, $isOptional); } } continue; } $setOffsetValueType(null, $callArgType, \false); } }; $constantArrays = $arrayType->getConstantArrays(); if (count($constantArrays) > 0) { $newArrayTypes = []; $prepend = $functionReflection->getName() === 'array_unshift'; foreach ($constantArrays as $constantArray) { $arrayTypeBuilder = $prepend ? ConstantArrayTypeBuilder::createEmpty() : ConstantArrayTypeBuilder::createFromConstantArray($constantArray); $setOffsetValueTypes($scope, $callArgs, static function (?Type $offsetType, Type $valueType, bool $optional) use(&$arrayTypeBuilder) : void { $arrayTypeBuilder->setOffsetValueType($offsetType, $valueType, $optional); }, $nonConstantArrayWasUnpacked); if ($prepend) { $keyTypes = $constantArray->getKeyTypes(); $valueTypes = $constantArray->getValueTypes(); foreach ($keyTypes as $k => $keyType) { $arrayTypeBuilder->setOffsetValueType(count($keyType->getConstantStrings()) === 1 ? $keyType->getConstantStrings()[0] : null, $valueTypes[$k], $constantArray->isOptionalKey($k)); } } $constantArray = $arrayTypeBuilder->getArray(); if ($constantArray->isConstantArray()->yes() && $nonConstantArrayWasUnpacked) { $array = new ArrayType($constantArray->generalize(GeneralizePrecision::lessSpecific())->getIterableKeyType(), $constantArray->getIterableValueType()); $isList = $constantArray->isList()->yes(); $constantArray = $constantArray->isIterableAtLeastOnce()->yes() ? TypeCombinator::intersect($array, new NonEmptyArrayType()) : $array; $constantArray = $isList ? AccessoryArrayListType::intersectWith($constantArray) : $constantArray; } $newArrayTypes[] = $constantArray; } return TypeCombinator::union(...$newArrayTypes); } $setOffsetValueTypes($scope, $callArgs, static function (?Type $offsetType, Type $valueType, bool $optional) use(&$arrayType) : void { $isIterableAtLeastOnce = $arrayType->isIterableAtLeastOnce()->yes() || !$optional; $arrayType = $arrayType->setOffsetValueType($offsetType, $valueType); if ($isIterableAtLeastOnce) { return; } $arrayType = TypeCombinator::union($arrayType, new ConstantArrayType([], [])); }); return $arrayType; } private function getArraySortPreserveListFunctionType(Type $type) : Type { $isIterableAtLeastOnce = $type->isIterableAtLeastOnce(); if ($isIterableAtLeastOnce->no()) { return $type; } return TypeTraverser::map($type, static function (Type $type, callable $traverse) use($isIterableAtLeastOnce) : Type { if ($type instanceof UnionType || $type instanceof IntersectionType) { return $traverse($type); } if (!$type instanceof ArrayType) { return $type; } $newArrayType = AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $type->getIterableValueType())); if ($isIterableAtLeastOnce->yes()) { $newArrayType = TypeCombinator::intersect($newArrayType, new NonEmptyArrayType()); } return $newArrayType; }); } private function getArraySortDoNotPreserveListFunctionType(Type $type) : Type { $isIterableAtLeastOnce = $type->isIterableAtLeastOnce(); if ($isIterableAtLeastOnce->no()) { return $type; } return TypeTraverser::map($type, static function (Type $type, callable $traverse) use($isIterableAtLeastOnce) : Type { if ($type instanceof UnionType) { return $traverse($type); } $constantArrays = $type->getConstantArrays(); if (count($constantArrays) > 0) { $types = []; foreach ($constantArrays as $constantArray) { $types[] = new ConstantArrayType($constantArray->getKeyTypes(), $constantArray->getValueTypes(), $constantArray->getNextAutoIndexes(), $constantArray->getOptionalKeys(), $constantArray->isList()->and(TrinaryLogic::createMaybe())); } return TypeCombinator::union(...$types); } $newArrayType = new ArrayType($type->getIterableKeyType(), $type->getIterableValueType()); if ($isIterableAtLeastOnce->yes()) { $newArrayType = TypeCombinator::intersect($newArrayType, new NonEmptyArrayType()); } return $newArrayType; }); } private function getFunctionThrowPoint(FunctionReflection $functionReflection, ?ParametersAcceptor $parametersAcceptor, FuncCall $funcCall, \PHPStan\Analyser\MutatingScope $scope) : ?\PHPStan\Analyser\ThrowPoint { $normalizedFuncCall = $funcCall; if ($parametersAcceptor !== null) { $normalizedFuncCall = \PHPStan\Analyser\ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $funcCall); } if ($normalizedFuncCall !== null) { foreach ($this->dynamicThrowTypeExtensionProvider->getDynamicFunctionThrowTypeExtensions() as $extension) { if (!$extension->isFunctionSupported($functionReflection)) { continue; } $throwType = $extension->getThrowTypeFromFunctionCall($functionReflection, $normalizedFuncCall, $scope); if ($throwType === null) { return null; } return \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwType, $funcCall, \false); } } $throwType = $functionReflection->getThrowType(); if ($throwType === null && $parametersAcceptor !== null) { $returnType = $parametersAcceptor->getReturnType(); if ($returnType instanceof NeverType && $returnType->isExplicit()) { $throwType = new ObjectType(Throwable::class); } } if ($throwType !== null) { if (!$throwType->isVoid()->yes()) { return \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwType, $funcCall, \true); } } elseif ($this->implicitThrows) { $requiredParameters = null; if ($parametersAcceptor !== null) { $requiredParameters = 0; foreach ($parametersAcceptor->getParameters() as $parameter) { if ($parameter->isOptional()) { continue; } $requiredParameters++; } } if (!$functionReflection->isBuiltin() || $requiredParameters === null || $requiredParameters > 0 || count($funcCall->getArgs()) > 0) { $functionReturnedType = $scope->getType($funcCall); if (!(new ObjectType(Throwable::class))->isSuperTypeOf($functionReturnedType)->yes()) { return \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $funcCall); } } } return null; } private function getMethodThrowPoint(MethodReflection $methodReflection, ParametersAcceptor $parametersAcceptor, MethodCall $methodCall, \PHPStan\Analyser\MutatingScope $scope) : ?\PHPStan\Analyser\ThrowPoint { $normalizedMethodCall = \PHPStan\Analyser\ArgumentsNormalizer::reorderMethodArguments($parametersAcceptor, $methodCall); if ($normalizedMethodCall !== null) { foreach ($this->dynamicThrowTypeExtensionProvider->getDynamicMethodThrowTypeExtensions() as $extension) { if (!$extension->isMethodSupported($methodReflection)) { continue; } $throwType = $extension->getThrowTypeFromMethodCall($methodReflection, $normalizedMethodCall, $scope); if ($throwType === null) { return null; } return \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwType, $methodCall, \false); } } $throwType = $methodReflection->getThrowType(); if ($throwType === null) { $returnType = $parametersAcceptor->getReturnType(); if ($returnType instanceof NeverType && $returnType->isExplicit()) { $throwType = new ObjectType(Throwable::class); } } if ($throwType !== null) { if (!$throwType->isVoid()->yes()) { return \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwType, $methodCall, \true); } } elseif ($this->implicitThrows) { $methodReturnedType = $scope->getType($methodCall); if (!(new ObjectType(Throwable::class))->isSuperTypeOf($methodReturnedType)->yes()) { return \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $methodCall); } } return null; } /** * @param Node\Arg[] $args */ private function getConstructorThrowPoint(MethodReflection $constructorReflection, ParametersAcceptor $parametersAcceptor, ClassReflection $classReflection, New_ $new, Name $className, array $args, \PHPStan\Analyser\MutatingScope $scope) : ?\PHPStan\Analyser\ThrowPoint { $methodCall = new StaticCall($className, $constructorReflection->getName(), $args); $normalizedMethodCall = \PHPStan\Analyser\ArgumentsNormalizer::reorderStaticCallArguments($parametersAcceptor, $methodCall); if ($normalizedMethodCall !== null) { foreach ($this->dynamicThrowTypeExtensionProvider->getDynamicStaticMethodThrowTypeExtensions() as $extension) { if (!$extension->isStaticMethodSupported($constructorReflection)) { continue; } $throwType = $extension->getThrowTypeFromStaticMethodCall($constructorReflection, $normalizedMethodCall, $scope); if ($throwType === null) { return null; } return \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwType, $new, \false); } } if ($constructorReflection->getThrowType() !== null) { $throwType = $constructorReflection->getThrowType(); if (!$throwType->isVoid()->yes()) { return \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwType, $new, \true); } } elseif ($this->implicitThrows) { if ($classReflection->getName() !== Throwable::class && !$classReflection->isSubclassOf(Throwable::class)) { return \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $methodCall); } } return null; } private function getStaticMethodThrowPoint(MethodReflection $methodReflection, ParametersAcceptor $parametersAcceptor, StaticCall $methodCall, \PHPStan\Analyser\MutatingScope $scope) : ?\PHPStan\Analyser\ThrowPoint { $normalizedMethodCall = \PHPStan\Analyser\ArgumentsNormalizer::reorderStaticCallArguments($parametersAcceptor, $methodCall); if ($normalizedMethodCall !== null) { foreach ($this->dynamicThrowTypeExtensionProvider->getDynamicStaticMethodThrowTypeExtensions() as $extension) { if (!$extension->isStaticMethodSupported($methodReflection)) { continue; } $throwType = $extension->getThrowTypeFromStaticMethodCall($methodReflection, $normalizedMethodCall, $scope); if ($throwType === null) { return null; } return \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwType, $methodCall, \false); } } if ($methodReflection->getThrowType() !== null) { $throwType = $methodReflection->getThrowType(); if (!$throwType->isVoid()->yes()) { return \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwType, $methodCall, \true); } } elseif ($this->implicitThrows) { $methodReturnedType = $scope->getType($methodCall); if (!(new ObjectType(Throwable::class))->isSuperTypeOf($methodReturnedType)->yes()) { return \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $methodCall); } } return null; } /** * @return string[] */ private function getAssignedVariables(Expr $expr) : array { if ($expr instanceof Expr\Variable) { if (is_string($expr->name)) { return [$expr->name]; } return []; } if ($expr instanceof Expr\List_ || $expr instanceof Expr\Array_) { $names = []; foreach ($expr->items as $item) { if ($item === null) { continue; } $names = array_merge($names, $this->getAssignedVariables($item->value)); } return $names; } if ($expr instanceof ArrayDimFetch) { return $this->getAssignedVariables($expr->var); } return []; } /** * @param callable(Node $node, Scope $scope): void $nodeCallback */ private function callNodeCallbackWithExpression(callable $nodeCallback, Expr $expr, \PHPStan\Analyser\MutatingScope $scope, \PHPStan\Analyser\ExpressionContext $context) : void { if ($context->isDeep()) { $scope = $scope->exitFirstLevelStatements(); } $nodeCallback($expr, $scope); } /** * @param callable(Node $node, Scope $scope): void $nodeCallback */ private function processClosureNode(Node\Stmt $stmt, Expr\Closure $expr, \PHPStan\Analyser\MutatingScope $scope, callable $nodeCallback, \PHPStan\Analyser\ExpressionContext $context, ?Type $passedToType) : \PHPStan\Analyser\ProcessClosureResult { foreach ($expr->params as $param) { $this->processParamNode($stmt, $param, $scope, $nodeCallback); } $byRefUses = []; $closureCallArgs = $expr->getAttribute(ClosureArgVisitor::ATTRIBUTE_NAME); $callableParameters = $this->createCallableParameters($scope, $expr, $closureCallArgs, $passedToType); $useScope = $scope; foreach ($expr->uses as $use) { if ($use->byRef) { $byRefUses[] = $use; $useScope = $useScope->enterExpressionAssign($use->var); $inAssignRightSideVariableName = $context->getInAssignRightSideVariableName(); $inAssignRightSideType = $context->getInAssignRightSideType(); $inAssignRightSideNativeType = $context->getInAssignRightSideNativeType(); if ($inAssignRightSideVariableName === $use->var->name && $inAssignRightSideType !== null && $inAssignRightSideNativeType !== null) { if ($inAssignRightSideType instanceof ClosureType) { $variableType = $inAssignRightSideType; } else { $alreadyHasVariableType = $scope->hasVariableType($inAssignRightSideVariableName); if ($alreadyHasVariableType->no()) { $variableType = TypeCombinator::union(new NullType(), $inAssignRightSideType); } else { $variableType = TypeCombinator::union($scope->getVariableType($inAssignRightSideVariableName), $inAssignRightSideType); } } if ($inAssignRightSideNativeType instanceof ClosureType) { $variableNativeType = $inAssignRightSideNativeType; } else { $alreadyHasVariableType = $scope->hasVariableType($inAssignRightSideVariableName); if ($alreadyHasVariableType->no()) { $variableNativeType = TypeCombinator::union(new NullType(), $inAssignRightSideNativeType); } else { $variableNativeType = TypeCombinator::union($scope->getVariableType($inAssignRightSideVariableName), $inAssignRightSideNativeType); } } $scope = $scope->assignVariable($inAssignRightSideVariableName, $variableType, $variableNativeType); } } $this->processExprNode($stmt, $use->var, $useScope, $nodeCallback, $context); if (!$use->byRef) { continue; } $useScope = $useScope->exitExpressionAssign($use->var); } if ($expr->returnType !== null) { $nodeCallback($expr->returnType, $scope); } $closureScope = $scope->enterAnonymousFunction($expr, $callableParameters); $closureScope = $closureScope->processClosureScope($scope, null, $byRefUses); $closureType = $closureScope->getAnonymousFunctionReflection(); if (!$closureType instanceof ClosureType) { throw new ShouldNotHappenException(); } $nodeCallback(new InClosureNode($closureType, $expr), $closureScope); $executionEnds = []; $gatheredReturnStatements = []; $gatheredYieldStatements = []; $closureImpurePoints = []; $invalidateExpressions = []; $closureStmtsCallback = static function (Node $node, \PHPStan\Analyser\Scope $scope) use($nodeCallback, &$executionEnds, &$gatheredReturnStatements, &$gatheredYieldStatements, &$closureScope, &$closureImpurePoints, &$invalidateExpressions) : void { $nodeCallback($node, $scope); if ($scope->getAnonymousFunctionReflection() !== $closureScope->getAnonymousFunctionReflection()) { return; } if ($node instanceof PropertyAssignNode) { $closureImpurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $node, 'propertyAssign', 'property assignment', \true); return; } if ($node instanceof ExecutionEndNode) { $executionEnds[] = $node; return; } if ($node instanceof InvalidateExprNode) { $invalidateExpressions[] = $node; return; } if ($node instanceof Expr\Yield_ || $node instanceof Expr\YieldFrom) { $gatheredYieldStatements[] = $node; } if (!$node instanceof Return_) { return; } $gatheredReturnStatements[] = new ReturnStatement($scope, $node); }; if (count($byRefUses) === 0) { $statementResult = $this->processStmtNodes($expr, $expr->stmts, $closureScope, $closureStmtsCallback, \PHPStan\Analyser\StatementContext::createTopLevel()); $nodeCallback(new ClosureReturnStatementsNode($expr, $gatheredReturnStatements, $gatheredYieldStatements, $statementResult, $executionEnds, array_merge($statementResult->getImpurePoints(), $closureImpurePoints)), $closureScope); return new \PHPStan\Analyser\ProcessClosureResult($scope, $statementResult->getThrowPoints(), $statementResult->getImpurePoints(), $invalidateExpressions); } $count = 0; $closureResultScope = null; do { $prevScope = $closureScope; $intermediaryClosureScopeResult = $this->processStmtNodes($expr, $expr->stmts, $closureScope, static function () : void { }, \PHPStan\Analyser\StatementContext::createTopLevel()); $intermediaryClosureScope = $intermediaryClosureScopeResult->getScope(); foreach ($intermediaryClosureScopeResult->getExitPoints() as $exitPoint) { $intermediaryClosureScope = $intermediaryClosureScope->mergeWith($exitPoint->getScope()); } if ($expr->getAttribute(ImmediatelyInvokedClosureVisitor::ATTRIBUTE_NAME) === \true) { $closureResultScope = $intermediaryClosureScope; break; } $closureScope = $scope->enterAnonymousFunction($expr, $callableParameters); $closureScope = $closureScope->processClosureScope($intermediaryClosureScope, $prevScope, $byRefUses); if ($closureScope->equals($prevScope)) { break; } if ($count >= self::GENERALIZE_AFTER_ITERATION) { $closureScope = $prevScope->generalizeWith($closureScope); } $count++; } while ($count < self::LOOP_SCOPE_ITERATIONS); if ($closureResultScope === null) { $closureResultScope = $closureScope; } $statementResult = $this->processStmtNodes($expr, $expr->stmts, $closureScope, $closureStmtsCallback, \PHPStan\Analyser\StatementContext::createTopLevel()); $nodeCallback(new ClosureReturnStatementsNode($expr, $gatheredReturnStatements, $gatheredYieldStatements, $statementResult, $executionEnds, array_merge($statementResult->getImpurePoints(), $closureImpurePoints)), $closureScope); return new \PHPStan\Analyser\ProcessClosureResult($scope->processClosureScope($closureResultScope, null, $byRefUses), $statementResult->getThrowPoints(), $statementResult->getImpurePoints(), $invalidateExpressions); } /** * @param InvalidateExprNode[] $invalidatedExpressions * @param string[] $uses */ private function processImmediatelyCalledCallable(\PHPStan\Analyser\MutatingScope $scope, array $invalidatedExpressions, array $uses) : \PHPStan\Analyser\MutatingScope { if ($scope->isInClass()) { $uses[] = 'this'; } $finder = new NodeFinder(); foreach ($invalidatedExpressions as $invalidateExpression) { $found = \false; foreach ($uses as $use) { $result = $finder->findFirst([$invalidateExpression->getExpr()], static function ($node) use($use) { return $node instanceof Variable && $node->name === $use; }); if ($result === null) { continue; } $found = \true; break; } if (!$found) { continue; } $scope = $scope->invalidateExpression($invalidateExpression->getExpr(), \true); } return $scope; } /** * @param callable(Node $node, Scope $scope): void $nodeCallback */ private function processArrowFunctionNode(Node\Stmt $stmt, Expr\ArrowFunction $expr, \PHPStan\Analyser\MutatingScope $scope, callable $nodeCallback, ?Type $passedToType) : \PHPStan\Analyser\ExpressionResult { foreach ($expr->params as $param) { $this->processParamNode($stmt, $param, $scope, $nodeCallback); } if ($expr->returnType !== null) { $nodeCallback($expr->returnType, $scope); } $arrowFunctionCallArgs = $expr->getAttribute(ArrowFunctionArgVisitor::ATTRIBUTE_NAME); $arrowFunctionScope = $scope->enterArrowFunction($expr, $this->createCallableParameters($scope, $expr, $arrowFunctionCallArgs, $passedToType)); $arrowFunctionType = $arrowFunctionScope->getAnonymousFunctionReflection(); if (!$arrowFunctionType instanceof ClosureType) { throw new ShouldNotHappenException(); } $nodeCallback(new InArrowFunctionNode($arrowFunctionType, $expr), $arrowFunctionScope); $exprResult = $this->processExprNode($stmt, $expr->expr, $arrowFunctionScope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createTopLevel()); return new \PHPStan\Analyser\ExpressionResult($scope, \false, $exprResult->getThrowPoints(), $exprResult->getImpurePoints()); } /** * @param Node\Arg[] $args * @return ParameterReflection[]|null */ public function createCallableParameters(\PHPStan\Analyser\Scope $scope, Expr $closureExpr, ?array $args, ?Type $passedToType) : ?array { $callableParameters = null; if ($args !== null) { $closureType = $scope->getType($closureExpr); if ($closureType->isCallable()->no()) { return null; } $acceptors = $closureType->getCallableParametersAcceptors($scope); if (count($acceptors) === 1) { $callableParameters = $acceptors[0]->getParameters(); foreach ($callableParameters as $index => $callableParameter) { if (!isset($args[$index])) { continue; } $type = $scope->getType($args[$index]->value); $callableParameters[$index] = new NativeParameterReflection($callableParameter->getName(), $callableParameter->isOptional(), $type, $callableParameter->passedByReference(), $callableParameter->isVariadic(), $callableParameter->getDefaultValue()); } } } elseif ($passedToType !== null && !$passedToType->isCallable()->no()) { if ($passedToType instanceof UnionType) { $passedToType = TypeCombinator::union(...array_filter($passedToType->getTypes(), static function (Type $type) { return $type->isCallable()->yes(); })); if ($passedToType->isCallable()->no()) { return null; } } $acceptors = $passedToType->getCallableParametersAcceptors($scope); if (count($acceptors) > 0) { foreach ($acceptors as $acceptor) { if ($callableParameters === null) { $callableParameters = array_map(static function (ParameterReflection $callableParameter) { return new NativeParameterReflection($callableParameter->getName(), $callableParameter->isOptional(), $callableParameter->getType(), $callableParameter->passedByReference(), $callableParameter->isVariadic(), $callableParameter->getDefaultValue()); }, $acceptor->getParameters()); continue; } $newParameters = []; foreach ($acceptor->getParameters() as $i => $callableParameter) { if (!array_key_exists($i, $callableParameters)) { $newParameters[] = $callableParameter; continue; } $newParameters[] = $callableParameters[$i]->union(new NativeParameterReflection($callableParameter->getName(), $callableParameter->isOptional(), $callableParameter->getType(), $callableParameter->passedByReference(), $callableParameter->isVariadic(), $callableParameter->getDefaultValue())); } $callableParameters = $newParameters; } } } return $callableParameters; } /** * @param callable(Node $node, Scope $scope): void $nodeCallback */ private function processParamNode(Node\Stmt $stmt, Node\Param $param, \PHPStan\Analyser\MutatingScope $scope, callable $nodeCallback) : void { $this->processAttributeGroups($stmt, $param->attrGroups, $scope, $nodeCallback); $nodeCallback($param, $scope); if ($param->type !== null) { $nodeCallback($param->type, $scope); } if ($param->default === null) { return; } $this->processExprNode($stmt, $param->default, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); } /** * @param AttributeGroup[] $attrGroups * @param callable(Node $node, Scope $scope): void $nodeCallback */ private function processAttributeGroups(Node\Stmt $stmt, array $attrGroups, \PHPStan\Analyser\MutatingScope $scope, callable $nodeCallback) : void { foreach ($attrGroups as $attrGroup) { foreach ($attrGroup->attrs as $attr) { foreach ($attr->args as $arg) { $this->processExprNode($stmt, $arg->value, $scope, $nodeCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $nodeCallback($arg, $scope); } $nodeCallback($attr, $scope); } $nodeCallback($attrGroup, $scope); } } /** * @param MethodReflection|FunctionReflection|null $calleeReflection * @param callable(Node $node, Scope $scope): void $nodeCallback */ private function processArgs(Node\Stmt $stmt, $calleeReflection, ?ExtendedMethodReflection $nakedMethodReflection, ?ParametersAcceptor $parametersAcceptor, CallLike $callLike, \PHPStan\Analyser\MutatingScope $scope, callable $nodeCallback, \PHPStan\Analyser\ExpressionContext $context, ?\PHPStan\Analyser\MutatingScope $closureBindScope = null) : \PHPStan\Analyser\ExpressionResult { $args = $callLike->getArgs(); if ($parametersAcceptor !== null) { $parameters = $parametersAcceptor->getParameters(); } $hasYield = \false; $throwPoints = []; $impurePoints = []; foreach ($args as $i => $arg) { $assignByReference = \false; $parameter = null; $parameterType = null; $parameterNativeType = null; if (isset($parameters) && $parametersAcceptor !== null) { if (isset($parameters[$i])) { $assignByReference = $parameters[$i]->passedByReference()->createsNewVariable(); $parameterType = $parameters[$i]->getType(); if ($parameters[$i] instanceof ParameterReflectionWithPhpDocs) { $parameterNativeType = $parameters[$i]->getNativeType(); } $parameter = $parameters[$i]; } elseif (count($parameters) > 0 && $parametersAcceptor->isVariadic()) { $lastParameter = $parameters[count($parameters) - 1]; $assignByReference = $lastParameter->passedByReference()->createsNewVariable(); $parameterType = $lastParameter->getType(); if ($lastParameter instanceof ParameterReflectionWithPhpDocs) { $parameterNativeType = $lastParameter->getNativeType(); } $parameter = $lastParameter; } } $lookForUnset = \false; if ($assignByReference) { $isBuiltin = \false; if ($calleeReflection instanceof FunctionReflection && $calleeReflection->isBuiltin()) { $isBuiltin = \true; } elseif ($calleeReflection instanceof ExtendedMethodReflection && $calleeReflection->getDeclaringClass()->isBuiltin()) { $isBuiltin = \true; } if ($isBuiltin || ($parameterNativeType === null || !$parameterNativeType->isNull()->no())) { $scope = $this->lookForSetAllowedUndefinedExpressions($scope, $arg->value); $lookForUnset = \true; } } if ($calleeReflection !== null) { $scope = $scope->pushInFunctionCall($calleeReflection, $parameter); } $originalArg = $arg->getAttribute(\PHPStan\Analyser\ArgumentsNormalizer::ORIGINAL_ARG_ATTRIBUTE) ?? $arg; $nodeCallback($originalArg, $scope); $originalScope = $scope; $scopeToPass = $scope; if ($i === 0 && $closureBindScope !== null) { $scopeToPass = $closureBindScope; } if ($parameter instanceof ParameterReflectionWithPhpDocs) { $parameterCallImmediately = $parameter->isImmediatelyInvokedCallable(); if ($parameterCallImmediately->maybe()) { $callCallbackImmediately = $calleeReflection instanceof FunctionReflection; } else { $callCallbackImmediately = $parameterCallImmediately->yes(); } } else { $callCallbackImmediately = $calleeReflection instanceof FunctionReflection; } if ($arg->value instanceof Expr\Closure) { $restoreThisScope = null; if ($closureBindScope === null && $parameter instanceof ParameterReflectionWithPhpDocs && $parameter->getClosureThisType() !== null && !$arg->value->static) { $restoreThisScope = $scopeToPass; $scopeToPass = $scopeToPass->assignVariable('this', $parameter->getClosureThisType(), new ObjectWithoutClassType()); } if ($parameter !== null) { $overwritingParameterType = $this->getParameterTypeFromParameterClosureTypeExtension($callLike, $calleeReflection, $parameter, $scopeToPass); if ($overwritingParameterType !== null) { $parameterType = $overwritingParameterType; } } $this->callNodeCallbackWithExpression($nodeCallback, $arg->value, $scopeToPass, $context); $closureResult = $this->processClosureNode($stmt, $arg->value, $scopeToPass, $nodeCallback, $context, $parameterType ?? null); if ($callCallbackImmediately) { $throwPoints = array_merge($throwPoints, array_map(static function (\PHPStan\Analyser\ThrowPoint $throwPoint) use($scope, $arg) { return $throwPoint->isExplicit() ? \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwPoint->getType(), $arg->value, $throwPoint->canContainAnyThrowable()) : \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $arg->value); }, $closureResult->getThrowPoints())); $impurePoints = array_merge($impurePoints, $closureResult->getImpurePoints()); } $uses = []; foreach ($arg->value->uses as $use) { if (!is_string($use->var->name)) { continue; } $uses[] = $use->var->name; } $scope = $closureResult->getScope(); $invalidateExpressions = $closureResult->getInvalidateExpressions(); if ($restoreThisScope !== null) { $nodeFinder = new NodeFinder(); $cb = static function ($expr) { return $expr instanceof Variable && $expr->name === 'this'; }; foreach ($invalidateExpressions as $j => $invalidateExprNode) { $foundThis = $nodeFinder->findFirst([$invalidateExprNode->getExpr()], $cb); if ($foundThis === null) { continue; } unset($invalidateExpressions[$j]); } $invalidateExpressions = array_values($invalidateExpressions); $scope = $scope->restoreThis($restoreThisScope); } $scope = $this->processImmediatelyCalledCallable($scope, $invalidateExpressions, $uses); } elseif ($arg->value instanceof Expr\ArrowFunction) { if ($closureBindScope === null && $parameter instanceof ParameterReflectionWithPhpDocs && $parameter->getClosureThisType() !== null && !$arg->value->static) { $scopeToPass = $scopeToPass->assignVariable('this', $parameter->getClosureThisType(), new ObjectWithoutClassType()); } if ($parameter !== null) { $overwritingParameterType = $this->getParameterTypeFromParameterClosureTypeExtension($callLike, $calleeReflection, $parameter, $scopeToPass); if ($overwritingParameterType !== null) { $parameterType = $overwritingParameterType; } } $this->callNodeCallbackWithExpression($nodeCallback, $arg->value, $scopeToPass, $context); $arrowFunctionResult = $this->processArrowFunctionNode($stmt, $arg->value, $scopeToPass, $nodeCallback, $parameterType ?? null); if ($callCallbackImmediately) { $throwPoints = array_merge($throwPoints, array_map(static function (\PHPStan\Analyser\ThrowPoint $throwPoint) use($scope, $arg) { return $throwPoint->isExplicit() ? \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwPoint->getType(), $arg->value, $throwPoint->canContainAnyThrowable()) : \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $arg->value); }, $arrowFunctionResult->getThrowPoints())); $impurePoints = array_merge($impurePoints, $arrowFunctionResult->getImpurePoints()); } } else { $exprType = $scope->getType($arg->value); $exprResult = $this->processExprNode($stmt, $arg->value, $scopeToPass, $nodeCallback, $context->enterDeep()); $throwPoints = array_merge($throwPoints, $exprResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $exprResult->getImpurePoints()); $scope = $exprResult->getScope(); $hasYield = $hasYield || $exprResult->hasYield(); if ($exprType->isCallable()->yes()) { $acceptors = $exprType->getCallableParametersAcceptors($scope); if (count($acceptors) === 1) { $scope = $this->processImmediatelyCalledCallable($scope, $acceptors[0]->getInvalidateExpressions(), $acceptors[0]->getUsedVariables()); if ($callCallbackImmediately) { $callableThrowPoints = array_map(static function (SimpleThrowPoint $throwPoint) use($scope, $arg) { return $throwPoint->isExplicit() ? \PHPStan\Analyser\ThrowPoint::createExplicit($scope, $throwPoint->getType(), $arg->value, $throwPoint->canContainAnyThrowable()) : \PHPStan\Analyser\ThrowPoint::createImplicit($scope, $arg->value); }, $acceptors[0]->getThrowPoints()); if (!$this->implicitThrows) { $callableThrowPoints = array_values(array_filter($callableThrowPoints, static function (\PHPStan\Analyser\ThrowPoint $throwPoint) { return $throwPoint->isExplicit(); })); } $throwPoints = array_merge($throwPoints, $callableThrowPoints); $impurePoints = array_merge($impurePoints, array_map(static function (SimpleImpurePoint $impurePoint) use($scope, $arg) { return new \PHPStan\Analyser\ImpurePoint($scope, $arg->value, $impurePoint->getIdentifier(), $impurePoint->getDescription(), $impurePoint->isCertain()); }, $acceptors[0]->getImpurePoints())); } } } } if ($assignByReference && $lookForUnset) { $scope = $this->lookForUnsetAllowedUndefinedExpressions($scope, $arg->value); } if ($calleeReflection !== null) { $scope = $scope->popInFunctionCall(); } if ($i !== 0 || $closureBindScope === null) { continue; } $scope = $scope->restoreOriginalScopeAfterClosureBind($originalScope); } foreach ($args as $i => $arg) { if (!isset($parameters) || $parametersAcceptor === null) { continue; } $byRefType = new MixedType(); $assignByReference = \false; $currentParameter = null; if (isset($parameters[$i])) { $currentParameter = $parameters[$i]; } elseif (count($parameters) > 0 && $parametersAcceptor->isVariadic()) { $currentParameter = $parameters[count($parameters) - 1]; } if ($currentParameter !== null) { $assignByReference = $currentParameter->passedByReference()->createsNewVariable(); if ($assignByReference) { if ($currentParameter instanceof ParameterReflectionWithPhpDocs && $currentParameter->getOutType() !== null) { $byRefType = $currentParameter->getOutType(); } elseif ($calleeReflection instanceof MethodReflection && !$calleeReflection->getDeclaringClass()->isBuiltin() && $this->paramOutType) { $byRefType = $currentParameter->getType(); } elseif ($calleeReflection instanceof FunctionReflection && !$calleeReflection->isBuiltin() && $this->paramOutType) { $byRefType = $currentParameter->getType(); } } } if ($assignByReference) { if ($currentParameter === null) { throw new ShouldNotHappenException(); } $argValue = $arg->value; if (!$argValue instanceof Variable || $argValue->name !== 'this') { $paramOutType = $this->getParameterOutExtensionsType($callLike, $calleeReflection, $currentParameter, $scope); if ($paramOutType !== null) { $byRefType = $paramOutType; } $result = $this->processAssignVar($scope, $stmt, $argValue, new TypeExpr($byRefType), static function (Node $node, \PHPStan\Analyser\Scope $scope) use($nodeCallback) : void { if (!$node instanceof PropertyAssignNode && !$node instanceof VariableAssignNode) { return; } $nodeCallback($node, $scope); }, $context, static function (\PHPStan\Analyser\MutatingScope $scope) : \PHPStan\Analyser\ExpressionResult { return new \PHPStan\Analyser\ExpressionResult($scope, \false, [], []); }, \true); $scope = $result->getScope(); } } elseif ($calleeReflection !== null && $calleeReflection->hasSideEffects()->yes()) { $argType = $scope->getType($arg->value); if (!$argType->isObject()->no()) { $nakedReturnType = null; if ($nakedMethodReflection !== null) { $nakedParametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $args, $nakedMethodReflection->getVariants(), $nakedMethodReflection->getNamedArgumentsVariants()); $nakedReturnType = $nakedParametersAcceptor->getReturnType(); } if ($nakedReturnType === null || !(new ThisType($nakedMethodReflection->getDeclaringClass()))->isSuperTypeOf($nakedReturnType)->yes() || $nakedMethodReflection->isPure()->no()) { $nodeCallback(new InvalidateExprNode($arg->value), $scope); $scope = $scope->invalidateExpression($arg->value, \true); } } elseif (!(new ResourceType())->isSuperTypeOf($argType)->no()) { $nodeCallback(new InvalidateExprNode($arg->value), $scope); $scope = $scope->invalidateExpression($arg->value, \true); } } } return new \PHPStan\Analyser\ExpressionResult($scope, $hasYield, $throwPoints, $impurePoints); } /** * @param MethodReflection|FunctionReflection|null $calleeReflection */ private function getParameterTypeFromParameterClosureTypeExtension(CallLike $callLike, $calleeReflection, ParameterReflection $parameter, \PHPStan\Analyser\MutatingScope $scope) : ?Type { if ($callLike instanceof FuncCall && $calleeReflection instanceof FunctionReflection) { foreach ($this->parameterClosureTypeExtensionProvider->getFunctionParameterClosureTypeExtensions() as $functionParameterClosureTypeExtension) { if ($functionParameterClosureTypeExtension->isFunctionSupported($calleeReflection, $parameter)) { return $functionParameterClosureTypeExtension->getTypeFromFunctionCall($calleeReflection, $callLike, $parameter, $scope); } } } elseif ($calleeReflection instanceof MethodReflection) { if ($callLike instanceof StaticCall) { foreach ($this->parameterClosureTypeExtensionProvider->getStaticMethodParameterClosureTypeExtensions() as $staticMethodParameterClosureTypeExtension) { if ($staticMethodParameterClosureTypeExtension->isStaticMethodSupported($calleeReflection, $parameter)) { return $staticMethodParameterClosureTypeExtension->getTypeFromStaticMethodCall($calleeReflection, $callLike, $parameter, $scope); } } } elseif ($callLike instanceof MethodCall) { foreach ($this->parameterClosureTypeExtensionProvider->getMethodParameterClosureTypeExtensions() as $methodParameterClosureTypeExtension) { if ($methodParameterClosureTypeExtension->isMethodSupported($calleeReflection, $parameter)) { return $methodParameterClosureTypeExtension->getTypeFromMethodCall($calleeReflection, $callLike, $parameter, $scope); } } } } return null; } /** * @param MethodReflection|FunctionReflection|null $calleeReflection */ private function getParameterOutExtensionsType(CallLike $callLike, $calleeReflection, ParameterReflection $currentParameter, \PHPStan\Analyser\MutatingScope $scope) : ?Type { $paramOutTypes = []; if ($callLike instanceof FuncCall && $calleeReflection instanceof FunctionReflection) { foreach ($this->parameterOutTypeExtensionProvider->getFunctionParameterOutTypeExtensions() as $functionParameterOutTypeExtension) { if (!$functionParameterOutTypeExtension->isFunctionSupported($calleeReflection, $currentParameter)) { continue; } $resolvedType = $functionParameterOutTypeExtension->getParameterOutTypeFromFunctionCall($calleeReflection, $callLike, $currentParameter, $scope); if ($resolvedType === null) { continue; } $paramOutTypes[] = $resolvedType; } } elseif ($callLike instanceof MethodCall && $calleeReflection instanceof MethodReflection) { foreach ($this->parameterOutTypeExtensionProvider->getMethodParameterOutTypeExtensions() as $methodParameterOutTypeExtension) { if (!$methodParameterOutTypeExtension->isMethodSupported($calleeReflection, $currentParameter)) { continue; } $resolvedType = $methodParameterOutTypeExtension->getParameterOutTypeFromMethodCall($calleeReflection, $callLike, $currentParameter, $scope); if ($resolvedType === null) { continue; } $paramOutTypes[] = $resolvedType; } } elseif ($callLike instanceof StaticCall && $calleeReflection instanceof MethodReflection) { foreach ($this->parameterOutTypeExtensionProvider->getStaticMethodParameterOutTypeExtensions() as $staticMethodParameterOutTypeExtension) { if (!$staticMethodParameterOutTypeExtension->isStaticMethodSupported($calleeReflection, $currentParameter)) { continue; } $resolvedType = $staticMethodParameterOutTypeExtension->getParameterOutTypeFromStaticMethodCall($calleeReflection, $callLike, $currentParameter, $scope); if ($resolvedType === null) { continue; } $paramOutTypes[] = $resolvedType; } } if (count($paramOutTypes) === 1) { return $paramOutTypes[0]; } if (count($paramOutTypes) > 1) { return TypeCombinator::union(...$paramOutTypes); } return null; } /** * @param callable(Node $node, Scope $scope): void $nodeCallback * @param Closure(MutatingScope $scope): ExpressionResult $processExprCallback */ private function processAssignVar(\PHPStan\Analyser\MutatingScope $scope, Node\Stmt $stmt, Expr $var, Expr $assignedExpr, callable $nodeCallback, \PHPStan\Analyser\ExpressionContext $context, Closure $processExprCallback, bool $enterExpressionAssign) : \PHPStan\Analyser\ExpressionResult { $nodeCallback($var, $enterExpressionAssign ? $scope->enterExpressionAssign($var) : $scope); $hasYield = \false; $throwPoints = []; $impurePoints = []; $isAssignOp = $assignedExpr instanceof Expr\AssignOp && !$enterExpressionAssign; if ($var instanceof Variable && is_string($var->name)) { $result = $processExprCallback($scope); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); if (in_array($var->name, \PHPStan\Analyser\Scope::SUPERGLOBAL_VARIABLES, \true)) { $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $var, 'superglobal', 'assign to superglobal variable', \true); } $assignedExpr = $this->unwrapAssign($assignedExpr); $type = $scope->getType($assignedExpr); $conditionalExpressions = []; if ($assignedExpr instanceof Ternary) { $if = $assignedExpr->if; if ($if === null) { $if = $assignedExpr->cond; } $condScope = $this->processExprNode($stmt, $assignedExpr->cond, $scope, static function () : void { }, \PHPStan\Analyser\ExpressionContext::createDeep())->getScope(); $truthySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($condScope, $assignedExpr->cond, \PHPStan\Analyser\TypeSpecifierContext::createTruthy()); $falseySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($condScope, $assignedExpr->cond, \PHPStan\Analyser\TypeSpecifierContext::createFalsey()); $truthyScope = $condScope->filterBySpecifiedTypes($truthySpecifiedTypes); $falsyScope = $condScope->filterBySpecifiedTypes($falseySpecifiedTypes); $truthyType = $truthyScope->getType($if); $falseyType = $falsyScope->getType($assignedExpr->else); if ($truthyType->isSuperTypeOf($falseyType)->no() && $falseyType->isSuperTypeOf($truthyType)->no()) { $conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType); $conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType); $conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType); $conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType); } } $scope = $result->getScope(); $truthySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, \PHPStan\Analyser\TypeSpecifierContext::createTruthy()); $falseySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, \PHPStan\Analyser\TypeSpecifierContext::createFalsey()); $truthyType = TypeCombinator::removeFalsey($type); $falseyType = TypeCombinator::intersect($type, StaticTypeFactory::falsey()); $conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType); $conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType); $conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType); $conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType); $nodeCallback(new VariableAssignNode($var, $assignedExpr, $isAssignOp), $result->getScope()); $scope = $scope->assignVariable($var->name, $type, $scope->getNativeType($assignedExpr)); foreach ($conditionalExpressions as $exprString => $holders) { $scope = $scope->addConditionalExpressions($exprString, $holders); } } elseif ($var instanceof ArrayDimFetch) { $dimFetchStack = []; $originalVar = $var; $assignedPropertyExpr = $assignedExpr; while ($var instanceof ArrayDimFetch) { $varForSetOffsetValue = $var->var; if ($varForSetOffsetValue instanceof PropertyFetch || $varForSetOffsetValue instanceof StaticPropertyFetch) { $varForSetOffsetValue = new OriginalPropertyTypeExpr($varForSetOffsetValue); } $assignedPropertyExpr = new SetOffsetValueTypeExpr($varForSetOffsetValue, $var->dim, $assignedPropertyExpr); $dimFetchStack[] = $var; $var = $var->var; } // 1. eval root expr if ($enterExpressionAssign) { $scope = $scope->enterExpressionAssign($var); } $result = $this->processExprNode($stmt, $var, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $result->hasYield(); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); $scope = $result->getScope(); if ($enterExpressionAssign) { $scope = $scope->exitExpressionAssign($var); } // 2. eval dimensions $offsetTypes = []; $offsetNativeTypes = []; $dimFetchStack = array_reverse($dimFetchStack); $lastDimKey = array_key_last($dimFetchStack); foreach ($dimFetchStack as $key => $dimFetch) { $dimExpr = $dimFetch->dim; // Callback was already called for last dim at the beginning of the method. if ($key !== $lastDimKey) { $nodeCallback($dimFetch, $enterExpressionAssign ? $scope->enterExpressionAssign($dimFetch) : $scope); } if ($dimExpr === null) { $offsetTypes[] = null; $offsetNativeTypes[] = null; } else { $offsetTypes[] = $scope->getType($dimExpr); $offsetNativeTypes[] = $scope->getNativeType($dimExpr); if ($enterExpressionAssign) { $scope->enterExpressionAssign($dimExpr); } $result = $this->processExprNode($stmt, $dimExpr, $scope, $nodeCallback, $context->enterDeep()); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $scope = $result->getScope(); if ($enterExpressionAssign) { $scope = $scope->exitExpressionAssign($dimExpr); } } } $valueToWrite = $scope->getType($assignedExpr); $nativeValueToWrite = $scope->getNativeType($assignedExpr); $originalValueToWrite = $valueToWrite; $originalNativeValueToWrite = $nativeValueToWrite; // 3. eval assigned expr $result = $processExprCallback($scope); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); $scope = $result->getScope(); $varType = $scope->getType($var); $varNativeType = $scope->getNativeType($var); // 4. compose types if ($varType instanceof ErrorType) { $varType = new ConstantArrayType([], []); } if ($varNativeType instanceof ErrorType) { $varNativeType = new ConstantArrayType([], []); } $offsetValueType = $varType; $offsetNativeValueType = $varNativeType; $valueToWrite = $this->produceArrayDimFetchAssignValueToWrite($offsetTypes, $offsetValueType, $valueToWrite); if (!$offsetValueType->equals($offsetNativeValueType) || !$valueToWrite->equals($nativeValueToWrite)) { $nativeValueToWrite = $this->produceArrayDimFetchAssignValueToWrite($offsetNativeTypes, $offsetNativeValueType, $nativeValueToWrite); } else { $rewritten = \false; foreach ($offsetTypes as $i => $offsetType) { $offsetNativeType = $offsetNativeTypes[$i]; if ($offsetType === null) { if ($offsetNativeType !== null) { throw new ShouldNotHappenException(); } continue; } elseif ($offsetNativeType === null) { throw new ShouldNotHappenException(); } if ($offsetType->equals($offsetNativeType)) { continue; } $nativeValueToWrite = $this->produceArrayDimFetchAssignValueToWrite($offsetNativeTypes, $offsetNativeValueType, $nativeValueToWrite); $rewritten = \true; break; } if (!$rewritten) { $nativeValueToWrite = $valueToWrite; } } if ($varType->isArray()->yes() || !(new ObjectType(ArrayAccess::class))->isSuperTypeOf($varType)->yes()) { if ($var instanceof Variable && is_string($var->name)) { $nodeCallback(new VariableAssignNode($var, $assignedPropertyExpr, $isAssignOp), $scope); $scope = $scope->assignVariable($var->name, $valueToWrite, $nativeValueToWrite); } else { if ($var instanceof PropertyFetch || $var instanceof StaticPropertyFetch) { $nodeCallback(new PropertyAssignNode($var, $assignedPropertyExpr, $isAssignOp), $scope); if ($var instanceof PropertyFetch && $var->name instanceof Node\Identifier && !$isAssignOp) { $scope = $scope->assignInitializedProperty($scope->getType($var->var), $var->name->toString()); } } $scope = $scope->assignExpression($var, $valueToWrite, $nativeValueToWrite); } if ($originalVar->dim instanceof Variable || $originalVar->dim instanceof Node\Scalar) { $currentVarType = $scope->getType($originalVar); if (!$originalValueToWrite->isSuperTypeOf($currentVarType)->yes()) { $scope = $scope->assignExpression($originalVar, $originalValueToWrite, $originalNativeValueToWrite); } } } else { if ($var instanceof Variable) { $nodeCallback(new VariableAssignNode($var, $assignedPropertyExpr, $isAssignOp), $scope); } elseif ($var instanceof PropertyFetch || $var instanceof StaticPropertyFetch) { $nodeCallback(new PropertyAssignNode($var, $assignedPropertyExpr, $isAssignOp), $scope); if ($var instanceof PropertyFetch && $var->name instanceof Node\Identifier && !$isAssignOp) { $scope = $scope->assignInitializedProperty($scope->getType($var->var), $var->name->toString()); } } } if (!$varType->isArray()->yes() && !(new ObjectType(ArrayAccess::class))->isSuperTypeOf($varType)->no()) { $throwPoints = array_merge($throwPoints, $this->processExprNode($stmt, new MethodCall($var, 'offsetSet'), $scope, static function () : void { }, $context)->getThrowPoints()); } } elseif ($var instanceof PropertyFetch) { $objectResult = $this->processExprNode($stmt, $var->var, $scope, $nodeCallback, $context); $hasYield = $objectResult->hasYield(); $throwPoints = $objectResult->getThrowPoints(); $impurePoints = $objectResult->getImpurePoints(); $scope = $objectResult->getScope(); $propertyName = null; if ($var->name instanceof Node\Identifier) { $propertyName = $var->name->name; } else { $propertyNameResult = $this->processExprNode($stmt, $var->name, $scope, $nodeCallback, $context); $hasYield = $hasYield || $propertyNameResult->hasYield(); $throwPoints = array_merge($throwPoints, $propertyNameResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $propertyNameResult->getImpurePoints()); $scope = $propertyNameResult->getScope(); } $result = $processExprCallback($scope); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); $scope = $result->getScope(); $propertyHolderType = $scope->getType($var->var); if ($propertyName !== null && $propertyHolderType->hasProperty($propertyName)->yes()) { $propertyReflection = $propertyHolderType->getProperty($propertyName, $scope); $assignedExprType = $scope->getType($assignedExpr); $nodeCallback(new PropertyAssignNode($var, $assignedExpr, $isAssignOp), $scope); if ($propertyReflection->canChangeTypeAfterAssignment()) { $scope = $scope->assignExpression($var, $assignedExprType, $scope->getNativeType($assignedExpr)); } $declaringClass = $propertyReflection->getDeclaringClass(); if ($declaringClass->hasNativeProperty($propertyName)) { $nativeProperty = $declaringClass->getNativeProperty($propertyName); if (!$nativeProperty->getNativeType()->accepts($assignedExprType, \true)->yes()) { $throwPoints[] = \PHPStan\Analyser\ThrowPoint::createExplicit($scope, new ObjectType(TypeError::class), $assignedExpr, \false); } if ($enterExpressionAssign) { $scope = $scope->assignInitializedProperty($propertyHolderType, $propertyName); } } } else { // fallback $assignedExprType = $scope->getType($assignedExpr); $nodeCallback(new PropertyAssignNode($var, $assignedExpr, $isAssignOp), $scope); $scope = $scope->assignExpression($var, $assignedExprType, $scope->getNativeType($assignedExpr)); // simulate dynamic property assign by __set to get throw points if (!$propertyHolderType->hasMethod('__set')->no()) { $throwPoints = array_merge($throwPoints, $this->processExprNode($stmt, new MethodCall($var->var, '__set'), $scope, static function () : void { }, $context)->getThrowPoints()); } } } elseif ($var instanceof Expr\StaticPropertyFetch) { if ($var->class instanceof Node\Name) { $propertyHolderType = $scope->resolveTypeByName($var->class); } else { $this->processExprNode($stmt, $var->class, $scope, $nodeCallback, $context); $propertyHolderType = $scope->getType($var->class); } $propertyName = null; if ($var->name instanceof Node\Identifier) { $propertyName = $var->name->name; } else { $propertyNameResult = $this->processExprNode($stmt, $var->name, $scope, $nodeCallback, $context); $hasYield = $propertyNameResult->hasYield(); $throwPoints = $propertyNameResult->getThrowPoints(); $impurePoints = $propertyNameResult->getImpurePoints(); $scope = $propertyNameResult->getScope(); } $result = $processExprCallback($scope); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); $scope = $result->getScope(); if ($propertyName !== null) { $propertyReflection = $scope->getPropertyReflection($propertyHolderType, $propertyName); $assignedExprType = $scope->getType($assignedExpr); $nodeCallback(new PropertyAssignNode($var, $assignedExpr, $isAssignOp), $scope); if ($propertyReflection !== null && $propertyReflection->canChangeTypeAfterAssignment()) { $scope = $scope->assignExpression($var, $assignedExprType, $scope->getNativeType($assignedExpr)); } } else { // fallback $assignedExprType = $scope->getType($assignedExpr); $nodeCallback(new PropertyAssignNode($var, $assignedExpr, $isAssignOp), $scope); $scope = $scope->assignExpression($var, $assignedExprType, $scope->getNativeType($assignedExpr)); } } elseif ($var instanceof List_ || $var instanceof Array_) { $result = $processExprCallback($scope); $hasYield = $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); $scope = $result->getScope(); foreach ($var->items as $i => $arrayItem) { if ($arrayItem === null) { continue; } $itemScope = $scope; if ($enterExpressionAssign) { $itemScope = $itemScope->enterExpressionAssign($arrayItem->value); } $itemScope = $this->lookForSetAllowedUndefinedExpressions($itemScope, $arrayItem->value); $nodeCallback($arrayItem, $itemScope); if ($arrayItem->key !== null) { $keyResult = $this->processExprNode($stmt, $arrayItem->key, $itemScope, $nodeCallback, $context->enterDeep()); $hasYield = $hasYield || $keyResult->hasYield(); $throwPoints = array_merge($throwPoints, $keyResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $keyResult->getImpurePoints()); $itemScope = $keyResult->getScope(); } $valueResult = $this->processExprNode($stmt, $arrayItem->value, $itemScope, $nodeCallback, $context->enterDeep()); $hasYield = $hasYield || $valueResult->hasYield(); $throwPoints = array_merge($throwPoints, $valueResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $valueResult->getImpurePoints()); if ($arrayItem->key === null) { $dimExpr = new Node\Scalar\LNumber($i); } else { $dimExpr = $arrayItem->key; } $result = $this->processAssignVar($scope, $stmt, $arrayItem->value, new GetOffsetValueTypeExpr($assignedExpr, $dimExpr), $nodeCallback, $context, static function (\PHPStan\Analyser\MutatingScope $scope) : \PHPStan\Analyser\ExpressionResult { return new \PHPStan\Analyser\ExpressionResult($scope, \false, [], []); }, $enterExpressionAssign); $scope = $result->getScope(); $hasYield = $hasYield || $result->hasYield(); $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); $impurePoints = array_merge($impurePoints, $result->getImpurePoints()); } } elseif ($var instanceof ExistingArrayDimFetch) { $dimFetchStack = []; $assignedPropertyExpr = $assignedExpr; while ($var instanceof ExistingArrayDimFetch) { $varForSetOffsetValue = $var->getVar(); if ($varForSetOffsetValue instanceof PropertyFetch || $varForSetOffsetValue instanceof StaticPropertyFetch) { $varForSetOffsetValue = new OriginalPropertyTypeExpr($varForSetOffsetValue); } $assignedPropertyExpr = new SetExistingOffsetValueTypeExpr($varForSetOffsetValue, $var->getDim(), $assignedPropertyExpr); $dimFetchStack[] = $var; $var = $var->getVar(); } $offsetTypes = []; $offsetNativeTypes = []; foreach (array_reverse($dimFetchStack) as $dimFetch) { $dimExpr = $dimFetch->getDim(); $offsetTypes[] = $scope->getType($dimExpr); $offsetNativeTypes[] = $scope->getNativeType($dimExpr); } $valueToWrite = $scope->getType($assignedExpr); $nativeValueToWrite = $scope->getNativeType($assignedExpr); $varType = $scope->getType($var); $varNativeType = $scope->getNativeType($var); $offsetValueType = $varType; $offsetNativeValueType = $varNativeType; $offsetValueTypeStack = [$offsetValueType]; $offsetValueNativeTypeStack = [$offsetNativeValueType]; foreach (array_slice($offsetTypes, 0, -1) as $offsetType) { $offsetValueType = $offsetValueType->getOffsetValueType($offsetType); $offsetValueTypeStack[] = $offsetValueType; } foreach (array_slice($offsetNativeTypes, 0, -1) as $offsetNativeType) { $offsetNativeValueType = $offsetNativeValueType->getOffsetValueType($offsetNativeType); $offsetValueNativeTypeStack[] = $offsetNativeValueType; } foreach (array_reverse($offsetTypes) as $offsetType) { /** @var Type $offsetValueType */ $offsetValueType = array_pop($offsetValueTypeStack); $valueToWrite = $offsetValueType->setExistingOffsetValueType($offsetType, $valueToWrite); } foreach (array_reverse($offsetNativeTypes) as $offsetNativeType) { /** @var Type $offsetNativeValueType */ $offsetNativeValueType = array_pop($offsetValueNativeTypeStack); $nativeValueToWrite = $offsetNativeValueType->setExistingOffsetValueType($offsetNativeType, $nativeValueToWrite); } if ($var instanceof Variable && is_string($var->name)) { $nodeCallback(new VariableAssignNode($var, $assignedPropertyExpr, $isAssignOp), $scope); $scope = $scope->assignVariable($var->name, $valueToWrite, $nativeValueToWrite); } else { if ($var instanceof PropertyFetch || $var instanceof StaticPropertyFetch) { $nodeCallback(new PropertyAssignNode($var, $assignedPropertyExpr, $isAssignOp), $scope); } $scope = $scope->assignExpression($var, $valueToWrite, $nativeValueToWrite); } } return new \PHPStan\Analyser\ExpressionResult($scope, $hasYield, $throwPoints, $impurePoints); } /** * @param list $offsetTypes */ private function produceArrayDimFetchAssignValueToWrite(array $offsetTypes, Type $offsetValueType, Type $valueToWrite) : Type { $offsetValueTypeStack = [$offsetValueType]; foreach (array_slice($offsetTypes, 0, -1) as $offsetType) { if ($offsetType === null) { $offsetValueType = new ConstantArrayType([], []); } else { $offsetValueType = $offsetValueType->getOffsetValueType($offsetType); if ($offsetValueType instanceof ErrorType) { $offsetValueType = new ConstantArrayType([], []); } } $offsetValueTypeStack[] = $offsetValueType; } foreach (array_reverse($offsetTypes) as $i => $offsetType) { /** @var Type $offsetValueType */ $offsetValueType = array_pop($offsetValueTypeStack); if (!$offsetValueType instanceof MixedType) { $types = [new ArrayType(new MixedType(), new MixedType()), new ObjectType(ArrayAccess::class), new NullType()]; if ($offsetType !== null && $offsetType->isInteger()->yes()) { $types[] = new StringType(); } $offsetValueType = TypeCombinator::intersect($offsetValueType, TypeCombinator::union(...$types)); } $valueToWrite = $offsetValueType->setOffsetValueType($offsetType, $valueToWrite, $i === 0); } return $valueToWrite; } private function unwrapAssign(Expr $expr) : Expr { if ($expr instanceof Assign) { return $this->unwrapAssign($expr->expr); } return $expr; } /** * @param array $conditionalExpressions * @return array */ private function processSureTypesForConditionalExpressionsAfterAssign(\PHPStan\Analyser\Scope $scope, string $variableName, array $conditionalExpressions, \PHPStan\Analyser\SpecifiedTypes $specifiedTypes, Type $variableType) : array { foreach ($specifiedTypes->getSureTypes() as $exprString => [$expr, $exprType]) { if (!$expr instanceof Variable) { continue; } if (!is_string($expr->name)) { continue; } if ($expr->name === $variableName) { continue; } if (!isset($conditionalExpressions[$exprString])) { $conditionalExpressions[$exprString] = []; } $holder = new \PHPStan\Analyser\ConditionalExpressionHolder(['$' . $variableName => \PHPStan\Analyser\ExpressionTypeHolder::createYes(new Variable($variableName), $variableType)], \PHPStan\Analyser\ExpressionTypeHolder::createYes($expr, TypeCombinator::intersect($scope->getType($expr), $exprType))); $conditionalExpressions[$exprString][$holder->getKey()] = $holder; } return $conditionalExpressions; } /** * @param array $conditionalExpressions * @return array */ private function processSureNotTypesForConditionalExpressionsAfterAssign(\PHPStan\Analyser\Scope $scope, string $variableName, array $conditionalExpressions, \PHPStan\Analyser\SpecifiedTypes $specifiedTypes, Type $variableType) : array { foreach ($specifiedTypes->getSureNotTypes() as $exprString => [$expr, $exprType]) { if (!$expr instanceof Variable) { continue; } if (!is_string($expr->name)) { continue; } if ($expr->name === $variableName) { continue; } if (!isset($conditionalExpressions[$exprString])) { $conditionalExpressions[$exprString] = []; } $holder = new \PHPStan\Analyser\ConditionalExpressionHolder(['$' . $variableName => \PHPStan\Analyser\ExpressionTypeHolder::createYes(new Variable($variableName), $variableType)], \PHPStan\Analyser\ExpressionTypeHolder::createYes($expr, TypeCombinator::remove($scope->getType($expr), $exprType))); $conditionalExpressions[$exprString][$holder->getKey()] = $holder; } return $conditionalExpressions; } /** * @param callable(Node $node, Scope $scope): void $nodeCallback */ private function processStmtVarAnnotation(\PHPStan\Analyser\MutatingScope $scope, Node\Stmt $stmt, ?Expr $defaultExpr, callable $nodeCallback) : \PHPStan\Analyser\MutatingScope { $function = $scope->getFunction(); $variableLessTags = []; foreach ($stmt->getComments() as $comment) { if (!$comment instanceof Doc) { continue; } $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $scope->isInClass() ? $scope->getClassReflection()->getName() : null, $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $function !== null ? $function->getName() : null, $comment->getText()); $assignedVariable = null; if ($stmt instanceof Node\Stmt\Expression && ($stmt->expr instanceof Assign || $stmt->expr instanceof AssignRef) && $stmt->expr->var instanceof Variable && is_string($stmt->expr->var->name)) { $assignedVariable = $stmt->expr->var->name; } foreach ($resolvedPhpDoc->getVarTags() as $name => $varTag) { if (is_int($name)) { $variableLessTags[] = $varTag; continue; } if ($name === $assignedVariable) { continue; } $certainty = $scope->hasVariableType($name); if ($certainty->no()) { continue; } if ($scope->isInClass() && $scope->getFunction() === null) { continue; } if ($scope->canAnyVariableExist()) { $certainty = TrinaryLogic::createYes(); } $variableNode = new Variable($name, $stmt->getAttributes()); $originalType = $scope->getVariableType($name); if (!$originalType->equals($varTag->getType())) { $nodeCallback(new VarTagChangedExpressionTypeNode($varTag, $variableNode), $scope); } $scope = $scope->assignVariable($name, $varTag->getType(), $scope->getNativeType($variableNode), $certainty); } } if (count($variableLessTags) === 1 && $defaultExpr !== null) { $originalType = $scope->getType($defaultExpr); $varTag = $variableLessTags[0]; if (!$originalType->equals($varTag->getType())) { $nodeCallback(new VarTagChangedExpressionTypeNode($varTag, $defaultExpr), $scope); } $scope = $scope->assignExpression($defaultExpr, $varTag->getType(), new MixedType()); } return $scope; } /** * @param array $variableNames */ private function processVarAnnotation(\PHPStan\Analyser\MutatingScope $scope, array $variableNames, Node\Stmt $node, bool &$changed = \false) : \PHPStan\Analyser\MutatingScope { $function = $scope->getFunction(); $varTags = []; foreach ($node->getComments() as $comment) { if (!$comment instanceof Doc) { continue; } $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($scope->getFile(), $scope->isInClass() ? $scope->getClassReflection()->getName() : null, $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, $function !== null ? $function->getName() : null, $comment->getText()); foreach ($resolvedPhpDoc->getVarTags() as $key => $varTag) { $varTags[$key] = $varTag; } } if (count($varTags) === 0) { return $scope; } foreach ($variableNames as $variableName) { if (!isset($varTags[$variableName])) { continue; } $variableType = $varTags[$variableName]->getType(); $changed = \true; $scope = $scope->assignVariable($variableName, $variableType, new MixedType()); } if (count($variableNames) === 1 && count($varTags) === 1 && isset($varTags[0])) { $variableType = $varTags[0]->getType(); $changed = \true; $scope = $scope->assignVariable($variableNames[0], $variableType, new MixedType()); } return $scope; } private function enterForeach(\PHPStan\Analyser\MutatingScope $scope, \PHPStan\Analyser\MutatingScope $originalScope, Foreach_ $stmt) : \PHPStan\Analyser\MutatingScope { if ($stmt->expr instanceof Variable && is_string($stmt->expr->name)) { $scope = $this->processVarAnnotation($scope, [$stmt->expr->name], $stmt); } $iterateeType = $originalScope->getType($stmt->expr); if ($stmt->valueVar instanceof Variable && is_string($stmt->valueVar->name) && ($stmt->keyVar === null || $stmt->keyVar instanceof Variable && is_string($stmt->keyVar->name))) { $keyVarName = null; if ($stmt->keyVar instanceof Variable && is_string($stmt->keyVar->name)) { $keyVarName = $stmt->keyVar->name; } $scope = $scope->enterForeach($originalScope, $stmt->expr, $stmt->valueVar->name, $keyVarName); $vars = [$stmt->valueVar->name]; if ($keyVarName !== null) { $vars[] = $keyVarName; } } else { $scope = $this->processAssignVar($scope, $stmt, $stmt->valueVar, new GetIterableValueTypeExpr($stmt->expr), static function () : void { }, \PHPStan\Analyser\ExpressionContext::createDeep(), static function (\PHPStan\Analyser\MutatingScope $scope) : \PHPStan\Analyser\ExpressionResult { return new \PHPStan\Analyser\ExpressionResult($scope, \false, [], []); }, \true)->getScope(); $vars = $this->getAssignedVariables($stmt->valueVar); if ($stmt->keyVar instanceof Variable && is_string($stmt->keyVar->name)) { $scope = $scope->enterForeachKey($originalScope, $stmt->expr, $stmt->keyVar->name); $vars[] = $stmt->keyVar->name; } elseif ($stmt->keyVar !== null) { $scope = $this->processAssignVar($scope, $stmt, $stmt->keyVar, new GetIterableKeyTypeExpr($stmt->expr), static function () : void { }, \PHPStan\Analyser\ExpressionContext::createDeep(), static function (\PHPStan\Analyser\MutatingScope $scope) : \PHPStan\Analyser\ExpressionResult { return new \PHPStan\Analyser\ExpressionResult($scope, \false, [], []); }, \true)->getScope(); $vars = array_merge($vars, $this->getAssignedVariables($stmt->keyVar)); } } $constantArrays = $iterateeType->getConstantArrays(); if ($stmt->getDocComment() === null && $iterateeType->isConstantArray()->yes() && count($constantArrays) === 1 && $stmt->valueVar instanceof Variable && is_string($stmt->valueVar->name) && $stmt->keyVar instanceof Variable && is_string($stmt->keyVar->name)) { $valueConditionalHolders = []; $arrayDimFetchConditionalHolders = []; foreach ($constantArrays[0]->getKeyTypes() as $i => $keyType) { $valueType = $constantArrays[0]->getValueTypes()[$i]; $holder = new \PHPStan\Analyser\ConditionalExpressionHolder(['$' . $stmt->keyVar->name => \PHPStan\Analyser\ExpressionTypeHolder::createYes(new Variable($stmt->keyVar->name), $keyType)], new \PHPStan\Analyser\ExpressionTypeHolder($stmt->valueVar, $valueType, TrinaryLogic::createYes())); $valueConditionalHolders[$holder->getKey()] = $holder; $arrayDimFetchHolder = new \PHPStan\Analyser\ConditionalExpressionHolder(['$' . $stmt->keyVar->name => \PHPStan\Analyser\ExpressionTypeHolder::createYes(new Variable($stmt->keyVar->name), $keyType)], new \PHPStan\Analyser\ExpressionTypeHolder(new ArrayDimFetch($stmt->expr, $stmt->keyVar), $valueType, TrinaryLogic::createYes())); $arrayDimFetchConditionalHolders[$arrayDimFetchHolder->getKey()] = $arrayDimFetchHolder; } $scope = $scope->addConditionalExpressions('$' . $stmt->valueVar->name, $valueConditionalHolders); if ($stmt->expr instanceof Variable && is_string($stmt->expr->name)) { $scope = $scope->addConditionalExpressions(sprintf('$%s[$%s]', $stmt->expr->name, $stmt->keyVar->name), $arrayDimFetchConditionalHolders); } } return $this->processVarAnnotation($scope, $vars, $stmt); } /** * @param callable(Node $node, Scope $scope): void $nodeCallback */ private function processTraitUse(Node\Stmt\TraitUse $node, \PHPStan\Analyser\MutatingScope $classScope, callable $nodeCallback) : void { $parentTraitNames = []; $parent = $classScope->getParentScope(); while ($parent !== null) { if ($parent->isInTrait()) { $parentTraitNames[] = $parent->getTraitReflection()->getName(); } $parent = $parent->getParentScope(); } foreach ($node->traits as $trait) { $traitName = (string) $trait; if (in_array($traitName, $parentTraitNames, \true)) { continue; } if (!$this->reflectionProvider->hasClass($traitName)) { continue; } $traitReflection = $this->reflectionProvider->getClass($traitName); $traitFileName = $traitReflection->getFileName(); if ($traitFileName === null) { continue; // trait from eval or from PHP itself } $fileName = $this->fileHelper->normalizePath($traitFileName); if (!isset($this->analysedFiles[$fileName])) { continue; } $adaptations = []; foreach ($node->adaptations as $adaptation) { if ($adaptation->trait === null) { $adaptations[] = $adaptation; continue; } if ($adaptation->trait->toLowerString() !== $trait->toLowerString()) { continue; } $adaptations[] = $adaptation; } $parserNodes = $this->parser->parseFile($fileName); $this->processNodesForTraitUse($parserNodes, $traitReflection, $classScope, $adaptations, $nodeCallback); } } /** * @param Node[]|Node|scalar|null $node * @param Node\Stmt\TraitUseAdaptation[] $adaptations * @param callable(Node $node, Scope $scope): void $nodeCallback */ private function processNodesForTraitUse($node, ClassReflection $traitReflection, \PHPStan\Analyser\MutatingScope $scope, array $adaptations, callable $nodeCallback) : void { if ($node instanceof Node) { if ($node instanceof Node\Stmt\Trait_ && $traitReflection->getName() === (string) $node->namespacedName && $traitReflection->getNativeReflection()->getStartLine() === $node->getStartLine()) { $methodModifiers = []; $methodNames = []; foreach ($adaptations as $adaptation) { if (!$adaptation instanceof Node\Stmt\TraitUseAdaptation\Alias) { continue; } $methodName = $adaptation->method->toLowerString(); if ($adaptation->newModifier !== null) { $methodModifiers[$methodName] = $adaptation->newModifier; } if ($adaptation->newName === null) { continue; } $methodNames[$methodName] = $adaptation->newName; } $stmts = $node->stmts; foreach ($stmts as $i => $stmt) { if (!$stmt instanceof Node\Stmt\ClassMethod) { continue; } $methodName = $stmt->name->toLowerString(); $methodAst = clone $stmt; $stmts[$i] = $methodAst; if (array_key_exists($methodName, $methodModifiers)) { $methodAst->flags = $methodAst->flags & ~Node\Stmt\Class_::VISIBILITY_MODIFIER_MASK | $methodModifiers[$methodName]; } if (!array_key_exists($methodName, $methodNames)) { continue; } $methodAst->setAttribute('originalTraitMethodName', $methodAst->name->toLowerString()); $methodAst->name = $methodNames[$methodName]; } if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } $traitScope = $scope->enterTrait($traitReflection); $nodeCallback(new InTraitNode($node, $traitReflection, $scope->getClassReflection()), $traitScope); $this->processStmtNodes($node, $stmts, $traitScope, $nodeCallback, \PHPStan\Analyser\StatementContext::createTopLevel()); return; } if ($node instanceof Node\Stmt\ClassLike) { return; } if ($node instanceof Node\FunctionLike) { return; } foreach ($node->getSubNodeNames() as $subNodeName) { $subNode = $node->{$subNodeName}; $this->processNodesForTraitUse($subNode, $traitReflection, $scope, $adaptations, $nodeCallback); } } elseif (is_array($node)) { foreach ($node as $subNode) { $this->processNodesForTraitUse($subNode, $traitReflection, $scope, $adaptations, $nodeCallback); } } } private function processCalledMethod(MethodReflection $methodReflection) : ?\PHPStan\Analyser\MutatingScope { $declaringClass = $methodReflection->getDeclaringClass(); if ($declaringClass->isAnonymous()) { return null; } if ($declaringClass->getFileName() === null) { return null; } $stackName = sprintf('%s::%s', $declaringClass->getName(), $methodReflection->getName()); if (array_key_exists($stackName, $this->calledMethodResults)) { return $this->calledMethodResults[$stackName]; } if (array_key_exists($stackName, $this->calledMethodStack)) { return null; } if (count($this->calledMethodStack) > 0) { return null; } $this->calledMethodStack[$stackName] = \true; $fileName = $this->fileHelper->normalizePath($declaringClass->getFileName()); if (!isset($this->analysedFiles[$fileName])) { return null; } $parserNodes = $this->parser->parseFile($fileName); $returnStatement = null; $this->processNodesForCalledMethod($parserNodes, $fileName, $methodReflection, static function (Node $node, \PHPStan\Analyser\Scope $scope) use($methodReflection, &$returnStatement) : void { if (!$node instanceof MethodReturnStatementsNode) { return; } if ($node->getClassReflection()->getName() !== $methodReflection->getDeclaringClass()->getName()) { return; } if ($returnStatement !== null) { return; } $returnStatement = $node; }); $calledMethodEndScope = null; if ($returnStatement !== null) { foreach ($returnStatement->getExecutionEnds() as $executionEnd) { $statementResult = $executionEnd->getStatementResult(); $endNode = $executionEnd->getNode(); if ($endNode instanceof Node\Stmt\Throw_) { continue; } if ($endNode instanceof Node\Stmt\Expression) { $exprType = $statementResult->getScope()->getType($endNode->expr); if ($exprType instanceof NeverType && $exprType->isExplicit()) { continue; } } if ($calledMethodEndScope === null) { $calledMethodEndScope = $statementResult->getScope(); continue; } $calledMethodEndScope = $calledMethodEndScope->mergeWith($statementResult->getScope()); } foreach ($returnStatement->getReturnStatements() as $statement) { if ($calledMethodEndScope === null) { $calledMethodEndScope = $statement->getScope(); continue; } $calledMethodEndScope = $calledMethodEndScope->mergeWith($statement->getScope()); } } unset($this->calledMethodStack[$stackName]); $this->calledMethodResults[$stackName] = $calledMethodEndScope; return $calledMethodEndScope; } /** * @param Node[]|Node|scalar|null $node * @param callable(Node $node, Scope $scope): void $nodeCallback */ private function processNodesForCalledMethod($node, string $fileName, MethodReflection $methodReflection, callable $nodeCallback) : void { if ($node instanceof Node) { $declaringClass = $methodReflection->getDeclaringClass(); if ($node instanceof Node\Stmt\Class_ && $node->namespacedName !== null && $declaringClass->getName() === (string) $node->namespacedName && $declaringClass->getNativeReflection()->getStartLine() === $node->getStartLine()) { $stmts = $node->stmts; foreach ($stmts as $stmt) { if (!$stmt instanceof Node\Stmt\ClassMethod) { continue; } if ($stmt->name->toString() !== $methodReflection->getName()) { continue; } if ($stmt->getEndLine() - $stmt->getStartLine() > 50) { continue; } $scope = $this->scopeFactory->create(\PHPStan\Analyser\ScopeContext::create($fileName))->enterClass($declaringClass); $this->processStmtNode($stmt, $scope, $nodeCallback, \PHPStan\Analyser\StatementContext::createTopLevel()); } return; } if ($node instanceof Node\Stmt\ClassLike) { return; } if ($node instanceof Node\FunctionLike) { return; } foreach ($node->getSubNodeNames() as $subNodeName) { $subNode = $node->{$subNodeName}; $this->processNodesForCalledMethod($subNode, $fileName, $methodReflection, $nodeCallback); } } elseif (is_array($node)) { foreach ($node as $subNode) { $this->processNodesForCalledMethod($subNode, $fileName, $methodReflection, $nodeCallback); } } } /** * @return array{TemplateTypeMap, array, array, array, ?Type, ?Type, ?string, bool, bool, bool, bool|null, bool, bool, string|null, Assertions, ?Type, array, array<(string|int), VarTag>, bool} * @param Node\FunctionLike|Node\Stmt\Property $node */ public function getPhpDocs(\PHPStan\Analyser\Scope $scope, $node) : array { $templateTypeMap = TemplateTypeMap::createEmpty(); $phpDocParameterTypes = []; $phpDocImmediatelyInvokedCallableParameters = []; $phpDocClosureThisTypeParameters = []; $phpDocReturnType = null; $phpDocThrowType = null; $deprecatedDescription = null; $isDeprecated = \false; $isInternal = \false; $isFinal = \false; $isPure = null; $isAllowedPrivateMutation = \false; $acceptsNamedArguments = \true; $isReadOnly = $scope->isInClass() && $scope->getClassReflection()->isImmutable(); $asserts = Assertions::createEmpty(); $selfOutType = null; $docComment = $node->getDocComment() !== null ? $node->getDocComment()->getText() : null; $file = $scope->getFile(); $class = $scope->isInClass() ? $scope->getClassReflection()->getName() : null; $trait = $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null; $resolvedPhpDoc = null; $functionName = null; $phpDocParameterOutTypes = []; if ($node instanceof Node\Stmt\ClassMethod) { if (!$scope->isInClass()) { throw new ShouldNotHappenException(); } $functionName = $node->name->name; $positionalParameterNames = array_map(static function (Node\Param $param) : string { if (!$param->var instanceof Variable || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } return $param->var->name; }, $node->getParams()); $resolvedPhpDoc = $this->phpDocInheritanceResolver->resolvePhpDocForMethod($docComment, $file, $scope->getClassReflection(), $trait, $node->name->name, $positionalParameterNames); if ($node->name->toLowerString() === '__construct') { foreach ($node->params as $param) { if ($param->flags === 0) { continue; } if ($param->getDocComment() === null) { continue; } if (!$param->var instanceof Variable || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } $paramPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($file, $class, $trait, '__construct', $param->getDocComment()->getText()); $varTags = $paramPhpDoc->getVarTags(); if (isset($varTags[0]) && count($varTags) === 1) { $phpDocType = $varTags[0]->getType(); } elseif (isset($varTags[$param->var->name])) { $phpDocType = $varTags[$param->var->name]->getType(); } else { continue; } $phpDocParameterTypes[$param->var->name] = $phpDocType; } } } elseif ($node instanceof Node\Stmt\Function_) { $functionName = trim($scope->getNamespace() . '\\' . $node->name->name, '\\'); } if ($docComment !== null && $resolvedPhpDoc === null) { $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($file, $class, $trait, $functionName, $docComment); } $varTags = []; if ($resolvedPhpDoc !== null) { $templateTypeMap = $resolvedPhpDoc->getTemplateTypeMap(); $phpDocImmediatelyInvokedCallableParameters = $resolvedPhpDoc->getParamsImmediatelyInvokedCallable(); foreach ($resolvedPhpDoc->getParamTags() as $paramName => $paramTag) { if (array_key_exists($paramName, $phpDocParameterTypes)) { continue; } $paramType = $paramTag->getType(); if ($scope->isInClass()) { $paramType = $this->transformStaticType($scope->getClassReflection(), $paramType); } $phpDocParameterTypes[$paramName] = $paramType; } foreach ($resolvedPhpDoc->getParamClosureThisTags() as $paramName => $paramClosureThisTag) { if (array_key_exists($paramName, $phpDocClosureThisTypeParameters)) { continue; } $paramClosureThisType = $paramClosureThisTag->getType(); if ($scope->isInClass()) { $paramClosureThisType = $this->transformStaticType($scope->getClassReflection(), $paramClosureThisType); } $phpDocClosureThisTypeParameters[$paramName] = $paramClosureThisType; } foreach ($resolvedPhpDoc->getParamOutTags() as $paramName => $paramOutTag) { $phpDocParameterOutTypes[$paramName] = $paramOutTag->getType(); } if ($node instanceof Node\FunctionLike) { $nativeReturnType = $scope->getFunctionType($node->getReturnType(), \false, \false); $phpDocReturnType = $this->getPhpDocReturnType($resolvedPhpDoc, $nativeReturnType); if ($phpDocReturnType !== null && $scope->isInClass()) { $phpDocReturnType = $this->transformStaticType($scope->getClassReflection(), $phpDocReturnType); } } $phpDocThrowType = $resolvedPhpDoc->getThrowsTag() !== null ? $resolvedPhpDoc->getThrowsTag()->getType() : null; $deprecatedDescription = $resolvedPhpDoc->getDeprecatedTag() !== null ? $resolvedPhpDoc->getDeprecatedTag()->getMessage() : null; $isDeprecated = $resolvedPhpDoc->isDeprecated(); $isInternal = $resolvedPhpDoc->isInternal(); $isFinal = $resolvedPhpDoc->isFinal(); $isPure = $resolvedPhpDoc->isPure(); $isAllowedPrivateMutation = $resolvedPhpDoc->isAllowedPrivateMutation(); $acceptsNamedArguments = $resolvedPhpDoc->acceptsNamedArguments(); if ($acceptsNamedArguments && $scope->isInClass()) { $acceptsNamedArguments = $scope->getClassReflection()->acceptsNamedArguments(); } $isReadOnly = $isReadOnly || $resolvedPhpDoc->isReadOnly(); $asserts = Assertions::createFromResolvedPhpDocBlock($resolvedPhpDoc); $selfOutType = $resolvedPhpDoc->getSelfOutTag() !== null ? $resolvedPhpDoc->getSelfOutTag()->getType() : null; $varTags = $resolvedPhpDoc->getVarTags(); } return [$templateTypeMap, $phpDocParameterTypes, $phpDocImmediatelyInvokedCallableParameters, $phpDocClosureThisTypeParameters, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal, $isPure, $acceptsNamedArguments, $isReadOnly, $docComment, $asserts, $selfOutType, $phpDocParameterOutTypes, $varTags, $isAllowedPrivateMutation]; } private function transformStaticType(ClassReflection $declaringClass, Type $type) : Type { return TypeTraverser::map($type, static function (Type $type, callable $traverse) use($declaringClass) : Type { if ($type instanceof StaticType) { $changedType = $type->changeBaseClass($declaringClass); if ($declaringClass->isFinal() && !$type instanceof ThisType) { $changedType = $changedType->getStaticObjectType(); } return $traverse($changedType); } return $traverse($type); }); } private function getPhpDocReturnType(ResolvedPhpDocBlock $resolvedPhpDoc, Type $nativeReturnType) : ?Type { $returnTag = $resolvedPhpDoc->getReturnTag(); if ($returnTag === null) { return null; } $phpDocReturnType = $returnTag->getType(); if ($returnTag->isExplicit()) { return $phpDocReturnType; } if ($nativeReturnType->isSuperTypeOf(TemplateTypeHelper::resolveToBounds($phpDocReturnType))->yes()) { return $phpDocReturnType; } return null; } /** * @template T of Node * @param array $nodes * @return T|null */ private function getFirstUnreachableNode(array $nodes, bool $earlyBinding) : ?Node { foreach ($nodes as $node) { if ($node instanceof Node\Stmt\Nop) { continue; } if ($earlyBinding && ($node instanceof Node\Stmt\Function_ || $node instanceof Node\Stmt\ClassLike || $node instanceof Node\Stmt\HaltCompiler)) { continue; } return $node; } return null; } } statement = $statement; $this->scope = $scope; } public function getStatement() : Stmt { return $this->statement; } public function getScope() : \PHPStan\Analyser\MutatingScope { return $this->scope; } } container = $container; } public function create() : \PHPStan\Analyser\TypeSpecifier { $typeSpecifier = new \PHPStan\Analyser\TypeSpecifier($this->container->getByType(ExprPrinter::class), $this->container->getByType(ReflectionProvider::class), $this->container->getServicesByTag(self::FUNCTION_TYPE_SPECIFYING_EXTENSION_TAG), $this->container->getServicesByTag(self::METHOD_TYPE_SPECIFYING_EXTENSION_TAG), $this->container->getServicesByTag(self::STATIC_METHOD_TYPE_SPECIFYING_EXTENSION_TAG), $this->container->getParameter('rememberPossiblyImpureFunctionValues')); foreach (array_merge($this->container->getServicesByTag(BrokerFactory::PROPERTIES_CLASS_REFLECTION_EXTENSION_TAG), $this->container->getServicesByTag(BrokerFactory::METHODS_CLASS_REFLECTION_EXTENSION_TAG), $this->container->getServicesByTag(BrokerFactory::DYNAMIC_METHOD_RETURN_TYPE_EXTENSION_TAG), $this->container->getServicesByTag(BrokerFactory::DYNAMIC_STATIC_METHOD_RETURN_TYPE_EXTENSION_TAG), $this->container->getServicesByTag(BrokerFactory::DYNAMIC_FUNCTION_RETURN_TYPE_EXTENSION_TAG)) as $extension) { if (!$extension instanceof \PHPStan\Analyser\TypeSpecifierAwareExtension) { continue; } $extension->setTypeSpecifier($typeSpecifier); } return $typeSpecifier; } } $nodeType * @param string|RuleError $ruleError */ public function transform($ruleError, \PHPStan\Analyser\Scope $scope, string $nodeType, int $nodeLine) : \PHPStan\Analyser\Error { $line = $nodeLine; $canBeIgnored = \true; $fileName = $scope->getFileDescription(); $filePath = $scope->getFile(); $traitFilePath = null; $tip = null; $identifier = null; $metadata = []; if ($scope->isInTrait()) { $traitReflection = $scope->getTraitReflection(); if ($traitReflection->getFileName() !== null) { $traitFilePath = $traitReflection->getFileName(); } } if (is_string($ruleError)) { $message = $ruleError; } else { $message = $ruleError->getMessage(); if ($ruleError instanceof LineRuleError && $ruleError->getLine() !== -1) { $line = $ruleError->getLine(); } if ($ruleError instanceof FileRuleError && $ruleError->getFile() !== '') { $fileName = $ruleError->getFileDescription(); $filePath = $ruleError->getFile(); $traitFilePath = null; } if ($ruleError instanceof TipRuleError) { $tip = $ruleError->getTip(); } if ($ruleError instanceof IdentifierRuleError) { $identifier = $ruleError->getIdentifier(); } if ($ruleError instanceof MetadataRuleError) { $metadata = $ruleError->getMetadata(); } if ($ruleError instanceof NonIgnorableRuleError) { $canBeIgnored = \false; } } return new \PHPStan\Analyser\Error($message, $fileName, $line, $canBeIgnored, $filePath, $traitFilePath, $tip, $nodeLine, $nodeType, $identifier, $metadata); } } $temporaryFileErrors * @param LinesToIgnore $linesToIgnore * @param LinesToIgnore $unmatchedLineIgnores */ public function process(array $temporaryFileErrors, array $linesToIgnore, array $unmatchedLineIgnores) : \PHPStan\Analyser\LocalIgnoresProcessorResult { $fileErrors = []; $locallyIgnoredErrors = []; foreach ($temporaryFileErrors as $tmpFileError) { $line = $tmpFileError->getLine(); if ($line !== null && $tmpFileError->canBeIgnored() && array_key_exists($tmpFileError->getFile(), $linesToIgnore) && array_key_exists($line, $linesToIgnore[$tmpFileError->getFile()])) { $identifiers = $linesToIgnore[$tmpFileError->getFile()][$line]; if ($identifiers === null) { $locallyIgnoredErrors[] = $tmpFileError; unset($unmatchedLineIgnores[$tmpFileError->getFile()][$line]); continue; } if ($tmpFileError->getIdentifier() === null) { $fileErrors[] = $tmpFileError; continue; } foreach ($identifiers as $i => $ignoredIdentifier) { if ($ignoredIdentifier !== $tmpFileError->getIdentifier()) { continue; } unset($identifiers[$i]); if (count($identifiers) > 0) { $linesToIgnore[$tmpFileError->getFile()][$line] = array_values($identifiers); } else { unset($linesToIgnore[$tmpFileError->getFile()][$line]); } if (array_key_exists($tmpFileError->getFile(), $unmatchedLineIgnores) && array_key_exists($line, $unmatchedLineIgnores[$tmpFileError->getFile()])) { $unmatchedIgnoredIdentifiers = $unmatchedLineIgnores[$tmpFileError->getFile()][$line]; if (is_array($unmatchedIgnoredIdentifiers)) { foreach ($unmatchedIgnoredIdentifiers as $j => $unmatchedIgnoredIdentifier) { if ($ignoredIdentifier !== $unmatchedIgnoredIdentifier) { continue; } unset($unmatchedIgnoredIdentifiers[$j]); if (count($unmatchedIgnoredIdentifiers) > 0) { $unmatchedLineIgnores[$tmpFileError->getFile()][$line] = array_values($unmatchedIgnoredIdentifiers); } else { unset($unmatchedLineIgnores[$tmpFileError->getFile()][$line]); } break; } } } $locallyIgnoredErrors[] = $tmpFileError; continue 2; } } $fileErrors[] = $tmpFileError; } return new \PHPStan\Analyser\LocalIgnoresProcessorResult($fileErrors, $locallyIgnoredErrors, $linesToIgnore, $unmatchedLineIgnores); } } */ private $fileErrors; /** * @var list */ private $locallyIgnoredErrors; /** * @var LinesToIgnore */ private $linesToIgnore; /** * @var LinesToIgnore */ private $unmatchedLineIgnores; /** * @param list $fileErrors * @param list $locallyIgnoredErrors * @param LinesToIgnore $linesToIgnore * @param LinesToIgnore $unmatchedLineIgnores */ public function __construct(array $fileErrors, array $locallyIgnoredErrors, array $linesToIgnore, array $unmatchedLineIgnores) { $this->fileErrors = $fileErrors; $this->locallyIgnoredErrors = $locallyIgnoredErrors; $this->linesToIgnore = $linesToIgnore; $this->unmatchedLineIgnores = $unmatchedLineIgnores; } /** * @return list */ public function getFileErrors() : array { return $this->fileErrors; } /** * @return list */ public function getLocallyIgnoredErrors() : array { return $this->locallyIgnoredErrors; } /** * @return LinesToIgnore */ public function getLinesToIgnore() : array { return $this->linesToIgnore; } /** * @return LinesToIgnore */ public function getUnmatchedLineIgnores() : array { return $this->unmatchedLineIgnores; } } */ private $conditionExpressionTypeHolders; /** * @var ExpressionTypeHolder */ private $typeHolder; /** * @param array $conditionExpressionTypeHolders */ public function __construct(array $conditionExpressionTypeHolders, \PHPStan\Analyser\ExpressionTypeHolder $typeHolder) { $this->conditionExpressionTypeHolders = $conditionExpressionTypeHolders; $this->typeHolder = $typeHolder; if (count($conditionExpressionTypeHolders) === 0) { throw new ShouldNotHappenException(); } } /** * @return array */ public function getConditionExpressionTypeHolders() : array { return $this->conditionExpressionTypeHolders; } public function getTypeHolder() : \PHPStan\Analyser\ExpressionTypeHolder { return $this->typeHolder; } public function getKey() : string { $parts = []; foreach ($this->conditionExpressionTypeHolders as $exprString => $typeHolder) { $parts[] = $exprString . '=' . $typeHolder->getType()->describe(VerbosityLevel::precise()); } return sprintf('%s => %s (%s)', implode(' && ', $parts), $this->typeHolder->getType()->describe(VerbosityLevel::precise()), $this->typeHolder->getCertainty()->describe()); } } fileAnalyser = $fileAnalyser; $this->ruleRegistry = $ruleRegistry; $this->collectorRegistry = $collectorRegistry; $this->nodeScopeResolver = $nodeScopeResolver; $this->internalErrorsCountLimit = $internalErrorsCountLimit; } /** * @param string[] $files * @param Closure(string $file): void|null $preFileCallback * @param Closure(int ): void|null $postFileCallback * @param string[]|null $allAnalysedFiles */ public function analyse(array $files, ?Closure $preFileCallback = null, ?Closure $postFileCallback = null, bool $debug = \false, ?array $allAnalysedFiles = null) : \PHPStan\Analyser\AnalyserResult { if ($allAnalysedFiles === null) { $allAnalysedFiles = $files; } $this->nodeScopeResolver->setAnalysedFiles($allAnalysedFiles); $allAnalysedFiles = array_fill_keys($allAnalysedFiles, \true); /** @var list $errors */ $errors = []; /** @var list $filteredPhpErrors */ $filteredPhpErrors = []; /** @var list $allPhpErrors */ $allPhpErrors = []; /** @var list $locallyIgnoredErrors */ $locallyIgnoredErrors = []; $linesToIgnore = []; $unmatchedLineIgnores = []; /** @var list $collectedData */ $collectedData = []; $internalErrorsCount = 0; $reachedInternalErrorsCountLimit = \false; $dependencies = []; $usedTraitDependencies = []; $exportedNodes = []; foreach ($files as $file) { if ($preFileCallback !== null) { $preFileCallback($file); } try { $fileAnalyserResult = $this->fileAnalyser->analyseFile($file, $allAnalysedFiles, $this->ruleRegistry, $this->collectorRegistry, null); $errors = array_merge($errors, $fileAnalyserResult->getErrors()); $filteredPhpErrors = array_merge($filteredPhpErrors, $fileAnalyserResult->getFilteredPhpErrors()); $allPhpErrors = array_merge($allPhpErrors, $fileAnalyserResult->getAllPhpErrors()); $locallyIgnoredErrors = array_merge($locallyIgnoredErrors, $fileAnalyserResult->getLocallyIgnoredErrors()); $linesToIgnore[$file] = $fileAnalyserResult->getLinesToIgnore(); $unmatchedLineIgnores[$file] = $fileAnalyserResult->getUnmatchedLineIgnores(); $collectedData = array_merge($collectedData, $fileAnalyserResult->getCollectedData()); $dependencies[$file] = $fileAnalyserResult->getDependencies(); $usedTraitDependencies[$file] = $fileAnalyserResult->getUsedTraitDependencies(); $fileExportedNodes = $fileAnalyserResult->getExportedNodes(); if (count($fileExportedNodes) > 0) { $exportedNodes[$file] = $fileExportedNodes; } } catch (Throwable $t) { if ($debug) { throw $t; } $internalErrorsCount++; $errors[] = (new \PHPStan\Analyser\Error($t->getMessage(), $file, null, $t))->withIdentifier('phpstan.internal')->withMetadata([\PHPStan\Analyser\InternalError::STACK_TRACE_METADATA_KEY => \PHPStan\Analyser\InternalError::prepareTrace($t), \PHPStan\Analyser\InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $t->getTraceAsString()]); if ($internalErrorsCount >= $this->internalErrorsCountLimit) { $reachedInternalErrorsCountLimit = \true; break; } } if ($postFileCallback === null) { continue; } $postFileCallback(1); } return new \PHPStan\Analyser\AnalyserResult($errors, $filteredPhpErrors, $allPhpErrors, $locallyIgnoredErrors, $linesToIgnore, $unmatchedLineIgnores, [], $collectedData, $internalErrorsCount === 0 ? $dependencies : null, $internalErrorsCount === 0 ? $usedTraitDependencies : null, $exportedNodes, $reachedInternalErrorsCountLimit, memory_get_peak_usage(\true)); } } initializerExprTypeResolver = $initializerExprTypeResolver; } /** * @return TypeResult */ public function getIdenticalResult(\PHPStan\Analyser\Scope $scope, Identical $expr) : TypeResult { if ($expr->left instanceof Variable && is_string($expr->left->name) && $expr->right instanceof Variable && is_string($expr->right->name) && $expr->left->name === $expr->right->name) { return new TypeResult(new ConstantBooleanType(\true), []); } $leftType = $scope->getType($expr->left); $rightType = $scope->getType($expr->right); if (!$scope instanceof \PHPStan\Analyser\MutatingScope) { return $this->initializerExprTypeResolver->resolveIdenticalType($leftType, $rightType); } if (($expr->left instanceof Node\Expr\PropertyFetch || $expr->left instanceof Node\Expr\StaticPropertyFetch) && $rightType->isNull()->yes() && !$scope->hasPropertyNativeType($expr->left)) { return new TypeResult(new BooleanType(), []); } if (($expr->right instanceof Node\Expr\PropertyFetch || $expr->right instanceof Node\Expr\StaticPropertyFetch) && $leftType->isNull()->yes() && !$scope->hasPropertyNativeType($expr->right)) { return new TypeResult(new BooleanType(), []); } return $this->initializerExprTypeResolver->resolveIdenticalType($leftType, $rightType); } /** * @return TypeResult */ public function getNotIdenticalResult(\PHPStan\Analyser\Scope $scope, Node\Expr\BinaryOp\NotIdentical $expr) : TypeResult { $identicalResult = $this->getIdenticalResult($scope, new Identical($expr->left, $expr->right)); $identicalType = $identicalResult->type; if ($identicalType instanceof ConstantBooleanType) { return new TypeResult(new ConstantBooleanType(!$identicalType->getValue()), $identicalResult->reasons); } return new TypeResult(new BooleanType(), []); } } file = $file; $this->classReflection = $classReflection; $this->traitReflection = $traitReflection; } /** @api */ public static function create(string $file) : self { return new self($file, null, null); } public function beginFile() : self { return new self($this->file, null, null); } public function enterClass(ClassReflection $classReflection) : self { if ($this->classReflection !== null && !$classReflection->isAnonymous()) { throw new ShouldNotHappenException(); } if ($classReflection->isTrait()) { throw new ShouldNotHappenException(); } return new self($this->file, $classReflection, null); } public function enterTrait(ClassReflection $traitReflection) : self { if ($this->classReflection === null) { throw new ShouldNotHappenException(); } if (!$traitReflection->isTrait()) { throw new ShouldNotHappenException(); } return new self($this->file, $this->classReflection, $traitReflection); } public function equals(self $otherContext) : bool { if ($this->file !== $otherContext->file) { return \false; } if ($this->getClassReflection() === null) { return $otherContext->getClassReflection() === null; } elseif ($otherContext->getClassReflection() === null) { return \false; } $isSameClass = $this->getClassReflection()->getName() === $otherContext->getClassReflection()->getName(); if ($this->getTraitReflection() === null) { return $otherContext->getTraitReflection() === null && $isSameClass; } elseif ($otherContext->getTraitReflection() === null) { return \false; } $isSameTrait = $this->getTraitReflection()->getName() === $otherContext->getTraitReflection()->getName(); return $isSameClass && $isSameTrait; } public function getFile() : string { return $this->file; } public function getClassReflection() : ?ClassReflection { return $this->classReflection; } public function getTraitReflection() : ?ClassReflection { return $this->traitReflection; } } |null */ private $nodeType; /** * @var ?string */ private $identifier; /** * @var mixed[] */ private $metadata; public const PATTERN_IDENTIFIER = '[a-zA-Z0-9](?:[a-zA-Z0-9\\.]*[a-zA-Z0-9])?'; /** * Error constructor. * * @param class-string|null $nodeType * @param mixed[] $metadata * @param bool|Throwable $canBeIgnored */ public function __construct(string $message, string $file, ?int $line = null, $canBeIgnored = \true, ?string $filePath = null, ?string $traitFilePath = null, ?string $tip = null, ?int $nodeLine = null, ?string $nodeType = null, ?string $identifier = null, array $metadata = []) { $this->message = $message; $this->file = $file; $this->line = $line; $this->canBeIgnored = $canBeIgnored; $this->filePath = $filePath; $this->traitFilePath = $traitFilePath; $this->tip = $tip; $this->nodeLine = $nodeLine; $this->nodeType = $nodeType; $this->identifier = $identifier; $this->metadata = $metadata; if ($this->identifier !== null && !self::validateIdentifier($this->identifier)) { throw new ShouldNotHappenException(sprintf('Invalid identifier: %s', $this->identifier)); } } public function getMessage() : string { return $this->message; } public function getFile() : string { return $this->file; } public function getFilePath() : string { if ($this->filePath === null) { return $this->file; } return $this->filePath; } public function changeFilePath(string $newFilePath) : self { if ($this->traitFilePath !== null) { throw new ShouldNotHappenException('Errors in traits not yet supported'); } return new self($this->message, $newFilePath, $this->line, $this->canBeIgnored, $newFilePath, null, $this->tip, $this->nodeLine, $this->nodeType, $this->identifier, $this->metadata); } public function changeTraitFilePath(string $newFilePath) : self { return new self($this->message, $this->file, $this->line, $this->canBeIgnored, $this->filePath, $newFilePath, $this->tip, $this->nodeLine, $this->nodeType, $this->identifier, $this->metadata); } public function getTraitFilePath() : ?string { return $this->traitFilePath; } public function getLine() : ?int { return $this->line; } public function canBeIgnored() : bool { return $this->canBeIgnored === \true; } public function hasNonIgnorableException() : bool { return $this->canBeIgnored instanceof Throwable; } public function getTip() : ?string { return $this->tip; } public function withoutTip() : self { if ($this->tip === null) { return $this; } return new self($this->message, $this->file, $this->line, $this->canBeIgnored, $this->filePath, $this->traitFilePath, null, $this->nodeLine, $this->nodeType); } public function doNotIgnore() : self { if (!$this->canBeIgnored()) { return $this; } return new self($this->message, $this->file, $this->line, \false, $this->filePath, $this->traitFilePath, $this->tip, $this->nodeLine, $this->nodeType); } public function withIdentifier(string $identifier) : self { if ($this->identifier !== null) { throw new ShouldNotHappenException(sprintf('Error already has an identifier: %s', $this->identifier)); } return new self($this->message, $this->file, $this->line, $this->canBeIgnored, $this->filePath, $this->traitFilePath, $this->tip, $this->nodeLine, $this->nodeType, $identifier, $this->metadata); } /** * @param mixed[] $metadata */ public function withMetadata(array $metadata) : self { if ($this->metadata !== []) { throw new ShouldNotHappenException('Error already has metadata'); } return new self($this->message, $this->file, $this->line, $this->canBeIgnored, $this->filePath, $this->traitFilePath, $this->tip, $this->nodeLine, $this->nodeType, $this->identifier, $metadata); } public function getNodeLine() : ?int { return $this->nodeLine; } /** * @return class-string|null */ public function getNodeType() : ?string { return $this->nodeType; } /** * Error identifier set via `RuleErrorBuilder::identifier()`. * * List of all current error identifiers in PHPStan: https://phpstan.org/error-identifiers */ public function getIdentifier() : ?string { return $this->identifier; } /** * @return mixed[] */ public function getMetadata() : array { return $this->metadata; } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['message' => $this->message, 'file' => $this->file, 'line' => $this->line, 'canBeIgnored' => is_bool($this->canBeIgnored) ? $this->canBeIgnored : 'exception', 'filePath' => $this->filePath, 'traitFilePath' => $this->traitFilePath, 'tip' => $this->tip, 'nodeLine' => $this->nodeLine, 'nodeType' => $this->nodeType, 'identifier' => $this->identifier, 'metadata' => $this->metadata]; } /** * @param mixed[] $json */ public static function decode(array $json) : self { return new self($json['message'], $json['file'], $json['line'], $json['canBeIgnored'] === 'exception' ? new Exception() : $json['canBeIgnored'], $json['filePath'], $json['traitFilePath'], $json['tip'], $json['nodeLine'] ?? null, $json['nodeType'] ?? null, $json['identifier'] ?? null, $json['metadata'] ?? []); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self { return new self($properties['message'], $properties['file'], $properties['line'], $properties['canBeIgnored'], $properties['filePath'], $properties['traitFilePath'], $properties['tip'], $properties['nodeLine'] ?? null, $properties['nodeType'] ?? null, $properties['identifier'] ?? null, $properties['metadata'] ?? []); } public static function validateIdentifier(string $identifier) : bool { return Strings::match($identifier, '~^' . self::PATTERN_IDENTIFIER . '$~') !== null; } } expr = $expr; $this->type = $type; $this->certainty = $certainty; } public static function createYes(Expr $expr, Type $type) : self { return new self($expr, $type, TrinaryLogic::createYes()); } public static function createMaybe(Expr $expr, Type $type) : self { return new self($expr, $type, TrinaryLogic::createMaybe()); } public function equals(self $other) : bool { if (!$this->certainty->equals($other->certainty)) { return \false; } return $this->type->equals($other->type); } public function and(self $other) : self { if ($this->getType()->equals($other->getType())) { $type = $this->getType(); } else { $type = TypeCombinator::union($this->getType(), $other->getType()); } return new self($this->expr, $type, $this->getCertainty()->and($other->getCertainty())); } public function getExpr() : Expr { return $this->expr; } public function getType() : Type { return $this->type; } public function getCertainty() : TrinaryLogic { return $this->certainty; } } internalScopeFactory = $internalScopeFactory; } public function create(\PHPStan\Analyser\ScopeContext $context) : \PHPStan\Analyser\MutatingScope { return $this->internalScopeFactory->create($context); } } getArgs(); if (count($args) < 1) { return null; } $passThruArgs = []; $callbackArg = null; foreach ($args as $i => $arg) { if ($callbackArg === null) { if ($arg->name === null && $i === 0) { $callbackArg = $arg; continue; } if ($arg->name !== null && $arg->name->toString() === 'callback') { $callbackArg = $arg; continue; } } $passThruArgs[] = $arg; } if ($callbackArg === null) { return null; } $calledOnType = $scope->getType($callbackArg->value); if (!$calledOnType->isCallable()->yes()) { return null; } $callableParametersAcceptors = $calledOnType->getCallableParametersAcceptors($scope); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $passThruArgs, $callableParametersAcceptors, null); $acceptsNamedArguments = \true; foreach ($callableParametersAcceptors as $callableParametersAcceptor) { $acceptsNamedArguments = $acceptsNamedArguments && $callableParametersAcceptor->acceptsNamedArguments(); } return [$parametersAcceptor, new FuncCall($callbackArg->value, $passThruArgs, $callUserFuncCall->getAttributes()), $acceptsNamedArguments]; } public static function reorderFuncArguments(ParametersAcceptor $parametersAcceptor, FuncCall $functionCall) : ?FuncCall { $reorderedArgs = self::reorderArgs($parametersAcceptor, $functionCall->getArgs()); if ($reorderedArgs === null) { return null; } return new FuncCall($functionCall->name, $reorderedArgs, $functionCall->getAttributes()); } public static function reorderMethodArguments(ParametersAcceptor $parametersAcceptor, MethodCall $methodCall) : ?MethodCall { $reorderedArgs = self::reorderArgs($parametersAcceptor, $methodCall->getArgs()); if ($reorderedArgs === null) { return null; } return new MethodCall($methodCall->var, $methodCall->name, $reorderedArgs, $methodCall->getAttributes()); } public static function reorderStaticCallArguments(ParametersAcceptor $parametersAcceptor, StaticCall $staticCall) : ?StaticCall { $reorderedArgs = self::reorderArgs($parametersAcceptor, $staticCall->getArgs()); if ($reorderedArgs === null) { return null; } return new StaticCall($staticCall->class, $staticCall->name, $reorderedArgs, $staticCall->getAttributes()); } public static function reorderNewArguments(ParametersAcceptor $parametersAcceptor, New_ $new) : ?New_ { $reorderedArgs = self::reorderArgs($parametersAcceptor, $new->getArgs()); if ($reorderedArgs === null) { return null; } return new New_($new->class, $reorderedArgs, $new->getAttributes()); } /** * @param Arg[] $callArgs * @return ?array */ public static function reorderArgs(ParametersAcceptor $parametersAcceptor, array $callArgs) : ?array { if (count($callArgs) === 0) { return []; } $signatureParameters = $parametersAcceptor->getParameters(); $hasNamedArgs = \false; foreach ($callArgs as $arg) { if ($arg->name !== null) { $hasNamedArgs = \true; break; } } if (!$hasNamedArgs) { return $callArgs; } $hasVariadic = \false; $argumentPositions = []; foreach ($signatureParameters as $i => $parameter) { if ($hasVariadic) { // variadic parameter must be last return null; } $hasVariadic = $parameter->isVariadic(); $argumentPositions[$parameter->getName()] = $i; } $reorderedArgs = []; $additionalNamedArgs = []; $appendArgs = []; foreach ($callArgs as $i => $arg) { if ($arg->name === null) { // add regular args as is $reorderedArgs[$i] = $arg; } elseif (array_key_exists($arg->name->toString(), $argumentPositions)) { $argName = $arg->name->toString(); // order named args into the position the signature expects them $attributes = $arg->getAttributes(); $attributes[self::ORIGINAL_ARG_ATTRIBUTE] = $arg; $reorderedArgs[$argumentPositions[$argName]] = new Arg($arg->value, $arg->byRef, $arg->unpack, $attributes, null); } else { if (!$hasVariadic) { $attributes = $arg->getAttributes(); $attributes[self::ORIGINAL_ARG_ATTRIBUTE] = $arg; $appendArgs[] = new Arg($arg->value, $arg->byRef, $arg->unpack, $attributes, null); continue; } $attributes = $arg->getAttributes(); $attributes[self::ORIGINAL_ARG_ATTRIBUTE] = $arg; $additionalNamedArgs[] = new Arg($arg->value, $arg->byRef, $arg->unpack, $attributes, null); } } // replace variadic parameter with additional named args, except if it is already set $additionalNamedArgsOffset = count($argumentPositions) - 1; if (array_key_exists($additionalNamedArgsOffset, $reorderedArgs)) { $additionalNamedArgsOffset++; } foreach ($additionalNamedArgs as $i => $additionalNamedArg) { $reorderedArgs[$additionalNamedArgsOffset + $i] = $additionalNamedArg; } if (count($reorderedArgs) === 0) { foreach ($appendArgs as $arg) { $reorderedArgs[] = $arg; } return $reorderedArgs; } // fill up all holes with default values until the last given argument for ($j = 0; $j < max(array_keys($reorderedArgs)); $j++) { if (array_key_exists($j, $reorderedArgs)) { continue; } if (!array_key_exists($j, $signatureParameters)) { throw new ShouldNotHappenException('Parameter signatures cannot have holes'); } $parameter = $signatureParameters[$j]; // we can only fill up optional parameters with default values if (!$parameter->isOptional()) { return null; } $defaultValue = $parameter->getDefaultValue(); if ($defaultValue === null) { if (!$parameter->isVariadic()) { throw new ShouldNotHappenException('An optional parameter must have a default value'); } $defaultValue = new ConstantArrayType([], []); } $reorderedArgs[$j] = new Arg(new TypeExpr($defaultValue)); } ksort($reorderedArgs); foreach ($appendArgs as $arg) { $reorderedArgs[] = $arg; } return $reorderedArgs; } } scope = $scope; $this->hasYield = $hasYield; $this->isAlwaysTerminating = $isAlwaysTerminating; $this->exitPoints = $exitPoints; $this->throwPoints = $throwPoints; $this->impurePoints = $impurePoints; $this->endStatements = $endStatements; } public function getScope() : \PHPStan\Analyser\MutatingScope { return $this->scope; } public function hasYield() : bool { return $this->hasYield; } public function isAlwaysTerminating() : bool { return $this->isAlwaysTerminating; } public function filterOutLoopExitPoints() : self { if (!$this->isAlwaysTerminating) { return $this; } foreach ($this->exitPoints as $exitPoint) { $statement = $exitPoint->getStatement(); if (!$statement instanceof Stmt\Break_ && !$statement instanceof Stmt\Continue_) { continue; } $num = $statement->num; if (!$num instanceof LNumber) { return new self($this->scope, $this->hasYield, \false, $this->exitPoints, $this->throwPoints, $this->impurePoints); } if ($num->value !== 1) { continue; } return new self($this->scope, $this->hasYield, \false, $this->exitPoints, $this->throwPoints, $this->impurePoints); } return $this; } /** * @return StatementExitPoint[] */ public function getExitPoints() : array { return $this->exitPoints; } /** * @param class-string|class-string $stmtClass * @return StatementExitPoint[] */ public function getExitPointsByType(string $stmtClass) : array { $exitPoints = []; foreach ($this->exitPoints as $exitPoint) { $statement = $exitPoint->getStatement(); if (!$statement instanceof $stmtClass) { continue; } $value = $statement->num; if ($value === null) { $exitPoints[] = $exitPoint; continue; } if (!$value instanceof LNumber) { $exitPoints[] = $exitPoint; continue; } $value = $value->value; if ($value !== 1) { continue; } $exitPoints[] = $exitPoint; } return $exitPoints; } /** * @return StatementExitPoint[] */ public function getExitPointsForOuterLoop() : array { $exitPoints = []; foreach ($this->exitPoints as $exitPoint) { $statement = $exitPoint->getStatement(); if (!$statement instanceof Stmt\Continue_ && !$statement instanceof Stmt\Break_) { $exitPoints[] = $exitPoint; continue; } if ($statement->num === null) { continue; } if (!$statement->num instanceof LNumber) { continue; } $value = $statement->num->value; if ($value === 1) { continue; } $newNode = null; if ($value > 2) { $newNode = new LNumber($value - 1); } if ($statement instanceof Stmt\Continue_) { $newStatement = new Stmt\Continue_($newNode); } else { $newStatement = new Stmt\Break_($newNode); } $exitPoints[] = new \PHPStan\Analyser\StatementExitPoint($newStatement, $exitPoint->getScope()); } return $exitPoints; } /** * @return ThrowPoint[] */ public function getThrowPoints() : array { return $this->throwPoints; } /** * @return ImpurePoint[] */ public function getImpurePoints() : array { return $this->impurePoints; } /** * Top-level StatementResult represents the state of the code * at the end of control flow statements like If_ or TryCatch. * * It shows how Scope etc. looks like after If_ no matter * which code branch was executed. * * For If_, "end statements" contain the state of the code * at the end of each branch - if, elseifs, else, including the last * statement node in each branch. * * For nested ifs, end statements try to contain the last non-control flow * statement like Return_ or Throw_, instead of If_, TryCatch, or Foreach_. * * @return EndStatementResult[] */ public function getEndStatements() : array { return $this->endStatements; } } */ private $collectorErrors; /** * @var list */ private $locallyIgnoredCollectorErrors; /** * @param list $collectorErrors * @param list $locallyIgnoredCollectorErrors */ public function __construct(\PHPStan\Analyser\AnalyserResult $analyserResult, array $collectorErrors, array $locallyIgnoredCollectorErrors) { $this->analyserResult = $analyserResult; $this->collectorErrors = $collectorErrors; $this->locallyIgnoredCollectorErrors = $locallyIgnoredCollectorErrors; } /** * @return list */ public function getErrors() : array { return $this->analyserResult->getErrors(); } public function getAnalyserResult() : \PHPStan\Analyser\AnalyserResult { return $this->analyserResult; } /** * @return list */ public function getCollectorErrors() : array { return $this->collectorErrors; } /** * @return list */ public function getLocallyIgnoredCollectorErrors() : array { return $this->locallyIgnoredCollectorErrors; } } scope = $scope; $this->node = $node; $this->identifier = $identifier; $this->description = $description; $this->certain = $certain; } public function getScope() : \PHPStan\Analyser\Scope { return $this->scope; } /** * @return Node\Expr|Node\Stmt|VirtualNode */ public function getNode() { return $this->node; } /** * @return ImpurePointIdentifier */ public function getIdentifier() : string { return $this->identifier; } public function getDescription() : string { return $this->description; } public function isCertain() : bool { return $this->certain; } } isPublic(); } public function canCallMethod(MethodReflection $methodReflection) : bool { return $methodReflection->isPublic(); } public function canAccessConstant(ConstantReflection $constantReflection) : bool { return $constantReflection->isPublic(); } } getTraitReflection() */ public function isInTrait() : bool; public function getTraitReflection() : ?ClassReflection; public function getFunction() : ?PhpFunctionFromParserNodeReflection; public function getFunctionName() : ?string; public function getParentScope() : ?self; public function hasVariableType(string $variableName) : TrinaryLogic; public function getVariableType(string $variableName) : Type; public function canAnyVariableExist() : bool; /** * @return array */ public function getDefinedVariables() : array; /** * @return array */ public function getMaybeDefinedVariables() : array; public function hasConstant(Name $name) : bool; public function getPropertyReflection(Type $typeWithProperty, string $propertyName) : ?ExtendedPropertyReflection; public function getMethodReflection(Type $typeWithMethod, string $methodName) : ?ExtendedMethodReflection; public function getConstantReflection(Type $typeWithConstant, string $constantName) : ?ConstantReflection; public function getIterableKeyType(Type $iteratee) : Type; public function getIterableValueType(Type $iteratee) : Type; public function isInAnonymousFunction() : bool; public function getAnonymousFunctionReflection() : ?ParametersAcceptor; public function getAnonymousFunctionReturnType() : ?Type; public function getType(Expr $node) : Type; public function getNativeType(Expr $expr) : Type; public function getKeepVoidType(Expr $node) : Type; /** * @deprecated Use getNativeType() */ public function doNotTreatPhpDocTypesAsCertain() : self; public function resolveName(Name $name) : string; public function resolveTypeByName(Name $name) : TypeWithClassName; /** * @param mixed $value */ public function getTypeFromValue($value) : Type; /** @deprecated use hasExpressionType instead */ public function isSpecified(Expr $node) : bool; public function hasExpressionType(Expr $node) : TrinaryLogic; public function isInClassExists(string $className) : bool; public function isInFunctionExists(string $functionName) : bool; public function isInClosureBind() : bool; /** @return list */ public function getFunctionCallStack() : array; /** @return list */ public function getFunctionCallStackWithParameters() : array; public function isParameterValueNullable(Param $parameter) : bool; /** * @param Node\Name|Node\Identifier|Node\ComplexType|null $type */ public function getFunctionType($type, bool $isNullable, bool $isVariadic) : Type; public function isInExpressionAssign(Expr $expr) : bool; public function isUndefinedExpressionAllowed(Expr $expr) : bool; public function filterByTruthyValue(Expr $expr) : self; public function filterByFalseyValue(Expr $expr) : self; public function isInFirstLevelStatement() : bool; } */ private $sureTypes; /** * @var array */ private $sureNotTypes; /** * @var bool */ private $overwrite; /** * @var array */ private $newConditionalExpressionHolders; /** * @var ?Expr */ private $rootExpr; /** * @api * @param array $sureTypes * @param array $sureNotTypes * @param array $newConditionalExpressionHolders */ public function __construct(array $sureTypes = [], array $sureNotTypes = [], bool $overwrite = \false, array $newConditionalExpressionHolders = [], ?Expr $rootExpr = null) { $this->sureTypes = $sureTypes; $this->sureNotTypes = $sureNotTypes; $this->overwrite = $overwrite; $this->newConditionalExpressionHolders = $newConditionalExpressionHolders; $this->rootExpr = $rootExpr; } /** * @api * @return array */ public function getSureTypes() : array { return $this->sureTypes; } /** * @api * @return array */ public function getSureNotTypes() : array { return $this->sureNotTypes; } public function shouldOverwrite() : bool { return $this->overwrite; } /** * @return array */ public function getNewConditionalExpressionHolders() : array { return $this->newConditionalExpressionHolders; } public function getRootExpr() : ?Expr { return $this->rootExpr; } /** @api */ public function intersectWith(\PHPStan\Analyser\SpecifiedTypes $other) : self { $sureTypeUnion = []; $sureNotTypeUnion = []; $rootExpr = $this->mergeRootExpr($this->rootExpr, $other->rootExpr); foreach ($this->sureTypes as $exprString => [$exprNode, $type]) { if (!isset($other->sureTypes[$exprString])) { continue; } $sureTypeUnion[$exprString] = [$exprNode, TypeCombinator::union($type, $other->sureTypes[$exprString][1])]; } foreach ($this->sureNotTypes as $exprString => [$exprNode, $type]) { if (!isset($other->sureNotTypes[$exprString])) { continue; } $sureNotTypeUnion[$exprString] = [$exprNode, TypeCombinator::intersect($type, $other->sureNotTypes[$exprString][1])]; } return new self($sureTypeUnion, $sureNotTypeUnion, $this->overwrite && $other->overwrite, [], $rootExpr); } /** @api */ public function unionWith(\PHPStan\Analyser\SpecifiedTypes $other) : self { $sureTypeUnion = $this->sureTypes + $other->sureTypes; $sureNotTypeUnion = $this->sureNotTypes + $other->sureNotTypes; $rootExpr = $this->mergeRootExpr($this->rootExpr, $other->rootExpr); foreach ($this->sureTypes as $exprString => [$exprNode, $type]) { if (!isset($other->sureTypes[$exprString])) { continue; } $sureTypeUnion[$exprString] = [$exprNode, TypeCombinator::intersect($type, $other->sureTypes[$exprString][1])]; } foreach ($this->sureNotTypes as $exprString => [$exprNode, $type]) { if (!isset($other->sureNotTypes[$exprString])) { continue; } $sureNotTypeUnion[$exprString] = [$exprNode, TypeCombinator::union($type, $other->sureNotTypes[$exprString][1])]; } return new self($sureTypeUnion, $sureNotTypeUnion, $this->overwrite || $other->overwrite, [], $rootExpr); } public function normalize(\PHPStan\Analyser\Scope $scope) : self { $sureTypes = $this->sureTypes; foreach ($this->sureNotTypes as $exprString => [$exprNode, $sureNotType]) { if (!isset($sureTypes[$exprString])) { $sureTypes[$exprString] = [$exprNode, TypeCombinator::remove($scope->getType($exprNode), $sureNotType)]; continue; } $sureTypes[$exprString][1] = TypeCombinator::remove($sureTypes[$exprString][1], $sureNotType); } return new self($sureTypes, [], $this->overwrite, $this->newConditionalExpressionHolders, $this->rootExpr); } private function mergeRootExpr(?Expr $rootExprA, ?Expr $rootExprB) : ?Expr { if ($rootExprA === $rootExprB) { return $rootExprA; } if ($rootExprA === null || $rootExprB === null) { return $rootExprA ?? $rootExprB; } return null; } } */ private $expressionTypes; /** * @var array */ private $nativeExpressionTypes; /** * @var array */ private $conditionalExpressions; /** * @var list */ private $inClosureBindScopeClasses; /** * @var ?ParametersAcceptor */ private $anonymousFunctionReflection; /** * @var bool */ private $inFirstLevelStatement; /** * @var array */ private $currentlyAssignedExpressions; /** * @var array */ private $currentlyAllowedUndefinedExpressions; /** * @var list */ private $inFunctionCallsStack; /** * @var bool */ private $afterExtractCall; /** * @var ?Scope */ private $parentScope; /** * @var bool */ private $nativeTypesPromoted; /** * @var bool */ private $explicitMixedInUnknownGenericNew; /** * @var bool */ private $explicitMixedForGlobalVariables; private const BOOLEAN_EXPRESSION_MAX_PROCESS_DEPTH = 4; private const KEEP_VOID_ATTRIBUTE_NAME = 'keepVoid'; /** @var Type[] */ private $resolvedTypes = []; /** @var array */ private $truthyScopes = []; /** @var array */ private $falseyScopes = []; /** @var non-empty-string|null */ private $namespace; /** * @var ?self */ private $scopeOutOfFirstLevelStatement = null; /** * @var ?self */ private $scopeWithPromotedNativeTypes = null; /** * @var int */ private static $resolveClosureTypeDepth = 0; /** * @param array $expressionTypes * @param array $conditionalExpressions * @param list $inClosureBindScopeClasses * @param array $currentlyAssignedExpressions * @param array $currentlyAllowedUndefinedExpressions * @param array $nativeExpressionTypes * @param list $inFunctionCallsStack * @param PhpFunctionFromParserNodeReflection|null $function */ public function __construct(\PHPStan\Analyser\InternalScopeFactory $scopeFactory, ReflectionProvider $reflectionProvider, InitializerExprTypeResolver $initializerExprTypeResolver, DynamicReturnTypeExtensionRegistry $dynamicReturnTypeExtensionRegistry, ExpressionTypeResolverExtensionRegistry $expressionTypeResolverExtensionRegistry, ExprPrinter $exprPrinter, \PHPStan\Analyser\TypeSpecifier $typeSpecifier, PropertyReflectionFinder $propertyReflectionFinder, Parser $parser, \PHPStan\Analyser\NodeScopeResolver $nodeScopeResolver, \PHPStan\Analyser\RicherScopeGetTypeHelper $richerScopeGetTypeHelper, \PHPStan\Analyser\ConstantResolver $constantResolver, \PHPStan\Analyser\ScopeContext $context, PhpVersion $phpVersion, bool $declareStrictTypes = \false, $function = null, ?string $namespace = null, array $expressionTypes = [], array $nativeExpressionTypes = [], array $conditionalExpressions = [], array $inClosureBindScopeClasses = [], ?ParametersAcceptor $anonymousFunctionReflection = null, bool $inFirstLevelStatement = \true, array $currentlyAssignedExpressions = [], array $currentlyAllowedUndefinedExpressions = [], array $inFunctionCallsStack = [], bool $afterExtractCall = \false, ?\PHPStan\Analyser\Scope $parentScope = null, bool $nativeTypesPromoted = \false, bool $explicitMixedInUnknownGenericNew = \false, bool $explicitMixedForGlobalVariables = \false) { $this->scopeFactory = $scopeFactory; $this->reflectionProvider = $reflectionProvider; $this->initializerExprTypeResolver = $initializerExprTypeResolver; $this->dynamicReturnTypeExtensionRegistry = $dynamicReturnTypeExtensionRegistry; $this->expressionTypeResolverExtensionRegistry = $expressionTypeResolverExtensionRegistry; $this->exprPrinter = $exprPrinter; $this->typeSpecifier = $typeSpecifier; $this->propertyReflectionFinder = $propertyReflectionFinder; $this->parser = $parser; $this->nodeScopeResolver = $nodeScopeResolver; $this->richerScopeGetTypeHelper = $richerScopeGetTypeHelper; $this->constantResolver = $constantResolver; $this->context = $context; $this->phpVersion = $phpVersion; $this->declareStrictTypes = $declareStrictTypes; $this->function = $function; $this->expressionTypes = $expressionTypes; $this->nativeExpressionTypes = $nativeExpressionTypes; $this->conditionalExpressions = $conditionalExpressions; $this->inClosureBindScopeClasses = $inClosureBindScopeClasses; $this->anonymousFunctionReflection = $anonymousFunctionReflection; $this->inFirstLevelStatement = $inFirstLevelStatement; $this->currentlyAssignedExpressions = $currentlyAssignedExpressions; $this->currentlyAllowedUndefinedExpressions = $currentlyAllowedUndefinedExpressions; $this->inFunctionCallsStack = $inFunctionCallsStack; $this->afterExtractCall = $afterExtractCall; $this->parentScope = $parentScope; $this->nativeTypesPromoted = $nativeTypesPromoted; $this->explicitMixedInUnknownGenericNew = $explicitMixedInUnknownGenericNew; $this->explicitMixedForGlobalVariables = $explicitMixedForGlobalVariables; if ($namespace === '') { $namespace = null; } $this->namespace = $namespace; } /** @api */ public function getFile() : string { return $this->context->getFile(); } /** @api */ public function getFileDescription() : string { if ($this->context->getTraitReflection() === null) { return $this->getFile(); } /** @var ClassReflection $classReflection */ $classReflection = $this->context->getClassReflection(); $className = $classReflection->getDisplayName(); if (!$classReflection->isAnonymous()) { $className = sprintf('class %s', $className); } $traitReflection = $this->context->getTraitReflection(); if ($traitReflection->getFileName() === null) { throw new ShouldNotHappenException(); } return sprintf('%s (in context of %s)', $traitReflection->getFileName(), $className); } /** @api */ public function isDeclareStrictTypes() : bool { return $this->declareStrictTypes; } public function enterDeclareStrictTypes() : self { return $this->scopeFactory->create($this->context, \true, null, null, $this->expressionTypes, $this->nativeExpressionTypes); } /** @api */ public function isInClass() : bool { return $this->context->getClassReflection() !== null; } /** @api */ public function isInTrait() : bool { return $this->context->getTraitReflection() !== null; } /** @api */ public function getClassReflection() : ?ClassReflection { return $this->context->getClassReflection(); } /** @api */ public function getTraitReflection() : ?ClassReflection { return $this->context->getTraitReflection(); } /** * @api */ public function getFunction() : ?PhpFunctionFromParserNodeReflection { return $this->function; } /** @api */ public function getFunctionName() : ?string { return $this->function !== null ? $this->function->getName() : null; } /** @api */ public function getNamespace() : ?string { return $this->namespace; } /** @api */ public function getParentScope() : ?\PHPStan\Analyser\Scope { return $this->parentScope; } /** @api */ public function canAnyVariableExist() : bool { return $this->function === null && !$this->isInAnonymousFunction() || $this->afterExtractCall; } public function afterExtractCall() : self { return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $this->expressionTypes, $this->nativeExpressionTypes, [], $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->isInFirstLevelStatement(), $this->currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, $this->inFunctionCallsStack, \true, $this->parentScope, $this->nativeTypesPromoted); } public function afterClearstatcacheCall() : self { $expressionTypes = $this->expressionTypes; foreach (array_keys($expressionTypes) as $exprString) { // list from https://www.php.net/manual/en/function.clearstatcache.php // stat(), lstat(), file_exists(), is_writable(), is_readable(), is_executable(), is_file(), is_dir(), is_link(), filectime(), fileatime(), filemtime(), fileinode(), filegroup(), fileowner(), filesize(), filetype(), and fileperms(). foreach (['stat', 'lstat', 'file_exists', 'is_writable', 'is_writeable', 'is_readable', 'is_executable', 'is_file', 'is_dir', 'is_link', 'filectime', 'fileatime', 'filemtime', 'fileinode', 'filegroup', 'fileowner', 'filesize', 'filetype', 'fileperms'] as $functionName) { if (!str_starts_with($exprString, $functionName . '(') && !str_starts_with($exprString, '\\' . $functionName . '(')) { continue; } unset($expressionTypes[$exprString]); continue 2; } } return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $expressionTypes, $this->nativeExpressionTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->isInFirstLevelStatement(), $this->currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, $this->inFunctionCallsStack, $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } public function afterOpenSslCall(string $openSslFunctionName) : self { $expressionTypes = $this->expressionTypes; if (in_array($openSslFunctionName, ['openssl_cipher_iv_length', 'openssl_cms_decrypt', 'openssl_cms_encrypt', 'openssl_cms_read', 'openssl_cms_sign', 'openssl_cms_verify', 'openssl_csr_export_to_file', 'openssl_csr_export', 'openssl_csr_get_public_key', 'openssl_csr_get_subject', 'openssl_csr_new', 'openssl_csr_sign', 'openssl_decrypt', 'openssl_dh_compute_key', 'openssl_digest', 'openssl_encrypt', 'openssl_get_curve_names', 'openssl_get_privatekey', 'openssl_get_publickey', 'openssl_open', 'openssl_pbkdf2', 'openssl_pkcs12_export_to_file', 'openssl_pkcs12_export', 'openssl_pkcs12_read', 'openssl_pkcs7_decrypt', 'openssl_pkcs7_encrypt', 'openssl_pkcs7_read', 'openssl_pkcs7_sign', 'openssl_pkcs7_verify', 'openssl_pkey_derive', 'openssl_pkey_export_to_file', 'openssl_pkey_export', 'openssl_pkey_get_private', 'openssl_pkey_get_public', 'openssl_pkey_new', 'openssl_private_decrypt', 'openssl_private_encrypt', 'openssl_public_decrypt', 'openssl_public_encrypt', 'openssl_random_pseudo_bytes', 'openssl_seal', 'openssl_sign', 'openssl_spki_export_challenge', 'openssl_spki_export', 'openssl_spki_new', 'openssl_spki_verify', 'openssl_verify', 'openssl_x509_checkpurpose', 'openssl_x509_export_to_file', 'openssl_x509_export', 'openssl_x509_fingerprint', 'openssl_x509_read', 'openssl_x509_verify'], \true)) { unset($expressionTypes['\\openssl_error_string()']); } return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $expressionTypes, $this->nativeExpressionTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->isInFirstLevelStatement(), $this->currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, $this->inFunctionCallsStack, $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } /** @api */ public function hasVariableType(string $variableName) : TrinaryLogic { if ($this->isGlobalVariable($variableName)) { return TrinaryLogic::createYes(); } $varExprString = '$' . $variableName; if (!isset($this->expressionTypes[$varExprString])) { if ($this->canAnyVariableExist()) { return TrinaryLogic::createMaybe(); } return TrinaryLogic::createNo(); } return $this->expressionTypes[$varExprString]->getCertainty(); } /** @api */ public function getVariableType(string $variableName) : Type { if ($this->hasVariableType($variableName)->maybe()) { if ($variableName === 'argc') { return IntegerRangeType::fromInterval(1, null); } if ($variableName === 'argv') { return AccessoryArrayListType::intersectWith(TypeCombinator::intersect(new ArrayType(new IntegerType(), new StringType()), new NonEmptyArrayType())); } if ($this->canAnyVariableExist()) { return new MixedType(); } } if ($this->isGlobalVariable($variableName)) { return new ArrayType(new BenevolentUnionType([new IntegerType(), new StringType()]), new MixedType($this->explicitMixedForGlobalVariables)); } if ($this->hasVariableType($variableName)->no()) { throw new \PHPStan\Analyser\UndefinedVariableException($this, $variableName); } $varExprString = '$' . $variableName; if (!array_key_exists($varExprString, $this->expressionTypes)) { return new MixedType(); } return TypeUtils::resolveLateResolvableTypes($this->expressionTypes[$varExprString]->getType()); } /** * @api * @return array */ public function getDefinedVariables() : array { $variables = []; foreach ($this->expressionTypes as $exprString => $holder) { if (!$holder->getExpr() instanceof Variable) { continue; } if (!$holder->getCertainty()->yes()) { continue; } $variables[] = substr($exprString, 1); } return $variables; } /** * @api * @return array */ public function getMaybeDefinedVariables() : array { $variables = []; foreach ($this->expressionTypes as $exprString => $holder) { if (!$holder->getExpr() instanceof Variable) { continue; } if (!$holder->getCertainty()->maybe()) { continue; } $variables[] = substr($exprString, 1); } return $variables; } private function isGlobalVariable(string $variableName) : bool { return in_array($variableName, self::SUPERGLOBAL_VARIABLES, \true); } /** @api */ public function hasConstant(Name $name) : bool { $isCompilerHaltOffset = $name->toString() === '__COMPILER_HALT_OFFSET__'; if ($isCompilerHaltOffset) { return $this->fileHasCompilerHaltStatementCalls(); } if (!$name->isFullyQualified() && $this->getNamespace() !== null) { if ($this->hasExpressionType(new ConstFetch(new FullyQualified([$this->getNamespace(), $name->toString()])))->yes()) { return \true; } } if ($this->hasExpressionType(new ConstFetch(new FullyQualified($name->toString())))->yes()) { return \true; } return $this->reflectionProvider->hasConstant($name, $this); } private function fileHasCompilerHaltStatementCalls() : bool { $nodes = $this->parser->parseFile($this->getFile()); foreach ($nodes as $node) { if ($node instanceof Node\Stmt\HaltCompiler) { return \true; } } return \false; } /** @api */ public function isInAnonymousFunction() : bool { return $this->anonymousFunctionReflection !== null; } /** @api */ public function getAnonymousFunctionReflection() : ?ParametersAcceptor { return $this->anonymousFunctionReflection; } /** @api */ public function getAnonymousFunctionReturnType() : ?Type { if ($this->anonymousFunctionReflection === null) { return null; } return $this->anonymousFunctionReflection->getReturnType(); } /** @api */ public function getType(Expr $node) : Type { if ($node instanceof GetIterableKeyTypeExpr) { return $this->getIterableKeyType($this->getType($node->getExpr())); } if ($node instanceof GetIterableValueTypeExpr) { return $this->getIterableValueType($this->getType($node->getExpr())); } if ($node instanceof GetOffsetValueTypeExpr) { return $this->getType($node->getVar())->getOffsetValueType($this->getType($node->getDim())); } if ($node instanceof ExistingArrayDimFetch) { return $this->getType(new Expr\ArrayDimFetch($node->getVar(), $node->getDim())); } if ($node instanceof UnsetOffsetExpr) { return $this->getType($node->getVar())->unsetOffset($this->getType($node->getDim())); } if ($node instanceof SetOffsetValueTypeExpr) { return $this->getType($node->getVar())->setOffsetValueType($node->getDim() !== null ? $this->getType($node->getDim()) : null, $this->getType($node->getValue())); } if ($node instanceof SetExistingOffsetValueTypeExpr) { return $this->getType($node->getVar())->setExistingOffsetValueType($this->getType($node->getDim()), $this->getType($node->getValue())); } if ($node instanceof TypeExpr) { return $node->getExprType(); } if ($node instanceof OriginalPropertyTypeExpr) { $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node->getPropertyFetch(), $this); if ($propertyReflection === null) { return new ErrorType(); } return $propertyReflection->getReadableType(); } $key = $this->getNodeKey($node); if (!array_key_exists($key, $this->resolvedTypes)) { $this->resolvedTypes[$key] = TypeUtils::resolveLateResolvableTypes($this->resolveType($key, $node)); } return $this->resolvedTypes[$key]; } private function getNodeKey(Expr $node) : string { $key = $this->exprPrinter->printExpr($node); $attributes = $node->getAttributes(); if ($node instanceof Node\FunctionLike && ($attributes[ArrayMapArgVisitor::ATTRIBUTE_NAME] ?? null) !== null && ($attributes['startFilePos'] ?? null) !== null) { $key .= '/*' . $attributes['startFilePos'] . '*/'; } if (($attributes[self::KEEP_VOID_ATTRIBUTE_NAME] ?? null) === \true) { $key .= '/*' . self::KEEP_VOID_ATTRIBUTE_NAME . '*/'; } return $key; } private function getClosureScopeCacheKey() : string { $parts = []; foreach ($this->expressionTypes as $exprString => $expressionTypeHolder) { $parts[] = sprintf('%s::%s', $exprString, $expressionTypeHolder->getType()->describe(VerbosityLevel::cache())); } $parts[] = '---'; foreach ($this->nativeExpressionTypes as $exprString => $expressionTypeHolder) { $parts[] = sprintf('%s::%s', $exprString, $expressionTypeHolder->getType()->describe(VerbosityLevel::cache())); } $parts[] = sprintf(':%d', count($this->inFunctionCallsStack)); foreach ($this->inFunctionCallsStack as [$method, $parameter]) { if ($parameter === null) { $parts[] = ',null'; continue; } $parts[] = sprintf(',%s', $parameter->getType()->describe(VerbosityLevel::cache())); } return md5(implode("\n", $parts)); } private function resolveType(string $exprString, Expr $node) : Type { foreach ($this->expressionTypeResolverExtensionRegistry->getExtensions() as $extension) { $type = $extension->getType($node, $this); if ($type !== null) { return $type; } } if ($node instanceof Expr\Exit_ || $node instanceof Expr\Throw_) { return new NonAcceptingNeverType(); } if (!$node instanceof Variable && $this->hasExpressionType($node)->yes()) { return $this->expressionTypes[$exprString]->getType(); } if ($node instanceof AlwaysRememberedExpr) { return $node->getExprType(); } if ($node instanceof Expr\BinaryOp\Smaller) { return $this->getType($node->left)->isSmallerThan($this->getType($node->right))->toBooleanType(); } if ($node instanceof Expr\BinaryOp\SmallerOrEqual) { return $this->getType($node->left)->isSmallerThanOrEqual($this->getType($node->right))->toBooleanType(); } if ($node instanceof Expr\BinaryOp\Greater) { return $this->getType($node->right)->isSmallerThan($this->getType($node->left))->toBooleanType(); } if ($node instanceof Expr\BinaryOp\GreaterOrEqual) { return $this->getType($node->right)->isSmallerThanOrEqual($this->getType($node->left))->toBooleanType(); } if ($node instanceof Expr\BinaryOp\Equal) { if ($node->left instanceof Variable && is_string($node->left->name) && $node->right instanceof Variable && is_string($node->right->name) && $node->left->name === $node->right->name) { return new ConstantBooleanType(\true); } $leftType = $this->getType($node->left); $rightType = $this->getType($node->right); return $this->initializerExprTypeResolver->resolveEqualType($leftType, $rightType)->type; } if ($node instanceof Expr\BinaryOp\NotEqual) { return $this->getType(new Expr\BooleanNot(new BinaryOp\Equal($node->left, $node->right))); } if ($node instanceof Expr\Empty_) { $result = $this->issetCheck($node->expr, static function (Type $type) : ?bool { $isNull = $type->isNull(); $isFalsey = $type->toBoolean()->isFalse(); if ($isNull->maybe()) { return null; } if ($isFalsey->maybe()) { return null; } if ($isNull->yes()) { return $isFalsey->no(); } return !$isFalsey->yes(); }); if ($result === null) { return new BooleanType(); } return new ConstantBooleanType(!$result); } if ($node instanceof Node\Expr\BooleanNot) { $exprBooleanType = $this->getType($node->expr)->toBoolean(); if ($exprBooleanType instanceof ConstantBooleanType) { return new ConstantBooleanType(!$exprBooleanType->getValue()); } return new BooleanType(); } if ($node instanceof Node\Expr\BitwiseNot) { return $this->initializerExprTypeResolver->getBitwiseNotType($node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Node\Expr\BinaryOp\BooleanAnd || $node instanceof Node\Expr\BinaryOp\LogicalAnd) { $leftBooleanType = $this->getType($node->left)->toBoolean(); if ($leftBooleanType->isFalse()->yes()) { return new ConstantBooleanType(\false); } if ($this->getBooleanExpressionDepth($node->left) <= self::BOOLEAN_EXPRESSION_MAX_PROCESS_DEPTH) { $noopCallback = static function () : void { }; $leftResult = $this->nodeScopeResolver->processExprNode(new Node\Stmt\Expression($node->left), $node->left, $this, $noopCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $rightBooleanType = $leftResult->getTruthyScope()->getType($node->right)->toBoolean(); } else { $rightBooleanType = $this->filterByTruthyValue($node->left)->getType($node->right)->toBoolean(); } if ($rightBooleanType->isFalse()->yes()) { return new ConstantBooleanType(\false); } if ($leftBooleanType->isTrue()->yes() && $rightBooleanType->isTrue()->yes()) { return new ConstantBooleanType(\true); } return new BooleanType(); } if ($node instanceof Node\Expr\BinaryOp\BooleanOr || $node instanceof Node\Expr\BinaryOp\LogicalOr) { $leftBooleanType = $this->getType($node->left)->toBoolean(); if ($leftBooleanType->isTrue()->yes()) { return new ConstantBooleanType(\true); } if ($this->getBooleanExpressionDepth($node->left) <= self::BOOLEAN_EXPRESSION_MAX_PROCESS_DEPTH) { $noopCallback = static function () : void { }; $leftResult = $this->nodeScopeResolver->processExprNode(new Node\Stmt\Expression($node->left), $node->left, $this, $noopCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); $rightBooleanType = $leftResult->getFalseyScope()->getType($node->right)->toBoolean(); } else { $rightBooleanType = $this->filterByFalseyValue($node->left)->getType($node->right)->toBoolean(); } if ($rightBooleanType->isTrue()->yes()) { return new ConstantBooleanType(\true); } if ($leftBooleanType->isFalse()->yes() && $rightBooleanType->isFalse()->yes()) { return new ConstantBooleanType(\false); } return new BooleanType(); } if ($node instanceof Node\Expr\BinaryOp\LogicalXor) { $leftBooleanType = $this->getType($node->left)->toBoolean(); $rightBooleanType = $this->getType($node->right)->toBoolean(); if ($leftBooleanType instanceof ConstantBooleanType && $rightBooleanType instanceof ConstantBooleanType) { return new ConstantBooleanType($leftBooleanType->getValue() xor $rightBooleanType->getValue()); } return new BooleanType(); } if ($node instanceof Expr\BinaryOp\Identical) { return $this->richerScopeGetTypeHelper->getIdenticalResult($this, $node)->type; } if ($node instanceof Expr\BinaryOp\NotIdentical) { return $this->richerScopeGetTypeHelper->getNotIdenticalResult($this, $node)->type; } if ($node instanceof Expr\Instanceof_) { $expressionType = $this->getType($node->expr); if ($this->isInTrait() && TypeUtils::findThisType($expressionType) !== null) { return new BooleanType(); } if ($expressionType instanceof NeverType) { return new ConstantBooleanType(\false); } $uncertainty = \false; if ($node->class instanceof Node\Name) { $unresolvedClassName = $node->class->toString(); if (strtolower($unresolvedClassName) === 'static' && $this->isInClass()) { $classType = new StaticType($this->getClassReflection()); } else { $className = $this->resolveName($node->class); $classType = new ObjectType($className); } } else { $classType = $this->getType($node->class); $classType = TypeTraverser::map($classType, static function (Type $type, callable $traverse) use(&$uncertainty) : Type { if ($type instanceof UnionType || $type instanceof IntersectionType) { return $traverse($type); } if ($type->getObjectClassNames() !== []) { $uncertainty = \true; return $type; } if ($type instanceof GenericClassStringType) { $uncertainty = \true; return $type->getGenericType(); } if ($type instanceof ConstantStringType) { return new ObjectType($type->getValue()); } return new MixedType(); }); } if ($classType->isSuperTypeOf(new MixedType())->yes()) { return new BooleanType(); } $isSuperType = $classType->isSuperTypeOf($expressionType); if ($isSuperType->no()) { return new ConstantBooleanType(\false); } elseif ($isSuperType->yes() && !$uncertainty) { return new ConstantBooleanType(\true); } return new BooleanType(); } if ($node instanceof Node\Expr\UnaryPlus) { return $this->getType($node->expr)->toNumber(); } if ($node instanceof Expr\ErrorSuppress || $node instanceof Expr\Assign) { return $this->getType($node->expr); } if ($node instanceof Node\Expr\UnaryMinus) { return $this->initializerExprTypeResolver->getUnaryMinusType($node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\BinaryOp\Concat) { return $this->initializerExprTypeResolver->getConcatType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\AssignOp\Concat) { return $this->initializerExprTypeResolver->getConcatType($node->var, $node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof BinaryOp\BitwiseAnd) { return $this->initializerExprTypeResolver->getBitwiseAndType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\AssignOp\BitwiseAnd) { return $this->initializerExprTypeResolver->getBitwiseAndType($node->var, $node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof BinaryOp\BitwiseOr) { return $this->initializerExprTypeResolver->getBitwiseOrType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\AssignOp\BitwiseOr) { return $this->initializerExprTypeResolver->getBitwiseOrType($node->var, $node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof BinaryOp\BitwiseXor) { return $this->initializerExprTypeResolver->getBitwiseXorType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\AssignOp\BitwiseXor) { return $this->initializerExprTypeResolver->getBitwiseXorType($node->var, $node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\BinaryOp\Spaceship) { return $this->initializerExprTypeResolver->getSpaceshipType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof BinaryOp\Div) { return $this->initializerExprTypeResolver->getDivType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\AssignOp\Div) { return $this->initializerExprTypeResolver->getDivType($node->var, $node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof BinaryOp\Mod) { return $this->initializerExprTypeResolver->getModType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\AssignOp\Mod) { return $this->initializerExprTypeResolver->getModType($node->var, $node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof BinaryOp\Plus) { return $this->initializerExprTypeResolver->getPlusType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\AssignOp\Plus) { return $this->initializerExprTypeResolver->getPlusType($node->var, $node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof BinaryOp\Minus) { return $this->initializerExprTypeResolver->getMinusType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\AssignOp\Minus) { return $this->initializerExprTypeResolver->getMinusType($node->var, $node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof BinaryOp\Mul) { return $this->initializerExprTypeResolver->getMulType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\AssignOp\Mul) { return $this->initializerExprTypeResolver->getMulType($node->var, $node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof BinaryOp\Pow) { return $this->initializerExprTypeResolver->getPowType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\AssignOp\Pow) { return $this->initializerExprTypeResolver->getPowType($node->var, $node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof BinaryOp\ShiftLeft) { return $this->initializerExprTypeResolver->getShiftLeftType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\AssignOp\ShiftLeft) { return $this->initializerExprTypeResolver->getShiftLeftType($node->var, $node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof BinaryOp\ShiftRight) { return $this->initializerExprTypeResolver->getShiftRightType($node->left, $node->right, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\AssignOp\ShiftRight) { return $this->initializerExprTypeResolver->getShiftRightType($node->var, $node->expr, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\Clone_) { return $this->getType($node->expr); } if ($node instanceof LNumber) { return $this->initializerExprTypeResolver->getType($node, InitializerExprContext::fromScope($this)); } elseif ($node instanceof String_) { return $this->initializerExprTypeResolver->getType($node, InitializerExprContext::fromScope($this)); } elseif ($node instanceof Node\Scalar\Encapsed) { $resultType = null; foreach ($node->parts as $part) { $partType = $part instanceof EncapsedStringPart ? new ConstantStringType($part->value) : $this->getType($part)->toString(); if ($resultType === null) { $resultType = $partType; continue; } $resultType = $this->initializerExprTypeResolver->resolveConcatType($resultType, $partType); } return $resultType ?? new ConstantStringType(''); } elseif ($node instanceof DNumber) { return $this->initializerExprTypeResolver->getType($node, InitializerExprContext::fromScope($this)); } elseif ($node instanceof Expr\CallLike && $node->isFirstClassCallable()) { if ($node instanceof FuncCall) { if ($node->name instanceof Name) { if ($this->reflectionProvider->hasFunction($node->name, $this)) { $function = $this->reflectionProvider->getFunction($node->name, $this); return $this->createFirstClassCallable($function, $function->getVariants()); } return new ObjectType(Closure::class); } $callableType = $this->getType($node->name); if (!$callableType->isCallable()->yes()) { return new ObjectType(Closure::class); } return $this->createFirstClassCallable(null, $callableType->getCallableParametersAcceptors($this)); } if ($node instanceof MethodCall) { if (!$node->name instanceof Node\Identifier) { return new ObjectType(Closure::class); } $varType = $this->getType($node->var); $method = $this->getMethodReflection($varType, $node->name->toString()); if ($method === null) { return new ObjectType(Closure::class); } return $this->createFirstClassCallable($method, $method->getVariants()); } if ($node instanceof Expr\StaticCall) { if (!$node->class instanceof Name) { return new ObjectType(Closure::class); } if (!$node->name instanceof Node\Identifier) { return new ObjectType(Closure::class); } $classType = $this->resolveTypeByNameWithLateStaticBinding($node->class, $node->name); $methodName = $node->name->toString(); if (!$classType->hasMethod($methodName)->yes()) { return new ObjectType(Closure::class); } $method = $classType->getMethod($methodName, $this); return $this->createFirstClassCallable($method, $method->getVariants()); } if ($node instanceof New_) { return new ErrorType(); } throw new ShouldNotHappenException(); } elseif ($node instanceof Expr\Closure || $node instanceof Expr\ArrowFunction) { $parameters = []; $isVariadic = \false; $firstOptionalParameterIndex = null; foreach ($node->params as $i => $param) { $isOptionalCandidate = $param->default !== null || $param->variadic; if ($isOptionalCandidate) { if ($firstOptionalParameterIndex === null) { $firstOptionalParameterIndex = $i; } } else { $firstOptionalParameterIndex = null; } } foreach ($node->params as $i => $param) { if ($param->variadic) { $isVariadic = \true; } if (!$param->var instanceof Variable || !is_string($param->var->name)) { throw new ShouldNotHappenException(); } $parameters[] = new NativeParameterReflection($param->var->name, $firstOptionalParameterIndex !== null && $i >= $firstOptionalParameterIndex, $this->getFunctionType($param->type, $this->isParameterValueNullable($param), \false), $param->byRef ? PassedByReference::createCreatesNewVariable() : PassedByReference::createNo(), $param->variadic, $param->default !== null ? $this->getType($param->default) : null); } $callableParameters = null; $arrayMapArgs = $node->getAttribute(ArrayMapArgVisitor::ATTRIBUTE_NAME); if ($arrayMapArgs !== null) { $callableParameters = []; foreach ($arrayMapArgs as $funcCallArg) { $callableParameters[] = new DummyParameter('item', $this->getType($funcCallArg->value)->getIterableValueType(), \false, PassedByReference::createNo(), \false, null); } } else { $inFunctionCallsStackCount = count($this->inFunctionCallsStack); if ($inFunctionCallsStackCount > 0) { [, $inParameter] = $this->inFunctionCallsStack[$inFunctionCallsStackCount - 1]; if ($inParameter !== null) { $callableParameters = $this->nodeScopeResolver->createCallableParameters($this, $node, null, $inParameter->getType()); } } } if ($node instanceof Expr\ArrowFunction) { $arrowScope = $this->enterArrowFunctionWithoutReflection($node, $callableParameters); if ($node->expr instanceof Expr\Yield_ || $node->expr instanceof Expr\YieldFrom) { $yieldNode = $node->expr; if ($yieldNode instanceof Expr\Yield_) { if ($yieldNode->key === null) { $keyType = new IntegerType(); } else { $keyType = $arrowScope->getType($yieldNode->key); } if ($yieldNode->value === null) { $valueType = new NullType(); } else { $valueType = $arrowScope->getType($yieldNode->value); } } else { $yieldFromType = $arrowScope->getType($yieldNode->expr); $keyType = $arrowScope->getIterableKeyType($yieldFromType); $valueType = $arrowScope->getIterableValueType($yieldFromType); } $returnType = new GenericObjectType(Generator::class, [$keyType, $valueType, new MixedType(), new VoidType()]); } else { $returnType = $arrowScope->getKeepVoidType($node->expr); if ($node->returnType !== null) { $nativeReturnType = $this->getFunctionType($node->returnType, \false, \false); $returnType = self::intersectButNotNever($nativeReturnType, $returnType); } } $arrowFunctionImpurePoints = []; $invalidateExpressions = []; $arrowFunctionExprResult = $this->nodeScopeResolver->processExprNode(new Node\Stmt\Expression($node->expr), $node->expr, $arrowScope, static function (Node $node, \PHPStan\Analyser\Scope $scope) use($arrowScope, &$arrowFunctionImpurePoints, &$invalidateExpressions) : void { if ($scope->getAnonymousFunctionReflection() !== $arrowScope->getAnonymousFunctionReflection()) { return; } if ($node instanceof InvalidateExprNode) { $invalidateExpressions[] = $node; return; } if (!$node instanceof PropertyAssignNode) { return; } $arrowFunctionImpurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $node, 'propertyAssign', 'property assignment', \true); }, \PHPStan\Analyser\ExpressionContext::createDeep()); $throwPoints = $arrowFunctionExprResult->getThrowPoints(); $impurePoints = array_merge($arrowFunctionImpurePoints, $arrowFunctionExprResult->getImpurePoints()); $usedVariables = []; } else { $cachedTypes = $node->getAttribute('phpstanCachedTypes', []); $cacheKey = $this->getClosureScopeCacheKey(); if (array_key_exists($cacheKey, $cachedTypes)) { $cachedClosureData = $cachedTypes[$cacheKey]; return new ClosureType($parameters, $cachedClosureData['returnType'], $isVariadic, TemplateTypeMap::createEmpty(), TemplateTypeMap::createEmpty(), TemplateTypeVarianceMap::createEmpty(), [], $cachedClosureData['throwPoints'], $cachedClosureData['impurePoints'], $cachedClosureData['invalidateExpressions'], $cachedClosureData['usedVariables'], \true); } if (self::$resolveClosureTypeDepth >= 2) { return new ClosureType($parameters, $this->getFunctionType($node->returnType, \false, \false), $isVariadic); } self::$resolveClosureTypeDepth++; $closureScope = $this->enterAnonymousFunctionWithoutReflection($node, $callableParameters); $closureReturnStatements = []; $closureYieldStatements = []; $onlyNeverExecutionEnds = null; $closureImpurePoints = []; $invalidateExpressions = []; try { $closureStatementResult = $this->nodeScopeResolver->processStmtNodes($node, $node->stmts, $closureScope, static function (Node $node, \PHPStan\Analyser\Scope $scope) use($closureScope, &$closureReturnStatements, &$closureYieldStatements, &$onlyNeverExecutionEnds, &$closureImpurePoints, &$invalidateExpressions) : void { if ($scope->getAnonymousFunctionReflection() !== $closureScope->getAnonymousFunctionReflection()) { return; } if ($node instanceof InvalidateExprNode) { $invalidateExpressions[] = $node; return; } if ($node instanceof PropertyAssignNode) { $closureImpurePoints[] = new \PHPStan\Analyser\ImpurePoint($scope, $node, 'propertyAssign', 'property assignment', \true); return; } if ($node instanceof ExecutionEndNode) { if ($node->getStatementResult()->isAlwaysTerminating()) { foreach ($node->getStatementResult()->getExitPoints() as $exitPoint) { if ($exitPoint->getStatement() instanceof Node\Stmt\Return_) { $onlyNeverExecutionEnds = \false; continue; } if ($onlyNeverExecutionEnds === null) { $onlyNeverExecutionEnds = \true; } break; } if (count($node->getStatementResult()->getExitPoints()) === 0) { if ($onlyNeverExecutionEnds === null) { $onlyNeverExecutionEnds = \true; } } } else { $onlyNeverExecutionEnds = \false; } return; } if ($node instanceof Node\Stmt\Return_) { $closureReturnStatements[] = [$node, $scope]; } if (!$node instanceof Expr\Yield_ && !$node instanceof Expr\YieldFrom) { return; } $closureYieldStatements[] = [$node, $scope]; }, \PHPStan\Analyser\StatementContext::createTopLevel()); } finally { self::$resolveClosureTypeDepth--; } $throwPoints = $closureStatementResult->getThrowPoints(); $impurePoints = array_merge($closureImpurePoints, $closureStatementResult->getImpurePoints()); $returnTypes = []; $hasNull = \false; foreach ($closureReturnStatements as [$returnNode, $returnScope]) { if ($returnNode->expr === null) { $hasNull = \true; continue; } $returnTypes[] = $returnScope->getType($returnNode->expr); } if (count($returnTypes) === 0) { if ($onlyNeverExecutionEnds === \true && !$hasNull) { $returnType = new NonAcceptingNeverType(); } else { $returnType = new VoidType(); } } else { if ($onlyNeverExecutionEnds === \true) { $returnTypes[] = new NonAcceptingNeverType(); } if ($hasNull) { $returnTypes[] = new NullType(); } $returnType = TypeCombinator::union(...$returnTypes); } if (count($closureYieldStatements) > 0) { $keyTypes = []; $valueTypes = []; foreach ($closureYieldStatements as [$yieldNode, $yieldScope]) { if ($yieldNode instanceof Expr\Yield_) { if ($yieldNode->key === null) { $keyTypes[] = new IntegerType(); } else { $keyTypes[] = $yieldScope->getType($yieldNode->key); } if ($yieldNode->value === null) { $valueTypes[] = new NullType(); } else { $valueTypes[] = $yieldScope->getType($yieldNode->value); } continue; } $yieldFromType = $yieldScope->getType($yieldNode->expr); $keyTypes[] = $yieldScope->getIterableKeyType($yieldFromType); $valueTypes[] = $yieldScope->getIterableValueType($yieldFromType); } $returnType = new GenericObjectType(Generator::class, [TypeCombinator::union(...$keyTypes), TypeCombinator::union(...$valueTypes), new MixedType(), $returnType]); } else { if ($node->returnType !== null) { $nativeReturnType = $this->getFunctionType($node->returnType, \false, \false); $returnType = self::intersectButNotNever($nativeReturnType, $returnType); } } $usedVariables = []; foreach ($node->uses as $use) { if (!is_string($use->var->name)) { continue; } $usedVariables[] = $use->var->name; } foreach ($node->uses as $use) { if (!$use->byRef) { continue; } $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($this, $node, 'functionCall', 'call to a Closure with by-ref use', \true); break; } } foreach ($parameters as $parameter) { if ($parameter->passedByReference()->no()) { continue; } $impurePoints[] = new \PHPStan\Analyser\ImpurePoint($this, $node, 'functionCall', 'call to a Closure with by-ref parameter', \true); } $throwPointsForClosureType = array_map(static function (\PHPStan\Analyser\ThrowPoint $throwPoint) { return $throwPoint->isExplicit() ? SimpleThrowPoint::createExplicit($throwPoint->getType(), $throwPoint->canContainAnyThrowable()) : SimpleThrowPoint::createImplicit(); }, $throwPoints); $impurePointsForClosureType = array_map(static function (\PHPStan\Analyser\ImpurePoint $impurePoint) { return new SimpleImpurePoint($impurePoint->getIdentifier(), $impurePoint->getDescription(), $impurePoint->isCertain()); }, $impurePoints); $cachedTypes = $node->getAttribute('phpstanCachedTypes', []); $cachedTypes[$this->getClosureScopeCacheKey()] = ['returnType' => $returnType, 'throwPoints' => $throwPointsForClosureType, 'impurePoints' => $impurePointsForClosureType, 'invalidateExpressions' => $invalidateExpressions, 'usedVariables' => $usedVariables]; $node->setAttribute('phpstanCachedTypes', $cachedTypes); return new ClosureType($parameters, $returnType, $isVariadic, TemplateTypeMap::createEmpty(), TemplateTypeMap::createEmpty(), TemplateTypeVarianceMap::createEmpty(), [], $throwPointsForClosureType, $impurePointsForClosureType, $invalidateExpressions, $usedVariables, \true); } elseif ($node instanceof New_) { if ($node->class instanceof Name) { $type = $this->exactInstantiation($node, $node->class->toString()); if ($type !== null) { return $type; } $lowercasedClassName = strtolower($node->class->toString()); if ($lowercasedClassName === 'static') { if (!$this->isInClass()) { return new ErrorType(); } return new StaticType($this->getClassReflection()); } if ($lowercasedClassName === 'parent') { return new NonexistentParentClassType(); } return new ObjectType($node->class->toString()); } if ($node->class instanceof Node\Stmt\Class_) { $anonymousClassReflection = $this->reflectionProvider->getAnonymousClassReflection($node->class, $this); return new ObjectType($anonymousClassReflection->getName()); } $exprType = $this->getType($node->class); return $exprType->getObjectTypeOrClassStringObjectType(); } elseif ($node instanceof Array_) { return $this->initializerExprTypeResolver->getArrayType($node, function (Expr $expr) : Type { return $this->getType($expr); }); } elseif ($node instanceof Int_) { return $this->getType($node->expr)->toInteger(); } elseif ($node instanceof Bool_) { return $this->getType($node->expr)->toBoolean(); } elseif ($node instanceof Double) { return $this->getType($node->expr)->toFloat(); } elseif ($node instanceof Node\Expr\Cast\String_) { return $this->getType($node->expr)->toString(); } elseif ($node instanceof Node\Expr\Cast\Array_) { return $this->getType($node->expr)->toArray(); } elseif ($node instanceof Node\Scalar\MagicConst) { return $this->initializerExprTypeResolver->getType($node, InitializerExprContext::fromScope($this)); } elseif ($node instanceof Object_) { $castToObject = static function (Type $type) : Type { $constantArrays = $type->getConstantArrays(); if (count($constantArrays) > 0) { $objects = []; foreach ($constantArrays as $constantArray) { $properties = []; $optionalProperties = []; foreach ($constantArray->getKeyTypes() as $i => $keyType) { if (!$keyType instanceof ConstantStringType) { // an object with integer properties is >weird< continue; } $valueType = $constantArray->getValueTypes()[$i]; $optional = $constantArray->isOptionalKey($i); if ($optional) { $optionalProperties[] = $keyType->getValue(); } $properties[$keyType->getValue()] = $valueType; } $objects[] = TypeCombinator::intersect(new ObjectShapeType($properties, $optionalProperties), new ObjectType(stdClass::class)); } return TypeCombinator::union(...$objects); } if ($type->isObject()->yes()) { return $type; } return new ObjectType('stdClass'); }; $exprType = $this->getType($node->expr); if ($exprType instanceof UnionType) { return TypeCombinator::union(...array_map($castToObject, $exprType->getTypes())); } return $castToObject($exprType); } elseif ($node instanceof Unset_) { return new NullType(); } elseif ($node instanceof Expr\PostInc || $node instanceof Expr\PostDec) { return $this->getType($node->var); } elseif ($node instanceof Expr\PreInc || $node instanceof Expr\PreDec) { $varType = $this->getType($node->var); $varScalars = $varType->getConstantScalarValues(); if (count($varScalars) > 0) { $newTypes = []; foreach ($varScalars as $varValue) { if ($node instanceof Expr\PreInc) { if (!is_bool($varValue)) { ++$varValue; } } elseif (is_numeric($varValue)) { --$varValue; } $newTypes[] = $this->getTypeFromValue($varValue); } return TypeCombinator::union(...$newTypes); } elseif ($varType->isString()->yes()) { if ($varType->isLiteralString()->yes()) { return new IntersectionType([new StringType(), new AccessoryLiteralStringType()]); } if ($varType->isNumericString()->yes()) { return new BenevolentUnionType([new IntegerType(), new FloatType()]); } return new BenevolentUnionType([new StringType(), new IntegerType(), new FloatType()]); } if ($node instanceof Expr\PreInc) { return $this->getType(new BinaryOp\Plus($node->var, new LNumber(1))); } return $this->getType(new BinaryOp\Minus($node->var, new LNumber(1))); } elseif ($node instanceof Expr\Yield_) { $functionReflection = $this->getFunction(); if ($functionReflection === null) { return new MixedType(); } $returnType = $functionReflection->getReturnType(); $generatorSendType = $returnType->getTemplateType(Generator::class, 'TSend'); if ($generatorSendType instanceof ErrorType) { return new MixedType(); } return $generatorSendType; } elseif ($node instanceof Expr\YieldFrom) { $yieldFromType = $this->getType($node->expr); $generatorReturnType = $yieldFromType->getTemplateType(Generator::class, 'TReturn'); if ($generatorReturnType instanceof ErrorType) { return new MixedType(); } return $generatorReturnType; } elseif ($node instanceof Expr\Match_) { $cond = $node->cond; $condType = $this->getType($cond); $types = []; $matchScope = $this; $arms = $node->arms; if ($condType->isEnum()->yes()) { // enum match analysis would work even without this if branch // but would be much slower // this avoids using ObjectType::$subtractedType which is slow for huge enums // because of repeated union type normalization $enumCases = $condType->getEnumCases(); if (count($enumCases) > 0) { $indexedEnumCases = []; foreach ($enumCases as $enumCase) { $indexedEnumCases[strtolower($enumCase->getClassName())][$enumCase->getEnumCaseName()] = $enumCase; } $unusedIndexedEnumCases = $indexedEnumCases; foreach ($arms as $i => $arm) { if ($arm->conds === null) { continue; } $conditionCases = []; foreach ($arm->conds as $armCond) { if (!$armCond instanceof Expr\ClassConstFetch) { continue 2; } if (!$armCond->class instanceof Name) { continue 2; } if (!$armCond->name instanceof Node\Identifier) { continue 2; } $fetchedClassName = $this->resolveName($armCond->class); $loweredFetchedClassName = strtolower($fetchedClassName); if (!array_key_exists($loweredFetchedClassName, $indexedEnumCases)) { continue 2; } $caseName = $armCond->name->toString(); if (!array_key_exists($caseName, $indexedEnumCases[$loweredFetchedClassName])) { continue 2; } $conditionCases[] = $indexedEnumCases[$loweredFetchedClassName][$caseName]; unset($unusedIndexedEnumCases[$loweredFetchedClassName][$caseName]); } $conditionCasesCount = count($conditionCases); if ($conditionCasesCount === 0) { throw new ShouldNotHappenException(); } elseif ($conditionCasesCount === 1) { $conditionCaseType = $conditionCases[0]; } else { $conditionCaseType = new UnionType($conditionCases); } $types[] = $matchScope->addTypeToExpression($cond, $conditionCaseType)->getType($arm->body); unset($arms[$i]); } $remainingCases = []; foreach ($unusedIndexedEnumCases as $cases) { foreach ($cases as $case) { $remainingCases[] = $case; } } $remainingCasesCount = count($remainingCases); if ($remainingCasesCount === 0) { $remainingType = new NeverType(); } elseif ($remainingCasesCount === 1) { $remainingType = $remainingCases[0]; } else { $remainingType = new UnionType($remainingCases); } $matchScope = $matchScope->addTypeToExpression($cond, $remainingType); } } foreach ($arms as $arm) { if ($arm->conds === null) { if ($node->hasAttribute(self::KEEP_VOID_ATTRIBUTE_NAME)) { $arm->body->setAttribute(self::KEEP_VOID_ATTRIBUTE_NAME, $node->getAttribute(self::KEEP_VOID_ATTRIBUTE_NAME)); } $types[] = $matchScope->getType($arm->body); continue; } if (count($arm->conds) === 0) { throw new ShouldNotHappenException(); } if (count($arm->conds) === 1) { $filteringExpr = new BinaryOp\Identical($cond, $arm->conds[0]); } else { $items = []; foreach ($arm->conds as $filteringExpr) { $items[] = new Expr\ArrayItem($filteringExpr); } $filteringExpr = new FuncCall(new Name\FullyQualified('in_array'), [new Arg($cond), new Arg(new Array_($items)), new Arg(new ConstFetch(new Name\FullyQualified('true')))]); } $filteringExprType = $matchScope->getType($filteringExpr); if (!$filteringExprType->isFalse()->yes()) { $truthyScope = $matchScope->filterByTruthyValue($filteringExpr); if ($node->hasAttribute(self::KEEP_VOID_ATTRIBUTE_NAME)) { $arm->body->setAttribute(self::KEEP_VOID_ATTRIBUTE_NAME, $node->getAttribute(self::KEEP_VOID_ATTRIBUTE_NAME)); } $types[] = $truthyScope->getType($arm->body); } $matchScope = $matchScope->filterByFalseyValue($filteringExpr); } return TypeCombinator::union(...$types); } if ($node instanceof Expr\Isset_) { $issetResult = \true; foreach ($node->vars as $var) { $result = $this->issetCheck($var, static function (Type $type) : ?bool { $isNull = $type->isNull(); if ($isNull->maybe()) { return null; } return !$isNull->yes(); }); if ($result !== null) { if (!$result) { return new ConstantBooleanType($result); } continue; } $issetResult = $result; } if ($issetResult === null) { return new BooleanType(); } return new ConstantBooleanType($issetResult); } if ($node instanceof Expr\AssignOp\Coalesce) { return $this->getType(new BinaryOp\Coalesce($node->var, $node->expr, $node->getAttributes())); } if ($node instanceof Expr\BinaryOp\Coalesce) { $issetLeftExpr = new Expr\Isset_([$node->left]); $leftType = $this->filterByTruthyValue($issetLeftExpr)->getType($node->left); $result = $this->issetCheck($node->left, static function (Type $type) : ?bool { $isNull = $type->isNull(); if ($isNull->maybe()) { return null; } return !$isNull->yes(); }); if ($result !== null && $result !== \false) { return TypeCombinator::removeNull($leftType); } $rightType = $this->filterByFalseyValue($issetLeftExpr)->getType($node->right); if ($result === null) { return TypeCombinator::union(TypeCombinator::removeNull($leftType), $rightType); } return $rightType; } if ($node instanceof ConstFetch) { $constName = (string) $node->name; $loweredConstName = strtolower($constName); if ($loweredConstName === 'true') { return new ConstantBooleanType(\true); } elseif ($loweredConstName === 'false') { return new ConstantBooleanType(\false); } elseif ($loweredConstName === 'null') { return new NullType(); } $namespacedName = null; if (!$node->name->isFullyQualified() && $this->getNamespace() !== null) { $namespacedName = new FullyQualified([$this->getNamespace(), $node->name->toString()]); } $globalName = new FullyQualified($node->name->toString()); foreach ([$namespacedName, $globalName] as $name) { if ($name === null) { continue; } $constFetch = new ConstFetch($name); if ($this->hasExpressionType($constFetch)->yes()) { return $this->constantResolver->resolveConstantType($name->toString(), $this->expressionTypes[$this->getNodeKey($constFetch)]->getType()); } } $constantType = $this->constantResolver->resolveConstant($node->name, $this); if ($constantType !== null) { return $constantType; } return new ErrorType(); } elseif ($node instanceof Node\Expr\ClassConstFetch && $node->name instanceof Node\Identifier) { if ($this->hasExpressionType($node)->yes()) { return $this->expressionTypes[$exprString]->getType(); } return $this->initializerExprTypeResolver->getClassConstFetchTypeByReflection($node->class, $node->name->name, $this->isInClass() ? $this->getClassReflection() : null, function (Expr $expr) : Type { return $this->getType($expr); }); } if ($node instanceof Expr\Ternary) { $noopCallback = static function () : void { }; $condResult = $this->nodeScopeResolver->processExprNode(new Node\Stmt\Expression($node->cond), $node->cond, $this, $noopCallback, \PHPStan\Analyser\ExpressionContext::createDeep()); if ($node->if === null) { $conditionType = $this->getType($node->cond); $booleanConditionType = $conditionType->toBoolean(); if ($booleanConditionType->isTrue()->yes()) { return $condResult->getTruthyScope()->getType($node->cond); } if ($booleanConditionType->isFalse()->yes()) { return $condResult->getFalseyScope()->getType($node->else); } return TypeCombinator::union(TypeCombinator::removeFalsey($condResult->getTruthyScope()->getType($node->cond)), $condResult->getFalseyScope()->getType($node->else)); } $booleanConditionType = $this->getType($node->cond)->toBoolean(); if ($booleanConditionType->isTrue()->yes()) { return $condResult->getTruthyScope()->getType($node->if); } if ($booleanConditionType->isFalse()->yes()) { return $condResult->getFalseyScope()->getType($node->else); } return TypeCombinator::union($condResult->getTruthyScope()->getType($node->if), $condResult->getFalseyScope()->getType($node->else)); } if ($node instanceof Variable && is_string($node->name)) { if ($this->hasVariableType($node->name)->no()) { return new ErrorType(); } return $this->getVariableType($node->name); } if ($node instanceof Expr\ArrayDimFetch && $node->dim !== null) { return $this->getNullsafeShortCircuitingType($node->var, $this->getTypeFromArrayDimFetch($node, $this->getType($node->dim), $this->getType($node->var))); } if ($node instanceof MethodCall && $node->name instanceof Node\Identifier) { if ($this->nativeTypesPromoted) { $typeCallback = function () use($node) : Type { $methodReflection = $this->getMethodReflection($this->getNativeType($node->var), $node->name->name); if ($methodReflection === null) { return new ErrorType(); } return ParametersAcceptorSelector::combineAcceptors($methodReflection->getVariants())->getNativeReturnType(); }; return $this->getNullsafeShortCircuitingType($node->var, $typeCallback()); } $typeCallback = function () use($node) : Type { $returnType = $this->methodCallReturnType($this->getType($node->var), $node->name->name, $node); if ($returnType === null) { return new ErrorType(); } return $returnType; }; return $this->getNullsafeShortCircuitingType($node->var, $typeCallback()); } if ($node instanceof Expr\NullsafeMethodCall) { $varType = $this->getType($node->var); if ($varType->isNull()->yes()) { return new NullType(); } if (!TypeCombinator::containsNull($varType)) { return $this->getType(new MethodCall($node->var, $node->name, $node->args)); } return TypeCombinator::union($this->filterByTruthyValue(new BinaryOp\NotIdentical($node->var, new ConstFetch(new Name('null'))))->getType(new MethodCall($node->var, $node->name, $node->args)), new NullType()); } if ($node instanceof Expr\StaticCall && $node->name instanceof Node\Identifier) { if ($this->nativeTypesPromoted) { $typeCallback = function () use($node) : Type { if ($node->class instanceof Name) { $staticMethodCalledOnType = $this->resolveTypeByNameWithLateStaticBinding($node->class, $node->name); } else { $staticMethodCalledOnType = $this->getNativeType($node->class); } $methodReflection = $this->getMethodReflection($staticMethodCalledOnType, $node->name->name); if ($methodReflection === null) { return new ErrorType(); } return ParametersAcceptorSelector::combineAcceptors($methodReflection->getVariants())->getNativeReturnType(); }; $callType = $typeCallback(); if ($node->class instanceof Expr) { return $this->getNullsafeShortCircuitingType($node->class, $callType); } return $callType; } $typeCallback = function () use($node) : Type { if ($node->class instanceof Name) { $staticMethodCalledOnType = $this->resolveTypeByNameWithLateStaticBinding($node->class, $node->name); } else { $staticMethodCalledOnType = TypeCombinator::removeNull($this->getType($node->class))->getObjectTypeOrClassStringObjectType(); } $returnType = $this->methodCallReturnType($staticMethodCalledOnType, $node->name->toString(), $node); if ($returnType === null) { return new ErrorType(); } return $returnType; }; $callType = $typeCallback(); if ($node->class instanceof Expr) { return $this->getNullsafeShortCircuitingType($node->class, $callType); } return $callType; } if ($node instanceof PropertyFetch && $node->name instanceof Node\Identifier) { if ($this->nativeTypesPromoted) { $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node, $this); if ($propertyReflection === null) { return new ErrorType(); } $nativeType = $propertyReflection->getNativeType(); if ($nativeType === null) { return new ErrorType(); } return $this->getNullsafeShortCircuitingType($node->var, $nativeType); } $typeCallback = function () use($node) : Type { $returnType = $this->propertyFetchType($this->getType($node->var), $node->name->name, $node); if ($returnType === null) { return new ErrorType(); } return $returnType; }; return $this->getNullsafeShortCircuitingType($node->var, $typeCallback()); } if ($node instanceof Expr\NullsafePropertyFetch) { $varType = $this->getType($node->var); if ($varType->isNull()->yes()) { return new NullType(); } if (!TypeCombinator::containsNull($varType)) { return $this->getType(new PropertyFetch($node->var, $node->name)); } return TypeCombinator::union($this->filterByTruthyValue(new BinaryOp\NotIdentical($node->var, new ConstFetch(new Name('null'))))->getType(new PropertyFetch($node->var, $node->name)), new NullType()); } if ($node instanceof Expr\StaticPropertyFetch && $node->name instanceof Node\VarLikeIdentifier) { if ($this->nativeTypesPromoted) { $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node, $this); if ($propertyReflection === null) { return new ErrorType(); } $nativeType = $propertyReflection->getNativeType(); if ($nativeType === null) { return new ErrorType(); } if ($node->class instanceof Expr) { return $this->getNullsafeShortCircuitingType($node->class, $nativeType); } return $nativeType; } $typeCallback = function () use($node) : Type { if ($node->class instanceof Name) { $staticPropertyFetchedOnType = $this->resolveTypeByName($node->class); } else { $staticPropertyFetchedOnType = TypeCombinator::removeNull($this->getType($node->class))->getObjectTypeOrClassStringObjectType(); } $returnType = $this->propertyFetchType($staticPropertyFetchedOnType, $node->name->toString(), $node); if ($returnType === null) { return new ErrorType(); } return $returnType; }; $fetchType = $typeCallback(); if ($node->class instanceof Expr) { return $this->getNullsafeShortCircuitingType($node->class, $fetchType); } return $fetchType; } if ($node instanceof FuncCall) { if ($node->name instanceof Expr) { $calledOnType = $this->getType($node->name); if ($calledOnType->isCallable()->no()) { return new ErrorType(); } return ParametersAcceptorSelector::selectFromArgs($this, $node->getArgs(), $calledOnType->getCallableParametersAcceptors($this), null)->getReturnType(); } if (!$this->reflectionProvider->hasFunction($node->name, $this)) { return new ErrorType(); } $functionReflection = $this->reflectionProvider->getFunction($node->name, $this); if ($this->nativeTypesPromoted) { return ParametersAcceptorSelector::combineAcceptors($functionReflection->getVariants())->getNativeReturnType(); } if ($functionReflection->getName() === 'call_user_func') { $result = \PHPStan\Analyser\ArgumentsNormalizer::reorderCallUserFuncArguments($node, $this); if ($result !== null) { [, $innerFuncCall] = $result; return $this->getType($innerFuncCall); } } $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($this, $node->getArgs(), $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants()); $normalizedNode = \PHPStan\Analyser\ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $node); if ($normalizedNode !== null) { foreach ($this->dynamicReturnTypeExtensionRegistry->getDynamicFunctionReturnTypeExtensions() as $dynamicFunctionReturnTypeExtension) { if (!$dynamicFunctionReturnTypeExtension->isFunctionSupported($functionReflection)) { continue; } $resolvedType = $dynamicFunctionReturnTypeExtension->getTypeFromFunctionCall($functionReflection, $normalizedNode, $this); if ($resolvedType !== null) { return $resolvedType; } } } return $this->transformVoidToNull($parametersAcceptor->getReturnType(), $node); } return new MixedType(); } private function getNullsafeShortCircuitingType(Expr $expr, Type $type) : Type { if ($expr instanceof Expr\NullsafePropertyFetch || $expr instanceof Expr\NullsafeMethodCall) { $varType = $this->getType($expr->var); if (TypeCombinator::containsNull($varType)) { return TypeCombinator::addNull($type); } return $type; } if ($expr instanceof Expr\ArrayDimFetch) { return $this->getNullsafeShortCircuitingType($expr->var, $type); } if ($expr instanceof PropertyFetch) { return $this->getNullsafeShortCircuitingType($expr->var, $type); } if ($expr instanceof Expr\StaticPropertyFetch && $expr->class instanceof Expr) { return $this->getNullsafeShortCircuitingType($expr->class, $type); } if ($expr instanceof MethodCall) { return $this->getNullsafeShortCircuitingType($expr->var, $type); } if ($expr instanceof Expr\StaticCall && $expr->class instanceof Expr) { return $this->getNullsafeShortCircuitingType($expr->class, $type); } return $type; } private function transformVoidToNull(Type $type, Node $node) : Type { if ($node->getAttribute(self::KEEP_VOID_ATTRIBUTE_NAME) === \true) { return $type; } return TypeTraverser::map($type, static function (Type $type, callable $traverse) : Type { if ($type instanceof UnionType || $type instanceof IntersectionType) { return $traverse($type); } if ($type->isVoid()->yes()) { return new NullType(); } return $type; }); } /** * @param callable(Type): ?bool $typeCallback */ public function issetCheck(Expr $expr, callable $typeCallback, ?bool $result = null) : ?bool { // mirrored in PHPStan\Rules\IssetCheck if ($expr instanceof Node\Expr\Variable && is_string($expr->name)) { $hasVariable = $this->hasVariableType($expr->name); if ($hasVariable->maybe()) { return null; } if ($result === null) { if ($hasVariable->yes()) { if ($expr->name === '_SESSION') { return null; } return $typeCallback($this->getVariableType($expr->name)); } return \false; } return $result; } elseif ($expr instanceof Node\Expr\ArrayDimFetch && $expr->dim !== null) { $type = $this->getType($expr->var); if (!$type->isOffsetAccessible()->yes()) { return $result ?? $this->issetCheckUndefined($expr->var); } $dimType = $this->getType($expr->dim); $hasOffsetValue = $type->hasOffsetValueType($dimType); if ($hasOffsetValue->no()) { return \false; } // If offset cannot be null, store this error message and see if one of the earlier offsets is. // E.g. $array['a']['b']['c'] ?? null; is a valid coalesce if a OR b or C might be null. if ($hasOffsetValue->yes()) { $result = $typeCallback($type->getOffsetValueType($dimType)); if ($result !== null) { return $this->issetCheck($expr->var, $typeCallback, $result); } } // Has offset, it is nullable return null; } elseif ($expr instanceof Node\Expr\PropertyFetch || $expr instanceof Node\Expr\StaticPropertyFetch) { $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($expr, $this); if ($propertyReflection === null) { if ($expr instanceof Node\Expr\PropertyFetch) { return $this->issetCheckUndefined($expr->var); } if ($expr->class instanceof Expr) { return $this->issetCheckUndefined($expr->class); } return null; } if (!$propertyReflection->isNative()) { if ($expr instanceof Node\Expr\PropertyFetch) { return $this->issetCheckUndefined($expr->var); } if ($expr->class instanceof Expr) { return $this->issetCheckUndefined($expr->class); } return null; } $nativeType = $propertyReflection->getNativeType(); if (!$nativeType instanceof MixedType) { if (!$this->hasExpressionType($expr)->yes()) { if ($expr instanceof Node\Expr\PropertyFetch) { return $this->issetCheckUndefined($expr->var); } if ($expr->class instanceof Expr) { return $this->issetCheckUndefined($expr->class); } return null; } } if ($result !== null) { return $result; } $result = $typeCallback($propertyReflection->getWritableType()); if ($result !== null) { if ($expr instanceof Node\Expr\PropertyFetch) { return $this->issetCheck($expr->var, $typeCallback, $result); } if ($expr->class instanceof Expr) { return $this->issetCheck($expr->class, $typeCallback, $result); } } return $result; } if ($result !== null) { return $result; } return $typeCallback($this->getType($expr)); } private function issetCheckUndefined(Expr $expr) : ?bool { if ($expr instanceof Node\Expr\Variable && is_string($expr->name)) { $hasVariable = $this->hasVariableType($expr->name); if (!$hasVariable->no()) { return null; } return \false; } if ($expr instanceof Node\Expr\ArrayDimFetch && $expr->dim !== null) { $type = $this->getType($expr->var); if (!$type->isOffsetAccessible()->yes()) { return $this->issetCheckUndefined($expr->var); } $dimType = $this->getType($expr->dim); $hasOffsetValue = $type->hasOffsetValueType($dimType); if (!$hasOffsetValue->no()) { return $this->issetCheckUndefined($expr->var); } return \false; } if ($expr instanceof Expr\PropertyFetch) { return $this->issetCheckUndefined($expr->var); } if ($expr instanceof Expr\StaticPropertyFetch && $expr->class instanceof Expr) { return $this->issetCheckUndefined($expr->class); } return null; } /** * @param ParametersAcceptor[] $variants * @param FunctionReflection|ExtendedMethodReflection|null $function */ private function createFirstClassCallable($function, array $variants) : Type { $closureTypes = []; foreach ($variants as $variant) { $returnType = $variant->getReturnType(); if ($variant instanceof ParametersAcceptorWithPhpDocs) { $returnType = $this->nativeTypesPromoted ? $variant->getNativeReturnType() : $returnType; } $templateTags = []; foreach ($variant->getTemplateTypeMap()->getTypes() as $templateType) { if (!$templateType instanceof TemplateType) { continue; } $templateTags[$templateType->getName()] = new TemplateTag($templateType->getName(), $templateType->getBound(), $templateType->getDefault(), $templateType->getVariance()); } $throwPoints = []; $impurePoints = []; $acceptsNamedArguments = \true; if ($variant instanceof CallableParametersAcceptor) { $throwPoints = $variant->getThrowPoints(); $impurePoints = $variant->getImpurePoints(); $acceptsNamedArguments = $variant->acceptsNamedArguments(); } elseif ($function !== null) { $returnTypeForThrow = $variant->getReturnType(); $throwType = $function->getThrowType(); if ($throwType === null) { if ($returnTypeForThrow instanceof NeverType && $returnTypeForThrow->isExplicit()) { $throwType = new ObjectType(Throwable::class); } } if ($throwType !== null) { if (!$throwType->isVoid()->yes()) { $throwPoints[] = SimpleThrowPoint::createExplicit($throwType, \true); } } else { if (!(new ObjectType(Throwable::class))->isSuperTypeOf($returnTypeForThrow)->yes()) { $throwPoints[] = SimpleThrowPoint::createImplicit(); } } $impurePoint = SimpleImpurePoint::createFromVariant($function, $variant); if ($impurePoint !== null) { $impurePoints[] = $impurePoint; } $acceptsNamedArguments = $function->acceptsNamedArguments(); } $parameters = $variant->getParameters(); $closureTypes[] = new ClosureType($parameters, $returnType, $variant->isVariadic(), $variant->getTemplateTypeMap(), $variant->getResolvedTemplateTypeMap(), $variant instanceof ParametersAcceptorWithPhpDocs ? $variant->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(), $templateTags, $throwPoints, $impurePoints, [], [], $acceptsNamedArguments); } return TypeCombinator::union(...$closureTypes); } /** @api */ public function getNativeType(Expr $expr) : Type { return $this->promoteNativeTypes()->getType($expr); } public function getKeepVoidType(Expr $node) : Type { $clonedNode = clone $node; $clonedNode->setAttribute(self::KEEP_VOID_ATTRIBUTE_NAME, \true); return $this->getType($clonedNode); } /** * @api * @deprecated Use getNativeType() */ public function doNotTreatPhpDocTypesAsCertain() : \PHPStan\Analyser\Scope { return $this->promoteNativeTypes(); } private function promoteNativeTypes() : self { if ($this->nativeTypesPromoted) { return $this; } if ($this->scopeWithPromotedNativeTypes !== null) { return $this->scopeWithPromotedNativeTypes; } return $this->scopeWithPromotedNativeTypes = $this->scopeFactory->create($this->context, $this->declareStrictTypes, $this->function, $this->namespace, $this->nativeExpressionTypes, [], [], $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->inFirstLevelStatement, $this->currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, $this->inFunctionCallsStack, $this->afterExtractCall, $this->parentScope, \true); } /** * @param Node\Expr\PropertyFetch|Node\Expr\StaticPropertyFetch $propertyFetch */ public function hasPropertyNativeType($propertyFetch) : bool { $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($propertyFetch, $this); if ($propertyReflection === null) { return \false; } if (!$propertyReflection->isNative()) { return \false; } return !$propertyReflection->getNativeType() instanceof MixedType; } /** @api */ protected function getTypeFromArrayDimFetch(Expr\ArrayDimFetch $arrayDimFetch, Type $offsetType, Type $offsetAccessibleType) : Type { if ($arrayDimFetch->dim === null) { throw new ShouldNotHappenException(); } if (!$offsetAccessibleType->isArray()->yes() && (new ObjectType(ArrayAccess::class))->isSuperTypeOf($offsetAccessibleType)->yes()) { return $this->getType(new MethodCall($arrayDimFetch->var, new Node\Identifier('offsetGet'), [new Node\Arg($arrayDimFetch->dim)])); } return $offsetAccessibleType->getOffsetValueType($offsetType); } private function resolveExactName(Name $name) : ?string { $originalClass = (string) $name; switch (strtolower($originalClass)) { case 'self': if (!$this->isInClass()) { return null; } return $this->getClassReflection()->getName(); case 'parent': if (!$this->isInClass()) { return null; } $currentClassReflection = $this->getClassReflection(); if ($currentClassReflection->getParentClass() !== null) { return $currentClassReflection->getParentClass()->getName(); } return null; case 'static': return null; } return $originalClass; } /** @api */ public function resolveName(Name $name) : string { $originalClass = (string) $name; if ($this->isInClass()) { $lowerClass = strtolower($originalClass); if (in_array($lowerClass, ['self', 'static'], \true)) { if ($this->inClosureBindScopeClasses !== [] && $this->inClosureBindScopeClasses !== ['static']) { return $this->inClosureBindScopeClasses[0]; } return $this->getClassReflection()->getName(); } elseif ($lowerClass === 'parent') { $currentClassReflection = $this->getClassReflection(); if ($currentClassReflection->getParentClass() !== null) { return $currentClassReflection->getParentClass()->getName(); } } } return $originalClass; } /** @api */ public function resolveTypeByName(Name $name) : TypeWithClassName { if ($name->toLowerString() === 'static' && $this->isInClass()) { if ($this->inClosureBindScopeClasses !== [] && $this->inClosureBindScopeClasses !== ['static']) { if ($this->reflectionProvider->hasClass($this->inClosureBindScopeClasses[0])) { return new StaticType($this->reflectionProvider->getClass($this->inClosureBindScopeClasses[0])); } } return new StaticType($this->getClassReflection()); } $originalClass = $this->resolveName($name); if ($this->isInClass()) { if ($this->inClosureBindScopeClasses === [$originalClass]) { if ($this->reflectionProvider->hasClass($originalClass)) { return new ThisType($this->reflectionProvider->getClass($originalClass)); } return new ObjectType($originalClass); } $thisType = new ThisType($this->getClassReflection()); $ancestor = $thisType->getAncestorWithClassName($originalClass); if ($ancestor !== null) { return $ancestor; } } return new ObjectType($originalClass); } private function resolveTypeByNameWithLateStaticBinding(Name $class, Node\Identifier $name) : TypeWithClassName { $classType = $this->resolveTypeByName($class); if ($classType instanceof StaticType && !in_array($class->toLowerString(), ['self', 'static', 'parent'], \true)) { $methodReflectionCandidate = $this->getMethodReflection($classType, $name->name); if ($methodReflectionCandidate !== null && $methodReflectionCandidate->isStatic()) { $classType = $classType->getStaticObjectType(); } } return $classType; } /** * @api * @param mixed $value */ public function getTypeFromValue($value) : Type { return ConstantTypeHelper::getTypeFromValue($value); } /** * @api * @deprecated use hasExpressionType instead */ public function isSpecified(Expr $node) : bool { return !$node instanceof Variable && $this->hasExpressionType($node)->yes(); } /** @api */ public function hasExpressionType(Expr $node) : TrinaryLogic { if ($node instanceof Variable && is_string($node->name)) { return $this->hasVariableType($node->name); } $exprString = $this->getNodeKey($node); if (!isset($this->expressionTypes[$exprString])) { return TrinaryLogic::createNo(); } return $this->expressionTypes[$exprString]->getCertainty(); } /** * @param MethodReflection|FunctionReflection|null $reflection */ public function pushInFunctionCall($reflection, ?ParameterReflection $parameter) : self { $stack = $this->inFunctionCallsStack; $stack[] = [$reflection, $parameter]; return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $this->expressionTypes, $this->nativeExpressionTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->isInFirstLevelStatement(), $this->currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, $stack, $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } public function popInFunctionCall() : self { $stack = $this->inFunctionCallsStack; array_pop($stack); return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $this->expressionTypes, $this->nativeExpressionTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->isInFirstLevelStatement(), $this->currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, $stack, $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } /** @api */ public function isInClassExists(string $className) : bool { foreach ($this->inFunctionCallsStack as [$inFunctionCall]) { if (!$inFunctionCall instanceof FunctionReflection) { continue; } if (in_array($inFunctionCall->getName(), ['class_exists', 'interface_exists', 'trait_exists'], \true)) { return \true; } } $expr = new FuncCall(new FullyQualified('class_exists'), [new Arg(new String_(ltrim($className, '\\')))]); return $this->getType($expr)->isTrue()->yes(); } public function getFunctionCallStack() : array { return array_values(array_filter(array_map(static function ($values) { return $values[0]; }, $this->inFunctionCallsStack), static function ($reflection) { return $reflection !== null; })); } public function getFunctionCallStackWithParameters() : array { return array_values(array_filter($this->inFunctionCallsStack, static function ($item) { return $item[0] !== null; })); } /** @api */ public function isInFunctionExists(string $functionName) : bool { $expr = new FuncCall(new FullyQualified('function_exists'), [new Arg(new String_(ltrim($functionName, '\\')))]); return $this->getType($expr)->isTrue()->yes(); } /** @api */ public function enterClass(ClassReflection $classReflection) : self { $thisHolder = \PHPStan\Analyser\ExpressionTypeHolder::createYes(new Variable('this'), new ThisType($classReflection)); $constantTypes = $this->getConstantTypes(); $constantTypes['$this'] = $thisHolder; $nativeConstantTypes = $this->getNativeConstantTypes(); $nativeConstantTypes['$this'] = $thisHolder; return $this->scopeFactory->create($this->context->enterClass($classReflection), $this->isDeclareStrictTypes(), null, $this->getNamespace(), $constantTypes, $nativeConstantTypes, [], [], null, \true, [], [], [], \false, $classReflection->isAnonymous() ? $this : null); } public function enterTrait(ClassReflection $traitReflection) : self { $namespace = null; $traitName = $traitReflection->getName(); $traitNameParts = explode('\\', $traitName); if (count($traitNameParts) > 1) { $namespace = implode('\\', array_slice($traitNameParts, 0, -1)); } return $this->scopeFactory->create($this->context->enterTrait($traitReflection), $this->isDeclareStrictTypes(), $this->getFunction(), $namespace, $this->expressionTypes, $this->nativeExpressionTypes, [], $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection); } /** * @api * @param Type[] $phpDocParameterTypes * @param Type[] $parameterOutTypes * @param array $immediatelyInvokedCallableParameters * @param array $phpDocClosureThisTypeParameters */ public function enterClassMethod(Node\Stmt\ClassMethod $classMethod, TemplateTypeMap $templateTypeMap, array $phpDocParameterTypes, ?Type $phpDocReturnType, ?Type $throwType, ?string $deprecatedDescription, bool $isDeprecated, bool $isInternal, bool $isFinal, ?bool $isPure = null, bool $acceptsNamedArguments = \true, ?Assertions $asserts = null, ?Type $selfOutType = null, ?string $phpDocComment = null, array $parameterOutTypes = [], array $immediatelyInvokedCallableParameters = [], array $phpDocClosureThisTypeParameters = [], bool $isConstructor = \false) : self { if (!$this->isInClass()) { throw new ShouldNotHappenException(); } return $this->enterFunctionLike(new PhpMethodFromParserNodeReflection($this->getClassReflection(), $classMethod, $this->getFile(), $templateTypeMap, $this->getRealParameterTypes($classMethod), array_map(function (Type $type) : Type { return $this->transformStaticType(TemplateTypeHelper::toArgument($type)); }, $phpDocParameterTypes), $this->getRealParameterDefaultValues($classMethod), $this->transformStaticType($this->getFunctionType($classMethod->returnType, \false, \false)), $phpDocReturnType !== null ? $this->transformStaticType(TemplateTypeHelper::toArgument($phpDocReturnType)) : null, $throwType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal, $isPure, $acceptsNamedArguments, $asserts ?? Assertions::createEmpty(), $selfOutType, $phpDocComment, array_map(function (Type $type) : Type { return $this->transformStaticType(TemplateTypeHelper::toArgument($type)); }, $parameterOutTypes), $immediatelyInvokedCallableParameters, array_map(function (Type $type) : Type { return $this->transformStaticType(TemplateTypeHelper::toArgument($type)); }, $phpDocClosureThisTypeParameters), $isConstructor), !$classMethod->isStatic()); } private function transformStaticType(Type $type) : Type { return TypeTraverser::map($type, function (Type $type, callable $traverse) : Type { if (!$this->isInClass()) { return $type; } if ($type instanceof StaticType) { $classReflection = $this->getClassReflection(); $changedType = $type->changeBaseClass($classReflection); if ($classReflection->isFinal() && !$type instanceof ThisType) { $changedType = $changedType->getStaticObjectType(); } return $traverse($changedType); } return $traverse($type); }); } /** * @return Type[] */ private function getRealParameterTypes(Node\FunctionLike $functionLike) : array { $realParameterTypes = []; foreach ($functionLike->getParams() as $parameter) { if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { throw new ShouldNotHappenException(); } $realParameterTypes[$parameter->var->name] = $this->getFunctionType($parameter->type, $this->isParameterValueNullable($parameter) && $parameter->flags === 0, \false); } return $realParameterTypes; } /** * @return Type[] */ private function getRealParameterDefaultValues(Node\FunctionLike $functionLike) : array { $realParameterDefaultValues = []; foreach ($functionLike->getParams() as $parameter) { if ($parameter->default === null) { continue; } if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { throw new ShouldNotHappenException(); } $realParameterDefaultValues[$parameter->var->name] = $this->getType($parameter->default); } return $realParameterDefaultValues; } /** * @api * @param Type[] $phpDocParameterTypes * @param Type[] $parameterOutTypes * @param array $immediatelyInvokedCallableParameters * @param array $phpDocClosureThisTypeParameters */ public function enterFunction(Node\Stmt\Function_ $function, TemplateTypeMap $templateTypeMap, array $phpDocParameterTypes, ?Type $phpDocReturnType, ?Type $throwType, ?string $deprecatedDescription, bool $isDeprecated, bool $isInternal, bool $isFinal, ?bool $isPure = null, bool $acceptsNamedArguments = \true, ?Assertions $asserts = null, ?string $phpDocComment = null, array $parameterOutTypes = [], array $immediatelyInvokedCallableParameters = [], array $phpDocClosureThisTypeParameters = []) : self { return $this->enterFunctionLike(new PhpFunctionFromParserNodeReflection($function, $this->getFile(), $templateTypeMap, $this->getRealParameterTypes($function), array_map(static function (Type $type) : Type { return TemplateTypeHelper::toArgument($type); }, $phpDocParameterTypes), $this->getRealParameterDefaultValues($function), $this->getFunctionType($function->returnType, $function->returnType === null, \false), $phpDocReturnType !== null ? TemplateTypeHelper::toArgument($phpDocReturnType) : null, $throwType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal, $isPure, $acceptsNamedArguments, $asserts ?? Assertions::createEmpty(), $phpDocComment, array_map(static function (Type $type) : Type { return TemplateTypeHelper::toArgument($type); }, $parameterOutTypes), $immediatelyInvokedCallableParameters, $phpDocClosureThisTypeParameters), \false); } private function enterFunctionLike(PhpFunctionFromParserNodeReflection $functionReflection, bool $preserveThis) : self { $parametersByName = []; foreach ($functionReflection->getParameters() as $parameter) { $parametersByName[$parameter->getName()] = $parameter; } $expressionTypes = []; $nativeExpressionTypes = []; $conditionalTypes = []; foreach ($functionReflection->getParameters() as $parameter) { $parameterType = $parameter->getType(); if ($parameterType instanceof ConditionalTypeForParameter) { $targetParameterName = substr($parameterType->getParameterName(), 1); if (array_key_exists($targetParameterName, $parametersByName)) { $targetParameter = $parametersByName[$targetParameterName]; $ifType = $parameterType->isNegated() ? $parameterType->getElse() : $parameterType->getIf(); $elseType = $parameterType->isNegated() ? $parameterType->getIf() : $parameterType->getElse(); $holder = new \PHPStan\Analyser\ConditionalExpressionHolder([$parameterType->getParameterName() => \PHPStan\Analyser\ExpressionTypeHolder::createYes(new Variable($targetParameterName), TypeCombinator::intersect($targetParameter->getType(), $parameterType->getTarget()))], new \PHPStan\Analyser\ExpressionTypeHolder(new Variable($parameter->getName()), $ifType, TrinaryLogic::createYes())); $conditionalTypes['$' . $parameter->getName()][$holder->getKey()] = $holder; $holder = new \PHPStan\Analyser\ConditionalExpressionHolder([$parameterType->getParameterName() => \PHPStan\Analyser\ExpressionTypeHolder::createYes(new Variable($targetParameterName), TypeCombinator::remove($targetParameter->getType(), $parameterType->getTarget()))], new \PHPStan\Analyser\ExpressionTypeHolder(new Variable($parameter->getName()), $elseType, TrinaryLogic::createYes())); $conditionalTypes['$' . $parameter->getName()][$holder->getKey()] = $holder; } } $paramExprString = '$' . $parameter->getName(); if ($parameter->isVariadic()) { if ($this->phpVersion->supportsNamedArguments() && $functionReflection->acceptsNamedArguments()) { $parameterType = new ArrayType(new UnionType([new IntegerType(), new StringType()]), $parameterType); } else { $parameterType = AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $parameterType)); } } $parameterNode = new Variable($parameter->getName()); $expressionTypes[$paramExprString] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($parameterNode, $parameterType); $parameterOriginalValueExpr = new ParameterVariableOriginalValueExpr($parameter->getName()); $parameterOriginalValueExprString = $this->getNodeKey($parameterOriginalValueExpr); $expressionTypes[$parameterOriginalValueExprString] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($parameterOriginalValueExpr, $parameterType); $nativeParameterType = $parameter->getNativeType(); if ($parameter->isVariadic()) { if ($this->phpVersion->supportsNamedArguments() && $functionReflection->acceptsNamedArguments()) { $nativeParameterType = new ArrayType(new UnionType([new IntegerType(), new StringType()]), $nativeParameterType); } else { $nativeParameterType = AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $nativeParameterType)); } } $nativeExpressionTypes[$paramExprString] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($parameterNode, $nativeParameterType); $nativeExpressionTypes[$parameterOriginalValueExprString] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($parameterOriginalValueExpr, $nativeParameterType); } if ($preserveThis && array_key_exists('$this', $this->expressionTypes)) { $expressionTypes['$this'] = $this->expressionTypes['$this']; } if ($preserveThis && array_key_exists('$this', $this->nativeExpressionTypes)) { $nativeExpressionTypes['$this'] = $this->nativeExpressionTypes['$this']; } return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $functionReflection, $this->getNamespace(), array_merge($this->getConstantTypes(), $expressionTypes), array_merge($this->getNativeConstantTypes(), $nativeExpressionTypes), $conditionalTypes); } /** @api */ public function enterNamespace(string $namespaceName) : self { return $this->scopeFactory->create($this->context->beginFile(), $this->isDeclareStrictTypes(), null, $namespaceName); } /** * @param list $scopeClasses */ public function enterClosureBind(?Type $thisType, ?Type $nativeThisType, array $scopeClasses) : self { $expressionTypes = $this->expressionTypes; if ($thisType !== null) { $expressionTypes['$this'] = \PHPStan\Analyser\ExpressionTypeHolder::createYes(new Variable('this'), $thisType); } else { unset($expressionTypes['$this']); } $nativeExpressionTypes = $this->nativeExpressionTypes; if ($nativeThisType !== null) { $nativeExpressionTypes['$this'] = \PHPStan\Analyser\ExpressionTypeHolder::createYes(new Variable('this'), $nativeThisType); } else { unset($nativeExpressionTypes['$this']); } if ($scopeClasses === ['static'] && $this->isInClass()) { $scopeClasses = [$this->getClassReflection()->getName()]; } return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $expressionTypes, $nativeExpressionTypes, $this->conditionalExpressions, $scopeClasses, $this->anonymousFunctionReflection); } public function restoreOriginalScopeAfterClosureBind(self $originalScope) : self { $expressionTypes = $this->expressionTypes; if (isset($originalScope->expressionTypes['$this'])) { $expressionTypes['$this'] = $originalScope->expressionTypes['$this']; } else { unset($expressionTypes['$this']); } $nativeExpressionTypes = $this->nativeExpressionTypes; if (isset($originalScope->nativeExpressionTypes['$this'])) { $nativeExpressionTypes['$this'] = $originalScope->nativeExpressionTypes['$this']; } else { unset($nativeExpressionTypes['$this']); } return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $expressionTypes, $nativeExpressionTypes, $this->conditionalExpressions, $originalScope->inClosureBindScopeClasses, $this->anonymousFunctionReflection); } public function restoreThis(self $restoreThisScope) : self { $expressionTypes = $this->expressionTypes; $nativeExpressionTypes = $this->nativeExpressionTypes; if ($restoreThisScope->isInClass()) { $nodeFinder = new NodeFinder(); $cb = static function ($expr) { return $expr instanceof Variable && $expr->name === 'this'; }; foreach ($restoreThisScope->expressionTypes as $exprString => $expressionTypeHolder) { $expr = $expressionTypeHolder->getExpr(); $thisExpr = $nodeFinder->findFirst([$expr], $cb); if ($thisExpr === null) { continue; } $expressionTypes[$exprString] = $expressionTypeHolder; } foreach ($restoreThisScope->nativeExpressionTypes as $exprString => $expressionTypeHolder) { $expr = $expressionTypeHolder->getExpr(); $thisExpr = $nodeFinder->findFirst([$expr], $cb); if ($thisExpr === null) { continue; } $nativeExpressionTypes[$exprString] = $expressionTypeHolder; } } else { unset($expressionTypes['$this']); unset($nativeExpressionTypes['$this']); } return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $expressionTypes, $nativeExpressionTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->inFirstLevelStatement, [], [], $this->inFunctionCallsStack, $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } public function enterClosureCall(Type $thisType, Type $nativeThisType) : self { $expressionTypes = $this->expressionTypes; $expressionTypes['$this'] = \PHPStan\Analyser\ExpressionTypeHolder::createYes(new Variable('this'), $thisType); $nativeExpressionTypes = $this->nativeExpressionTypes; $nativeExpressionTypes['$this'] = \PHPStan\Analyser\ExpressionTypeHolder::createYes(new Variable('this'), $nativeThisType); return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $expressionTypes, $nativeExpressionTypes, $this->conditionalExpressions, $thisType->getObjectClassNames(), $this->anonymousFunctionReflection); } /** @api */ public function isInClosureBind() : bool { return $this->inClosureBindScopeClasses !== []; } /** * @api * @param ParameterReflection[]|null $callableParameters */ public function enterAnonymousFunction(Expr\Closure $closure, ?array $callableParameters = null) : self { $anonymousFunctionReflection = $this->getType($closure); if (!$anonymousFunctionReflection instanceof ClosureType) { throw new ShouldNotHappenException(); } $scope = $this->enterAnonymousFunctionWithoutReflection($closure, $callableParameters); return $this->scopeFactory->create($scope->context, $scope->isDeclareStrictTypes(), $scope->getFunction(), $scope->getNamespace(), $scope->expressionTypes, $scope->nativeExpressionTypes, [], $scope->inClosureBindScopeClasses, $anonymousFunctionReflection, \true, [], [], $this->inFunctionCallsStack, \false, $this, $this->nativeTypesPromoted); } /** * @param ParameterReflection[]|null $callableParameters */ private function enterAnonymousFunctionWithoutReflection(Expr\Closure $closure, ?array $callableParameters = null) : self { $expressionTypes = []; $nativeTypes = []; foreach ($closure->params as $i => $parameter) { if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { throw new ShouldNotHappenException(); } $paramExprString = sprintf('$%s', $parameter->var->name); $isNullable = $this->isParameterValueNullable($parameter); $parameterType = $this->getFunctionType($parameter->type, $isNullable, $parameter->variadic); if ($callableParameters !== null) { if (isset($callableParameters[$i])) { $parameterType = self::intersectButNotNever($parameterType, $callableParameters[$i]->getType()); } elseif (count($callableParameters) > 0) { $lastParameter = $callableParameters[count($callableParameters) - 1]; if ($lastParameter->isVariadic()) { $parameterType = self::intersectButNotNever($parameterType, $lastParameter->getType()); } else { $parameterType = self::intersectButNotNever($parameterType, new MixedType()); } } else { $parameterType = self::intersectButNotNever($parameterType, new MixedType()); } } $holder = \PHPStan\Analyser\ExpressionTypeHolder::createYes($parameter->var, $parameterType); $expressionTypes[$paramExprString] = $holder; $nativeTypes[$paramExprString] = $holder; } $nonRefVariableNames = []; foreach ($closure->uses as $use) { if (!is_string($use->var->name)) { throw new ShouldNotHappenException(); } $variableName = $use->var->name; $paramExprString = '$' . $use->var->name; if ($use->byRef) { $holder = \PHPStan\Analyser\ExpressionTypeHolder::createYes($use->var, new MixedType()); $expressionTypes[$paramExprString] = $holder; $nativeTypes[$paramExprString] = $holder; continue; } $nonRefVariableNames[$variableName] = \true; if ($this->hasVariableType($variableName)->no()) { $variableType = new ErrorType(); $variableNativeType = new ErrorType(); } else { $variableType = $this->getVariableType($variableName); $variableNativeType = $this->getNativeType($use->var); } $expressionTypes[$paramExprString] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($use->var, $variableType); $nativeTypes[$paramExprString] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($use->var, $variableNativeType); } foreach ($this->invalidateStaticExpressions($this->expressionTypes) as $exprString => $typeHolder) { $expr = $typeHolder->getExpr(); if ($expr instanceof Variable) { continue; } $variables = (new NodeFinder())->findInstanceOf([$expr], Variable::class); if ($variables === [] && !$this->expressionTypeIsUnchangeable($typeHolder)) { continue; } foreach ($variables as $variable) { if (!$variable instanceof Variable) { continue 2; } if (!is_string($variable->name)) { continue 2; } if (!array_key_exists($variable->name, $nonRefVariableNames)) { continue 2; } } $expressionTypes[$exprString] = $typeHolder; } if ($this->hasVariableType('this')->yes() && !$closure->static) { $node = new Variable('this'); $expressionTypes['$this'] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($node, $this->getType($node)); $nativeTypes['$this'] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($node, $this->getNativeType($node)); } return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), array_merge($this->getConstantTypes(), $expressionTypes), array_merge($this->getNativeConstantTypes(), $nativeTypes), [], $this->inClosureBindScopeClasses, new TrivialParametersAcceptor(), \true, [], [], [], \false, $this, $this->nativeTypesPromoted); } private function expressionTypeIsUnchangeable(\PHPStan\Analyser\ExpressionTypeHolder $typeHolder) : bool { $expr = $typeHolder->getExpr(); $type = $typeHolder->getType(); return $expr instanceof FuncCall && !$expr->isFirstClassCallable() && $expr->name instanceof FullyQualified && $expr->name->toLowerString() === 'function_exists' && isset($expr->getArgs()[0]) && count($this->getType($expr->getArgs()[0]->value)->getConstantStrings()) === 1 && $type->isTrue()->yes(); } /** * @param array $expressionTypes * @return array */ private function invalidateStaticExpressions(array $expressionTypes) : array { $filteredExpressionTypes = []; $nodeFinder = new NodeFinder(); foreach ($expressionTypes as $exprString => $expressionType) { $staticExpression = $nodeFinder->findFirst([$expressionType->getExpr()], static function ($node) { return $node instanceof Expr\StaticCall || $node instanceof Expr\StaticPropertyFetch; }); if ($staticExpression !== null) { continue; } $filteredExpressionTypes[$exprString] = $expressionType; } return $filteredExpressionTypes; } /** * @api * @param ParameterReflection[]|null $callableParameters */ public function enterArrowFunction(Expr\ArrowFunction $arrowFunction, ?array $callableParameters = null) : self { $anonymousFunctionReflection = $this->getType($arrowFunction); if (!$anonymousFunctionReflection instanceof ClosureType) { throw new ShouldNotHappenException(); } $scope = $this->enterArrowFunctionWithoutReflection($arrowFunction, $callableParameters); return $this->scopeFactory->create($scope->context, $scope->isDeclareStrictTypes(), $scope->getFunction(), $scope->getNamespace(), $scope->expressionTypes, $scope->nativeExpressionTypes, $scope->conditionalExpressions, $scope->inClosureBindScopeClasses, $anonymousFunctionReflection, \true, [], [], $this->inFunctionCallsStack, $scope->afterExtractCall, $scope->parentScope, $this->nativeTypesPromoted); } /** * @param ParameterReflection[]|null $callableParameters */ private function enterArrowFunctionWithoutReflection(Expr\ArrowFunction $arrowFunction, ?array $callableParameters) : self { $arrowFunctionScope = $this; foreach ($arrowFunction->params as $i => $parameter) { if ($parameter->type === null) { $parameterType = new MixedType(); } else { $isNullable = $this->isParameterValueNullable($parameter); $parameterType = $this->getFunctionType($parameter->type, $isNullable, $parameter->variadic); } if ($callableParameters !== null) { if (isset($callableParameters[$i])) { $parameterType = self::intersectButNotNever($parameterType, $callableParameters[$i]->getType()); } elseif (count($callableParameters) > 0) { $lastParameter = $callableParameters[count($callableParameters) - 1]; if ($lastParameter->isVariadic()) { $parameterType = self::intersectButNotNever($parameterType, $lastParameter->getType()); } else { $parameterType = self::intersectButNotNever($parameterType, new MixedType()); } } else { $parameterType = self::intersectButNotNever($parameterType, new MixedType()); } } if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { throw new ShouldNotHappenException(); } $arrowFunctionScope = $arrowFunctionScope->assignVariable($parameter->var->name, $parameterType, $parameterType); } if ($arrowFunction->static) { $arrowFunctionScope = $arrowFunctionScope->invalidateExpression(new Variable('this')); } return $this->scopeFactory->create($arrowFunctionScope->context, $this->isDeclareStrictTypes(), $arrowFunctionScope->getFunction(), $arrowFunctionScope->getNamespace(), $this->invalidateStaticExpressions($arrowFunctionScope->expressionTypes), $arrowFunctionScope->nativeExpressionTypes, $arrowFunctionScope->conditionalExpressions, $arrowFunctionScope->inClosureBindScopeClasses, new TrivialParametersAcceptor(), \true, [], [], [], $arrowFunctionScope->afterExtractCall, $arrowFunctionScope->parentScope, $this->nativeTypesPromoted); } public function isParameterValueNullable(Node\Param $parameter) : bool { if ($parameter->default instanceof ConstFetch) { return strtolower((string) $parameter->default->name) === 'null'; } return \false; } /** * @api * @param Node\Name|Node\Identifier|Node\ComplexType|null $type */ public function getFunctionType($type, bool $isNullable, bool $isVariadic) : Type { if ($isNullable) { return TypeCombinator::addNull($this->getFunctionType($type, \false, $isVariadic)); } if ($isVariadic) { if ($this->phpVersion->supportsNamedArguments()) { return new ArrayType(new UnionType([new IntegerType(), new StringType()]), $this->getFunctionType($type, \false, \false)); } return AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), $this->getFunctionType($type, \false, \false))); } if ($type instanceof Name) { $className = (string) $type; $lowercasedClassName = strtolower($className); if ($lowercasedClassName === 'parent') { if ($this->isInClass() && $this->getClassReflection()->getParentClass() !== null) { return new ObjectType($this->getClassReflection()->getParentClass()->getName()); } return new NonexistentParentClassType(); } } return ParserNodeTypeToPHPStanType::resolve($type, $this->isInClass() ? $this->getClassReflection() : null); } private static function intersectButNotNever(Type $nativeType, Type $inferredType) : Type { if ($nativeType->isSuperTypeOf($inferredType)->no()) { return $nativeType; } $result = TypeCombinator::intersect($nativeType, $inferredType); if (TypeCombinator::containsNull($nativeType)) { return TypeCombinator::addNull($result); } return $result; } public function enterMatch(Expr\Match_ $expr) : self { if ($expr->cond instanceof Variable) { return $this; } if ($expr->cond instanceof AlwaysRememberedExpr) { $cond = $expr->cond->expr; } else { $cond = $expr->cond; } $type = $this->getType($cond); $nativeType = $this->getNativeType($cond); $condExpr = new AlwaysRememberedExpr($cond, $type, $nativeType); $expr->cond = $condExpr; return $this->assignExpression($condExpr, $type, $nativeType); } public function enterForeach(self $originalScope, Expr $iteratee, string $valueName, ?string $keyName) : self { $iterateeType = $originalScope->getType($iteratee); $nativeIterateeType = $originalScope->getNativeType($iteratee); $scope = $this->assignVariable($valueName, $originalScope->getIterableValueType($iterateeType), $originalScope->getIterableValueType($nativeIterateeType)); if ($keyName !== null) { $scope = $scope->enterForeachKey($originalScope, $iteratee, $keyName); } return $scope; } public function enterForeachKey(self $originalScope, Expr $iteratee, string $keyName) : self { $iterateeType = $originalScope->getType($iteratee); $nativeIterateeType = $originalScope->getNativeType($iteratee); $scope = $this->assignVariable($keyName, $originalScope->getIterableKeyType($iterateeType), $originalScope->getIterableKeyType($nativeIterateeType)); if ($iterateeType->isArray()->yes()) { $scope = $scope->assignExpression(new Expr\ArrayDimFetch($iteratee, new Variable($keyName)), $originalScope->getIterableValueType($iterateeType), $originalScope->getIterableValueType($nativeIterateeType)); } return $scope; } /** * @deprecated Use enterCatchType * @param Node\Name[] $classes */ public function enterCatch(array $classes, ?string $variableName) : self { $type = TypeCombinator::union(...array_map(static function (Node\Name $class) : ObjectType { return new ObjectType((string) $class); }, $classes)); return $this->enterCatchType($type, $variableName); } public function enterCatchType(Type $catchType, ?string $variableName) : self { if ($variableName === null) { return $this; } return $this->assignVariable($variableName, TypeCombinator::intersect($catchType, new ObjectType(Throwable::class)), TypeCombinator::intersect($catchType, new ObjectType(Throwable::class))); } public function enterExpressionAssign(Expr $expr) : self { $exprString = $this->getNodeKey($expr); $currentlyAssignedExpressions = $this->currentlyAssignedExpressions; $currentlyAssignedExpressions[$exprString] = \true; $scope = $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $this->expressionTypes, $this->nativeExpressionTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->isInFirstLevelStatement(), $currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, [], $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); $scope->resolvedTypes = $this->resolvedTypes; $scope->truthyScopes = $this->truthyScopes; $scope->falseyScopes = $this->falseyScopes; return $scope; } public function exitExpressionAssign(Expr $expr) : self { $exprString = $this->getNodeKey($expr); $currentlyAssignedExpressions = $this->currentlyAssignedExpressions; unset($currentlyAssignedExpressions[$exprString]); $scope = $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $this->expressionTypes, $this->nativeExpressionTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->isInFirstLevelStatement(), $currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, [], $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); $scope->resolvedTypes = $this->resolvedTypes; $scope->truthyScopes = $this->truthyScopes; $scope->falseyScopes = $this->falseyScopes; return $scope; } /** @api */ public function isInExpressionAssign(Expr $expr) : bool { $exprString = $this->getNodeKey($expr); return array_key_exists($exprString, $this->currentlyAssignedExpressions); } public function setAllowedUndefinedExpression(Expr $expr) : self { if ($this->phpVersion->deprecatesDynamicProperties() && $expr instanceof Expr\StaticPropertyFetch) { return $this; } $exprString = $this->getNodeKey($expr); $currentlyAllowedUndefinedExpressions = $this->currentlyAllowedUndefinedExpressions; $currentlyAllowedUndefinedExpressions[$exprString] = \true; $scope = $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $this->expressionTypes, $this->nativeExpressionTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->isInFirstLevelStatement(), $this->currentlyAssignedExpressions, $currentlyAllowedUndefinedExpressions, [], $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); $scope->resolvedTypes = $this->resolvedTypes; $scope->truthyScopes = $this->truthyScopes; $scope->falseyScopes = $this->falseyScopes; return $scope; } public function unsetAllowedUndefinedExpression(Expr $expr) : self { $exprString = $this->getNodeKey($expr); $currentlyAllowedUndefinedExpressions = $this->currentlyAllowedUndefinedExpressions; unset($currentlyAllowedUndefinedExpressions[$exprString]); $scope = $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $this->expressionTypes, $this->nativeExpressionTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->isInFirstLevelStatement(), $this->currentlyAssignedExpressions, $currentlyAllowedUndefinedExpressions, [], $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); $scope->resolvedTypes = $this->resolvedTypes; $scope->truthyScopes = $this->truthyScopes; $scope->falseyScopes = $this->falseyScopes; return $scope; } /** @api */ public function isUndefinedExpressionAllowed(Expr $expr) : bool { $exprString = $this->getNodeKey($expr); return array_key_exists($exprString, $this->currentlyAllowedUndefinedExpressions); } public function assignVariable(string $variableName, Type $type, Type $nativeType, ?TrinaryLogic $certainty = null) : self { $node = new Variable($variableName); $scope = $this->assignExpression($node, $type, $nativeType); if ($certainty !== null) { if ($certainty->no()) { throw new ShouldNotHappenException(); } elseif (!$certainty->yes()) { $exprString = '$' . $variableName; $scope->expressionTypes[$exprString] = new \PHPStan\Analyser\ExpressionTypeHolder($node, $type, $certainty); $scope->nativeExpressionTypes[$exprString] = new \PHPStan\Analyser\ExpressionTypeHolder($node, $nativeType, $certainty); } } $parameterOriginalValueExprString = $this->getNodeKey(new ParameterVariableOriginalValueExpr($variableName)); unset($scope->expressionTypes[$parameterOriginalValueExprString]); unset($scope->nativeExpressionTypes[$parameterOriginalValueExprString]); return $scope; } public function unsetExpression(Expr $expr) : self { $scope = $this; if ($expr instanceof Expr\ArrayDimFetch && $expr->dim !== null) { $exprVarType = $scope->getType($expr->var); $dimType = $scope->getType($expr->dim); $unsetType = $exprVarType->unsetOffset($dimType); $exprVarNativeType = $scope->getNativeType($expr->var); $dimNativeType = $scope->getNativeType($expr->dim); $unsetNativeType = $exprVarNativeType->unsetOffset($dimNativeType); $scope = $scope->assignExpression($expr->var, $unsetType, $unsetNativeType)->invalidateExpression(new FuncCall(new FullyQualified('count'), [new Arg($expr->var)]))->invalidateExpression(new FuncCall(new FullyQualified('sizeof'), [new Arg($expr->var)]))->invalidateExpression(new FuncCall(new Name('count'), [new Arg($expr->var)]))->invalidateExpression(new FuncCall(new Name('sizeof'), [new Arg($expr->var)])); if ($expr->var instanceof Expr\ArrayDimFetch && $expr->var->dim !== null) { $scope = $scope->assignExpression($expr->var->var, $this->getType($expr->var->var)->setOffsetValueType($scope->getType($expr->var->dim), $scope->getType($expr->var)), $this->getNativeType($expr->var->var)->setOffsetValueType($scope->getNativeType($expr->var->dim), $scope->getNativeType($expr->var))); } } return $scope->invalidateExpression($expr); } public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType, ?TrinaryLogic $certainty = null) : self { if ($expr instanceof ConstFetch) { $loweredConstName = strtolower($expr->name->toString()); if (in_array($loweredConstName, ['true', 'false', 'null'], \true)) { return $this; } } if ($expr instanceof FuncCall && $expr->name instanceof Name && $type->isFalse()->yes()) { $functionName = $this->reflectionProvider->resolveFunctionName($expr->name, $this); if ($functionName !== null && in_array(strtolower($functionName), ['is_dir', 'is_file', 'file_exists'], \true)) { return $this; } } $scope = $this; if ($expr instanceof Expr\ArrayDimFetch && $expr->dim !== null) { $dimType = $scope->getType($expr->dim)->toArrayKey(); if ($dimType instanceof ConstantIntegerType || $dimType instanceof ConstantStringType) { $exprVarType = $scope->getType($expr->var); if (!$exprVarType instanceof MixedType && !$exprVarType->isArray()->no()) { $types = [new ArrayType(new MixedType(), new MixedType()), new ObjectType(ArrayAccess::class), new NullType()]; if ($dimType instanceof ConstantIntegerType) { $types[] = new StringType(); } $scope = $scope->specifyExpressionType($expr->var, TypeCombinator::intersect(TypeCombinator::intersect($exprVarType, TypeCombinator::union(...$types)), new HasOffsetValueType($dimType, $type)), $scope->getNativeType($expr->var), $certainty); } } } if ($certainty === null) { $certainty = TrinaryLogic::createYes(); } elseif ($certainty->no()) { throw new ShouldNotHappenException(); } $exprString = $this->getNodeKey($expr); $expressionTypes = $scope->expressionTypes; $expressionTypes[$exprString] = new \PHPStan\Analyser\ExpressionTypeHolder($expr, $type, $certainty); $nativeTypes = $scope->nativeExpressionTypes; $nativeTypes[$exprString] = new \PHPStan\Analyser\ExpressionTypeHolder($expr, $nativeType, $certainty); $scope = $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $expressionTypes, $nativeTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->inFirstLevelStatement, $this->currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, $this->inFunctionCallsStack, $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); if ($expr instanceof AlwaysRememberedExpr) { return $scope->specifyExpressionType($expr->expr, $type, $nativeType, $certainty); } return $scope; } public function assignExpression(Expr $expr, Type $type, ?Type $nativeType = null) : self { if ($nativeType === null) { $nativeType = new MixedType(); } $scope = $this; if ($expr instanceof PropertyFetch) { $scope = $this->invalidateExpression($expr)->invalidateMethodsOnExpression($expr->var); } elseif ($expr instanceof Expr\StaticPropertyFetch) { $scope = $this->invalidateExpression($expr); } elseif ($expr instanceof Variable) { $scope = $this->invalidateExpression($expr); } return $scope->specifyExpressionType($expr, $type, $nativeType); } public function assignInitializedProperty(Type $fetchedOnType, string $propertyName) : self { if (!$this->isInClass()) { return $this; } if (TypeUtils::findThisType($fetchedOnType) === null) { return $this; } $propertyReflection = $this->getPropertyReflection($fetchedOnType, $propertyName); if ($propertyReflection === null) { return $this; } $declaringClass = $propertyReflection->getDeclaringClass(); if ($this->getClassReflection()->getName() !== $declaringClass->getName()) { return $this; } if (!$declaringClass->hasNativeProperty($propertyName)) { return $this; } return $this->assignExpression(new PropertyInitializationExpr($propertyName), new MixedType(), new MixedType()); } public function invalidateExpression(Expr $expressionToInvalidate, bool $requireMoreCharacters = \false) : self { $expressionTypes = $this->expressionTypes; $nativeExpressionTypes = $this->nativeExpressionTypes; $invalidated = \false; $exprStringToInvalidate = $this->getNodeKey($expressionToInvalidate); foreach ($expressionTypes as $exprString => $exprTypeHolder) { $exprExpr = $exprTypeHolder->getExpr(); if (!$this->shouldInvalidateExpression($exprStringToInvalidate, $expressionToInvalidate, $exprExpr, $requireMoreCharacters)) { continue; } unset($expressionTypes[$exprString]); unset($nativeExpressionTypes[$exprString]); $invalidated = \true; } $newConditionalExpressions = []; foreach ($this->conditionalExpressions as $conditionalExprString => $holders) { if (count($holders) === 0) { continue; } if ($this->shouldInvalidateExpression($exprStringToInvalidate, $expressionToInvalidate, $holders[array_key_first($holders)]->getTypeHolder()->getExpr())) { $invalidated = \true; continue; } foreach ($holders as $holder) { $conditionalTypeHolders = $holder->getConditionExpressionTypeHolders(); foreach ($conditionalTypeHolders as $conditionalTypeHolder) { if ($this->shouldInvalidateExpression($exprStringToInvalidate, $expressionToInvalidate, $conditionalTypeHolder->getExpr())) { $invalidated = \true; continue 3; } } } $newConditionalExpressions[$conditionalExprString] = $holders; } if (!$invalidated) { return $this; } return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $expressionTypes, $nativeExpressionTypes, $newConditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->inFirstLevelStatement, $this->currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, [], $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } private function shouldInvalidateExpression(string $exprStringToInvalidate, Expr $exprToInvalidate, Expr $expr, bool $requireMoreCharacters = \false) : bool { if ($requireMoreCharacters && $exprStringToInvalidate === $this->getNodeKey($expr)) { return \false; } // Variables will not contain traversable expressions. skip the NodeFinder overhead if ($expr instanceof Variable && is_string($expr->name) && !$requireMoreCharacters) { return $exprStringToInvalidate === $this->getNodeKey($expr); } $nodeFinder = new NodeFinder(); $expressionToInvalidateClass = get_class($exprToInvalidate); $found = $nodeFinder->findFirst([$expr], function (Node $node) use($expressionToInvalidateClass, $exprStringToInvalidate) : bool { if (!$node instanceof $expressionToInvalidateClass) { return \false; } $nodeString = $this->getNodeKey($node); return $nodeString === $exprStringToInvalidate; }); if ($found === null) { return \false; } if ($this->phpVersion->supportsReadOnlyProperties() && $expr instanceof PropertyFetch && $expr->name instanceof Node\Identifier && $requireMoreCharacters) { $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($expr, $this); if ($propertyReflection !== null) { $nativePropertyReflection = $propertyReflection->getNativeReflection(); if ($nativePropertyReflection !== null && $nativePropertyReflection->isReadOnly()) { return \false; } } } return \true; } private function invalidateMethodsOnExpression(Expr $expressionToInvalidate) : self { $exprStringToInvalidate = $this->getNodeKey($expressionToInvalidate); $expressionTypes = $this->expressionTypes; $nativeExpressionTypes = $this->nativeExpressionTypes; $invalidated = \false; $nodeFinder = new NodeFinder(); foreach ($expressionTypes as $exprString => $exprTypeHolder) { $expr = $exprTypeHolder->getExpr(); $found = $nodeFinder->findFirst([$expr], function (Node $node) use($exprStringToInvalidate) : bool { if (!$node instanceof MethodCall) { return \false; } return $this->getNodeKey($node->var) === $exprStringToInvalidate; }); if ($found === null) { continue; } unset($expressionTypes[$exprString]); unset($nativeExpressionTypes[$exprString]); $invalidated = \true; } if (!$invalidated) { return $this; } return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $expressionTypes, $nativeExpressionTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->inFirstLevelStatement, $this->currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, [], $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } private function setExpressionCertainty(Expr $expr, TrinaryLogic $certainty) : self { if ($this->hasExpressionType($expr)->no()) { throw new ShouldNotHappenException(); } $originalExprType = $this->getType($expr); $nativeType = $this->getNativeType($expr); return $this->specifyExpressionType($expr, $originalExprType, $nativeType, $certainty); } public function addTypeToExpression(Expr $expr, Type $type) : self { $originalExprType = $this->getType($expr); $nativeType = $this->getNativeType($expr); if ($originalExprType->equals($nativeType)) { $newType = TypeCombinator::intersect($type, $originalExprType); return $this->specifyExpressionType($expr, $newType, $newType); } return $this->specifyExpressionType($expr, TypeCombinator::intersect($type, $originalExprType), TypeCombinator::intersect($type, $nativeType)); } public function removeTypeFromExpression(Expr $expr, Type $typeToRemove) : self { $exprType = $this->getType($expr); if ($exprType instanceof NeverType || $typeToRemove instanceof NeverType) { return $this; } return $this->specifyExpressionType($expr, TypeCombinator::remove($exprType, $typeToRemove), TypeCombinator::remove($this->getNativeType($expr), $typeToRemove)); } /** * @api * @return MutatingScope */ public function filterByTruthyValue(Expr $expr) : \PHPStan\Analyser\Scope { $exprString = $this->getNodeKey($expr); if (array_key_exists($exprString, $this->truthyScopes)) { return $this->truthyScopes[$exprString]; } $specifiedTypes = $this->typeSpecifier->specifyTypesInCondition($this, $expr, \PHPStan\Analyser\TypeSpecifierContext::createTruthy()); $scope = $this->filterBySpecifiedTypes($specifiedTypes); $this->truthyScopes[$exprString] = $scope; return $scope; } /** * @api * @return MutatingScope */ public function filterByFalseyValue(Expr $expr) : \PHPStan\Analyser\Scope { $exprString = $this->getNodeKey($expr); if (array_key_exists($exprString, $this->falseyScopes)) { return $this->falseyScopes[$exprString]; } $specifiedTypes = $this->typeSpecifier->specifyTypesInCondition($this, $expr, \PHPStan\Analyser\TypeSpecifierContext::createFalsey()); $scope = $this->filterBySpecifiedTypes($specifiedTypes); $this->falseyScopes[$exprString] = $scope; return $scope; } public function filterBySpecifiedTypes(\PHPStan\Analyser\SpecifiedTypes $specifiedTypes) : self { $typeSpecifications = []; foreach ($specifiedTypes->getSureTypes() as $exprString => [$expr, $type]) { if ($expr instanceof Node\Scalar || $expr instanceof Array_ || $expr instanceof Expr\UnaryMinus && $expr->expr instanceof Node\Scalar) { continue; } $typeSpecifications[] = ['sure' => \true, 'exprString' => (string) $exprString, 'expr' => $expr, 'type' => $type]; } foreach ($specifiedTypes->getSureNotTypes() as $exprString => [$expr, $type]) { if ($expr instanceof Node\Scalar || $expr instanceof Array_ || $expr instanceof Expr\UnaryMinus && $expr->expr instanceof Node\Scalar) { continue; } $typeSpecifications[] = ['sure' => \false, 'exprString' => (string) $exprString, 'expr' => $expr, 'type' => $type]; } usort($typeSpecifications, static function (array $a, array $b) : int { $length = strlen($a['exprString']) - strlen($b['exprString']); if ($length !== 0) { return $length; } return $b['sure'] - $a['sure']; // @phpstan-ignore minus.leftNonNumeric, minus.rightNonNumeric }); $scope = $this; $specifiedExpressions = []; foreach ($typeSpecifications as $typeSpecification) { $expr = $typeSpecification['expr']; $type = $typeSpecification['type']; if ($expr instanceof IssetExpr) { $issetExpr = $expr; $expr = $issetExpr->getExpr(); if ($typeSpecification['sure']) { $scope = $scope->setExpressionCertainty($expr, TrinaryLogic::createMaybe()); } else { $scope = $scope->unsetExpression($expr); } continue; } if ($typeSpecification['sure']) { if ($specifiedTypes->shouldOverwrite()) { $scope = $scope->assignExpression($expr, $type, $type); } else { $scope = $scope->addTypeToExpression($expr, $type); } } else { $scope = $scope->removeTypeFromExpression($expr, $type); } $specifiedExpressions[$this->getNodeKey($expr)] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($expr, $scope->getType($expr)); } $conditions = []; foreach ($scope->conditionalExpressions as $conditionalExprString => $conditionalExpressions) { foreach ($conditionalExpressions as $conditionalExpression) { foreach ($conditionalExpression->getConditionExpressionTypeHolders() as $holderExprString => $conditionalTypeHolder) { if (!array_key_exists($holderExprString, $specifiedExpressions) || !$specifiedExpressions[$holderExprString]->equals($conditionalTypeHolder)) { continue 2; } } $conditions[$conditionalExprString][] = $conditionalExpression; $specifiedExpressions[$conditionalExprString] = $conditionalExpression->getTypeHolder(); } } foreach ($conditions as $conditionalExprString => $expressions) { $certainty = TrinaryLogic::lazyExtremeIdentity($expressions, static function (\PHPStan\Analyser\ConditionalExpressionHolder $holder) { return $holder->getTypeHolder()->getCertainty(); }); if ($certainty->no()) { unset($scope->expressionTypes[$conditionalExprString]); } else { $type = TypeCombinator::intersect(...array_map(static function (\PHPStan\Analyser\ConditionalExpressionHolder $holder) { return $holder->getTypeHolder()->getType(); }, $expressions)); $scope->expressionTypes[$conditionalExprString] = array_key_exists($conditionalExprString, $scope->expressionTypes) ? new \PHPStan\Analyser\ExpressionTypeHolder($scope->expressionTypes[$conditionalExprString]->getExpr(), TypeCombinator::intersect($scope->expressionTypes[$conditionalExprString]->getType(), $type), TrinaryLogic::maxMin($scope->expressionTypes[$conditionalExprString]->getCertainty(), $certainty)) : $expressions[0]->getTypeHolder(); } } return $scope->scopeFactory->create($scope->context, $scope->isDeclareStrictTypes(), $scope->getFunction(), $scope->getNamespace(), $scope->expressionTypes, $scope->nativeExpressionTypes, array_merge($specifiedTypes->getNewConditionalExpressionHolders(), $scope->conditionalExpressions), $scope->inClosureBindScopeClasses, $scope->anonymousFunctionReflection, $scope->inFirstLevelStatement, $scope->currentlyAssignedExpressions, $scope->currentlyAllowedUndefinedExpressions, $scope->inFunctionCallsStack, $scope->afterExtractCall, $scope->parentScope, $scope->nativeTypesPromoted); } /** * @param ConditionalExpressionHolder[] $conditionalExpressionHolders */ public function addConditionalExpressions(string $exprString, array $conditionalExpressionHolders) : self { $conditionalExpressions = $this->conditionalExpressions; $conditionalExpressions[$exprString] = $conditionalExpressionHolders; return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $this->expressionTypes, $this->nativeExpressionTypes, $conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->inFirstLevelStatement, $this->currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, $this->inFunctionCallsStack, $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } public function exitFirstLevelStatements() : self { if (!$this->inFirstLevelStatement) { return $this; } if ($this->scopeOutOfFirstLevelStatement !== null) { return $this->scopeOutOfFirstLevelStatement; } $scope = $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $this->expressionTypes, $this->nativeExpressionTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, \false, $this->currentlyAssignedExpressions, $this->currentlyAllowedUndefinedExpressions, $this->inFunctionCallsStack, $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); $scope->resolvedTypes = $this->resolvedTypes; $scope->truthyScopes = $this->truthyScopes; $scope->falseyScopes = $this->falseyScopes; $this->scopeOutOfFirstLevelStatement = $scope; return $scope; } /** @api */ public function isInFirstLevelStatement() : bool { return $this->inFirstLevelStatement; } public function mergeWith(?self $otherScope) : self { if ($otherScope === null) { return $this; } $ourExpressionTypes = $this->expressionTypes; $theirExpressionTypes = $otherScope->expressionTypes; $mergedExpressionTypes = $this->mergeVariableHolders($ourExpressionTypes, $theirExpressionTypes); $conditionalExpressions = $this->intersectConditionalExpressions($otherScope->conditionalExpressions); $conditionalExpressions = $this->createConditionalExpressions($conditionalExpressions, $ourExpressionTypes, $theirExpressionTypes, $mergedExpressionTypes); $conditionalExpressions = $this->createConditionalExpressions($conditionalExpressions, $theirExpressionTypes, $ourExpressionTypes, $mergedExpressionTypes); return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $mergedExpressionTypes, $this->mergeVariableHolders($this->nativeExpressionTypes, $otherScope->nativeExpressionTypes), $conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->inFirstLevelStatement, [], [], [], $this->afterExtractCall && $otherScope->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } /** * @param array $otherConditionalExpressions * @return array */ private function intersectConditionalExpressions(array $otherConditionalExpressions) : array { $newConditionalExpressions = []; foreach ($this->conditionalExpressions as $exprString => $holders) { if (!array_key_exists($exprString, $otherConditionalExpressions)) { continue; } $otherHolders = $otherConditionalExpressions[$exprString]; foreach (array_keys($holders) as $key) { if (!array_key_exists($key, $otherHolders)) { continue 2; } } $newConditionalExpressions[$exprString] = $holders; } return $newConditionalExpressions; } /** * @param array $conditionalExpressions * @param array $ourExpressionTypes * @param array $theirExpressionTypes * @param array $mergedExpressionTypes * @return array */ private function createConditionalExpressions(array $conditionalExpressions, array $ourExpressionTypes, array $theirExpressionTypes, array $mergedExpressionTypes) : array { $newVariableTypes = $ourExpressionTypes; foreach ($theirExpressionTypes as $exprString => $holder) { if (!array_key_exists($exprString, $mergedExpressionTypes)) { continue; } if (!$mergedExpressionTypes[$exprString]->getType()->equals($holder->getType())) { continue; } unset($newVariableTypes[$exprString]); } $typeGuards = []; foreach ($newVariableTypes as $exprString => $holder) { if (!$holder->getCertainty()->yes()) { continue; } if (!array_key_exists($exprString, $mergedExpressionTypes)) { continue; } if ($mergedExpressionTypes[$exprString]->getType()->equals($holder->getType())) { continue; } $typeGuards[$exprString] = $holder; } if (count($typeGuards) === 0) { return $conditionalExpressions; } foreach ($newVariableTypes as $exprString => $holder) { if (array_key_exists($exprString, $mergedExpressionTypes) && $mergedExpressionTypes[$exprString]->equals($holder)) { continue; } $variableTypeGuards = $typeGuards; unset($variableTypeGuards[$exprString]); if (count($variableTypeGuards) === 0) { continue; } $conditionalExpression = new \PHPStan\Analyser\ConditionalExpressionHolder($variableTypeGuards, $holder); $conditionalExpressions[$exprString][$conditionalExpression->getKey()] = $conditionalExpression; } foreach ($mergedExpressionTypes as $exprString => $mergedExprTypeHolder) { if (array_key_exists($exprString, $ourExpressionTypes)) { continue; } $conditionalExpression = new \PHPStan\Analyser\ConditionalExpressionHolder($typeGuards, new \PHPStan\Analyser\ExpressionTypeHolder($mergedExprTypeHolder->getExpr(), new ErrorType(), TrinaryLogic::createNo())); $conditionalExpressions[$exprString][$conditionalExpression->getKey()] = $conditionalExpression; } return $conditionalExpressions; } /** * @param array $ourVariableTypeHolders * @param array $theirVariableTypeHolders * @return array */ private function mergeVariableHolders(array $ourVariableTypeHolders, array $theirVariableTypeHolders) : array { $intersectedVariableTypeHolders = []; foreach ($ourVariableTypeHolders as $exprString => $variableTypeHolder) { if (isset($theirVariableTypeHolders[$exprString])) { $intersectedVariableTypeHolders[$exprString] = $variableTypeHolder->and($theirVariableTypeHolders[$exprString]); } else { $intersectedVariableTypeHolders[$exprString] = \PHPStan\Analyser\ExpressionTypeHolder::createMaybe($variableTypeHolder->getExpr(), $variableTypeHolder->getType()); } } foreach ($theirVariableTypeHolders as $exprString => $variableTypeHolder) { if (isset($intersectedVariableTypeHolders[$exprString])) { continue; } $intersectedVariableTypeHolders[$exprString] = \PHPStan\Analyser\ExpressionTypeHolder::createMaybe($variableTypeHolder->getExpr(), $variableTypeHolder->getType()); } return $intersectedVariableTypeHolders; } public function mergeInitializedProperties(self $calledMethodScope) : self { $scope = $this; foreach ($calledMethodScope->expressionTypes as $exprString => $typeHolder) { $exprString = (string) $exprString; if (!str_starts_with($exprString, '__phpstanPropertyInitialization(')) { continue; } $propertyName = substr($exprString, strlen('__phpstanPropertyInitialization('), -1); $propertyExpr = new PropertyInitializationExpr($propertyName); if (!array_key_exists($exprString, $scope->expressionTypes)) { $scope = $scope->assignExpression($propertyExpr, new MixedType(), new MixedType()); $scope->expressionTypes[$exprString] = $typeHolder; continue; } $certainty = $scope->expressionTypes[$exprString]->getCertainty(); $scope = $scope->assignExpression($propertyExpr, new MixedType(), new MixedType()); $scope->expressionTypes[$exprString] = new \PHPStan\Analyser\ExpressionTypeHolder($typeHolder->getExpr(), $typeHolder->getType(), $typeHolder->getCertainty()->or($certainty)); } return $scope; } public function processFinallyScope(self $finallyScope, self $originalFinallyScope) : self { return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $this->processFinallyScopeVariableTypeHolders($this->expressionTypes, $finallyScope->expressionTypes, $originalFinallyScope->expressionTypes), $this->processFinallyScopeVariableTypeHolders($this->nativeExpressionTypes, $finallyScope->nativeExpressionTypes, $originalFinallyScope->nativeExpressionTypes), $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->inFirstLevelStatement, [], [], [], $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } /** * @param array $ourVariableTypeHolders * @param array $finallyVariableTypeHolders * @param array $originalVariableTypeHolders * @return array */ private function processFinallyScopeVariableTypeHolders(array $ourVariableTypeHolders, array $finallyVariableTypeHolders, array $originalVariableTypeHolders) : array { foreach ($finallyVariableTypeHolders as $exprString => $variableTypeHolder) { if (isset($originalVariableTypeHolders[$exprString]) && !$originalVariableTypeHolders[$exprString]->getType()->equals($variableTypeHolder->getType())) { $ourVariableTypeHolders[$exprString] = $variableTypeHolder; continue; } if (isset($originalVariableTypeHolders[$exprString])) { continue; } $ourVariableTypeHolders[$exprString] = $variableTypeHolder; } return $ourVariableTypeHolders; } /** * @param Expr\ClosureUse[] $byRefUses */ public function processClosureScope(self $closureScope, ?self $prevScope, array $byRefUses) : self { $nativeExpressionTypes = $this->nativeExpressionTypes; $expressionTypes = $this->expressionTypes; if (count($byRefUses) === 0) { return $this; } foreach ($byRefUses as $use) { if (!is_string($use->var->name)) { throw new ShouldNotHappenException(); } $variableName = $use->var->name; $variableExprString = '$' . $variableName; if (!$closureScope->hasVariableType($variableName)->yes()) { $holder = \PHPStan\Analyser\ExpressionTypeHolder::createYes($use->var, new NullType()); $expressionTypes[$variableExprString] = $holder; $nativeExpressionTypes[$variableExprString] = $holder; continue; } $variableType = $closureScope->getVariableType($variableName); if ($prevScope !== null) { $prevVariableType = $prevScope->getVariableType($variableName); if (!$variableType->equals($prevVariableType)) { $variableType = TypeCombinator::union($variableType, $prevVariableType); $variableType = self::generalizeType($variableType, $prevVariableType, 0); } } $expressionTypes[$variableExprString] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($use->var, $variableType); $nativeExpressionTypes[$variableExprString] = \PHPStan\Analyser\ExpressionTypeHolder::createYes($use->var, $variableType); } return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $expressionTypes, $nativeExpressionTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->inFirstLevelStatement, [], [], $this->inFunctionCallsStack, $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } public function processAlwaysIterableForeachScopeWithoutPollute(self $finalScope) : self { $expressionTypes = $this->expressionTypes; foreach ($finalScope->expressionTypes as $variableExprString => $variableTypeHolder) { if (!isset($expressionTypes[$variableExprString])) { $expressionTypes[$variableExprString] = \PHPStan\Analyser\ExpressionTypeHolder::createMaybe($variableTypeHolder->getExpr(), $variableTypeHolder->getType()); continue; } $expressionTypes[$variableExprString] = new \PHPStan\Analyser\ExpressionTypeHolder($variableTypeHolder->getExpr(), $variableTypeHolder->getType(), $variableTypeHolder->getCertainty()->and($expressionTypes[$variableExprString]->getCertainty())); } $nativeTypes = $this->nativeExpressionTypes; foreach ($finalScope->nativeExpressionTypes as $variableExprString => $variableTypeHolder) { if (!isset($nativeTypes[$variableExprString])) { $nativeTypes[$variableExprString] = \PHPStan\Analyser\ExpressionTypeHolder::createMaybe($variableTypeHolder->getExpr(), $variableTypeHolder->getType()); continue; } $nativeTypes[$variableExprString] = new \PHPStan\Analyser\ExpressionTypeHolder($variableTypeHolder->getExpr(), $variableTypeHolder->getType(), $variableTypeHolder->getCertainty()->and($nativeTypes[$variableExprString]->getCertainty())); } return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $expressionTypes, $nativeTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->inFirstLevelStatement, [], [], [], $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } public function generalizeWith(self $otherScope) : self { $variableTypeHolders = $this->generalizeVariableTypeHolders($this->expressionTypes, $otherScope->expressionTypes); $nativeTypes = $this->generalizeVariableTypeHolders($this->nativeExpressionTypes, $otherScope->nativeExpressionTypes); return $this->scopeFactory->create($this->context, $this->isDeclareStrictTypes(), $this->getFunction(), $this->getNamespace(), $variableTypeHolders, $nativeTypes, $this->conditionalExpressions, $this->inClosureBindScopeClasses, $this->anonymousFunctionReflection, $this->inFirstLevelStatement, [], [], [], $this->afterExtractCall, $this->parentScope, $this->nativeTypesPromoted); } /** * @param array $variableTypeHolders * @param array $otherVariableTypeHolders * @return array */ private function generalizeVariableTypeHolders(array $variableTypeHolders, array $otherVariableTypeHolders) : array { foreach ($variableTypeHolders as $variableExprString => $variableTypeHolder) { if (!isset($otherVariableTypeHolders[$variableExprString])) { continue; } $variableTypeHolders[$variableExprString] = new \PHPStan\Analyser\ExpressionTypeHolder($variableTypeHolder->getExpr(), self::generalizeType($variableTypeHolder->getType(), $otherVariableTypeHolders[$variableExprString]->getType(), 0), $variableTypeHolder->getCertainty()); } return $variableTypeHolders; } private static function generalizeType(Type $a, Type $b, int $depth) : Type { if ($a->equals($b)) { return $a; } $constantIntegers = ['a' => [], 'b' => []]; $constantFloats = ['a' => [], 'b' => []]; $constantBooleans = ['a' => [], 'b' => []]; $constantStrings = ['a' => [], 'b' => []]; $constantArrays = ['a' => [], 'b' => []]; $generalArrays = ['a' => [], 'b' => []]; $integerRanges = ['a' => [], 'b' => []]; $otherTypes = []; foreach (['a' => TypeUtils::flattenTypes($a), 'b' => TypeUtils::flattenTypes($b)] as $key => $types) { foreach ($types as $type) { if ($type instanceof ConstantIntegerType) { $constantIntegers[$key][] = $type; continue; } if ($type instanceof ConstantFloatType) { $constantFloats[$key][] = $type; continue; } if ($type instanceof ConstantBooleanType) { $constantBooleans[$key][] = $type; continue; } if ($type instanceof ConstantStringType) { $constantStrings[$key][] = $type; continue; } if ($type->isConstantArray()->yes()) { $constantArrays[$key][] = $type; continue; } if ($type->isArray()->yes()) { $generalArrays[$key][] = $type; continue; } if ($type instanceof IntegerRangeType) { $integerRanges[$key][] = $type; continue; } $otherTypes[] = $type; } } $resultTypes = []; foreach ([$constantFloats, $constantBooleans, $constantStrings] as $constantTypes) { if (count($constantTypes['a']) === 0) { if (count($constantTypes['b']) > 0) { $resultTypes[] = TypeCombinator::union(...$constantTypes['b']); } continue; } elseif (count($constantTypes['b']) === 0) { $resultTypes[] = TypeCombinator::union(...$constantTypes['a']); continue; } $aTypes = TypeCombinator::union(...$constantTypes['a']); $bTypes = TypeCombinator::union(...$constantTypes['b']); if ($aTypes->equals($bTypes)) { $resultTypes[] = $aTypes; continue; } $resultTypes[] = TypeCombinator::union(...$constantTypes['a'], ...$constantTypes['b'])->generalize(GeneralizePrecision::moreSpecific()); } if (count($constantArrays['a']) > 0) { if (count($constantArrays['b']) === 0) { $resultTypes[] = TypeCombinator::union(...$constantArrays['a']); } else { $constantArraysA = TypeCombinator::union(...$constantArrays['a']); $constantArraysB = TypeCombinator::union(...$constantArrays['b']); if ($constantArraysA->getIterableKeyType()->equals($constantArraysB->getIterableKeyType()) && $constantArraysA->getArraySize()->getGreaterOrEqualType()->isSuperTypeOf($constantArraysB->getArraySize())->yes()) { $resultArrayBuilder = ConstantArrayTypeBuilder::createEmpty(); foreach (TypeUtils::flattenTypes($constantArraysA->getIterableKeyType()) as $keyType) { $resultArrayBuilder->setOffsetValueType($keyType, self::generalizeType($constantArraysA->getOffsetValueType($keyType), $constantArraysB->getOffsetValueType($keyType), $depth + 1), !$constantArraysA->hasOffsetValueType($keyType)->and($constantArraysB->hasOffsetValueType($keyType))->negate()->no()); } $resultTypes[] = $resultArrayBuilder->getArray(); } else { $resultType = new ArrayType(TypeCombinator::union(self::generalizeType($constantArraysA->getIterableKeyType(), $constantArraysB->getIterableKeyType(), $depth + 1)), TypeCombinator::union(self::generalizeType($constantArraysA->getIterableValueType(), $constantArraysB->getIterableValueType(), $depth + 1))); if ($constantArraysA->isIterableAtLeastOnce()->yes() && $constantArraysB->isIterableAtLeastOnce()->yes() && $constantArraysA->getArraySize()->getGreaterOrEqualType()->isSuperTypeOf($constantArraysB->getArraySize())->yes()) { $resultType = TypeCombinator::intersect($resultType, new NonEmptyArrayType()); } if ($constantArraysA->isList()->yes() && $constantArraysB->isList()->yes()) { $resultType = AccessoryArrayListType::intersectWith($resultType); } $resultTypes[] = $resultType; } } } elseif (count($constantArrays['b']) > 0) { $resultTypes[] = TypeCombinator::union(...$constantArrays['b']); } if (count($generalArrays['a']) > 0) { if (count($generalArrays['b']) === 0) { $resultTypes[] = TypeCombinator::union(...$generalArrays['a']); } else { $generalArraysA = TypeCombinator::union(...$generalArrays['a']); $generalArraysB = TypeCombinator::union(...$generalArrays['b']); $aValueType = $generalArraysA->getIterableValueType(); $bValueType = $generalArraysB->getIterableValueType(); if ($aValueType->isArray()->yes() && $aValueType->isConstantArray()->no() && $bValueType->isArray()->yes() && $bValueType->isConstantArray()->no()) { $aDepth = self::getArrayDepth($aValueType) + $depth; $bDepth = self::getArrayDepth($bValueType) + $depth; if (($aDepth > 2 || $bDepth > 2) && abs($aDepth - $bDepth) > 0) { $aValueType = new MixedType(); $bValueType = new MixedType(); } } $resultType = new ArrayType(TypeCombinator::union(self::generalizeType($generalArraysA->getIterableKeyType(), $generalArraysB->getIterableKeyType(), $depth + 1)), TypeCombinator::union(self::generalizeType($aValueType, $bValueType, $depth + 1))); if ($generalArraysA->isIterableAtLeastOnce()->yes() && $generalArraysB->isIterableAtLeastOnce()->yes()) { $resultType = TypeCombinator::intersect($resultType, new NonEmptyArrayType()); } if ($generalArraysA->isList()->yes() && $generalArraysB->isList()->yes()) { $resultType = AccessoryArrayListType::intersectWith($resultType); } if ($generalArraysA->isOversizedArray()->yes() && $generalArraysB->isOversizedArray()->yes()) { $resultType = TypeCombinator::intersect($resultType, new OversizedArrayType()); } $resultTypes[] = $resultType; } } elseif (count($generalArrays['b']) > 0) { $resultTypes[] = TypeCombinator::union(...$generalArrays['b']); } if (count($constantIntegers['a']) > 0) { if (count($constantIntegers['b']) === 0) { $resultTypes[] = TypeCombinator::union(...$constantIntegers['a']); } else { $constantIntegersA = TypeCombinator::union(...$constantIntegers['a']); $constantIntegersB = TypeCombinator::union(...$constantIntegers['b']); if ($constantIntegersA->equals($constantIntegersB)) { $resultTypes[] = $constantIntegersA; } else { $min = null; $max = null; foreach ($constantIntegers['a'] as $int) { if ($min === null || $int->getValue() < $min) { $min = $int->getValue(); } if ($max !== null && $int->getValue() <= $max) { continue; } $max = $int->getValue(); } $gotGreater = \false; $gotSmaller = \false; foreach ($constantIntegers['b'] as $int) { if ($int->getValue() > $max) { $gotGreater = \true; } if ($int->getValue() >= $min) { continue; } $gotSmaller = \true; } if ($gotGreater && $gotSmaller) { $resultTypes[] = new IntegerType(); } elseif ($gotGreater) { $resultTypes[] = IntegerRangeType::fromInterval($min, null); } elseif ($gotSmaller) { $resultTypes[] = IntegerRangeType::fromInterval(null, $max); } else { $resultTypes[] = TypeCombinator::union($constantIntegersA, $constantIntegersB); } } } } elseif (count($constantIntegers['b']) > 0) { $resultTypes[] = TypeCombinator::union(...$constantIntegers['b']); } if (count($integerRanges['a']) > 0) { if (count($integerRanges['b']) === 0) { $resultTypes[] = TypeCombinator::union(...$integerRanges['a']); } else { $integerRangesA = TypeCombinator::union(...$integerRanges['a']); $integerRangesB = TypeCombinator::union(...$integerRanges['b']); if ($integerRangesA->equals($integerRangesB)) { $resultTypes[] = $integerRangesA; } else { $min = null; $max = null; foreach ($integerRanges['a'] as $range) { if ($range->getMin() === null) { $rangeMin = PHP_INT_MIN; } else { $rangeMin = $range->getMin(); } if ($range->getMax() === null) { $rangeMax = PHP_INT_MAX; } else { $rangeMax = $range->getMax(); } if ($min === null || $rangeMin < $min) { $min = $rangeMin; } if ($max !== null && $rangeMax <= $max) { continue; } $max = $rangeMax; } $gotGreater = \false; $gotSmaller = \false; foreach ($integerRanges['b'] as $range) { if ($range->getMin() === null) { $rangeMin = PHP_INT_MIN; } else { $rangeMin = $range->getMin(); } if ($range->getMax() === null) { $rangeMax = PHP_INT_MAX; } else { $rangeMax = $range->getMax(); } if ($rangeMax > $max) { $gotGreater = \true; } if ($rangeMin >= $min) { continue; } $gotSmaller = \true; } if ($min === PHP_INT_MIN) { $min = null; } if ($max === PHP_INT_MAX) { $max = null; } if ($gotGreater && $gotSmaller) { $resultTypes[] = new IntegerType(); } elseif ($gotGreater) { $resultTypes[] = IntegerRangeType::fromInterval($min, null); } elseif ($gotSmaller) { $resultTypes[] = IntegerRangeType::fromInterval(null, $max); } else { $resultTypes[] = TypeCombinator::union($integerRangesA, $integerRangesB); } } } } elseif (count($integerRanges['b']) > 0) { $resultTypes[] = TypeCombinator::union(...$integerRanges['b']); } $accessoryTypes = array_map(static function (Type $type) : Type { return $type->generalize(GeneralizePrecision::moreSpecific()); }, TypeUtils::getAccessoryTypes($a)); return TypeCombinator::union(TypeCombinator::intersect(TypeCombinator::union(...$resultTypes, ...$otherTypes), ...$accessoryTypes), ...$otherTypes); } private static function getArrayDepth(Type $type) : int { $depth = 0; $arrays = TypeUtils::getAnyArrays($type); while (count($arrays) > 0) { $temp = $type->getIterableValueType(); $type = $temp; $arrays = TypeUtils::getAnyArrays($type); $depth++; } return $depth; } public function equals(self $otherScope) : bool { if (!$this->context->equals($otherScope->context)) { return \false; } if (!$this->compareVariableTypeHolders($this->expressionTypes, $otherScope->expressionTypes)) { return \false; } return $this->compareVariableTypeHolders($this->nativeExpressionTypes, $otherScope->nativeExpressionTypes); } /** * @param array $variableTypeHolders * @param array $otherVariableTypeHolders */ private function compareVariableTypeHolders(array $variableTypeHolders, array $otherVariableTypeHolders) : bool { if (count($variableTypeHolders) !== count($otherVariableTypeHolders)) { return \false; } foreach ($variableTypeHolders as $variableExprString => $variableTypeHolder) { if (!isset($otherVariableTypeHolders[$variableExprString])) { return \false; } if (!$variableTypeHolder->getCertainty()->equals($otherVariableTypeHolders[$variableExprString]->getCertainty())) { return \false; } if (!$variableTypeHolder->getType()->equals($otherVariableTypeHolders[$variableExprString]->getType())) { return \false; } unset($otherVariableTypeHolders[$variableExprString]); } return \true; } private function getBooleanExpressionDepth(Expr $expr, int $depth = 0) : int { while ($expr instanceof BinaryOp\BooleanOr || $expr instanceof BinaryOp\LogicalOr || $expr instanceof BinaryOp\BooleanAnd || $expr instanceof BinaryOp\LogicalAnd) { return $this->getBooleanExpressionDepth($expr->left, $depth + 1); } return $depth; } /** @api */ public function canAccessProperty(PropertyReflection $propertyReflection) : bool { return $this->canAccessClassMember($propertyReflection); } /** @api */ public function canCallMethod(MethodReflection $methodReflection) : bool { if ($this->canAccessClassMember($methodReflection)) { return \true; } return $this->canAccessClassMember($methodReflection->getPrototype()); } /** @api */ public function canAccessConstant(ConstantReflection $constantReflection) : bool { return $this->canAccessClassMember($constantReflection); } private function canAccessClassMember(ClassMemberReflection $classMemberReflection) : bool { if ($classMemberReflection->isPublic()) { return \true; } $classReflectionName = $classMemberReflection->getDeclaringClass()->getName(); $canAccessClassMember = static function (ClassReflection $classReflection) use($classMemberReflection, $classReflectionName) { if ($classMemberReflection->isPrivate()) { return $classReflection->getName() === $classReflectionName; } // protected if ($classReflection->getName() === $classReflectionName || $classReflection->isSubclassOf($classReflectionName)) { return \true; } return $classMemberReflection->getDeclaringClass()->isSubclassOf($classReflection->getName()); }; foreach ($this->inClosureBindScopeClasses as $inClosureBindScopeClass) { if (!$this->reflectionProvider->hasClass($inClosureBindScopeClass)) { continue; } if ($canAccessClassMember($this->reflectionProvider->getClass($inClosureBindScopeClass))) { return \true; } } if ($this->isInClass()) { return $canAccessClassMember($this->getClassReflection()); } return \false; } /** * @return string[] */ public function debug() : array { $descriptions = []; foreach ($this->expressionTypes as $name => $variableTypeHolder) { $key = sprintf('%s (%s)', $name, $variableTypeHolder->getCertainty()->describe()); $descriptions[$key] = $variableTypeHolder->getType()->describe(VerbosityLevel::precise()); } foreach ($this->nativeExpressionTypes as $exprString => $nativeTypeHolder) { $key = sprintf('native %s (%s)', $exprString, $nativeTypeHolder->getCertainty()->describe()); $descriptions[$key] = $nativeTypeHolder->getType()->describe(VerbosityLevel::precise()); } foreach ($this->conditionalExpressions as $exprString => $holders) { foreach (array_values($holders) as $i => $holder) { $key = sprintf('condition about %s #%d', $exprString, $i + 1); $parts = []; foreach ($holder->getConditionExpressionTypeHolders() as $conditionalExprString => $expressionTypeHolder) { $parts[] = $conditionalExprString . '=' . $expressionTypeHolder->getType()->describe(VerbosityLevel::precise()); } $condition = implode(' && ', $parts); $descriptions[$key] = sprintf('if %s then %s is %s (%s)', $condition, $exprString, $holder->getTypeHolder()->getType()->describe(VerbosityLevel::precise()), $holder->getTypeHolder()->getCertainty()->describe()); } } return $descriptions; } /** * @param non-empty-string $className */ private function exactInstantiation(New_ $node, string $className) : ?Type { $resolvedClassName = $this->resolveExactName(new Name($className)); $isStatic = \false; if ($resolvedClassName === null) { if (strtolower($className) !== 'static') { return null; } if (!$this->isInClass()) { return null; } $resolvedClassName = $this->getClassReflection()->getName(); $isStatic = \true; } if (!$this->reflectionProvider->hasClass($resolvedClassName)) { return null; } $classReflection = $this->reflectionProvider->getClass($resolvedClassName); if ($classReflection->hasConstructor()) { $constructorMethod = $classReflection->getConstructor(); } else { $constructorMethod = new DummyConstructorReflection($classReflection); } $resolvedTypes = []; $methodCall = new Expr\StaticCall(new Name($resolvedClassName), new Node\Identifier($constructorMethod->getName()), $node->getArgs()); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($this, $methodCall->getArgs(), $constructorMethod->getVariants(), $constructorMethod->getNamedArgumentsVariants()); $normalizedMethodCall = \PHPStan\Analyser\ArgumentsNormalizer::reorderStaticCallArguments($parametersAcceptor, $methodCall); if ($normalizedMethodCall !== null) { foreach ($this->dynamicReturnTypeExtensionRegistry->getDynamicStaticMethodReturnTypeExtensionsForClass($classReflection->getName()) as $dynamicStaticMethodReturnTypeExtension) { if (!$dynamicStaticMethodReturnTypeExtension->isStaticMethodSupported($constructorMethod)) { continue; } $resolvedType = $dynamicStaticMethodReturnTypeExtension->getTypeFromStaticMethodCall($constructorMethod, $normalizedMethodCall, $this); if ($resolvedType === null) { continue; } $resolvedTypes[] = $resolvedType; } } if (count($resolvedTypes) > 0) { return TypeCombinator::union(...$resolvedTypes); } $methodResult = $this->getType($methodCall); if ($methodResult instanceof NeverType && $methodResult->isExplicit()) { return $methodResult; } $objectType = $isStatic ? new StaticType($classReflection) : new ObjectType($resolvedClassName); if (!$classReflection->isGeneric()) { return $objectType; } $assignedToProperty = $node->getAttribute(NewAssignedToPropertyVisitor::ATTRIBUTE_NAME); if ($assignedToProperty !== null) { $constructorVariant = $constructorMethod->getOnlyVariant(); $classTemplateTypes = $classReflection->getTemplateTypeMap()->getTypes(); $originalClassTemplateTypes = $classTemplateTypes; foreach ($constructorVariant->getParameters() as $parameter) { TypeTraverser::map($parameter->getType(), static function (Type $type, callable $traverse) use(&$classTemplateTypes) : Type { if ($type instanceof TemplateType && array_key_exists($type->getName(), $classTemplateTypes)) { $classTemplateType = $classTemplateTypes[$type->getName()]; if ($classTemplateType instanceof TemplateType && $classTemplateType->getScope()->equals($type->getScope())) { unset($classTemplateTypes[$type->getName()]); } return $type; } return $traverse($type); }); } if (count($classTemplateTypes) === count($originalClassTemplateTypes)) { $propertyType = TypeCombinator::removeNull($this->getType($assignedToProperty)); if ($objectType->isSuperTypeOf($propertyType)->yes()) { return $propertyType; } } } if ($constructorMethod instanceof DummyConstructorReflection) { if ($isStatic) { return new GenericStaticType($classReflection, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()), null, []); } return new GenericObjectType($resolvedClassName, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds())); } if ($constructorMethod->getDeclaringClass()->getName() !== $classReflection->getName()) { if (!$constructorMethod->getDeclaringClass()->isGeneric()) { if ($isStatic) { return new GenericStaticType($classReflection, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()), null, []); } return new GenericObjectType($resolvedClassName, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds())); } $newType = new GenericObjectType($resolvedClassName, $classReflection->typeMapToList($classReflection->getTemplateTypeMap())); $ancestorType = $newType->getAncestorWithClassName($constructorMethod->getDeclaringClass()->getName()); if ($ancestorType === null) { if ($isStatic) { return new GenericStaticType($classReflection, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()), null, []); } return new GenericObjectType($resolvedClassName, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds())); } $ancestorClassReflections = $ancestorType->getObjectClassReflections(); if (count($ancestorClassReflections) !== 1) { if ($isStatic) { return new GenericStaticType($classReflection, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()), null, []); } return new GenericObjectType($resolvedClassName, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds())); } $newParentNode = new New_(new Name($constructorMethod->getDeclaringClass()->getName()), $node->args); $newParentType = $this->getType($newParentNode); $newParentTypeClassReflections = $newParentType->getObjectClassReflections(); if (count($newParentTypeClassReflections) !== 1) { if ($isStatic) { return new GenericStaticType($classReflection, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()), null, []); } return new GenericObjectType($resolvedClassName, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds())); } $newParentTypeClassReflection = $newParentTypeClassReflections[0]; $ancestorClassReflection = $ancestorClassReflections[0]; $ancestorMapping = []; foreach ($ancestorClassReflection->getActiveTemplateTypeMap()->getTypes() as $typeName => $templateType) { if (!$templateType instanceof TemplateType) { continue; } $ancestorMapping[$typeName] = $templateType; } $resolvedTypeMap = []; foreach ($newParentTypeClassReflection->getActiveTemplateTypeMap()->getTypes() as $typeName => $type) { if (!array_key_exists($typeName, $ancestorMapping)) { continue; } $ancestorType = $ancestorMapping[$typeName]; if (!$ancestorType->getBound()->isSuperTypeOf($type)->yes()) { continue; } if (!array_key_exists($ancestorType->getName(), $resolvedTypeMap)) { $resolvedTypeMap[$ancestorType->getName()] = $type; continue; } $resolvedTypeMap[$ancestorType->getName()] = TypeCombinator::union($resolvedTypeMap[$ancestorType->getName()], $type); } if ($isStatic) { return new GenericStaticType($classReflection, $classReflection->typeMapToList(new TemplateTypeMap($resolvedTypeMap)), null, []); } return new GenericObjectType($resolvedClassName, $classReflection->typeMapToList(new TemplateTypeMap($resolvedTypeMap))); } $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($this, $methodCall->getArgs(), $constructorMethod->getVariants(), $constructorMethod->getNamedArgumentsVariants()); if ($this->explicitMixedInUnknownGenericNew) { $resolvedTemplateTypeMap = $parametersAcceptor->getResolvedTemplateTypeMap(); $newGenericType = new GenericObjectType($resolvedClassName, $classReflection->typeMapToList($classReflection->getTemplateTypeMap())); if ($isStatic) { $newGenericType = new GenericStaticType($classReflection, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()), null, []); } return TypeTraverser::map($newGenericType, static function (Type $type, callable $traverse) use($resolvedTemplateTypeMap) : Type { if ($type instanceof TemplateType && !$type->isArgument()) { $newType = $resolvedTemplateTypeMap->getType($type->getName()); if ($newType === null || $newType instanceof ErrorType) { return $type->getBound(); } return TemplateTypeHelper::generalizeInferredTemplateType($type, $newType); } return $traverse($type); }); } $resolvedPhpDoc = $classReflection->getResolvedPhpDoc(); if ($resolvedPhpDoc === null) { return $objectType; } $list = []; $typeMap = $parametersAcceptor->getResolvedTemplateTypeMap(); foreach ($resolvedPhpDoc->getTemplateTags() as $tag) { $templateType = $typeMap->getType($tag->getName()); if ($templateType !== null) { $list[] = $templateType; continue; } $default = $tag->getDefault(); if ($default !== null) { $list[] = $default; continue; } $bound = $tag->getBound(); if ($bound instanceof MixedType && $bound->isExplicitMixed()) { $bound = new MixedType(\false); } $list[] = $bound; } if ($isStatic) { return new GenericStaticType($classReflection, $list, null, []); } return new GenericObjectType($resolvedClassName, $list); } private function filterTypeWithMethod(Type $typeWithMethod, string $methodName) : ?Type { if ($typeWithMethod instanceof UnionType) { $typeWithMethod = $typeWithMethod->filterTypes(static function (Type $innerType) use($methodName) { return $innerType->hasMethod($methodName)->yes(); }); } if (!$typeWithMethod->hasMethod($methodName)->yes()) { return null; } return $typeWithMethod; } /** @api */ public function getMethodReflection(Type $typeWithMethod, string $methodName) : ?ExtendedMethodReflection { $type = $this->filterTypeWithMethod($typeWithMethod, $methodName); if ($type === null) { return null; } return $type->getMethod($methodName, $this); } /** @api */ public function getNakedMethod(Type $typeWithMethod, string $methodName) : ?ExtendedMethodReflection { $type = $this->filterTypeWithMethod($typeWithMethod, $methodName); if ($type === null) { return null; } return $type->getUnresolvedMethodPrototype($methodName, $this)->getNakedMethod(); } /** * @param MethodCall|Node\Expr\StaticCall $methodCall */ private function methodCallReturnType(Type $typeWithMethod, string $methodName, Expr $methodCall) : ?Type { $typeWithMethod = $this->filterTypeWithMethod($typeWithMethod, $methodName); if ($typeWithMethod === null) { return null; } $methodReflection = $typeWithMethod->getMethod($methodName, $this); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($this, $methodCall->getArgs(), $methodReflection->getVariants(), $methodReflection->getNamedArgumentsVariants()); if ($methodCall instanceof MethodCall) { $normalizedMethodCall = \PHPStan\Analyser\ArgumentsNormalizer::reorderMethodArguments($parametersAcceptor, $methodCall); } else { $normalizedMethodCall = \PHPStan\Analyser\ArgumentsNormalizer::reorderStaticCallArguments($parametersAcceptor, $methodCall); } if ($normalizedMethodCall === null) { return $this->transformVoidToNull($parametersAcceptor->getReturnType(), $methodCall); } $resolvedTypes = []; foreach ($typeWithMethod->getObjectClassNames() as $className) { if ($normalizedMethodCall instanceof MethodCall) { foreach ($this->dynamicReturnTypeExtensionRegistry->getDynamicMethodReturnTypeExtensionsForClass($className) as $dynamicMethodReturnTypeExtension) { if (!$dynamicMethodReturnTypeExtension->isMethodSupported($methodReflection)) { continue; } $resolvedType = $dynamicMethodReturnTypeExtension->getTypeFromMethodCall($methodReflection, $normalizedMethodCall, $this); if ($resolvedType === null) { continue; } $resolvedTypes[] = $resolvedType; } } else { foreach ($this->dynamicReturnTypeExtensionRegistry->getDynamicStaticMethodReturnTypeExtensionsForClass($className) as $dynamicStaticMethodReturnTypeExtension) { if (!$dynamicStaticMethodReturnTypeExtension->isStaticMethodSupported($methodReflection)) { continue; } $resolvedType = $dynamicStaticMethodReturnTypeExtension->getTypeFromStaticMethodCall($methodReflection, $normalizedMethodCall, $this); if ($resolvedType === null) { continue; } $resolvedTypes[] = $resolvedType; } } } if (count($resolvedTypes) > 0) { return $this->transformVoidToNull(TypeCombinator::union(...$resolvedTypes), $methodCall); } return $this->transformVoidToNull($parametersAcceptor->getReturnType(), $methodCall); } /** @api */ public function getPropertyReflection(Type $typeWithProperty, string $propertyName) : ?ExtendedPropertyReflection { if ($typeWithProperty instanceof UnionType) { $typeWithProperty = $typeWithProperty->filterTypes(static function (Type $innerType) use($propertyName) { return $innerType->hasProperty($propertyName)->yes(); }); } if (!$typeWithProperty->hasProperty($propertyName)->yes()) { return null; } return $typeWithProperty->getProperty($propertyName, $this); } /** * @param PropertyFetch|Node\Expr\StaticPropertyFetch $propertyFetch */ private function propertyFetchType(Type $fetchedOnType, string $propertyName, Expr $propertyFetch) : ?Type { $propertyReflection = $this->getPropertyReflection($fetchedOnType, $propertyName); if ($propertyReflection === null) { return null; } if ($this->isInExpressionAssign($propertyFetch)) { return $propertyReflection->getWritableType(); } return $propertyReflection->getReadableType(); } public function getConstantReflection(Type $typeWithConstant, string $constantName) : ?ConstantReflection { if ($typeWithConstant instanceof UnionType) { $typeWithConstant = $typeWithConstant->filterTypes(static function (Type $innerType) use($constantName) { return $innerType->hasConstant($constantName)->yes(); }); } if (!$typeWithConstant->hasConstant($constantName)->yes()) { return null; } return $typeWithConstant->getConstant($constantName); } /** * @return array */ private function getConstantTypes() : array { $constantTypes = []; foreach ($this->expressionTypes as $exprString => $typeHolder) { $expr = $typeHolder->getExpr(); if (!$expr instanceof ConstFetch) { continue; } $constantTypes[$exprString] = $typeHolder; } return $constantTypes; } /** * @return array */ private function getNativeConstantTypes() : array { $constantTypes = []; foreach ($this->nativeExpressionTypes as $exprString => $typeHolder) { $expr = $typeHolder->getExpr(); if (!$expr instanceof ConstFetch) { continue; } $constantTypes[$exprString] = $typeHolder; } return $constantTypes; } public function getIterableKeyType(Type $iteratee) : Type { if ($iteratee instanceof UnionType) { $filtered = $iteratee->filterTypes(static function (Type $innerType) { return $innerType->isIterable()->yes(); }); if (!$filtered instanceof NeverType) { $iteratee = $filtered; } } return $iteratee->getIterableKeyType(); } public function getIterableValueType(Type $iteratee) : Type { if ($iteratee instanceof UnionType) { $filtered = $iteratee->filterTypes(static function (Type $innerType) { return $innerType->isIterable()->yes(); }); if (!$filtered instanceof NeverType) { $iteratee = $filtered; } } return $iteratee->getIterableValueType(); } } getType($expr))) { // We're in most likely in context of a null-safe operator ($scope->moreSpecificType is defined for $expr) // Modifying the expression would not bring any value or worse ruin the context information return $expr; } return self::getNullsafeShortcircuitedExpr($expr); } /** * @internal Use NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope */ public static function getNullsafeShortcircuitedExpr(Expr $expr) : Expr { if ($expr instanceof Expr\NullsafeMethodCall) { return new Expr\MethodCall(self::getNullsafeShortcircuitedExpr($expr->var), $expr->name, $expr->args); } if ($expr instanceof Expr\MethodCall) { $var = self::getNullsafeShortcircuitedExpr($expr->var); if ($expr->var === $var) { return $expr; } return new Expr\MethodCall($var, $expr->name, $expr->getArgs()); } if ($expr instanceof Expr\StaticCall && $expr->class instanceof Expr) { $class = self::getNullsafeShortcircuitedExpr($expr->class); if ($expr->class === $class) { return $expr; } return new Expr\StaticCall($class, $expr->name, $expr->getArgs()); } if ($expr instanceof Expr\ArrayDimFetch) { $var = self::getNullsafeShortcircuitedExpr($expr->var); if ($expr->var === $var) { return $expr; } return new Expr\ArrayDimFetch($var, $expr->dim); } if ($expr instanceof Expr\NullsafePropertyFetch) { return new Expr\PropertyFetch(self::getNullsafeShortcircuitedExpr($expr->var), $expr->name); } if ($expr instanceof Expr\PropertyFetch) { $var = self::getNullsafeShortcircuitedExpr($expr->var); if ($expr->var === $var) { return $expr; } return new Expr\PropertyFetch($var, $expr->name); } if ($expr instanceof Expr\StaticPropertyFetch && $expr->class instanceof Expr) { $class = self::getNullsafeShortcircuitedExpr($expr->class); if ($expr->class === $class) { return $expr; } return new Expr\StaticPropertyFetch($class, $expr->name); } return $expr; } } */ private $unorderedErrors; /** * @var list */ private $filteredPhpErrors; /** * @var list */ private $allPhpErrors; /** * @var list */ private $locallyIgnoredErrors; /** * @var array */ private $linesToIgnore; /** * @var array */ private $unmatchedLineIgnores; /** * @var list */ private $internalErrors; /** * @var list */ private $collectedData; /** * @var array>|null */ private $dependencies; /** * @var array>|null */ private $usedTraitDependencies; /** * @var array> */ private $exportedNodes; /** * @var bool */ private $reachedInternalErrorsCountLimit; /** * @var int */ private $peakMemoryUsageBytes; /** @var list|null */ private $errors = null; /** * @param list $unorderedErrors * @param list $filteredPhpErrors * @param list $allPhpErrors * @param list $locallyIgnoredErrors * @param array $linesToIgnore * @param array $unmatchedLineIgnores * @param list $collectedData * @param list $internalErrors * @param array>|null $dependencies * @param array>|null $usedTraitDependencies * @param array> $exportedNodes */ public function __construct(array $unorderedErrors, array $filteredPhpErrors, array $allPhpErrors, array $locallyIgnoredErrors, array $linesToIgnore, array $unmatchedLineIgnores, array $internalErrors, array $collectedData, ?array $dependencies, ?array $usedTraitDependencies, array $exportedNodes, bool $reachedInternalErrorsCountLimit, int $peakMemoryUsageBytes) { $this->unorderedErrors = $unorderedErrors; $this->filteredPhpErrors = $filteredPhpErrors; $this->allPhpErrors = $allPhpErrors; $this->locallyIgnoredErrors = $locallyIgnoredErrors; $this->linesToIgnore = $linesToIgnore; $this->unmatchedLineIgnores = $unmatchedLineIgnores; $this->internalErrors = $internalErrors; $this->collectedData = $collectedData; $this->dependencies = $dependencies; $this->usedTraitDependencies = $usedTraitDependencies; $this->exportedNodes = $exportedNodes; $this->reachedInternalErrorsCountLimit = $reachedInternalErrorsCountLimit; $this->peakMemoryUsageBytes = $peakMemoryUsageBytes; } /** * @return list */ public function getUnorderedErrors() : array { return $this->unorderedErrors; } /** * @return list */ public function getErrors() : array { if (!isset($this->errors)) { $this->errors = $this->unorderedErrors; usort($this->errors, static function (\PHPStan\Analyser\Error $a, \PHPStan\Analyser\Error $b) : int { return [$a->getFile(), $a->getLine(), $a->getMessage()] <=> [$b->getFile(), $b->getLine(), $b->getMessage()]; }); } return $this->errors; } /** * @return list */ public function getFilteredPhpErrors() : array { return $this->filteredPhpErrors; } /** * @return list */ public function getAllPhpErrors() : array { return $this->allPhpErrors; } /** * @return list */ public function getLocallyIgnoredErrors() : array { return $this->locallyIgnoredErrors; } /** * @return array */ public function getLinesToIgnore() : array { return $this->linesToIgnore; } /** * @return array */ public function getUnmatchedLineIgnores() : array { return $this->unmatchedLineIgnores; } /** * @return list */ public function getInternalErrors() : array { return $this->internalErrors; } /** * @return list */ public function getCollectedData() : array { return $this->collectedData; } /** * @return array>|null */ public function getDependencies() : ?array { return $this->dependencies; } /** * @return array>|null */ public function getUsedTraitDependencies() : ?array { return $this->usedTraitDependencies; } /** * @return array> */ public function getExportedNodes() : array { return $this->exportedNodes; } public function hasReachedInternalErrorsCountLimit() : bool { return $this->reachedInternalErrorsCountLimit; } public function getPeakMemoryUsageBytes() : int { return $this->peakMemoryUsageBytes; } } scope = $scope; $this->specifiedExpressions = $specifiedExpressions; } public function getScope() : \PHPStan\Analyser\MutatingScope { return $this->scope; } /** * @return EnsuredNonNullabilityResultExpression[] */ public function getSpecifiedExpressions() : array { return $this->specifiedExpressions; } } */ private $uses; /** * @var ?string */ private $className; /** * @var ?string */ private $functionName; /** * @var array */ private $typeAliasesMap; /** * @var bool */ private $bypassTypeAliases; /** * @var array */ private $constUses; /** * @var ?string */ private $typeAliasClassName; /** * @var TemplateTypeMap */ private $templateTypeMap; /** * @api * @param non-empty-string|null $namespace * @param array $uses alias(string) => fullName(string) * @param array $constUses alias(string) => fullName(string) * @param array $typeAliasesMap */ public function __construct(?string $namespace, array $uses, ?string $className = null, ?string $functionName = null, ?TemplateTypeMap $templateTypeMap = null, array $typeAliasesMap = [], bool $bypassTypeAliases = \false, array $constUses = [], ?string $typeAliasClassName = null) { $this->namespace = $namespace; $this->uses = $uses; $this->className = $className; $this->functionName = $functionName; $this->typeAliasesMap = $typeAliasesMap; $this->bypassTypeAliases = $bypassTypeAliases; $this->constUses = $constUses; $this->typeAliasClassName = $typeAliasClassName; $this->templateTypeMap = $templateTypeMap ?? TemplateTypeMap::createEmpty(); } public function getNamespace() : ?string { return $this->namespace; } /** * @return array */ public function getUses() : array { return $this->uses; } public function hasUseAlias(string $name) : bool { return isset($this->uses[strtolower($name)]); } /** * @return array */ public function getConstUses() : array { return $this->constUses; } public function getClassName() : ?string { return $this->className; } public function getClassNameForTypeAlias() : ?string { return $this->typeAliasClassName ?? $this->className; } public function resolveStringName(string $name) : string { if (str_starts_with($name, '\\')) { return ltrim($name, '\\'); } $nameParts = explode('\\', $name); $firstNamePart = strtolower($nameParts[0]); if (isset($this->uses[$firstNamePart])) { if (count($nameParts) === 1) { return $this->uses[$firstNamePart]; } array_shift($nameParts); return sprintf('%s\\%s', $this->uses[$firstNamePart], implode('\\', $nameParts)); } if ($this->namespace !== null) { return sprintf('%s\\%s', $this->namespace, $name); } return $name; } /** * @return non-empty-list */ public function resolveConstantNames(string $name) : array { if (str_starts_with($name, '\\')) { return [ltrim($name, '\\')]; } $nameParts = explode('\\', $name); $firstNamePart = strtolower($nameParts[0]); if (count($nameParts) > 1) { if (isset($this->uses[$firstNamePart])) { array_shift($nameParts); return [sprintf('%s\\%s', $this->uses[$firstNamePart], implode('\\', $nameParts))]; } } elseif (isset($this->constUses[$firstNamePart])) { return [$this->constUses[$firstNamePart]]; } if ($this->namespace !== null) { return [sprintf('%s\\%s', $this->namespace, $name), $name]; } return [$name]; } public function getTemplateTypeScope() : ?TemplateTypeScope { if ($this->className !== null) { if ($this->functionName !== null) { return TemplateTypeScope::createWithMethod($this->className, $this->functionName); } return TemplateTypeScope::createWithClass($this->className); } if ($this->functionName !== null) { return TemplateTypeScope::createWithFunction($this->functionName); } return null; } public function getTemplateTypeMap() : TemplateTypeMap { return $this->templateTypeMap; } public function resolveTemplateTypeName(string $name) : ?Type { return $this->templateTypeMap->getType($name); } public function withTemplateTypeMap(TemplateTypeMap $map) : self { if ($map->isEmpty() && $this->templateTypeMap->isEmpty()) { return $this; } return new self($this->namespace, $this->uses, $this->className, $this->functionName, new TemplateTypeMap(array_merge($this->templateTypeMap->getTypes(), $map->getTypes())), $this->typeAliasesMap, $this->bypassTypeAliases, $this->constUses); } public function withoutNamespaceAndUses() : self { return new self(null, [], $this->className, $this->functionName, $this->templateTypeMap, $this->typeAliasesMap, $this->bypassTypeAliases, $this->constUses); } public function withClassName(string $className) : self { return new self($this->namespace, $this->uses, $className, $this->functionName, $this->templateTypeMap, $this->typeAliasesMap, $this->bypassTypeAliases, $this->constUses); } public function unsetTemplateType(string $name) : self { $map = $this->templateTypeMap; if (!$map->hasType($name)) { return $this; } return new self($this->namespace, $this->uses, $this->className, $this->functionName, $this->templateTypeMap->unsetType($name), $this->typeAliasesMap, $this->bypassTypeAliases, $this->constUses); } public function bypassTypeAliases() : self { return new self($this->namespace, $this->uses, $this->className, $this->functionName, $this->templateTypeMap, $this->typeAliasesMap, \true, $this->constUses); } public function shouldBypassTypeAliases() : bool { return $this->bypassTypeAliases; } public function hasTypeAlias(string $alias) : bool { return array_key_exists($alias, $this->typeAliasesMap); } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self { return new self($properties['namespace'], $properties['uses'], $properties['className'], $properties['functionName'], $properties['templateTypeMap'], $properties['typeAliasesMap'], $properties['bypassTypeAliases'], $properties['constUses']); } } */ class InternalError implements JsonSerializable { /** * @var string */ private $message; /** * @var string */ private $contextDescription; /** * @var Trace */ private $trace; /** * @var ?string */ private $traceAsString; /** * @var bool */ private $shouldReportBug; public const STACK_TRACE_METADATA_KEY = 'stackTrace'; public const STACK_TRACE_AS_STRING_METADATA_KEY = 'stackTraceAsString'; /** * @param Trace $trace */ public function __construct(string $message, string $contextDescription, array $trace, ?string $traceAsString, bool $shouldReportBug) { $this->message = $message; $this->contextDescription = $contextDescription; $this->trace = $trace; $this->traceAsString = $traceAsString; $this->shouldReportBug = $shouldReportBug; } /** * @return Trace */ public static function prepareTrace(Throwable $exception) : array { $trace = array_map(static function (array $trace) { return ['file' => $trace['file'] ?? null, 'line' => $trace['line'] ?? null]; }, $exception->getTrace()); array_unshift($trace, ['file' => $exception->getFile(), 'line' => $exception->getLine()]); return $trace; } public function getMessage() : string { return $this->message; } public function getContextDescription() : string { return $this->contextDescription; } /** * @return Trace */ public function getTrace() : array { return $this->trace; } public function getTraceAsString() : ?string { return $this->traceAsString; } public function shouldReportBug() : bool { return $this->shouldReportBug; } /** * @param mixed[] $json */ public static function decode(array $json) : self { return new self($json['message'], $json['contextDescription'], $json['trace'], $json['traceAsString'], $json['shouldReportBug']); } /** * @return mixed */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['message' => $this->message, 'contextDescription' => $this->contextDescription, 'trace' => $this->trace, 'traceAsString' => $this->traceAsString, 'shouldReportBug' => $this->shouldReportBug]; } } isDeep = $isDeep; $this->inAssignRightSideVariableName = $inAssignRightSideVariableName; $this->inAssignRightSideType = $inAssignRightSideType; $this->inAssignRightSideNativeType = $inAssignRightSideNativeType; } public static function createTopLevel() : self { return new self(\false, null, null, null); } public static function createDeep() : self { return new self(\true, null, null, null); } public function enterDeep() : self { if ($this->isDeep) { return $this; } return new self(\true, $this->inAssignRightSideVariableName, $this->inAssignRightSideType, $this->inAssignRightSideNativeType); } public function isDeep() : bool { return $this->isDeep; } public function enterRightSideAssign(string $variableName, Type $type, Type $nativeType) : self { return new self($this->isDeep, $variableName, $type, $nativeType); } public function getInAssignRightSideVariableName() : ?string { return $this->inAssignRightSideVariableName; } public function getInAssignRightSideType() : ?Type { return $this->inAssignRightSideType; } public function getInAssignRightSideNativeType() : ?Type { return $this->inAssignRightSideNativeType; } } isTopLevel = $isTopLevel; } public static function createTopLevel() : self { return new self(\true); } public static function createDeep() : self { return new self(\false); } public function isTopLevel() : bool { return $this->isTopLevel; } public function enterDeep() : self { if ($this->isTopLevel) { return self::createDeep(); } return $this; } } reflectionProviderProvider = $reflectionProviderProvider; $this->container = $container; } public function create() : \PHPStan\Analyser\ConstantResolver { return new \PHPStan\Analyser\ConstantResolver($this->reflectionProviderProvider, $this->container->getParameter('dynamicConstantNames')); } } $expressionTypes * @param array $nativeExpressionTypes * @param array $conditionalExpressions * @param list $inClosureBindScopeClasses * @param array $currentlyAssignedExpressions * @param array $currentlyAllowedUndefinedExpressions * @param list $inFunctionCallsStack * @param FunctionReflection|MethodReflection|null $function */ public function create(\PHPStan\Analyser\ScopeContext $context, bool $declareStrictTypes = \false, $function = null, ?string $namespace = null, array $expressionTypes = [], array $nativeExpressionTypes = [], array $conditionalExpressions = [], array $inClosureBindScopeClasses = [], ?ParametersAcceptor $anonymousFunctionReflection = null, bool $inFirstLevelStatement = \true, array $currentlyAssignedExpressions = [], array $currentlyAllowedUndefinedExpressions = [], array $inFunctionCallsStack = [], bool $afterExtractCall = \false, ?\PHPStan\Analyser\Scope $parentScope = null, bool $nativeTypesPromoted = \false) : \PHPStan\Analyser\MutatingScope; } scopeClass = $scopeClass; $this->container = $container; $this->explicitMixedInUnknownGenericNew = $this->container->getParameter('featureToggles')['explicitMixedInUnknownGenericNew']; $this->explicitMixedForGlobalVariables = $this->container->getParameter('featureToggles')['explicitMixedForGlobalVariables']; } /** * @param array $expressionTypes * @param array $nativeExpressionTypes * @param array $conditionalExpressions * @param array $currentlyAssignedExpressions * @param array $currentlyAllowedUndefinedExpressions * @param list $inFunctionCallsStack * @param FunctionReflection|MethodReflection|null $function */ public function create(\PHPStan\Analyser\ScopeContext $context, bool $declareStrictTypes = \false, $function = null, ?string $namespace = null, array $expressionTypes = [], array $nativeExpressionTypes = [], array $conditionalExpressions = [], array $inClosureBindScopeClasses = [], ?ParametersAcceptor $anonymousFunctionReflection = null, bool $inFirstLevelStatement = \true, array $currentlyAssignedExpressions = [], array $currentlyAllowedUndefinedExpressions = [], array $inFunctionCallsStack = [], bool $afterExtractCall = \false, ?\PHPStan\Analyser\Scope $parentScope = null, bool $nativeTypesPromoted = \false) : \PHPStan\Analyser\MutatingScope { $scopeClass = $this->scopeClass; if (!is_a($scopeClass, \PHPStan\Analyser\MutatingScope::class, \true)) { throw new ShouldNotHappenException(); } return new $scopeClass($this, $this->container->getByType(ReflectionProvider::class), $this->container->getByType(InitializerExprTypeResolver::class), $this->container->getByType(DynamicReturnTypeExtensionRegistryProvider::class)->getRegistry(), $this->container->getByType(ExpressionTypeResolverExtensionRegistryProvider::class)->getRegistry(), $this->container->getByType(ExprPrinter::class), $this->container->getByType(\PHPStan\Analyser\TypeSpecifier::class), $this->container->getByType(PropertyReflectionFinder::class), $this->container->getService('currentPhpVersionSimpleParser'), $this->container->getByType(\PHPStan\Analyser\NodeScopeResolver::class), $this->container->getByType(\PHPStan\Analyser\RicherScopeGetTypeHelper::class), $this->container->getByType(\PHPStan\Analyser\ConstantResolver::class), $context, $this->container->getByType(PhpVersion::class), $declareStrictTypes, $function, $namespace, $expressionTypes, $nativeExpressionTypes, $conditionalExpressions, $inClosureBindScopeClasses, $anonymousFunctionReflection, $inFirstLevelStatement, $currentlyAssignedExpressions, $currentlyAllowedUndefinedExpressions, $inFunctionCallsStack, $afterExtractCall, $parentScope, $nativeTypesPromoted, $this->explicitMixedInUnknownGenericNew, $this->explicitMixedForGlobalVariables); } } scope = $scope; $this->hasYield = $hasYield; $this->throwPoints = $throwPoints; $this->impurePoints = $impurePoints; $this->truthyScopeCallback = $truthyScopeCallback; $this->falseyScopeCallback = $falseyScopeCallback; } public function getScope() : \PHPStan\Analyser\MutatingScope { return $this->scope; } public function hasYield() : bool { return $this->hasYield; } /** * @return ThrowPoint[] */ public function getThrowPoints() : array { return $this->throwPoints; } /** * @return ImpurePoint[] */ public function getImpurePoints() : array { return $this->impurePoints; } public function getTruthyScope() : \PHPStan\Analyser\MutatingScope { if ($this->truthyScopeCallback === null) { return $this->scope; } if ($this->truthyScope !== null) { return $this->truthyScope; } $callback = $this->truthyScopeCallback; $this->truthyScope = $callback(); return $this->truthyScope; } public function getFalseyScope() : \PHPStan\Analyser\MutatingScope { if ($this->falseyScopeCallback === null) { return $this->scope; } if ($this->falseyScope !== null) { return $this->falseyScope; } $callback = $this->falseyScopeCallback; $this->falseyScope = $callback(); return $this->falseyScope; } } statement = $statement; $this->result = $result; } public function getStatement() : Stmt { return $this->statement; } public function getResult() : \PHPStan\Analyser\StatementResult { return $this->result; } } scope = $scope; $this->variableName = $variableName; parent::__construct(sprintf('Undefined variable: $%s', $variableName)); } public function getScope() : \PHPStan\Analyser\Scope { return $this->scope; } public function getVariableName() : string { return $this->variableName; } public function getTip() : ?string { return null; } } */ private $currentlyResolving = []; /** * @param string[] $dynamicConstantNames */ public function __construct(ReflectionProviderProvider $reflectionProviderProvider, array $dynamicConstantNames) { $this->reflectionProviderProvider = $reflectionProviderProvider; $this->dynamicConstantNames = $dynamicConstantNames; } public function resolveConstant(Name $name, ?NamespaceAnswerer $scope) : ?Type { if (!$this->getReflectionProvider()->hasConstant($name, $scope)) { return null; } /** @var string $resolvedConstantName */ $resolvedConstantName = $this->getReflectionProvider()->resolveConstantName($name, $scope); $constantType = $this->resolvePredefinedConstant($resolvedConstantName); if ($constantType !== null) { return $constantType; } if (array_key_exists($resolvedConstantName, $this->currentlyResolving)) { return new MixedType(); } $this->currentlyResolving[$resolvedConstantName] = \true; $constantReflection = $this->getReflectionProvider()->getConstant($name, $scope); $constantType = $constantReflection->getValueType(); $type = $this->resolveConstantType($resolvedConstantName, $constantType); unset($this->currentlyResolving[$resolvedConstantName]); return $type; } public function resolvePredefinedConstant(string $resolvedConstantName) : ?Type { // core, https://www.php.net/manual/en/reserved.constants.php if ($resolvedConstantName === 'PHP_VERSION') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($resolvedConstantName === 'PHP_MAJOR_VERSION') { return IntegerRangeType::fromInterval(5, null); } if ($resolvedConstantName === 'PHP_MINOR_VERSION') { return IntegerRangeType::fromInterval(0, null); } if ($resolvedConstantName === 'PHP_RELEASE_VERSION') { return IntegerRangeType::fromInterval(0, null); } if ($resolvedConstantName === 'PHP_VERSION_ID') { return IntegerRangeType::fromInterval(50207, null); } if ($resolvedConstantName === 'PHP_ZTS') { return new UnionType([new ConstantIntegerType(0), new ConstantIntegerType(1)]); } if ($resolvedConstantName === 'PHP_DEBUG') { return new UnionType([new ConstantIntegerType(0), new ConstantIntegerType(1)]); } if ($resolvedConstantName === 'PHP_MAXPATHLEN') { return IntegerRangeType::fromInterval(1, null); } if ($resolvedConstantName === 'PHP_OS') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($resolvedConstantName === 'PHP_OS_FAMILY') { return new UnionType([new ConstantStringType('Windows'), new ConstantStringType('BSD'), new ConstantStringType('Darwin'), new ConstantStringType('Solaris'), new ConstantStringType('Linux'), new ConstantStringType('Unknown')]); } if ($resolvedConstantName === 'PHP_SAPI') { return new UnionType([new ConstantStringType('apache'), new ConstantStringType('apache2handler'), new ConstantStringType('cgi'), new ConstantStringType('cli'), new ConstantStringType('cli-server'), new ConstantStringType('embed'), new ConstantStringType('fpm-fcgi'), new ConstantStringType('litespeed'), new ConstantStringType('phpdbg'), new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()])]); } if ($resolvedConstantName === 'PHP_EOL') { return new UnionType([new ConstantStringType("\n"), new ConstantStringType("\r\n")]); } if ($resolvedConstantName === 'PHP_INT_MAX') { return PHP_INT_SIZE === 8 ? new UnionType([new ConstantIntegerType(2147483647), new ConstantIntegerType(9223372036854775807)]) : new ConstantIntegerType(2147483647); } if ($resolvedConstantName === 'PHP_INT_MIN') { // Why the -1 you might wonder, the answer is to fit it into an int :/ see https://3v4l.org/4SHIQ return PHP_INT_SIZE === 8 ? new UnionType([new ConstantIntegerType(-9223372036854775807 - 1), new ConstantIntegerType(-2147483647 - 1)]) : new ConstantIntegerType(-2147483647 - 1); } if ($resolvedConstantName === 'PHP_INT_SIZE') { return new UnionType([new ConstantIntegerType(4), new ConstantIntegerType(8)]); } if ($resolvedConstantName === 'PHP_FLOAT_DIG') { return IntegerRangeType::fromInterval(1, null); } if ($resolvedConstantName === 'PHP_EXTENSION_DIR') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($resolvedConstantName === 'PHP_PREFIX') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($resolvedConstantName === 'PHP_BINDIR') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($resolvedConstantName === 'PHP_BINARY') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($resolvedConstantName === 'PHP_MANDIR') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($resolvedConstantName === 'PHP_LIBDIR') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($resolvedConstantName === 'PHP_DATADIR') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($resolvedConstantName === 'PHP_SYSCONFDIR') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($resolvedConstantName === 'PHP_LOCALSTATEDIR') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($resolvedConstantName === 'PHP_CONFIG_FILE_PATH') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if ($resolvedConstantName === 'PHP_SHLIB_SUFFIX') { return new UnionType([new ConstantStringType('so'), new ConstantStringType('dll')]); } if ($resolvedConstantName === 'PHP_FD_SETSIZE') { return IntegerRangeType::fromInterval(1, null); } if ($resolvedConstantName === '__COMPILER_HALT_OFFSET__') { return IntegerRangeType::fromInterval(1, null); } // core other, https://www.php.net/manual/en/info.constants.php if ($resolvedConstantName === 'PHP_WINDOWS_VERSION_MAJOR') { return IntegerRangeType::fromInterval(4, null); } if ($resolvedConstantName === 'PHP_WINDOWS_VERSION_MINOR') { return IntegerRangeType::fromInterval(0, null); } if ($resolvedConstantName === 'PHP_WINDOWS_VERSION_BUILD') { return IntegerRangeType::fromInterval(1, null); } // dir, https://www.php.net/manual/en/dir.constants.php if ($resolvedConstantName === 'DIRECTORY_SEPARATOR') { return new UnionType([new ConstantStringType('/'), new ConstantStringType('\\')]); } if ($resolvedConstantName === 'PATH_SEPARATOR') { return new UnionType([new ConstantStringType(':'), new ConstantStringType(';')]); } // iconv, https://www.php.net/manual/en/iconv.constants.php if ($resolvedConstantName === 'ICONV_IMPL') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } // libxml, https://www.php.net/manual/en/libxml.constants.php if ($resolvedConstantName === 'LIBXML_VERSION') { return IntegerRangeType::fromInterval(1, null); } if ($resolvedConstantName === 'LIBXML_DOTTED_VERSION') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } // openssl, https://www.php.net/manual/en/openssl.constants.php if ($resolvedConstantName === 'OPENSSL_VERSION_NUMBER') { return IntegerRangeType::fromInterval(1, null); } // pcre, https://www.php.net/manual/en/pcre.constants.php if ($resolvedConstantName === 'PCRE_VERSION') { return new IntersectionType([new StringType(), new AccessoryNonFalsyStringType()]); } if (in_array($resolvedConstantName, ['STDIN', 'STDOUT', 'STDERR'], \true)) { return new ResourceType(); } if ($resolvedConstantName === 'NAN') { return new ConstantFloatType(NAN); } if ($resolvedConstantName === 'INF') { return new ConstantFloatType(INF); } return null; } public function resolveConstantType(string $constantName, Type $constantType) : Type { if ($constantType->isConstantValue()->yes() && in_array($constantName, $this->dynamicConstantNames, \true)) { return $constantType->generalize(GeneralizePrecision::lessSpecific()); } return $constantType; } public function resolveClassConstantType(string $className, string $constantName, Type $constantType, ?Type $nativeType) : Type { $lookupConstantName = sprintf('%s::%s', $className, $constantName); if (in_array($lookupConstantName, $this->dynamicConstantNames, \true)) { if ($nativeType !== null) { return $nativeType; } if ($constantType->isConstantValue()->yes()) { return $constantType->generalize(GeneralizePrecision::lessSpecific()); } } return $constantType; } private function getReflectionProvider() : ReflectionProvider { return $this->reflectionProviderProvider->getReflectionProvider(); } } */ private $storage = []; /** * @return mixed|null */ public function load(string $key, string $variableKey) { if (!isset($this->storage[$key])) { return null; } $item = $this->storage[$key]; if (!$item->isVariableKeyValid($variableKey)) { return null; } return $item->getData(); } /** * @param mixed $data */ public function save(string $key, string $variableKey, $data) : void { $item = new \PHPStan\Cache\CacheItem($variableKey, $data); @var_export($item, \true); $this->storage[$key] = $item; } } variableKey = $variableKey; $this->data = $data; } public function isVariableKeyValid(string $variableKey) : bool { return $this->variableKey === $variableKey; } /** * @return mixed */ public function getData() { return $this->data; } /** * @param mixed[] $properties */ public static function __set_state(array $properties) : self { return new self($properties['variableKey'], $properties['data']); } } directory = $directory; } /** * @return mixed|null */ public function load(string $key, string $variableKey) { [, , $filePath] = $this->getFilePaths($key); return (static function () use($variableKey, $filePath) { $cacheItem = @(include $filePath); if (!$cacheItem instanceof \PHPStan\Cache\CacheItem) { return null; } if (!$cacheItem->isVariableKeyValid($variableKey)) { return null; } return $cacheItem->getData(); })(); } /** * @param mixed $data * @throws DirectoryCreatorException */ public function save(string $key, string $variableKey, $data) : void { [$firstDirectory, $secondDirectory, $path] = $this->getFilePaths($key); DirectoryCreator::ensureDirectoryExists($this->directory, 0777); DirectoryCreator::ensureDirectoryExists($firstDirectory, 0777); DirectoryCreator::ensureDirectoryExists($secondDirectory, 0777); $tmpPath = sprintf('%s/%s.tmp', $this->directory, Random::generate()); $errorBefore = error_get_last(); $exported = @var_export(new \PHPStan\Cache\CacheItem($variableKey, $data), \true); $errorAfter = error_get_last(); if ($errorAfter !== null && $errorBefore !== $errorAfter) { throw new ShouldNotHappenException(sprintf('Error occurred while saving item %s (%s) to cache: %s', $key, $variableKey, $errorAfter['message'])); } FileWriter::write($tmpPath, sprintf("directory, substr($keyHash, 0, 2)); $secondDirectory = sprintf('%s/%s', $firstDirectory, substr($keyHash, 2, 2)); $filePath = sprintf('%s/%s.php', $secondDirectory, $keyHash); return [$firstDirectory, $secondDirectory, $filePath]; } } storage = $storage; } /** * @return mixed|null */ public function load(string $key, string $variableKey) { return $this->storage->load($key, $variableKey); } /** * @param mixed $data */ public function save(string $key, string $variableKey, $data) : void { $this->storage->save($key, $variableKey, $data); } } versionId = $versionId; $this->composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths; } public function create() : \PHPStan\Php\PhpVersionFactory { $composerPhpVersion = null; if (count($this->composerAutoloaderProjectPaths) > 0) { $composerJsonPath = end($this->composerAutoloaderProjectPaths) . '/composer.json'; if (is_file($composerJsonPath)) { try { $composerJsonContents = FileReader::read($composerJsonPath); $composer = Json::decode($composerJsonContents, Json::FORCE_ARRAY); $platformVersion = $composer['config']['platform']['php'] ?? null; if (is_string($platformVersion)) { $composerPhpVersion = $platformVersion; } } catch (CouldNotReadFileException|JsonException $e) { // pass } } } return new \PHPStan\Php\PhpVersionFactory($this->versionId, $composerPhpVersion); } } versionId = $versionId; $this->source = $source; } public function getSourceLabel() : string { switch ($this->source) { case self::SOURCE_RUNTIME: return 'runtime'; case self::SOURCE_CONFIG: return 'config'; case self::SOURCE_COMPOSER_PLATFORM_PHP: return 'config.platform.php in composer.json'; } return 'unknown'; } public function getVersionId() : int { return $this->versionId; } public function getVersionString() : string { $first = (int) floor($this->versionId / 10000); $second = (int) floor($this->versionId % 10000 / 100); $third = (int) floor($this->versionId % 100); return $first . '.' . $second . ($third !== 0 ? '.' . $third : ''); } public function supportsNullCoalesceAssign() : bool { return $this->versionId >= 70400; } public function supportsParameterContravariance() : bool { return $this->versionId >= 70400; } public function supportsReturnCovariance() : bool { return $this->versionId >= 70400; } public function supportsNoncapturingCatches() : bool { return $this->versionId >= 80000; } public function supportsNativeUnionTypes() : bool { return $this->versionId >= 80000; } public function deprecatesRequiredParameterAfterOptional() : bool { return $this->versionId >= 80000; } public function deprecatesRequiredParameterAfterOptionalNullableAndDefaultNull() : bool { return $this->versionId >= 80100; } public function deprecatesRequiredParameterAfterOptionalUnionOrMixed() : bool { return $this->versionId >= 80300; } public function supportsLessOverridenParametersWithVariadic() : bool { return $this->versionId >= 80000; } public function supportsThrowExpression() : bool { return $this->versionId >= 80000; } public function supportsClassConstantOnExpression() : bool { return $this->versionId >= 80000; } public function supportsLegacyConstructor() : bool { return $this->versionId < 80000; } public function supportsPromotedProperties() : bool { return $this->versionId >= 80000; } public function supportsParameterTypeWidening() : bool { return $this->versionId >= 70200; } public function supportsUnsetCast() : bool { return $this->versionId < 80000; } public function supportsNamedArguments() : bool { return $this->versionId >= 80000; } public function throwsTypeErrorForInternalFunctions() : bool { return $this->versionId >= 80000; } public function throwsValueErrorForInternalFunctions() : bool { return $this->versionId >= 80000; } public function supportsHhPrintfSpecifier() : bool { return $this->versionId >= 80000; } public function isEmptyStringValidAliasForNoneInMbSubstituteCharacter() : bool { return $this->versionId < 80000; } public function supportsAllUnicodeScalarCodePointsInMbSubstituteCharacter() : bool { return $this->versionId >= 70200; } public function isNumericStringValidArgInMbSubstituteCharacter() : bool { return $this->versionId < 80000; } public function isNullValidArgInMbSubstituteCharacter() : bool { return $this->versionId >= 80000; } public function isInterfaceConstantImplicitlyFinal() : bool { return $this->versionId < 80100; } public function supportsFinalConstants() : bool { return $this->versionId >= 80100; } public function supportsReadOnlyProperties() : bool { return $this->versionId >= 80100; } public function supportsEnums() : bool { return $this->versionId >= 80100; } public function supportsPureIntersectionTypes() : bool { return $this->versionId >= 80100; } public function supportsCaseInsensitiveConstantNames() : bool { return $this->versionId < 80000; } public function hasStricterRoundFunctions() : bool { return $this->versionId >= 80000; } public function hasTentativeReturnTypes() : bool { return $this->versionId >= 80100; } public function supportsFirstClassCallables() : bool { return $this->versionId >= 80100; } public function supportsArrayUnpackingWithStringKeys() : bool { return $this->versionId >= 80100; } public function throwsOnInvalidMbStringEncoding() : bool { return $this->versionId >= 80000; } public function supportsPassNoneEncodings() : bool { return $this->versionId < 70300; } public function producesWarningForFinalPrivateMethods() : bool { return $this->versionId >= 80000; } public function deprecatesDynamicProperties() : bool { return $this->versionId >= 80200; } public function strSplitReturnsEmptyArray() : bool { return $this->versionId >= 80200; } public function supportsDisjunctiveNormalForm() : bool { return $this->versionId >= 80200; } public function serializableRequiresMagicMethods() : bool { return $this->versionId >= 80100; } public function arrayFunctionsReturnNullWithNonArray() : bool { return $this->versionId < 80000; } public function castsNumbersToStringsOnLooseComparison() : bool { return $this->versionId >= 80000; } public function supportsCallableInstanceMethods() : bool { return $this->versionId < 80000; } public function supportsJsonValidate() : bool { return $this->versionId >= 80300; } public function supportsConstantsInTraits() : bool { return $this->versionId >= 80200; } public function supportsNativeTypesInClassConstants() : bool { return $this->versionId >= 80300; } public function supportsAbstractTraitMethods() : bool { return $this->versionId >= 80000; } public function supportsOverrideAttribute() : bool { return $this->versionId >= 80300; } public function supportsDynamicClassConstantFetch() : bool { return $this->versionId >= 80300; } public function supportsReadOnlyClasses() : bool { return $this->versionId >= 80200; } public function supportsReadOnlyAnonymousClasses() : bool { return $this->versionId >= 80300; } public function supportsNeverReturnTypeInArrowFunction() : bool { return $this->versionId >= 80200; } public function supportsPregUnmatchedAsNull() : bool { // while PREG_UNMATCHED_AS_NULL is defined in php-src since 7.2.x it starts working as expected with 7.4.x // https://3v4l.org/v3HE4 return $this->versionId >= 70400; } public function supportsPregCaptureOnlyNamedGroups() : bool { // https://php.watch/versions/8.2/preg-n-no-capture-modifier return $this->versionId >= 80200; } public function hasDateTimeExceptions() : bool { return $this->versionId >= 80300; } public function isCurloptUrlCheckingFileSchemeWithOpenBasedir() : bool { // Before PHP 8.0, when setting CURLOPT_URL, an unparsable URL or a file:// scheme would fail if open_basedir is used // https://github.com/php/php-src/blob/php-7.4.33/ext/curl/interface.c#L139-L158 // https://github.com/php/php-src/blob/php-8.0.0/ext/curl/interface.c#L128-L130 return $this->versionId < 80000; } public function highlightStringDoesNotReturnFalse() : bool { return $this->versionId >= 80400; } public function deprecatesImplicitlyNullableParameterTypes() : bool { return $this->versionId >= 80400; } public function substrReturnFalseInsteadOfEmptyString() : bool { return $this->versionId < 80000; } } versionId = $versionId; $this->composerPhpVersion = $composerPhpVersion; } public function create() : \PHPStan\Php\PhpVersion { $versionId = $this->versionId; if ($versionId !== null) { $source = \PHPStan\Php\PhpVersion::SOURCE_CONFIG; } elseif ($this->composerPhpVersion !== null) { $parts = explode('.', $this->composerPhpVersion); $tmp = (int) $parts[0] * 10000 + (int) ($parts[1] ?? 0) * 100 + (int) ($parts[2] ?? 0); $tmp = max($tmp, 70100); $versionId = min($tmp, 80499); $source = \PHPStan\Php\PhpVersion::SOURCE_COMPOSER_PLATFORM_PHP; } else { $versionId = PHP_VERSION_ID; $source = \PHPStan\Php\PhpVersion::SOURCE_RUNTIME; } return new \PHPStan\Php\PhpVersion($versionId, $source); } } get($name); } } get('CODEBUILD_CI') !== \false; } public function getCiName() : string { return CiDetector::CI_AWS_CODEBUILD; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createFromBoolean(\mb_strpos($this->env->getString('CODEBUILD_WEBHOOK_EVENT'), 'PULL_REQUEST') === 0); } public function getBuildNumber() : string { return $this->env->getString('CODEBUILD_BUILD_NUMBER'); } public function getBuildUrl() : string { return $this->env->getString('CODEBUILD_BUILD_URL'); } public function getGitCommit() : string { return $this->env->getString('CODEBUILD_RESOLVED_SOURCE_VERSION'); } public function getGitBranch() : string { $gitReference = $this->env->getString('CODEBUILD_WEBHOOK_HEAD_REF'); return \preg_replace('~^refs/heads/~', '', $gitReference) ?? ''; } public function getRepositoryName() : string { return ''; // unsupported } public function getRepositoryUrl() : string { return $this->env->getString('CODEBUILD_SOURCE_REPO_URL'); } } env = $env; } } get('CIRCLECI') !== \false; } public function getCiName() : string { return CiDetector::CI_CIRCLE; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->env->getString('CI_PULL_REQUEST') !== ''); } public function getBuildNumber() : string { return $this->env->getString('CIRCLE_BUILD_NUM'); } public function getBuildUrl() : string { return $this->env->getString('CIRCLE_BUILD_URL'); } public function getGitCommit() : string { return $this->env->getString('CIRCLE_SHA1'); } public function getGitBranch() : string { return $this->env->getString('CIRCLE_BRANCH'); } public function getRepositoryName() : string { return \sprintf('%s/%s', $this->env->getString('CIRCLE_PROJECT_USERNAME'), $this->env->getString('CIRCLE_PROJECT_REPONAME')); } public function getRepositoryUrl() : string { return $this->env->getString('CIRCLE_REPOSITORY_URL'); } } get('GITLAB_CI') !== \false; } public function getCiName() : string { return CiDetector::CI_GITLAB; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->env->get('CI_MERGE_REQUEST_ID') !== \false || $this->env->get('CI_EXTERNAL_PULL_REQUEST_IID') !== \false); } public function getBuildNumber() : string { return !empty($this->env->getString('CI_JOB_ID')) ? $this->env->getString('CI_JOB_ID') : $this->env->getString('CI_BUILD_ID'); } public function getBuildUrl() : string { return $this->env->getString('CI_PROJECT_URL') . '/builds/' . $this->getBuildNumber(); } public function getGitCommit() : string { return !empty($this->env->getString('CI_COMMIT_SHA')) ? $this->env->getString('CI_COMMIT_SHA') : $this->env->getString('CI_BUILD_REF'); } public function getGitBranch() : string { return !empty($this->env->getString('CI_COMMIT_REF_NAME')) ? $this->env->getString('CI_COMMIT_REF_NAME') : $this->env->getString('CI_BUILD_REF_NAME'); } public function getRepositoryName() : string { return $this->env->getString('CI_PROJECT_PATH'); } public function getRepositoryUrl() : string { return !empty($this->env->getString('CI_REPOSITORY_URL')) ? $this->env->getString('CI_REPOSITORY_URL') : $this->env->getString('CI_BUILD_REPO'); } } get('TRAVIS') !== \false; } public function getCiName() : string { return CiDetector::CI_TRAVIS; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->env->getString('TRAVIS_PULL_REQUEST') !== 'false'); } public function getBuildNumber() : string { return $this->env->getString('TRAVIS_JOB_NUMBER'); } public function getBuildUrl() : string { return \sprintf('%s/%s/jobs/%s', self::TRAVIS_BASE_URL, $this->env->get('TRAVIS_REPO_SLUG'), $this->env->get('TRAVIS_JOB_ID')); } public function getGitCommit() : string { return $this->env->getString('TRAVIS_COMMIT'); } public function getGitBranch() : string { if ($this->isPullRequest()->no()) { return $this->env->getString('TRAVIS_BRANCH'); } // If the build is for PR, return name of the branch with the PR, not the target PR branch // https://github.com/travis-ci/travis-ci/issues/6652 return $this->env->getString('TRAVIS_PULL_REQUEST_BRANCH'); } public function getRepositoryName() : string { return $this->env->getString('TRAVIS_REPO_SLUG'); } public function getRepositoryUrl() : string { return ''; // unsupported } } get('WERCKER') === 'true'; } public function getCiName() : string { return CiDetector::CI_WERCKER; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getBuildNumber() : string { return $this->env->getString('WERCKER_RUN_ID'); } public function getBuildUrl() : string { return $this->env->getString('WERCKER_RUN_URL'); } public function getGitCommit() : string { return $this->env->getString('WERCKER_GIT_COMMIT'); } public function getGitBranch() : string { return $this->env->getString('WERCKER_GIT_BRANCH'); } public function getRepositoryName() : string { return $this->env->getString('WERCKER_GIT_OWNER') . '/' . $this->env->getString('WERCKER_GIT_REPOSITORY'); } public function getRepositoryUrl() : string { return ''; // unsupported } } get('TEAMCITY_VERSION') !== \false; } public function getCiName() : string { return CiDetector::CI_TEAMCITY; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getBuildNumber() : string { return $this->env->getString('BUILD_NUMBER'); } public function getBuildUrl() : string { return ''; // unsupported } public function getGitCommit() : string { return $this->env->getString('BUILD_VCS_NUMBER'); } public function getGitBranch() : string { return ''; // unsupported } public function getRepositoryName() : string { return ''; // unsupported } public function getRepositoryUrl() : string { return ''; // unsupported } } get('APPVEYOR') === 'True'; } public function getCiName() : string { return CiDetector::CI_APPVEYOR; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->env->getString('APPVEYOR_PULL_REQUEST_NUMBER') !== ''); } public function getBuildNumber() : string { return $this->env->getString('APPVEYOR_BUILD_NUMBER'); } public function getBuildUrl() : string { return \sprintf('%s/project/%s/%s/builds/%s', $this->env->get('APPVEYOR_URL'), $this->env->get('APPVEYOR_ACCOUNT_NAME'), $this->env->get('APPVEYOR_PROJECT_SLUG'), $this->env->get('APPVEYOR_BUILD_ID')); } public function getGitCommit() : string { return $this->env->getString('APPVEYOR_REPO_COMMIT'); } public function getGitBranch() : string { $prBranch = $this->env->getString('APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH'); if ($this->isPullRequest()->no() || empty($prBranch)) { return $this->env->getString('APPVEYOR_REPO_BRANCH'); } return $prBranch; } public function getRepositoryName() : string { return $this->env->getString('APPVEYOR_REPO_NAME'); } public function getRepositoryUrl() : string { return ''; // unsupported } } get('BUDDY') !== \false; } public function getCiName() : string { return CiDetector::CI_BUDDY; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->env->getString('BUDDY_EXECUTION_PULL_REQUEST_ID') !== ''); } public function getBuildNumber() : string { return $this->env->getString('BUDDY_EXECUTION_ID'); } public function getBuildUrl() : string { return $this->env->getString('BUDDY_EXECUTION_URL'); } public function getGitCommit() : string { return $this->env->getString('BUDDY_EXECUTION_REVISION'); } public function getGitBranch() : string { $prBranch = $this->env->getString('BUDDY_EXECUTION_PULL_REQUEST_HEAD_BRANCH'); if ($this->isPullRequest()->no() || empty($prBranch)) { return $this->env->getString('BUDDY_EXECUTION_BRANCH'); } return $prBranch; } public function getRepositoryName() : string { return $this->env->getString('BUDDY_REPO_SLUG'); } public function getRepositoryUrl() : string { return $this->env->getString('BUDDY_SCM_URL'); } } get('CI_NAME') === 'codeship'; } public function getCiName() : string { return CiDetector::CI_CODESHIP; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->env->getString('CI_PULL_REQUEST') !== 'false'); } public function getBuildNumber() : string { return $this->env->getString('CI_BUILD_NUMBER'); } public function getBuildUrl() : string { return $this->env->getString('CI_BUILD_URL'); } public function getGitCommit() : string { return $this->env->getString('COMMIT_ID'); } public function getGitBranch() : string { return $this->env->getString('CI_BRANCH'); } public function getRepositoryName() : string { return $this->env->getString('CI_REPO_NAME'); } public function getRepositoryUrl() : string { return ''; // unsupported } } get('GITHUB_ACTIONS') !== \false; } public function getCiName() : string { return CiDetector::CI_GITHUB_ACTIONS; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->env->getString('GITHUB_EVENT_NAME') === 'pull_request'); } public function getBuildNumber() : string { return $this->env->getString('GITHUB_RUN_NUMBER'); } public function getBuildUrl() : string { return \sprintf('%s/%s/commit/%s/checks', self::GITHUB_BASE_URL, $this->env->get('GITHUB_REPOSITORY'), $this->env->get('GITHUB_SHA')); } public function getGitCommit() : string { return $this->env->getString('GITHUB_SHA'); } public function getGitBranch() : string { $prBranch = $this->env->getString('GITHUB_HEAD_REF'); if ($this->isPullRequest()->no() || empty($prBranch)) { $gitReference = $this->env->getString('GITHUB_REF'); return \preg_replace('~^refs/heads/~', '', $gitReference) ?? ''; } return $prBranch; } public function getRepositoryName() : string { return $this->env->getString('GITHUB_REPOSITORY'); } public function getRepositoryUrl() : string { return \sprintf('%s/%s', self::GITHUB_BASE_URL, $this->env->get('GITHUB_REPOSITORY')); } } get('BITBUCKET_COMMIT') !== \false; } public function getCiName() : string { return CiDetector::CI_BITBUCKET_PIPELINES; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->env->getString('BITBUCKET_PR_ID') !== ''); } public function getBuildNumber() : string { return $this->env->getString('BITBUCKET_BUILD_NUMBER'); } public function getBuildUrl() : string { return \sprintf('%s/addon/pipelines/home#!/results/%s', $this->env->get('BITBUCKET_GIT_HTTP_ORIGIN'), $this->env->get('BITBUCKET_BUILD_NUMBER')); } public function getGitCommit() : string { return $this->env->getString('BITBUCKET_COMMIT'); } public function getGitBranch() : string { return $this->env->getString('BITBUCKET_BRANCH'); } public function getRepositoryName() : string { return $this->env->getString('BITBUCKET_REPO_FULL_NAME'); } public function getRepositoryUrl() : string { return \sprintf('ssh://%s', $this->env->get('BITBUCKET_GIT_SSH_ORIGIN')); } } get('bamboo_buildKey') !== \false; } public function getCiName() : string { return CiDetector::CI_BAMBOO; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->env->get('bamboo_repository_pr_key') !== \false); } public function getBuildNumber() : string { return $this->env->getString('bamboo_buildNumber'); } public function getBuildUrl() : string { return $this->env->getString('bamboo_resultsUrl'); } public function getGitCommit() : string { return $this->env->getString('bamboo_planRepository_revision'); } public function getGitBranch() : string { $prBranch = $this->env->getString('bamboo_repository_pr_sourceBranch'); if ($this->isPullRequest()->no() || empty($prBranch)) { return $this->env->getString('bamboo_planRepository_branch'); } return $prBranch; } public function getRepositoryName() : string { return $this->env->getString('bamboo_planRepository_name'); } public function getRepositoryUrl() : string { return $this->env->getString('bamboo_planRepository_repositoryUrl'); } } get('JENKINS_URL') !== \false; } public function getCiName() : string { return CiDetector::CI_JENKINS; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createMaybe(); } public function getBuildNumber() : string { return $this->env->getString('BUILD_NUMBER'); } public function getBuildUrl() : string { return $this->env->getString('BUILD_URL'); } public function getGitCommit() : string { return $this->env->getString('GIT_COMMIT'); } public function getGitBranch() : string { return $this->env->getString('GIT_BRANCH'); } public function getRepositoryName() : string { return ''; // unsupported } public function getRepositoryUrl() : string { return $this->env->getString('GIT_URL'); } } get('CI') === 'drone'; } public function getCiName() : string { return CiDetector::CI_DRONE; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->env->getString('DRONE_PULL_REQUEST') !== ''); } public function getBuildNumber() : string { return $this->env->getString('DRONE_BUILD_NUMBER'); } public function getBuildUrl() : string { return $this->env->getString('DRONE_BUILD_LINK'); } public function getGitCommit() : string { return $this->env->getString('DRONE_COMMIT_SHA'); } public function getGitBranch() : string { return $this->env->getString('DRONE_COMMIT_BRANCH'); } public function getRepositoryName() : string { return $this->env->getString('DRONE_REPO'); } public function getRepositoryUrl() : string { return $this->env->getString('DRONE_REPO_LINK'); } } get('CONTINUOUSPHP') === 'continuousphp'; } public function getCiName() : string { return CiDetector::CI_CONTINUOUSPHP; } public function isPullRequest() : TrinaryLogic { return TrinaryLogic::createFromBoolean($this->env->getString('CPHP_PR_ID') !== ''); } public function getBuildNumber() : string { return $this->env->getString('CPHP_BUILD_ID'); } public function getBuildUrl() : string { return $this->env->getString(''); } public function getGitCommit() : string { return $this->env->getString('CPHP_GIT_COMMIT'); } public function getGitBranch() : string { $gitReference = $this->env->getString('CPHP_GIT_REF'); return \preg_replace('~^refs/heads/~', '', $gitReference) ?? ''; } public function getRepositoryName() : string { return ''; // unsupported } public function getRepositoryUrl() : string { return $this->env->getString(''); } } value = $value; } public static function createMaybe() : self { return self::create(self::MAYBE); } public static function createFromBoolean(bool $value) : self { return self::create($value ? self::YES : self::NO); } private static function create(int $value) : self { return self::$registry[$value] = self::$registry[$value] ?? new self($value); } /** * Return true if its known for sure that the value is true */ public function yes() : bool { return $this->value === self::YES; } /** * Return true if its not known for sure whether the value is true or false */ public function maybe() : bool { return $this->value === self::MAYBE; } /** * Return true if its known for sure that the value is false */ public function no() : bool { return $this->value === self::NO; } /** * Return string representation of the value. * "Yes" when the value is true, "No" when its false, "Maybe" when its not known for sure whether its true or false. */ public function describe() : string { static $labels = [self::NO => 'No', self::MAYBE => 'Maybe', self::YES => 'Yes']; return $labels[$this->value]; } } environment = new Env(); } public static function fromEnvironment(Env $environment) : self { $detector = new static(); $detector->environment = $environment; return $detector; } /** * Is current environment an recognized CI server? */ public function isCiDetected() : bool { $ciServer = $this->detectCurrentCiServer(); return $ciServer !== null; } /** * Detect current CI server and return instance of its settings * * @throws CiNotDetectedException */ public function detect() : CiInterface { $ciServer = $this->detectCurrentCiServer(); if ($ciServer === null) { throw new CiNotDetectedException('No CI server detected in current environment'); } return $ciServer; } /** * @return string[] */ protected function getCiServers() : array { return [Ci\AppVeyor::class, Ci\AwsCodeBuild::class, Ci\Bamboo::class, Ci\BitbucketPipelines::class, Ci\Buddy::class, Ci\Circle::class, Ci\Codeship::class, Ci\Continuousphp::class, Ci\Drone::class, Ci\GitHubActions::class, Ci\GitLab::class, Ci\Jenkins::class, Ci\TeamCity::class, Ci\Travis::class, Ci\Wercker::class]; } protected function detectCurrentCiServer() : ?CiInterface { $ciServers = $this->getCiServers(); foreach ($ciServers as $ciClass) { $callback = [$ciClass, 'isDetected']; if (\is_callable($callback)) { if ($callback($this->environment)) { return new $ciClass($this->environment); } } } return null; } } { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "local>Ocramius/.github:renovate-config" ] } findFile directory, rather than * ClassLoader->loadClass because this library has a strict requirement that we * do NOT actually load the classes */ class ComposerSourceLocator extends \PHPStan\BetterReflection\SourceLocator\Type\AbstractSourceLocator { /** * @var \Composer\Autoload\ClassLoader */ private $classLoader; public function __construct(ClassLoader $classLoader, Locator $astLocator) { $this->classLoader = $classLoader; parent::__construct($astLocator); } /** * {@inheritDoc} * * @throws InvalidArgumentException * @throws InvalidFileLocation */ protected function createLocatedSource(Identifier $identifier) : ?\PHPStan\BetterReflection\SourceLocator\Located\LocatedSource { if ($identifier->getType()->getName() !== IdentifierType::IDENTIFIER_CLASS) { return null; } $filename = $this->classLoader->findFile($identifier->getName()); if ($filename === \false) { return null; } return new LocatedSource(file_get_contents($filename), $identifier->getName(), $filename); } } astLocator = $astLocator; } /** * {@inheritDoc} * * @throws ParseToAstFailure */ public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?\PHPStan\BetterReflection\Reflection\Reflection { $locatedSource = $this->createLocatedSource($identifier); if (!$locatedSource) { return null; } try { return $this->astLocator->findReflection($reflector, $locatedSource, $identifier); } catch (IdentifierNotFound $exception) { return null; } } /** * {@inheritDoc} * * @throws ParseToAstFailure */ public final function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { $locatedSource = $this->createLocatedSource(new Identifier(Identifier::WILDCARD, $identifierType)); if (!$locatedSource) { return []; } return $this->astLocator->findReflectionsOfType($reflector, $locatedSource, $identifierType); } } }|list|null $installedJson */ $installedJson = json_decode($jsonContent, \true); if (!is_array($composer)) { throw FailedToParseJson::inFile($composerJsonPath); } if (!is_array($installedJson)) { throw FailedToParseJson::inFile($installedJsonPath); } /** @psalm-var list $installed */ $installed = $installedJson['packages'] ?? $installedJson; $classMapPaths = array_merge($this->prefixPaths($this->packageToClassMapPaths($composer), $realInstallationPath . '/'), ...array_map(function (array $package) use($realInstallationPath, $vendorDir) : array { return $this->prefixPaths($this->packageToClassMapPaths($package), $this->packagePrefixPath($realInstallationPath, $package, $vendorDir)); }, $installed)); $classMapFiles = array_filter($classMapPaths, 'is_file'); $classMapDirectories = array_values(array_filter($classMapPaths, 'is_dir')); $filePaths = array_merge($this->prefixPaths($this->packageToFilePaths($composer), $realInstallationPath . '/'), ...array_map(function (array $package) use($realInstallationPath, $vendorDir) : array { return $this->prefixPaths($this->packageToFilePaths($package), $this->packagePrefixPath($realInstallationPath, $package, $vendorDir)); }, $installed)); return new AggregateSourceLocator(array_merge([new PsrAutoloaderLocator(Psr4Mapping::fromArrayMappings(array_merge_recursive($this->prefixWithInstallationPath($this->packageToPsr4AutoloadNamespaces($composer), $realInstallationPath), ...array_map(function (array $package) use($realInstallationPath, $vendorDir) : array { return $this->prefixWithPackagePath($this->packageToPsr4AutoloadNamespaces($package), $realInstallationPath, $package, $vendorDir); }, $installed))), $astLocator), new PsrAutoloaderLocator(Psr0Mapping::fromArrayMappings(array_merge_recursive($this->prefixWithInstallationPath($this->packageToPsr0AutoloadNamespaces($composer), $realInstallationPath), ...array_map(function (array $package) use($realInstallationPath, $vendorDir) : array { return $this->prefixWithPackagePath($this->packageToPsr0AutoloadNamespaces($package), $realInstallationPath, $package, $vendorDir); }, $installed))), $astLocator), new DirectoriesSourceLocator($classMapDirectories, $astLocator)], ...array_map(static function (string $file) use($astLocator) : array { assert($file !== ''); return [new SingleFileSourceLocator($file, $astLocator)]; }, array_merge($classMapFiles, $filePaths)))); } /** * @param ComposerPackage|Composer $package * * @return array> */ private function packageToPsr4AutoloadNamespaces(array $package) : array { return array_map(static function ($namespacePaths) : array { return (array) $namespacePaths; }, $package['autoload']['psr-4'] ?? []); } /** * @param ComposerPackage|Composer $package * * @return array> */ private function packageToPsr0AutoloadNamespaces(array $package) : array { return array_map(static function ($namespacePaths) : array { return (array) $namespacePaths; }, $package['autoload']['psr-0'] ?? []); } /** * @param ComposerPackage|Composer $package * * @return list */ private function packageToClassMapPaths(array $package) : array { return $package['autoload']['classmap'] ?? []; } /** * @param ComposerPackage|Composer $package * * @return list */ private function packageToFilePaths(array $package) : array { return $package['autoload']['files'] ?? []; } /** @param ComposerPackage $package */ private function packagePrefixPath(string $trimmedInstallationPath, array $package, string $vendorDir) : string { return $trimmedInstallationPath . '/' . $vendorDir . '/' . $package['name'] . '/'; } /** * @param array> $paths * @param ComposerPackage $package $package * * @return array> */ private function prefixWithPackagePath(array $paths, string $trimmedInstallationPath, array $package, string $vendorDir) : array { $prefix = $this->packagePrefixPath($trimmedInstallationPath, $package, $vendorDir); return array_map(function (array $paths) use($prefix) : array { return $this->prefixPaths($paths, $prefix); }, $paths); } /** * @param array> $paths * * @return array> */ private function prefixWithInstallationPath(array $paths, string $trimmedInstallationPath) : array { return array_map(function (array $paths) use($trimmedInstallationPath) : array { return $this->prefixPaths($paths, $trimmedInstallationPath . '/'); }, $paths); } /** * @param list $paths * * @return list */ private function prefixPaths(array $paths, string $prefix) : array { return array_map(static function (string $path) use($prefix) : string { return $prefix . $path; }, $paths); } } >, * psr-4?: array>, * classmap?: list, * files?: list, * exclude-from-classmap?: list * } * @psalm-type ComposerPackage array{ * name: string, * autoload: ComposerAutoload * } * @psalm-type Composer array{ * autoload: ComposerAutoload, * config?: array{vendor-dir?: string} * } */ final class MakeLocatorForComposerJson { public function __invoke(string $installationPath, Locator $astLocator) : SourceLocator { $realInstallationPath = (string) realpath($installationPath); if (!is_dir($realInstallationPath)) { throw InvalidProjectDirectory::atPath($installationPath); } $composerJsonPath = $realInstallationPath . '/composer.json'; if (!is_file($composerJsonPath)) { throw MissingComposerJson::inProjectPath($installationPath); } $composerJsonContent = file_get_contents($composerJsonPath); assert(is_string($composerJsonContent)); /** @psalm-var array{autoload: ComposerAutoload}|null $composer */ $composer = json_decode($composerJsonContent, \true); if (!is_array($composer)) { throw FailedToParseJson::inFile($composerJsonPath); } $pathPrefix = $realInstallationPath . '/'; $classMapPaths = $this->prefixPaths($this->packageToClassMapPaths($composer), $pathPrefix); $classMapFiles = array_filter($classMapPaths, 'is_file'); $classMapDirectories = array_values(array_filter($classMapPaths, 'is_dir')); $filePaths = $this->prefixPaths($this->packageToFilePaths($composer), $pathPrefix); return new AggregateSourceLocator(array_merge([new PsrAutoloaderLocator(Psr4Mapping::fromArrayMappings($this->prefixWithInstallationPath($this->packageToPsr4AutoloadNamespaces($composer), $pathPrefix)), $astLocator), new PsrAutoloaderLocator(Psr0Mapping::fromArrayMappings($this->prefixWithInstallationPath($this->packageToPsr0AutoloadNamespaces($composer), $pathPrefix)), $astLocator), new DirectoriesSourceLocator($classMapDirectories, $astLocator)], ...array_map(static function (string $file) use($astLocator) : array { assert($file !== ''); return [new SingleFileSourceLocator($file, $astLocator)]; }, array_merge($classMapFiles, $filePaths)))); } /** * @param array{autoload: ComposerAutoload} $package * * @return array> */ private function packageToPsr4AutoloadNamespaces(array $package) : array { return array_map(static function ($namespacePaths) : array { return (array) $namespacePaths; }, $package['autoload']['psr-4'] ?? []); } /** * @param array{autoload: ComposerAutoload} $package * * @return array> */ private function packageToPsr0AutoloadNamespaces(array $package) : array { return array_map(static function ($namespacePaths) : array { return (array) $namespacePaths; }, $package['autoload']['psr-0'] ?? []); } /** * @param array{autoload: ComposerAutoload} $package * * @return list */ private function packageToClassMapPaths(array $package) : array { return $package['autoload']['classmap'] ?? []; } /** * @param array{autoload: ComposerAutoload} $package * * @return list */ private function packageToFilePaths(array $package) : array { return $package['autoload']['files'] ?? []; } /** * @param array> $paths * * @return array> */ private function prefixWithInstallationPath(array $paths, string $trimmedInstallationPath) : array { return array_map(function (array $paths) use($trimmedInstallationPath) : array { return $this->prefixPaths($paths, $trimmedInstallationPath); }, $paths); } /** * @param list $paths * * @return list */ private function prefixPaths(array $paths, string $prefix) : array { return array_map(static function (string $path) use($prefix) : string { return $prefix . $path; }, $paths); } } }|list|null $installedJson */ $installedJson = json_decode($jsonContent, \true); if (!is_array($installedJson)) { throw FailedToParseJson::inFile($installedJsonPath); } /** @psalm-var list $installed */ $installed = $installedJson['packages'] ?? $installedJson; $classMapPaths = array_merge([], ...array_map(function (array $package) use($realInstallationPath, $vendorDir) : array { return $this->prefixPaths($this->packageToClassMapPaths($package), $this->packagePrefixPath($realInstallationPath, $package, $vendorDir)); }, $installed)); $classMapFiles = array_filter($classMapPaths, 'is_file'); $classMapDirectories = array_values(array_filter($classMapPaths, 'is_dir')); $filePaths = array_merge([], ...array_map(function (array $package) use($realInstallationPath, $vendorDir) : array { return $this->prefixPaths($this->packageToFilePaths($package), $this->packagePrefixPath($realInstallationPath, $package, $vendorDir)); }, $installed)); return new AggregateSourceLocator(array_merge([new PsrAutoloaderLocator(Psr4Mapping::fromArrayMappings(array_merge_recursive([], ...array_map(function (array $package) use($realInstallationPath, $vendorDir) : array { return $this->prefixWithPackagePath($this->packageToPsr4AutoloadNamespaces($package), $realInstallationPath, $package, $vendorDir); }, $installed))), $astLocator), new PsrAutoloaderLocator(Psr0Mapping::fromArrayMappings(array_merge_recursive([], ...array_map(function (array $package) use($realInstallationPath, $vendorDir) : array { return $this->prefixWithPackagePath($this->packageToPsr0AutoloadNamespaces($package), $realInstallationPath, $package, $vendorDir); }, $installed))), $astLocator), new DirectoriesSourceLocator($classMapDirectories, $astLocator)], ...array_map(static function (string $file) use($astLocator) : array { assert($file !== ''); return [new SingleFileSourceLocator($file, $astLocator)]; }, array_merge($classMapFiles, $filePaths)))); } /** * @param ComposerPackage $package * * @return array> */ private function packageToPsr4AutoloadNamespaces(array $package) : array { return array_map(static function ($namespacePaths) : array { return (array) $namespacePaths; }, $package['autoload']['psr-4'] ?? []); } /** * @param ComposerPackage $package * * @return array> */ private function packageToPsr0AutoloadNamespaces(array $package) : array { return array_map(static function ($namespacePaths) : array { return (array) $namespacePaths; }, $package['autoload']['psr-0'] ?? []); } /** * @param ComposerPackage $package * * @return list */ private function packageToClassMapPaths(array $package) : array { return $package['autoload']['classmap'] ?? []; } /** * @param ComposerPackage $package * * @return list */ private function packageToFilePaths(array $package) : array { return $package['autoload']['files'] ?? []; } /** @param ComposerPackage $package */ private function packagePrefixPath(string $trimmedInstallationPath, array $package, string $vendorDir) : string { return $trimmedInstallationPath . '/' . $vendorDir . '/' . $package['name'] . '/'; } /** * @param array> $paths * @param ComposerPackage $package * * @return array> */ private function prefixWithPackagePath(array $paths, string $trimmedInstallationPath, array $package, string $vendorDir) : array { $prefix = $this->packagePrefixPath($trimmedInstallationPath, $package, $vendorDir); return array_map(function (array $paths) use($prefix) : array { return $this->prefixPaths($paths, $prefix); }, $paths); } /** * @param array $paths * * @return array */ private function prefixPaths(array $paths, string $prefix) : array { return array_map(static function (string $path) use($prefix) : string { return $prefix . $path; }, $paths); } } mapping = $mapping; $this->astLocator = $astLocator; } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?\PHPStan\BetterReflection\Reflection\Reflection { /** @phpstan-var non-empty-string $file */ foreach ($this->mapping->resolvePossibleFilePaths($identifier) as $file) { try { FileChecker::assertReadableFile($file); return $this->astLocator->findReflection($reflector, new LocatedSource(file_get_contents($file), $identifier->getName(), $file), $identifier); } catch (InvalidFileLocation $exception) { // Ignore } catch (IdentifierNotFound $exception) { // on purpose - autoloading is allowed to fail, and silently-failing autoloaders are normal/endorsed } } return null; } /** * Find all identifiers of a type * * @return list */ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return (new DirectoriesSourceLocator($this->mapping->directories(), $this->astLocator))->locateIdentifiersByType($reflector, $identifierType); } } */ public function resolvePossibleFilePaths(Identifier $identifier) : array; /** @return list */ public function directories() : array; } > */ private $mappings = []; private function __construct() { } /** @param array> $mappings */ public static function fromArrayMappings(array $mappings) : self { $instance = new self(); $instance->mappings = array_map(static function (array $directories) : array { return array_map(static function (string $directory) : string { return rtrim($directory, '/'); }, $directories); }, $mappings); return $instance; } /** {@inheritDoc} */ public function resolvePossibleFilePaths(Identifier $identifier) : array { if (!$identifier->isClass()) { return []; } $className = $identifier->getName(); foreach ($this->mappings as $prefix => $paths) { if ($prefix === '') { continue; } if (strpos($className, $prefix) === 0) { return array_map(static function (string $path) use($className) : string { return $path . '/' . str_replace(['\\', '_'], '/', $className) . '.php'; }, $paths); } } return []; } /** {@inheritDoc} */ public function directories() : array { return array_values(array_unique(array_merge([], ...array_values($this->mappings)))); } } > */ private $mappings = []; private function __construct() { } /** @param array> $mappings */ public static function fromArrayMappings(array $mappings) : self { $instance = new self(); $instance->mappings = array_map(static function (array $directories) : array { return array_map(static function (string $directory) : string { return rtrim($directory, '/'); }, $directories); }, $mappings); return $instance; } /** {@inheritDoc} */ public function resolvePossibleFilePaths(Identifier $identifier) : array { if (!$identifier->isClass()) { return []; } $className = $identifier->getName(); $matchingPrefixes = $this->matchingPrefixes($className); return array_values(array_filter(array_merge([], ...array_map(static function (array $paths, string $prefix) use($className) : array { $subPath = ltrim(str_replace('\\', '/', substr($className, strlen($prefix))), '/'); if ($subPath === '') { return []; } return array_map(static function (string $path) use($subPath) : string { return $path . '/' . $subPath . '.php'; }, $paths); }, $matchingPrefixes, array_keys($matchingPrefixes))))); } /** @return array> */ private function matchingPrefixes(string $className) : array { return array_filter($this->mappings, static function (string $prefix) use($className) : bool { if ($prefix === '') { return \false; } return strpos($className, $prefix) === 0; }, ARRAY_FILTER_USE_KEY); } /** {@inheritDoc} */ public function directories() : array { return array_values(array_unique(array_merge([], ...array_values($this->mappings)))); } } */ private $fileSystemIterator; /** * @var \PHPStan\BetterReflection\SourceLocator\Ast\Locator */ private $astLocator; /** * @param Iterator $fileInfoIterator note: only SplFileInfo allowed in this iterator * * @throws InvalidFileInfo In case of iterator not contains only SplFileInfo. */ public function __construct(Iterator $fileInfoIterator, Locator $astLocator) { $this->astLocator = $astLocator; foreach ($fileInfoIterator as $fileInfo) { if (!$fileInfo instanceof SplFileInfo) { throw InvalidFileInfo::fromNonSplFileInfo($fileInfo); } } $this->fileSystemIterator = $fileInfoIterator; } /** @throws InvalidFileLocation */ private function getAggregatedSourceLocator() : \PHPStan\BetterReflection\SourceLocator\Type\AggregateSourceLocator { // @infection-ignore-all Coalesce: There's no difference, it's just optimization return $this->aggregateSourceLocator ?? ($this->aggregateSourceLocator = new \PHPStan\BetterReflection\SourceLocator\Type\AggregateSourceLocator(array_values(array_filter(array_map(function (SplFileInfo $item) : ?\PHPStan\BetterReflection\SourceLocator\Type\SingleFileSourceLocator { $realPath = $item->getRealPath(); if (!($item->isFile() && pathinfo($realPath, PATHINFO_EXTENSION) === 'php')) { return null; } return new \PHPStan\BetterReflection\SourceLocator\Type\SingleFileSourceLocator($realPath, $this->astLocator); }, iterator_to_array($this->fileSystemIterator)))))); } /** * {@inheritDoc} * * @throws InvalidFileLocation */ public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?\PHPStan\BetterReflection\Reflection\Reflection { return $this->getAggregatedSourceLocator()->locateIdentifier($reflector, $identifier); } /** * {@inheritDoc} * * @throws InvalidFileLocation */ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return $this->getAggregatedSourceLocator()->locateIdentifiersByType($reflector, $identifierType); } } $directories directories to scan * * @throws InvalidDirectory * @throws InvalidFileInfo */ public function __construct(array $directories, Locator $astLocator) { $this->aggregateSourceLocator = new \PHPStan\BetterReflection\SourceLocator\Type\AggregateSourceLocator(array_map(static function (string $directory) use($astLocator) : \PHPStan\BetterReflection\SourceLocator\Type\FileIteratorSourceLocator { if (!is_dir($directory)) { throw InvalidDirectory::fromNonDirectory($directory); } return new \PHPStan\BetterReflection\SourceLocator\Type\FileIteratorSourceLocator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS)), $astLocator); }, $directories)); } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?\PHPStan\BetterReflection\Reflection\Reflection { return $this->aggregateSourceLocator->locateIdentifier($reflector, $identifier); } /** * {@inheritDoc} */ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return $this->aggregateSourceLocator->locateIdentifiersByType($reflector, $identifierType); } } source = $source; parent::__construct($astLocator); } /** * {@inheritDoc} * * @throws InvalidArgumentException * @throws InvalidFileLocation */ protected function createLocatedSource(Identifier $identifier) : ?\PHPStan\BetterReflection\SourceLocator\Located\LocatedSource { return new LocatedSource($this->source, $identifier->getName(), null); } } astLocator()); $this->phpParser = $phpParser ?? $betterReflection->phpParser(); $this->constantVisitor = $this->createConstantVisitor(); $this->nodeTraverser = new NodeTraverser(); $this->nodeTraverser->addVisitor(new NameResolver()); $this->nodeTraverser->addVisitor($this->constantVisitor); } /** * {@inheritDoc} * * @throws InvalidArgumentException * @throws InvalidFileLocation */ protected function createLocatedSource(Identifier $identifier) : ?\PHPStan\BetterReflection\SourceLocator\Located\LocatedSource { $locatedData = $this->attemptAutoloadForIdentifier($identifier); if ($locatedData === null) { return null; } if (!is_file($locatedData['fileName'])) { return null; } if (strtolower($identifier->getName()) !== strtolower($locatedData['name'])) { return new AliasLocatedSource(file_get_contents($locatedData['fileName']), $locatedData['name'], $locatedData['fileName'], $identifier->getName()); } return new LocatedSource(file_get_contents($locatedData['fileName']), $identifier->getName(), $locatedData['fileName']); } /** * Attempts to locate the specified identifier. * * @return array{fileName: string, name: string}|null * * @throws ReflectionException */ private function attemptAutoloadForIdentifier(Identifier $identifier) : ?array { if ($identifier->isClass()) { return $this->locateClassByName($identifier->getName()); } if ($identifier->isFunction()) { return $this->locateFunctionByName($identifier->getName()); } if ($identifier->isConstant()) { return $this->locateConstantByName($identifier->getName()); } return null; } /** * Attempt to locate a class by name. * * If class already exists, simply use internal reflection API to get the * filename and store it. * * If class does not exist, we make an assumption that whatever autoloaders * that are registered will be loading a file. We then override the file:// * protocol stream wrapper to "capture" the filename we expect the class to * be in, and then restore it. Note that class_exists will cause an error * that it cannot find the file, so we squelch the errors by overriding the * error handler temporarily. * * Note: the following code is designed so that the first hit on an actual * **file** leads to a path being resolved. No actual autoloading nor * file reading should happen, and most certainly no other classes * should exist after execution. The only filesystem access is to * check whether the file exists. * * @return array{fileName: string, name: string}|null * * @throws ReflectionException */ private function locateClassByName(string $className) : ?array { if (ClassExistenceChecker::exists($className, \false)) { $classReflection = new ReflectionClass($className); $filename = $classReflection->getFileName(); if (!is_string($filename)) { return null; } return ['fileName' => $filename, 'name' => $classReflection->getName()]; } $this->silenceErrors(); try { $locatedFile = FileReadTrapStreamWrapper::withStreamWrapperOverride(static function () use($className) : ?string { foreach (spl_autoload_functions() as $preExistingAutoloader) { $preExistingAutoloader($className); /** * This static variable is populated by the side-effect of the stream wrapper * trying to read the file path when `include()` is used by an autoloader. * * This will not be `null` when the autoloader tried to read a file. */ if (FileReadTrapStreamWrapper::$autoloadLocatedFile !== null) { return FileReadTrapStreamWrapper::$autoloadLocatedFile; } } return null; }); if ($locatedFile === null) { return null; } return ['fileName' => $locatedFile, 'name' => $className]; } finally { restore_error_handler(); } } private function silenceErrors() : void { set_error_handler(static function () : bool { return \true; }); } /** * We can only load functions if they already exist, because PHP does not * have function autoloading. Therefore if it exists, we simply use the * internal reflection API to find the filename. If it doesn't we can do * nothing so throw an exception. * * @return array{fileName: string, name: string}|null * * @throws ReflectionException */ private function locateFunctionByName(string $functionName) : ?array { if (!function_exists($functionName)) { return null; } $reflectionFileName = (new ReflectionFunction($functionName))->getFileName(); if (!is_string($reflectionFileName)) { return null; } return ['fileName' => $reflectionFileName, 'name' => $functionName]; } /** * We can only load constants if they already exist, because PHP does not * have constant autoloading. Therefore if it exists, we simply use brute force * to search throughout all included files to find the right filename. * * @return array{fileName: string, name: string}|null */ private function locateConstantByName(string $constantName) : ?array { if (!defined($constantName)) { return null; } /** @var array|resource|null>> $constants */ $constants = get_defined_constants(\true); if (!array_key_exists($constantName, $constants['user'])) { return null; } /** @psalm-suppress UndefinedMethod */ $this->constantVisitor->setConstantName($constantName); $constantFileName = null; // Note: looking at files in reverse order, since newer files are more likely to have // defined a constant that is being looked up. Earlier files are possibly related // to libraries/frameworks that we rely upon. // @infection-ignore-all UnwrapArrayReverse: Ignore because the result is some with or without array_reverse() /** @phpstan-var non-empty-string $includedFileName */ foreach (array_reverse(get_included_files()) as $includedFileName) { try { FileChecker::assertReadableFile($includedFileName); } catch (InvalidFileLocation $exception) { continue; } /** @var list $ast */ $ast = $this->phpParser->parse(file_get_contents($includedFileName)); $this->nodeTraverser->traverse($ast); /** @psalm-suppress UndefinedMethod */ if ($this->constantVisitor->getNode() !== null) { $constantFileName = $includedFileName; break; } } if ($constantFileName === null) { return null; } return ['fileName' => $constantFileName, 'name' => $constantName]; } private function createConstantVisitor() : NodeVisitorAbstract { return new class extends NodeVisitorAbstract { /** * @var string|null */ private $constantName = null; /** * @var \PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall|null */ private $node = null; public function enterNode(Node $node) : ?int { if ($node instanceof Node\Stmt\Const_) { foreach ($node->consts as $constNode) { if ((($constNodeNamespacedName = $constNode->namespacedName) ? $constNodeNamespacedName->toString() : null) === $this->constantName) { $this->node = $node; return NodeTraverser::STOP_TRAVERSAL; } } return NodeTraverser::DONT_TRAVERSE_CHILDREN; } if ($node instanceof Node\Expr\FuncCall) { try { ConstantNodeChecker::assertValidDefineFunctionCall($node); } catch (InvalidConstantNode $exception) { return null; } $argumentNameNode = $node->args[0]; assert($argumentNameNode instanceof Node\Arg); $nameNode = $argumentNameNode->value; assert($nameNode instanceof Node\Scalar\String_); if ($nameNode->value === $this->constantName) { $this->node = $node; return NodeTraverser::STOP_TRAVERSAL; } } return null; } public function setConstantName(string $constantName) : void { $this->constantName = $constantName; } /** @return Node\Stmt\Const_|Node\Expr\FuncCall|null */ public function getNode() { return $this->node; } }; } } getClassesFromFile * (which loads all classes from specified file) */ class SingleFileSourceLocator extends \PHPStan\BetterReflection\SourceLocator\Type\AbstractSourceLocator { /** * @var non-empty-string */ private $fileName; /** * @param non-empty-string $fileName * * @throws InvalidFileLocation */ public function __construct(string $fileName, Locator $astLocator) { $this->fileName = $fileName; FileChecker::assertReadableFile($fileName); parent::__construct($astLocator); } /** * {@inheritDoc} * * @throws InvalidArgumentException * @throws InvalidFileLocation */ protected function createLocatedSource(Identifier $identifier) : ?\PHPStan\BetterReflection\SourceLocator\Located\LocatedSource { return new LocatedSource(file_get_contents($this->fileName), $identifier->getName(), $this->fileName); } } indexed by reflector key and identifier cache key */ private $cacheByIdentifierKeyAndOid = []; /** @var array> indexed by reflector key and identifier type cache key */ private $cacheByIdentifierTypeKeyAndOid = []; /** * @var \PHPStan\BetterReflection\SourceLocator\Type\SourceLocator */ private $wrappedSourceLocator; public function __construct(\PHPStan\BetterReflection\SourceLocator\Type\SourceLocator $wrappedSourceLocator) { $this->wrappedSourceLocator = $wrappedSourceLocator; } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?\PHPStan\BetterReflection\Reflection\Reflection { $cacheKey = sprintf('%s_%s', $this->reflectorCacheKey($reflector), $this->identifierToCacheKey($identifier)); if (array_key_exists($cacheKey, $this->cacheByIdentifierKeyAndOid)) { return $this->cacheByIdentifierKeyAndOid[$cacheKey]; } return $this->cacheByIdentifierKeyAndOid[$cacheKey] = $this->wrappedSourceLocator->locateIdentifier($reflector, $identifier); } /** @return list */ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { $cacheKey = sprintf('%s_%s', $this->reflectorCacheKey($reflector), $this->identifierTypeToCacheKey($identifierType)); if (array_key_exists($cacheKey, $this->cacheByIdentifierTypeKeyAndOid)) { return $this->cacheByIdentifierTypeKeyAndOid[$cacheKey]; } return $this->cacheByIdentifierTypeKeyAndOid[$cacheKey] = $this->wrappedSourceLocator->locateIdentifiersByType($reflector, $identifierType); } private function reflectorCacheKey(Reflector $reflector) : string { return sprintf('type:%s#oid:%d', \get_class($reflector), spl_object_id($reflector)); } private function identifierToCacheKey(Identifier $identifier) : string { return sprintf('%s#name:%s', $this->identifierTypeToCacheKey($identifier->getType()), $identifier->getName()); } private function identifierTypeToCacheKey(IdentifierType $identifierType) : string { return sprintf('type:%s', $identifierType->getName()); } } */ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array; } */ private $sourceLocators = []; /** @param list $sourceLocators */ public function __construct(array $sourceLocators = []) { $this->sourceLocators = $sourceLocators; } public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?\PHPStan\BetterReflection\Reflection\Reflection { foreach ($this->sourceLocators as $sourceLocator) { $located = $sourceLocator->locateIdentifier($reflector, $identifier); if ($located) { return $located; } } return null; } /** * {@inheritDoc} */ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return array_merge([], ...array_map(static function (\PHPStan\BetterReflection\SourceLocator\Type\SourceLocator $sourceLocator) use($reflector, $identifierType) : array { return $sourceLocator->locateIdentifiersByType($reflector, $identifierType); }, $this->sourceLocators)); } } |null */ private static $registeredStreamWrapperProtocols = null; /** * Read this property to determine the last file on which reads were attempted * * @psalm-readonly * @psalm-allow-private-mutation * @var string|null */ public static $autoloadLocatedFile = null; /** @var resource */ public $context; /** * @param callable() : ExecutedMethodReturnType $executeMeWithinStreamWrapperOverride * @param list $streamWrapperProtocols * * @psalm-return ExecutedMethodReturnType * * @psalm-template ExecutedMethodReturnType of mixed * @return mixed */ public static function withStreamWrapperOverride(callable $executeMeWithinStreamWrapperOverride, array $streamWrapperProtocols = self::DEFAULT_STREAM_WRAPPER_PROTOCOLS) { self::$registeredStreamWrapperProtocols = $streamWrapperProtocols; self::$autoloadLocatedFile = null; try { foreach ($streamWrapperProtocols as $protocol) { stream_wrapper_unregister($protocol); stream_wrapper_register($protocol, self::class); } $result = $executeMeWithinStreamWrapperOverride(); } finally { foreach ($streamWrapperProtocols as $protocol) { @stream_wrapper_restore($protocol); } self::$registeredStreamWrapperProtocols = null; self::$autoloadLocatedFile = null; } return $result; } /** * Our wrapper simply records which file we tried to load and returns * boolean false indicating failure. * * @internal do not call this method directly! This is stream wrapper * voodoo logic that you **DO NOT** want to touch! * * @see https://php.net/manual/en/class.streamwrapper.php * @see https://php.net/manual/en/streamwrapper.stream-open.php * * @param string $path * @param string $mode * @param int $options * @param string $opened_path */ public function stream_open($path, $mode, $options, &$opened_path) : bool { self::$autoloadLocatedFile = $path; // @infection-ignore-all FalseValue return \false; } /** * url_stat is triggered by calls like "file_exists". The call to "file_exists" must not be overloaded. * This function restores the original "file" stream, issues a call to "stat" to get the real results, * and then re-registers the AutoloadSourceLocator stream wrapper. * * @internal do not call this method directly! This is stream wrapper * voodoo logic that you **DO NOT** want to touch! * * @see https://php.net/manual/en/class.streamwrapper.php * @see https://php.net/manual/en/streamwrapper.url-stat.php * * @param string $path * @param int $flags * * @return mixed[]|bool */ public function url_stat($path, $flags) { if (self::$registeredStreamWrapperProtocols === null) { throw new LogicException(sprintf('%s not registered: cannot operate. Do not call this method directly.', self::class)); } foreach (self::$registeredStreamWrapperProtocols as $protocol) { stream_wrapper_restore($protocol); } if (($flags & STREAM_URL_STAT_QUIET) === STREAM_URL_STAT_QUIET) { $result = @stat($path); } else { $result = stat($path); } foreach (self::$registeredStreamWrapperProtocols as $protocol) { stream_wrapper_unregister($protocol); stream_wrapper_register($protocol, self::class); } return $result; } } parser = $parser; $this->coreFunctionReflection = new CoreFunctionReflection($closure); } /** * {@inheritDoc} * * @throws ParseToAstFailure */ public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?\PHPStan\BetterReflection\Reflection\Reflection { return $this->getReflectionFunction($reflector, $identifier->getType()); } /** * {@inheritDoc} * * @throws ParseToAstFailure */ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return array_filter([$this->getReflectionFunction($reflector, $identifierType)]); } private function getReflectionFunction(Reflector $reflector, IdentifierType $identifierType) : ?\PHPStan\BetterReflection\Reflection\ReflectionFunction { if (!$identifierType->isFunction()) { return null; } /** @phpstan-var non-empty-string $fileName */ $fileName = $this->coreFunctionReflection->getFileName(); if (strpos($fileName, 'eval()\'d code') !== \false) { throw EvaledClosureCannotBeLocated::create(); } FileChecker::assertReadableFile($fileName); $fileName = FileHelper::normalizeWindowsPath($fileName); $nodeVisitor = new class($fileName, $this->coreFunctionReflection->getStartLine()) extends NodeVisitorAbstract { /** @var list */ private $closureNodes = []; /** * @var \PhpParser\Node\Stmt\Namespace_|null */ private $currentNamespace = null; /** * @var string */ private $fileName; /** * @var int */ private $startLine; public function __construct(string $fileName, int $startLine) { $this->fileName = $fileName; $this->startLine = $startLine; } /** * {@inheritDoc} */ public function enterNode(Node $node) { if ($node instanceof Namespace_) { $this->currentNamespace = $node; return null; } if ($node->getStartLine() === $this->startLine && ($node instanceof Node\Expr\Closure || $node instanceof Node\Expr\ArrowFunction)) { $this->closureNodes[] = ['node' => $node, 'namespace' => $this->currentNamespace]; } return null; } /** * {@inheritDoc} */ public function leaveNode(Node $node) { if (!$node instanceof Namespace_) { return null; } $this->currentNamespace = null; return null; } /** * @return array{node: Node\Expr\Closure|Node\Expr\ArrowFunction, namespace: Namespace_|null} * * @throws NoClosureOnLine * @throws TwoClosuresOnSameLine */ public function getClosureNodes() : array { if ($this->closureNodes === []) { throw NoClosureOnLine::create($this->fileName, $this->startLine); } if (isset($this->closureNodes[1])) { throw TwoClosuresOnSameLine::create($this->fileName, $this->startLine); } return $this->closureNodes[0]; } }; $fileContents = file_get_contents($fileName); /** @var list $ast */ $ast = $this->parser->parse($fileContents); $nodeTraverser = new NodeTraverser(); $nodeTraverser->addVisitor(new NameResolver()); $nodeTraverser->addVisitor($nodeVisitor); $nodeTraverser->traverse($ast); $closureNodes = $nodeVisitor->getClosureNodes(); $reflectionFunction = (new NodeToReflection())->__invoke($reflector, $closureNodes['node'], new AnonymousLocatedSource($fileContents, $fileName), $closureNodes['namespace']); assert($reflectionFunction instanceof ReflectionFunction); return $reflectionFunction; } } parser = $parser; $this->coreClassReflection = new CoreReflectionClass($anonymousClassObject); } /** * {@inheritDoc} * * @throws ParseToAstFailure */ public function locateIdentifier(Reflector $reflector, Identifier $identifier) : ?\PHPStan\BetterReflection\Reflection\Reflection { return $this->getReflectionClass($reflector, $identifier->getType()); } /** * {@inheritDoc} * * @throws ParseToAstFailure */ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType) : array { return array_filter([$this->getReflectionClass($reflector, $identifierType)]); } private function getReflectionClass(Reflector $reflector, IdentifierType $identifierType) : ?\PHPStan\BetterReflection\Reflection\ReflectionClass { if (!$identifierType->isClass()) { return null; } if (!$this->coreClassReflection->isAnonymous()) { return null; } /** @phpstan-var non-empty-string $fileName */ $fileName = $this->coreClassReflection->getFileName(); if (strpos($fileName, 'eval()\'d code') !== \false) { throw EvaledAnonymousClassCannotBeLocated::create(); } FileChecker::assertReadableFile($fileName); $fileName = FileHelper::normalizeWindowsPath($fileName); $nodeVisitor = new class($fileName, $this->coreClassReflection->getStartLine()) extends NodeVisitorAbstract { /** @var list */ private $anonymousClassNodes = []; /** * @var string */ private $fileName; /** * @var int */ private $startLine; public function __construct(string $fileName, int $startLine) { $this->fileName = $fileName; $this->startLine = $startLine; } /** * {@inheritDoc} */ public function enterNode(Node $node) { if (!$node instanceof Node\Stmt\Class_ || $node->name !== null || $node->getLine() !== $this->startLine) { return null; } $this->anonymousClassNodes[] = $node; return null; } public function getAnonymousClassNode() : Class_ { if ($this->anonymousClassNodes === []) { throw NoAnonymousClassOnLine::create($this->fileName, $this->startLine); } if (isset($this->anonymousClassNodes[1])) { throw TwoAnonymousClassesOnSameLine::create($this->fileName, $this->startLine); } return $this->anonymousClassNodes[0]; } }; $fileContents = file_get_contents($fileName); /** @var list $ast */ $ast = $this->parser->parse($fileContents); $nodeTraverser = new NodeTraverser(); $nodeTraverser->addVisitor(new NameResolver()); $nodeTraverser->addVisitor($nodeVisitor); $nodeTraverser->traverse($ast); $reflectionClass = (new NodeToReflection())->__invoke($reflector, $nodeVisitor->getAnonymousClassNode(), new AnonymousLocatedSource($fileContents, $fileName), null); assert($reflectionClass instanceof ReflectionClass); return $reflectionClass; } } stubber = $stubber; parent::__construct($astLocator); } /** * {@inheritDoc} * * @throws InvalidArgumentException * @throws InvalidFileLocation */ protected function createLocatedSource(Identifier $identifier) : ?\PHPStan\BetterReflection\SourceLocator\Located\LocatedSource { $classReflection = $this->getInternalReflectionClass($identifier); if ($classReflection === null) { return null; } $stubData = $this->stubber->generateClassStub($classReflection->getName()); if ($stubData === null) { return null; } return new EvaledLocatedSource($stubData->getStub(), $classReflection->getName()); } private function getInternalReflectionClass(Identifier $identifier) : ?\ReflectionClass { if (!$identifier->isClass()) { return null; } /** @psalm-var class-string|trait-string $name */ $name = $identifier->getName(); if (!ClassExistenceChecker::exists($name, \false)) { return null; // not an available internal class } $reflection = new ReflectionClass($name); $sourceFile = $reflection->getFileName(); return $sourceFile !== \false && is_file($sourceFile) ? null : $reflection; } } stubber = $stubber; parent::__construct($astLocator); } /** * {@inheritDoc} * * @throws InvalidArgumentException * @throws InvalidFileLocation */ protected function createLocatedSource(Identifier $identifier) : ?\PHPStan\BetterReflection\SourceLocator\Located\LocatedSource { return $this->getClassSource($identifier) ?? $this->getFunctionSource($identifier) ?? $this->getConstantSource($identifier); } private function getClassSource(Identifier $identifier) : ?\PHPStan\BetterReflection\SourceLocator\Located\InternalLocatedSource { if (!$identifier->isClass()) { return null; } /** @psalm-var class-string|trait-string $className */ $className = $identifier->getName(); return $this->createLocatedSourceFromStubData($identifier, $this->stubber->generateClassStub($className)); } private function getFunctionSource(Identifier $identifier) : ?\PHPStan\BetterReflection\SourceLocator\Located\InternalLocatedSource { if (!$identifier->isFunction()) { return null; } return $this->createLocatedSourceFromStubData($identifier, $this->stubber->generateFunctionStub($identifier->getName())); } private function getConstantSource(Identifier $identifier) : ?\PHPStan\BetterReflection\SourceLocator\Located\InternalLocatedSource { if (!$identifier->isConstant()) { return null; } return $this->createLocatedSourceFromStubData($identifier, $this->stubber->generateConstantStub($identifier->getName())); } private function createLocatedSourceFromStubData(Identifier $identifier, ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData $stubData) : ?\PHPStan\BetterReflection\SourceLocator\Located\InternalLocatedSource { if ($stubData === null) { return null; } $extensionName = $stubData->getExtensionName(); if ($extensionName === null) { // Not internal return null; } return new InternalLocatedSource($stubData->getStub(), $identifier->getName(), $extensionName, $stubData->getFileName()); } } aliasName = $aliasName; parent::__construct($source, $name, $filename); } public function getAliasName() : ?string { return $this->aliasName; } } source = $source; $this->name = $name; if ($filename !== null) { assert($filename !== ''); $filename = FileHelper::normalizeWindowsPath($filename); } $this->filename = $filename; } public function getSource() : string { return $this->source; } public function getName() : ?string { return $this->name; } /** @return non-empty-string|null */ public function getFileName() : ?string { return $this->filename; } /** * Is the located source in PHP internals? */ public function isInternal() : bool { return \false; } /** @return non-empty-string|null */ public function getExtensionName() : ?string { return null; } /** * Is the located source produced by eval() or \function_create()? */ public function isEvaled() : bool { return \false; } public function getAliasName() : ?string { return null; } } extensionName = $extensionName; parent::__construct($source, $name, $fileName); } public function isInternal() : bool { return \true; } /** @return non-empty-string|null */ public function getExtensionName() : ?string { return $this->extensionName; } } phpVersion = $phpVersion; $this->builderFactory = new BuilderFactory(); $this->prettyPrinter = $prettyPrinter; } /** @param class-string|trait-string $className */ public function generateClassStub(string $className) : ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData { if (!ClassExistenceChecker::exists($className, \false)) { return null; } $enumExists = function (string $enum, bool $autoload = \true) : bool { if (function_exists('enum_exists')) { return \enum_exists($enum, $autoload); } return $autoload && \class_exists($enum) && \false; }; /** phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName */ $isEnum = function_exists('enum_exists') && $enumExists($className, \false); /** phpcs:enable */ $classReflection = $isEnum ? new CoreReflectionEnum($className) : new CoreReflectionClass($className); $classNode = $this->createClass($classReflection); if ($classNode instanceof Class_) { $this->addClassModifiers($classNode, $classReflection); } if ($classNode instanceof Class_ || $classNode instanceof Interface_ || $classNode instanceof Enum_) { $this->addExtendsAndImplements($classNode, $classReflection); } if ($classNode instanceof Class_ || $classNode instanceof Trait_) { $this->addProperties($classNode, $classReflection); } if ($classNode instanceof Class_ || $classNode instanceof Trait_ || $classNode instanceof Enum_) { $this->addTraitUse($classNode, $classReflection); } $this->addAttributes($classNode, $classReflection); $this->addDocComment($classNode, $classReflection); if ($classNode instanceof Enum_ && $classReflection instanceof CoreReflectionEnum) { $this->addEnumBackingType($classNode, $classReflection); $this->addEnumCases($classNode, $classReflection); } $this->addClassConstants($classNode, $classReflection); $this->addMethods($classNode, $classReflection); $node = $classNode->getNode(); $stub = $classReflection->inNamespace() ? $this->generateStubInNamespace($node, $classReflection->getNamespaceName()) : $this->generateStub($node); $extensionName = ($getExtension = $classReflection->getExtension()) ? $getExtension->getName() : null; assert(is_string($extensionName) && $extensionName !== '' || $extensionName === null); return $this->createStubData($stub, $extensionName, $classReflection->getFileName() !== \false ? $classReflection->getFileName() : null); } public function generateFunctionStub(string $functionName) : ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData { if (!function_exists($functionName)) { return null; } return $this->generateFunctionStubFromReflection(new CoreReflectionFunction($functionName)); } public function generateFunctionStubFromReflection(CoreReflectionFunction $functionReflection) : ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData { $shortName = $functionReflection->getShortName(); if ($functionReflection->isClosure()) { $shortName = '{closure}'; } $functionNode = $this->builderFactory->function($shortName); $this->addAttributes($functionNode, $functionReflection); $this->addDocComment($functionNode, $functionReflection); $this->addParameters($functionNode, $functionReflection); $returnType = $functionReflection->getReturnType(); if ($returnType === null && method_exists($functionReflection, 'getTentativeReturnType')) { $returnType = $functionReflection->getTentativeReturnType(); } if ($returnType !== null) { assert($returnType instanceof CoreReflectionNamedType || $returnType instanceof CoreReflectionUnionType || $returnType instanceof CoreReflectionIntersectionType); $functionNode->setReturnType($this->formatType($returnType)); } $extensionName = ($getExtension = $functionReflection->getExtension()) ? $getExtension->getName() : null; assert(is_string($extensionName) && $extensionName !== '' || $extensionName === null); if (!$functionReflection->inNamespace() || $functionReflection->isClosure()) { return $this->createStubData($this->generateStub($functionNode->getNode()), $extensionName, $functionReflection->getFileName() !== \false ? $functionReflection->getFileName() : null); } return $this->createStubData($this->generateStubInNamespace($functionNode->getNode(), $functionReflection->getNamespaceName()), $extensionName, $functionReflection->getFileName() !== \false ? $functionReflection->getFileName() : null); } public function generateConstantStub(string $constantName) : ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData { $constantData = $this->findConstantData($constantName); if ($constantData === null) { return null; } [$constantValue, $extensionName] = $constantData; if ($extensionName === null) { return null; } if (is_resource($constantValue)) { $constantValue = $this->builderFactory->funcCall('constant', [$constantName]); } $constantNode = $this->builderFactory->funcCall('define', [$constantName, $constantValue]); return $this->createStubData($this->generateStub($constantNode), $extensionName, null); } /** @return array{0: scalar|list|resource|null, 1: non-empty-string|null}|null */ private function findConstantData(string $constantName) { /** @var array|resource|null>> $constants */ $constants = get_defined_constants(\true); foreach ($constants as $constantExtensionName => $extensionConstants) { if (array_key_exists($constantName, $extensionConstants)) { return [$extensionConstants[$constantName], $constantExtensionName !== 'user' ? $constantExtensionName : null]; } } return null; } /** * @return \PhpParser\Builder\Class_|\PhpParser\Builder\Interface_|\PhpParser\Builder\Trait_|\PhpParser\Builder\Enum_ */ private function createClass(CoreReflectionClass $classReflection) { if ($classReflection instanceof CoreReflectionEnum) { return $this->builderFactory->enum($classReflection->getShortName()); } if ($classReflection->isTrait()) { return $this->builderFactory->trait($classReflection->getShortName()); } if ($classReflection->isInterface()) { return $this->builderFactory->interface($classReflection->getShortName()); } return $this->builderFactory->class($classReflection->getShortName()); } /** * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Interface_|\PhpParser\Builder\Trait_|\PhpParser\Builder\Enum_|\PhpParser\Builder\ClassConst|\PhpParser\Builder\EnumCase|\PhpParser\Builder\Method|\PhpParser\Builder\Property|\PhpParser\Builder\Function_|\PhpParser\Builder\Param $node * @param CoreReflectionClass|CoreReflectionClassConstant|CoreReflectionEnumUnitCase|CoreReflectionMethod|CoreReflectionProperty|CoreReflectionFunction|CoreReflectionParameter $reflection */ private function addAttributes($node, $reflection) : void { if (!method_exists($reflection, 'getAttributes')) { return; } $attributeReflections = $reflection->getAttributes(); if ($attributeReflections === []) { return; } foreach ($attributeReflections as $attributeReflection) { $node->addAttribute($this->builderFactory->attribute(new FullyQualified($attributeReflection->getName()), $attributeReflection->getArguments())); } } /** * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Interface_|\PhpParser\Builder\Trait_|\PhpParser\Builder\Enum_|\PhpParser\Builder\Method|\PhpParser\Builder\Property|\PhpParser\Builder\Function_ $node * @param CoreReflectionClass|CoreReflectionMethod|CoreReflectionProperty|CoreReflectionFunction $reflection */ private function addDocComment($node, $reflection) : void { $docComment = $reflection->getDocComment() !== \false ? $reflection->getDocComment() : ''; $annotations = []; if (($reflection instanceof CoreReflectionMethod || $reflection instanceof CoreReflectionFunction) && $reflection->isInternal()) { if ($reflection->isDeprecated()) { $annotations[] = '@deprecated'; } if (method_exists($reflection, 'hasTentativeReturnType') && $reflection->hasTentativeReturnType()) { $annotations[] = sprintf('@%s', AnnotationHelper::TENTATIVE_RETURN_TYPE_ANNOTATION); } } if ($docComment === '' && $annotations === []) { return; } if ($docComment === '') { $docComment = sprintf("/**\n* %s\n*/", implode("\n *", $annotations)); } elseif ($annotations !== []) { $docComment = preg_replace('~\\s+\\*/$~', sprintf("\n* %s\n*/", implode("\n *", $annotations)), $docComment); } $node->setDocComment(new Doc($docComment)); } private function addEnumBackingType(Enum_ $enumNode, CoreReflectionEnum $enumReflection) : void { if (!$enumReflection->isBacked()) { return; } $backingType = $enumReflection->getBackingType(); assert($backingType instanceof CoreReflectionNamedType); $enumNode->setScalarType($backingType->getName()); } private function addClassModifiers(Class_ $classNode, CoreReflectionClass $classReflection) : void { if (!$classReflection->isInterface() && $classReflection->isAbstract()) { // Interface \Iterator is interface and abstract $classNode->makeAbstract(); } if (!$classReflection->isFinal()) { return; } $classNode->makeFinal(); } /** * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Interface_|\PhpParser\Builder\Enum_ $classNode */ private function addExtendsAndImplements($classNode, CoreReflectionClass $classReflection) : void { $interfaces = $classReflection->getInterfaceNames(); if ($classNode instanceof Class_ || $classNode instanceof Interface_) { $parentClass = $classReflection->getParentClass(); if ($parentClass !== \false) { $classNode->extend(new FullyQualified($parentClass->getName())); $interfaces = array_diff($interfaces, $parentClass->getInterfaceNames()); } } foreach ($classReflection->getInterfaces() as $interface) { $interfaces = array_diff($interfaces, $interface->getInterfaceNames()); } foreach ($interfaces as $interfaceName) { if (method_exists($classReflection, 'isEnum') && $classReflection->isEnum() && in_array($interfaceName, [BackedEnum::class, UnitEnum::class], \true)) { continue; } $interfaceNode = new FullyQualified($interfaceName); if ($classNode instanceof Interface_) { $classNode->extend($interfaceNode); } else { $classNode->implement($interfaceNode); } } } /** * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Trait_|\PhpParser\Builder\Enum_ $classNode */ private function addTraitUse($classNode, CoreReflectionClass $classReflection) : void { /** @var array $traitAliases */ $traitAliases = $classReflection->getTraitAliases(); $traitUseAdaptations = []; foreach ($traitAliases as $methodNameAlias => $methodInfo) { [$traitName, $methodName] = explode('::', $methodInfo); $traitUseAdaptation = $this->builderFactory->traitUseAdaptation(new FullyQualified($traitName), $methodName); $traitUseAdaptation->as($methodNameAlias); $traitUseAdaptations[$traitName] = $traitUseAdaptation; } foreach ($classReflection->getTraitNames() as $traitName) { $traitUse = $this->builderFactory->useTrait(new FullyQualified($traitName)); if (array_key_exists($traitName, $traitUseAdaptations)) { $traitUse->with($traitUseAdaptations[$traitName]); } $classNode->addStmt($traitUse); } } /** * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Trait_ $classNode */ private function addProperties($classNode, CoreReflectionClass $classReflection) : void { foreach ($classReflection->getProperties() as $propertyReflection) { if (!$this->isPropertyDeclaredInClass($propertyReflection, $classReflection)) { continue; } $propertyNode = $this->builderFactory->property($propertyReflection->getName()); $this->addPropertyModifiers($propertyNode, $propertyReflection); $this->addAttributes($propertyNode, $propertyReflection); $this->addDocComment($propertyNode, $propertyReflection); if (method_exists($propertyReflection, 'hasDefaultValue') && $propertyReflection->hasDefaultValue()) { try { $propertyNode->setDefault($propertyReflection->getDeclaringClass()->getDefaultProperties()[$propertyReflection->getName()] ?? null); } catch (LogicException $exception) { // Nothing } } if ($this->phpVersion >= 70400) { $propertyType = method_exists($propertyReflection, 'getType') ? method_exists($propertyReflection, 'getType') ? $propertyReflection->getType() : null : null; if ($propertyType !== null) { assert($propertyType instanceof CoreReflectionNamedType || $propertyType instanceof CoreReflectionUnionType || $propertyType instanceof CoreReflectionIntersectionType); $propertyNode->setType($this->formatType($propertyType)); } } $classNode->addStmt($propertyNode); } } private function isPropertyDeclaredInClass(CoreReflectionProperty $propertyReflection, CoreReflectionClass $classReflection) : bool { if ($propertyReflection->getDeclaringClass()->getName() !== $classReflection->getName()) { return \false; } foreach ($classReflection->getTraits() as $trait) { if ($trait->hasProperty($propertyReflection->getName())) { return \false; } } return \true; } private function addPropertyModifiers(Property $propertyNode, CoreReflectionProperty $propertyReflection) : void { if ($this->phpVersion >= 80100) { if (method_exists($propertyReflection, 'isReadOnly') && $propertyReflection->isReadOnly()) { $propertyNode->makeReadonly(); } } if ($propertyReflection->isStatic()) { $propertyNode->makeStatic(); } if ($propertyReflection->isPublic()) { $propertyNode->makePublic(); } elseif ($propertyReflection->isProtected()) { $propertyNode->makeProtected(); } else { $propertyNode->makePrivate(); } } private function addEnumCases(Enum_ $enumNode, CoreReflectionEnum $enumReflection) : void { foreach ($enumReflection->getCases() as $enumCaseReflection) { $enumCaseNode = $this->builderFactory->enumCase($enumCaseReflection->getName()); $this->addAttributes($enumCaseNode, $enumCaseReflection); if ($enumCaseReflection instanceof CoreReflectionEnumBackedCase) { $enumCaseNode->setValue($enumCaseReflection->getBackingValue()); } $enumNode->addStmt($enumCaseNode); } } /** * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Interface_|\PhpParser\Builder\Trait_|\PhpParser\Builder\Enum_ $classNode */ private function addClassConstants($classNode, CoreReflectionClass $classReflection) : void { foreach ($classReflection->getReflectionConstants() as $constantReflection) { if (method_exists($constantReflection, 'isEnumCase') && $constantReflection->isEnumCase()) { continue; } if ($constantReflection->getDeclaringClass()->getName() !== $classReflection->getName()) { continue; } $classConstantNode = $this->builderFactory->classConst($constantReflection->getName(), $constantReflection->getValue()); if (method_exists($constantReflection, 'getType')) { $constantType = $constantReflection->getType(); if ($constantType !== null) { assert($constantType instanceof CoreReflectionNamedType || $constantType instanceof CoreReflectionUnionType || $constantType instanceof CoreReflectionIntersectionType); $classConstantNode->setType($this->formatType($constantType)); } } $this->addAttributes($classConstantNode, $constantReflection); if ($constantReflection->getDocComment() !== \false) { $classConstantNode->setDocComment(new Doc($constantReflection->getDocComment())); } $this->addClassConstantModifiers($classConstantNode, $constantReflection); $classNode->addStmt($classConstantNode); } } private function addClassConstantModifiers(ClassConst $classConstantNode, CoreReflectionClassConstant $classConstantReflection) : void { if (method_exists($classConstantReflection, 'isFinal') && $classConstantReflection->isFinal()) { $classConstantNode->makeFinal(); } if ($classConstantReflection->isPrivate()) { $classConstantNode->makePrivate(); } elseif ($classConstantReflection->isProtected()) { $classConstantNode->makeProtected(); } else { $classConstantNode->makePublic(); } } /** * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Interface_|\PhpParser\Builder\Trait_|\PhpParser\Builder\Enum_ $classNode */ private function addMethods($classNode, CoreReflectionClass $classReflection) : void { foreach ($classReflection->getMethods() as $methodReflection) { if (!$this->isMethodDeclaredInClass($methodReflection, $classReflection)) { continue; } $methodNode = $this->builderFactory->method($methodReflection->getName()); $this->addMethodFlags($methodNode, $methodReflection); $this->addAttributes($methodNode, $methodReflection); $this->addDocComment($methodNode, $methodReflection); $this->addParameters($methodNode, $methodReflection); $returnType = $methodReflection->getReturnType(); if ($returnType === null && method_exists($methodReflection, 'getTentativeReturnType')) { $returnType = $methodReflection->getTentativeReturnType(); } if ($returnType !== null) { assert($returnType instanceof CoreReflectionNamedType || $returnType instanceof CoreReflectionUnionType || $returnType instanceof CoreReflectionIntersectionType); $methodNode->setReturnType($this->formatType($returnType)); } $classNode->addStmt($methodNode); } } private function isMethodDeclaredInClass(CoreReflectionMethod $methodReflection, CoreReflectionClass $classReflection) : bool { if ($methodReflection->getDeclaringClass()->getName() !== $classReflection->getName()) { return \false; } $methodName = $methodReflection->getName(); /** @var array $traitAliases */ $traitAliases = $classReflection->getTraitAliases(); if (array_key_exists($methodName, $traitAliases)) { return \false; } foreach ($classReflection->getTraits() as $trait) { if ($trait->hasMethod($methodName)) { return \false; } } if ($classReflection instanceof CoreReflectionEnum) { if ($methodName === 'cases') { return \false; } if ($classReflection->isBacked() && in_array($methodName, ['from', 'tryFrom'], \true)) { return \false; } } return \true; } private function addMethodFlags(Method $methodNode, CoreReflectionMethod $methodReflection) : void { if ($methodReflection->isFinal()) { $methodNode->makeFinal(); } if ($methodReflection->isAbstract() && !$methodReflection->getDeclaringClass()->isInterface()) { $methodNode->makeAbstract(); } if ($methodReflection->isStatic()) { $methodNode->makeStatic(); } if ($methodReflection->isPublic()) { $methodNode->makePublic(); } if ($methodReflection->isProtected()) { $methodNode->makeProtected(); } if ($methodReflection->isPrivate()) { $methodNode->makePrivate(); } if (!$methodReflection->returnsReference()) { return; } $methodNode->makeReturnByRef(); } private function addParameters(FunctionLike $functionNode, CoreReflectionFunctionAbstract $functionReflectionAbstract) : void { foreach ($functionReflectionAbstract->getParameters() as $parameterReflection) { $parameterNode = $this->builderFactory->param($parameterReflection->getName()); $this->addParameterModifiers($parameterReflection, $parameterNode); $this->setParameterDefaultValue($parameterReflection, $parameterNode); $this->addAttributes($parameterNode, $parameterReflection); $functionNode->addParam($parameterNode); } } private function addParameterModifiers(CoreReflectionParameter $parameterReflection, Param $parameterNode) : void { if ($parameterReflection->isVariadic()) { $parameterNode->makeVariadic(); } if ($parameterReflection->isPassedByReference()) { $parameterNode->makeByRef(); } $parameterType = $parameterReflection->getType(); if ($parameterType === null) { return; } assert($parameterType instanceof CoreReflectionNamedType || $parameterType instanceof CoreReflectionUnionType || $parameterType instanceof CoreReflectionIntersectionType); $parameterNode->setType($this->formatType($parameterType)); } private function setParameterDefaultValue(CoreReflectionParameter $parameterReflection, Param $parameterNode) : void { if (!$parameterReflection->isOptional()) { return; } if ($parameterReflection->isVariadic()) { return; } if (!$parameterReflection->isDefaultValueAvailable()) { if ($parameterReflection->allowsNull()) { $parameterNode->setDefault(null); } else { $parameterNode->setDefault(new Node\Expr\ConstFetch(new FullyQualified('UNKNOWN'))); } return; } $defaultValue = $parameterReflection->getDefaultValue(); if (is_object($defaultValue)) { $className = get_class($defaultValue); $enumExists = function (string $enum, bool $autoload = \true) : bool { if (function_exists('enum_exists')) { return \enum_exists($enum, $autoload); } return $autoload && \class_exists($enum) && \false; }; $isEnum = function_exists('enum_exists') && $enumExists($className, \false); if ($isEnum) { $parameterNode->setDefault(new Node\Expr\ClassConstFetch(new FullyQualified($className), new Node\Identifier($defaultValue->name))); return; } if ($this->phpVersion >= 80100) { $parameterNode->setDefault(new Node\Expr\New_(new FullyQualified($className))); } else { $parameterNode->setDefault(new Node\Expr\ConstFetch(new Name('null'))); } return; } $parameterNode->setDefault($defaultValue); } /** * @return \PhpParser\Node\Name|\PhpParser\Node\NullableType|\PhpParser\Node\UnionType|\PhpParser\Node\IntersectionType */ private function formatType(CoreReflectionType $type) { if ($type instanceof CoreReflectionIntersectionType) { /** @var list $types */ $types = $this->formatTypes($type->getTypes()); if ($this->phpVersion >= 80100) { return new IntersectionType($types); } return $types[0]; } if ($type instanceof CoreReflectionUnionType) { /** @var list $types */ $types = $this->formatTypes($type->getTypes()); if ($this->phpVersion >= 80200) { return new UnionType($types); } if ($this->phpVersion < 80000) { return $types[0]; } $intersectionTypes = []; $otherNames = []; foreach ($types as $type) { if ($type instanceof IntersectionType) { $intersectionTypes[] = $type; continue; } $otherNames[] = $type; } if ($this->phpVersion >= 80100) { if (\count($intersectionTypes) > 0) { return $intersectionTypes[0]; } } if (\count($otherNames) > 1) { return new UnionType($otherNames); } if (\count($otherNames) > 0) { return $otherNames[0]; } return new Name('null'); } assert($type instanceof CoreReflectionNamedType); $name = $type->getName(); $nameNode = $this->formatNamedType($type); if (!$type->allowsNull() || $name === 'mixed' || $name === 'null') { return $nameNode; } return new NullableType($nameNode); } /** * @param list $types * * @return list */ private function formatTypes(array $types) : array { return array_map(function (CoreReflectionType $type) { $formattedType = $this->formatType($type); assert($formattedType instanceof Name || $formattedType instanceof UnionType || $formattedType instanceof IntersectionType); return $formattedType; }, $types); } private function formatNamedType(CoreReflectionNamedType $type) : Name { $name = $type->getName(); return $type->isBuiltin() || in_array($name, ['self', 'parent', 'static'], \true) ? new Name($name) : new FullyQualified($name); } private function generateStubInNamespace(Node $node, string $namespaceName) : string { $namespaceBuilder = $this->builderFactory->namespace($namespaceName); $namespaceBuilder->addStmt($node); return $this->generateStub($namespaceBuilder->getNode()); } private function generateStub(Node $node) : string { return sprintf("prettyPrinter->prettyPrint([$node]), $node instanceof Node\Expr\FuncCall ? ';' : ''); } /** @param non-empty-string|null $extensionName */ private function createStubData(string $stub, ?string $extensionName, ?string $fileName) : \PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData { return new \PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData($stub, $extensionName, $fileName); } } */ private $classNodes = []; /** @var array> */ private $functionNodes = []; /** @var array */ private $constantNodes = []; /** * @var \PhpParser\BuilderFactory */ private $builderFactory; public function __construct(BuilderFactory $builderFactory) { $this->builderFactory = $builderFactory; } public function enterNode(Node $node) : ?int { if ($node instanceof Node\Stmt\Namespace_) { $this->currentNamespace = $node; return null; } if ($node instanceof Node\Stmt\ClassLike) { $classNamespacedName = $node->namespacedName; assert($classNamespacedName instanceof Node\Name); $className = $classNamespacedName->toString(); $this->classNodes[$className] = [$node, $this->currentNamespace]; foreach ($node->getConstants() as $constantsNode) { foreach ($constantsNode->consts as $constNode) { $constClassName = sprintf('%s::%s', $className, $constNode->name->toString()); $this->updateConstantValue($constNode, $constClassName); } } // We need to traverse children to resolve attributes names for methods, properties etc. return null; } if ($node instanceof Node\Stmt\ClassMethod) { return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN; } if ($node instanceof Node\Stmt\Function_) { $functionNamespacedName = $node->namespacedName; assert($functionNamespacedName instanceof Node\Name); $functionName = $functionNamespacedName->toString(); $this->functionNodes[$functionName][] = [$node, $this->currentNamespace]; return NodeTraverser::DONT_TRAVERSE_CHILDREN; } if ($node instanceof Node\Stmt\Const_) { foreach ($node->consts as $constNode) { $constNamespacedName = $constNode->namespacedName; assert($constNamespacedName instanceof Node\Name); $constNodeName = $constNamespacedName->toString(); $this->updateConstantValue($constNode, $constNodeName); $this->constantNodes[$constNodeName] = [$node, $this->currentNamespace]; } return NodeTraverser::DONT_TRAVERSE_CHILDREN; } if ($node instanceof Node\Expr\FuncCall) { $argumentNameNode = $node->args[0]; assert($argumentNameNode instanceof Node\Arg); $nameNode = $argumentNameNode->value; assert($nameNode instanceof Node\Scalar\String_); $constantName = $nameNode->value; // The definition is stubs looks like `define('STDIN', fopen('php://stdin', 'r'))` // We will modify it to `define('STDIN', constant('STDIN')); // The later definition can pass validation in `ConstantNodeChecker` and has support in `CompileNodeToValue` if (in_array($constantName, ['STDIN', 'STDOUT', 'STDERR'], \true) && array_key_exists(1, $node->args) && $node->args[1] instanceof Node\Arg) { $node->args[1]->value = $this->builderFactory->funcCall('constant', [$constantName]); } // @codeCoverageIgnoreStart // @infection-ignore-all // No invalid definition in PhpStorm stubs try { ConstantNodeChecker::assertValidDefineFunctionCall($node); } catch (InvalidConstantNode $exception) { return null; } // @codeCoverageIgnoreEnd if (in_array($constantName, self::TRUE_FALSE_NULL, \true)) { $constantName = strtoupper($constantName); $nameNode->value = $constantName; } $this->updateConstantValue($node, $constantName); $this->constantNodes[$constantName] = [$node, $this->currentNamespace]; if (array_key_exists(2, $node->args) && $node->args[2] instanceof Node\Arg && $node->args[2]->value instanceof Node\Expr\ConstFetch && $node->args[2]->value->name->toLowerString() === 'true') { $this->constantNodes[strtolower($constantName)] = [$node, $this->currentNamespace]; } return NodeTraverser::DONT_TRAVERSE_CHILDREN; } return null; } /** * {@inheritDoc} */ public function leaveNode(Node $node) { if ($node instanceof Node\Stmt\Namespace_) { $this->currentNamespace = null; } return null; } /** @return array */ public function getClassNodes() : array { return $this->classNodes; } /** @return array> */ public function getFunctionNodes() : array { return $this->functionNodes; } /** @return array */ public function getConstantNodes() : array { return $this->constantNodes; } public function clearNodes() : void { $this->classNodes = []; $this->functionNodes = []; $this->constantNodes = []; } /** * Some constants have different values on different systems, some are not actual in stubs. * @param \PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Const_ $node */ private function updateConstantValue($node, string $constantName) : void { // prevent autoloading while discovering class constants $parts = explode('::', $constantName, 2); if (count($parts) === 2) { [$className, $classConstName] = $parts; if (!class_exists($className, \false)) { return; } } if (!defined($constantName)) { return; } // @ because access to deprecated constant throws deprecated warning /** @var scalar|resource|list|null $constantValue */ $constantValue = @constant($constantName); $normalizedConstantValue = is_resource($constantValue) ? $this->builderFactory->funcCall('constant', [$constantName]) : $this->builderFactory->val($constantValue); if ($node instanceof Node\Expr\FuncCall) { $argumentValueNode = $node->args[1]; assert($argumentValueNode instanceof Node\Arg); $argumentValueNode->value = $normalizedConstantValue; } else { $node->value = $normalizedConstantValue; } } } */ private $sourceStubbers; public function __construct(\PHPStan\BetterReflection\SourceLocator\SourceStubber\SourceStubber $sourceStubber, \PHPStan\BetterReflection\SourceLocator\SourceStubber\SourceStubber ...$otherSourceStubbers) { $this->sourceStubbers = array_values(array_merge([$sourceStubber], $otherSourceStubbers)); } /** @param class-string|trait-string $className */ public function generateClassStub(string $className) : ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData { foreach ($this->sourceStubbers as $sourceStubber) { $stubData = $sourceStubber->generateClassStub($className); if ($stubData !== null) { return $stubData; } } return null; } public function generateFunctionStub(string $functionName) : ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData { foreach ($this->sourceStubbers as $sourceStubber) { $stubData = $sourceStubber->generateFunctionStub($functionName); if ($stubData !== null) { return $stubData; } } return null; } public function generateConstantStub(string $constantName) : ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData { return array_reduce($this->sourceStubbers, static function (?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData $stubData, \PHPStan\BetterReflection\SourceLocator\SourceStubber\SourceStubber $sourceStubber) use($constantName) : ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData { return $stubData ?? $sourceStubber->generateConstantStub($constantName); }, null); } } stub = $stub; $this->extensionName = $extensionName; $this->fileName = $fileName; } public function getStub() : string { return $this->stub; } /** @return non-empty-string|null */ public function getExtensionName() : ?string { return $this->extensionName; } public function getFileName() : ?string { return $this->fileName; } } */ private $classNodes = []; /** * `null` means "function is not supported in the required PHP version" * * @var array */ private $functionNodes = []; /** * `null` means "failed lookup" for constant that is not case insensitive or "constant is not supported in the required PHP version" * * @var array */ private $constantNodes = []; /** * @var bool */ private static $mapsInitialized = \false; /** @var array */ private static $classMap; /** @var array */ private static $functionMap; /** @var array */ private static $constantMap; /** * @var \PhpParser\Parser */ private $phpParser; /** * @var int */ private $phpVersion = PHP_VERSION_ID; public function __construct(Parser $phpParser, Standard $prettyPrinter, int $phpVersion = PHP_VERSION_ID) { $this->phpParser = $phpParser; $this->phpVersion = $phpVersion; $this->builderFactory = new BuilderFactory(); $this->prettyPrinter = $prettyPrinter; $this->cachingVisitor = new CachingVisitor($this->builderFactory); $this->nodeTraverser = new NodeTraverser(); $this->nodeTraverser->addVisitor(new NameResolver()); $this->nodeTraverser->addVisitor($this->cachingVisitor); if (self::$mapsInitialized) { return; } /** @psalm-suppress PropertyTypeCoercion */ self::$classMap = array_change_key_case(PhpStormStubsMap::CLASSES); /** @psalm-suppress PropertyTypeCoercion */ self::$functionMap = array_change_key_case(PhpStormStubsMap::FUNCTIONS); /** @psalm-suppress PropertyTypeCoercion */ self::$constantMap = array_change_key_case(PhpStormStubsMap::CONSTANTS); self::$mapsInitialized = \true; } public function hasClass(string $className) : bool { $lowercaseClassName = strtolower($className); return array_key_exists($lowercaseClassName, self::$classMap); } public function isPresentClass(string $className) : ?bool { $lowercaseClassName = strtolower($className); if (!array_key_exists($lowercaseClassName, self::$classMap)) { return null; } $classNode = $this->getClassNodeData($lowercaseClassName); return $classNode !== null; } public function isPresentFunction(string $functionName) : ?bool { $lowercaseFunctionName = strtolower($functionName); if (!array_key_exists($lowercaseFunctionName, self::$functionMap)) { return null; } $functionNode = $this->getFunctionNodeData($lowercaseFunctionName); return $functionNode !== null; } /** @param class-string|trait-string $className */ public function generateClassStub(string $className) : ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData { if (strtolower($className) === 'iterable') { return null; } $classNodeData = $this->getClassNodeData($className); if ($classNodeData === null) { return null; } $classNode = $classNodeData[0]; if ($classNode instanceof Node\Stmt\Class_) { if ($classNode->extends !== null) { $modifiedExtends = $this->replaceExtendsOrImplementsByPhpVersion($className, [$classNode->extends]); $classNode->extends = $modifiedExtends !== [] ? $modifiedExtends[0] : null; } $classNode->implements = $this->replaceExtendsOrImplementsByPhpVersion($className, $classNode->implements); } elseif ($classNode instanceof Node\Stmt\Interface_) { $classNode->extends = $this->replaceExtendsOrImplementsByPhpVersion($className, $classNode->extends); } $filePath = self::$classMap[strtolower($className)]; $extension = $this->getExtensionFromFilePath($filePath); $stub = $this->createStub($classNode, $classNodeData[1]); if ($className === Traversable::class) { // See https://github.com/JetBrains/phpstorm-stubs/commit/0778a26992c47d7dbee4d0b0bfb7fad4344371b1#diff-575bacb45377d474336c71cbf53c1729 $stub = str_replace(' extends \\iterable', '', $stub); } elseif ($className === Generator::class) { $stub = str_replace('PS_UNRESERVE_PREFIX_throw', 'throw', $stub); } return new \PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData($stub, $extension, $this->getAbsoluteFilePath($filePath)); } /** @return array{0: Node\Stmt\ClassLike, 1: Node\Stmt\Namespace_|null}|null */ private function getClassNodeData(string $className) { $lowercaseClassName = strtolower($className); if (!array_key_exists($lowercaseClassName, self::$classMap)) { return null; } $filePath = self::$classMap[$lowercaseClassName]; if (!array_key_exists($lowercaseClassName, $this->classNodes)) { $this->parseFile($filePath); /** @psalm-suppress RedundantCondition */ if (!array_key_exists($lowercaseClassName, $this->classNodes)) { // Save `null` so we don't parse the file again for the same $lowercaseClassName $this->classNodes[$lowercaseClassName] = null; } } return $this->classNodes[$lowercaseClassName]; } /** * @return array{0: Node\Stmt\Function_, 1: Node\Stmt\Namespace_|null}|null */ private function getFunctionNodeData(string $functionName) : ?array { $lowercaseFunctionName = strtolower($functionName); if (!array_key_exists($lowercaseFunctionName, self::$functionMap)) { return null; } $filePath = self::$functionMap[$lowercaseFunctionName]; if (!array_key_exists($lowercaseFunctionName, $this->functionNodes)) { $this->parseFile($filePath); /** @psalm-suppress RedundantCondition */ if (!array_key_exists($lowercaseFunctionName, $this->functionNodes)) { // Save `null` so we don't parse the file again for the same $lowercaseFunctionName $this->functionNodes[$lowercaseFunctionName] = null; } } return $this->functionNodes[$lowercaseFunctionName]; } public function generateFunctionStub(string $functionName) : ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData { $functionNodeData = $this->getFunctionNodeData($functionName); if ($functionNodeData === null) { return null; } $filePath = self::$functionMap[strtolower($functionName)]; $extension = $this->getExtensionFromFilePath($filePath); return new \PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData($this->createStub($functionNodeData[0], $functionNodeData[1]), $extension, $this->getAbsoluteFilePath($filePath)); } public function generateConstantStub(string $constantName) : ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData { $lowercaseConstantName = strtolower($constantName); if (!array_key_exists($lowercaseConstantName, self::$constantMap)) { return null; } if (array_key_exists($lowercaseConstantName, $this->constantNodes) && $this->constantNodes[$lowercaseConstantName] === null) { return null; } $filePath = self::$constantMap[$lowercaseConstantName]; $constantNodeData = $this->constantNodes[$constantName] ?? $this->constantNodes[$lowercaseConstantName] ?? null; if ($constantNodeData === null) { $this->parseFile($filePath); $constantNodeData = $this->constantNodes[$constantName] ?? $this->constantNodes[$lowercaseConstantName] ?? null; if ($constantNodeData === null) { // Still `null` - the constant is not case-insensitive. Save `null` so we don't parse the file again for the same $constantName $this->constantNodes[$lowercaseConstantName] = null; return null; } } $extension = $this->getExtensionFromFilePath($filePath); return new \PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData($this->createStub($constantNodeData[0], $constantNodeData[1]), $extension, $this->getAbsoluteFilePath($filePath)); } private function parseFile(string $filePath) : void { $absoluteFilePath = $this->getAbsoluteFilePath($filePath); FileChecker::assertReadableFile($absoluteFilePath); /** @var list $ast */ $ast = $this->phpParser->parse(file_get_contents($absoluteFilePath)); // "@since" and "@removed" annotations in some cases do not contain a PHP version, but an extension version - e.g. "@since 1.3.0" // So we check PHP version only for stubs of core extensions $isCoreExtension = $this->isCoreExtension($this->getExtensionFromFilePath($filePath)); $this->cachingVisitor->clearNodes(); $this->nodeTraverser->traverse($ast); foreach ($this->cachingVisitor->getClassNodes() as $className => $classNodeData) { [$classNode] = $classNodeData; if ($isCoreExtension) { if ($className !== 'Attribute' && $className !== 'ReturnTypeWillChange' && $className !== 'AllowDynamicProperties' && $className !== 'SensitiveParameter' && $className !== 'Override' && !$this->isSupportedInPhpVersion($classNode)) { continue; } $classNode->stmts = $this->modifyStmtsByPhpVersion($classNode->stmts); } $this->classNodes[strtolower($className)] = $classNodeData; } foreach ($this->cachingVisitor->getFunctionNodes() as $functionName => $functionNodesData) { foreach ($functionNodesData as $functionNodeData) { [$functionNode] = $functionNodeData; if ($isCoreExtension) { if (!$this->isSupportedInPhpVersion($functionNode)) { continue; } $this->modifyFunctionReturnTypeByPhpVersion($functionNode); $this->modifyFunctionParametersByPhpVersion($functionNode); } $lowercaseFunctionName = strtolower($functionName); if (array_key_exists($lowercaseFunctionName, $this->functionNodes)) { continue; } $this->functionNodes[$lowercaseFunctionName] = $functionNodeData; } } foreach ($this->cachingVisitor->getConstantNodes() as $constantName => $constantNodeData) { [$constantNode] = $constantNodeData; if ($isCoreExtension && !$this->isSupportedInPhpVersion($constantNode)) { continue; } $this->constantNodes[$constantName] = $constantNodeData; } } /** * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall $node */ private function createStub($node, ?\PhpParser\Node\Stmt\Namespace_ $namespaceNode) : string { if ($node instanceof Node\Expr\FuncCall) { try { ConstantNodeChecker::assertValidDefineFunctionCall($node); $this->addDeprecatedDocComment($node); } catch (InvalidConstantNode $exception) { // just keep going } } if (!$node instanceof Node\Expr\FuncCall) { $this->addDeprecatedDocComment($node); $nodeWithNamespaceName = $node instanceof Node\Stmt\Const_ ? $node->consts[0] : $node; $namespacedName = $nodeWithNamespaceName->namespacedName; assert($namespacedName instanceof Node\Name); $namespaceBuilder = $this->builderFactory->namespace($namespacedName->slice(0, -1)); if ($namespaceNode !== null) { foreach ($namespaceNode->stmts as $stmt) { if (!$stmt instanceof Node\Stmt\Use_ && !$stmt instanceof Node\Stmt\GroupUse) { continue; } $namespaceBuilder->addStmt($stmt); } } $namespaceBuilder->addStmt($node); $node = $namespaceBuilder->getNode(); } return sprintf("prettyPrinter->prettyPrint([$node]), $node instanceof Node\Expr\FuncCall ? ';' : ''); } /** @return non-empty-string */ private function getExtensionFromFilePath(string $filePath) : string { $extensionName = explode('/', $filePath)[0]; assert($extensionName !== ''); return $extensionName; } /** @return non-empty-string */ private function getAbsoluteFilePath(string $filePath) : string { return sprintf('%s/%s', $this->getStubsDirectory(), $filePath); } /** * Some stubs extend/implement classes from newer PHP versions. We need to filter those names in regard to set PHP version so that those stubs remain valid. * * @param array $nameNodes * * @return list */ private function replaceExtendsOrImplementsByPhpVersion(string $className, array $nameNodes) : array { $modifiedNames = []; foreach ($nameNodes as $nameNode) { $name = $nameNode->toString(); if ($className === ParseError::class) { if ($name === CompileError::class && $this->phpVersion < 70300) { $modifiedNames[] = new Node\Name\FullyQualified(Error::class); continue; } } elseif ($className === SplFixedArray::class) { if ($name === JsonSerializable::class && $this->phpVersion < 80100) { continue; } if ($name === IteratorAggregate::class && $this->phpVersion < 80000) { continue; } if ($name === Iterator::class && $this->phpVersion >= 80000) { continue; } } elseif ($className === SimpleXMLElement::class) { if ($name === RecursiveIterator::class && $this->phpVersion < 80000) { continue; } } elseif ($className === DatePeriod::class || $className === PDOStatement::class) { if ($name === IteratorAggregate::class && $this->phpVersion < 80000) { $modifiedNames[] = new Node\Name\FullyQualified(Traversable::class); continue; } } elseif ($className === SplObjectStorage::class) { if ($name === SeekableIterator::class && $this->phpVersion < 80400) { $modifiedNames[] = new Node\Name\FullyQualified(Iterator::class); continue; } } if ($this->getClassNodeData($name) === null) { continue; } $modifiedNames[] = $nameNode; } return $modifiedNames; } /** * @param array $stmts * * @return list */ private function modifyStmtsByPhpVersion(array $stmts) : array { $newStmts = []; foreach ($stmts as $stmt) { assert($stmt instanceof Node\Stmt\ClassConst || $stmt instanceof Node\Stmt\Property || $stmt instanceof Node\Stmt\ClassMethod || $stmt instanceof Node\Stmt\EnumCase); if (!$this->isSupportedInPhpVersion($stmt)) { continue; } if ($stmt instanceof Node\Stmt\Property) { $this->modifyStmtTypeByPhpVersion($stmt); } if ($stmt instanceof Node\Stmt\ClassMethod) { $this->modifyFunctionReturnTypeByPhpVersion($stmt); $this->modifyFunctionParametersByPhpVersion($stmt); } $this->addDeprecatedDocComment($stmt); $newStmts[] = $stmt; } return $newStmts; } /** * @param \PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $stmt */ private function modifyStmtTypeByPhpVersion($stmt) : void { $type = $this->getStmtType($stmt); if ($type === null) { return; } $stmt->type = $type; } /** * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $function */ private function modifyFunctionReturnTypeByPhpVersion($function) : void { $isTentativeReturnType = $this->getNodeAttribute($function, 'JetBrains\\PhpStorm\\Internal\\TentativeType') !== null; if ($isTentativeReturnType) { // Tentative types are the most correct in stubs // If the type is tentative in stubs, we should remove the type for PHP < 8.1 if ($this->phpVersion >= 80100) { $this->addAnnotationToDocComment($function, AnnotationHelper::TENTATIVE_RETURN_TYPE_ANNOTATION); } else { $function->returnType = null; } return; } $type = $this->getStmtType($function); if ($type === null) { return; } $function->returnType = $type; } /** * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $function */ private function modifyFunctionParametersByPhpVersion($function) : void { $parameters = []; foreach ($function->getParams() as $parameterNode) { if (!$this->isSupportedInPhpVersion($parameterNode)) { continue; } $this->modifyStmtTypeByPhpVersion($parameterNode); $parameters[] = $parameterNode; } $function->params = $parameters; } /** * @param \PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $node * @return \PhpParser\Node\Name|\PhpParser\Node\Identifier|\PhpParser\Node\ComplexType|null */ private function getStmtType($node) { $languageLevelTypeAwareAttribute = $this->getNodeAttribute($node, 'JetBrains\\PhpStorm\\Internal\\LanguageLevelTypeAware'); if ($languageLevelTypeAwareAttribute === null) { return null; } assert($languageLevelTypeAwareAttribute->args[0]->value instanceof Node\Expr\Array_); /** @var list $types */ $types = $languageLevelTypeAwareAttribute->args[0]->value->items; usort($types, static function (Node\Expr\ArrayItem $a, Node\Expr\ArrayItem $b) : int { return $b->key <=> $a->key; }); foreach ($types as $type) { assert($type->key instanceof Node\Scalar\String_); assert($type->value instanceof Node\Scalar\String_); if ($this->parsePhpVersion($type->key->value) > $this->phpVersion) { continue; } return $this->normalizeType($type->value->value); } assert($languageLevelTypeAwareAttribute->args[1]->value instanceof Node\Scalar\String_); return $languageLevelTypeAwareAttribute->args[1]->value->value !== '' ? $this->normalizeType($languageLevelTypeAwareAttribute->args[1]->value->value) : null; } /** * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Stmt\EnumCase $node */ private function addDeprecatedDocComment($node) : void { if ($node instanceof Node\Expr\FuncCall) { if (!$this->isDeprecatedByPhpDocInPhpVersion($node)) { $this->removeAnnotationFromDocComment($node, 'deprecated'); } return; } if ($node instanceof Node\Stmt\Const_) { return; } if (!$this->isDeprecatedInPhpVersion($node)) { $this->removeAnnotationFromDocComment($node, 'deprecated'); return; } $this->addAnnotationToDocComment($node, 'deprecated'); } /** * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Stmt\EnumCase $node */ private function addAnnotationToDocComment($node, string $annotationName) : void { $docComment = $node->getDocComment(); if ($docComment === null) { $docCommentText = sprintf('/** @%s */', $annotationName); } else { $docCommentText = preg_replace('~(\\r?\\n\\s*)\\*/~', sprintf('\\1* @%s\\1*/', $annotationName), $docComment->getText()); } $node->setDocComment(new Doc($docCommentText)); } /** * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Stmt\EnumCase $node */ private function removeAnnotationFromDocComment($node, string $annotationName) : void { $docComment = $node->getDocComment(); if ($docComment === null) { return; } $docCommentText = preg_replace('~@' . $annotationName . '.*$~m', '', $docComment->getText()); $node->setDocComment(new Doc($docCommentText)); } private function isCoreExtension(string $extension) : bool { return in_array($extension, self::CORE_EXTENSIONS, \true); } private function isDeprecatedByPhpDocInPhpVersion(Node\Expr\FuncCall $node) : bool { $docComment = $node->getDocComment(); if ($docComment === null) { return \false; } if (preg_match('#@deprecated\\s+(\\d+)\\.(\\d+)(?:\\.(\\d+))?$#m', $docComment->getText(), $matches) === 1) { $major = $matches[1]; $minor = $matches[2]; $patch = $matches[3] ?? 0; $versionId = sprintf('%d%02d%02d', $major, $minor, $patch); return $this->phpVersion >= $versionId; } return \true; } /** * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\EnumCase $node */ private function isDeprecatedInPhpVersion($node) : bool { $deprecatedAttribute = $this->getNodeAttribute($node, 'JetBrains\\PhpStorm\\Deprecated'); if ($deprecatedAttribute === null) { return \false; } foreach ($deprecatedAttribute->args as $attributeArg) { if ($attributeArg->name !== null && $attributeArg->name->toString() === 'since') { assert($attributeArg->value instanceof Node\Scalar\String_); return $this->parsePhpVersion($attributeArg->value->value) <= $this->phpVersion; } } return \true; } /** * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Param|\PhpParser\Node\Stmt\EnumCase $node */ private function isSupportedInPhpVersion($node) : bool { [$fromVersion, $toVersion] = $this->getSupportedPhpVersions($node); if ($fromVersion !== null && $fromVersion > $this->phpVersion) { return \false; } return $toVersion === null || $toVersion >= $this->phpVersion; } /** @return array{0: int|null, 1: int|null} * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Param|\PhpParser\Node\Stmt\EnumCase $node */ private function getSupportedPhpVersions($node) : array { $fromVersion = null; $toVersion = null; $docComment = $node->getDocComment(); if ($docComment !== null) { if (preg_match('~@since\\s+(?P\\d+\\.\\d+(?:\\.\\d+)?)\\s+~', $docComment->getText(), $sinceMatches) === 1) { $fromVersion = $this->parsePhpVersion($sinceMatches['version']); } if (preg_match('~@removed\\s+(?P\\d+\\.\\d+(?:\\.\\d+)?)\\s+~', $docComment->getText(), $removedMatches) === 1) { $toVersion = $this->parsePhpVersion($removedMatches['version']) - 1; } } $elementsAvailable = $this->getNodeAttribute($node, 'JetBrains\\PhpStorm\\Internal\\PhpStormStubsElementAvailable'); if ($elementsAvailable !== null) { foreach ($elementsAvailable->args as $i => $attributeArg) { $isFrom = \false; if ($attributeArg->name !== null && $attributeArg->name->toString() === 'from') { $isFrom = \true; } if ($attributeArg->name === null && $i === 0) { $isFrom = \true; } if ($isFrom) { assert($attributeArg->value instanceof Node\Scalar\String_); $fromVersion = $this->parsePhpVersion($attributeArg->value->value); } $isTo = \false; if ($attributeArg->name !== null && $attributeArg->name->toString() === 'to') { $isTo = \true; } if ($attributeArg->name === null && $i === 1) { $isTo = \true; } if (!$isTo) { continue; } assert($attributeArg->value instanceof Node\Scalar\String_); $toVersion = $this->parsePhpVersion($attributeArg->value->value, 99); } } return [$fromVersion, $toVersion]; } /** * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Param|\PhpParser\Node\Stmt\EnumCase $node */ private function getNodeAttribute($node, string $attributeName) : ?\PhpParser\Node\Attribute { if ($node instanceof Node\Expr\FuncCall || $node instanceof Node\Stmt\Const_) { return null; } foreach ($node->attrGroups as $attributesGroupNode) { foreach ($attributesGroupNode->attrs as $attributeNode) { if ($attributeNode->name->toString() === $attributeName) { return $attributeNode; } } } return null; } private function parsePhpVersion(string $version, int $defaultPatch = 0) : int { $parts = array_map('intval', explode('.', $version)); return $parts[0] * 10000 + $parts[1] * 100 + ($parts[2] ?? $defaultPatch); } /** * @return \PhpParser\Node\Name|\PhpParser\Node\Identifier|\PhpParser\Node\ComplexType|null */ private function normalizeType(string $type) { // There are some invalid types in stubs, eg. `string[]|string|null` if (\strpos($type, '[') !== \false) { return null; } /** @psalm-suppress InternalClass, InternalMethod */ return BuilderHelpers::normalizeType($type); } private function getStubsDirectory() : string { if ($this->stubsDirectory !== null) { return $this->stubsDirectory; } foreach (self::SEARCH_DIRECTORIES as $directory) { if (is_dir($directory)) { return $this->stubsDirectory = $directory; } } // @codeCoverageIgnoreStart // @infection-ignore-all // Untestable code throw CouldNotFindPhpStormStubs::create(); // @codeCoverageIgnoreEnd } } astConversionStrategy = $astConversionStrategy; } /** * Find all reflections of a given type in an Abstract Syntax Tree * * @param Node[] $ast * * @return list */ public function __invoke(Reflector $reflector, array $ast, IdentifierType $identifierType, LocatedSource $locatedSource) : array { $nodeVisitor = new class($reflector, $identifierType, $locatedSource, $this->astConversionStrategy) extends NodeVisitorAbstract { /** @var list */ private $reflections = []; /** * @var \PhpParser\Node\Stmt\Namespace_|null */ private $currentNamespace = null; /** * @var \PHPStan\BetterReflection\Reflector\Reflector */ private $reflector; /** * @var \PHPStan\BetterReflection\Identifier\IdentifierType */ private $identifierType; /** * @var \PHPStan\BetterReflection\SourceLocator\Located\LocatedSource */ private $locatedSource; /** * @var \PHPStan\BetterReflection\SourceLocator\Ast\Strategy\AstConversionStrategy */ private $astConversionStrategy; public function __construct(Reflector $reflector, IdentifierType $identifierType, LocatedSource $locatedSource, AstConversionStrategy $astConversionStrategy) { $this->reflector = $reflector; $this->identifierType = $identifierType; $this->locatedSource = $locatedSource; $this->astConversionStrategy = $astConversionStrategy; } /** * {@inheritDoc} */ public function enterNode(Node $node) { if ($node instanceof Namespace_) { $this->currentNamespace = $node; } return null; } /** * {@inheritDoc} */ public function leaveNode(Node $node) { if ($this->identifierType->isClass() && ($node instanceof Node\Stmt\Class_ || $node instanceof Node\Stmt\Interface_ || $node instanceof Node\Stmt\Trait_ || $node instanceof Node\Stmt\Enum_)) { $classNamespace = $node->name === null ? null : $this->currentNamespace; $this->reflections[] = $this->astConversionStrategy->__invoke($this->reflector, $node, $this->locatedSource, $classNamespace); return null; } if ($this->identifierType->isConstant()) { if ($node instanceof Node\Stmt\Const_) { for ($i = 0; $i < count($node->consts); $i++) { $this->reflections[] = $this->astConversionStrategy->__invoke($this->reflector, $node, $this->locatedSource, $this->currentNamespace, $i); } return null; } if ($node instanceof Node\Expr\FuncCall) { try { ConstantNodeChecker::assertValidDefineFunctionCall($node); } catch (InvalidConstantNode $exception) { return null; } if ($node->name->hasAttribute('namespacedName')) { $namespacedName = $node->name->getAttribute('namespacedName'); assert($namespacedName instanceof Name); try { $this->reflector->reflectFunction($namespacedName->toString()); return null; } catch (IdentifierNotFound $exception) { // Global define() } } $this->reflections[] = $this->astConversionStrategy->__invoke($this->reflector, $node, $this->locatedSource, $this->currentNamespace); return null; } } if ($this->identifierType->isFunction() && $node instanceof Node\Stmt\Function_) { $this->reflections[] = $this->astConversionStrategy->__invoke($this->reflector, $node, $this->locatedSource, $this->currentNamespace); } if ($node instanceof Namespace_) { $this->currentNamespace = null; } return null; } /** @return list */ public function getReflections() : array { return $this->reflections; } }; $nodeTraverser = new NodeTraverser(); $nodeTraverser->addVisitor(new NameResolver()); $nodeTraverser->addVisitor($nodeVisitor); $nodeTraverser->traverse($ast); return $nodeVisitor->getReflections(); } } indexed by source hash */ private $sourceHashToAst = []; /** * @var \PhpParser\Parser */ private $wrappedParser; public function __construct(Parser $wrappedParser) { $this->wrappedParser = $wrappedParser; } public function parse(string $code, ?\PhpParser\ErrorHandler $errorHandler = null) : ?array { // note: this code is mathematically buggy by default, as we are using a hash to identify // cache entries. The string length is added to further reduce likeliness (although // already imperceptible) of key collisions. // In the "real world", this code will work just fine. $hash = sprintf('%s:%d', hash('sha256', $code), strlen($code)); if (array_key_exists($hash, $this->sourceHashToAst)) { /** @var Node\Stmt[]|null $ast */ $ast = unserialize($this->sourceHashToAst[$hash]); return $ast; } $ast = $this->wrappedParser->parse($code, $errorHandler); $this->sourceHashToAst[$hash] = serialize($ast); return $ast; } } name : null) !== null ? implode('\\', $namespace->name->getParts()) : null; if ($namespaceName === '') { throw new LogicException('Namespace name should never be empty'); } if ($node instanceof Node\Stmt\Enum_) { return ReflectionEnum::createFromNode($reflector, $node, $locatedSource, $namespaceName); } if ($node instanceof Node\Stmt\ClassLike) { return ReflectionClass::createFromNode($reflector, $node, $locatedSource, $namespaceName); } if ($node instanceof Node\Stmt\Const_) { return ReflectionConstant::createFromNode($reflector, $node, $locatedSource, $namespaceName, $positionInNode); } if ($node instanceof Node\Expr\FuncCall) { return ReflectionConstant::createFromNode($reflector, $node, $locatedSource); } return ReflectionFunction::createFromNode($reflector, $node, $locatedSource, $namespaceName); } } parser = $parser; $this->findReflectionsInTree = new \PHPStan\BetterReflection\SourceLocator\Ast\FindReflectionsInTree(new NodeToReflection()); } /** * @throws IdentifierNotFound * @throws Exception\ParseToAstFailure */ public function findReflection(Reflector $reflector, LocatedSource $locatedSource, Identifier $identifier) : Reflection { return $this->findInArray($this->findReflectionsOfType($reflector, $locatedSource, $identifier->getType()), $identifier, $locatedSource->getName()); } /** * Get an array of reflections found in some code. * * @return list * * @throws Exception\ParseToAstFailure */ public function findReflectionsOfType(Reflector $reflector, LocatedSource $locatedSource, IdentifierType $identifierType) : array { try { /** @var list $ast */ $ast = $this->parser->parse($locatedSource->getSource()); return $this->findReflectionsInTree->__invoke($reflector, $ast, $identifierType, $locatedSource); } catch (Throwable $exception) { throw \PHPStan\BetterReflection\SourceLocator\Ast\Exception\ParseToAstFailure::fromLocatedSource($locatedSource, $exception); } } /** * Given an array of Reflections, try to find the identifier. * * @param list $reflections * * @throws IdentifierNotFound */ private function findInArray(array $reflections, Identifier $identifier, ?string $name) : Reflection { if ($name === null) { throw IdentifierNotFound::fromIdentifier($identifier); } $identifierName = strtolower($name); foreach ($reflections as $reflection) { if (strtolower($reflection->getName()) === $identifierName) { return $reflection; } } throw IdentifierNotFound::fromIdentifier($identifier); } } getFileName(); if ($fileName !== null) { $additionalInformation = sprintf(' in file %s', $fileName); } if ($previous instanceof Error) { $errorStartLine = $previous->getStartLine(); $source = null; if ($errorStartLine !== -1) { $additionalInformation .= sprintf(' (line %d)', $errorStartLine); $lines = explode("\n", $locatedSource->getSource()); $minLine = max(1, $errorStartLine - 5); $maxLine = min(count($lines), $errorStartLine + 5); $source = implode("\n", array_slice($lines, $minLine - 1, $maxLine - $minLine + 1)); } $additionalInformation .= sprintf(': %s', $previous->getRawMessage()); if ($source !== null) { $additionalInformation .= sprintf("\n\n%s", $source); } } else { $additionalInformation .= sprintf(': %s', $previous->getMessage()); } return new self(sprintf('AST failed to parse in located source%s', $additionalInformation), 0, $previous); } } value = $value; $this->constantName = $constantName; } } reflector = $reflector; $this->contextReflection = $contextReflection; } public function getReflector() : Reflector { return $this->reflector; } /** @return non-empty-string|null */ public function getFileName() : ?string { if ($this->contextReflection instanceof ReflectionConstant) { $fileName = $this->contextReflection->getFileName(); if ($fileName === null) { return null; } return $this->realPath($fileName); } $fileName = (($getClass = $this->getClass()) ? $getClass->getFileName() : null) ?? (($getFunction = $this->getFunction()) ? $getFunction->getFileName() : null); if ($fileName === null) { return null; } return $this->realPath($fileName); } private function realPath(string $fileName) : string { return FileHelper::normalizePath($fileName, '/'); } public function getNamespace() : ?string { if ($this->contextReflection instanceof ReflectionConstant) { return $this->contextReflection->getNamespaceName(); } // @infection-ignore-all Coalesce: There's no difference return (($getClass = $this->getClass()) ? $getClass->getNamespaceName() : null) ?? (($getFunction = $this->getFunction()) ? $getFunction->getNamespaceName() : null); } public function getClass() : ?\PHPStan\BetterReflection\Reflection\ReflectionClass { if ($this->contextReflection instanceof ReflectionClass) { return $this->contextReflection; } if ($this->contextReflection instanceof ReflectionFunction) { return null; } if ($this->contextReflection instanceof ReflectionConstant) { return null; } if ($this->contextReflection instanceof ReflectionClassConstant) { return $this->contextReflection->getDeclaringClass(); } if ($this->contextReflection instanceof ReflectionEnumCase) { return $this->contextReflection->getDeclaringClass(); } return $this->contextReflection->getImplementingClass(); } /** * @return \PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|null */ public function getFunction() { if ($this->contextReflection instanceof ReflectionMethod) { return $this->contextReflection; } if ($this->contextReflection instanceof ReflectionFunction) { return $this->contextReflection; } if ($this->contextReflection instanceof ReflectionParameter) { return $this->contextReflection->getDeclaringFunction(); } return null; } } expr, $context); } $constantName = null; if ($node instanceof Node\Expr\ConstFetch && !in_array($node->name->toLowerString(), self::TRUE_FALSE_NULL, \true)) { $constantName = $this->resolveConstantName($node, $context); } elseif ($node instanceof Node\Expr\ClassConstFetch) { $constantName = $this->resolveClassConstantName($node, $context); } $constExprEvaluator = new ConstExprEvaluator(function (Node\Expr $node) use($context, $constantName) { if ($node instanceof Node\Expr\ConstFetch) { return $this->getConstantValue($node, $constantName, $context); } if ($node instanceof Node\Expr\ClassConstFetch) { return $this->getClassConstantValue($node, $constantName, $context); } if ($node instanceof Node\Expr\New_) { return $this->compileNew($node, $context); } if ($node instanceof Node\Scalar\MagicConst\Dir) { return $this->compileDirConstant($context, $node); } if ($node instanceof Node\Scalar\MagicConst\File) { return $this->compileFileConstant($context, $node); } if ($node instanceof Node\Scalar\MagicConst\Class_) { return $this->compileClassConstant($context); } if ($node instanceof Node\Scalar\MagicConst\Line) { return $node->getLine(); } if ($node instanceof Node\Scalar\MagicConst\Namespace_) { return $context->getNamespace() ?? ''; } if ($node instanceof Node\Scalar\MagicConst\Method) { $class = $context->getClass(); $function = $context->getFunction(); if ($class !== null && $function !== null) { return sprintf('%s::%s', $class->getName(), $function->getName()); } if ($function !== null) { return $function->getName(); } return ''; } if ($node instanceof Node\Scalar\MagicConst\Function_) { return (($getFunction = $context->getFunction()) ? $getFunction->getName() : null) ?? ''; } if ($node instanceof Node\Scalar\MagicConst\Trait_) { $class = $context->getClass(); if ($class !== null && $class->isTrait()) { return $class->getName(); } return ''; } if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name && $node->name->toLowerString() === 'constant' && $node->args[0] instanceof Node\Arg && $node->args[0]->value instanceof Node\Scalar\String_ && defined($node->args[0]->value->value)) { return constant($node->args[0]->value->value); } if ($node instanceof Node\Expr\PropertyFetch && $node->var instanceof Node\Expr\ClassConstFetch) { return $this->getEnumPropertyValue($node, $context); } throw \PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode::forUnRecognizedExpressionInContext($node, $context); }); /** @psalm-var mixed $value */ $value = $constExprEvaluator->evaluateDirectly($node); return new \PHPStan\BetterReflection\NodeCompiler\CompiledValue($value, $constantName); } /** * @return mixed */ private function getEnumPropertyValue(Node\Expr\PropertyFetch $node, \PHPStan\BetterReflection\NodeCompiler\CompilerContext $context) { assert($node->var instanceof Node\Expr\ClassConstFetch); assert($node->var->class instanceof Node\Name); $className = $this->resolveClassName($node->var->class->toString(), $context); $class = $context->getReflector()->reflectClass($className); if (!$class instanceof ReflectionEnum) { throw \PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode::becauseOfInvalidEnumCasePropertyFetch($context, $class, $node); } assert($node->var->name instanceof Node\Identifier); $caseName = $node->var->name->name; assert($caseName !== ''); $case = $class->getCase($caseName); if ($case === null) { throw \PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode::becauseOfInvalidEnumCasePropertyFetch($context, $class, $node); } assert($node->name instanceof Node\Identifier); switch ($node->name->toString()) { case 'value': return $case->getValue(); case 'name': return $case->getName(); default: throw \PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode::becauseOfInvalidEnumCasePropertyFetch($context, $class, $node); } } private function resolveConstantName(Node\Expr\ConstFetch $constNode, \PHPStan\BetterReflection\NodeCompiler\CompilerContext $context) : string { $constantName = $constNode->name->toString(); $namespace = $context->getNamespace() ?? ''; if ($constNode->name->isUnqualified()) { $namespacedConstantName = sprintf('%s\\%s', $namespace, $constantName); if ($this->constantExists($namespacedConstantName, $context)) { return $namespacedConstantName; } } if ($this->constantExists($constantName, $context)) { return $constantName; } throw \PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode::becauseOfNotFoundConstantReference($context, $constNode, $constantName); } private function constantExists(string $constantName, \PHPStan\BetterReflection\NodeCompiler\CompilerContext $context) : bool { if (defined($constantName)) { return \true; } try { $context->getReflector()->reflectConstant($constantName); return \true; } catch (IdentifierNotFound $exception) { return \false; } } /** * @return mixed */ private function getConstantValue(Node\Expr\ConstFetch $node, ?string $constantName, \PHPStan\BetterReflection\NodeCompiler\CompilerContext $context) { // It's not resolved when constant value is expression // @infection-ignore-all Assignment, AssignCoalesce: There's no difference, ??= is just optimization $constantName = $constantName ?? $this->resolveConstantName($node, $context); if (defined($constantName)) { return constant($constantName); } return $context->getReflector()->reflectConstant($constantName)->getValue(); } private function resolveClassConstantName(Node\Expr\ClassConstFetch $node, \PHPStan\BetterReflection\NodeCompiler\CompilerContext $context) : string { assert($node->name instanceof Node\Identifier); $constantName = $node->name->name; assert($node->class instanceof Node\Name); $className = $node->class->toString(); return sprintf('%s::%s', $this->resolveClassName($className, $context), $constantName); } /** * @return mixed */ private function getClassConstantValue(Node\Expr\ClassConstFetch $node, ?string $classConstantName, \PHPStan\BetterReflection\NodeCompiler\CompilerContext $context) { // It's not resolved when constant value is expression // @infection-ignore-all Assignment, AssignCoalesce: There's no difference, ??= is just optimization $classConstantName = $classConstantName ?? $this->resolveClassConstantName($node, $context); [$className, $constantName] = explode('::', $classConstantName); assert($constantName !== ''); if ($constantName === 'class') { return $className; } $classContext = $context->getClass(); $classReflection = $classContext !== null && $classContext->getName() === $className ? $classContext : $context->getReflector()->reflectClass($className); if ($classReflection instanceof ReflectionEnum) { if ($classReflection->hasCase($constantName)) { return constant(sprintf('%s::%s', $className, $constantName)); } } if ($classReflection instanceof ReflectionEnum) { if ($classReflection->hasCase($constantName)) { throw \PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode::becauseOfValueIsEnum($context, $classReflection, $node); } } $reflectionConstant = $classReflection->getConstant($constantName); if (!$reflectionConstant instanceof ReflectionClassConstant) { throw \PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode::becauseOfNotFoundClassConstantReference($context, $classReflection, $node); } return $reflectionConstant->getValue(); } private function compileNew(Node\Expr\New_ $node, \PHPStan\BetterReflection\NodeCompiler\CompilerContext $context) : object { assert($node->class instanceof Node\Name); /** @psalm-var class-string $className */ $className = $node->class->toString(); if (!class_exists($className)) { throw \PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode::becauseOfClassCannotBeLoaded($context, $node, $className); } $arguments = []; foreach ($node->args as $argNo => $arg) { $arguments[(($argName = $arg->name) ? $argName->toString() : null) ?? $argNo] = $this($arg->value, $context)->value; } return new $className(...$arguments); } /** * Compile a __DIR__ node */ private function compileDirConstant(\PHPStan\BetterReflection\NodeCompiler\CompilerContext $context, Node\Scalar\MagicConst\Dir $node) : string { $fileName = $context->getFileName(); if ($fileName === null) { throw \PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode::becauseOfMissingFileName($context, $node); } if (!is_file($fileName)) { throw \PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode::becauseOfNonexistentFile($context, $fileName); } return dirname($fileName); } /** * Compile a __FILE__ node */ private function compileFileConstant(\PHPStan\BetterReflection\NodeCompiler\CompilerContext $context, Node\Scalar\MagicConst\File $node) : string { $fileName = $context->getFileName(); if ($fileName === null) { throw \PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode::becauseOfMissingFileName($context, $node); } if (!is_file($fileName)) { throw \PHPStan\BetterReflection\NodeCompiler\Exception\UnableToCompileNode::becauseOfNonexistentFile($context, $fileName); } return $fileName; } /** * Compiles magic constant __CLASS__ */ private function compileClassConstant(\PHPStan\BetterReflection\NodeCompiler\CompilerContext $context) : string { return (($getClass = $context->getClass()) ? $getClass->getName() : null) ?? ''; } private function resolveClassName(string $className, \PHPStan\BetterReflection\NodeCompiler\CompilerContext $context) : string { if ($className !== 'self' && $className !== 'static' && $className !== 'parent') { return $className; } $classContext = $context->getClass(); assert($classContext !== null); if ($className !== 'parent') { return $classContext->getName(); } $parentClass = $classContext->getParentClass(); assert($parentClass instanceof ReflectionClass); return $parentClass->getName(); } } constantName; } public static function forUnRecognizedExpressionInContext(Node\Expr $expression, CompilerContext $context) : self { return new self(sprintf('Unable to compile expression in %s: unrecognized node type %s in file %s (line %d)', self::compilerContextToContextDescription($context), \get_class($expression), self::getFileName($context), $expression->getLine())); } public static function becauseOfNotFoundClassConstantReference(CompilerContext $fetchContext, ReflectionClass $targetClass, Node\Expr\ClassConstFetch $constantFetch) : self { assert($constantFetch->name instanceof Node\Identifier); return new self(sprintf('Could not locate constant %s::%s while trying to evaluate constant expression in %s in file %s (line %d)', $targetClass->getName(), $constantFetch->name->name, self::compilerContextToContextDescription($fetchContext), self::getFileName($fetchContext), $constantFetch->getLine())); } public static function becauseOfNotFoundConstantReference(CompilerContext $fetchContext, Node\Expr\ConstFetch $constantFetch, string $constantName) : self { $exception = new self(sprintf('Could not locate constant "%s" while evaluating expression in %s in file %s (line %d)', $constantName, self::compilerContextToContextDescription($fetchContext), self::getFileName($fetchContext), $constantFetch->getLine())); $exception->constantName = $constantName; return $exception; } public static function becauseOfInvalidEnumCasePropertyFetch(CompilerContext $fetchContext, ReflectionClass $targetClass, Node\Expr\PropertyFetch $propertyFetch) : self { assert($propertyFetch->var instanceof Node\Expr\ClassConstFetch); assert($propertyFetch->var->name instanceof Node\Identifier); assert($propertyFetch->name instanceof Node\Identifier); return new self(sprintf('Could not get %s::%s->%s while trying to evaluate constant expression in %s in file %s (line %d)', $targetClass->getName(), $propertyFetch->var->name->name, $propertyFetch->name->toString(), self::compilerContextToContextDescription($fetchContext), self::getFileName($fetchContext), $propertyFetch->getLine())); } /** * @param \PhpParser\Node\Scalar\MagicConst\Dir|\PhpParser\Node\Scalar\MagicConst\File $node */ public static function becauseOfMissingFileName(CompilerContext $context, $node) : self { return new self(sprintf('No file name for %s (line %d)', self::compilerContextToContextDescription($context), $node->getLine())); } public static function becauseOfNonexistentFile(CompilerContext $context, string $fileName) : self { return new self(sprintf('File not found for %s: %s', self::compilerContextToContextDescription($context), $fileName)); } public static function becauseOfClassCannotBeLoaded(CompilerContext $context, Node\Expr\New_ $newNode, string $className) : self { return new self(sprintf('Cound not load class "%s" while evaluating expression in %s in file %s (line %d)', $className, self::compilerContextToContextDescription($context), self::getFileName($context), $newNode->getLine())); } public static function becauseOfValueIsEnum(CompilerContext $fetchContext, ReflectionClass $targetClass, Node\Expr\ClassConstFetch $constantFetch) : self { assert($constantFetch->name instanceof Node\Identifier); return new self(sprintf('An enum expression %s::%s is not supported in %s in file %s (line %d)', $targetClass->getName(), $constantFetch->name->name, self::compilerContextToContextDescription($fetchContext), self::getFileName($fetchContext), $constantFetch->getLine())); } private static function getFileName(CompilerContext $fetchContext) : string { $fileName = $fetchContext->getFileName(); return $fileName !== null ? FileHelper::normalizeWindowsPath($fileName) : '""'; } private static function compilerContextToContextDescription(CompilerContext $fetchContext) : string { $class = $fetchContext->getClass(); $function = $fetchContext->getFunction(); if ($class !== null && $function !== null) { return sprintf('method %s::%s()', $class->getName(), $function->getName()); } if ($class !== null) { return sprintf('class %s', $class->getName()); } if ($function !== null) { return sprintf('function %s()', $function->getName()); } $namespace = $fetchContext->getNamespace(); if ($namespace !== null) { return sprintf('namespace %s', $namespace); } return 'global namespace'; } } */ private $attributes; /** @var non-empty-string|null */ private $docComment; /** @var positive-int */ private $startLine; /** @var positive-int */ private $endLine; /** @var positive-int */ private $startColumn; /** @var positive-int */ private $endColumn; /** @psalm-allow-private-mutation * @var \PHPStan\BetterReflection\NodeCompiler\CompiledValue|null */ private $compiledValue = null; /** * @var \PHPStan\BetterReflection\Reflector\Reflector */ private $reflector; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionEnum */ private $enum; private function __construct(Reflector $reflector, EnumCase $node, \PHPStan\BetterReflection\Reflection\ReflectionEnum $enum) { $this->reflector = $reflector; $this->enum = $enum; $name = $node->name->toString(); assert($name !== ''); $this->name = $name; $this->value = $node->expr; $this->attributes = ReflectionAttributeHelper::createAttributes($reflector, $this, $node->attrGroups); $this->docComment = GetLastDocComment::forNode($node); $startLine = $node->getStartLine(); assert($startLine > 0); $endLine = $node->getEndLine(); assert($endLine > 0); $this->startLine = $startLine; $this->endLine = $endLine; $this->startColumn = CalculateReflectionColumn::getStartColumn($this->enum->getLocatedSource()->getSource(), $node); $this->endColumn = CalculateReflectionColumn::getEndColumn($this->enum->getLocatedSource()->getSource(), $node); } /** @internal */ public static function createFromNode(Reflector $reflector, EnumCase $node, \PHPStan\BetterReflection\Reflection\ReflectionEnum $enum) : self { return new self($reflector, $node, $enum); } /** @return non-empty-string */ public function getName() : string { return $this->name; } /** * @deprecated Use getValueExpression() */ public function getValueExpr() : Node\Expr { return $this->getValueExpression(); } /** * Check ReflectionEnum::isBacked() being true first to avoid throwing exception. * * @throws LogicException */ public function getValueExpression() : Node\Expr { if ($this->value === null) { throw new LogicException('This enum case does not have a value'); } return $this->value; } /** * @return string|int */ public function getValue() { $value = $this->getCompiledValue()->value; assert(is_string($value) || is_int($value)); return $value; } /** * Check ReflectionEnum::isBacked() being true first to avoid throwing exception. * * @throws LogicException */ private function getCompiledValue() : CompiledValue { if ($this->value === null) { throw new LogicException('This enum case does not have a value'); } if ($this->compiledValue === null) { $this->compiledValue = (new CompileNodeToValue())->__invoke($this->value, new CompilerContext($this->reflector, $this)); } return $this->compiledValue; } /** @return positive-int */ public function getStartLine() : int { return $this->startLine; } /** @return positive-int */ public function getEndLine() : int { return $this->endLine; } /** @return positive-int */ public function getStartColumn() : int { return $this->startColumn; } /** @return positive-int */ public function getEndColumn() : int { return $this->endColumn; } public function getDeclaringEnum() : \PHPStan\BetterReflection\Reflection\ReflectionEnum { return $this->enum; } public function getDeclaringClass() : \PHPStan\BetterReflection\Reflection\ReflectionClass { return $this->enum; } /** @return non-empty-string|null */ public function getDocComment() : ?string { return $this->docComment; } public function isDeprecated() : bool { return AnnotationHelper::isDeprecated($this->docComment); } /** @return list */ public function getAttributes() : array { return $this->attributes; } /** @return list */ public function getAttributesByName(string $name) : array { return ReflectionAttributeHelper::filterAttributesByName($this->getAttributes(), $name); } /** * @param class-string $className * * @return list */ public function getAttributesByInstance(string $className) : array { return ReflectionAttributeHelper::filterAttributesByInstance($this->getAttributes(), $className); } /** @return non-empty-string */ public function __toString() : string { return ReflectionEnumCaseStringCast::toString($this); } } */ private $modifiers; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\ReflectionIntersectionType|null */ private $type; /** * @var \PhpParser\Node\Expr|null */ private $default; /** @var non-empty-string|null */ private $docComment; /** @var list */ private $attributes; /** @var positive-int|null */ private $startLine; /** @var positive-int|null */ private $endLine; /** @var positive-int|null */ private $startColumn; /** @var positive-int|null */ private $endColumn; /** @psalm-allow-private-mutation * @var \PHPStan\BetterReflection\NodeCompiler\CompiledValue|null */ private $compiledDefaultValue = null; /** * @var \PHPStan\BetterReflection\Reflector\Reflector */ private $reflector; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionClass */ private $declaringClass; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionClass */ private $implementingClass; /** * @var bool */ private $isPromoted; /** * @var bool */ private $declaredAtCompileTime; private function __construct(Reflector $reflector, PropertyNode $node, Node\Stmt\PropertyProperty $propertyNode, \PHPStan\BetterReflection\Reflection\ReflectionClass $declaringClass, \PHPStan\BetterReflection\Reflection\ReflectionClass $implementingClass, bool $isPromoted, bool $declaredAtCompileTime) { $this->reflector = $reflector; $this->declaringClass = $declaringClass; $this->implementingClass = $implementingClass; $this->isPromoted = $isPromoted; $this->declaredAtCompileTime = $declaredAtCompileTime; $name = $propertyNode->name->name; assert($name !== ''); $this->name = $name; $this->modifiers = $this->computeModifiers($node); $this->type = $this->createType($node); $this->default = $propertyNode->default; $this->docComment = GetLastDocComment::forNode($node); $this->attributes = ReflectionAttributeHelper::createAttributes($reflector, $this, $node->attrGroups); $startLine = null; if ($node->hasAttribute('startLine')) { $startLine = $node->getStartLine(); assert($startLine > 0); } $endLine = null; if ($node->hasAttribute('endLine')) { $endLine = $node->getEndLine(); assert($endLine > 0); } $this->startLine = $startLine; $this->endLine = $endLine; try { $this->startColumn = CalculateReflectionColumn::getStartColumn($declaringClass->getLocatedSource()->getSource(), $node); } catch (NoNodePosition $exception) { $this->startColumn = null; } try { $this->endColumn = CalculateReflectionColumn::getEndColumn($declaringClass->getLocatedSource()->getSource(), $node); } catch (NoNodePosition $exception) { $this->endColumn = null; } } /** * Create a reflection of a class's property by its name * * @param non-empty-string $propertyName * * @throws OutOfBoundsException */ public static function createFromName(string $className, string $propertyName) : self { $property = \PHPStan\BetterReflection\Reflection\ReflectionClass::createFromName($className)->getProperty($propertyName); if ($property === null) { throw new OutOfBoundsException(sprintf('Could not find property: %s', $propertyName)); } return $property; } /** * Create a reflection of an instance's property by its name * * @param non-empty-string $propertyName * * @throws ReflectionException * @throws IdentifierNotFound * @throws OutOfBoundsException */ public static function createFromInstance(object $instance, string $propertyName) : self { $property = \PHPStan\BetterReflection\Reflection\ReflectionClass::createFromInstance($instance)->getProperty($propertyName); if ($property === null) { throw new OutOfBoundsException(sprintf('Could not find property: %s', $propertyName)); } return $property; } /** @internal */ public function withImplementingClass(\PHPStan\BetterReflection\Reflection\ReflectionClass $implementingClass) : self { $clone = clone $this; $clone->implementingClass = $implementingClass; if ($clone->type !== null) { $clone->type = $clone->type->withOwner($clone); } $clone->attributes = array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionAttribute $attribute) use($clone) : \PHPStan\BetterReflection\Reflection\ReflectionAttribute { return $attribute->withOwner($clone); }, $this->attributes); $this->compiledDefaultValue = null; return $clone; } /** @return non-empty-string */ public function __toString() : string { return ReflectionPropertyStringCast::toString($this); } /** * @internal * * @param PropertyNode $node Node has to be processed by the PhpParser\NodeVisitor\NameResolver */ public static function createFromNode(Reflector $reflector, PropertyNode $node, Node\Stmt\PropertyProperty $propertyProperty, \PHPStan\BetterReflection\Reflection\ReflectionClass $declaringClass, \PHPStan\BetterReflection\Reflection\ReflectionClass $implementingClass, bool $isPromoted = \false, bool $declaredAtCompileTime = \true) : self { return new self($reflector, $node, $propertyProperty, $declaringClass, $implementingClass, $isPromoted, $declaredAtCompileTime); } /** * Has the property been declared at compile-time? * * Note that unless the property is static, this is hard coded to return * true, because we are unable to reflect instances of classes, therefore * we can be sure that all properties are always declared at compile-time. */ public function isDefault() : bool { return $this->declaredAtCompileTime; } /** * Get the core-reflection-compatible modifier values. * * @return int-mask-of */ public function getModifiers() : int { return $this->modifiers; } /** * Get the name of the property. * * @return non-empty-string */ public function getName() : string { return $this->name; } /** * Is the property private? */ public function isPrivate() : bool { return ($this->modifiers & CoreReflectionProperty::IS_PRIVATE) === CoreReflectionProperty::IS_PRIVATE; } /** * Is the property protected? */ public function isProtected() : bool { return ($this->modifiers & CoreReflectionProperty::IS_PROTECTED) === CoreReflectionProperty::IS_PROTECTED; } /** * Is the property public? */ public function isPublic() : bool { return ($this->modifiers & CoreReflectionProperty::IS_PUBLIC) === CoreReflectionProperty::IS_PUBLIC; } /** * Is the property static? */ public function isStatic() : bool { return ($this->modifiers & CoreReflectionProperty::IS_STATIC) === CoreReflectionProperty::IS_STATIC; } public function isPromoted() : bool { return $this->isPromoted; } public function isInitialized($object = null) : bool { if ($object === null && $this->isStatic()) { return !$this->hasType() || $this->hasDefaultValue(); } try { $this->getValue($object); return \true; // @phpstan-ignore-next-line } catch (Error $e) { if (\strpos($e->getMessage(), 'must not be accessed before initialization') !== \false) { return \false; } throw $e; } } public function isReadOnly() : bool { return ($this->modifiers & ReflectionPropertyAdapter::IS_READONLY_COMPATIBILITY) === ReflectionPropertyAdapter::IS_READONLY_COMPATIBILITY || $this->getDeclaringClass()->isReadOnly(); } public function getDeclaringClass() : \PHPStan\BetterReflection\Reflection\ReflectionClass { return $this->declaringClass; } public function getImplementingClass() : \PHPStan\BetterReflection\Reflection\ReflectionClass { return $this->implementingClass; } /** @return non-empty-string|null */ public function getDocComment() : ?string { return $this->docComment; } public function hasDefaultValue() : bool { return !$this->hasType() || $this->default !== null; } /** * @deprecated Use getDefaultValueExpression() */ public function getDefaultValueExpr() : ?\PhpParser\Node\Expr { return $this->getDefaultValueExpression(); } public function getDefaultValueExpression() : ?\PhpParser\Node\Expr { return $this->default; } /** * Get the default value of the property (as defined before constructor is * called, when the property is defined) * * @deprecated Use getDefaultValueExpr() * @return mixed */ public function getDefaultValue() { if ($this->default === null) { return null; } if ($this->compiledDefaultValue === null) { $this->compiledDefaultValue = (new CompileNodeToValue())->__invoke($this->default, new CompilerContext($this->reflector, $this)); } /** @psalm-var scalar|array|null $value */ $value = $this->compiledDefaultValue->value; return $value; } public function isDeprecated() : bool { return AnnotationHelper::isDeprecated($this->getDocComment()); } /** * Get the line number that this property starts on. * * @return positive-int * * @throws CodeLocationMissing */ public function getStartLine() : int { if ($this->startLine === null) { throw CodeLocationMissing::create(); } return $this->startLine; } /** * Get the line number that this property ends on. * * @return positive-int * * @throws CodeLocationMissing */ public function getEndLine() : int { if ($this->endLine === null) { throw CodeLocationMissing::create(); } return $this->endLine; } /** * @return positive-int * * @throws CodeLocationMissing */ public function getStartColumn() : int { if ($this->startColumn === null) { throw CodeLocationMissing::create(); } return $this->startColumn; } /** * @return positive-int * * @throws CodeLocationMissing */ public function getEndColumn() : int { if ($this->endColumn === null) { throw CodeLocationMissing::create(); } return $this->endColumn; } /** @return list */ public function getAttributes() : array { return $this->attributes; } /** @return list */ public function getAttributesByName(string $name) : array { return ReflectionAttributeHelper::filterAttributesByName($this->getAttributes(), $name); } /** * @param class-string $className * * @return list */ public function getAttributesByInstance(string $className) : array { return ReflectionAttributeHelper::filterAttributesByInstance($this->getAttributes(), $className); } /** * @throws ClassDoesNotExist * @throws NoObjectProvided * @throws ObjectNotInstanceOfClass * @return mixed */ public function getValue($object = null) { $implementingClassName = $this->getImplementingClass()->getName(); if ($this->isStatic()) { $this->assertClassExist($implementingClassName); $closure = Closure::bind(function (string $implementingClassName, string $propertyName) { return $implementingClassName::${$propertyName}; }, null, $implementingClassName); assert($closure instanceof Closure); return $closure->__invoke($implementingClassName, $this->getName()); } $instance = $this->assertObject($object); $closure = Closure::bind(function (object $instance, string $propertyName) { return $instance->{$propertyName}; }, $instance, $implementingClassName); assert($closure instanceof Closure); return $closure->__invoke($instance, $this->getName()); } /** * @throws ClassDoesNotExist * @throws NoObjectProvided * @throws NotAnObject * @throws ObjectNotInstanceOfClass * @param mixed $object * @param mixed $value */ public function setValue($object, $value = null) : void { $implementingClassName = $this->getImplementingClass()->getName(); if ($this->isStatic()) { $this->assertClassExist($implementingClassName); $closure = Closure::bind(function (string $_implementingClassName, string $_propertyName, $value) : void { /** @psalm-suppress MixedAssignment */ $_implementingClassName::${$_propertyName} = $value; }, null, $implementingClassName); assert($closure instanceof Closure); $closure->__invoke($implementingClassName, $this->getName(), func_num_args() === 2 ? $value : $object); return; } $instance = $this->assertObject($object); $closure = Closure::bind(function (object $instance, string $propertyName, $value) : void { $instance->{$propertyName} = $value; }, $instance, $implementingClassName); assert($closure instanceof Closure); $closure->__invoke($instance, $this->getName(), $value); } /** * Does this property allow null? */ public function allowsNull() : bool { return $this->type === null || $this->type->allowsNull(); } /** * @return \PHPStan\BetterReflection\Reflection\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\ReflectionIntersectionType|null */ private function createType(PropertyNode $node) { $type = $node->type; if ($type === null) { return null; } assert($type instanceof Node\Identifier || $type instanceof Node\Name || $type instanceof Node\NullableType || $type instanceof Node\UnionType || $type instanceof Node\IntersectionType); return \PHPStan\BetterReflection\Reflection\ReflectionType::createFromNode($this->reflector, $this, $type); } /** * Get the ReflectionType instance representing the type declaration for * this property * * (note: this has nothing to do with DocBlocks). * @return \PHPStan\BetterReflection\Reflection\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\ReflectionIntersectionType|null */ public function getType() { return $this->type; } /** * Does this property have a type declaration? * * (note: this has nothing to do with DocBlocks). */ public function hasType() : bool { return $this->type !== null; } /** * @param class-string $className * * @throws ClassDoesNotExist */ private function assertClassExist(string $className) : void { if (!ClassExistenceChecker::classExists($className, \true) && !ClassExistenceChecker::traitExists($className, \true)) { throw new ClassDoesNotExist('Property cannot be retrieved as the class does not exist'); } } /** * @throws NoObjectProvided * @throws NotAnObject * @throws ObjectNotInstanceOfClass * * @psalm-assert object $object * @param mixed $object */ private function assertObject($object) : object { if ($object === null) { throw NoObjectProvided::create(); } if (!is_object($object)) { throw NotAnObject::fromNonObject($object); } $implementingClassName = $this->getImplementingClass()->getName(); if (\get_class($object) !== $implementingClassName) { throw ObjectNotInstanceOfClass::fromClassName($implementingClassName); } return $object; } /** @return int-mask-of */ private function computeModifiers(PropertyNode $node) : int { $modifiers = $node->isReadonly() ? ReflectionPropertyAdapter::IS_READONLY_COMPATIBILITY : 0; $modifiers += $node->isStatic() ? CoreReflectionProperty::IS_STATIC : 0; $modifiers += $node->isPrivate() ? CoreReflectionProperty::IS_PRIVATE : 0; $modifiers += $node->isProtected() ? CoreReflectionProperty::IS_PROTECTED : 0; $modifiers += $node->isPublic() ? CoreReflectionProperty::IS_PUBLIC : 0; return $modifiers; } } */ private $types; /** @internal * @param \PHPStan\BetterReflection\Reflection\ReflectionParameter|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionEnum|\PHPStan\BetterReflection\Reflection\ReflectionProperty|\PHPStan\BetterReflection\Reflection\ReflectionClassConstant $owner */ public function __construct(Reflector $reflector, $owner, IntersectionType $type) { /** @var non-empty-list $types */ $types = array_map(static function ($type) use($reflector, $owner) : \PHPStan\BetterReflection\Reflection\ReflectionNamedType { $type = \PHPStan\BetterReflection\Reflection\ReflectionType::createFromNode($reflector, $owner, $type); assert($type instanceof \PHPStan\BetterReflection\Reflection\ReflectionNamedType); return $type; }, $type->types); $this->types = $types; } /** @internal * @param \PHPStan\BetterReflection\Reflection\ReflectionParameter|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionEnum|\PHPStan\BetterReflection\Reflection\ReflectionProperty|\PHPStan\BetterReflection\Reflection\ReflectionClassConstant $owner * @return $this */ public function withOwner($owner) { $clone = clone $this; foreach ($clone->types as $typeNo => $innerType) { $clone->types[$typeNo] = $innerType->withOwner($owner); } return $clone; } /** @return non-empty-list */ public function getTypes() : array { return $this->types; } /** @return false */ public function allowsNull() : bool { return \false; } /** @return non-empty-string */ public function __toString() : string { // @infection-ignore-all UnwrapArrayMap: It works without array_map() as well but this is less magical return implode('&', array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionNamedType $type) : string { return $type->__toString(); }, $this->types)); } } */ private $classNames; /** @param array $classNames */ private function __construct(array $classNames) { $this->classNames = $classNames; } public static function createEmpty() : self { return new self([]); } /** @param class-string $className */ public function push(string $className) : void { if (array_key_exists($className, $this->classNames)) { throw CircularReference::fromClassName($className); } $this->classNames[$className] = null; } } */ private $modifiers; /** @var non-empty-string|null */ private $docComment; /** @var list */ private $attributes; /** @var positive-int */ private $startLine; /** @var positive-int */ private $endLine; /** @var positive-int */ private $startColumn; /** @var positive-int */ private $endColumn; /** @var class-string|null */ private $parentClassName; /** @var list */ private $implementsClassNames; /** @var list */ private $traitClassNames; /** @var array */ private $immediateConstants; /** @var array */ private $immediateProperties; /** @var array */ private $immediateMethods; /** @var array{aliases: array, modifiers: array>, precedences: array} */ private $traitsData; /** * @var array|null * @psalm-allow-private-mutation */ private $cachedConstants = null; /** * @var array|null * @psalm-allow-private-mutation */ private $cachedProperties = null; /** @var array|null */ private $cachedInterfaces = null; /** @var list|null */ private $cachedInterfaceNames = null; /** @var list|null */ private $cachedTraits = null; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionMethod|null */ private $cachedConstructor = null; /** * @var string|null */ private $cachedName = null; /** * @psalm-allow-private-mutation * @var array|null */ private $cachedMethods = null; /** * @var list|null * @psalm-allow-private-mutation */ private $cachedParentClasses = null; /** * @var \PHPStan\BetterReflection\Reflector\Reflector */ private $reflector; /** * @var \PHPStan\BetterReflection\SourceLocator\Located\LocatedSource */ private $locatedSource; /** * @var non-empty-string|null */ private $namespace = null; /** * @internal * * @param non-empty-string|null $namespace * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node */ protected function __construct(Reflector $reflector, $node, LocatedSource $locatedSource, ?string $namespace = null) { $this->reflector = $reflector; $this->locatedSource = $locatedSource; $this->namespace = $namespace; $this->name = null; $this->shortName = null; if ($node->name instanceof Node\Identifier) { $namespacedName = $node->namespacedName; if ($namespacedName === null) { /** @psalm-var class-string|trait-string */ $name = $node->name->name; } else { /** @psalm-var class-string|trait-string */ $name = $namespacedName->toString(); } $this->name = $name; $this->shortName = $node->name->name; } $this->isInterface = $node instanceof InterfaceNode; $this->isTrait = $node instanceof TraitNode; $this->isEnum = $node instanceof EnumNode; $this->isBackedEnum = $node instanceof EnumNode && $node->scalarType !== null; $this->modifiers = $this->computeModifiers($node); $this->docComment = GetLastDocComment::forNode($node); $this->attributes = ReflectionAttributeHelper::createAttributes($reflector, $this, $node->attrGroups); $startLine = $node->getStartLine(); assert($startLine > 0); $endLine = $node->getEndLine(); assert($endLine > 0); $this->startLine = $startLine; $this->endLine = $endLine; $this->startColumn = CalculateReflectionColumn::getStartColumn($locatedSource->getSource(), $node); $this->endColumn = CalculateReflectionColumn::getEndColumn($locatedSource->getSource(), $node); /** @var class-string|null $parentClassName */ $parentClassName = $node instanceof ClassNode ? ($nodeExtends = $node->extends) ? $nodeExtends->toString() : null : null; $this->parentClassName = $parentClassName; // @infection-ignore-all UnwrapArrayMap: It works without array_map() as well but this is less magical /** @var list $implementsClassNames */ $implementsClassNames = array_map(static function (Node\Name $name) : string { return $name->toString(); }, $node instanceof TraitNode ? [] : ($node instanceof InterfaceNode ? $node->extends : $node->implements)); $this->implementsClassNames = $implementsClassNames; /** @var list $traitClassNames */ $traitClassNames = array_merge([], ...array_map( // @infection-ignore-all UnwrapArrayMap: It works without array_map() as well but this is less magical static function (TraitUse $traitUse) : array { return array_map(static function (Node\Name $traitName) : string { return $traitName->toString(); }, $traitUse->traits); }, $node->getTraitUses() )); $this->traitClassNames = $traitClassNames; $this->immediateConstants = $this->createImmediateConstants($node, $reflector); $this->immediateProperties = $this->createImmediateProperties($node, $reflector); $this->immediateMethods = $this->createImmediateMethods($node, $reflector); $this->traitsData = $this->computeTraitsData($node); } /** @return non-empty-string */ public function __toString() : string { return ReflectionClassStringCast::toString($this); } /** * Create a ReflectionClass by name, using default reflectors etc. * * @deprecated Use Reflector instead. * * @throws IdentifierNotFound */ public static function createFromName(string $className) : self { return (new BetterReflection())->reflector()->reflectClass($className); } /** * Create a ReflectionClass from an instance, using default reflectors etc. * * This is simply a helper method that calls ReflectionObject::createFromInstance(). * * @see ReflectionObject::createFromInstance * * @throws IdentifierNotFound * @throws ReflectionException */ public static function createFromInstance(object $instance) : self { return \PHPStan\BetterReflection\Reflection\ReflectionObject::createFromInstance($instance); } /** * Create from a Class Node. * * @internal * * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node Node has to be processed by the PhpParser\NodeVisitor\NameResolver * @param non-empty-string|null $namespace optional - if omitted, we assume it is global namespaced class */ public static function createFromNode(Reflector $reflector, $node, LocatedSource $locatedSource, ?string $namespace = null) : self { return new self($reflector, $node, $locatedSource, $namespace); } /** * Get the "short" name of the class (e.g. for A\B\Foo, this will return * "Foo"). * * @return non-empty-string */ public function getShortName() : string { if ($this->shortName !== null) { return $this->shortName; } $fileName = $this->getFileName(); if ($fileName === null) { $fileName = sha1($this->locatedSource->getSource()); } return sprintf('%s%s%c%s(%d)', $this->getAnonymousClassNamePrefix(), self::ANONYMOUS_CLASS_NAME_SUFFIX, "\x00", $fileName, $this->getStartLine()); } /** * PHP creates the name of the anonymous class based on first parent * or implemented interface. */ private function getAnonymousClassNamePrefix() : string { if ($this->parentClassName !== null) { return $this->parentClassName; } if ($this->implementsClassNames !== []) { return $this->implementsClassNames[0]; } return 'class'; } /** * Get the "full" name of the class (e.g. for A\B\Foo, this will return * "A\B\Foo"). * * @return class-string|trait-string */ public function getName() : string { if ($this->cachedName !== null) { return $this->cachedName; } if (!$this->inNamespace()) { /** @psalm-var class-string|trait-string */ return $this->cachedName = $this->getShortName(); } assert($this->name !== null); return $this->cachedName = $this->name; } /** @return class-string|null */ public function getParentClassName() : ?string { return $this->parentClassName; } /** * Get the "namespace" name of the class (e.g. for A\B\Foo, this will * return "A\B"). * * @return non-empty-string|null */ public function getNamespaceName() : ?string { return $this->namespace; } /** * Decide if this class is part of a namespace. Returns false if the class * is in the global namespace or does not have a specified namespace. */ public function inNamespace() : bool { return $this->namespace !== null; } /** @return non-empty-string|null */ public function getExtensionName() : ?string { return $this->locatedSource->getExtensionName(); } /** @return list */ private function createMethodsFromTrait(\PHPStan\BetterReflection\Reflection\ReflectionMethod $method) : array { $methodModifiers = $method->getModifiers(); $methodHash = $this->methodHash($method->getImplementingClass()->getName(), $method->getName()); if (array_key_exists($methodHash, $this->traitsData['modifiers'])) { $newModifierAst = $this->traitsData['modifiers'][$methodHash]; if ($this->traitsData['modifiers'][$methodHash] & ClassNode::VISIBILITY_MODIFIER_MASK) { $methodModifiersWithoutVisibility = $methodModifiers; if (($methodModifiers & CoreReflectionMethod::IS_PUBLIC) === CoreReflectionMethod::IS_PUBLIC) { $methodModifiersWithoutVisibility -= CoreReflectionMethod::IS_PUBLIC; } if (($methodModifiers & CoreReflectionMethod::IS_PROTECTED) === CoreReflectionMethod::IS_PROTECTED) { $methodModifiersWithoutVisibility -= CoreReflectionMethod::IS_PROTECTED; } if (($methodModifiers & CoreReflectionMethod::IS_PRIVATE) === CoreReflectionMethod::IS_PRIVATE) { $methodModifiersWithoutVisibility -= CoreReflectionMethod::IS_PRIVATE; } $newModifier = 0; if (($newModifierAst & ClassNode::MODIFIER_PUBLIC) === ClassNode::MODIFIER_PUBLIC) { $newModifier = CoreReflectionMethod::IS_PUBLIC; } if (($newModifierAst & ClassNode::MODIFIER_PROTECTED) === ClassNode::MODIFIER_PROTECTED) { $newModifier = CoreReflectionMethod::IS_PROTECTED; } if (($newModifierAst & ClassNode::MODIFIER_PRIVATE) === ClassNode::MODIFIER_PRIVATE) { $newModifier = CoreReflectionMethod::IS_PRIVATE; } $methodModifiers = $methodModifiersWithoutVisibility | $newModifier; } if (($newModifierAst & ClassNode::MODIFIER_FINAL) === ClassNode::MODIFIER_FINAL) { $methodModifiers |= CoreReflectionMethod::IS_FINAL; } } $createMethod = function (?string $aliasMethodName) use($method, $methodModifiers) : \PHPStan\BetterReflection\Reflection\ReflectionMethod { assert($aliasMethodName === null || $aliasMethodName !== ''); /** @phpstan-ignore-next-line */ return $method->withImplementingClass($this, $aliasMethodName, $methodModifiers); }; $methods = []; if (!array_key_exists($methodHash, $this->traitsData['precedences'])) { $methods[] = $createMethod($method->getAliasName()); } foreach ($this->traitsData['aliases'] as $aliasMethodName => $traitAliasDefinition) { if ($methodHash !== $traitAliasDefinition) { continue; } $methods[] = $createMethod($aliasMethodName); } return $methods; } /** * Construct a flat list of all methods in this precise order from: * - current class * - parent class * - traits used in parent class * - interfaces implemented in parent class * - traits used in current class * - interfaces implemented in current class * * Methods are not merged via their name as array index, since internal PHP method * sorting does not follow `\array_merge()` semantics. * * @return array indexed by method name */ private function getMethodsIndexedByLowercasedName(AlreadyVisitedClasses $alreadyVisitedClasses) : array { if ($this->cachedMethods !== null) { return $this->cachedMethods; } $alreadyVisitedClasses->push($this->getName()); $immediateMethods = $this->getImmediateMethods(); $className = $this->getName(); $methods = \array_combine(array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionMethod $method) : string { return strtolower($method->getName()); }, $immediateMethods), $immediateMethods); $parentClass = $this->getParentClass(); if ($parentClass !== null) { foreach ($parentClass->getMethodsIndexedByLowercasedName($alreadyVisitedClasses) as $lowercasedMethodName => $method) { if (array_key_exists($lowercasedMethodName, $methods)) { continue; } $methods[$lowercasedMethodName] = $method->withCurrentClass($this); } } foreach ($this->getTraits() as $trait) { $alreadyVisitedClassesCopy = clone $alreadyVisitedClasses; foreach ($trait->getMethodsIndexedByLowercasedName($alreadyVisitedClassesCopy) as $method) { foreach ($this->createMethodsFromTrait($method) as $traitMethod) { $lowercasedMethodName = strtolower($traitMethod->getName()); if (!array_key_exists($lowercasedMethodName, $methods)) { $methods[$lowercasedMethodName] = $traitMethod; continue; } if ($traitMethod->isAbstract()) { continue; } // Non-abstract trait method can overwrite existing method: // - when existing method comes from parent class // - when existing method comes from trait and is abstract $existingMethod = $methods[$lowercasedMethodName]; if ($existingMethod->getDeclaringClass()->getName() === $className && !($existingMethod->isAbstract() && $existingMethod->getDeclaringClass()->isTrait())) { continue; } $methods[$lowercasedMethodName] = $traitMethod; } } } foreach ($this->getImmediateInterfaces() as $interface) { $alreadyVisitedClassesCopy = clone $alreadyVisitedClasses; foreach ($interface->getMethodsIndexedByLowercasedName($alreadyVisitedClassesCopy) as $lowercasedMethodName => $method) { if (array_key_exists($lowercasedMethodName, $methods)) { continue; } $methods[$lowercasedMethodName] = $method; } } $this->cachedMethods = $methods; return $this->cachedMethods; } /** * Fetch an array of all methods for this class. * * Filter the results to include only methods with certain attributes. Defaults * to no filtering. * Any combination of \ReflectionMethod::IS_STATIC, * \ReflectionMethod::IS_PUBLIC, * \ReflectionMethod::IS_PROTECTED, * \ReflectionMethod::IS_PRIVATE, * \ReflectionMethod::IS_ABSTRACT, * \ReflectionMethod::IS_FINAL. * For example if $filter = \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_FINAL * the only the final public methods will be returned * * @param int-mask-of $filter * * @return array */ public function getMethods(int $filter = 0) : array { $methods = $this->getMethodsIndexedByLowercasedName(AlreadyVisitedClasses::createEmpty()); if ($filter !== 0) { $methods = array_filter($methods, static function (\PHPStan\BetterReflection\Reflection\ReflectionMethod $method) use($filter) : bool { return (bool) ($filter & $method->getModifiers()); }); } return \array_combine(array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionMethod $method) : string { return $method->getName(); }, $methods), $methods); } /** * Get only the methods that this class implements (i.e. do not search * up parent classes etc.) * * @see ReflectionClass::getMethods for the usage of $filter * * @param int-mask-of $filter * * @return array */ public function getImmediateMethods(int $filter = 0) : array { if ($filter === 0) { return $this->immediateMethods; } return array_filter($this->immediateMethods, static function (\PHPStan\BetterReflection\Reflection\ReflectionMethod $method) use($filter) : bool { return (bool) ($filter & $method->getModifiers()); }); } /** @return array * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node */ private function createImmediateMethods($node, Reflector $reflector) : array { $methods = []; foreach ($node->getMethods() as $methodNode) { $method = \PHPStan\BetterReflection\Reflection\ReflectionMethod::createFromNode($reflector, $methodNode, $this->locatedSource, $this->getNamespaceName(), $this, $this, $this); if (array_key_exists($method->getName(), $methods)) { continue; } $methods[$method->getName()] = $method; } if ($node instanceof EnumNode) { $methods = $this->addEnumMethods($node, $methods); } return $methods; } /** * @param array $methods * * @return array */ private function addEnumMethods(EnumNode $node, array $methods) : array { $internalLocatedSource = new InternalLocatedSource('', $this->getName(), 'Core', $this->getFileName()); $createMethod = function (string $name, array $params, $returnType) use($internalLocatedSource) : \PHPStan\BetterReflection\Reflection\ReflectionMethod { return \PHPStan\BetterReflection\Reflection\ReflectionMethod::createFromNode($this->reflector, new ClassMethod(new Node\Identifier($name), ['flags' => ClassNode::MODIFIER_PUBLIC | ClassNode::MODIFIER_STATIC, 'params' => $params, 'returnType' => $returnType]), $internalLocatedSource, $this->getNamespaceName(), $this, $this, $this); }; $methods['cases'] = $createMethod('cases', [], new Node\Identifier('array')); if ($node->scalarType === null) { return $methods; } $valueParameter = new Node\Param(new Node\Expr\Variable('value'), null, new Node\UnionType([new Node\Identifier('string'), new Node\Identifier('int')])); $methods['from'] = $createMethod('from', [$valueParameter], new Node\Identifier('static')); $methods['tryFrom'] = $createMethod('tryFrom', [$valueParameter], new Node\NullableType(new Node\Identifier('static'))); return $methods; } /** * Get a single method with the name $methodName. * * @param non-empty-string $methodName */ public function getMethod(string $methodName) : ?\PHPStan\BetterReflection\Reflection\ReflectionMethod { $lowercaseMethodName = strtolower($methodName); $methods = $this->getMethodsIndexedByLowercasedName(AlreadyVisitedClasses::createEmpty()); return $methods[$lowercaseMethodName] ?? null; } /** * Does the class have the specified method? * * @param non-empty-string $methodName */ public function hasMethod(string $methodName) : bool { return $this->getMethod($methodName) !== null; } /** * Get an associative array of only the constants for this specific class (i.e. do not search * up parent classes etc.), with keys as constant names and values as {@see ReflectionClassConstant} objects. * * @param int-mask-of $filter * * @return array indexed by name */ public function getImmediateConstants(int $filter = 0) : array { if ($filter === 0) { return $this->immediateConstants; } return array_filter($this->immediateConstants, static function (\PHPStan\BetterReflection\Reflection\ReflectionClassConstant $constant) use($filter) : bool { return (bool) ($filter & $constant->getModifiers()); }); } /** * Does this class have the specified constant? * * @param non-empty-string $name */ public function hasConstant(string $name) : bool { return $this->getConstant($name) !== null; } /** * Get the reflection object of the specified class constant. * * Returns null if not specified. * * @param non-empty-string $name */ public function getConstant(string $name) : ?\PHPStan\BetterReflection\Reflection\ReflectionClassConstant { return $this->getConstants()[$name] ?? null; } /** @return array * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node */ private function createImmediateConstants($node, Reflector $reflector) : array { $constants = []; foreach ($node->getConstants() as $constantsNode) { foreach (array_keys($constantsNode->consts) as $constantPositionInNode) { assert(is_int($constantPositionInNode)); $constant = \PHPStan\BetterReflection\Reflection\ReflectionClassConstant::createFromNode($reflector, $constantsNode, $constantPositionInNode, $this, $this); $constants[$constant->getName()] = $constant; } } return $constants; } /** * Get an associative array of the defined constants in this class, * with keys as constant names and values as {@see ReflectionClassConstant} objects. * * @param int-mask-of $filter * * @return array indexed by name */ public function getConstants(int $filter = 0) : array { $constants = $this->getConstantsConsideringAlreadyVisitedClasses(AlreadyVisitedClasses::createEmpty()); if ($filter === 0) { return $constants; } return array_filter($constants, static function (\PHPStan\BetterReflection\Reflection\ReflectionClassConstant $constant) use($filter) : bool { return (bool) ($filter & $constant->getModifiers()); }); } /** @return array indexed by name */ private function getConstantsConsideringAlreadyVisitedClasses(AlreadyVisitedClasses $alreadyVisitedClasses) : array { if ($this->cachedConstants !== null) { return $this->cachedConstants; } $alreadyVisitedClasses->push($this->getName()); // Note: constants are not merged via their name as array index, since internal PHP constant // sorting does not follow `\array_merge()` semantics $constants = $this->getImmediateConstants(); $parentClass = $this->getParentClass(); if ($parentClass !== null) { foreach ($parentClass->getConstantsConsideringAlreadyVisitedClasses($alreadyVisitedClasses) as $constantName => $constant) { if ($constant->isPrivate()) { continue; } if (array_key_exists($constantName, $constants)) { continue; } $constants[$constantName] = $constant; } } foreach ($this->getTraits() as $trait) { foreach ($trait->getConstantsConsideringAlreadyVisitedClasses($alreadyVisitedClasses) as $constantName => $constant) { if (array_key_exists($constantName, $constants)) { continue; } $constants[$constantName] = $constant->withImplementingClass($this); } } foreach ($this->getImmediateInterfaces() as $interface) { $alreadyVisitedClassesCopy = clone $alreadyVisitedClasses; foreach ($interface->getConstantsConsideringAlreadyVisitedClasses($alreadyVisitedClassesCopy) as $constantName => $constant) { if (array_key_exists($constantName, $constants)) { continue; } $constants[$constantName] = $constant; } } $this->cachedConstants = $constants; return $this->cachedConstants; } /** * Get the constructor method for this class. */ public function getConstructor() : ?\PHPStan\BetterReflection\Reflection\ReflectionMethod { if ($this->cachedConstructor !== null) { return $this->cachedConstructor; } $constructors = array_values(array_filter($this->getMethods(), static function (\PHPStan\BetterReflection\Reflection\ReflectionMethod $method) : bool { return $method->isConstructor(); })); return $this->cachedConstructor = $constructors[0] ?? null; } /** * Get only the properties for this specific class (i.e. do not search * up parent classes etc.) * * @see ReflectionClass::getProperties() for the usage of filter * * @param int-mask-of $filter * * @return array */ public function getImmediateProperties(int $filter = 0) : array { if ($filter === 0) { return $this->immediateProperties; } return array_filter($this->immediateProperties, static function (\PHPStan\BetterReflection\Reflection\ReflectionProperty $property) use($filter) : bool { return (bool) ($filter & $property->getModifiers()); }); } /** @return array * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node */ private function createImmediateProperties($node, Reflector $reflector) : array { $properties = []; foreach ($node->getProperties() as $propertiesNode) { foreach ($propertiesNode->props as $propertyPropertyNode) { $property = \PHPStan\BetterReflection\Reflection\ReflectionProperty::createFromNode($reflector, $propertiesNode, $propertyPropertyNode, $this, $this); $properties[$property->getName()] = $property; } } foreach ($node->getMethods() as $methodNode) { if ($methodNode->name->toLowerString() !== '__construct') { continue; } foreach ($methodNode->params as $parameterNode) { if ($parameterNode->flags === 0) { // No flags, no promotion continue; } $parameterNameNode = $parameterNode->var; assert($parameterNameNode instanceof Node\Expr\Variable); assert(is_string($parameterNameNode->name)); $propertyNode = new Node\Stmt\Property($parameterNode->flags, [new Node\Stmt\PropertyProperty($parameterNameNode->name)], $parameterNode->getAttributes(), $parameterNode->type, $parameterNode->attrGroups); $property = \PHPStan\BetterReflection\Reflection\ReflectionProperty::createFromNode($reflector, $propertyNode, $propertyNode->props[0], $this, $this, \true); $properties[$property->getName()] = $property; } } if ($node instanceof EnumNode || $node instanceof InterfaceNode) { $properties = $this->addEnumProperties($properties, $node, $reflector); } return $properties; } /** * @param array $properties * * @return array * @param EnumNode|InterfaceNode $node */ private function addEnumProperties(array $properties, $node, Reflector $reflector) : array { $createProperty = function (string $name, $type) use($reflector) : \PHPStan\BetterReflection\Reflection\ReflectionProperty { $propertyNode = new Node\Stmt\Property(ClassNode::MODIFIER_PUBLIC | ClassNode::MODIFIER_READONLY, [new Node\Stmt\PropertyProperty($name)], [], $type); return \PHPStan\BetterReflection\Reflection\ReflectionProperty::createFromNode($reflector, $propertyNode, $propertyNode->props[0], $this, $this); }; if ($node instanceof InterfaceNode) { $interfaceName = $this->getName(); if ($interfaceName === 'UnitEnum') { $properties['name'] = $createProperty('name', 'string'); } if ($interfaceName === 'BackedEnum') { $properties['value'] = $createProperty('value', new Node\UnionType([new Node\Identifier('int'), new Node\Identifier('string')])); } } else { $properties['name'] = $createProperty('name', 'string'); if ($node->scalarType !== null) { $properties['value'] = $createProperty('value', $node->scalarType); } } return $properties; } /** * Get the properties for this class. * * Filter the results to include only properties with certain attributes. Defaults * to no filtering. * Any combination of \ReflectionProperty::IS_STATIC, * \ReflectionProperty::IS_PUBLIC, * \ReflectionProperty::IS_PROTECTED, * \ReflectionProperty::IS_PRIVATE. * For example if $filter = \ReflectionProperty::IS_STATIC | \ReflectionProperty::IS_PUBLIC * only the static public properties will be returned * * @param int-mask-of $filter * * @return array */ public function getProperties(int $filter = 0) : array { $properties = $this->getPropertiesConsideringAlreadyVisitedClasses(AlreadyVisitedClasses::createEmpty()); if ($filter === 0) { return $properties; } return array_filter($properties, static function (\PHPStan\BetterReflection\Reflection\ReflectionProperty $property) use($filter) : bool { return (bool) ($filter & $property->getModifiers()); }); } /** @return array */ private function getPropertiesConsideringAlreadyVisitedClasses(AlreadyVisitedClasses $alreadyVisitedClasses) : array { if ($this->cachedProperties !== null) { return $this->cachedProperties; } $alreadyVisitedClasses->push($this->getName()); $immediateProperties = $this->getImmediateProperties(); // Merging together properties from parent class, interfaces, traits, current class (in this precise order) $properties = array_merge(array_filter((($getParentClass = $this->getParentClass()) ? $getParentClass->getPropertiesConsideringAlreadyVisitedClasses($alreadyVisitedClasses) : null) ?? [], static function (\PHPStan\BetterReflection\Reflection\ReflectionProperty $property) { return !$property->isPrivate(); }), ...array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionClass $ancestor) use($alreadyVisitedClasses) : array { return $ancestor->getPropertiesConsideringAlreadyVisitedClasses(clone $alreadyVisitedClasses); }, array_values($this->getImmediateInterfaces()))); foreach ($this->getTraits() as $trait) { foreach ($trait->getPropertiesConsideringAlreadyVisitedClasses($alreadyVisitedClasses) as $traitProperty) { $traitPropertyName = $traitProperty->getName(); if (array_key_exists($traitPropertyName, $properties) || array_key_exists($traitPropertyName, $immediateProperties)) { continue; } $properties[$traitPropertyName] = $traitProperty->withImplementingClass($this); } } // Merge immediate properties last to get the required order $properties = array_merge($properties, $immediateProperties); $this->cachedProperties = $properties; return $this->cachedProperties; } /** * Get the property called $name. * * Returns null if property does not exist. * * @param non-empty-string $name */ public function getProperty(string $name) : ?\PHPStan\BetterReflection\Reflection\ReflectionProperty { $properties = $this->getProperties(); if (!isset($properties[$name])) { return null; } return $properties[$name]; } /** * Does this class have the specified property? * * @param non-empty-string $name */ public function hasProperty(string $name) : bool { return $this->getProperty($name) !== null; } /** @return array */ public function getDefaultProperties() : array { return array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionProperty $property) { return $property->getDefaultValue(); }, $this->getProperties()); } /** @return non-empty-string|null */ public function getFileName() : ?string { return $this->locatedSource->getFileName(); } public function getLocatedSource() : LocatedSource { return $this->locatedSource; } /** * Get the line number that this class starts on. * * @return positive-int */ public function getStartLine() : int { return $this->startLine; } /** * Get the line number that this class ends on. * * @return positive-int */ public function getEndLine() : int { return $this->endLine; } /** @return positive-int */ public function getStartColumn() : int { return $this->startColumn; } /** @return positive-int */ public function getEndColumn() : int { return $this->endColumn; } /** * Get the parent class, if it is defined. */ public function getParentClass() : ?\PHPStan\BetterReflection\Reflection\ReflectionClass { $parentClassName = $this->getParentClassName(); if ($parentClassName === null) { return null; } if ($this->name === $parentClassName) { throw CircularReference::fromClassName($parentClassName); } try { return $this->reflector->reflectClass($parentClassName); } catch (IdentifierNotFound $exception) { return null; } } /** * Gets the parent class names. * * @return list A numerical array with parent class names as the values. */ public function getParentClassNames() : array { return array_map(static function (self $parentClass) : string { return $parentClass->getName(); }, $this->getParentClasses()); } /** @return list */ private function getParentClasses() : array { if ($this->cachedParentClasses === null) { $parentClasses = []; $parentClassName = $this->parentClassName; while ($parentClassName !== null) { try { $parentClass = $this->reflector->reflectClass($parentClassName); } catch (IdentifierNotFound $exception) { break; } if ($this->name === $parentClassName || array_key_exists($parentClassName, $parentClasses)) { throw CircularReference::fromClassName($parentClassName); } $parentClasses[$parentClassName] = $parentClass; $parentClassName = $parentClass->parentClassName; } $this->cachedParentClasses = array_values($parentClasses); } return $this->cachedParentClasses; } /** @return non-empty-string|null */ public function getDocComment() : ?string { return $this->docComment; } public function isAnonymous() : bool { return $this->name === null; } /** * Is this an internal class? */ public function isInternal() : bool { return $this->locatedSource->isInternal(); } /** * Is this a user-defined function (will always return the opposite of * whatever isInternal returns). */ public function isUserDefined() : bool { return !$this->isInternal(); } public function isDeprecated() : bool { return AnnotationHelper::isDeprecated($this->docComment); } /** * Is this class an abstract class. */ public function isAbstract() : bool { return ($this->modifiers & CoreReflectionClass::IS_EXPLICIT_ABSTRACT) === CoreReflectionClass::IS_EXPLICIT_ABSTRACT; } /** * Is this class a final class. */ public function isFinal() : bool { if ($this->isEnum) { return \true; } return ($this->modifiers & CoreReflectionClass::IS_FINAL) === CoreReflectionClass::IS_FINAL; } public function isReadOnly() : bool { return ($this->modifiers & ReflectionClassAdapter::IS_READONLY_COMPATIBILITY) === ReflectionClassAdapter::IS_READONLY_COMPATIBILITY; } /** * Get the core-reflection-compatible modifier values. * * @return int-mask-of */ public function getModifiers() : int { return $this->modifiers; } /** @return int-mask-of * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node */ private function computeModifiers($node) : int { if (!$node instanceof ClassNode) { return 0; } $modifiers = $node->isAbstract() ? CoreReflectionClass::IS_EXPLICIT_ABSTRACT : 0; $modifiers += $node->isFinal() ? CoreReflectionClass::IS_FINAL : 0; $modifiers += $node->isReadonly() ? ReflectionClassAdapter::IS_READONLY_COMPATIBILITY : 0; return $modifiers; } /** * Is this reflection a trait? */ public function isTrait() : bool { return $this->isTrait; } /** * Is this reflection an interface? */ public function isInterface() : bool { return $this->isInterface; } /** * Get the traits used, if any are defined. If this class does not have any * defined traits, this will return an empty array. * * @return list */ public function getTraits() : array { if ($this->cachedTraits !== null) { return $this->cachedTraits; } $traits = []; foreach ($this->traitClassNames as $traitClassName) { try { $traits[] = $this->reflector->reflectClass($traitClassName); } catch (IdentifierNotFound $exception) { // pass } } return $this->cachedTraits = $traits; } /** * @param array $interfaces * * @return array */ private function addStringableInterface(array $interfaces) : array { if (BetterReflection::$phpVersion < 80000) { return $interfaces; } /** @psalm-var class-string $stringableClassName */ $stringableClassName = Stringable::class; if (array_key_exists($stringableClassName, $interfaces) || $this->isInterface && $this->getName() === $stringableClassName) { return $interfaces; } foreach (array_keys($this->immediateMethods) as $immediateMethodName) { if (strtolower($immediateMethodName) === '__tostring') { try { $stringableInterfaceReflection = $this->reflector->reflectClass($stringableClassName); $interfaces[$stringableClassName] = $stringableInterfaceReflection; } catch (IdentifierNotFound $exception) { // Stringable interface does not exist on target PHP version } // @infection-ignore-all Break_: There's no difference between break and continue - break is just optimization break; } } return $interfaces; } /** * @param array $interfaces * * @return array * * @psalm-suppress MoreSpecificReturnType */ private function addEnumInterfaces(array $interfaces) : array { assert($this->isEnum === \true); $interfaces[UnitEnum::class] = $this->reflector->reflectClass(UnitEnum::class); if ($this->isBackedEnum) { $interfaces[BackedEnum::class] = $this->reflector->reflectClass(BackedEnum::class); } /** @psalm-suppress LessSpecificReturnStatement */ return $interfaces; } /** @return list */ public function getTraitClassNames() : array { return $this->traitClassNames; } /** * Get the names of the traits used as an array of strings, if any are * defined. If this class does not have any defined traits, this will * return an empty array. * * @return list */ public function getTraitNames() : array { return array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionClass $trait) : string { /** @psalm-var trait-string $traitName */ $traitName = $trait->getName(); return $traitName; }, $this->getTraits()); } /** * Return a list of the aliases used when importing traits for this class. * The returned array is in key/value pair in this format:. * * 'aliasedMethodName' => 'ActualClass::actualMethod' * * @return array * * @example * // When reflecting a class such as: * class Foo * { * use MyTrait { * myTraitMethod as myAliasedMethod; * } * } * // This method would return * // ['myAliasedMethod' => 'MyTrait::myTraitMethod'] */ public function getTraitAliases() : array { return $this->traitsData['aliases']; } /** * Returns data when importing traits for this class: * * 'aliases': List of the aliases used when importing traits. In format: * * 'aliasedMethodName' => 'ActualClass::actualMethod' * * Example: * // When reflecting a code such as: * * use MyTrait { * myTraitMethod as myAliasedMethod; * } * * // This method would return * // ['myAliasedMethod' => 'MyTrait::myTraitMethod'] * * 'modifiers': Used modifiers when importing traits. In format: * * 'methodName' => 'modifier' * * Example: * // When reflecting a code such as: * * use MyTrait { * myTraitMethod as public; * } * * // This method would return * // ['myTraitMethod' => 1] * * 'precedences': Precedences used when importing traits. In format: * * 'Class::method' => 'Class::method' * * Example: * // When reflecting a code such as: * * use MyTrait, MyTrait2 { * MyTrait2::foo insteadof MyTrait1; * } * * // This method would return * // ['MyTrait1::foo' => 'MyTrait2::foo'] * * @return array{aliases: array, modifiers: array>, precedences: array} * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node */ private function computeTraitsData($node) : array { $traitsData = ['aliases' => [], 'modifiers' => [], 'precedences' => []]; foreach ($node->getTraitUses() as $traitUsage) { $traitNames = $traitUsage->traits; $adaptations = $traitUsage->adaptations; foreach ($adaptations as $adaptation) { $usedTrait = $adaptation->trait; if ($usedTrait === null) { $usedTrait = end($traitNames); } $methodHash = $this->methodHash($usedTrait->toString(), $adaptation->method->toString()); if ($adaptation instanceof Node\Stmt\TraitUseAdaptation\Alias) { if ($adaptation->newModifier !== null) { /** @var int-mask-of $modifier */ $modifier = $adaptation->newModifier; $traitsData['modifiers'][$methodHash] = $modifier; } if ($adaptation->newName) { $adaptationName = $adaptation->newName->name; assert($adaptationName !== ''); $traitsData['aliases'][$adaptationName] = $methodHash; continue; } } if (!$adaptation instanceof Node\Stmt\TraitUseAdaptation\Precedence || !$adaptation->insteadof) { continue; } foreach ($adaptation->insteadof as $insteadof) { $adaptationNameHash = $this->methodHash($insteadof->toString(), $adaptation->method->toString()); $traitsData['precedences'][$adaptationNameHash] = $methodHash; } } } return $traitsData; } /** * @return non-empty-string * * @psalm-pure */ private function methodHash(string $className, string $methodName) : string { return sprintf('%s::%s', $className, strtolower($methodName)); } /** @return list */ public function getInterfaceClassNames() : array { return $this->implementsClassNames; } /** * Gets the interfaces. * * @link https://php.net/manual/en/reflectionclass.getinterfaces.php * * @return array An associative array of interfaces, with keys as interface names and the array * values as {@see ReflectionClass} objects. */ public function getInterfaces() : array { if ($this->cachedInterfaces !== null) { return $this->cachedInterfaces; } $interfaces = array_merge([$this->getCurrentClassImplementedInterfacesIndexedByName()], array_map(static function (self $parentClass) : array { return $parentClass->getCurrentClassImplementedInterfacesIndexedByName(); }, $this->getParentClasses())); return $this->cachedInterfaces = array_merge(...array_reverse($interfaces)); } /** * Get only the interfaces that this class implements (i.e. do not search * up parent classes etc.) * * @return array */ public function getImmediateInterfaces() : array { if ($this->isTrait) { return []; } $interfaces = []; foreach ($this->implementsClassNames as $interfaceClassName) { try { $interfaces[$interfaceClassName] = $this->reflector->reflectClass($interfaceClassName); } catch (IdentifierNotFound $exception) { continue; } } if ($this->isEnum) { $interfaces = $this->addEnumInterfaces($interfaces); } return $this->addStringableInterface($interfaces); } /** * Gets the interface names. * * @link https://php.net/manual/en/reflectionclass.getinterfacenames.php * * @return list A numerical array with interface names as the values. */ public function getInterfaceNames() : array { if ($this->cachedInterfaceNames !== null) { return $this->cachedInterfaceNames; } return $this->cachedInterfaceNames = array_values(array_map(static function (self $interface) : string { return $interface->getName(); }, $this->getInterfaces())); } /** * Checks whether the given object is an instance. * * @link https://php.net/manual/en/reflectionclass.isinstance.php */ public function isInstance(object $object) : bool { $className = $this->getName(); // note: since $object was loaded, we can safely assume that $className is available in the current // php script execution context return $object instanceof $className; } /** * Checks whether the given class string is a subclass of this class. * * @link https://php.net/manual/en/reflectionclass.isinstance.php */ public function isSubclassOf(string $className) : bool { return in_array(ltrim($className, '\\'), $this->getParentClassNames(), \true); } /** * Checks whether this class implements the given interface. * * @link https://php.net/manual/en/reflectionclass.implementsinterface.php */ public function implementsInterface(string $interfaceName) : bool { return in_array(ltrim($interfaceName, '\\'), $this->getInterfaceNames(), \true); } /** * Checks whether this reflection is an instantiable class * * @link https://php.net/manual/en/reflectionclass.isinstantiable.php */ public function isInstantiable() : bool { // @TODO doesn't consider internal non-instantiable classes yet. if ($this->isAbstract()) { return \false; } if ($this->isInterface()) { return \false; } if ($this->isTrait()) { return \false; } $constructor = $this->getConstructor(); if ($constructor === null) { return \true; } return $constructor->isPublic(); } /** * Checks whether this is a reflection of a class that supports the clone operator * * @link https://php.net/manual/en/reflectionclass.iscloneable.php */ public function isCloneable() : bool { if (!$this->isInstantiable()) { return \false; } $cloneMethod = $this->getMethod('__clone'); if ($cloneMethod === null) { return \true; } return $cloneMethod->isPublic(); } /** * Checks if iterateable * * @link https://php.net/manual/en/reflectionclass.isiterateable.php */ public function isIterateable() : bool { return $this->isInstantiable() && $this->implementsInterface(Traversable::class); } public function isEnum() : bool { return $this->isEnum; } /** @return array */ private function getCurrentClassImplementedInterfacesIndexedByName() : array { if ($this->isTrait) { return []; } if ($this->isInterface) { // assumption: first key is the current interface return array_slice($this->getInterfacesHierarchy(AlreadyVisitedClasses::createEmpty()), 1); } $interfaces = []; foreach ($this->implementsClassNames as $name) { try { $interface = $this->reflector->reflectClass($name); foreach ($interface->getInterfacesHierarchy(AlreadyVisitedClasses::createEmpty()) as $n => $i) { $interfaces[$n] = $i; } } catch (IdentifierNotFound $exception) { continue; } } if ($this->isEnum) { $interfaces = $this->addEnumInterfaces($interfaces); } return $this->addStringableInterface($interfaces); } /** * This method allows us to retrieve all interfaces parent of this interface. Do not use on class nodes! * * @return array parent interfaces of this interface */ private function getInterfacesHierarchy(AlreadyVisitedClasses $alreadyVisitedClasses) : array { if (!$this->isInterface) { return []; } $interfaceClassName = $this->getName(); $alreadyVisitedClasses->push($interfaceClassName); /** @var array $interfaces */ $interfaces = [$interfaceClassName => $this]; foreach ($this->getImmediateInterfaces() as $interface) { $alreadyVisitedClassesCopyForInterface = clone $alreadyVisitedClasses; foreach ($interface->getInterfacesHierarchy($alreadyVisitedClassesCopyForInterface) as $extendedInterfaceName => $extendedInterface) { $interfaces[$extendedInterfaceName] = $extendedInterface; } } return $this->addStringableInterface($interfaces); } /** * Get the value of a static property, if it exists. Throws a * PropertyDoesNotExist exception if it does not exist or is not static. * (note, differs very slightly from internal reflection behaviour) * * @param non-empty-string $propertyName * * @throws ClassDoesNotExist * @throws NoObjectProvided * @throws NotAnObject * @throws ObjectNotInstanceOfClass * @return mixed */ public function getStaticPropertyValue(string $propertyName) { $property = $this->getProperty($propertyName); if (!$property || !$property->isStatic()) { throw PropertyDoesNotExist::fromName($propertyName); } return $property->getValue(); } /** * Set the value of a static property * * @param non-empty-string $propertyName * * @throws ClassDoesNotExist * @throws NoObjectProvided * @throws NotAnObject * @throws ObjectNotInstanceOfClass * @param mixed $value */ public function setStaticPropertyValue(string $propertyName, $value) : void { $property = $this->getProperty($propertyName); if (!$property || !$property->isStatic()) { throw PropertyDoesNotExist::fromName($propertyName); } $property->setValue($value); } /** @return array */ public function getStaticProperties() : array { $staticProperties = []; foreach ($this->getProperties() as $property) { if (!$property->isStatic()) { continue; } /** @psalm-suppress MixedAssignment */ $staticProperties[$property->getName()] = $property->getValue(); } return $staticProperties; } /** @return list */ public function getAttributes() : array { return $this->attributes; } /** @return list */ public function getAttributesByName(string $name) : array { return ReflectionAttributeHelper::filterAttributesByName($this->getAttributes(), $name); } /** * @param class-string $className * * @return list */ public function getAttributesByInstance(string $className) : array { return ReflectionAttributeHelper::filterAttributesByInstance($this->getAttributes(), $className); } } reflector = $reflector; $this->reflectionClass = $reflectionClass; $this->object = $object; } /** * Pass an instance of an object to this method to reflect it * * @throws ReflectionException * @throws IdentifierNotFound */ public static function createFromInstance(object $instance) : \PHPStan\BetterReflection\Reflection\ReflectionClass { $className = \get_class($instance); $betterReflection = new BetterReflection(); if (preg_match(\PHPStan\BetterReflection\Reflection\ReflectionClass::ANONYMOUS_CLASS_NAME_PREFIX_REGEXP, $className) === 1) { $reflector = new DefaultReflector(new AggregateSourceLocator([$betterReflection->sourceLocator(), new AnonymousClassObjectSourceLocator($instance, $betterReflection->phpParser())])); } else { $reflector = $betterReflection->reflector(); } return new self($reflector, $reflector->reflectClass($className), $instance); } /** * Reflect on runtime properties for the current instance * * @see ReflectionClass::getProperties() for the usage of $filter * * @param int-mask-of $filter * * @return array */ private function getRuntimeProperties(int $filter = 0) : array { if (!$this->reflectionClass->isInstance($this->object)) { throw new InvalidArgumentException('Cannot reflect runtime properties of a separate class'); } if ($filter !== 0 && !($filter & CoreReflectionProperty::IS_PUBLIC)) { return []; } // Ensure we have already cached existing properties so we can add to them $this->reflectionClass->getProperties(); // Only known current way is to use internal ReflectionObject to get // the runtime-declared properties :/ $reflectionProperties = (new CoreReflectionObject($this->object))->getProperties(); $runtimeProperties = []; foreach ($reflectionProperties as $property) { $propertyName = $property->getName(); if ($this->reflectionClass->hasProperty($propertyName)) { continue; } $propertyNode = $this->createPropertyNodeFromRuntimePropertyReflection($property, $this->object); $runtimeProperties[$propertyName] = \PHPStan\BetterReflection\Reflection\ReflectionProperty::createFromNode($this->reflector, $propertyNode, $propertyNode->props[0], $this, $this, \false, \false); } return $runtimeProperties; } /** * Create an AST PropertyNode given a reflection * * Note that we don't copy across DocBlock, protected, private or static * because runtime properties can't have these attributes. */ private function createPropertyNodeFromRuntimePropertyReflection(CoreReflectionProperty $property, object $instance) : PropertyNode { $builder = new PropertyNodeBuilder($property->getName()); $builder->setDefault($property->getValue($instance)); $builder->makePublic(); return $builder->getNode(); } public function getShortName() : string { return $this->reflectionClass->getShortName(); } public function getName() : string { return $this->reflectionClass->getName(); } public function getNamespaceName() : ?string { return $this->reflectionClass->getNamespaceName(); } public function inNamespace() : bool { return $this->reflectionClass->inNamespace(); } /** @return non-empty-string|null */ public function getExtensionName() : ?string { return $this->reflectionClass->getExtensionName(); } /** * {@inheritDoc} */ public function getMethods(int $filter = 0) : array { return $this->reflectionClass->getMethods($filter); } /** * {@inheritDoc} */ public function getImmediateMethods(int $filter = 0) : array { return $this->reflectionClass->getImmediateMethods($filter); } /** @param non-empty-string $methodName */ public function getMethod(string $methodName) : ?\PHPStan\BetterReflection\Reflection\ReflectionMethod { return $this->reflectionClass->getMethod($methodName); } /** @param non-empty-string $methodName */ public function hasMethod(string $methodName) : bool { return $this->reflectionClass->hasMethod($methodName); } /** * {@inheritDoc} */ public function getImmediateConstants(int $filter = 0) : array { return $this->reflectionClass->getImmediateConstants($filter); } /** * {@inheritDoc} */ public function getConstants(int $filter = 0) : array { return $this->reflectionClass->getConstants($filter); } public function hasConstant(string $name) : bool { return $this->reflectionClass->hasConstant($name); } public function getConstant(string $name) : ?\PHPStan\BetterReflection\Reflection\ReflectionClassConstant { return $this->reflectionClass->getConstant($name); } public function getConstructor() : ?\PHPStan\BetterReflection\Reflection\ReflectionMethod { return $this->reflectionClass->getConstructor(); } /** * {@inheritDoc} */ public function getProperties(int $filter = 0) : array { return array_merge($this->reflectionClass->getProperties($filter), $this->getRuntimeProperties($filter)); } /** * {@inheritDoc} */ public function getImmediateProperties(int $filter = 0) : array { return array_merge($this->reflectionClass->getImmediateProperties($filter), $this->getRuntimeProperties($filter)); } public function getProperty(string $name) : ?\PHPStan\BetterReflection\Reflection\ReflectionProperty { $runtimeProperties = $this->getRuntimeProperties(); if (isset($runtimeProperties[$name])) { return $runtimeProperties[$name]; } return $this->reflectionClass->getProperty($name); } public function hasProperty(string $name) : bool { $runtimeProperties = $this->getRuntimeProperties(); return isset($runtimeProperties[$name]) || $this->reflectionClass->hasProperty($name); } /** * {@inheritDoc} */ public function getDefaultProperties() : array { return array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionProperty $property) { return $property->getDefaultValue(); }, array_filter($this->getProperties(), static function (\PHPStan\BetterReflection\Reflection\ReflectionProperty $property) : bool { return $property->isDefault(); })); } /** @return non-empty-string|null */ public function getFileName() : ?string { return $this->reflectionClass->getFileName(); } public function getLocatedSource() : LocatedSource { return $this->reflectionClass->getLocatedSource(); } public function getStartLine() : int { return $this->reflectionClass->getStartLine(); } public function getEndLine() : int { return $this->reflectionClass->getEndLine(); } public function getStartColumn() : int { return $this->reflectionClass->getStartColumn(); } public function getEndColumn() : int { return $this->reflectionClass->getEndColumn(); } public function getParentClass() : ?\PHPStan\BetterReflection\Reflection\ReflectionClass { return $this->reflectionClass->getParentClass(); } /** @return class-string|null */ public function getParentClassName() : ?string { return $this->reflectionClass->getParentClassName(); } /** * {@inheritDoc} */ public function getParentClassNames() : array { return $this->reflectionClass->getParentClassNames(); } /** @return non-empty-string|null */ public function getDocComment() : ?string { return $this->reflectionClass->getDocComment(); } public function isAnonymous() : bool { return $this->reflectionClass->isAnonymous(); } public function isInternal() : bool { return $this->reflectionClass->isInternal(); } public function isUserDefined() : bool { return $this->reflectionClass->isUserDefined(); } public function isDeprecated() : bool { return $this->reflectionClass->isDeprecated(); } public function isAbstract() : bool { return $this->reflectionClass->isAbstract(); } public function isFinal() : bool { return $this->reflectionClass->isFinal(); } public function isReadOnly() : bool { return $this->reflectionClass->isReadOnly(); } public function getModifiers() : int { return $this->reflectionClass->getModifiers(); } public function isTrait() : bool { return $this->reflectionClass->isTrait(); } public function isInterface() : bool { return $this->reflectionClass->isInterface(); } /** * {@inheritDoc} */ public function getTraitClassNames() : array { return $this->reflectionClass->getTraitClassNames(); } /** * {@inheritDoc} */ public function getTraits() : array { return $this->reflectionClass->getTraits(); } /** * {@inheritDoc} */ public function getTraitNames() : array { return $this->reflectionClass->getTraitNames(); } /** * {@inheritDoc} */ public function getTraitAliases() : array { return $this->reflectionClass->getTraitAliases(); } /** * {@inheritDoc} */ public function getInterfaceClassNames() : array { return $this->reflectionClass->getInterfaceClassNames(); } /** * {@inheritDoc} */ public function getInterfaces() : array { return $this->reflectionClass->getInterfaces(); } /** * {@inheritDoc} */ public function getImmediateInterfaces() : array { return $this->reflectionClass->getImmediateInterfaces(); } /** * {@inheritDoc} */ public function getInterfaceNames() : array { return $this->reflectionClass->getInterfaceNames(); } public function isInstance(object $object) : bool { return $this->reflectionClass->isInstance($object); } public function isSubclassOf(string $className) : bool { return $this->reflectionClass->isSubclassOf($className); } public function implementsInterface(string $interfaceName) : bool { return $this->reflectionClass->implementsInterface($interfaceName); } public function isInstantiable() : bool { return $this->reflectionClass->isInstantiable(); } public function isCloneable() : bool { return $this->reflectionClass->isCloneable(); } public function isIterateable() : bool { return $this->reflectionClass->isIterateable(); } public function isEnum() : bool { return $this->reflectionClass->isEnum(); } /** * {@inheritDoc} */ public function getStaticProperties() : array { return $this->reflectionClass->getStaticProperties(); } /** * @param mixed $value */ public function setStaticPropertyValue(string $propertyName, $value) : void { $this->reflectionClass->setStaticPropertyValue($propertyName, $value); } /** * @return mixed */ public function getStaticPropertyValue(string $propertyName) { return $this->reflectionClass->getStaticPropertyValue($propertyName); } /** @return list */ public function getAttributes() : array { return $this->reflectionClass->getAttributes(); } /** @return list */ public function getAttributesByName(string $name) : array { return $this->reflectionClass->getAttributesByName($name); } /** * @param class-string $className * * @return list */ public function getAttributesByInstance(string $className) : array { return $this->reflectionClass->getAttributesByInstance($className); } } $value */ $value = $constantReflection->getValue(); return sprintf("Constant [ %s%s %s %s ] { %s }\n", $constantReflection->isFinal() ? 'final ' : '', self::visibilityToString($constantReflection), gettype($value), $constantReflection->getName(), is_array($value) ? 'Array' : (string) $value); } /** @psalm-pure */ private static function visibilityToString(ReflectionClassConstant $constantReflection) : string { if ($constantReflection->isProtected()) { return 'protected'; } if ($constantReflection->isPrivate()) { return 'private'; } return 'public'; } } isStatic()) { $stateModifier = $propertyReflection->isDefault() ? ' ' : ' '; } $type = $propertyReflection->getType(); return sprintf('Property [%s %s%s%s%s $%s ]', $stateModifier, self::visibilityToString($propertyReflection), $propertyReflection->isStatic() ? ' static' : '', $propertyReflection->isReadOnly() ? ' readonly' : '', $type !== null ? sprintf(' %s', \PHPStan\BetterReflection\Reflection\StringCast\ReflectionTypeStringCast::toString($type)) : '', $propertyReflection->getName()); } /** @psalm-pure */ private static function visibilityToString(ReflectionProperty $propertyReflection) : string { if ($propertyReflection->isProtected()) { return 'protected'; } if ($propertyReflection->isPrivate()) { return 'private'; } return 'public'; } } getArguments(); $argumentsFormat = $arguments !== [] ? " {\n - Arguments [%d] {%s\n }\n}" : ''; return sprintf('Attribute [ %s ]' . $argumentsFormat . "\n", $attributeReflection->getName(), count($arguments), self::argumentsToString($arguments)); } /** * @param array $arguments * * @psalm-pure */ private static function argumentsToString(array $arguments) : string { if ($arguments === []) { return ''; } $string = ''; $argumentNo = 0; /** @psalm-suppress MixedAssignment */ foreach ($arguments as $argumentName => $argumentValue) { $string .= sprintf("\n Argument #%d [ %s%s ]", $argumentNo, is_string($argumentName) ? sprintf('%s = ', $argumentName) : '', self::argumentValueToString($argumentValue)); $argumentNo++; } return $string; } /** @psalm-pure * @param mixed $value */ private static function argumentValueToString($value) : string { if (is_array($value)) { return 'Array'; } if (is_string($value) && strlen($value) > 15) { return var_export(substr($value, 0, 15) . '...', \true); } return var_export($value, \true); } } %s%s%s %s%s%s ] {\n"; $format .= "%s\n"; $format .= " - Constants [%d] {%s\n }\n\n"; $format .= " - Static properties [%d] {%s\n }\n\n"; $format .= " - Static methods [%d] {%s\n }\n\n"; $format .= " - Properties [%d] {%s\n }\n\n"; $format .= $isObject ? " - Dynamic properties [%d] {%s\n }\n\n" : '%s%s'; $format .= " - Methods [%d] {%s\n }\n"; $format .= "}\n"; $type = self::typeToString($classReflection); $constants = $classReflection->getConstants(); $enumCases = $classReflection instanceof ReflectionEnum ? $classReflection->getCases() : []; $staticProperties = self::getStaticProperties($classReflection); $staticMethods = self::getStaticMethods($classReflection); $defaultProperties = self::getDefaultProperties($classReflection); $dynamicProperties = self::getDynamicProperties($classReflection); $methods = self::getMethods($classReflection); return sprintf($format, $isObject ? 'Object of class' : $type, self::sourceToString($classReflection), $classReflection->isFinal() ? 'final ' : '', $classReflection->isAbstract() ? 'abstract ' : '', strtolower($type), $classReflection->getName(), self::extendsToString($classReflection), self::implementsToString($classReflection), self::fileAndLinesToString($classReflection), count($constants) + count($enumCases), self::constantsToString($constants, $enumCases), count($staticProperties), self::propertiesToString($staticProperties), count($staticMethods), self::methodsToString($staticMethods), count($defaultProperties), self::propertiesToString($defaultProperties), $isObject ? count($dynamicProperties) : '', $isObject ? self::propertiesToString($dynamicProperties) : '', count($methods), self::methodsToString($methods, 2)); } /** @psalm-pure */ private static function typeToString(ReflectionClass $classReflection) : string { if ($classReflection->isInterface()) { return 'Interface'; } if ($classReflection->isTrait()) { return 'Trait'; } return 'Class'; } /** @psalm-pure */ private static function sourceToString(ReflectionClass $classReflection) : string { if ($classReflection->isUserDefined()) { return 'user'; } $extensionName = $classReflection->getExtensionName(); assert(is_string($extensionName)); return sprintf('internal:%s', $extensionName); } /** @psalm-pure */ private static function extendsToString(ReflectionClass $classReflection) : string { $parentClass = $classReflection->getParentClass(); if ($parentClass === null) { return ''; } return ' extends ' . $parentClass->getName(); } /** @psalm-pure */ private static function implementsToString(ReflectionClass $classReflection) : string { $interfaceNames = $classReflection->getInterfaceNames(); if ($interfaceNames === []) { return ''; } return ' implements ' . implode(', ', $interfaceNames); } /** @psalm-pure */ private static function fileAndLinesToString(ReflectionClass $classReflection) : string { if ($classReflection->isInternal()) { return ''; } $fileName = $classReflection->getFileName(); if ($fileName === null) { return ''; } return sprintf(" @@ %s %d-%d\n", $fileName, $classReflection->getStartLine(), $classReflection->getEndLine()); } /** * @param array $constants * @param array $enumCases * * @psalm-pure */ private static function constantsToString(array $constants, array $enumCases) : string { if ($constants === [] && $enumCases === []) { return ''; } $items = array_map(static function (ReflectionEnumCase $enumCaseReflection) : string { return trim(\PHPStan\BetterReflection\Reflection\StringCast\ReflectionEnumCaseStringCast::toString($enumCaseReflection)); }, $enumCases) + array_map(static function (ReflectionClassConstant $constantReflection) : string { return trim(\PHPStan\BetterReflection\Reflection\StringCast\ReflectionClassConstantStringCast::toString($constantReflection)); }, $constants); return self::itemsToString($items); } /** * @param array $properties * * @psalm-pure */ private static function propertiesToString(array $properties) : string { if ($properties === []) { return ''; } return self::itemsToString(array_map(static function (ReflectionProperty $propertyReflection) : string { return \PHPStan\BetterReflection\Reflection\StringCast\ReflectionPropertyStringCast::toString($propertyReflection); }, $properties)); } /** * @param array $methods * * @psalm-pure */ private static function methodsToString(array $methods, int $emptyLinesAmongItems = 1) : string { if ($methods === []) { return ''; } return self::itemsToString(array_map(static function (ReflectionMethod $method) : string { return \PHPStan\BetterReflection\Reflection\StringCast\ReflectionMethodStringCast::toString($method); }, $methods), $emptyLinesAmongItems); } /** * @param array $items * * @psalm-pure */ private static function itemsToString(array $items, int $emptyLinesAmongItems = 1) : string { $string = implode(str_repeat("\n", $emptyLinesAmongItems), $items); return "\n" . preg_replace('/(^|\\n)(?!\\n)/', '\\1' . self::indent(), $string); } /** @psalm-pure */ private static function indent() : string { return str_repeat(' ', 4); } /** * @return array * * @psalm-pure */ private static function getStaticProperties(ReflectionClass $classReflection) : array { return array_filter($classReflection->getProperties(), static function (ReflectionProperty $propertyReflection) : bool { return $propertyReflection->isStatic(); }); } /** * @return array * * @psalm-pure */ private static function getStaticMethods(ReflectionClass $classReflection) : array { return array_filter($classReflection->getMethods(), static function (ReflectionMethod $methodReflection) : bool { return $methodReflection->isStatic(); }); } /** * @return array * * @psalm-pure */ private static function getDefaultProperties(ReflectionClass $classReflection) : array { return array_filter($classReflection->getProperties(), static function (ReflectionProperty $propertyReflection) : bool { return !$propertyReflection->isStatic() && $propertyReflection->isDefault(); }); } /** * @return array * * @psalm-pure */ private static function getDynamicProperties(ReflectionClass $classReflection) : array { return array_filter($classReflection->getProperties(), static function (ReflectionProperty $propertyReflection) : bool { return !$propertyReflection->isStatic() && !$propertyReflection->isDefault(); }); } /** * @return array * * @psalm-pure */ private static function getMethods(ReflectionClass $classReflection) : array { return array_filter($classReflection->getMethods(), static function (ReflectionMethod $methodReflection) : bool { return !$methodReflection->isStatic(); }); } } getNumberOfParameters() > 0 || $methodReflection->hasReturnType() ? "\n\n - Parameters [%d] {%s\n }" : ''; $returnTypeFormat = $methodReflection->hasReturnType() ? "\n - Return [ %s ]" : ''; return sprintf('Method [ <%s%s%s%s%s%s>%s%s%s %s method %s ] {%s' . $parametersFormat . $returnTypeFormat . "\n}", self::sourceToString($methodReflection), $methodReflection->isConstructor() ? ', ctor' : '', $methodReflection->isDestructor() ? ', dtor' : '', self::overwritesToString($methodReflection), self::inheritsToString($methodReflection), self::prototypeToString($methodReflection), $methodReflection->isFinal() ? ' final' : '', $methodReflection->isStatic() ? ' static' : '', $methodReflection->isAbstract() ? ' abstract' : '', self::visibilityToString($methodReflection), $methodReflection->getName(), self::fileAndLinesToString($methodReflection), count($methodReflection->getParameters()), self::parametersToString($methodReflection), self::returnTypeToString($methodReflection)); } /** @psalm-pure */ private static function sourceToString(ReflectionMethod $methodReflection) : string { if ($methodReflection->isUserDefined()) { return 'user'; } $extensionName = $methodReflection->getExtensionName(); assert(is_string($extensionName)); return sprintf('internal:%s', $extensionName); } /** @psalm-pure */ private static function overwritesToString(ReflectionMethod $methodReflection) : string { $parentClass = $methodReflection->getDeclaringClass()->getParentClass(); if ($parentClass === null) { return ''; } if (!$parentClass->hasMethod($methodReflection->getName())) { return ''; } return sprintf(', overwrites %s', $parentClass->getName()); } /** @psalm-pure */ private static function inheritsToString(ReflectionMethod $methodReflection) : string { if ($methodReflection->getDeclaringClass() === $methodReflection->getCurrentClass()) { return ''; } return sprintf(', inherits %s', $methodReflection->getDeclaringClass()->getName()); } /** @psalm-pure */ private static function prototypeToString(ReflectionMethod $methodReflection) : string { try { return sprintf(', prototype %s', $methodReflection->getPrototype()->getDeclaringClass()->getName()); } catch (MethodPrototypeNotFound $exception) { return ''; } } /** @psalm-pure */ private static function visibilityToString(ReflectionMethod $methodReflection) : string { if ($methodReflection->isProtected()) { return 'protected'; } if ($methodReflection->isPrivate()) { return 'private'; } return 'public'; } /** @psalm-pure */ private static function fileAndLinesToString(ReflectionMethod $methodReflection) : string { if ($methodReflection->isInternal()) { return ''; } $fileName = $methodReflection->getFileName(); assert(is_string($fileName)); return sprintf("\n @@ %s %d - %d", $fileName, $methodReflection->getStartLine(), $methodReflection->getEndLine()); } /** @psalm-pure */ private static function parametersToString(ReflectionMethod $methodReflection) : string { return array_reduce($methodReflection->getParameters(), static function (string $string, ReflectionParameter $parameterReflection) : string { return $string . "\n " . \PHPStan\BetterReflection\Reflection\StringCast\ReflectionParameterStringCast::toString($parameterReflection); }, ''); } /** @psalm-pure */ private static function returnTypeToString(ReflectionMethod $methodReflection) : string { $type = $methodReflection->getReturnType(); if ($type === null) { return ''; } return \PHPStan\BetterReflection\Reflection\StringCast\ReflectionTypeStringCast::toString($type); } } $value */ $value = $constantReflection->getValue(); if (is_object($value)) { $valueAsString = 'Object'; } elseif (is_array($value)) { $valueAsString = 'Array'; } else { $valueAsString = (string) $value; } return sprintf('Constant [ <%s> %s %s ] {%s %s }', self::sourceToString($constantReflection), gettype($value), $constantReflection->getName(), self::fileAndLinesToString($constantReflection), $valueAsString); } /** @psalm-pure */ private static function sourceToString(ReflectionConstant $constantReflection) : string { if ($constantReflection->isUserDefined()) { return 'user'; } $extensionName = $constantReflection->getExtensionName(); assert(is_string($extensionName)); return sprintf('internal:%s', $extensionName); } /** @psalm-pure */ private static function fileAndLinesToString(ReflectionConstant $constantReflection) : string { if ($constantReflection->isInternal()) { return ''; } $fileName = $constantReflection->getFileName(); if ($fileName === null) { return ''; } return sprintf("\n @@ %s %d - %d\n", $fileName, $constantReflection->getStartLine(), $constantReflection->getEndLine()); } } getNumberOfParameters() > 0 || $functionReflection->hasReturnType() ? "\n\n - Parameters [%d] {%s\n }" : ''; $returnTypeFormat = $functionReflection->hasReturnType() ? "\n - Return [ %s ]" : ''; return sprintf('Function [ <%s> function %s ] {%s' . $parametersFormat . $returnTypeFormat . "\n}", self::sourceToString($functionReflection), $functionReflection->getName(), self::fileAndLinesToString($functionReflection), count($functionReflection->getParameters()), self::parametersToString($functionReflection), self::returnTypeToString($functionReflection)); } /** @psalm-pure */ private static function sourceToString(ReflectionFunction $functionReflection) : string { if ($functionReflection->isUserDefined()) { return 'user'; } $extensionName = $functionReflection->getExtensionName(); assert(is_string($extensionName)); return sprintf('internal:%s', $extensionName); } /** @psalm-pure */ private static function fileAndLinesToString(ReflectionFunction $functionReflection) : string { if ($functionReflection->isInternal()) { return ''; } $fileName = $functionReflection->getFileName(); if ($fileName === null) { return ''; } return sprintf("\n @@ %s %d - %d", $fileName, $functionReflection->getStartLine(), $functionReflection->getEndLine()); } /** @psalm-pure */ private static function parametersToString(ReflectionFunction $functionReflection) : string { return array_reduce($functionReflection->getParameters(), static function (string $string, ReflectionParameter $parameterReflection) : string { return $string . "\n " . \PHPStan\BetterReflection\Reflection\StringCast\ReflectionParameterStringCast::toString($parameterReflection); }, ''); } /** @psalm-pure */ private static function returnTypeToString(ReflectionFunction $methodReflection) : string { $type = $methodReflection->getReturnType(); if ($type === null) { return ''; } return \PHPStan\BetterReflection\Reflection\StringCast\ReflectionTypeStringCast::toString($type); } } getPosition(), $parameterReflection->isOptional() ? '' : '', self::typeToString($parameterReflection), $parameterReflection->isVariadic() ? '...' : '', $parameterReflection->isPassedByReference() ? '&' : '', $parameterReflection->getName(), self::valueToString($parameterReflection)); } /** @psalm-pure */ private static function typeToString(ReflectionParameter $parameterReflection) : string { $type = $parameterReflection->getType(); if ($type === null) { return ''; } return \PHPStan\BetterReflection\Reflection\StringCast\ReflectionTypeStringCast::toString($type) . ' '; } /** @psalm-pure */ private static function valueToString(ReflectionParameter $parameterReflection) : string { if (!($parameterReflection->isOptional() && $parameterReflection->isDefaultValueAvailable())) { return ''; } $defaultValue = $parameterReflection->getDefaultValue(); if (is_array($defaultValue)) { return ' = Array'; } if (is_string($defaultValue) && strlen($defaultValue) > 15) { return ' = ' . var_export(substr($defaultValue, 0, 15) . '...', \true); } return ' = ' . var_export($defaultValue, \true); } } getDeclaringEnum(); $value = $enumReflection->isBacked() ? $enumCaseReflection->getValue() : 'Object'; $type = $enumReflection->isBacked() ? gettype($value) : $enumReflection->getName(); return sprintf("Constant [ public %s %s ] { %s }\n", $type, $enumCaseReflection->getName(), $value); } } getTypes(), static function (ReflectionType $type) : bool { return !($type instanceof ReflectionNamedType && $type->getName() === 'null'); })); if ($type->allowsNull() && count($nonNullTypes) === 1 && $nonNullTypes[0] instanceof ReflectionNamedType) { return '?' . $nonNullTypes[0]->__toString(); } } return $type->__toString(); } } */ private $arguments = []; /** * @var \PHPStan\BetterReflection\Reflector\Reflector */ private $reflector; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionClass|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionClassConstant|\PHPStan\BetterReflection\Reflection\ReflectionEnumCase|\PHPStan\BetterReflection\Reflection\ReflectionProperty|\PHPStan\BetterReflection\Reflection\ReflectionParameter */ private $owner; /** * @var bool */ private $isRepeated; /** @internal * @param \PHPStan\BetterReflection\Reflection\ReflectionClass|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionClassConstant|\PHPStan\BetterReflection\Reflection\ReflectionEnumCase|\PHPStan\BetterReflection\Reflection\ReflectionProperty|\PHPStan\BetterReflection\Reflection\ReflectionParameter $owner */ public function __construct(Reflector $reflector, Node\Attribute $node, $owner, bool $isRepeated) { $this->reflector = $reflector; $this->owner = $owner; $this->isRepeated = $isRepeated; $name = $node->name->toString(); assert($name !== ''); $this->name = $name; foreach ($node->args as $argNo => $arg) { $this->arguments[(($argName = $arg->name) ? $argName->toString() : null) ?? $argNo] = $arg->value; } } /** @internal * @param \PHPStan\BetterReflection\Reflection\ReflectionClass|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionClassConstant|\PHPStan\BetterReflection\Reflection\ReflectionEnumCase|\PHPStan\BetterReflection\Reflection\ReflectionProperty|\PHPStan\BetterReflection\Reflection\ReflectionParameter $owner */ public function withOwner($owner) : self { $clone = clone $this; $clone->owner = $owner; return $clone; } /** @return non-empty-string */ public function getName() : string { return $this->name; } public function getClass() : \PHPStan\BetterReflection\Reflection\ReflectionClass { return $this->reflector->reflectClass($this->getName()); } /** @return array */ public function getArgumentsExpressions() : array { return $this->arguments; } /** * @deprecated Use getArgumentsExpressions() * @return array */ public function getArguments() : array { $compiler = new CompileNodeToValue(); $context = new CompilerContext($this->reflector, $this->owner); return array_map(static function (Node\Expr $value) use($compiler, $context) { return $compiler->__invoke($value, $context)->value; }, $this->arguments); } /** @return int-mask-of */ public function getTarget() : int { switch (\true) { case $this->owner instanceof \PHPStan\BetterReflection\Reflection\ReflectionClass: return Attribute::TARGET_CLASS; case $this->owner instanceof \PHPStan\BetterReflection\Reflection\ReflectionFunction: return Attribute::TARGET_FUNCTION; case $this->owner instanceof \PHPStan\BetterReflection\Reflection\ReflectionMethod: return Attribute::TARGET_METHOD; case $this->owner instanceof \PHPStan\BetterReflection\Reflection\ReflectionProperty: return Attribute::TARGET_PROPERTY; case $this->owner instanceof \PHPStan\BetterReflection\Reflection\ReflectionClassConstant: return Attribute::TARGET_CLASS_CONSTANT; case $this->owner instanceof \PHPStan\BetterReflection\Reflection\ReflectionEnumCase: return Attribute::TARGET_CLASS_CONSTANT; case $this->owner instanceof \PHPStan\BetterReflection\Reflection\ReflectionParameter: return Attribute::TARGET_PARAMETER; default: throw new LogicException('unknown owner'); } } public function isRepeated() : bool { return $this->isRepeated; } /** @return non-empty-string */ public function __toString() : string { return ReflectionAttributeStringCast::toString($this); } } null, 'float' => null, 'string' => null, 'bool' => null, 'callable' => null, 'self' => null, 'parent' => null, 'array' => null, 'iterable' => null, 'object' => null, 'void' => null, 'mixed' => null, 'static' => null, 'null' => null, 'never' => null, 'false' => null, 'true' => null]; /** @var non-empty-string */ private $name; /** * @var \PHPStan\BetterReflection\Reflector\Reflector */ private $reflector; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionParameter|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionEnum|\PHPStan\BetterReflection\Reflection\ReflectionProperty|\PHPStan\BetterReflection\Reflection\ReflectionClassConstant */ private $owner; /** * @var \PhpParser\Node\Identifier|\PhpParser\Node\Name */ private $type; /** @internal * @param \PHPStan\BetterReflection\Reflection\ReflectionParameter|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionEnum|\PHPStan\BetterReflection\Reflection\ReflectionProperty|\PHPStan\BetterReflection\Reflection\ReflectionClassConstant $owner * @param \PhpParser\Node\Identifier|\PhpParser\Node\Name $type */ public function __construct(Reflector $reflector, $owner, $type) { $this->reflector = $reflector; $this->owner = $owner; $this->type = $type; $name = $type->toString(); assert($name !== ''); $this->name = $name; } /** @internal * @param \PHPStan\BetterReflection\Reflection\ReflectionParameter|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionEnum|\PHPStan\BetterReflection\Reflection\ReflectionProperty|\PHPStan\BetterReflection\Reflection\ReflectionClassConstant $owner * @return $this */ public function withOwner($owner) { $clone = clone $this; $clone->owner = $owner; return $clone; } /** @return non-empty-string */ public function getName() : string { return $this->name; } /** * Checks if it is a built-in type (i.e., it's not an object...) * * @see https://php.net/manual/en/reflectiontype.isbuiltin.php */ public function isBuiltin() : bool { return array_key_exists(strtolower($this->name), self::BUILT_IN_TYPES); } public function getClass() : \PHPStan\BetterReflection\Reflection\ReflectionClass { if (!$this->isBuiltin()) { return $this->reflector->reflectClass($this->name); } if ($this->owner instanceof \PHPStan\BetterReflection\Reflection\ReflectionEnum || $this->owner instanceof \PHPStan\BetterReflection\Reflection\ReflectionFunction || $this->owner instanceof \PHPStan\BetterReflection\Reflection\ReflectionParameter && $this->owner->getDeclaringFunction() instanceof \PHPStan\BetterReflection\Reflection\ReflectionFunction) { throw new LogicException(sprintf('The type %s cannot be resolved to class', $this->name)); } $lowercaseName = strtolower($this->name); if ($lowercaseName === 'self') { $class = $this->owner->getImplementingClass(); assert($class instanceof \PHPStan\BetterReflection\Reflection\ReflectionClass); return $class; } if ($lowercaseName === 'parent') { $class = $this->owner->getDeclaringClass(); assert($class instanceof \PHPStan\BetterReflection\Reflection\ReflectionClass); $parentClass = $class->getParentClass(); assert($parentClass instanceof \PHPStan\BetterReflection\Reflection\ReflectionClass); return $parentClass; } if ($this->owner instanceof \PHPStan\BetterReflection\Reflection\ReflectionMethod && $lowercaseName === 'static') { return $this->owner->getCurrentClass(); } throw new LogicException(sprintf('The type %s cannot be resolved to class', $this->name)); } public function allowsNull() : bool { switch (strtolower($this->name)) { case 'mixed': return \true; case 'null': return \true; default: return \false; } } public function isIdentifier() : bool { return $this->type instanceof Identifier; } /** @return non-empty-string */ public function __toString() : string { return $this->getName(); } } */ private $attributes; /** @var positive-int|null */ private $startLine; /** @var positive-int|null */ private $endLine; /** @var positive-int|null */ private $startColumn; /** @var positive-int|null */ private $endColumn; /** @psalm-allow-private-mutation * @var \PHPStan\BetterReflection\NodeCompiler\CompiledValue|null */ private $compiledDefaultValue = null; /** * @var \PHPStan\BetterReflection\Reflector\Reflector */ private $reflector; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction */ private $function; /** * @var int */ private $parameterIndex; /** * @var bool */ private $isOptional; /** * @param \PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction $function */ private function __construct(Reflector $reflector, ParamNode $node, $function, int $parameterIndex, bool $isOptional) { $this->reflector = $reflector; $this->function = $function; $this->parameterIndex = $parameterIndex; $this->isOptional = $isOptional; assert($node->var instanceof Node\Expr\Variable); assert(is_string($node->var->name)); $name = $node->var->name; assert($name !== ''); $this->name = $name; $this->default = $node->default; $this->isPromoted = $node->flags !== 0; $this->type = $this->createType($node); $this->isVariadic = $node->variadic; $this->byRef = $node->byRef; $this->attributes = ReflectionAttributeHelper::createAttributes($reflector, $this, $node->attrGroups); if ($node->hasAttribute('startLine')) { $startLine = $node->getStartLine(); assert($startLine > 0); } else { $startLine = null; } if ($node->hasAttribute('endLine')) { $endLine = $node->getEndLine(); assert($endLine > 0); } else { $endLine = null; } $this->startLine = $startLine; $this->endLine = $endLine; try { $this->startColumn = CalculateReflectionColumn::getStartColumn($function->getLocatedSource()->getSource(), $node); } catch (NoNodePosition $exception) { $this->startColumn = null; } try { $this->endColumn = CalculateReflectionColumn::getEndColumn($function->getLocatedSource()->getSource(), $node); } catch (NoNodePosition $exception) { $this->endColumn = null; } } /** * Create a reflection of a parameter using a class name * * @param non-empty-string $methodName * @param non-empty-string $parameterName * * @throws OutOfBoundsException */ public static function createFromClassNameAndMethod(string $className, string $methodName, string $parameterName) : self { $parameter = ($getMethod = \PHPStan\BetterReflection\Reflection\ReflectionClass::createFromName($className)->getMethod($methodName)) ? $getMethod->getParameter($parameterName) : null; if ($parameter === null) { throw new OutOfBoundsException(sprintf('Could not find parameter: %s', $parameterName)); } return $parameter; } /** * Create a reflection of a parameter using an instance * * @param non-empty-string $methodName * @param non-empty-string $parameterName * * @throws OutOfBoundsException */ public static function createFromClassInstanceAndMethod(object $instance, string $methodName, string $parameterName) : self { $parameter = ($getMethod = \PHPStan\BetterReflection\Reflection\ReflectionClass::createFromInstance($instance)->getMethod($methodName)) ? $getMethod->getParameter($parameterName) : null; if ($parameter === null) { throw new OutOfBoundsException(sprintf('Could not find parameter: %s', $parameterName)); } return $parameter; } /** * Create a reflection of a parameter using a closure * * @param non-empty-string $parameterName * * @throws OutOfBoundsException */ public static function createFromClosure(Closure $closure, string $parameterName) : \PHPStan\BetterReflection\Reflection\ReflectionParameter { $parameter = \PHPStan\BetterReflection\Reflection\ReflectionFunction::createFromClosure($closure)->getParameter($parameterName); if ($parameter === null) { throw new OutOfBoundsException(sprintf('Could not find parameter: %s', $parameterName)); } return $parameter; } /** * Create the parameter from the given spec. Possible $spec parameters are: * * - [$instance, 'method'] * - ['Foo', 'bar'] * - ['foo'] * - [function () {}] * * @param object[]|string[]|string|Closure $spec * @param non-empty-string $parameterName * * @throws Exception * @throws InvalidArgumentException */ public static function createFromSpec($spec, string $parameterName) : self { try { if (is_array($spec) && count($spec) === 2 && is_string($spec[1])) { assert($spec[1] !== ''); if (is_object($spec[0])) { return self::createFromClassInstanceAndMethod($spec[0], $spec[1], $parameterName); } return self::createFromClassNameAndMethod($spec[0], $spec[1], $parameterName); } if (is_string($spec)) { $parameter = \PHPStan\BetterReflection\Reflection\ReflectionFunction::createFromName($spec)->getParameter($parameterName); if ($parameter === null) { throw new OutOfBoundsException(sprintf('Could not find parameter: %s', $parameterName)); } return $parameter; } if ($spec instanceof Closure) { return self::createFromClosure($spec, $parameterName); } } catch (OutOfBoundsException $e) { throw new InvalidArgumentException('Could not create reflection from the spec given', 0, $e); } throw new InvalidArgumentException('Could not create reflection from the spec given'); } /** @return non-empty-string */ public function __toString() : string { return ReflectionParameterStringCast::toString($this); } /** * @internal * * @param ParamNode $node Node has to be processed by the PhpParser\NodeVisitor\NameResolver * @param \PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction $function */ public static function createFromNode(Reflector $reflector, ParamNode $node, $function, int $parameterIndex, bool $isOptional) : self { return new self($reflector, $node, $function, $parameterIndex, $isOptional); } /** @internal * @param \PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction $function */ public function withFunction($function) : self { $clone = clone $this; $clone->function = $function; if ($clone->type !== null) { $clone->type = $clone->type->withOwner($clone); } $clone->attributes = array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionAttribute $attribute) use($clone) : \PHPStan\BetterReflection\Reflection\ReflectionAttribute { return $attribute->withOwner($clone); }, $this->attributes); $this->compiledDefaultValue = null; return $clone; } /** @throws LogicException */ private function getCompiledDefaultValue() : CompiledValue { if (!$this->isDefaultValueAvailable()) { throw new LogicException('This parameter does not have a default value available'); } if ($this->compiledDefaultValue === null) { $this->compiledDefaultValue = (new CompileNodeToValue())->__invoke($this->default, new CompilerContext($this->reflector, $this)); } return $this->compiledDefaultValue; } /** * Get the name of the parameter. * * @return non-empty-string */ public function getName() : string { return $this->name; } /** * Get the function (or method) that declared this parameter. * @return \PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction */ public function getDeclaringFunction() { return $this->function; } /** * Get the class from the method that this parameter belongs to, if it * exists. * * This will return null if the declaring function is not a method. */ public function getDeclaringClass() : ?\PHPStan\BetterReflection\Reflection\ReflectionClass { if ($this->function instanceof \PHPStan\BetterReflection\Reflection\ReflectionMethod) { return $this->function->getDeclaringClass(); } return null; } public function getImplementingClass() : ?\PHPStan\BetterReflection\Reflection\ReflectionClass { if ($this->function instanceof \PHPStan\BetterReflection\Reflection\ReflectionMethod) { return $this->function->getImplementingClass(); } return null; } /** * Is the parameter optional? * * Note this is distinct from "isDefaultValueAvailable" because you can have * a default value, but the parameter not be optional. In the example, the * $foo parameter isOptional() == false, but isDefaultValueAvailable == true * * @example someMethod($foo = 'foo', $bar) */ public function isOptional() : bool { return $this->isOptional; } /** * Does the parameter have a default, regardless of whether it is optional. * * Note this is distinct from "isOptional" because you can have * a default value, but the parameter not be optional. In the example, the * $foo parameter isOptional() == false, but isDefaultValueAvailable == true * * @example someMethod($foo = 'foo', $bar) * @psalm-assert-if-true Node\Expr $this->default */ public function isDefaultValueAvailable() : bool { return $this->default !== null; } /** * @deprecated Use getDefaultValueExpression() */ public function getDefaultValueExpr() : ?\PhpParser\Node\Expr { return $this->getDefaultValueExpression(); } public function getDefaultValueExpression() : ?\PhpParser\Node\Expr { return $this->default; } /** * Get the default value of the parameter. * * @deprecated Use getDefaultValueExpression() * * @throws LogicException * @throws UnableToCompileNode * @return mixed */ public function getDefaultValue() { /** @psalm-var scalar|array|null $value */ $value = $this->getCompiledDefaultValue()->value; return $value; } /** * Does this method allow null for a parameter? */ public function allowsNull() : bool { $type = $this->getType(); if ($type === null) { return \true; } return $type->allowsNull(); } /** * Find the position of the parameter, left to right, starting at zero. */ public function getPosition() : int { return $this->parameterIndex; } /** * Get the ReflectionType instance representing the type declaration for * this parameter * * (note: this has nothing to do with DocBlocks). * @return \PHPStan\BetterReflection\Reflection\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\ReflectionIntersectionType|null */ public function getType() { return $this->type; } /** * @return \PHPStan\BetterReflection\Reflection\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\ReflectionIntersectionType|null */ private function createType(ParamNode $node) { $type = $node->type; if ($type === null) { return null; } assert($type instanceof Node\Identifier || $type instanceof Node\Name || $type instanceof Node\NullableType || $type instanceof Node\UnionType || $type instanceof Node\IntersectionType); $allowsNull = $this->default instanceof Node\Expr\ConstFetch && $this->default->name->toLowerString() === 'null' && !$this->isPromoted; return \PHPStan\BetterReflection\Reflection\ReflectionType::createFromNode($this->reflector, $this, $type, $allowsNull); } /** * Does this parameter have a type declaration? * * (note: this has nothing to do with DocBlocks). */ public function hasType() : bool { return $this->type !== null; } /** * Is this parameter a variadic (denoted by ...$param). */ public function isVariadic() : bool { return $this->isVariadic; } /** * Is this parameter passed by reference (denoted by &$param). */ public function isPassedByReference() : bool { return $this->byRef; } public function canBePassedByValue() : bool { return !$this->isPassedByReference(); } public function isPromoted() : bool { return $this->isPromoted; } /** @throws LogicException */ public function isDefaultValueConstant() : bool { return $this->getCompiledDefaultValue()->constantName !== null; } /** @throws LogicException */ public function getDefaultValueConstantName() : string { $compiledDefaultValue = $this->getCompiledDefaultValue(); if ($compiledDefaultValue->constantName === null) { throw new LogicException('This parameter is not a constant default value, so cannot have a constant name'); } return $compiledDefaultValue->constantName; } /** * @return positive-int * * @throws CodeLocationMissing */ public function getStartLine() : int { if ($this->startLine === null) { throw CodeLocationMissing::create(); } return $this->startLine; } /** * @return positive-int * * @throws CodeLocationMissing */ public function getEndLine() : int { if ($this->endLine === null) { throw CodeLocationMissing::create(); } return $this->endLine; } /** * @return positive-int * * @throws CodeLocationMissing */ public function getStartColumn() : int { if ($this->startColumn === null) { throw CodeLocationMissing::create(); } return $this->startColumn; } /** * @return positive-int * * @throws CodeLocationMissing */ public function getEndColumn() : int { if ($this->endColumn === null) { throw CodeLocationMissing::create(); } return $this->endColumn; } /** @return list */ public function getAttributes() : array { return $this->attributes; } /** @return list */ public function getAttributesByName(string $name) : array { return ReflectionAttributeHelper::filterAttributesByName($this->getAttributes(), $name); } /** * @param class-string $className * * @return list */ public function getAttributesByInstance(string $className) : array { return ReflectionAttributeHelper::filterAttributesByInstance($this->getAttributes(), $className); } } * @psalm-allow-private-mutation */ private $parameters; /** @psalm-allow-private-mutation * @var bool */ private $returnsReference; /** @psalm-allow-private-mutation * @var \PHPStan\BetterReflection\Reflection\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\ReflectionIntersectionType|null */ private $returnType; /** * @var list * @psalm-allow-private-mutation */ private $attributes; /** * @var non-empty-string|null * @psalm-allow-private-mutation */ private $docComment; /** * @var positive-int|null * @psalm-allow-private-mutation */ private $startLine; /** * @var positive-int|null * @psalm-allow-private-mutation */ private $endLine; /** * @var positive-int|null * @psalm-allow-private-mutation */ private $startColumn; /** * @var positive-int|null * @psalm-allow-private-mutation */ private $endColumn; /** @psalm-allow-private-mutation * @var bool */ private $couldThrow = \false; /** @psalm-allow-private-mutation * @var bool */ private $isClosure = \false; /** @psalm-allow-private-mutation * @var bool */ private $isGenerator = \false; /** @return non-empty-string */ public abstract function __toString() : string; /** @return non-empty-string */ public abstract function getShortName() : string; /** @psalm-external-mutation-free * @param MethodNode|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node */ private function fillFromNode($node) : void { $this->parameters = $this->createParameters($node); $this->returnsReference = $node->returnsByRef(); $this->returnType = $this->createReturnType($node); $this->attributes = ReflectionAttributeHelper::createAttributes($this->reflector, $this, $node->attrGroups); $this->docComment = GetLastDocComment::forNode($node); $this->couldThrow = $this->computeCouldThrow($node); $startLine = null; if ($node->hasAttribute('startLine')) { $startLine = $node->getStartLine(); assert($startLine > 0); } $endLine = null; if ($node->hasAttribute('endLine')) { $endLine = $node->getEndLine(); assert($endLine > 0); } $this->startLine = $startLine; $this->endLine = $endLine; try { $this->startColumn = CalculateReflectionColumn::getStartColumn($this->getLocatedSource()->getSource(), $node); } catch (NoNodePosition $exception) { $this->startColumn = null; } try { $this->endColumn = CalculateReflectionColumn::getEndColumn($this->getLocatedSource()->getSource(), $node); } catch (NoNodePosition $exception) { $this->endColumn = null; } } /** @return array * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node */ private function createParameters($node) : array { $parameters = []; /** @var list $nodeParams */ $nodeParams = $node->params; foreach ($nodeParams as $paramIndex => $paramNode) { $parameter = \PHPStan\BetterReflection\Reflection\ReflectionParameter::createFromNode($this->reflector, $paramNode, $this, $paramIndex, $this->isParameterOptional($nodeParams, $paramIndex)); $parameters[$parameter->getName()] = $parameter; } return $parameters; } /** * Get the "full" name of the function (e.g. for A\B\foo, this will return * "A\B\foo"). * * @return non-empty-string */ public function getName() : string { $namespace = $this->getNamespaceName(); if ($namespace === null) { return $this->getShortName(); } return $namespace . '\\' . $this->getShortName(); } /** * Get the "namespace" name of the function (e.g. for A\B\foo, this will * return "A\B"). * * @return non-empty-string|null */ public function getNamespaceName() : ?string { return $this->namespace; } /** * Decide if this function is part of a namespace. Returns false if the class * is in the global namespace or does not have a specified namespace. */ public function inNamespace() : bool { return $this->namespace !== null; } /** * Get the number of parameters for this class. * * @return positive-int|0 */ public function getNumberOfParameters() : int { return count($this->parameters); } /** * Get the number of required parameters for this method. * * @return positive-int|0 */ public function getNumberOfRequiredParameters() : int { return count(array_filter($this->parameters, static function (\PHPStan\BetterReflection\Reflection\ReflectionParameter $p) : bool { return !$p->isOptional(); })); } /** * Get an array list of the parameters for this method signature, as an * array of ReflectionParameter instances. * * @return list */ public function getParameters() : array { return array_values($this->parameters); } /** @param list $parameterNodes */ private function isParameterOptional(array $parameterNodes, int $parameterIndex) : bool { foreach ($parameterNodes as $otherParameterIndex => $otherParameterNode) { if ($otherParameterIndex < $parameterIndex) { continue; } // When we find next parameter that does not have a default or is not variadic, // it means current parameter cannot be optional EVEN if it has a default value if ($otherParameterNode->default === null && !$otherParameterNode->variadic) { return \false; } } return \true; } /** * Get a single parameter by name. Returns null if parameter not found for * the function. * * @param non-empty-string $parameterName */ public function getParameter(string $parameterName) : ?\PHPStan\BetterReflection\Reflection\ReflectionParameter { return $this->parameters[$parameterName] ?? null; } /** @return non-empty-string|null */ public function getDocComment() : ?string { return $this->docComment; } /** @return non-empty-string|null */ public function getFileName() : ?string { return $this->locatedSource->getFileName(); } public function getLocatedSource() : LocatedSource { return $this->locatedSource; } /** * Is this function a closure? */ public function isClosure() : bool { return $this->isClosure; } public function isDeprecated() : bool { return AnnotationHelper::isDeprecated($this->docComment); } public function isInternal() : bool { return $this->locatedSource->isInternal(); } /** * Is this a user-defined function (will always return the opposite of * whatever isInternal returns). */ public function isUserDefined() : bool { return !$this->isInternal(); } /** @return non-empty-string|null */ public function getExtensionName() : ?string { return $this->locatedSource->getExtensionName(); } /** * Check if the function has a variadic parameter. */ public function isVariadic() : bool { foreach ($this->parameters as $parameter) { if ($parameter->isVariadic()) { return \true; } } return \false; } /** Checks if the function/method contains `throw` expressions. */ public function couldThrow() : bool { return $this->couldThrow; } /** * @param MethodNode|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node */ private function computeCouldThrow($node) : bool { $statements = $node->getStmts(); if ($statements === null) { return \false; } $visitor = new FindingVisitor(static function (Node $node) : bool { return $node instanceof NodeThrow; }); $traverser = new NodeTraverser(); $traverser->addVisitor($visitor); $traverser->traverse($statements); return $visitor->getFoundNodes() !== []; } /** * Recursively search an array of statements (PhpParser nodes) to find if a * yield expression exists anywhere (thus indicating this is a generator). */ private function nodeIsOrContainsYield(Node $node) : bool { if ($node instanceof YieldNode) { return \true; } if ($node instanceof YieldFromNode) { return \true; } /** @psalm-var string $nodeName */ foreach ($node->getSubNodeNames() as $nodeName) { $nodeProperty = $node->{$nodeName}; if ($nodeProperty instanceof Node && $this->nodeIsOrContainsYield($nodeProperty)) { return \true; } if (!is_array($nodeProperty)) { continue; } /** @psalm-var mixed $nodePropertyArrayItem */ foreach ($nodeProperty as $nodePropertyArrayItem) { if ($nodePropertyArrayItem instanceof Node && $this->nodeIsOrContainsYield($nodePropertyArrayItem)) { return \true; } } } return \false; } /** * Check if this function can be used as a generator (i.e. contains the * "yield" keyword). */ public function isGenerator() : bool { return $this->isGenerator; } /** * Get the line number that this function starts on. * * @return positive-int * * @throws CodeLocationMissing */ public function getStartLine() : int { if ($this->startLine === null) { throw CodeLocationMissing::create(); } return $this->startLine; } /** * Get the line number that this function ends on. * * @return positive-int * * @throws CodeLocationMissing */ public function getEndLine() : int { if ($this->endLine === null) { throw CodeLocationMissing::create(); } return $this->endLine; } /** * @return positive-int * * @throws CodeLocationMissing */ public function getStartColumn() : int { if ($this->startColumn === null) { throw CodeLocationMissing::create(); } return $this->startColumn; } /** * @return positive-int * * @throws CodeLocationMissing */ public function getEndColumn() : int { if ($this->endColumn === null) { throw CodeLocationMissing::create(); } return $this->endColumn; } /** * Is this function declared as a reference. */ public function returnsReference() : bool { return $this->returnsReference; } /** * Get the return type declaration * @return \PHPStan\BetterReflection\Reflection\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\ReflectionIntersectionType|null */ public function getReturnType() { if ($this->hasTentativeReturnType()) { return null; } return $this->returnType; } /** * Do we have a return type declaration */ public function hasReturnType() : bool { if ($this->hasTentativeReturnType()) { return \false; } return $this->returnType !== null; } public function hasTentativeReturnType() : bool { if ($this->isUserDefined()) { return \false; } return AnnotationHelper::hasTentativeReturnType($this->docComment); } /** * @return \PHPStan\BetterReflection\Reflection\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\ReflectionIntersectionType|null */ public function getTentativeReturnType() { if (!$this->hasTentativeReturnType()) { return null; } return $this->returnType; } /** * @param MethodNode|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node * @return \PHPStan\BetterReflection\Reflection\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\ReflectionIntersectionType|null */ private function createReturnType($node) { $returnType = $node->getReturnType(); if ($returnType === null) { return null; } assert($returnType instanceof Node\Identifier || $returnType instanceof Node\Name || $returnType instanceof Node\NullableType || $returnType instanceof Node\UnionType || $returnType instanceof Node\IntersectionType); return \PHPStan\BetterReflection\Reflection\ReflectionType::createFromNode($this->reflector, $this, $returnType); } /** @return list */ public function getAttributes() : array { return $this->attributes; } /** @return list */ public function getAttributesByName(string $name) : array { return ReflectionAttributeHelper::filterAttributesByName($this->getAttributes(), $name); } /** * @param class-string $className * * @return list */ public function getAttributesByInstance(string $className) : array { return ReflectionAttributeHelper::filterAttributesByInstance($this->getAttributes(), $className); } } type; $allowsNull = \true; } if ($type instanceof Identifier || $type instanceof Name) { if ($type->toLowerString() === 'null' || $type->toLowerString() === 'mixed' || !$allowsNull) { return new \PHPStan\BetterReflection\Reflection\ReflectionNamedType($reflector, $owner, $type); } return new \PHPStan\BetterReflection\Reflection\ReflectionUnionType($reflector, $owner, new UnionType([$type, new Identifier('null')])); } if ($type instanceof IntersectionType) { return new \PHPStan\BetterReflection\Reflection\ReflectionIntersectionType($reflector, $owner, $type); } if (!$allowsNull) { return new \PHPStan\BetterReflection\Reflection\ReflectionUnionType($reflector, $owner, $type); } foreach ($type->types as $innerUnionType) { if (($innerUnionType instanceof Identifier || $innerUnionType instanceof Name) && $innerUnionType->toLowerString() === 'null') { return new \PHPStan\BetterReflection\Reflection\ReflectionUnionType($reflector, $owner, $type); } } $types = $type->types; $types[] = new Identifier('null'); return new \PHPStan\BetterReflection\Reflection\ReflectionUnionType($reflector, $owner, new UnionType($types)); } /** * Does the type allow null? */ public abstract function allowsNull() : bool; /** * Convert this string type to a string * * @return non-empty-string */ public abstract function __toString() : string; } */ private $types; /** @internal * @param \PHPStan\BetterReflection\Reflection\ReflectionParameter|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionEnum|\PHPStan\BetterReflection\Reflection\ReflectionProperty|\PHPStan\BetterReflection\Reflection\ReflectionClassConstant $owner */ public function __construct(Reflector $reflector, $owner, UnionType $type) { /** @var non-empty-list $types */ $types = array_map(static function ($type) use($reflector, $owner) { $type = \PHPStan\BetterReflection\Reflection\ReflectionType::createFromNode($reflector, $owner, $type); assert($type instanceof \PHPStan\BetterReflection\Reflection\ReflectionNamedType || $type instanceof \PHPStan\BetterReflection\Reflection\ReflectionIntersectionType); return $type; }, $type->types); $this->types = $types; } /** @internal * @param \PHPStan\BetterReflection\Reflection\ReflectionParameter|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionEnum|\PHPStan\BetterReflection\Reflection\ReflectionProperty|\PHPStan\BetterReflection\Reflection\ReflectionClassConstant $owner * @return $this */ public function withOwner($owner) { $clone = clone $this; foreach ($clone->types as $typeNo => $innerType) { $clone->types[$typeNo] = $innerType->withOwner($owner); } return $clone; } /** @return non-empty-list */ public function getTypes() : array { return $this->types; } public function allowsNull() : bool { foreach ($this->types as $type) { if ($type->allowsNull()) { return \true; } } return \false; } /** @return non-empty-string */ public function __toString() : string { return implode('|', array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionType $type) : string { if ($type instanceof \PHPStan\BetterReflection\Reflection\ReflectionIntersectionType) { return sprintf('(%s)', $type->__toString()); } return $type->__toString(); }, $this->types)); } } */ private $modifiers; /** * @var \PHPStan\BetterReflection\Reflector\Reflector */ private $reflector; /** * @var \PHPStan\BetterReflection\SourceLocator\Located\LocatedSource */ private $locatedSource; /** * @var non-empty-string|null */ private $namespace; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionClass */ private $declaringClass; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionClass */ private $implementingClass; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionClass */ private $currentClass; /** * @var non-empty-string|null */ private $aliasName; /** * @param non-empty-string|null $aliasName * @param non-empty-string|null $namespace * @param MethodNode|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node */ private function __construct(Reflector $reflector, $node, LocatedSource $locatedSource, ?string $namespace, \PHPStan\BetterReflection\Reflection\ReflectionClass $declaringClass, \PHPStan\BetterReflection\Reflection\ReflectionClass $implementingClass, \PHPStan\BetterReflection\Reflection\ReflectionClass $currentClass, ?string $aliasName) { $this->reflector = $reflector; $this->locatedSource = $locatedSource; $this->namespace = $namespace; $this->declaringClass = $declaringClass; $this->implementingClass = $implementingClass; $this->currentClass = $currentClass; $this->aliasName = $aliasName; assert($node instanceof MethodNode); $name = $node->name->name; assert($name !== ''); $this->name = $name; $this->modifiers = $this->computeModifiers($node); $this->fillFromNode($node); } /** * @internal * * @param non-empty-string|null $aliasName * @param non-empty-string|null $namespace */ public static function createFromNode(Reflector $reflector, MethodNode $node, LocatedSource $locatedSource, ?string $namespace, \PHPStan\BetterReflection\Reflection\ReflectionClass $declaringClass, \PHPStan\BetterReflection\Reflection\ReflectionClass $implementingClass, \PHPStan\BetterReflection\Reflection\ReflectionClass $currentClass, ?string $aliasName = null) : self { return new self($reflector, $node, $locatedSource, $namespace, $declaringClass, $implementingClass, $currentClass, $aliasName); } /** * Create a reflection of a method by it's name using a named class * * @param non-empty-string $methodName * * @throws IdentifierNotFound * @throws OutOfBoundsException */ public static function createFromName(string $className, string $methodName) : self { $method = \PHPStan\BetterReflection\Reflection\ReflectionClass::createFromName($className)->getMethod($methodName); if ($method === null) { throw new OutOfBoundsException(sprintf('Could not find method: %s', $methodName)); } return $method; } /** * Create a reflection of a method by it's name using an instance * * @param non-empty-string $methodName * * @throws ReflectionException * @throws IdentifierNotFound * @throws OutOfBoundsException */ public static function createFromInstance(object $instance, string $methodName) : self { $method = \PHPStan\BetterReflection\Reflection\ReflectionClass::createFromInstance($instance)->getMethod($methodName); if ($method === null) { throw new OutOfBoundsException(sprintf('Could not find method: %s', $methodName)); } return $method; } /** * @internal * * @param non-empty-string|null $aliasName * @param int-mask-of $modifiers */ public function withImplementingClass(\PHPStan\BetterReflection\Reflection\ReflectionClass $implementingClass, ?string $aliasName, int $modifiers) : self { $clone = clone $this; $clone->aliasName = $aliasName; $clone->modifiers = $modifiers; $clone->implementingClass = $implementingClass; $clone->currentClass = $implementingClass; if ($clone->returnType !== null) { $clone->returnType = $clone->returnType->withOwner($clone); } $clone->parameters = array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionParameter $parameter) use($clone) : \PHPStan\BetterReflection\Reflection\ReflectionParameter { return $parameter->withFunction($clone); }, $this->parameters); $clone->attributes = array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionAttribute $attribute) use($clone) : \PHPStan\BetterReflection\Reflection\ReflectionAttribute { return $attribute->withOwner($clone); }, $this->attributes); return $clone; } /** @internal */ public function withCurrentClass(\PHPStan\BetterReflection\Reflection\ReflectionClass $currentClass) : self { $clone = clone $this; $clone->currentClass = $currentClass; if ($clone->returnType !== null) { $clone->returnType = $clone->returnType->withOwner($clone); } // We don't need to clone parameters and attributes return $clone; } /** @return non-empty-string */ public function getShortName() : string { if ($this->aliasName !== null) { return $this->aliasName; } return $this->name; } /** @return non-empty-string|null */ public function getAliasName() : ?string { return $this->aliasName; } /** * Find the prototype for this method, if it exists. If it does not exist * it will throw a MethodPrototypeNotFound exception. * * @throws Exception\MethodPrototypeNotFound */ public function getPrototype() : self { $currentClass = $this->getImplementingClass(); foreach ($currentClass->getImmediateInterfaces() as $interface) { $interfaceMethod = $interface->getMethod($this->getName()); if ($interfaceMethod !== null) { return $interfaceMethod; } } $currentClass = $currentClass->getParentClass(); if ($currentClass !== null) { $prototype = ($getMethod = $currentClass->getMethod($this->getName())) ? $getMethod->findPrototype() : null; if ($prototype !== null && (!$this->isConstructor() || $prototype->isAbstract())) { return $prototype; } } throw new \PHPStan\BetterReflection\Reflection\Exception\MethodPrototypeNotFound(sprintf('Method %s::%s does not have a prototype', $this->getDeclaringClass()->getName(), $this->getName())); } private function findPrototype() : ?self { if ($this->isAbstract()) { return $this; } if ($this->isPrivate()) { return null; } try { return $this->getPrototype(); } catch (\PHPStan\BetterReflection\Reflection\Exception\MethodPrototypeNotFound $exception) { return $this; } } /** * Get the core-reflection-compatible modifier values. * * @return int-mask-of */ public function getModifiers() : int { return $this->modifiers; } /** @return int-mask-of */ private function computeModifiers(MethodNode $node) : int { $modifiers = $node->isStatic() ? CoreReflectionMethod::IS_STATIC : 0; $modifiers += $node->isPublic() ? CoreReflectionMethod::IS_PUBLIC : 0; $modifiers += $node->isProtected() ? CoreReflectionMethod::IS_PROTECTED : 0; $modifiers += $node->isPrivate() ? CoreReflectionMethod::IS_PRIVATE : 0; $modifiers += $node->isAbstract() ? CoreReflectionMethod::IS_ABSTRACT : 0; $modifiers += $node->isFinal() ? CoreReflectionMethod::IS_FINAL : 0; return $modifiers; } /** @return non-empty-string */ public function __toString() : string { return ReflectionMethodStringCast::toString($this); } public function inNamespace() : bool { return \false; } public function getNamespaceName() : ?string { return null; } public function isClosure() : bool { return \false; } /** * Is the method abstract. */ public function isAbstract() : bool { return ($this->modifiers & CoreReflectionMethod::IS_ABSTRACT) === CoreReflectionMethod::IS_ABSTRACT || $this->declaringClass->isInterface(); } /** * Is the method final. */ public function isFinal() : bool { return ($this->modifiers & CoreReflectionMethod::IS_FINAL) === CoreReflectionMethod::IS_FINAL; } /** * Is the method private visibility. */ public function isPrivate() : bool { return ($this->modifiers & CoreReflectionMethod::IS_PRIVATE) === CoreReflectionMethod::IS_PRIVATE; } /** * Is the method protected visibility. */ public function isProtected() : bool { return ($this->modifiers & CoreReflectionMethod::IS_PROTECTED) === CoreReflectionMethod::IS_PROTECTED; } /** * Is the method public visibility. */ public function isPublic() : bool { return ($this->modifiers & CoreReflectionMethod::IS_PUBLIC) === CoreReflectionMethod::IS_PUBLIC; } /** * Is the method static. */ public function isStatic() : bool { return ($this->modifiers & CoreReflectionMethod::IS_STATIC) === CoreReflectionMethod::IS_STATIC; } /** * Is the method a constructor. */ public function isConstructor() : bool { if (strtolower($this->getName()) === '__construct') { return \true; } $declaringClass = $this->getDeclaringClass(); if ($declaringClass->inNamespace()) { return \false; } return strtolower($this->getName()) === strtolower($declaringClass->getShortName()); } /** * Is the method a destructor. */ public function isDestructor() : bool { return strtolower($this->getName()) === '__destruct'; } /** * Get the class that declares this method. */ public function getDeclaringClass() : \PHPStan\BetterReflection\Reflection\ReflectionClass { return $this->declaringClass; } /** * Get the class that implemented the method based on trait use. */ public function getImplementingClass() : \PHPStan\BetterReflection\Reflection\ReflectionClass { return $this->implementingClass; } /** * Get the current reflected class. * * @internal */ public function getCurrentClass() : \PHPStan\BetterReflection\Reflection\ReflectionClass { return $this->currentClass; } /** * @throws ClassDoesNotExist * @throws NoObjectProvided * @throws ObjectNotInstanceOfClass */ public function getClosure($object = null) : Closure { $declaringClassName = $this->getDeclaringClass()->getName(); if ($this->isStatic()) { $this->assertClassExist($declaringClassName); return function (...$args) { return $this->callStaticMethod($args); }; } $instance = $this->assertObject($object); return function (...$args) use($instance) { return $this->callObjectMethod($instance, $args); }; } /** * @throws ClassDoesNotExist * @throws NoObjectProvided * @throws ObjectNotInstanceOfClass * @param mixed ...$args * @return mixed */ public function invoke($object = null, ...$args) { return $this->invokeArgs($object, $args); } /** * @param array $args * * @throws ClassDoesNotExist * @throws NoObjectProvided * @throws ObjectNotInstanceOfClass * @return mixed */ public function invokeArgs($object = null, array $args = []) { $implementingClassName = $this->getImplementingClass()->getName(); if ($this->isStatic()) { $this->assertClassExist($implementingClassName); return $this->callStaticMethod($args); } return $this->callObjectMethod($this->assertObject($object), $args); } /** @param array $args * @return mixed */ private function callStaticMethod(array $args) { $implementingClassName = $this->getImplementingClass()->getName(); /** @psalm-suppress InvalidStringClass */ $closure = Closure::bind(function (string $implementingClassName, string $_methodName, array $methodArgs) { return $implementingClassName::$_methodName(...$methodArgs); }, null, $implementingClassName); assert($closure instanceof Closure); return $closure->__invoke($implementingClassName, $this->getName(), $args); } /** @param array $args * @return mixed */ private function callObjectMethod(object $object, array $args) { /** @psalm-suppress MixedMethodCall */ $closure = Closure::bind(function (object $object, string $methodName, array $methodArgs) { return $object->{$methodName}(...$methodArgs); }, $object, $this->getImplementingClass()->getName()); assert($closure instanceof Closure); return $closure->__invoke($object, $this->getName(), $args); } /** @throws ClassDoesNotExist */ private function assertClassExist(string $className) : void { if (!ClassExistenceChecker::classExists($className, \true) && !ClassExistenceChecker::traitExists($className, \true)) { throw new ClassDoesNotExist(sprintf('Method of class %s cannot be used as the class does not exist', $className)); } } /** * @throws NoObjectProvided * @throws ObjectNotInstanceOfClass */ private function assertObject($object) : object { if ($object === null) { throw NoObjectProvided::create(); } $implementingClassName = $this->getImplementingClass()->getName(); if (\get_class($object) !== $implementingClassName) { throw ObjectNotInstanceOfClass::fromClassName($implementingClassName); } return $object; } } */ private $modifiers; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\ReflectionIntersectionType|null */ private $type; /** * @var \PhpParser\Node\Expr */ private $value; /** @var non-empty-string|null */ private $docComment; /** @var list */ private $attributes; /** @var positive-int */ private $startLine; /** @var positive-int */ private $endLine; /** @var positive-int */ private $startColumn; /** @var positive-int */ private $endColumn; /** @psalm-allow-private-mutation * @var \PHPStan\BetterReflection\NodeCompiler\CompiledValue|null */ private $compiledValue = null; /** * @var \PHPStan\BetterReflection\Reflector\Reflector */ private $reflector; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionClass */ private $declaringClass; /** * @var \PHPStan\BetterReflection\Reflection\ReflectionClass */ private $implementingClass; private function __construct(Reflector $reflector, ClassConst $node, int $positionInNode, \PHPStan\BetterReflection\Reflection\ReflectionClass $declaringClass, \PHPStan\BetterReflection\Reflection\ReflectionClass $implementingClass) { $this->reflector = $reflector; $this->declaringClass = $declaringClass; $this->implementingClass = $implementingClass; $name = $node->consts[$positionInNode]->name->name; assert($name !== ''); $this->name = $name; $this->modifiers = $this->computeModifiers($node); $this->type = $this->createType($node); $this->value = $node->consts[$positionInNode]->value; $this->docComment = GetLastDocComment::forNode($node); $this->attributes = ReflectionAttributeHelper::createAttributes($reflector, $this, $node->attrGroups); $startLine = $node->getStartLine(); assert($startLine > 0); $endLine = $node->getEndLine(); assert($endLine > 0); $this->startLine = $startLine; $this->endLine = $endLine; $this->startColumn = CalculateReflectionColumn::getStartColumn($declaringClass->getLocatedSource()->getSource(), $node); $this->endColumn = CalculateReflectionColumn::getEndColumn($declaringClass->getLocatedSource()->getSource(), $node); } /** * Create a reflection of a class's constant by Const Node * * @internal */ public static function createFromNode(Reflector $reflector, ClassConst $node, int $positionInNode, \PHPStan\BetterReflection\Reflection\ReflectionClass $declaringClass, \PHPStan\BetterReflection\Reflection\ReflectionClass $implementingClass) : self { return new self($reflector, $node, $positionInNode, $declaringClass, $implementingClass); } /** @internal */ public function withImplementingClass(\PHPStan\BetterReflection\Reflection\ReflectionClass $implementingClass) : self { $clone = clone $this; $clone->implementingClass = $implementingClass; $clone->attributes = array_map(static function (\PHPStan\BetterReflection\Reflection\ReflectionAttribute $attribute) use($clone) : \PHPStan\BetterReflection\Reflection\ReflectionAttribute { return $attribute->withOwner($clone); }, $this->attributes); $this->compiledValue = null; return $clone; } /** * Get the name of the reflection (e.g. if this is a ReflectionClass this * will be the class name). * * @return non-empty-string */ public function getName() : string { return $this->name; } /** * @return \PHPStan\BetterReflection\Reflection\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\ReflectionIntersectionType|null */ private function createType(ClassConst $node) { $type = $node->type; if ($type === null) { return null; } assert($type instanceof Node\Identifier || $type instanceof Node\Name || $type instanceof Node\NullableType || $type instanceof Node\UnionType || $type instanceof Node\IntersectionType); return \PHPStan\BetterReflection\Reflection\ReflectionType::createFromNode($this->reflector, $this, $type); } /** * @return \PHPStan\BetterReflection\Reflection\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\ReflectionIntersectionType|null */ public function getType() { return $this->type; } public function hasType() : bool { return $this->type !== null; } /** * @deprecated Use getValueExpression */ public function getValueExpr() : Node\Expr { return $this->getValueExpression(); } public function getValueExpression() : Node\Expr { return $this->value; } /** * Returns constant value * * @deprecated Use getValueExpression() * @return mixed */ public function getValue() { if ($this->compiledValue === null) { $this->compiledValue = (new CompileNodeToValue())->__invoke($this->value, new CompilerContext($this->reflector, $this)); } return $this->compiledValue->value; } /** * Constant is public */ public function isPublic() : bool { return ($this->modifiers & ReflectionClassConstantAdapter::IS_PUBLIC_COMPATIBILITY) === ReflectionClassConstantAdapter::IS_PUBLIC_COMPATIBILITY; } /** * Constant is private */ public function isPrivate() : bool { // Private constant cannot be final return $this->modifiers === ReflectionClassConstantAdapter::IS_PRIVATE_COMPATIBILITY; } /** * Constant is protected */ public function isProtected() : bool { return ($this->modifiers & ReflectionClassConstantAdapter::IS_PROTECTED_COMPATIBILITY) === ReflectionClassConstantAdapter::IS_PROTECTED_COMPATIBILITY; } public function isFinal() : bool { $final = ($this->modifiers & ReflectionClassConstantAdapter::IS_FINAL_COMPATIBILITY) === ReflectionClassConstantAdapter::IS_FINAL_COMPATIBILITY; if ($final) { return \true; } if (BetterReflection::$phpVersion >= 80100) { return \false; } return $this->getDeclaringClass()->isInterface(); } /** * Returns a bitfield of the access modifiers for this constant * * @return int-mask-of */ public function getModifiers() : int { return $this->modifiers; } /** * Get the line number that this constant starts on. * * @return positive-int */ public function getStartLine() : int { return $this->startLine; } /** * Get the line number that this constant ends on. * * @return positive-int */ public function getEndLine() : int { return $this->endLine; } /** @return positive-int */ public function getStartColumn() : int { return $this->startColumn; } /** @return positive-int */ public function getEndColumn() : int { return $this->endColumn; } /** * Get the declaring class */ public function getDeclaringClass() : \PHPStan\BetterReflection\Reflection\ReflectionClass { return $this->declaringClass; } /** * Get the class that implemented the method based on trait use. */ public function getImplementingClass() : \PHPStan\BetterReflection\Reflection\ReflectionClass { return $this->implementingClass; } /** @return non-empty-string|null */ public function getDocComment() : ?string { return $this->docComment; } public function isDeprecated() : bool { return AnnotationHelper::isDeprecated($this->getDocComment()); } /** @return non-empty-string */ public function __toString() : string { return ReflectionClassConstantStringCast::toString($this); } /** @return list */ public function getAttributes() : array { return $this->attributes; } /** @return list */ public function getAttributesByName(string $name) : array { return ReflectionAttributeHelper::filterAttributesByName($this->getAttributes(), $name); } /** * @param class-string $className * * @return list */ public function getAttributesByInstance(string $className) : array { return ReflectionAttributeHelper::filterAttributesByInstance($this->getAttributes(), $className); } /** @return int-mask-of */ private function computeModifiers(ClassConst $node) : int { $modifiers = $node->isFinal() ? ReflectionClassConstantAdapter::IS_FINAL_COMPATIBILITY : 0; $modifiers += $node->isPrivate() ? ReflectionClassConstantAdapter::IS_PRIVATE_COMPATIBILITY : 0; $modifiers += $node->isProtected() ? ReflectionClassConstantAdapter::IS_PROTECTED_COMPATIBILITY : 0; $modifiers += $node->isPublic() ? ReflectionClassConstantAdapter::IS_PUBLIC_COMPATIBILITY : 0; return $modifiers; } } reflector = $reflector; $this->locatedSource = $locatedSource; $this->namespace = $namespace; assert($node instanceof Node\Stmt\Function_ || $node instanceof Node\Expr\Closure || $node instanceof Node\Expr\ArrowFunction); $name = $node instanceof Node\Expr\Closure || $node instanceof Node\Expr\ArrowFunction ? self::CLOSURE_NAME : $node->name->name; assert($name !== ''); $this->name = $name; $this->fillFromNode($node); $isClosure = $node instanceof Node\Expr\Closure || $node instanceof Node\Expr\ArrowFunction; $this->isStatic = $isClosure && $node->static; $this->isClosure = $isClosure; $this->isGenerator = $this->nodeIsOrContainsYield($node); } /** * @deprecated Use Reflector instead. * * @throws IdentifierNotFound */ public static function createFromName(string $functionName) : self { return (new BetterReflection())->reflector()->reflectFunction($functionName); } /** @throws IdentifierNotFound */ public static function createFromClosure(Closure $closure) : self { $configuration = new BetterReflection(); return (new DefaultReflector(new AggregateSourceLocator([$configuration->sourceLocator(), new ClosureSourceLocator($closure, $configuration->phpParser())])))->reflectFunction(self::CLOSURE_NAME); } /** @return non-empty-string */ public function __toString() : string { return ReflectionFunctionStringCast::toString($this); } /** * @internal * * @param non-empty-string|null $namespace * @param \PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node */ public static function createFromNode(Reflector $reflector, $node, LocatedSource $locatedSource, ?string $namespace = null) : self { return new self($reflector, $node, $locatedSource, $namespace); } /** * Get the "short" name of the function (e.g. for A\B\foo, this will return * "foo"). * * @return non-empty-string */ public function getShortName() : string { return $this->name; } /** * Check to see if this function has been disabled (by the PHP INI file * directive `disable_functions`). * * Note - we cannot reflect on internal functions (as there is no PHP source * code we can access. This means, at present, we can only EVER return false * from this function, because you cannot disable user-defined functions. * * @see https://php.net/manual/en/ini.core.php#ini.disable-functions * * @todo https://github.com/Roave/BetterReflection/issues/14 */ public function isDisabled() : bool { return \false; } public function isStatic() : bool { return $this->isStatic; } /** * @throws NotImplemented * @throws FunctionDoesNotExist */ public function getClosure() : Closure { $this->assertIsNoClosure(); $functionName = $this->getName(); $this->assertFunctionExist($functionName); return static function (...$args) use($functionName) { return $functionName(...$args); }; } /** * @throws NotImplemented * @throws FunctionDoesNotExist * @param mixed ...$args * @return mixed */ public function invoke(...$args) { return $this->invokeArgs($args); } /** * @param array $args * * @throws NotImplemented * @throws FunctionDoesNotExist * @return mixed */ public function invokeArgs(array $args = []) { $this->assertIsNoClosure(); $functionName = $this->getName(); $this->assertFunctionExist($functionName); return $functionName(...$args); } /** @throws NotImplemented */ private function assertIsNoClosure() : void { if ($this->isClosure()) { throw new NotImplemented('Not implemented for closures'); } } /** @throws FunctionDoesNotExist */ private function assertFunctionExist(string $functionName) : void { if (!function_exists($functionName)) { throw FunctionDoesNotExist::fromName($functionName); } } } betterReflectionProperty = $betterReflectionProperty; unset($this->name); unset($this->class); } public function __toString() : string { return $this->betterReflectionProperty->__toString(); } public function getName() : string { return $this->betterReflectionProperty->getName(); } /** * {@inheritDoc} * @return mixed */ #[\ReturnTypeWillChange] public function getValue($object = null) { try { return $this->betterReflectionProperty->getValue($object); } catch (NoObjectProvided $exception) { return null; } catch (Throwable $e) { throw new CoreReflectionException($e->getMessage(), 0, $e); } } /** @psalm-suppress MethodSignatureMismatch * @param mixed $objectOrValue * @param mixed $value */ public function setValue($objectOrValue, $value = null) : void { try { $this->betterReflectionProperty->setValue($objectOrValue, $value); } catch (NoObjectProvided $exception) { throw new ArgumentCountError('ReflectionProperty::setValue() expects exactly 2 arguments, 1 given'); } catch (NotAnObject $exception) { throw new TypeError(sprintf('ReflectionProperty::setValue(): Argument #1 ($objectOrValue) must be of type object, %s given', gettype($objectOrValue))); } catch (Throwable $e) { throw new CoreReflectionException($e->getMessage(), 0, $e); } } public function hasType() : bool { return $this->betterReflectionProperty->hasType(); } /** * @return ReflectionUnionType|ReflectionNamedType|ReflectionIntersectionType|null */ public function getType() : ?\ReflectionType { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionType::fromTypeOrNull($this->betterReflectionProperty->getType()); } public function isPublic() : bool { return $this->betterReflectionProperty->isPublic(); } public function isPrivate() : bool { return $this->betterReflectionProperty->isPrivate(); } public function isProtected() : bool { return $this->betterReflectionProperty->isProtected(); } public function isStatic() : bool { return $this->betterReflectionProperty->isStatic(); } public function isDefault() : bool { return $this->betterReflectionProperty->isDefault(); } public function getModifiers() : int { return $this->betterReflectionProperty->getModifiers(); } public function getDeclaringClass() : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($this->betterReflectionProperty->getImplementingClass()); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getDocComment() { return $this->betterReflectionProperty->getDocComment() ?? \false; } /** * {@inheritDoc} * @codeCoverageIgnore * @infection-ignore-all */ public function setAccessible($accessible) : void { } public function hasDefaultValue() : bool { return $this->betterReflectionProperty->hasDefaultValue(); } /** * @deprecated Use getDefaultValueExpression() * @return mixed */ #[\ReturnTypeWillChange] public function getDefaultValue() { return $this->betterReflectionProperty->getDefaultValue(); } /** * @deprecated Use getDefaultValueExpression() */ public function getDefaultValueExpr() : Expr { return $this->betterReflectionProperty->getDefaultValueExpression(); } public function getDefaultValueExpression() : Expr { return $this->betterReflectionProperty->getDefaultValueExpression(); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function isInitialized($object = null) { try { return $this->betterReflectionProperty->isInitialized($object); } catch (Throwable $e) { throw new CoreReflectionException($e->getMessage(), 0, $e); } } public function isPromoted() : bool { return $this->betterReflectionProperty->isPromoted(); } /** * @param class-string|null $name * * @return list */ public function getAttributes(?string $name = null, int $flags = 0) : array { if ($flags !== 0 && $flags !== \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); } if ($name !== null && $flags !== 0) { $attributes = $this->betterReflectionProperty->getAttributesByInstance($name); } elseif ($name !== null) { $attributes = $this->betterReflectionProperty->getAttributesByName($name); } else { $attributes = $this->betterReflectionProperty->getAttributes(); } return array_map(static function (BetterReflectionAttribute $betterReflectionAttribute) { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttributeFactory::create($betterReflectionAttribute); }, $attributes); } public function isReadOnly() : bool { return $this->betterReflectionProperty->isReadOnly(); } /** * @return mixed */ public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionProperty->getName(); } if ($name === 'class') { return $this->betterReflectionProperty->getImplementingClass()->getName(); } throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name)); } public function getBetterReflection() : BetterReflectionProperty { return $this->betterReflectionProperty; } } name); unset($this->class); } /** * Get the name of the reflection (e.g. if this is a ReflectionClass this * will be the class name). */ public function getName() : string { return $this->betterReflectionEnumCase->getName(); } public function hasType() : bool { return \false; } public function getType() : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\Adapter\ReflectionIntersectionType|null { return null; } public function getValue() : UnitEnum { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } public function isPublic() : bool { return \true; } public function isPrivate() : bool { return \false; } public function isProtected() : bool { return \false; } public function getModifiers() : int { return self::IS_PUBLIC; } public function getDeclaringClass() : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($this->betterReflectionEnumCase->getDeclaringClass()); } public function getDocComment() : string|false { return $this->betterReflectionEnumCase->getDocComment() ?? \false; } /** @return non-empty-string */ public function __toString() : string { return $this->betterReflectionEnumCase->__toString(); } /** * @param class-string|null $name * * @return list */ public function getAttributes(string|null $name = null, int $flags = 0) : array { if ($flags !== 0 && $flags !== \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); } if ($name !== null && $flags !== 0) { $attributes = $this->betterReflectionEnumCase->getAttributesByInstance($name); } elseif ($name !== null) { $attributes = $this->betterReflectionEnumCase->getAttributesByName($name); } else { $attributes = $this->betterReflectionEnumCase->getAttributes(); } /** @psalm-suppress ImpureFunctionCall */ return array_map(static fn(BetterReflectionAttribute $betterReflectionAttribute): \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute|\PHPStan\BetterReflection\Reflection\Adapter\FakeReflectionAttribute => \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); } public function isFinal() : bool { return \true; } public function isEnumCase() : bool { return \true; } public function getEnum() : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnum { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnum($this->betterReflectionEnumCase->getDeclaringEnum()); } /** * @deprecated Use getValueExpression() */ public function getBackingValue() : int|string { return $this->betterReflectionEnumCase->getValue(); } /** * @deprecated Use getValueExpression() */ public function getValueExpr() : Expr { return $this->getValueExpression(); } public function getValueExpression() : Expr { return $this->betterReflectionEnumCase->getValueExpression(); } public function __get(string $name) : mixed { if ($name === 'name') { return $this->betterReflectionEnumCase->getName(); } if ($name === 'class') { return $this->betterReflectionEnumCase->getDeclaringClass()->getName(); } throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name)); } } betterReflectionType = $betterReflectionType; } /** @return non-empty-list */ public function getTypes() : array { return array_map(static function (BetterReflectionNamedType $type) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType { $adapterType = \PHPStan\BetterReflection\Reflection\Adapter\ReflectionType::fromType($type); assert($adapterType instanceof \PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType); return $adapterType; }, $this->betterReflectionType->getTypes()); } /** @return non-empty-string */ public function __toString() : string { return $this->betterReflectionType->__toString(); } /** @return false */ public function allowsNull() : bool { return $this->betterReflectionType->allowsNull(); } } * @psalm-suppress PropertyNotSetInConstructor */ final class ReflectionClass extends CoreReflectionClass { /** @internal */ public const IS_READONLY_COMPATIBILITY = 65536; /** * @var BetterReflectionClass|BetterReflectionEnum */ private $betterReflectionClass; /** * @param BetterReflectionClass|BetterReflectionEnum $betterReflectionClass */ public function __construct($betterReflectionClass) { $this->betterReflectionClass = $betterReflectionClass; unset($this->name); } /** @return non-empty-string */ public function __toString() : string { return $this->betterReflectionClass->__toString(); } /** * @return mixed */ public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionClass->getName(); } throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name)); } /** * @psalm-mutation-free * @return class-string */ public function getName() : string { return $this->betterReflectionClass->getName(); } /** @psalm-mutation-free */ public function isAnonymous() : bool { return $this->betterReflectionClass->isAnonymous(); } /** @psalm-mutation-free */ public function isInternal() : bool { return $this->betterReflectionClass->isInternal(); } /** @psalm-mutation-free */ public function isUserDefined() : bool { return $this->betterReflectionClass->isUserDefined(); } /** @psalm-mutation-free */ public function isInstantiable() : bool { return $this->betterReflectionClass->isInstantiable(); } /** @psalm-mutation-free */ public function isCloneable() : bool { return $this->betterReflectionClass->isCloneable(); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getFileName() { $fileName = $this->betterReflectionClass->getFileName(); return $fileName !== null ? FileHelper::normalizeSystemPath($fileName) : \false; } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getStartLine() { return $this->betterReflectionClass->getStartLine(); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getEndLine() { return $this->betterReflectionClass->getEndLine(); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getDocComment() { return $this->betterReflectionClass->getDocComment() ?? \false; } /** * @psalm-mutation-free * @return ReflectionMethod|null */ public function getConstructor() : ?CoreReflectionMethod { $constructor = $this->betterReflectionClass->getConstructor(); if ($constructor === null) { return null; } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod($constructor); } /** * {@inheritDoc} */ public function hasMethod($name) : bool { if ($name === '') { return \false; } return $this->betterReflectionClass->hasMethod($name); } /** * @param string $name * @return ReflectionMethod */ public function getMethod($name) : CoreReflectionMethod { $method = $name !== '' ? $this->betterReflectionClass->getMethod($name) : null; if ($method === null) { throw new CoreReflectionException(sprintf('Method %s::%s() does not exist', $this->betterReflectionClass->getName(), $name)); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod($method); } /** * @param int-mask-of|null $filter * @return ReflectionMethod[] */ public function getMethods($filter = null) : array { /** @psalm-suppress ImpureFunctionCall */ return array_values(array_map(static function (BetterReflectionMethod $method) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod($method); }, $this->betterReflectionClass->getMethods($filter ?? 0))); } /** * {@inheritDoc} */ public function hasProperty($name) : bool { if ($name === '') { return \false; } return $this->betterReflectionClass->hasProperty($name); } /** * @param string $name * @return ReflectionProperty */ public function getProperty($name) : \ReflectionProperty { $betterReflectionProperty = $name !== '' ? $this->betterReflectionClass->getProperty($name) : null; if ($betterReflectionProperty === null) { throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionClass->getName(), $name)); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty($betterReflectionProperty); } /** * @param int-mask-of|null $filter * @return ReflectionProperty[] */ public function getProperties($filter = null) : array { /** @psalm-suppress ImpureFunctionCall */ return array_values(array_map(static function (BetterReflectionProperty $property) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty($property); }, $this->betterReflectionClass->getProperties($filter ?? 0))); } /** * {@inheritDoc} */ public function hasConstant($name) : bool { if ($name === '') { return \false; } if ($this->betterReflectionClass instanceof BetterReflectionEnum && $this->betterReflectionClass->hasCase($name)) { return \true; } return $this->betterReflectionClass->hasConstant($name); } /** * @deprecated Use getReflectionConstants() * * @param int-mask-of|null $filter * * @return array * * @psalm-mutation-free */ public function getConstants(?int $filter = null) : array { /** @psalm-suppress ImpureFunctionCall */ return array_map(function ($betterConstantOrEnumCase) { return $this->getConstantValue($betterConstantOrEnumCase); }, $this->filterBetterReflectionClassConstants($filter)); } /** * @deprecated Use getReflectionConstant() * @return mixed */ #[\ReturnTypeWillChange] public function getConstant($name) { if ($name === '') { return \false; } if ($this->betterReflectionClass instanceof BetterReflectionEnum) { $enumCase = $this->betterReflectionClass->getCase($name); if ($enumCase !== null) { return $this->getConstantValue($enumCase); } } $betterReflectionConstant = $this->betterReflectionClass->getConstant($name); if ($betterReflectionConstant === null) { return \false; } return $betterReflectionConstant->getValue(); } /** @psalm-pure * @param BetterReflectionClassConstant|BetterReflectionEnumCase $betterConstantOrEnumCase * @return mixed */ private function getConstantValue($betterConstantOrEnumCase) { if ($betterConstantOrEnumCase instanceof BetterReflectionEnumCase) { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } return $betterConstantOrEnumCase->getValue(); } /** * @param string $name * @return ReflectionClassConstant|false */ #[\ReturnTypeWillChange] public function getReflectionConstant($name) { if ($name === '') { return \false; } if ($this->betterReflectionClass instanceof BetterReflectionEnum) { $enumCase = $this->betterReflectionClass->getCase($name); if ($enumCase !== null) { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant($enumCase); } } $betterReflectionConstant = $this->betterReflectionClass->getConstant($name); if ($betterReflectionConstant === null) { return \false; } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant($betterReflectionConstant); } /** * @param int-mask-of|null $filter * * @return list * * @psalm-mutation-free */ public function getReflectionConstants(?int $filter = null) : array { return array_values(array_map(static function ($betterConstantOrEnum) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant($betterConstantOrEnum); }, $this->filterBetterReflectionClassConstants($filter))); } /** * @param int-mask-of|null $filter * * @return array * * @psalm-mutation-free */ private function filterBetterReflectionClassConstants(?int $filter) : array { $reflectionConstants = $this->betterReflectionClass->getConstants($filter ?? 0); if ($this->betterReflectionClass instanceof BetterReflectionEnum && ($filter === null || $filter & \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant::IS_PUBLIC_COMPATIBILITY)) { $reflectionConstants += $this->betterReflectionClass->getCases(); } return $reflectionConstants; } /** @return list */ public function getInterfaceClassNames() : array { return $this->betterReflectionClass->getInterfaceClassNames(); } /** * @psalm-mutation-free * @return array */ public function getInterfaces() : array { /** @psalm-suppress ImpureFunctionCall */ return array_map(static function (BetterReflectionClass $interface) : self { return new self($interface); }, $this->betterReflectionClass->getInterfaces()); } /** * @return list * * @psalm-mutation-free */ public function getInterfaceNames() : array { return $this->betterReflectionClass->getInterfaceNames(); } /** @psalm-mutation-free */ public function isInterface() : bool { return $this->betterReflectionClass->isInterface(); } /** @return list */ public function getTraitClassNames() : array { return $this->betterReflectionClass->getTraitClassNames(); } /** * @psalm-mutation-free * @return array */ public function getTraits() : array { $traits = $this->betterReflectionClass->getTraits(); /** @var list $traitNames */ $traitNames = array_map(static function (BetterReflectionClass $trait) : string { return $trait->getName(); }, $traits); /** @psalm-suppress ImpureFunctionCall */ return array_combine($traitNames, array_map(static function (BetterReflectionClass $trait) : self { return new self($trait); }, $traits)); } /** * @return list * * @psalm-mutation-free */ public function getTraitNames() : array { return $this->betterReflectionClass->getTraitNames(); } /** * @return array * * @psalm-mutation-free */ public function getTraitAliases() : array { return $this->betterReflectionClass->getTraitAliases(); } /** @psalm-mutation-free */ public function isTrait() : bool { return $this->betterReflectionClass->isTrait(); } /** @psalm-mutation-free */ public function isAbstract() : bool { return $this->betterReflectionClass->isAbstract(); } /** @psalm-mutation-free */ public function isFinal() : bool { return $this->betterReflectionClass->isFinal(); } /** @psalm-mutation-free */ public function isReadOnly() : bool { return $this->betterReflectionClass->isReadOnly(); } /** @psalm-mutation-free */ public function getModifiers() : int { return $this->betterReflectionClass->getModifiers(); } /** * {@inheritDoc} */ public function isInstance($object) : bool { return $this->betterReflectionClass->isInstance($object); } /** * @return object * @param mixed $arg * @param mixed $args */ #[\ReturnTypeWillChange] public function newInstance($arg = null, ...$args) { ClassExistenceChecker::classExists($this->getName(), \true); $reflection = new CoreReflectionClass($this->getName()); return $reflection->newInstance(...func_get_args()); } public function newInstanceWithoutConstructor() : object { ClassExistenceChecker::classExists($this->getName(), \true); $reflection = new CoreReflectionClass($this->getName()); return $reflection->newInstanceWithoutConstructor(); } public function newInstanceArgs(?array $args = null) : object { ClassExistenceChecker::classExists($this->getName(), \true); $reflection = new CoreReflectionClass($this->getName()); return $reflection->newInstanceArgs($args); } /** @return class-string|null */ public function getParentClassName() : ?string { return $this->betterReflectionClass->getParentClassName(); } /** * @return self|false */ #[\ReturnTypeWillChange] public function getParentClass() { $parentClass = $this->betterReflectionClass->getParentClass(); if ($parentClass === null) { return \false; } return new self($parentClass); } /** * {@inheritDoc} */ public function isSubclassOf($class) : bool { $realParentClassNames = $this->betterReflectionClass->getParentClassNames(); $parentClassNames = array_combine(array_map(static function (string $parentClassName) : string { return strtolower($parentClassName); }, $realParentClassNames), $realParentClassNames); $className = $class instanceof CoreReflectionClass ? $class->getName() : $class; $lowercasedClassName = strtolower($className); $realParentClassName = $parentClassNames[$lowercasedClassName] ?? $className; if ($this->betterReflectionClass->isSubclassOf($realParentClassName)) { return \true; } return $this->implementsInterface($className); } /** * @return array * * @psalm-suppress LessSpecificImplementedReturnType */ public function getStaticProperties() : array { return $this->betterReflectionClass->getStaticProperties(); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getStaticPropertyValue($name, $default = null) { $betterReflectionProperty = $name !== '' ? $this->betterReflectionClass->getProperty($name) : null; if ($betterReflectionProperty === null) { if (func_num_args() === 2) { return $default; } throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionClass->getName(), $name)); } $property = new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty($betterReflectionProperty); if (!$property->isStatic()) { throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionClass->getName(), $name)); } return $property->getValue(); } /** * {@inheritDoc} */ public function setStaticPropertyValue($name, $value) : void { $betterReflectionProperty = $name !== '' ? $this->betterReflectionClass->getProperty($name) : null; if ($betterReflectionProperty === null) { throw new CoreReflectionException(sprintf('Class %s does not have a property named %s', $this->betterReflectionClass->getName(), $name)); } $property = new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty($betterReflectionProperty); if (!$property->isStatic()) { throw new CoreReflectionException(sprintf('Class %s does not have a property named %s', $this->betterReflectionClass->getName(), $name)); } $property->setValue($value); } /** * @return array * * @psalm-mutation-free */ public function getDefaultProperties() : array { return $this->betterReflectionClass->getDefaultProperties(); } /** @psalm-mutation-free */ public function isIterateable() : bool { return $this->betterReflectionClass->isIterateable(); } /** @psalm-mutation-free */ public function isIterable() : bool { return $this->isIterateable(); } /** * @param \ReflectionClass|string $interface */ public function implementsInterface($interface) : bool { $realInterfaceNames = $this->betterReflectionClass->getInterfaceNames(); $interfaceNames = array_combine(array_map(static function (string $interfaceName) : string { return strtolower($interfaceName); }, $realInterfaceNames), $realInterfaceNames); $interfaceName = $interface instanceof CoreReflectionClass ? $interface->getName() : $interface; $lowercasedInterfaceName = strtolower($interfaceName); $realInterfaceName = $interfaceNames[$lowercasedInterfaceName] ?? $interfaceName; return $this->betterReflectionClass->implementsInterface($realInterfaceName); } /** @psalm-mutation-free */ public function getExtension() : ?CoreReflectionExtension { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getExtensionName() { return $this->betterReflectionClass->getExtensionName() ?? \false; } /** @psalm-mutation-free */ public function inNamespace() : bool { return $this->betterReflectionClass->inNamespace(); } /** @psalm-mutation-free */ public function getNamespaceName() : string { return $this->betterReflectionClass->getNamespaceName() ?? ''; } /** @psalm-mutation-free */ public function getShortName() : string { return $this->betterReflectionClass->getShortName(); } /** * @param class-string|null $name * * @return list */ public function getAttributes(?string $name = null, int $flags = 0) : array { if ($flags !== 0 && $flags !== \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); } if ($name !== null && $flags !== 0) { $attributes = $this->betterReflectionClass->getAttributesByInstance($name); } elseif ($name !== null) { $attributes = $this->betterReflectionClass->getAttributesByName($name); } else { $attributes = $this->betterReflectionClass->getAttributes(); } /** @psalm-suppress ImpureFunctionCall */ return array_map(static function (BetterReflectionAttribute $betterReflectionAttribute) { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttributeFactory::create($betterReflectionAttribute); }, $attributes); } /** @psalm-mutation-free */ public function isEnum() : bool { return $this->betterReflectionClass->isEnum(); } } betterReflectionObject = $betterReflectionObject; unset($this->name); } public function __toString() : string { return $this->betterReflectionObject->__toString(); } public function getName() : string { return $this->betterReflectionObject->getName(); } public function isInternal() : bool { return $this->betterReflectionObject->isInternal(); } public function isUserDefined() : bool { return $this->betterReflectionObject->isUserDefined(); } public function isInstantiable() : bool { return $this->betterReflectionObject->isInstantiable(); } public function isCloneable() : bool { return $this->betterReflectionObject->isCloneable(); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getFileName() { $fileName = $this->betterReflectionObject->getFileName(); return $fileName !== null ? FileHelper::normalizeSystemPath($fileName) : \false; } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getStartLine() { return $this->betterReflectionObject->getStartLine(); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getEndLine() { return $this->betterReflectionObject->getEndLine(); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getDocComment() { return $this->betterReflectionObject->getDocComment() ?? \false; } public function getConstructor() : ?\PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod { $constructor = $this->betterReflectionObject->getConstructor(); if ($constructor === null) { return null; } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod($constructor); } /** * {@inheritDoc} */ public function hasMethod($name) : bool { if ($name === '') { return \false; } return $this->betterReflectionObject->hasMethod($this->getMethodRealName($name)); } /** * {@inheritDoc} */ public function getMethod($name) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod { $method = $name !== '' ? $this->betterReflectionObject->getMethod($this->getMethodRealName($name)) : null; if ($method === null) { throw new CoreReflectionException(sprintf('Method %s::%s() does not exist', $this->betterReflectionObject->getName(), $name)); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod($method); } /** * @param non-empty-string $name * * @return non-empty-string */ private function getMethodRealName(string $name) : string { $realMethodNames = array_map(static function (BetterReflectionMethod $method) : string { return $method->getName(); }, $this->betterReflectionObject->getMethods()); $methodNames = array_combine(array_map(static function (string $methodName) : string { return strtolower($methodName); }, $realMethodNames), $realMethodNames); $lowercasedName = strtolower($name); return $methodNames[$lowercasedName] ?? $name; } /** * @param int-mask-of|null $filter * @return ReflectionMethod[] */ public function getMethods($filter = null) : array { return array_values(array_map(static function (BetterReflectionMethod $method) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod($method); }, $this->betterReflectionObject->getMethods($filter ?? 0))); } /** * {@inheritDoc} */ public function hasProperty($name) : bool { if ($name === '') { return \false; } return $this->betterReflectionObject->hasProperty($name); } /** * @param string $name * @return ReflectionProperty */ public function getProperty($name) : \ReflectionProperty { $property = $name !== '' ? $this->betterReflectionObject->getProperty($name) : null; if ($property === null) { throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionObject->getName(), $name)); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty($property); } /** * @param int-mask-of|null $filter * @return ReflectionProperty[] */ public function getProperties($filter = null) : array { return array_values(array_map(static function (BetterReflectionProperty $property) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty($property); }, $this->betterReflectionObject->getProperties($filter ?? 0))); } /** * {@inheritDoc} */ public function hasConstant($name) : bool { if ($name === '') { return \false; } return $this->betterReflectionObject->hasConstant($name); } /** * @param int-mask-of|null $filter * * @return array */ public function getConstants(?int $filter = null) : array { return array_map(static function (BetterReflectionClassConstant $betterConstant) { return $betterConstant->getValue(); }, $this->betterReflectionObject->getConstants($filter ?? 0)); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getConstant($name) { if ($name === '') { return \false; } $betterReflectionConstant = $this->betterReflectionObject->getConstant($name); if ($betterReflectionConstant === null) { return \false; } return $betterReflectionConstant->getValue(); } /** * @param string $name * @return ReflectionClassConstant|false */ #[\ReturnTypeWillChange] public function getReflectionConstant($name) { if ($name === '') { return \false; } $betterReflectionConstant = $this->betterReflectionObject->getConstant($name); if ($betterReflectionConstant === null) { return \false; } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant($betterReflectionConstant); } /** * @param int-mask-of|null $filter * * @return list */ public function getReflectionConstants(?int $filter = null) : array { return array_values(array_map(static function (BetterReflectionClassConstant $betterConstant) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant($betterConstant); }, $this->betterReflectionObject->getConstants($filter ?? 0))); } /** @return array */ public function getInterfaces() : array { return array_map(static function (BetterReflectionClass $interface) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($interface); }, $this->betterReflectionObject->getInterfaces()); } /** @return list */ public function getInterfaceNames() : array { return $this->betterReflectionObject->getInterfaceNames(); } public function isInterface() : bool { return $this->betterReflectionObject->isInterface(); } /** @return array */ public function getTraits() : array { $traits = $this->betterReflectionObject->getTraits(); /** @var list $traitNames */ $traitNames = array_map(static function (BetterReflectionClass $trait) : string { return $trait->getName(); }, $traits); return array_combine($traitNames, array_map(static function (BetterReflectionClass $trait) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($trait); }, $traits)); } /** @return list */ public function getTraitNames() : array { return $this->betterReflectionObject->getTraitNames(); } /** @return array */ public function getTraitAliases() : array { return $this->betterReflectionObject->getTraitAliases(); } public function isTrait() : bool { return $this->betterReflectionObject->isTrait(); } public function isAbstract() : bool { return $this->betterReflectionObject->isAbstract(); } public function isFinal() : bool { return $this->betterReflectionObject->isFinal(); } public function isReadOnly() : bool { return $this->betterReflectionObject->isReadOnly(); } public function getModifiers() : int { return $this->betterReflectionObject->getModifiers(); } /** * {@inheritDoc} */ public function isInstance($object) : bool { return $this->betterReflectionObject->isInstance($object); } /** * @param mixed $arg * @param mixed ...$args * * @return object */ #[\ReturnTypeWillChange] public function newInstance($arg = null, ...$args) { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function newInstanceWithoutConstructor() { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function newInstanceArgs(?array $args = null) { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } /** * @return ReflectionClass|false */ #[\ReturnTypeWillChange] public function getParentClass() { $parentClass = $this->betterReflectionObject->getParentClass(); if ($parentClass === null) { return \false; } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($parentClass); } /** * {@inheritDoc} */ public function isSubclassOf($class) : bool { $realParentClassNames = $this->betterReflectionObject->getParentClassNames(); $parentClassNames = array_combine(array_map(static function (string $parentClassName) : string { return strtolower($parentClassName); }, $realParentClassNames), $realParentClassNames); $className = $class instanceof CoreReflectionClass ? $class->getName() : $class; $lowercasedClassName = strtolower($className); $realParentClassName = $parentClassNames[$lowercasedClassName] ?? $className; return $this->betterReflectionObject->isSubclassOf($realParentClassName); } /** * @return array * * @psalm-suppress LessSpecificImplementedReturnType */ public function getStaticProperties() : array { return $this->betterReflectionObject->getStaticProperties(); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getStaticPropertyValue($name, $default = null) { $betterReflectionProperty = $name !== '' ? $this->betterReflectionObject->getProperty($name) : null; if ($betterReflectionProperty === null) { if (func_num_args() === 2) { return $default; } throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionObject->getName(), $name)); } $property = new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty($betterReflectionProperty); if (!$property->isStatic()) { throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionObject->getName(), $name)); } return $property->getValue(); } /** * {@inheritDoc} */ public function setStaticPropertyValue($name, $value) : void { $betterReflectionProperty = $name !== '' ? $this->betterReflectionObject->getProperty($name) : null; if ($betterReflectionProperty === null) { throw new CoreReflectionException(sprintf('Class %s does not have a property named %s', $this->betterReflectionObject->getName(), $name)); } $property = new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty($betterReflectionProperty); if (!$property->isStatic()) { throw new CoreReflectionException(sprintf('Class %s does not have a property named %s', $this->betterReflectionObject->getName(), $name)); } $property->setValue($value); } /** @return array|null> */ public function getDefaultProperties() : array { return $this->betterReflectionObject->getDefaultProperties(); } public function isIterateable() : bool { return $this->betterReflectionObject->isIterateable(); } public function isIterable() : bool { return $this->isIterateable(); } /** * @param \ReflectionClass|string $interface */ public function implementsInterface($interface) : bool { $realInterfaceNames = $this->betterReflectionObject->getInterfaceNames(); $interfaceNames = array_combine(array_map(static function (string $interfaceName) : string { return strtolower($interfaceName); }, $realInterfaceNames), $realInterfaceNames); $interfaceName = $interface instanceof CoreReflectionClass ? $interface->getName() : $interface; $lowercasedInterfaceName = strtolower($interfaceName); $realInterfaceName = $interfaceNames[$lowercasedInterfaceName] ?? $interfaceName; return $this->betterReflectionObject->implementsInterface($realInterfaceName); } public function getExtension() : ?CoreReflectionExtension { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getExtensionName() { return $this->betterReflectionObject->getExtensionName() ?? \false; } public function inNamespace() : bool { return $this->betterReflectionObject->inNamespace(); } public function getNamespaceName() : string { return $this->betterReflectionObject->getNamespaceName() ?? ''; } public function getShortName() : string { return $this->betterReflectionObject->getShortName(); } public function isAnonymous() : bool { return $this->betterReflectionObject->isAnonymous(); } /** * @param class-string|null $name * * @return list */ public function getAttributes(?string $name = null, int $flags = 0) : array { if ($flags !== 0 && $flags !== \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); } if ($name !== null && $flags !== 0) { $attributes = $this->betterReflectionObject->getAttributesByInstance($name); } elseif ($name !== null) { $attributes = $this->betterReflectionObject->getAttributesByName($name); } else { $attributes = $this->betterReflectionObject->getAttributes(); } return array_map(static function (BetterReflectionAttribute $betterReflectionAttribute) { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttributeFactory::create($betterReflectionAttribute); }, $attributes); } public function isEnum() : bool { return $this->betterReflectionObject->isEnum(); } /** * @return mixed */ public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionObject->getName(); } throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name)); } } */ final class ReflectionAttribute extends CoreReflectionAttribute { /** * @var BetterReflectionAttribute */ private $betterReflectionAttribute; public function __construct(BetterReflectionAttribute $betterReflectionAttribute) { $this->betterReflectionAttribute = $betterReflectionAttribute; } /** @psalm-mutation-free */ public function getName() : string { return $this->betterReflectionAttribute->getName(); } /** * @return int-mask-of * * @psalm-mutation-free * @psalm-suppress ImplementedReturnTypeMismatch */ public function getTarget() : int { return $this->betterReflectionAttribute->getTarget(); } /** @psalm-mutation-free */ public function isRepeated() : bool { return $this->betterReflectionAttribute->isRepeated(); } /** * @deprecated Use getArgumentsExpressions() * @return array */ public function getArguments() : array { return $this->betterReflectionAttribute->getArguments(); } /** @return array */ public function getArgumentsExpressions() : array { return $this->betterReflectionAttribute->getArgumentsExpressions(); } public function newInstance() : object { $class = $this->getName(); return new $class(...$this->getArguments()); } /** @return non-empty-string */ public function __toString() : string { return $this->betterReflectionAttribute->__toString(); } } betterReflectionType = $betterReflectionType; $this->allowsNull = $allowsNull; } public function getName() : string { return $this->betterReflectionType->getName(); } /** @return non-empty-string */ public function __toString() : string { $type = strtolower($this->betterReflectionType->getName()); if (!$this->allowsNull || $type === 'mixed' || $type === 'null') { return $this->betterReflectionType->__toString(); } return '?' . $this->betterReflectionType->__toString(); } public function allowsNull() : bool { return $this->allowsNull; } public function isBuiltin() : bool { $type = strtolower($this->betterReflectionType->getName()); if ($type === 'self' || $type === 'parent' || $type === 'static') { return \false; } return $this->betterReflectionType->isBuiltin(); } public function isIdentifier() : bool { return $this->betterReflectionType->isIdentifier(); } } betterReflectionParameter = $betterReflectionParameter; unset($this->name); } /** @return non-empty-string */ public function __toString() : string { return $this->betterReflectionParameter->__toString(); } public function getName() : string { return $this->betterReflectionParameter->getName(); } public function isPassedByReference() : bool { return $this->betterReflectionParameter->isPassedByReference(); } public function canBePassedByValue() : bool { return $this->betterReflectionParameter->canBePassedByValue(); } /** * @return ReflectionFunction|ReflectionMethod */ public function getDeclaringFunction() : CoreReflectionFunctionAbstract { $function = $this->betterReflectionParameter->getDeclaringFunction(); if ($function instanceof BetterReflectionMethod) { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod($function); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionFunction($function); } /** @return ReflectionClass|null */ public function getDeclaringClass() : ?CoreReflectionClass { $declaringClass = $this->betterReflectionParameter->getDeclaringClass(); if ($declaringClass === null) { return null; } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($declaringClass); } /** @return ReflectionClass|null */ public function getClass() : ?CoreReflectionClass { $type = $this->betterReflectionParameter->getType(); if ($type === null) { return null; } if ($type instanceof BetterReflectionIntersectionType) { return null; } if ($type instanceof BetterReflectionNamedType) { $classType = $type; } else { $unionTypes = $type->getTypes(); if (count($unionTypes) !== 2) { return null; } if (!$type->allowsNull()) { return null; } foreach ($unionTypes as $unionInnerType) { if (!$unionInnerType instanceof BetterReflectionNamedType) { return null; } if ($unionInnerType->allowsNull()) { continue; } $classType = $unionInnerType; break; } } try { /** @phpstan-ignore-next-line */ return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($classType->getClass()); } catch (LogicException $exception) { return null; } } public function isArray() : bool { return $this->isType($this->betterReflectionParameter->getType(), 'array'); } public function isCallable() : bool { return $this->isType($this->betterReflectionParameter->getType(), 'callable'); } /** * For isArray() and isCallable(). * @param BetterReflectionNamedType|BetterReflectionUnionType|BetterReflectionIntersectionType|null $typeReflection */ private function isType($typeReflection, string $type) : bool { if ($typeReflection === null) { return \false; } if ($typeReflection instanceof BetterReflectionIntersectionType) { return \false; } $isOneOfAllowedTypes = static function (BetterReflectionType $namedType, string ...$types) : bool { foreach ($types as $type) { if ($namedType instanceof BetterReflectionNamedType && strtolower($namedType->getName()) === $type) { return \true; } } return \false; }; if ($typeReflection instanceof BetterReflectionUnionType) { $unionTypes = $typeReflection->getTypes(); foreach ($unionTypes as $unionType) { if (!$isOneOfAllowedTypes($unionType, $type, 'null')) { return \false; } } return \true; } return $isOneOfAllowedTypes($typeReflection, $type); } public function allowsNull() : bool { return $this->betterReflectionParameter->allowsNull(); } public function getPosition() : int { return $this->betterReflectionParameter->getPosition(); } public function isOptional() : bool { return $this->betterReflectionParameter->isOptional(); } public function isVariadic() : bool { return $this->betterReflectionParameter->isVariadic(); } public function isDefaultValueAvailable() : bool { return $this->betterReflectionParameter->isDefaultValueAvailable(); } /** * @deprecated Use getDefaultValueExpression() */ #[\ReturnTypeWillChange] public function getDefaultValue() { return $this->betterReflectionParameter->getDefaultValue(); } /** * @deprecated Use getDefaultValueExpression() */ public function getDefaultValueExpr() : Expr { return $this->betterReflectionParameter->getDefaultValueExpression(); } public function getDefaultValueExpression() : Expr { return $this->betterReflectionParameter->getDefaultValueExpression(); } public function isDefaultValueConstant() : bool { return $this->betterReflectionParameter->isDefaultValueConstant(); } public function getDefaultValueConstantName() : string { return $this->betterReflectionParameter->getDefaultValueConstantName(); } public function hasType() : bool { return $this->betterReflectionParameter->hasType(); } /** * @return ReflectionUnionType|ReflectionNamedType|ReflectionIntersectionType|null */ public function getType() : ?\ReflectionType { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionType::fromTypeOrNull($this->betterReflectionParameter->getType()); } public function isPromoted() : bool { return $this->betterReflectionParameter->isPromoted(); } /** * @param class-string|null $name * * @return list */ public function getAttributes(?string $name = null, int $flags = 0) : array { if ($flags !== 0 && $flags !== \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); } if ($name !== null && $flags !== 0) { $attributes = $this->betterReflectionParameter->getAttributesByInstance($name); } elseif ($name !== null) { $attributes = $this->betterReflectionParameter->getAttributesByName($name); } else { $attributes = $this->betterReflectionParameter->getAttributes(); } /** @psalm-suppress ImpureFunctionCall */ return array_map(static function (BetterReflectionAttribute $betterReflectionAttribute) { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttributeFactory::create($betterReflectionAttribute); }, $attributes); } /** * @return mixed */ public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionParameter->getName(); } throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name)); } } getTypes(), static function (BetterReflectionType $type) : bool { return !($type instanceof BetterReflectionNamedType && $type->getName() === 'null'); })); if ($betterReflectionType->allowsNull() && count($nonNullTypes) === 1 && $nonNullTypes[0] instanceof BetterReflectionNamedType) { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType($nonNullTypes[0], \true); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionUnionType($betterReflectionType); } if ($betterReflectionType instanceof BetterReflectionIntersectionType) { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionIntersectionType($betterReflectionType); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType($betterReflectionType, $betterReflectionType->allowsNull()); } } betterReflectionType = $betterReflectionType; } /** @return non-empty-list */ public function getTypes() : array { return array_map(static function (BetterReflectionType $type) { $adapterType = \PHPStan\BetterReflection\Reflection\Adapter\ReflectionType::fromType($type); assert($adapterType instanceof \PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType || $adapterType instanceof \PHPStan\BetterReflection\Reflection\Adapter\ReflectionIntersectionType); return $adapterType; }, $this->betterReflectionType->getTypes()); } /** @return non-empty-string */ public function __toString() : string { return $this->betterReflectionType->__toString(); } public function allowsNull() : bool { return $this->betterReflectionType->allowsNull(); } } betterReflectionMethod = $betterReflectionMethod; unset($this->name); unset($this->class); } /** @return non-empty-string */ public function __toString() : string { return $this->betterReflectionMethod->__toString(); } public function inNamespace() : bool { return $this->betterReflectionMethod->inNamespace(); } public function isClosure() : bool { return $this->betterReflectionMethod->isClosure(); } public function isDeprecated() : bool { return $this->betterReflectionMethod->isDeprecated(); } public function isInternal() : bool { return $this->betterReflectionMethod->isInternal(); } public function isUserDefined() : bool { return $this->betterReflectionMethod->isUserDefined(); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getClosureThis() { throw new NotImplemented('Not implemented'); } public function getClosureScopeClass() : ?CoreReflectionClass { throw new NotImplemented('Not implemented'); } public function getClosureCalledClass() : ?CoreReflectionClass { throw new NotImplemented('Not implemented'); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getDocComment() { return $this->betterReflectionMethod->getDocComment() ?? \false; } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getStartLine() { try { return $this->betterReflectionMethod->getStartLine(); } catch (CodeLocationMissing $exception) { return \false; } } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getEndLine() { try { return $this->betterReflectionMethod->getEndLine(); } catch (CodeLocationMissing $exception) { return \false; } } /** @psalm-suppress ImplementedReturnTypeMismatch */ public function getExtension() : ?CoreReflectionExtension { throw new NotImplemented('Not implemented'); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getExtensionName() { return $this->betterReflectionMethod->getExtensionName() ?? \false; } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getFileName() { $fileName = $this->betterReflectionMethod->getFileName(); return $fileName !== null ? FileHelper::normalizeSystemPath($fileName) : \false; } public function getName() : string { return $this->betterReflectionMethod->getName(); } public function getNamespaceName() : string { return $this->betterReflectionMethod->getNamespaceName() ?? ''; } public function getNumberOfParameters() : int { return $this->betterReflectionMethod->getNumberOfParameters(); } public function getNumberOfRequiredParameters() : int { return $this->betterReflectionMethod->getNumberOfRequiredParameters(); } /** @return list */ public function getParameters() : array { return array_map(static function (BetterReflectionParameter $parameter) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionParameter { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionParameter($parameter); }, $this->betterReflectionMethod->getParameters()); } public function hasReturnType() : bool { return $this->betterReflectionMethod->hasReturnType(); } /** @return ReflectionUnionType|ReflectionNamedType|ReflectionIntersectionType|null */ public function getReturnType() : ?CoreReflectionType { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionType::fromTypeOrNull($this->betterReflectionMethod->getReturnType()); } public function getShortName() : string { return $this->betterReflectionMethod->getShortName(); } /** @return array */ public function getStaticVariables() : array { throw new NotImplemented('Not implemented'); } public function returnsReference() : bool { return $this->betterReflectionMethod->returnsReference(); } public function isGenerator() : bool { return $this->betterReflectionMethod->isGenerator(); } public function isVariadic() : bool { return $this->betterReflectionMethod->isVariadic(); } public function isPublic() : bool { return $this->betterReflectionMethod->isPublic(); } public function isPrivate() : bool { return $this->betterReflectionMethod->isPrivate(); } public function isProtected() : bool { return $this->betterReflectionMethod->isProtected(); } public function isAbstract() : bool { return $this->betterReflectionMethod->isAbstract(); } public function isFinal() : bool { return $this->betterReflectionMethod->isFinal(); } public function isStatic() : bool { return $this->betterReflectionMethod->isStatic(); } public function isConstructor() : bool { return $this->betterReflectionMethod->isConstructor(); } public function isDestructor() : bool { return $this->betterReflectionMethod->isDestructor(); } /** * {@inheritDoc} */ public function getClosure($object = null) : Closure { try { return $this->betterReflectionMethod->getClosure($object); } catch (NoObjectProvided $e) { throw new ValueError($e->getMessage(), 0, $e); } catch (Throwable $e) { throw new CoreReflectionException($e->getMessage(), 0, $e); } } public function getModifiers() : int { return $this->betterReflectionMethod->getModifiers(); } /** * @param object $object * @param mixed $arg * @param mixed ...$args * * @return mixed * * @throws CoreReflectionException */ #[\ReturnTypeWillChange] public function invoke($object = null, $arg = null, ...$args) { try { return $this->betterReflectionMethod->invoke($object, $arg, ...$args); } catch (NoObjectProvided $exception) { return null; } catch (Throwable $e) { throw new CoreReflectionException($e->getMessage(), 0, $e); } } /** * @param object $object * @param mixed[] $args * * @return mixed * * @throws CoreReflectionException */ #[\ReturnTypeWillChange] public function invokeArgs($object = null, array $args = []) { try { return $this->betterReflectionMethod->invokeArgs($object, $args); } catch (NoObjectProvided $exception) { return null; } catch (Throwable $e) { throw new CoreReflectionException($e->getMessage(), 0, $e); } } public function getDeclaringClass() : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($this->betterReflectionMethod->getImplementingClass()); } public function getPrototype() : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod { return new self($this->betterReflectionMethod->getPrototype()); } public function hasPrototype() : bool { try { $this->betterReflectionMethod->getPrototype(); return \true; } catch (MethodPrototypeNotFound $exception) { return \false; } } /** * {@inheritDoc} * @codeCoverageIgnore * @infection-ignore-all */ public function setAccessible($accessible) : void { } /** * @param class-string|null $name * * @return list */ public function getAttributes(?string $name = null, int $flags = 0) : array { if ($flags !== 0 && $flags !== \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); } if ($name !== null && $flags !== 0) { $attributes = $this->betterReflectionMethod->getAttributesByInstance($name); } elseif ($name !== null) { $attributes = $this->betterReflectionMethod->getAttributesByName($name); } else { $attributes = $this->betterReflectionMethod->getAttributes(); } return array_map(static function (BetterReflectionAttribute $betterReflectionAttribute) { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttributeFactory::create($betterReflectionAttribute); }, $attributes); } public function hasTentativeReturnType() : bool { return $this->betterReflectionMethod->hasTentativeReturnType(); } /** @return ReflectionUnionType|ReflectionNamedType|ReflectionIntersectionType|null */ public function getTentativeReturnType() : ?CoreReflectionType { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionType::fromTypeOrNull($this->betterReflectionMethod->getTentativeReturnType()); } /** @return mixed[] */ public function getClosureUsedVariables() : array { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } /** * @return mixed */ public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionMethod->getName(); } if ($name === 'class') { return $this->betterReflectionMethod->getImplementingClass()->getName(); } throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name)); } public function getBetterReflection() : BetterReflectionMethod { return $this->betterReflectionMethod; } } betterClassConstantOrEnumCase = $betterClassConstantOrEnumCase; unset($this->name); unset($this->class); } public function getName() : string { return $this->betterClassConstantOrEnumCase->getName(); } /** @psalm-mutation-free */ public function hasType() : bool { if ($this->betterClassConstantOrEnumCase instanceof BetterReflectionEnumCase) { return \false; } return $this->betterClassConstantOrEnumCase->hasType(); } /** * @psalm-mutation-free * @return ReflectionUnionType|ReflectionNamedType|ReflectionIntersectionType|null */ public function getType() : ?CoreReflectionType { if ($this->betterClassConstantOrEnumCase instanceof BetterReflectionEnumCase) { return null; } return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionType::fromTypeOrNull($this->betterClassConstantOrEnumCase->getType()); } /** * @deprecated Use getValueExpression() */ #[\ReturnTypeWillChange] public function getValue() { if ($this->betterClassConstantOrEnumCase instanceof BetterReflectionEnumCase) { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } return $this->betterClassConstantOrEnumCase->getValue(); } /** * @deprecated Use getValueExpression() */ public function getValueExpr() : Expr { return $this->getValueExpression(); } public function getValueExpression() : Expr { return $this->betterClassConstantOrEnumCase->getValueExpression(); } public function isPublic() : bool { if ($this->betterClassConstantOrEnumCase instanceof BetterReflectionEnumCase) { return \true; } return $this->betterClassConstantOrEnumCase->isPublic(); } public function isPrivate() : bool { if ($this->betterClassConstantOrEnumCase instanceof BetterReflectionEnumCase) { return \false; } return $this->betterClassConstantOrEnumCase->isPrivate(); } public function isProtected() : bool { if ($this->betterClassConstantOrEnumCase instanceof BetterReflectionEnumCase) { return \false; } return $this->betterClassConstantOrEnumCase->isProtected(); } public function getModifiers() : int { if ($this->betterClassConstantOrEnumCase instanceof BetterReflectionEnumCase) { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant::IS_PUBLIC_COMPATIBILITY; } return $this->betterClassConstantOrEnumCase->getModifiers(); } public function getDeclaringClass() : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass { if ($this->betterClassConstantOrEnumCase instanceof BetterReflectionEnumCase) { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($this->betterClassConstantOrEnumCase->getDeclaringClass()); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($this->betterClassConstantOrEnumCase->getImplementingClass()); } /** * Returns the doc comment for this constant * * @return string|false */ #[\ReturnTypeWillChange] public function getDocComment() { return $this->betterClassConstantOrEnumCase->getDocComment() ?? \false; } /** * To string * * @link https://php.net/manual/en/reflector.tostring.php * * @return non-empty-string */ public function __toString() : string { return $this->betterClassConstantOrEnumCase->__toString(); } /** * @param class-string|null $name * * @return list */ public function getAttributes(?string $name = null, int $flags = 0) : array { if ($flags !== 0 && $flags !== \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); } if ($name !== null && $flags !== 0) { $attributes = $this->betterClassConstantOrEnumCase->getAttributesByInstance($name); } elseif ($name !== null) { $attributes = $this->betterClassConstantOrEnumCase->getAttributesByName($name); } else { $attributes = $this->betterClassConstantOrEnumCase->getAttributes(); } /** @psalm-suppress ImpureFunctionCall */ return array_map(static function (BetterReflectionAttribute $betterReflectionAttribute) { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttributeFactory::create($betterReflectionAttribute); }, $attributes); } public function isFinal() : bool { if ($this->betterClassConstantOrEnumCase instanceof BetterReflectionEnumCase) { return \true; } return $this->betterClassConstantOrEnumCase->isFinal(); } public function isEnumCase() : bool { return $this->betterClassConstantOrEnumCase instanceof BetterReflectionEnumCase; } /** * @return mixed */ public function __get(string $name) { if ($name === 'name') { return $this->betterClassConstantOrEnumCase->getName(); } if ($name === 'class') { return $this->getDeclaringClass()->getName(); } throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name)); } } = 80000 && PHP_VERSION_ID < 80012) { return new \PHPStan\BetterReflection\Reflection\Adapter\FakeReflectionAttribute($betterReflectionAttribute); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute($betterReflectionAttribute); } } betterReflectionFunction = $betterReflectionFunction; unset($this->name); } public function __toString() : string { return $this->betterReflectionFunction->__toString(); } public function inNamespace() : bool { return $this->betterReflectionFunction->inNamespace(); } public function isClosure() : bool { return $this->betterReflectionFunction->isClosure(); } public function isDeprecated() : bool { return $this->betterReflectionFunction->isDeprecated(); } public function isInternal() : bool { return $this->betterReflectionFunction->isInternal(); } public function isUserDefined() : bool { return $this->betterReflectionFunction->isUserDefined(); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getClosureThis() { throw new NotImplemented('Not implemented'); } public function getClosureScopeClass() : ?CoreReflectionClass { throw new NotImplemented('Not implemented'); } public function getClosureCalledClass() : ?CoreReflectionClass { throw new NotImplemented('Not implemented'); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getDocComment() { return $this->betterReflectionFunction->getDocComment() ?? \false; } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getStartLine() { return $this->betterReflectionFunction->getStartLine(); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getEndLine() { return $this->betterReflectionFunction->getEndLine(); } /** @psalm-suppress ImplementedReturnTypeMismatch */ public function getExtension() : ?CoreReflectionExtension { throw new NotImplemented('Not implemented'); } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getExtensionName() { return $this->betterReflectionFunction->getExtensionName() ?? \false; } /** * {@inheritDoc} */ #[\ReturnTypeWillChange] public function getFileName() { $fileName = $this->betterReflectionFunction->getFileName(); return $fileName !== null ? FileHelper::normalizeSystemPath($fileName) : \false; } public function getName() : string { return $this->betterReflectionFunction->getName(); } public function getNamespaceName() : string { return $this->betterReflectionFunction->getNamespaceName() ?? ''; } public function getNumberOfParameters() : int { return $this->betterReflectionFunction->getNumberOfParameters(); } public function getNumberOfRequiredParameters() : int { return $this->betterReflectionFunction->getNumberOfRequiredParameters(); } /** @return list */ public function getParameters() : array { return array_map(static function (BetterReflectionParameter $parameter) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionParameter { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionParameter($parameter); }, $this->betterReflectionFunction->getParameters()); } public function hasReturnType() : bool { return $this->betterReflectionFunction->hasReturnType(); } /** @return ReflectionUnionType|ReflectionNamedType|ReflectionIntersectionType|null */ public function getReturnType() : ?CoreReflectionType { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionType::fromTypeOrNull($this->betterReflectionFunction->getReturnType()); } public function getShortName() : string { return $this->betterReflectionFunction->getShortName(); } /** @return array */ public function getStaticVariables() : array { throw new NotImplemented('Not implemented'); } public function returnsReference() : bool { return $this->betterReflectionFunction->returnsReference(); } public function isGenerator() : bool { return $this->betterReflectionFunction->isGenerator(); } public function isVariadic() : bool { return $this->betterReflectionFunction->isVariadic(); } public function isDisabled() : bool { return $this->betterReflectionFunction->isDisabled(); } /** * @param mixed $arg * @param mixed ...$args * * @return mixed * * @throws CoreReflectionException */ #[\ReturnTypeWillChange] public function invoke($arg = null, ...$args) { try { return $this->betterReflectionFunction->invoke(...func_get_args()); } catch (Throwable $e) { throw new CoreReflectionException($e->getMessage(), 0, $e); } } /** * @param mixed[] $args */ #[\ReturnTypeWillChange] public function invokeArgs(array $args) { try { return $this->betterReflectionFunction->invokeArgs($args); } catch (Throwable $e) { throw new CoreReflectionException($e->getMessage(), 0, $e); } } public function getClosure() : Closure { return $this->betterReflectionFunction->getClosure(); } /** @return mixed[] */ public function getClosureUsedVariables() : array { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } public function hasTentativeReturnType() : bool { return $this->betterReflectionFunction->hasTentativeReturnType(); } /** @return ReflectionUnionType|ReflectionNamedType|ReflectionIntersectionType|null */ public function getTentativeReturnType() : ?CoreReflectionType { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionType::fromTypeOrNull($this->betterReflectionFunction->getTentativeReturnType()); } public function isStatic() : bool { return $this->betterReflectionFunction->isStatic(); } /** * @param class-string|null $name * * @return list */ public function getAttributes(?string $name = null, int $flags = 0) : array { if ($flags !== 0 && $flags !== \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); } if ($name !== null && $flags !== 0) { $attributes = $this->betterReflectionFunction->getAttributesByInstance($name); } elseif ($name !== null) { $attributes = $this->betterReflectionFunction->getAttributesByName($name); } else { $attributes = $this->betterReflectionFunction->getAttributes(); } return array_map(static function (BetterReflectionAttribute $betterReflectionAttribute) { return \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttributeFactory::create($betterReflectionAttribute); }, $attributes); } /** * @return mixed */ public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionFunction->getName(); } throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name)); } public function isAnonymous() : bool { return $this->betterReflectionFunction->isClosure(); } } name); unset($this->class); } /** * Get the name of the reflection (e.g. if this is a ReflectionClass this * will be the class name). */ public function getName() : string { return $this->betterReflectionEnumCase->getName(); } public function hasType() : bool { return \false; } public function getType() : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionUnionType|\PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType|\PHPStan\BetterReflection\Reflection\Adapter\ReflectionIntersectionType|null { return null; } public function getValue() : UnitEnum { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } public function isPublic() : bool { return \true; } public function isPrivate() : bool { return \false; } public function isProtected() : bool { return \false; } public function getModifiers() : int { return self::IS_PUBLIC; } public function getDeclaringClass() : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($this->betterReflectionEnumCase->getDeclaringClass()); } public function getDocComment() : string|false { return $this->betterReflectionEnumCase->getDocComment() ?? \false; } /** @return non-empty-string */ public function __toString() : string { return $this->betterReflectionEnumCase->__toString(); } /** * @param class-string|null $name * * @return list */ public function getAttributes(string|null $name = null, int $flags = 0) : array { if ($flags !== 0 && $flags !== \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); } if ($name !== null && $flags !== 0) { $attributes = $this->betterReflectionEnumCase->getAttributesByInstance($name); } elseif ($name !== null) { $attributes = $this->betterReflectionEnumCase->getAttributesByName($name); } else { $attributes = $this->betterReflectionEnumCase->getAttributes(); } /** @psalm-suppress ImpureFunctionCall */ return array_map(static fn(BetterReflectionAttribute $betterReflectionAttribute): \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute|\PHPStan\BetterReflection\Reflection\Adapter\FakeReflectionAttribute => \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); } public function isFinal() : bool { return \true; } public function isEnumCase() : bool { return \true; } public function getEnum() : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnum { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnum($this->betterReflectionEnumCase->getDeclaringEnum()); } public function __get(string $name) : mixed { if ($name === 'name') { return $this->betterReflectionEnumCase->getName(); } if ($name === 'class') { return $this->betterReflectionEnumCase->getDeclaringClass()->getName(); } throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name)); } } betterReflectionAttribute = $betterReflectionAttribute; } public function getName() : string { return $this->betterReflectionAttribute->getName(); } public function getTarget() : int { return $this->betterReflectionAttribute->getTarget(); } public function isRepeated() : bool { return $this->betterReflectionAttribute->isRepeated(); } /** * @deprecated Use getArgumentsExpressions() * @return array */ public function getArguments() : array { return $this->betterReflectionAttribute->getArguments(); } /** @return array */ public function getArgumentsExpressions() : array { return $this->betterReflectionAttribute->getArgumentsExpressions(); } public function newInstance() : object { $class = $this->getName(); return new $class(...$this->getArguments()); } public function __toString() : string { return $this->betterReflectionAttribute->__toString(); } } name); } /** @return non-empty-string */ public function __toString() : string { return $this->betterReflectionEnum->__toString(); } public function __get(string $name) : mixed { if ($name === 'name') { return $this->betterReflectionEnum->getName(); } throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name)); } /** @return class-string */ public function getName() : string { return $this->betterReflectionEnum->getName(); } public function isAnonymous() : bool { return $this->betterReflectionEnum->isAnonymous(); } public function isInternal() : bool { return $this->betterReflectionEnum->isInternal(); } public function isUserDefined() : bool { return $this->betterReflectionEnum->isUserDefined(); } public function isInstantiable() : bool { return $this->betterReflectionEnum->isInstantiable(); } public function isCloneable() : bool { return $this->betterReflectionEnum->isCloneable(); } /** @return non-empty-string|false */ public function getFileName() : string|false { $fileName = $this->betterReflectionEnum->getFileName(); return $fileName !== null ? FileHelper::normalizeSystemPath($fileName) : \false; } public function getStartLine() : int|false { return $this->betterReflectionEnum->getStartLine(); } public function getEndLine() : int|false { return $this->betterReflectionEnum->getEndLine(); } public function getDocComment() : string|false { return $this->betterReflectionEnum->getDocComment() ?? \false; } /** @return ReflectionMethod|null */ public function getConstructor() : ?CoreReflectionMethod { $constructor = $this->betterReflectionEnum->getConstructor(); if ($constructor === null) { return null; } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod($constructor); } public function hasMethod(string $name) : bool { if ($name === '') { return \false; } return $this->betterReflectionEnum->hasMethod($name); } public function getMethod(string $name) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod { $method = $name !== '' ? $this->betterReflectionEnum->getMethod($name) : null; if ($method === null) { throw new CoreReflectionException(sprintf('Method %s::%s() does not exist', $this->betterReflectionEnum->getName(), $name)); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod($method); } /** * @param int-mask-of|null $filter * * @return list */ public function getMethods(int|null $filter = null) : array { /** @psalm-suppress ImpureFunctionCall */ return array_values(array_map(static fn(BetterReflectionMethod $method): \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod => new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionMethod($method), $this->betterReflectionEnum->getMethods($filter ?? 0))); } public function hasProperty(string $name) : bool { if ($name === '') { return \false; } return $this->betterReflectionEnum->hasProperty($name); } public function getProperty(string $name) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty { $betterReflectionProperty = $name !== '' ? $this->betterReflectionEnum->getProperty($name) : null; if ($betterReflectionProperty === null) { throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionEnum->getName(), $name)); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty($betterReflectionProperty); } /** * @param int-mask-of|null $filter * * @return list */ public function getProperties(int|null $filter = null) : array { /** @psalm-suppress ImpureFunctionCall */ return array_values(array_map(static fn(BetterReflectionProperty $property): \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty => new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty($property), $this->betterReflectionEnum->getProperties($filter ?? 0))); } public function hasConstant(string $name) : bool { if ($name === '') { return \false; } return $this->betterReflectionEnum->hasCase($name) || $this->betterReflectionEnum->hasConstant($name); } /** * @deprecated Use getReflectionConstants() * * @param int-mask-of|null $filter * * @return array */ public function getConstants(int|null $filter = null) : array { /** @psalm-suppress ImpureFunctionCall */ return array_map(fn(BetterReflectionClassConstant|BetterReflectionEnumCase $betterConstantOrEnumCase): mixed => $this->getConstantValue($betterConstantOrEnumCase), $this->filterBetterReflectionClassConstants($filter)); } /** * @deprecated Use getReflectionConstant() */ public function getConstant(string $name) : mixed { if ($name === '') { return \false; } $enumCase = $this->betterReflectionEnum->getCase($name); if ($enumCase !== null) { return $this->getConstantValue($enumCase); } $betterReflectionConstant = $this->betterReflectionEnum->getConstant($name); if ($betterReflectionConstant === null) { return \false; } return $betterReflectionConstant->getValue(); } private function getConstantValue(BetterReflectionClassConstant|BetterReflectionEnumCase $betterConstantOrEnumCase) : mixed { if ($betterConstantOrEnumCase instanceof BetterReflectionEnumCase) { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } return $betterConstantOrEnumCase->getValue(); } public function getReflectionConstant(string $name) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant|false { if ($name === '') { return \false; } // @infection-ignore-all Coalesce: There's no difference $betterReflectionConstantOrEnumCase = $this->betterReflectionEnum->getCase($name) ?? $this->betterReflectionEnum->getConstant($name); if ($betterReflectionConstantOrEnumCase === null) { return \false; } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant($betterReflectionConstantOrEnumCase); } /** * @param int-mask-of|null $filter * * @return list */ public function getReflectionConstants(int|null $filter = null) : array { return array_values(array_map(static fn(BetterReflectionClassConstant|BetterReflectionEnumCase $betterConstantOrEnum): \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant => new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant($betterConstantOrEnum), $this->filterBetterReflectionClassConstants($filter))); } /** * @param int-mask-of|null $filter * * @return array */ private function filterBetterReflectionClassConstants(int|null $filter) : array { $reflectionConstants = $this->betterReflectionEnum->getConstants($filter ?? 0); if ($filter === null || $filter & \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant::IS_PUBLIC_COMPATIBILITY) { $reflectionConstants += $this->betterReflectionEnum->getCases(); } return $reflectionConstants; } /** @return array */ public function getInterfaces() : array { /** @psalm-suppress ImpureFunctionCall */ return array_map(static fn(BetterReflectionClass $interface): \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass => new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($interface), $this->betterReflectionEnum->getInterfaces()); } /** @return list */ public function getInterfaceNames() : array { return $this->betterReflectionEnum->getInterfaceNames(); } public function isInterface() : bool { return $this->betterReflectionEnum->isInterface(); } /** @return array */ public function getTraits() : array { $traits = $this->betterReflectionEnum->getTraits(); /** @var list $traitNames */ $traitNames = array_map(static fn(BetterReflectionClass $trait): string => $trait->getName(), $traits); /** @psalm-suppress ImpureFunctionCall */ return array_combine($traitNames, array_map(static fn(BetterReflectionClass $trait): \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass => new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass($trait), $traits)); } /** @return list */ public function getTraitNames() : array { return $this->betterReflectionEnum->getTraitNames(); } /** @return array */ public function getTraitAliases() : array { return $this->betterReflectionEnum->getTraitAliases(); } public function isTrait() : bool { return $this->betterReflectionEnum->isTrait(); } public function isAbstract() : bool { return $this->betterReflectionEnum->isAbstract(); } public function isFinal() : bool { return $this->betterReflectionEnum->isFinal(); } public function isReadOnly() : bool { return $this->betterReflectionEnum->isReadOnly(); } public function getModifiers() : int { return $this->betterReflectionEnum->getModifiers(); } public function isInstance(object $object) : bool { return $this->betterReflectionEnum->isInstance($object); } public function newInstance(mixed ...$args) : object { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } public function newInstanceWithoutConstructor() : object { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } public function newInstanceArgs(array|null $args = null) : object { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } public function getParentClass() : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass|false { return \false; } public function isSubclassOf(CoreReflectionClass|string $class) : bool { $realParentClassNames = $this->betterReflectionEnum->getParentClassNames(); $parentClassNames = array_combine(array_map(static fn(string $parentClassName): string => strtolower($parentClassName), $realParentClassNames), $realParentClassNames); $className = $class instanceof CoreReflectionClass ? $class->getName() : $class; $lowercasedClassName = strtolower($className); $realParentClassName = $parentClassNames[$lowercasedClassName] ?? $className; if ($this->betterReflectionEnum->isSubclassOf($realParentClassName)) { return \true; } return $this->implementsInterface($className); } /** * @return array * * @psalm-suppress LessSpecificImplementedReturnType */ public function getStaticProperties() : array { return $this->betterReflectionEnum->getStaticProperties(); } public function getStaticPropertyValue(string $name, mixed $default = null) : mixed { throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionEnum->getName(), $name)); } public function setStaticPropertyValue(string $name, mixed $value) : void { throw new CoreReflectionException(sprintf('Class %s does not have a property named %s', $this->betterReflectionEnum->getName(), $name)); } /** @return array */ public function getDefaultProperties() : array { return $this->betterReflectionEnum->getDefaultProperties(); } public function isIterateable() : bool { return $this->betterReflectionEnum->isIterateable(); } public function isIterable() : bool { return $this->isIterateable(); } public function implementsInterface(CoreReflectionClass|string $interface) : bool { $realInterfaceNames = $this->betterReflectionEnum->getInterfaceNames(); $interfaceNames = array_combine(array_map(static fn(string $interfaceName): string => strtolower($interfaceName), $realInterfaceNames), $realInterfaceNames); $interfaceName = $interface instanceof CoreReflectionClass ? $interface->getName() : $interface; $lowercasedInterfaceName = strtolower($interfaceName); $realInterfaceName = $interfaceNames[$lowercasedInterfaceName] ?? $interfaceName; return $this->betterReflectionEnum->implementsInterface($realInterfaceName); } public function getExtension() : ?CoreReflectionExtension { throw new \PHPStan\BetterReflection\Reflection\Adapter\Exception\NotImplemented('Not implemented'); } /** @return non-empty-string|false */ public function getExtensionName() : string|false { return $this->betterReflectionEnum->getExtensionName() ?? \false; } public function inNamespace() : bool { return $this->betterReflectionEnum->inNamespace(); } public function getNamespaceName() : string { return $this->betterReflectionEnum->getNamespaceName() ?? ''; } public function getShortName() : string { return $this->betterReflectionEnum->getShortName(); } /** * @param class-string|null $name * * @return list */ public function getAttributes(string|null $name = null, int $flags = 0) : array { if ($flags !== 0 && $flags !== \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); } if ($name !== null && $flags !== 0) { $attributes = $this->betterReflectionEnum->getAttributesByInstance($name); } elseif ($name !== null) { $attributes = $this->betterReflectionEnum->getAttributesByName($name); } else { $attributes = $this->betterReflectionEnum->getAttributes(); } /** @psalm-suppress ImpureFunctionCall */ return array_map(static fn(BetterReflectionAttribute $betterReflectionAttribute): \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute|\PHPStan\BetterReflection\Reflection\Adapter\FakeReflectionAttribute => \PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); } public function isEnum() : bool { return $this->betterReflectionEnum->isEnum(); } public function hasCase(string $name) : bool { if ($name === '') { return \false; } return $this->betterReflectionEnum->hasCase($name); } public function getCase(string $name) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnumUnitCase|\PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnumBackedCase { $case = $name !== '' ? $this->betterReflectionEnum->getCase($name) : null; if ($case === null) { throw new CoreReflectionException(sprintf('Case %s::%s does not exist', $this->betterReflectionEnum->getName(), $name)); } if ($this->betterReflectionEnum->isBacked()) { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnumBackedCase($case); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnumUnitCase($case); } /** @return list */ public function getCases() : array { /** @psalm-suppress ImpureFunctionCall */ return array_map(function (BetterReflectionEnumCase $case) : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnumUnitCase|\PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnumBackedCase { if ($this->betterReflectionEnum->isBacked()) { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnumBackedCase($case); } return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnumUnitCase($case); }, array_values($this->betterReflectionEnum->getCases())); } public function isBacked() : bool { return $this->betterReflectionEnum->isBacked(); } public function getBackingType() : \PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType|null { if ($this->betterReflectionEnum->isBacked()) { return new \PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType($this->betterReflectionEnum->getBackingType(), \false); } return null; } } reflector = $reflector; $this->locatedSource = $locatedSource; /** @psalm-allow-private-mutation */ $this->namespace = $namespace; $this->setNamesFromNode($node, $positionInNode); if ($node instanceof Node\Expr\FuncCall) { $argumentValueNode = $node->args[1]; assert($argumentValueNode instanceof Node\Arg); $this->value = $argumentValueNode->value; } else { /** @psalm-suppress PossiblyNullArrayOffset */ $this->value = $node->consts[$positionInNode]->value; } $this->docComment = GetLastDocComment::forNode($node); $startLine = $node->getStartLine(); assert($startLine > 0); $endLine = $node->getEndLine(); assert($endLine > 0); $this->startLine = $startLine; $this->endLine = $endLine; $this->startColumn = CalculateReflectionColumn::getStartColumn($this->locatedSource->getSource(), $node); $this->endColumn = CalculateReflectionColumn::getEndColumn($this->locatedSource->getSource(), $node); } /** * Create a ReflectionConstant by name, using default reflectors etc. * * @deprecated Use Reflector instead. * * @throws IdentifierNotFound */ public static function createFromName(string $constantName) : self { return (new BetterReflection())->reflector()->reflectConstant($constantName); } /** * Create a reflection of a constant * * @internal * * @param Node\Stmt\Const_|Node\Expr\FuncCall $node Node has to be processed by the PhpParser\NodeVisitor\NameResolver * @param non-empty-string|null $namespace */ public static function createFromNode(Reflector $reflector, Node $node, LocatedSource $locatedSource, ?string $namespace = null, ?int $positionInNode = null) : self { if ($node instanceof Node\Stmt\Const_) { assert(is_int($positionInNode)); return self::createFromConstKeyword($reflector, $node, $locatedSource, $namespace, $positionInNode); } return self::createFromDefineFunctionCall($reflector, $node, $locatedSource); } /** @param non-empty-string|null $namespace */ private static function createFromConstKeyword(Reflector $reflector, Node\Stmt\Const_ $node, LocatedSource $locatedSource, ?string $namespace, int $positionInNode) : self { return new self($reflector, $node, $locatedSource, $namespace, $positionInNode); } /** @throws InvalidConstantNode */ private static function createFromDefineFunctionCall(Reflector $reflector, Node\Expr\FuncCall $node, LocatedSource $locatedSource) : self { ConstantNodeChecker::assertValidDefineFunctionCall($node); return new self($reflector, $node, $locatedSource); } /** * Get the "short" name of the constant (e.g. for A\B\FOO, this will return * "FOO"). * * @return non-empty-string */ public function getShortName() : string { return $this->shortName; } /** * Get the "full" name of the constant (e.g. for A\B\FOO, this will return * "A\B\FOO"). * * @return non-empty-string */ public function getName() : string { return $this->name; } /** * Get the "namespace" name of the constant (e.g. for A\B\FOO, this will * return "A\B"). * * @return non-empty-string|null */ public function getNamespaceName() : ?string { return $this->namespace; } /** * Decide if this constant is part of a namespace. Returns false if the constant * is in the global namespace or does not have a specified namespace. */ public function inNamespace() : bool { return $this->namespace !== null; } /** @return non-empty-string|null */ public function getExtensionName() : ?string { return $this->locatedSource->getExtensionName(); } /** * Is this an internal constant? */ public function isInternal() : bool { return $this->locatedSource->isInternal(); } /** * Is this a user-defined function (will always return the opposite of * whatever isInternal returns). */ public function isUserDefined() : bool { return !$this->isInternal(); } public function isDeprecated() : bool { return AnnotationHelper::isDeprecated($this->getDocComment()); } /** * @deprecated Use getValueExpression() * @return Node\Expr */ public function getValueExpr() : Node\Expr { return $this->getValueExpression(); } public function getValueExpression() : Node\Expr { return $this->value; } /** * @deprecated Use getValueExpression() * @return mixed */ public function getValue() { if ($this->compiledValue === null) { $this->compiledValue = (new CompileNodeToValue())->__invoke($this->value, new CompilerContext($this->reflector, $this)); } return $this->compiledValue->value; } /** @return non-empty-string|null */ public function getFileName() : ?string { return $this->locatedSource->getFileName(); } public function getLocatedSource() : LocatedSource { return $this->locatedSource; } /** * Get the line number that this constant starts on. * * @return positive-int */ public function getStartLine() : int { return $this->startLine; } /** * Get the line number that this constant ends on. * * @return positive-int */ public function getEndLine() : int { return $this->endLine; } /** @return positive-int */ public function getStartColumn() : int { return $this->startColumn; } /** @return positive-int */ public function getEndColumn() : int { return $this->endColumn; } /** @return non-empty-string|null */ public function getDocComment() : ?string { return $this->docComment; } /** @return non-empty-string */ public function __toString() : string { return ReflectionConstantStringCast::toString($this); } /** * @param \PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall $node */ private function setNamesFromNode($node, ?int $positionInNode) : void { if ($node instanceof Node\Expr\FuncCall) { $name = $this->getNameFromDefineFunctionCall($node); $nameParts = explode('\\', $name); $this->namespace = implode('\\', array_slice($nameParts, 0, -1)) ?: null; $shortName = $nameParts[count($nameParts) - 1]; assert($shortName !== ''); } else { /** @psalm-suppress PossiblyNullArrayOffset */ $constNode = $node->consts[$positionInNode]; $namespacedName = $constNode->namespacedName; assert($namespacedName instanceof Node\Name); $name = $namespacedName->toString(); assert($name !== ''); $shortName = $constNode->name->name; assert($shortName !== ''); } $this->name = $name; $this->shortName = $shortName; } /** @return non-empty-string */ private function getNameFromDefineFunctionCall(Node\Expr\FuncCall $node) : string { $argumentNameNode = $node->args[0]; assert($argumentNameNode instanceof Node\Arg); $nameNode = $argumentNameNode->value; assert($nameNode instanceof Node\Scalar\String_); /** @psalm-var non-empty-string */ return $nameNode->value; } } printer(); return new self(sprintf('Invalid arrow function body node (first 50 characters: %s)', substr($printer->prettyPrint([$node]), 0, 50))); } } printer(); return new self(sprintf('Invalid constant node (first 50 characters: %s)', substr($printer->prettyPrint([$node]), 0, 50))); } } getName())); } } * * @psalm-pure * @param \PHPStan\BetterReflection\Reflection\ReflectionClass|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionClassConstant|\PHPStan\BetterReflection\Reflection\ReflectionEnumCase|\PHPStan\BetterReflection\Reflection\ReflectionProperty|\PHPStan\BetterReflection\Reflection\ReflectionParameter $reflection */ public static function createAttributes(Reflector $reflector, $reflection, array $attrGroups) : array { $repeated = []; foreach ($attrGroups as $attributesGroupNode) { foreach ($attributesGroupNode->attrs as $attributeNode) { $repeated[$attributeNode->name->toLowerString()][] = $attributeNode; } } $attributes = []; foreach ($attrGroups as $attributesGroupNode) { foreach ($attributesGroupNode->attrs as $attributeNode) { $attributes[] = new ReflectionAttribute($reflector, $attributeNode, $reflection, count($repeated[$attributeNode->name->toLowerString()]) > 1); } } return $attributes; } /** * @param list $attributes * * @return list * * @psalm-pure */ public static function filterAttributesByName(array $attributes, string $name) : array { return array_values(array_filter($attributes, static function (ReflectionAttribute $attribute) use($name) : bool { return $attribute->getName() === $name; })); } /** * @param list $attributes * @param class-string $className * * @return list * * @psalm-pure */ public static function filterAttributesByInstance(array $attributes, string $className) : array { return array_values(array_filter($attributes, static function (ReflectionAttribute $attribute) use($className) : bool { $class = $attribute->getClass(); return $class->getName() === $className || $class->isSubclassOf($className) || $class->implementsInterface($className); })); } } */ private $cases; /** * @var \PHPStan\BetterReflection\Reflector\Reflector */ private $reflector; /** * @param non-empty-string|null $namespace * * @phpcs:disable Generic.CodeAnalysis.UselessOverridingMethod.Found */ private function __construct(Reflector $reflector, EnumNode $node, LocatedSource $locatedSource, ?string $namespace = null) { $this->reflector = $reflector; parent::__construct($reflector, $node, $locatedSource, $namespace); $this->backingType = $this->createBackingType($node); $this->cases = $this->createCases($node); } /** * @internal * * @param EnumNode $node * @param non-empty-string|null $namespace * * @psalm-suppress MoreSpecificImplementedParamType * @return $this */ public static function createFromNode(Reflector $reflector, $node, LocatedSource $locatedSource, ?string $namespace = null) : \PHPStan\BetterReflection\Reflection\ReflectionClass { $node = $node; assert($node instanceof EnumNode); return new self($reflector, $node, $locatedSource, $namespace); } /** @param non-empty-string $name */ public function hasCase(string $name) : bool { return array_key_exists($name, $this->cases); } /** @param non-empty-string $name */ public function getCase(string $name) : ?\PHPStan\BetterReflection\Reflection\ReflectionEnumCase { return $this->cases[$name] ?? null; } /** @return array */ public function getCases() : array { return $this->cases; } /** @return array */ private function createCases(EnumNode $node) : array { $enumCasesNodes = array_filter($node->stmts, static function (Node\Stmt $stmt) : bool { return $stmt instanceof Node\Stmt\EnumCase; }); return array_combine(array_map(static function (Node\Stmt\EnumCase $enumCaseNode) : string { $enumCaseName = $enumCaseNode->name->toString(); assert($enumCaseName !== ''); return $enumCaseName; }, $enumCasesNodes), array_map(function (Node\Stmt\EnumCase $enumCaseNode) : \PHPStan\BetterReflection\Reflection\ReflectionEnumCase { return \PHPStan\BetterReflection\Reflection\ReflectionEnumCase::createFromNode($this->reflector, $enumCaseNode, $this); }, $enumCasesNodes)); } public function isBacked() : bool { return $this->backingType !== null; } public function getBackingType() : \PHPStan\BetterReflection\Reflection\ReflectionNamedType { if ($this->backingType === null) { throw new LogicException('This enum does not have a backing type available'); } return $this->backingType; } private function createBackingType(EnumNode $node) : ?\PHPStan\BetterReflection\Reflection\ReflectionNamedType { if ($node->scalarType === null) { return null; } $backingType = \PHPStan\BetterReflection\Reflection\ReflectionNamedType::createFromNode($this->reflector, $this, $node->scalarType); assert($backingType instanceof \PHPStan\BetterReflection\Reflection\ReflectionNamedType); return $backingType; } } reflector = new \PHPStan\BetterReflection\Reflector\DefaultReflector($sourceLocator); } /** * Create a ReflectionFunction for the specified $functionName. * * @throws IdentifierNotFound */ public function reflect(string $constantName) : ReflectionConstant { return $this->reflector->reflectConstant($constantName); } /** * Get all the classes available in the scope specified by the SourceLocator. * * @return ReflectionConstant[] */ public function getAllConstants() : array { return $this->reflector->reflectAllConstants(); } public function reflectClass(string $identifierName) : ReflectionClass { return $this->reflector->reflectClass($identifierName); } /** * @return list */ public function reflectAllClasses() : iterable { return $this->reflector->reflectAllClasses(); } public function reflectFunction(string $identifierName) : ReflectionFunction { return $this->reflector->reflectFunction($identifierName); } /** * @return list */ public function reflectAllFunctions() : iterable { return $this->reflector->reflectAllFunctions(); } public function reflectConstant(string $identifierName) : ReflectionConstant { return $this->reflector->reflectConstant($identifierName); } /** * @return list */ public function reflectAllConstants() : iterable { return $this->reflector->reflectAllConstants(); } } reflector = new \PHPStan\BetterReflection\Reflector\DefaultReflector($sourceLocator); } /** * Create a ReflectionFunction for the specified $functionName. * * @throws IdentifierNotFound */ public function reflect(string $functionName) : ReflectionFunction { return $this->reflector->reflectFunction($functionName); } /** * Get all the classes available in the scope specified by the SourceLocator. * * @return ReflectionFunction[] */ public function getAllFunctions() : array { return $this->reflector->reflectAllFunctions(); } public function reflectClass(string $identifierName) : ReflectionClass { return $this->reflector->reflectClass($identifierName); } /** * @return list */ public function reflectAllClasses() : iterable { return $this->reflector->reflectAllClasses(); } public function reflectFunction(string $identifierName) : ReflectionFunction { return $this->reflector->reflectFunction($identifierName); } /** * @return list */ public function reflectAllFunctions() : iterable { return $this->reflector->reflectAllFunctions(); } public function reflectConstant(string $identifierName) : ReflectionConstant { return $this->reflector->reflectConstant($identifierName); } /** * @return list */ public function reflectAllConstants() : iterable { return $this->reflector->reflectAllConstants(); } } */ public function reflectAllClasses() : iterable; /** * Create a ReflectionFunction for the specified $functionName. * * @throws IdentifierNotFound */ public function reflectFunction(string $identifierName) : ReflectionFunction; /** * Get all the functions available in the scope specified by the SourceLocator. * * @return list */ public function reflectAllFunctions() : iterable; /** * Create a ReflectionConstant for the specified $constantName. * * @throws IdentifierNotFound */ public function reflectConstant(string $identifierName) : ReflectionConstant; /** * Get all the constants available in the scope specified by the SourceLocator. * * @return list */ public function reflectAllConstants() : iterable; } reflector = new \PHPStan\BetterReflection\Reflector\DefaultReflector($sourceLocator); } /** * Create a ReflectionClass for the specified $className. * * @throws IdentifierNotFound */ public function reflect(string $className) : ReflectionClass { return $this->reflector->reflectClass($className); } /** * Get all the classes available in the scope specified by the SourceLocator. * * @return ReflectionClass[] */ public function getAllClasses() : array { return $this->reflector->reflectAllClasses(); } public function reflectClass(string $identifierName) : ReflectionClass { return $this->reflector->reflectClass($identifierName); } /** * @return list */ public function reflectAllClasses() : iterable { return $this->reflector->reflectAllClasses(); } public function reflectFunction(string $identifierName) : ReflectionFunction { return $this->reflector->reflectFunction($identifierName); } /** * @return list */ public function reflectAllFunctions() : iterable { return $this->reflector->reflectAllFunctions(); } public function reflectConstant(string $identifierName) : ReflectionConstant { return $this->reflector->reflectConstant($identifierName); } /** * @return list */ public function reflectAllConstants() : iterable { return $this->reflector->reflectAllConstants(); } } sourceLocator = $sourceLocator; } /** * Create a ReflectionClass for the specified $className. * * @throws IdentifierNotFound */ public function reflectClass(string $identifierName) : ReflectionClass { $identifier = new Identifier($identifierName, new IdentifierType(IdentifierType::IDENTIFIER_CLASS)); $classInfo = $this->sourceLocator->locateIdentifier($this, $identifier); if ($classInfo === null) { throw \PHPStan\BetterReflection\Reflector\Exception\IdentifierNotFound::fromIdentifier($identifier); } assert($classInfo instanceof ReflectionClass); return $classInfo; } /** * Get all the classes available in the scope specified by the SourceLocator. * * @return list */ public function reflectAllClasses() : iterable { /** @var list $allClasses */ $allClasses = $this->sourceLocator->locateIdentifiersByType($this, new IdentifierType(IdentifierType::IDENTIFIER_CLASS)); return $allClasses; } /** * Create a ReflectionFunction for the specified $functionName. * * @throws IdentifierNotFound */ public function reflectFunction(string $identifierName) : ReflectionFunction { $identifier = new Identifier($identifierName, new IdentifierType(IdentifierType::IDENTIFIER_FUNCTION)); $functionInfo = $this->sourceLocator->locateIdentifier($this, $identifier); if ($functionInfo === null) { throw \PHPStan\BetterReflection\Reflector\Exception\IdentifierNotFound::fromIdentifier($identifier); } assert($functionInfo instanceof ReflectionFunction); return $functionInfo; } /** * Get all the functions available in the scope specified by the SourceLocator. * * @return list */ public function reflectAllFunctions() : iterable { /** @var list $allFunctions */ $allFunctions = $this->sourceLocator->locateIdentifiersByType($this, new IdentifierType(IdentifierType::IDENTIFIER_FUNCTION)); return $allFunctions; } /** * Create a ReflectionConstant for the specified $constantName. * * @throws IdentifierNotFound */ public function reflectConstant(string $identifierName) : ReflectionConstant { $identifier = new Identifier($identifierName, new IdentifierType(IdentifierType::IDENTIFIER_CONSTANT)); $constantInfo = $this->sourceLocator->locateIdentifier($this, $identifier); if ($constantInfo === null) { throw \PHPStan\BetterReflection\Reflector\Exception\IdentifierNotFound::fromIdentifier($identifier); } assert($constantInfo instanceof ReflectionConstant); return $constantInfo; } /** * Get all the constants available in the scope specified by the SourceLocator. * * @return list */ public function reflectAllConstants() : iterable { /** @var list $allConstants */ $allConstants = $this->sourceLocator->locateIdentifiersByType($this, new IdentifierType(IdentifierType::IDENTIFIER_CONSTANT)); return $allConstants; } } identifier = $identifier; parent::__construct($message); } public function getIdentifier() : Identifier { return $this->identifier; } public static function fromIdentifier(Identifier $identifier) : self { return new self(sprintf('%s "%s" could not be found in the located source', $identifier->getType()->getName(), $identifier->getName()), $identifier); } } sourceLocator = $sourceLocator; $this->astLocator = $astLocator; } /** * Find a reflection on the specified line number. * * Returns null if no reflections found on the line. * * @param non-empty-string $filename * * @throws InvalidFileLocation * @throws ParseToAstFailure * @throws InvalidArgumentException * @return \PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionClass|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionConstant|\PHPStan\BetterReflection\Reflection\Reflection|null */ public function __invoke(string $filename, int $lineNumber) { $reflections = $this->computeReflections($filename); foreach ($reflections as $reflection) { if ($reflection instanceof ReflectionClass && $this->containsLine($reflection, $lineNumber)) { foreach ($reflection->getMethods() as $method) { if ($this->containsLine($method, $lineNumber)) { return $method; } } return $reflection; } if ($reflection instanceof ReflectionFunction && $this->containsLine($reflection, $lineNumber)) { return $reflection; } if ($reflection instanceof ReflectionConstant && $this->containsLine($reflection, $lineNumber)) { return $reflection; } } return null; } /** * Find all class and function reflections in the specified file * * @param non-empty-string $filename * * @return list * * @throws ParseToAstFailure * @throws InvalidFileLocation */ private function computeReflections(string $filename) : array { $singleFileSourceLocator = new SingleFileSourceLocator($filename, $this->astLocator); $reflector = new DefaultReflector(new AggregateSourceLocator([$singleFileSourceLocator, $this->sourceLocator])); return array_merge($singleFileSourceLocator->locateIdentifiersByType($reflector, new IdentifierType(IdentifierType::IDENTIFIER_CLASS)), $singleFileSourceLocator->locateIdentifiersByType($reflector, new IdentifierType(IdentifierType::IDENTIFIER_FUNCTION)), $singleFileSourceLocator->locateIdentifiersByType($reflector, new IdentifierType(IdentifierType::IDENTIFIER_CONSTANT))); } /** * Check to see if the line is within the boundaries of the reflection specified. * @param \PHPStan\BetterReflection\Reflection\ReflectionClass|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionConstant $reflection */ private function containsLine($reflection, int $lineNumber) : bool { return $lineNumber >= $reflection->getStartLine() && $lineNumber <= $reflection->getEndLine(); } } name instanceof Node\Name) { throw InvalidConstantNode::create($node); } if ($node->name->toLowerString() !== 'define') { throw InvalidConstantNode::create($node); } if (!in_array(count($node->args), self::DEFINE_ARGUMENTS_COUNTS, \true)) { throw InvalidConstantNode::create($node); } if (!$node->args[0] instanceof Node\Arg || !$node->args[0]->value instanceof Node\Scalar\String_) { throw InvalidConstantNode::create($node); } if (!$node->args[1] instanceof Node\Arg) { throw InvalidConstantNode::create($node); } $valueNode = $node->args[1]->value; if ($valueNode instanceof Node\Expr\FuncCall && !($valueNode->name instanceof Node\Name && $valueNode->name->toLowerString() === 'constant')) { throw InvalidConstantNode::create($node); } if ($valueNode instanceof Node\Expr\Variable) { throw InvalidConstantNode::create($node); } } } getDocComment(); if ($docComment === null) { return null; } /** @psalm-suppress ImpureMethodCall */ $comment = $docComment->getReformattedText(); assert(is_string($comment) && $comment !== ''); return $comment; } } hasAttribute('startFilePos')) { return -1; } return self::calculateColumn($source, $node->getStartFilePos()); } /** * @throws InvalidNodePosition * @throws NoNodePosition * * @psalm-pure */ public static function getEndColumn(string $source, Node $node) : int { if (!$node->hasAttribute('endFilePos')) { return -1; } return self::calculateColumn($source, $node->getEndFilePos()); } /** * @throws InvalidNodePosition * * @psalm-pure */ private static function calculateColumn(string $source, int $position) : int { $sourceLength = strlen($source); if ($position >= $sourceLength) { return -1; } $lineStartPosition = strrpos($source, "\n", $position - $sourceLength); /** @psalm-var positive-int */ return $lineStartPosition === \false ? $position + 1 : $position - $lineStartPosition; } } sourceLocator = self::$sharedSourceLocator; $this->reflector = self::$sharedReflector; $this->phpParser = self::$sharedPhpParser; $this->sourceStubber = self::$sharedSourceStubber; $this->printer = self::$sharedPrinter; } public function sourceLocator() : SourceLocator { $astLocator = $this->astLocator(); $sourceStubber = $this->sourceStubber(); return $this->sourceLocator ?? ($this->sourceLocator = new MemoizingSourceLocator(new AggregateSourceLocator([new PhpInternalSourceLocator($astLocator, $sourceStubber), new EvaledCodeSourceLocator($astLocator, $sourceStubber), new AutoloadSourceLocator($astLocator, $this->phpParser())]))); } public function reflector() : Reflector { return $this->reflector ?? ($this->reflector = new DefaultReflector($this->sourceLocator())); } public function phpParser() : Parser { return $this->phpParser ?? ($this->phpParser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7, new Emulative(['usedAttributes' => ['comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos']]))); } public function astLocator() : AstLocator { return $this->astLocator ?? ($this->astLocator = new AstLocator($this->phpParser())); } public function findReflectionsOnLine() : FindReflectionOnLine { return $this->findReflectionOnLine ?? ($this->findReflectionOnLine = new FindReflectionOnLine($this->sourceLocator(), $this->astLocator())); } public function sourceStubber() : SourceStubber { return $this->sourceStubber ?? ($this->sourceStubber = new AggregateSourceStubber(new PhpStormStubsSourceStubber($this->phpParser(), $this->printer(), self::$phpVersion), new ReflectionSourceStubber($this->printer()))); } public function printer() : Standard { return $this->printer ?? ($this->printer = new Standard(['shortArraySyntax' => \true])); } } null, self::IDENTIFIER_FUNCTION => null, self::IDENTIFIER_CONSTANT => null]; /** * @var string */ private $name; public function __construct(string $type = self::IDENTIFIER_CLASS) { if (!array_key_exists($type, self::VALID_TYPES)) { throw new InvalidArgumentException(sprintf('%s is not a valid identifier type', $type)); } $this->name = $type; } public function getName() : string { return $this->name; } public function isClass() : bool { return $this->name === self::IDENTIFIER_CLASS; } public function isFunction() : bool { return $this->name === self::IDENTIFIER_FUNCTION; } public function isConstant() : bool { return $this->name === self::IDENTIFIER_CONSTANT; } } type = $type; if ($name === self::WILDCARD || $name === ReflectionFunction::CLOSURE_NAME || strpos($name, ReflectionClass::ANONYMOUS_CLASS_NAME_PREFIX) === 0) { $this->name = $name; return; } $name = ltrim($name, '\\'); if (!preg_match(self::VALID_NAME_REGEXP, $name)) { throw InvalidIdentifierName::fromInvalidName($name); } $this->name = $name; } public function getName() : string { return $this->name; } public function getType() : \PHPStan\BetterReflection\Identifier\IdentifierType { return $this->type; } public function isClass() : bool { return $this->type->isClass(); } public function isFunction() : bool { return $this->type->isFunction(); } public function isConstant() : bool { return $this->type->isConstant(); } } 8, 'endcap' => GEOSBUF_CAP_ROUND, 'join' => GEOSBUF_JOIN_ROUND, 'mitre_limit' => 5.0, 'single_sided' => false ]): GEOSGeometry {} /** * @param float $distance * @param array $styleArray * Keys supported: * 'quad_segs' * Type: int * Number of segments used to approximate * a quarter circle (defaults to 8). * 'join' * Type: long * Join style (defaults to GEOSBUF_JOIN_ROUND) * 'mitre_limit' * Type: double * mitre ratio limit (only affects joins with GEOSBUF_JOIN_MITRE style) * 'miter_limit' is also accepted as a synonym for 'mitre_limit'. * @return GEOSGeometry * @throws Exception */ public function offsetCurve(float $distance, array $styleArray = [ 'quad_segs' => 8, 'join' => GEOSBUF_JOIN_ROUND, 'mitre_limit' => 5.0 ]): GEOSGeometry {} /** * @return GEOSGeometry * @throws Exception */ public function envelope(): GEOSGeometry {} /** * @param GEOSGeometry $geom * @return GEOSGeometry * @throws Exception */ public function intersection(GEOSGeometry $geom): GEOSGeometry {} /** * @return GEOSGeometry * @throws Exception */ public function convexHull(): GEOSGeometry {} /** * @param GEOSGeometry $geom * @return GEOSGeometry * @throws Exception */ public function difference(GEOSGeometry $geom): GEOSGeometry {} /** * @param GEOSGeometry $geom * @return GEOSGeometry * @throws Exception */ public function symDifference(GEOSGeometry $geom): GEOSGeometry {} /** * @return GEOSGeometry * @throws Exception */ public function boundary(): GEOSGeometry {} /** * @param GEOSGeometry|null $geom * @return GEOSGeometry * @throws Exception */ public function union(GEOSGeometry $geom = null): GEOSGeometry {} /** * @return GEOSGeometry * @throws Exception */ public function pointOnSurface(): GEOSGeometry {} /** * @return GEOSGeometry * @throws Exception */ public function centroid(): GEOSGeometry {} /** * @param GEOSGeometry $geom * @param string|null $pattern * @return bool|string * @throws Exception */ public function relate(GEOSGeometry $geom, string $pattern = null) {} /** * @param GEOSGeometry $geom * @param int $rule * @return string * @throws Exception */ public function relateBoundaryNodeRule(GEOSGeometry $geom, int $rule = GEOSRELATE_BNR_OGC): string {} /** * @param float $tolerance * @param bool $preserveTopology * @return GEOSGeometry * @throws Exception */ public function simplify(float $tolerance, bool $preserveTopology = false): GEOSGeometry {} /** * @return GEOSGeometry * @throws Exception */ public function normalize(): GEOSGeometry {} /** * @param float $gridSize * @param int $flags * @return GEOSGeometry * @throws Exception */ public function setPrecision(float $gridSize, int $flags = 0): GEOSGeometry {} /** * @return float */ public function getPrecision(): float {} /** * @return GEOSGeometry * @throws Exception */ public function extractUniquePoints(): GEOSGeometry {} /** * @param GEOSGeometry $geom * @return bool * @throws Exception */ public function disjoint(GEOSGeometry $geom): bool {} /** * @param GEOSGeometry $geom * @return bool * @throws Exception */ public function touches(GEOSGeometry $geom): bool {} /** * @param GEOSGeometry $geom * @return bool * @throws Exception */ public function intersects(GEOSGeometry $geom): bool {} /** * @param GEOSGeometry $geom * @return bool * @throws Exception */ public function crosses(GEOSGeometry $geom): bool {} /** * @param GEOSGeometry $geom * @return bool * @throws Exception */ public function within(GEOSGeometry $geom): bool {} /** * @param GEOSGeometry $geom * @return bool * @throws Exception */ public function contains(GEOSGeometry $geom): bool {} /** * @param GEOSGeometry $geom * @return bool * @throws Exception */ public function overlaps(GEOSGeometry $geom): bool {} /** * @param GEOSGeometry $geom * @return bool * @throws Exception */ public function covers(GEOSGeometry $geom): bool {} /** * @param GEOSGeometry $geom * @return bool * @throws Exception */ public function coveredBy(GEOSGeometry $geom): bool {} /** * @param GEOSGeometry $geom * @return bool * @throws Exception */ public function equals(GEOSGeometry $geom): bool {} /** * @param GEOSGeometry $geom * @param float $tolerance * @return bool * @throws Exception */ public function equalsExact(GEOSGeometry $geom, float $tolerance = 0): bool {} /** * @return bool * @throws Exception */ public function isEmpty(): bool {} /** * @return array * @throws Exception */ public function checkValidity(): array {} /** * @return bool * @throws Exception */ public function isSimple(): bool {} /** * @return bool * @throws Exception */ public function isRing(): bool {} /** * @return bool * @throws Exception */ public function hasZ(): bool {} /** * @return bool * @throws Exception */ public function isClosed(): bool {} /** * @return string * @throws Exception */ public function typeName(): string {} /** * @return int * @throws Exception */ public function typeId(): int {} /** * @return int */ public function getSRID(): int {} /** * @param int $srid * @throws Exception */ public function setSRID(int $srid): void {} /** * @return int * @throws Exception */ public function numGeometries(): int {} /** * @param int $n * @return GEOSGeometry * @throws Exception */ public function geometryN(int $n): GEOSGeometry {} /** * @return int * @throws Exception */ public function numInteriorRings(): int {} /** * @return int * @throws Exception */ public function numPoints(): int {} /** * @return float * @throws Exception */ public function getX(): float {} /** * @return float * @throws Exception */ public function getY(): float {} /** * @param int $n * @return GEOSGeometry * @throws Exception */ public function interiorRingN(int $n): GEOSGeometry {} /** * @return GEOSGeometry * @throws Exception */ public function exteriorRing(): GEOSGeometry {} /** * @return int * @throws Exception */ public function numCoordinates(): int {} /** * @return int * @throws Exception */ public function dimension(): int {} /** * @return int * @throws Exception */ public function coordinateDimension(): int {} /** * @param int $n * @return GEOSGeometry * @throws Exception */ public function pointN(int $n): GEOSGeometry {} /** * @return GEOSGeometry * @throws Exception */ public function startPoint(): GEOSGeometry {} /** * @return GEOSGeometry * @throws Exception */ public function endPoint(): GEOSGeometry {} /** * @return float * @throws Exception */ public function area(): float {} /** * @return float * @throws Exception */ public function length(): float {} /** * @param GEOSGeometry $geom * @return float * @throws Exception */ public function distance(GEOSGeometry $geom): float {} /** * @param GEOSGeometry $geom * @return float * @throws Exception */ public function hausdorffDistance(GEOSGeometry $geom): float {} /** * @param GEOSGeometry $geom * @param float $tolerance * @return GEOSGeometry */ public function snapTo(GEOSGeometry $geom, float $tolerance): GEOSGeometry {} /** * @return GEOSGeometry * @throws Exception */ public function node(): GEOSGeometry {} /** * @param float $tolerance Snapping tolerance to use for improved robustness * @param bool $onlyEdges if true, will return a MULTILINESTRING, * otherwise (the default) it will return a GEOMETRYCOLLECTION containing triangular POLYGONs. * @return GEOSGeometry * @throws Exception */ public function delaunayTriangulation(float $tolerance = 0.0, bool $onlyEdges = false): GEOSGeometry {} /** * @param float $tolerance Snapping tolerance to use for improved robustness * @param bool $onlyEdges If true will return a MULTILINESTRING, * otherwise (the default) it will return a GEOMETRYCOLLECTION containing POLYGONs. * @param GEOSGeometry|null $extent Clip returned diagram by the extent of the given geometry * @return GEOSGeometry * @throws Exception */ public function voronoiDiagram(float $tolerance = 0.0, bool $onlyEdges = false, GEOSGeometry $extent = null): GEOSGeometry {} /** * @param float $xmin * @param float $ymin * @param float $xmax * @param float $ymax * @return GEOSGeometry * @throws Exception */ public function clipByRect(float $xmin, float $ymin, float $xmax, float $ymax): GEOSGeometry {} } /** * Class GEOSWKBWriter * @see https://github.com/libgeos/php-geos/blob/master/tests/004_WKBWriter.phpt */ class GEOSWKBWriter { /** * GEOSWKBWriter constructor. */ public function __construct() {} /** * @return int */ public function getOutputDimension(): int {} /** * @param int $dimension * @throws Exception */ public function setOutputDimension(int $dimension): void {} /** * @return int */ public function getByteOrder(): int {} /** * @param int $byteOrder * @throws Exception */ public function setByteOrder(int $byteOrder): void {} /** * @return int */ public function getIncludeSRID(): int {} /** * @param int $srid * @throws Exception */ public function setIncludeSRID(int $srid): void {} /** * @param GEOSGeometry $geom * @return string * @throws Exception */ public function write(GEOSGeometry $geom): string {} /** * @param GEOSGeometry $geom * @return string * @throws Exception */ public function writeHEX(GEOSGeometry $geom): string {} } /** * Class GEOSWKBReader * @see https://github.com/libgeos/php-geos/blob/master/tests/005_WKBReader.phpt */ class GEOSWKBReader { /** * GEOSWKBReader constructor. */ public function __construct() {} /** * @param string $wkb * @return GEOSGeometry * @throws Exception */ public function read(string $wkb): GEOSGeometry {} /** * @param string $wkb * @return GEOSGeometry * @throws Exception */ public function readHEX(string $wkb): GEOSGeometry {} } * Construct a new Judy object. A Judy object can be accessed like a PHP Array. * @link https://php.net/manual/en/judy.construct.php * @param int $judy_type

The Judy type to be used.

*/ public function __construct($judy_type) {} /** * (PECL judy >= 0.1.1)
* Destruct a Judy object. * @link https://php.net/manual/en/judy.destruct.php */ public function __destruct() {} /** * (PECL judy >= 0.1.1)
* Locate the Nth index present in the Judy array. * @link https://php.net/manual/en/judy.bycount.php * @param int $nth_index

Nth index to return. If nth_index equal 1, then it will return the first index in the array.

* @return int

Return the index at the given Nth position.

*/ public function byCount($nth_index) {} /** * (PECL judy >= 0.1.1)
* Count the number of elements in the Judy array. * @link https://php.net/manual/en/judy.count.php * @param int $index_start [optional]

Start counting from the given index. Default is first index.

* @param int $index_end [optional]

Stop counting when reaching this index. Default is last index.

* @return int

Return the number of elements.

*/ public function count($index_start = 0, $index_end = -1) {} /** * (PECL judy >= 0.1.1)
* Search (inclusive) for the first index present that is equal to or greater than the passed Index. * @link https://php.net/manual/en/judy.first.php * @param mixed $index [optional]

The index can be an integer or a string corresponding to the index where to start the search.

* @return mixed

Return the corresponding index in the array.

*/ public function first($index = 0) {} /** * (PECL judy >= 0.1.1)
* Search (inclusive) for the first absent index that is equal to or greater than the passed Index. * @link https://php.net/manual/en/judy.firstempty.php * @param mixed $index [optional]

The index can be an integer or a string corresponding to the index where to start the search.

* @return mixed

Return the corresponding index in the array.

*/ public function firstEmpty($index = 0) {} /** * (PECL judy >= 0.1.1)
* Free the entire Judy array. * @link https://php.net/manual/en/judy.free.php */ public function free() {} /** * (PECL judy >= 0.1.1)
* Return an integer corresponding to the Judy type of the current object. * @link https://php.net/manual/en/judy.gettype.php * @return int

Return an integer corresponding to a Judy type.

*/ public function getType() {} /** * (PECL judy >= 0.1.1)
* Search (inclusive) for the last index present that is equal to or less than the passed Index. * @link https://php.net/manual/en/judy.last.php * @param int|string $index [optional]

The index can be an integer or a string corresponding to the index where to start the search.

* @return mixed

Return the corresponding index in the array.

*/ public function last($index = -1) {} /** * (PECL judy >= 0.1.1)
* Search (inclusive) for the last absent index that is equal to or less than the passed Index. * @link https://php.net/manual/en/judy.lastempty.php * @param int|string $index [optional]

The index can be an integer or a string corresponding to the index where to start the search.

* @return mixed

Return the corresponding index in the array.

*/ public function lastEmpty($index = -1) {} /** * (PECL judy >= 0.1.1)
* Return the memory used by the Judy array. * @link https://php.net/manual/en/judy.memoryusage.php * @return int

Return the memory used in bytes.

*/ public function memoryUsage() {} /** * (PECL judy >= 0.1.1)
* Search (exclusive) for the next index present that is greater than the passed Index. * @link https://php.net/manual/en/judy.next.php * @param mixed $index

The index can be an integer or a string corresponding to the index where to start the search.

* @return mixed

Return the corresponding index in the array.

*/ public function next($index) {} /** * (PECL judy >= 0.1.1)
* Search (exclusive) for the next absent index that is greater than the passed Index. * @link https://php.net/manual/en/judy.nextempty.php * @param int|string $index

The index can be an integer or a string corresponding to the index where to start the search.

* @return mixed

Return the corresponding index in the array.

*/ public function nextEmpty($index) {} /** * (PECL judy >= 0.1.1)
* Whether or not an offset exists. * @link https://php.net/manual/en/judy.offsetexists.php * @param mixed $offset

An offset to check for.

* @return bool

Returns TRUE on success or FALSE on failure.

*/ public function offsetExists($offset) {} /** * (PECL judy >= 0.1.1)
* Returns the value at specified offset. * @link https://php.net/manual/en/judy.offsetget.php * @param mixed $offset

An offset to check for.

* @return mixed

Can return all value types.

*/ public function offsetGet($offset) {} /** * (PECL judy >= 0.1.1)
* Assigns a value to the specified offset. * @link https://php.net/manual/en/judy.offsetset.php * @param mixed $offset

The offset to assign the value to.

* @param mixed $value

The value to set.

*/ public function offsetSet($offset, $value) {} /** * (PECL judy >= 0.1.1)
* Unsets an offset. * @link https://php.net/manual/en/judy.offsetunset.php * @param mixed $offset

The offset to assign the value to.

*/ public function offsetUnset($offset) {} /** * (PECL judy >= 0.1.1)
* Search (exclusive) for the previous index present that is less than the passed Index. * @link https://php.net/manual/en/judy.prev.php * @param mixed $index

The index can be an integer or a string corresponding to the index where to start the search.

* @return mixed

Return the corresponding index in the array.

*/ public function prev($index) {} /** * (PECL judy >= 0.1.1)
* Search (exclusive) for the previous index absent that is less than the passed Index. * @link https://php.net/manual/en/judy.prevempty.php * @param mixed $index

The index can be an integer or a string corresponding to the index where to start the search.

* @return mixed

Return the corresponding index in the array.

*/ public function prevEmpty($index) {} /** * (PECL judy >= 0.1.1)
* Count the number of elements in the Judy array.
* This method is an alias of const count. * @link https://php.net/manual/en/judy.size.php * @param int $index_start [optional]

Start counting from the given index. Default is first index.

* @param int $index_end [optional]

Stop counting when reaching this index. Default is last index.

* @return int

Return the number of elements.

*/ public function size($index_start = 0, $index_end = -1) {} } // End of judy. * An optional seed value *

* @param int $mode [optional]

* Use one of the following constants to specify the implementation of the algorithm to use. *

* @return void */ function mt_srand( #[LanguageLevelTypeAware(['8.3' => 'int|null'], default: 'int')] $seed = null, #[PhpStormStubsElementAvailable(from: '7.1')] int $mode = MT_RAND_MT19937 ): void {} /** * Seed the random number generator *

Note: As of PHP 7.1.0, {@see srand()} has been made * an alias of {@see mt_srand()}. *

* @link https://php.net/manual/en/function.srand.php * @param int|null $seed

* Optional seed value *

* @param int $mode [optional]

* Use one of the following constants to specify the implementation of the algorithm to use. *

* @return void */ function srand( #[LanguageLevelTypeAware(['8.3' => 'int|null'], default: 'int')] $seed = null, #[PhpStormStubsElementAvailable(from: '7.1')] int $mode = MT_RAND_MT19937 ): void {} /** * Generate a random integer * @link https://php.net/manual/en/function.rand.php * @param int $min [optional] * @param int $max [optional] * @return int A pseudo random value between min * (or 0) and max (or getrandmax, inclusive). */ function rand(int $min, int $max): int {} /** * Generate a random value via the Mersenne Twister Random Number Generator * @link https://php.net/manual/en/function.mt-rand.php * @param int $min [optional]

* Optional lowest value to be returned (default: 0) *

* @param int $max [optional]

* Optional highest value to be returned (default: mt_getrandmax()) *

* @return int A random integer value between min (or 0) * and max (or mt_getrandmax, inclusive) */ function mt_rand(int $min, int $max): int {} /** * Show largest possible random value * @link https://php.net/manual/en/function.mt-getrandmax.php * @return int the maximum random value returned by mt_rand */ #[Pure] function mt_getrandmax(): int {} /** * Show largest possible random value * @link https://php.net/manual/en/function.getrandmax.php * @return int The largest possible random value returned by rand */ #[Pure] function getrandmax(): int {} /** * Generates cryptographically secure pseudo-random bytes * @link https://php.net/manual/en/function.random-bytes.php * @param int $length The length of the random string that should be returned in bytes. * @return string Returns a string containing the requested number of cryptographically secure random bytes. * @since 7.0 * @throws Random\RandomException if an appropriate source of randomness cannot be found. */ function random_bytes(int $length): string {} /** * Generates cryptographically secure pseudo-random integers * @link https://php.net/manual/en/function.random-int.php * @param int $min The lowest value to be returned, which must be PHP_INT_MIN or higher. * @param int $max The highest value to be returned, which must be less than or equal to PHP_INT_MAX. * @return int Returns a cryptographically secure random integer in the range min to max, inclusive. * @since 7.0 * @throws Random\RandomException if an appropriate source of randomness cannot be found. */ function random_int(int $min, int $max): int {} } namespace Random\Engine { /** * @since 8.2 */ final class Mt19937 implements \Random\Engine { public function __construct(int|null $seed = null, int $mode = MT_RAND_MT19937) {} public function generate(): string {} public function __serialize(): array {} public function __unserialize(array $data): void {} public function __debugInfo(): array {} } /** * @since 8.2 */ final class PcgOneseq128XslRr64 implements \Random\Engine { public function __construct(string|int|null $seed = null) {} public function generate(): string {} public function jump(int $advance): void {} public function __serialize(): array {} public function __unserialize(array $data): void {} public function __debugInfo(): array {} } /** * @since 8.2 */ final class Xoshiro256StarStar implements \Random\Engine { public function __construct(string|int|null $seed = null) {} public function generate(): string {} public function jump(): void {} public function jumpLong(): void {} public function __serialize(): array {} public function __unserialize(array $data): void {} public function __debugInfo(): array {} } /** * @since 8.2 */ final class Secure implements \Random\CryptoSafeEngine { public function generate(): string {} } } namespace Random { use Error; use Exception; /** * @since 8.2 */ interface Engine { public function generate(): string; } /** * @since 8.2 */ interface CryptoSafeEngine extends Engine {} /** * @since 8.2 */ final class Randomizer { public readonly Engine $engine; public function __construct(?Engine $engine = null) {} public function nextInt(): int {} public function getInt(int $min, int $max): int {} public function getBytes(int $length): string {} public function shuffleArray(array $array): array {} public function shuffleBytes(string $bytes): string {} public function pickArrayKeys(array $array, int $num): array {} public function __serialize(): array {} public function __unserialize(array $data): void {} /** * @since 8.3 */ public function nextFloat(): float {} /** * @since 8.3 */ public function getFloat(float $min, float $max, IntervalBoundary $boundary = IntervalBoundary::ClosedOpen): float {} /** * @since 8.3 */ public function getBytesFromString(string $string, int $length): string {} } /** * @since 8.2 */ class RandomError extends Error {} /** * @since 8.2 */ class BrokenRandomEngineError extends RandomError {} /** * @since 8.2 */ class RandomException extends Exception {} /** * @since 8.3 */ enum IntervalBoundary implements \UnitEnum { public string $name; case ClosedOpen; case ClosedClosed; case OpenClosed; case OpenOpen; public static function cases(): array {} } } 'localhost', * 'port' => 6379, * 'readTimeout' => 2.5, * 'connectTimeout' => 2.5, * 'persistent' => true, * // Valid formats: NULL, ['user', 'pass'], 'pass', or ['pass'] * 'auth' => ['phpredis', 'phpredis'], * // See PHP stream options for valid SSL configuration settings. * 'ssl' => ['verify_peer' => false], * // How quickly to retry a connection after we time out or it closes. * // Note that this setting is overridden by 'backoff' strategies. * 'retryInterval' => 100, * // Which backoff algorithm to use. 'decorrelated jitter' is * // likely the best one for most solution, but there are many * // to choose from: * // REDIS_BACKOFF_ALGORITHM_DEFAULT * // REDIS_BACKOFF_ALGORITHM_CONSTANT * // REDIS_BACKOFF_ALGORITHM_UNIFORM * // REDIS_BACKOFF_ALGORITHM_EXPONENTIAL * // REDIS_BACKOFF_ALGORITHM_FULL_JITTER * // REDIS_BACKOFF_ALGORITHM_EQUAL_JITTER * // REDIS_BACKOFF_ALGORITHM_DECORRELATED_JITTER * // 'base', and 'cap' are in milliseconds and represent the first * // delay redis will use when reconnecting, and the maximum delay * // we will reach while retrying. * 'backoff' => [ * 'algorithm' => Redis::BACKOFF_ALGORITHM_DECORRELATED_JITTER, * 'base' => 500, * 'cap' => 750, * ] * ]; * Note: If you do wish to connect via the constructor, only 'host' is * strictly required, which will cause PhpRedis to connect to that * host on Redis' default port (6379). * @param array|null $options * @see https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ * @see Redis::connect() */ public function __construct(?array $options = null) {} public function __destruct() {} /** * Compress a value with the currently configured compressor as set with * Redis::setOption(). * @param string $value The value to be compressed * @return string The compressed result * @see Redis::setOption() */ public function _compress(string $value): string {} /** * Uncompress the provided argument that has been compressed with the * currently configured compressor as set with Redis::setOption(). * @param string $value The compressed value to uncompress. * @return string The uncompressed result. * @see Redis::setOption() */ public function _uncompress(string $value): string {} /** * Prefix the passed argument with the currently set key prefix as set * with Redis::setOption(). * @param string $key The key/string to prefix * @return string The prefixed string */ public function _prefix(string $key): string {} /** * Serialize the provided value with the currently set serializer as set * with Redis::setOption(). * @param mixed $value The value to serialize * @return string The serialized result * @see Redis::setOption() */ public function _serialize(mixed $value): string {} /** * Unserialize the passed argument with the currently set serializer as set * with Redis::setOption(). * @param string $value The value to unserialize * @return mixed The unserialized result * @see Redis::setOption() */ public function _unserialize(string $value): mixed {} /** * Pack the provided value with the configured serializer and compressor * as set with Redis::setOption(). * @param mixed $value The value to pack * @return string The packed result having been serialized and * compressed. */ public function _pack(mixed $value): string {} /** * Unpack the provided value with the configured compressor and serializer * as set with Redis::setOption(). * @param string $value The value which has been serialized and compressed. * @return mixed The uncompressed and eserialized value. */ public function _unpack(string $value): mixed {} public function acl(string $subcmd, string ...$args): mixed {} /** * Append data to a Redis STRING key. * @param string $key The key in question * @param mixed $value The data to append to the key. * @return Redis|int|false The new string length of the key or false on failure. * @see https://redis.io/commands/append * @example * $redis->set('foo', 'hello); * $redis->append('foo', 'world'); */ public function append(string $key, mixed $value): Redis|int|false {} /** * Authenticate a Redis connection after its been established. * $redis->auth('password'); * $redis->auth(['password']); * $redis->auth(['username', 'password']); * @see https://redis.io/commands/auth * @param mixed $credentials A string password, or an array with one or two string elements. * @return Redis|bool Whether the AUTH was successful. */ public function auth(#[\SensitiveParameter] mixed $credentials): Redis|bool {} /** * Execute a save of the Redis database in the background. * @see https://redis.io/commands/bgsave * @return Redis|bool Whether the command was successful. */ public function bgSave(): Redis|bool {} /** * Asynchronously rewrite Redis' append-only file * @see https://redis.io/commands/bgrewriteaof * @return Redis|bool Whether the command was successful. */ public function bgrewriteaof(): Redis|bool {} /** * Count the number of set bits in a Redis string. * @see https://redis.io/commands/bitcount/ * @param string $key The key in question (must be a string key) * @param int $start The index where Redis should start counting. If omitted it * defaults to zero, which means the start of the string. * @param int $end The index where Redis should stop counting. If omitted it * defaults to -1, meaning the very end of the string. * @param bool $bybit Whether or not Redis should treat $start and $end as bit * positions, rather than bytes. * @return Redis|int|false The number of bits set in the requested range. */ public function bitcount(string $key, int $start = 0, int $end = -1, bool $bybit = false): Redis|int|false {} public function bitop(string $operation, string $deskey, string $srckey, string ...$other_keys): Redis|int|false {} /** * Return the position of the first bit set to 0 or 1 in a string. * @see https://redis.io/commands/bitpos/ * @param string $key The key to check (must be a string) * @param bool $bit Whether to look for an unset (0) or set (1) bit. * @param int $start Where in the string to start looking. * @param int $end Where in the string to stop looking. * @param bool $bybit If true, Redis will treat $start and $end as BIT values and not bytes, so if start * was 0 and end was 2, Redis would only search the first two bits. * @return Redis|int|false The position of the first set or unset bit. **/ public function bitpos(string $key, bool $bit, int $start = 0, int $end = -1, bool $bybit = false): Redis|int|false {} /** * Pop an element off the beginning of a Redis list or lists, potentially blocking up to a specified * timeout. This method may be called in two distinct ways, of which examples are provided below. * @see https://redis.io/commands/blpop/ * @param string|array $key_or_keys This can either be a string key or an array of one or more * keys. * @param string|float|int $timeout_or_key If the previous argument was a string key, this can either * be an additional key, or the timeout you wish to send to * the command. * @return Redis|array|null|false Can return various things depending on command and data in Redis. * @example * $redis->blPop('list1', 'list2', 'list3', 1.5); * $relay->blPop(['list1', 'list2', 'list3'], 1.5); */ public function blPop(string|array $key_or_keys, string|float|int $timeout_or_key, mixed ...$extra_args): Redis|array|null|false {} /** * Pop an element off of the end of a Redis list or lists, potentially blocking up to a specified timeout. * The calling convention is identical to Redis::blPop() so see that documentation for more details. * @see https://redis.io/commands/brpop/ * @see Redis::blPop() */ public function brPop(string|array $key_or_keys, string|float|int $timeout_or_key, mixed ...$extra_args): Redis|array|null|false {} /** * Pop an element from the end of a Redis list, pushing it to the beginning of another Redis list, * optionally blocking up to a specified timeout. * @see https://redis.io/commands/brpoplpush/ * @param string $src The source list * @param string $dst The destination list * @param int|float $timeout The number of seconds to wait. Note that you must be connected * to Redis >= 6.0.0 to send a floating point timeout. */ public function brpoplpush(string $src, string $dst, int|float $timeout): Redis|string|false {} /** * POP the maximum scoring element off of one or more sorted sets, blocking up to a specified * timeout if no elements are available. * Following are examples of the two main ways to call this method. * **NOTE**: We reccomend calling this function with an array and a timeout as the other strategy * may be deprecated in future versions of PhpRedis * @see https://redis.io/commands/bzpopmax * @param string|array $key Either a string key or an array of one or more keys. * @param string|int $timeout_or_key If the previous argument was an array, this argument * must be a timeout value. Otherwise it could also be * another key. * @param mixed $extra_args Can consist of additional keys, until the last argument * which needs to be a timeout. * @return Redis|array|false The popped elements. * @example * $redis->bzPopMax('key1', 'key2', 'key3', 1.5); * $redis->bzPopMax(['key1', 'key2', 'key3'], 1.5); */ public function bzPopMax(string|array $key, string|int $timeout_or_key, mixed ...$extra_args): Redis|array|false {} /** * POP the minimum scoring element off of one or more sorted sets, blocking up to a specified timeout * if no elements are available * This command is identical in semantics to bzPopMax so please see that method for more information. * @see https://redis.io/commands/bzpopmin * @see Redis::bzPopMax() */ public function bzPopMin(string|array $key, string|int $timeout_or_key, mixed ...$extra_args): Redis|array|false {} /** * POP one or more elements from one or more sorted sets, blocking up to a specified amount of time * when no elements are available. * @param float $timeout How long to block if there are no element available * @param array $keys The sorted sets to pop from * @param string $from The string 'MIN' or 'MAX' (case insensitive) telling Redis whether you wish to * pop the lowest or highest scoring members from the set(s). * @param int $count Pop up to how many elements. * @return Redis|array|null|false This function will return an array of popped elements, or false * depending on whether any elements could be popped within the * specified timeout. * NOTE: If Redis::OPT_NULL_MULTIBULK_AS_NULL is set to true via Redis::setOption(), this method will * instead return NULL when Redis doesn't pop any elements. */ public function bzmpop(float $timeout, array $keys, string $from, int $count = 1): Redis|array|null|false {} /** * POP one or more of the highest or lowest scoring elements from one or more sorted sets. * @see https://redis.io/commands/zmpop * @param array $keys One or more sorted sets * @param string $from The string 'MIN' or 'MAX' (case insensitive) telling Redis whether you want to * pop the lowest or highest scoring elements. * @param int $count Pop up to how many elements at once. * @return Redis|array|null|false An array of popped elements or false if none could be popped. */ public function zmpop(array $keys, string $from, int $count = 1): Redis|array|null|false {} /** * Pop one or more elements from one or more Redis LISTs, blocking up to a specified timeout when * no elements are available. * @see https://redis.io/commands/blmpop * @param float $timeout The number of seconds Redis will block when no elements are available. * @param array $keys One or more Redis LISTs to pop from. * @param string $from The string 'LEFT' or 'RIGHT' (case insensitive), telling Redis whether * to pop elements from the beginning or end of the LISTs. * @param int $count Pop up to how many elements at once. * @return Redis|array|null|false One or more elements popped from the list(s) or false if all LISTs * were empty. */ public function blmpop(float $timeout, array $keys, string $from, int $count = 1): Redis|array|null|false {} /** * Pop one or more elements off of one or more Redis LISTs. * @see https://redis.io/commands/lmpop * @param array $keys An array with one or more Redis LIST key names. * @param string $from The string 'LEFT' or 'RIGHT' (case insensitive), telling Redis whether to pop\ * elements from the beginning or end of the LISTs. * @param int $count The maximum number of elements to pop at once. * @return Redis|array|null|false One or more elements popped from the LIST(s) or false if all the LISTs * were empty. */ public function lmpop(array $keys, string $from, int $count = 1): Redis|array|null|false {} /** * Reset any last error on the connection to NULL * @return bool This should always return true or throw an exception if we're not connected. * @see Redis::getLastError() * @example * $redis = new Redis(['host' => 'localhost']); * $redis->set('string', 'this_is_a_string'); * $redis->smembers('string'); * var_dump($redis->getLastError()); * $redis->clearLastError(); * var_dump($redis->getLastError()); */ public function clearLastError(): bool {} public function client(string $opt, mixed ...$args): mixed {} public function close(): bool {} public function command(?string $opt = null, mixed ...$args): mixed {} /** * Execute the Redis CONFIG command in a variety of ways. * What the command does in particular depends on the `$operation` qualifier. * Operations that PhpRedis supports are: RESETSTAT, REWRITE, GET, and SET. * @param string $operation The CONFIG operation to execute (e.g. GET, SET, REWRITE). * @param array|string|null $key_or_settings One or more keys or values. * @param string|null $value The value if this is a `CONFIG SET` operation. * @return mixed * @see https://redis.io/commands/config * @example * $redis->config('GET', 'timeout'); * $redis->config('GET', ['timeout', 'databases']); * $redis->config('SET', 'timeout', 30); * $redis->config('SET', ['timeout' => 30, 'loglevel' => 'warning']); */ public function config(string $operation, array|string|null $key_or_settings = null, ?string $value = null): mixed {} public function connect( string $host, int $port = 6379, float $timeout = 0, ?string $persistent_id = null, int $retry_interval = 0, float $read_timeout = 0, ?array $context = null ): bool {} /** * Make a copy of a key. * $redis = new Redis(['host' => 'localhost']); * @param string $src The key to copy * @param string $dst The name of the new key created from the source key. * @param array|null $options An array with modifiers on how COPY should operate. * * $options = [ * 'REPLACE' => true|false # Whether to replace an existing key. * 'DB' => int # Copy key to specific db. * ]; * * @return Redis|bool True if the copy was completed and false if not. * @see https://redis.io/commands/copy * @example * $redis->pipeline() * ->select(1) * ->del('newkey') * ->select(0) * ->del('newkey') * ->mset(['source1' => 'value1', 'exists' => 'old_value']) * ->exec(); * var_dump($redis->copy('source1', 'newkey')); * var_dump($redis->copy('source1', 'newkey', ['db' => 1])); * var_dump($redis->copy('source1', 'exists')); * var_dump($redis->copy('source1', 'exists', ['REPLACE' => true])); */ public function copy(string $src, string $dst, ?array $options = null): Redis|bool {} /** * Return the number of keys in the currently selected Redis database. * @see https://redis.io/commands/dbsize * @return Redis|int|false The number of keys or false on failure. * @example * $redis = new Redis(['host' => 'localhost']); * $redis->flushdb(); * $redis->set('foo', 'bar'); * var_dump($redis->dbsize()); * $redis->mset(['a' => 'a', 'b' => 'b', 'c' => 'c', 'd' => 'd']); * var_dump($redis->dbsize()); */ public function dbSize(): Redis|int|false {} public function debug(string $key): Redis|string {} /** * Decrement a Redis integer by 1 or a provided value. * @param string $key The key to decrement * @param int $by How much to decrement the key. Note that if this value is * not sent or is set to `1`, PhpRedis will actually invoke * the 'DECR' command. If it is any value other than `1` * PhpRedis will actually send the `DECRBY` command. * @return Redis|int|false The new value of the key or false on failure. * @see https://redis.io/commands/decr * @see https://redis.io/commands/decrby * @example $redis->decr('counter'); * @example $redis->decr('counter', 2); */ public function decr(string $key, int $by = 1): Redis|int|false {} /** * Decrement a redis integer by a value * @param string $key The integer key to decrement. * @param int $value How much to decrement the key. * @return Redis|int|false The new value of the key or false on failure. * @see https://redis.io/commands/decrby * @example $redis->decrby('counter', 1); * @example $redis->decrby('counter', 2); */ public function decrBy(string $key, int $value): Redis|int|false {} /** * Delete one or more keys from Redis. * This method can be called in two distinct ways. The first is to pass a single array * of keys to delete, and the second is to pass N arguments, all names of keys. See * below for an example of both strategies. * @param array|string $key Either an array with one or more key names or a string with * the name of a key. * @param string ...$other_keys One or more additional keys passed in a variadic fashion. * @return Redis|int|false The number of keys that were deleted * @see https://redis.io/commands/del * @example $redis->del('key:0', 'key:1'); * @example $redis->del(['key:2', 'key:3', 'key:4']); */ public function del(array|string $key, string ...$other_keys): Redis|int|false {} /** * @deprecated */ public function delete(array|string $key, string ...$other_keys): Redis|int|false {} /** * Discard a transaction currently in progress. * @return Redis|bool True if we could discard the transaction. * @example * $redis->getMode(); * $redis->set('foo', 'bar'); * $redis->discard(); * $redis->getMode(); */ public function discard(): Redis|bool {} /** * Dump Redis' internal binary representation of a key. * $redis->zRange('new-zset', 0, -1, true); * * @param string $key The key to dump. * @return Redis|string A binary string representing the key's value. * @see https://redis.io/commands/dump * @example * $redis->zadd('zset', 0, 'zero', 1, 'one', 2, 'two'); * $binary = $redis->dump('zset'); * $redis->restore('new-zset', 0, $binary); */ public function dump(string $key): Redis|string {} /** * Have Redis repeat back an arbitrary string to the client. * @param string $str The string to echo * @return Redis|string|false The string sent to Redis or false on failure. * @see https://redis.io/commands/echo * @example $redis->echo('Hello, World'); */ public function echo(string $str): Redis|string|false {} /** * Execute a LUA script on the redis server. * @see https://redis.io/commands/eval/ * @param string $script A string containing the LUA script * @param array $args An array of arguments to pass to this script * @param int $num_keys How many of the arguments are keys. This is needed * as redis distinguishes between key name arguments * and other data. * @return mixed LUA scripts may return arbitrary data so this method can return * strings, arrays, nested arrays, etc. */ public function eval(string $script, array $args = [], int $num_keys = 0): mixed {} /** * This is simply the read-only variant of eval, meaning the underlying script * may not modify data in redis. * @see Redis::eval_ro() */ public function eval_ro(string $script_sha, array $args = [], int $num_keys = 0): mixed {} /** * Execute a LUA script on the server but instead of sending the script, send * the SHA1 hash of the script. * @param string $sha1 The SHA1 hash of the lua code. Note that the script * must already exist on the server, either having been * loaded with `SCRIPT LOAD` or having been executed directly * with `EVAL` first. * @param array $args Arguments to send to the script. * @param int $num_keys The number of arguments that are keys * @return mixed Returns whatever the specific script does. * @see https://redis.io/commands/evalsha/ * @see Redis::eval(); */ public function evalsha(string $sha1, array $args = [], int $num_keys = 0): mixed {} /** * This is simply the read-only variant of evalsha, meaning the underlying script * may not modify data in redis. * @see Redis::evalsha() */ public function evalsha_ro(string $sha1, array $args = [], int $num_keys = 0): mixed {} /** * Execute either a MULTI or PIPELINE block and return the array of replies. * @return Redis|array|false The array of pipeline'd or multi replies or false on failure. * @see https://redis.io/commands/exec * @see https://redis.io/commands/multi * @see Redis::pipeline() * @see Redis::multi() * @example * $res = $redis->multi() * ->set('foo', 'bar') * ->get('foo') * ->del('list') * ->rpush('list', 'one', 'two', 'three') * ->exec(); */ public function exec(): Redis|array|false {} /** * Test if one or more keys exist. * @param mixed $key Either an array of keys or a string key * @param mixed $other_keys If the previous argument was a string, you may send any number of * additional keys to test. * @return Redis|int|bool The number of keys that do exist and false on failure * @see https://redis.io/commands/exists * @example $redis->exists(['k1', 'k2', 'k3']); * @example $redis->exists('k4', 'k5', 'notakey'); */ public function exists(mixed $key, mixed ...$other_keys): Redis|int|bool {} /** * Sets an expiration in seconds on the key in question. If connected to * redis-server >= 7.0.0 you may send an additional "mode" argument which * modifies how the command will execute. * @param string $key The key to set an expiration on. * @param int $timeout The number of seconds after which key will be automatically deleted. * @param string|null $mode A two character modifier that changes how the * command works. * * NX - Set expiry only if key has no expiry * XX - Set expiry only if key has an expiry * LT - Set expiry only when new expiry is < current expiry * GT - Set expiry only when new expiry is > current expiry * * @return Redis|bool True if an expiration was set and false otherwise. * @see https://redis.io/commands/expire */ public function expire(string $key, int $timeout, ?string $mode = null): Redis|bool {} /* * Set a key's expiration to a specific Unix timestamp in seconds. * * If connected to Redis >= 7.0.0 you can pass an optional 'mode' argument. * @see Redis::expire() For a description of the mode argument. * * @param string $key The key to set an expiration on. * * @return Redis|bool True if an expiration was set, false if not. * */ /** * Set a key to expire at an exact unix timestamp. * @param string $key The key to set an expiration on. * @param int $timestamp The unix timestamp to expire at. * @param string|null $mode An option 'mode' that modifies how the command acts (see {@link Redis::expire}). * @return Redis|bool True if an expiration was set, false if not. * @see https://redis.io/commands/expireat * @see https://redis.io/commands/expire * @see Redis::expire() */ public function expireAt(string $key, int $timestamp, ?string $mode = null): Redis|bool {} public function failover(?array $to = null, bool $abort = false, int $timeout = 0): Redis|bool {} /** * Get the expiration of a given key as a unix timestamp * @param string $key The key to check. * @return Redis|int|false The timestamp when the key expires, or -1 if the key has no expiry * and -2 if the key doesn't exist. * @see https://redis.io/commands/expiretime * @example * $redis->setEx('mykey', 60, 'myval'); * $redis->expiretime('mykey'); */ public function expiretime(string $key): Redis|int|false {} /** * Get the expriation timestamp of a given Redis key but in milliseconds. * @see https://redis.io/commands/pexpiretime * @see Redis::expiretime() * @param string $key The key to check * @return Redis|int|false The expiration timestamp of this key (in milliseconds) or -1 if the * key has no expiration, and -2 if it does not exist. */ public function pexpiretime(string $key): Redis|int|false {} /** * Invoke a function. * @param string $fn The name of the function * @param array $keys Optional list of keys * @param array $args Optional list of args * @return mixed Function may return arbitrary data so this method can return * strings, arrays, nested arrays, etc. * @see https://redis.io/commands/fcall */ public function fcall(string $fn, array $keys = [], array $args = []): mixed {} /** * This is a read-only variant of the FCALL command that cannot execute commands that modify data. * @param string $fn The name of the function * @param array $keys Optional list of keys * @param array $args Optional list of args * @return mixed Function may return arbitrary data so this method can return * strings, arrays, nested arrays, etc. * @see https://redis.io/commands/fcall_ro */ public function fcall_ro(string $fn, array $keys = [], array $args = []): mixed {} /** * Deletes every key in all Redis databases * @param bool $sync Whether to perform the task in a blocking or non-blocking way. * @return Redis|bool * @see https://redis.io/commands/flushall */ public function flushAll(?bool $sync = null): Redis|bool {} /** * Deletes all the keys of the currently selected database. * @param bool $sync Whether to perform the task in a blocking or non-blocking way. * @return Redis|bool * @see https://redis.io/commands/flushdb */ public function flushDB(?bool $sync = null): Redis|bool {} /** * Functions is an API for managing code to be executed on the server. * @param string $operation The subcommand you intend to execute. Valid options are as follows * 'LOAD' - Create a new library with the given library name and code. * 'DELETE' - Delete the given library. * 'LIST' - Return general information on all the libraries * 'STATS' - Return information about the current function running * 'KILL' - Kill the current running function * 'FLUSH' - Delete all the libraries * 'DUMP' - Return a serialized payload representing the current libraries * 'RESTORE' - Restore the libraries represented by the given payload * @param mixed ...$args Additional arguments * @return Redis|bool|string|array Depends on subcommand. * @see https://redis.io/commands/function */ public function function(string $operation, mixed ...$args): Redis|bool|string|array {} /** * Add one or more members to a geospacial sorted set * @param string $key The sorted set to add data to. * @param float $lng The longitude of the first member * @param float $lat The lattitude of the first member. * @param mixed ...$other_triples_and_options You can continue to pass longitude, lattitude, and member * arguments to add as many members as you wish. Optionally, the final argument may be * a string with options for the command @return Redis|int|false The number of added elements is returned. If the 'CH' option is specified, * the return value is the number of members *changed*. * @see Redis documentation for the options. * @example $redis->geoAdd('cities', -121.8374, 39.7284, 'Chico', -122.03218, 37.322, 'Cupertino'); * @example $redis->geoadd('cities', -121.837478, 39.728494, 'Chico', ['XX', 'CH']); * @see https://redis.io/commands/geoadd */ public function geoadd(string $key, float $lng, float $lat, string $member, mixed ...$other_triples_and_options): Redis|int|false {} /** * Get the distance between two members of a geospacially encoded sorted set. * @param string $key The Sorted set to query. * @param string $src The first member. * @param string $dst The second member. * @param string|null $unit Which unit to use when computing distance, defaulting to meters. * * M - meters * KM - kilometers * FT - feet * MI - miles * * @return Redis|float|false The calculated distance in whichever units were specified or false * if one or both members did not exist. * @example $redis->geodist('cities', 'Chico', 'Cupertino', 'mi'); * @see https://redis.io/commands/geodist */ public function geodist(string $key, string $src, string $dst, ?string $unit = null): Redis|float|false {} /** * Retrieve one or more GeoHash encoded strings for members of the set. * @param string $key The key to query * @param string $member The first member to request * @param string ...$other_members One or more additional members to request. * @return Redis|array|false An array of GeoHash encoded values. * @see https://redis.io/commands/geohash * @see https://en.wikipedia.org/wiki/Geohash * @example $redis->geohash('cities', 'Chico', 'Cupertino'); */ public function geohash(string $key, string $member, string ...$other_members): Redis|array|false {} /** * Return the longitude and lattitude for one or more members of a geospacially encoded sorted set. * @param string $key The set to query. * @param string $member The first member to query. * @param string ...$other_members One or more members to query. * @return Redis|array|false array of longitude and lattitude pairs. * @see https://redis.io/commands/geopos * @example $redis->geopos('cities', 'Seattle', 'New York'); */ public function geopos(string $key, string $member, string ...$other_members): Redis|array|false {} /** * Retrieve members of a geospacially sorted set that are within a certain radius of a location. * @param string $key The set to query * @param float $lng The longitude of the location to query. * @param float $lat The latitude of the location to query. * @param float $radius The radius of the area to include. * @param string $unit The unit of the provided radius (defaults to 'meters). * See {@link Redis::geodist} for possible units. * @param array $options An array of options that modifies how the command behaves. * * $options = [ * 'WITHCOORD', # Return members and their coordinates. * 'WITHDIST', # Return members and their distances from the center. * 'WITHHASH', # Return members GeoHash string. * 'ASC' | 'DESC', # The sort order of returned members * # Limit to N returned members. Optionally a two element array may be * # passed as the `LIMIT` argument, and the `ANY` argument. * 'COUNT' => [], or [, ] * # Instead of returning members, store them in the specified key. * 'STORE' => * # Store the distances in the specified key * 'STOREDIST' => * ]; * * @return mixed This command can return various things, depending on the options passed. * @see https://redis.io/commands/georadius * @example $redis->georadius('cities', 47.608013, -122.335167, 1000, 'km'); */ public function georadius(string $key, float $lng, float $lat, float $radius, string $unit, array $options = []): mixed {} /** * A readonly variant of `GEORADIUS` that may be executed on replicas. * @see Redis::georadius */ public function georadius_ro(string $key, float $lng, float $lat, float $radius, string $unit, array $options = []): mixed {} /** * Similar to `GEORADIUS` except it uses a member as the center of the query. * @param string $key The key to query. * @param string $member The member to treat as the center of the query. * @param float $radius The radius from the member to include. * @param string $unit The unit of the provided radius * See {@link Redis::geodist} for possible units. * @param array $options An array with various options to modify the command's behavior. * See {@link Redis::georadius} for options. * @return mixed This command can return various things depending on options. * @example $redis->georadiusbymember('cities', 'Seattle', 200, 'mi'); */ public function georadiusbymember(string $key, string $member, float $radius, string $unit, array $options = []): mixed {} /** * This is the read-only variant of `GEORADIUSBYMEMBER` that can be run on replicas. */ public function georadiusbymember_ro(string $key, string $member, float $radius, string $unit, array $options = []): mixed {} /** * Search a geospacial sorted set for members in various ways. * @param string $key The set to query. * @param array|string $position Either a two element array with longitude and lattitude, or * a string representing a member of the set. * @param array|int|float $shape Either a number representine the radius of a circle to search, or * a two element array representing the width and height of a box * to search. * @param string $unit The unit of our shape. See {@link Redis::geodist} for possible units. * @param array $options @see {@link Redis::georadius} for options. Note that the `STORE` * options are not allowed for this command. */ public function geosearch(string $key, array|string $position, array|int|float $shape, string $unit, array $options = []): array {} /** * Search a geospacial sorted set for members within a given area or range, storing the results into * a new set. * @param string $dst The destination where results will be stored. * @param string $src The key to query. * @param array|string $position Either a two element array with longitude and lattitude, or * a string representing a member of the set. * @param array|int|float $shape Either a number representine the radius of a circle to search, or * a two element array representing the width and height of a box * to search. * @param string $unit The unit of our shape. See {@link Redis::geodist} for possible units. * @param array $options * * $options = [ * 'ASC' | 'DESC', # The sort order of returned members * 'WITHDIST' # Also store distances. * # Limit to N returned members. Optionally a two element array may be * # passed as the `LIMIT` argument, and the `ANY` argument. * 'COUNT' => [], or [, ] * ]; * */ public function geosearchstore(string $dst, string $src, array|string $position, array|int|float $shape, string $unit, array $options = []): Redis|array|int|false {} /** * Retrieve a string keys value. * @param string $key The key to query * @return mixed The keys value or false if it did not exist. * @see https://redis.io/commands/get * @example $redis->get('foo'); */ public function get(string $key): mixed {} /** * Get the authentication information on the connection, if any. * @return mixed The authentication information used to authenticate the connection. * @see Redis::auth() */ public function getAuth(): mixed {} /** * Get the bit at a given index in a string key. * @param string $key The key to query. * @param int $idx The Nth bit that we want to query. * @example $redis->getbit('bitmap', 1337); * @see https://redis.io/commands/getbit */ public function getBit(string $key, int $idx): Redis|int|false {} /** * Get the value of a key and optionally set it's expiration. * @param string $key The key to query * @param array $options Options to modify how the command works. * * $options = [ * 'EX' => # Expire in N seconds * 'PX' => # Expire in N milliseconds * 'EXAT' => # Expire at a unix timestamp (in seconds) * 'PXAT' => # Expire at a unix timestamp (in milliseconds); * 'PERSIST' # Remove any configured expiration on the key. * ]; * * @return Redis|string|bool The key's value or false if it didn't exist. * @see https://redis.io/comands/getex * @example $redis->getEx('mykey', ['EX' => 60]); */ public function getEx(string $key, array $options = []): Redis|string|bool {} /** * Get the database number PhpRedis thinks we're connected to. * This value is updated internally in PhpRedis each time {@link Redis::select} is called. * @return int The database we're connected to. * @see Redis::select() * @see https://redis.io/commands/select */ public function getDBNum(): int {} /** * Get a key from Redis and delete it in an atomic operation. * @param string $key The key to get/delete. * @return Redis|string|bool The value of the key or false if it didn't exist. * @see https://redis.io/commands/getdel * @example $redis->getdel('token:123'); */ public function getDel(string $key): Redis|string|bool {} /** * Return the host or Unix socket we are connected to. * @return string The host or Unix socket. */ public function getHost(): string {} /** * Get the last error returned to us from Redis, if any. * @return string|null The error string or NULL if there is none. */ public function getLastError(): ?string {} /** * Returns whether the connection is in ATOMIC, MULTI, or PIPELINE mode * @return int The mode we're in. */ public function getMode(): int {} /** * Retrieve the value of a configuration setting as set by Redis::setOption() * @return mixed The setting itself or false on failure * @see Redis::setOption() for a detailed list of options and their values. */ public function getOption(int $option): mixed {} /** * Get the persistent connection ID, if there is one. * @return string|null The ID or NULL if we don't have one. */ public function getPersistentID(): ?string {} /** * Get the port we are connected to. This number will be zero if we are connected to a unix socket. * @return int The port. */ public function getPort(): int {} /** * Retrieve a substring of a string by index. * @param string $key The string to query. * @param int $start The zero-based starting index. * @param int $end The zero-based ending index. * @return Redis|string|false The substring or false on failure. * @see https://redis.io/commands/getrange * @example * $redis->set('silly-word', 'Supercalifragilisticexpialidocious'); * echo $redis->getRange('silly-word', 0, 4) . "\n"; */ public function getRange(string $key, int $start, int $end): Redis|string|false {} /** * Get the longest common subsequence between two string keys. * @param string $key1 The first key to check * @param string $key2 The second key to check * @param array|null $options An optional array of modifiers for the comand. * * $options = [ * 'MINMATCHLEN' => int # Exclude matching substrings that are less than this value * 'WITHMATCHLEN' => bool # Whether each match should also include its length. * 'LEN' # Return the length of the longest subsequence * 'IDX' # Each returned match will include the indexes where the * # match occurs in each string. * ]; * * NOTE: 'LEN' cannot be used with 'IDX'. * @return Redis|string|array|int|false Various reply types depending on options. * @see https://redis.io/commands/lcs * @example * $redis->set('seq1', 'gtaggcccgcacggtctttaatgtatccctgtttaccatgccatacctgagcgcatacgc'); * $redis->set('seq2', 'aactcggcgcgagtaccaggccaaggtcgttccagagcaaagactcgtgccccgctgagc'); * echo $redis->lcs('seq1', 'seq2') . "\n"; */ public function lcs(string $key1, string $key2, ?array $options = null): Redis|string|array|int|false {} /** * Get the currently set read timeout on the connection. * @return float The timeout. */ public function getReadTimeout(): float {} /** * Sets a key and returns any previously set value, if the key already existed. * @param string $key The key to set. * @param mixed $value The value to set the key to. * @return Redis|string|false The old value of the key or false if it didn't exist. * @see https://redis.io/commands/getset * @example * $redis->getset('captain', 'Pike'); * $redis->getset('captain', 'Kirk'); */ public function getset(string $key, mixed $value): Redis|string|false {} /** * Retrieve any set connection timeout * @return float|false The currently set timeout or false on failure (e.g. we aren't connected). */ public function getTimeout(): float|false {} /** * Get the number of bytes sent and received on the socket. * @return array An array in the form [$sent_bytes, $received_bytes] */ public function getTransferredBytes(): array {} /** * Reset the number of bytes sent and received on the socket. * @return void */ public function clearTransferredBytes(): void {} /** * Remove one or more fields from a hash. * @param string $key The hash key in question. * @param string $field The first field to remove * @param string ...$other_fields One or more additional fields to remove. * @return Redis|int|false The number of fields actually removed. * @see https://redis.io/commands/hdel * @example $redis->hDel('communication', 'Alice', 'Bob'); */ public function hDel(string $key, string $field, string ...$other_fields): Redis|int|false {} /** * Checks whether a field exists in a hash. * @param string $key The hash to query. * @param string $field The field to check * @return Redis|bool True if it exists, false if not. * @see https://redis.io/commands/hexists * @example $redis->hExists('communication', 'Alice'); */ public function hExists(string $key, string $field): Redis|bool {} public function hGet(string $key, string $member): mixed {} /** * Read every field and value from a hash. * @param string $key The hash to query. * @return Redis|array|false All fields and values or false if the key didn't exist. * @see https://redis.io/commands/hgetall * @example $redis->hgetall('myhash'); */ public function hGetAll(string $key): Redis|array|false {} /** * Increment a hash field's value by an integer * @param string $key The hash to modify * @param string $field The field to increment * @param int $value How much to increment the value. * @return Redis|int|false The new value of the field. * @see https://redis.io/commands/hincrby * @example * $redis->hMSet('player:1', ['name' => 'Alice', 'score' => 0]); * $redis->hincrby('player:1', 'score', 10); */ public function hIncrBy(string $key, string $field, int $value): Redis|int|false {} /** * Increment a hash field by a floating point value * @param string $key The hash with the field to increment. * @param string $field The field to increment. * @return Redis|float|false The field value after incremented. * @see https://redis.io/commands/hincrbyfloat * @example * $redis->hincrbyfloat('numbers', 'tau', 2 * 3.1415926); */ public function hIncrByFloat(string $key, string $field, float $value): Redis|float|false {} /** * Retrieve all of the fields of a hash. * @param string $key The hash to query. * @return Redis|array|false The fields in the hash or false if the hash doesn't exist. * @see https://redis.io/commands/hkeys * @example $redis->hkeys('myhash'); */ public function hKeys(string $key): Redis|array|false {} /** * Get the number of fields in a hash. * @see https://redis.io/commands/hlen * @param string $key The hash to check. * @return Redis|int|false The number of fields or false if the key didn't exist. * @example $redis->hlen('myhash'); */ public function hLen(string $key): Redis|int|false {} /** * Get one or more fields from a hash. * @param string $key The hash to query. * @param array $fields One or more fields to query in the hash. * @return Redis|array|false The fields and values or false if the key didn't exist. * @see https://redis.io/commands/hmget * @example $redis->hMGet('player:1', ['name', 'score']); */ public function hMget(string $key, array $fields): Redis|array|false {} /** * Add or update one or more hash fields and values * @param string $key The hash to create/update * @param array $fieldvals An associative array with fields and their values. * @return Redis|bool True if the operation was successful * @see https://redis.io/commands/hmset * @example $redis->hmset('updates', ['status' => 'starting', 'elapsed' => 0]); */ public function hMset(string $key, array $fieldvals): Redis|bool {} /** * Get one or more random field from a hash. * @param string $key The hash to query. * @param array|null $options An array of options to modify how the command behaves. * * $options = [ * 'COUNT' => int # An optional number of fields to return. * 'WITHVALUES' => bool # Also return the field values. * ]; * * @return Redis|array|string One or more random fields (and possibly values). * @see https://redis.io/commands/hrandfield * @example $redis->hrandfield('settings'); * @example $redis->hrandfield('settings', ['count' => 2, 'withvalues' => true]); */ public function hRandField(string $key, ?array $options = null): Redis|string|array {} public function hSet(string $key, string $member, mixed $value): Redis|int|false {} /** * Set a hash field and value, but only if that field does not exist * @param string $key The hash to update. * @param string $field The value to set. * @return Redis|bool True if the field was set and false if not. * @see https://redis.io/commands/hsetnx * @example * $redis->hsetnx('player:1', 'lock', 'enabled'); * $redis->hsetnx('player:1', 'lock', 'enabled'); */ public function hSetNx(string $key, string $field, string $value): Redis|bool {} /** * Get the string length of a hash field * @param string $key The hash to query. * @param string $field The field to query. * @return Redis|int|false The string length of the field or false. * @example * $redis = new Redis(['host' => 'localhost']); * $redis->del('hash'); * $redis->hmset('hash', ['50bytes' => str_repeat('a', 50)]); * $redis->hstrlen('hash', '50bytes'); * @see https://redis.io/commands/hstrlen */ public function hStrLen(string $key, string $field): Redis|int|false {} /** * Get all of the values from a hash. * @param string $key The hash to query. * @return Redis|array|false The values from the hash. * @see https://redis.io/commands/hvals * @example $redis->hvals('player:1'); */ public function hVals(string $key): Redis|array|false {} /** * Iterate over the fields and values of a hash in an incremental fashion. * @see https://redis.io/commands/hscan * @see https://redis.io/commands/scan * @param string $key The hash to query. * @param int|null $iterator The scan iterator, which should be initialized to NULL before the first call. * This value will be updated after every call to hscan, until it reaches zero * meaning the scan is complete. * @param string|null $pattern An optional glob-style pattern to filter fields with. * @param int $count An optional hint to Redis about how many fields and values to return per HSCAN. * @return Redis|array|bool An array with a subset of fields and values. * @example * $redis = new Redis(['host' => 'localhost']); * $redis->del('big-hash'); * for ($i = 0; $i < 1000; $i++) { * $fields["field:$i"] = "value:$i"; * } * $redis->hmset('big-hash', $fields); * $it = null; * do { * // Scan the hash but limit it to fields that match '*:1?3' * $fields = $redis->hscan('big-hash', $it, '*:1?3'); * foreach ($fields as $field => $value) { * echo "[$field] => $value\n"; * } * } while ($it != 0); */ public function hscan(string $key, ?int &$iterator, ?string $pattern = null, int $count = 0): Redis|array|bool {} /** * Increment a key's value, optionally by a specifc amount. * @see https://redis.io/commands/incr * @see https://redis.io/commands/incrby * @param string $key The key to increment * @param int $by An optional amount to increment by. * @return Redis|int|false The new value of the key after incremented. * @example $redis->incr('mycounter'); * @example $redis->incr('mycounter', 10); */ public function incr(string $key, int $by = 1): Redis|int|false {} /** * Increment a key by a specific integer value * @see https://redis.io/commands/incrby * @param string $key The key to increment. * @param int $value The amount to increment. * @example * $redis->set('primes', 2); * $redis->incrby('primes', 1); * $redis->incrby('primes', 2); * $redis->incrby('primes', 2); * $redis->incrby('primes', 4); */ public function incrBy(string $key, int $value): Redis|int|false {} /** * Increment a numeric key by a floating point value. * @param string $key The key to increment * @param float $value How much to increment (or decrement) the value. * @return Redis|float|false The new value of the key or false if the key didn't contain a string. * @example * $redis->incrbyfloat('tau', 3.1415926); * $redis->incrbyfloat('tau', 3.1415926); */ public function incrByFloat(string $key, float $value): Redis|float|false {} /** * Retrieve information about the connected redis-server. If no arguments are passed to * this function, redis will return every info field. Alternatively you may pass a specific * section you want returned (e.g. 'server', or 'memory') to receive only information pertaining * to that section. * If connected to Redis server >= 7.0.0 you may pass multiple optional sections. * @see https://redis.io/commands/info/ * @param string ...$sections Optional section(s) you wish Redis server to return. * @return Redis|array|false */ public function info(string ...$sections): Redis|array|false {} /** * Check if we are currently connected to a Redis instance. * @return bool True if we are, false if not */ public function isConnected(): bool {} /** @return Redis|array|false */ public function keys(string $pattern) {} public function lInsert(string $key, string $pos, mixed $pivot, mixed $value) {} /** * Retrieve the lenght of a list. * @param string $key The list * @return Redis|int|false The number of elements in the list or false on failure. */ public function lLen(string $key): Redis|int|false {} /** * Move an element from one list into another. * @param string $src The source list. * @param string $dst The destination list * @param string $wherefrom Where in the source list to retrieve the element. This can be either * - `Redis::LEFT`, or `Redis::RIGHT`. * @param string $whereto Where in the destination list to put the element. This can be either * - `Redis::LEFT`, or `Redis::RIGHT`. * @return Redis|string|false The element removed from the source list. * @example * $redis->rPush('numbers', 'one', 'two', 'three'); * $redis->lMove('numbers', 'odds', Redis::LEFT, Redis::LEFT); */ public function lMove(string $src, string $dst, string $wherefrom, string $whereto): Redis|string|false {} /** * Move an element from one list to another, blocking up to a timeout until an element is available. * @param string $src The source list * @param string $dst The destination list * @param string $wherefrom Where in the source list to extract the element. * - `Redis::LEFT`, or `Redis::RIGHT`. * @param string $whereto Where in the destination list to put the element. * - `Redis::LEFT`, or `Redis::RIGHT`. * @param float $timeout How long to block for an element. * @return Redis|string|false * @example * $redis->lPush('numbers', 'one'); * $redis->blmove('numbers', 'odds', Redis::LEFT, Redis::LEFT 1.0); * // This call will block, if no additional elements are in 'numbers' * $redis->blmove('numbers', 'odds', Redis::LEFT, Redis::LEFT, 1.0); */ public function blmove(string $src, string $dst, string $wherefrom, string $whereto, float $timeout): Redis|string|false {} /** * Pop one or more elements off a list. * @param string $key The list to pop from. * @param int $count Optional number of elements to remove. By default one element is popped. * @return Redis|bool|string|array Will return the element(s) popped from the list or false/NULL * if none was removed. * @see https://redis.io/commands/lpop * @example $redis->lpop('mylist'); * @example $redis->lpop('mylist', 4); */ public function lPop(string $key, int $count = 0): Redis|bool|string|array {} /** * Retrieve the index of an element in a list. * @param string $key The list to query. * @param mixed $value The value to search for. * @param array|null $options Options to configure how the command operates * * $options = [ * # How many matches to return. By default a single match is returned. * # If count is set to zero, it means unlimited. * 'COUNT' => * # Specify which match you want returned. `RANK` 1 means "the first match" * # 2 means the second, and so on. If passed as a negative number the * # RANK is computed right to left, so a `RANK` of -1 means "the last match". * 'RANK' => * # This argument allows you to limit how many elements Redis will search before * # returning. This is useful to prevent Redis searching very long lists while * # blocking the client. * 'MAXLEN => * ]; * * @return Redis|null|bool|int|array Returns one or more of the matching indexes, or null/false if none were found. */ public function lPos(string $key, mixed $value, ?array $options = null): Redis|null|bool|int|array {} /** * Prepend one or more elements to a list. * @param string $key The list to prepend. * @param mixed $elements One or more elements to prepend. * @return Redis|int|false The new length of the list after prepending. * @see https://redis.io/commands/lpush * @example $redis->lPush('mylist', 'cat', 'bear', 'aligator'); */ public function lPush(string $key, mixed ...$elements): Redis|int|false {} /** * Append one or more elements to a list. * @param string $key The list to append to. * @param mixed $elements one or more elements to append. * @return Redis|int|false The new length of the list * @see https://redis.io/commands/rpush * @example $redis->rPush('mylist', 'xray', 'yankee', 'zebra'); */ public function rPush(string $key, mixed ...$elements): Redis|int|false {} /** * Prepend an element to a list but only if the list exists * @param string $key The key to prepend to. * @param mixed $value The value to prepend. * @return Redis|int|false The new length of the list. */ public function lPushx(string $key, mixed $value): Redis|int|false {} /** * Append an element to a list but only if the list exists * @param string $key The key to prepend to. * @param mixed $value The value to prepend. * @return Redis|int|false The new length of the list. */ public function rPushx(string $key, mixed $value): Redis|int|false {} /** * Set a list element at an index to a specific value. * @param string $key The list to modify. * @param int $index The position of the element to change. * @param mixed $value The new value. * @return Redis|bool True if the list was modified. * @see https://redis.io/commands/lset */ public function lSet(string $key, int $index, mixed $value): Redis|bool {} /** * Retrieve the last time Redis' database was persisted to disk. * @return int The unix timestamp of the last save time * @see https://redis.io/commands/lastsave */ public function lastSave(): int {} /** * Get the element of a list by its index. * @param string $key The key to query * @param int $index The index to check. * @return mixed The index or NULL/false if the element was not found. */ public function lindex(string $key, int $index): mixed {} /** * Retrieve elements from a list. * @param string $key The list to query. * @param int $start The beginning index to retrieve. This number can be negative * meaning start from the end of the list. * @param int $end The end index to retrieve. This can also be negative to start * from the end of the list. * @return Redis|array|false The range of elements between the indexes. * @example $redis->lrange('mylist', 0, -1); // the whole list * @example $redis->lrange('mylist', -2, -1); // the last two elements in the list. */ public function lrange(string $key, int $start, int $end): Redis|array|false {} /** * Remove one or more matching elements from a list. * @param string $key The list to truncate. * @param mixed $value The value to remove. * @param int $count How many elements matching the value to remove. * @return Redis|int|false The number of elements removed. * @see https://redis.io/commands/lrem */ public function lrem(string $key, mixed $value, int $count = 0): Redis|int|false {} /** * Trim a list to a subrange of elements. * @param string $key The list to trim * @param int $start The starting index to keep * @param int $end The ending index to keep. * @return Redis|bool true if the list was trimmed. * @example $redis->ltrim('mylist', 0, 3); // Keep the first four elements */ public function ltrim(string $key, int $start, int $end): Redis|bool {} /** * Get one ore more string keys. * @param array $keys The keys to retrieve * @return Redis|array an array of keys with their values. * @example $redis->mget(['key1', 'key2']); */ public function mget(array $keys): Redis|array {} public function migrate( string $host, int $port, string|array $key, int $dstdb, int $timeout, bool $copy = false, bool $replace = false, #[\SensitiveParameter] mixed $credentials = null ): Redis|bool {} /** * Move a key to a different database on the same redis instance. * @param string $key The key to move * @return Redis|bool True if the key was moved */ public function move(string $key, int $index): Redis|bool {} /** * Set one ore more string keys. * @param array $key_values An array with keys and their values. * @return Redis|bool True if the keys could be set. * @see https://redis.io/commands/mset * @example $redis->mSet(['foo' => 'bar', 'baz' => 'bop']); */ public function mset(array $key_values): Redis|bool {} /** * Set one ore more string keys but only if none of the key exist. * @param array $key_values An array of keys with their values. * @return Redis|bool True if the keys were set and false if not. * @see https://redis.io/commands/msetnx * @example $redis->msetnx(['foo' => 'bar', 'baz' => 'bop']); */ public function msetnx(array $key_values): Redis|bool {} /** * Begin a transaction. * @param int $value The type of transaction to start. This can either be `Redis::MULTI` or * `Redis::PIPELINE'. * @return Redis|bool True if the transaction could be started. * @see https://redis.io/commands/multi * @example * $redis->multi(); * $redis->set('foo', 'bar'); * $redis->get('foo'); * $redis->exec(); */ public function multi(int $value = Redis::MULTI): bool|Redis {} public function object(string $subcommand, string $key): Redis|int|string|false {} /** * @deprecated */ public function open(string $host, int $port = 6379, float $timeout = 0, ?string $persistent_id = null, int $retry_interval = 0, float $read_timeout = 0, ?array $context = null): bool {} public function pconnect(string $host, int $port = 6379, float $timeout = 0, ?string $persistent_id = null, int $retry_interval = 0, float $read_timeout = 0, ?array $context = null): bool {} /** * Remove the expiration from a key. * @param string $key The key to operate against. * @return Redis|bool True if a timeout was removed and false if it was not or the key didn't exist. */ public function persist(string $key): Redis|bool {} /** * Sets an expiration in milliseconds on a given key. If connected to Redis >= 7.0.0 * you can pass an optional mode argument that modifies how the command will execute. * @param string $key The key to set an expiration on. * @param int $timeout The number of milliseconds after which key will be automatically deleted. * @param string|null $mode A two character modifier that changes how the * command works. * @return bool True if an expiry was set on the key, and false otherwise. * @see Redis::expire() for a description of the mode argument. */ public function pexpire(string $key, int $timeout, ?string $mode = null): bool {} /** * Set a key's expiration to a specific Unix Timestamp in milliseconds. If connected to * Redis >= 7.0.0 you can pass an optional 'mode' argument. * @param string $key The key to set an expiration on. * @param int $timestamp The unix timestamp to expire at. * @param string|null $mode A two character modifier that changes how the * command works. * @return Redis|bool True if an expiration was set on the key, false otherwise. * @see Redis::expire() For a description of the mode argument. */ public function pexpireAt(string $key, int $timestamp, ?string $mode = null): Redis|bool {} /** * Add one or more elements to a Redis HyperLogLog key * @see https://redis.io/commands/pfadd * @param string $key The key in question. * @param array $elements One or more elements to add. * @return Redis|int Returns 1 if the set was altered, and zero if not. */ public function pfadd(string $key, array $elements): Redis|int {} /** * Retrieve the cardinality of a Redis HyperLogLog key. * @see https://redis.io/commands/pfcount * @param array|string $key_or_keys Either one key or an array of keys * @return Redis|int|false The estimated cardinality of the set. */ public function pfcount(array|string $key_or_keys): Redis|int|false {} /** * Merge one or more source HyperLogLog sets into a destination set. * @see https://redis.io/commands/pfmerge * @param string $dst The destination key. * @param array $srckeys One or more source keys. * @return Redis|bool Always returns true. */ public function pfmerge(string $dst, array $srckeys): Redis|bool {} /** * PING the redis server with an optional string argument. * @see https://redis.io/commands/ping * @param string|null $message An optional string message that Redis will reply with, if passed. * @return Redis|string|false If passed no message, this command will simply return `true`. * If a message is passed, it will return the message. * @example $redis->ping(); * @example $redis->ping('beep boop'); */ public function ping(?string $message = null): Redis|string|bool {} /** * Enter into pipeline mode. * Pipeline mode is the highest performance way to send many commands to Redis * as they are aggregated into one stream of commands and then all sent at once * when the user calls Redis::exec(). * NOTE: That this is shorthand for Redis::multi(Redis::PIPELINE) * @return Redis|bool The redis object is returned, to facilitate method chaining. * @example * $redis->pipeline() * ->set('foo', 'bar') * ->del('mylist') * ->rpush('mylist', 'a', 'b', 'c') * ->exec(); */ public function pipeline(): bool|Redis {} /** * @deprecated */ public function popen(string $host, int $port = 6379, float $timeout = 0, ?string $persistent_id = null, int $retry_interval = 0, float $read_timeout = 0, ?array $context = null): bool {} /** * Set a key with an expiration time in milliseconds * @param string $key The key to set * @param int $expire The TTL to set, in milliseconds. * @param mixed $value The value to set the key to. * @return Redis|bool True if the key could be set. * @example $redis->psetex('mykey', 1000, 'myval'); */ public function psetex(string $key, int $expire, mixed $value): Redis|bool {} /** * Subscribe to one or more glob-style patterns * @param array $patterns One or more patterns to subscribe to. * @param callable $cb A callback with the following prototype: * * function ($redis, $channel, $message) { } * * @return bool True if we were subscribed. * @see https://redis.io/commands/psubscribe */ public function psubscribe(array $patterns, callable $cb): bool {} /** * Get a keys time to live in milliseconds. * @param string $key The key to check. * @return Redis|int|false The key's TTL or one of two special values if it has none. * * -1 - The key has no TTL. * -2 - The key did not exist. * * @see https://redis.io/commands/pttl * @example $redis->pttl('ttl-key'); */ public function pttl(string $key): Redis|int|false {} /** * Publish a message to a pubsub channel * @see https://redis.io/commands/publish * @param string $channel The channel to publish to. * @param string $message The message itself. * @return Redis|int|false The number of subscribed clients to the given channel. */ public function publish(string $channel, string $message): Redis|int|false {} public function pubsub(string $command, mixed $arg = null): mixed {} /** * Unsubscribe from one or more channels by pattern * @see https://redis.io/commands/punsubscribe * @see https://redis.io/commands/subscribe * @see Redis::subscribe() * @param array $patterns One or more glob-style patterns of channel names. * @return Redis|array|bool The array of subscribed patterns or false on failure. */ public function punsubscribe(array $patterns): Redis|array|bool {} /** * Pop one or more elements from the end of a list. * @param string $key A redis LIST key name. * @param int $count The maximum number of elements to pop at once. * NOTE: The `count` argument requires Redis >= 6.2.0 * @return Redis|array|string|bool One ore more popped elements or false if all were empty. * @see https://redis.io/commands/rpop * @example $redis->rPop('mylist'); * @example $redis->rPop('mylist', 4); */ public function rPop(string $key, int $count = 0): Redis|array|string|bool {} /** * Return a random key from the current database * @see https://redis.io/commands/randomkey * @return Redis|string|false A random key name or false if no keys exist */ public function randomKey(): Redis|string|false {} /** * Execute any arbitrary Redis command by name. * @param string $command The command to execute * @param mixed $args One or more arguments to pass to the command. * @return mixed Can return any number of things depending on command executed. * @example $redis->rawCommand('del', 'mystring', 'mylist'); * @example $redis->rawCommand('set', 'mystring', 'myvalue'); * @example $redis->rawCommand('rpush', 'mylist', 'one', 'two', 'three'); */ public function rawcommand(string $command, mixed ...$args): mixed {} /** * Unconditionally rename a key from $old_name to $new_name * @see https://redis.io/commands/rename * @param string $old_name The original name of the key * @param string $new_name The new name for the key * @return Redis|bool True if the key was renamed or false if not. */ public function rename(string $old_name, string $new_name): Redis|bool {} /** * Renames $key_src to $key_dst but only if newkey does not exist. * @see https://redis.io/commands/renamenx * @param string $key_src The source key name * @param string $key_dst The destination key name. * @return Redis|bool True if the key was renamed, false if not. * @example * $redis->set('src', 'src_key'); * $redis->set('existing-dst', 'i_exist'); * $redis->renamenx('src', 'dst'); * $redis->renamenx('dst', 'existing-dst'); */ public function renameNx(string $key_src, string $key_dst): Redis|bool {} /** * Reset the state of the connection. * @return Redis|bool Should always return true unless there is an error. */ public function reset(): Redis|bool {} /** * Restore a key by the binary payload generated by the DUMP command. * @param string $key The name of the key you wish to create. * @param int $ttl What Redis should set the key's TTL (in milliseconds) to once it is created. * Zero means no TTL at all. * @param string $value The serialized binary value of the string (generated by DUMP). * @param array|null $options An array of additional options that modifies how the command operates. * * $options = [ * 'ABSTTL' # If this is present, the `$ttl` provided by the user should * # be an absolute timestamp, in milliseconds() * 'REPLACE' # This flag instructs Redis to store the key even if a key with * # that name already exists. * 'IDLETIME' => int # Tells Redis to set the keys internal 'idletime' value to a * # specific number (see the Redis command OBJECT for more info). * 'FREQ' => int # Tells Redis to set the keys internal 'FREQ' value to a specific * # number (this relates to Redis' LFU eviction algorithm). * ]; * * @return Redis|bool True if the key was stored, false if not. * @see https://redis.io/commands/restore * @see https://redis.io/commands/dump * @see Redis::dump() * @example * $redis->sAdd('captains', 'Janeway', 'Picard', 'Sisko', 'Kirk', 'Archer'); * $serialized = $redis->dump('captains'); * $redis->restore('captains-backup', 0, $serialized); */ public function restore(string $key, int $ttl, string $value, ?array $options = null): Redis|bool {} /** * Query whether the connected instance is a primary or replica * @return mixed Will return an array with the role of the connected instance unless there is * an error. */ public function role(): mixed {} /** * Atomically pop an element off the end of a Redis LIST and push it to the beginning of * another. * @param string $srckey The source key to pop from. * @param string $dstkey The destination key to push to. * @return Redis|string|false The popped element or false if the source key was empty. * @see https://redis.io/commands/rpoplpush * @example * $redis->pipeline() * ->del('list1', 'list2') * ->rpush('list1', 'list1-1', 'list1-2') * ->rpush('list2', 'list2-1', 'list2-2') * ->exec(); * $redis->rpoplpush('list2', 'list1'); */ public function rpoplpush(string $srckey, string $dstkey): Redis|string|false {} /** * Add one or more values to a Redis SET key. * @param string $key The key name * @param mixed $value A value to add to the set. * @param mixed ...$other_values One or more additional values to add * @return Redis|int|false The number of values added to the set. * @see https://redis.io/commands/sadd * @example * $redis->del('myset'); * $redis->sadd('myset', 'foo', 'bar', 'baz'); * $redis->sadd('myset', 'foo', 'new'); */ public function sAdd(string $key, mixed $value, mixed ...$other_values): Redis|int|false {} /** * Add one ore more values to a Redis SET key. This is an alternative to Redis::sadd() but * instead of being variadic, takes a single array of values. * @see https://redis.io/commands/sadd * @see Redis::sadd() * @param string $key The set to add values to. * @param array $values One or more members to add to the set. * @return int The number of members added to the set. * @example * $redis->del('myset'); * $redis->sAddArray('myset', ['foo', 'bar', 'baz']); * $redis->sAddArray('myset', ['foo', 'new']); */ public function sAddArray(string $key, array $values): int {} /** * Given one or more Redis SETS, this command returns all of the members from the first * set that are not in any subsequent set. * @param string $key The first set * @param string ...$other_keys One or more additional sets * @return Redis|array|false Returns the elements from keys 2..N that don't exist in the * first sorted set, or false on failure. * @see https://redis.io/commands/sdiff * @example * $redis->pipeline() * ->del('set1', 'set2', 'set3') * ->sadd('set1', 'apple', 'banana', 'carrot', 'date') * ->sadd('set2', 'carrot') * ->sadd('set3', 'apple', 'carrot', 'eggplant') * ->exec(); * $redis->sdiff('set1', 'set2', 'set3'); */ public function sDiff(string $key, string ...$other_keys): Redis|array|false {} /** * This method performs the same operation as SDIFF except it stores the resulting diff * values in a specified destination key. * @see https://redis.io/commands/sdiffstore * @see Redis::sdiff() * @param string $dst The key where to store the result * @param string $key The first key to perform the DIFF on * @param string ...$other_keys One or more additional keys. * @return Redis|int|false The number of values stored in the destination set or false on failure. */ public function sDiffStore(string $dst, string $key, string ...$other_keys): Redis|int|false {} /** * Given one or more Redis SET keys, this command will return all of the elements that are * in every one. * @see https://redis.io/commands/sinter * @param array|string $key The first SET key to intersect. * @param string ...$other_keys One or more Redis SET keys. * @example * $redis->pipeline() * ->del('alice_likes', 'bob_likes', 'bill_likes') * ->sadd('alice_likes', 'asparagus', 'broccoli', 'carrot', 'potato') * ->sadd('bob_likes', 'asparagus', 'carrot', 'potato') * ->sadd('bill_likes', 'broccoli', 'potato') * ->exec(); * var_dump($redis->sinter('alice_likes', 'bob_likes', 'bill_likes')); * */ public function sInter(array|string $key, string ...$other_keys): Redis|array|false {} /** * Compute the intersection of one or more sets and return the cardinality of the result. * @param array $keys One or more set key names. * @param int $limit A maximum cardinality to return. This is useful to put an upper bound * on the amount of work Redis will do. * @return Redis|int|false The * @see https://redis.io/commands/sintercard * @example * $redis->sAdd('set1', 'apple', 'pear', 'banana', 'carrot'); * $redis->sAdd('set2', 'apple', 'banana'); * $redis->sAdd('set3', 'pear', 'banana'); * $redis->sInterCard(['set1', 'set2', 'set3']); * ?> * */ public function sintercard(array $keys, int $limit = -1): Redis|int|false {} /** * Perform the intersection of one or more Redis SETs, storing the result in a destination * key, rather than returning them. * @param array|string $key Either a string key, or an array of keys (with at least two * elements, consisting of the destination key name and one * or more source keys names. * @param string ...$other_keys If the first argument was a string, subsequent arguments should * be source key names. * @return Redis|int|false The number of values stored in the destination key or false on failure. * @see https://redis.io/commands/sinterstore * @see Redis::sinter() * @example $redis->sInterStore(['dst', 'src1', 'src2', 'src3']); * @example $redis->sInterStore('dst', 'src1', 'src'2', 'src3'); * ?> * */ public function sInterStore(array|string $key, string ...$other_keys): Redis|int|false {} /** * Retrieve every member from a set key. * @param string $key The set name. * @return Redis|array|false Every element in the set or false on failure. * @see https://redis.io/commands/smembers * @example * $redis->sAdd('tng-crew', ...['Picard', 'Riker', 'Data', 'Worf', 'La Forge', 'Troi', 'Crusher', 'Broccoli']); * $redis->sMembers('tng-crew'); */ public function sMembers(string $key): Redis|array|false {} /** * Check if one or more values are members of a set. * @see https://redis.io/commands/smismember * @see https://redis.io/commands/smember * @see Redis::smember() * @param string $key The set to query. * @param string $member The first value to test if exists in the set. * @param string ...$other_members Any number of additional values to check. * @return Redis|array|false An array of integers representing whether each passed value * was a member of the set. * @example * $redis->sAdd('ds9-crew', ...["Sisko", "Kira", "Dax", "Worf", "Bashir", "O'Brien"]); * $members = $redis->sMIsMember('ds9-crew', ...['Sisko', 'Picard', 'Data', 'Worf']); */ public function sMisMember(string $key, string $member, string ...$other_members): Redis|array|false {} /** * Pop a member from one set and push it onto another. This command will create the * destination set if it does not currently exist. * @see https://redis.io/commands/smove * @param string $src The source set. * @param string $dst The destination set. * @param mixed $value The member you wish to move. * @return Redis|bool True if the member was moved, and false if it wasn't in the set. * @example * $redis->sAdd('numbers', 'zero', 'one', 'two', 'three', 'four'); * $redis->sMove('numbers', 'evens', 'zero'); * $redis->sMove('numbers', 'evens', 'two'); * $redis->sMove('numbers', 'evens', 'four'); */ public function sMove(string $src, string $dst, mixed $value): Redis|bool {} /** * Remove one or more elements from a set. * @see https://redis.io/commands/spop * @param string $key The set in question. * @param int $count An optional number of members to pop. This defaults to * removing one element. * @example * $redis->del('numbers', 'evens'); * $redis->sAdd('numbers', 'zero', 'one', 'two', 'three', 'four'); * $redis->sPop('numbers'); */ public function sPop(string $key, int $count = 0): Redis|string|array|false {} /** * Retrieve one or more random members of a set. * @param string $key The set to query. * @param int $count An optional count of members to return. * If this value is positive, Redis will return *up to* the requested * number but with unique elements that will never repeat. This means * you may recieve fewer then `$count` replies. * If the number is negative, Redis will return the exact number requested * but the result may contain duplicate elements. * @return Redis|array|string|false One or more random members or false on failure. * @see https://redis.io/commands/srandmember * @example $redis->sRandMember('myset'); * @example $redis->sRandMember('myset', 10); * @example $redis->sRandMember('myset', -10); */ public function sRandMember(string $key, int $count = 0): Redis|string|array|false {} /** * Returns the union of one or more Redis SET keys. * @see https://redis.io/commands/sunion * @param string $key The first SET to do a union with * @param string ...$other_keys One or more subsequent keys * @return Redis|array|false The union of the one or more input sets or false on failure. * @example $redis->sunion('set1', 'set2'); */ public function sUnion(string $key, string ...$other_keys): Redis|array|false {} /** * Perform a union of one or more Redis SET keys and store the result in a new set * @see https://redis.io/commands/sunionstore * @see Redis::sunion() * @param string $dst The destination key * @param string $key The first source key * @param string ...$other_keys One or more additional source keys * @return Redis|int|false The number of elements stored in the destination SET or * false on failure. */ public function sUnionStore(string $dst, string $key, string ...$other_keys): Redis|int|false {} /** * Persist the Redis database to disk. This command will block the server until the save is * completed. For a nonblocking alternative, see Redis::bgsave(). * @see https://redis.io/commands/save * @see Redis::bgsave() * @return Redis|bool Returns true unless an error occurs. */ public function save(): Redis|bool {} /** * Incrementally scan the Redis keyspace, with optional pattern and type matching. * A note about Redis::SCAN_NORETRY and Redis::SCAN_RETRY. * For convenience, PhpRedis can retry SCAN commands itself when Redis returns an empty array of * keys with a nonzero iterator. This can happen when matching against a pattern that very few * keys match inside a key space with a great many keys. The following example demonstrates how * to use Redis::scan() with the option disabled and enabled. * @param int|null $iterator The cursor returned by Redis for every subsequent call to SCAN. On * the initial invocation of the call, it should be initialized by the * caller to NULL. Each time SCAN is invoked, the iterator will be * updated to a new number, until finally Redis will set the value to * zero, indicating that the scan is complete. * @param string|null $pattern An optional glob-style pattern for matching key names. If passed as * NULL, it is the equivalent of sending '*' (match every key). * @param int $count A hint to redis that tells it how many keys to return in a single * call to SCAN. The larger the number, the longer Redis may block * clients while iterating the key space. * @param string|null $type An optional argument to specify which key types to scan (e.g. * 'STRING', 'LIST', 'SET') * @return array|false An array of keys, or false if no keys were returned for this * invocation of scan. Note that it is possible for Redis to return * zero keys before having scanned the entire key space, so the caller * should instead continue to SCAN until the iterator reference is * returned to zero. * @see https://redis.io/commands/scan * @see Redis::setOption() * @example * $redis = new Redis(['host' => 'localhost']); * $redis->setOption(Redis::OPT_SCAN, Redis::SCAN_NORETRY); * $it = null; * do { * $keys = $redis->scan($it, '*zorg*'); * foreach ($keys as $key) { * echo "KEY: $key\n"; * } * } while ($it != 0); * $redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY); * $it = null; * // When Redis::SCAN_RETRY is enabled, we can use simpler logic, as we will never receive an * // empty array of keys when the iterator is nonzero. * while ($keys = $redis->scan($it, '*zorg*')) { * foreach ($keys as $key) { * echo "KEY: $key\n"; * } * } */ public function scan(?int &$iterator, ?string $pattern = null, int $count = 0, ?string $type = null): array|false {} /** * Retrieve the number of members in a Redis set. * @param string $key The set to get the cardinality of. * @return Redis|int|false The cardinality of the set or false on failure. * @see https://redis.io/commands/scard * @example $redis->scard('set'); * */ public function scard(string $key): Redis|int|false {} /** * An administrative command used to interact with LUA scripts stored on the server. * @see https://redis.io/commands/script * @param string $command The script suboperation to execute. * @param mixed $args One ore more additional argument * @return mixed This command returns various things depending on the specific operation executed. * @example $redis->script('load', 'return 1'); * @example $redis->script('exists', sha1('return 1')); */ public function script(string $command, mixed ...$args): mixed {} /** * Select a specific Redis database. * @param int $db The database to select. Note that by default Redis has 16 databases (0-15). * @return Redis|bool true on success and false on failure * @see https://redis.io/commands/select * @example $redis->select(1); */ public function select(int $db): Redis|bool {} /** * Create or set a Redis STRING key to a value. * @param string $key The key name to set. * @param mixed $value The value to set the key to. * @param array|int $options Either an array with options for how to perform the set or an * integer with an expiration. If an expiration is set PhpRedis * will actually send the `SETEX` command. * OPTION DESCRIPTION * ------------ -------------------------------------------------------------- * ['EX' => 60] expire 60 seconds. * ['PX' => 6000] expire in 6000 milliseconds. * ['EXAT' => time() + 10] expire in 10 seconds. * ['PXAT' => time()*1000 + 1000] expire in 1 second. * ['KEEPTTL' => true] Redis will not update the key's current TTL. * ['XX'] Only set the key if it already exists. * ['NX'] Only set the key if it doesn't exist. * ['GET'] Instead of returning `+OK` return the previous value of the * key or NULL if the key didn't exist. * @return Redis|string|bool True if the key was set or false on failure. * @see https://redis.io/commands/set * @see https://redis.io/commands/setex * @example $redis->set('key', 'value'); * @example $redis->set('key', 'expires_in_60_seconds', 60); */ public function set(string $key, mixed $value, mixed $options = null): Redis|string|bool {} /** * Set a specific bit in a Redis string to zero or one * @see https://redis.io/commands/setbit * @param string $key The Redis STRING key to modify * @param bool $value Whether to set the bit to zero or one. * @return Redis|int|false The original value of the bit or false on failure. * @example * $redis->set('foo', 'bar'); * $redis->setbit('foo', 7, 1); */ public function setBit(string $key, int $idx, bool $value): Redis|int|false {} /** * Update or append to a Redis string at a specific starting index * @see https://redis.io/commands/setrange * @param string $key The key to update * @param int $index Where to insert the provided value * @param string $value The value to copy into the string. * @return Redis|int|false The new length of the string or false on failure * @example * $redis->set('message', 'Hello World'); * $redis->setRange('message', 6, 'Redis'); */ public function setRange(string $key, int $index, string $value): Redis|int|false {} /** * Set a configurable option on the Redis object. * Following are a list of options you can set: * | OPTION | TYPE | DESCRIPTION | * | --------------- | ---- | ----------- | * | OPT_MAX_RETRIES | int | The maximum number of times Redis will attempt to reconnect if it gets disconnected, before throwing an exception. | * | OPT_SCAN | enum | Redis::OPT_SCAN_RETRY, or Redis::OPT_SCAN_NORETRY. Whether PhpRedis should automatically SCAN again when zero keys but a nonzero iterator are returned. | * | OPT_SERIALIZER | enum | Set the automatic data serializer.
`Redis::SERIALIZER_NONE`
`Redis::SERIALIZER_PHP`
`Redis::SERIALIZER_IGBINARY`
`Redis::SERIALIZER_MSGPACK`, `Redis::SERIALIZER_JSON`| * | OPT_PREFIX | string | A string PhpRedis will use to prefix every key we read or write. | * | OPT_READ_TIMEOUT | float | How long PhpRedis will block for a response from Redis before throwing a 'read error on connection' exception. | * | OPT_TCP_KEEPALIVE | bool | Set or disable TCP_KEEPALIVE on the connection. | * | OPT_COMPRESSION | enum | Set the compression algorithm
`Redis::COMPRESSION_NONE`
`Redis::COMPRESSION_LZF`
`Redis::COMPRESSION_LZ4`
`Redis::COMPRESSION_ZSTD` | * | OPT_REPLY_LITERAL | bool | If set to true, PhpRedis will return the literal string Redis returns for LINE replies (e.g. '+OK'), rather than `true`. | * | OPT_COMPRESSION_LEVEL | int | Set a specific compression level if Redis is compressing data. | * | OPT_NULL_MULTIBULK_AS_NULL | bool | Causes PhpRedis to return `NULL` rather than `false` for NULL MULTIBULK replies | * | OPT_BACKOFF_ALGORITHM | enum | The exponential backoff strategy to use. | * | OPT_BACKOFF_BASE | int | The minimum delay between retries when backing off. | * | OPT_BACKOFF_CAP | int | The maximum delay between replies when backing off. | * @param int $option The option constant. * @param mixed $value The option value. * @return bool true if the setting was updated, false if not. * @see Redis::__construct() for details about backoff strategies. * @see Redis::getOption() */ public function setOption(int $option, mixed $value): bool {} /** * Set a Redis STRING key with a specific expiration in seconds. * @param string $key The name of the key to set. * @param int $expire The key's expiration in seconds. * @param mixed $value The value to set the key. * @return Redis|bool True on success or false on failure. * @example $redis->setex('60s-ttl', 60, 'some-value'); */ public function setex(string $key, int $expire, mixed $value) {} /** * Set a key to a value, but only if that key does not already exist. * @see https://redis.io/commands/setnx * @param string $key The key name to set. * @param mixed $value What to set the key to. * @return Redis|bool Returns true if the key was set and false otherwise. * @example $redis->setnx('existing-key', 'existing-value'); * @example $redis->setnx('new-key', 'new-value'); */ public function setnx(string $key, mixed $value): Redis|bool {} /** * Check whether a given value is the member of a Redis SET. * @param string $key The redis set to check. * @param mixed $value The value to test. * @return Redis|bool True if the member exists and false if not. * @example $redis->sismember('myset', 'mem1', 'mem2'); */ public function sismember(string $key, mixed $value): Redis|bool {} /** * Turn a redis instance into a replica of another or promote a replica * to a primary. * This method and the corresponding command in Redis has been marked deprecated * and users should instead use Redis::replicaof() if connecting to redis-server * >= 5.0.0. * @deprecated * @see https://redis.io/commands/slaveof * @see https://redis.io/commands/replicaof * @see Redis::replicaof() */ public function slaveof(?string $host = null, int $port = 6379): Redis|bool {} /** * Used to turn a Redis instance into a replica of another, or to remove * replica status promoting the instance to a primary. * @see https://redis.io/commands/replicaof * @see https://redis.io/commands/slaveof * @see Redis::slaveof() * @param string|null $host The host of the primary to start replicating. * @param int $port The port of the primary to start replicating. * @return Redis|bool Success if we were successfully able to start replicating a primary or * were able to promote teh replicat to a primary. * @example * $redis = new Redis(['host' => 'localhost']); * // Attempt to become a replica of a Redis instance at 127.0.0.1:9999 * $redis->replicaof('127.0.0.1', 9999); * // When passed no arguments, PhpRedis will deliver the command `REPLICAOF NO ONE` * // attempting to promote the instance to a primary. * $redis->replicaof(); */ public function replicaof(?string $host = null, int $port = 6379): Redis|bool {} /** * Update one or more keys last modified metadata. * @see https://redis.io/commands/touch/ * @param array|string $key_or_array * @param string ...$more_keys One or more keys to send to the command. * @return Redis|int|false This command returns the number of keys that exist and * had their last modified time reset */ public function touch(array|string $key_or_array, string ...$more_keys): Redis|int|false {} /** * Interact with Redis' slowlog functionality in various ways, depending * on the value of 'operation'. * @param string $operation The operation you wish to perform. This can * be one of the following values: * 'GET' - Retrieve the Redis slowlog as an array. * 'LEN' - Retrieve the length of the slowlog. * 'RESET' - Remove all slowlog entries. * @param int $length This optional argument can be passed when operation * is 'get' and will specify how many elements to retrieve. * If omitted Redis will send up to a default number of * entries, which is configurable. * Note: With Redis >= 7.0.0 you can send -1 to mean "all". * @return mixed * @see https://redis.io/commands/slowlog/ * @example $redis->slowlog('get', -1); // Retrieve all slowlog entries. * @example $redis->slowlog('len'); // Retrieve slowlog length. * @example $redis->slowlog('reset'); // Reset the slowlog. */ public function slowlog(string $operation, int $length = 0): mixed {} /** * Sort the contents of a Redis key in various ways. * @see https://redis.io/commands/sort/ * @param string $key The key you wish to sort * @param array|null $options Various options controlling how you would like the * data sorted. See blow for a detailed description * of this options array. * @return mixed This command can either return an array with the sorted data * or the number of elements placed in a destination set when * using the STORE option. * @example * $options = [ * 'SORT' => 'ASC'|| 'DESC' // Sort in descending or descending order. * 'ALPHA' => true || false // Whether to sort alphanumerically. * 'LIMIT' => [0, 10] // Return a subset of the data at offset, count * 'BY' => 'weight_*' // For each element in the key, read data from the * external key weight_* and sort based on that value. * 'GET' => 'weight_*' // For each element in the source key, retrieve the * data from key weight_* and return that in the result * rather than the source keys' element. This can * be used in combination with 'BY' * ]; */ public function sort(string $key, ?array $options = null): mixed {} /** * This is simply a read-only variant of the sort command * @see Redis::sort() */ public function sort_ro(string $key, ?array $options = null): mixed {} /** * @deprecated */ public function sortAsc(string $key, ?string $pattern = null, mixed $get = null, int $offset = -1, int $count = -1, ?string $store = null): array {} /** * @deprecated */ public function sortAscAlpha(string $key, ?string $pattern = null, mixed $get = null, int $offset = -1, int $count = -1, ?string $store = null): array {} /** * @deprecated */ public function sortDesc(string $key, ?string $pattern = null, mixed $get = null, int $offset = -1, int $count = -1, ?string $store = null): array {} /** * @deprecated */ public function sortDescAlpha(string $key, ?string $pattern = null, mixed $get = null, int $offset = -1, int $count = -1, ?string $store = null): array {} /** * Remove one or more values from a Redis SET key. * @see https://redis.io/commands/srem * @param string $key The Redis SET key in question. * @param mixed $value The first value to remove. * @param mixed ...$other_values One or more additional values to remove. * @return Redis|int|false The number of values removed from the set or false on failure. * @example $redis->sRem('set1', 'mem1', 'mem2', 'not-in-set'); */ public function srem(string $key, mixed $value, mixed ...$other_values): Redis|int|false {} /** * Scan the members of a redis SET key. * @see https://redis.io/commands/sscan * @see https://redis.io/commands/scan * @see Redis::setOption() * @param string $key The Redis SET key in question. * @param int|null $iterator A reference to an iterator which should be initialized to NULL that * PhpRedis will update with the value returned from Redis after each * subsequent call to SSCAN. Once this cursor is zero you know all * members have been traversed. * @param string|null $pattern An optional glob style pattern to match against, so Redis only * returns the subset of members matching this pattern. * @param int $count A hint to Redis as to how many members it should scan in one command * before returning members for that iteration. * @return array|false * @example * $redis->del('myset'); * for ($i = 0; $i < 10000; $i++) { * $redis->sAdd('myset', "member:$i"); * } * $redis->sadd('myset', 'foofoo'); * $redis->setOption(Redis::OPT_SCAN, Redis::SCAN_NORETRY); * $scanned = 0; * $it = null; * // Without Redis::SCAN_RETRY we may receive empty results and * // a nonzero iterator. * do { * // Scan members containing '5' * $members = $redis->sscan('myset', $it, '*5*'); * foreach ($members as $member) { * echo "NORETRY: $member\n"; * $scanned++; * } * } while ($it != 0); * echo "TOTAL: $scanned\n"; * $redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY); * $scanned = 0; * $it = null; * // With Redis::SCAN_RETRY PhpRedis will never return an empty array * // when the cursor is non-zero * while (($members = $redis->sscan('myset', $it, '*5*'))) { * foreach ($members as $member) { * echo "RETRY: $member\n"; * $scanned++; * } * } */ public function sscan(string $key, ?int &$iterator, ?string $pattern = null, int $count = 0): array|false {} /** * Subscribes the client to the specified shard channels. * @param array $channels One or more channel names. * @param callable $cb The callback PhpRedis will invoke when we receive a message * from one of the subscribed channels. * @return bool True on success, false on faiilure. Note that this command will block the * client in a subscribe loop, waiting for messages to arrive. * @see https://redis.io/commands/ssubscribe * @example * $redis = new Redis(['host' => 'localhost']); * $redis->ssubscribe(['channel-1', 'channel-2'], function ($redis, $channel, $message) { * echo "[$channel]: $message\n"; * // Unsubscribe from the message channel when we read 'quit' * if ($message == 'quit') { * echo "Unsubscribing from '$channel'\n"; * $redis->sunsubscribe([$channel]); * } * }); * // Once we read 'quit' from both channel-1 and channel-2 the subscribe loop will be * // broken and this command will execute. * echo "Subscribe loop ended\n"; */ public function ssubscribe(array $channels, callable $cb): bool {} /** * Retrieve the length of a Redis STRING key. * @param string $key The key we want the length of. * @return Redis|int|false The length of the string key if it exists, zero if it does not, and * false on failure. * @see https://redis.io/commands/strlen * @example $redis->strlen('mykey'); */ public function strlen(string $key): Redis|int|false {} /** * Subscribe to one or more Redis pubsub channels. * @param array $channels One or more channel names. * @param callable $cb The callback PhpRedis will invoke when we receive a message * from one of the subscribed channels. * @return bool True on success, false on faiilure. Note that this command will block the * client in a subscribe loop, waiting for messages to arrive. * @see https://redis.io/commands/subscribe * @example * $redis = new Redis(['host' => 'localhost']); * $redis->subscribe(['channel-1', 'channel-2'], function ($redis, $channel, $message) { * echo "[$channel]: $message\n"; * // Unsubscribe from the message channel when we read 'quit' * if ($message == 'quit') { * echo "Unsubscribing from '$channel'\n"; * $redis->unsubscribe([$channel]); * } * }); * // Once we read 'quit' from both channel-1 and channel-2 the subscribe loop will be * // broken and this command will execute. * echo "Subscribe loop ended\n"; */ public function subscribe(array $channels, callable $cb): bool {} /** * Unsubscribes the client from the given shard channels, * or from all of them if none is given. * @param array $channels One or more channels to unsubscribe from. * @return Redis|array|bool The array of unsubscribed channels. * @see https://redis.io/commands/sunsubscribe * @see Redis::ssubscribe() * @example * $redis->ssubscribe(['channel-1', 'channel-2'], function ($redis, $channel, $message) { * if ($message == 'quit') { * echo "$channel => 'quit' detected, unsubscribing!\n"; * $redis->sunsubscribe([$channel]); * } else { * echo "$channel => $message\n"; * } * }); * echo "We've unsubscribed from both channels, exiting\n"; */ public function sunsubscribe(array $channels): Redis|array|bool {} /** * Atomically swap two Redis databases so that all of the keys in the source database will * now be in the destination database and vice-versa. * Note: This command simply swaps Redis' internal pointer to the database and is therefore * very fast, regardless of the size of the underlying databases. * @param int $src The source database number * @param int $dst The destination database number * @return Redis|bool Success if the databases could be swapped and false on failure. * @see https://redis.io/commands/swapdb * @see Redis::del() * @example * $redis->select(0); * $redis->set('db0-key', 'db0-value'); * $redis->swapdb(0, 1); * $redis->get('db0-key'); */ public function swapdb(int $src, int $dst): Redis|bool {} /** * Retrieve the server time from the connected Redis instance. * @see https://redis.io/commands/time * @return Redis|array A two element array consisting of a Unix Timestamp and the number of microseconds * elapsed since the second. * @example $redis->time(); */ public function time(): Redis|array {} /** * Get the amount of time a Redis key has before it will expire, in seconds. * @param string $key The Key we want the TTL for. * @return Redis|int|false (a) The number of seconds until the key expires, or -1 if the key has * no expiration, and -2 if the key does not exist. In the event of an * error, this command will return false. * @see https://redis.io/commands/ttl * @example $redis->ttl('mykey'); */ public function ttl(string $key): Redis|int|false {} /** * Get the type of a given Redis key. * @see https://redis.io/commands/type * @param string $key The key to check * @return Redis|int|false The Redis type constant or false on failure. * The Redis class defines several type constants that correspond with Redis key types. * Redis::REDIS_NOT_FOUND * Redis::REDIS_STRING * Redis::REDIS_SET * Redis::REDIS_LIST * Redis::REDIS_ZSET * Redis::REDIS_HASH * Redis::REDIS_STREAM * @example * foreach ($redis->keys('*') as $key) { * echo "$key => " . $redis->type($key) . "\n"; * } */ public function type(string $key): Redis|int|false {} /** * Delete one or more keys from the Redis database. Unlike this operation, the actual * deletion is asynchronous, meaning it is safe to delete large keys without fear of * Redis blocking for a long period of time. * @param array|string $key Either an array with one or more keys or a string with * the first key to delete. * @param string ...$other_keys If the first argument passed to this method was a string * you may pass any number of additional key names. * @return Redis|int|false The number of keys deleted or false on failure. * @see https://redis.io/commands/unlink * @see https://redis.io/commands/del * @see Redis::del() * @example $redis->unlink('key1', 'key2', 'key3'); * @example $redis->unlink(['key1', 'key2', 'key3']); */ public function unlink(array|string $key, string ...$other_keys): Redis|int|false {} /** * Unsubscribe from one or more subscribed channels. * @param array $channels One or more channels to unsubscribe from. * @return Redis|array|bool The array of unsubscribed channels. * @see https://redis.io/commands/unsubscribe * @see Redis::subscribe() * @example * $redis->subscribe(['channel-1', 'channel-2'], function ($redis, $channel, $message) { * if ($message == 'quit') { * echo "$channel => 'quit' detected, unsubscribing!\n"; * $redis->unsubscribe([$channel]); * } else { * echo "$channel => $message\n"; * } * }); * echo "We've unsubscribed from both channels, exiting\n"; */ public function unsubscribe(array $channels): Redis|array|bool {} /** * Remove any previously WATCH'ed keys in a transaction. * @see https://redis.io/commands/unwatch * @see https://redis.io/commands/unwatch * @see Redis::watch() * @return Redis|bool on success and false on failure. */ public function unwatch(): Redis|bool {} /** * Watch one or more keys for conditional execution of a transaction. * @param array|string $key Either an array with one or more key names, or a string key name * @param string ...$other_keys If the first argument was passed as a string, any number of additional * string key names may be passed variadically. * @return Redis|bool * @see https://redis.io/commands/watch * @see https://redis.io/commands/unwatch * @example * $redis1 = new Redis(['host' => 'localhost']); * $redis2 = new Redis(['host' => 'localhost']); * // Start watching 'incr-key' * $redis1->watch('incr-key'); * // Retrieve its value. * $val = $redis1->get('incr-key'); * // A second client modifies 'incr-key' after we read it. * $redis2->set('incr-key', 0); * // Because another client changed the value of 'incr-key' after we read it, this * // is no longer a proper increment operation, but because we are `WATCH`ing the * // key, this transaction will fail and we can try again. * // * // If were to comment out the above `$redis2->set('incr-key', 0)` line the * // transaction would succeed. * $redis1->multi(); * $redis1->set('incr-key', $val + 1); * $res = $redis1->exec(); * // bool(false) * var_dump($res); */ public function watch(array|string $key, string ...$other_keys): Redis|bool {} /** * Block the client up to the provided timeout until a certain number of replicas have confirmed * recieving them. * @see https://redis.io/commands/wait * @param int $numreplicas The number of replicas we want to confirm write operaions * @param int $timeout How long to wait (zero meaning forever). * @return int|false The number of replicas that have confirmed or false on failure. */ public function wait(int $numreplicas, int $timeout): int|false {} /** * Acknowledge one ore more messages that are pending (have been consumed using XREADGROUP but * not yet acknowledged by XACK.) * @param string $key The stream to query. * @param string $group The consumer group to use. * @param array $ids An array of stream entry IDs. * @return int|false The number of acknowledged messages * @see https://redis.io/commands/xack * @see https://redis.io/commands/xreadgroup * @see Redis::xack() * @example * $redis->xAdd('ships', '*', ['name' => 'Enterprise']); * $redis->xAdd('ships', '*', ['name' => 'Defiant']); * $redis->xGroup('CREATE', 'ships', 'Federation', '0-0'); * // Consume a single message with the consumer group 'Federation' * $ship = $redis->xReadGroup('Federation', 'Picard', ['ships' => '>'], 1); * /* Retrieve the ID of the message we read. * assert(isset($ship['ships'])); * $id = key($ship['ships']); * // The message we just read is now pending. * $res = $redis->xPending('ships', 'Federation')); * var_dump($res); * // We can tell Redis we were able to process the message by using XACK * $res = $redis->xAck('ships', 'Federation', [$id]); * assert($res === 1); * // The message should no longer be pending. * $res = $redis->xPending('ships', 'Federation'); * var_dump($res); */ public function xack(string $key, string $group, array $ids): int|false {} /** * Append a message to a stream. * @param string $key The stream name. * @param string $id The ID for the message we want to add. This can be the special value '*' * which means Redis will generate the ID that appends the message to the * end of the stream. It can also be a value in the form -* which will * generate an ID that appends to the end ot entries with the same value * (if any exist). * @param int $maxlen If specified Redis will append the new message but trim any number of the * oldest messages in the stream until the length is <= $maxlen. * @param bool $approx Used in conjunction with `$maxlen`, this flag tells Redis to trim the stream * but in a more efficient way, meaning the trimming may not be exactly to * `$maxlen` values. * @param bool $nomkstream If passed as `TRUE`, the stream must exist for Redis to append the message. * @see https://redis.io/commands/xadd * @example $redis->xAdd('ds9-season-1', '1-1', ['title' => 'Emissary Part 1']); * @example $redis->xAdd('ds9-season-1', '1-2', ['title' => 'A Man Alone']); */ public function xadd(string $key, string $id, array $values, int $maxlen = 0, bool $approx = false, bool $nomkstream = false): Redis|string|false {} /** * This command allows a consumer to claim pending messages that have been idle for a specified period of time. * Its purpose is to provide a mechanism for picking up messages that may have had a failed consumer. * @see https://redis.io/commands/xautoclaim * @see https://redis.io/commands/xclaim * @see https://redis.io/docs/data-types/streams-tutorial/ * @param string $key The stream to check. * @param string $group The consumer group to query. * @param string $consumer Which consumer to check. * @param int $min_idle The minimum time in milliseconds for the message to have been pending. * @param string $start The minimum message id to check. * @param int $count An optional limit on how many messages are returned. * @param bool $justid If the client only wants message IDs and not all of their data. * @return Redis|array|bool An array of pending IDs or false if there are none, or on failure. * @example * $redis->xGroup('CREATE', 'ships', 'combatants', '0-0', true); * $redis->xAdd('ships', '1424-74205', ['name' => 'Defiant']); * // Consume the ['name' => 'Defiant'] message * $msgs = $redis->xReadGroup('combatants', "Jem'Hadar", ['ships' => '>'], 1); * // The "Jem'Hadar" consumer has the message presently * $pending = $redis->xPending('ships', 'combatants'); * var_dump($pending); * // Asssume control of the pending message with a different consumer. * $res = $redis->xAutoClaim('ships', 'combatants', 'Sisko', 0, '0-0'); * // Now the 'Sisko' consumer owns the message * $pending = $redis->xPending('ships', 'combatants'); * var_dump($pending); */ public function xautoclaim(string $key, string $group, string $consumer, int $min_idle, string $start, int $count = -1, bool $justid = false): Redis|bool|array {} /** * This method allows a consumer to take ownership of pending stream entries, by ID. Another * command that does much the same thing but does not require passing specific IDs is `Redis::xAutoClaim`. * @see https://redis.io/commands/xclaim * @see https://redis.io/commands/xautoclaim. * @param string $key The stream we wish to claim messages for. * @param string $group Our consumer group. * @param string $consumer Our consumer. * @param int $min_idle The minimum idle-time in milliseconds a message must have for ownership to be transferred. * @param array $options An options array that modifies how the command operates. * * # Following is an options array describing every option you can pass. Note that * # 'IDLE', and 'TIME' are mutually exclusive. * $options = [ * 'IDLE' => 3 # Set the idle time of the message to a 3. By default * # the idle time is set to zero. * 'TIME' => 1000*time() # Same as IDLE except it takes a unix timestamp in * # milliseconds. * 'RETRYCOUNT' => 0 # Set the retry counter to zero. By default XCLAIM * # doesn't modify the counter. * 'FORCE' # Creates the pending message entry even if IDs are * # not already * # in the PEL with another client. * 'JUSTID' # Return only an array of IDs rather than the messages * # themselves. * ]; * * @return Redis|array|bool An array of claimed messags or false on failure. * @example * $redis->xGroup('CREATE', 'ships', 'combatants', '0-0', true); * $redis->xAdd('ships', '1424-74205', ['name' => 'Defiant']); * // Consume the ['name' => 'Defiant'] message * $msgs = $redis->xReadGroup('combatants', "Jem'Hadar", ['ships' => '>'], 1); * // The "Jem'Hadar" consumer has the message presently * $pending = $redis->xPending('ships', 'combatants'); * var_dump($pending); * assert($pending && isset($pending[1])); * // Claim the message by ID. * $claimed = $redis->xClaim('ships', 'combatants', 'Sisko', 0, [$pending[1]], ['JUSTID']); * var_dump($claimed); * // Now the 'Sisko' consumer owns the message * $pending = $redis->xPending('ships', 'combatants'); * var_dump($pending); */ public function xclaim(string $key, string $group, string $consumer, int $min_idle, array $ids, array $options): Redis|array|bool {} /** * Remove one or more specific IDs from a stream. * @param string $key The stream to modify. * @param array $ids One or more message IDs to remove. * @return Redis|int|false The number of messages removed or false on failure. * @example $redis->xDel('stream', ['1-1', '2-1', '3-1']); */ public function xdel(string $key, array $ids): Redis|int|false {} /** * XGROUP * Perform various operation on consumer groups for a particular Redis STREAM. What the command does * is primarily based on which operation is passed. * @see https://redis.io/commands/xgroup/ * @param string $operation The subcommand you intend to execute. Valid options are as follows * 'HELP' - Redis will return information about the command * Requires: none * 'CREATE' - Create a consumer group. * Requires: Key, group, consumer. * 'SETID' - Set the ID of an existing consumer group for the stream. * Requires: Key, group, id. * 'CREATECONSUMER' - Create a new consumer group for the stream. You must * also pass key, group, and the consumer name you wish to * create. * Requires: Key, group, consumer. * 'DELCONSUMER' - Delete a consumer from group attached to the stream. * Requires: Key, group, consumer. * 'DESTROY' - Delete a consumer group from a stream. * Requires: Key, group. * @param string|null $key The STREAM we're operating on. * @param string|null $group The consumer group we want to create/modify/delete. * @param string|null $id_or_consumer The STREAM id (e.g. '$') or consumer group. See the operation section * for information about which to send. * @param bool $mkstream This flag may be sent in combination with the 'CREATE' operation, and * cause Redis to also create the STREAM if it doesn't currently exist. * @param int $entries_read * @return mixed This command return various results depending on the operation performed. */ public function xgroup( string $operation, ?string $key = null, ?string $group = null, ?string $id_or_consumer = null, bool $mkstream = false, int $entries_read = -2 ): mixed {} /** * Retrieve information about a stream key. * @param string $operation The specific info operation to perform. * @param string|null $arg1 The first argument (depends on operation) * @param string|null $arg2 The second argument * @param int $count The COUNT argument to `XINFO STREAM` * @return mixed This command can return different things depending on the operation being called. * @see https://redis.io/commands/xinfo * @example $redis->xInfo('CONSUMERS', 'stream'); * @example $redis->xInfo('GROUPS', 'stream'); * @example $redis->xInfo('STREAM', 'stream'); */ public function xinfo(string $operation, ?string $arg1 = null, ?string $arg2 = null, int $count = -1): mixed {} /** * Get the number of messages in a Redis STREAM key. * @param string $key The Stream to check. * @return Redis|int|false The number of messages or false on failure. * @see https://redis.io/commands/xlen * @example $redis->xLen('stream'); */ public function xlen(string $key): Redis|int|false {} /** * Interact with stream messages that have been consumed by a consumer group but not yet * acknowledged with XACK. * @see https://redis.io/commands/xpending * @see https://redis.io/commands/xreadgroup * @param string $key The stream to inspect. * @param string $group The user group we want to see pending messages from. * @param string|null $start The minimum ID to consider. * @param string|null $end The maximum ID to consider. * @param int $count Optional maximum number of messages to return. * @param string|null $consumer If provided, limit the returned messages to a specific consumer. * @return Redis|array|false The pending messages belonging to the stream or false on failure. */ public function xpending(string $key, string $group, ?string $start = null, ?string $end = null, int $count = -1, ?string $consumer = null): Redis|array|false {} /** * Get a range of entries from a STREAM key. * @param string $key The stream key name to list. * @param string $start The minimum ID to return. * @param string $end The maximum ID to return. * @param int $count An optional maximum number of entries to return. * @return Redis|array|bool The entries in the stream within the requested range or false on failure. * @see https://redis.io/commands/xrange * @example $redis->xRange('stream', '0-1', '0-2'); * @example $redis->xRange('stream', '-', '+'); */ public function xrange(string $key, string $start, string $end, int $count = -1): Redis|array|bool {} /** * Consume one or more unconsumed elements in one or more streams. * @param array $streams An associative array with stream name keys and minimum id values. * @param int $count An optional limit to how many entries are returnd *per stream* * @param int $block An optional maximum number of milliseconds to block the caller if no * data is available on any of the provided streams. * @return Redis|array|bool An array of read elements or false if there aren't any. * @see https://redis.io/commands/xread * @example * $redis->xAdd('s03', '3-1', ['title' => 'The Search, Part I']); * $redis->xAdd('s03', '3-2', ['title' => 'The Search, Part II']); * $redis->xAdd('s03', '3-3', ['title' => 'The House Of Quark']); * $redis->xAdd('s04', '4-1', ['title' => 'The Way of the Warrior']); * $redis->xAdd('s04', '4-3', ['title' => 'The Visitor']); * $redis->xAdd('s04', '4-4', ['title' => 'Hippocratic Oath']); * $redis->xRead(['s03' => '3-2', 's04' => '4-1']); */ public function xread(array $streams, int $count = -1, int $block = -1): Redis|array|bool {} /** * Read one or more messages using a consumer group. * @param string $group The consumer group to use. * @param string $consumer The consumer to use. * @param array $streams An array of stream names and message IDs * @param int $count Optional maximum number of messages to return * @param int $block How long to block if there are no messages available. * @return Redis|array|bool Zero or more unread messages or false on failure. * @see https://redis.io/commands/xreadgroup * @example * $redis->xGroup('CREATE', 'episodes', 'ds9', '0-0', true); * $redis->xAdd('episodes', '1-1', ['title' => 'Emissary: Part 1']); * $redis->xAdd('episodes', '1-2', ['title' => 'A Man Alone']); * $messages = $redis->xReadGroup('ds9', 'sisko', ['episodes' => '>']); * // After having read the two messages, add another * $redis->xAdd('episodes', '1-3', ['title' => 'Emissary: Part 2']); * // Acknowledge the first two read messages * foreach ($messages as $stream => $stream_messages) { * $ids = array_keys($stream_messages); * $redis->xAck('stream', 'ds9', $ids); * } * // We can now pick up where we left off, and will only get the final message * $msgs = $redis->xReadGroup('ds9', 'sisko', ['episodes' => '>']); */ public function xreadgroup(string $group, string $consumer, array $streams, int $count = 1, int $block = 1): Redis|array|bool {} /** * Get a range of entries from a STREAM ke in reverse cronological order. * @param string $key The stream key to query. * @param string $end The maximum message ID to include. * @param string $start The minimum message ID to include. * @param int $count An optional maximum number of messages to include. * @return Redis|array|bool The entries within the requested range, from newest to oldest. * @see https://redis.io/commands/xrevrange * @see https://redis.io/commands/xrange * @example $redis->xRevRange('stream', '0-2', '0-1'); * @example $redis->xRevRange('stream', '+', '-'); */ public function xrevrange(string $key, string $end, string $start, int $count = -1): Redis|array|bool {} /** * Truncate a STREAM key in various ways. * @param string $key The STREAM key to trim. * @param string $threshold This can either be a maximum length, or a minimum id. * MAXLEN - An integer describing the maximum desired length of the stream after the command. * MINID - An ID that will become the new minimum ID in the stream, as Redis will trim all * messages older than this ID. * @param bool $approx Whether redis is allowed to do an approximate trimming of the stream. This is * more efficient for Redis given how streams are stored internally. * @param bool $minid When set to `true`, users should pass a minimum ID to the `$threshold` argument. * @param int $limit An optional upper bound on how many entries to trim during the command. * @return Redis|int|false The number of entries deleted from the stream. * @see https://redis.io/commands/xtrim * @example $redis->xTrim('stream', 3); * @example $redis->xTrim('stream', '2-1', false, true); */ public function xtrim(string $key, string $threshold, bool $approx = false, bool $minid = false, int $limit = -1): Redis|int|false {} /** * Add one or more elements and scores to a Redis sorted set. * @param string $key The sorted set in question. * @param array|float $score_or_options Either the score for the first element, or an array of options. * * $options = [ * 'NX', # Only update elements that already exist * 'NX', # Only add new elements but don't update existing ones. * 'LT' # Only update existing elements if the new score is * # less than the existing one. * 'GT' # Only update existing elements if the new score is * # greater than the existing one. * 'CH' # Instead of returning the number of elements added, * # Redis will return the number Of elements that were * # changed in the operation. * 'INCR' # Instead of setting each element to the provide score, * # increment the element by the * # provided score, much like ZINCRBY. When this option * # is passed, you may only send a single score and member. * ]; * Note: 'GX', 'LT', and 'NX' cannot be passed together, and PhpRedis * will send whichever one is last in the options array. * @param mixed $more_scores_and_mems A variadic number of additional scores and members. * @return Redis|int|float|false The return value varies depending on the options passed. * Following is information about the options that may be passed as the second argument: * @see https://redis.io/commands/zadd * @example $redis->zadd('zs', 1, 'first', 2, 'second', 3, 'third'); * @example $redis->zAdd('zs', ['XX'], 8, 'second', 99, 'new-element'); */ public function zAdd(string $key, array|float $score_or_options, mixed ...$more_scores_and_mems): Redis|int|float|false {} /** * Return the number of elements in a sorted set. * @param string $key The sorted set to retreive cardinality from. * @return Redis|int|false The number of elements in the set or false on failure * @see https://redis.io/commands/zcard * @example $redis->zCard('zs'); */ public function zCard(string $key): Redis|int|false {} /** * Count the number of members in a sorted set with scores inside a provided range. * @param string $key The sorted set to check. * @param string $start The minimum score to include in the count * @param string $end The maximum score to include in the count * NOTE: In addition to a floating point score you may pass the special values of '-inf' and * '+inf' meaning negative and positive infinity, respectively. * @see https://redis.io/commands/zcount * @example $redis->zCount('fruit-rankings', '0', '+inf'); * @example $redis->zCount('fruit-rankings', 50, 60); * @example $redis->zCount('fruit-rankings', '-inf', 0); */ public function zCount(string $key, string $start, string $end): Redis|int|false {} /** * Create or increment the score of a member in a Redis sorted set * @param string $key The sorted set in question. * @param float $value How much to increment the score. * @return Redis|float|false The new score of the member or false on failure. * @see https://redis.io/commands/zincrby * @example $redis->zIncrBy('zs', 5.0, 'bananas'); * @example $redis->zIncrBy('zs', 2.0, 'eggplants'); */ public function zIncrBy(string $key, float $value, mixed $member): Redis|float|false {} /** * Count the number of elements in a sorted set whos members fall within the provided * lexographical range. * @param string $key The sorted set to check. * @param string $min The minimum matching lexographical string * @param string $max The maximum matching lexographical string * @return Redis|int|false The number of members that fall within the range or false on failure. * @see https://redis.io/commands/zlexcount * @example * $redis->zAdd('captains', 0, 'Janeway', 0, 'Kirk', 0, 'Picard', 0, 'Sisko', 0, 'Archer'); * $redis->zLexCount('captains', '[A', '[S'); */ public function zLexCount(string $key, string $min, string $max): Redis|int|false {} /** * Retrieve the score of one or more members in a sorted set. * @see https://redis.io/commands/zmscore * @param string $key The sorted set * @param mixed $member The first member to return the score from * @param mixed $other_members One or more additional members to return the scores of. * @return Redis|array|false An array of the scores of the requested elements. * @example * $redis->zAdd('zs', 0, 'zero', 1, 'one', 2, 'two', 3, 'three'); * $redis->zMScore('zs', 'zero', 'two'); * $redis->zMScore('zs', 'one', 'not-a-member'); */ public function zMscore(string $key, mixed $member, mixed ...$other_members): Redis|array|false {} /** * Pop one or more of the highest scoring elements from a sorted set. * @param string $key The sorted set to pop elements from. * @param int|null $count An optional count of elements to pop. * @return Redis|array|false All of the popped elements with scores or false on fialure. * @see https://redis.io/commands/zpopmax * @example * $redis->zAdd('zs', 0, 'zero', 1, 'one', 2, 'two', 3, 'three'); * $redis->zPopMax('zs'); * $redis->zPopMax('zs', 2);. */ public function zPopMax(string $key, ?int $count = null): Redis|array|false {} /** * Pop one or more of the lowest scoring elements from a sorted set. * @param string $key The sorted set to pop elements from. * @param int|null $count An optional count of elements to pop. * @return Redis|array|false The popped elements with their scores or false on failure. * @see https://redis.io/commands/zpopmin * @example * $redis->zAdd('zs', 0, 'zero', 1, 'one', 2, 'two', 3, 'three'); * $redis->zPopMin('zs'); * $redis->zPopMin('zs', 2); */ public function zPopMin(string $key, ?int $count = null): Redis|array|false {} /** * Retrieve a range of elements of a sorted set between a start and end point. * How the command works in particular is greatly affected by the options that * are passed in. * @param string $key The sorted set in question. * @param mixed $start The starting index we want to return. * @param mixed $end The final index we want to return. * @param array|bool|null $options This value may either be an array of options to pass to * the command, or for historical purposes a boolean which * controls just the 'WITHSCORES' option. * * $options = [ * 'WITHSCORES' => true, # Return both scores and members. * 'LIMIT' => [10, 10], # Start at offset 10 and return 10 elements. * 'REV' # Return the elements in reverse order * 'BYSCORE', # Treat `start` and `end` as scores instead * 'BYLEX' # Treat `start` and `end` as lexicographical values. * ]; * * Note: 'BYLEX' and 'BYSCORE' are mutually exclusive. * @return Redis|array|false An array with matching elements or false on failure. * @see https://redis.io/commands/zrange/ * @example $redis->zRange('zset', 0, -1); * @example $redis->zRange('zset', '-inf', 'inf', ['byscore']); */ public function zRange(string $key, string|int $start, string|int $end, array|bool|null $options = null): Redis|array|false {} /** * Retrieve a range of elements from a sorted set by legographical range. * @param string $key The sorted set to retreive elements from * @param string $min The minimum legographical value to return * @param string $max The maximum legographical value to return * @param int $offset An optional offset within the matching values to return * @param int $count An optional count to limit the replies to (used in conjunction with offset) * @return Redis|array|false An array of matching elements or false on failure. * @see https://redis.io/commands/zrangebylex * @example * $redis = new Redis(['host' => 'localhost']); * $redis->zAdd('captains', 0, 'Janeway', 0, 'Kirk', 0, 'Picard', 0, 'Sisko', 0, 'Archer'); * $redis->zRangeByLex('captains', '[A', '[S'); * $redis->zRangeByLex('captains', '[A', '[S', 2, 2); */ public function zRangeByLex(string $key, string $min, string $max, int $offset = -1, int $count = -1): Redis|array|false {} /** * Retrieve a range of members from a sorted set by their score. * @param string $key The sorted set to query. * @param string $start The minimum score of elements that Redis should return. * @param string $end The maximum score of elements that Redis should return. * @param array $options Options that change how Redis will execute the command. * OPTION TYPE MEANING * 'WITHSCORES' bool Whether to also return scores. * 'LIMIT' [offset, count] Limit the reply to a subset of elements. * @return Redis|array|false The number of matching elements or false on failure. * @see https://redis.io/commands/zrangebyscore * @example $redis->zRangeByScore('zs', 20, 30, ['WITHSCORES' => true]); * @example $redis->zRangeByScore('zs', 20, 30, ['WITHSCORES' => true, 'LIMIT' => [5, 5]]); */ public function zRangeByScore(string $key, string $start, string $end, array $options = []): Redis|array|false {} /** * This command is similar to ZRANGE except that instead of returning the values directly * it will store them in a destination key provided by the user * @param string $dstkey The key to store the resulting element(s) * @param string $srckey The source key with element(s) to retrieve * @param string $start The starting index to store * @param string $end The ending index to store * @param array|bool|null $options Our options array that controls how the command will function. * @return Redis|int|false The number of elements stored in $dstkey or false on failure. * @see https://redis.io/commands/zrange/ * @see Redis::zRange * See {@link Redis::zRange} for a full description of the possible options. */ public function zrangestore( string $dstkey, string $srckey, string $start, string $end, array|bool|null $options = null ): Redis|int|false {} /** * Retrieve one or more random members from a Redis sorted set. * @param string $key The sorted set to pull random members from. * @param array|null $options One or more options that determine exactly how the command operates. * OPTION TYPE MEANING * 'COUNT' int The number of random members to return. * 'WITHSCORES' bool Whether to return scores and members instead of * @return Redis|string|array One ore more random elements. * @see https://redis.io/commands/zrandmember * @example $redis->zRandMember('zs', ['COUNT' => 2, 'WITHSCORES' => true]); */ public function zRandMember(string $key, ?array $options = null): Redis|string|array {} /** * Get the rank of a member of a sorted set, by score. * @param string $key The sorted set to check. * @param mixed $member The member to test. * @return Redis|int|false The rank of the requested member. * @see https://redis.io/commands/zrank * @example $redis->zRank('zs', 'zero'); * @example $redis->zRank('zs', 'three'); */ public function zRank(string $key, mixed $member): Redis|int|false {} /** * Remove one or more members from a Redis sorted set. * @param mixed $key The sorted set in question. * @param mixed $member The first member to remove. * @param mixed $other_members One or more members to remove passed in a variadic fashion. * @return Redis|int|false The number of members that were actually removed or false on failure. * @see https://redis.io/commands/zrem * @example $redis->zRem('zs', 'mem:0', 'mem:1', 'mem:2', 'mem:6', 'mem:7', 'mem:8', 'mem:9'); */ public function zRem(mixed $key, mixed $member, mixed ...$other_members): Redis|int|false {} /** * Remove zero or more elements from a Redis sorted set by legographical range. * @param string $key The sorted set to remove elements from. * @param string $min The start of the lexographical range to remove. * @param string $max The end of the lexographical range to remove * @return Redis|int|false The number of elements removed from the set or false on failure. * @see https://redis.io/commands/zremrangebylex * @see Redis::zrangebylex() * @example $redis->zRemRangeByLex('zs', '[a', '(b'); * @example $redis->zRemRangeByLex('zs', '(banana', '(eggplant'); */ public function zRemRangeByLex(string $key, string $min, string $max): Redis|int|false {} /** * Remove one or more members of a sorted set by their rank. * @param string $key The sorted set where we wnat to remove members. * @param int $start The rank when we want to start removing members * @param int $end The rank we want to stop removing membersk. * @return Redis|int|false The number of members removed from the set or false on failure. * @see https://redis.io/commands/zremrangebyrank * @example $redis->zRemRangeByRank('zs', 0, 3); */ public function zRemRangeByRank(string $key, int $start, int $end): Redis|int|false {} /** * Remove one or more members of a sorted set by their score. * @param string $key The sorted set where we wnat to remove members. * @param string $start The lowest score to remove. * @param string $end The highest score to remove. * @return Redis|int|false The number of members removed from the set or false on failure. * @see https://redis.io/commands/zremrangebyrank * @example * $redis->zAdd('zs', 2, 'two', 4, 'four', 6, 'six'); * $redis->zRemRangeByScore('zs', 2, 4); */ public function zRemRangeByScore(string $key, string $start, string $end): Redis|int|false {} /** * List the members of a Redis sorted set in reverse order * @param string $key The sorted set in question. * @param int $start The index to start listing elements * @param int $end The index to stop listing elements. * @param mixed $scores Whether or not Redis should also return each members score. See * the example below demonstrating how it may be used. * @return Redis|array|false The members (and possibly scores) of the matching elements or false * on failure. * @see https://redis.io/commands/zrevrange * @example $redis->zRevRange('zs', 0, -1); * @example $redis->zRevRange('zs', 2, 3); * @example $redis->zRevRange('zs', 0, -1, true); * @example $redis->zRevRange('zs', 0, -1, ['withscores' => true]); */ public function zRevRange(string $key, int $start, int $end, mixed $scores = null): Redis|array|false {} /** * List members of a Redis sorted set within a legographical range, in reverse order. * @param string $key The sorted set to list * @param string $max The maximum legographical element to include in the result. * @param string $min The minimum lexographical element to include in the result. * @param int $offset An option offset within the matching elements to start at. * @param int $count An optional count to limit the replies to. * @return Redis|array|false The matching members or false on failure. * @see https://redis.io/commands/zrevrangebylex * @see Redis::zrangebylex() * @example $redis->zRevRangeByLex('captains', '[Q', '[J'); * @example $redis->zRevRangeByLex('captains', '[Q', '[J', 1, 2); */ public function zRevRangeByLex(string $key, string $max, string $min, int $offset = -1, int $count = -1): Redis|array|false {} /** * List elements from a Redis sorted set by score, highest to lowest * @param string $key The sorted set to query. * @param string $max The highest score to include in the results. * @param string $min The lowest score to include in the results. * @param array|bool $options An options array that modifies how the command executes. * * $options = [ * 'WITHSCORES' => true|false # Whether or not to return scores * 'LIMIT' => [offset, count] # Return a subset of the matching members * ]; * * NOTE: For legacy reason, you may also simply pass `true` for the * options argument, to mean `WITHSCORES`. * @return Redis|array|false The matching members in reverse order of score or false on failure. * @see https://redis.io/commands/zrevrangebyscore * @example * $redis->zadd('oldest-people', 122.4493, 'Jeanne Calment', 119.2932, 'Kane Tanaka', * 119.2658, 'Sarah Knauss', 118.7205, 'Lucile Randon', * 117.7123, 'Nabi Tajima', 117.6301, 'Marie-Louise Meilleur', * 117.5178, 'Violet Brown', 117.3753, 'Emma Morano', * 117.2219, 'Chiyo Miyako', 117.0740, 'Misao Okawa'); * $redis->zRevRangeByScore('oldest-people', 122, 119); * $redis->zRevRangeByScore('oldest-people', 'inf', 118); * $redis->zRevRangeByScore('oldest-people', '117.5', '-inf', ['LIMIT' => [0, 1]]); */ public function zRevRangeByScore(string $key, string $max, string $min, array|bool $options = []): Redis|array|false {} /** * Retrieve a member of a sorted set by reverse rank. * @param string $key The sorted set to query. * @param mixed $member The member to look up. * @return Redis|int|false The reverse rank (the rank if counted high to low) of the member or * false on failure. * @see https://redis.io/commands/zrevrank * @example * $redis->zAdd('ds9-characters', 10, 'Sisko', 9, 'Garak', 8, 'Dax', 7, 'Odo'); * $redis->zrevrank('ds9-characters', 'Sisko'); * $redis->zrevrank('ds9-characters', 'Garak'); */ public function zRevRank(string $key, mixed $member): Redis|int|false {} /** * Get the score of a member of a sorted set. * @param string $key The sorted set to query. * @param mixed $member The member we wish to query. * @return Redis|float|false The score of the requested element or false if it is not found. * @see https://redis.io/commands/zscore * @example * $redis->zAdd('telescopes', 11.9, 'LBT', 10.4, 'GTC', 10, 'HET'); * $redis->zScore('telescopes', 'LBT'); */ public function zScore(string $key, mixed $member): Redis|float|false {} /** * Given one or more sorted set key names, return every element that is in the first * set but not any of the others. * @param array $keys One ore more sorted sets. * @param array|null $options An array which can contain ['WITHSCORES' => true] if you want Redis to * return members and scores. * @return Redis|array|false An array of members or false on failure. * @see https://redis.io/commands/zdiff * @example * $redis->zAdd('primes', 1, 'one', 3, 'three', 5, 'five'); * $redis->zAdd('evens', 2, 'two', 4, 'four'); * $redis->zAdd('mod3', 3, 'three', 6, 'six'); * $redis->zDiff(['primes', 'evens', 'mod3']); */ public function zdiff(array $keys, ?array $options = null): Redis|array|false {} /** * Store the difference of one or more sorted sets in a destination sorted set. * See {@link Redis::zdiff} for a more detailed description of how the diff operation works. * @param string $dst The destination set name. * @param array $keys One or more source key names * @return Redis|int|false The number of elements stored in the destination set or false on * failure. * @see https://redis.io/commands/zdiff * @see Redis::zdiff() */ public function zdiffstore(string $dst, array $keys): Redis|int|false {} /** * Compute the intersection of one or more sorted sets and return the members * @param array $keys One ore more sorted sets. * @param array|null $weights An optional array of weights to be applied to each set when performing * the intersection. * @param array|null $options Options for how Redis should combine duplicate elements when performing the * intersection. See Redis::zunion() for details. * @return Redis|array|false All of the members that exist in every set. * @see https://redis.io/commands/zinter * @example * $redis->zAdd('TNG', 2, 'Worf', 2.5, 'Data', 4.0, 'Picard'); * $redis->zAdd('DS9', 2.5, 'Worf', 3.0, 'Kira', 4.0, 'Sisko'); * $redis->zInter(['TNG', 'DS9']); * $redis->zInter(['TNG', 'DS9'], NULL, ['withscores' => true]); * $redis->zInter(['TNG', 'DS9'], NULL, ['withscores' => true, 'aggregate' => 'max']); */ public function zinter(array $keys, ?array $weights = null, ?array $options = null): Redis|array|false {} /** * Similar to ZINTER but instead of returning the intersected values, this command returns the * cardinality of the intersected set. * @see https://redis.io/commands/zintercard * @see https://redis.io/commands/zinter * @see Redis::zinter() * @param array $keys One ore more sorted set key names. * @param int $limit An optional upper bound on the returned cardinality. If set to a value * greater than zero, Redis will stop processing the intersection once the * resulting cardinality reaches this limit. * @return Redis|int|false The cardinality of the intersection or false on failure. * @example * $redis->zAdd('zs1', 1, 'one', 2, 'two', 3, 'three', 4, 'four'); * $redis->zAdd('zs2', 2, 'two', 4, 'four'); * $redis->zInterCard(['zs1', 'zs2']); */ public function zintercard(array $keys, int $limit = -1): Redis|int|false {} /** * Compute the intersection of one ore more sorted sets storing the result in a new sorted set. * @param string $dst The destination sorted set to store the intersected values. * @param array $keys One ore more sorted set key names. * @param array|null $weights An optional array of floats to weight each passed input set. * @param string|null $aggregate An optional aggregation method to use. * 'SUM' - Store sum of all intersected members (this is the default). * 'MIN' - Store minimum value for each intersected member. * 'MAX' - Store maximum value for each intersected member. * @return Redis|int|false The total number of members writtern to the destination set or false on failure. * @see https://redis.io/commands/zinterstore * @see https://redis.io/commands/zinter * @example * $redis->zAdd('zs1', 3, 'apples', 2, 'pears'); * $redis->zAdd('zs2', 4, 'pears', 3, 'bananas'); * $redis->zAdd('zs3', 2, 'figs', 3, 'pears'); * $redis->zInterStore('fruit-sum', ['zs1', 'zs2', 'zs3']); * $redis->zInterStore('fruit-max', ['zs1', 'zs2', 'zs3'], NULL, 'MAX'); */ public function zinterstore(string $dst, array $keys, ?array $weights = null, ?string $aggregate = null): Redis|int|false {} /** * Scan the members of a sorted set incrementally, using a cursor * @param string $key The sorted set to scan. * @param int|null $iterator A reference to an iterator that should be initialized to NULL initially, that * will be updated after each subsequent call to ZSCAN. Once the iterator * has returned to zero the scan is complete * @param string|null $pattern An optional glob-style pattern that limits which members are returned during * the scanning process. * @param int $count A hint for Redis that tells it how many elements it should test before returning * from the call. The higher the more work Redis may do in any one given call to * ZSCAN potentially blocking for longer periods of time. * @return Redis|array|false An array of elements or false on failure. * @see https://redis.io/commands/zscan * @see https://redis.io/commands/scan * @see Redis::scan() * NOTE: See Redis::scan() for detailed example code on how to call SCAN like commands. */ public function zscan(string $key, ?int &$iterator, ?string $pattern = null, int $count = 0): Redis|array|false {} /** * Retrieve the union of one or more sorted sets * @param array $keys One ore more sorted set key names * @param array|null $weights An optional array with floating point weights used when performing the union. * Note that if this argument is passed, it must contain the same number of * elements as the $keys array. * @param array|null $options An array that modifies how this command functions. * * $options = [ * # By default when members exist in more than one set Redis will SUM * # total score for each match. Instead, it can return the AVG, MIN, * # or MAX value based on this option. * 'AGGREGATE' => 'sum' | 'min' | 'max' * # Whether Redis should also return each members aggregated score. * 'WITHSCORES' => true | false * ] * * @return Redis|array|false The union of each sorted set or false on failure * @example * $redis->del('store1', 'store2', 'store3'); * $redis->zAdd('store1', 1, 'apples', 3, 'pears', 6, 'bananas'); * $redis->zAdd('store2', 3, 'apples', 5, 'coconuts', 2, 'bananas'); * $redis->zAdd('store3', 2, 'bananas', 6, 'apples', 4, 'figs'); * $redis->zUnion(['store1', 'store2', 'store3'], NULL, ['withscores' => true]); * $redis->zUnion(['store1', 'store3'], [2, .5], ['withscores' => true]); * $redis->zUnion(['store1', 'store3'], [2, .5], ['withscores' => true, 'aggregate' => 'MIN']); */ public function zunion(array $keys, ?array $weights = null, ?array $options = null): Redis|array|false {} /** * Perform a union on one or more Redis sets and store the result in a destination sorted set. * @param string $dst The destination set to store the union. * @param array $keys One or more input keys on which to perform our union. * @param array|null $weights An optional weights array used to weight each input set. * @param string|null $aggregate An optional modifier in how Redis will combine duplicate members. * Valid: 'MIN', 'MAX', 'SUM'. * @return Redis|int|false The number of members stored in the destination set or false on failure. * @see https://redis.io/commands/zunionstore * @see Redis::zunion() * @example * $redis->zAdd('zs1', 1, 'one', 3, 'three'); * $redis->zAdd('zs1', 2, 'two', 4, 'four'); * $redis->zadd('zs3', 1, 'one', 7, 'five'); * $redis->zUnionStore('dst', ['zs1', 'zs2', 'zs3']); */ public function zunionstore(string $dst, array $keys, ?array $weights = null, ?string $aggregate = null): Redis|int|false {} } class RedisException extends RuntimeException {} * $redis->info(); * */ public function info(): bool|array {} } * @link https://github.com/zgb7mtr/phpredis_cluster_phpdoc * * @method mixed eval($script, $args = array(), $numKeys = 0) */ class RedisCluster { public const AFTER = 'after'; public const BEFORE = 'before'; /** * Options */ public const OPT_SERIALIZER = 1; public const OPT_PREFIX = 2; public const OPT_READ_TIMEOUT = 3; public const OPT_SCAN = 4; public const OPT_SLAVE_FAILOVER = 5; /** * Cluster options */ public const FAILOVER_NONE = 0; public const FAILOVER_ERROR = 1; public const FAILOVER_DISTRIBUTE = 2; public const FAILOVER_DISTRIBUTE_SLAVES = 3; /** * SCAN options */ public const SCAN_NORETRY = 0; public const SCAN_RETRY = 1; /** * @since 5.3.0 */ public const SCAN_PREFIX = 2; /** * @since 5.3.0 */ public const SCAN_NOPREFIX = 3; /** * Serializers */ public const SERIALIZER_NONE = 0; public const SERIALIZER_PHP = 1; public const SERIALIZER_IGBINARY = 2; public const SERIALIZER_MSGPACK = 3; public const SERIALIZER_JSON = 4; /** * Multi */ public const ATOMIC = 0; public const MULTI = 1; public const PIPELINE = 2; /** * Type */ public const REDIS_NOT_FOUND = 0; public const REDIS_STRING = 1; public const REDIS_SET = 2; public const REDIS_LIST = 3; public const REDIS_ZSET = 4; public const REDIS_HASH = 5; /** * Creates a Redis Cluster client * * @param string|null $name * @param array|null $seeds * @param int|float $timeout * @param int|float $readTimeout * @param bool $persistent * @param mixed $auth * @param array|null $context * @throws RedisClusterException * * @example *
     * // Declaring a cluster with an array of seeds
     * $redisCluster = new RedisCluster(null,['127.0.0.1:6379']);
     *
     * // Loading a cluster configuration by name
     * // In order to load a named array, one must first define the seed nodes in redis.ini.
     * // The following lines would define the cluster 'mycluster', and be loaded automatically by phpredis.
     *
     * // # In redis.ini
     * // redis.clusters.seeds = "mycluster[]=localhost:7000&test[]=localhost:7001"
     * // redis.clusters.timeout = "mycluster=5"
     * // redis.clusters.read_timeout = "mycluster=10"
     * // redis.clusters.auth = "mycluster=password" OR ['user' => 'foo', 'pass' => 'bar] as example
     *
     * //Then, this cluster can be loaded by doing the following
     *
     * $redisClusterPro = new RedisCluster('mycluster');
     * $redisClusterDev = new RedisCluster('test');
     * 
*/ public function __construct($name, $seeds = null, $timeout = null, $readTimeout = null, $persistent = false, $auth = null, $context = null) {} /** * Disconnects from the RedisCluster instance, except when pconnect is used. */ public function close() {} /** * Get the value related to the specified key * * @param string $key * * @return string|false If key didn't exist, FALSE is returned. Otherwise, the value related to this key is * returned. * * @link https://redis.io/commands/get * @example *
     * $redisCluster->get('key');
     * 
*/ public function get($key) {} /** * Set the string value in argument as value of the key. * * @since If you're using Redis >= 2.6.12, you can pass extended options as explained in example * * @param string $key * @param string $value * @param int|array $timeout If you pass an integer, phpredis will redirect to SETEX, and will try to use Redis * >= 2.6.12 extended options if you pass an array with valid values. * * @return bool TRUE if the command is successful. * * @link https://redis.io/commands/set * @example *
     * // Simple key -> value set
     * $redisCluster->set('key', 'value');
     *
     * // Will redirect, and actually make an SETEX call
     * $redisCluster->set('key','value', 10);
     *
     * // Will set the key, if it doesn't exist, with a ttl of 10 seconds
     * $redisCluster->set('key', 'value', Array('nx', 'ex'=>10));
     *
     * // Will set a key, if it does exist, with a ttl of 1000 milliseconds
     * $redisCluster->set('key', 'value', Array('xx', 'px'=>1000));
     * 
*/ public function set($key, $value, $timeout = null) {} /** * Returns the values of all specified keys. * * For every key that does not hold a string value or does not exist, * the special value false is returned. Because of this, the operation never fails. * * @param array $array * * @return array * * @link https://redis.io/commands/mget * @example *
     * $redisCluster->del('x', 'y', 'z', 'h');    // remove x y z
     * $redisCluster->mset(array('x' => 'a', 'y' => 'b', 'z' => 'c'));
     * $redisCluster->hset('h', 'field', 'value');
     * var_dump($redisCluster->mget(array('x', 'y', 'z', 'h')));
     * // Output:
     * // array(3) {
     * // [0]=>
     * // string(1) "a"
     * // [1]=>
     * // string(1) "b"
     * // [2]=>
     * // string(1) "c"
     * // [3]=>
     * // bool(false)
     * // }
     * 
*/ public function mget(array $array) {} /** * Sets multiple key-value pairs in one atomic command. * MSETNX only returns TRUE if all the keys were set (see SETNX). * * @param array $array Pairs: array(key => value, ...) * * @return bool TRUE in case of success, FALSE in case of failure. * @link https://redis.io/commands/mset * @example *
     * $redisCluster->mset(array('key0' => 'value0', 'key1' => 'value1'));
     * var_dump($redisCluster->get('key0'));
     * var_dump($redisCluster->get('key1'));
     * // Output:
     * // string(6) "value0"
     * // string(6) "value1"
     * 
*/ public function mset(array $array) {} /** * @see mset() * * @param array $array * * @return int 1 (if the keys were set) or 0 (no key was set) * @link https://redis.io/commands/msetnx */ public function msetnx(array $array) {} /** * Remove specified keys. * * @param int|string|array $key1 An array of keys, or an undefined number of parameters, each a key: key1 key2 key3 * ... keyN * @param int|string ...$otherKeys * * @return int Number of keys deleted. * @link https://redis.io/commands/del * @example *
     * $redisCluster->set('key1', 'val1');
     * $redisCluster->set('key2', 'val2');
     * $redisCluster->set('key3', 'val3');
     * $redisCluster->set('key4', 'val4');
     * $redisCluster->del('key1', 'key2');          // return 2
     * $redisCluster->del(array('key3', 'key4'));   // return 2
     * 
*/ public function del($key1, ...$otherKeys) {} /** * Set the string value in argument as value of the key, with a time to live. * * @param string $key * @param int $ttl * @param mixed $value * * @return bool TRUE if the command is successful. * @link https://redis.io/commands/setex * @example *
     * $redisCluster->setex('key', 3600, 'value'); // sets key → value, with 1h TTL.
     * 
*/ public function setex($key, $ttl, $value) {} /** * PSETEX works exactly like SETEX with the sole difference that the expire time is specified in milliseconds * instead of seconds. * * @param string $key * @param int $ttl * @param string $value * * @return bool TRUE if the command is successful. * @link https://redis.io/commands/psetex * @example *
     * $redisCluster->psetex('key', 1000, 'value'); // sets key → value, with 1s TTL.
     * 
*/ public function psetex($key, $ttl, $value) {} /** * Set the string value in argument as value of the key if the key doesn't already exist in the database. * * @param string $key * @param string $value * * @return bool TRUE in case of success, FALSE in case of failure. * @link https://redis.io/commands/setnx * @example *
     * $redisCluster->setnx('key', 'value');   // return TRUE
     * $redisCluster->setnx('key', 'value');   // return FALSE
     * 
*/ public function setnx($key, $value) {} /** * Sets a value and returns the previous entry at that key. * * @param string $key * @param string $value * * @return string A string, the previous value located at this key. * @link https://redis.io/commands/getset * @example *
     * $redisCluster->set('x', '42');
     * $exValue = $redisCluster->getSet('x', 'lol');   // return '42', replaces x by 'lol'
     * $newValue = $redisCluster->get('x');            // return 'lol'
     * 
*/ public function getSet($key, $value) {} /** * Verify if the specified key exists. * * @param string $key * * @return bool If the key exists, return TRUE, otherwise return FALSE. * @link https://redis.io/commands/exists * @example *
     * $redisCluster->set('key', 'value');
     * $redisCluster->exists('key');               //  TRUE
     * $redisCluster->exists('NonExistingKey');    // FALSE
     * 
*/ public function exists($key) {} /** * Returns the keys that match a certain pattern. * * @param string $pattern pattern, using '*' as a wildcard. * * @return array of STRING: The keys that match a certain pattern. * @link https://redis.io/commands/keys * @example *
     * $allKeys = $redisCluster->keys('*');   // all keys will match this.
     * $keyWithUserPrefix = $redisCluster->keys('user*');
     * 
*/ public function keys($pattern) {} /** * Returns the type of data pointed by a given key. * * @param string $key * * @return int * * Depending on the type of the data pointed by the key, * this method will return the following value: * - string: RedisCluster::REDIS_STRING * - set: RedisCluster::REDIS_SET * - list: RedisCluster::REDIS_LIST * - zset: RedisCluster::REDIS_ZSET * - hash: RedisCluster::REDIS_HASH * - other: RedisCluster::REDIS_NOT_FOUND * @link https://redis.io/commands/type * @example $redisCluster->type('key'); */ public function type($key) {} /** * Returns and removes the first element of the list. * * @param string $key * * @return string|false if command executed successfully BOOL FALSE in case of failure (empty list) * @link https://redis.io/commands/lpop * @example *
     * $redisCluster->rPush('key1', 'A');
     * $redisCluster->rPush('key1', 'B');
     * $redisCluster->rPush('key1', 'C');
     * var_dump( $redisCluster->lRange('key1', 0, -1) );
     * // Output:
     * // array(3) {
     * //   [0]=> string(1) "A"
     * //   [1]=> string(1) "B"
     * //   [2]=> string(1) "C"
     * // }
     * $redisCluster->lPop('key1');
     * var_dump( $redisCluster->lRange('key1', 0, -1) );
     * // Output:
     * // array(2) {
     * //   [0]=> string(1) "B"
     * //   [1]=> string(1) "C"
     * // }
     * 
*/ public function lPop($key) {} /** * Returns and removes the last element of the list. * * @param string $key * * @return string|false if command executed successfully BOOL FALSE in case of failure (empty list) * @link https://redis.io/commands/rpop * @example *
     * $redisCluster->rPush('key1', 'A');
     * $redisCluster->rPush('key1', 'B');
     * $redisCluster->rPush('key1', 'C');
     * var_dump( $redisCluster->lRange('key1', 0, -1) );
     * // Output:
     * // array(3) {
     * //   [0]=> string(1) "A"
     * //   [1]=> string(1) "B"
     * //   [2]=> string(1) "C"
     * // }
     * $redisCluster->rPop('key1');
     * var_dump( $redisCluster->lRange('key1', 0, -1) );
     * // Output:
     * // array(2) {
     * //   [0]=> string(1) "A"
     * //   [1]=> string(1) "B"
     * // }
     * 
*/ public function rPop($key) {} /** * Set the list at index with the new value. * * @param string $key * @param int $index * @param string $value * * @return bool TRUE if the new value is setted. FALSE if the index is out of range, or data type identified by key * is not a list. * @link https://redis.io/commands/lset * @example *
     * $redisCluster->rPush('key1', 'A');
     * $redisCluster->rPush('key1', 'B');
     * $redisCluster->rPush('key1', 'C');  // key1 => [ 'A', 'B', 'C' ]
     * $redisCluster->lGet('key1', 0);     // 'A'
     * $redisCluster->lSet('key1', 0, 'X');
     * $redisCluster->lGet('key1', 0);     // 'X'
     * 
*/ public function lSet($key, $index, $value) {} /** * Removes and returns a random element from the set value at Key. * * @param string $key * * @return string "popped" value * bool FALSE if set identified by key is empty or doesn't exist. * @link https://redis.io/commands/spop * @example *
     * $redisCluster->sAdd('key1' , 'set1');
     * $redisCluster->sAdd('key1' , 'set2');
     * $redisCluster->sAdd('key1' , 'set3');
     * var_dump($redisCluster->sMembers('key1'));// 'key1' => {'set3', 'set1', 'set2'}
     * $redisCluster->sPop('key1');// 'set1'
     * var_dump($redisCluster->sMembers('key1'));// 'key1' => {'set3', 'set2'}
     * $redisCluster->sPop('key1');// 'set3',
     * var_dump($redisCluster->sMembers('key1'));// 'key1' => {'set2'}
     * 
*/ public function sPop($key) {} /** * Adds the string values to the head (left) of the list. Creates the list if the key didn't exist. * If the key exists and is not a list, FALSE is returned. * * @param string $key * @param string $value1 String, value to push in key * @param string $value2 Optional * @param string $valueN Optional * * @return int|false The new length of the list in case of success, FALSE in case of Failure. * @link https://redis.io/commands/lpush * @example *
     * $redisCluster->lPush('l', 'v1', 'v2', 'v3', 'v4')   // int(4)
     * var_dump( $redisCluster->lRange('l', 0, -1) );
     * //// Output:
     * // array(4) {
     * //   [0]=> string(2) "v4"
     * //   [1]=> string(2) "v3"
     * //   [2]=> string(2) "v2"
     * //   [3]=> string(2) "v1"
     * // }
     * 
*/ public function lPush($key, $value1, $value2 = null, $valueN = null) {} /** * Adds the string values to the tail (right) of the list. Creates the list if the key didn't exist. * If the key exists and is not a list, FALSE is returned. * * @param string $key * @param string $value1 String, value to push in key * @param string $value2 Optional * @param string $valueN Optional * * @return int|false The new length of the list in case of success, FALSE in case of Failure. * @link https://redis.io/commands/rpush * @example *
     * $redisCluster->rPush('r', 'v1', 'v2', 'v3', 'v4');    // int(4)
     * var_dump( $redisCluster->lRange('r', 0, -1) );
     * //// Output:
     * // array(4) {
     * //   [0]=> string(2) "v1"
     * //   [1]=> string(2) "v2"
     * //   [2]=> string(2) "v3"
     * //   [3]=> string(2) "v4"
     * // }
     * 
*/ public function rPush($key, $value1, $value2 = null, $valueN = null) {} /** * BLPOP is a blocking list pop primitive. * It is the blocking version of LPOP because it blocks the connection when * there are no elements to pop from any of the given lists. * An element is popped from the head of the first list that is non-empty, * with the given keys being checked in the order that they are given. * * @param array $keys Array containing the keys of the lists * Or STRING Key1 STRING Key2 STRING Key3 ... STRING Keyn * @param int $timeout Timeout * * @return array array('listName', 'element') * @link https://redis.io/commands/blpop * @example *
     * // Non blocking feature
     * $redisCluster->lPush('key1', 'A');
     * $redisCluster->del('key2');
     *
     * $redisCluster->blPop('key1', 'key2', 10); // array('key1', 'A')
     * // OR
     * $redisCluster->blPop(array('key1', 'key2'), 10); // array('key1', 'A')
     *
     * $redisCluster->brPop('key1', 'key2', 10); // array('key1', 'A')
     * // OR
     * $redisCluster->brPop(array('key1', 'key2'), 10); // array('key1', 'A')
     *
     * // Blocking feature
     *
     * // process 1
     * $redisCluster->del('key1');
     * $redisCluster->blPop('key1', 10);
     * // blocking for 10 seconds
     *
     * // process 2
     * $redisCluster->lPush('key1', 'A');
     *
     * // process 1
     * // array('key1', 'A') is returned
     * 
*/ public function blPop(array $keys, $timeout) {} /** * BRPOP is a blocking list pop primitive. * It is the blocking version of RPOP because it blocks the connection when * there are no elements to pop from any of the given lists. * An element is popped from the tail of the first list that is non-empty, * with the given keys being checked in the order that they are given. * See the BLPOP documentation(https://redis.io/commands/blpop) for the exact semantics, * since BRPOP is identical to BLPOP with the only difference being that * it pops elements from the tail of a list instead of popping from the head. * * @param array $keys Array containing the keys of the lists * Or STRING Key1 STRING Key2 STRING Key3 ... STRING Keyn * @param int $timeout Timeout * * @return array array('listName', 'element') * @link https://redis.io/commands/brpop * @example *
     * // Non blocking feature
     * $redisCluster->lPush('key1', 'A');
     * $redisCluster->del('key2');
     *
     * $redisCluster->blPop('key1', 'key2', 10); // array('key1', 'A')
     * // OR
     * $redisCluster->blPop(array('key1', 'key2'), 10); // array('key1', 'A')
     *
     * $redisCluster->brPop('key1', 'key2', 10); // array('key1', 'A')
     * // OR
     * $redisCluster->brPop(array('key1', 'key2'), 10); // array('key1', 'A')
     *
     * // Blocking feature
     *
     * // process 1
     * $redisCluster->del('key1');
     * $redisCluster->blPop('key1', 10);
     * // blocking for 10 seconds
     *
     * // process 2
     * $redisCluster->lPush('key1', 'A');
     *
     * // process 1
     * // array('key1', 'A') is returned
     * 
*/ public function brPop(array $keys, $timeout) {} /** * Adds the string value to the tail (right) of the list if the ist exists. FALSE in case of Failure. * * @param string $key * @param string $value String, value to push in key * * @return int|false The new length of the list in case of success, FALSE in case of Failure. * @link https://redis.io/commands/rpushx * @example *
     * $redisCluster->del('key1');
     * $redisCluster->rPushx('key1', 'A'); // returns 0
     * $redisCluster->rPush('key1', 'A'); // returns 1
     * $redisCluster->rPushx('key1', 'B'); // returns 2
     * $redisCluster->rPushx('key1', 'C'); // returns 3
     * // key1 now points to the following list: [ 'A', 'B', 'C' ]
     * 
*/ public function rPushx($key, $value) {} /** * Adds the string value to the head (left) of the list if the list exists. * * @param string $key * @param string $value String, value to push in key * * @return int|false The new length of the list in case of success, FALSE in case of Failure. * @link https://redis.io/commands/lpushx * @example *
     * $redisCluster->del('key1');
     * $redisCluster->lPushx('key1', 'A');     // returns 0
     * $redisCluster->lPush('key1', 'A');      // returns 1
     * $redisCluster->lPushx('key1', 'B');     // returns 2
     * $redisCluster->lPushx('key1', 'C');     // returns 3
     * // key1 now points to the following list: [ 'C', 'B', 'A' ]
     * 
*/ public function lPushx($key, $value) {} /** * Insert value in the list before or after the pivot value. the parameter options * specify the position of the insert (before or after). If the list didn't exists, * or the pivot didn't exists, the value is not inserted. * * @param string $key * @param string $position RedisCluster::BEFORE | RedisCluster::AFTER * @param string $pivot * @param string $value * * @return int The number of the elements in the list, -1 if the pivot didn't exists. * @link https://redis.io/commands/linsert * @example *
     * $redisCluster->del('key1');
     * $redisCluster->lInsert('key1', RedisCluster::AFTER, 'A', 'X');    // 0
     *
     * $redisCluster->lPush('key1', 'A');
     * $redisCluster->lPush('key1', 'B');
     * $redisCluster->lPush('key1', 'C');
     *
     * $redisCluster->lInsert('key1', RedisCluster::BEFORE, 'C', 'X');   // 4
     * $redisCluster->lRange('key1', 0, -1);                      // array('X', 'C', 'B', 'A')
     *
     * $redisCluster->lInsert('key1', RedisCluster::AFTER, 'C', 'Y');    // 5
     * $redisCluster->lRange('key1', 0, -1);                      // array('X', 'C', 'Y', 'B', 'A')
     *
     * $redisCluster->lInsert('key1', RedisCluster::AFTER, 'W', 'value'); // -1
     * 
*/ public function lInsert($key, $position, $pivot, $value) {} /** * Return the specified element of the list stored at the specified key. * 0 the first element, 1 the second ... -1 the last element, -2 the penultimate ... * Return FALSE in case of a bad index or a key that doesn't point to a list. * * @param string $key * @param int $index * * @return string|false the element at this index * Bool FALSE if the key identifies a non-string data type, or no value corresponds to this index in the list Key. * @link https://redis.io/commands/lindex * @example *
     * $redisCluster->rPush('key1', 'A');
     * $redisCluster->rPush('key1', 'B');
     * $redisCluster->rPush('key1', 'C');  // key1 => [ 'A', 'B', 'C' ]
     * $redisCluster->lGet('key1', 0);     // 'A'
     * $redisCluster->lGet('key1', -1);    // 'C'
     * $redisCluster->lGet('key1', 10);    // `FALSE`
     * 
*/ public function lIndex($key, $index) {} /** * Removes the first count occurrences of the value element from the list. * If count is zero, all the matching elements are removed. If count is negative, * elements are removed from tail to head. * * @param string $key * @param string $value * @param int $count * * @return int the number of elements to remove * bool FALSE if the value identified by key is not a list. * @link https://redis.io/commands/lrem * @example *
     * $redisCluster->lPush('key1', 'A');
     * $redisCluster->lPush('key1', 'B');
     * $redisCluster->lPush('key1', 'C');
     * $redisCluster->lPush('key1', 'A');
     * $redisCluster->lPush('key1', 'A');
     *
     * $redisCluster->lRange('key1', 0, -1);   // array('A', 'A', 'C', 'B', 'A')
     * $redisCluster->lRem('key1', 'A', 2);    // 2
     * $redisCluster->lRange('key1', 0, -1);   // array('C', 'B', 'A')
     * 
*/ public function lRem($key, $value, $count) {} /** * A blocking version of rpoplpush, with an integral timeout in the third parameter. * * @param string $srcKey * @param string $dstKey * @param int $timeout * * @return string|false The element that was moved in case of success, FALSE in case of timeout. * @link https://redis.io/commands/brpoplpush */ public function brpoplpush($srcKey, $dstKey, $timeout) {} /** * Pops a value from the tail of a list, and pushes it to the front of another list. * Also return this value. * * @since redis >= 1.2 * * @param string $srcKey * @param string $dstKey * * @return string|false The element that was moved in case of success, FALSE in case of failure. * @link https://redis.io/commands/rpoplpush * @example *
     * $redisCluster->del('x', 'y');
     *
     * $redisCluster->lPush('x', 'abc');
     * $redisCluster->lPush('x', 'def');
     * $redisCluster->lPush('y', '123');
     * $redisCluster->lPush('y', '456');
     *
     * // move the last of x to the front of y.
     * var_dump($redisCluster->rpoplpush('x', 'y'));
     * var_dump($redisCluster->lRange('x', 0, -1));
     * var_dump($redisCluster->lRange('y', 0, -1));
     *
     * ////Output:
     * //
     * //string(3) "abc"
     * //array(1) {
     * //  [0]=>
     * //  string(3) "def"
     * //}
     * //array(3) {
     * //  [0]=>
     * //  string(3) "abc"
     * //  [1]=>
     * //  string(3) "456"
     * //  [2]=>
     * //  string(3) "123"
     * //}
     * 
*/ public function rpoplpush($srcKey, $dstKey) {} /** * Returns the size of a list identified by Key. If the list didn't exist or is empty, * the command returns 0. If the data type identified by Key is not a list, the command return FALSE. * * @param string $key * * @return int The size of the list identified by Key exists. * bool FALSE if the data type identified by Key is not list * @link https://redis.io/commands/llen * @example *
     * $redisCluster->rPush('key1', 'A');
     * $redisCluster->rPush('key1', 'B');
     * $redisCluster->rPush('key1', 'C');  // key1 => [ 'A', 'B', 'C' ]
     * $redisCluster->lLen('key1');       // 3
     * $redisCluster->rPop('key1');
     * $redisCluster->lLen('key1');       // 2
     * 
*/ public function lLen($key) {} /** * Returns the set cardinality (number of elements) of the set stored at key. * * @param string $key * * @return int the cardinality (number of elements) of the set, or 0 if key does not exist. * @link https://redis.io/commands/scard * @example *
     * $redisCluster->sAdd('key1' , 'set1');
     * $redisCluster->sAdd('key1' , 'set2');
     * $redisCluster->sAdd('key1' , 'set3');   // 'key1' => {'set1', 'set2', 'set3'}
     * $redisCluster->sCard('key1');           // 3
     * $redisCluster->sCard('keyX');           // 0
     * 
*/ public function sCard($key) {} /** * Returns all the members of the set value stored at key. * This has the same effect as running SINTER with one argument key. * * @param string $key * * @return array All elements of the set. * @link https://redis.io/commands/smembers * @example *
     * $redisCluster->del('s');
     * $redisCluster->sAdd('s', 'a');
     * $redisCluster->sAdd('s', 'b');
     * $redisCluster->sAdd('s', 'a');
     * $redisCluster->sAdd('s', 'c');
     * var_dump($redisCluster->sMembers('s'));
     *
     * ////Output:
     * //
     * //array(3) {
     * //  [0]=>
     * //  string(1) "b"
     * //  [1]=>
     * //  string(1) "c"
     * //  [2]=>
     * //  string(1) "a"
     * //}
     * // The order is random and corresponds to redis' own internal representation of the set structure.
     * 
*/ public function sMembers($key) {} /** * Returns if member is a member of the set stored at key. * * @param string $key * @param string $value * * @return bool TRUE if value is a member of the set at key key, FALSE otherwise. * @link https://redis.io/commands/sismember * @example *
     * $redisCluster->sAdd('key1' , 'set1');
     * $redisCluster->sAdd('key1' , 'set2');
     * $redisCluster->sAdd('key1' , 'set3'); // 'key1' => {'set1', 'set2', 'set3'}
     *
     * $redisCluster->sIsMember('key1', 'set1'); // TRUE
     * $redisCluster->sIsMember('key1', 'setX'); // FALSE
     * 
*/ public function sIsMember($key, $value) {} /** * Adds a values to the set value stored at key. * If this value is already in the set, FALSE is returned. * * @param string $key Required key * @param mixed $value1 Required value * @param mixed $value2 Optional value * @param mixed $valueN Optional value * * @return int|false The number of elements added to the set * @link https://redis.io/commands/sadd * @example *
     * $redisCluster->sAdd('k', 'v1');                // int(1)
     * $redisCluster->sAdd('k', 'v1', 'v2', 'v3');    // int(2)
     * 
*/ public function sAdd($key, $value1, $value2 = null, $valueN = null) {} /** * Adds a values to the set value stored at key. * If this value is already in the set, FALSE is returned. * * @param string $key Required key * @param array $valueArray * * @return int|false The number of elements added to the set * @example *
     * $redisCluster->sAddArray('k', ['v1', 'v2', 'v3']);
     * //This is a feature in php only. Same as $redisCluster->sAdd('k', 'v1', 'v2', 'v3');
     * 
*/ public function sAddArray($key, array $valueArray) {} /** * Removes the specified members from the set value stored at key. * * @param string $key * @param string $member1 * @param string $member2 * @param string $memberN * * @return int The number of elements removed from the set. * @link https://redis.io/commands/srem * @example *
     * var_dump( $redisCluster->sAdd('k', 'v1', 'v2', 'v3') );    // int(3)
     * var_dump( $redisCluster->sRem('k', 'v2', 'v3') );          // int(2)
     * var_dump( $redisCluster->sMembers('k') );
     * //// Output:
     * // array(1) {
     * //   [0]=> string(2) "v1"
     * // }
     * 
*/ public function sRem($key, $member1, $member2 = null, $memberN = null) {} /** * Performs the union between N sets and returns it. * * @param string $key1 Any number of keys corresponding to sets in redis. * @param string $key2 ... * @param string $keyN ... * * @return array of strings: The union of all these sets. * @link https://redis.io/commands/sunionstore * @example *
     * $redisCluster->del('s0', 's1', 's2');
     *
     * $redisCluster->sAdd('s0', '1');
     * $redisCluster->sAdd('s0', '2');
     * $redisCluster->sAdd('s1', '3');
     * $redisCluster->sAdd('s1', '1');
     * $redisCluster->sAdd('s2', '3');
     * $redisCluster->sAdd('s2', '4');
     *
     * var_dump($redisCluster->sUnion('s0', 's1', 's2'));
     *
     * //// Output:
     * //
     * //array(4) {
     * //  [0]=>
     * //  string(1) "3"
     * //  [1]=>
     * //  string(1) "4"
     * //  [2]=>
     * //  string(1) "1"
     * //  [3]=>
     * //  string(1) "2"
     * //}
     * 
*/ public function sUnion($key1, $key2, $keyN = null) {} /** * Performs the same action as sUnion, but stores the result in the first key * * @param string $dstKey the key to store the diff into. * @param string $key1 Any number of keys corresponding to sets in redis. * @param string $key2 ... * @param string $keyN ... * * @return int Any number of keys corresponding to sets in redis. * @link https://redis.io/commands/sunionstore * @example *
     * $redisCluster->del('s0', 's1', 's2');
     *
     * $redisCluster->sAdd('s0', '1');
     * $redisCluster->sAdd('s0', '2');
     * $redisCluster->sAdd('s1', '3');
     * $redisCluster->sAdd('s1', '1');
     * $redisCluster->sAdd('s2', '3');
     * $redisCluster->sAdd('s2', '4');
     *
     * var_dump($redisCluster->sUnionStore('dst', 's0', 's1', 's2'));
     * var_dump($redisCluster->sMembers('dst'));
     *
     * //// Output:
     * //
     * //int(4)
     * //array(4) {
     * //  [0]=>
     * //  string(1) "3"
     * //  [1]=>
     * //  string(1) "4"
     * //  [2]=>
     * //  string(1) "1"
     * //  [3]=>
     * //  string(1) "2"
     * //}
     * 
*/ public function sUnionStore($dstKey, $key1, $key2, $keyN = null) {} /** * Returns the members of a set resulting from the intersection of all the sets * held at the specified keys. If just a single key is specified, then this command * produces the members of this set. If one of the keys is missing, FALSE is returned. * * @param string $key1 keys identifying the different sets on which we will apply the intersection. * @param string $key2 ... * @param string $keyN ... * * @return array contain the result of the intersection between those keys. * If the intersection between the different sets is empty, the return value will be empty array. * @link https://redis.io/commands/sinterstore * @example *
     * $redisCluster->sAdd('key1', 'val1');
     * $redisCluster->sAdd('key1', 'val2');
     * $redisCluster->sAdd('key1', 'val3');
     * $redisCluster->sAdd('key1', 'val4');
     *
     * $redisCluster->sAdd('key2', 'val3');
     * $redisCluster->sAdd('key2', 'val4');
     *
     * $redisCluster->sAdd('key3', 'val3');
     * $redisCluster->sAdd('key3', 'val4');
     *
     * var_dump($redisCluster->sInter('key1', 'key2', 'key3'));
     *
     * // Output:
     * //
     * //array(2) {
     * //  [0]=>
     * //  string(4) "val4"
     * //  [1]=>
     * //  string(4) "val3"
     * //}
     * 
*/ public function sInter($key1, $key2, $keyN = null) {} /** * Performs a sInter command and stores the result in a new set. * * @param string $dstKey the key to store the diff into. * @param string $key1 are intersected as in sInter. * @param string $key2 ... * @param string $keyN ... * * @return int|false The cardinality of the resulting set, or FALSE in case of a missing key. * @link https://redis.io/commands/sinterstore * @example *
     * $redisCluster->sAdd('key1', 'val1');
     * $redisCluster->sAdd('key1', 'val2');
     * $redisCluster->sAdd('key1', 'val3');
     * $redisCluster->sAdd('key1', 'val4');
     *
     * $redisCluster->sAdd('key2', 'val3');
     * $redisCluster->sAdd('key2', 'val4');
     *
     * $redisCluster->sAdd('key3', 'val3');
     * $redisCluster->sAdd('key3', 'val4');
     *
     * var_dump($redisCluster->sInterStore('output', 'key1', 'key2', 'key3'));
     * var_dump($redisCluster->sMembers('output'));
     *
     * //// Output:
     * //
     * //int(2)
     * //array(2) {
     * //  [0]=>
     * //  string(4) "val4"
     * //  [1]=>
     * //  string(4) "val3"
     * //}
     * 
*/ public function sInterStore($dstKey, $key1, $key2, $keyN = null) {} /** * Performs the difference between N sets and returns it. * * @param string $key1 Any number of keys corresponding to sets in redis. * @param string $key2 ... * @param string $keyN ... * * @return array of strings: The difference of the first set will all the others. * @link https://redis.io/commands/sdiff * @example *
     * $redisCluster->del('s0', 's1', 's2');
     *
     * $redisCluster->sAdd('s0', '1');
     * $redisCluster->sAdd('s0', '2');
     * $redisCluster->sAdd('s0', '3');
     * $redisCluster->sAdd('s0', '4');
     *
     * $redisCluster->sAdd('s1', '1');
     * $redisCluster->sAdd('s2', '3');
     *
     * var_dump($redisCluster->sDiff('s0', 's1', 's2'));
     *
     * //// Output:
     * //
     * //array(2) {
     * //  [0]=>
     * //  string(1) "4"
     * //  [1]=>
     * //  string(1) "2"
     * //}
     * 
*/ public function sDiff($key1, $key2, $keyN = null) {} /** * Performs the same action as sDiff, but stores the result in the first key * * @param string $dstKey the key to store the diff into. * @param string $key1 Any number of keys corresponding to sets in redis * @param string $key2 ... * @param string $keyN ... * * @return int|false The cardinality of the resulting set, or FALSE in case of a missing key. * @link https://redis.io/commands/sdiffstore * @example *
     * $redisCluster->del('s0', 's1', 's2');
     *
     * $redisCluster->sAdd('s0', '1');
     * $redisCluster->sAdd('s0', '2');
     * $redisCluster->sAdd('s0', '3');
     * $redisCluster->sAdd('s0', '4');
     *
     * $redisCluster->sAdd('s1', '1');
     * $redisCluster->sAdd('s2', '3');
     *
     * var_dump($redisCluster->sDiffStore('dst', 's0', 's1', 's2'));
     * var_dump($redisCluster->sMembers('dst'));
     *
     * //// Output:
     * //
     * //int(2)
     * //array(2) {
     * //  [0]=>
     * //  string(1) "4"
     * //  [1]=>
     * //  string(1) "2"
     * //}
     * 
*/ public function sDiffStore($dstKey, $key1, $key2, $keyN = null) {} /** * Returns a random element(s) from the set value at Key, without removing it. * * @param string $key * @param int $count [optional] * * @return string|array value(s) from the set * bool FALSE if set identified by key is empty or doesn't exist and count argument isn't passed. * @link https://redis.io/commands/srandmember * @example *
     * $redisCluster->sAdd('key1' , 'one');
     * $redisCluster->sAdd('key1' , 'two');
     * $redisCluster->sAdd('key1' , 'three');              // 'key1' => {'one', 'two', 'three'}
     *
     * var_dump( $redisCluster->sRandMember('key1') );     // 'key1' => {'one', 'two', 'three'}
     *
     * // string(5) "three"
     *
     * var_dump( $redisCluster->sRandMember('key1', 2) );  // 'key1' => {'one', 'two', 'three'}
     *
     * // array(2) {
     * //   [0]=> string(2) "one"
     * //   [1]=> string(2) "three"
     * // }
     * 
*/ public function sRandMember($key, $count = null) {} /** * Get the length of a string value. * * @param string $key * * @return int * @link https://redis.io/commands/strlen * @example *
     * $redisCluster->set('key', 'value');
     * $redisCluster->strlen('key'); // 5
     * 
*/ public function strlen($key) {} /** * Remove the expiration timer from a key. * * @param string $key * * @return bool TRUE if a timeout was removed, FALSE if the key didn’t exist or didn’t have an expiration timer. * @link https://redis.io/commands/persist * @example $redisCluster->persist('key'); */ public function persist($key) {} /** * Returns the remaining time to live of a key that has a timeout. * This introspection capability allows a Redis client to check how many seconds a given key will continue to be * part of the dataset. In Redis 2.6 or older the command returns -1 if the key does not exist or if the key exist * but has no associated expire. Starting with Redis 2.8 the return value in case of error changed: Returns -2 if * the key does not exist. Returns -1 if the key exists but has no associated expire. * * @param string $key * * @return int the time left to live in seconds. * @link https://redis.io/commands/ttl * @example $redisCluster->ttl('key'); */ public function ttl($key) {} /** * Returns the remaining time to live of a key that has an expire set, * with the sole difference that TTL returns the amount of remaining time in seconds while PTTL returns it in * milliseconds. In Redis 2.6 or older the command returns -1 if the key does not exist or if the key exist but has * no associated expire. Starting with Redis 2.8 the return value in case of error changed: Returns -2 if the key * does not exist. Returns -1 if the key exists but has no associated expire. * * @param string $key * * @return int the time left to live in milliseconds. * @link https://redis.io/commands/pttl * @example $redisCluster->pttl('key'); */ public function pttl($key) {} /** * Returns the cardinality of an ordered set. * * @param string $key * * @return int the set's cardinality * @link https://redis.io/commands/zsize * @example *
     * $redisCluster->zAdd('key', 0, 'val0');
     * $redisCluster->zAdd('key', 2, 'val2');
     * $redisCluster->zAdd('key', 10, 'val10');
     * $redisCluster->zCard('key');            // 3
     * 
*/ public function zCard($key) {} /** * Returns the number of elements of the sorted set stored at the specified key which have * scores in the range [start,end]. Adding a parenthesis before start or end excludes it * from the range. +inf and -inf are also valid limits. * * @param string $key * @param string $start * @param string $end * * @return int the size of a corresponding zRangeByScore. * @link https://redis.io/commands/zcount * @example *
     * $redisCluster->zAdd('key', 0, 'val0');
     * $redisCluster->zAdd('key', 2, 'val2');
     * $redisCluster->zAdd('key', 10, 'val10');
     * $redisCluster->zCount('key', 0, 3); // 2, corresponding to array('val0', 'val2')
     * 
*/ public function zCount($key, $start, $end) {} /** * Deletes the elements of the sorted set stored at the specified key which have scores in the range [start,end]. * * @param string $key * @param string $start double or "+inf" or "-inf" as a string * @param string $end double or "+inf" or "-inf" as a string * * @return int The number of values deleted from the sorted set * @link https://redis.io/commands/zremrangebyscore * @example *
     * $redisCluster->zAdd('key', 0, 'val0');
     * $redisCluster->zAdd('key', 2, 'val2');
     * $redisCluster->zAdd('key', 10, 'val10');
     * $redisCluster->zRemRangeByScore('key', '0', '3'); // 2
     * 
*/ public function zRemRangeByScore($key, $start, $end) {} /** * Returns the score of a given member in the specified sorted set. * * @param string $key * @param string $member * * @return float * @link https://redis.io/commands/zscore * @example *
     * $redisCluster->zAdd('key', 2.5, 'val2');
     * $redisCluster->zScore('key', 'val2'); // 2.5
     * 
*/ public function zScore($key, $member) {} /** * Adds the specified member with a given score to the sorted set stored at key. * * @param string $key Required key * @param float $score1 Required score * @param string $value1 Required value * @param float $score2 Optional score * @param string $value2 Optional value * @param float $scoreN Optional score * @param string $valueN Optional value * * @return int Number of values added * @link https://redis.io/commands/zadd * @example *
     * $redisCluster->zAdd('z', 1, 'v2', 2, 'v2', 3, 'v3', 4, 'v4' );  // int(3)
     * $redisCluster->zRem('z', 'v2', 'v3');                           // int(2)
     * var_dump( $redisCluster->zRange('z', 0, -1) );
     *
     * //// Output:
     * // array(1) {
     * //   [0]=> string(2) "v4"
     * // }
     * 
*/ public function zAdd($key, $score1, $value1, $score2 = null, $value2 = null, $scoreN = null, $valueN = null) {} /** * Increments the score of a member from a sorted set by a given amount. * * @param string $key * @param float $value (double) value that will be added to the member's score * @param string $member * * @return float the new value * @link https://redis.io/commands/zincrby * @example *
     * $redisCluster->del('key');
     * $redisCluster->zIncrBy('key', 2.5, 'member1');// key or member1 didn't exist, so member1's score is to 0 ;
     *                                              //before the increment and now has the value 2.5
     * $redisCluster->zIncrBy('key', 1, 'member1');    // 3.5
     * 
*/ public function zIncrBy($key, $value, $member) {} /** * Returns the length of a hash, in number of items * * @param string $key * * @return int|false the number of items in a hash, FALSE if the key doesn't exist or isn't a hash. * @link https://redis.io/commands/hlen * @example *
     * $redisCluster->del('h');
     * $redisCluster->hSet('h', 'key1', 'hello');
     * $redisCluster->hSet('h', 'key2', 'plop');
     * $redisCluster->hLen('h'); // returns 2
     * 
*/ public function hLen($key) {} /** * Returns the keys in a hash, as an array of strings. * * @param string $key * * @return array An array of elements, the keys of the hash. This works like PHP's array_keys(). * @link https://redis.io/commands/hkeys * @example *
     * $redisCluster->del('h');
     * $redisCluster->hSet('h', 'a', 'x');
     * $redisCluster->hSet('h', 'b', 'y');
     * $redisCluster->hSet('h', 'c', 'z');
     * $redisCluster->hSet('h', 'd', 't');
     * var_dump($redisCluster->hKeys('h'));
     *
     * //// Output:
     * //
     * // array(4) {
     * // [0]=>
     * // string(1) "a"
     * // [1]=>
     * // string(1) "b"
     * // [2]=>
     * // string(1) "c"
     * // [3]=>
     * // string(1) "d"
     * // }
     * // The order is random and corresponds to redis' own internal representation of the set structure.
     * 
*/ public function hKeys($key) {} /** * Returns the values in a hash, as an array of strings. * * @param string $key * * @return array An array of elements, the values of the hash. This works like PHP's array_values(). * @link https://redis.io/commands/hvals * @example *
     * $redisCluster->del('h');
     * $redisCluster->hSet('h', 'a', 'x');
     * $redisCluster->hSet('h', 'b', 'y');
     * $redisCluster->hSet('h', 'c', 'z');
     * $redisCluster->hSet('h', 'd', 't');
     * var_dump($redisCluster->hVals('h'));
     *
     * //// Output:
     * //
     * // array(4) {
     * //   [0]=>
     * //   string(1) "x"
     * //   [1]=>
     * //   string(1) "y"
     * //   [2]=>
     * //   string(1) "z"
     * //   [3]=>
     * //   string(1) "t"
     * // }
     * // The order is random and corresponds to redis' own internal representation of the set structure.
     * 
*/ public function hVals($key) {} /** * Gets a value from the hash stored at key. * If the hash table doesn't exist, or the key doesn't exist, FALSE is returned. * * @param string $key * @param string $hashKey * * @return string|false The value, if the command executed successfully BOOL FALSE in case of failure * @link https://redis.io/commands/hget * @example *
     * $redisCluster->del('h');
     * $redisCluster->hSet('h', 'a', 'x');
     * $redisCluster->hGet('h', 'a'); // 'X'
     * 
*/ public function hGet($key, $hashKey) {} /** * Returns the whole hash, as an array of strings indexed by strings. * * @param string $key * * @return array An array of elements, the contents of the hash. * @link https://redis.io/commands/hgetall * @example *
     * $redisCluster->del('h');
     * $redisCluster->hSet('h', 'a', 'x');
     * $redisCluster->hSet('h', 'b', 'y');
     * $redisCluster->hSet('h', 'c', 'z');
     * $redisCluster->hSet('h', 'd', 't');
     * var_dump($redisCluster->hGetAll('h'));
     *
     * //// Output:
     * //
     * // array(4) {
     * //   ["a"]=>
     * //   string(1) "x"
     * //   ["b"]=>
     * //   string(1) "y"
     * //   ["c"]=>
     * //   string(1) "z"
     * //   ["d"]=>
     * //   string(1) "t"
     * // }
     * // The order is random and corresponds to redis' own internal representation of the set structure.
     * 
*/ public function hGetAll($key) {} /** * Verify if the specified member exists in a key. * * @param string $key * @param string $hashKey * * @return bool If the member exists in the hash table, return TRUE, otherwise return FALSE. * @link https://redis.io/commands/hexists * @example *
     * $redisCluster->hSet('h', 'a', 'x');
     * $redisCluster->hExists('h', 'a');               //  TRUE
     * $redisCluster->hExists('h', 'NonExistingKey');  // FALSE
     * 
*/ public function hExists($key, $hashKey) {} /** * Increments the value of a member from a hash by a given amount. * * @param string $key * @param string $hashKey * @param int $value (integer) value that will be added to the member's value * * @return int the new value * @link https://redis.io/commands/hincrby * @example *
     * $redisCluster->del('h');
     * $redisCluster->hIncrBy('h', 'x', 2); // returns 2: h[x] = 2 now.
     * $redisCluster->hIncrBy('h', 'x', 1); // h[x] ← 2 + 1. Returns 3
     * 
*/ public function hIncrBy($key, $hashKey, $value) {} /** * Adds a value to the hash stored at key. If this value is already in the hash, FALSE is returned. * * @param string $key * @param string $hashKey * @param mixed $value * * @return int * 1 if value didn't exist and was added successfully, * 0 if the value was already present and was replaced, FALSE if there was an error. * @link https://redis.io/commands/hset * @example *
     * $redisCluster->del('h')
     * $redisCluster->hSet('h', 'key1', 'hello');  // 1, 'key1' => 'hello' in the hash at "h"
     * $redisCluster->hGet('h', 'key1');           // returns "hello"
     *
     * $redisCluster->hSet('h', 'key1', 'plop');   // 0, value was replaced.
     * $redisCluster->hGet('h', 'key1');           // returns "plop"
     * 
*/ public function hSet($key, $hashKey, $value) {} /** * Adds a value to the hash stored at key only if this field isn't already in the hash. * * @param string $key * @param string $hashKey * @param string $value * * @return bool TRUE if the field was set, FALSE if it was already present. * @link https://redis.io/commands/hsetnx * @example *
     * $redisCluster->del('h')
     * $redisCluster->hSetNx('h', 'key1', 'hello'); // TRUE, 'key1' => 'hello' in the hash at "h"
     * $redisCluster->hSetNx('h', 'key1', 'world'); // FALSE, 'key1' => 'hello' in the hash at "h". No change since the
     * field wasn't replaced.
     * 
*/ public function hSetNx($key, $hashKey, $value) {} /** * Retrieve the values associated to the specified fields in the hash. * * @param string $key * @param array $hashKeys * * @return array Array An array of elements, the values of the specified fields in the hash, * with the hash keys as array keys. * @link https://redis.io/commands/hmget * @example *
     * $redisCluster->del('h');
     * $redisCluster->hSet('h', 'field1', 'value1');
     * $redisCluster->hSet('h', 'field2', 'value2');
     * $redisCluster->hMGet('h', array('field1', 'field2')); // returns array('field1' => 'value1', 'field2' =>
     * 'value2')
     * 
*/ public function hMGet($key, $hashKeys) {} /** * Fills in a whole hash. Non-string values are converted to string, using the standard (string) cast. * NULL values are stored as empty strings * * @param string $key * @param array $hashKeys key → value array * * @return bool * @link https://redis.io/commands/hmset * @example *
     * $redisCluster->del('user:1');
     * $redisCluster->hMSet('user:1', array('name' => 'Joe', 'salary' => 2000));
     * $redisCluster->hIncrBy('user:1', 'salary', 100); // Joe earns 100 more now.
     * 
*/ public function hMSet($key, $hashKeys) {} /** * Removes a values from the hash stored at key. * If the hash table doesn't exist, or the key doesn't exist, FALSE is returned. * * @param string $key * @param string $hashKey1 * @param string $hashKey2 * @param string $hashKeyN * * @return int Number of deleted fields * @link https://redis.io/commands/hdel * @example *
     * $redisCluster->hMSet('h',
     *               array(
     *                    'f1' => 'v1',
     *                    'f2' => 'v2',
     *                    'f3' => 'v3',
     *                    'f4' => 'v4',
     *               ));
     *
     * var_dump( $redisCluster->hDel('h', 'f1') );        // int(1)
     * var_dump( $redisCluster->hDel('h', 'f2', 'f3') );  // int(2)
     *
     * var_dump( $redisCluster->hGetAll('h') );
     *
     * //// Output:
     * //
     * //  array(1) {
     * //    ["f4"]=> string(2) "v4"
     * //  }
     * 
*/ public function hDel($key, $hashKey1, $hashKey2 = null, $hashKeyN = null) {} /** * Increment the float value of a hash field by the given amount * * @param string $key * @param string $field * @param float $increment * * @return float * @link https://redis.io/commands/hincrbyfloat * @example *
     * $redisCluster->hset('h', 'float', 3);
     * $redisCluster->hset('h', 'int',   3);
     * var_dump( $redisCluster->hIncrByFloat('h', 'float', 1.5) ); // float(4.5)
     *
     * var_dump( $redisCluster->hGetAll('h') );
     *
     * //// Output:
     * //
     * // array(2) {
     * //   ["float"]=>
     * //   string(3) "4.5"
     * //   ["int"]=>
     * //   string(1) "3"
     * // }
     * 
*/ public function hIncrByFloat($key, $field, $increment) {} /** * Dump a key out of a redis database, the value of which can later be passed into redis using the RESTORE command. * The data that comes out of DUMP is a binary representation of the key as Redis stores it. * * @param string $key * * @return string|false The Redis encoded value of the key, or FALSE if the key doesn't exist * @link https://redis.io/commands/dump * @example *
     * $redisCluster->set('foo', 'bar');
     * $val = $redisCluster->dump('foo'); // $val will be the Redis encoded key value
     * 
*/ public function dump($key) {} /** * Returns the rank of a given member in the specified sorted set, starting at 0 for the item * with the smallest score. zRevRank starts at 0 for the item with the largest score. * * @param string $key * @param string $member * * @return int the item's score. * @link https://redis.io/commands/zrank * @example *
     * $redisCluster->del('z');
     * $redisCluster->zAdd('key', 1, 'one');
     * $redisCluster->zAdd('key', 2, 'two');
     * $redisCluster->zRank('key', 'one');     // 0
     * $redisCluster->zRank('key', 'two');     // 1
     * $redisCluster->zRevRank('key', 'one');  // 1
     * $redisCluster->zRevRank('key', 'two');  // 0
     * 
*/ public function zRank($key, $member) {} /** * @see zRank() * * @param string $key * @param string $member * * @return int the item's score * @link https://redis.io/commands/zrevrank */ public function zRevRank($key, $member) {} /** * Increment the number stored at key by one. * * @param string $key * * @return int the new value * @link https://redis.io/commands/incr * @example *
     * $redisCluster->incr('key1'); // key1 didn't exists, set to 0 before the increment and now has the value 1
     * $redisCluster->incr('key1'); // 2
     * $redisCluster->incr('key1'); // 3
     * $redisCluster->incr('key1'); // 4
     * 
*/ public function incr($key) {} /** * Decrement the number stored at key by one. * * @param string $key * * @return int the new value * @link https://redis.io/commands/decr * @example *
     * $redisCluster->decr('key1'); // key1 didn't exists, set to 0 before the increment and now has the value -1
     * $redisCluster->decr('key1'); // -2
     * $redisCluster->decr('key1'); // -3
     * 
*/ public function decr($key) {} /** * Increment the number stored at key by one. If the second argument is filled, it will be used as the integer * value of the increment. * * @param string $key key * @param int $value value that will be added to key (only for incrBy) * * @return int the new value * @link https://redis.io/commands/incrby * @example *
     * $redisCluster->incr('key1');        // key1 didn't exists, set to 0 before the increment and now has the value 1
     * $redisCluster->incr('key1');        // 2
     * $redisCluster->incr('key1');        // 3
     * $redisCluster->incr('key1');        // 4
     * $redisCluster->incrBy('key1', 10);  // 14
     * 
*/ public function incrBy($key, $value) {} /** * Decrement the number stored at key by one. If the second argument is filled, it will be used as the integer * value of the decrement. * * @param string $key * @param int $value that will be subtracted to key (only for decrBy) * * @return int the new value * @link https://redis.io/commands/decrby * @example *
     * $redisCluster->decr('key1');        // key1 didn't exists, set to 0 before the increment and now has the value -1
     * $redisCluster->decr('key1');        // -2
     * $redisCluster->decr('key1');        // -3
     * $redisCluster->decrBy('key1', 10);  // -13
     * 
*/ public function decrBy($key, $value) {} /** * Increment the float value of a key by the given amount * * @param string $key * @param float $increment * * @return float * @link https://redis.io/commands/incrbyfloat * @example *
     * $redisCluster->set('x', 3);
     * var_dump( $redisCluster->incrByFloat('x', 1.5) );   // float(4.5)
     *
     * var_dump( $redisCluster->get('x') );                // string(3) "4.5"
     * 
*/ public function incrByFloat($key, $increment) {} /** * Sets an expiration date (a timeout) on an item. * * @param string $key The key that will disappear. * @param int $ttl The key's remaining Time To Live, in seconds. * * @return bool TRUE in case of success, FALSE in case of failure. * @link https://redis.io/commands/expire * @example *
     * $redisCluster->set('x', '42');
     * $redisCluster->expire('x', 3);  // x will disappear in 3 seconds.
     * sleep(5);                    // wait 5 seconds
     * $redisCluster->get('x');            // will return `FALSE`, as 'x' has expired.
     * 
*/ public function expire($key, $ttl) {} /** * Sets an expiration date (a timeout in milliseconds) on an item. * * @param string $key The key that will disappear. * @param int $ttl The key's remaining Time To Live, in milliseconds. * * @return bool TRUE in case of success, FALSE in case of failure. * @link https://redis.io/commands/pexpire * @example *
     * $redisCluster->set('x', '42');
     * $redisCluster->pExpire('x', 11500); // x will disappear in 11500 milliseconds.
     * $redisCluster->ttl('x');            // 12
     * $redisCluster->pttl('x');           // 11500
     * 
*/ public function pExpire($key, $ttl) {} /** * Sets an expiration date (a timestamp) on an item. * * @param string $key The key that will disappear. * @param int $timestamp Unix timestamp. The key's date of death, in seconds from Epoch time. * * @return bool TRUE in case of success, FALSE in case of failure. * @link https://redis.io/commands/expireat * @example *
     * $redisCluster->set('x', '42');
     * $now = time();               // current timestamp
     * $redisCluster->expireAt('x', $now + 3); // x will disappear in 3 seconds.
     * sleep(5);                        // wait 5 seconds
     * $redisCluster->get('x');                // will return `FALSE`, as 'x' has expired.
     * 
*/ public function expireAt($key, $timestamp) {} /** * Sets an expiration date (a timestamp) on an item. Requires a timestamp in milliseconds * * @param string $key The key that will disappear. * @param int $timestamp Unix timestamp. The key's date of death, in seconds from Epoch time. * * @return bool TRUE in case of success, FALSE in case of failure. * @link https://redis.io/commands/pexpireat * @example *
     * $redisCluster->set('x', '42');
     * $redisCluster->pExpireAt('x', 1555555555005);
     * $redisCluster->ttl('x');                       // 218270121
     * $redisCluster->pttl('x');                      // 218270120575
     * 
*/ public function pExpireAt($key, $timestamp) {} /** * Append specified string to the string stored in specified key. * * @param string $key * @param string $value * * @return int Size of the value after the append * @link https://redis.io/commands/append * @example *
     * $redisCluster->set('key', 'value1');
     * $redisCluster->append('key', 'value2'); // 12
     * $redisCluster->get('key');              // 'value1value2'
     * 
*/ public function append($key, $value) {} /** * Return a single bit out of a larger string * * @param string $key * @param int $offset * * @return int the bit value (0 or 1) * @link https://redis.io/commands/getbit * @example *
     * $redisCluster->set('key', "\x7f");  // this is 0111 1111
     * $redisCluster->getBit('key', 0);    // 0
     * $redisCluster->getBit('key', 1);    // 1
     * 
*/ public function getBit($key, $offset) {} /** * Changes a single bit of a string. * * @param string $key * @param int $offset * @param bool|int $value bool or int (1 or 0) * * @return int 0 or 1, the value of the bit before it was set. * @link https://redis.io/commands/setbit * @example *
     * $redisCluster->set('key', "*");     // ord("*") = 42 = 0x2f = "0010 1010"
     * $redisCluster->setBit('key', 5, 1); // returns 0
     * $redisCluster->setBit('key', 7, 1); // returns 0
     * $redisCluster->get('key');          // chr(0x2f) = "/" = b("0010 1111")
     * 
*/ public function setBit($key, $offset, $value) {} /** * Bitwise operation on multiple keys. * * @param string $operation either "AND", "OR", "NOT", "XOR" * @param string $retKey return key * @param string $key1 * @param string $key2 * @param string $key3 * * @return int The size of the string stored in the destination key. * @link https://redis.io/commands/bitop * @example *
     * $redisCluster->set('bit1', '1'); // 11 0001
     * $redisCluster->set('bit2', '2'); // 11 0010
     *
     * $redisCluster->bitOp('AND', 'bit', 'bit1', 'bit2'); // bit = 110000
     * $redisCluster->bitOp('OR',  'bit', 'bit1', 'bit2'); // bit = 110011
     * $redisCluster->bitOp('NOT', 'bit', 'bit1', 'bit2'); // bit = 110011
     * $redisCluster->bitOp('XOR', 'bit', 'bit1', 'bit2'); // bit = 11
     * 
*/ public function bitOp($operation, $retKey, $key1, $key2, $key3 = null) {} /** * Return the position of the first bit set to 1 or 0 in a string. The position is returned, thinking of the * string as an array of bits from left to right, where the first byte's most significant bit is at position 0, * the second byte's most significant bit is at position 8, and so forth. * * @param string $key * @param int $bit * @param int $start * @param int $end * * @return int The command returns the position of the first bit set to 1 or 0 according to the request. * If we look for set bits (the bit argument is 1) and the string is empty or composed of just * zero bytes, -1 is returned. If we look for clear bits (the bit argument is 0) and the string * only contains bit set to 1, the function returns the first bit not part of the string on the * right. So if the string is three bytes set to the value 0xff the command BITPOS key 0 will * return 24, since up to bit 23 all the bits are 1. Basically, the function considers the right * of the string as padded with zeros if you look for clear bits and specify no range or the * start argument only. However, this behavior changes if you are looking for clear bits and * specify a range with both start and end. If no clear bit is found in the specified range, the * function returns -1 as the user specified a clear range and there are no 0 bits in that range. * @link https://redis.io/commands/bitpos * @example *
     * $redisCluster->set('key', '\xff\xff');
     * $redisCluster->bitpos('key', 1); // int(0)
     * $redisCluster->bitpos('key', 1, 1); // int(8)
     * $redisCluster->bitpos('key', 1, 3); // int(-1)
     * $redisCluster->bitpos('key', 0); // int(16)
     * $redisCluster->bitpos('key', 0, 1); // int(16)
     * $redisCluster->bitpos('key', 0, 1, 5); // int(-1)
     * 
*/ public function bitpos($key, $bit, $start = 0, $end = null) {} /** * Count bits in a string. * * @param string $key * * @return int The number of bits set to 1 in the value behind the input key. * @link https://redis.io/commands/bitcount * @example *
     * $redisCluster->set('bit', '345'); // // 11 0011  0011 0100  0011 0101
     * var_dump( $redisCluster->bitCount('bit', 0, 0) ); // int(4)
     * var_dump( $redisCluster->bitCount('bit', 1, 1) ); // int(3)
     * var_dump( $redisCluster->bitCount('bit', 2, 2) ); // int(4)
     * var_dump( $redisCluster->bitCount('bit', 0, 2) ); // int(11)
     * 
*/ public function bitCount($key) {} /** * @see lIndex() * * @param string $key * @param int $index * * @link https://redis.io/commands/lindex */ public function lGet($key, $index) {} /** * Return a substring of a larger string * * @param string $key * @param int $start * @param int $end * * @return string the substring * @link https://redis.io/commands/getrange * @example *
     * $redisCluster->set('key', 'string value');
     * $redisCluster->getRange('key', 0, 5);   // 'string'
     * $redisCluster->getRange('key', -5, -1); // 'value'
     * 
*/ public function getRange($key, $start, $end) {} /** * Trims an existing list so that it will contain only a specified range of elements. * * @param string $key * @param int $start * @param int $stop * * @return array|false Bool return FALSE if the key identify a non-list value. * @link https://redis.io/commands/ltrim * @example *
     * $redisCluster->rPush('key1', 'A');
     * $redisCluster->rPush('key1', 'B');
     * $redisCluster->rPush('key1', 'C');
     * $redisCluster->lRange('key1', 0, -1); // array('A', 'B', 'C')
     * $redisCluster->lTrim('key1', 0, 1);
     * $redisCluster->lRange('key1', 0, -1); // array('A', 'B')
     * 
*/ public function lTrim($key, $start, $stop) {} /** * Returns the specified elements of the list stored at the specified key in * the range [start, end]. start and stop are interpretated as indices: 0 the first element, * 1 the second ... -1 the last element, -2 the penultimate ... * * @param string $key * @param int $start * @param int $end * * @return array containing the values in specified range. * @link https://redis.io/commands/lrange * @example *
     * $redisCluster->rPush('key1', 'A');
     * $redisCluster->rPush('key1', 'B');
     * $redisCluster->rPush('key1', 'C');
     * $redisCluster->lRange('key1', 0, -1); // array('A', 'B', 'C')
     * 
*/ public function lRange($key, $start, $end) {} /** * Deletes the elements of the sorted set stored at the specified key which have rank in the range [start,end]. * * @param string $key * @param int $start * @param int $end * * @return int The number of values deleted from the sorted set * @link https://redis.io/commands/zremrangebyrank * @example *
     * $redisCluster->zAdd('key', 1, 'one');
     * $redisCluster->zAdd('key', 2, 'two');
     * $redisCluster->zAdd('key', 3, 'three');
     * $redisCluster->zRemRangeByRank('key', 0, 1); // 2
     * $redisCluster->zRange('key', 0, -1, true); // array('three' => 3)
     * 
*/ public function zRemRangeByRank($key, $start, $end) {} /** * Publish messages to channels. Warning: this function will probably change in the future. * * @param string $channel a channel to publish to * @param string $message string * * @link https://redis.io/commands/publish * @return int Number of clients that received the message * @example $redisCluster->publish('chan-1', 'hello, world!'); // send message. */ public function publish($channel, $message) {} /** * Renames a key. * * @param string $srcKey * @param string $dstKey * * @return bool TRUE in case of success, FALSE in case of failure. * @link https://redis.io/commands/rename * @example *
     * $redisCluster->set('x', '42');
     * $redisCluster->rename('x', 'y');
     * $redisCluster->get('y');   // → 42
     * $redisCluster->get('x');   // → `FALSE`
     * 
*/ public function rename($srcKey, $dstKey) {} /** * Renames a key. * * Same as rename, but will not replace a key if the destination already exists. * This is the same behaviour as setNx. * * @param string $srcKey * @param string $dstKey * * @return bool TRUE in case of success, FALSE in case of failure. * @link https://redis.io/commands/renamenx * @example *
     * $redisCluster->set('x', '42');
     * $redisCluster->renameNx('x', 'y');
     * $redisCluster->get('y');   // → 42
     * $redisCluster->get('x');   // → `FALSE`
     * 
*/ public function renameNx($srcKey, $dstKey) {} /** * When called with a single key, returns the approximated cardinality computed by the HyperLogLog data * structure stored at the specified variable, which is 0 if the variable does not exist. * * @param string|array $key * * @return int * @link https://redis.io/commands/pfcount * @example *
     * $redisCluster->pfAdd('key1', array('elem1', 'elem2'));
     * $redisCluster->pfAdd('key2', array('elem3', 'elem2'));
     * $redisCluster->pfCount('key1'); // int(2)
     * $redisCluster->pfCount(array('key1', 'key2')); // int(3)
     * 
*/ public function pfCount($key) {} /** * Adds all the element arguments to the HyperLogLog data structure stored at the key. * * @param string $key * @param array $elements * * @return bool * @link https://redis.io/commands/pfadd * @example $redisCluster->pfAdd('key', array('elem1', 'elem2')) */ public function pfAdd($key, array $elements) {} /** * Merge multiple HyperLogLog values into an unique value that will approximate the cardinality * of the union of the observed Sets of the source HyperLogLog structures. * * @param string $destKey * @param array $sourceKeys * * @return bool * @link https://redis.io/commands/pfmerge * @example *
     * $redisCluster->pfAdd('key1', array('elem1', 'elem2'));
     * $redisCluster->pfAdd('key2', array('elem3', 'elem2'));
     * $redisCluster->pfMerge('key3', array('key1', 'key2'));
     * $redisCluster->pfCount('key3'); // int(3)
     * 
*/ public function pfMerge($destKey, array $sourceKeys) {} /** * Changes a substring of a larger string. * * @param string $key * @param int $offset * @param string $value * * @return string the length of the string after it was modified. * @link https://redis.io/commands/setrange * @example *
     * $redisCluster->set('key', 'Hello world');
     * $redisCluster->setRange('key', 6, "redis"); // returns 11
     * $redisCluster->get('key');                  // "Hello redis"
     * 
*/ public function setRange($key, $offset, $value) {} /** * Restore a key from the result of a DUMP operation. * * @param string $key The key name * @param int $ttl How long the key should live (if zero, no expire will be set on the key) * @param string $value (binary). The Redis encoded key value (from DUMP) * * @return bool * @link https://redis.io/commands/restore * @example *
     * $redisCluster->set('foo', 'bar');
     * $val = $redisCluster->dump('foo');
     * $redisCluster->restore('bar', 0, $val); // The key 'bar', will now be equal to the key 'foo'
     * 
*/ public function restore($key, $ttl, $value) {} /** * Moves the specified member from the set at srcKey to the set at dstKey. * * @param string $srcKey * @param string $dstKey * @param string $member * * @return bool If the operation is successful, return TRUE. * If the srcKey and/or dstKey didn't exist, and/or the member didn't exist in srcKey, FALSE is returned. * @link https://redis.io/commands/smove * @example *
     * $redisCluster->sAdd('key1' , 'set11');
     * $redisCluster->sAdd('key1' , 'set12');
     * $redisCluster->sAdd('key1' , 'set13');          // 'key1' => {'set11', 'set12', 'set13'}
     * $redisCluster->sAdd('key2' , 'set21');
     * $redisCluster->sAdd('key2' , 'set22');          // 'key2' => {'set21', 'set22'}
     * $redisCluster->sMove('key1', 'key2', 'set13');  // 'key1' =>  {'set11', 'set12'}
     *                                          // 'key2' =>  {'set21', 'set22', 'set13'}
     * 
*/ public function sMove($srcKey, $dstKey, $member) {} /** * Returns a range of elements from the ordered set stored at the specified key, * with values in the range [start, end]. start and stop are interpreted as zero-based indices: * 0 the first element, * 1 the second ... * -1 the last element, * -2 the penultimate ... * * @param string $key * @param int $start * @param int $end * @param bool $withscores * * @return array Array containing the values in specified range. * @link https://redis.io/commands/zrange * @example *
     * $redisCluster->zAdd('key1', 0, 'val0');
     * $redisCluster->zAdd('key1', 2, 'val2');
     * $redisCluster->zAdd('key1', 10, 'val10');
     * $redisCluster->zRange('key1', 0, -1); // array('val0', 'val2', 'val10')
     * // with scores
     * $redisCluster->zRange('key1', 0, -1, true); // array('val0' => 0, 'val2' => 2, 'val10' => 10)
     * 
*/ public function zRange($key, $start, $end, $withscores = null) {} /** * Returns the elements of the sorted set stored at the specified key in the range [start, end] * in reverse order. start and stop are interpretated as zero-based indices: * 0 the first element, * 1 the second ... * -1 the last element, * -2 the penultimate ... * * @param string $key * @param int $start * @param int $end * @param bool $withscore * * @return array Array containing the values in specified range. * @link https://redis.io/commands/zrevrange * @example *
     * $redisCluster->zAdd('key', 0, 'val0');
     * $redisCluster->zAdd('key', 2, 'val2');
     * $redisCluster->zAdd('key', 10, 'val10');
     * $redisCluster->zRevRange('key', 0, -1); // array('val10', 'val2', 'val0')
     *
     * // with scores
     * $redisCluster->zRevRange('key', 0, -1, true); // array('val10' => 10, 'val2' => 2, 'val0' => 0)
     * 
*/ public function zRevRange($key, $start, $end, $withscore = null) {} /** * Returns the elements of the sorted set stored at the specified key which have scores in the * range [start,end]. Adding a parenthesis before start or end excludes it from the range. * +inf and -inf are also valid limits. * * zRevRangeByScore returns the same items in reverse order, when the start and end parameters are swapped. * * @param string $key * @param int $start * @param int $end * @param array $options Two options are available: * - withscores => TRUE, * - and limit => array($offset, $count) * * @return array Array containing the values in specified range. * @link https://redis.io/commands/zrangebyscore * @example *
     * $redisCluster->zAdd('key', 0, 'val0');
     * $redisCluster->zAdd('key', 2, 'val2');
     * $redisCluster->zAdd('key', 10, 'val10');
     * $redisCluster->zRangeByScore('key', 0, 3);
     * // array('val0', 'val2')
     * $redisCluster->zRangeByScore('key', 0, 3, array('withscores' => TRUE);
     * // array('val0' => 0, 'val2' => 2)
     * $redisCluster->zRangeByScore('key', 0, 3, array('limit' => array(1, 1));
     * // array('val2' => 2)
     * $redisCluster->zRangeByScore('key', 0, 3, array('limit' => array(1, 1));
     * // array('val2')
     * $redisCluster->zRangeByScore('key', 0, 3, array('withscores' => TRUE, 'limit' => array(1, 1));
     * // array('val2'=> 2)
     * 
*/ public function zRangeByScore($key, $start, $end, array $options = []) {} /** * @see zRangeByScore() * * @param string $key * @param int $start * @param int $end * @param array $options * * @return array */ public function zRevRangeByScore($key, $start, $end, array $options = []) {} /** * Returns a range of members in a sorted set, by lexicographical range * * @param string $key The ZSET you wish to run against. * @param int $min The minimum alphanumeric value you wish to get. * @param int $max The maximum alphanumeric value you wish to get. * @param int $offset Optional argument if you wish to start somewhere other than the first element. * @param int $limit Optional argument if you wish to limit the number of elements returned. * * @return array Array containing the values in the specified range. * @link https://redis.io/commands/zrangebylex * @example *
     * foreach (array('a', 'b', 'c', 'd', 'e', 'f', 'g') as $k => $char) {
     *     $redisCluster->zAdd('key', $k, $char);
     * }
     *
     * $redisCluster->zRangeByLex('key', '-', '[c'); // array('a', 'b', 'c')
     * $redisCluster->zRangeByLex('key', '-', '(c'); // array('a', 'b')
     * $redisCluster->zRevRangeByLex('key', '(c','-'); // array('b', 'a')
     * 
*/ public function zRangeByLex($key, $min, $max, $offset = null, $limit = null) {} /** * @see zRangeByLex() * * @param string $key * @param int $min * @param int $max * @param int $offset * @param int $limit * * @return array * @link https://redis.io/commands/zrevrangebylex */ public function zRevRangeByLex($key, $min, $max, $offset = null, $limit = null) {} /** * Count the number of members in a sorted set between a given lexicographical range. * * @param string $key * @param int $min * @param int $max * * @return int The number of elements in the specified score range. * @link https://redis.io/commands/zlexcount * @example *
     * foreach (array('a', 'b', 'c', 'd', 'e', 'f', 'g') as $k => $char) {
     *     $redisCluster->zAdd('key', $k, $char);
     * }
     * $redisCluster->zLexCount('key', '[b', '[f'); // 5
     * 
*/ public function zLexCount($key, $min, $max) {} /** * Remove all members in a sorted set between the given lexicographical range. * * @param string $key The ZSET you wish to run against. * @param string $min The minimum alphanumeric value you wish to get. * @param string $max The maximum alphanumeric value you wish to get. * * @return int|false the number of elements removed. * @link https://redis.io/commands/zremrangebylex * @example *
     * foreach (array('a', 'b', 'c', 'd', 'e', 'f', 'g') as $k => $char) {
     *     $redisCluster->zAdd('key', $k, $char);
     * }
     * $redisCluster->zRemRangeByLex('key', '(b','[d'); // 2 , remove element 'c' and 'd'
     * $redisCluster->zRange('key',0,-1);// array('a','b','e','f','g')
     * 
*/ public function zRemRangeByLex(string $key, string $min, string $max) {} /** * Add multiple sorted sets and store the resulting sorted set in a new key * * @param string $Output * @param array $ZSetKeys * @param null|array $Weights * @param string $aggregateFunction Either "SUM", "MIN", or "MAX": defines the behaviour to use on * duplicate entries during the zUnion. * * @return int The number of values in the new sorted set. * @link https://redis.io/commands/zunionstore * @example *
     * $redisCluster->del('k1');
     * $redisCluster->del('k2');
     * $redisCluster->del('k3');
     * $redisCluster->del('ko1');
     * $redisCluster->del('ko2');
     * $redisCluster->del('ko3');
     *
     * $redisCluster->zAdd('k1', 0, 'val0');
     * $redisCluster->zAdd('k1', 1, 'val1');
     *
     * $redisCluster->zAdd('k2', 2, 'val2');
     * $redisCluster->zAdd('k2', 3, 'val3');
     *
     * $redisCluster->zUnionStore('ko1', array('k1', 'k2')); // 4, 'ko1' => array('val0', 'val1', 'val2', 'val3')
     *
     * // Weighted zUnionStore
     * $redisCluster->zUnionStore('ko2', array('k1', 'k2'), array(1, 1)); // 4, 'ko2' => array('val0', 'val1', 'val2','val3')
     * $redisCluster->zUnionStore('ko3', array('k1', 'k2'), array(5, 1)); // 4, 'ko3' => array('val0', 'val2', 'val3','val1')
     * 
*/ public function zUnionStore($Output, $ZSetKeys, ?array $Weights = null, $aggregateFunction = 'SUM') {} /** * Intersect multiple sorted sets and store the resulting sorted set in a new key * * @param string $Output * @param array $ZSetKeys * @param null|array $Weights * @param string $aggregateFunction Either "SUM", "MIN", or "MAX": * defines the behaviour to use on duplicate entries during the zInterStore. * * @return int The number of values in the new sorted set. * @link https://redis.io/commands/zinterstore * @example *
     * $redisCluster->del('k1');
     * $redisCluster->del('k2');
     * $redisCluster->del('k3');
     *
     * $redisCluster->del('ko1');
     * $redisCluster->del('ko2');
     * $redisCluster->del('ko3');
     * $redisCluster->del('ko4');
     *
     * $redisCluster->zAdd('k1', 0, 'val0');
     * $redisCluster->zAdd('k1', 1, 'val1');
     * $redisCluster->zAdd('k1', 3, 'val3');
     *
     * $redisCluster->zAdd('k2', 2, 'val1');
     * $redisCluster->zAdd('k2', 3, 'val3');
     *
     * $redisCluster->zInterStore('ko1', array('k1', 'k2'));               // 2, 'ko1' => array('val1', 'val3')
     * $redisCluster->zInterStore('ko2', array('k1', 'k2'), array(1, 1));  // 2, 'ko2' => array('val1', 'val3')
     *
     * // Weighted zInterStore
     * $redisCluster->zInterStore('ko3', array('k1', 'k2'), array(1, 5), 'min'); // 2, 'ko3' => array('val1', 'val3')
     * $redisCluster->zInterStore('ko4', array('k1', 'k2'), array(1, 5), 'max'); // 2, 'ko4' => array('val3', 'val1')
     * 
*/ public function zInterStore($Output, $ZSetKeys, array $Weights = null, $aggregateFunction = 'SUM') {} /** * Deletes a specified member from the ordered set. * * @param string $key * @param string $member1 * @param string $member2 * @param string $memberN * * @return int Number of deleted values * @link https://redis.io/commands/zrem * @example *
     * $redisCluster->zAdd('z', 1, 'v1', 2, 'v2', 3, 'v3', 4, 'v4' );  // int(2)
     * $redisCluster->zRem('z', 'v2', 'v3');                           // int(2)
     * var_dump( $redisCluster->zRange('z', 0, -1) );
     * //// Output:
     * //
     * // array(2) {
     * //   [0]=> string(2) "v1"
     * //   [1]=> string(2) "v4"
     * // }
     * 
*/ public function zRem($key, $member1, $member2 = null, $memberN = null) {} /** * Sort * * @param string $key * @param array $option array(key => value, ...) - optional, with the following keys and values: * - 'by' => 'some_pattern_*', * - 'limit' => array(0, 1), * - 'get' => 'some_other_pattern_*' or an array of patterns, * - 'sort' => 'asc' or 'desc', * - 'alpha' => TRUE, * - 'store' => 'external-key' * * @return array * An array of values, or a number corresponding to the number of elements stored if that was used. * @link https://redis.io/commands/sort * @example *
     * $redisCluster->del('s');
     * $redisCluster->sadd('s', 5);
     * $redisCluster->sadd('s', 4);
     * $redisCluster->sadd('s', 2);
     * $redisCluster->sadd('s', 1);
     * $redisCluster->sadd('s', 3);
     *
     * var_dump($redisCluster->sort('s')); // 1,2,3,4,5
     * var_dump($redisCluster->sort('s', array('sort' => 'desc'))); // 5,4,3,2,1
     * var_dump($redisCluster->sort('s', array('sort' => 'desc', 'store' => 'out'))); // (int)5
     * 
*/ public function sort($key, $option = null) {} /** * Describes the object pointed to by a key. * The information to retrieve (string) and the key (string). * Info can be one of the following: * - "encoding" * - "refcount" * - "idletime" * * @param string $string * @param string $key * * @return string|false for "encoding", int for "refcount" and "idletime", FALSE if the key doesn't exist. * @link https://redis.io/commands/object * @example *
     * $redisCluster->object("encoding", "l"); // → ziplist
     * $redisCluster->object("refcount", "l"); // → 1
     * $redisCluster->object("idletime", "l"); // → 400 (in seconds, with a precision of 10 seconds).
     * 
*/ public function object($string = '', $key = '') {} /** * Subscribe to channels. Warning: this function will probably change in the future. * * @param array $channels an array of channels to subscribe to * @param string|array $callback either a string or an array($instance, 'method_name'). * The callback function receives 3 parameters: the redis instance, the channel * name, and the message. * * @return mixed Any non-null return value in the callback will be returned to the caller. * @link https://redis.io/commands/subscribe * @example *
     * function f($redisCluster, $chan, $msg) {
     *  switch($chan) {
     *      case 'chan-1':
     *          ...
     *          break;
     *
     *      case 'chan-2':
     *                     ...
     *          break;
     *
     *      case 'chan-2':
     *          ...
     *          break;
     *      }
     * }
     *
     * $redisCluster->subscribe(array('chan-1', 'chan-2', 'chan-3'), 'f'); // subscribe to 3 chans
     * 
*/ public function subscribe($channels, $callback) {} /** * Subscribe to channels by pattern * * @param array $patterns The number of elements removed from the set. * @param string|array $callback Either a string or an array with an object and method. * The callback will get four arguments ($redis, $pattern, $channel, $message) * * @return mixed Any non-null return value in the callback will be returned to the caller. * * @link https://redis.io/commands/psubscribe * @example *
     * function psubscribe($redisCluster, $pattern, $chan, $msg) {
     *  echo "Pattern: $pattern\n";
     *  echo "Channel: $chan\n";
     *  echo "Payload: $msg\n";
     * }
     * 
*/ public function psubscribe($patterns, $callback) {} /** * Unsubscribes the client from the given channels, or from all of them if none is given. * * @param $channels * @param $callback */ public function unSubscribe($channels, $callback) {} /** * Unsubscribes the client from the given patterns, or from all of them if none is given. * * @param $channels * @param $callback */ public function punSubscribe($channels, $callback) {} /** * Evaluate a LUA script serverside, from the SHA1 hash of the script instead of the script itself. * In order to run this command Redis will have to have already loaded the script, either by running it or via * the SCRIPT LOAD command. * * @param string $scriptSha * @param array $args * @param int $numKeys * * @return mixed @see eval() * @see eval() * @link https://redis.io/commands/evalsha * @example *
     * $script = 'return 1';
     * $sha = $redisCluster->script('load', $script);
     * $redisCluster->evalSha($sha); // Returns 1
     * 
*/ public function evalSha($scriptSha, $args = [], $numKeys = 0) {} /** * Scan the keyspace for keys. * * @param int &$iterator Iterator, initialized to NULL. * @param string|array $node Node identified by key or host/port array * @param string $pattern Pattern to match. * @param int $count Count of keys per iteration (only a suggestion to Redis). * * @return array|false This function will return an array of keys or FALSE if there are no more keys. * @link https://redis.io/commands/scan * @example *
     * $iterator = null;
     * while($keys = $redisCluster->scan($iterator)) {
     *     foreach($keys as $key) {
     *         echo $key . PHP_EOL;
     *     }
     * }
     * 
*/ public function scan(&$iterator, $node, $pattern = null, $count = 0) {} /** * Scan a set for members. * * @param string $key The set to search. * @param int &$iterator LONG (reference) to the iterator as we go. * @param null $pattern String, optional pattern to match against. * @param int $count How many members to return at a time (Redis might return a different amount). * * @return array|false PHPRedis will return an array of keys or FALSE when we're done iterating. * @link https://redis.io/commands/sscan * @example *
     * $iterator = null;
     * while ($members = $redisCluster->sScan('set', $iterator)) {
     *     foreach ($members as $member) {
     *         echo $member . PHP_EOL;
     *     }
     * }
     * 
*/ public function sScan($key, &$iterator, $pattern = null, $count = 0) {} /** * Scan a sorted set for members, with optional pattern and count. * * @param string $key String, the set to scan. * @param int &$iterator Long (reference), initialized to NULL. * @param string $pattern String (optional), the pattern to match. * @param int $count How many keys to return per iteration (Redis might return a different number). * * @return array|false PHPRedis will return matching keys from Redis, or FALSE when iteration is complete. * @link https://redis.io/commands/zscan * @example *
     * $iterator = null;
     * while ($members = $redis-zscan('zset', $iterator)) {
     *     foreach ($members as $member => $score) {
     *         echo $member . ' => ' . $score . PHP_EOL;
     *     }
     * }
     * 
*/ public function zScan($key, &$iterator, $pattern = null, $count = 0) {} /** * Scan a HASH value for members, with an optional pattern and count. * * @param string $key * @param int &$iterator * @param string $pattern Optional pattern to match against. * @param int $count How many keys to return in a go (only a sugestion to Redis). * * @return array An array of members that match our pattern. * @link https://redis.io/commands/hscan * @example *
     * $iterator = null;
     * while($elements = $redisCluster->hscan('hash', $iterator)) {
     *    foreach($elements as $key => $value) {
     *         echo $key . ' => ' . $value . PHP_EOL;
     *     }
     * }
     * 
*/ public function hScan($key, &$iterator, $pattern = null, $count = 0) {} /** * Detect whether we're in ATOMIC/MULTI/PIPELINE mode. * * @return int Either RedisCluster::ATOMIC, RedisCluster::MULTI or RedisCluster::PIPELINE * @example $redisCluster->getMode(); */ public function getMode() {} /** * The last error message (if any) * * @return string|null A string with the last returned script based error message, or NULL if there is no error * @example *
     * $redisCluster->eval('this-is-not-lua');
     * $err = $redisCluster->getLastError();
     * // "ERR Error compiling script (new function): user_script:1: '=' expected near '-'"
     * 
*/ public function getLastError() {} /** * Clear the last error message * * @return bool true * @example *
     * $redisCluster->set('x', 'a');
     * $redisCluster->incr('x');
     * $err = $redisCluster->getLastError();
     * // "ERR value is not an integer or out of range"
     * $redisCluster->clearLastError();
     * $err = $redisCluster->getLastError();
     * // NULL
     * 
*/ public function clearLastError() {} /** * Get client option * * @param int $option parameter * * @return int|string Parameter value. * @example * // return RedisCluster::SERIALIZER_NONE, RedisCluster::SERIALIZER_PHP, or RedisCluster::SERIALIZER_IGBINARY. * $redisCluster->getOption(RedisCluster::OPT_SERIALIZER); */ public function getOption($option) {} /** * Set client option. * * @param int $option parameter * @param int|string $value parameter value * * @return bool TRUE on success, FALSE on error. * @example *
     * $redisCluster->setOption(RedisCluster::OPT_SERIALIZER, RedisCluster::SERIALIZER_NONE);        // don't serialize data
     * $redisCluster->setOption(RedisCluster::OPT_SERIALIZER, RedisCluster::SERIALIZER_PHP);         // use built-in serialize/unserialize
     * $redisCluster->setOption(RedisCluster::OPT_SERIALIZER, RedisCluster::SERIALIZER_IGBINARY);    // use igBinary serialize/unserialize
     * $redisCluster->setOption(RedisCluster::OPT_PREFIX, 'myAppName:');                             // use custom prefix on all keys
     * 
*/ public function setOption($option, $value) {} /** * A utility method to prefix the value with the prefix setting for phpredis. * * @param mixed $value The value you wish to prefix * * @return string If a prefix is set up, the value now prefixed. If there is no prefix, the value will be returned unchanged. * @example *
     * $redisCluster->setOption(RedisCluster::OPT_PREFIX, 'my-prefix:');
     * $redisCluster->_prefix('my-value'); // Will return 'my-prefix:my-value'
     * 
*/ public function _prefix($value) {} /** * A utility method to serialize values manually. This method allows you to serialize a value with whatever * serializer is configured, manually. This can be useful for serialization/unserialization of data going in * and out of EVAL commands as phpredis can't automatically do this itself. Note that if no serializer is * set, phpredis will change Array values to 'Array', and Objects to 'Object'. * * @param mixed $value The value to be serialized. * * @return mixed * @example *
     * $redisCluster->setOption(RedisCluster::OPT_SERIALIZER, RedisCluster::SERIALIZER_NONE);
     * $redisCluster->_serialize("foo"); // returns "foo"
     * $redisCluster->_serialize(Array()); // Returns "Array"
     * $redisCluster->_serialize(new stdClass()); // Returns "Object"
     *
     * $redisCluster->setOption(RedisCluster::OPT_SERIALIZER, RedisCluster::SERIALIZER_PHP);
     * $redisCluster->_serialize("foo"); // Returns 's:3:"foo";'
     * 
*/ public function _serialize($value) {} /** * A utility method to unserialize data with whatever serializer is set up. If there is no serializer set, the * value will be returned unchanged. If there is a serializer set up, and the data passed in is malformed, an * exception will be thrown. This can be useful if phpredis is serializing values, and you return something from * redis in a LUA script that is serialized. * * @param string $value The value to be unserialized * * @return mixed * @example *
     * $redisCluster->setOption(RedisCluster::OPT_SERIALIZER, RedisCluster::SERIALIZER_PHP);
     * $redisCluster->_unserialize('a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}'); // Will return Array(1,2,3)
     * 
*/ public function _unserialize($value) {} /** * Return all redis master nodes * * @return array * @example *
     * $redisCluster->_masters(); // Will return [[0=>'127.0.0.1','6379'],[0=>'127.0.0.1','6380']]
     * 
*/ public function _masters() {} /** * Enter and exit transactional mode. * * @param int $mode RedisCluster::MULTI|RedisCluster::PIPELINE * Defaults to RedisCluster::MULTI. * A RedisCluster::MULTI block of commands runs as a single transaction; * a RedisCluster::PIPELINE block is simply transmitted faster to the server, but without any guarantee * of atomicity. discard cancels a transaction. * * @return RedisCluster returns the RedisCluster instance and enters multi-mode. * Once in multi-mode, all subsequent method calls return the same object until exec() is called. * @link https://redis.io/commands/multi * @example *
     * $ret = $redisCluster->multi()
     *      ->set('key1', 'val1')
     *      ->get('key1')
     *      ->set('key2', 'val2')
     *      ->get('key2')
     *      ->exec();
     *
     * //$ret == array (
     * //    0 => TRUE,
     * //    1 => 'val1',
     * //    2 => TRUE,
     * //    3 => 'val2');
     * 
*/ public function multi($mode = RedisCluster::MULTI) {} /** * @see multi() * @return void|array * @link https://redis.io/commands/exec */ public function exec() {} /** * @see multi() * @link https://redis.io/commands/discard */ public function discard() {} /** * Watches a key for modifications by another client. If the key is modified between WATCH and EXEC, * the MULTI/EXEC transaction will fail (return FALSE). unwatch cancels all the watching of all keys by this client. * * @param string|array $key : a list of keys * * @return void * @link https://redis.io/commands/watch * @example *
     * $redisCluster->watch('x');
     * // long code here during the execution of which other clients could well modify `x`
     * $ret = $redisCluster->multi()
     *          ->incr('x')
     *          ->exec();
     * // $ret = FALSE if x has been modified between the call to WATCH and the call to EXEC.
     * 
*/ public function watch($key) {} /** * @see watch() * @link https://redis.io/commands/unwatch */ public function unwatch() {} /** * Performs a synchronous save at a specific node. * * @param string|array $nodeParams key or [host,port] * * @return bool TRUE in case of success, FALSE in case of failure. * If a save is already running, this command will fail and return FALSE. * @link https://redis.io/commands/save * @example * $redisCluster->save('x'); //key * $redisCluster->save(['127.0.0.1',6379]); //[host,port] */ public function save($nodeParams) {} /** * Performs a background save at a specific node. * * @param string|array $nodeParams key or [host,port] * * @return bool TRUE in case of success, FALSE in case of failure. * If a save is already running, this command will fail and return FALSE. * @link https://redis.io/commands/bgsave */ public function bgsave($nodeParams) {} /** * Removes all entries from the current database at a specific node. * * @param string|array $nodeParams key or [host,port] * * @return bool Always TRUE. * @link https://redis.io/commands/flushdb */ public function flushDB($nodeParams) {} /** * Removes all entries from all databases at a specific node. * * @param string|array $nodeParams key or [host,port] * * @return bool Always TRUE. * @link https://redis.io/commands/flushall */ public function flushAll($nodeParams) {} /** * Returns the current database's size at a specific node. * * @param string|array $nodeParams key or [host,port] * * @return int DB size, in number of keys. * @link https://redis.io/commands/dbsize * @example *
     * $count = $redisCluster->dbSize('x');
     * echo "Redis has $count keys\n";
     * 
*/ public function dbSize($nodeParams) {} /** * Starts the background rewrite of AOF (Append-Only File) at a specific node. * * @param string|array $nodeParams key or [host,port] * * @return bool TRUE in case of success, FALSE in case of failure. * @link https://redis.io/commands/bgrewriteaof * @example $redisCluster->bgrewriteaof('x'); */ public function bgrewriteaof($nodeParams) {} /** * Returns the timestamp of the last disk save at a specific node. * * @param string|array $nodeParams key or [host,port] * * @return int timestamp. * @link https://redis.io/commands/lastsave * @example $redisCluster->lastSave('x'); */ public function lastSave($nodeParams) {} /** * Returns an associative array of strings and integers * * @param string $option Optional. The option to provide redis. * SERVER | CLIENTS | MEMORY | PERSISTENCE | STATS | REPLICATION | CPU | CLASTER | KEYSPACE * | COMANDSTATS * * Returns an associative array of strings and integers, with the following keys: * - redis_version * - redis_git_sha1 * - redis_git_dirty * - redis_build_id * - redis_mode * - os * - arch_bits * - multiplexing_api * - atomicvar_api * - gcc_version * - process_id * - run_id * - tcp_port * - uptime_in_seconds * - uptime_in_days * - hz * - lru_clock * - executable * - config_file * - connected_clients * - client_longest_output_list * - client_biggest_input_buf * - blocked_clients * - used_memory * - used_memory_human * - used_memory_rss * - used_memory_rss_human * - used_memory_peak * - used_memory_peak_human * - used_memory_peak_perc * - used_memory_peak * - used_memory_overhead * - used_memory_startup * - used_memory_dataset * - used_memory_dataset_perc * - total_system_memory * - total_system_memory_human * - used_memory_lua * - used_memory_lua_human * - maxmemory * - maxmemory_human * - maxmemory_policy * - mem_fragmentation_ratio * - mem_allocator * - active_defrag_running * - lazyfree_pending_objects * - mem_fragmentation_ratio * - loading * - rdb_changes_since_last_save * - rdb_bgsave_in_progress * - rdb_last_save_time * - rdb_last_bgsave_status * - rdb_last_bgsave_time_sec * - rdb_current_bgsave_time_sec * - rdb_last_cow_size * - aof_enabled * - aof_rewrite_in_progress * - aof_rewrite_scheduled * - aof_last_rewrite_time_sec * - aof_current_rewrite_time_sec * - aof_last_bgrewrite_status * - aof_last_write_status * - aof_last_cow_size * - changes_since_last_save * - aof_current_size * - aof_base_size * - aof_pending_rewrite * - aof_buffer_length * - aof_rewrite_buffer_length * - aof_pending_bio_fsync * - aof_delayed_fsync * - loading_start_time * - loading_total_bytes * - loading_loaded_bytes * - loading_loaded_perc * - loading_eta_seconds * - total_connections_received * - total_commands_processed * - instantaneous_ops_per_sec * - total_net_input_bytes * - total_net_output_bytes * - instantaneous_input_kbps * - instantaneous_output_kbps * - rejected_connections * - maxclients * - sync_full * - sync_partial_ok * - sync_partial_err * - expired_keys * - evicted_keys * - keyspace_hits * - keyspace_misses * - pubsub_channels * - pubsub_patterns * - latest_fork_usec * - migrate_cached_sockets * - slave_expires_tracked_keys * - active_defrag_hits * - active_defrag_misses * - active_defrag_key_hits * - active_defrag_key_misses * - role * - master_replid * - master_replid2 * - master_repl_offset * - second_repl_offset * - repl_backlog_active * - repl_backlog_size * - repl_backlog_first_byte_offset * - repl_backlog_histlen * - master_host * - master_port * - master_link_status * - master_last_io_seconds_ago * - master_sync_in_progress * - slave_repl_offset * - slave_priority * - slave_read_only * - master_sync_left_bytes * - master_sync_last_io_seconds_ago * - master_link_down_since_seconds * - connected_slaves * - min-slaves-to-write * - min-replicas-to-write * - min_slaves_good_slaves * - used_cpu_sys * - used_cpu_user * - used_cpu_sys_children * - used_cpu_user_children * - cluster_enabled * * @link https://redis.io/commands/info * @return array * @example *
     * $redisCluster->info();
     *
     * or
     *
     * $redisCluster->info("COMMANDSTATS"); //Information on the commands that have been run (>=2.6 only)
     * $redisCluster->info("CPU"); // just CPU information from Redis INFO
     * 
*/ public function info($option = null) {} /** * @since redis >= 2.8.12. * Returns the role of the instance in the context of replication * * @param string|array $nodeParams key or [host,port] * * @return array * @link https://redis.io/commands/role * @example *
     * $redisCluster->role(['127.0.0.1',6379]);
     * // [ 0=>'master',1 => 3129659, 2 => [ ['127.0.0.1','9001','3129242'], ['127.0.0.1','9002','3129543'] ] ]
     * 
*/ public function role($nodeParams) {} /** * Returns a random key at the specified node * * @param string|array $nodeParams key or [host,port] * * @return string an existing key in redis. * @link https://redis.io/commands/randomkey * @example *
     * $key = $redisCluster->randomKey('x');
     * $surprise = $redisCluster->get($key);  // who knows what's in there.
     * 
*/ public function randomKey($nodeParams) {} /** * Return the specified node server time. * * @param string|array $nodeParams key or [host,port] * * @return array If successfully, the time will come back as an associative array with element zero being the * unix timestamp, and element one being microseconds. * @link https://redis.io/commands/time * @example *
     * var_dump( $redisCluster->time('x') );
     * //// Output:
     * //
     * // array(2) {
     * //   [0] => string(10) "1342364352"
     * //   [1] => string(6) "253002"
     * // }
     * 
*/ public function time($nodeParams) {} /** * Check the specified node status * * @param string|array $nodeParams key or [host,port] * * @return string STRING: +PONG on success. Throws a RedisClusterException object on connectivity error, as described * above. * @link https://redis.io/commands/ping */ public function ping($nodeParams) {} /** * Returns message. * * @param string|array $nodeParams key or [host,port] * @param string $msg * * @return mixed */ public function echo($nodeParams, $msg) {} /** * Returns Array reply of details about all Redis Cluster commands. * * @return mixed array | bool */ public function command() {} /** * Send arbitrary things to the redis server at the specified node * * @param string|array $nodeParams key or [host,port] * @param string $command Required command to send to the server. * @param mixed $arguments Optional variable amount of arguments to send to the server. * * @return mixed */ public function rawCommand($nodeParams, $command, $arguments) {} /** * @since redis >= 3.0 * Executes cluster command * * @param string|array $nodeParams key or [host,port] * @param string $command Required command to send to the server. * @param mixed $arguments Optional variable amount of arguments to send to the server. * * @return mixed * @link https://redis.io/commands#cluster * @example *
     * $redisCluster->cluster(['127.0.0.1',6379],'INFO');
     * 
*/ public function cluster($nodeParams, $command, $arguments) {} /** * Allows you to get information of the cluster client * * @param string|array $nodeParams key or [host,port] * @param string $subCmd can be: 'LIST', 'KILL', 'GETNAME', or 'SETNAME' * @param string $args optional arguments */ public function client($nodeParams, $subCmd, $args) {} /** * Get or Set the redis config keys. * * @param string|array $nodeParams key or [host,port] * @param string $operation either `GET` or `SET` * @param string $key for `SET`, glob-pattern for `GET`. See https://redis.io/commands/config-get for examples. * @param string $value optional string (only for `SET`) * * @return array Associative array for `GET`, key -> value * @link https://redis.io/commands/config-get * @link https://redis.io/commands/config-set * @example *
     * $redisCluster->config(['127.0.0.1',6379], "GET", "*max-*-entries*");
     * $redisCluster->config(['127.0.0.1',6379], "SET", "dir", "/var/run/redis/dumps/");
     * 
*/ public function config($nodeParams, $operation, $key, $value) {} /** * A command allowing you to get information on the Redis pub/sub system. * * @param string|array $nodeParams key or [host,port] * * @param string $keyword String, which can be: "channels", "numsub", or "numpat" * @param string|array $argument Optional, variant. * For the "channels" subcommand, you can pass a string pattern. * For "numsub" an array of channel names * * @return array|int Either an integer or an array. * - channels Returns an array where the members are the matching channels. * - numsub Returns a key/value array where the keys are channel names and * values are their counts. * - numpat Integer return containing the number active pattern subscriptions. * @link https://redis.io/commands/pubsub * @example *
     * $redisCluster->pubsub(['127.0.0.1',6379], 'channels'); // All channels
     * $redisCluster->pubsub(['127.0.0.1',6379], 'channels', '*pattern*'); // Just channels matching your pattern
     * $redisCluster->pubsub(['127.0.0.1',6379], 'numsub', array('chan1', 'chan2')); // Get subscriber counts for
     * 'chan1' and 'chan2'
     * $redisCluster->pubsub(['127.0.0.1',6379], 'numpat'); // Get the number of pattern subscribers
     * 
*/ public function pubsub($nodeParams, $keyword, $argument) {} /** * Execute the Redis SCRIPT command to perform various operations on the scripting subsystem. * * @param string|array $nodeParams key or [host,port] * @param string $command load | flush | kill | exists * @param string $script * * @return mixed * @link https://redis.io/commands/script-load * @link https://redis.io/commands/script-kill * @link https://redis.io/commands/script-flush * @link https://redis.io/commands/script-exists * @example *
     * $redisCluster->script(['127.0.0.1',6379], 'load', $script);
     * $redisCluster->script(['127.0.0.1',6379], 'flush');
     * $redisCluster->script(['127.0.0.1',6379], 'kill');
     * $redisCluster->script(['127.0.0.1',6379], 'exists', $script1, [$script2, $script3, ...]);
     * 
* * SCRIPT LOAD will return the SHA1 hash of the passed script on success, and FALSE on failure. * SCRIPT FLUSH should always return TRUE * SCRIPT KILL will return true if a script was able to be killed and false if not * SCRIPT EXISTS will return an array with TRUE or FALSE for each passed script */ public function script($nodeParams, $command, $script) {} /** * This function is used in order to read and reset the Redis slow queries log. * * @param string|array $nodeParams key or [host,port] * @param string $command * @param mixed $argument * * @link https://redis.io/commands/slowlog * @example *
     * $redisCluster->slowLog(['127.0.0.1',6379],'get','2');
     * 
*/ public function slowLog($nodeParams, $command, $argument) {} /** * Add one or more geospatial items in the geospatial index represented using a sorted set * * @param string $key * @param float $longitude * @param float $latitude * @param string $member * * @link https://redis.io/commands/geoadd * @example *
     * $redisCluster->geoAdd('Sicily', 13.361389, 38.115556, 'Palermo'); // int(1)
     * $redisCluster->geoAdd('Sicily', 15.087269, 37.502669, "Catania"); // int(1)
     * 
*/ public function geoAdd($key, $longitude, $latitude, $member) {} /** * Returns members of a geospatial index as standard geohash strings * * @param string $key * @param string $member1 * @param string $member2 * @param string $memberN * * @example *
     * $redisCluster->geoAdd('Sicily', 13.361389, 38.115556, 'Palermo'); // int(1)
     * $redisCluster->geoAdd('Sicily', 15.087269, 37.502669, "Catania"); // int(1)
     * $redisCluster->geohash('Sicily','Palermo','Catania');//['sqc8b49rny0','sqdtr74hyu0']
     * 
*/ public function geohash($key, $member1, $member2 = null, $memberN = null) {} /** * Returns longitude and latitude of members of a geospatial index * * @param string $key * @param string $member1 * @param string $member2 * @param string $memberN * @example *
     * $redisCluster->geoAdd('Sicily', 15.087269, 37.502669, "Catania"); // int(1)
     * $redisCluster->geopos('Sicily','Palermo');//[['13.36138933897018433','38.11555639549629859']]
     * 
*/ public function geopos($key, $member1, $member2 = null, $memberN = null) {} /** * Returns the distance between two members of a geospatial index * * @param string $key * @param string $member1 * @param string $member2 * @param string $unit The unit must be one of the following, and defaults to meters: * m for meters. * km for kilometers. * mi for miles. * ft for feet. * * @link https://redis.io/commands/geoadd * @example *
     * $redisCluster->geoAdd('Sicily', 13.361389, 38.115556, 'Palermo'); // int(1)
     * $redisCluster->geoAdd('Sicily', 15.087269, 37.502669, "Catania"); // int(1)
     * $redisCluster->geoDist('Sicily', 'Palermo' ,'Catania'); // float(166274.1516)
     * $redisCluster->geoDist('Sicily', 'Palermo','Catania', 'km'); // float(166.2742)
     * 
*/ public function geoDist($key, $member1, $member2, $unit = 'm') {} /** * Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a point * * @param string $key * @param float $longitude * @param float $latitude * @param float $radius * @param string $radiusUnit String can be: "m" for meters; "km" for kilometers , "mi" for miles, or "ft" for feet. * @param array $options * * @link https://redis.io/commands/georadius * @example *
     * $redisCluster->del('Sicily');
     * $redisCluster->geoAdd('Sicily', 12.361389, 35.115556, 'Palermo'); // int(1)
     * $redisCluster->geoAdd('Sicily', 15.087269, 37.502669, "Catania"); // int(1)
     * $redisCluster->geoAdd('Sicily', 13.3585, 35.330022, "Agrigento"); // int(1)
     *
     * var_dump( $redisCluster->geoRadius('Sicily',13.3585, 35.330022, 300, 'km', ['WITHDIST' ,'DESC']) );
     *
     * array(3) {
     *    [0]=>
     *   array(2) {
     *        [0]=>
     *     string(7) "Catania"
     *        [1]=>
     *     string(8) "286.9362"
     *   }
     *   [1]=>
     *   array(2) {
     *        [0]=>
     *     string(7) "Palermo"
     *        [1]=>
     *     string(7) "93.6874"
     *   }
     *   [2]=>
     *   array(2) {
     *        [0]=>
     *     string(9) "Agrigento"
     *        [1]=>
     *     string(6) "0.0002"
     *   }
     * }
     * var_dump( $redisCluster->geoRadiusByMember('Sicily','Agrigento', 100, 'km', ['WITHDIST' ,'DESC']) );
     *
     * * array(2) {
     *    [0]=>
     *   array(2) {
     *        [0]=>
     *     string(7) "Palermo"
     *        [1]=>
     *     string(7) "93.6872"
     *   }
     *   [1]=>
     *   array(2) {
     *        [0]=>
     *     string(9) "Agrigento"
     *        [1]=>
     *     string(6) "0.0000"
     *   }
     * }
     *
     * 
     */
    public function geoRadius($key, $longitude, $latitude, $radius, $radiusUnit, array $options) {}

    /**
     * Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a member
     *
     * @see geoRadius
     *
     * @param string $key
     * @param string $member
     * @param float  $radius
     * @param string $radiusUnit
     * @param array  $options
     */
    public function geoRadiusByMember($key, $member, $radius, $radiusUnit, array $options) {}
}

class RedisClusterException extends Exception {}
.
 */

/**
 * Helper autocomplete for phpredis extension
 *
 * @author  Tawana Musewe 
 * @link    https://github.com/tbtmuse/phpredis-sentinel-phpdoc
 */
class RedisSentinel
{
    /**
     * Creates a Redis Sentinel
     *
     * @param string      $host          Sentinel IP address or hostname
     * @param int         $port          Sentinel Port
     * @param float       $timeout       Value in seconds (optional, default is 0 meaning unlimited)
     * @param string|null $persistent    Persistent connection id (optional, default is null meaning not persistent)
     * @param int         $retryInterval Value in milliseconds (optional, default is 0)
     * @param float       $readTimeout   Value in seconds (optional, default is 0 meaning unlimited)
     *
     * @example
     * // 1s timeout, 100ms delay between reconnection attempts.
     * $sentinel = new RedisSentinel('127.0.0.1', 26379, 1, null, 100);
     */
    public function __construct(
        string $host,
        int $port,
        float $timeout = 0,
        ?string $persistent = null,
        int $retryInterval = 0,
        float $readTimeout = 0
    ) {}

    /**
     * Creates a Redis Sentinel
     *
     * Accepts and array of options.
     *
     * Available options:
     *   - 'host' => string, Sentinel IP address or hostname
     *   - 'port' => int, Sentinel Port (optional, default is 26379)
     *   - 'connectTimeout' => float, Value in seconds (optional, default is 0 meaning unlimited)
     *   - 'persistent' => string, Persistent connection id (optional, default is NULL meaning not persistent)
     *   - 'retryInterval' => int, Value in milliseconds (optional, default is 0)
     *   - 'readTimeout' => float, Value in seconds (optional, default is 0 meaning unlimited)
     *   - 'auth' => string|array, Authentication credentials (optional, default is NULL meaning NOAUTH)
     *
     * @param array $options Associative array of options
     *
     * @example $sentinel = new RedisSentinel(['host' => '127.0.0.1']); // default parameters
     *
     * @since >= 6.0.0
     */
    public function __construct(array $options) {}

    /**
     * Check if the current Sentinel configuration is able to reach the quorum needed to failover a master, and the
     * majority needed to authorize the failover. This command should be used in monitoring systems to check if a
     * Sentinel deployment is ok.
     *
     * @param string $master Name of master
     *
     * @return bool True in case of success, False in case of failure.
     *
     * @example $sentinel->ckquorum('mymaster');
     *
     * @since   >= 5.2.0
     */
    public function ckquorum(string $master): bool {}

    /**
     * Force a failover as if the master was not reachable, and without asking for agreement to other Sentinels
     * (however a new version of the configuration will be published so that the other Sentinels will update
     * their configurations).
     *
     * @param string $master Name of master
     *
     * @return bool True in case of success, False in case of failure.
     *
     * @example $sentinel->failover('mymaster');
     *
     * @since   >= 5.2.0
     */
    public function failover(string $master): bool {}

    /**
     * Force Sentinel to rewrite its configuration on disk, including the current Sentinel state.
     *
     * Normally Sentinel rewrites the configuration every time something changes in its state (in the context of the
     * subset of the state which is persisted on disk across restart). However sometimes it is possible that the
     * configuration file is lost because of operation errors, disk failures, package upgrade scripts or configuration
     * managers. In those cases a way to to force Sentinel to rewrite the configuration file is handy.
     *
     * This command works even if the previous configuration file is completely missing.
     *
     * @return bool True in case of success, False in case of failure.
     *
     * @example $sentinel->flushconfig();
     *
     * @since   >= 5.2.0
     */
    public function flushconfig(): bool {}

    /**
     * Return the ip and port number of the master with that name. If a failover is in progress or terminated
     * successfully for this master it returns the address and port of the promoted replica.
     *
     * @param string $master Name of master
     *
     * @return array|false ['address', 'port'] in case of success, False in case of failure.
     *
     * @example $sentinel->getMasterAddrByName('mymaster');
     *
     * @since   >= 5.2.0
     */
    public function getMasterAddrByName(string $master) {}

    /**
     * Return the state and info of the specified master
     *
     * @param string $master Name of master
     *
     * @return array|false Associative array with info in case of success, False in case of failure.
     *
     * @example $sentinel->master('mymaster');
     *
     * @since   >= 5.2.0
     */
    public function master(string $master) {}

    /**
     * Return a list of monitored masters and their state
     *
     * @return array|false Array of arrays with info for each master in case of success, FALSE in case of failure.
     *
     * @example $sentinel->masters();
     *
     * @since   >= 5.2.0
     */
    public function masters() {}

    /**
     * Ping the sentinel
     *
     * @return bool True in case of success, False in case of failure
     *
     * @example $sentinel->ping();
     *
     * @since   >= 5.2.0
     */
    public function ping(): bool {}

    /**
     * Reset all the masters with matching name. The pattern argument is a glob-style pattern.
     * The reset process clears any previous state in a master (including a failover in progress), and removes every
     * replica and sentinel already discovered and associated with the master.
     *
     * @param string $pattern Glob-style pattern
     *
     * @return bool True in case of success, False in case of failure
     *
     * @example $sentinel->reset('*');
     *
     * @since   >= 5.2.0
     */
    public function reset(string $pattern): bool {}

    /**
     * Return a list of sentinel instances for this master, and their state
     *
     * @param string $master Name of master
     *
     * @return array|false Array of arrays with info for each sentinel in case of success, False in case of failure
     *
     * @example $sentinel->sentinels('mymaster');
     *
     * @since   >= 5.2.0
     */
    public function sentinels(string $master) {}

    /**
     * Return a list of sentinel instances for this master, and their state
     *
     * @param string $master Name of master
     *
     * @return array|false Array of arrays with info for each replica in case of success, False in case of failure
     *
     * @example $sentinel->slaves('mymaster');
     *
     * @since   >= 5.2.0
     */
    public function slaves(string $master) {}
}

     * 
SNMP_VALUE_LIBRARY
The return values will be as returned by the Net-SNMP library.
*
SNMP_VALUE_PLAIN
The return values will be the plain value without the SNMP type hint.
*
SNMP_VALUE_OBJECT
The return values will be objects with the properties "value" and "type", where the latter is one of the SNMP_OCTET_STR, SNMP_COUNTER etc. constants. The way "value" is returned is based on which one of SNMP_VALUE_LIBRARY, SNMP_VALUE_PLAIN is set
*
* @link https://secure.php.net/manual/en/class.snmp.php#snmp.props.max-oids */ public $valueretrieval; /** * @var bool Value of quick_print within the NET-SNMP library *

Sets the value of quick_print within the NET-SNMP library. When this is set (1), the SNMP library will return 'quick printed' values. This means that just the value will be printed. When quick_print is not enabled (default) the UCD SNMP library prints extra information including the type of the value (i.e. IpAddress or OID). Additionally, if quick_print is not enabled, the library prints additional hex values for all strings of three characters or less. * @link https://secure.php.net/manual/en/class.snmp.php#snmp.props.quick-print */ public $quick_print; /** * @var bool Controls the way enum values are printed *

Parameter toggles if walk/get etc. should automatically lookup enum values in the MIB and return them together with their human readable string. * @link https://secure.php.net/manual/en/class.snmp.php#snmp.props.enum-print */ public $enum_print; /** * @var int Controls OID output format *

OID .1.3.6.1.2.1.1.3.0 representation for various oid_output_format values *

*
SNMP_OID_OUTPUT_FULL
.iso.org.dod.internet.mgmt.mib-2.system.sysUpTime.sysUpTimeInstance
*
SNMP_OID_OUTPUT_NUMERIC
.1.3.6.1.2.1.1.3.0
*
SNMP_OID_OUTPUT_MODULE
DISMAN-EVENT-MIB::sysUpTimeInstance
*
SNMP_OID_OUTPUT_SUFFIX
sysUpTimeInstance
*
SNMP_OID_OUTPUT_UCD
system.sysUpTime.sysUpTimeInstance
*
SNMP_OID_OUTPUT_NONE
Undefined
*
* @link https://secure.php.net/manual/en/class.snmp.php#snmp.props.oid-output-format */ public $oid_output_format; /** * @var bool Controls disabling check for increasing OID while walking OID tree *

Some SNMP agents are known for returning OIDs out of order but can complete the walk anyway. Other agents return OIDs that are out of order and can cause SNMP::walk() to loop indefinitely until memory limit will be reached. PHP SNMP library by default performs OID increasing check and stops walking on OID tree when it detects possible loop with issuing warning about non-increasing OID faced. Set oid_increasing_check to FALSE to disable this check. * @link https://secure.php.net/manual/en/class.snmp.php#snmp.props.oid-increasing-check */ public $oid_increasing_check; /** * @var int Controls which failures will raise SNMPException instead of warning. Use bitwise OR'ed SNMP::ERRNO_* constants. By default all SNMP exceptions are disabled. * @link https://secure.php.net/manual/en/class.snmp.php#snmp.props.exceptions-enabled */ public $exceptions_enabled; /** * @var array Read-only property with remote agent configuration: hostname, port, default timeout, default retries count * @link https://secure.php.net/manual/en/class.snmp.php#snmp.props.info */ public $info; public const VERSION_1 = 0; public const VERSION_2c = 1; public const VERSION_2C = 1; public const VERSION_3 = 3; public const ERRNO_NOERROR = 0; public const ERRNO_ANY = 126; public const ERRNO_GENERIC = 2; public const ERRNO_TIMEOUT = 4; public const ERRNO_ERROR_IN_REPLY = 8; public const ERRNO_OID_NOT_INCREASING = 16; public const ERRNO_OID_PARSING_ERROR = 32; public const ERRNO_MULTIPLE_SET_QUERIES = 64; /** * Creates SNMP instance representing session to remote SNMP agent * @link https://php.net/manual/en/snmp.construct.php * @param int $version

SNMP protocol version: * SNMP::VERSION_1, * SNMP::VERSION_2C, * SNMP::VERSION_3.

* @param string $hostname The SNMP agent. hostname may be suffixed with * optional SNMP agent port after colon. IPv6 addresses must be enclosed in square * brackets if used with port. If FQDN is used for hostname * it will be resolved by php-snmp library, not by Net-SNMP engine. Usage * of IPv6 addresses when specifying FQDN may be forced by enclosing FQDN * into square brackets. Here it is some examples: * * * * * * * * * * * *
IPv4 with default port127.0.0.1
IPv6 with default port::1 or [::1]
IPv4 with specific port127.0.0.1:1161
IPv6 with specific port[::1]:1161
FQDN with default porthost.domain
FQDN with specific porthost.domain:1161
FQDN with default port, force usage of IPv6 address[host.domain]
FQDN with specific port, force usage of IPv6 address[host.domain]:1161
* @param string $community

The purpuse of community is * SNMP version specific:

* * * * * * *
SNMP::VERSION_1SNMP community
SNMP::VERSION_2CSNMP community
SNMP::VERSION_3SNMPv3 securityName
* @param int $timeout [optional] The number of microseconds until the first timeout. * @param int $retries [optional] The number of retries in case timeout occurs. * @since 5.4 */ public function __construct($version, $hostname, $community, $timeout = 1000000, $retries = 5) {} /** * Close SNMP session * @link https://php.net/manual/en/snmp.close.php * @return bool TRUE on success or FALSE on failure. * @since 5.4 */ public function close() {} /** * Configures security-related SNMPv3 session parameters * @link https://php.net/manual/en/snmp.setsecurity.php * @param string $sec_level the security level (noAuthNoPriv|authNoPriv|authPriv) * @param string $auth_protocol [optional] the authentication protocol (MD5 or SHA) * @param string $auth_passphrase [optional] the authentication pass phrase * @param string $priv_protocol [optional] the privacy protocol (DES or AES) * @param string $priv_passphrase [optional] the privacy pass phrase * @param string $contextName [optional] the context name * @param string $contextEngineID [optional] the context EngineID * @return bool TRUE on success or FALSE on failure. * @since 5.4 */ public function setSecurity($sec_level, $auth_protocol, $auth_passphrase, $priv_protocol, $priv_passphrase, $contextName, $contextEngineID) {} /** * Fetch an SNMP object * @link https://php.net/manual/en/snmp.get.php * @param mixed $object_id The SNMP object (OID) or objects * @param bool $preserve_keys [optional] When object_id is a array and preserve_keys set to TRUE keys in results will be taken exactly as in object_id, otherwise SNMP::oid_output_format property is used to determinate the form of keys. * @return mixed SNMP objects requested as string or array * depending on object_id type or FALSE on error. * @since 5.4 */ public function get($object_id, $preserve_keys = false) {} /** * Fetch an SNMP object which * follows the given object id * @link https://php.net/manual/en/snmp.getnext.php * @param mixed $object_id

* The SNMP object (OID) or objects *

* @return mixed SNMP objects requested as string or array * depending on object_id type or FALSE on error. * @since 5.4 */ public function getnext($object_id) {} /** * Fetch SNMP object subtree * @link https://php.net/manual/en/snmp.walk.php * @param string $object_id

Root of subtree to be fetched

* @param bool $suffix_as_keys [optional]

By default full OID notation is used for keys in output array. If set to TRUE subtree prefix will be removed from keys leaving only suffix of object_id.

* @param int $max_repetitions [optional]

This specifies the maximum number of iterations over the repeating variables. The default is to use this value from SNMP object.

* @param int $non_repeaters [optional]

This specifies the number of supplied variables that should not be iterated over. The default is to use this value from SNMP object.

* @return array|false associative array of the SNMP object ids and their values on success or FALSE on error. * When a SNMP error occures SNMP::getErrno and * SNMP::getError can be used for retrieving error * number (specific to SNMP extension, see class constants) and error message * respectively. * @since 5.4 */ public function walk($object_id, $suffix_as_keys = false, $max_repetitions, $non_repeaters) {} /** * Set the value of an SNMP object * @link https://php.net/manual/en/snmp.set.php * @param string $object_id

The SNMP object id

* @since 5.4 * *

When count of OIDs in object_id array is greater than * max_oids object property set method will have to use multiple queries * to perform requested value updates. In this case type and value checks * are made per-chunk so second or subsequent requests may fail due to * wrong type or value for OID requested. To mark this a warning is * raised when count of OIDs in object_id array is greater than max_oids. * When count of OIDs in object_id array is greater than max_oids object property set method will have to use multiple queries to perform requested value updates. In this case type and value checks are made per-chunk so second or subsequent requests may fail due to wrong type or value for OID requested. To mark this a warning is raised when count of OIDs in object_id array is greater than max_oids.

* @param mixed $type

The MIB defines the type of each object id. It has to be specified as a single character from the below list.

* types: * * * * * * * * * * * * * * *
=The type is taken from the MIB
iINTEGER
uINTEGER
sSTRING
xHEX STRING
dDECIMAL STRING
nNULLOBJ
oOBJID
tTIMETICKS
aIPADDRESS
bBITS
*

* If OPAQUE_SPECIAL_TYPES was defined while compiling the SNMP library, the following are also valid: *

* types: * * * * * * * *
Uunsigned int64
Isigned int64
Ffloat
Ddouble
*

* Most of these will use the obvious corresponding ASN.1 type. 's', 'x', 'd' and 'b' are all different ways of specifying an OCTET STRING value, and * the 'u' unsigned type is also used for handling Gauge32 values. *

* *

* If the MIB-Files are loaded by into the MIB Tree with "snmp_read_mib" or by specifying it in the libsnmp config, '=' may be used as * the type parameter for all object ids as the type can then be automatically read from the MIB. *

* *

* Note that there are two ways to set a variable of the type BITS like e.g. * "SYNTAX BITS {telnet(0), ftp(1), http(2), icmp(3), snmp(4), ssh(5), https(6)}": *

*
    *
  • * Using type "b" and a list of bit numbers. This method is not recommended since GET query for the same OID would return e.g. 0xF8. *
  • *
  • * Using type "x" and a hex number but without(!) the usual "0x" prefix. *
  • *
*

* See examples section for more details. *

* @param mixed $value

* The new value.

* @return bool TRUE on success or FALSE on failure. */ public function set($object_id, $type, $value) {} /** * Get last error code * @link https://php.net/manual/en/snmp.geterrno.php * @return int one of SNMP error code values described in constants chapter. * @since 5.4 */ public function getErrno() {} /** * Get last error message * @link https://php.net/manual/en/snmp.geterror.php * @return string String describing error from last SNMP request. * @since 5.4 */ public function getError() {} } /** * Represents an error raised by SNMP. You should not throw a * SNMPException from your own code. * See Exceptions for more * information about Exceptions in PHP. * @link https://php.net/manual/en/class.snmpexception.php */ class SNMPException extends RuntimeException { /** * @var string Textual error message. Exception::getMessage() to access it. */ protected $message; /** * @var string SNMP library error code. Use Exception::getCode() to access it. */ protected $code; } /** * Fetch an SNMP object * @link https://php.net/manual/en/function.snmpget.php * @param string $hostname

* The SNMP agent. *

* @param string $community

* The read community. *

* @param string $object_id

* The SNMP object. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return string|false SNMP object value on success or FALSE on error. */ function snmpget($hostname, $community, $object_id, $timeout = 1000000, $retries = 5) {} /** * Fetch the SNMP object which follows the given object id * @link https://php.net/manual/en/function.snmpgetnext.php * @param string $host

The hostname of the SNMP agent (server).

* @param string $community

The read community.

* @param string $object_id

The SNMP object id which precedes the wanted one.

* @param int $timeout [optional]

The number of microseconds until the first timeout.

* @param int $retries [optional]

The number of times to retry if timeouts occur.

* @return string|false SNMP object value on success or FALSE on error. * In case of an error, an E_WARNING message is shown. */ function snmpgetnext($host, $community, $object_id, $timeout = 1000000, $retries = 5) {} /** * Fetch all the SNMP objects from an agent * @link https://php.net/manual/en/function.snmpwalk.php * @param string $hostname

* The SNMP agent (server). *

* @param string $community

* The read community. *

* @param string $object_id

* If NULL, object_id is taken as the root of * the SNMP objects tree and all objects under that tree are returned as * an array. *

*

* If object_id is specified, all the SNMP objects * below that object_id are returned. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

The number of times to retry if timeouts occur.

* @return array an array of SNMP object values starting from the * object_id as root or FALSE on error. */ function snmpwalk($hostname, $community, $object_id, $timeout = 1000000, $retries = 5) {} /** * Return all objects including their respective object ID within the specified one * @link https://php.net/manual/en/function.snmprealwalk.php * @param string $host

The hostname of the SNMP agent (server).

* @param string $community

The read community.

* @param string $object_id

The SNMP object id which precedes the wanted one.

* @param int $timeout [optional]

The number of microseconds until the first timeout.

* @param int $retries [optional]

The number of times to retry if timeouts occur.

* @return array|false an associative array of the SNMP object ids and their values on success or FALSE on error. * In case of an error, an E_WARNING message is shown. */ function snmprealwalk($host, $community, $object_id, $timeout = 1000000, $retries = 5) {} /** * Query for a tree of information about a network entity * @link https://php.net/manual/en/function.snmpwalkoid.php * @param string $hostname

* The SNMP agent. *

* @param string $community

* The read community. *

* @param string $object_id

* If NULL, object_id is taken as the root of * the SNMP objects tree and all objects under that tree are returned as * an array. *

*

* If object_id is specified, all the SNMP objects * below that object_id are returned. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return array an associative array with object ids and their respective * object value starting from the object_id * as root or FALSE on error. */ function snmpwalkoid($hostname, $community, $object_id, $timeout = 1000000, $retries = 5) {} /** * Set the value of an SNMP object * @link https://php.net/manual/en/function.snmpset.php * @param string $host

* The hostname of the SNMP agent (server). *

* @param string $community

* The write community. *

* @param string $object_id

* The SNMP object id. *

* @param string $type The MIB defines the type of each object id. It has to be specified as a single character from the below list. *

* types * =The type is taken from the MIB * iINTEGER * uINTEGER * sSTRING * xHEX STRING * dDECIMAL STRING * nNULLOBJ * oOBJID * tTIMETICKS * aIPADDRESS * bBITS * * If OPAQUE_SPECIAL_TYPES was defined while compiling the SNMP library, the following are also valid: *

* types * Uunsigned int64 * Isigned int64 * Ffloat * Ddouble * * Most of these will use the obvious corresponding ASN.1 type. 's', 'x', 'd' and 'b' are all different ways of specifying an OCTET STRING value, and * the 'u' unsigned type is also used for handling Gauge32 values. *

* If the MIB-Files are loaded by into the MIB Tree with "snmp_read_mib" or by specifying it in the libsnmp config, '=' may be used as * the type parameter for all object ids as the type can then be automatically read from the MIB. *

* Note that there are two ways to set a variable of the type BITS like e.g. * "SYNTAX BITS {telnet(0), ftp(1), http(2), icmp(3), snmp(4), ssh(5), https(6)}": *

* Using type "b" and a list of bit numbers. This method is not recommended since GET query for the same OID would return e.g. 0xF8. * Using type "x" and a hex number but without(!) the usual "0x" prefix. * See examples section for more details. *

* @param mixed $value

* The new value. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return bool TRUE on success or FALSE on failure. *

* If the SNMP host rejects the data type, an E_WARNING message like "Warning: Error in packet. Reason: (badValue) The value given has the wrong type or length." is shown. * If an unknown or invalid OID is specified the warning probably reads "Could not add variable". *

*/ function snmpset($host, $community, $object_id, $type, $value, $timeout = 1000000, $retries = 5) {} /** * Fetches the current value of the UCD library's quick_print setting * @link https://php.net/manual/en/function.snmp-get-quick-print.php * @return bool TRUE if quick_print is on, FALSE otherwise. */ function snmp_get_quick_print() {} /** * Set the value of quick_print within the UCD SNMP library * @link https://php.net/manual/en/function.snmp-set-quick-print.php * @param bool $quick_print * @return bool No value is returned. */ function snmp_set_quick_print($quick_print) {} /** * Return all values that are enums with their enum value instead of the raw integer * @link https://php.net/manual/en/function.snmp-set-enum-print.php * @param int $enum_print

* As the value is interpreted as boolean by the Net-SNMP library, it can only be "0" or "1". *

* @return bool */ function snmp_set_enum_print($enum_print) {} /** * Set the OID output format * @link https://php.net/manual/en/function.snmp-set-oid-output-format.php * @param int $oid_format [optional] * OID .1.3.6.1.2.1.1.3.0 representation for various oid_format values * * *
SNMP_OID_OUTPUT_FULL.iso.org.dod.internet.mgmt.mib-2.system.sysUpTime.sysUpTimeInstance
SNMP_OID_OUTPUT_NUMERIC.1.3.6.1.2.1.1.3.0
*

Begining from PHP 5.4.0 four additional constants available: *

* * * * *
SNMP_OID_OUTPUT_MODULEDISMAN-EVENT-MIB::sysUpTimeInstance
SNMP_OID_OUTPUT_SUFFIXsysUpTimeInstance
SNMP_OID_OUTPUT_UCDsystem.sysUpTime.sysUpTimeInstance
SNMP_OID_OUTPUT_NONEUndefined
*

* @return bool No value is returned. */ function snmp_set_oid_output_format($oid_format = SNMP_OID_OUTPUT_MODULE) {} /** * Set the oid output format * @link https://php.net/manual/en/function.snmp-set-oid-numeric-print.php * @param int $oid_format * @return void */ function snmp_set_oid_numeric_print($oid_format) {} /** * Fetch an SNMP object * @link https://php.net/manual/en/function.snmp2-get.php * @param string $host

* The SNMP agent. *

* @param string $community

* The read community. *

* @param string $object_id

* The SNMP object. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return string|false SNMP object value on success or FALSE on error. */ function snmp2_get($host, $community, $object_id, $timeout = 1000000, $retries = 5) {} /** * Fetch the SNMP object which follows the given object id * @link https://php.net/manual/en/function.snmp2-getnext.php * @param string $host

* The hostname of the SNMP agent (server). *

* @param string $community

* The read community. *

* @param string $object_id

* The SNMP object id which precedes the wanted one. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return string|false SNMP object value on success or FALSE on error. * In case of an error, an E_WARNING message is shown. */ function snmp2_getnext($host, $community, $object_id, $timeout = 1000000, $retries = 5) {} /** * Fetch all the SNMP objects from an agent * @link https://php.net/manual/en/function.snmp2-walk.php * @param string $host

* The SNMP agent (server). *

* @param string $community

* The read community. *

* @param string $object_id

* If NULL, object_id is taken as the root of * the SNMP objects tree and all objects under that tree are returned as * an array. *

*

* If object_id is specified, all the SNMP objects * below that object_id are returned. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return array an array of SNMP object values starting from the * object_id as root or FALSE on error. */ function snmp2_walk($host, $community, $object_id, $timeout = 1000000, $retries = 5) {} /** * Return all objects including their respective object ID within the specified one * @link https://php.net/manual/en/function.snmp2-real-walk.php * @param string $host

* The hostname of the SNMP agent (server). *

* @param string $community

* The read community. *

* @param string $object_id

* The SNMP object id which precedes the wanted one. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return array|false an associative array of the SNMP object ids and their values on success or FALSE on error. * In case of an error, an E_WARNING message is shown. */ function snmp2_real_walk($host, $community, $object_id, $timeout = 1000000, $retries = 5) {} /** * Set the value of an SNMP object * @link https://php.net/manual/en/function.snmp2-set.php * @param string $host

* The hostname of the SNMP agent (server). *

* @param string $community

* The write community. *

* @param string $object_id

* The SNMP object id. *

* @param string $type

The MIB defines the type of each object id. It has to be specified as a single character from the below list. *

*

types:

* * * * * * * * * * * * *
=The type is taken from the MIB
iINTEGER
uINTEGER
sSTRING
xHEX STRING
dDECIMAL STRING
nNULLOBJ
oOBJID
tTIMETICKS
aIPADDRESS
bBITS
*

If OPAQUE_SPECIAL_TYPES was defined while compiling the SNMP library, the following are also valid: *

*

types:

* * * * * *
Uunsigned int64
Isigned int64
Ffloat
Ddouble
*

Most of these will use the obvious corresponding ASN.1 type. 's', 'x', 'd' and 'b' are all different ways of specifying an OCTET STRING value, and * the 'u' unsigned type is also used for handling Gauge32 values. *

* If the MIB-Files are loaded by into the MIB Tree with "snmp_read_mib" or by specifying it in the libsnmp config, '=' may be used as * the type parameter for all object ids as the type can then be automatically read from the MIB. *

* Note that there are two ways to set a variable of the type BITS like e.g. * "SYNTAX BITS {telnet(0), ftp(1), http(2), icmp(3), snmp(4), ssh(5), https(6)}": *

* Using type "b" and a list of bit numbers. This method is not recommended since GET query for the same OID would return e.g. 0xF8. * Using type "x" and a hex number but without(!) the usual "0x" prefix. * See examples section for more details. *

* @param string $value

* The new value. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return bool TRUE on success or FALSE on failure. *

* If the SNMP host rejects the data type, an E_WARNING message like "Warning: Error in packet. Reason: (badValue) The value given has the wrong type or length." is shown. * If an unknown or invalid OID is specified the warning probably reads "Could not add variable". *

*/ function snmp2_set($host, $community, $object_id, $type, $value, $timeout = 1000000, $retries = 5) {} /** * Fetch an SNMP object * @link https://php.net/manual/en/function.snmp3-get.php * @param string $host

* The hostname of the SNMP agent (server). *

* @param string $sec_name

* the security name, usually some kind of username *

* @param string $sec_level

* the security level (noAuthNoPriv|authNoPriv|authPriv) *

* @param string $auth_protocol

* the authentication protocol (MD5 or SHA) *

* @param string $auth_passphrase

* the authentication pass phrase *

* @param string $priv_protocol

* the privacy protocol (DES or AES) *

* @param string $priv_passphrase

* the privacy pass phrase *

* @param string $object_id

* The SNMP object id. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return string|false SNMP object value on success or FALSE on error. */ function snmp3_get($host, $sec_name, $sec_level, $auth_protocol, $auth_passphrase, $priv_protocol, $priv_passphrase, $object_id, $timeout = 1000000, $retries = 5) {} /** * Fetch the SNMP object which follows the given object id * @link https://php.net/manual/en/function.snmp3-getnext.php * @param string $host

* The hostname of the * SNMP agent (server). *

* @param string $sec_name

* the security name, usually some kind of username *

* @param string $sec_level

* the security level (noAuthNoPriv|authNoPriv|authPriv) *

* @param string $auth_protocol

* the authentication protocol (MD5 or SHA) *

* @param string $auth_passphrase

* the authentication pass phrase *

* @param string $priv_protocol

* the privacy protocol (DES or AES) *

* @param string $priv_passphrase

* the privacy pass phrase *

* @param string $object_id

* The SNMP object id. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return string|false SNMP object value on success or FALSE on error. * In case of an error, an E_WARNING message is shown. */ function snmp3_getnext($host, $sec_name, $sec_level, $auth_protocol, $auth_passphrase, $priv_protocol, $priv_passphrase, $object_id, $timeout = 1000000, $retries = 5) {} /** * Fetch all the SNMP objects from an agent * @link https://php.net/manual/en/function.snmp3-walk.php * @param string $host

* The hostname of the SNMP agent (server). *

* @param string $sec_name

* the security name, usually some kind of username *

* @param string $sec_level

* the security level (noAuthNoPriv|authNoPriv|authPriv) *

* @param string $auth_protocol

* the authentication protocol (MD5 or SHA) *

* @param string $auth_passphrase

* the authentication pass phrase *

* @param string $priv_protocol

* the privacy protocol (DES or AES) *

* @param string $priv_passphrase

* the privacy pass phrase *

* @param string $object_id

* If NULL, object_id is taken as the root of * the SNMP objects tree and all objects under that tree are returned as * an array. *

*

* If object_id is specified, all the SNMP objects * below that object_id are returned. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return array an array of SNMP object values starting from the * object_id as root or FALSE on error. */ function snmp3_walk($host, $sec_name, $sec_level, $auth_protocol, $auth_passphrase, $priv_protocol, $priv_passphrase, $object_id, $timeout = 1000000, $retries = 5) {} /** * Return all objects including their respective object ID within the specified one * @link https://php.net/manual/en/function.snmp3-real-walk.php * @param string $host

* The hostname of the * SNMP agent (server). *

* @param string $sec_name

* the security name, usually some kind of username *

* @param string $sec_level

* the security level (noAuthNoPriv|authNoPriv|authPriv) *

* @param string $auth_protocol

* the authentication protocol (MD5 or SHA) *

* @param string $auth_passphrase

* the authentication pass phrase *

* @param string $priv_protocol

* the privacy protocol (DES or AES) *

* @param string $priv_passphrase

* the privacy pass phrase *

* @param string $object_id

* The SNMP object id. *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return array an associative array of the * SNMP object ids and their values on success or FALSE on error. * In case of an error, an E_WARNING message is shown. */ function snmp3_real_walk($host, $sec_name, $sec_level, $auth_protocol, $auth_passphrase, $priv_protocol, $priv_passphrase, $object_id, $timeout = null, $retries = null) {} /** * Set the value of an SNMP object * @link https://php.net/manual/en/function.snmp3-set.php * @param string $host

* The hostname of the SNMP agent (server). *

* @param string $sec_name

* the security name, usually some kind of username *

* @param string $sec_level

* the security level (noAuthNoPriv|authNoPriv|authPriv) *

* @param string $auth_protocol

* the authentication protocol (MD5 or SHA) *

* @param string $auth_passphrase

* the authentication pass phrase *

* @param string $priv_protocol

* the privacy protocol (DES or AES) *

* @param string $priv_passphrase

* the privacy pass phrase *

* @param string $object_id

* The SNMP object id. *

* @param string $type

The MIB defines the type of each object id. It has to be specified as a single character from the below list.

*

types:

* * * * * * * * * * * * *
=The type is taken from the MIB
iINTEGER
uINTEGER
sSTRING
xHEX STRING
dDECIMAL STRING
nNULLOBJ
oOBJID
tTIMETICKS
aIPADDRESS
bBITS
*

If OPAQUE_SPECIAL_TYPES was defined while compiling the SNMP library, the following are also valid: *

*

types:

* * * * * *
Uunsigned int64
Isigned int64
Ffloat
Ddouble
*

Most of these will use the obvious corresponding ASN.1 type. 's', 'x', 'd' and 'b' are all different ways of specifying an OCTET STRING value, and * the 'u' unsigned type is also used for handling Gauge32 values. *

*

* If the MIB-Files are loaded by into the MIB Tree with "snmp_read_mib" or by specifying it in the libsnmp config, '=' may be used as * the type parameter for all object ids as the type can then be automatically read from the MIB. *

*

* Note that there are two ways to set a variable of the type BITS like e.g. * "SYNTAX BITS {telnet(0), ftp(1), http(2), icmp(3), snmp(4), ssh(5), https(6)}": *

*

* Using type "b" and a list of bit numbers. This method is not recommended since GET query for the same OID would return e.g. 0xF8. * Using type "x" and a hex number but without(!) the usual "0x" prefix. * See examples section for more details. *

* @param string $value

* The new value *

* @param int $timeout [optional]

* The number of microseconds until the first timeout. *

* @param int $retries [optional]

* The number of times to retry if timeouts occur. *

* @return bool TRUE on success or FALSE on failure. *

* If the SNMP host rejects the data type, an E_WARNING message like "Warning: Error in packet. Reason: (badValue) The value given has the wrong type or length." is shown. * If an unknown or invalid OID is specified the warning probably reads "Could not add variable". *

*/ function snmp3_set($host, $sec_name, $sec_level, $auth_protocol, $auth_passphrase, $priv_protocol, $priv_passphrase, $object_id, $type, $value, $timeout = 1000000, $retries = 5) {} /** * Specify the method how the SNMP values will be returned * @link https://php.net/manual/en/function.snmp-set-valueretrieval.php * @param int $method * types * * * * * * * * * * * * *
SNMP_VALUE_LIBRARYThe return values will be as returned by the Net-SNMP library.
SNMP_VALUE_PLAINThe return values will be the plain value without the SNMP type hint.
SNMP_VALUE_OBJECT * The return values will be objects with the properties "value" and "type", where the latter * is one of the SNMP_OCTET_STR, SNMP_COUNTER etc. constants. The * way "value" is returned is based on which one of constants * SNMP_VALUE_LIBRARY, SNMP_VALUE_PLAIN is set. *
* @return bool */ function snmp_set_valueretrieval($method) {} /** * Return the method how the SNMP values will be returned * @link https://php.net/manual/en/function.snmp-get-valueretrieval.php * @return int OR-ed combitantion of constants ( SNMP_VALUE_LIBRARY or * SNMP_VALUE_PLAIN ) with * possible SNMP_VALUE_OBJECT set. */ function snmp_get_valueretrieval() {} /** * Reads and parses a MIB file into the active MIB tree * @link https://php.net/manual/en/function.snmp-read-mib.php * @param string $filename

The filename of the MIB.

* @return bool */ function snmp_read_mib($filename) {} /** * As of 5.4 * @link https://php.net/manual/en/snmp.constants.php */ define('SNMP_OID_OUTPUT_SUFFIX', 1); /** * As of 5.4 * @link https://php.net/manual/en/snmp.constants.php */ define('SNMP_OID_OUTPUT_MODULE', 2); /** * As of 5.2 * @link https://php.net/manual/en/snmp.constants.php */ define('SNMP_OID_OUTPUT_FULL', 3); /** * As of 5.2 * @link https://php.net/manual/en/snmp.constants.php */ define('SNMP_OID_OUTPUT_NUMERIC', 4); /** * As of 5.4 * @link https://php.net/manual/en/snmp.constants.php */ define('SNMP_OID_OUTPUT_UCD', 5); /** * As of 5.4 * @link https://php.net/manual/en/snmp.constants.php */ define('SNMP_OID_OUTPUT_NONE', 6); define('SNMP_VALUE_LIBRARY', 0); define('SNMP_VALUE_PLAIN', 1); define('SNMP_VALUE_OBJECT', 2); define('SNMP_BIT_STR', 3); define('SNMP_OCTET_STR', 4); define('SNMP_OPAQUE', 68); define('SNMP_NULL', 5); define('SNMP_OBJECT_ID', 6); define('SNMP_IPADDRESS', 64); define('SNMP_COUNTER', 66); define('SNMP_UNSIGNED', 66); define('SNMP_TIMETICKS', 67); define('SNMP_UINTEGER', 71); define('SNMP_INTEGER', 2); define('SNMP_COUNTER64', 70); // End of snmp v.0.1 * @link https://github.com/iMega/grpc-phpdoc */ /** * Grpc * @see https://grpc.io * @see https://github.com/grpc/grpc/tree/master/src/php/ext/grpc */ namespace Grpc; /** * Register call error constants */ /** * everything went ok */ const CALL_OK = 0; /** * something failed, we don't know what */ const CALL_ERROR = 1; /** * this method is not available on the server */ const CALL_ERROR_NOT_ON_SERVER = 2; /** * this method is not available on the client */ const CALL_ERROR_NOT_ON_CLIENT = 3; /** * this method must be called before server_accept */ const CALL_ERROR_ALREADY_ACCEPTED = 4; /** * this method must be called before invoke */ const CALL_ERROR_ALREADY_INVOKED = 5; /** * this method must be called after invoke */ const CALL_ERROR_NOT_INVOKED = 6; /** * this call is already finished * (writes_done or write_status has already been called) */ const CALL_ERROR_ALREADY_FINISHED = 7; /** * there is already an outstanding read/write operation on the call */ const CALL_ERROR_TOO_MANY_OPERATIONS = 8; /** * the flags value was illegal for this call */ const CALL_ERROR_INVALID_FLAGS = 9; /** * invalid metadata was passed to this call */ const CALL_ERROR_INVALID_METADATA = 10; /** * invalid message was passed to this call */ const CALL_ERROR_INVALID_MESSAGE = 11; /** * completion queue for notification has not been registered with the * server */ const CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE = 12; /** * this batch of operations leads to more operations than allowed */ const CALL_ERROR_BATCH_TOO_BIG = 13; /** * payload type requested is not the type registered */ const CALL_ERROR_PAYLOAD_TYPE_MISMATCH = 14; /* * Register write flags */ /** * Hint that the write may be buffered and need not go out on the wire * immediately. GRPC is free to buffer the message until the next non-buffered * write, or until writes_done, but it need not buffer completely or at all. */ const WRITE_BUFFER_HINT = 1; /** * Force compression to be disabled for a particular write * (start_write/add_metadata). Illegal on invoke/accept. */ const WRITE_NO_COMPRESS = 2; /* * Register status constants */ /** * Not an error; returned on success */ const STATUS_OK = 0; /** * The operation was cancelled (typically by the caller). */ const STATUS_CANCELLED = 1; /** * Unknown error. An example of where this error may be returned is * if a Status value received from another address space belongs to * an error-space that is not known in this address space. Also * errors raised by APIs that do not return enough error information * may be converted to this error. */ const STATUS_UNKNOWN = 2; /** * Client specified an invalid argument. Note that this differs * from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments * that are problematic regardless of the state of the system * (e.g., a malformed file name). */ const STATUS_INVALID_ARGUMENT = 3; /** * Deadline expired before operation could complete. For operations * that change the state of the system, this error may be returned * even if the operation has completed successfully. For example, a * successful response from a server could have been delayed long * enough for the deadline to expire. */ const STATUS_DEADLINE_EXCEEDED = 4; /** * Some requested entity (e.g., file or directory) was not found. */ const STATUS_NOT_FOUND = 5; /* Some entity that we attempted to create (e.g., file or directory) * already exists. */ const STATUS_ALREADY_EXISTS = 6; /** * The caller does not have permission to execute the specified * operation. PERMISSION_DENIED must not be used for rejections * caused by exhausting some resource (use RESOURCE_EXHAUSTED * instead for those errors). PERMISSION_DENIED must not be * used if the caller can not be identified (use UNAUTHENTICATED * instead for those errors). */ const STATUS_PERMISSION_DENIED = 7; /** * The request does not have valid authentication credentials for the * operation. */ const STATUS_UNAUTHENTICATED = 16; /** * Some resource has been exhausted, perhaps a per-user quota, or * perhaps the entire file system is out of space. */ const STATUS_RESOURCE_EXHAUSTED = 8; /** * Operation was rejected because the system is not in a state * required for the operation's execution. For example, directory * to be deleted may be non-empty, an rmdir operation is applied to * a non-directory, etc. * * A litmus test that may help a service implementor in deciding * between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE: * (a) Use UNAVAILABLE if the client can retry just the failing call. * (b) Use ABORTED if the client should retry at a higher-level * (e.g., restarting a read-modify-write sequence). * (c) Use FAILED_PRECONDITION if the client should not retry until * the system state has been explicitly fixed. E.g., if an "rmdir" * fails because the directory is non-empty, FAILED_PRECONDITION * should be returned since the client should not retry unless * they have first fixed up the directory by deleting files from it. * (d) Use FAILED_PRECONDITION if the client performs conditional * REST Get/Update/Delete on a resource and the resource on the * server does not match the condition. E.g., conflicting * read-modify-write on the same resource. */ const STATUS_FAILED_PRECONDITION = 9; /** * The operation was aborted, typically due to a concurrency issue * like sequencer check failures, transaction aborts, etc. * * See litmus test above for deciding between FAILED_PRECONDITION, * ABORTED, and UNAVAILABLE. */ const STATUS_ABORTED = 10; /** * Operation was attempted past the valid range. E.g., seeking or * reading past end of file. * * Unlike INVALID_ARGUMENT, this error indicates a problem that may * be fixed if the system state changes. For example, a 32-bit file * system will generate INVALID_ARGUMENT if asked to read at an * offset that is not in the range [0,2^32-1], but it will generate * OUT_OF_RANGE if asked to read from an offset past the current * file size. * * There is a fair bit of overlap between FAILED_PRECONDITION and * OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific * error) when it applies so that callers who are iterating through * a space can easily look for an OUT_OF_RANGE error to detect when * they are done. */ const STATUS_OUT_OF_RANGE = 11; /** * Operation is not implemented or not supported/enabled in this service. */ const STATUS_UNIMPLEMENTED = 12; /** * Internal errors. Means some invariants expected by underlying * system has been broken. If you see one of these errors, * something is very broken. */ const STATUS_INTERNAL = 13; /** * The service is currently unavailable. This is a most likely a * transient condition and may be corrected by retrying with * a backoff. * * See litmus test above for deciding between FAILED_PRECONDITION, * ABORTED, and UNAVAILABLE. */ const STATUS_UNAVAILABLE = 14; /** * Unrecoverable data loss or corruption. */ const STATUS_DATA_LOSS = 15; /* * Register op type constants */ /** * Send initial metadata: one and only one instance MUST be sent for each * call, unless the call was cancelled - in which case this can be skipped. * This op completes after all bytes of metadata have been accepted by * outgoing flow control. */ const OP_SEND_INITIAL_METADATA = 0; /** * Send a message: 0 or more of these operations can occur for each call. * This op completes after all bytes for the message have been accepted by * outgoing flow control. */ const OP_SEND_MESSAGE = 1; /** Send a close from the client: one and only one instance MUST be sent from * the client, unless the call was cancelled - in which case this can be * skipped. * This op completes after all bytes for the call (including the close) * have passed outgoing flow control. */ const OP_SEND_CLOSE_FROM_CLIENT = 2; /** * Send status from the server: one and only one instance MUST be sent from * the server unless the call was cancelled - in which case this can be * skipped. * This op completes after all bytes for the call (including the status) * have passed outgoing flow control. */ const OP_SEND_STATUS_FROM_SERVER = 3; /** * Receive initial metadata: one and only one MUST be made on the client, * must not be made on the server. * This op completes after all initial metadata has been read from the * peer. */ const OP_RECV_INITIAL_METADATA = 4; /** * Receive a message: 0 or more of these operations can occur for each call. * This op completes after all bytes of the received message have been * read, or after a half-close has been received on this call. */ const OP_RECV_MESSAGE = 5; /** * Receive status on the client: one and only one must be made on the client. * This operation always succeeds, meaning ops paired with this operation * will also appear to succeed, even though they may not have. In that case * the status will indicate some failure. * This op completes after all activity on the call has completed. */ const OP_RECV_STATUS_ON_CLIENT = 6; /** * Receive close on the server: one and only one must be made on the * server. * This op completes after the close has been received by the server. * This operation always succeeds, meaning ops paired with this operation * will also appear to succeed, even though they may not have. */ const OP_RECV_CLOSE_ON_SERVER = 7; /* * Register connectivity state constants */ /** * channel is idle */ const CHANNEL_IDLE = 0; /** * channel is connecting */ const CHANNEL_CONNECTING = 1; /** * channel is ready for work */ const CHANNEL_READY = 2; /** * channel has seen a failure but expects to recover */ const CHANNEL_TRANSIENT_FAILURE = 3; /** * channel has seen a failure that it cannot recover from */ const CHANNEL_SHUTDOWN = 4; const CHANNEL_FATAL_FAILURE = 4; /** * Class Server * @see https://github.com/grpc/grpc/tree/master/src/php/ext/grpc */ class Server { /** * Constructs a new instance of the Server class * * @param array $args The arguments to pass to the server (optional) */ public function __construct(array $args) {} /** * Request a call on a server. Creates a single GRPC_SERVER_RPC_NEW event. * * @param int $tag_new The tag to associate with the new request * @param int $tag_cancel The tag to use if the call is cancelled */ public function requestCall($tag_new, $tag_cancel) {} /** * Add a http2 over tcp listener. * * @param string $addr The address to add * * @return bool true on success, false on failure */ public function addHttp2Port($addr) {} /** * Add a secure http2 over tcp listener. * * @param string $addr The address to add * @param ServerCredentials $creds_obj * * @return bool true on success, false on failure */ public function addSecureHttp2Port($addr, $creds_obj) {} /** * Start a server - tells all listeners to start listening */ public function start() {} } /** * Class ServerCredentials * @see https://github.com/grpc/grpc/tree/master/src/php/ext/grpc */ class ServerCredentials { /** * Create SSL credentials. * * @param string $pem_root_certs PEM encoding of the server root certificates * @param string $pem_private_key PEM encoding of the client's private key * @param string $pem_cert_chain PEM encoding of the client's certificate chain * * @return object Credentials The new SSL credentials object * @throws \InvalidArgumentException */ public static function createSsl( $pem_root_certs, $pem_private_key, $pem_cert_chain ) {} } /** * Class Channel * @see https://github.com/grpc/grpc/tree/master/src/php/ext/grpc */ class Channel { /** * Construct an instance of the Channel class. If the $args array contains a * "credentials" key mapping to a ChannelCredentials object, a secure channel * will be created with those credentials. * * @param string $target The hostname to associate with this channel * @param array $args The arguments to pass to the Channel (optional) * * @throws \InvalidArgumentException */ public function __construct($target, $args = []) {} /** * Get the endpoint this call/stream is connected to * * @return string The URI of the endpoint */ public function getTarget() {} /** * Get the connectivity state of the channel * * @param bool $try_to_connect try to connect on the channel * * @return int The grpc connectivity state * @throws \InvalidArgumentException */ public function getConnectivityState($try_to_connect = false) {} /** * Watch the connectivity state of the channel until it changed * * @param int $last_state The previous connectivity state of the channel * @param Timeval $deadline_obj The deadline this function should wait until * * @return bool If the connectivity state changes from last_state * before deadline * @throws \InvalidArgumentException */ public function watchConnectivityState($last_state, Timeval $deadline_obj) {} /** * Close the channel */ public function close() {} } /** * Class ChannelCredentials * @see https://github.com/grpc/grpc/tree/master/src/php/ext/grpc */ class ChannelCredentials { /** * Set default roots pem. * * @param string $pem_roots PEM encoding of the server root certificates * * @throws \InvalidArgumentException */ public static function setDefaultRootsPem($pem_roots) {} /** * Create a default channel credentials object. * * @return ChannelCredentials The new default channel credentials object */ public static function createDefault() {} /** * Create SSL credentials. * * @param string|null $pem_root_certs PEM encoding of the server root certificates * @param string|null $pem_private_key PEM encoding of the client's private key * @param string|null $pem_cert_chain PEM encoding of the client's certificate chain * * @return ChannelCredentials The new SSL credentials object * @throws \InvalidArgumentException */ public static function createSsl( string $pem_root_certs = null, string $pem_private_key = null, string $pem_cert_chain = null ) {} /** * Create composite credentials from two existing credentials. * * @param ChannelCredentials $cred1 The first credential * @param CallCredentials $cred2 The second credential * * @return ChannelCredentials The new composite credentials object * @throws \InvalidArgumentException */ public static function createComposite( ChannelCredentials $cred1, CallCredentials $cred2 ) {} /** * Create insecure channel credentials * * @return null */ public static function createInsecure() {} } /** * Class Call * @see https://github.com/grpc/grpc/tree/master/src/php/ext/grpc */ class Call { /** * Constructs a new instance of the Call class. * * @param Channel $channel The channel to associate the call with. * Must not be closed. * @param string $method The method to call * @param Timeval $absolute_deadline The deadline for completing the call * @param null|string $host_override The host is set by user (optional) * * @throws \InvalidArgumentException */ public function __construct( Channel $channel, $method, Timeval $absolute_deadline, $host_override = null ) {} /** * Start a batch of RPC actions. * * @param array $batch Array of actions to take * * @return object Object with results of all actions * @throws \InvalidArgumentException * @throws \LogicException */ public function startBatch(array $batch) {} /** * Set the CallCredentials for this call. * * @param CallCredentials $creds_obj The CallCredentials object * * @return int The error code * @throws \InvalidArgumentException */ public function setCredentials(CallCredentials $creds_obj) {} /** * Get the endpoint this call/stream is connected to * * @return string The URI of the endpoint */ public function getPeer() {} /** * Cancel the call. This will cause the call to end with STATUS_CANCELLED if it * has not already ended with another status. */ public function cancel() {} } /** * Class CallCredentials * @see https://github.com/grpc/grpc/tree/master/src/php/ext/grpc */ class CallCredentials { /** * Create composite credentials from two existing credentials. * * @param CallCredentials $cred1 The first credential * @param CallCredentials $cred2 The second credential * * @return CallCredentials The new composite credentials object * @throws \InvalidArgumentException */ public static function createComposite( CallCredentials $cred1, CallCredentials $cred2 ) {} /** * Create a call credentials object from the plugin API * * @param \Closure $callback The callback function * * @return CallCredentials The new call credentials object * @throws \InvalidArgumentException */ public static function createFromPlugin(\Closure $callback) {} } /** * Class Timeval * * @see https://github.com/grpc/grpc/tree/master/src/php/ext/grpc */ class Timeval { /** * Constructs a new instance of the Timeval class * * @param int $usec The number of microseconds in the interval */ public function __construct($usec) {} /** * Adds another Timeval to this one and returns the sum. Calculations saturate * at infinities. * * @param Timeval $other The other Timeval object to add * * @return Timeval A new Timeval object containing the sum * @throws \InvalidArgumentException */ public function add(Timeval $other) {} /** * Return negative, 0, or positive according to whether a < b, a == b, or a > b * respectively. * * @param Timeval $a The first time to compare * @param Timeval $b The second time to compare * * @return int * @throws \InvalidArgumentException */ public static function compare(Timeval $a, Timeval $b) {} /** * Returns the infinite future time value as a timeval object * * @return Timeval Infinite future time value */ public static function infFuture() {} /** * Returns the infinite past time value as a timeval object * * @return Timeval Infinite past time value */ public static function infPast() {} /** * Returns the current time as a timeval object * * @return Timeval The current time */ public static function now() {} /** * Checks whether the two times are within $threshold of each other * * @param Timeval $a The first time to compare * @param Timeval $b The second time to compare * @param Timeval $threshold The threshold to check against * * @return bool True if $a and $b are within $threshold, False otherwise * @throws \InvalidArgumentException */ public static function similar(Timeval $a, Timeval $b, Timeval $threshold) {} /** * Sleep until this time, interpreted as an absolute timeout */ public function sleepUntil() {} /** * Subtracts another Timeval from this one and returns the difference. * Calculations saturate at infinities. * * @param Timeval $other The other Timeval object to subtract * * @return Timeval A new Timeval object containing the sum * @throws \InvalidArgumentException */ public function subtract(Timeval $other) {} /** * Returns the zero time interval as a timeval object * * @return Timeval Zero length time interval */ public static function zero() {} } DOMElement object from a SimpleXMLElement object * @link https://php.net/manual/en/function.dom-import-simplexml.php * @param SimpleXMLElement $node

* The SimpleXMLElement node. *

* @return DOMElement|null The DOMElement node added or NULL if any errors occur. */ #[LanguageLevelTypeAware(['8.0' => 'DOMElement'], default: 'DOMElement|null')] function dom_import_simplexml(object $node) {} /** * Node is a DOMElement * @link https://php.net/manual/en/dom.constants.php */ define('XML_ELEMENT_NODE', 1); /** * Node is a DOMAttr * @link https://php.net/manual/en/dom.constants.php */ define('XML_ATTRIBUTE_NODE', 2); /** * Node is a DOMText * @link https://php.net/manual/en/dom.constants.php */ define('XML_TEXT_NODE', 3); /** * Node is a DOMCharacterData * @link https://php.net/manual/en/dom.constants.php */ define('XML_CDATA_SECTION_NODE', 4); /** * Node is a DOMEntityReference * @link https://php.net/manual/en/dom.constants.php */ define('XML_ENTITY_REF_NODE', 5); /** * Node is a DOMEntity * @link https://php.net/manual/en/dom.constants.php */ define('XML_ENTITY_NODE', 6); /** * Node is a DOMProcessingInstruction * @link https://php.net/manual/en/dom.constants.php */ define('XML_PI_NODE', 7); /** * Node is a DOMComment * @link https://php.net/manual/en/dom.constants.php */ define('XML_COMMENT_NODE', 8); /** * Node is a DOMDocument * @link https://php.net/manual/en/dom.constants.php */ define('XML_DOCUMENT_NODE', 9); /** * Node is a DOMDocumentType * @link https://php.net/manual/en/dom.constants.php */ define('XML_DOCUMENT_TYPE_NODE', 10); /** * Node is a DOMDocumentFragment * @link https://php.net/manual/en/dom.constants.php */ define('XML_DOCUMENT_FRAG_NODE', 11); /** * Node is a DOMNotation * @link https://php.net/manual/en/dom.constants.php */ define('XML_NOTATION_NODE', 12); define('XML_HTML_DOCUMENT_NODE', 13); define('XML_DTD_NODE', 14); define('XML_ELEMENT_DECL_NODE', 15); define('XML_ATTRIBUTE_DECL_NODE', 16); define('XML_ENTITY_DECL_NODE', 17); define('XML_NAMESPACE_DECL_NODE', 18); define('XML_LOCAL_NAMESPACE', 18); define('XML_ATTRIBUTE_CDATA', 1); define('XML_ATTRIBUTE_ID', 2); define('XML_ATTRIBUTE_IDREF', 3); define('XML_ATTRIBUTE_IDREFS', 4); define('XML_ATTRIBUTE_ENTITY', 6); define('XML_ATTRIBUTE_NMTOKEN', 7); define('XML_ATTRIBUTE_NMTOKENS', 8); define('XML_ATTRIBUTE_ENUMERATION', 9); define('XML_ATTRIBUTE_NOTATION', 10); /** * Error code not part of the DOM specification. Meant for PHP errors. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_PHP_ERR', 0); /** * If index or size is negative, or greater than the allowed value. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_INDEX_SIZE_ERR', 1); /** * If the specified range of text does not fit into a * DOMString. * @link https://php.net/manual/en/dom.constants.php */ define('DOMSTRING_SIZE_ERR', 2); /** * If any node is inserted somewhere it doesn't belong * @link https://php.net/manual/en/dom.constants.php */ define('DOM_HIERARCHY_REQUEST_ERR', 3); /** * If a node is used in a different document than the one that created it. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_WRONG_DOCUMENT_ERR', 4); /** * If an invalid or illegal character is specified, such as in a name. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_INVALID_CHARACTER_ERR', 5); /** * If data is specified for a node which does not support data. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_NO_DATA_ALLOWED_ERR', 6); /** * If an attempt is made to modify an object where modifications are not allowed. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_NO_MODIFICATION_ALLOWED_ERR', 7); /** * If an attempt is made to reference a node in a context where it does not exist. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_NOT_FOUND_ERR', 8); /** * If the implementation does not support the requested type of object or operation. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_NOT_SUPPORTED_ERR', 9); /** * If an attempt is made to add an attribute that is already in use elsewhere. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_INUSE_ATTRIBUTE_ERR', 10); /** * If an attempt is made to use an object that is not, or is no longer, usable. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_INVALID_STATE_ERR', 11); /** * If an invalid or illegal string is specified. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_SYNTAX_ERR', 12); /** * If an attempt is made to modify the type of the underlying object. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_INVALID_MODIFICATION_ERR', 13); /** * If an attempt is made to create or change an object in a way which is * incorrect with regard to namespaces. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_NAMESPACE_ERR', 14); /** * If a parameter or an operation is not supported by the underlying object. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_INVALID_ACCESS_ERR', 15); /** * If a call to a method such as insertBefore or removeChild would make the Node * invalid with respect to "partial validity", this exception would be raised and * the operation would not be done. * @link https://php.net/manual/en/dom.constants.php */ define('DOM_VALIDATION_ERR', 16); // End of dom v.20031129 'string'], default: '')] public $nodeName; /** * @var string|null * The value of this node, depending on its type * @link https://php.net/manual/en/class.domnode.php#domnode.props.nodevalue */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $nodeValue; /** * @var int * Gets the type of the node. One of the predefined * XML_xxx_NODE constants * @link https://php.net/manual/en/class.domnode.php#domnode.props.nodetype */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $nodeType; /** * @var DOMNode|null * The parent of this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.parentnode */ #[LanguageLevelTypeAware(['8.1' => 'DOMNode|null'], default: '')] public $parentNode; /** * @var DOMNodeList * A DOMNodeList that contains all children of this node. If there are no children, this is an empty DOMNodeList. * @link https://php.net/manual/en/class.domnode.php#domnode.props.childnodes */ #[LanguageLevelTypeAware(['8.1' => 'DOMNodeList'], default: '')] public $childNodes; /** * @var DOMNode|null * The first child of this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.firstchild */ #[LanguageLevelTypeAware(['8.1' => 'DOMNode|null'], default: '')] public $firstChild; /** * @var DOMNode|null * The last child of this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.lastchild */ #[LanguageLevelTypeAware(['8.1' => 'DOMNode|null'], default: '')] public $lastChild; /** * @var DOMNode|null * The node immediately preceding this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.previoussibling */ #[LanguageLevelTypeAware(['8.1' => 'DOMNode|null'], default: '')] public $previousSibling; /** * @var DOMNode|null * The node immediately following this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.nextsibling */ #[LanguageLevelTypeAware(['8.1' => 'DOMNode|null'], default: '')] public $nextSibling; /** * @var DOMNamedNodeMap|null * A DOMNamedNodeMap containing the attributes of this node (if it is a DOMElement) or NULL otherwise. * @link https://php.net/manual/en/class.domnode.php#domnode.props.attributes */ #[LanguageLevelTypeAware(['8.1' => 'DOMNamedNodeMap|null'], default: '')] public $attributes; /** * @var DOMDocument|null * The DOMDocument object associated with this node, or NULL if this node is a DOMDocument. * @link https://php.net/manual/en/class.domnode.php#domnode.props.ownerdocument */ #[LanguageLevelTypeAware(['8.1' => 'DOMDocument|null'], default: '')] public $ownerDocument; /** * @var string|null * The namespace URI of this node, or NULL if it is unspecified. * @link https://php.net/manual/en/class.domnode.php#domnode.props.namespaceuri */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $namespaceURI; /** * @var string|null * The namespace prefix of this node, or NULL if it is unspecified. * @link https://php.net/manual/en/class.domnode.php#domnode.props.prefix */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $prefix; /** * @var string|null * Returns the local part of the qualified name of this node. * @link https://php.net/manual/en/class.domnode.php#domnode.props.localname */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $localName; /** * @var string|null * The absolute base URI of this node or NULL if the implementation wasn't able to obtain an absolute URI. * @link https://php.net/manual/en/class.domnode.php#domnode.props.baseuri */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $baseURI; /** * @var string * This attribute returns the text content of this node and its descendants. * @link https://php.net/manual/en/class.domnode.php#domnode.props.textcontent */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $textContent; #[PhpStormStubsElementAvailable(from: '8.3')] public bool $isConnected; #[PhpStormStubsElementAvailable(from: '8.3')] public ?DOMElement $parentElement; /** * Adds a new child before a reference node * @link https://php.net/manual/en/domnode.insertbefore.php * @param DOMNode $node

* The new node. *

* @param null|DOMNode $child [optional]

* The reference node. If not supplied, newnode is * appended to the children. *

* @return DOMNode The inserted node. */ public function insertBefore( DOMNode $node, #[LanguageLevelTypeAware(['8.0' => 'DOMNode|null'], default: 'DOMNode')] $child = null ) {} /** * Replaces a child * @link https://php.net/manual/en/domnode.replacechild.php * @param DOMNode $node

* The new node. It must be a member of the target document, i.e. * created by one of the DOMDocument->createXXX() methods or imported in * the document by . *

* @param DOMNode $child

* The old node. *

* @return DOMNode|false The old node or false if an error occur. */ public function replaceChild(DOMNode $node, DOMNode $child) {} /** * Removes child from list of children * @link https://php.net/manual/en/domnode.removechild.php * @param DOMNode $child

* The removed child. *

* @return DOMNode If the child could be removed the functions returns the old child. */ public function removeChild(DOMNode $child) {} /** * Adds new child at the end of the children * @link https://php.net/manual/en/domnode.appendchild.php * @param DOMNode $node

* The appended child. *

* @return DOMNode The node added. */ public function appendChild(DOMNode $node) {} /** * Checks if node has children * @link https://php.net/manual/en/domnode.haschildnodes.php * @return bool true on success or false on failure. */ #[TentativeType] public function hasChildNodes(): bool {} /** * Clones a node * @link https://php.net/manual/en/domnode.clonenode.php * @param bool $deep

* Indicates whether to copy all descendant nodes. This parameter is * defaulted to false. *

* @return static The cloned node. */ public function cloneNode( #[PhpStormStubsElementAvailable(from: '5.3', to: '5.6')] $deep, #[PhpStormStubsElementAvailable(from: '7.0')] #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $deep = false ) {} /** * Normalizes the node * @link https://php.net/manual/en/domnode.normalize.php * @return void */ #[TentativeType] public function normalize(): void {} /** * Checks if feature is supported for specified version * @link https://php.net/manual/en/domnode.issupported.php * @param string $feature

* The feature to test. See the example of * DOMImplementation::hasFeature for a * list of features. *

* @param string $version

* The version number of the feature to test. *

* @return bool true on success or false on failure. */ #[TentativeType] public function isSupported( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $feature, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $version ): bool {} /** * Checks if node has attributes * @link https://php.net/manual/en/domnode.hasattributes.php * @return bool true on success or false on failure. */ #[TentativeType] public function hasAttributes(): bool {} /** * @return int */ #[LanguageLevelTypeAware(['8.4' => 'int'], default: '')] public function compareDocumentPosition(DOMNode $other) {} /** * Indicates if two nodes are the same node * @link https://php.net/manual/en/domnode.issamenode.php * @param DOMNode $otherNode

* The compared node. *

* @return bool true on success or false on failure. */ #[TentativeType] public function isSameNode(DOMNode $otherNode): bool {} /** * Gets the namespace prefix of the node based on the namespace URI * @link https://php.net/manual/en/domnode.lookupprefix.php * @param string $namespace

* The namespace URI. *

* @return string The prefix of the namespace. */ #[TentativeType] public function lookupPrefix(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $namespace): ?string {} /** * Checks if the specified namespaceURI is the default namespace or not * @link https://php.net/manual/en/domnode.isdefaultnamespace.php * @param string $namespace

* The namespace URI to look for. *

* @return bool Return true if namespaceURI is the default * namespace, false otherwise. */ #[TentativeType] public function isDefaultNamespace(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $namespace): bool {} /** * Gets the namespace URI of the node based on the prefix * @link https://php.net/manual/en/domnode.lookupnamespaceuri.php * @param string|null $prefix

* The prefix of the namespace. *

* @return string|null The namespace URI of the node. */ #[PhpStormStubsElementAvailable(from: '8.0')] #[TentativeType] public function lookupNamespaceURI(?string $prefix): ?string {} /** * Gets the namespace URI of the node based on the prefix * @link https://php.net/manual/en/domnode.lookupnamespaceuri.php * @param string|null $prefix

* The prefix of the namespace. *

* @return string|null The namespace URI of the node. */ #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] public function lookupNamespaceUri($prefix) {} /** * @param DOMNode|null $arg * @return bool */ #[LanguageLevelTypeAware(['8.3' => 'bool'], default: '')] public function isEqualNode(#[LanguageLevelTypeAware(['8.3' => 'DOMNode|null'], default: 'DOMNode')] $otherNode) {} public function getFeature($feature, $version) {} public function setUserData($key, $data, $handler) {} public function getUserData($key) {} /** * Gets an XPath location path for the node * @return string|null the XPath, or NULL in case of an error. * @link https://secure.php.net/manual/en/domnode.getnodepath.php */ #[TentativeType] public function getNodePath(): ?string {} /** * Get line number for a node * @link https://php.net/manual/en/domnode.getlineno.php * @return int Always returns the line number where the node was defined in. */ #[TentativeType] public function getLineNo(): int {} /** * Canonicalize nodes to a string * @param bool $exclusive [optional] Enable exclusive parsing of only the nodes matched by the provided xpath or namespace prefixes. * @param bool $withComments [optional] Retain comments in output. * @param null|array $xpath [optional] An array of xpaths to filter the nodes by. * @param null|array $nsPrefixes [optional] An array of namespace prefixes to filter the nodes by. * @return string|false Canonicalized nodes as a string or FALSE on failure */ #[TentativeType] public function C14N( #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $exclusive = false, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $withComments = false, #[LanguageLevelTypeAware(['8.0' => 'array|null'], default: 'array')] $xpath = null, #[LanguageLevelTypeAware(['8.0' => 'array|null'], default: 'array')] $nsPrefixes = null ): string|false {} /** * Canonicalize nodes to a file. * @link https://www.php.net/manual/en/domnode.c14nfile * @param string $uri Number of bytes written or FALSE on failure * @param bool $exclusive [optional] Enable exclusive parsing of only the nodes matched by the provided xpath or namespace prefixes. * @param bool $withComments [optional] Retain comments in output. * @param null|array $xpath [optional] An array of xpaths to filter the nodes by. * @param null|array $nsPrefixes [optional] An array of namespace prefixes to filter the nodes by. * @return int|false Number of bytes written or FALSE on failure */ #[TentativeType] public function C14NFile( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $uri, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $exclusive = false, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $withComments = false, #[LanguageLevelTypeAware(['8.0' => 'array|null'], default: 'array')] $xpath = null, #[LanguageLevelTypeAware(['8.0' => 'array|null'], default: 'array')] $nsPrefixes = null ): int|false {} /** * @since 8.3 */ public function contains(DOMNode|DOMNameSpaceNode|null $other): bool {} /** * @since 8.3 */ public function getRootNode(?array $options = null): DOMNode {} /** * @since 8.1 */ public function __sleep(): array {} /** * @since 8.1 */ public function __wakeup(): void {} } /** * DOM operations raise exceptions under particular circumstances, i.e., * when an operation is impossible to perform for logical reasons. * @link https://php.net/manual/en/class.domexception.php */ final class DOMException extends Exception { /** * @link https://php.net/manual/en/class.domexception.php#domexception.props.code * @var int An integer indicating the type of error generated */ public $code; } class DOMStringList { /** * @param $index * @return mixed */ public function item($index) {} } /** * @link https://php.net/manual/en/ref.dom.php * @removed 8.0 */ class DOMNameList { /** * @param $index * @return mixed */ public function getName($index) {} /** * @param $index * @return mixed */ public function getNamespaceURI($index) {} } /** * @removed 8.0 */ class DOMImplementationList { /** * @param $index * @return mixed */ public function item($index) {} } /** * @removed 8.0 */ class DOMImplementationSource { /** * @param $features * @return mixed */ public function getDomimplementation($features) {} /** * @param $features * @return mixed */ public function getDomimplementations($features) {} } /** * The DOMImplementation interface provides a number * of methods for performing operations that are independent of any * particular instance of the document object model. * @link https://php.net/manual/en/class.domimplementation.php */ class DOMImplementation { /** * @param string $feature * @param string $version * @return mixed */ #[TentativeType] public function getFeature( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $feature, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $version ): never {} /** * Test if the DOM implementation implements a specific feature * @link https://php.net/manual/en/domimplementation.hasfeature.php * @param string $feature

* The feature to test. *

* @param string $version

* The version number of the feature to test. In * level 2, this can be either 2.0 or 1.0. *

* @return bool true on success or false on failure. */ public function hasFeature($feature, $version) {} /** * Creates an empty DOMDocumentType object * @link https://php.net/manual/en/domimplementation.createdocumenttype.php * @param string $qualifiedName

* The qualified name of the document type to create. *

* @param string $publicId

* The external subset public identifier. *

* @param string $systemId

* The external subset system identifier. *

* @return DOMDocumentType|false A new DOMDocumentType node with its * ownerDocument set to null. * @throws DOMException If there is an error with the namespace */ public function createDocumentType( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $publicId, #[PhpStormStubsElementAvailable(from: '8.0')] string $publicId = '', #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $systemId, #[PhpStormStubsElementAvailable(from: '8.0')] string $systemId = '' ) {} /** * Creates a DOMDocument object of the specified type with its document element * @link https://php.net/manual/en/domimplementation.createdocument.php * @param string|null $namespace

* The namespace URI of the document element to create. *

* @param string $qualifiedName

* The qualified name of the document element to create. *

* @param DOMDocumentType|null $doctype

* The type of document to create or null. *

* @return DOMDocument|false A new DOMDocument object. If * namespaceURI, qualifiedName, and doctype are null, the * returned DOMDocument is empty with no document element. * @throws DOMException If $doctype has already been used * with adifferent document or was created from a different * implementation. If there is an error with the namespace, * as determined by $namespace and $qualifiedName. */ #[LanguageLevelTypeAware(['8.4' => 'DOMDocument'], default: 'DOMDocument|false')] #[TentativeType] public function createDocument( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $namespace, #[PhpStormStubsElementAvailable(from: '8.0')] ?string $namespace = null, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $qualifiedName, #[PhpStormStubsElementAvailable(from: '8.0')] string $qualifiedName = '', #[PhpStormStubsElementAvailable(from: '5.3', to: '7.3')] DOMDocumentType $doctype, #[PhpStormStubsElementAvailable(from: '7.4')] #[LanguageLevelTypeAware(['8.0' => 'DOMDocumentType|null'], default: 'DOMDocumentType')] $doctype = null ) {} } class DOMNameSpaceNode { #[LanguageLevelTypeAware(['8.1' => 'DOMNode|null'], default: '')] public $parentNode; #[LanguageLevelTypeAware(['8.1' => 'DOMDocument|null'], default: '')] public $ownerDocument; #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $namespaceURI; #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $localName; #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $prefix; #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $nodeType; #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $nodeValue; #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $nodeName; public ?DOMElement $parentElement; public bool $isConnected; /** * @since 8.1 */ public function __sleep(): array {} /** * @since 8.1 */ public function __wakeup(): void {} } /** * The DOMDocumentFragment class * @link https://php.net/manual/en/class.domdocumentfragment.php */ class DOMDocumentFragment extends DOMNode implements DOMParentNode { #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $childElementCount; #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $lastElementChild; #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $firstElementChild; public function __construct() {} /** * Append raw XML data * @link https://php.net/manual/en/domdocumentfragment.appendxml.php * @param string $data

* XML to append. *

* @return bool true on success or false on failure. */ #[TentativeType] public function appendXML(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data): bool {} /** * {@inheritDoc} */ public function append(...$nodes): void {} /** * {@inheritDoc} */ public function prepend(...$nodes): void {} /** * @since 8.3 * {@inheritDoc} */ public function replaceChildren(...$nodes): void {} } /** * The DOMDocument class represents an entire HTML or XML * document; serves as the root of the document tree. * @link https://php.net/manual/en/class.domdocument.php */ class DOMDocument extends DOMNode implements DOMParentNode { /** * @var string|null * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.actualencoding */ #[Deprecated("Actual encoding of the document, is a readonly equivalent to encoding.")] #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $actualEncoding; /** * @var DOMConfiguration * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.config * @see DOMDocument::normalizeDocument() */ #[Deprecated("Configuration used when DOMDocument::normalizeDocument() is invoked.")] #[LanguageLevelTypeAware(['8.1' => 'mixed'], default: '')] public $config; /** * @var DOMDocumentType * The Document Type Declaration associated with this document. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.doctype */ #[LanguageLevelTypeAware(['8.1' => 'DOMDocumentType|null'], default: '')] public $doctype; /** * @var DOMElement * This is a convenience attribute that allows direct access to the child node * that is the document element of the document. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.documentelement */ #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $documentElement; /** * @var string|null * The location of the document or NULL if undefined. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.documenturi */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $documentURI; /** * @var string|null * Encoding of the document, as specified by the XML declaration. This attribute is not present * in the final DOM Level 3 specification, but is the only way of manipulating XML document * encoding in this implementation. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.encoding */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $encoding; /** * @var bool * Nicely formats output with indentation and extra space. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.formatoutput */ #[LanguageLevelTypeAware(['8.1' => 'bool'], default: '')] public $formatOutput; /** * @var DOMImplementation * The DOMImplementation object that handles this document. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.implementation */ #[LanguageLevelTypeAware(['8.1' => 'DOMImplementation'], default: '')] public $implementation; /** * @var bool * Do not remove redundant white space. Default to TRUE. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.preservewhitespace */ #[LanguageLevelTypeAware(['8.1' => 'bool'], default: '')] public $preserveWhiteSpace = true; /** * @var bool * Proprietary. Enables recovery mode, i.e. trying to parse non-well formed documents. * This attribute is not part of the DOM specification and is specific to libxml. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.recover */ #[LanguageLevelTypeAware(['8.1' => 'bool'], default: '')] public $recover; /** * @var bool * Set it to TRUE to load external entities from a doctype declaration. This is useful for * including character entities in your XML document. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.resolveexternals */ #[LanguageLevelTypeAware(['8.1' => 'bool'], default: '')] public $resolveExternals; /** * @var bool * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.standalone */ #[Deprecated("Whether or not the document is standalone, as specified by the XML declaration, corresponds to xmlStandalone.")] #[LanguageLevelTypeAware(['8.1' => 'bool'], default: '')] public $standalone; /** * @var bool * Throws DOMException on errors. Default to TRUE. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.stricterrorchecking */ #[LanguageLevelTypeAware(['8.1' => 'bool'], default: '')] public $strictErrorChecking = true; /** * @var bool * Proprietary. Whether or not to substitute entities. This attribute is not part of the DOM * specification and is specific to libxml. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.substituteentities */ #[LanguageLevelTypeAware(['8.1' => 'bool'], default: '')] public $substituteEntities; /** * @var bool * Loads and validates against the DTD. Default to FALSE. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.validateonparse */ #[LanguageLevelTypeAware(['8.1' => 'bool'], default: '')] public $validateOnParse = false; /** * @var string * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.version */ #[Deprecated('Version of XML, corresponds to xmlVersion')] #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $version; /** * @var string|null * An attribute specifying, as part of the XML declaration, the encoding of this document. This is NULL when * unspecified or when it is not known, such as when the Document was created in memory. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.xmlencoding */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $xmlEncoding; /** * @var bool * An attribute specifying, as part of the XML declaration, whether this document is standalone. * This is FALSE when unspecified. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.xmlstandalone */ #[LanguageLevelTypeAware(['8.1' => 'bool'], default: '')] public $xmlStandalone; /** * @var string|null * An attribute specifying, as part of the XML declaration, the version number of this document. If there is no * declaration and if this document supports the "XML" feature, the value is "1.0". * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.xmlversion */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $xmlVersion; #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $childElementCount; #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $lastElementChild; #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $firstElementChild; /** * Create new element node * @link https://php.net/manual/en/domdocument.createelement.php * @param string $localName

* The tag name of the element. *

* @param string $value [optional]

* The value of the element. By default, an empty element will be created. * You can also set the value later with DOMElement->nodeValue. *

* @return DOMElement|false A new instance of class DOMElement or false * if an error occurred. * @throws DOMException If invalid $localName */ public function createElement( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $localName, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $value = '' ) {} /** * Create new document fragment * @link https://php.net/manual/en/domdocument.createdocumentfragment.php * @return DOMDocumentFragment|false The new DOMDocumentFragment or false if an error occurred. */ #[TentativeType] public function createDocumentFragment(): DOMDocumentFragment {} /** * Create new text node * @link https://php.net/manual/en/domdocument.createtextnode.php * @param string $data

* The content of the text. *

* @return DOMText|false The new DOMText or false if an error occurred. */ #[TentativeType] public function createTextNode(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data): DOMText {} /** * Create new comment node * @link https://php.net/manual/en/domdocument.createcomment.php * @param string $data

* The content of the comment. *

* @return DOMComment|false The new DOMComment or false if an error occurred. */ #[TentativeType] public function createComment(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data): DOMComment {} /** * Create new cdata node * @link https://php.net/manual/en/domdocument.createcdatasection.php * @param string $data

* The content of the cdata. *

* @return DOMCDATASection|false The new DOMCDATASection or false if an error occurred. */ public function createCDATASection(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data) {} /** * Creates new PI node * @link https://php.net/manual/en/domdocument.createprocessinginstruction.php * @param string $target

* The target of the processing instruction. *

* @param string $data

* The content of the processing instruction. *

* @return DOMProcessingInstruction|false The new DOMProcessingInstruction or false if an error occurred. */ public function createProcessingInstruction( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $target, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.3')] $data, #[PhpStormStubsElementAvailable(from: '7.4')] #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data = '' ) {} /** * Create new attribute * @link https://php.net/manual/en/domdocument.createattribute.php * @param string $localName

* The name of the attribute. *

* @return DOMAttr|false The new DOMAttr or false if an error occurred. * @throws DOMException If invalid $localName */ public function createAttribute(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $localName) {} /** * Create new entity reference node * @link https://php.net/manual/en/domdocument.createentityreference.php * @param string $name

* The content of the entity reference, e.g. the entity reference minus * the leading & and the trailing * ; characters. *

* @return DOMEntityReference|false The new DOMEntityReference or false if an error * occurred. */ public function createEntityReference(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name) {} /** * Searches for all elements with given tag name * @link https://php.net/manual/en/domdocument.getelementsbytagname.php * @param string $qualifiedName

* The name of the tag to match on. The special value * * matches all tags. *

* @return DOMNodeList A new DOMNodeList object containing all the matched * elements. */ #[TentativeType] public function getElementsByTagName(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName): DOMNodeList {} /** * Import node into current document * @link https://php.net/manual/en/domdocument.importnode.php * @param DOMNode $node

* The node to import. *

* @param bool $deep

* If set to true, this method will recursively import the subtree under * the importedNode. *

*

* To copy the nodes attributes deep needs to be set to true *

* @return DOMNode|false The copied node or false, if it cannot be copied. */ public function importNode( DOMNode $node, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.3')] $deep, #[PhpStormStubsElementAvailable(from: '7.4')] #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $deep = false ) {} /** * Create new element node with an associated namespace * @link https://php.net/manual/en/domdocument.createelementns.php * @param string|null $namespace

* The URI of the namespace. *

* @param string $qualifiedName

* The qualified name of the element, as prefix:tagname. *

* @param string $value [optional]

* The value of the element. By default, an empty element will be created. * You can also set the value later with DOMElement->nodeValue. *

* @return DOMElement|false The new DOMElement or false if an error occurred. * @throws DOMException If invalid $namespace or $qualifiedName */ public function createElementNS( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $value = '' ) {} /** * Create new attribute node with an associated namespace * @link https://php.net/manual/en/domdocument.createattributens.php * @param string|null $namespace

* The URI of the namespace. *

* @param string $qualifiedName

* The tag name and prefix of the attribute, as prefix:tagname. *

* @return DOMAttr|false The new DOMAttr or false if an error occurred. * @throws DOMException If invalid $namespace or $qualifiedName */ public function createAttributeNS( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName ) {} /** * Searches for all elements with given tag name in specified namespace * @link https://php.net/manual/en/domdocument.getelementsbytagnamens.php * @param string $namespace

* The namespace URI of the elements to match on. * The special value * matches all namespaces. *

* @param string $localName

* The local name of the elements to match on. * The special value * matches all local names. *

* @return DOMNodeList A new DOMNodeList object containing all the matched * elements. */ #[TentativeType] public function getElementsByTagNameNS( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $localName ): DOMNodeList {} /** * Searches for an element with a certain id * @link https://php.net/manual/en/domdocument.getelementbyid.php * @param string $elementId

* The unique id value for an element. *

* @return DOMElement|null The DOMElement or null if the element is * not found. */ #[TentativeType] public function getElementById(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $elementId): ?DOMElement {} #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'DOMNode|false'], default: '')] public function adoptNode(DOMNode $node) {} /** * {@inheritDoc} */ public function append(...$nodes): void {} /** * {@inheritDoc} */ public function prepend(...$nodes): void {} /** * @since 8.3 * {@inheritDoc} */ public function replaceChildren(...$nodes): void {} /** * Normalizes the document * @link https://php.net/manual/en/domdocument.normalizedocument.php * @return void */ #[TentativeType] public function normalizeDocument(): void {} /** * @param DOMNode $node * @param $namespace * @param $qualifiedName */ public function renameNode(DOMNode $node, $namespace, $qualifiedName) {} /** * Load XML from a file * @link https://php.net/manual/en/domdocument.load.php * @param string $filename

* The path to the XML document. *

* @param int $options [optional]

* Bitwise OR * of the libxml option constants. *

* @return DOMDocument|bool true on success or false on failure. Prior to PHP 8.3 if called statically, returns a * DOMDocument and issues E_STRICT * warning. */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'bool'], default: 'DOMDocument|bool')] public function load( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $options = 0 ) {} /** * Dumps the internal XML tree back into a file * @link https://php.net/manual/en/domdocument.save.php * @param string $filename

* The path to the saved XML document. *

* @param int $options [optional]

* Additional Options. Currently only LIBXML_NOEMPTYTAG is supported. *

* @return int|false the number of bytes written or false if an error occurred. */ public function save($filename, $options = null) {} /** * Load XML from a string * @link https://php.net/manual/en/domdocument.loadxml.php * @param string $source

* The string containing the XML. *

* @param int $options [optional]

* Bitwise OR * of the libxml option constants. *

* @return DOMDocument|bool true on success or false on failure. Prior to PHP 8.3 if called statically, returns a * DOMDocument and issues E_STRICT * warning. */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'bool'], default: 'DOMDocument|bool')] public function loadXML( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $source, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $options = 0 ) {} /** * Dumps the internal XML tree back into a string * @link https://php.net/manual/en/domdocument.savexml.php * @param null|DOMNode $node [optional]

* Use this parameter to output only a specific node without XML declaration * rather than the entire document. *

* @param int $options [optional]

* Additional Options. Currently only LIBXML_NOEMPTYTAG is supported. *

* @return string|false the XML, or false if an error occurred. */ #[TentativeType] public function saveXML( #[LanguageLevelTypeAware(['7.1' => '?DOMNode'], default: '')] $node = null, #[PhpStormStubsElementAvailable(from: '7.0')] #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $options = 0 ): string|false {} /** * Creates a new DOMDocument object * @link https://php.net/manual/en/domdocument.construct.php * @param string $version [optional] The version number of the document as part of the XML declaration. * @param string $encoding [optional] The encoding of the document as part of the XML declaration. */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $version = '1.0', #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $encoding = '' ) {} /** * Validates the document based on its DTD * @link https://php.net/manual/en/domdocument.validate.php * @return bool true on success or false on failure. * If the document have no DTD attached, this method will return false. */ #[TentativeType] public function validate(): bool {} /** * Substitutes XIncludes in a DOMDocument Object * @link https://php.net/manual/en/domdocument.xinclude.php * @param int $options [optional]

* libxml parameters. Available * since PHP 5.1.0 and Libxml 2.6.7. *

* @return int|false the number of XIncludes in the document. */ #[TentativeType] public function xinclude(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $options = 0): int|false {} /** * Load HTML from a string * @link https://php.net/manual/en/domdocument.loadhtml.php * @param string $source

* The HTML string. *

* @param int $options [optional]

* Since PHP 5.4.0 and Libxml 2.6.0, you may also * use the options parameter to specify additional Libxml parameters. *

* @return DOMDocument|bool true on success or false on failure. Prior to PHP 8.3 if called statically, returns a * DOMDocument and issues E_STRICT * warning. */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'bool'], default: 'DOMDocument|bool')] public function loadHTML( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $source, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $options = 0 ) {} /** * Load HTML from a file * @link https://php.net/manual/en/domdocument.loadhtmlfile.php * @param string $filename

* The path to the HTML file. *

* @param int $options [optional]

* Since PHP 5.4.0 and Libxml 2.6.0, you may also * use the options parameter to specify additional Libxml parameters. *

* @return DOMDocument|bool true on success or false on failure. Prior to PHP 8.3 if called statically, returns a * DOMDocument and issues E_STRICT * warning. */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'bool'], default: 'DOMDocument|bool')] public function loadHTMLFile( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $options = 0 ) {} /** * Dumps the internal document into a string using HTML formatting * @link https://php.net/manual/en/domdocument.savehtml.php * @param null|DOMNode $node [optional] parameter to output a subset of the document. * @return string|false The HTML, or false if an error occurred. */ public function saveHTML(DOMNode $node = null) {} /** * Dumps the internal document into a file using HTML formatting * @link https://php.net/manual/en/domdocument.savehtmlfile.php * @param string $filename

* The path to the saved HTML document. *

* @return int|false the number of bytes written or false if an error occurred. */ #[TentativeType] public function saveHTMLFile(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename): int|false {} /** * Validates a document based on a schema * @link https://php.net/manual/en/domdocument.schemavalidate.php * @param string $filename

* The path to the schema. *

* @param int $options [optional]

* Bitwise OR * of the libxml option constants. *

* @return bool true on success or false on failure. */ public function schemaValidate($filename, $options = null) {} /** * Validates a document based on a schema * @link https://php.net/manual/en/domdocument.schemavalidatesource.php * @param string $source

* A string containing the schema. *

* @param int $flags [optional]

A bitmask of Libxml schema validation flags. Currently the only supported value is LIBXML_SCHEMA_CREATE. * Available since PHP 5.5.2 and Libxml 2.6.14.

* @return bool true on success or false on failure. */ public function schemaValidateSource($source, $flags) {} /** * Performs relaxNG validation on the document * @link https://php.net/manual/en/domdocument.relaxngvalidate.php * @param string $filename

* The RNG file. *

* @return bool true on success or false on failure. */ #[TentativeType] public function relaxNGValidate(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename): bool {} /** * Performs relaxNG validation on the document * @link https://php.net/manual/en/domdocument.relaxngvalidatesource.php * @param string $source

* A string containing the RNG schema. *

* @return bool true on success or false on failure. */ #[TentativeType] public function relaxNGValidateSource(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $source): bool {} /** * Register extended class used to create base node type * @link https://php.net/manual/en/domdocument.registernodeclass.php * @param string $baseClass

* The DOM class that you want to extend. You can find a list of these * classes in the chapter introduction. *

* @param string $extendedClass

* Your extended class name. If null is provided, any previously * registered class extending baseclass will * be removed. *

* @return bool true on success or false on failure. */ #[TentativeType] #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] public function registerNodeClass( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $baseClass, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $extendedClass ) {} } /** * The DOMNodeList class * @link https://php.net/manual/en/class.domnodelist.php */ class DOMNodeList implements IteratorAggregate, Countable { /** * @var int * The number of nodes in the list. The range of valid child node indices is 0 to length - 1 inclusive. * @link https://php.net/manual/en/class.domnodelist.php#domnodelist.props.length */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] #[Immutable] public $length; /** * Retrieves a node specified by index * @link https://php.net/manual/en/domnodelist.item.php * @param int $index

* Index of the node into the collection. * The range of valid child node indices is 0 to length - 1 inclusive. *

* @return DOMElement|DOMNode|DOMNameSpaceNode|null The node at the indexth position in the * DOMNodeList, or null if that is not a valid * index. */ public function item(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index) {} /** * @return int<0, max> * @since 7.2 */ #[TentativeType] public function count(): int {} /** * @return Iterator * @since 8.0 */ public function getIterator(): Iterator {} } /** * The DOMNamedNodeMap class * @link https://php.net/manual/en/class.domnamednodemap.php * @property-read int $length The number of nodes in the map. The range of valid child node indices is 0 to length - 1 inclusive. */ class DOMNamedNodeMap implements IteratorAggregate, Countable { /** * The number of nodes in the map. The range of valid child node indices is 0 to length - 1 inclusive. * @var int * @readonly */ #[PhpStormStubsElementAvailable(from: '8.1')] public $length; /** * Retrieves a node specified by name * @link https://php.net/manual/en/domnamednodemap.getnameditem.php * @param string $qualifiedName

* The nodeName of the node to retrieve. *

* @return DOMNode|null A node (of any type) with the specified nodeName, or * null if no node is found. */ #[TentativeType] public function getNamedItem(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName): ?DOMNode {} /** * @param DOMNode $arg */ public function setNamedItem(DOMNode $arg) {} /** * @param $name [optional] */ public function removeNamedItem($name) {} /** * Retrieves a node specified by index * @link https://php.net/manual/en/domnamednodemap.item.php * @param int $index

* Index into this map. *

* @return DOMNode|null The node at the indexth position in the map, or null * if that is not a valid index (greater than or equal to the number of nodes * in this map). */ #[TentativeType] public function item( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.0')] $index = 0, #[PhpStormStubsElementAvailable(from: '7.1')] #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index ): ?DOMNode {} /** * Retrieves a node specified by local name and namespace URI * @link https://php.net/manual/en/domnamednodemap.getnameditemns.php * @param string $namespace

* The namespace URI of the node to retrieve. *

* @param string $localName

* The local name of the node to retrieve. *

* @return DOMNode|null A node (of any type) with the specified local name and namespace URI, or * null if no node is found. */ #[TentativeType] public function getNamedItemNS( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $namespaceURI = '', #[PhpStormStubsElementAvailable(from: '8.0')] ?string $namespace, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $localName = '', #[PhpStormStubsElementAvailable(from: '8.0')] string $localName ): ?DOMNode {} /** * @param DOMNode $arg [optional] */ public function setNamedItemNS(DOMNode $arg) {} /** * @param $namespace [optional] * @param $localName [optional] */ public function removeNamedItemNS($namespace, $localName) {} /** * @return int<0,max> * @since 7.2 */ #[TentativeType] public function count(): int {} /** * @return Iterator * @since 8.0 */ public function getIterator(): Iterator {} } /** * The DOMCharacterData class represents nodes with character data. * No nodes directly correspond to this class, but other nodes do inherit from it. * @link https://php.net/manual/en/class.domcharacterdata.php */ class DOMCharacterData extends DOMNode implements DOMChildNode { /** * @var string * The contents of the node. * @link https://php.net/manual/en/class.domcharacterdata.php#domcharacterdata.props.data */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $data; /** * @var int * The length of the contents. * @link https://php.net/manual/en/class.domcharacterdata.php#domcharacterdata.props.length */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $length; #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $nextElementSibling; #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $previousElementSibling; /** * Extracts a range of data from the node * @link https://php.net/manual/en/domcharacterdata.substringdata.php * @param int $offset

* Start offset of substring to extract. *

* @param int $count

* The number of characters to extract. *

* @return string The specified substring. If the sum of offset * and count exceeds the length, then all 16-bit units * to the end of the data are returned. */ public function substringData( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $count ) {} /** * Append the string to the end of the character data of the node * @link https://php.net/manual/en/domcharacterdata.appenddata.php * @param string $data

* The string to append. *

*/ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function appendData(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data) {} /** * Insert a string at the specified 16-bit unit offset * @link https://php.net/manual/en/domcharacterdata.insertdata.php * @param int $offset

* The character offset at which to insert. *

* @param string $data

* The string to insert. *

* @return bool */ #[TentativeType] public function insertData( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data ): bool {} /** * Remove a range of characters from the node * @link https://php.net/manual/en/domcharacterdata.deletedata.php * @param int $offset

* The offset from which to start removing. *

* @param int $count

* The number of characters to delete. If the sum of * offset and count exceeds * the length, then all characters to the end of the data are deleted. *

* @return void */ #[TentativeType] public function deleteData( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $count ): bool {} /** * Replace a substring within the DOMCharacterData node * @link https://php.net/manual/en/domcharacterdata.replacedata.php * @param int $offset

* The offset from which to start replacing. *

* @param int $count

* The number of characters to replace. If the sum of * offset and count exceeds * the length, then all characters to the end of the data are replaced. *

* @param string $data

* The string with which the range must be replaced. *

* @return bool */ #[TentativeType] public function replaceData( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $count, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data ): bool {} /** * {@inheritDoc} */ public function remove(): void {} /** * {@inheritDoc} */ public function before(...$nodes): void {} /** * {@inheritDoc} */ public function after(...$nodes): void {} /** * {@inheritDoc} */ public function replaceWith(...$nodes): void {} } /** * The DOMAttr interface represents an attribute in an DOMElement object. * @link https://php.net/manual/en/class.domattr.php */ class DOMAttr extends DOMNode { /** * @var string * (PHP5)
* The name of the attribute * @link https://php.net/manual/en/class.domattr.php#domattr.props.name */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $name; /** * @var DOMElement * (PHP5)
* The element which contains the attribute * @link https://php.net/manual/en/class.domattr.php#domattr.props.ownerelement */ #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $ownerElement; /** * @var bool * (PHP5)
* Not implemented yet, always is NULL * @link https://php.net/manual/en/class.domattr.php#domattr.props.schematypeinfo */ #[LanguageLevelTypeAware(['8.1' => 'mixed'], default: '')] public $schemaTypeInfo; /** * @var bool * (PHP5)
* Not implemented yet, always is NULL * @link https://php.net/manual/en/class.domattr.php#domattr.props.specified */ #[LanguageLevelTypeAware(['8.1' => 'bool'], default: '')] public $specified; /** * @var string * (PHP5)
* The value of the attribute * @link https://php.net/manual/en/class.domattr.php#domattr.props.value */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $value; /** * Checks if attribute is a defined ID * @link https://php.net/manual/en/domattr.isid.php * @return bool true on success or false on failure. */ #[TentativeType] public function isId(): bool {} /** * Creates a new {@see DOMAttr} object * @link https://php.net/manual/en/domattr.construct.php * @param string $name

The tag name of the attribute.

* @param string $value [optional]

The value of the attribute.

* @throws DOMException If invalid $name */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $value = '' ) {} } /** * The DOMElement class * @link https://php.net/manual/en/class.domelement.php */ class DOMElement extends DOMNode implements DOMParentNode, DOMChildNode { /** * @var DOMNode|null * The parent of this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.parentnode */ public $parentNode; /** * @var DOMNode|null * The first child of this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.firstchild */ public $firstChild; /** * @var DOMNode|null * The last child of this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.lastchild */ public $lastChild; /** * @var DOMNode|null * The node immediately preceding this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.previoussibling */ public $previousSibling; /** * @var DOMNode|null * The node immediately following this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.nextsibling */ public $nextSibling; /** * @var DOMNamedNodeMap * A DOMNamedNodeMap containing the attributes of this node (if it is a DOMElement) or NULL otherwise. * @link https://php.net/manual/en/class.domnode.php#domnode.props.attributes */ #[LanguageLevelTypeAware(['8.1' => 'DOMNamedNodeMap'], default: '')] public $attributes; /** * @var bool * Not implemented yet, always return NULL * @link https://php.net/manual/en/class.domelement.php#domelement.props.schematypeinfo */ #[LanguageLevelTypeAware(['8.1' => 'mixed'], default: '')] public $schemaTypeInfo; /** * @var string * The element name * @link https://php.net/manual/en/class.domelement.php#domelement.props.tagname */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $tagName; #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $firstElementChild; #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $lastElementChild; #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $childElementCount; #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $previousElementSibling; #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $nextElementSibling; public string $id; public string $className; /** * Returns value of attribute * @link https://php.net/manual/en/domelement.getattribute.php * @param string $qualifiedName

* The name of the attribute. *

* @return string The value of the attribute, or an empty string if no attribute with the * given name is found. */ #[TentativeType] public function getAttribute(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName): string {} /** * Adds new attribute * @link https://php.net/manual/en/domelement.setattribute.php * @param string $qualifiedName

* The name of the attribute. *

* @param string $value

* The value of the attribute. *

* @return DOMAttr|false The new DOMAttr or false if an error occurred. */ public function setAttribute( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $value ) {} /** * Removes attribute * @link https://php.net/manual/en/domelement.removeattribute.php * @param string $qualifiedName

* The name of the attribute. *

* @return bool true on success or false on failure. */ #[TentativeType] public function removeAttribute(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName): bool {} /** * Returns attribute node * @link https://php.net/manual/en/domelement.getattributenode.php * @param string $qualifiedName

* The name of the attribute. *

* @return DOMAttr The attribute node. */ public function getAttributeNode(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName) {} /** * Adds new attribute node to element * @link https://php.net/manual/en/domelement.setattributenode.php * @param DOMAttr $attr

* The attribute node. *

* @return DOMAttr|null Old node if the attribute has been replaced or null. */ public function setAttributeNode(DOMAttr $attr) {} /** * Removes attribute * @link https://php.net/manual/en/domelement.removeattributenode.php * @param DOMAttr $attr

* The attribute node. *

* @return bool true on success or false on failure. */ public function removeAttributeNode(DOMAttr $attr) {} /** * Gets elements by tagname * @link https://php.net/manual/en/domelement.getelementsbytagname.php * @param string $qualifiedName

* The tag name. Use * to return all elements within * the element tree. *

* @return DOMNodeList This function returns a new instance of the class * DOMNodeList of all matched elements. */ #[TentativeType] public function getElementsByTagName(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName): DOMNodeList {} /** * Returns value of attribute * @link https://php.net/manual/en/domelement.getattributens.php * @param string $namespace

* The namespace URI. *

* @param string $localName

* The local name. *

* @return string The value of the attribute, or an empty string if no attribute with the * given localName and namespaceURI * is found. */ #[TentativeType] public function getAttributeNS( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $localName ): string {} /** * Adds new attribute * @link https://php.net/manual/en/domelement.setattributens.php * @param string $namespace

* The namespace URI. *

* @param string $qualifiedName

* The qualified name of the attribute, as prefix:tagname. *

* @param string $value

* The value of the attribute. *

* @return void */ #[TentativeType] public function setAttributeNS( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $value ): void {} /** * Removes attribute * @link https://php.net/manual/en/domelement.removeattributens.php * @param string $namespace

* The namespace URI. *

* @param string $localName

* The local name. *

* @return bool true on success or false on failure. */ #[TentativeType] public function removeAttributeNS( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $localName ): void {} /** * Returns attribute node * @link https://php.net/manual/en/domelement.getattributenodens.php * @param string $namespace

* The namespace URI. *

* @param string $localName

* The local name. *

* @return DOMAttr The attribute node. */ public function getAttributeNodeNS( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $localName ) {} /** * Adds new attribute node to element * @link https://php.net/manual/en/domelement.setattributenodens.php * @param DOMAttr $attr * @return DOMAttr the old node if the attribute has been replaced. */ public function setAttributeNodeNS(DOMAttr $attr) {} /** * Get elements by namespaceURI and localName * @link https://php.net/manual/en/domelement.getelementsbytagnamens.php * @param string $namespace

* The namespace URI. *

* @param string $localName

* The local name. Use * to return all elements within * the element tree. *

* @return DOMNodeList This function returns a new instance of the class * DOMNodeList of all matched elements in the order in * which they are encountered in a preorder traversal of this element tree. */ #[TentativeType] public function getElementsByTagNameNS( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $localName ): DOMNodeList {} /** * Checks to see if attribute exists * @link https://php.net/manual/en/domelement.hasattribute.php * @param string $qualifiedName

* The attribute name. *

* @return bool true on success or false on failure. */ #[TentativeType] public function hasAttribute(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName): bool {} /** * Checks to see if attribute exists * @link https://php.net/manual/en/domelement.hasattributens.php * @param string $namespace

* The namespace URI. *

* @param string $localName

* The local name. *

* @return bool true on success or false on failure. */ #[TentativeType] public function hasAttributeNS( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $localName ): bool {} /** * Declares the attribute specified by name to be of type ID * @link https://php.net/manual/en/domelement.setidattribute.php * @param string $qualifiedName

* The name of the attribute. *

* @param bool $isId

* Set it to true if you want name to be of type * ID, false otherwise. *

* @return void */ #[TentativeType] public function setIdAttribute( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $isId ): void {} /** * Declares the attribute specified by local name and namespace URI to be of type ID * @link https://php.net/manual/en/domelement.setidattributens.php * @param string $namespace

* The namespace URI of the attribute. *

* @param string $qualifiedName

* The local name of the attribute, as prefix:tagname. *

* @param bool $isId

* Set it to true if you want name to be of type * ID, false otherwise. *

* @return void */ #[TentativeType] public function setIdAttributeNS( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $isId ): void {} /** * Declares the attribute specified by node to be of type ID * @link https://php.net/manual/en/domelement.setidattributenode.php * @param DOMAttr $attr

* The attribute node. *

* @param bool $isId

* Set it to true if you want name to be of type * ID, false otherwise. *

* @return void */ #[TentativeType] public function setIdAttributeNode(DOMAttr $attr, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $isId): void {} /** * {@inheritDoc} */ public function remove(): void {} /** * {@inheritDoc} */ public function before(...$nodes): void {} /** * {@inheritDoc} */ public function after(...$nodes): void {} /** * {@inheritDoc} */ public function replaceWith(...$nodes): void {} /** * {@inheritDoc} */ public function append(...$nodes): void {} /** * {@inheritDoc} */ public function prepend(...$nodes): void {} /** * @since 8.3 * {@inheritDoc} */ public function replaceChildren(...$nodes): void {} /** * Creates a new DOMElement object * @link https://php.net/manual/en/domelement.construct.php * @param string $qualifiedName The tag name of the element. When also passing in namespaceURI, the element name may take a prefix to be associated with the URI. * @param string|null $value [optional] The value of the element. * @param string $namespace [optional] A namespace URI to create the element within a specific namespace. * @throws DOMException If invalid $qualifiedName */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $value = null, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $namespace = '' ) {} /** * @since 8.3 */ public function getAttributeNames(): array {} /** * @since 8.3 */ public function toggleAttribute(string $qualifiedName, ?bool $force = null): bool {} /** * @since 8.3 */ public function insertAdjacentElement(string $where, DOMElement $element): ?DOMElement {} /** * @since 8.3 */ public function insertAdjacentText(string $where, string $data): void {} } /** * The DOMText class inherits from DOMCharacterData and represents the textual content of * a DOMElement or DOMAttr. * @link https://php.net/manual/en/class.domtext.php */ class DOMText extends DOMCharacterData { /** * Holds all the text of logically-adjacent (not separated by Element, Comment or Processing Instruction) Text nodes. * @link https://php.net/manual/en/class.domtext.php#domtext.props.wholeText */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $wholeText; /** * Breaks this node into two nodes at the specified offset * @link https://php.net/manual/en/domtext.splittext.php * @param int $offset

* The offset at which to split, starting from 0. *

* @return DOMText The new node of the same type, which contains all the content at and after the * offset. */ public function splitText(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset) {} /** * Indicates whether this text node contains whitespace * @link https://php.net/manual/en/domtext.iswhitespaceinelementcontent.php * @return bool true on success or false on failure. */ #[TentativeType] public function isWhitespaceInElementContent(): bool {} #[TentativeType] public function isElementContentWhitespace(): bool {} /** * @param $content */ public function replaceWholeText($content) {} /** * Creates a new DOMText object * @link https://php.net/manual/en/domtext.construct.php * @param string $data [optional] The value of the text node. If not supplied an empty text node is created. */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data = '') {} } /** * The DOMComment class represents comment nodes, * characters delimited by lt;!-- and -->. * @link https://php.net/manual/en/class.domcomment.php */ class DOMComment extends DOMCharacterData { /** * Creates a new DOMComment object * @link https://php.net/manual/en/domcomment.construct.php * @param string $data [optional] The value of the comment */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data = '') {} } /** * @removed 8.0 */ class DOMTypeinfo {} /** * @removed 8.0 */ class DOMUserDataHandler { public function handle() {} } /** * @removed 8.0 */ class DOMDomError {} /** * @removed 8.0 */ class DOMErrorHandler { /** * @param DOMDomError $error */ public function handleError(DOMDomError $error) {} } /** * @removed 8.0 */ class DOMLocator {} /** * @removed 8.0 */ class DOMConfiguration { /** * @param $name * @param $value */ public function setParameter($name, $value) {} /** * @param $name [optional] */ public function getParameter($name) {} /** * @param $name [optional] * @param $value [optional] */ public function canSetParameter($name, $value) {} } /** * The DOMCdataSection inherits from DOMText for textural representation of CData constructs. * @link https://secure.php.net/manual/en/class.domcdatasection.php */ class DOMCdataSection extends DOMText { /** * The value of the CDATA node. If not supplied, an empty CDATA node is created. * @param string $data The value of the CDATA node. If not supplied, an empty CDATA node is created. * @link https://secure.php.net/manual/en/domcdatasection.construct.php */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data) {} } /** * The DOMDocumentType class * @link https://php.net/manual/en/class.domdocumenttype.php */ class DOMDocumentType extends DOMNode { /** * @var string * The public identifier of the external subset. * @link https://php.net/manual/en/class.domdocumenttype.php#domdocumenttype.props.publicid */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $publicId; /** * @var string * The system identifier of the external subset. This may be an absolute URI or not. * @link https://php.net/manual/en/class.domdocumenttype.php#domdocumenttype.props.systemid */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $systemId; /** * @var string * The name of DTD; i.e., the name immediately following the DOCTYPE keyword. * @link https://php.net/manual/en/class.domdocumenttype.php#domdocumenttype.props.name */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $name; /** * @var DOMNamedNodeMap * A DOMNamedNodeMap containing the general entities, both external and internal, declared in the DTD. * @link https://php.net/manual/en/class.domdocumenttype.php#domdocumenttype.props.entities */ #[LanguageLevelTypeAware(['8.1' => 'DOMNamedNodeMap'], default: '')] public $entities; /** * @var DOMNamedNodeMap * A DOMNamedNodeMap containing the notations declared in the DTD. * @link https://php.net/manual/en/class.domdocumenttype.php#domdocumenttype.props.notations */ #[LanguageLevelTypeAware(['8.1' => 'DOMNamedNodeMap'], default: '')] public $notations; /** * @var string|null * The internal subset as a string, or null if there is none. This is does not contain the delimiting square brackets. * @link https://php.net/manual/en/class.domdocumenttype.php#domdocumenttype.props.internalsubset */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $internalSubset; } /** * The DOMNotation class * @link https://php.net/manual/en/class.domnotation.php */ class DOMNotation extends DOMNode { /** * @var string * * @link https://php.net/manual/en/class.domnotation.php#domnotation.props.publicid */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $publicId; /** * @var string * * @link https://php.net/manual/en/class.domnotation.php#domnotation.props.systemid */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $systemId; } /** * The DOMEntity class represents a known entity, either parsed or unparsed, in an XML document. * @link https://php.net/manual/en/class.domentity.php */ class DOMEntity extends DOMNode { /** * @var string|null * The public identifier associated with the entity if specified, and NULL otherwise. * @link https://php.net/manual/en/class.domentity.php#domentity.props.publicid */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $publicId; /** * @var string|null * The system identifier associated with the entity if specified, and NULL otherwise. This may be an * absolute URI or not. * @link https://php.net/manual/en/class.domentity.php#domentity.props.systemid */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $systemId; /** * @var string|null * For unparsed entities, the name of the notation for the entity. For parsed entities, this is NULL. * @link https://php.net/manual/en/class.domentity.php#domentity.props.notationname */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $notationName; /** * @var string|null * An attribute specifying the encoding used for this entity at the time of parsing, when it is an external * parsed entity. This is NULL if it an entity from the internal subset or if it is not known. * @link https://php.net/manual/en/class.domentity.php#domentity.props.actualencoding */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $actualEncoding; /** * @var string|null * An attribute specifying, as part of the text declaration, the encoding of this entity, when it is an external * parsed entity. This is NULL otherwise. * @link https://php.net/manual/en/class.domentity.php#domentity.props.encoding */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $encoding; /** * @var string|null * An attribute specifying, as part of the text declaration, the version number of this entity, when it is an * external parsed entity. This is NULL otherwise. * @link https://php.net/manual/en/class.domentity.php#domentity.props.version */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $version; } /** * Extends DOMNode. * @link https://php.net/manual/en/class.domentityreference.php */ class DOMEntityReference extends DOMNode { /** * Creates a new DOMEntityReference object * @link https://php.net/manual/en/domentityreference.construct.php * @param string $name The name of the entity reference. */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name) {} } /** * The DOMProcessingInstruction class * @link https://php.net/manual/en/class.domprocessinginstruction.php */ class DOMProcessingInstruction extends DOMNode { /** * @link https://php.net/manual/en/class.domprocessinginstruction.php#domprocessinginstruction.props.target */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $target; /** * @link https://php.net/manual/en/class.domprocessinginstruction.php#domprocessinginstruction.props.data */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $data; /** * Creates a new DOMProcessingInstruction object * @link https://php.net/manual/en/domprocessinginstruction.construct.php * @param string $name The tag name of the processing instruction. * @param string $value [optional] The value of the processing instruction. */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $value = '' ) {} } class DOMStringExtend { /** * @param $offset32 */ public function findOffset16($offset32) {} /** * @param $offset16 */ public function findOffset32($offset16) {} } /** * The DOMXPath class (supports XPath 1.0) * @link https://php.net/manual/en/class.domxpath.php */ class DOMXPath { /** * @var DOMDocument * * @link https://php.net/manual/en/class.domxpath.php#domxpath.props.document */ #[LanguageLevelTypeAware(['8.1' => 'DOMDocument'], default: '')] public $document; #[LanguageLevelTypeAware(['8.1' => 'bool'], default: '')] public $registerNodeNamespaces; /** * Creates a new DOMXPath object * @link https://php.net/manual/en/domxpath.construct.php * @param DOMDocument $document The DOMDocument associated with the DOMXPath. * @param bool $registerNodeNS [optional] allow global flag to configure query() or evaluate() calls. Since 8.0. */ public function __construct(DOMDocument $document, #[PhpStormStubsElementAvailable(from: '8.0')] bool $registerNodeNS = true) {} /** * Registers the namespace with the DOMXPath object * @link https://php.net/manual/en/domxpath.registernamespace.php * @param string $prefix

* The prefix. *

* @param string $namespace

* The URI of the namespace. *

* @return bool true on success or false on failure. */ #[TentativeType] public function registerNamespace( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $prefix, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $namespace ): bool {} /** * Evaluates the given XPath expression * @link https://php.net/manual/en/domxpath.query.php * @param string $expression

* The XPath expression to execute. *

* @param DOMNode $contextNode [optional]

* The optional contextnode can be specified for * doing relative XPath queries. By default, the queries are relative to * the root element. *

* @param bool $registerNodeNS [optional]

The optional registerNodeNS can be specified to * disable automatic registration of the context node.

* @return DOMNodeList|false a DOMNodeList containing all nodes matching * the given XPath expression. Any expression which does not return nodes * will return an empty DOMNodeList. The return is false if the expression * is malformed or the contextnode is invalid. */ #[TentativeType] public function query( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] #[Language('XPath')] $expression, #[LanguageLevelTypeAware(['8.0' => 'DOMNode|null'], default: '')] $contextNode = null, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $registerNodeNS = true ): mixed {} /** * Evaluates the given XPath expression and returns a typed result if possible. * @link https://php.net/manual/en/domxpath.evaluate.php * @param string $expression

* The XPath expression to execute. *

* @param DOMNode $contextNode [optional]

* The optional contextnode can be specified for * doing relative XPath queries. By default, the queries are relative to * the root element. *

* @param bool $registerNodeNS [optional] *

* The optional registerNodeNS can be specified to disable automatic registration of the context node. *

* @return mixed a typed result if possible or a DOMNodeList * containing all nodes matching the given XPath expression. */ #[TentativeType] public function evaluate( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] #[Language('XPath')] $expression, #[LanguageLevelTypeAware(['8.0' => 'DOMNode|null'], default: '')] $contextNode = null, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $registerNodeNS = true ): mixed {} /** * Register PHP functions as XPath functions * @link https://php.net/manual/en/domxpath.registerphpfunctions.php * @param string|string[] $restrict [optional]

* Use this parameter to only allow certain functions to be called from XPath. *

*

* This parameter can be either a string (a function name) or * an array of function names. *

* @return void */ public function registerPhpFunctions($restrict = null) {} /** * @since 8.4 */ public function registerPhpFunctionNS(string $namespaceURI, string $name, callable $callable): void {} /** * @since 8.4 */ public static function quote(string $str): string {} } /** * @property-read DOMElement|null $firstElementChild * @property-read DOMElement|null $lastElementChild * @property-read int $childElementCount * * @since 8.0 */ interface DOMParentNode { /** * Appends one or many nodes to the list of children behind the last * child node. * * @param DOMNode|string|null ...$nodes * @return void * @since 8.0 */ public function append(...$nodes): void; /** * Prepends one or many nodes to the list of children before the first * child node. * * @param DOMNode|string|null ...$nodes * @return void * @since 8.0 */ public function prepend(...$nodes): void; /** * @since 8.3 */ public function replaceChildren(...$nodes): void; } /** * @property-read DOMElement|null $previousElementSibling * @property-read DOMElement|null $nextElementSibling * * @since 8.0 */ interface DOMChildNode { /** * Acts as a simpler version of {@see DOMNode::removeChild()}. * * @return void * @since 8.0 */ public function remove(): void; /** * Add passed node(s) before the current node * * @param DOMNode|string|null ...$nodes * @return void * @since 8.0 */ public function before(...$nodes): void; /** * Add passed node(s) after the current node * * @param DOMNode|string|null ...$nodes * @return void * @since 8.0 */ public function after(...$nodes): void; /** * Replace current node with new node(s), a combination * of {@see DOMChildNode::remove()} + {@see DOMChildNode::append()}. * * @param DOMNode|string|null ...$nodes * @return void * @since 8.0 */ public function replaceWith(...$nodes): void; } * A mailbox name consists of a server and a mailbox path on this server. * The special name INBOX stands for the current users * personal mailbox. Mailbox names that contain international characters * besides those in the printable ASCII space have to be encoded width * imap_utf7_encode. *

*

* The server part, which is enclosed in '{' and '}', consists of the servers * name or ip address, an optional port (prefixed by ':'), and an optional * protocol specification (prefixed by '/'). *

*

* The server part is mandatory in all mailbox * parameters. *

*

* All names which start with { are remote names, and are * in the form "{" remote_system_name [":" port] [flags] "}" * [mailbox_name] where: * remote_system_name - Internet domain name or * bracketed IP address of server.

* @param string $user

* The user name *

* @param string $password

* The password associated with the username *

* @param int $flags [optional]

* The options are a bit mask with one or more of * the following: * OP_READONLY - Open mailbox read-only

* @param int $retries [optional]

* Number of maximum connect attempts *

* @param null|array $options

* Connection parameters, the following (string) keys maybe used * to set one or more connection parameters: * DISABLE_AUTHENTICATOR - Disable authentication properties

* @return resource|false an IMAP stream on success or FALSE on error. */ #[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection|false'], default: 'resource|false')] function imap_open(string $mailbox, string $user, string $password, int $flags = 0, int $retries = 0, array $options = []) {} /** * Reopen IMAP stream to new mailbox * @link https://php.net/manual/en/function.imap-reopen.php * @param resource $imap * @param string $mailbox

* The mailbox name, see imap_open for more * information *

* @param int $flags [optional]

* The options are a bit mask with one or more of * the following: * OP_READONLY - Open mailbox read-only

* @param int $retries [optional]

* Number of maximum connect attempts *

* @return bool TRUE if the stream is reopened, FALSE otherwise. */ function imap_reopen( #[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $mailbox, int $flags = 0, int $retries = 0 ): bool {} /** * Close an IMAP stream * @link https://php.net/manual/en/function.imap-close.php * @param resource $imap * @param int $flags [optional]

* If set to CL_EXPUNGE, the function will silently * expunge the mailbox before closing, removing all messages marked for * deletion. You can achieve the same thing by using * imap_expunge *

*/ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function imap_close(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $flags = 0) {} /** * Gets the number of messages in the current mailbox * @link https://php.net/manual/en/function.imap-num-msg.php * @param resource $imap * @return int|false Return the number of messages in the current mailbox, as an integer. */ function imap_num_msg(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap): int|false {} /** * Gets the number of recent messages in current mailbox * @link https://php.net/manual/en/function.imap-num-recent.php * @param resource $imap * @return int the number of recent messages in the current mailbox, as an * integer. */ function imap_num_recent(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap): int {} /** * Returns headers for all messages in a mailbox * @link https://php.net/manual/en/function.imap-headers.php * @param resource $imap * @return array|false an array of string formatted with header info. One * element per mail message. */ function imap_headers(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap): array|false {} /** * Read the header of the message * @link https://php.net/manual/en/function.imap-headerinfo.php * @param resource|IMAP\Connection $imap An IMAP stream returned by imap_open(). * @param int $message_num The message number * @param int $from_length [optional] Number of characters for the fetchfrom property. Must be greater than or equal to zero. * @param int $subject_length [optional] Number of characters for the fetchsubject property Must be greater than or equal to zero. * @param $default_host [optional] * @return stdClass|false Returns the information in an object with following properties: *
*
toaddress
full to: line, up to 1024 characters
*
to
an array of objects from the To: line, with the following properties: personal, adl, mailbox, and host
*
fromaddress
full from: line, up to 1024 characters
*
from
an array of objects from the From: line, with the following properties: personal, adl, mailbox, and host
*
ccaddress
full cc: line, up to 1024 characters
*
cc
an array of objects from the Cc: line, with the following properties: personal, adl, mailbox, and host
*
bccaddress
full bcc: line, up to 1024 characters
*
bcc
an array of objects from the Bcc: line, with the following properties: personal, adl, mailbox, and host
*
reply_toaddress
full Reply-To: line, up to 1024 characters
*
reply_to
an array of objects from the Reply-To: line, with the following properties: personal, adl, mailbox, and host
*
senderaddress
full sender: line, up to 1024 characters
*
sender
an array of objects from the Sender: line, with the following properties: personal, adl, mailbox, and host
*
return_pathaddress
full Return-Path: line, up to 1024 characters
*
return_path
an array of objects from the Return-Path: line, with the following properties: personal, adl, mailbox, and host
*
remail -
*
date
The message date as found in its headers
*
Date
Same as date
*
subject
The message subject
*
Subject
Same a subject
*
in_reply_to -
*
message_id -
*
newsgroups -
*
followup_to -
*
references -
*
Recent
R if recent and seen, N if recent and not seen, ' ' if not recent.
*
Unseen
U if not seen AND not recent, ' ' if seen OR not seen and recent
*
Flagged
F if flagged, ' ' if not flagged
*
Answered
A if answered, ' ' if unanswered
*
Deleted
D if deleted, ' ' if not deleted
*
Draft
X if draft, ' ' if not draft
*
Msgno
The message number
*
MailDate -
*
Size
The message size
*
udate
mail message date in Unix time
*
fetchfrom
from line formatted to fit fromlength characters
*
fetchsubject
subject line formatted to fit subjectlength characters
*
*/ function imap_headerinfo( #[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $message_num, int $from_length = 0, int $subject_length = 0, #[PhpStormStubsElementAvailable(to: '7.4')] $default_host = null ): stdClass|false {} /** * Parse mail headers from a string * @link https://php.net/manual/en/function.imap-rfc822-parse-headers.php * @param string $headers

* The parsed headers data *

* @param string $default_hostname [optional]

* The default host name *

* @return object|stdClass an object similar to the one returned by * imap_header, except for the flags and other * properties that come from the IMAP server. */ function imap_rfc822_parse_headers(string $headers, string $default_hostname = "UNKNOWN"): stdClass {} /** * Returns a properly formatted email address given the mailbox, host, and personal info * @link https://php.net/manual/en/function.imap-rfc822-write-address.php * @param string $mailbox

* The mailbox name, see imap_open for more * information *

* @param string $hostname

* The email host part *

* @param string $personal

* The name of the account owner *

* @return string|false a string properly formatted email address as defined in RFC2822. */ function imap_rfc822_write_address(string $mailbox, string $hostname, string $personal): string|false {} /** * Parses an address string * @link https://php.net/manual/en/function.imap-rfc822-parse-adrlist.php * @param string $string

* A string containing addresses *

* @param string $default_hostname

* The default host name *

* @return array an array of objects. The objects properties are: *

* mailbox - the mailbox name (username) * host - the host name * personal - the personal name * adl - at domain source route *

*/ function imap_rfc822_parse_adrlist(string $string, string $default_hostname): array {} /** * Read the message body * @link https://php.net/manual/en/function.imap-body.php * @param resource $imap * @param int $message_num

* The message number *

* @param int $flags [optional]

* The optional options are a bit mask * with one or more of the following: * FT_UID - The msg_number is a UID

* @return string|false the body of the specified message, as a string. */ function imap_body( #[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $message_num, int $flags = 0 ): string|false {} /** * Read the structure of a specified body section of a specific message * @link https://php.net/manual/en/function.imap-bodystruct.php * @param resource $imap * @param int $message_num

* The message number *

* @param string $section

* The body section to read *

* @return object the information in an object, for a detailed description * of the object structure and properties see * imap_fetchstructure. */ #[LanguageLevelTypeAware(['8.1' => 'stdClass|false'], default: 'object')] function imap_bodystruct(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $message_num, string $section) {} /** * Fetch a particular section of the body of the message * @link https://php.net/manual/en/function.imap-fetchbody.php * @param resource $imap * @param int $message_num

* The message number *

* @param string $section

* The part number. It is a string of integers delimited by period which * index into a body part list as per the IMAP4 specification *

* @param int $flags [optional]

* A bitmask with one or more of the following: * FT_UID - The msg_number is a UID

* @return string|false a particular section of the body of the specified messages as a * text string. */ function imap_fetchbody( #[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $message_num, string $section, int $flags = 0 ): string|false {} /** * Fetch MIME headers for a particular section of the message * @link https://php.net/manual/en/function.imap-fetchmime.php * @param resource $imap * @param int $message_num

* The message number *

* @param string $section

* The part number. It is a string of integers delimited by period which * index into a body part list as per the IMAP4 specification *

* @param int $flags [optional]

* A bitmask with one or more of the following: * FT_UID - The msg_number is a UID

* @return string|false the MIME headers of a particular section of the body of the specified messages as a * text string. * @since 5.3.6 */ function imap_fetchmime( #[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $message_num, string $section, int $flags = 0 ): string|false {} /** * Save a specific body section to a file * @link https://php.net/manual/en/function.imap-savebody.php * @param resource $imap * @param mixed $file

* The path to the saved file as a string, or a valid file descriptor * returned by fopen. *

* @param int $message_num

* The message number *

* @param string $section [optional]

* The part number. It is a string of integers delimited by period which * index into a body part list as per the IMAP4 specification *

* @param int $flags [optional]

* A bitmask with one or more of the following: * FT_UID - The msg_number is a UID

* @return bool TRUE on success or FALSE on failure. * @since 5.1.3 */ function imap_savebody( #[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, $file, int $message_num, string $section = "", int $flags = 0 ): bool {} /** * Returns header for a message * @link https://php.net/manual/en/function.imap-fetchheader.php * @param resource $imap * @param int $message_num

* The message number *

* @param int $flags [optional]

* The possible options are: * FT_UID - The msgno * argument is a UID

* @return string|false the header of the specified message as a text string. */ function imap_fetchheader( #[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $message_num, int $flags = 0 ): string|false {} /** * Read the structure of a particular message * @link https://php.net/manual/en/function.imap-fetchstructure.php * @param resource $imap * @param int $message_num

* The message number *

* @param int $flags [optional]

* This optional parameter only has a single option, * FT_UID, which tells the function to treat the * msg_number argument as a * UID. *

* @return object|stdClass|false an object includes the envelope, internal date, size, flags and * body structure along with a similar object for each mime attachment. The * structure of the returned objects is as follows: *

*

*

* Returned Objects for imap_fetchstructure * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
typePrimary body type
encodingBody transfer encoding
ifsubtypeTRUE if there is a subtype string
subtypeMIME subtype
ifdescriptionTRUE if there is a description string
descriptionContent description string
ifidTRUE if there is an identification string
idIdentification string
linesNumber of lines
bytesNumber of bytes
ifdispositionTRUE if there is a disposition string
dispositionDisposition string
ifdparametersTRUE if the dparameters array exists
dparametersAn array of objects where each object has an * "attribute" and a "value" * property corresponding to the parameters on the * Content-disposition MIME * header.
ifparametersTRUE if the parameters array exists
parametersAn array of objects where each object has an * "attribute" and a "value" * property.
partsAn array of objects identical in structure to the top-level * object, each of which corresponds to a MIME body * part.
*

*

*

* Primary body type (may vary with used library) * * * * * * * * *
0text
1multipart
2message
3application
4audio
5image
6video
7other
*

*

*

* Transfer encodings (may vary with used library) * * * * * * *
07BIT
18BIT
2BINARY
3BASE64
4QUOTED-PRINTABLE
5OTHER
*/ function imap_fetchstructure(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $message_num, int $flags = 0): stdClass|false {} /** * Clears IMAP cache * @link https://php.net/manual/en/function.imap-gc.php * @param resource $imap * @param int $flags

* Specifies the cache to purge. It may one or a combination * of the following constants: * IMAP_GC_ELT (message cache elements), * IMAP_GC_ENV (enveloppe and bodies), * IMAP_GC_TEXTS (texts). *

*/ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function imap_gc( #[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] int $flags = 0, #[PhpStormStubsElementAvailable(from: '8.0')] int $flags ) {} /** * Delete all messages marked for deletion * @link https://php.net/manual/en/function.imap-expunge.php * @param resource $imap */ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function imap_expunge(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap) {} /** * Mark a message for deletion from current mailbox * @link https://php.net/manual/en/function.imap-delete.php * @param resource $imap * @param string $message_nums

* The message number *

* @param int $flags [optional]

* You can set the FT_UID which tells the function * to treat the msg_number argument as an * UID. *

*/ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function imap_delete(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $message_nums, int $flags = 0) {} /** * Unmark the message which is marked deleted * @link https://php.net/manual/en/function.imap-undelete.php * @param resource $imap * @param string $message_nums

* The message number *

* @param int $flags [optional] */ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function imap_undelete(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $message_nums, int $flags = 0) {} /** * Check current mailbox * @link https://php.net/manual/en/function.imap-check.php * @param resource $imap * @return object|stdClass|false the information in an object with following properties: * Date - current system time formatted according to RFC2822 * Driver - protocol used to access this mailbox: * POP3, IMAP, NNTP * Mailbox - the mailbox name * Nmsgs - number of messages in the mailbox * Recent - number of recent messages in the mailbox *

*

* Returns FALSE on failure. */ function imap_check(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap): stdClass|false {} /** * Returns the list of mailboxes that matches the given text * @link https://php.net/manual/en/function.imap-listscan.php * @param resource $imap * @param string $reference

* ref should normally be just the server * specification as described in imap_open *

* @param string $pattern Specifies where in the mailbox hierarchy * to start searching.

There are two special characters you can * pass as part of the pattern: * '*' and '%'. * '*' means to return all mailboxes. If you pass * pattern as '*', you will * get a list of the entire mailbox hierarchy. * '%' * means to return the current level only. * '%' as the pattern * parameter will return only the top level * mailboxes; '~/mail/%' on UW_IMAPD will return every mailbox in the ~/mail directory, but none in subfolders of that directory.

* @param string $content

* The searched string *

* @return array|false an array containing the names of the mailboxes that have * content in the text of the mailbox. */ function imap_listscan(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $reference, string $pattern, string $content): array|false {} /** * Copy specified messages to a mailbox * @link https://php.net/manual/en/function.imap-mail-copy.php * @param resource $imap * @param string $message_nums

* msglist is a range not just message * numbers (as described in RFC2060). *

* @param string $mailbox

* The mailbox name, see imap_open for more * information *

* @param int $flags [optional]

* options is a bitmask of one or more of * CP_UID - the sequence numbers contain UIDS

* @return bool TRUE on success or FALSE on failure. */ function imap_mail_copy(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $message_nums, string $mailbox, int $flags = 0): bool {} /** * Move specified messages to a mailbox * @link https://php.net/manual/en/function.imap-mail-move.php * @param resource $imap * @param string $message_nums

* msglist is a range not just message numbers * (as described in RFC2060). *

* @param string $mailbox

* The mailbox name, see imap_open for more * information *

* @param int $flags [optional]

* options is a bitmask and may contain the single option: * CP_UID - the sequence numbers contain UIDS

* @return bool TRUE on success or FALSE on failure. */ function imap_mail_move(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $message_nums, string $mailbox, int $flags = 0): bool {} /** * Create a MIME message based on given envelope and body sections * @link https://php.net/manual/en/function.imap-mail-compose.php * @param array $envelope

* An associative array of headers fields. Valid keys are: "remail", * "return_path", "date", "from", "reply_to", "in_reply_to", "subject", * "to", "cc", "bcc", "message_id" and "custom_headers" (which contains * associative array of other headers). *

* @param array $bodies

* An indexed array of bodies *

*

* A body is an associative array which can consist of the following keys: * "type", "encoding", "charset", "type.parameters", "subtype", "id", * "description", "disposition.type", "disposition", "contents.data", * "lines", "bytes" and "md5". *

* @return string|false the MIME message. */ function imap_mail_compose(array $envelope, array $bodies): string|false {} /** * Create a new mailbox * @link https://php.net/manual/en/function.imap-createmailbox.php * @param resource $imap * @param string $mailbox

* The mailbox name, see imap_open for more * information. Names containing international characters should be * encoded by imap_utf7_encode *

* @return bool TRUE on success or FALSE on failure. */ function imap_createmailbox(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $mailbox): bool {} /** * Rename an old mailbox to new mailbox * @link https://php.net/manual/en/function.imap-renamemailbox.php * @param resource $imap * @param string $from

* The old mailbox name, see imap_open for more * information *

* @param string $to

* The new mailbox name, see imap_open for more * information *

* @return bool TRUE on success or FALSE on failure. */ function imap_renamemailbox(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $from, string $to): bool {} /** * Delete a mailbox * @link https://php.net/manual/en/function.imap-deletemailbox.php * @param resource $imap * @param string $mailbox

* The mailbox name, see imap_open for more * information *

* @return bool TRUE on success or FALSE on failure. */ function imap_deletemailbox(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $mailbox): bool {} /** * Subscribe to a mailbox * @link https://php.net/manual/en/function.imap-subscribe.php * @param resource $imap * @param string $mailbox

* The mailbox name, see imap_open for more * information *

* @return bool TRUE on success or FALSE on failure. */ function imap_subscribe(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $mailbox): bool {} /** * Unsubscribe from a mailbox * @link https://php.net/manual/en/function.imap-unsubscribe.php * @param resource $imap * @param string $mailbox

* The mailbox name, see imap_open for more * information *

* @return bool TRUE on success or FALSE on failure. */ function imap_unsubscribe(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $mailbox): bool {} /** * Append a string message to a specified mailbox * @link https://php.net/manual/en/function.imap-append.php * @param resource $imap * @param string $folder

* The mailbox name, see imap_open for more * information *

* @param string $message

* The message to be append, as a string *

*

* When talking to the Cyrus IMAP server, you must use "\r\n" as * your end-of-line terminator instead of "\n" or the operation will * fail *

* @param string $options [optional]

* If provided, the options will also be written * to the mailbox *

* @param string $internal_date [optional]

* If this parameter is set, it will set the INTERNALDATE on the appended message. The parameter should be a date string that conforms to the rfc2060 specifications for a date_time value. *

* @return bool TRUE on success or FALSE on failure. */ function imap_append(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $folder, string $message, ?string $options = null, ?string $internal_date = null): bool {} /** * Check if the IMAP stream is still active * @link https://php.net/manual/en/function.imap-ping.php * @param resource $imap * @return bool TRUE if the stream is still alive, FALSE otherwise. */ function imap_ping(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap): bool {} /** * Decode BASE64 encoded text * @link https://php.net/manual/en/function.imap-base64.php * @param string $string

* The encoded text *

* @return string|false the decoded message as a string. */ function imap_base64(string $string): string|false {} /** * Convert a quoted-printable string to an 8 bit string * @link https://php.net/manual/en/function.imap-qprint.php * @param string $string

* A quoted-printable string *

* @return string|false an 8 bits string. */ function imap_qprint(string $string): string|false {} /** * Convert an 8bit string to a quoted-printable string * @link https://php.net/manual/en/function.imap-8bit.php * @param string $string

* The 8bit string to convert *

* @return string|false a quoted-printable string. */ function imap_8bit(string $string): string|false {} /** * Convert an 8bit string to a base64 string * @link https://php.net/manual/en/function.imap-binary.php * @param string $string

* The 8bit string *

* @return string|false a base64 encoded string. */ function imap_binary(string $string): string|false {} /** * Converts MIME-encoded text to UTF-8 * @link https://php.net/manual/en/function.imap-utf8.php * @param string $mime_encoded_text

* A MIME encoded string. MIME encoding method and the UTF-8 * specification are described in RFC2047 and RFC2044 respectively. *

* @return string an UTF-8 encoded string. */ function imap_utf8(string $mime_encoded_text): string {} /** * Returns status information on a mailbox * @link https://php.net/manual/en/function.imap-status.php * @param resource $imap * @param string $mailbox

* The mailbox name, see imap_open for more * information *

* @param int $flags

* Valid flags are: * SA_MESSAGES - set $status->messages to the * number of messages in the mailbox * @return object This function returns an object containing status information. * The object has the following properties: messages, * recent, unseen, * uidnext, and uidvalidity. *

*

* flags is also set, which contains a bitmask which can * be checked against any of the above constants.

*/ #[LanguageLevelTypeAware(['8.1' => 'stdClass|false'], default: 'object')] function imap_status(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $mailbox, int $flags) {} /** * @param $stream_id * @param $options */ function imap_status_current($stream_id, $options) {} /** * Get information about the current mailbox * @link https://php.net/manual/en/function.imap-mailboxmsginfo.php * @param resource $imap * @return object|stdClass|false the information in an object with following properties: * * Mailbox properties * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Datedate of last change (current datetime)
Driverdriver
Mailboxname of the mailbox
Nmsgsnumber of messages
Recentnumber of recent messages
Unreadnumber of unread messages
Deletednumber of deleted messages
Sizemailbox size
*

*

* Returns FALSE on failure. */ function imap_mailboxmsginfo(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap): stdClass {} /** * Sets flags on messages * @link https://php.net/manual/en/function.imap-setflag-full.php * @param resource $imap * @param string $sequence

* A sequence of message numbers. You can enumerate desired messages * with the X,Y syntax, or retrieve all messages * within an interval with the X:Y syntax *

* @param string $flag

* The flags which you can set are \Seen, * \Answered, \Flagged, * \Deleted, and \Draft as * defined by RFC2060. *

* @param int $options [optional]

* A bit mask that may contain the single option: * ST_UID - The sequence argument contains UIDs * instead of sequence numbers

*/ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function imap_setflag_full(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $sequence, string $flag, int $options = NIL) {} /** * Clears flags on messages * @link https://php.net/manual/en/function.imap-clearflag-full.php * @param resource $imap * @param string $sequence

* A sequence of message numbers. You can enumerate desired messages * with the X,Y syntax, or retrieve all messages * within an interval with the X:Y syntax *

* @param string $flag

* The flags which you can unset are "\\Seen", "\\Answered", "\\Flagged", * "\\Deleted", and "\\Draft" (as defined by RFC2060) *

* @param int $options [optional]

* options are a bit mask and may contain * the single option: * ST_UID - The sequence argument contains UIDs * instead of sequence numbers

*/ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function imap_clearflag_full(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $sequence, string $flag, int $options = 0) {} /** * Gets and sort messages * @link https://php.net/manual/en/function.imap-sort.php * @param resource $imap * @param int $criteria

* Criteria can be one (and only one) of the following: * SORTDATE - message Date

* @param bool $reverse

* Set this to 1 for reverse sorting *

* @param int $flags [optional]

* The options are a bitmask of one or more of the * following: * SE_UID - Return UIDs instead of sequence numbers

* @param string|null $search_criteria [optional] * @param string|null $charset [optional] * @return array|false an array of message numbers sorted by the given * parameters. */ function imap_sort( #[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $criteria, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: 'int')] $reverse, int $flags = 0, ?string $search_criteria = null, ?string $charset = null ): array|false {} /** * This function returns the UID for the given message sequence number * @link https://php.net/manual/en/function.imap-uid.php * @param resource $imap * @param int $message_num

* The message number. *

* @return int|false The UID of the given message. */ function imap_uid(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $message_num): int|false {} /** * Gets the message sequence number for the given UID * @link https://php.net/manual/en/function.imap-msgno.php * @param resource $imap * @param int $message_uid

* The message UID *

* @return int the message sequence number for the given * uid. */ function imap_msgno(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $message_uid): int {} /** * Read the list of mailboxes * @link https://php.net/manual/en/function.imap-list.php * @param resource $imap * @param string $reference

* ref should normally be just the server * specification as described in imap_open. *

* @param string $pattern Specifies where in the mailbox hierarchy * to start searching.

There are two special characters you can * pass as part of the pattern: * '*' and '%'. * '*' means to return all mailboxes. If you pass * pattern as '*', you will * get a list of the entire mailbox hierarchy. * '%' * means to return the current level only. * '%' as the pattern * parameter will return only the top level * mailboxes; '~/mail/%' on UW_IMAPD will return every mailbox in the ~/mail directory, but none in subfolders of that directory.

* @return array|false an array containing the names of the mailboxes. */ function imap_list(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $reference, string $pattern): array|false {} /** * List all the subscribed mailboxes * @link https://php.net/manual/en/function.imap-lsub.php * @param resource $imap * @param string $reference

* ref should normally be just the server * specification as described in imap_open *

* @param string $pattern Specifies where in the mailbox hierarchy * to start searching.

There are two special characters you can * pass as part of the pattern: * '*' and '%'. * '*' means to return all mailboxes. If you pass * pattern as '*', you will * get a list of the entire mailbox hierarchy. * '%' * means to return the current level only. * '%' as the pattern * parameter will return only the top level * mailboxes; '~/mail/%' on UW_IMAPD will return every mailbox in the ~/mail directory, but none in subfolders of that directory.

* @return array|false an array of all the subscribed mailboxes. */ function imap_lsub(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $reference, string $pattern): array|false {} /** * Read an overview of the information in the headers of the given message * @link https://php.net/manual/en/function.imap-fetch-overview.php * @param resource $imap * @param string $sequence

* A message sequence description. You can enumerate desired messages * with the X,Y syntax, or retrieve all messages * within an interval with the X:Y syntax *

* @param int $flags [optional]

* sequence will contain a sequence of message * indices or UIDs, if this parameter is set to * FT_UID. *

* @return array|false an array of objects describing one message header each. * The object will only define a property if it exists. The possible * properties are: * subject - the messages subject * from - who sent it * to - recipient * date - when was it sent * message_id - Message-ID * references - is a reference to this message id * in_reply_to - is a reply to this message id * size - size in bytes * uid - UID the message has in the mailbox * msgno - message sequence number in the mailbox * recent - this message is flagged as recent * flagged - this message is flagged * answered - this message is flagged as answered * deleted - this message is flagged for deletion * seen - this message is flagged as already read * draft - this message is flagged as being a draft */ function imap_fetch_overview(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $sequence, int $flags = 0): array|false {} /** * Returns all IMAP alert messages that have occurred * @link https://php.net/manual/en/function.imap-alerts.php * @return array|false an array of all of the IMAP alert messages generated or FALSE if * no alert messages are available. */ function imap_alerts(): array|false {} /** * Returns all of the IMAP errors that have occurred * @link https://php.net/manual/en/function.imap-errors.php * @return array|false This function returns an array of all of the IMAP error messages * generated since the last imap_errors call, * or the beginning of the page. Returns FALSE if no error messages are * available. */ function imap_errors(): array|false {} /** * Gets the last IMAP error that occurred during this page request * @link https://php.net/manual/en/function.imap-last-error.php * @return string|false the full text of the last IMAP error message that occurred on the * current page. Returns FALSE if no error messages are available. */ function imap_last_error(): string|false {} /** * This function returns an array of messages matching the given search criteria * @link https://php.net/manual/en/function.imap-search.php * @param resource $imap * @param string $criteria

* A string, delimited by spaces, in which the following keywords are * allowed. Any multi-word arguments (e.g. * FROM "joey smith") must be quoted. Results will match * all criteria entries. * ALL - return all messages matching the rest of the criteria

* @param int $flags [optional]

* Valid values for options are * SE_UID, which causes the returned array to * contain UIDs instead of messages sequence numbers. *

* @param string $charset * @return array|false an array of message numbers or UIDs. *

* Return FALSE if it does not understand the search * criteria or no messages have been found. *

*/ function imap_search( #[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $criteria, int $flags = SE_FREE, string $charset = "" ): array|false {} /** * Decodes a modified UTF-7 encoded string * @link https://php.net/manual/en/function.imap-utf7-decode.php * @param string $string

* A modified UTF-7 encoding string, as defined in RFC 2060, section 5.1.3 (original UTF-7 * was defined in RFC1642). *

* @return string|false a string that is encoded in ISO-8859-1 and consists of the same * sequence of characters in text, or FALSE * if text contains invalid modified UTF-7 sequence * or text contains a character that is not part of * ISO-8859-1 character set. */ function imap_utf7_decode(string $string): string|false {} /** * Converts ISO-8859-1 string to modified UTF-7 text * @link https://php.net/manual/en/function.imap-utf7-encode.php * @param string $string

* An ISO-8859-1 string. *

* @return string data encoded with the modified UTF-7 * encoding as defined in RFC 2060, * section 5.1.3 (original UTF-7 was defined in RFC1642). */ function imap_utf7_encode(string $string): string {} /** * Decode MIME header elements * @link https://php.net/manual/en/function.imap-mime-header-decode.php * @param string $string

* The MIME text *

* @return array|false The decoded elements are returned in an array of objects, where each * object has two properties, charset and * text. *

*

* If the element hasn't been encoded, and in other words is in * plain US-ASCII, the charset property of that element is * set to default. */ function imap_mime_header_decode(string $string): array|false {} /** * Returns a tree of threaded message * @link https://php.net/manual/en/function.imap-thread.php * @param resource $imap * @param int $flags [optional] * @return array|false imap_thread returns an associative array containing * a tree of messages threaded by REFERENCES, or FALSE * on error. *

*

* Every message in the current mailbox will be represented by three entries * in the resulting array: *

* $thread["XX.num"] - current message number *

*

* $thread["XX.next"] *

*

* $thread["XX.branch"] *

*/ function imap_thread(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $flags = SE_FREE): array|false {} /** * Set or fetch imap timeout * @link https://php.net/manual/en/function.imap-timeout.php * @param int $timeout_type

* One of the following: * IMAP_OPENTIMEOUT, * IMAP_READTIMEOUT, * IMAP_WRITETIMEOUT, or * IMAP_CLOSETIMEOUT. *

* @param int $timeout [optional]

* The timeout, in seconds. *

* @return int|bool If the timeout parameter is set, this function * returns TRUE on success and FALSE on failure. *

*

* If timeout is not provided or evaluates to -1, * the current timeout value of timeout_type is * returned as an integer. */ function imap_timeout(int $timeout_type, int $timeout = -1): int|bool {} /** * Retrieve the quota level settings, and usage statics per mailbox * @link https://php.net/manual/en/function.imap-get-quota.php * @param resource $imap * @param string $quota_root

* quota_root should normally be in the form of * user.name where name is the mailbox you wish to * retrieve information about. *

* @return array|false an array with integer values limit and usage for the given * mailbox. The value of limit represents the total amount of space * allowed for this mailbox. The usage value represents the mailboxes * current level of capacity. Will return FALSE in the case of failure. *

*

* As of PHP 4.3, the function more properly reflects the * functionality as dictated by the RFC2087. * The array return value has changed to support an unlimited number of returned * resources (i.e. messages, or sub-folders) with each named resource receiving * an individual array key. Each key value then contains an another array with * the usage and limit values within it. *

*

* For backwards compatibility reasons, the original access methods are * still available for use, although it is suggested to update. */ #[ArrayShape(["usage" => "int", "limit" => "int"])] function imap_get_quota(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $quota_root): array|false {} /** * Retrieve the quota settings per user * @link https://php.net/manual/en/function.imap-get-quotaroot.php * @param resource $imap * @param string $mailbox

* quota_root should normally be in the form of * which mailbox (i.e. INBOX). *

* @return array|false an array of integer values pertaining to the specified user * mailbox. All values contain a key based upon the resource name, and a * corresponding array with the usage and limit values within. *

*

* This function will return FALSE in the case of call failure, and an * array of information about the connection upon an un-parsable response * from the server. */ function imap_get_quotaroot(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $mailbox): array|false {} /** * Sets a quota for a given mailbox * @link https://php.net/manual/en/function.imap-set-quota.php * @param resource $imap * @param string $quota_root

* The mailbox to have a quota set. This should follow the IMAP standard * format for a mailbox: user.name. *

* @param int $mailbox_size

* The maximum size (in KB) for the quota_root *

* @return bool TRUE on success or FALSE on failure. */ function imap_set_quota(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $quota_root, int $mailbox_size): bool {} /** * Sets the ACL for a given mailbox * @link https://php.net/manual/en/function.imap-setacl.php * @param resource $imap * @param string $mailbox

* The mailbox name, see imap_open for more * information *

* @param string $user_id

* The user to give the rights to. *

* @param string $rights

* The rights to give to the user. Passing an empty string will delete * acl. *

* @return bool TRUE on success or FALSE on failure. */ function imap_setacl(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $mailbox, string $user_id, string $rights): bool {} /** * Gets the ACL for a given mailbox * @link https://php.net/manual/en/function.imap-getacl.php * @param resource $imap * @param string $mailbox

* The mailbox name, see imap_open for more * information *

* @return array|false an associative array of "folder" => "acl" pairs. */ function imap_getacl(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $mailbox): array|false {} /** * @param $stream_id * @param $mailbox */ function imap_myrights($stream_id, $mailbox) {} /** * @param $stream_id * @param $mailbox * @param $entry * @param $attr * @param $value */ function imap_setannotation($stream_id, $mailbox, $entry, $attr, $value) {} /** * @param $stream_id * @param $mailbox * @param $entry * @param $attr */ function imap_getannotation($stream_id, $mailbox, $entry, $attr) {} /** * Send an email message * @link https://php.net/manual/en/function.imap-mail.php * @param string $to

* The receiver *

* @param string $subject

* The mail subject *

* @param string $message

* The mail body, see imap_mail_compose *

* @param string $additional_headers [optional]

* As string with additional headers to be set on the mail *

* @param string $cc [optional] * @param string $bcc [optional]

* The receivers specified in bcc will get the * mail, but are excluded from the headers. *

* @param string $return_path [optional]

* Use this parameter to specify return path upon mail delivery failure. * This is useful when using PHP as a mail client for multiple users. *

* @return bool TRUE on success or FALSE on failure. */ function imap_mail(string $to, string $subject, string $message, ?string $additional_headers = null, ?string $cc = null, ?string $bcc = null, ?string $return_path = null): bool {} /** * Alias of imap_headerinfo * @link https://php.net/manual/en/function.imap-header.php * @param resource $stream_id An IMAP stream returned by imap_open(). * @param int $msg_no The message number * @param int $from_length [optional] Number of characters for the fetchfrom property. Must be greater than or equal to zero. * @param int $subject_length [optional] Number of characters for the fetchsubject property Must be greater than or equal to zero. * @param $default_host [optional] * @return object Returns the information in an object with following properties: *
*
toaddress
full to: line, up to 1024 characters
*
to
an array of objects from the To: line, with the following properties: personal, adl, mailbox, and host
*
fromaddress
full from: line, up to 1024 characters
*
from
an array of objects from the From: line, with the following properties: personal, adl, mailbox, and host
*
ccaddress
full cc: line, up to 1024 characters
*
cc
an array of objects from the Cc: line, with the following properties: personal, adl, mailbox, and host
*
bccaddress
full bcc: line, up to 1024 characters
*
bcc
an array of objects from the Bcc: line, with the following properties: personal, adl, mailbox, and host
*
reply_toaddress
full Reply-To: line, up to 1024 characters
*
reply_to
an array of objects from the Reply-To: line, with the following properties: personal, adl, mailbox, and host
*
senderaddress
full sender: line, up to 1024 characters
*
sender
an array of objects from the Sender: line, with the following properties: personal, adl, mailbox, and host
*
return_pathaddress
full Return-Path: line, up to 1024 characters
*
return_path
an array of objects from the Return-Path: line, with the following properties: personal, adl, mailbox, and host
*
remail -
*
date
The message date as found in its headers
*
Date
Same as date
*
subject
The message subject
*
Subject
Same a subject
*
in_reply_to -
*
message_id -
*
newsgroups -
*
followup_to -
*
references -
*
Recent
R if recent and seen, N if recent and not seen, ' ' if not recent.
*
Unseen
U if not seen AND not recent, ' ' if seen OR not seen and recent
*
Flagged
F if flagged, ' ' if not flagged
*
Answered
A if answered, ' ' if unanswered
*
Deleted
D if deleted, ' ' if not deleted
*
Draft
X if draft, ' ' if not draft
*
Msgno
The message number
*
MailDate -
*
Size
The message size
*
udate
mail message date in Unix time
*
fetchfrom
from line formatted to fit fromlength characters
*
fetchsubject
subject line formatted to fit subjectlength characters
*
*/ #[PhpStormStubsElementAvailable(to: '7.4')] function imap_header($stream_id, $msg_no, $from_length = 0, $subject_length = 0, $default_host = null) {} /** * Alias of imap_list * @link https://php.net/manual/en/function.imap-listmailbox.php * @param resource $imap * @param string $reference * @param string $pattern * @return array|false */ function imap_listmailbox(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $reference, string $pattern): array|false {} /** * Read the list of mailboxes, returning detailed information on each one * @link https://php.net/manual/en/function.imap-getmailboxes.php * @param resource $imap * @param string $reference

* ref should normally be just the server * specification as described in imap_open *

* @param string $pattern Specifies where in the mailbox hierarchy * to start searching.

There are two special characters you can * pass as part of the pattern: * '*' and '%'. * '*' means to return all mailboxes. If you pass * pattern as '*', you will * get a list of the entire mailbox hierarchy. * '%' * means to return the current level only. * '%' as the pattern * parameter will return only the top level * mailboxes; '~/mail/%' on UW_IMAPD will return every mailbox in the ~/mail directory, but none in subfolders of that directory.

* @return array|false an array of objects containing mailbox information. Each * object has the attributes name, specifying * the full name of the mailbox; delimiter, * which is the hierarchy delimiter for the part of the hierarchy * this mailbox is in; and * attributes. Attributes * is a bitmask that can be tested against: *

* LATT_NOINFERIORS - This mailbox contains, and may not contain any * "children" (there are no mailboxes below this one). Calling * imap_createmailbox will not work on this mailbox. *

*

* LATT_NOSELECT - This is only a container, * not a mailbox - you cannot open it. *

*

* LATT_MARKED - This mailbox is marked. This means that it may * contain new messages since the last time it was checked. Not provided by all IMAP * servers. *

*

* LATT_UNMARKED - This mailbox is not marked, does not contain new * messages. If either MARKED or UNMARKED is * provided, you can assume the IMAP server supports this feature for this mailbox. *

*/ function imap_getmailboxes(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $reference, string $pattern): array|false {} /** * Alias of imap_listscan * @link https://php.net/manual/en/function.imap-scanmailbox.php * @param $imap * @param $reference * @param $pattern * @param $content */ function imap_scanmailbox(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $reference, string $pattern, string $content): array|false {} /** * Alias of imap_lsub * @link https://php.net/manual/en/function.imap-listsubscribed.php * @param resource $imap * @param string $reference * @param string $pattern * @return array|false */ function imap_listsubscribed(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $reference, string $pattern): array|false {} /** * List all the subscribed mailboxes * @link https://php.net/manual/en/function.imap-getsubscribed.php * @param resource $imap * @param string $reference

* ref should normally be just the server * specification as described in imap_open *

* @param string $pattern Specifies where in the mailbox hierarchy * to start searching.

There are two special characters you can * pass as part of the pattern: * '*' and '%'. * '*' means to return all mailboxes. If you pass * pattern as '*', you will * get a list of the entire mailbox hierarchy. * '%' * means to return the current level only. * '%' as the pattern * parameter will return only the top level * mailboxes; '~/mail/%' on UW_IMAPD will return every mailbox in the ~/mail directory, but none in subfolders of that directory.

* @return array|false an array of objects containing mailbox information. Each * object has the attributes name, specifying * the full name of the mailbox; delimiter, * which is the hierarchy delimiter for the part of the hierarchy * this mailbox is in; and * attributes. Attributes * is a bitmask that can be tested against: * LATT_NOINFERIORS - This mailbox has no * "children" (there are no mailboxes below this one). * LATT_NOSELECT - This is only a container, * not a mailbox - you cannot open it. * LATT_MARKED - This mailbox is marked. * Only used by UW-IMAPD. * LATT_UNMARKED - This mailbox is not marked. * Only used by UW-IMAPD. */ function imap_getsubscribed(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $reference, string $pattern): array|false {} /** * (PHP 4, PHP 5)
* Alias of imap_body() * @param resource $imap An IMAP stream returned by imap_open() * @param int $message_num message number * @param int $flags [optional] A bitmask with one or more of the following:
    *
  • FT_UID - The msg_number is a UID *
  • FT_PEEK - Do not set the \Seen flag if not already set *
  • FT_INTERNAL - The return string is in internal format, will not canonicalize to CRLF.

* @return string|false body of the specified message */ function imap_fetchtext(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, int $message_num, int $flags = 0): string|false {} /** * Alias of imap_listscan * @link https://php.net/manual/en/function.imap-scan.php * @param $imap * @param $reference * @param $pattern * @param $content */ function imap_scan(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $reference, string $pattern, string $content): array|false {} /** * Alias of imap_createmailbox * @link https://php.net/manual/en/function.imap-create.php * @param $imap * @param $mailbox */ function imap_create(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $mailbox): bool {} /** * Alias of imap_renamemailbox * @link https://php.net/manual/en/function.imap-rename.php * @param $imap * @param $from * @param $to */ function imap_rename(#[LanguageLevelTypeAware(['8.1' => 'IMAP\Connection'], default: 'resource')] $imap, string $from, string $to): bool {} /** * Decode a modified UTF-7 string to UTF-8 * * @link https://www.php.net/manual/en/function.imap-mutf7-to-utf8.php * * @param string $string * @return string|false */ function imap_mutf7_to_utf8(string $string): string|false {} /** * Encode a UTF-8 string to modified UTF-7 * * @link https://www.php.net/manual/en/function.imap-utf8-to-mutf7.php * * @param string $string * @return string|false */ function imap_utf8_to_mutf7(string $string): string|false {} /** * @since 8.2 */ function imap_is_open(IMAP\Connection $imap): bool {} /** * @deprecated 8.1 */ define('NIL', 0); define('IMAP_OPENTIMEOUT', 1); define('IMAP_READTIMEOUT', 2); define('IMAP_WRITETIMEOUT', 3); define('IMAP_CLOSETIMEOUT', 4); define('OP_DEBUG', 1); /** * Open mailbox read-only * @link https://php.net/manual/en/imap.constants.php */ define('OP_READONLY', 2); /** * Don't use or update a .newsrc for news * (NNTP only) * @link https://php.net/manual/en/imap.constants.php */ define('OP_ANONYMOUS', 4); define('OP_SHORTCACHE', 8); define('OP_SILENT', 16); define('OP_PROTOTYPE', 32); /** * For IMAP and NNTP * names, open a connection but don't open a mailbox. * @link https://php.net/manual/en/imap.constants.php */ define('OP_HALFOPEN', 64); define('OP_EXPUNGE', 128); define('OP_SECURE', 256); /** * silently expunge the mailbox before closing when * calling imap_close * @link https://php.net/manual/en/imap.constants.php */ define('CL_EXPUNGE', 32768); /** * The parameter is a UID * @link https://php.net/manual/en/imap.constants.php */ define('FT_UID', 1); /** * Do not set the \Seen flag if not already set * @link https://php.net/manual/en/imap.constants.php */ define('FT_PEEK', 2); define('FT_NOT', 4); /** * The return string is in internal format, will not canonicalize to CRLF. * @link https://php.net/manual/en/imap.constants.php */ define('FT_INTERNAL', 8); define('FT_PREFETCHTEXT', 32); /** * The sequence argument contains UIDs instead of sequence numbers * @link https://php.net/manual/en/imap.constants.php */ define('ST_UID', 1); define('ST_SILENT', 2); define('ST_SET', 4); /** * the sequence numbers contain UIDS * @link https://php.net/manual/en/imap.constants.php */ define('CP_UID', 1); /** * Delete the messages from the current mailbox after copying * with imap_mail_copy * @link https://php.net/manual/en/imap.constants.php */ define('CP_MOVE', 2); /** * Return UIDs instead of sequence numbers * @link https://php.net/manual/en/imap.constants.php */ define('SE_UID', 1); define('SE_FREE', 2); /** * Don't prefetch searched messages * @link https://php.net/manual/en/imap.constants.php */ define('SE_NOPREFETCH', 4); define('SO_FREE', 8); define('SO_NOSERVER', 8); define('SA_MESSAGES', 1); define('SA_RECENT', 2); define('SA_UNSEEN', 4); define('SA_UIDNEXT', 8); define('SA_UIDVALIDITY', 16); define('SA_ALL', 31); /** * This mailbox has no "children" (there are no * mailboxes below this one). * @link https://php.net/manual/en/imap.constants.php */ define('LATT_NOINFERIORS', 1); /** * This is only a container, not a mailbox - you * cannot open it. * @link https://php.net/manual/en/imap.constants.php */ define('LATT_NOSELECT', 2); /** * This mailbox is marked. Only used by UW-IMAPD. * @link https://php.net/manual/en/imap.constants.php */ define('LATT_MARKED', 4); /** * This mailbox is not marked. Only used by * UW-IMAPD. * @link https://php.net/manual/en/imap.constants.php */ define('LATT_UNMARKED', 8); define('LATT_REFERRAL', 16); define('LATT_HASCHILDREN', 32); define('LATT_HASNOCHILDREN', 64); /** * Sort criteria for imap_sort: * message Date * @link https://php.net/manual/en/imap.constants.php */ define('SORTDATE', 0); /** * Sort criteria for imap_sort: * arrival date * @link https://php.net/manual/en/imap.constants.php */ define('SORTARRIVAL', 1); /** * Sort criteria for imap_sort: * mailbox in first From address * @link https://php.net/manual/en/imap.constants.php */ define('SORTFROM', 2); /** * Sort criteria for imap_sort: * message subject * @link https://php.net/manual/en/imap.constants.php */ define('SORTSUBJECT', 3); /** * Sort criteria for imap_sort: * mailbox in first To address * @link https://php.net/manual/en/imap.constants.php */ define('SORTTO', 4); /** * Sort criteria for imap_sort: * mailbox in first cc address * @link https://php.net/manual/en/imap.constants.php */ define('SORTCC', 5); /** * Sort criteria for imap_sort: * size of message in octets * @link https://php.net/manual/en/imap.constants.php */ define('SORTSIZE', 6); define('TYPETEXT', 0); define('TYPEMULTIPART', 1); define('TYPEMESSAGE', 2); define('TYPEAPPLICATION', 3); define('TYPEAUDIO', 4); define('TYPEIMAGE', 5); define('TYPEVIDEO', 6); define('TYPEMODEL', 7); define('TYPEOTHER', 8); define('ENC7BIT', 0); define('ENC8BIT', 1); define('ENCBINARY', 2); define('ENCBASE64', 3); define('ENCQUOTEDPRINTABLE', 4); define('ENCOTHER', 5); /** * Garbage collector, clear message cache elements. * @link https://php.net/manual/en/imap.constants.php */ define('IMAP_GC_ELT', 1); /** * Garbage collector, clear envelopes and bodies. * @link https://php.net/manual/en/imap.constants.php */ define('IMAP_GC_ENV', 2); /** * Garbage collector, clear texts. * @link https://php.net/manual/en/imap.constants.php */ define('IMAP_GC_TEXTS', 4); * The location of the image file. This cannot be an URL. * Since 7.2.0 this can either be a path to the file (stream wrappers are also supported as usual) * or a stream resource. *

* @param string|null $required_sections [optional]

* Is a comma separated list of sections that need to be present in file * to produce a result array. If none of the requested * sections could be found the return value is FALSE. * * FILE * FileName, FileSize, FileDateTime, SectionsFound * * * COMPUTED * * html, Width, Height, IsColor, and more if available. Height and * Width are computed the same way getimagesize * does so their values must not be part of any header returned. * Also, html is a height/width text string to be used inside normal * HTML. * * * * ANY_TAG * Any information that has a Tag e.g. IFD0, EXIF, ... * * * IFD0 * * All tagged data of IFD0. In normal imagefiles this contains * image size and so forth. * * * * THUMBNAIL * * A file is supposed to contain a thumbnail if it has a second IFD. * All tagged information about the embedded thumbnail is stored in * this section. * * * * COMMENT * Comment headers of JPEG images. * * * EXIF * * The EXIF section is a sub section of IFD0. It contains * more detailed information about an image. Most of these entries * are digital camera related. * * *

* @param bool $as_arrays [optional]

* Specifies whether or not each section becomes an array. The * sections COMPUTED, * THUMBNAIL, and COMMENT * always become arrays as they may contain values whose names conflict * with other sections. *

* @param bool $read_thumbnail [optional]

* When set to TRUE the thumbnail itself is read. Otherwise, only the * tagged data is read. *

* @return array|false It returns an associative array where the array indexes are * the header names and the array values are the values associated with * those headers. If no data can be returned, * exif_read_data will return FALSE. */ function exif_read_data($file, ?string $required_sections, bool $as_arrays = false, bool $read_thumbnail = false): array|false {} /** * Alias of exif_read_data * @link https://php.net/manual/en/function.read-exif-data.php * @param $filename * @param $sections [optional] * @param $arrays [optional] * @param $thumbnail [optional] * @removed 8.0 */ #[Deprecated(replacement: "exif_read_data(%parametersList%)", since: "7.2")] function read_exif_data($filename, $sections = null, $arrays = false, $thumbnail = false) {} /** * Get the header name for an index * @link https://php.net/manual/en/function.exif-tagname.php * @param int $index

* The Tag ID for which a Tag Name will be looked up. *

* @return string|false the header name, or FALSE if index is * not a defined EXIF tag id. */ function exif_tagname(int $index): string|false {} /** * Retrieve the embedded thumbnail of a TIFF or JPEG image * @link https://php.net/manual/en/function.exif-thumbnail.php * @param string|resource $file

* The location of the image file. This cannot be an URL. * Since 7.2.0 this can either be a path to the file (stream wrappers are also supported as usual) * or a stream resource. *

* @param int &$width [optional]

* The return width of the returned thumbnail. *

* @param int &$height [optional]

* The returned height of the returned thumbnail. *

* @param int &$image_type [optional]

* The returned image type of the returned thumbnail. This is either * TIFF or JPEG. *

* @return string|false the embedded thumbnail, or FALSE if the image contains no * thumbnail. */ function exif_thumbnail($file, &$width, &$height, &$image_type): string|false {} /** * Determine the type of an image * @link https://php.net/manual/en/function.exif-imagetype.php * @param string $filename The image being checked. * @return int|false When a correct signature is found, the appropriate constant value will be * returned otherwise the return value is FALSE. The return value is the * same value that getimagesize returns in index 2 but * exif_imagetype is much faster. *

*

* exif_imagetype will emit an E_NOTICE * and return FALSE if it is unable to read enough bytes from the file to * determine the image type. */ function exif_imagetype(string $filename): int|false {} define('EXIF_USE_MBSTRING', 1); // End of exif v.1.4 $Id$ amqp.host The host to connect too. Note: Max 1024 characters. * 'port' => amqp.port Port on the host. * 'vhost' => amqp.vhost The virtual host on the host. Note: Max 128 characters. * 'login' => amqp.login The login name to use. Note: Max 128 characters. * 'password' => amqp.password Password. Note: Max 128 characters. * 'read_timeout' => Timeout in for income activity. Note: 0 or greater seconds. May be fractional. * 'write_timeout' => Timeout in for outcome activity. Note: 0 or greater seconds. May be fractional. * 'connect_timeout' => Connection timeout. Note: 0 or greater seconds. May be fractional. * 'rpc_timeout' => RPC timeout. Note: 0 or greater seconds. May be fractional. * * Connection tuning options (see http://www.rabbitmq.com/amqp-0-9-1-reference.html#connection.tune for details): * 'channel_max' => Specifies highest channel number that the server permits. 0 means standard extension limit * (see PHP_AMQP_MAX_CHANNELS constant) * 'frame_max' => The largest frame size that the server proposes for the connection, including frame header * and end-byte. 0 means standard extension limit (depends on librabbimq default frame size limit) * 'heartbeat' => The delay, in seconds, of the connection heartbeat that the server wants. * 0 means the server does not want a heartbeat. Note, librabbitmq has limited heartbeat support, * which means heartbeats checked only during blocking calls. * * TLS support (see https://www.rabbitmq.com/ssl.html for details): * 'cacert' => Path to the CA cert file in PEM format.. * 'cert' => Path to the client certificate in PEM foramt. * 'key' => Path to the client key in PEM format. * 'verify' => Enable or disable peer verification. If peer verification is enabled then the common name in the * server certificate must match the server name. Peer verification is enabled by default. * * 'connection_name' => A user determined name for the connection * ) * * @param array $credentials Optional array of credential information for * connecting to the AMQP broker. */ public function __construct(array $credentials = []) {} /** * Check whether the connection to the AMQP broker is still valid. * * Cannot reliably detect dropped connections or unusual socket errors, as it does not actively * engage the socket. * * @return bool TRUE if connected, FALSE otherwise. */ public function isConnected() {} /** * Whether connection persistent. * * When no connection is established, it will always return FALSE. The same disclaimer as for * {@see AMQPConnection::isConnected()} applies. * * @return bool TRUE if persistently connected, FALSE otherwise. */ public function isPersistent() {} /** * Establish a transient connection with the AMQP broker. * * This method will initiate a connection with the AMQP broker. * * @throws AMQPConnectionException * @return void */ public function connect() {} /** * Closes the transient connection with the AMQP broker. * * This method will close an open connection with the AMQP broker. * * @throws AMQPConnectionException When attempting to disconnect a persistent connection * * @return void */ public function disconnect() {} /** * Close any open transient connections and initiate a new one with the AMQP broker. * * @return void */ public function reconnect() {} /** * Establish a persistent connection with the AMQP broker. * * This method will initiate a connection with the AMQP broker * or reuse an existing one if present. * * @throws AMQPConnectionException * @return void */ public function pconnect() {} /** * Closes a persistent connection with the AMQP broker. * * This method will close an open persistent connection with the AMQP * broker. * * @throws AMQPConnectionException When attempting to disconnect a transient connection * * @return void */ public function pdisconnect() {} /** * Close any open persistent connections and initiate a new one with the AMQP broker. * * @throws AMQPConnectionException * * @return void */ public function preconnect() {} /** * Get the configured host. * * @return string The configured hostname of the broker */ public function getHost() {} /** * Get the configured login. * * @return string The configured login as a string. */ public function getLogin() {} /** * Get the configured password. * * @return string The configured password as a string. */ public function getPassword() {} /** * Get the configured port. * * @return int The configured port as an integer. */ public function getPort() {} /** * Get the configured vhost. * * @return string The configured virtual host as a string. */ public function getVhost() {} /** * Set the hostname used to connect to the AMQP broker. * * @param string $host The hostname of the AMQP broker. * * @throws AMQPConnectionException If host is longer then 1024 characters. * * @return void */ public function setHost($host) {} /** * Set the login string used to connect to the AMQP broker. * * @param string $login The login string used to authenticate * with the AMQP broker. * * @throws AMQPConnectionException If login is longer then 32 characters. * * @return void */ public function setLogin($login) {} /** * Set the password string used to connect to the AMQP broker. * * @param string $password The password string used to authenticate * with the AMQP broker. * * @throws AMQPConnectionException If password is longer then 32characters. * * @return void */ public function setPassword($password) {} /** * Set the port used to connect to the AMQP broker. * * @param int $port The port used to connect to the AMQP broker. * * @throws AMQPConnectionException If port is longer not between * 1 and 65535. * * @return void */ public function setPort($port) {} /** * Sets the virtual host to which to connect on the AMQP broker. * * @param string $vhost The virtual host to use on the AMQP * broker. * * @throws AMQPConnectionException If host is longer then 32 characters. * * @return void */ public function setVhost($vhost) {} /** * Sets the interval of time to wait for income activity from AMQP broker * * @deprecated use AMQPConnection::setReadTimeout($timeout) instead * * @param float $timeout * * @throws AMQPConnectionException If timeout is less than 0. * * @return void */ #[Deprecated(replacement: "%class%->setReadTimout(%parameter0%)")] public function setTimeout($timeout) {} /** * Get the configured interval of time to wait for income activity * from AMQP broker * * @deprecated use AMQPConnection::getReadTimeout() instead * * @return float */ #[Deprecated(replacement: '%class%->getReadTimout(%parameter0%)')] public function getTimeout() {} /** * Sets the interval of time to wait for income activity from AMQP broker * * @param float $timeout * * @throws AMQPConnectionException If timeout is less than 0. * * @return void */ public function setReadTimeout($timeout) {} /** * Get the configured interval of time to wait for income activity * from AMQP broker * * @return float */ public function getReadTimeout() {} /** * Sets the interval of time to wait for outcome activity to AMQP broker * * @param float $timeout * * @throws AMQPConnectionException If timeout is less than 0. * * @return void */ public function setWriteTimeout($timeout) {} /** * Get the configured interval of time to wait for outcome activity * to AMQP broker * * @return float */ public function getWriteTimeout() {} /** * Get the configured timeout (in seconds) for connecting to the AMQP broker */ public function getConnectTimeout(): float {} /** * Sets the interval of time to wait for RPC activity to AMQP broker * * @param float $timeout * * @throws AMQPConnectionException If timeout is less than 0. * * @return void */ public function setRpcTimeout($timeout) {} /** * Get the configured interval of time to wait for RPC activity * to AMQP broker * * @return float */ public function getRpcTimeout() {} /** * Return last used channel id during current connection session. * * @return int */ public function getUsedChannels() {} /** * Get the maximum number of channels the connection can handle. * * When connection is connected, effective connection value returned, which is normally the same as original * correspondent value passed to constructor, otherwise original value passed to constructor returned. * * @return int */ public function getMaxChannels() {} /** * Get max supported frame size per connection in bytes. * * When connection is connected, effective connection value returned, which is normally the same as original * correspondent value passed to constructor, otherwise original value passed to constructor returned. * * @return int */ public function getMaxFrameSize() {} /** * Get number of seconds between heartbeats of the connection in seconds. * * When connection is connected, effective connection value returned, which is normally the same as original * correspondent value passed to constructor, otherwise original value passed to constructor returned. * * @return int */ public function getHeartbeatInterval() {} /** * Get path to the CA cert file in PEM format * * @return string|null */ public function getCACert() {} /** * Set path to the CA cert file in PEM format * * @param string $cacert * * @return void */ public function setCACert($cacert) {} /** * Get path to the client certificate in PEM format * * @return string|null */ public function getCert() {} /** * Set path to the client certificate in PEM format * * @param string $cert * * @return void */ public function setCert($cert) {} /** * Get path to the client key in PEM format * * @return string|null */ public function getKey() {} /** * Set path to the client key in PEM format * * @param string|null $key * * @return void */ public function setKey($key) {} /** * Get whether peer verification enabled or disabled * * @return bool */ public function getVerify() {} /** * Enable or disable peer verification * * @param bool $verify * * @return void */ public function setVerify($verify) {} /** * set authentication method * * @param int $saslMethod AMQP_SASL_METHOD_PLAIN | AMQP_SASL_METHOD_EXTERNAL * * @return void */ public function setSaslMethod($method) {} /** * Get authentication mechanism configuration * * @return int AMQP_SASL_METHOD_PLAIN | AMQP_SASL_METHOD_EXTERNAL */ public function getSaslMethod() {} public function setConnectionName(?string $connectionName): void {} public function getConnectionName(): ?string {} } /** * stub class representing AMQPConnectionException from pecl-amqp */ class AMQPConnectionException extends AMQPException {} /** * Interface representing AMQP values */ interface AMQPValue { public function toAmqpValue(): float|array|AMQPDecimal|bool|int|AMQPValue|string|AMQPTimestamp|null; } /** * stub class representing AMQPDecimal from pecl-amqp */ final /* readonly */ class AMQPDecimal implements AMQPValue { public const EXPONENT_MIN = 0; public const EXPONENT_MAX = 255; public const SIGNIFICAND_MIN = 0; public const SIGNIFICAND_MAX = 4294967295; /** * @param $exponent * @param $significand * * @throws AMQPExchangeValue */ public function __construct($exponent, $significand) {} /** @return int */ public function getExponent() {} /** @return int */ public function getSignificand() {} public function toAmqpValue(): float|array|AMQPDecimal|bool|int|AMQPValue|string|AMQPTimestamp|null {} } /** * stub class representing AMQPEnvelope from pecl-amqp */ class AMQPEnvelope extends AMQPBasicProperties { /** * Get the body of the message. * * @return string The contents of the message body. */ public function getBody() {} /** * Get the routing key of the message. * * @return string The message routing key. */ public function getRoutingKey() {} /** * Get the consumer tag of the message. * * @return string|null The consumer tag of the message. */ public function getConsumerTag() {} /** * Get the delivery tag of the message. * * @return int|null The delivery tag of the message. */ public function getDeliveryTag() {} /** * Get the exchange name on which the message was published. * * @return string|null The exchange name on which the message was published. */ public function getExchangeName() {} /** * Whether this is a redelivery of the message. * * Whether this is a redelivery of a message. If this message has been * delivered and AMQPEnvelope::nack() was called, the message will be put * back on the queue to be redelivered, at which point the message will * always return TRUE when this method is called. * * @return bool TRUE if this is a redelivery, FALSE otherwise. */ public function isRedelivery() {} /** * Get a specific message header. * * @param string $headerName Name of the header to get the value from. * * @return mixed The contents of the specified header or null if not set. */ public function getHeader($headerName) {} /** * Check whether specific message header exists. * * @param string $headerName Name of the header to check. * * @return bool */ public function hasHeader($headerName) {} } /** * stub class representing AMQPEnvelopeException from pecl-amqp */ class AMQPEnvelopeException extends AMQPException { public function getEnvelope(): AMQPEnvelope {} } /** * stub class representing AMQPException from pecl-amqp */ class AMQPException extends Exception {} /** * stub class representing AMQPExchange from pecl-amqp */ class AMQPExchange { /** * Create an instance of AMQPExchange. * * Returns a new instance of an AMQPExchange object, associated with the * given AMQPChannel object. * * @param AMQPChannel $channel A valid AMQPChannel object, connected * to a broker. * * @throws AMQPExchangeException When amqp_channel is not connected to * a broker. * @throws AMQPConnectionException If the connection to the broker was * lost. */ public function __construct(AMQPChannel $channel) {} /** * Bind to another exchange. * * Bind an exchange to another exchange using the specified routing key. * * @param string $exchangeName Name of the exchange to bind. * @param string $routingKey The routing key to use for binding. * @param array $arguments Additional binding arguments. * * @throws AMQPExchangeException On failure. * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return void */ public function bind($exchangeName, $routingKey = '', array $arguments = []) {} /** * Remove binding to another exchange. * * Remove a routing key binding on an another exchange from the given exchange. * * @param string $exchangeName Name of the exchange to bind. * @param string $routingKey The routing key to use for binding. * @param array $arguments Additional binding arguments. * * @throws AMQPExchangeException On failure. * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return void */ public function unbind($exchangeName, $routingKey = '', array $arguments = []) {} /** * Declare a new exchange on the broker. * * @throws AMQPExchangeException On failure. * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return void */ public function declareExchange() {} /** * Declare a new exchange on the broker. * * @throws AMQPExchangeException On failure. * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return void */ public function declare(): void {} /** * Delete the exchange from the broker. * * @param string $exchangeName Optional name of exchange to delete. * @param int $flags Optionally AMQP_IFUNUSED can be specified * to indicate the exchange should not be * deleted until no clients are connected to * it. * * @throws AMQPExchangeException On failure. * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return void */ public function delete($exchangeName = null, $flags = AMQP_NOPARAM) {} /** * Get the argument associated with the given key. * Get the argument associated with the given key. * * @param string $argumentName The key to look up. * * @throws AMQPExchangeException If key does not exist * * @return bool|int|float|string|null */ public function getArgument($argumentName) {} /** * Check whether argument associated with the given key exists. * * @param string $argumentName The key to look up. * * @return bool */ public function hasArgument($argumentName) {} /** * Get all arguments set on the given exchange. * * @return array An array containing all of the set key/value pairs. */ public function getArguments() {} /** * Get all the flags currently set on the given exchange. * * @return int An integer bitmask of all the flags currently set on this * exchange object. */ public function getFlags() {} /** * Get the configured name. * * @return string|null The configured name as a string. */ public function getName() {} /** * Get the configured type. * * @return string|null The configured type as a string. */ public function getType() {} /** * Publish a message to an exchange. * * Publish a message to the exchange represented by the AMQPExchange object. * * @param string $message The message to publish. * @param string|null $routingKey The optional routing key to which to * publish to. * @param int|null $flags One or more of AMQP_MANDATORY and * AMQP_IMMEDIATE. * @param array $headers One of content_type, content_encoding, * message_id, user_id, app_id, delivery_mode, * priority, timestamp, expiration, type * or reply_to, headers. * * @throws AMQPExchangeException On failure. * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return void */ public function publish( $message, $routingKey = null, $flags = null, array $headers = [] ) {} /** * Set the value for the given key. * * @param string $argumentName Name of the argument to set. * @param string|int $argumentValue Value of the argument to set. * * @return void */ public function setArgument($argumentName, $argumentValue) {} /** * Set the value for the given key. * * @param string $argumentName Name of the argument to remove. */ public function removeArgument(string $argumentName): void {} /** * Set all arguments on the exchange. * * @param array $arguments An array of key/value pairs of arguments. * * @return bool TRUE on success or FALSE on failure. */ public function setArguments(array $arguments) {} /** * Set the flags on an exchange. * * @param int|null $flags A bitmask of flags. This call currently only * considers the following flags: * AMQP_DURABLE, AMQP_PASSIVE * (and AMQP_DURABLE, if librabbitmq version >= 0.5.3) * * @return void */ public function setFlags($flags) {} /** * Set the name of the exchange. * * @param string $exchangeName The name of the exchange to set as string. * * @return void */ public function setName($exchangeName) {} /** * Set the type of the exchange. * * Set the type of the exchange. This can be any of AMQP_EX_TYPE_DIRECT, * AMQP_EX_TYPE_FANOUT, AMQP_EX_TYPE_HEADERS or AMQP_EX_TYPE_TOPIC. * * @param string $exchangeType The type of exchange as a string. * * @return void */ public function setType($exchangeType) {} /** * Get the AMQPChannel object in use * * @return AMQPChannel */ public function getChannel() {} /** * Get the AMQPConnection object in use * * @return AMQPConnection */ public function getConnection() {} } /** * stub class representing AMQPExchangeException from pecl-amqp */ class AMQPExchangeException extends AMQPException {} /** * stub class representing AMQPQueue from pecl-amqp */ class AMQPQueue { /** * Create an instance of an AMQPQueue object. * * @param AMQPChannel $channel The amqp channel to use. * * @throws AMQPQueueException When amqp_channel is not connected to a * broker. * @throws AMQPConnectionException If the connection to the broker was lost. */ public function __construct(AMQPChannel $channel) {} /** * Acknowledge the receipt of a message. * * This method allows the acknowledgement of a message that is retrieved * without the AMQP_AUTOACK flag through AMQPQueue::get() or * AMQPQueue::consume() * * @param int $deliveryTag The message delivery tag of which to * acknowledge receipt. * @param int|null $flags The only valid flag that can be passed is * AMQP_MULTIPLE. * * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return void */ public function ack($deliveryTag, $flags = null) {} /** * Bind the given queue to a routing key on an exchange. * * @param string $exchangeName Name of the exchange to bind to. * @param string|null $routingKey Pattern or routing key to bind with. * @param array $arguments Additional binding arguments. * * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return bool */ public function bind($exchangeName, $routingKey = null, array $arguments = []) {} /** * Cancel a queue that is already bound to an exchange and routing key. * * @param string $consumer_tag The consumer tag cancel. If no tag provided, * or it is empty string, the latest consumer * tag on this queue will be used and after * successful request it will set to null. * If it also empty, no `basic.cancel` * request will be sent. When consumer_tag give * and it equals to latest consumer_tag on queue, * it will be interpreted as latest consumer_tag usage. * * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return bool */ public function cancel($consumer_tag = '') {} /** * Consume messages from a queue. * * Blocking function that will retrieve the next message from the queue as * it becomes available and will pass it off to the callback. * * @param callable|null $callback A callback function to which the * consumed message will be passed. The * function must accept at a minimum * one parameter, an AMQPEnvelope object, * and an optional second parameter * the AMQPQueue object from which callback * was invoked. The AMQPQueue::consume() will * not return the processing thread back to * the PHP script until the callback * function returns FALSE. * If the callback is omitted or null is passed, * then the messages delivered to this client will * be made available to the first real callback * registered. That allows one to have a single * callback consuming from multiple queues. * @param int|null $flags A bitmask of any of the flags: AMQP_AUTOACK, * AMQP_JUST_CONSUME. Note: when AMQP_JUST_CONSUME * flag used all other flags are ignored and * $consumerTag parameter has no sense. * AMQP_JUST_CONSUME flag prevent from sending * `basic.consume` request and just run $callback * if it provided. Calling method with empty $callback * and AMQP_JUST_CONSUME makes no sense. * @param string|null $consumerTag A string describing this consumer. Used * for canceling subscriptions with cancel(). * * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * @throws AMQPEnvelopeException When no queue found for envelope. * @throws AMQPQueueException If timeout occurs or queue is not exists. * * @return void */ public function consume( callable $callback = null, $flags = null, $consumerTag = null ) {} /** * Declare a new queue on the broker. * * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * @throws AMQPQueueException On failure. * * @return int the message count. */ public function declareQueue() {} /** * Declare a new queue on the broker. * * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * @throws AMQPQueueException On failure. * * @return int the message count. */ public function declare(): int {} /** * Delete a queue from the broker. * * This includes its entire contents of unread or unacknowledged messages. * * @param int $flags Optionally AMQP_IFUNUSED can be specified * to indicate the queue should not be * deleted until no clients are connected to * it. * * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return int The number of deleted messages. */ public function delete($flags = AMQP_NOPARAM) {} /** * Retrieve the next message from the queue. * * Retrieve the next available message from the queue. If no messages are * present in the queue, this function will return NULL immediately. This * is a non blocking alternative to the AMQPQueue::consume() method. * Currently, the only supported flag for the flags parameter is * AMQP_AUTOACK. If this flag is passed in, then the message returned will * automatically be marked as acknowledged by the broker as soon as the * frames are sent to the client. * * @param int $flags A bitmask of supported flags for the * method call. Currently, the only the * supported flag is AMQP_AUTOACK. If this * value is not provided, it will use the * value of ini-setting amqp.auto_ack. * * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * @throws AMQPQueueException If queue is not exist. * * @return AMQPEnvelope|null */ public function get($flags = null) {} /** * Get all the flags currently set on the given queue. * * @return int An integer bitmask of all the flags currently set on this * exchange object. */ public function getFlags(): int {} /** * Get the configured name. * * @return string|null The configured name as a string. */ public function getName(): ?string {} /** * Mark a message as explicitly not acknowledged. * * Mark the message identified by delivery_tag as explicitly not * acknowledged. This method can only be called on messages that have not * yet been acknowledged, meaning that messages retrieved with by * AMQPQueue::consume() and AMQPQueue::get() and using the AMQP_AUTOACK * flag are not eligible. When called, the broker will immediately put the * message back onto the queue, instead of waiting until the connection is * closed. This method is only supported by the RabbitMQ broker. The * behavior of calling this method while connected to any other broker is * undefined. * * @param int $deliveryTag Delivery tag of last message to reject. * @param int $flags AMQP_REQUEUE to requeue the message(s), * AMQP_MULTIPLE to nack all previous * unacked messages as well. * * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return bool */ public function nack($deliveryTag, $flags = AMQP_NOPARAM) {} /** * Mark one message as explicitly not acknowledged. * * Mark the message identified by delivery_tag as explicitly not * acknowledged. This method can only be called on messages that have not * yet been acknowledged, meaning that messages retrieved with by * AMQPQueue::consume() and AMQPQueue::get() and using the AMQP_AUTOACK * flag are not eligible. * * @param int $deliveryTag Delivery tag of the message to reject. * @param int|null $flags AMQP_REQUEUE to requeue the message(s). * * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return bool */ public function reject($deliveryTag, $flags = null) {} /** * Recover unacknowledged messages delivered to the current consumer. * * Recover all the unacknowledged messages delivered to the current consumer. * If $requeue is true, the broker can redeliver the messages to different * consumers. If $requeue is FALSE, it can only redeliver it to the current * consumer. RabbitMQ does not implement $request = false. * This method exposes `basic.recover` from the AMQP spec. * * @param bool $requeue If TRUE, deliver to any consumer, if FALSE, deliver to the current consumer only * @throws AMQPConnectionException If the connection to the broker was lost. * @throws AMQPChannelException If the channel is not open. */ public function recover(bool $requeue = true): void {} /** * Purge the contents of a queue. * * Returns the number of purged messages * * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return int */ public function purge() {} /** * Get the argument associated with the given key. * * @param string $argumentName The key to look up. * @throws AMQPQueueException If key does not exist * @return bool|int|float|string|null|array|AMQPValue|AMQPDecimal|AMQPTimestamp */ public function getArgument($argumentName) {} /** * Set a queue argument. * * @param string $argumentName The key to set. * @param bool|int|float|string|null|array|AMQPValue|AMQPDecimal|AMQPTimestamp $argumentValue The argument value to set. * * @return void */ public function setArgument(string $argumentName, $argumentValue) {} /** * Set a queue argument. * * @param string $argumentName The argument name to set. */ public function removeArgument(string $argumentName): void {} /** * Set all arguments on the given queue. * * All other argument settings will be wiped. * * @param array $arguments An array of name/value pairs of arguments. */ public function setArguments(array $arguments): void {} /** * Get all set arguments as an array of key/value pairs. * * @return array An array containing all the set key/value pairs. */ public function getArguments(): array {} /** * Check whether a queue has specific argument. * * @param string $argumentName The argument name to check. * * @return bool */ public function hasArgument(string $argumentName): bool {} /** * Set the flags on the queue. * * @param int|null $flags A bitmask of flags: * AMQP_DURABLE, AMQP_PASSIVE, * AMQP_EXCLUSIVE, AMQP_AUTODELETE. * * @return bool */ public function setFlags($flags = null) {} /** * Set the queue name. * * @param string $name The name of the queue. * * @return bool */ public function setName($name) {} /** * Remove a routing key binding on an exchange from the given queue. * * @param string $exchangeName The name of the exchange on which the * queue is bound. * @param string|null $routingKey The binding routing key used by the * queue. * @param array $arguments Additional binding arguments. * * @throws AMQPChannelException If the channel is not open. * @throws AMQPConnectionException If the connection to the broker was lost. * * @return bool */ public function unbind($exchangeName, $routingKey = null, array $arguments = []) {} /** * Get the AMQPChannel object in use * * @return AMQPChannel */ public function getChannel() {} /** * Get the AMQPConnection object in use * * @return AMQPConnection */ public function getConnection() {} /** * Get latest consumer tag. If no consumer available or the latest on was canceled null will be returned. * * @return string|null */ public function getConsumerTag() {} } /** * stub class representing AMQPQueueException from pecl-amqp */ class AMQPQueueException extends AMQPException {} class AMQPValueException extends AMQPException {} /** * stub class representing AMQPTimestamp from pecl-amqp */ final /* readonly */ class AMQPTimestamp implements AMQPValue { public const MIN = 0.0; public const MAX = 18446744073709551616; /** * @throws AMQPValueException */ public function __construct(float $timestamp) {} public function __toString(): string {} public function getTimestamp(): float {} public function toAmqpValue(): float|array|AMQPDecimal|bool|int|AMQPValue|string|AMQPTimestamp|null {} } /** * stub class representing AMQPExchangeValue from pecl-amqp */ class AMQPExchangeValue extends AMQPException {} * Shall start recording coverage information * @return void */ function start() {} /** * (PHP >= 7.0, PECL pcov >= 1.0.0)
* Shall stop recording coverage information * @return void */ function stop() {} /** * (PHP >= 7.0, PECL pcov >= 1.0.0)
* Shall collect coverage information * @param int $type [optional]

* pcov\all shall collect coverage information for all files * pcov\inclusive shall collect coverage information for the specified files * pcov\exclusive shall collect coverage information for all but the specified files *

* @param array $filter

* path of files (realpath) that should be filtered *

* @return array */ function collect(int $type = all, array $filter = []) {} /** * (PHP >= 7.0, PECL pcov >= 1.0.0)
* Shall clear stored information * @param bool $files [optional]

* set true to clear file tables * Note: clearing the file tables may have surprising consequences *

* @return void */ function clear(bool $files = false) {} /** * (PHP >= 7.0, PECL pcov >= 1.0.0)
* Shall return list of files waiting to be collected * @return array */ function waiting() {} /** * (PHP >= 7.0, PECL pcov >= 1.0.0)
* Shall return the current size of the trace and cfg arena * @return int */ function memory() {} } * Checks out a working copy from the repository * @link https://php.net/manual/en/function.svn-checkout.php * @param string $repos

* String URL path to directory in repository to check out. *

* @param string $targetpath

* String local path to directory to check out in to *

* Relative paths will be resolved as if the current working directory was the one that contains the PHP binary. To use the calling script's working directory, use realpath or dirname(__FILE__). * @param int $revision [optional]

* Integer revision number of repository to check out. Default is * HEAD, the most recent revision. *

* @param int $flags [optional]

* Any combination of SVN_NON_RECURSIVE and * SVN_IGNORE_EXTERNALS. *

* @return bool TRUE on success or FALSE on failure. */ function svn_checkout($repos, $targetpath, $revision = SVN_REVISION_HEAD, $flags = 0) {} /** * (PECL svn >= 0.1.0)
* Returns the contents of a file in a repository * @link https://php.net/manual/en/function.svn-cat.php * @param string $repos_url

* String URL path to item in a repository. *

* @param int $revision_no [optional]

* Integer revision number of item to retrieve, default is the HEAD * revision. *

* @return string the string contents of the item from the repository on * success, and FALSE on failure. */ function svn_cat($repos_url, $revision_no = SVN_REVISION_HEAD) {} /** * (PECL svn >= 0.1.0)
* Returns list of directory contents in repository URL, optionally at revision number * @link https://php.net/manual/en/function.svn-ls.php * @param string $repos_url * @param int $revision_no [optional] * @param bool $recurse [optional]

* Enables recursion. *

* @param bool $peg [optional] * @return array On success, this function returns an array file listing in the format * of: *
 * [0] => Array
 * (
 * [created_rev] => integer revision number of last edit
 * [last_author] => string author name of last edit
 * [size] => integer byte file size of file
 * [time] => string date of last edit in form 'M d H:i'
 * or 'M d Y', depending on how old the file is
 * [time_t] => integer unix timestamp of last edit
 * [name] => name of file/directory
 * [type] => type, can be 'file' or 'dir'
 * )
 * [1] => ...
 * 
*/ function svn_ls($repos_url, $revision_no = SVN_REVISION_HEAD, $recurse = false, $peg = false) {} /** * (PECL svn >= 0.1.0)
* Returns the commit log messages of a repository URL * @link https://php.net/manual/en/function.svn-log.php * @param string $repos_url

* Repository URL of the item to retrieve log history from. *

* @param int $start_revision [optional]

* Revision number of the first log to retrieve. Use * SVN_REVISION_HEAD to retrieve the log from * the most recent revision. *

* @param int $end_revision [optional]

* Revision number of the last log to retrieve. Defaults to * start_revision if specified or to * SVN_REVISION_INITIAL otherwise. *

* @param int $limit [optional]

* Number of logs to retrieve. *

* @param int $flags [optional]

* Any combination of SVN_OMIT_MESSAGES, * SVN_DISCOVER_CHANGED_PATHS and * SVN_STOP_ON_COPY. *

* @return array On success, this function returns an array file listing in the format * of: *
 * [0] => Array, ordered most recent (highest) revision first
 * (
 * [rev] => integer revision number
 * [author] => string author name
 * [msg] => string log message
 * [date] => string date formatted per ISO 8601, i.e. date('c')
 * [paths] => Array, describing changed files
 * (
 * [0] => Array
 * (
 * [action] => string letter signifying change
 * [path] => absolute repository path of changed file
 * )
 * [1] => ...
 * )
 * )
 * [1] => ...
 * 
*

*

* The output will always be a numerically indexed array of arrays, * even when there are none or only one log message(s). *

*

* The value of action is a subset of the * status output * in the first column, where possible values are: *

* * Actions * * * * * * * * * * * * * * * * * * * * *
LetterDescription
MItem/props was modified
AItem was added
DItem was deleted
RItem was replaced
*

* If no changes were made to the item, an empty array is returned. */ function svn_log($repos_url, $start_revision = null, $end_revision = null, $limit = 0, $flags = SVN_DISCOVER_CHANGED_PATHS|SVN_STOP_ON_COPY) {} /** * (PECL svn >= 0.1.0)
* Sets an authentication parameter * @link https://php.net/manual/en/function.svn-auth-set-parameter.php * @param string $key

* String key name. Use the authentication constants * defined by this extension to specify a key. *

* @param string $value

* String value to set to parameter at key. Format of value varies * with the parameter. *

* @return void No value is returned. */ function svn_auth_set_parameter($key, $value) {} /** * (PECL svn >= 0.1.0)
* Retrieves authentication parameter * @link https://php.net/manual/en/function.svn-auth-get-parameter.php * @param string $key

* String key name. Use the authentication constants * defined by this extension to specify a key. *

* @return string|null the string value of the parameter at key; * returns NULL if parameter does not exist. */ function svn_auth_get_parameter($key) {} /** * (PECL svn >= 0.1.0)
* Returns the version of the SVN client libraries * @link https://php.net/manual/en/function.svn-client-version.php * @return string String version number, usually in form of x.y.z. */ function svn_client_version() {} function svn_config_ensure() {} /** * (PECL svn >= 0.1.0)
* Recursively diffs two paths * @link https://php.net/manual/en/function.svn-diff.php * @param string $path1

* First path to diff. This can be a URL to a file/directory in an SVN * repository or a local file/directory path. *

* Relative paths will be resolved as if the current working directory was the one that contains the PHP binary. To use the calling script's working directory, use realpath or dirname(__FILE__). * If a local file path has only backslashes and no forward slashes, * this extension will fail to find the path. Always * replace all backslashes with forward slashes when using this * function. * @param int $rev1

* First path's revision number. Use SVN_REVISION_HEAD * to specify the most recent revision. *

* @param string $path2

* Second path to diff. See path1 for description. *

* @param int $rev2

* Second path's revision number. See rev1 * for description. *

* @return array an array-list consisting of two streams: the first is the diff output * and the second contains error stream output. The streams can be * read using fread. Returns FALSE or NULL on * error. *

*

* The diff output will, by default, be in the form of Subversion's * custom unified diff format, but an * external * diff engine may be * used depending on Subversion's configuration. */ function svn_diff($path1, $rev1, $path2, $rev2) {} /** * (PECL svn >= 0.1.0)
* Recursively cleanup a working copy directory, finishing incomplete operations and removing locks * @link https://php.net/manual/en/function.svn-cleanup.php * @param string $workingdir

* String path to local working directory to cleanup *

* Relative paths will be resolved as if the current working directory was the one that contains the PHP binary. To use the calling script's working directory, use realpath or dirname(__FILE__). * @return bool TRUE on success or FALSE on failure. */ function svn_cleanup($workingdir) {} /** * (PECL svn >= 0.3.0)
* Revert changes to the working copy * @link https://php.net/manual/en/function.svn-revert.php * @param string $path

* The path to the working repository. *

* @param bool $recursive [optional]

* Optionally make recursive changes. *

* @return bool TRUE on success or FALSE on failure. */ function svn_revert($path, $recursive = false) {} function svn_resolved() {} /** * (PECL svn >= 0.1.0)
* Sends changes from the local working copy to the repository * @link https://php.net/manual/en/function.svn-commit.php * @param string $log

* String log text to commit *

* @param array $targets

* Array of local paths of files to be committed *

* This parameter must be an array, a string for a single * target is not acceptable. * Relative paths will be resolved as if the current working directory was the one that contains the PHP binary. To use the calling script's working directory, use realpath or dirname(__FILE__). * @param bool $recursive [optional]

* Boolean flag to disable recursive committing of * directories in the targets array. * Default is TRUE. *

* @return array array in form of: *
 * array(
 * 0 => integer revision number of commit
 * 1 => string ISO 8601 date and time of commit
 * 2 => name of committer
 * )
 * 
*

* Returns FALSE on failure. *

*/ function svn_commit($log, array $targets, $recursive = true) {} function svn_lock() {} function svn_unlock() {} /** * (PECL svn >= 0.1.0)
* Schedules the addition of an item in a working directory * @link https://php.net/manual/en/function.svn-add.php * @param string $path

* Path of item to add. *

* Relative paths will be resolved as if the current working directory was the one that contains the PHP binary. To use the calling script's working directory, use realpath or dirname(__FILE__). * @param bool $recursive [optional]

* If item is directory, whether or not to recursively add * all of its contents. Default is TRUE *

* @param bool $force [optional]

* If true, Subversion will recurse into already versioned directories * in order to add unversioned files that may be hiding in those * directories. Default is FALSE *

* @return bool TRUE on success or FALSE on failure. */ function svn_add($path, $recursive = true, $force = false) {} /** * (PECL svn >= 0.1.0)
* Returns the status of working copy files and directories * @link https://php.net/manual/en/function.svn-status.php * @param string $path

* Local path to file or directory to retrieve status of. *

* Relative paths will be resolved as if the current working directory was the one that contains the PHP binary. To use the calling script's working directory, use realpath or dirname(__FILE__). * @param int $flags [optional]

* Any combination of SVN_NON_RECURSIVE, * SVN_ALL (regardless of modification status), * SVN_SHOW_UPDATES (entries will be added for items * that are out-of-date), SVN_NO_IGNORE (disregard * svn:ignore properties when scanning for new files) * and SVN_IGNORE_EXTERNALS. *

* @return array a numerically indexed array of associative arrays detailing * the status of items in the repository: *

*
 * Array (
 * [0] => Array (
 * // information on item
 * )
 * [1] => ...
 * )
 * 
*

* The information on the item is an associative array that can contain * the following keys: *

* path * String path to file/directory of this entry on local filesystem. * text_status * Status of item's text. Refer to status constants for possible values. * repos_text_status * Status of item's text in repository. Only accurate if * update was set to TRUE. * Refer to status constants for possible values. * prop_status * Status of item's properties. Refer to status constants for possible values. * repos_prop_status * Status of item's property in repository. Only accurate if * update was set to TRUE. Refer to status constants for possible values. * locked * Whether or not the item is locked. (Only set if TRUE.) * copied * Whether or not the item was copied (scheduled for addition with * history). (Only set if TRUE.) * switched * Whether or not the item was switched using the switch command. * (Only set if TRUE) *

* These keys are only set if the item is versioned: *

* name * Base name of item in repository. * url * URL of item in repository. * repos * Base URL of repository. * revision * Integer revision of item in working copy. * kind * Type of item, i.e. file or directory. Refer to type constants for possible values. * schedule * Scheduled action for item, i.e. addition or deletion. Constants * for these magic numbers are not available, they can * be emulated by using: * * if (!defined('svn_wc_schedule_normal')) { * define('svn_wc_schedule_normal', 0); // nothing special * define('svn_wc_schedule_add', 1); // item will be added * define('svn_wc_schedule_delete', 2); // item will be deleted * define('svn_wc_schedule_replace', 3); // item will be added and deleted * } * * deleted * Whether or not the item was deleted, but parent revision lags * behind. (Only set if TRUE.) * absent * Whether or not the item is absent, that is, Subversion knows that * there should be something there but there isn't. (Only set if * TRUE.) * incomplete * Whether or not the entries file for a directory is incomplete. * (Only set if TRUE.) * cmt_date * Integer Unix timestamp of last commit date. (Unaffected by update.) * cmt_rev * Integer revision of last commit. (Unaffected by update.) * cmt_author * String author of last commit. (Unaffected by update */ function svn_status($path, $flags = 0) {} /** * (PECL svn >= 0.1.0)
* Update working copy * @link https://php.net/manual/en/function.svn-update.php * @param string $path

* Path to local working copy. *

* Relative paths will be resolved as if the current working directory was the one that contains the PHP binary. To use the calling script's working directory, use realpath or dirname(__FILE__). * @param int $revno [optional]

* Revision number to update to, default is SVN_REVISION_HEAD. *

* @param bool $recurse [optional]

* Whether or not to recursively update directories. *

* @return int|false new revision number on success, returns FALSE on failure. */ function svn_update($path, $revno = SVN_REVISION_HEAD, $recurse = true) {} /** * (PECL svn >= 0.2.0)
* Imports an unversioned path into a repository * @link https://php.net/manual/en/function.svn-import.php * @param string $path

* Path of file or directory to import. *

* Relative paths will be resolved as if the current working directory was the one that contains the PHP binary. To use the calling script's working directory, use realpath or dirname(__FILE__). * @param string $url

* Repository URL to import into. *

* @param bool $nonrecursive

* Whether or not to refrain from recursively processing directories. *

* @return bool TRUE on success or FALSE on failure. */ function svn_import($path, $url, $nonrecursive) {} function svn_info() {} /** * (PECL svn >= 0.3.0)
* Export the contents of a SVN directory * @link https://php.net/manual/en/function.svn-export.php * @param string $frompath

* The path to the current repository. *

* @param string $topath

* The path to the new repository. *

* @param bool $working_copy [optional]

* If TRUE, it will export uncommitted files from the working copy. *

* @param int $revision_no [optional] * @return bool TRUE on success or FALSE on failure. */ function svn_export($frompath, $topath, $working_copy = true, $revision_no = -1) {} function svn_copy() {} function svn_switch() {} /** * (PECL svn >= 0.3.0)
* Get the SVN blame for a file * @link https://php.net/manual/en/function.svn-blame.php * @param string $repository_url

* The repository URL. *

* @param int $revision_no [optional]

* The revision number. *

* @return array An array of SVN blame information separated by line * which includes the revision number, line number, line of code, * author, and date. */ function svn_blame($repository_url, $revision_no = SVN_REVISION_HEAD) {} /** * (PECL svn >= 0.4.0)
* Delete items from a working copy or repository. * @link https://php.net/manual/en/function.svn-delete.php * @param string $path

* Path of item to delete. *

* Relative paths will be resolved as if the current working directory was the one that contains the PHP binary. To use the calling script's working directory, use realpath or dirname(__FILE__). * @param bool $force [optional]

* If TRUE, the file will be deleted even if it has local modifications. * Otherwise, local modifications will result in a failure. Default is * FALSE *

* @return bool TRUE on success or FALSE on failure. */ function svn_delete($path, $force = false) {} /** * (PECL svn >= 0.4.0)
* Creates a directory in a working copy or repository * @link https://php.net/manual/en/function.svn-mkdir.php * @param string $path

* The path to the working copy or repository. *

* @param string $log_message [optional] * @return bool TRUE on success or FALSE on failure. */ function svn_mkdir($path, $log_message = null) {} /** * @link https://php.net/manual/en/ref.svn.php * @param string $src_path * @param string $dst_path * @param bool $force [optional] * @return mixed */ function svn_move($src_path, $dst_path, $force = false) {} /** * @link https://php.net/manual/en/ref.svn.php * @param string $path * @param bool $recurse [optional] * @param int $revision [optional] * @return mixed */ function svn_proplist($path, $recurse = false, $revision) {} /** * @param string $path * @param string $property_name * @param bool $recurse [optional] * @param int $revision [optional] * @return mixed */ function svn_propget($path, $property_name, $recurse = false, $revision) {} /** * (PECL svn >= 0.1.0)
* Create a new subversion repository at path * @link https://php.net/manual/en/function.svn-repos-create.php * @param string $path

* Its description *

* @param null|array $config [optional]

* Its description *

* @param null|array $fsconfig [optional]

* Its description *

* @return resource What the function returns, first on success, then on failure. */ function svn_repos_create($path, ?array $config = null, ?array $fsconfig = null) {} /** * (PECL svn >= 0.1.0)
* Run recovery procedures on the repository located at path. * @link https://php.net/manual/en/function.svn-repos-recover.php * @param string $path

* Its description *

* @return bool What the function returns, first on success, then on failure. */ function svn_repos_recover($path) {} /** * (PECL svn >= 0.1.0)
* Make a hot-copy of the repos at repospath; copy it to destpath * @link https://php.net/manual/en/function.svn-repos-hotcopy.php * @param string $repospath

* Its description *

* @param string $destpath

* Its description *

* @param bool $cleanlogs

* Its description *

* @return bool What the function returns, first on success, then on failure. */ function svn_repos_hotcopy($repospath, $destpath, $cleanlogs) {} /** * (PECL svn >= 0.1.0)
* Open a shared lock on a repository. * @link https://php.net/manual/en/function.svn-repos-open.php * @param string $path

* Its description *

* @return resource What the function returns, first on success, then on failure. */ function svn_repos_open($path) {} /** * (PECL svn >= 0.1.0)
* Gets a handle on the filesystem for a repository * @link https://php.net/manual/en/function.svn-repos-fs.php * @param resource $repos

* Its description *

* @return resource What the function returns, first on success, then on failure. */ function svn_repos_fs($repos) {} /** * (PECL svn >= 0.2.0)
* Create a new transaction * @link https://php.net/manual/en/function.svn-repos-fs-begin-txn-for-commit.php * @param resource $repos

* Its description *

* @param int $rev

* Its description *

* @param string $author

* Its description *

* @param string $log_msg

* Its description *

* @return resource What the function returns, first on success, then on failure. */ function svn_repos_fs_begin_txn_for_commit($repos, $rev, $author, $log_msg) {} /** * (PECL svn >= 0.2.0)
* Commits a transaction and returns the new revision * @link https://php.net/manual/en/function.svn-repos-fs-commit-txn.php * @param resource $txn

* Its description *

* @return int What the function returns, first on success, then on failure. */ function svn_repos_fs_commit_txn($txn) {} /** * (PECL svn >= 0.1.0)
* Get a handle on a specific version of the repository root * @link https://php.net/manual/en/function.svn-fs-revision-root.php * @param resource $fs

* Its description *

* @param int $revnum

* Its description *

* @return resource What the function returns, first on success, then on failure. */ function svn_fs_revision_root($fs, $revnum) {} /** * (PECL svn >= 0.1.0)
* Determines what kind of item lives at path in a given repository fsroot * @link https://php.net/manual/en/function.svn-fs-check-path.php * @param resource $fsroot

* Its description *

* @param string $path

* Its description *

* @return int What the function returns, first on success, then on failure. */ function svn_fs_check_path($fsroot, $path) {} /** * (PECL svn >= 0.1.0)
* Fetches the value of a named property * @link https://php.net/manual/en/function.svn-fs-revision-prop.php * @param resource $fs

* Its description *

* @param int $revnum

* Its description *

* @param string $propname

* Its description *

* @return string What the function returns, first on success, then on failure. */ function svn_fs_revision_prop($fs, $revnum, $propname) {} /** * (PECL svn >= 0.1.0)
* Enumerates the directory entries under path; returns a hash of dir names to file type * @link https://php.net/manual/en/function.svn-fs-dir-entries.php * @param resource $fsroot

* Its description *

* @param string $path

* Its description *

* @return array What the function returns, first on success, then on failure. */ function svn_fs_dir_entries($fsroot, $path) {} /** * (PECL svn >= 0.1.0)
* Returns the revision in which path under fsroot was created * @link https://php.net/manual/en/function.svn-fs-node-created-rev.php * @param resource $fsroot

* Its description *

* @param string $path

* Its description *

* @return int What the function returns, first on success, then on failure. */ function svn_fs_node_created_rev($fsroot, $path) {} /** * (PECL svn >= 0.1.0)
* Returns the number of the youngest revision in the filesystem * @link https://php.net/manual/en/function.svn-fs-youngest-rev.php * @param resource $fs

* Its description *

* @return int What the function returns, first on success, then on failure. */ function svn_fs_youngest_rev($fs) {} /** * (PECL svn >= 0.1.0)
* Returns a stream to access the contents of a file from a given version of the fs * @link https://php.net/manual/en/function.svn-fs-file-contents.php * @param resource $fsroot

* Its description *

* @param string $path

* Its description *

* @return resource What the function returns, first on success, then on failure. */ function svn_fs_file_contents($fsroot, $path) {} /** * (PECL svn >= 0.1.0)
* Returns the length of a file from a given version of the fs * @link https://php.net/manual/en/function.svn-fs-file-length.php * @param resource $fsroot

* Its description *

* @param string $path

* Its description *

* @return int What the function returns, first on success, then on failure. */ function svn_fs_file_length($fsroot, $path) {} /** * (PECL svn >= 0.2.0)
* Creates and returns a transaction root * @link https://php.net/manual/en/function.svn-fs-txn-root.php * @param resource $txn

* Its description *

* @return resource What the function returns, first on success, then on failure. */ function svn_fs_txn_root($txn) {} /** * (PECL svn >= 0.2.0)
* Creates a new empty file, returns true if all is ok, false otherwise * @link https://php.net/manual/en/function.svn-fs-make-file.php * @param resource $root

* Its description *

* @param string $path

* Its description *

* @return bool What the function returns, first on success, then on failure. */ function svn_fs_make_file($root, $path) {} /** * (PECL svn >= 0.2.0)
* Creates a new empty directory, returns true if all is ok, false otherwise * @link https://php.net/manual/en/function.svn-fs-make-dir.php * @param resource $root

* Its description *

* @param string $path

* Its description *

* @return bool What the function returns, first on success, then on failure. */ function svn_fs_make_dir($root, $path) {} /** * (PECL svn >= 0.2.0)
* Creates and returns a stream that will be used to replace * @link https://php.net/manual/en/function.svn-fs-apply-text.php * @param resource $root

* Its description *

* @param string $path

* Its description *

* @return resource What the function returns, first on success, then on failure. */ function svn_fs_apply_text($root, $path) {} /** * (PECL svn >= 0.2.0)
* Copies a file or a directory, returns true if all is ok, false otherwise * @link https://php.net/manual/en/function.svn-fs-copy.php * @param resource $from_root

* Its description *

* @param string $from_path

* Its description *

* @param resource $to_root

* Its description *

* @param string $to_path

* Its description *

* @return bool What the function returns, first on success, then on failure. */ function svn_fs_copy($from_root, $from_path, $to_root, $to_path) {} /** * (PECL svn >= 0.2.0)
* Deletes a file or a directory, return true if all is ok, false otherwise * @link https://php.net/manual/en/function.svn-fs-delete.php * @param resource $root

* Its description *

* @param string $path

* Its description *

* @return bool What the function returns, first on success, then on failure. */ function svn_fs_delete($root, $path) {} /** * (PECL svn >= 0.2.0)
* Create a new transaction * @link https://php.net/manual/en/function.svn-fs-begin-txn2.php * @param resource $repos

* Its description *

* @param int $rev

* Its description *

* @return resource What the function returns, first on success, then on failure. */ function svn_fs_begin_txn2($repos, $rev) {} /** * (PECL svn >= 0.2.0)
* Return true if the path points to a directory, false otherwise * @link https://php.net/manual/en/function.svn-fs-is-dir.php * @param resource $root

* Its description *

* @param string $path

* Its description *

* @return bool What the function returns, first on success, then on failure. */ function svn_fs_is_dir($root, $path) {} /** * (PECL svn >= 0.2.0)
* Return true if the path points to a file, false otherwise * @link https://php.net/manual/en/function.svn-fs-is-file.php * @param resource $root

* Its description *

* @param string $path

* Its description *

* @return bool What the function returns, first on success, then on failure. */ function svn_fs_is_file($root, $path) {} /** * (PECL svn >= 0.1.0)
* Returns the value of a property for a node * @link https://php.net/manual/en/function.svn-fs-node-prop.php * @param resource $fsroot

* Its description *

* @param string $path

* Its description *

* @param string $propname

* Its description *

* @return string What the function returns, first on success, then on failure. */ function svn_fs_node_prop($fsroot, $path, $propname) {} /** * (PECL svn >= 0.2.0)
* Return true if everything is ok, false otherwise * @link https://php.net/manual/en/function.svn-fs-change-node-prop.php * @param resource $root

* Its description *

* @param string $path

* Its description *

* @param string $name

* Its description *

* @param string $value

* Its description *

* @return bool What the function returns, first on success, then on failure. */ function svn_fs_change_node_prop($root, $path, $name, $value) {} /** * (PECL svn >= 0.2.0)
* Return true if content is different, false otherwise * @link https://php.net/manual/en/function.svn-fs-contents-changed.php * @param resource $root1

* Its description *

* @param string $path1

* Its description *

* @param resource $root2

* Its description *

* @param string $path2

* Its description *

* @return bool What the function returns, first on success, then on failure. */ function svn_fs_contents_changed($root1, $path1, $root2, $path2) {} /** * (PECL svn >= 0.2.0)
* Return true if props are different, false otherwise * @link https://php.net/manual/en/function.svn-fs-props-changed.php * @param resource $root1

* Its description *

* @param string $path1

* Its description *

* @param resource $root2

* Its description *

* @param string $path2

* Its description *

* @return bool What the function returns, first on success, then on failure. */ function svn_fs_props_changed($root1, $path1, $root2, $path2) {} /** * (PECL svn >= 0.2.0)
* Abort a transaction, returns true if everything is okay, false otherwise * @link https://php.net/manual/en/function.svn-fs-abort-txn.php * @param resource $txn

* Its description *

* @return bool What the function returns, first on success, then on failure. */ function svn_fs_abort_txn($txn) {} /** * Property for default username to use when performing basic authentication * @link https://php.net/manual/en/svn.constants.php */ define('SVN_AUTH_PARAM_DEFAULT_USERNAME', "svn:auth:username"); /** * Property for default password to use when performing basic authentication * @link https://php.net/manual/en/svn.constants.php */ define('SVN_AUTH_PARAM_DEFAULT_PASSWORD', "svn:auth:password"); define('SVN_AUTH_PARAM_NON_INTERACTIVE', "svn:auth:non-interactive"); define('SVN_AUTH_PARAM_DONT_STORE_PASSWORDS', "svn:auth:dont-store-passwords"); define('SVN_AUTH_PARAM_NO_AUTH_CACHE', "svn:auth:no-auth-cache"); define('SVN_AUTH_PARAM_SSL_SERVER_FAILURES', "svn:auth:ssl:failures"); define('SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO', "svn:auth:ssl:cert-info"); define('SVN_AUTH_PARAM_CONFIG', "svn:auth:config-category-servers"); define('SVN_AUTH_PARAM_SERVER_GROUP', "svn:auth:server-group"); define('SVN_AUTH_PARAM_CONFIG_DIR', "svn:auth:config-dir"); /** * Custom property for ignoring SSL cert verification errors * @link https://php.net/manual/en/svn.constants.php */ define('PHP_SVN_AUTH_PARAM_IGNORE_SSL_VERIFY_ERRORS', "php:svn:auth:ignore-ssl-verify-errors"); /** * Configuration key that determines filesystem type * @link https://php.net/manual/en/svn.constants.php */ define('SVN_FS_CONFIG_FS_TYPE', "fs-type"); /** * Filesystem is Berkeley-DB implementation * @link https://php.net/manual/en/svn.constants.php */ define('SVN_FS_TYPE_BDB', "bdb"); /** * Filesystem is native-filesystem implementation * @link https://php.net/manual/en/svn.constants.php */ define('SVN_FS_TYPE_FSFS', "fsfs"); /** * svn:date * @link https://php.net/manual/en/svn.constants.php */ define('SVN_PROP_REVISION_DATE', "svn:date"); /** * svn:original-date * @link https://php.net/manual/en/svn.constants.php */ define('SVN_PROP_REVISION_ORIG_DATE', "svn:original-date"); /** * svn:author * @link https://php.net/manual/en/svn.constants.php */ define('SVN_PROP_REVISION_AUTHOR', "svn:author"); /** * svn:log * @link https://php.net/manual/en/svn.constants.php */ define('SVN_PROP_REVISION_LOG', "svn:log"); define('SVN_REVISION_INITIAL', 1); /** * Magic number (-1) specifying the HEAD revision * @link https://php.net/manual/en/svn.constants.php */ define('SVN_REVISION_HEAD', -1); define('SVN_REVISION_BASE', -2); define('SVN_REVISION_COMMITTED', -3); define('SVN_REVISION_PREV', -4); define('SVN_REVISION_UNSPECIFIED', -5); define('SVN_NON_RECURSIVE', 1); define('SVN_DISCOVER_CHANGED_PATHS', 2); define('SVN_OMIT_MESSAGES', 4); define('SVN_STOP_ON_COPY', 8); define('SVN_ALL', 16); define('SVN_SHOW_UPDATES', 32); define('SVN_NO_IGNORE', 64); /** * Status does not exist * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_NONE', 1); /** * Item is not versioned in working copy * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_UNVERSIONED', 2); /** * Item exists, nothing else is happening * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_NORMAL', 3); /** * Item is scheduled for addition * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_ADDED', 4); /** * Item is versioned but missing from the working copy * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_MISSING', 5); /** * Item is scheduled for deletion * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_DELETED', 6); /** * Item was deleted and then re-added * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_REPLACED', 7); /** * Item (text or properties) was modified * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_MODIFIED', 8); /** * Item's local modifications were merged with repository modifications * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_MERGED', 9); /** * Item's local modifications conflicted with repository modifications * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_CONFLICTED', 10); /** * Item is unversioned but configured to be ignored * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_IGNORED', 11); /** * Unversioned item is in the way of a versioned resource * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_OBSTRUCTED', 12); /** * Unversioned path that is populated using svn:externals * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_EXTERNAL', 13); /** * Directory does not contain complete entries list * @link https://php.net/manual/en/svn.constants.php */ define('SVN_WC_STATUS_INCOMPLETE', 14); /** * Absent * @link https://php.net/manual/en/svn.constants.php */ define('SVN_NODE_NONE', 0); /** * File * @link https://php.net/manual/en/svn.constants.php */ define('SVN_NODE_FILE', 1); /** * Directory * @link https://php.net/manual/en/svn.constants.php */ define('SVN_NODE_DIR', 2); /** * Something Subversion cannot identify * @link https://php.net/manual/en/svn.constants.php */ define('SVN_NODE_UNKNOWN', 3); define('SVN_WC_SCHEDULE_NORMAL', 0); define('SVN_WC_SCHEDULE_ADD', 1); define('SVN_WC_SCHEDULE_DELETE', 2); define('SVN_WC_SCHEDULE_REPLACE', 3); true, // if the specified database does not exist will create a new one 'error_if_exists' => false, // if the opened database exists will throw exception 'paranoid_checks' => false, 'block_cache_size' => 8 * (2 << 20), 'write_buffer_size' => 4 << 20, 'block_size' => 4096, 'max_open_files' => 1000, 'block_restart_interval' => 16, 'compression' => LEVELDB_SNAPPY_COMPRESSION, 'comparator' => null, // any callable parameter return 0, -1, 1 ], array $read_options = [ 'verify_check_sum' => false, //may be set to true to force checksum verification of all data that is read from the file system on behalf of a particular read. By default, no such verification is done. 'fill_cache' => true, //When performing a bulk read, the application may set this to false to disable the caching so that the data processed by the bulk read does not end up displacing most of the cached contents. ], array $write_options = [ //Only one element named sync in the write option array. By default, each write to leveldb is asynchronous. 'sync' => false ]) {} /** * @param string $key * @param array $read_options * * @return string|false */ public function get($key, array $read_options = []) {} /** * Alias of LevelDB::put() * * @param string $key * @param string $value * @param array $write_options */ public function set($key, $value, array $write_options = []) {} /** * @param string $key * @param string $value * @param array $write_options */ public function put($key, $value, array $write_options = []) {} /** * @param string $key * @param array $write_options * * @return bool */ public function delete($key, array $write_options = []) {} /** * Executes all of the operations added in the write batch. * * @param LevelDBWriteBatch $batch * @param array $write_options */ public function write(LevelDBWriteBatch $batch, array $write_options = []) {} /** * Valid properties: * - leveldb.stats: returns the status of the entire db * - leveldb.num-files-at-level: returns the number of files for each level. For example, you can use leveldb.num-files-at-level0 the number of files for zero level. * - leveldb.sstables: returns current status of sstables * * @param string $name * * @return mixed */ public function getProperty($name) {} public function getApproximateSizes($start, $limit) {} public function compactRange($start, $limit) {} public function close() {} /** * @param array $options * * @return LevelDBIterator */ public function getIterator(array $options = []) {} /** * @return LevelDBSnapshot */ public function getSnapshot() {} public static function destroy($name, array $options = []) {} public static function repair($name, array $options = []) {} } class LevelDBIterator implements Iterator { public function __construct(LevelDB $db, array $read_options = []) {} public function valid() {} public function rewind() {} public function last() {} public function seek($key) {} public function next() {} public function prev() {} public function key() {} public function current() {} public function getError() {} public function destroy() {} } class LevelDBWriteBatch { public function __construct() {} public function set($key, $value, array $write_options = []) {} public function put($key, $value, array $write_options = []) {} public function delete($key, array $write_options = []) {} public function clear() {} } class LevelDBSnapshot { public function __construct(LevelDB $db) {} public function release() {} } class LevelDBException extends Exception {} * @copyright Copyright 2013-2016 Aerospike, Inc. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2 * @link https://github.com/aerospike/aerospike-client-php/blob/master/doc/README.md#handling-unsupported-types * @filesource */ namespace Aerospike; /** * \Aerospike\Bytes is a utility for wrapping PHP strings containing * potentially harmful bytes such as \0. By wrapping the binary-string, the * Aerospike client will serialize the data into an as_bytes rather than an * as_string. * This ensures that the string will not get truncated or otherwise lose data. * The main difference is that strings in the Aerospike cluster can have a * secondary index built over them, and queries executed against the index, * while bytes data cannot. * * @package Aerospike * @author Ronen Botzer */ class Bytes implements \Serializable { /** * The container for the binary-string * @var string */ public $s; /** * Constructor for \Aerospike\Bytes class. * * @param string $bin_str a PHP binary-string such as gzdeflate() produces. */ public function __construct($bin_str) { $this->s = $bin_str; } /** * Returns a serialized representation of the binary-string. * Called by serialize() * * @return string */ public function serialize() { return $this->s; } /** * Re-wraps the binary-string when called by unserialize(). * * @param string $bin_str a PHP binary-string. Called by unserialize(). * @return string */ public function unserialize($bin_str) { return $this->s = $bin_str; } /** * Returns the binary-string held in the \Aerospike\Bytes object. * * @return string */ public function __toString() { return $this->s; } /** * Unwraps an \Aerospike\Bytes object, returning the binary-string inside. * * @param \Aerospike\Bytes $bytes_wrap * @return string */ public static function unwrap(Bytes $bytes_wrap) { return $bytes_wrap->s; } } * @copyright Copyright 2013-2018 Aerospike, Inc. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2 * @link https://www.aerospike.com/docs/client/php/ * @filesource */ use JetBrains\PhpStorm\Deprecated; /** * The Aerospike client class * * The Aerospike config options for `php.ini`: * ```php * // The connection timeout in milliseconds. * aerospike.connect_timeout = 1000; * // The read operation timeout in milliseconds. * aerospike.read_timeout = 1000; * // The write operation timeout in milliseconds. * aerospike.write_timeout = 1000; * // Whether to send and store the record's (ns,set,key) data along with * // its (unique identifier) digest. 0: digest, 1: send * aerospike.key_policy = 0; // only digest * // The unsupported type handler. 0: none, 1: PHP, 2: user-defined * aerospike.serializer = 1; // php serializer * // Path to the user-defined Lua function modules. * aerospike.udf.lua_user_path = /usr/local/aerospike/usr-lua; * // Indicates if shared memory should be used for cluster tending. * // Recommended for multi-process cases such as FPM. { true, false } * aerospike.shm.use = false; * // Explicitly sets the shm key for this client to store shared-memory * // cluster tending results in. * aerospike.shm.key = 0xA8000000; // integer value * // Shared memory maximum number of server nodes allowed. Leave a cushion so * // new nodes can be added without needing a client restart. * aerospike.shm.max_nodes = 16; * // Shared memory maximum number of namespaces allowed. Leave a cushion for * // new namespaces. * aerospike.shm.max_namespaces = 8; * // Take over shared memory cluster tending if the cluster hasn't been tended * // by this threshold in seconds. * aerospike.shm.takeover_threshold_sec = 30; * // Control the batch protocol. 0: batch-index, 1: batch-direct * aerospike.use_batch_direct = 0; * // The client will compress records larger than this value in bytes for transport. * aerospike.compression_threshold = 0; * // Max size of the synchronous connection pool for each server node * aerospike.max_threads = 300; * // Number of threads stored in underlying thread pool that is used in * // batch/scan/query commands. In ZTS builds, this is always 0. * aerospike.thread_pool_size = 16; * // When turning on the optional logging in the client, this is the path to the log file. * aerospike.log_path = NULL; * aerospike.log_level = NULL; * aerospike.nesting_depth = 3; * * // session handler * session.save_handler = aerospike; // to use the Aerospike session handler * session.gc_maxlifetime = 1440; // the TTL of the record used to store the session in seconds * session.save_path = NULL; // should follow the format ns|set|addr:port[,addr:port[,...]]. Ex: "test|sess|127.0.0.1:3000". The host info of just one cluster node is necessary * ``` * @author Robert Marks */ class Aerospike { // Lifecycle and Connection Methods /** * Construct an Aerospike client object, and connect to the cluster defined * in $config. * * Aerospike::isConnected() can be used to test whether the connection has * succeeded. If a config or connection error has occured, Aerospike::error() * and Aerospike::errorno() can be used to inspect it. * * ```php * $config = [ * "hosts" => [ * ["addr" => "localhost", "port" => 3000] * ], * "shm" => [] * ]; * // Set a default policy for write and read operations * $writeOpts = [Aerospike::OPT_POLICY_KEY => Aerospike::POLICY_KEY_SEND]; * $readOpts = [Aerospike::OPT_TOTAL_TIMEOUT => 150]; * $opts = [Aerospike::OPT_WRITE_DEFAULT_POL => $writeOpts, Aerospike::OPT_READ_DEFAULT_POL => $readOpts]; * $client = new Aerospike($config, true, $opts); * if (!$client->isConnected()) { * echo "Aerospike failed to connect[{$client->errorno()}]: {$client->error()}\n"; * exit(1); * } * ``` * @see Aerospike php.ini config parameters * @link https://github.com/aerospike/aerospike-client-php/blob/master/doc/README.md#configuration-in-a-web-server-context Configuration in a Web Server Context * @param array $config holds cluster connection and client config information * * _hosts_ a **required** array of host pairs. One node or more (for failover) * may be defined. Once a connection is established to the * "seed" node, the client will retrieve the full list of nodes in * the cluster, and manage its connections to them. * * _addr_ hostname or IP of the node * * _port_ the port of the node * * _user_ **required** for the Enterprise Edition * * _pass_ **required** for the Enterprise Edition * * _shm_ optional. Shared-memory cluster tending is enabled if an array * (even an empty one) is provided. Disabled by default. * * _shm\_key_ explicitly sets the shm key for the cluster. It is * otherwise implicitly evaluated per unique hostname, and can be * inspected with shmKey(). (default: 0xA8000000) * * _shm\_max\_nodes_ maximum number of nodes allowed. Pad so new nodes * can be added without configuration changes (default: 16) * * _shm\_max\_namespaces_ maximum number of namespaces allowed (default: 8) * * _shm\_takeover\_threshold\_sec_ take over tending if the cluster * hasn't been checked for this many seconds (default: 30) * * _max\_threads_ (default: 300) * * _thread\_pool\_size_ should be at least the number of nodes in the cluster (default: 16) In ZTS builds this is set to 0 * * _compression\_threshold_ client will compress records larger than this value for transport (default: 0) * * _tender\_interval_ polling interval in milliseconds for cluster tender (default: 1000) * * _cluster\_name_ if specified, only server nodes matching this name will be used when determining the cluster * * _rack\_aware_ Boolean: Track server rack data. This field is useful when directing read commands to * the server node that contains the key and exists on the same rack as the client. * This serves to lower cloud provider costs when nodes are distributed across different * racks/data centers. * POLICY_REPLICA_PREFER_RACK must be set as the replica policy for reads and _rack\_id_ must be set toenable this functionality. * (Default: false) * * _rack\_id_ Integer. Rack where this client instance resides. * * _rack\_aware_, POLICY_REPLICA_PREFER_RACK and server rack configuration must also be * set to enable this functionality. * * Default: 0 * * Aerospike::OPT_TLS_CONFIG an array of TLS setup parameters whose keys include * * * Aerospike::OPT_TLS_ENABLE boolean Whether or not to enable TLS. * * * Aerospike::OPT_OPT_TLS_CAFILE * * * Aerospike::OPT_TLS_CAPATH * * * Aerospike::OPT_TLS_PROTOCOLS * * * Aerospike::OPT_TLS_CIPHER_SUITE * * * Aerospike::OPT_TLS_CRL_CHECK * * * Aerospike::OPT_TLS_CRL_CHECK_ALL * * * Aerospike::OPT_TLS_CERT_BLACKLIST * * * Aerospike::OPT_TLS_LOG_SESSION_INFO * * * Aerospike::OPT_TLS_KEYFILE * * * Aerospike::OPT_TLS_CERTFILE * @param bool $persistent_connection In a multiprocess context, such as a * web server, the client should be configured to use * persistent connections. This allows for reduced overhead, * saving on discovery of the cluster topology, fetching its partition * map, and on opening connections to the nodes. * @param array $options An optional client config array whose keys include * * Aerospike::OPT_CONNECT_TIMEOUT * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_EXISTS * * Aerospike::OPT_SERIALIZER * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_POLICY_REPLICA * * Aerospike::OPT_POLICY_READ_MODE_AP * * Aerospike::OPT_POLICY_READ_MODE_SC * * Aerospike::OPT_READ_DEFAULT_POL An array of default policies for read operations. * * Aerospike::OPT_WRITE_DEFAULT_POL An array of default policies for write operations. * * AEROSPIKE::OPT_REMOVE_DEFAULT_POL An array of default policies for remove operations. * * Aerospike::OPT_BATCH_DEFAULT_POL An array of default policies for batch operations. * * Aerospike::OPT_OPERATE_DEFAULT_POL An array of default policies for operate operations. * * Aerospike::OPT_QUERY_DEFAULT_POL An array of default policies for query operations. * * Aerospike::OPT_SCAN_DEFAULT_POL An array of default policies for scan operations. * * Aerospike::OPT_APPLY_DEFAULT_POL An array of default policies for apply operations. * @see Aerospike::OPT_CONNECT_TIMEOUT Aerospike::OPT_CONNECT_TIMEOUT options * @see Aerospike::OPT_READ_TIMEOUT Aerospike::OPT_READ_TIMEOUT options * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_EXISTS Aerospike::OPT_POLICY_EXISTS options * @see Aerospike::OPT_SERIALIZER Aerospike::OPT_SERIALIZER options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_POLICY_REPLICA Aerospike::OPT_POLICY_REPLICA options * @see Aerospike::OPT_POLICY_READ_MODE_AP Aerospike::OPT_POLICY_READ_MODE_AP options * @see Aerospike::OPT_POLICY_READ_MODE_SC Aerospike::OPT_POLICY_READ_MODE_SC options * @see Aerospike::isConnected() isConnected() * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() */ public function __construct($config, $persistent_connection = true, array $options = []) {} /** * Disconnect from the Aerospike cluster and clean up resources. * * No need to ever call this method explicilty. * @return void */ public function __destruct() {} /** * Test whether the client is connected to the cluster. * * If a connection error has occured, Aerospike::error() and Aerospike::errorno() * can be used to inspect it. * ```php * if (!$client->isConnected()) { * echo "Aerospike failed to connect[{$client->errorno()}]: {$client->error()}\n"; * exit(1); * } * ``` * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return bool */ public function isConnected() {} /** * Disconnect the client from all the cluster nodes. * * This method should be explicitly called when using non-persistent connections. * @see Aerospike::isConnected() * @see Aerospike::reconnect() * @return void */ public function close() {} /** * Reconnect the client to the cluster nodes. * * Aerospike::isConnected() can be used to test whether the re-connection * succeded. If a connection error occured Aerospike::error() and * Aerospike::errorno() can be used to inspect it. * ```php * $client = new Aerospike($config, false); * $client->close(); * $client->reconnect(); * if (!$client->isConnected()) { * echo "Aerospike failed to connect[{$client->errorno()}]: {$client->error()}\n"; * exit(1); * } * ``` * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return void */ public function reconnect() {} /** * Expose the shared memory key used by shared-memory cluster tending * * If shm cluster tending is enabled, Aerospike::shmKey will return the * value of the shm key being used by the client. If it was set explicitly * under the client's shm config parameter, or through the global * `aerospike.shm.key` we expect to see that value. Otherwise the implicit * value generated by the client will be returned * @return int|null null if not enabled */ public function shmKey() {} /** * Return the error message associated with the last operation. * * If the operation was successful the return value should be an empty string. * ```php * $client = new Aerospike($config, false); * if (!$client->isConnected()) { * echo "{$client->error()} [{$client->errorno()}]"; * exit(1); * } * ``` * On connection error would show: * ``` * Unable to connect to server [-1] * ``` * @see Aerospike::OK Error Codes * @return string */ public function error() {} /** * Return the error code associated with the last operation. * If the operation was successful the return value should be 0 (Aerospike::OK) * @see Aerospike::OK Error Codes * @return int */ public function errorno() {} // Key-Value Methods. /** * Return an array that represents the record's key. * * This value can be passed as the $key arguement required by other * key-value methods. * * In Aerospike, a record is identified by the tuple (namespace, set, * primary key), or by the digest which results from hashing this tuple * through RIPEMD-160. * * ** Initializing a key ** * * ```php * $key = $client->initKey("test", "users", 1234); * var_dump($key); * ``` * * ```bash *array(3) { * ["ns"]=> * string(4) "test" * ["set"]=> * string(5) "users" * ["key"]=> * int(1234) *} * ``` * * ** Setting a digest ** * * ```php * $base64_encoded_digest = '7EV9CpdMSNVoWn76A9E33Iu95+M='; * $digest = base64_decode($base64_encoded_digest); * $key = $client->initKey("test", "users", $digest, true); * var_dump($key); * ``` * * ```bash *array(3) { * ["ns"]=> * string(4) "test" * ["set"]=> * string(5) "users" * ["digest"]=> * string(20) "?E} *?LH?hZ~??7Ü‹???" *} * ``` * * @link https://github.com/aerospike/aerospike-client-php/blob/master/doc/README.md#configuration-in-a-web-server-context Configuration in a Web Server Context * @param string $ns the namespace * @param string $set the set within the given namespace * @param int|string $pk The primary key in the application, or the RIPEMD-160 digest of the (namespce, set, primary-key) tuple * @param bool $is_digest True if the *$pk* argument is a digest * @return array * @see Aerospike::getKeyDigest() getKeyDigest() */ public function initKey($ns, $set, $pk, $is_digest = false) {} /** * Return the digest of hashing the (namespace, set, primary-key) tuple * with RIPEMD-160. * * The digest uniquely identifies the record in the cluster, and is used to * calculate a partition ID. Using the partition ID, the client can identify * the node holding the record's master partition or replica partition(s) by * looking it up against the cluster's partition map. * * ```php * $digest = $client->getKeyDigest("test", "users", 1); * $key = $client->initKey("test", "users", $digest, true); * var_dump($digest, $key); * ``` * * ```bash * string(20) "9!?@%??;???Wp?'??Ag" * array(3) { * ["ns"]=> * string(4) "test" * ["set"]=> * string(5) "users" * ["digest"]=> * string(20) "9!?@%??;???Wp?'??Ag" * } * ``` * * @link https://github.com/aerospike/aerospike-client-php/blob/master/doc/README.md#configuration-in-a-web-server-context Configuration in a Web Server Context * @param string $ns the namespace * @param string $set the set within the given namespace * @param int|string $pk The primary key in the application * @return string * @see Aerospike::initKey() initKey() */ public function getKeyDigest($ns, $set, $pk) {} /** * Write a record identified by the $key with $bins, an array of bin-name => bin-value pairs. * * By default Aerospike::put() behaves in a set-and-replace mode, similar to * how new keys are added to an array, or the value of existing ones is overwritten. * This behavior can be modified using the *$options* parameter. * * **Note:** a binary-string which includes a null-byte will get truncated * at the position of the **\0** character if it is not wrapped. For more * information and the workaround see 'Handling Unsupported Types'. * * **Example #1 Aerospike::put() default behavior example** * ```php * $key = $client->initKey("test", "users", 1234); * $bins = ["email" => "hey@example.com", "name" => "Hey There"]; * // will ensure a record exists at the given key with the specified bins * $status = $client->put($key, $bins); * if ($status == Aerospike::OK) { * echo "Record written.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * * // Updating the record * $bins = ["name" => "You There", "age" => 33]; * // will update the name bin, and create a new 'age' bin * $status = $client->put($key, $bins); * if ($status == Aerospike::OK) { * echo "Record updated.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * Record written. * Record updated. * ``` * * **Example #2 Fail unless the put explicitly creates a new record** * ```php * * // This time we expect an error, due to the record already existing (assuming we * // ran Example #1) * $status = $client->put($key, $bins, 0, [Aerospike::OPT_POLICY_EXISTS => Aerospike::POLICY_EXISTS_CREATE]); * * if ($status == Aerospike::OK) { * echo "Record written.\n"; * } elseif ($status == Aerospike::ERR_RECORD_EXISTS) { * echo "The Aerospike server already has a record with the given key.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * The Aerospike cluster already has a record with the given key. * ``` * * **Example #3 Fail if the record has been written since it was last read * (CAS)** * ```php * // Get the record metadata and note its generation * $client->exists($key, $metadata); * $gen = $metadata['generation']; * $gen_policy = [Aerospike::POLICY_GEN_EQ, $gen]; * $res = $client->put($key, $bins, 0, [Aerospike::OPT_POLICY_GEN => $gen_policy]); * * if ($res == Aerospike::OK) { * echo "Record written.\n"; * } elseif ($res == Aerospike::ERR_RECORD_GENERATION) { * echo "The record has been written since we last read it.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ?> * ``` * ``` * The record has been written since we last read it. * ``` * * **Example #4 Handling binary strings** * ```php * $str = 'Glagnar\'s Human Rinds, "It\'s a bunch\'a munch\'a crunch\'a human!'; * $deflated = new \Aerospike\Bytes(gzdeflate($str)); * $wrapped = new \Aerospike\Bytes("trunc\0ated"); * * $key = $client->initKey('test', 'demo', 'wrapped-bytes'); * $status = $client->put($key, ['unwrapped'=>"trunc\0ated", 'wrapped'=> $wrapped, 'deflated' => $deflated]); * if ($status !== Aerospike::OK) { * die($client->error()); * } * $client->get($key, $record); * $wrapped = \Aerospike\Bytes::unwrap($record['bins']['wrapped']); * $deflated = $record['bins']['deflated']; * $inflated = gzinflate($deflated->s); * echo "$inflated\n"; * echo "wrapped binary-string: "; * var_dump($wrapped); * $unwrapped = $record['bins']['unwrapped']; * echo "The binary-string that was given to put() without a wrapper: $unwrapped\n"; * ``` * ``` * Glagnar's Human Rinds, "It's a bunch'a munch'a crunch'a human! * wrapped binary-string: string(10) "truncated" * The binary-string that was given to put() without a wrapper: trunc * ``` * @link https://www.aerospike.com/docs/architecture/data-model.html Aerospike Data Model * @link https://www.aerospike.com/docs/guide/kvs.html Key-Value Store * @link https://github.com/aerospike/aerospike-client-php/blob/master/doc/README.md#handling-unsupported-types Handling Unsupported Types * @link https://www.aerospike.com/docs/client/c/usage/kvs/write.html#change-record-time-to-live-ttl Time-to-live * @link https://www.aerospike.com/docs/guide/glossary.html Glossary * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param array $bins The array of bin names and values to write. **Bin names cannot be longer than 14 characters.** Binary data containing the null byte (**\0**) may get truncated. See 'Handling Unsupported Types' for more details and a workaround * @param int $ttl The record's time-to-live in seconds * @param array $options an optional array of write policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_SERIALIZER * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_EXISTS * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::COMPRESSION_THRESHOLD * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_SERIALIZER Aerospike::OPT_SERIALIZER options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_EXISTS Aerospike::OPT_POLICY_EXISTS options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::COMPRESSION_THRESHOLD * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function put(array $key, array $bins, $ttl = 0, array $options = []) {} /** * Read a record with a given key, and store it in $record * * The bins returned in *$record* can be filtered by passing a *$select* * array of bin names. Non-existent bins will appear in the *$record* with a `NULL` value. * * **Example #1 Aerospike::get() default behavior example** * ```php * $key = $client->initKey("test", "users", 1234); * $status = $client->get($key, $record); * if ($status == Aerospike::OK) { * var_dump($record); * } elseif ($status == Aerospike::ERR_RECORD_NOT_FOUND) { * echo "A user with key ". $key['key']. " does not exist in the database\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * array(3) { * ["key"]=> * array(4) { * ["digest"]=> * string(40) "436a3b9fcafb96d12844ab1377c0ff0d7a0b70cc" * ["namespace"]=> * NULL * ["set"]=> * NULL * ["key"]=> * NULL * } * ["metadata"]=> * array(2) { * ["generation"]=> * int(3) * ["ttl"]=> * int(12345) * } * ["bins"]=> * array(3) { * ["email"]=> * string(9) "hey@example.com" * ["name"]=> * string(9) "You There" * ["age"]=> * int(33) * } * } * ``` * **Example #2 get the record with filtered bins** * ```php * // assuming this follows Example #1, getting a filtered record * $filter = ["email", "manager"]; * unset($record); * $status = $client->get($key, $record, $filter); * if ($status == Aerospike::OK) { * var_dump($record); * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * array(3) { * ["key"]=> * array(4) { * ["digest"]=> * string(40) "436a3b9fcafb96d12844ab1377c0ff0d7a0b70cc" * ["namespace"]=> * NULL * ["set"]=> * NULL * ["key"]=> * NULL * } * ["metadata"]=> * array(2) { * ["generation"]=> * int(3) * ["ttl"]=> * int(12344) * } * ["bins"]=> * array(2) { * ["email"]=> * string(15) "hey@example.com" * ["manager"]=> * NULL * } * } * ``` * @link https://www.aerospike.com/docs/architecture/data-model.html Aerospike Data Model * @link https://www.aerospike.com/docs/guide/kvs.html Key-Value Store * @link https://www.aerospike.com/docs/guide/glossary.html Glossary * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param array &$record a reference to a variable which will contain the retrieved record of `['key', metadata', 'bins]` with the structure: * ``` * Array: * key => Array * ns => namespace * set => set name * key => primary-key, present if written with POLICY_KEY_SEND * digest => the record's RIPEMD-160 digest, always present * metadata => Array * ttl => time in seconds until the record expires * generation => the number of times the record has been written * bins => Array of bin-name => bin-value pairs * ``` * @param null|array $select only these bins out of the record (optional) * @param array $options an optional array of read policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_DESERIALIZE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * * Aerospike::OPT_POLICY_REPLICA * * Aerospike::OPT_POLICY_READ_MODE_AP * * Aerospike::OPT_POLICY_READ_MODE_SC * @see Aerospike::OPT_READ_TIMEOUT Aerospike::OPT_READ_TIMEOUT options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_DESERIALIZE Aerospike::OPT_DESERIALIZE option * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OPT_POLICY_REPLICA Aerospike::OPT_POLICY_REPLICA options * @see Aerospike::OPT_POLICY_READ_MODE_AP Aerospike::OPT_POLICY_READ_MODE_AP options * @see Aerospike::OPT_POLICY_READ_MODE_SC Aerospike::OPT_POLICY_READ_MODE_SC options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function get(array $key, &$record, $select = null, array $options = []) {} /** * Get the metadata of a record with a given key, and store it in $metadata * * ```php * $key = $client->initKey("test", "users", 1234); * $status = $client->exists($key, $metadata); * if ($status == Aerospike::OK) { * var_dump($metadata); * } elseif ($status == Aerospike::ERR_RECORD_NOT_FOUND) { * echo "A user with key ". $key['key']. " does not exist in the database\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * array(2) { * ["generation"]=> * int(4) * ["ttl"]=> * int(1337) * } * ``` * **or** * ``` * A user with key 1234 does not exist in the database. * ``` * @link https://www.aerospike.com/docs/guide/glossary.html Glossary * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param array &$metadata a reference to a variable which will be filled with an array of `['ttl', 'generation']` values * @param array $options an optional array of read policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::OPT_DESERIALIZE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_REPLICA * * Aerospike::OPT_POLICY_READ_MODE_AP * * Aerospike::OPT_POLICY_READ_MODE_SC * @see Aerospike::OPT_READ_TIMEOUT Aerospike::OPT_READ_TIMEOUT options * @see Aerospike::OPT_DESERIALIZE Aerospike::OPT_DESERIALIZE option * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_REPLICA Aerospike::OPT_POLICY_REPLICA options * @see Aerospike::OPT_POLICY_READ_MODE_AP Aerospike::OPT_POLICY_READ_MODE_AP options * @see Aerospike::OPT_POLICY_READ_MODE_SC Aerospike::OPT_POLICY_READ_MODE_SC options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function exists(array $key, &$metadata, array $options = []) {} /** * Touch the record identified by the $key, resetting its time-to-live. * * ```php * $key = $client->initKey("test", "users", 1234); * $status = $client->touch($key, 120); * if ($status == Aerospike::OK) { * echo "Added 120 seconds to the record's expiration.\n" * } elseif ($status == Aerospike::ERR_RECORD_NOT_FOUND) { * echo "A user with key ". $key['key']. " does not exist in the database\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * Added 120 seconds to the record's expiration. * ``` * **or** * ``` * A user with key 1234 does not exist in the database. * ``` * @link https://www.aerospike.com/docs/client/c/usage/kvs/write.html#change-record-time-to-live-ttl Time-to-live * @link https://www.aerospike.com/docs/guide/FAQ.html FAQ * @link https://discuss.aerospike.com/t/records-ttl-and-evictions/737 Record TTL and Evictions * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param int $ttl The record's time-to-live in seconds * @param array $options an optional array of write policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_DESERIALIZE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_DESERIALIZE Aerospike::OPT_DESERIALIZE option * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function touch(array $key, $ttl = 0, array $options = []) {} /** * Remove the record identified by the $key. * * ```php * $key = $client->initKey("test", "users", 1234); * $status = $client->remove($key); * if ($status == Aerospike::OK) { * echo "Record removed.\n"; * } elseif ($status == Aerospike::ERR_RECORD_NOT_FOUND) { * echo "A user with key ". $key['key']. " does not exist in the database\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * Record removed. * ``` * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param array $options an optional array of write policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_POLICY_DURABLE_DELETE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_POLICY_DURABLE_DELETE Aerospike::OPT_POLICY_DURABLE_DELETE options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function remove(array $key, array $options = []) {} /** * Remove $bins from the record identified by the $key. * * ```php * $key = ["ns" => "test", "set" => "users", "key" => 1234]; * $options = array(Aerospike::OPT_TTL => 3600); * $status = $client->removeBin($key, ["age"], $options); * if ($status == Aerospike::OK) { * echo "Removed bin 'age' from the record.\n"; * } elseif ($status == Aerospike::ERR_RECORD_NOT_FOUND) { * echo "The database has no record with the given key.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param array $bins A list of bin names to remove * @param array $options an optional array of write policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::COMPRESSION_THRESHOLD * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::COMPRESSION_THRESHOLD * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function removeBin(array $key, array $bins, array $options = []) {} /** * Remove all the records from a namespace or set * * Remove records in a specified namespace/set efficiently. This method is * many orders of magnitude faster than deleting records one at a time. * **Note:** works with Aerospike Server versions >= 3.12 * See {@link https://www.aerospike.com/docs/reference/info#truncate Truncate command information} * * This asynchronous server call may return before the truncation is complete. * The user can still write new records after the server returns because new * records will have last update times greater than the truncate cutoff * (set at the time of truncate call). * * The truncate command does not durably delete records in the Community Edition. * The Enterprise Edition provides durability through the truncate command. * * ```php * $secondsInDay = 24 * 60 * 60; * * // Multiply by 10 ^ 9 to get nanoseconds * $yesterday = 1000000000 * (time() - $secondsInDay); * * // Remove all records in test/truncateSet updated before 24 hours ago * $status = $client->truncate("test", "demoSet", $yesterday); * * // Truncate all records in test, regardless of update time * $status = $client->truncate("test", null, 0); * ``` * @version 3.12 Requires server >= 3.12 * @param string $ns the namespace * @param string $set the set within the given namespace * @param int $nanos cutoff threshold indicating that records * last updated before the threshold will be removed. Units are in * nanoseconds since unix epoch (1970-01-01 00:00:00). A value of 0 * indicates that all records in the set should be truncated * regardless of update time. The value must not be in the future. * @param array $options an optional array of write policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function truncate($ns, $set, $nanos, array $options = []) {} /** * Increment the value of $bin in the record identified by the $key by an * $offset. * * ```php * $key = $client->initKey("test", "users", 1234); * $options = [Aerospike::OPT_TTL => 7200]; * $status = $client->increment($key, 'pto', -4, $options); * if ($status == Aerospike::OK) { * echo "Decremented four vacation days from the user's PTO balance.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin The name of the bin to increment * @param int|float $offset The value by which to increment the bin * @param array $options an optional array of write policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function increment(array $key, $bin, $offset, array $options = []) {} /** * Append a string $value to the one already in $bin, in the record identified by the $key. * * ```php * $key = $client->initKey("test", "users", 1234); * $options = [Aerospike::OPT_TTL => 3600]; * $status = $client->append($key, 'name', ' Ph.D.', $options); * if ($status == Aerospike::OK) { * echo "Added the Ph.D. suffix to the user.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin The name of the bin * @param string $value The string value to append to the bin * @param array $options an optional array of write policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_DESERIALIZE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_DESERIALIZE Aerospike::OPT_DESERIALIZE option * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function append(array $key, $bin, $value, array $options = []) {} /** * Prepend a string $value to the one already in $bin, in the record identified by the $key. * * ```php * $key = $client->initKey("test", "users", 1234); * $options = [Aerospike::OPT_TTL => 3600]; * $status = $client->prepend($key, 'name', '*', $options); * if ($status == Aerospike::OK) { * echo "Starred the user.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin The name of the bin * @param string $value The string value to prepend to the bin * @param array $options an optional array of write policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_DESERIALIZE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_DESERIALIZE Aerospike::OPT_DESERIALIZE option * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function prepend(array $key, $bin, $value, array $options = []) {} /** * Perform multiple bin operations on a record with a given key, with write operations happening before read ones. * * Non-existent bins being read will have a `NULL` value. * * Currently a call to operate() can include only one write operation per-bin. * For example, you cannot both append and prepend to the same bin, in the same call. * * Like other bin operations, operate() only works on existing records (i.e. ones that were previously created with a put()). * * **Example #1 Combining several write operations into one multi-op call** * * ``` * [ * ["op" => Aerospike::OPERATOR_APPEND, "bin" => "name", "val" => " Ph.D."], * ["op" => Aerospike::OPERATOR_INCR, "bin" => "age", "val" => 1], * ["op" => Aerospike::OPERATOR_READ, "bin" => "age"] * ] * ``` * * ```php * $config = ["hosts" => [["addr"=>"localhost", "port"=>3000]], "shm"=>[]]; * $client = new Aerospike($config, true); * if (!$client->isConnected()) { * echo "Aerospike failed to connect[{$client->errorno()}]: {$client->error()}\n"; * exit(1); * } * * $key = $client->initKey("test", "users", 1234); * $operations = [ * ["op" => Aerospike::OPERATOR_APPEND, "bin" => "name", "val" => " Ph.D."], * ["op" => Aerospike::OPERATOR_INCR, "bin" => "age", "val" => 1], * ["op" => Aerospike::OPERATOR_READ, "bin" => "age"], * ]; * $options = [Aerospike::OPT_TTL => 600]; * $status = $client->operate($key, $operations, $returned, $options); * if ($status == Aerospike::OK) { * var_dump($returned); * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * array(1) { * ["age"]=> * int(34) * } * ``` * * **Example #2 Implementing an LRU by reading a bin and touching a record in the same operation** * * ``` * [ * ["op" => Aerospike::OPERATOR_READ, "bin" => "age"], * ["op" => Aerospike::OPERATOR_TOUCH, "ttl" => 20] * ] * ``` * @link https://www.aerospike.com/docs/guide/kvs.html Key-Value Store * @link https://github.com/aerospike/aerospike-client-php/blob/master/doc/README.md#handling-unsupported-types Handling Unsupported Types * @link https://www.aerospike.com/docs/client/c/usage/kvs/write.html#change-record-time-to-live-ttl Time-to-live * @link https://www.aerospike.com/docs/guide/glossary.html Glossary * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param array $operations The array of of one or more per-bin operations conforming to the following structure: * ``` * Write Operation: * op => Aerospike::OPERATOR_WRITE * bin => bin name (cannot be longer than 14 characters) * val => the value to store in the bin * * Increment Operation: * op => Aerospike::OPERATOR_INCR * bin => bin name * val => the integer by which to increment the value in the bin * * Prepend Operation: * op => Aerospike::OPERATOR_PREPEND * bin => bin name * val => the string to prepend the string value in the bin * * Append Operation: * op => Aerospike::OPERATOR_APPEND * bin => bin name * val => the string to append the string value in the bin * * Read Operation: * op => Aerospike::OPERATOR_READ * bin => name of the bin we want to read after any write operations * * Touch Operation: reset the time-to-live of the record and increment its generation * (only combines with read operations) * op => Aerospike::OPERATOR_TOUCH * ttl => a positive integer value to set as time-to-live for the record * * Delete Operation: * op => Aerospike::OPERATOR_DELETE * * List Append Operation: * op => Aerospike::OP_LIST_APPEND, * bin => "events", * val => 1234 * * List Merge Operation: * op => Aerospike::OP_LIST_MERGE, * bin => "events", * val => [ 123, 456 ] * * List Insert Operation: * op => Aerospike::OP_LIST_INSERT, * bin => "events", * index => 2, * val => 1234 * * List Insert Items Operation: * op => Aerospike::OP_LIST_INSERT_ITEMS, * bin => "events", * index => 2, * val => [ 123, 456 ] * * List Pop Operation: * op => Aerospike::OP_LIST_POP, # returns a value * bin => "events", * index => 2 * * List Pop Range Operation: * op => Aerospike::OP_LIST_POP_RANGE, # returns a value * bin => "events", * index => 2, * val => 3 # remove 3 elements starting at index 2 * * List Remove Operation: * op => Aerospike::OP_LIST_REMOVE, * bin => "events", * index => 2 * * List Remove Range Operation: * op => Aerospike::OP_LIST_REMOVE_RANGE, * bin => "events", * index => 2, * val => 3 # remove 3 elements starting at index 2 * * List Clear Operation: * op => Aerospike::OP_LIST_CLEAR, * bin => "events" * * List Set Operation: * op => Aerospike::OP_LIST_SET, * bin => "events", * index => 2, * val => "latest event at index 2" # set this value at index 2 * * List Get Operation: * op => Aerospike::OP_LIST_GET, # returns a value * bin => "events", * index => 2 # similar to Aerospike::OPERATOR_READ but only returns the value * at index 2 of the list, not the whole bin * * List Get Range Operation: * op => Aerospike::OP_LIST_GET_RANGE, # returns a value * bin => "events", * index => 2, * val => 3 # get 3 elements starting at index 2 * * List Trim Operation: * op => Aerospike::OP_LIST_TRIM, * bin => "events", * index => 2, * val => 3 # remove all elements not in the range between index 2 and index 2 + 3 * * List Size Operation: * op => Aerospike::OP_LIST_SIZE, # returns a value * bin => "events" # gets the size of a list contained in the bin * * * Map operations * * Map Policies: * Many of the following operations require a map policy, the policy is an array * containing any of the keys AEROSPIKE::OPT_MAP_ORDER, AEROSPIKE::OPT_MAP_WRITE_MODE * * the value for AEROSPIKE::OPT_MAP_ORDER should be one of AEROSPIKE::AS_MAP_UNORDERED , AEROSPIKE::AS_MAP_KEY_ORDERED , AEROSPIKE::AS_MAP_KEY_VALUE_ORDERED * the default value is currently AEROSPIKE::AS_MAP_UNORDERED * * the value for AEROSPIKE::OPT_MAP_WRITE_MODE should be one of: AEROSPIKE::AS_MAP_UPDATE, AEROSPIKE::AS_MAP_UPDATE_ONLY , AEROSPIKE::AS_MAP_CREATE_ONLY * the default value is currently AEROSPIKE::AS_MAP_UPDATE * * the value for AEROSPIKE::OPT_MAP_WRITE_FLAGS should be one of: AEROSPIKE::AS_MAP_WRITE_DEFAULT, AEROSPIKE::AS_MAP_WRITE_CREATE_ONLY, AEROSPIKE::AS_MAP_WRITE_UPDATE_ONLY, AEROSPIKE::AS_MAP_WRITE_NO_FAIL, AEROSPIKE::AS_MAP_WRITE_PARTIAL * the default value is currently AEROSPIKE::AS_MAP_WRITE_DEFAULT * * Map return types: * many of the map operations require a return_type entry. * this specifies the format in which the response should be returned. The options are: * AEROSPIKE::AS_MAP_RETURN_NONE # Do not return a result. * AEROSPIKE::AS_MAP_RETURN_INDEX # Return key index order. * AEROSPIKE::AS_MAP_RETURN_REVERSE_INDEX # Return reverse key order. * AEROSPIKE::AS_MAP_RETURN_RANK # Return value order. * AEROSPIKE::AS_MAP_RETURN_REVERSE_RANK # Return reserve value order. * AEROSPIKE::AS_MAP_RETURN_COUNT # Return count of items selected. * AEROSPIKE::AS_MAP_RETURN_KEY # Return key for single key read and key list for range read. * AEROSPIKE::AS_MAP_RETURN_VALUE # Return value for single key read and value list for range read. * AEROSPIKE::AS_MAP_RETURN_KEY_VALUE # Return key/value items. Will be of the form ['key1', 'val1', 'key2', 'val2', 'key3', 'val3] * * Map policy Operation: * op => Aerospike::OP_MAP_SET_POLICY, * bin => "map", * map_policy => [ AEROSPIKE::OPT_MAP_ORDER => AEROSPIKE::AS_MAP_KEY_ORDERED] * * Map clear operation: (Remove all items from a map) * op => AEROSPIKE::OP_MAP_CLEAR, * bin => "bin_name" * * * Map Size Operation: Return the number of items in a map * op => AEROSPIKE::OP_MAP_SIZE, * bin => "bin_name" * * Map Get by Key operation * op => AEROSPIKE::OP_MAP_GET_BY_KEY , * bin => "bin_name", * key => "my_key", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get By Key Range operation: * op => AEROSPIKE::OP_MAP_GET_BY_KEY_RANGE , * bin => "bin_name", * key => "aaa", * range_end => "bbb" * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get By Value operation: * op => AEROSPIKE::OP_MAP_GET_BY_VALUE , * bin => "bin_name", * value => "my_val" * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get by Value Range operation: * op => AEROSPIKE::OP_MAP_GET_BY_VALUE_RANGE , * bin => "bin_name", * value => "value_a", * range_end => "value_z", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get By Index operation * op => AEROSPIKE::OP_MAP_GET_BY_INDEX , * bin => "bin_name", * index => 2, * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get by Index Range operation * op => AEROSPIKE::OP_MAP_GET_BY_INDEX_RANGE, * bin => "bin_name", * index => 2, * count => 2, * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get By Rank operation * op => AEROSPIKE::OP_MAP_GET_BY_RANK , * bin => "bin_name", * rank => -1, # get the item with the largest value * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get by Rank Range operation * op => AEROSPIKE::OP_MAP_GET_BY_RANK_RANGE , * rank => -2 , * count => 2 , * bin => "bin_name", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Put operation * op => AEROSPIKE::OP_MAP_PUT , * bin => "bin_name", * key => "aero", * val => "spike", * map_policy => [ AEROSPIKE::OPT_MAP_ORDER => AEROSPIKE::AS_MAP_KEY_ORDERED] * * Map Put Items operations * op => AEROSPIKE::OP_MAP_PUT_ITEMS , * bin => "bin_name", * val => [1, "a", 1.5], * map_policy => [ AEROSPIKE::OPT_MAP_ORDER => AEROSPIKE::AS_MAP_KEY_ORDERED] * * Map Increment operation * op => AEROSPIKE::OP_MAP_INCREMENT , * bin => "bin_name", * val => 5, #increment the value by 5 * key => "key_to_increment", * map_policy => [ AEROSPIKE::OPT_MAP_ORDER => AEROSPIKE::AS_MAP_KEY_ORDERED] * * Map Decrement operation * op => AEROSPIKE::OP_MAP_DECREMENT , * bin => "bin_name", * key => "key_to_decrement", * val => 5, #decrement by 5 * map_policy => [ AEROSPIKE::OPT_MAP_ORDER => AEROSPIKE::AS_MAP_KEY_ORDERED] * * Map Remove by Key operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_KEY , * bin => "bin_name", * key => "key_to_remove", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Remove by Key list operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_KEY_LIST , * bin => "bin_name", * key => ["key1", 2, "key3"], * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map remove by Key Range operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_KEY_RANGE , * bin => "bin", * key => "a", * range_end => "d", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map remove by Value operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_VALUE , * bin => "bin_name", * val => 5, * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map remove by value range operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_VALUE_RANGE , * bin => "bin_name", * val => "a", * range_end => "d" * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map remove by value list operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_VALUE_LIST , * bin => "bin_name", * val => [1, 2, 3, 4], * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Remove by Index operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_INDEX , * index => 2, * bin => "bin_name", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Remove By Index Range operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_INDEX_RANGE , * bin => "bin_name", * index => 3 , * count => 3 , * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Remove by Rank operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_RANK , * rank => -1 , * bin => "bin_name", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map remove by rank range * op => AEROSPIKE::OP_MAP_REMOVE_BY_RANK_RANGE, * bin => "bin_name", * rank => -1, * count => return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * * * ``` * * @param array &$returned a pass-by-reference array of bins retrieved by read operations. If multiple operations exist for a specific bin name, the last operation will be the one placed as the value * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_POLICY_REPLICA * * Aerospike::OPT_POLICY_READ_MODE_AP * * Aerospike::OPT_POLICY_READ_MODE_SC * * Aerospike::OPT_POLICY_DURABLE_DELETE * * Aerospike::OPT_DESERIALIZE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_POLICY_REPLICA Aerospike::OPT_POLICY_REPLICA options * @see Aerospike::OPT_POLICY_READ_MODE_AP Aerospike::OPT_POLICY_READ_MODE_AP options * @see Aerospike::OPT_POLICY_READ_MODE_SC Aerospike::OPT_POLICY_READ_MODE_SC options * @see Aerospike::OPT_POLICY_DURABLE_DELETE Aerospike::OPT_POLICY_DURABLE_DELETE options * @see Aerospike::OPT_DESERIALIZE Aerospike::OPT_DESERIALIZE option * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @see Aerospike::OPERATOR_WRITE Aerospike::OPERATOR_WRITE and other operators * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function operate(array $key, array $operations, &$returned, array $options = []) {} /** * Perform multiple bin operations on a record with a given key, with write operations happening before read ones. * The order of the resulting elements will correspond to the order of the operations in the parameters. * * Non-existent bins being read will have a `NULL` value. * * Currently a call to operateOrdered() can include only one write operation per-bin. * For example, you cannot both append and prepend to the same bin, in the same call. * * Like other bin operations, operateOrdered() only works on existing records (i.e. ones that were previously created with a put()). * * **Example #1 Combining several write operations into one multi-op call** * * ```php * $config = ["hosts" => [["addr"=>"localhost", "port"=>3000]], "shm"=>[]]; * $client = new Aerospike($config, true); * if (!$client->isConnected()) { * echo "Aerospike failed to connect[{$client->errorno()}]: {$client->error()}\n"; * exit(1); * } * * $key = $client->initKey("test", "demo", "pk458"); * $operations = [ * array("op" => Aerospike::OP_LIST_APPEND, "bin" => "age", "val"=>49), * array("op" => Aerospike::OP_LIST_GET, "bin" => "age", "index"=>0), * array("op" => Aerospike::OP_LIST_POP, "bin" => "age", "index"=>0) * ]; * $returned = "output value"; * $status = $client->operateOrdered($key, $operations, $returned); * * if ($status == Aerospike::OK) { * var_dump($returned); * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * * @link https://www.aerospike.com/docs/guide/kvs.html Key-Value Store * @link https://github.com/aerospike/aerospike-client-php/blob/master/doc/README.md#handling-unsupported-types Handling Unsupported Types * @link https://www.aerospike.com/docs/client/c/usage/kvs/write.html#change-record-time-to-live-ttl Time-to-live * @link https://www.aerospike.com/docs/guide/glossary.html Glossary * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param array $operations The array of of one or more per-bin operations conforming to the following structure: * ``` * Write Operation: * op => Aerospike::OPERATOR_WRITE * bin => bin name (cannot be longer than 14 characters) * val => the value to store in the bin * * Increment Operation: * op => Aerospike::OPERATOR_INCR * bin => bin name * val => the integer by which to increment the value in the bin * * Prepend Operation: * op => Aerospike::OPERATOR_PREPEND * bin => bin name * val => the string to prepend the string value in the bin * * Append Operation: * op => Aerospike::OPERATOR_APPEND * bin => bin name * val => the string to append the string value in the bin * * Read Operation: * op => Aerospike::OPERATOR_READ * bin => name of the bin we want to read after any write operations * * Touch Operation: reset the time-to-live of the record and increment its generation * (only combines with read operations) * op => Aerospike::OPERATOR_TOUCH * ttl => a positive integer value to set as time-to-live for the record * * Delete Operation: * op => Aerospike::OPERATOR_DELETE * * List Append Operation: * op => Aerospike::OP_LIST_APPEND, * bin => "events", * val => 1234 * * List Merge Operation: * op => Aerospike::OP_LIST_MERGE, * bin => "events", * val => [ 123, 456 ] * * List Insert Operation: * op => Aerospike::OP_LIST_INSERT, * bin => "events", * index => 2, * val => 1234 * * List Insert Items Operation: * op => Aerospike::OP_LIST_INSERT_ITEMS, * bin => "events", * index => 2, * val => [ 123, 456 ] * * List Pop Operation: * op => Aerospike::OP_LIST_POP, # returns a value * bin => "events", * index => 2 * * List Pop Range Operation: * op => Aerospike::OP_LIST_POP_RANGE, # returns a value * bin => "events", * index => 2, * val => 3 # remove 3 elements starting at index 2 * * List Remove Operation: * op => Aerospike::OP_LIST_REMOVE, * bin => "events", * index => 2 * * List Remove Range Operation: * op => Aerospike::OP_LIST_REMOVE_RANGE, * bin => "events", * index => 2, * val => 3 # remove 3 elements starting at index 2 * * List Clear Operation: * op => Aerospike::OP_LIST_CLEAR, * bin => "events" * * List Set Operation: * op => Aerospike::OP_LIST_SET, * bin => "events", * index => 2, * val => "latest event at index 2" # set this value at index 2 * * List Get Operation: * op => Aerospike::OP_LIST_GET, # returns a value * bin => "events", * index => 2 # similar to Aerospike::OPERATOR_READ but only returns the value * at index 2 of the list, not the whole bin * * List Get Range Operation: * op => Aerospike::OP_LIST_GET_RANGE, # returns a value * bin => "events", * index => 2, * val => 3 # get 3 elements starting at index 2 * * List Trim Operation: * op => Aerospike::OP_LIST_TRIM, * bin => "events", * index => 2, * val => 3 # remove all elements not in the range between index 2 and index 2 + 3 * * List Size Operation: * op => Aerospike::OP_LIST_SIZE, # returns a value * bin => "events" # gets the size of a list contained in the bin * * * Map operations * * Map Policies: * Many of the following operations require a map policy, the policy is an array * containing any of the keys AEROSPIKE::OPT_MAP_ORDER, AEROSPIKE::OPT_MAP_WRITE_MODE * * the value for AEROSPIKE::OPT_MAP_ORDER should be one of AEROSPIKE::AS_MAP_UNORDERED , AEROSPIKE::AS_MAP_KEY_ORDERED , AEROSPIKE::AS_MAP_KEY_VALUE_ORDERED * the default value is currently AEROSPIKE::AS_MAP_UNORDERED * * the value for AEROSPIKE::OPT_MAP_WRITE_MODE should be one of: AEROSPIKE::AS_MAP_UPDATE, AEROSPIKE::AS_MAP_UPDATE_ONLY , AEROSPIKE::AS_MAP_CREATE_ONLY * the default value is currently AEROSPIKE::AS_MAP_UPDATE * * the value for AEROSPIKE::OPT_MAP_WRITE_FLAGS should be one of: AEROSPIKE::AS_MAP_WRITE_DEFAULT, AEROSPIKE::AS_MAP_WRITE_CREATE_ONLY, AEROSPIKE::AS_MAP_WRITE_UPDATE_ONLY, AEROSPIKE::AS_MAP_WRITE_NO_FAIL, AEROSPIKE::AS_MAP_WRITE_PARTIAL * the default value is currently AEROSPIKE::AS_MAP_WRITE_DEFAULT * * Map return types: * many of the map operations require a return_type entry. * this specifies the format in which the response should be returned. The options are: * AEROSPIKE::AS_MAP_RETURN_NONE # Do not return a result. * AEROSPIKE::AS_MAP_RETURN_INDEX # Return key index order. * AEROSPIKE::AS_MAP_RETURN_REVERSE_INDEX # Return reverse key order. * AEROSPIKE::AS_MAP_RETURN_RANK # Return value order. * AEROSPIKE::AS_MAP_RETURN_REVERSE_RANK # Return reserve value order. * AEROSPIKE::AS_MAP_RETURN_COUNT # Return count of items selected. * AEROSPIKE::AS_MAP_RETURN_KEY # Return key for single key read and key list for range read. * AEROSPIKE::AS_MAP_RETURN_VALUE # Return value for single key read and value list for range read. * AEROSPIKE::AS_MAP_RETURN_KEY_VALUE # Return key/value items. Will be of the form ['key1', 'val1', 'key2', 'val2', 'key3', 'val3] * * Map policy Operation: * op => Aerospike::OP_MAP_SET_POLICY, * bin => "map", * map_policy => [ AEROSPIKE::OPT_MAP_ORDER => AEROSPIKE::AS_MAP_KEY_ORDERED] * * Map clear operation: (Remove all items from a map) * op => AEROSPIKE::OP_MAP_CLEAR, * bin => "bin_name" * * * Map Size Operation: Return the number of items in a map * op => AEROSPIKE::OP_MAP_SIZE, * bin => "bin_name" * * Map Get by Key operation * op => AEROSPIKE::OP_MAP_GET_BY_KEY , * bin => "bin_name", * key => "my_key", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get By Key Range operation: * op => AEROSPIKE::OP_MAP_GET_BY_KEY_RANGE , * bin => "bin_name", * key => "aaa", * range_end => "bbb" * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get By Value operation: * op => AEROSPIKE::OP_MAP_GET_BY_VALUE , * bin => "bin_name", * value => "my_val" * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get by Value Range operation: * op => AEROSPIKE::OP_MAP_GET_BY_VALUE_RANGE , * bin => "bin_name", * value => "value_a", * range_end => "value_z", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get By Index operation * op => AEROSPIKE::OP_MAP_GET_BY_INDEX , * bin => "bin_name", * index => 2, * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get by Index Range operation * op => AEROSPIKE::OP_MAP_GET_BY_INDEX_RANGE, * bin => "bin_name", * index => 2, * count => 2, * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get By Rank operation * op => AEROSPIKE::OP_MAP_GET_BY_RANK , * bin => "bin_name", * rank => -1, # get the item with the largest value * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Get by Rank Range operation * op => AEROSPIKE::OP_MAP_GET_BY_RANK_RANGE , * rank => -2 , * count => 2 , * bin => "bin_name", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Put operation * op => AEROSPIKE::OP_MAP_PUT , * bin => "bin_name", * key => "aero", * val => "spike", * map_policy => [ AEROSPIKE::OPT_MAP_ORDER => AEROSPIKE::AS_MAP_KEY_ORDERED] * * Map Put Items operations * op => AEROSPIKE::OP_MAP_PUT_ITEMS , * bin => "bin_name", * val => [1, "a", 1.5], * map_policy => [ AEROSPIKE::OPT_MAP_ORDER => AEROSPIKE::AS_MAP_KEY_ORDERED] * * Map Increment operation * op => AEROSPIKE::OP_MAP_INCREMENT , * bin => "bin_name", * val => 5, #increment the value by 5 * key => "key_to_increment", * map_policy => [ AEROSPIKE::OPT_MAP_ORDER => AEROSPIKE::AS_MAP_KEY_ORDERED] * * Map Decrement operation * op => AEROSPIKE::OP_MAP_DECREMENT , * bin => "bin_name", * key => "key_to_decrement", * val => 5, #decrement by 5 * map_policy => [ AEROSPIKE::OPT_MAP_ORDER => AEROSPIKE::AS_MAP_KEY_ORDERED] * * Map Remove by Key operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_KEY , * bin => "bin_name", * key => "key_to_remove", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Remove by Key list operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_KEY_LIST , * bin => "bin_name", * key => ["key1", 2, "key3"], * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map remove by Key Range operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_KEY_RANGE , * bin => "bin", * key => "a", * range_end => "d", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map remove by Value operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_VALUE , * bin => "bin_name", * val => 5, * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map remove by value range operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_VALUE_RANGE , * bin => "bin_name", * val => "a", * range_end => "d" * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map remove by value list operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_VALUE_LIST , * bin => "bin_name", * val => [1, 2, 3, 4], * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Remove by Index operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_INDEX , * index => 2, * bin => "bin_name", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Remove By Index Range operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_INDEX_RANGE , * bin => "bin_name", * index => 3 , * count => 3 , * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map Remove by Rank operation * op => AEROSPIKE::OP_MAP_REMOVE_BY_RANK , * rank => -1 , * bin => "bin_name", * return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * Map remove by rank range * op => AEROSPIKE::OP_MAP_REMOVE_BY_RANK_RANGE, * bin => "bin_name", * rank => -1, * count => return_type => AEROSPIKE::MAP_RETURN_KEY_VALUE * * * * ``` * * @param array &$returned a pass-by-reference array of bins retrieved by read operations. If multiple operations exist for a specific bin name, the last operation will be the one placed as the value * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_POLICY_REPLICA * * Aerospike::OPT_POLICY_READ_MODE_AP * * Aerospike::OPT_POLICY_READ_MODE_SC * * Aerospike::OPT_POLICY_DURABLE_DELETE * * Aerospike::OPT_DESERIALIZE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_POLICY_REPLICA Aerospike::OPT_POLICY_REPLICA options * @see Aerospike::OPT_POLICY_READ_MODE_AP Aerospike::OPT_POLICY_READ_MODE_AP options * @see Aerospike::OPT_POLICY_READ_MODE_SC Aerospike::OPT_POLICY_READ_MODE_SC options * @see Aerospike::OPT_POLICY_DURABLE_DELETE Aerospike::OPT_POLICY_DURABLE_DELETE options * @see Aerospike::OPT_DESERIALIZE Aerospike::OPT_DESERIALIZE option * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @see Aerospike::OPERATOR_WRITE Aerospike::OPERATOR_WRITE and other operators * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function operateOrdered(array $key, array $operations, &$returned, array $options = []) {} /** * Count the number of elements in a list type bin * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param int &$count pass-by-reference param * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_REPLICA * * Aerospike::OPT_POLICY_READ_MODE_AP * * Aerospike::OPT_POLICY_READ_MODE_SC * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_READ_TIMEOUT Aerospike::OPT_READ_TIMEOUT options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_REPLICA Aerospike::OPT_POLICY_REPLICA options * @see Aerospike::OPT_POLICY_READ_MODE_AP Aerospike::OPT_POLICY_READ_MODE_AP options * @see Aerospike::OPT_POLICY_READ_MODE_SC Aerospike::OPT_POLICY_READ_MODE_SC options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listSize(array $key, $bin, &$count, array $options = []) {} /** * Add a single value (of any type) to the end of a list type bin * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param mixed $value * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listAppend(array $key, $bin, $value, array $options = []) {} /** * Add several items to the end of a list type bin * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param array $items * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listMerge(array $key, $bin, array $items, array $options = []) {} /** * Insert a single element (of any type) at a specified index of a list type bin * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param int $index * @param mixed $value * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listInsert(array $key, $bin, $index, $value, array $options = []) {} /** * Insert several elements at a specified index of a list type bin * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param int $index * @param array $elements * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listInsertItems(array $key, $bin, $index, array $elements, array $options = []) {} /** * Remove and get back the element at a specified index of a list type bin * Index -1 is the last item in the list, -3 is the third from last, 0 is the first in the list. * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param int $index * @param mixed &$element pass-by-reference param * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_POLICY_DURABLE_DELETE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_DURABLE_DELETE Aerospike::OPT_POLICY_DURABLE_DELETE options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listPop(array $key, $bin, $index, &$element, array $options = []) {} /** * Remove and get back several elements at a specified index range of a list type bin * Index -1 is the last item in the list, -3 is the third from last, 0 is the first in the list. * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param int $index * @param int $count * @param array &$elements pass-by-reference param. After the method call it will be an array holding the popped elements. * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_POLICY_DURABLE_DELETE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_POLICY_DURABLE_DELETE Aerospike::OPT_POLICY_DURABLE_DELETE options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listPopRange(array $key, $bin, $index, $count, &$elements, array $options = []) {} /** * Remove a list element at a specified index of a list type bin * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param int $index * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_POLICY_DURABLE_DELETE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_POLICY_DURABLE_DELETE Aerospike::OPT_POLICY_DURABLE_DELETE options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listRemove(array $key, $bin, $index, array $options = []) {} /** * Remove several list elements at a specified index range of a list type bin * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param int $index * @param int $count * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_POLICY_DURABLE_DELETE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_POLICY_DURABLE_DELETE Aerospike::OPT_POLICY_DURABLE_DELETE options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listRemoveRange(array $key, $bin, $index, $count, array $options = []) {} /** * Trim the list, removing all elements not in the specified index range of a list type bin * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param int $index * @param int $count * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_POLICY_DURABLE_DELETE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_POLICY_DURABLE_DELETE Aerospike::OPT_POLICY_DURABLE_DELETE options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listTrim(array $key, $bin, $index, $count, array $options = []) {} /** * Remove all the elements from a list type bin * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_POLICY_DURABLE_DELETE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_POLICY_DURABLE_DELETE Aerospike::OPT_POLICY_DURABLE_DELETE options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listClear(array $key, $bin, array $options = []) {} /** * Set an element at a specified index of a list type bin * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param int $index * @param mixed $value * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_TTL * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_GEN * * Aerospike::OPT_POLICY_COMMIT_LEVEL * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_TTL Aerospike::OPT_TTL options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_GEN Aerospike::OPT_POLICY_GEN options * @see Aerospike::OPT_POLICY_COMMIT_LEVEL Aerospike::OPT_POLICY_COMMIT_LEVEL options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listSet(array $key, $bin, $index, $value, array $options = []) {} /** * Get an element from a specified index of a list type bin * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param int $index * @param array &$element pass-by-reference param which will hold the returned element. * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_REPLICA * * Aerospike::OPT_POLICY_READ_MODE_AP * * Aerospike::OPT_POLICY_READ_MODE_SC * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_READ_TIMEOUT Aerospike::OPT_READ_TIMEOUT options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_REPLICA Aerospike::OPT_POLICY_REPLICA options * @see Aerospike::OPT_POLICY_READ_MODE_AP Aerospike::OPT_POLICY_READ_MODE_AP options * @see Aerospike::OPT_POLICY_READ_MODE_SC Aerospike::OPT_POLICY_READ_MODE_SC options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listGet(array $key, $bin, $index, array &$element, array $options = []) {} /** * Get several elements starting at a specified index from a list type bin * * @version 3.7 Requires server >= 3.7 * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $bin * @param int $index * @param int $count * @param array &$elements pass-by-reference param which will hold an array of returned elements from the specified list bin. * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_POLICY_REPLICA * * Aerospike::OPT_POLICY_READ_MODE_AP * * Aerospike::OPT_POLICY_READ_MODE_SC * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_READ_TIMEOUT Aerospike::OPT_READ_TIMEOUT options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_POLICY_REPLICA Aerospike::OPT_POLICY_REPLICA options * @see Aerospike::OPT_POLICY_READ_MODE_AP Aerospike::OPT_POLICY_READ_MODE_AP options * @see Aerospike::OPT_POLICY_READ_MODE_SC Aerospike::OPT_POLICY_READ_MODE_SC options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listGetRange(array $key, $bin, $index, $count, &$elements, array $options = []) {} // Batch Operation Methods /** * Read a batch of records from a list of given keys, and fill $records with the resulting indexed array * * Each record is an array consisting of *key*, *metadata* and *bins* (see: {@see Aerospike::get() get()}). * Non-existent records will have `NULL` for their *metadata* and *bins* fields. * The bins returned can be filtered by passing an array of bin names. * * **Note** that the protocol getMany() will use (batch-direct or batch-index) * is configurable through the config parameter `Aerospike::USE_BATCH_DIRECT` * or `php.ini` config parameter `aerospike.use_batch_direct`. * By default batch-index is used with servers that support it (version >= 3.6.0). * * **Example #1 Aerospike::getMany() default behavior example** * ```php * $config = ["hosts" => [["addr"=>"localhost", "port"=>3000]], "shm"=>[]]; * $client = new Aerospike($config, true); * if (!$client->isConnected()) { * echo "Aerospike failed to connect[{$client->errorno()}]: {$client->error()}\n"; * exit(1); * } * * $key1 = $client->initKey("test", "users", 1234); * $key2 = $client->initKey("test", "users", 1235); // this key does not exist * $key3 = $client->initKey("test", "users", 1236); * $keys = array($key1, $key2, $key3); * $status = $client->getMany($keys, $records); * if ($status == Aerospike::OK) { * var_dump($records); * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * array(3) { * [0]=> * array(3) { * ["key"]=> * array(4) { * ["ns"]=> * string(4) "test" * ["set"]=> * string(5) "users" * ["key"]=> * int(1234) * ["digest"]=> * string(20) "M?v2Kp??? * * ?[??4?v * } * ["metadata"]=> * array(2) { * ["ttl"]=> * int(4294967295) * ["generation"]=> * int(1) * } * ["bins"]=> * array(3) { * ["email"]=> * string(15) "hey@example.com" * ["name"]=> * string(9) "You There" * ["age"]=> * int(33) * } * } * [1]=> * array(3) { * ["key"]=> * array(4) { * ["ns"]=> * string(4) "test" * ["set"]=> * string(5) "users" * ["key"]=> * int(1235) * ["digest"]=> * string(20) "?C??[?vwS??ƨ?????" * } * ["metadata"]=> * NULL * ["bins"]=> * NULL * } * [2]=> * array(3) { * ["key"]=> * array(4) { * ["ns"]=> * string(4) "test" * ["set"]=> * string(5) "users" * ["key"]=> * int(1236) * ["digest"]=> * string(20) "'?9? * ?????? * ? ?" * } * ["metadata"]=> * array(2) { * ["ttl"]=> * int(4294967295) * ["generation"]=> * int(1) * } * ["bins"]=> * array(3) { * ["email"]=> * string(19) "thisguy@example.com" * ["name"]=> * string(8) "This Guy" * ["age"]=> * int(42) * } * } * } * ``` * **Example #2 getMany records with filtered bins** * ```php * // assuming this follows Example #1 * * $filter = ["email"]; * $keys = [$key1, $key3]; * $status = $client->getMany($keys, $records, $filter); * if ($status == Aerospike::OK) { * var_dump($records); * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * array(2) { * [0]=> * array(3) { * ["key"]=> * array(4) { * ["ns"]=> * string(4) "test" * ["set"]=> * string(5) "users" * ["key"]=> * int(1234) * ["digest"]=> * string(20) "M?v2Kp??? * * ?[??4?v * } * ["metadata"]=> * array(2) { * ["ttl"]=> * int(4294967295) * ["generation"]=> * int(4) * } * ["bins"]=> * array(1) { * ["email"]=> * string(15) "hey@example.com" * } * } * [1]=> * array(3) { * ["key"]=> * array(4) { * ["ns"]=> * string(4) "test" * ["set"]=> * string(5) "users" * ["key"]=> * int(1236) * ["digest"]=> * string(20) "'?9? * ?????? * ? ?" * } * ["metadata"]=> * array(2) { * ["ttl"]=> * int(4294967295) * ["generation"]=> * int(4) * } * ["bins"]=> * array(1) { * ["email"]=> * string(19) "thisguy@example.com" * } * } * } * ``` * @param array $keys an array of initialized keys, each key an array with keys `['ns','set','key']` or `['ns','set','digest']` * @param array &$records a pass-by-reference variable which will hold an array of record values, each record an array of `['key', 'metadata', 'bins']` * @param array $select only these bins out of the record (optional) * @param array $options an optional array of read policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::USE_BATCH_DIRECT * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * * Aerospike::OPT_BATCH_CONCURRENT * * Aerospike::OPT_SEND_SET_NAME * * Aerospike::OPT_ALLOW_INLINE * @see Aerospike::USE_BATCH_DIRECT Aerospike::USE_BATCH_DIRECT options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @see Aerospike::get() get() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function getMany(array $keys, &$records, array $select = [], array $options = []) {} /** * Check if a batch of records exists in the database and fill $metdata with the results * * Checks for the existence a batch of given *keys* (see: {@see Aerospike::exists() exists()}), * and return an indexed array matching the order of the *keys*. * Non-existent records will have `NULL` for their *metadata*. * * **Note** that the protocol existsMany() will use (batch-direct or batch-index) * is configurable through the config parameter `Aerospike::USE_BATCH_DIRECT` * or `php.ini` config parameter `aerospike.use_batch_direct`. * By default batch-index is used with servers that support it (version >= 3.6.0). * * **Example #1 Aerospike::existsMany() default behavior example** * ```php * $config = ["hosts" => [["addr"=>"localhost", "port"=>3000]], "shm"=>[]]; * $client = new Aerospike($config, true); * if (!$client->isConnected()) { * echo "Aerospike failed to connect[{$client->errorno()}]: {$client->error()}\n"; * exit(1); * } * * $key1 = $client->initKey("test", "users", 1234); * $key2 = $client->initKey("test", "users", 1235); // this key does not exist * $key3 = $client->initKey("test", "users", 1236); * $keys = array($key1, $key2, $key3); * $status = $client->existsMany($keys, $metadata); * if ($status == Aerospike::OK) { * var_dump($records); * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * array(3) { * [0]=> * array(3) { * ["key"]=> * array(4) { * ["ns"]=> * string(4) "test" * ["set"]=> * string(5) "users" * ["key"]=> * int(1234) * ["digest"]=> * string(20) "M?v2Kp??? * * ?[??4?v * } * ["metadata"]=> * array(2) { * ["ttl"]=> * int(4294967295) * ["generation"]=> * int(1) * } * } * [1]=> * array(3) { * ["key"]=> * array(4) { * ["ns"]=> * string(4) "test" * ["set"]=> * string(5) "users" * ["key"]=> * int(1235) * ["digest"]=> * string(20) "?C??[?vwS??ƨ?????" * } * ["metadata"]=> * NULL * } * [2]=> * array(3) { * ["key"]=> * array(4) { * ["ns"]=> * string(4) "test" * ["set"]=> * string(5) "users" * ["key"]=> * int(1236) * ["digest"]=> * string(20) "'?9? * ?????? * ? ?" * } * ["metadata"]=> * array(2) { * ["ttl"]=> * int(4294967295) * ["generation"]=> * int(1) * } * } * } * ``` * @param array $keys an array of initialized keys, each key an array with keys `['ns','set','key']` or `['ns','set','digest']` * @param array &$metadata a pass-by-reference array of metadata values, each an array of `['key', 'metadata']` * @param array $options an optional array of read policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::USE_BATCH_DIRECT * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * * Aerospike::OPT_BATCH_CONCURRENT * * Aerospike::OPT_SEND_SET_NAME * * Aerospike::OPT_ALLOW_INLINE * @see Aerospike::USE_BATCH_DIRECT Aerospike::USE_BATCH_DIRECT options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::OK Aerospike::OK and error status codes * @see Aerospike::error() error() * @see Aerospike::errorno() errorno() * @see Aerospike::exists() exists() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function existsMany(array $keys, array &$metadata, array $options = []) {} // Scan and Query /** * Scan a namespace or set * * Scan a _ns.set_, and invoke a callback function *record_cb* on each * record streaming back from the cluster. * * Optionally select the bins to be returned. Non-existent bins in this list will appear in the * record with a NULL value. * * ```php * $options = [Aerospike::OPT_SCAN_PRIORITY => Aerospike::SCAN_PRIORITY_MEDIUM]; * $processed = 0; * $status = $client->scan('test', 'users', function ($record) use (&$processed) { * if (!is_null($record['bins']['email'])) echo $record['bins']['email']."\n"; * if ($processed++ > 19) return false; // halt the stream by returning a false * }, ['email'], $options); * * var_dump($status, $processed); * ``` * ``` * foo@example.com * : * bar@example.com * I think a sample of 20 records is enough * ``` * @link https://www.aerospike.com/docs/architecture/data-model.html Aerospike Data Model * @link https://www.aerospike.com/docs/guide/scan.html Scans * @link https://www.aerospike.com/docs/operations/manage/scans/ Managing Scans * @param string $ns the namespace * @param string $set the set within the given namespace * @param callable $record_cb A callback function invoked for each record streaming back from the cluster * @param array $select An array of bin names which are the subset to be returned * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::OPT_SOCKET_TIMEOUT maximum socket idle time in milliseconds (0 means do not apply a socket idle timeout) * * Aerospike::OPT_SCAN_PRIORITY * * Aerospike::OPT_SCAN_PERCENTAGE of the records in the set to return * * Aerospike::OPT_SCAN_CONCURRENTLY whether to run the scan in parallel * * Aerospike::OPT_SCAN_NOBINS whether to not retrieve bins for the records * * Aerospike::OPT_SCAN_RPS_LIMIT limit the scan to process OPT_SCAN_RPS_LIMIT per second. * * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function scan($ns, $set, callable $record_cb, array $select = [], array $options = []) {} /** * Query a secondary index on a namespace or set * * Query a _ns.set_ with a specified predicate, and invoke a callback function *record_cb* on each * record matched by the query and streaming back from the cluster. * * Optionally select the bins to be returned. Non-existent bins in this list will appear in the * record with a NULL value. * * ```php * $result = []; * $where = Aerospike::predicateBetween("age", 30, 39); * $status = $client->query("test", "users", $where, function ($record) use (&$result) { * $result[] = $record['bins']; * }); * if ($status !== Aerospike::OK) { * echo "An error occured while querying[{$client->errorno()}] {$client->error()}\n"; * } else { * echo "The query returned ".count($result)." records\n"; * } * ``` * ``` * foo@example.com * : * bar@example.com * I think a sample of 20 records is enough * ``` * @link https://www.aerospike.com/docs/architecture/data-model.html Aerospike Data Model * @link https://www.aerospike.com/docs/guide/query.html Query * @link https://www.aerospike.com/docs/operations/manage/queries/index.html Managing Queries * @param string $ns the namespace * @param string $set the set within the given namespace * @param array $where the predicate for the query, usually created by the * predicate helper methods. The arrays conform to one of the following: * ``` * Array: * bin => bin name * op => one of Aerospike::OP_EQ, Aerospike::OP_BETWEEN, Aerospike::OP_CONTAINS, Aerospike::OP_RANGE, etc * val => scalar integer/string for OP_EQ and OP_CONTAINS or [$min, $max] for OP_BETWEEN and OP_RANGE * * or an empty array() for no predicate * ``` * examples * ``` * ["bin"=>"name", "op"=>Aerospike::OP_EQ, "val"=>"foo"] * ["bin"=>"age", "op"=>Aerospike::OP_BETWEEN, "val"=>[35,50]] * ["bin"=>"movies", "op"=>Aerospike::OP_CONTAINS, "val"=>"12 Monkeys"] * ["bin"=>"movies", "op"=>Aerospike::OP_RANGE, "val"=>[10,1000]] * [] // no predicate * ``` * @param callable $record_cb A callback function invoked for each record streaming back from the cluster * @param array $select An array of bin names which are the subset to be returned * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * * Aerospike::OPT_QUERY_NOBINS * @see Aerospike::predicateEquals() * @see Aerospike::predicateBetween() * @see Aerospike::predicateContains() * @see Aerospike::predicateRange() * @see Aerospike::predicateGeoContainsGeoJSONPoint() * @see Aerospike::predicateGeoWithinGeoJSONRegion() * @see Aerospike::predicateGeoContainsPoint() * @see Aerospike::predicateGeoWithinRadius() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function query($ns, $set, array $where, callable $record_cb, array $select = [], array $options = []) {} /** * Helper method for creating an EQUALS predicate * @param string $bin name * @param int|string $val * @see Aerospike::query() * @see Aerospike::queryApply() * @see Aerospike::aggregate() * @return array expressing the predicate, to be used by query(), queryApply() or aggregate() * ``` * Associative Array: * bin => bin name * op => Aerospike::OP_EQ * val => scalar integer/string value * ``` */ public static function predicateEquals($bin, $val) {} /** * Helper method for creating a BETWEEN predicate * @param string $bin name * @param int $min * @param int $max * @see Aerospike::query() * @see Aerospike::queryApply() * @see Aerospike::aggregate() * @return array expressing the predicate, to be used by query(), queryApply() or aggregate() * ``` * Associative Array: * bin => bin name * op => Aerospike::OP_BETWEEN * val => [min, max] * ``` */ public static function predicateBetween($bin, $min, $max) {} /** * Helper method for creating an CONTAINS predicate * * Similar to predicateEquals(), predicateContains() looks for an exact * match of a value inside a complex type - a list containing the value * (if the index type is *INDEX_TYPE_LIST*), the value contained in the keys * of a map (if the index type is *INDEX_TYPE_MAPKEYS*), or a record with the * given value contained in the values of a map (if the index type was * *INDEX_TYPE_MAPVALUES*). * @param string $bin name * @param int $index_type one of Aerospike::INDEX_TYPE_* * @param int|string $val * @see Aerospike::query() * @see Aerospike::queryApply() * @see Aerospike::aggregate() * @return array expressing the predicate, to be used by query(), queryApply() or aggregate() * ``` * Associative Array: * bin => bin name * index_type => Aerospike::INDEX_TYPE_* * op => Aerospike::OP_CONTAINS * val => scalar integer/string value * ``` */ public static function predicateContains($bin, $index_type, $val) {} /** * Helper method for creating a RANGE predicate * * Similar to predicateBetween(), predicateRange() looks for records with a * range of values inside a complex type - a list containing the values * (if the index type is *INDEX_TYPE_LIST*), the values contained in the keys * of a map (if the index type is *INDEX_TYPE_MAPKEYS*), or a record with the * given values contained in the values of a map (if the index type was * *INDEX_TYPE_MAPVALUES*) * @param string $bin name * @param int $index_type one of Aerospike::INDEX_TYPE_* * @param int $min * @param int $max * @see Aerospike::query() * @see Aerospike::queryApply() * @see Aerospike::aggregate() * @return array expressing the predicate, to be used by query(), queryApply() or aggregate() * ``` * Associative Array: * bin => bin name * index_type => Aerospike::INDEX_TYPE_* * op => Aerospike::OP_BETWEEN * val => [min, max] * ``` */ public static function predicateRange($bin, $index_type, $min, $max) {} /** * Helper method for creating a GEOCONTAINS point predicate * @param string $bin name * @param string $point GeoJSON string describing a point * @see Aerospike::query() * @see Aerospike::queryApply() * @see Aerospike::aggregate() * @return array expressing the predicate, to be used by query(), queryApply() or aggregate() * ``` * Associative Array: * bin => bin name * op => Aerospike::OP_GEOCONTAINSPOINT * val => GeoJSON string * ``` */ public static function predicateGeoContainsGeoJSONPoint($bin, $point) {} /** * Helper method for creating a GEOCONTAINS point predicate * @param string $bin name * @param float $long longitude of the point * @param float $lat latitude of the point * @see Aerospike::query() * @see Aerospike::queryApply() * @see Aerospike::aggregate() * @return array expressing the predicate, to be used by query(), queryApply() or aggregate() * ``` * Associative Array: * bin => bin name * op => Aerospike::OP_GEOCONTAINSPOINT * val => GeoJSON string produced from $long and $lat * ``` */ public static function predicateGeoContainsPoint($bin, $long, $lat) {} /** * Helper method for creating a GEOWITHIN region predicate * @param string $bin name * @param string $region GeoJSON string describing the region (polygon) * @see Aerospike::query() * @see Aerospike::queryApply() * @see Aerospike::aggregate() * @return array expressing the predicate, to be used by query(), queryApply() or aggregate() * ``` * Associative Array: * bin => bin name * op => Aerospike::OP_GEOWITHINREGION * val => GeoJSON string * ``` */ public static function predicateGeoWithinGeoJSONRegion($bin, $region) {} /** * Helper method for creating a GEOWITHIN circle region predicate * @param string $bin name * @param float $long longitude of the point * @param float $lat latitude of the point * @param float $radiusMeter radius of the circle in meters * @see Aerospike::query() * @see Aerospike::queryApply() * @see Aerospike::aggregate() * @return array expressing the predicate, to be used by query(), queryApply() or aggregate() * ``` * Associative Array: * bin => bin name * op => Aerospike::OP_GEOWITHINREGION * val => GeoJSON string produced from $long, $lat and $radius * ``` */ public static function predicateGeoWithinRadius($bin, $long, $lat, $radiusMeter) {} /** * Get the status of a background job triggered by Aerospike::scanApply or Aerospike::queryApply * * ```php * // after a queryApply() where $job_id was set: * do { * time_nanosleep(0, 30000000); // pause 30ms * $status = $client->jobInfo($job_id, Aerospike::JOB_QUERY, $job_info); * var_dump($job_info); * } while($job_info['status'] != Aerospike::JOB_STATUS_COMPLETED); * ``` * * @param int $job_id The Job ID * @param int $job_type The type of the job, either Aerospike::JOB_QUERY, or Aerospike::JOB_SCAN * @param array &$info The status of the background job filled (by reference) as an array of * ``` * [ * 'progress_pct' => progress percentage for the job * 'records_read' => number of records read by the job * 'status' => one of Aerospike::STATUS_* * ] * ``` * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * @see Aerospike::scanApply() * @see Aerospike::queryApply() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function jobInfo($job_id, $job_type, array &$info, array $options = []) {} // UDF Methods /** * Register a UDF module with the cluster * * Note that modules containing stream UDFs need to also be copied to the * path described in `aerospike.udf.lua_user_path`, as the last reduce * iteration is run locally on the client (after reducing on all the nodes * of the cluster). * * Currently the only UDF language supported is Lua. * ```php * $status = $client->register('/path/to/my_udf.lua', 'my_udf.lua'); * if ($status == Aerospike::OK) { * echo "UDF module at $path is registered as my_udf on the Aerospike DB.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * @link https://www.aerospike.com/docs/udf/udf_guide.html UDF Development Guide * @param string $path the path to the Lua file on the client-side machine * @param string $module the name of the UDF module to register with the cluster * @param int $language * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OK Aerospike::OK and error status codes * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function register($path, $module, $language = Aerospike::UDF_TYPE_LUA, $options = []) {} /** * Remove a UDF module from the cluster * * ```php * $status = $client->deregister('my_udf'); * if ($status == Aerospike::OK) { * echo "UDF module my_udf was removed from the Aerospike DB.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * @param string $module the name of the UDF module registered with the cluster * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT * @see Aerospike::ERR_UDF_NOT_FOUND UDF error status codes * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function deregister($module, $options = []) {} /** * List the UDF modules registered with the cluster * * The modules array has the following structure: * ``` * Array of: * name => module name * type => Aerospike::UDF_TYPE_* * ``` * **Example** * ```php * $status = $client->listRegistered($modules); * if ($status == Aerospike::OK) { * var_dump($modules); * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * array(2) { * [0]=> * array(2) { * ["name"]=> * string(13) "my_record_udf" * ["type"]=> * int(0) * } * [1]=> * array(2) { * ["name"]=> * string(13) "my_stream_udf" * ["type"]=> * int(0) * } * } * ``` * @param array &$modules pass-by-reference param * @param int $language * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * @see Aerospike::OPT_READ_TIMEOUT Aerospike::OPT_READ_TIMEOUT * @see Aerospike::OK Aerospike::OK and error status codes * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function listRegistered(&$modules, $language = Aerospike::UDF_TYPE_LUA, $options = []) {} /** * Get the code for a UDF module registered with the cluster * * Populates _code_ with the content of the matching UDF _module_ that was * previously registered with the server. * * **Example** * ```php * $status = $client->getRegistered('my_udf', $code); * if ($status == Aerospike::OK) { * var_dump($code); * } elseif ($status == Aerospike::ERR_LUA_FILE_NOT_FOUND) { * echo "The UDF module my_udf was not found to be registered with the server.\n"; * } * ``` * ``` * string(351) "function startswith(rec, bin_name, prefix) * if not aerospike:exists(rec) then * return false * end * if not prefix then * return true * end * if not rec[bin_name] then * return false * end * local bin_val = rec[bin_name] * l = prefix:len() * if l > bin_val:len() then * return false * end * ret = bin_val:sub(1, l) == prefix * return ret * end * " * ``` * @param string $module the name of the UDF module registered with the cluster * @param string &$code pass-by-reference param * @param string $language * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * @see Aerospike::OPT_READ_TIMEOUT Aerospike::OPT_READ_TIMEOUT * @see Aerospike::ERR_LUA_FILE_NOT_FOUND UDF error status codes * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function getRegistered($module, &$code, $language = Aerospike::UDF_TYPE_LUA, $options = []) {} /** * Apply a UDF to a record * * Applies the UDF _module.function_ to a record with a given _key_. * Arguments can be passed to the UDF and any returned value optionally captured. * * Currently the only UDF language supported is Lua. * ```php * $key = ["ns" => "test", "set" => "users", "key" => "1234"]; * $status = $client->apply($key, 'my_udf', 'startswith', ['email', 'hey@'], $returned); * if ($status == Aerospike::OK) { * if ($returned) { * echo "The email of the user with key {$key['key']} starts with 'hey@'.\n"; * } else { * echo "The email of the user with key {$key['key']} does not start with 'hey@'.\n"; * } * } elseif ($status == Aerospike::ERR_UDF_NOT_FOUND) { * echo "The UDF module my_udf.lua was not registered with the Aerospike DB.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * ``` * The email of the user with key 1234 starts with 'hey@'. * ``` * @link https://www.aerospike.com/docs/udf/udf_guide.html UDF Development Guide * @link https://www.aerospike.com/docs/udf/developing_record_udfs.html Developing Record UDFs * @link https://www.aerospike.com/docs/udf/api_reference.html Lua UDF - API Reference * @param array $key The key identifying the record. An array with keys `['ns','set','key']` or `['ns','set','digest']` * @param string $module the name of the UDF module registered with the cluster * @param string $function the name of the UDF * @param array $args optional arguments for the UDF * @param mixed &$returned pass-by-reference param * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_POLICY_KEY * * Aerospike::OPT_SERIALIZER * * Aerospike::OPT_POLICY_DURABLE_DELETE * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_POLICY_KEY Aerospike::OPT_POLICY_KEY options * @see Aerospike::OPT_SERIALIZER Aerospike::OPT_SERIALIZER options * @see Aerospike::OPT_POLICY_DURABLE_DELETE Aerospike::OPT_POLICY_DURABLE_DELETE options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::ERR_LUA UDF error status codes * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function apply(array $key, $module, $function, array $args = [], &$returned = null, $options = []) {} /** * Apply a UDF to each record in a scan * * Scan the *ns.set* and apply a UDF _module.function_ to each of its records. * Arguments can be passed to the UDF and any returned value optionally captured. * * Currently the only UDF language supported is Lua. * ```php * $status = $client->scanApply("test", "users", "my_udf", "mytransform", array(20), $job_id); * if ($status === Aerospike::OK) { * var_dump("Job ID is $job_id"); * } else if ($status === Aerospike::ERR_CLIENT) { * echo "An error occured while initiating the BACKGROUND SCAN [{$client->errorno()}] ".$client->error(); * } else { * echo "An error occured while running the BACKGROUND SCAN [{$client->errorno()}] ".$client->error(); * } * ``` * ``` * string(12) "Job ID is 1" * ``` * @link https://www.aerospike.com/docs/udf/udf_guide.html UDF Development Guide * @link https://www.aerospike.com/docs/udf/developing_record_udfs.html Developing Record UDFs * @link https://www.aerospike.com/docs/udf/api_reference.html Lua UDF - API Reference * @param string $ns the namespace * @param string $set the set within the given namespace * @param string $module the name of the UDF module registered with the cluster * @param string $function the name of the UDF * @param array $args optional arguments for the UDF * @param int &$job_id pass-by-reference filled by the job ID of the scan * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_POLICY_DURABLE_DELETE * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * * Aerospike::OPT_FAIL_ON_CLUSTER_CHANGE * * Aerospike::OPT_SCAN_RPS_LIMIT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_POLICY_DURABLE_DELETE Aerospike::OPT_POLICY_DURABLE_DELETE options * @see Aerospike::ERR_LUA UDF error status codes * @see Aerospike::jobInfo() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function scanApply($ns, $set, $module, $function, array $args, &$job_id, array $options = []) {} /** * Apply a UDF to each record in a query * * Query the *ns.set* with a predicate, and apply a UDF _module.function_ * to each of matched records. * Arguments can be passed to the UDF and any returned value optionally captured. * * Currently the only UDF language supported is Lua. * ```php * $where = Aerospike::predicateBetween("age", 30, 39); * $status = $client->queryApply("test", "users", "my_udf", "mytransform", [20], $job_id); * if ($status === Aerospike::OK) { * var_dump("Job ID is $job_id"); * } else if ($status === Aerospike::ERR_CLIENT) { * echo "An error occured while initiating the BACKGROUND SCAN [{$client->errorno()}] ".$client->error(); * } else { * echo "An error occured while running the BACKGROUND SCAN [{$client->errorno()}] ".$client->error(); * } * ``` * ``` * string(12) "Job ID is 1" * ``` * @link https://www.aerospike.com/docs/udf/udf_guide.html UDF Development Guide * @link https://www.aerospike.com/docs/udf/developing_record_udfs.html Developing Record UDFs * @link https://www.aerospike.com/docs/udf/api_reference.html Lua UDF - API Reference * @param string $ns the namespace * @param string $set the set within the given namespace * @param array $where the predicate for the query, usually created by the * predicate methods. The arrays conform to one of the following: * ``` * Array: * bin => bin name * op => one of Aerospike::OP_EQ, Aerospike::OP_BETWEEN, Aerospike::OP_CONTAINS, Aerospike::OP_RANGE, etc * val => scalar integer/string for OP_EQ and OP_CONTAINS or [$min, $max] for OP_BETWEEN and OP_RANGE * * or an empty array() for no predicate * ``` * examples * ``` * ["bin"=>"name", "op"=>Aerospike::OP_EQ, "val"=>"foo"] * ["bin"=>"age", "op"=>Aerospike::OP_BETWEEN, "val"=>[35,50]] * ["bin"=>"movies", "op"=>Aerospike::OP_CONTAINS, "val"=>"12 Monkeys"] * ["bin"=>"movies", "op"=>Aerospike::OP_RANGE, "val"=>[10,1000]] * [] // no predicate * ``` * @param string $module the name of the UDF module registered with the cluster * @param string $function the name of the UDF * @param array $args optional arguments for the UDF * @param int &$job_id pass-by-reference filled by the job ID of the scan * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * * Aerospike::OPT_POLICY_DURABLE_DELETE * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_WRITE_TIMEOUT Aerospike::OPT_WRITE_TIMEOUT options * @see Aerospike::OPT_POLICY_DURABLE_DELETE Aerospike::OPT_POLICY_DURABLE_DELETE options * @see Aerospike::OPT_SLEEP_BETWEEN_RETRIES Aerospike::OPT_SLEEP_BETWEEN_RETRIES options * @see Aerospike::OPT_TOTAL_TIMEOUT Aerospike::OPT_TOTAL_TIMEOUT options * @see Aerospike::OPT_SOCKET_TIMEOUT Aerospike::OPT_SOCKET_TIMEOUT options * @see Aerospike::MAX_RETRIES Aerospike::MAX_RETRIES options * @see Aerospike::ERR_LUA UDF error status codes * @see Aerospike::jobInfo() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function queryApply($ns, $set, array $where, $module, $function, array $args, &$job_id, array $options = []) {} /** * Apply a stream UDF to a scan or secondary index query * * Apply the UDF _module.function_ to the result of running a secondary * index query on _ns.set_. The aggregated _returned_ variable is then * filled, with its type depending on the UDF. It may be a string, integer * or array, and potentially an array of arrays, such as in the case the * UDF does not specify a reducer and there are multiple nodes in the * cluster, each sending back the result of its own aggregation. * * As with query(), if an empty array is given as the _where_ predicate a * 'scan aggregation' is initiated instead of a query, which means the * stream UDF is applied to all the records returned by the scan. * * **Note** that modules containing stream UDFs need to also be copied to the * path described in `aerospike.udf.lua_user_path`, as the last reduce * iteration is run locally on the client, after reducing on all the nodes * of the cluster. * * **Note** aggregate is currently unsupported in PHP built with ZTS enabled. * Attempting to use it in that environment will fail. * * Currently the only UDF language supported is Lua. * * **Example Stream UDF** * * Module registered as stream_udf.lua * ``` * local function having_ge_threshold(bin_having, ge_threshold) * debug("group_count::thresh_filter: %s > %s ?", tostring(rec[bin_having]), tostring(ge_threshold)) * return function(rec) * if rec[bin_having] < ge_threshold then * return false * end * return true * end * end * * local function count(group_by_bin) * return function(group, rec) * if rec[group_by_bin] then * local bin_name = rec[group_by_bin] * group[bin_name] = (group[bin_name] or 0) + 1 * end * return group * end * end * * local function add_values(val1, val2) * return val1 + val2 * end * * local function reduce_groups(a, b) * return map.merge(a, b, add_values) * end * * function group_count(stream, group_by_bin, bin_having, ge_threshold) * if bin_having and ge_threshold then * local myfilter = having_ge_threshold(bin_having, ge_threshold) * return stream : filter(myfilter) : aggregate(map{}, count(group_by_bin)) : reduce(reduce_groups) * else * return stream : aggregate(map{}, count(group_by_bin)) : reduce(reduce_groups) * end * end * ``` * **Example of aggregating a stream UDF to the result of a secondary index query** * ```php * // assuming test.users has a bin first_name, show the first name distribution * // for users in their twenties * $where = Aerospike::predicateBetween("age", 20, 29); * $status = $client->aggregate("test", "users", $where, "stream_udf", "group_count", ["first_name"], $names); * if ($status == Aerospike::OK) { * var_dump($names); * } else { * echo "An error occured while running the AGGREGATE [{$client->errorno()}] ".$client->error(); * } * ``` * ``` * array(5) { * ["Claudio"]=> * int(1) * ["Michael"]=> * int(3) * ["Jennifer"]=> * int(2) * ["Jessica"]=> * int(3) * ["Jonathan"]=> * int(3) * } * ``` * @link https://www.aerospike.com/docs/udf/udf_guide.html UDF Development Guide * @link https://www.aerospike.com/docs/udf/developing_stream_udfs.html Developing Stream UDFs * @link https://www.aerospike.com/docs/guide/aggregation.html Aggregation * @param string $ns the namespace * @param string $set the set within the given namespace * @param array $where the predicate for the query, usually created by the * predicate methods. The arrays conform to one of the following: * ``` * Array: * bin => bin name * op => one of Aerospike::OP_EQ, Aerospike::OP_BETWEEN, Aerospike::OP_CONTAINS, Aerospike::OP_RANGE * val => scalar integer/string for OP_EQ and OP_CONTAINS or [$min, $max] for OP_BETWEEN and OP_RANGE * * or an empty array() for no predicate * ``` * examples * ``` * ["bin"=>"name", "op"=>Aerospike::OP_EQ, "val"=>"foo"] * ["bin"=>"age", "op"=>Aerospike::OP_BETWEEN, "val"=>[35,50]] * ["bin"=>"movies", "op"=>Aerospike::OP_CONTAINS, "val"=>"12 Monkeys"] * ["bin"=>"movies", "op"=>Aerospike::OP_RANGE, "val"=>[10,1000]] * [] // no predicate * ``` * @param string $module the name of the UDF module registered with the cluster * @param string $function the name of the UDF * @param array $args optional arguments for the UDF * @param mixed &$returned pass-by-reference param * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::OPT_READ_TIMEOUT * * Aerospike::OPT_SLEEP_BETWEEN_RETRIES * * Aerospike::OPT_TOTAL_TIMEOUT * * Aerospike::OPT_MAX_RETRIES * * Aerospike::OPT_SOCKET_TIMEOUT * @see Aerospike::OPT_READ_TIMEOUT Aerospike::OPT_READ_TIMEOUT options * @see Aerospike::ERR_LUA UDF error status codes * @see Aerospike::predicateEquals() * @see Aerospike::predicateBetween() * @see Aerospike::predicateContains() * @see Aerospike::predicateRange() * @see Aerospike::predicateGeoContainsGeoJSONPoint() * @see Aerospike::predicateGeoWithinGeoJSONRegion() * @see Aerospike::predicateGeoContainsPoint() * @see Aerospike::predicateGeoWithinRadius() * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function aggregate($ns, $set, array $where, $module, $function, array $args, &$returned, array $options = []) {} // Admin methods /** * Create a secondary index on a bin of a specified set * * Create a secondary index of a given *index_type* on a namespace *ns*, *set* and *bin* with a specified *name* * ```php * $status = $client->addIndex("test", "user", "email", "user_email_idx", Aerospike::INDEX_TYPE_DEFAULT, Aerospike::INDEX_STRING); * if ($status == Aerospike::OK) { * echo "Index user_email_idx created on test.user.email\n"; * } else if ($status == Aerospike::ERR_INDEX_FOUND) { * echo "This index has already been created.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * * $client->addIndex("test", "user", "movies", "user_movie_titles_idx", Aerospike::INDEX_TYPE_MAPKEYS, Aerospike::INDEX_STRING); * $client->addIndex("test", "user", "movies", "user_movie_views_idx", Aerospike::INDEX_TYPE_MAPVALUES, Aerospike::INDEX_NUMERIC); * $client->addIndex("test", "user", "aliases", "user_aliases_idx", Aerospike::INDEX_TYPE_LIST, Aerospike::INDEX_STRING); * * $client->info("sindex", $res); * echo($res); * ``` * @param string $ns the namespace * @param string $set the set within the given namespace * @param string $bin the bin on which the secondary index is to be created * @param string $name the name of the index * @param int $indexType one of *Aerospike::INDEX\_TYPE\_\** * @param int $dataType one of *Aerospike::INDEX_NUMERIC* and *Aerospike::INDEX_STRING* * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * @see Aerospike::INDEX_TYPE_DEFAULT * @see Aerospike::INDEX_STRING * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function addIndex($ns, $set, $bin, $name, $indexType, $dataType, array $options = []) {} /** * Drop a secondary index * * ```php * $status = $client->dropIndex("test", "user_email_idx"); * if ($status == Aerospike::OK) { * echo "Index user_email_idx was dropped from namespace 'test'\n"; * } else if ($status == Aerospike::ERR_INDEX_NOT_FOUND) { * echo "No such index exists.\n"; * } else { * echo "[{$client->errorno()}] ".$client->error(); * } * ``` * @param string $ns the namespace * @param string $name the name of the index * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_WRITE_TIMEOUT * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function dropIndex($ns, $name, array $options = []) {} // Info Methods /** * Send an info request to a single cluster node * * Interface with the cluster's command and control functions. * A formatted request string is sent to a cluster node, and a formatted * response returned. * * A specific host can be optionally set, otherwise the request command is * sent to the host definded for client constructor. * * ```php * $client->info('bins/test', $response); * var_dump($response); * ``` * ``` * string(53) "bins/test num-bin-names=2,bin-names-quota=32768,demo,characters" * ``` * @link https://www.aerospike.com/docs/reference/info Info Command Reference * @param string $request a formatted info command * @param string &$response a formatted response from the server, filled by reference * @param null|array $host an array holding the cluster node connection information cluster * and manage its connections to them. ```[ 'addr' => $addr , 'port' => $port ]``` * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * @return int The status code of the operation. Compare to the Aerospike class status constants. */ public function info($request, &$response, $host = null, array $options = []) {} /** * Send an info request to a single cluster node * * Interface with the cluster's command and control functions. * A formatted request string is sent to a cluster node, and a formatted * response returned. * * A specific host can be optionally set, otherwise the request command is * sent to the host definded for client constructor. * * ```php * $response = $client->infoMany('build'); * var_dump($response); * ``` * ``` * array(3) { * ["BB936F106CA0568"]=> * string(6) "build 3.3.19" * ["AE712F245BB9876"]=> * string(6) "build 3.3.19" * ["DCBA9AA34EE12FA"]=> * string(6) "build 3.3.19" * } * ``` * @link https://www.aerospike.com/docs/reference/info Info Command Reference * @param string $request a formatted info command * @param null|array $host an array of _host_ arrays, each with ```[ 'addr' => $addr , 'port' => $port ]``` * @param array $options an optional array of policy options, whose keys include * * Aerospike::OPT_READ_TIMEOUT * @return array results in the format * ``` * Array: * NODE-ID => response string * ``` */ public function infoMany($request, $host = null, array $options = []) {} /** * Get the addresses of the cluster nodes * * ```php * $nodes = $client->getNodes(); * var_dump($nodes); * ``` * ``` * array(2) { * [0]=> * array(2) { * ["addr"]=> * string(15) "192.168.120.145" * ["port"]=> * string(4) "3000" * } * [1]=> * array(2) { * ["addr"]=> * string(15) "192.168.120.144" * ["port"]=> * string(4) "3000" * } * } * ``` * @return array results in the format * ``` * Array: * Array: * 'addr' => the IP address of the node * 'port' => the port of the node * ``` */ public function getNodes() {} // Logging Methods /** * Set the logging threshold of the Aerospike object * * @param int $log_level one of `Aerospike::LOG_LEVEL_*` values * * Aerospike::LOG_LEVEL_OFF * * Aerospike::LOG_LEVEL_ERROR * * Aerospike::LOG_LEVEL_WARN * * Aerospike::LOG_LEVEL_INFO * * Aerospike::LOG_LEVEL_DEBUG * * Aerospike::LOG_LEVEL_TRACE * @see Aerospike::LOG_LEVEL_OFF Aerospike::LOG_LEVEL_* constants */ public function setLogLevel($log_level) {} /** * Set a handler for log events * * Registers a callback method that will be triggered whenever a logging event above the declared log threshold occurs. * * ```php * $config = ["hosts" => [["addr"=>"localhost", "port"=>3000]], "shm"=>[]]; * $client = new Aerospike($config, true); * if (!$client->isConnected()) { * echo "Aerospike failed to connect[{$client->errorno()}]: {$client->error()}\n"; * exit(1); * } * $client->setLogLevel(Aerospike::LOG_LEVEL_DEBUG); * $client->setLogHandler(function ($level, $file, $function, $line) { * switch ($level) { * case Aerospike::LOG_LEVEL_ERROR: * $lvl_str = 'ERROR'; * break; * case Aerospike::LOG_LEVEL_WARN: * $lvl_str = 'WARN'; * break; * case Aerospike::LOG_LEVEL_INFO: * $lvl_str = 'INFO'; * break; * case Aerospike::LOG_LEVEL_DEBUG: * $lvl_str = 'DEBUG'; * break; * case Aerospike::LOG_LEVEL_TRACE: * $lvl_str = 'TRACE'; * break; * default: * $lvl_str = '???'; * } * error_log("[$lvl_str] in $function at $file:$line"); * }); * ``` * * @see Aerospike::LOG_LEVEL_OFF Aerospike::LOG_LEVEL_* constants * @param callable $log_handler a callback function with the signature * ```php * function log_handler ( int $level, string $file, string $function, int $line ) : void * ``` */ public function setLogHandler(callable $log_handler) {} // Unsupported Type Handler Methods /** * Set a serialization handler for unsupported types * * Registers a callback method that will be triggered whenever a write method handles a value whose type is unsupported. * This is a static method and the *serialize_cb* handler is global across all instances of the Aerospike class. * * ```php * Aerospike::setSerializer(function ($val) { * return gzcompress(json_encode($val)); * }); * ``` * * @link https://github.com/aerospike/aerospike-client-php/tree/master/doc#handling-unsupported-types Handling Unsupported Types * @param callable $serialize_cb a callback invoked for each value of an unsupported type, when writing to the cluster. The function must follow the signature * ```php * function aerospike_serialize ( mixed $value ) : string * ``` * @see Aerospike::OPT_SERIALIZER Aerospike::OPT_SERIALIZER options */ public function setSerializer(callable $serialize_cb) {} /** * Set a deserialization handler for unsupported types * * Registers a callback method that will be triggered whenever a read method handles a value whose type is unsupported. * This is a static method and the *unserialize_cb* handler is global across all instances of the Aerospike class. * * ```php * Aerospike::setDeserializer(function ($val) { * return json_decode(gzuncompress($val)); * }); * ``` * * @link https://github.com/aerospike/aerospike-client-php/tree/master/doc#handling-unsupported-types Handling Unsupported Types * @param callable $unserialize_cb a callback invoked for each value of an unsupported type, when reading from the cluster. The function must follow the signature * ```php * // $value is binary data of type AS_BYTES_BLOB * function aerospike_deserialize ( string $value ) * ``` * @see Aerospike::OPT_SERIALIZER Aerospike::OPT_SERIALIZER options */ public function setDeserializer(callable $unserialize_cb) {} /* * Options can be assigned values that modify default behavior * Used by the constructor, read, write, scan, query, apply, and info * operations. */ /* Key used to specify an array of read policy defaults used in the constructor. See https://github.com/aerospike/aerospike-client-php/blob/master/doc/policies.md */ public const OPT_READ_DEFAULT_POL = "OPT_READ_DEFAULT_POL"; /* Key used to specify an array of write policy defaults used in the constructor. See https://github.com/aerospike/aerospike-client-php/blob/master/doc/policies.md */ public const OPT_WRITE_DEFAULT_POL = "OPT_WRITE_DEFAULT_POL"; /* Key used to specify an array of remove policy defaults used in the constructor. See https://github.com/aerospike/aerospike-client-php/blob/master/doc/policies.md */ public const OPT_REMOVE_DEFAULT_POL = "OPT_REMOVE_DEFAULT_POL"; /* Key used to specify an array of batch policy defaults used in the constructor. See https://github.com/aerospike/aerospike-client-php/blob/master/doc/policies.md */ public const OPT_BATCH_DEFAULT_POL = "OPT_BATCH_DEFAULT_POL"; /* Key used to specify an array of operate policy defaults used in the constructor. See https://github.com/aerospike/aerospike-client-php/blob/master/doc/policies.md */ public const OPT_OPERATE_DEFAULT_POL = "OPT_OPERATE_DEFAULT_POL"; /* Key used to specify an array of query policy defaults used in the constructor. See https://github.com/aerospike/aerospike-client-php/blob/master/doc/policies.md */ public const OPT_QUERY_DEFAULT_POL = "OPT_QUERY_DEFAULT_POL"; /* Key used to specify an array of scan policy defaults used in the constructor. See https://github.com/aerospike/aerospike-client-php/blob/master/doc/policies.md */ public const OPT_SCAN_DEFAULT_POL = "OPT_SCAN_DEFAULT_POL"; /* Key used to specify an array of apply policy defaults used in the constructor. See https://github.com/aerospike/aerospike-client-php/blob/master/doc/policies.md */ public const OPT_APPLY_DEFAULT_POL = "OPT_APPLY_DEFAULT_POL"; /* Key used in the options argument of the constructor used to point to an array of TLS configuration parameters. Use of TLS requires an enterprise version of the Aerospike Server. */ public const OPT_TLS_CONFIG = "OPT_TLS_CONFIG"; /* Key used in the OPT_TLS boolean Whether or not to enable TLS. */ public const OPT_TLS_ENABLE = "OPT_TLS_ENABLE"; /* Key used to specify a string path to a trusted CA certificate file. By default TLS will use system standard trusted CA certificates */ public const OPT_OPT_TLS_CAFILE = "OPT_OPT_TLS_CAFILE"; /* Key used to specify a Path to a directory of trusted certificates. See the OpenSSL SSL_CTX_load_verify_locations manual page for more information about the format of the directory. */ public const OPT_TLS_CAPATH = "OPT_TLS_CAPATH"; /*Key used to specify a string representation of allowed protocols. Specifies enabled protocols. This format is the same as Apache's SSLProtocol documented at https://httpd.apache.org/docs/current/mod/mod_ssl.html#sslprotocol . If not specified the client will use "-all +TLSv1.2". */ public const OPT_TLS_PROTOCOLS = "OPT_TLS_PROTOCOLS"; /* Key used to specify a string. Specifies enabled cipher suites. The format is the same as OpenSSL's Cipher List Format documented at https://www.openssl.org/docs/manmaster/apps/ciphers.html .If not specified the OpenSSL default cipher suite described in the ciphers documentation will be used. If you are not sure what cipher suite to select this option is best left unspecified */ public const OPT_TLS_CIPHER_SUITE = "OPT_TLS_CIPHER_SUITE"; /* Key used to specify a boolean. Enable CRL checking for the certificate chain leaf certificate. An error occurs if a suitable CRL cannot be found. By default CRL checking is disabled. */ public const OPT_TLS_CRL_CHECK = "OPT_TLS_CRL_CHECK"; /* Key used to specify a bolean. Enable CRL checking for the entire certificate chain. An error occurs if a suitable CRL cannot be found. By default CRL checking is disabled. */ public const OPT_TLS_CRL_CHECK_ALL = "OPT_TLS_CRL_CHECK_ALL"; /* Key used to specify a path to a certificate blacklist file. The file should contain one line for each blacklisted certificate. Each line starts with the certificate serial number expressed in hex. Each entry may optionally specify the issuer name of the certificate (serial numbers are only required to be unique per issuer). Example records: 867EC87482B2 /C=US/ST=CA/O=Acme/OU=Engineering/CN=Test Chain CA E2D4B0E570F9EF8E885C065899886461 */ public const OPT_TLS_CERT_BLACKLIST = "OPT_TLS_CERT_BLACKLIST"; /* Boolean: Log session information for each connection. */ public const OPT_TLS_LOG_SESSION_INFO = "OPT_TLS_LOG_SESSION_INFO"; /* Path to the client's key for mutual authentication. By default mutual authentication is disabled. */ public const OPT_TLS_KEYFILE = "OPT_TLS_KEYFILE"; /* Path to the client's certificate chain file for mutual authentication. By default mutual authentication is disabled. */ public const OPT_TLS_CERTFILE = "OPT_TLS_CERTFILE"; /** * Defines the length of time (in milliseconds) the client waits on establishing a connection. * value in milliseconds (default: 1000) */ public const OPT_CONNECT_TIMEOUT = "OPT_CONNECT_TIMEOUT"; /** * Defines the length of time (in milliseconds) the client waits on a read * operation. * value in milliseconds (default: 1000) */ public const OPT_READ_TIMEOUT = "OPT_READ_TIMEOUT"; /** * Defines the length of time (in milliseconds) the client waits on a write * operation. * value in milliseconds (default: 1000) */ public const OPT_WRITE_TIMEOUT = "OPT_WRITE_TIMEOUT"; /** * Sets the TTL of the record along with a write operation. * * * TTL > 0 sets the number of seconds into the future in which to expire the record. * * TTL = 0 uses the default TTL defined for the namespace. * * TTL = -1 means the record should never expire. * * TTL = -2 means the record's TTL should not be modified. * value in seconds, or the special values 0, -1 or -2 (default: 0) */ public const OPT_TTL = "OPT_TTL"; /** * Accepts one of the POLICY_KEY_* values. * * {@link https://www.aerospike.com/docs/client/php/usage/kvs/record-structure.html Records} * are uniquely identified by their digest, and can optionally store the value of their primary key * (their unique ID in the application). * Key storage policy option (digest-only or send key) */ public const OPT_POLICY_KEY = "OPT_POLICY_KEY"; /** * Do not store the primary key with the record (default) * digest only */ public const POLICY_KEY_DIGEST = 0; /** * Store the primary key with the record * store the primary key with the record */ public const POLICY_KEY_SEND = 1; /** * Accepts one of the POLICY_EXISTS_* values. * * By default writes will try to create a record or update its bins, which * is a behavior similar to how arrays work in PHP. Setting a write with a * different POLICY\_EXISTS\_* value can simulate a more DML-like behavior, * similar to an RDBMS. * existence policy option */ public const OPT_POLICY_EXISTS = "OPT_POLICY_EXISTS"; /** * "CREATE_OR_UPDATE" behavior. Create the record if it does not exist, * or update its bins if it does. (default) * create or update behavior */ public const POLICY_EXISTS_IGNORE = 0; /** * Create a record ONLY if it DOES NOT exist. * create only behavior (fail otherwise) */ public const POLICY_EXISTS_CREATE = 1; /** * Update a record ONLY if it exists. * update only behavior (fail otherwise) */ public const POLICY_EXISTS_UPDATE = 2; /** * Replace a record ONLY if it exists. * replace only behavior (fail otherwise) */ public const POLICY_EXISTS_REPLACE = 3; /** * Create the record if it does not exist, or replace its bins if it does. * create or replace behavior */ public const POLICY_EXISTS_CREATE_OR_REPLACE = 4; /** * Set to an array( Aerospike::POLICY_GEN_* [, (int) $gen_value ] ) * * Specifies the behavior of write opertions with regards to the record's * generation. Used to implement a check-and-set (CAS) pattern. * generation policy option */ public const OPT_POLICY_GEN = "OPT_POLICY_GEN"; /** * Do not consider generation for the write operation. * write a record, regardless of generation (default) */ public const POLICY_GEN_IGNORE = 0; /** * Only write if the record was not modified since a given generation value. * write a record, ONLY if generations are equal */ public const POLICY_GEN_EQ = 1; /** * write a record, ONLY if local generation is greater-than remote generation */ public const POLICY_GEN_GT = 2; /** * Set to one of the SERIALIZER_* values. * * Supported types, such as string, integer, and array get directly cast to * the matching Aerospike types, such as as_string, as_integer, and as_map. * Unsupported types, such as boolean, need a serializer to handle them. * determines a handler for unsupported data types */ public const OPT_SERIALIZER = "OPT_SERIALIZER"; /** * Throw an exception instead of serializing unsupported types. * throw an error when serialization is required */ public const SERIALIZER_NONE = 0; /** * Use the built-in PHP serializer for any unsupported types. * use the PHP serialize/unserialize functions (default) */ public const SERIALIZER_PHP = 1; /** * Use a user-defined serializer for any unsupported types. * use a pair of functions written in PHP for serialization */ public const SERIALIZER_USER = 2; /** * Accepts one of the POLICY_COMMIT_LEVEL_* values. * * One of the {@link https://www.aerospike.com/docs/architecture/consistency.html per-transaction consistency levels}. * Specifies the number of replicas required to be successfully committed * before returning success in a write operation to provide the desired * consistency level. * commit level policy option */ public const OPT_POLICY_COMMIT_LEVEL = "OPT_POLICY_COMMIT_LEVEL"; /** * Return succcess only after successfully committing all replicas. * write to the master and all replicas (default) */ public const POLICY_COMMIT_LEVEL_ALL = 0; /** * Return succcess after successfully committing the master replica. * master will asynchronously write to replicas */ public const POLICY_COMMIT_LEVEL_MASTER = 1; /** * Accepts one of the POLICY_REPLICA_* values. * * One of the {@link https://www.aerospike.com/docs/architecture/consistency.html per-transaction consistency levels}. * Specifies which partition replica to read from. * replica policy option */ public const OPT_POLICY_REPLICA = "OPT_POLICY_REPLICA"; /** * Read from the partition master replica node. * read from master */ public const POLICY_REPLICA_MASTER = 0; /** * Read from an unspecified replica node. * read from any replica node */ public const POLICY_REPLICA_ANY = 1; /** * Always try node containing master partition first. If connection fails and * `retry_on_timeout` is true, try node containing replica partition. * Currently restricted to master and one replica. (default) * attempt to read from master first, then try the node containing replica partition if connection failed. (default) */ public const POLICY_REPLICA_SEQUENCE = 2; /** * Try node on the same rack as the client first. If there are no nodes on the * same rack, use POLICY_REPLICA_SEQUENCE instead. * * "rack_aware" must be set to true in the client constructor, and "rack_id" must match the server rack configuration * to enable this functionality. * attemp to read from master first, then try the node containing replica partition if connection failed. (default) */ public const POLICY_REPLICA_PREFER_RACK = 3; /** * Accepts one of the POLICY_READ_MODE_AP_* values. * * One of the {@link https://www.aerospike.com/docs/architecture/consistency.html per-transaction consistency levels}. * Specifies the number of replicas to be consulted in a read operation to * provide the desired consistency level in availability mode. * policy read option for availability namespaces */ public const OPT_POLICY_READ_MODE_AP = "OPT_POLICY_READ_MODE_AP"; /** * Involve a single replica in the operation. * (default) */ public const POLICY_READ_MODE_AP_ONE = 0; /** * Involve all replicas in the operation. * */ public const AS_POLICY_READ_MODE_AP_ALL = 1; /** * Accepts one of the POLICY_READ_MODE_SC_* values. * * One of the {@link https://www.aerospike.com/docs/architecture/consistency.html per-transaction consistency levels}. * Specifies the number of replicas to be consulted in a read operation to * provide the desired consistency level. * policy read option for consistency namespaces */ public const OPT_POLICY_READ_MODE_SC = "OPT_POLICY_READ_MODE_SC"; /** * Always read from master. Record versions are local to session. * (default) */ public const POLICY_READ_MODE_SC_SESSION = 0; /** * Always read from master. Record versions are global and thus serialized. * */ public const POLICY_READ_MODE_SC_LINEARIZE = 1; /** * Read from master or fully migrated replica. Record versions may not always increase. * */ public const POLICY_READ_MODE_SC_ALLOW_REPLICA = 2; /** * Read from master or fully migrated replica. Unavailable partitions are allowed. Record versions may not always increase. * */ public const POLICY_READ_MODE_SC_ALLOW_UNAVAILABLE = 3; /* * Should raw bytes representing a list or map be deserialized to an array. * Set to false for backup programs that just need access to raw bytes. * Default: true */ public const OPT_DESERIALIZE = "deserialize"; /** * Milliseconds to sleep between retries. Enter zero to skip sleep. * const OPT_SLEEP_BETWEEN_RETRIES */ public const OPT_SLEEP_BETWEEN_RETRIES = "sleep_between_retries"; /** * Maximum number of retries before aborting the current transaction. * The initial attempt is not counted as a retry. * If OPT_MAX_RETRIES is exceeded, the transaction will return error ERR_TIMEOUT. * WARNING: Database writes that are not idempotent (such as "add") * should not be retried because the write operation may be performed * multiple times if the client timed out previous transaction attempts. * It's important to use a distinct write policy for non-idempotent * writes which sets OPT_MAX_RETRIES = 0; **/ public const OPT_MAX_RETRIES = "OPT_MAX_RETRIES"; /** * Total transaction timeout in milliseconds. * The OPT_TOTAL_TIMEOUT is tracked on the client and sent to the server along with * the transaction in the wire protocol. The client will most likely timeout * first, but the server also has the capability to timeout the transaction. * If OPT_TOTAL_TIMEOUT is not zero and OPT_TOTAL_TIMEOUT is reached before the transaction * completes, the transaction will return error ERR_TIMEOUT. * If OPT_TOTAL_TIMEOUT is zero, there will be no total time limit. */ public const OPT_TOTAL_TIMEOUT = "OPT_TOTAL_TIMEOUT"; /** * Socket idle timeout in milliseconds when processing a database command. * If OPT_SOCKET_TIMEOUT is not zero and the socket has been idle for at least OPT_SOCKET_TIMEOUT, * both OPT_MAX_RETRIES and OPT_TOTAL_TIMEOUT are checked. If OPT_MAX_RETRIES and OPT_TOTAL_TIMEOUT are not * exceeded, the transaction is retried. * If both OPT_SOCKET_TIMEOUT and OPT_TOTAL_TIMEOUT are non-zero and OPT_SOCKET_TIMEOUT > OPT_TOTAL_TIMEOUT, * then OPT_SOCKET_TIMEOUT will be set to OPT_TOTAL_TIMEOUT. If OPT_SOCKET_TIMEOUT is zero, there will be * no socket idle limit. */ public const OPT_SOCKET_TIMEOUT = "OPT_SOCKET_TIMEOUT"; /** * Determine if batch commands to each server are run in parallel threads. */ public const OPT_BATCH_CONCURRENT = "OPT_BATCH_CONCURRENT"; /** * Allow batch to be processed immediately in the server's receiving thread when the server * deems it to be appropriate. If false, the batch will always be processed in separate * transaction threads. This field is only relevant for the new batch index protocol. * * For batch exists or batch reads of smaller sized records (<= 1K per record), inline * processing will be significantly faster on "in memory" namespaces. The server disables * inline processing on disk based namespaces regardless of this policy field. * * Inline processing can introduce the possibility of unfairness because the server * can process the entire batch before moving onto the next command. * Default: true */ public const OPT_ALLOW_INLINE = "OPT_ALLOW_INLINE"; /** * Send set name field to server for every key in the batch for batch index protocol. * This is only necessary when authentication is enabled and security roles are defined * on a per set basis. * Default: false */ public const OPT_SEND_SET_NAME = "OPT_SEND_SET_NAME"; /** * Abort the scan if the cluster is not in a stable state. Default false */ public const OPT_FAIL_ON_CLUSTER_CHANGE = "OPT_FAIL_ON_CLUSTER_CHANGE"; /** * Accepts one of the SCAN_PRIORITY_* values. * * The priority of the scan */ public const OPT_SCAN_PRIORITY = "OPT_SCAN_PRIORITY"; /** * The cluster will auto-adjust the priority of the scan. * auto-adjust the scan priority (default) */ public const SCAN_PRIORITY_AUTO = "SCAN_PRIORITY_AUTO"; /** * Set the scan as having low priority. * low priority scan */ public const SCAN_PRIORITY_LOW = "SCAN_PRIORITY_LOW"; /** * Set the scan as having medium priority. * medium priority scan */ public const SCAN_PRIORITY_MEDIUM = "SCAN_PRIORITY_MEDIUM"; /** * Set the scan as having high priority. * high priority scan */ public const SCAN_PRIORITY_HIGH = "SCAN_PRIORITY_HIGH"; /** * Do not return the bins of the records matched by the scan. * * boolean value (default: false) */ public const OPT_SCAN_NOBINS = "OPT_SCAN_NOBINS"; /** * Set the scan to run over a given percentage of the possible records. * * integer value from 1-100 (default: 100) */ public const OPT_SCAN_PERCENTAGE = "OPT_SCAN_PERCENTAGE"; /** * Scan all the nodes in the cluster concurrently. * * boolean value (default: false) */ public const OPT_SCAN_CONCURRENTLY = "OPT_SCAN_CONCURRENTLY"; /** * Do not return the bins of the records matched by the query. * * boolean value (default: false) */ public const OPT_QUERY_NOBINS = "OPT_QUERY_NOBINS"; /** * Revert to the older batch-direct protocol, instead of batch-index. * * boolean value (default: false) */ public const USE_BATCH_DIRECT = "USE_BATCH_DIRECT"; /** * Set to true to enable durable delete for the operation. * Durable deletes are an Enterprise Edition feature * * boolean value (default: false) */ public const OPT_POLICY_DURABLE_DELETE = "OPT_POLICY_DURABLE_DELETE"; /** * Map policy declaring the ordering of an Aerospike map type * * @see Aerospike::AS_MAP_UNORDERED * @see Aerospike::AS_MAP_KEY_ORDERED * @see Aerospike::AS_MAP_KEY_VALUE_ORDERED * */ public const OPT_MAP_ORDER = "OPT_MAP_ORDER"; /** * The Aerospike map is unordered * (default) */ public const AS_MAP_UNORDERED = "AS_MAP_UNORDERED"; /** * The Aerospike map is ordered by key * */ public const AS_MAP_KEY_ORDERED = "AS_MAP_KEY_ORDERED"; /** * The Aerospike map is ordered by key and value * */ public const AS_MAP_KEY_VALUE_ORDERED = "AS_MAP_KEY_VALUE_ORDERED"; /** * Map policy declaring the behavior of map write operations * @see Aerospike::AS_MAP_UPDATE * @see Aerospike::AS_MAP_UPDATE_ONLY * @see Aerospike::AS_MAP_CREATE_ONLY * */ public const OPT_MAP_WRITE_MODE = "OPT_MAP_WRITE_MODE"; /** * (default) */ public const AS_MAP_UPDATE = "AS_MAP_UPDATE"; public const AS_MAP_UPDATE_ONLY = "AS_MAP_UPDATE_ONLY"; public const AS_MAP_CREATE_ONLY = "AS_MAP_CREATE_ONLY"; /** * Map policy flags declaring the behavior of map write operations * @see Aerospike::AS_MAP_WRITE_DEFAULT * @see Aerospike::AS_MAP_WRITE_CREATE_ONLY * @see Aerospike::AS_MAP_WRITE_UPDATE_ONLY * @see Aerospike::AS_MAP_WRITE_NO_FAIL * @see Aerospike::AS_MAP_WRITE_PARTIAL * */ public const OPT_MAP_WRITE_FLAGS = "OPT_MAP_WRITE_FLAGS"; /** * Default. Allow create or update. * (default) */ public const AS_MAP_WRITE_DEFAULT = "AS_MAP_WRITE_DEFAULT"; /** * If the key already exists, the item will be denied. If the key does not exist, a new item will be created. * */ public const AS_MAP_WRITE_CREATE_ONLY = "AS_MAP_WRITE_CREATE_ONLY"; /** * If the key already exists, the item will be overwritten. If the key does not exist, the item will be denied. * */ public const AS_MAP_WRITE_UPDATE_ONLY = "AS_MAP_WRITE_UPDATE_ONLY"; /** * Do not raise error if a map item is denied due to write flag constraints (always succeed). * */ public const AS_MAP_WRITE_NO_FAIL = "AS_MAP_WRITE_NO_FAIL"; /** * Allow other valid map items to be committed if a map item is denied due to write flag constraints. * */ public const AS_MAP_WRITE_PARTIAL = "AS_MAP_WRITE_PARTIAL"; /** * Do not return a result for the map operation (get and remove operations) * @link https://www.aerospike.com/docs/guide/cdt-map.html#map-apis Map Result Types * */ public const MAP_RETURN_NONE = "AS_MAP_RETURN_NONE"; /** * Return in key index order * @link https://www.aerospike.com/docs/guide/cdt-map.html#map-apis Map Result Types * */ public const MAP_RETURN_INDEX = "AS_MAP_RETURN_INDEX"; /** * Return in reverse key order * @link https://www.aerospike.com/docs/guide/cdt-map.html#map-apis Map Result Types * */ public const MAP_RETURN_REVERSE_INDEX = "AS_MAP_RETURN_REVERSE_INDEX"; /** * Return in value order * @link https://www.aerospike.com/docs/guide/cdt-map.html#map-apis Map Result Types * */ public const MAP_RETURN_RANK = "AS_MAP_RETURN_RANK"; /** * Return in reverse value order * @link https://www.aerospike.com/docs/guide/cdt-map.html#map-apis Map Result Types * */ public const MAP_RETURN_REVERSE_RANK = "AS_MAP_RETURN_REVERSE_RANK"; /** * Return count of items selected * @link https://www.aerospike.com/docs/guide/cdt-map.html#map-apis Map Result Types * */ public const MAP_RETURN_COUNT = "AS_MAP_RETURN_COUNT"; /** * Return key for single key read and key list for range read * @link https://www.aerospike.com/docs/guide/cdt-map.html#map-apis Map Result Types * */ public const MAP_RETURN_KEY = "AS_MAP_RETURN_KEY"; /** * Return value for single key read and value list for range read * @link https://www.aerospike.com/docs/guide/cdt-map.html#map-apis Map Result Types * */ public const MAP_RETURN_VALUE = "AS_MAP_RETURN_VALUE"; /** * Return key/value items * Will be of the form ['key1', 'val1', 'key2', 'val2', 'key3', 'val3] * @link https://www.aerospike.com/docs/guide/cdt-map.html#map-apis Map Result Types * */ public const MAP_RETURN_KEY_VALUE = "AS_MAP_RETURN_KEY_VALUE"; public const LOG_LEVEL_OFF = "LOG_LEVEL_OFF"; public const LOG_LEVEL_ERROR = "LOG_LEVEL_ERROR"; public const LOG_LEVEL_WARN = "LOG_LEVEL_WARN"; public const LOG_LEVEL_INFO = "LOG_LEVEL_INFO"; public const LOG_LEVEL_DEBUG = "LOG_LEVEL_DEBUG"; public const LOG_LEVEL_TRACE = "LOG_LEVEL_TRACE"; /** * Aerospike Status Codes * * Each Aerospike API method invocation returns a status code from the * server. * * The status codes map to the * {@link https://github.com/aerospike/aerospike-client-c/blob/master/src/include/aerospike/as_status.h status codes} * of the C client. * * Success */ public const OK = "AEROSPIKE_OK"; // -10 - -1 - Client Errors /** * Synchronous connection error * */ public const ERR_CONNECTION = "AEROSPIKE_ERR_CONNECTION"; /** * Node invalid or could not be found * */ public const ERR_TLS_ERROR = "AEROSPIKE_ERR_TLS"; /** * Node invalid or could not be found * */ public const ERR_INVALID_NODE = "AEROSPIKE_ERR_INVALID_NODE"; /** * Client hit the max asynchronous connections * */ public const ERR_NO_MORE_CONNECTIONS = "AEROSPIKE_ERR_NO_MORE_CONNECTIONS"; /** * Asynchronous connection error * */ public const ERR_ASYNC_CONNECTION = "AEROSPIKE_ERR_ASYNC_CONNECTION"; /** * Query or scan was aborted in user's callback * */ public const ERR_CLIENT_ABORT = "AEROSPIKE_ERR_CLIENT_ABORT"; /** * Host name could not be found in DNS lookup * */ public const ERR_INVALID_HOST = "AEROSPIKE_ERR_INVALID_HOST"; /** * Invalid client API parameter * */ public const ERR_PARAM = "AEROSPIKE_ERR_PARAM"; /** * Generic client API usage error * */ public const ERR_CLIENT = "AEROSPIKE_ERR_CLIENT"; // 1-49 - Basic Server Errors /** * Generic error returned by server * */ public const ERR_SERVER = "AEROSPIKE_ERR_SERVER"; /** * No record is found with the specified namespace/set/key combination. * May be returned by a read, or a write with OPT_POLICY_EXISTS * set to POLICY_EXISTS_UPDATE * */ public const ERR_RECORD_NOT_FOUND = "AEROSPIKE_ERR_RECORD_NOT_FOUND"; /** * Generation of record does not satisfy the OPT_POLICY_GEN write policy * */ public const ERR_RECORD_GENERATION = "AEROSPIKE_ERR_RECORD_GENERATION"; /** * Illegal parameter sent from client. Check client parameters and verify * each is supported by current server version * */ public const ERR_REQUEST_INVALID = "AEROSPIKE_ERR_REQUEST_INVALID"; /** * The operation cannot be applied to the current bin on the server * */ public const ERR_OP_NOT_APPLICABLE = "AEROSPIKE_ERR_OP_NOT_APPLICABLE"; /** * Record already exists. May be returned by a write with the * OPT_POLICY_EXISTS write policy set to POLICY_EXISTS_CREATE * */ public const ERR_RECORD_EXISTS = "AEROSPIKE_ERR_RECORD_EXISTS"; /** * (future) For future write requests which specify 'BIN_CREATE_ONLY', * request failed because one of the bins in the write already exists * */ public const ERR_BIN_EXISTS = "AEROSPIKE_ERR_BIN_EXISTS"; /** * On scan requests, the scan terminates because cluster is in migration. * Only occur when client requested 'fail_on_cluster_change' policy on scan * */ public const ERR_CLUSTER_CHANGE = "AEROSPIKE_ERR_CLUSTER_CHANGE"; /** * Occurs when stop_writes is true (either memory - stop-writes-pct - * or disk - min-avail-pct). Can also occur if memory cannot be allocated * anymore (but stop_writes should in general hit first). Namespace will no * longer be able to accept write requests * */ public const ERR_SERVER_FULL = "AEROSPIKE_ERR_SERVER_FULL"; /** * Request was not completed during the allocated time, thus aborted * */ public const ERR_TIMEOUT = "AEROSPIKE_ERR_TIMEOUT"; /** * Write request is rejected because XDR is not running. * Only occur when XDR configuration xdr-stop-writes-noxdr is on * */ #[Deprecated("Will be reused as ERR_ALWAYS_FORBIDDEN")] public const ERR_ALWAYS_FORBIDDEN = "AEROSPIKE_ERR_ALWAYS_FORBIDDEN"; /** * Server is not accepting requests. * Occur during single node on a quick restart to join existing cluster * */ public const ERR_CLUSTER = "AEROSPIKE_ERR_CLUSTER"; /** * Operation is not allowed due to data type or namespace configuration incompatibility. * For example, append to a float data type, or insert a non-integer when * namespace is configured as data-in-index * */ public const ERR_BIN_INCOMPATIBLE_TYPE = "AEROSPIKE_ERR_BIN_INCOMPATIBLE_TYPE"; /** * Attempt to write a record whose size is bigger than the configured write-block-size * */ public const ERR_RECORD_TOO_BIG = "AEROSPIKE_ERR_RECORD_TOO_BIG"; /** * Too many concurrent operations (> transaction-pending-limit) on the same record. * A "hot-key" situation * */ public const ERR_RECORD_BUSY = "AEROSPIKE_ERR_RECORD_BUSY"; /** * Scan aborted by user on server * */ public const ERR_SCAN_ABORTED = "AEROSPIKE_ERR_SCAN_ABORTED"; /** * The client is trying to use a feature that does not yet exist in the * version of the server node it is talking to * */ public const ERR_UNSUPPORTED_FEATURE = "AEROSPIKE_ERR_UNSUPPORTED_FEATURE"; /** * (future) For future write requests which specify 'REPLACE_ONLY', * request fail because specified bin name does not exist in record * */ public const ERR_BIN_NOT_FOUND = "AEROSPIKE_ERR_BIN_NOT_FOUND"; /** * Write request is rejected because one or more storage devices of the node are not keeping up * */ public const ERR_DEVICE_OVERLOAD = "AEROSPIKE_ERR_DEVICE_OVERLOAD"; /** * For update request on records which has key stored, the incoming key does not match * the existing stored key. This indicates a RIPEMD160 key collision has happend (report as a bug) * */ public const ERR_RECORD_KEY_MISMATCH = "AEROSPIKE_ERR_RECORD_KEY_MISMATCH"; /** * Namespace in request not found on server * */ public const ERR_NAMESPACE_NOT_FOUND = "AEROSPIKE_ERR_NAMESPACE_NOT_FOUND"; /** * Bin name length greater than 14 characters, or maximum number of unique bin names are exceeded * */ public const ERR_BIN_NAME = "AEROSPIKE_ERR_BIN_NAME"; /** * Operation not allowed at this time. * For writes, the set is in the middle of being deleted, or the set's stop-write is reached; * For scan, too many concurrent scan jobs (> scan-max-active); * For XDR-ed cluster, fail writes which are not replicated from another datacenter * */ public const ERR_FAIL_FORBIDDEN = "AEROSPIKE_ERR_FORBIDDEN"; /** * Target was not found for operations that requires a target to be found * */ public const ERR_FAIL_ELEMENT_NOT_FOUND = "AEROSPIKE_ERR_FAIL_NOT_FOUND"; /** * Target already exist for operations that requires the target to not exist * */ public const ERR_FAIL_ELEMENT_EXISTS = "AEROSPIKE_ERR_FAIL_ELEMENT_EXISTS"; // 50-89 - Security Specific Errors /** * Security functionality not supported by connected server * */ public const ERR_SECURITY_NOT_SUPPORTED = "AEROSPIKE_ERR_SECURITY_NOT_SUPPORTED"; /** * Security functionality not enabled by connected server * */ public const ERR_SECURITY_NOT_ENABLED = "AEROSPIKE_ERR_SECURITY_NOT_ENABLED"; /** * Security scheme not supported * */ public const ERR_SECURITY_SCHEME_NOT_SUPPORTED = "AEROSPIKE_ERR_SECURITY_SCHEME_NOT_SUPPORTED"; /** * Unrecognized security command * */ public const ERR_INVALID_COMMAND = "AEROSPIKE_ERR_INVALID_COMMAND"; /** * Field is not valid * */ public const ERR_INVALID_FIELD = "AEROSPIKE_ERR_INVALID_FIELD"; /** * Security protocol not followed * */ public const ERR_ILLEGAL_STATE = "AEROSPIKE_ERR_ILLEGAL_STATE"; /** * No user supplied or unknown user * */ public const ERR_INVALID_USER = "AEROSPIKE_ERR_INVALID_USER"; /** * User already exists * */ public const ERR_USER_ALREADY_EXISTS = "AEROSPIKE_ERR_USER_ALREADY_EXISTS"; /** * Password does not exists or not recognized * */ public const ERR_INVALID_PASSWORD = "AEROSPIKE_ERR_INVALID_PASSWORD"; /** * Expired password * */ public const ERR_EXPIRED_PASSWORD = "AEROSPIKE_ERR_EXPIRED_PASSWORD"; /** * Forbidden password (e.g. recently used) * */ public const ERR_FORBIDDEN_PASSWORD = "AEROSPIKE_ERR_FORBIDDEN_PASSWORD"; /** * Invalid credential or credential does not exist * */ public const ERR_INVALID_CREDENTIAL = "AEROSPIKE_ERR_INVALID_CREDENTIAL"; /** * No role(s) or unknown role(s) * */ public const ERR_INVALID_ROLE = "AEROSPIKE_ERR_INVALID_ROLE"; /** * Privilege is invalid * */ public const ERR_INVALID_PRIVILEGE = "AEROSPIKE_ERR_INVALID_PRIVILEGE"; /** * User must be authenticated before performing database operations * */ public const ERR_NOT_AUTHENTICATED = "AEROSPIKE_ERR_NOT_AUTHENTICATED"; /** * User does not possess the required role to perform the database operation * */ public const ERR_ROLE_VIOLATION = "AEROSPIKE_ERR_ROLE_VIOLATION"; /** * Role already exists * */ public const ERR_ROLE_ALREADY_EXISTS = "AEROSPIKE_ERR_ROLE_ALREADY_EXISTS"; // 100-109 - UDF Specific Errors // /** * A user defined function failed to execute * */ public const ERR_UDF = "AEROSPIKE_ERR_UDF"; /** * The UDF does not exist * */ public const ERR_UDF_NOT_FOUND = "AEROSPIKE_ERR_UDF_NOT_FOUND"; /** * The LUA file does not exist * */ public const ERR_LUA_FILE_NOT_FOUND = "AEROSPIKE_ERR_LUA_FILE_NOT_FOUND"; // 150-159 - Batch Specific Errors /** * Batch functionality has been disabled by configuring the batch-index-thread=0 * */ public const ERR_BATCH_DISABLED = "AEROSPIKE_ERR_BATCH_DISABLED"; /** * Batch max requests has been exceeded * */ public const ERR_BATCH_MAX_REQUESTS_EXCEEDED = "AEROSPIKE_ERR_BATCH_MAX_REQUESTS_EXCEEDED"; /** * All batch queues are full * */ public const ERR_BATCH_QUEUES_FULL = "AEROSPIKE_ERR_BATCH_QUEUES_FULL"; // 160-169 - Geo Specific Errors /** * GeoJSON is malformed or not supported * */ public const ERR_GEO_INVALID_GEOJSON = "AEROSPIKE_ERR_GEO_INVALID_GEOJSON"; // 200-219 - Secondary Index Specific Errors /** * Secondary index already exists * * Accepts one of the POLICY_KEY_* values. * * {@link https://www.aerospike.com/docs/client/php/usage/kvs/record-structure.html Records} * are uniquely identified by their digest, and can optionally store the value of their primary key * (their unique ID in the application). * Key storage policy option (digest-only or send key) */ public const ERR_INDEX_FOUND = "AEROSPIKE_ERR_INDEX_FOUND"; /** * Secondary index does not exist * */ public const ERR_INDEX_NOT_FOUND = "AEROSPIKE_ERR_INDEX_NOT_FOUND"; /** * Secondary index memory space exceeded * */ public const ERR_INDEX_OOM = "AEROSPIKE_ERR_INDEX_OOM"; /** * Secondary index not available for query. Occurs when indexing creation has not finished * */ public const ERR_INDEX_NOT_READABLE = "AEROSPIKE_ERR_INDEX_NOT_READABLE"; /** * Generic secondary index error * */ public const ERR_INDEX = "AEROSPIKE_ERR_INDEX"; /** * Index name maximun length exceeded * */ public const ERR_INDEX_NAME_MAXLEN = "AEROSPIKE_ERR_INDEX_NAME_MAXLEN"; /** * Maximum number of indicies exceeded * */ public const ERR_INDEX_MAXCOUNT = "AEROSPIKE_ERR_INDEX_MAXCOUNT"; /** * Secondary index query aborted * */ public const ERR_QUERY_ABORTED = "AEROSPIKE_ERR_QUERY_ABORTED"; /** * Secondary index queue full * */ public const ERR_QUERY_QUEUE_FULL = "AEROSPIKE_ERR_QUERY_QUEUE_FULL"; /** * Secondary index query timed out on server * */ public const ERR_QUERY_TIMEOUT = "AEROSPIKE_ERR_QUERY_TIMEOUT"; /** * Generic query error * */ public const ERR_QUERY = "AEROSPIKE_ERR_QUERY"; /** * write operator for the operate() method * */ public const OPERATOR_WRITE = "OPERATOR_WRITE"; /** * read operator for the operate() method * */ public const OPERATOR_READ = "OPERATOR_READ"; /** * increment operator for the operate() method * */ public const OPERATOR_INCR = "OPERATOR_INCR"; /** * prepend operator for the operate() method * */ public const OPERATOR_PREPEND = "OPERATOR_PREPEND"; /** * append operator for the operate() method * */ public const OPERATOR_APPEND = "OPERATOR_APPEND"; /** * touch operator for the operate() method * */ public const OPERATOR_TOUCH = "OPERATOR_TOUCH"; /** * delete operator for the operate() method * */ public const OPERATOR_DELETE = "OPERATOR_DELETE"; // List operation constants /** * list-append operator for the operate() method * */ public const OP_LIST_APPEND = "OP_LIST_APPEND"; /** * list-merge operator for the operate() method * */ public const OP_LIST_MERGE = "OP_LIST_MERGE"; /** * list-insert operator for the operate() method * */ public const OP_LIST_INSERT = "OP_LIST_INSERT"; /** * list-insert-items operator for the operate() method * */ public const OP_LIST_INSERT_ITEMS = "OP_LIST_INSERT_ITEMS"; /** * list-pop operator for the operate() method * */ public const OP_LIST_POP = "OP_LIST_POP"; /** * list-pop-range operator for the operate() method * */ public const OP_LIST_POP_RANGE = "OP_LIST_POP_RANGE"; /** * list-remove operator for the operate() method * */ public const OP_LIST_REMOVE = "OP_LIST_REMOVE"; /** * list-remove-range operator for the operate() method * */ public const OP_LIST_REMOVE_RANGE = "OP_LIST_REMOVE_RANGE"; /** * list-clear operator for the operate() method * */ public const OP_LIST_CLEAR = "OP_LIST_CLEAR"; /** * list-set operator for the operate() method * */ public const OP_LIST_SET = "OP_LIST_SET"; /** * list-get operator for the operate() method * */ public const OP_LIST_GET = "OP_LIST_GET"; /** * list-get-range operator for the operate() method * */ public const OP_LIST_GET_RANGE = "OP_LIST_GET_RANGE"; /** * list-trim operator for the operate() method * */ public const OP_LIST_TRIM = "OP_LIST_TRIM"; /** * list-size operator for the operate() method * */ public const OP_LIST_SIZE = "OP_LIST_SIZE"; // Map operation constants /** * map-size operator for the operate() method * */ public const OP_MAP_SIZE = "OP_MAP_SIZE"; /** * map-size operator for the operate() method * */ public const OP_MAP_CLEAR = "OP_MAP_CLEAR"; /** * map-set-policy operator for the operate() method * */ public const OP_MAP_SET_POLICY = "OP_MAP_SET_POLICY"; /** * map-get-by-key operator for the operate() method * */ public const OP_MAP_GET_BY_KEY = "OP_MAP_GET_BY_KEY"; /** * map-get-by-key-range operator for the operate() method * */ public const OP_MAP_GET_BY_KEY_RANGE = "OP_MAP_GET_BY_KEY_RANGE"; /** * map-get-by-value operator for the operate() method * */ public const OP_MAP_GET_BY_VALUE = "OP_MAP_GET_BY_VALUE"; /** * map-get-by-value-range operator for the operate() method * */ public const OP_MAP_GET_BY_VALUE_RANGE = "OP_MAP_GET_BY_VALUE_RANGE"; /** * map-get-by-index operator for the operate() method * */ public const OP_MAP_GET_BY_INDEX = "OP_MAP_GET_BY_INDEX"; /** * map-get-by-index-range operator for the operate() method * */ public const OP_MAP_GET_BY_INDEX_RANGE = "OP_MAP_GET_BY_INDEX_RANGE"; /** * map-get-by-rank operator for the operate() method * */ public const OP_MAP_GET_BY_RANK = "OP_MAP_GET_BY_RANK"; /** * map-get-by-rank-range operator for the operate() method * */ public const OP_MAP_GET_BY_RANK_RANGE = "OP_MAP_GET_BY_RANK_RANGE"; /** * map-put operator for the operate() method * */ public const OP_MAP_PUT = "OP_MAP_PUT"; /** * map-put-items operator for the operate() method * */ public const OP_MAP_PUT_ITEMS = "OP_MAP_PUT_ITEMS"; /** * map-increment operator for the operate() method * */ public const OP_MAP_INCREMENT = "OP_MAP_INCREMENT"; /** * map-decrement operator for the operate() method * */ public const OP_MAP_DECREMENT = "OP_MAP_DECREMENT"; /** * map-remove-by-key operator for the operate() method * */ public const OP_MAP_REMOVE_BY_KEY = "OP_MAP_REMOVE_BY_KEY"; /** * map-remove-by-key-list operator for the operate() method * */ public const OP_MAP_REMOVE_BY_KEY_LIST = "OP_MAP_REMOVE_BY_KEY_LIST"; /** * map-remove-by-key-range key operator for the operate() method * */ public const OP_MAP_REMOVE_BY_KEY_RANGE = "OP_MAP_REMOVE_BY_KEY_RANGE"; /** * map-remove-by-value operator for the operate() method * */ public const OP_MAP_REMOVE_BY_VALUE = "OP_MAP_REMOVE_BY_VALUE"; /** * map-remove-by-value operator for the operate() method * */ public const OP_MAP_REMOVE_BY_VALUE_RANGE = "OP_MAP_REMOVE_BY_VALUE_RANGE"; /** * map-remove-by-value-list operator for the operate() method * */ public const OP_MAP_REMOVE_BY_VALUE_LIST = "OP_MAP_REMOVE_BY_VALUE_LIST"; /** * map-remove-by-index operator for the operate() method * */ public const OP_MAP_REMOVE_BY_INDEX = "OP_MAP_REMOVE_BY_INDEX"; /** * map-remove-by-index-range operator for the operate() method * */ public const OP_MAP_REMOVE_BY_INDEX_RANGE = "OP_MAP_REMOVE_BY_INDEX_RANGE"; /** * map-remove-by-rank operator for the operate() method * */ public const OP_MAP_REMOVE_BY_RANK = "OP_MAP_REMOVE_BY_RANK"; /** * map-remove-by-rank-range operator for the operate() method * */ public const OP_MAP_REMOVE_BY_RANK_RANGE = "OP_MAP_REMOVE_BY_RANK_RANGE"; // Query Predicate Operators /** * predicate operator for equality check of scalar integer or string value * * @see Aerospike::predicateEquals */ public const OP_EQ = "="; /** * predicate operator matching whether an integer falls between a range of integer values * * @see Aerospike::predicateBetween */ public const OP_BETWEEN = "BETWEEN"; /** * predicate operator for a whether a specific value is in an indexed list, mapkeys, or mapvalues * * @see Aerospike::predicateContains */ public const OP_CONTAINS = "CONTAINS"; /** * predicate operator for whether an indexed list, mapkeys, or mapvalues has an integer value within a specified range * * @see Aerospike::predicateRange */ public const OP_RANGE = "RANGE"; /** * geospatial predicate operator for points within a specified region * */ public const OP_GEOWITHINREGION = "GEOWITHIN"; /** * geospatial predicate operator for regons containing a sepcified point * */ public const OP_GEOCONTAINSPOINT = "GEOCONTAINS"; /** * Scan status is undefined */ #[Deprecated('use JOB_STATUS_UNDEF along with jobInfo()')] public const SCAN_STATUS_UNDEF = "SCAN_STATUS_UNDEF"; /** * Scan is currently running */ #[Deprecated('use JOB_STATUS_INPROGRESS along with jobInfo()')] public const SCAN_STATUS_INPROGRESS = "SCAN_STATUS_INPROGRESS"; /** * Scan completed successfully */ #[Deprecated] public const SCAN_STATUS_ABORTED = "SCAN_STATUS_ABORTED"; /** * Scan was aborted due to failure or the user */ #[Deprecated('use JOB_STATUS_COMPLETED along with jobInfo()')] public const SCAN_STATUS_COMPLETED = "SCAN_STATUS_COMPLETED"; // Status values returned by jobInfo() /** * Job status is undefined */ public const JOB_STATUS_UNDEF = "JOB_STATUS_UNDEF"; /** * Job is currently running */ public const JOB_STATUS_INPROGRESS = "JOB_STATUS_INPROGRESS"; /** * Job completed successfully */ public const JOB_STATUS_COMPLETED = "JOB_STATUS_COMPLETED"; // Index (container) types /** * The bin being indexed should contain scalar values such as string or integer * */ public const INDEX_TYPE_DEFAULT = "INDEX_TYPE_DEFAULT"; /** * The bin being indexed should contain a list * */ public const INDEX_TYPE_LIST = "INDEX_TYPE_LIST"; /** * The bin being indexed should contain a map. The map keys will be indexed * */ public const INDEX_TYPE_MAPKEYS = "INDEX_TYPE_MAPKEYS"; /** * The bin being indexed should contain a map. The map values will be indexed * */ public const INDEX_TYPE_MAPVALUES = "INDEX_TYPE_MAPVALUES"; // Data type /** * If and only if the container type matches, the value should be of type string * */ public const INDEX_STRING = "INDEX_STRING"; /** * If and only if the container type matches, the value should be of type integer * */ public const INDEX_NUMERIC = "INDEX_NUMERIC"; /** * If and only if the container type matches, the value should be GeoJSON * */ public const INDEX_GEO2DSPHERE = "INDEX_GEO2DSPHERE"; /** * Declare the UDF module's language to be Lua * */ public const UDF_TYPE_LUA = "UDF_TYPE_LUA"; // Security role privileges /** * Privilege to read data * * @link https://www.aerospike.com/docs/guide/security/access-control.html Access Control */ public const PRIV_READ = "PRIV_READ"; /** * Privilege to read and write data * * @link https://www.aerospike.com/docs/guide/security/access-control.html Access Control */ public const PRIV_READ_WRITE = "PRIV_READ_WRITE"; /** * Privilege to read, write and execute user-defined functions * * @link https://www.aerospike.com/docs/guide/security/access-control.html Access Control */ public const PRIV_READ_WRITE_UDF = "PRIV_READ_WRITE_UDF"; /** * Privilege to create and assign roles to users * * @link https://www.aerospike.com/docs/guide/security/access-control.html Access Control */ public const PRIV_USER_ADMIN = "PRIV_USER_ADMIN"; /** * Privilege to manage indexes and UDFs, monitor and abort scan/query jobs, get server config * * @link https://www.aerospike.com/docs/guide/security/access-control.html Access Control */ public const PRIV_DATA_ADMIN = "PRIV_DATA_ADMIN"; // can perform data admin functions that do not involve user admin /** Privilege to modify dynamic server configs, get config and stats, and all data admin privileges * * @link https://www.aerospike.com/docs/guide/security/access-control.html Access Control */ public const PRIV_SYS_ADMIN = "PRIV_SYS_ADMIN"; // can perform sysadmin functions that do not involve user admin /* // TODO: // security methods public int createRole ( string $role, array $privileges [, array $options ] ) public int grantPrivileges ( string $role, array $privileges [, array $options ] ) public int revokePrivileges ( string $role, array $privileges [, array $options ] ) public int queryRole ( string $role, array &$privileges [, array $options ] ) public int queryRoles ( array &$roles [, array $options ] ) public int dropRole ( string $role [, array $options ] ) public int createUser ( string $user, string $password, array $roles [, array $options ] ) public int setPassword ( string $user, string $password [, array $options ] ) public int changePassword ( string $user, string $password [, array $options ] ) public int grantRoles ( string $user, array $roles [, array $options ] ) public int revokeRoles ( string $user, array $roles [, array $options ] ) public int queryUser ( string $user, array &$roles [, array $options ] ) public int queryUsers ( array &$roles [, array $options ] ) public int dropUser ( string $user [, array $options ] ) */ } *
  • "start" - offset where lock begins
  • *
  • "length" - size of locked area. zero means to end of file
  • *
  • "whence" - Where l_start is relative to: can be SEEK_SET, SEEK_END and SEEK_CUR
  • *
  • "type" - type of lock: can be F_RDLCK (read lock), F_WRLCK (write lock) or F_UNLCK (unlock)
  • * * @return mixed Returns the result of the C call. */ function dio_fcntl($fd, int $cmd, ...$args) {} /** * Opens a file (creating it if necessary) at a lower level than theC library input/ouput stream functions allow * * dio_open ( string $filename , int $flags [, int $mode = 0 ] ) : resource * * @link https://www.php.net/manual/en/function.dio-open.php * @param string $filename The pathname of the file to open. * @param int $flags The flags parameter is a bitwise-ORed value comprising flags from the following list. *
      *
    • O_RDONLY - opens the file for read access.
    • *
    • O_WRONLY - opens the file for write access.
    • *
    • O_RDWR - opens the file for both reading and writing.
    • *
    • O_CREAT - creates the file, if it doesn't already exist.
    • *
    • O_EXCL - if both O_CREAT and O_EXCL are set and the file already exists, dio_open() will fail.
    • *
    • O_TRUNC - if the file exists and is opened for write access, the file will be truncated to zero length.
    • *
    • O_APPEND - write operations write data at the end of the file.
    • *
    • O_NONBLOCK - sets non blocking mode.
    • *
    • O_NOCTTY - prevent the OS from assigning the opened file as the process's controllingterminal when opening a TTY device file.
    • *
    * @param int $mode If flags contains O_CREAT, mode will set the permissions of the file (creation permissions). * @return resource|false A file descriptor or FALSE on error. */ function dio_open(string $filename, int $flags, int $mode = 0) {} /** * Reads bytes from a file descriptor. * * dio_read ( resource $fd [, int $len = 1024 ] ) : string * * @param resource $fd The file descriptor returned by dio_open(). * @param int $len The number of bytes to read. If not specified, dio_read() reads 1k sized block. * @return string The bytes read from fd. * @link https://www.php.net/manual/en/function.dio-read.php */ function dio_read($fd, int $len = 1024) {} /** * Seeks to pos on fd from whence * * dio_seek ( resource $fd , int $pos [, int $whence = SEEK_SET ] ): int * * @param resource $fd The file descriptor returned by dio_open(). * @param int $pos The new position. * @param int $whence Specifies how the position pos should be interpreted: *
      *
    • SEEK_SET - (Default) Specifies that pos is specified from the beginning of the file.
    • *
    • SEEK_CUR - Specifies that pos is a count of characters from the current file position. This count may be positive or negative.
    • *
    • SEEK_END - Specifies that pos is a count of characters from the end of the file.
    • *
    * @return int * @link https://www.php.net/manual/en/function.dio-seek.php */ function dio_seek($fd, int $pos, int $whence = SEEK_SET) {} /** * Gets stat information about the file descriptor fd * * dio_stat ( resource $fd ) : array * * @param resource $fd The file descriptor returned by dio_open(). * @return array|null Returns an associative array with the following keys: *
      *
    • "device" - device
    • *
    • "inode" - inode
    • *
    • "mode" - mode
    • *
    • "nlink" - number of hard links
    • *
    • "uid" - user id
    • *
    • "gid" - group id
    • *
    • "device_type" - device type (if inode device)
    • *
    • "size" - total size in bytes
    • *
    • "blocksize" - blocksize
    • *
    • "blocks" - number of blocks allocated
    • *
    • "atime" - time of last access
    • *
    • "mtime" - time of last modification
    • *
    • "ctime" - time of last change
    • *
    * On error dio_stat() returns NULL. * @link https://www.php.net/manual/en/function.dio-stat.php */ function dio_stat($fd) {} /** * Sets terminal attributes and baud rate for a serial port * * dio_tcsetattr ( resource $fd , array $options ) : bool * * @param resource $fd The file descriptor returned by dio_open(). * @param array $options The currently available options are: *
      *
    • "baud" - baud rate of the port - can be 38400, 19200, 9600, 4800, 2400, 1800, 1200, 600, 300, 200, 150, 134, 110, 75 or 50, default value is 9600.
    • *
    • "bits" - data bits - can be 8,7,6 or 5. Default value is 8.
    • *
    • "stop" - stop bits - can be 1 or 2. Default value is 1.
    • *
    • "parity" - can be 0,1 or 2. Default value is 0.
    • *
    * @return void * @link https://www.php.net/manual/en/function.dio-tcsetattr.php */ function dio_tcsetattr($fd, array $options) {} /** * Truncates a file to at most offset bytes in size. * * dio_truncate ( resource $fd , int $offset ) : bool * * If the file previously was larger than this size, the extra data is lost. * If the file previously was shorter, it is unspecified whether the file is left unchanged or is extended. * In the latter case the extended part reads as zero bytes. * @param resource $fd The file descriptor returned by dio_open(). * @param int $offset The offset in bytes. * @return bool Returns TRUE on success or FALSE on failure. * @link https://www.php.net/manual/en/function.dio-truncate.php */ function dio_truncate($fd, int $offset) {} /** * Writes data to fd with optional truncation at length * * dio_write ( resource $fd , string $data [, int $len = 0 ] ) : int * * @link https://www.php.net/manual/en/function.dio-write.php * @param resource $fd The file descriptor returned by dio_open(). * @param string $data The written data. * @param int $len The length of data to write in bytes. If not specified, the function writes all the data to the specified file. * @return int Returns the number of bytes written to fd. */ function dio_write($fd, string $data, int $len = 0) {} /** * Opens a raw direct IO stream. * * dio_raw ( string filename , string mode [, array options] ) : ?resource * * @param string $filename The pathname of the file to open. * @param string $mode The mode parameter specifies the type of access you require to the stream (as fopen()). * @param array|null $options The currently available options are: *
      *
    • "data_rate" - baud rate of the port - can be 75, 110, 134, 150, 300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 38400, 57600, 115200, 56000, 128000 or 256000 default value is 9600.
    • *
    • "data_bits" - can be 8, 7, 6 or 5. Default value is 8.
    • *
    • "stop_bits" - can be 1 or 2. Default value is 1.
    • *
    • "parity" - can be 0, 1 or 2. Default value is 0.
    • *
    • "flow_control" - can be 0 or 1. Default value is 1.
    • *
    • "is_canonical" - can be 0 or 1. Default value is 1.
    • *
    * @return resource|null A stream resource or null on error. */ function dio_raw(string $filename, string $mode, ?array $options) {} /** * Opens a serial direct IO stream. * * dio_serial ( string $filename , string $mode [, array $options = null] ) : ?resource * * @param string $filename The pathname of the file to open. * @param string $mode The mode parameter specifies the type of access you require to the stream (as fopen()). * @param array|null $options The currently available options are: *
      *
    • "data_rate" - baud rate of the port - can be 75, 110, 134, 150, 300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 38400, 57600, 115200, 56000, 128000 or 256000 default value is 9600.
    • *
    • "data_bits" - can be 8, 7, 6 or 5. Default value is 8.
    • *
    • "stop_bits" - can be 1 or 2. Default value is 1.
    • *
    • "parity" - can be 0, 1 or 2. Default value is 0.
    • *
    • "flow_control" - can be 0 or 1. Default value is 1.
    • *
    • "is_canonical" - can be 0 or 1. Default value is 1.
    • *
    * @return resource|null A stream resource or null on error. */ function dio_serial(string $filename, string $mode, ?array $options) {} * Returns the value of the specified configuration option for the tidy document * @link https://php.net/manual/en/tidy.getopt.php * @param string $option

    * You will find a list with each configuration option and their types * at: http://tidy.sourceforge.net/docs/quickref.html. *

    * @return string|int|bool the value of the specified option. * The return type depends on the type of the specified one. */ #[TentativeType] public function getOpt(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $option): string|int|bool {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Execute configured cleanup and repair operations on parsed markup * @link https://php.net/manual/en/tidy.cleanrepair.php * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function cleanRepair(): bool {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Parse markup in file or URI * @link https://php.net/manual/en/tidy.parsefile.php * @param string $filename

    * If the filename parameter is given, this function * will also read that file and initialize the object with the file, * acting like tidy_parse_file. *

    * @param mixed $config [optional]

    * The config config can be passed either as an * array or as a string. If a string is passed, it is interpreted as the * name of the configuration file, otherwise, it is interpreted as the * options themselves. *

    *

    * For an explanation about each option, see * http://tidy.sourceforge.net/docs/quickref.html. *

    * @param string|null $encoding [optional]

    * The encoding parameter sets the encoding for * input/output documents. The possible values for encoding are: * ascii, latin0, latin1, * raw, utf8, iso2022, * mac, win1252, ibm858, * utf16, utf16le, utf16be, * big5, and shiftjis. *

    * @param bool $useIncludePath [optional]

    * Search for the file in the include_path. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function parseFile( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename, #[LanguageLevelTypeAware(['8.0' => 'array|string|null'], default: '')] $config = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $encoding = null, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $useIncludePath = false ): bool {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Parse a document stored in a string * @link https://php.net/manual/en/tidy.parsestring.php * @param string $string

    * The data to be parsed. *

    * @param mixed $config [optional]

    * The config config can be passed either as an * array or as a string. If a string is passed, it is interpreted as the * name of the configuration file, otherwise, it is interpreted as the * options themselves. *

    *

    * For an explanation about each option, visit http://tidy.sourceforge.net/docs/quickref.html. *

    * @param string|null $encoding [optional]

    * The encoding parameter sets the encoding for * input/output documents. The possible values for encoding are: * ascii, latin0, latin1, * raw, utf8, iso2022, * mac, win1252, ibm858, * utf16, utf16le, utf16be, * big5, and shiftjis. *

    * @return bool a new tidy instance. */ #[TentativeType] public function parseString( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $string, #[LanguageLevelTypeAware(['8.0' => 'array|string|null'], default: '')] $config = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $encoding = null ): bool {} /** * (PHP 5, PECL tidy >= 0.7.0)
    * Repair a string using an optionally provided configuration file * @link https://php.net/manual/en/tidy.repairstring.php * @param string $string

    * The data to be repaired. *

    * @param array|string|null $config [optional]

    * The config config can be passed either as an * array or as a string. If a string is passed, it is interpreted as the * name of the configuration file, otherwise, it is interpreted as the * options themselves. *

    *

    * Check http://tidy.sourceforge.net/docs/quickref.html for * an explanation about each option. *

    * @param string|null $encoding [optional]

    * The encoding parameter sets the encoding for * input/output documents. The possible values for encoding are: * ascii, latin0, latin1, * raw, utf8, iso2022, * mac, win1252, ibm858, * utf16, utf16le, utf16be, * big5, and shiftjis. *

    * @return string|false the repaired string. */ #[TentativeType] public static function repairString( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $string, #[LanguageLevelTypeAware(['8.0' => 'array|string|null'], default: '')] $config = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $encoding = null ): string|false {} /** * (PHP 5, PECL tidy >= 0.7.0)
    * Repair a file and return it as a string * @link https://php.net/manual/en/tidy.repairfile.php * @param string $filename

    * The file to be repaired. *

    * @param array|string|null $config [optional]

    * The config config can be passed either as an * array or as a string. If a string is passed, it is interpreted as the * name of the configuration file, otherwise, it is interpreted as the * options themselves. *

    *

    * Check http://tidy.sourceforge.net/docs/quickref.html for an * explanation about each option. *

    * @param string|null $encoding [optional]

    * The encoding parameter sets the encoding for * input/output documents. The possible values for encoding are: * ascii, latin0, latin1, * raw, utf8, iso2022, * mac, win1252, ibm858, * utf16, utf16le, utf16be, * big5, and shiftjis. *

    * @param bool $useIncludePath [optional]

    * Search for the file in the include_path. *

    * @return string|false the repaired contents as a string. */ #[TentativeType] public static function repairFile( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename, #[LanguageLevelTypeAware(['8.0' => 'array|string|null'], default: '')] $config = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $encoding = null, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $useIncludePath = false ): string|false {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Run configured diagnostics on parsed and repaired markup * @link https://php.net/manual/en/tidy.diagnose.php * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function diagnose(): bool {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Get release date (version) for Tidy library * @link https://php.net/manual/en/tidy.getrelease.php * @return string a string with the release date of the Tidy library. */ #[TentativeType] public function getRelease(): string {} /** * (PHP 5, PECL tidy >= 0.7.0)
    * Get current Tidy configuration * @link https://php.net/manual/en/tidy.getconfig.php * @return array an array of configuration options. *

    *

    * For an explanation about each option, visit http://tidy.sourceforge.net/docs/quickref.html. */ #[TentativeType] public function getConfig(): array {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Get status of specified document * @link https://php.net/manual/en/tidy.getstatus.php * @return int 0 if no error/warning was raised, 1 for warnings or accessibility * errors, or 2 for errors. */ #[TentativeType] public function getStatus(): int {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Get the Detected HTML version for the specified document * @link https://php.net/manual/en/tidy.gethtmlver.php * @return int the detected HTML version. *

    *

    * This function is not yet implemented in the Tidylib itself, so it always * return 0. */ #[TentativeType] public function getHtmlVer(): int {} /** * Returns the documentation for the given option name * @link https://php.net/manual/en/tidy.getoptdoc.php * @param string $option

    * The option name *

    * @return string|false a string if the option exists and has documentation available, or * FALSE otherwise. */ #[TentativeType] public function getOptDoc(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $option): string|false {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Indicates if the document is a XHTML document * @link https://php.net/manual/en/tidy.isxhtml.php * @return bool This function returns TRUE if the specified tidy * object is a XHTML document, or FALSE otherwise. *

    *

    * This function is not yet implemented in the Tidylib itself, so it always * return FALSE. */ #[TentativeType] public function isXhtml(): bool {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Indicates if the document is a generic (non HTML/XHTML) XML document * @link https://php.net/manual/en/tidy.isxml.php * @return bool This function returns TRUE if the specified tidy * object is a generic XML document (non HTML/XHTML), * or FALSE otherwise. *

    *

    * This function is not yet implemented in the Tidylib itself, so it always * return FALSE. */ #[TentativeType] public function isXml(): bool {} /** * (PHP 5, PECL tidy 0.5.2-1.0.0)
    * Returns a tidyNode object representing the root of the tidy parse tree * @link https://php.net/manual/en/tidy.root.php * @return tidyNode|null the tidyNode object. */ #[TentativeType] public function root(): ?tidyNode {} /** * (PHP 5, PECL tidy 0.5.2-1.0.0)
    * Returns a tidyNode object starting from the <head> tag of the tidy parse tree * @link https://php.net/manual/en/tidy.head.php * @return tidyNode|null the tidyNode object. */ #[TentativeType] public function head(): ?tidyNode {} /** * (PHP 5, PECL tidy 0.5.2-1.0.0)
    * Returns a tidyNode object starting from the <html> tag of the tidy parse tree * @link https://php.net/manual/en/tidy.html.php * @return tidyNode|null the tidyNode object. */ #[TentativeType] public function html(): ?tidyNode {} /** * (PHP 5, PECL tidy 0.5.2-1.0)
    * Returns a tidyNode object starting from the <body> tag of the tidy parse tree * @link https://php.net/manual/en/tidy.body.php * @return tidyNode|null a tidyNode object starting from the * <body> tag of the tidy parse tree. */ #[TentativeType] public function body(): ?tidyNode {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Constructs a new tidy object * @link https://php.net/manual/en/tidy.construct.php * @param string $filename [optional]

    * If the filename parameter is given, this function * will also read that file and initialize the object with the file, * acting like tidy_parse_file. *

    * @param mixed $config [optional]

    * The config config can be passed either as an * array or as a string. If a string is passed, it is interpreted as the * name of the configuration file, otherwise, it is interpreted as the * options themselves. *

    *

    * For an explanation about each option, visit http://tidy.sourceforge.net/docs/quickref.html. *

    * @param string|null $encoding [optional]

    * The encoding parameter sets the encoding for * input/output documents. The possible values for encoding are: * ascii, latin0, latin1, * raw, utf8, iso2022, * mac, win1252, ibm858, * utf16, utf16le, utf16be, * big5, and shiftjis. *

    * @param bool $useIncludePath [optional]

    * Search for the file in the include_path. *

    */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $filename = null, #[LanguageLevelTypeAware(['8.0' => 'array|string|null'], default: '')] $config = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $encoding = null, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $useIncludePath = null ) {} } /** * An HTML node in an HTML file, as detected by tidy. * @link https://php.net/manual/en/class.tidynode.php */ final class tidyNode { /** *

    The HTML representation of the node, including the surrounding tags.

    * @var string */ public readonly string $value; /** *

    The name of the HTML node

    * @var string */ public readonly string $name; /** *

    The type of the tag (one of the constants above, e.g. TIDY_NODETYPE_PHP)

    * @var int */ public readonly int $type; /** *

    The line number at which the tags is located in the file

    * @var int */ public readonly int $line; /** *

    The column number at which the tags is located in the file

    * @var int */ public readonly int $column; /** *

    Indicates if the node is a proprietary tag

    * @var bool */ public readonly bool $proprietary; /** *

    The ID of the tag (one of the constants above, e.g. TIDY_TAG_FRAME)

    * @var int|null */ public readonly ?int $id; /** *

    * An array of string, representing * the attributes names (as keys) of the current node. *

    * @var array|null */ public readonly ?array $attribute; /** *

    * An array of tidyNode, representing * the children of the current node. *

    * @var array|null */ public readonly ?array $child; /** * Checks if a node has children * @link https://php.net/manual/en/tidynode.haschildren.php * @return bool TRUE if the node has children, FALSE otherwise. * @since 5.0.1 */ public function hasChildren():bool {} /** * Checks if a node has siblings * @link https://php.net/manual/en/tidynode.hassiblings.php * @return bool TRUE if the node has siblings, FALSE otherwise. * @since 5.0.1 */ public function hasSiblings(): bool {} /** * Checks if a node represents a comment * @link https://php.net/manual/en/tidynode.iscomment.php * @return bool TRUE if the node is a comment, FALSE otherwise. * @since 5.0.1 */ public function isComment():bool {} /** * Checks if a node is part of a HTML document * @link https://php.net/manual/en/tidynode.ishtml.php * @return bool TRUE if the node is part of a HTML document, FALSE otherwise. * @since 5.0.1 */ public function isHtml(): bool {} /** * Checks if a node represents text (no markup) * @link https://php.net/manual/en/tidynode.istext.php * @return bool TRUE if the node represent a text, FALSE otherwise. * @since 5.0.1 */ public function isText(): bool {} /** * Checks if this node is JSTE * @link https://php.net/manual/en/tidynode.isjste.php * @return bool TRUE if the node is JSTE, FALSE otherwise. * @since 5.0.1 */ public function isJste(): bool {} /** * Checks if this node is ASP * @link https://php.net/manual/en/tidynode.isasp.php * @return bool TRUE if the node is ASP, FALSE otherwise. * @since 5.0.1 */ public function isAsp(): bool {} /** * Checks if a node is PHP * @link https://php.net/manual/en/tidynode.isphp.php * @return bool TRUE if the current node is PHP code, FALSE otherwise. * @since 5.0.1 */ public function isPhp(): bool {} /** * Returns the parent node of the current node * @link https://php.net/manual/en/tidynode.getparent.php * @return tidyNode|null a tidyNode if the node has a parent, or NULL * otherwise. * @since 5.2.2 */ public function getParent(): ?tidyNode {} private function __construct() {} } /** * (PHP 5, PECL tidy >= 0.5.2)
    * Returns the value of the specified configuration option for the tidy document * @link https://php.net/manual/en/tidy.getopt.php * @param tidy $tidy

    * The Tidy object. *

    * @param string $option

    * You will find a list with each configuration option and their types * at: http://tidy.sourceforge.net/docs/quickref.html. *

    * @return string|int|bool the value of the specified option. * The return type depends on the type of the specified one. */ function tidy_getopt(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy, string $option):string|int|bool {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Parse a document stored in a string * @link https://php.net/manual/en/tidy.parsestring.php * @param string $string

    * The data to be parsed. *

    * @param mixed $config [optional]

    * The config config can be passed either as an * array or as a string. If a string is passed, it is interpreted as the * name of the configuration file, otherwise, it is interpreted as the * options themselves. *

    *

    * For an explanation about each option, visit http://tidy.sourceforge.net/docs/quickref.html. *

    * @param string|null $encoding [optional]

    * The encoding parameter sets the encoding for * input/output documents. The possible values for encoding are: * ascii, latin0, latin1, * raw, utf8, iso2022, * mac, win1252, ibm858, * utf16, utf16le, utf16be, * big5, and shiftjis. *

    * @return tidy|false a new tidy instance. */ function tidy_parse_string(string $string, array|string|null $config = null, null|string $encoding = null):tidy|false {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Parse markup in file or URI * @link https://php.net/manual/en/tidy.parsefile.php * @param string $filename

    * If the filename parameter is given, this function * will also read that file and initialize the object with the file, * acting like tidy_parse_file. *

    * @param mixed $config [optional]

    * The config config can be passed either as an * array or as a string. If a string is passed, it is interpreted as the * name of the configuration file, otherwise, it is interpreted as the * options themselves. *

    *

    * For an explanation about each option, see * http://tidy.sourceforge.net/docs/quickref.html. *

    * @param string|null $encoding [optional]

    * The encoding parameter sets the encoding for * input/output documents. The possible values for encoding are: * ascii, latin0, latin1, * raw, utf8, iso2022, * mac, win1252, ibm858, * utf16, utf16le, utf16be, * big5, and shiftjis. *

    * @param bool $useIncludePath [optional]

    * Search for the file in the include_path. *

    * @return tidy|false a new tidy instance. */ function tidy_parse_file(string $filename, array|string|null $config = null, null|string $encoding = null, bool $useIncludePath = false):tidy|false {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Return a string representing the parsed tidy markup * @link https://php.net/manual/en/function.tidy-get-output.php * @param tidy $tidy

    * The Tidy object. *

    * @return string the parsed tidy markup. */ function tidy_get_output(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):string {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Return warnings and errors which occurred parsing the specified document * @link https://php.net/manual/en/tidy.props.errorbuffer.php * @param tidy $tidy

    * The Tidy object. *

    * @return string|false the error buffer as a string. */ function tidy_get_error_buffer(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):string|false {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Execute configured cleanup and repair operations on parsed markup * @link https://php.net/manual/en/tidy.cleanrepair.php * @param tidy $tidy The Tidy object. * @return bool TRUE on success or FALSE on failure. */ function tidy_clean_repair(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):bool {} /** * (PHP 5, PECL tidy >= 0.7.0)
    * Repair a string using an optionally provided configuration file * @link https://php.net/manual/en/tidy.repairstring.php * @param string $string

    * The data to be repaired. *

    * @param mixed $config [optional]

    * The config config can be passed either as an * array or as a string. If a string is passed, it is interpreted as the * name of the configuration file, otherwise, it is interpreted as the * options themselves. *

    *

    * Check http://tidy.sourceforge.net/docs/quickref.html for * an explanation about each option. *

    * @param string|null $encoding [optional]

    * The encoding parameter sets the encoding for * input/output documents. The possible values for encoding are: * ascii, latin0, latin1, * raw, utf8, iso2022, * mac, win1252, ibm858, * utf16, utf16le, utf16be, * big5, and shiftjis. *

    * @return string|false the repaired string. */ function tidy_repair_string(string $string, array|string|null $config = null, null|string $encoding = null):string|false {} /** * (PHP 5, PECL tidy >= 0.7.0)
    * Repair a file and return it as a string * @link https://php.net/manual/en/tidy.repairfile.php * @param string $filename

    * The file to be repaired. *

    * @param mixed $config [optional]

    * The config config can be passed either as an * array or as a string. If a string is passed, it is interpreted as the * name of the configuration file, otherwise, it is interpreted as the * options themselves. *

    *

    * Check http://tidy.sourceforge.net/docs/quickref.html for an * explanation about each option. *

    * @param string|null $encoding [optional]

    * The encoding parameter sets the encoding for * input/output documents. The possible values for encoding are: * ascii, latin0, latin1, * raw, utf8, iso2022, * mac, win1252, ibm858, * utf16, utf16le, utf16be, * big5, and shiftjis. *

    * @param bool $useIncludePath [optional]

    * Search for the file in the include_path. *

    * @return string|false the repaired contents as a string. */ function tidy_repair_file(string $filename, array|string|null $config = null, null|string $encoding = null, bool $useIncludePath = false):string|false {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Run configured diagnostics on parsed and repaired markup * @link https://php.net/manual/en/tidy.diagnose.php * @param tidy $tidy

    * The Tidy object. *

    * @return bool TRUE on success or FALSE on failure. */ function tidy_diagnose(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):bool {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Get release date (version) for Tidy library * @link https://php.net/manual/en/tidy.getrelease.php * @return string a string with the release date of the Tidy library. */ function tidy_get_release():string {} /** * (PHP 5, PECL tidy >= 0.7.0)
    * Get current Tidy configuration * @link https://php.net/manual/en/tidy.getconfig.php * @param tidy $tidy

    * The Tidy object. *

    * @return array an array of configuration options. *

    * For an explanation about each option, visit http://tidy.sourceforge.net/docs/quickref.html. *

    */ function tidy_get_config(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):array {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Get status of specified document * @link https://php.net/manual/en/tidy.getstatus.php * @param tidy $tidy

    * The Tidy object. *

    * @return int 0 if no error/warning was raised, 1 for warnings or accessibility * errors, or 2 for errors. */ function tidy_get_status(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):int {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Get the Detected HTML version for the specified document * @link https://php.net/manual/en/tidy.gethtmlver.php * @param tidy $tidy

    * The Tidy object. *

    * @return int the detected HTML version. *

    * This function is not yet implemented in the Tidylib itself, so it always * return 0. *

    */ function tidy_get_html_ver(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):int {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Indicates if the document is a XHTML document * @link https://php.net/manual/en/tidy.isxhtml.php * @param tidy $tidy

    * The Tidy object. *

    * @return bool This function returns TRUE if the specified tidy * object is a XHTML document, or FALSE otherwise. *

    *

    * This function is not yet implemented in the Tidylib itself, so it always * return FALSE. */ function tidy_is_xhtml(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):bool {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Indicates if the document is a generic (non HTML/XHTML) XML document * @link https://php.net/manual/en/tidy.isxml.php * @param tidy $tidy

    * The Tidy object. *

    * @return bool This function returns TRUE if the specified tidy * object is a generic XML document (non HTML/XHTML), * or FALSE otherwise. *

    *

    * This function is not yet implemented in the Tidylib itself, so it always * return FALSE. */ function tidy_is_xml(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):bool {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Returns the Number of Tidy errors encountered for specified document * @link https://php.net/manual/en/function.tidy-error-count.php * @param tidy $tidy

    * The Tidy object. *

    * @return int the number of errors. */ function tidy_error_count(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy): int {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Returns the Number of Tidy warnings encountered for specified document * @link https://php.net/manual/en/function.tidy-warning-count.php * @param tidy $tidy

    * The Tidy object. *

    * @return int the number of warnings. */ function tidy_warning_count(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):int {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Returns the Number of Tidy accessibility warnings encountered for specified document * @link https://php.net/manual/en/function.tidy-access-count.php * @param tidy $tidy

    * The Tidy object. *

    * @return int the number of warnings. */ function tidy_access_count(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy): int {} /** * (PHP 5, PECL tidy >= 0.5.2)
    * Returns the Number of Tidy configuration errors encountered for specified document * @link https://php.net/manual/en/function.tidy-config-count.php * @param tidy $tidy

    * The Tidy object. *

    * @return int the number of errors. */ function tidy_config_count(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):int {} /** * Returns the documentation for the given option name * @link https://php.net/manual/en/tidy.getoptdoc.php * @param tidy $tidy

    * The Tidy object. *

    * @param string $option

    * The option name *

    * @return string|false a string if the option exists and has documentation available, or * FALSE otherwise. */ function tidy_get_opt_doc(tidy $tidy, string $option):string|false {} /** * (PHP 5, PECL tidy 0.5.2-1.0.0)
    * Returns a tidyNode object representing the root of the tidy parse tree * @link https://php.net/manual/en/tidy.root.php * @param tidy $tidy

    * The Tidy object. *

    * @return tidyNode|null the tidyNode object. */ function tidy_get_root(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):?tidyNode {} /** * (PHP 5, PECL tidy 0.5.2-1.0.0)
    * Returns a tidyNode object starting from the <head> tag of the tidy parse tree * @link https://php.net/manual/en/tidy.head.php * @param tidy $tidy

    * The Tidy object. *

    * @return tidyNode|null the tidyNode object. */ function tidy_get_head(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):?tidyNode {} /** * (PHP 5, PECL tidy 0.5.2-1.0.0)
    * Returns a tidyNode object starting from the <html> tag of the tidy parse tree * @link https://php.net/manual/en/tidy.html.php * @param tidy $tidy

    * The Tidy object. *

    * @return tidyNode|null the tidyNode object. */ function tidy_get_html(#[PhpStormStubsElementAvailable(from: '8.0')] tidy $tidy):?tidyNode {} /** * (PHP 5, PECL tidy 0.5.2-1.0)
    * Returns a tidyNode object starting from the <body> tag of the tidy parse tree * @link https://php.net/manual/en/tidy.body.php * @param tidy $tidy

    * The Tidy object. *

    * @return tidyNode|null a tidyNode object starting from the * <body> tag of the tidy parse tree. */ function tidy_get_body(tidy $tidy): ?tidyNode {} /** * ob_start callback function to repair the buffer * @link https://php.net/manual/en/function.ob-tidyhandler.php * @param string $input

    * The buffer. *

    * @param int $mode [optional]

    * The buffer mode. *

    * @return string the modified buffer. */ function ob_tidyhandler($input, $mode = null) {} /** * description * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_TAG_UNKNOWN', 0); define('TIDY_TAG_A', 1); define('TIDY_TAG_ABBR', 2); define('TIDY_TAG_ACRONYM', 3); define('TIDY_TAG_ADDRESS', 4); define('TIDY_TAG_ALIGN', 5); define('TIDY_TAG_APPLET', 6); define('TIDY_TAG_AREA', 7); define('TIDY_TAG_B', 8); define('TIDY_TAG_BASE', 9); define('TIDY_TAG_BASEFONT', 10); define('TIDY_TAG_BDO', 11); define('TIDY_TAG_BGSOUND', 12); define('TIDY_TAG_BIG', 13); define('TIDY_TAG_BLINK', 14); define('TIDY_TAG_BLOCKQUOTE', 15); define('TIDY_TAG_BODY', 16); define('TIDY_TAG_BR', 17); define('TIDY_TAG_BUTTON', 18); define('TIDY_TAG_CAPTION', 19); define('TIDY_TAG_CENTER', 20); define('TIDY_TAG_CITE', 21); define('TIDY_TAG_CODE', 22); define('TIDY_TAG_COL', 23); define('TIDY_TAG_COLGROUP', 24); define('TIDY_TAG_COMMENT', 25); define('TIDY_TAG_DD', 26); define('TIDY_TAG_DEL', 27); define('TIDY_TAG_DFN', 28); define('TIDY_TAG_DIR', 29); define('TIDY_TAG_DIV', 30); define('TIDY_TAG_DL', 31); define('TIDY_TAG_DT', 32); define('TIDY_TAG_EM', 33); define('TIDY_TAG_EMBED', 34); define('TIDY_TAG_FIELDSET', 35); define('TIDY_TAG_FONT', 36); define('TIDY_TAG_FORM', 37); define('TIDY_TAG_FRAME', 38); define('TIDY_TAG_FRAMESET', 39); define('TIDY_TAG_H1', 40); define('TIDY_TAG_H2', 41); define('TIDY_TAG_H3', 42); define('TIDY_TAG_H4', 43); define('TIDY_TAG_H5', 44); define('TIDY_TAG_H6', 45); define('TIDY_TAG_HEAD', 46); define('TIDY_TAG_HR', 47); define('TIDY_TAG_HTML', 48); define('TIDY_TAG_I', 49); define('TIDY_TAG_IFRAME', 50); define('TIDY_TAG_ILAYER', 51); define('TIDY_TAG_IMG', 52); define('TIDY_TAG_INPUT', 53); define('TIDY_TAG_INS', 54); define('TIDY_TAG_ISINDEX', 55); define('TIDY_TAG_KBD', 56); define('TIDY_TAG_KEYGEN', 57); define('TIDY_TAG_LABEL', 58); define('TIDY_TAG_LAYER', 59); define('TIDY_TAG_LEGEND', 60); define('TIDY_TAG_LI', 61); define('TIDY_TAG_LINK', 62); define('TIDY_TAG_LISTING', 63); define('TIDY_TAG_MAP', 64); define('TIDY_TAG_MARQUEE', 65); define('TIDY_TAG_MENU', 66); define('TIDY_TAG_META', 67); define('TIDY_TAG_MULTICOL', 68); define('TIDY_TAG_NOBR', 69); define('TIDY_TAG_NOEMBED', 70); define('TIDY_TAG_NOFRAMES', 71); define('TIDY_TAG_NOLAYER', 72); define('TIDY_TAG_NOSAVE', 73); define('TIDY_TAG_NOSCRIPT', 74); define('TIDY_TAG_OBJECT', 75); define('TIDY_TAG_OL', 76); define('TIDY_TAG_OPTGROUP', 77); define('TIDY_TAG_OPTION', 78); define('TIDY_TAG_P', 79); define('TIDY_TAG_PARAM', 80); define('TIDY_TAG_PLAINTEXT', 81); define('TIDY_TAG_PRE', 82); define('TIDY_TAG_Q', 83); define('TIDY_TAG_RB', 84); define('TIDY_TAG_RBC', 85); define('TIDY_TAG_RP', 86); define('TIDY_TAG_RT', 87); define('TIDY_TAG_RTC', 88); define('TIDY_TAG_RUBY', 89); define('TIDY_TAG_S', 90); define('TIDY_TAG_SAMP', 91); define('TIDY_TAG_SCRIPT', 92); define('TIDY_TAG_SELECT', 93); define('TIDY_TAG_SERVER', 94); define('TIDY_TAG_SERVLET', 95); define('TIDY_TAG_SMALL', 96); define('TIDY_TAG_SPACER', 97); define('TIDY_TAG_SPAN', 98); define('TIDY_TAG_STRIKE', 99); define('TIDY_TAG_STRONG', 100); define('TIDY_TAG_STYLE', 101); define('TIDY_TAG_SUB', 102); define('TIDY_TAG_SUP', 103); define('TIDY_TAG_TABLE', 104); define('TIDY_TAG_TBODY', 105); define('TIDY_TAG_TD', 106); define('TIDY_TAG_TEXTAREA', 107); define('TIDY_TAG_TFOOT', 108); define('TIDY_TAG_TH', 109); define('TIDY_TAG_THEAD', 110); define('TIDY_TAG_TITLE', 111); define('TIDY_TAG_TR', 112); define('TIDY_TAG_TT', 113); define('TIDY_TAG_U', 114); define('TIDY_TAG_UL', 115); define('TIDY_TAG_VAR', 116); define('TIDY_TAG_WBR', 117); define('TIDY_TAG_XMP', 118); /** * @since 7.4 */ define('TIDY_TAG_ARTICLE', 123); /** * @since 7.4 */ define('TIDY_TAG_ASIDE', 124); /** * @since 7.4 */ define('TIDY_TAG_AUDIO', 125); /** * @since 7.4 */ define('TIDY_TAG_BDI', 126); /** * @since 7.4 */ define('TIDY_TAG_CANVAS', 127); /** * @since 7.4 */ define('TIDY_TAG_COMMAND', 128); /** * @since 7.4 */ define('TIDY_TAG_DATALIST', 129); /** * @since 7.4 */ define('TIDY_TAG_DETAILS', 130); /** * @since 7.4 */ define('TIDY_TAG_DIALOG', 131); /** * @since 7.4 */ define('TIDY_TAG_FIGCAPTION', 132); /** * @since 7.4 */ define('TIDY_TAG_FIGURE', 133); /** * @since 7.4 */ define('TIDY_TAG_FOOTER', 134); /** * @since 7.4 */ define('TIDY_TAG_HEADER', 135); /** * @since 7.4 */ define('TIDY_TAG_HGROUP', 136); /** * @since 7.4 */ define('TIDY_TAG_MAIN', 137); /** * @since 7.4 */ define('TIDY_TAG_MARK', 138); /** * @since 7.4 */ define('TIDY_TAG_MENUITEM', 139); /** * @since 7.4 */ define('TIDY_TAG_METER', 140); /** * @since 7.4 */ define('TIDY_TAG_NAV', 141); /** * @since 7.4 */ define('TIDY_TAG_OUTPUT', 142); /** * @since 7.4 */ define('TIDY_TAG_PROGRESS', 143); /** * @since 7.4 */ define('TIDY_TAG_SECTION', 144); /** * @since 7.4 */ define('TIDY_TAG_SOURCE', 145); /** * @since 7.4 */ define('TIDY_TAG_SUMMARY', 146); /** * @since 7.4 */ define('TIDY_TAG_TEMPLATE', 147); /** * @since 7.4 */ define('TIDY_TAG_TIME', 148); /** * @since 7.4 */ define('TIDY_TAG_TRACK', 149); /** * @since 7.4 */ define('TIDY_TAG_VIDEO', 150); /** * root node * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_ROOT', 0); /** * doctype * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_DOCTYPE', 1); /** * HTML comment * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_COMMENT', 2); /** * Processing Instruction * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_PROCINS', 3); /** * Text * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_TEXT', 4); /** * start tag * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_START', 5); /** * end tag * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_END', 6); /** * empty tag * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_STARTEND', 7); /** * CDATA * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_CDATA', 8); /** * XML section * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_SECTION', 9); /** * ASP code * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_ASP', 10); /** * JSTE code * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_JSTE', 11); /** * PHP code * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_PHP', 12); /** * XML declaration * @link https://php.net/manual/en/tidy.constants.php */ define('TIDY_NODETYPE_XMLDECL', 13); // End of tidy v.2.0 * XML response returned by XMLRPC method. *

    * @param string $encoding [optional]

    * Input encoding supported by iconv. *

    * @return mixed either an array, or an integer, or a string, or a boolean according * to the response returned by the XMLRPC method. */ function xmlrpc_decode($xml, $encoding = "iso-8859-1") {} /** * Decodes XML into native PHP types * @link https://php.net/manual/en/function.xmlrpc-decode-request.php * @param string $xml * @param string &$method * @param string $encoding [optional] * @return mixed */ function xmlrpc_decode_request($xml, &$method, $encoding = null) {} /** * Generates XML for a method request * @link https://php.net/manual/en/function.xmlrpc-encode-request.php * @param string $method

    * Name of the method to call. *

    * @param mixed $params

    * Method parameters compatible with method signature. *

    * @param null|array $output_options [optional]

    * Array specifying output options may contain (default values are * emphasised): * output_type: php, xml

    * @return string a string containing the XML representation of the request. */ function xmlrpc_encode_request($method, $params, ?array $output_options = null) {} /** * Gets xmlrpc type for a PHP value * @link https://php.net/manual/en/function.xmlrpc-get-type.php * @param mixed $value

    * PHP value *

    * @return string the XML-RPC type. */ function xmlrpc_get_type($value) {} /** * Sets xmlrpc type, base64 or datetime, for a PHP string value * @link https://php.net/manual/en/function.xmlrpc-set-type.php * @param string &$value

    * Value to set the type *

    * @param string $type

    * 'base64' or 'datetime' *

    * @return bool TRUE on success or FALSE on failure. * If successful, value is converted to an object. */ function xmlrpc_set_type(&$value, $type) {} /** * Determines if an array value represents an XMLRPC fault * @link https://php.net/manual/en/function.xmlrpc-is-fault.php * @param array $arg

    * Array returned by xmlrpc_decode. *

    * @return bool TRUE if the argument means fault, FALSE otherwise. Fault * description is available in $arg["faultString"], fault * code is in $arg["faultCode"]. */ function xmlrpc_is_fault(array $arg) {} /** * Creates an xmlrpc server * @link https://php.net/manual/en/function.xmlrpc-server-create.php * @return resource */ function xmlrpc_server_create() {} /** * Destroys server resources * @link https://php.net/manual/en/function.xmlrpc-server-destroy.php * @param resource $server * @return int */ function xmlrpc_server_destroy($server) {} /** * Register a PHP function to resource method matching method_name * @link https://php.net/manual/en/function.xmlrpc-server-register-method.php * @param resource $server * @param string $method_name * @param callable $function * @return bool */ function xmlrpc_server_register_method($server, $method_name, $function) {} /** * Parses XML requests and call methods * @link https://php.net/manual/en/function.xmlrpc-server-call-method.php * @param resource $server * @param string $xml * @param mixed $user_data * @param null|array $output_options [optional] * @return string */ function xmlrpc_server_call_method($server, $xml, $user_data, ?array $output_options = null) {} /** * Decodes XML into a list of method descriptions * @link https://php.net/manual/en/function.xmlrpc-parse-method-descriptions.php * @param string $xml * @return array */ function xmlrpc_parse_method_descriptions($xml) {} /** * Adds introspection documentation * @link https://php.net/manual/en/function.xmlrpc-server-add-introspection-data.php * @param resource $server * @param array $desc * @return int */ function xmlrpc_server_add_introspection_data($server, array $desc) {} /** * Register a PHP function to generate documentation * @link https://php.net/manual/en/function.xmlrpc-server-register-introspection-callback.php * @param resource $server * @param string $function * @return bool */ function xmlrpc_server_register_introspection_callback($server, $function) {} // End of xmlrpc v.0.51 setProperty('report', 'true'). * * @return XdmNode */ public function getValidationReport() {} /** * Set the parameters required for XQuery Processor * * @param string $name * @param XdmValue $value * @return void */ public function setParameter($name, $value) {} /** * Set properties for Schema Validator. * * @param string $name * @param string $value * @return void */ public function setProperty($name, $value) {} /** * Clear parameter values set * * @return void */ public function clearParameters() {} /** * Clear property values set * * @return void */ public function clearProperties() {} /** * Clear any exception thrown * * @return void */ public function exceptionClear() {} /** * Get the $i'th error code if there are any errors * * @param int $i * @return string */ public function getErrorCode($i) {} /** * Get the $i'th error message if there are any errors * * @param int $i * @return string */ public function getErrorMessage($i) {} /** * Get number of error during execution of the validator * * @return int */ public function getExceptionCount() {} } /** * @link https://www.saxonica.com/saxon-c/documentation/index.html#!api/saxon_c_php_api/saxon_c_php_xdmvalue */ class XdmValue { /** * Get the first item in the sequence * * @return XdmItem */ public function getHead() {} /** * Get the n'th item in the value, counting from zero * * @param int $index * @return XdmItem */ public function itemAt($index) {} /** * Get the number of items in the sequence * * @return int */ public function size() {} /** * Add item to the sequence at the end. * * @param XdmItem $item */ public function addXdmItem($item) {} } /** * @link https://www.saxonica.com/saxon-c/documentation/index.html#!api/saxon_c_php_api/saxon_c_php_xdmitem */ class XdmItem extends XdmValue { /** * Get the string value of the item. For a node, this gets the string value of the node. For an atomic value, it has the same effect as casting the value to a string. In all cases the result is the same as applying the XPath string() function. * * @return string */ public function getStringValue() {} /** * Determine whether the item is a node value or not. * * @return bool */ public function isNode() {} /** * Determine whether the item is an atomic value or not. * * @return bool */ public function isAtomic() {} /** * Provided the item is an atomic value we return the {@link XdmAtomicValue} otherwise return null * * @return XdmAtomicValue|null */ public function getAtomicValue() {} /** * Provided the item is a node value we return the {@link XdmNode} otherwise return null * * @return XdmNode|null */ public function getNodeValue() {} } /** * @link https://www.saxonica.com/saxon-c/documentation/index.html#!api/saxon_c_php_api/saxon_c_php_xdmnode */ class XdmNode extends XdmItem { /** * Get the string value of the item. For a node, this gets the string value of the node. * * @return string */ public function getStringValue() {} /** * Get the kind of node * * @return int */ public function getNodeKind() {} /** * Get the name of the node, as a EQName * * @return string */ public function getNodeName() {} /** * Determine whether the item is an atomic value or a node. This method will return FALSE as the item is not atomic * * @return false */ public function isAtomic() {} /** * Get the count of child node at this current node * * @return int */ public function getChildCount() {} /** * Get the count of attribute nodes at this node * * @return int */ public function getAttributeCount() {} /** * Get the n'th child node at this node. If the child node selected does not exist then return null * * @param int $index * @return XdmNode|null */ public function getChildNode($index) {} /** * Get the parent of this node. If parent node does not exist then return null * * @return XdmNode|null */ public function getParent() {} /** * Get the n'th attribute node at this node. If the attribute node selected does not exist then return null * * @param int $index * @return XdmNode|null */ public function getAttributeNode($index) {} /** * Get the n'th attribute node value at this node. If the attribute node selected does not exist then return null * * @param int $index * @return string|null */ public function getAttributeValue($index) {} } /** * @link https://www.saxonica.com/saxon-c/documentation/index.html#!api/saxon_c_php_api/saxon_c_php_xdmatomicvalue */ class XdmAtomicValue extends XdmItem { /** * Get the string value of the item. For an atomic value, it has the same effect as casting the value to a string. In all cases the result is the same as applying the XPath string() function. * * @return string */ public function getStringValue() {} /** * Get the value converted to a boolean using the XPath casting rules * * @return bool */ public function getBooleanValue() {} /** * Get the value converted to a float using the XPath casting rules. If the value is a string, the XSD 1.1 rules are used, which means that the string "+INF" is recognised * * @return float */ public function getDoubleValue() {} /** * Get the value converted to an integer using the XPath casting rules * * @return int */ public function getLongValue() {} /** * Determine whether the item is an atomic value or a node. Return TRUE if the item is an atomic value * * @return true */ public function isAtomic() {} } */ // start of PECL/rrd v1.0 /** * Gets latest error message * @link https://php.net/manual/en/function.rrd-error.php * @return string Latest error message. * @since PECL rrd >= 0.9.0 */ function rrd_error() {} /** * Creates rrd database file * @link https://php.net/manual/en/function.rrd-create.php * @param string $filename

    * Filename for newly created rrd file. *

    * @param array $options

    * Options for rrd create - list of strings. See man page of rrd create for whole list of options. *

    * @return bool TRUE on success or FALSE on failure. * @since PECL rrd >= 0.9.0 */ function rrd_create($filename, $options) {} /** * Gets data for graph output from RRD database file as array. This function has same result as rrd_graph(), but fetched data are returned as array, no image file is created. * @link https://php.net/manual/en/function.rrd-fetch.php * @param string $file

    * RRD database file name. *

    * @param array $options

    * Array of options for resolution specification. *

    * @return array Array with information about retrieved graph data. * @since PECL rrd >= 0.9.0 */ function rrd_fetch($file, $options) {} /** * Gets the timestamp of the first sample from from the specified RRA of the RRD file. * @link https://php.net/manual/en/function.rrd-first.php * @param string $file

    * RRD database file name. *

    * @param int $raaindex

    * The index number of the RRA that is to be examined. Default value is 0. *

    * @return int|false Integer as unix timestamp, FALSE if some error occurs. * @since PECL rrd >= 0.9.0 */ function rrd_first($file, $raaindex = 0) {} /** * Creates image from a data. * @link https://php.net/manual/en/function.rrd-graph.php * @param string $file

    * The filename to output the graph to. This will generally end in either .png, .svg or .eps, depending on the format you want to output. *

    * @param array $options

    * Options for generating image. See man page of rrd graph for all possible options. All options (data definitions, variable definitions, etc.) are allowed. *

    * @return array|false If image is created successfully an array with information about generated image is returned, FALSE when error occurs. * @since PECL rrd >= 0.9.0 */ function rrd_graph($file, $options) {} /** * Returns information about particular RRD database file. * @link https://php.net/manual/en/function.rrd-info.php * @param string $file

    * RRD database file name. *

    * @return array|false Array with information about requsted RRD file, FALSE when error occurs. * @since PECL rrd >= 0.9.0 */ function rrd_info($file) {} /** * Returns the UNIX timestamp of the most recent update of the RRD database. * @link https://php.net/manual/en/function.rrd-last.php * @param string $file

    * RRD database file name. *

    * @return int Integer as unix timestamp of the most recent data from the RRD database. * @since PECL rrd >= 0.9.0 */ function rrd_last($file) {} /** * Gets array of the UNIX timestamp and the values stored for each date in the most recent update of the RRD database file. * @link https://php.net/manual/en/function.rrd-lastupdate.php * @param string $file

    * RRD database file name. *

    * @return array|false Array of information about last update, FALSE when error occurs. * @since PECL rrd >= 0.9.0 */ function rrd_lastupdate($file) {} /** * Restores the RRD file from the XML dump. * @link https://php.net/manual/en/function.rrd-restore.php * @param string $xml_file

    * XML filename with the dump of the original RRD database file. *

    * @param string $rrd_file

    * Restored RRD database file name. *

    * @param array $options

    * Array of options for restoring. See man page for rrd restore. *

    * @return bool Returns TRUE on success, FALSE otherwise. * @since PECL rrd >= 0.9.0 */ function rrd_restore($xml_file, $rrd_file, $options = []) {} /** * Change some options in the RRD dabase header file. E.g. renames the source for the data etc. * @link https://php.net/manual/en/function.rrd-tune.php * @param string $file

    * RRD database file name. *

    * @param array $options

    * Options with RRD database file properties which will be changed. See rrd tune man page for details. *

    * @return bool Returns TRUE on success, FALSE otherwise. * @since PECL rrd >= 0.9.0 */ function rrd_tune($file, $options) {} /** * Updates the RRD database file. The input data is time interpolated according to the properties of the RRD database file. * @link https://php.net/manual/en/function.rrd-update.php * @param string $file

    * RRD database file name. This database will be updated. *

    * @param array $options

    * Options for updating the RRD database. This is list of strings. See man page of rrd update for whole list of options. *

    * @return bool Updates the RRD database file. The input data is time interpolated according to the properties of the RRD database file. * @since PECL rrd >= 0.9.0 */ function rrd_update($file, $options) {} /** * Returns information about underlying rrdtool library. * @link https://php.net/manual/en/function.rrd-version.php * @return string String with rrdtool version number e.g. "1.4.3". * @since PECL rrd >= 1.0.0 */ function rrd_version() {} /** * Exports the information about RRD database file. This data can be converted to XML file via user space PHP script and then restored back as RRD database file. * @link https://php.net/manual/en/function.rrd-xport.php * @param array $options

    * Array of options for the export, see rrd xport man page. *

    * @return array|false Array with information about RRD database file, FALSE when error occurs. * @since PECL rrd >= 0.9.0 */ function rrd_xport($options) {} /** * Close any outstanding connection to rrd caching daemon

    * This function is automatically called when the whole PHP process is terminated. It depends on used SAPI. For example, it's called automatically at the end of command line script.

    * It's up user whether he wants to call this function at the end of every request or otherwise.

    * @link https://php.net/manual/en/function.rrdc-disconnect.php * @return void * @since PECL rrd >= 1.1.2 */ function rrd_disconnect() {} /** * Close any outstanding connection to rrd caching daemon. * This function is automatically called when the whole PHP process is terminated. It depends on used SAPI. * For example, it's called automatically at the end of command line script. * It's up user whether he wants to call this function at the end of every request or otherwise. */ function rrdc_disconnect() {} /** * Class for creation of RRD database file. * @link https://php.net/manual/en/class.rrdcreator.php * @since PECL rrd >= 0.9.0 */ class RRDCreator { /** * Adds RRA - archive of data values for each data source.

    * Archive consists of a number of data values or statistics for each of the defined data-sources (DS). Data sources are defined by method RRDCreator::addDataSource(). You need call this method for each requested archive. *

    * @link https://php.net/manual/en/rrdcreator.addarchive.php * @see RRDCreator::addDataSource() * @param string $description

    * Class for creation of RRD database file. *

    * @return void * @since PECL rrd >= 0.9.0 */ public function addArchive($description) {} /** * Adds data source definition for RRD database.

    * RRD can accept input from several data sources (DS), e.g incoming and outgoing traffic. This method adds data source by description. You need call this method for each data source. *

    * @link https://php.net/manual/en/rrdcreator.adddatasource.php * @param string $description

    * Definition of data source - DS. This has same format as DS definition in rrd create command. See man page of rrd create for more details. *

    * @return void * @since PECL rrd >= 0.9.0 */ public function addDataSource($description) {} /** * Creates new RRDCreator instance. * @link https://php.net/manual/en/rrdcreator.construct.php * @param string $path

    * Path for newly created RRD database file. *

    * @param string $startTime

    * Time for the first value in RRD database. Parameter supports all formats which are supported by rrd create call. *

    * @param int $step

    * Base interval in seconds with which data will be fed into the RRD database. *

    * @since PECL rrd >= 0.9.0 */ public function __construct($path, $startTime = '', $step = 0) {} /** * Saves the RRD database into file, which name is defined by RRDCreator::__construct() * @link https://php.net/manual/en/rrdcreator.save.php * @see RRDCreator::__construct() * @return bool TRUE on success or FALSE on failure. * @since PECL rrd >= 0.9.0 */ public function save() {} } /** * Class for exporting data from RRD database to image file. * @link https://php.net/manual/en/class.rrdgraph.php * @since PECL rrd >= 0.9.0 */ class RRDGraph { /** * Creates new RRDGraph instance. This instance is responsible for rendering the result of RRD database query into image. * @link https://php.net/manual/en/rrdgraph.construct.php * @param string $path

    * Full path for the newly created image. *

    * @since PECL rrd >= 0.9.0 */ public function __construct($path) {} /** * Saves the result of RRD database query into image defined by RRDGraph::__construct(). * @link https://php.net/manual/en/rrdgraph.save.php * @return array|false Array with information about generated image is returned, FALSE if error occurs. * @since PECL rrd >= 0.9.0 */ public function save() {} /** * Saves the RRD database query into image and returns the verbose information about generated graph.

    * If "-" is used as image filename, image data are also returned in result array. *

    * @link https://php.net/manual/en/rrdgraph.saveverbose.php * @return array|false Array with detailed information about generated image is returned, optionally with image data, FALSE if error occurs. * @since PECL rrd >= 0.9.0 */ public function saveVerbose() {} /** * Sets the options for rrd graph export * @link https://php.net/manual/en/rrdgraph.setoptions.php * @param array $options

    * List of options for the image generation from the RRD database file. It can be list of strings or list of strings with keys for better readability. Read the rrd graph man pages for list of available options. *

    * @return void * @since PECL rrd >= 0.9.0 */ public function setOptions($options) {} } /** * Class for updating RDD database file. * @link https://php.net/manual/en/class.rrdupdater.php * @since PECL rrd >= 0.9.0 */ class RRDUpdater { /** * Creates new RRDUpdater instance. This instance is responsible for updating the RRD database file. * RRDUpdater constructor. * @link https://php.net/manual/en/rrdupdater.construct.php * @param string $path

    * Filesystem path for RRD database file, which will be updated. *

    * @since PECL rrd >= 0.9.0 */ public function __construct($path) {} /** * Update the RRD file defined via RRDUpdater::__construct(). The file is updated with a specific values. * @link https://php.net/manual/en/rrdupdater.update.php * @param array $values

    * Data for update. Key is data source name. *

    * @param string $time

    * Time value for updating the RRD with a particulat data. Default value is current time. *

    * @return bool TRUE on success or FALSE on failure. * @throws \Exception on error * @since PECL rrd >= 0.9.0 */ public function update($values, $time = '') {} } // end of PECL/rrd v1.0 getCode(). * This can be compared against the `SIMDJSON_ERR_*` constants. * * Before simdjson 2.1.0, a regular RuntimeException with an error code of 0 was thrown. */ class SimdJsonException extends RuntimeException {} /** * Thrown for error conditions on fields such as $depth that are not expected to be * from user-provided JSON, with similar behavior to php 8.0. * * NOTE: https://www.php.net/valueerror was added in php 8.0. * In older php versions, this extends Error instead. * * When support for php 8.0 is dropped completely, * a major release of simdjson will likely switch to a standard ValueError. */ class SimdJsonValueError extends ValueError {} CURLSSH_AUTH_PUBLICKEY, * CURLSSH_AUTH_PASSWORD, * CURLSSH_AUTH_HOST, * CURLSSH_AUTH_KEYBOARD. Set to * CURLSSH_AUTH_ANY to let libcurl pick one. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSH_AUTH_TYPES', 151); /** * TRUE tells the library to perform all the required proxy authentication * and connection setup, but no data transfer. This option is implemented for * HTTP, SMTP and POP3. * @since 5.5 * @link https://php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_CONNECT_ONLY', 141); /** * With the CURLOPT_FOLLOWLOCATION option disabled: * redirect URL found in the last transaction, that should be requested manually next. * With the CURLOPT_FOLLOWLOCATION option enabled: * this is empty. The redirect URL in this case is available in CURLINFO_EFFECTIVE_URL * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 5.3.7 */ define('CURLINFO_REDIRECT_URL', 1048607); /** * IP address of the most recent connection * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 5.4.7 */ define('CURLINFO_PRIMARY_IP', 1048608); /** * Destination port of the most recent connection * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 5.4.7 */ define('CURLINFO_PRIMARY_PORT', 2097192); /** * Local (source) IP address of the most recent connection * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 5.4.7 */ define('CURLINFO_LOCAL_IP', 1048617); /** * Local (source) port of the most recent connection * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 5.4.7 */ define('CURLINFO_LOCAL_PORT', 2097194); /** * A result of {@see curl_share_init()}. Makes the cURL handle to use the data from the shared handle. * @link https://php.net/manual/en/function.curl-setopt.php * @since 5.5 */ define('CURLOPT_SHARE', 10100); /** * Allows an application to select what kind of IP addresses to use when resolving host names. * This is only interesting when using host names that resolve addresses using more than one version of IP, * possible values are CURL_IPRESOLVE_WHATEVER, CURL_IPRESOLVE_V4, CURL_IPRESOLVE_V6, by default CURL_IPRESOLVE_WHATEVER. * @link https://php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_IPRESOLVE', 113); /** * Value for the CURLOPT_IPRESOLVE option. * Default, resolves addresses to all IP versions that your system allows. * @link https://www.php.net/manual/en/function.curl-setopt.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_IPRESOLVE.html */ define('CURL_IPRESOLVE_WHATEVER', 0); /** * Value for the CURLOPT_IPRESOLVE option. * Resolve to IPv4 addresses. * @link https://www.php.net/manual/en/function.curl-setopt.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_IPRESOLVE.html */ define('CURL_IPRESOLVE_V4', 1); /** * Value for the CURLOPT_IPRESOLVE option. * Resolve to IPv6 addresses. * @link https://www.php.net/manual/en/function.curl-setopt.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_IPRESOLVE.html */ define('CURL_IPRESOLVE_V6', 2); /** * TRUE to use a global DNS cache. This option is not thread-safe. * It is conditionally enabled by default if PHP is built for non-threaded use (CLI, FCGI, Apache2-Prefork, etc.). * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_DNS_USE_GLOBAL_CACHE', 91); /** * The number of seconds to keep DNS entries in memory. * This option is set to 120 (2 minutes) by default. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_DNS_CACHE_TIMEOUT', 92); /** * An alternative port number to connect to. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_PORT', 3); /** * The file that the transfer should be written to. The default is STDOUT (the browser window). * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FILE', 10001); /** * Custom pointer passed to the read callback. * If you use the CURLOPT_READFUNCTION option, this is the pointer you'll get as input in the 4th argument to the callback. * @link https://www.php.net/manual/en/function.curl-setopt.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_READDATA.html */ define('CURLOPT_READDATA', 10009); /** * The file that the transfer should be read from when uploading. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_INFILE', 10009); /** * The expected size, in bytes, of the file when uploading a file to a remote site. * Note that using this option will not stop libcurl from sending more data, as exactly what is sent depends on CURLOPT_READFUNCTION. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_INFILESIZE', 14); /** * The URL to fetch. This can also be set when initializing a session with {@see curl_init()}. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_URL', 10002); /** * The HTTP proxy to tunnel requests through. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_PROXY', 10004); /** * TRUE to output verbose information. * Writes output to STDERR, or the file specified using CURLOPT_STDERR. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_VERBOSE', 41); /** * TRUE to include the header in the output. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_HEADER', 42); /** * An array of HTTP header fields to set, in the format array('Content-type: text/plain', 'Content-length: 100') * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_HTTPHEADER', 10023); /** * TRUE to disable the progress meter for cURL transfers. * (PHP automatically sets this option to TRUE, this should only be changed for debugging purposes.) * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_NOPROGRESS', 43); /** * A callback accepting five parameters. * The first is the cURL resource, * the second is the total number of bytes expected to be downloaded in this transfer, * the third is the number of bytes downloaded so far, * the fourth is the total number of bytes expected to be uploaded in this transfer, * and the fifth is the number of bytes uploaded so far. * (The callback is only called when the CURLOPT_NOPROGRESS option is set to FALSE.) * Return a non-zero value to abort the transfer. In which case, the transfer will set a CURLE_ABORTED_BY_CALLBACK error. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.3 */ define('CURLOPT_PROGRESSFUNCTION', 20056); /** * TRUE to exclude the body from the output. Request method is then set to HEAD. Changing this to FALSE does not change it to GET. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_NOBODY', 44); /** * TRUE to fail verbosely if the HTTP code returned is greater than or equal to 400. * The default behavior is to return the page normally, ignoring the code. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FAILONERROR', 45); /** * TRUE to prepare for an upload. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_UPLOAD', 46); /** * TRUE to do a regular HTTP POST. * This POST is the normal application/x-www-form-urlencoded kind, most commonly used by HTML forms. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_POST', 47); /** * TRUE to only list the names of an FTP directory. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FTPLISTONLY', 48); /** * TRUE to append to the remote file instead of overwriting it. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FTPAPPEND', 50); /** * TRUE to scan the ~/.netrc file to find a username and password for the remote site that a connection is being established with. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_NETRC', 51); /** * A bitmask of 1 (301 Moved Permanently), 2 (302 Found) and 4 (303 See Other) if the HTTP POST method should be maintained * when CURLOPT_FOLLOWLOCATION is set and a specific type of redirect occurs. * @link https://secure.php.net/manual/en/function.curl-setopt.php * @since 5.3.2 */ define('CURLOPT_POSTREDIR', 161); /** * TRUE to output SSL certification information to STDERR on secure transfers. * Requires CURLOPT_VERBOSE to be on to have an effect. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.3.2 */ define('CURLOPT_CERTINFO', 172); /** * An alias of CURLOPT_TRANSFERTEXT. Use that instead. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FTPASCII', -1); /** * TRUE to be completely silent with regards to the cURL functions. * @link https://www.php.net/manual/en/function.curl-setopt.php * @deprecated use CURLOPT_RETURNTRANSFER instead since cURL 7.15.5 */ define('CURLOPT_MUTE', -1); /** * Bitmask of CURLPROTO_* values. If used, this bitmask limits what protocols libcurl may use in the transfer. * This allows you to have a libcurl built to support a wide range of protocols but still limit specific transfers * to only be allowed to use a subset of them. * By default libcurl will accept all protocols it supports. See also CURLOPT_REDIR_PROTOCOLS. * Valid protocol options are: * CURLPROTO_HTTP, CURLPROTO_HTTPS, CURLPROTO_FTP, CURLPROTO_FTPS, CURLPROTO_SCP, CURLPROTO_SFTP, * CURLPROTO_TELNET, CURLPROTO_LDAP, CURLPROTO_LDAPS, CURLPROTO_DICT, CURLPROTO_FILE, CURLPROTO_TFTP, * CURLPROTO_ALL * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.2.10 */ define('CURLOPT_PROTOCOLS', 181); /** * Bitmask of CURLPROTO_* values. If used, this bitmask limits what protocols libcurl may use in a transfer * that it follows to in a redirect when CURLOPT_FOLLOWLOCATION is enabled. * This allows you to limit specific transfers to only be allowed to use a subset of protocols in redirections. * By default libcurl will allow all protocols except for FILE and SCP. * This is a difference compared to pre-7.19.4 versions which unconditionally would follow to all protocols supported. * See also CURLOPT_PROTOCOLS for protocol constant values. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.2.10 */ define('CURLOPT_REDIR_PROTOCOLS', 182); /** * If a download exceeds this speed (counted in bytes per second) on cumulative average during the transfer, * the transfer will pause to keep the average rate less than or equal to the parameter value. * Defaults to unlimited speed. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.4 */ define('CURLOPT_MAX_RECV_SPEED_LARGE', 30146); /** * If an upload exceeds this speed (counted in bytes per second) on cumulative average during the transfer, * the transfer will pause to keep the average rate less than or equal to the parameter value. * Defaults to unlimited speed. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.4 */ define('CURLOPT_MAX_SEND_SPEED_LARGE', 30145); /** * A callback accepting three parameters. * The first is the cURL resource, the second is a string containing a password prompt, and the third is the maximum password length. * Return the string containing the password. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_PASSWDFUNCTION', -1); /** * TRUE to follow any "Location: " header that the server sends as part of the HTTP header * (note this is recursive, PHP will follow as many "Location: " headers that it is sent, unless CURLOPT_MAXREDIRS is set). * This constant is not available when open_basedir * or safe_mode are enabled. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FOLLOWLOCATION', 52); /** * TRUE to HTTP PUT a file. The file to PUT must be set with CURLOPT_INFILE and CURLOPT_INFILESIZE. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_PUT', 54); /** * A username and password formatted as "[username]:[password]" to use for the connection. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_USERPWD', 10005); /** * A username and password formatted as "[username]:[password]" to use for the connection to the proxy. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_PROXYUSERPWD', 10006); /** * Range(s) of data to retrieve in the format "X-Y" where X or Y are optional. * HTTP transfers also support several intervals, separated with commas in the format "X-Y,N-M". * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_RANGE', 10007); /** * The maximum number of seconds to allow cURL functions to execute. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_TIMEOUT', 13); /** * The maximum number of milliseconds to allow cURL functions to execute. * If libcurl is built to use the standard system name resolver, * that portion of the connect will still use full-second resolution for timeouts with a minimum timeout allowed of one second. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.2 */ define('CURLOPT_TIMEOUT_MS', 155); /** * The full data to post in a HTTP "POST" operation. * To post a file, prepend a filename with @ and use the full path. * The filetype can be explicitly specified by following the filename with the type in the format ';type=mimetype'. * This parameter can either be passed * as a urlencoded string like 'para1=val1¶2=val2&...' * or as an array with the field name as key and field data as value. * If value is an array, the Content-Type header will be set to multipart/form-data. * As of PHP 5.2.0, value must be an array if files are passed to this option with the @ prefix. * As of PHP 5.5.0, the @ prefix is deprecated and files can be sent using CURLFile. * The @ prefix can be disabled for safe passing of values beginning with @ by setting the CURLOPT_SAFE_UPLOAD option to TRUE. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_POSTFIELDS', 10015); /** * The contents of the "Referer: " header to be used in a HTTP request. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_REFERER', 10016); /** * A string containing 32 hexadecimal digits. * The string should be the MD5 checksum of the remote host's public key, and libcurl will reject the connection to the host unless the md5sums match. * This option is only for SCP and SFTP transfers. * @link https://php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSH_HOST_PUBLIC_KEY_MD5', 10162); /** * The file name for your public key. If not used, libcurl defaults to $HOME/.ssh/id_dsa.pub * if the HOME environment variable is set, and just "id_dsa.pub" in the current directory if HOME is not set. * @link https://php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSH_PUBLIC_KEYFILE', 10152); /** * The file name for your private key. If not used, libcurl defaults to $HOME/.ssh/id_dsa * if the HOME environment variable is set, and just "id_dsa" in the current directory if HOME is not set. * If the file is password-protected, set the password with CURLOPT_KEYPASSWD. * @link https://php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSH_PRIVATE_KEYFILE', 10153); /** * The contents of the "User-Agent: " header to be used in a HTTP request. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_USERAGENT', 10018); /** * The value which will be used to get the IP address to use for the FTP "PORT" instruction. * The "PORT" instruction tells the remote server to connect to our specified IP address. * The string may be a plain IP address, a hostname, a network interface name (under Unix), * or just a plain '-' to use the systems default IP address. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FTPPORT', 10017); /** * TRUE to first try an EPSV command for FTP transfers before reverting back to PASV. Set to FALSE to disable EPSV. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FTP_USE_EPSV', 85); /** * The transfer speed, in bytes per second, that the transfer should be below during the count of CURLOPT_LOW_SPEED_TIME seconds * before PHP considers the transfer too slow and aborts. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_LOW_SPEED_LIMIT', 19); /** * The number of seconds the transfer speed should be below CURLOPT_LOW_SPEED_LIMIT * before PHP considers the transfer too slow and aborts. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_LOW_SPEED_TIME', 20); /** * The offset, in bytes, to resume a transfer from. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_RESUME_FROM', 21); /** * The contents of the "Cookie: " header to be used in the HTTP request. * Note that multiple cookies are separated with a semicolon followed by a space (e.g., "fruit=apple; colour=red") * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_COOKIE', 10022); /** * TRUE to mark this as a new cookie "session". * It will force libcurl to ignore all cookies it is about to load that are "session cookies" from the previous session. * By default, libcurl always stores and loads all cookies, independent if they are session cookies or not. * Session cookies are cookies without expiry date and they are meant to be alive and existing for this "session" only. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_COOKIESESSION', 96); /** * TRUE to automatically set the Referer: field in requests where it follows a Location: redirect. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_AUTOREFERER', 58); /** * The name of a file containing a PEM formatted certificate. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSLCERT', 10025); /** * The password required to use the CURLOPT_SSLCERT certificate. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSLCERTPASSWD', 10026); /** * The file that the header part of the transfer is written to. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_WRITEHEADER', 10029); /** * 1 to check the existence of a common name in the SSL peer certificate. (Deprecated) * 2 to check the existence of a common name and also verify that it matches the hostname provided. * 0 to not check the names. In production environments the value of this option should be kept at 2 (default value). * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSL_VERIFYHOST', 81); /** * The name of the file containing the cookie data. * The cookie file can be in Netscape format, or just plain HTTP-style headers dumped into a file. * If the name is an empty string, no cookies are loaded, but cookie handling is still enabled. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_COOKIEFILE', 10031); /** * One of CURL_SSLVERSION_DEFAULT (0), CURL_SSLVERSION_TLSv1 (1), CURL_SSLVERSION_SSLv2 (2), CURL_SSLVERSION_SSLv3 (3), * CURL_SSLVERSION_TLSv1_0 (4), CURL_SSLVERSION_TLSv1_1 (5) or CURL_SSLVERSION_TLSv1_2 (6). * The maximum TLS version can be set by using one of the CURL_SSLVERSION_MAX_* constants. * It is also possible to OR one of the CURL_SSLVERSION_* constants with one of the CURL_SSLVERSION_MAX_* constants. * CURL_SSLVERSION_MAX_DEFAULT (the maximum version supported by the library), CURL_SSLVERSION_MAX_TLSv1_0, CURL_SSLVERSION_MAX_TLSv1_1, * CURL_SSLVERSION_MAX_TLSv1_2, or CURL_SSLVERSION_MAX_TLSv1_3. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSLVERSION', 32); /** * Value for the CURLOPT_SSLVERSION option. * @link https://www.php.net/manual/en/curl.constants.php */ define('CURL_SSLVERSION_DEFAULT', 0); /** * Value for the CURLOPT_SSLVERSION option. * @link https://www.php.net/manual/en/curl.constants.php */ define('CURL_SSLVERSION_TLSv1', 1); /** * Value for the CURLOPT_SSLVERSION option. * @link https://www.php.net/manual/en/curl.constants.php */ define('CURL_SSLVERSION_SSLv2', 2); /** * Value for the CURLOPT_SSLVERSION option. * @link https://www.php.net/manual/en/curl.constants.php */ define('CURL_SSLVERSION_SSLv3', 3); /** * Value for the CURLOPT_SSLVERSION option. * @link https://www.php.net/manual/en/curl.constants.php * @since 5.6.3 * @since 5.5.19 */ define('CURL_SSLVERSION_TLSv1_0', 4); /** * Value for the CURLOPT_SSLVERSION option. * @link https://www.php.net/manual/en/curl.constants.php * @since 5.6.3 * @since 5.5.19 */ define('CURL_SSLVERSION_TLSv1_1', 5); /** * Value for the CURLOPT_SSLVERSION option. * @link https://www.php.net/manual/en/curl.constants.php * @since 5.6.3 * @since 5.5.19 */ define('CURL_SSLVERSION_TLSv1_2', 6); /** * How CURLOPT_TIMEVALUE is treated. * Use CURL_TIMECOND_IFMODSINCE to return the page only if it has been modified since the time specified in CURLOPT_TIMEVALUE. * If it hasn't been modified, a "304 Not Modified" header will be returned assuming CURLOPT_HEADER is TRUE. * Use CURL_TIMECOND_IFUNMODSINCE for the reverse effect. * CURL_TIMECOND_IFMODSINCE is the default. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_TIMECONDITION', 33); /** * The time in seconds since January 1st, 1970. * The time will be used by CURLOPT_TIMECONDITION. By default, CURL_TIMECOND_IFMODSINCE is used. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_TIMEVALUE', 34); /** * A custom request method to use instead of "GET" or "HEAD" when doing a HTTP request. * This is useful for doing "DELETE" or other, more obscure HTTP requests. * Valid values are things like "GET", "POST", "CONNECT" and so on; i.e. Do not enter a whole HTTP request line here. * For instance, entering "GET /index.html HTTP/1.0\r\n\r\n" would be incorrect. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_CUSTOMREQUEST', 10036); /** * An alternative location to output errors to instead of STDERR. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_STDERR', 10037); /** * TRUE to use ASCII mode for FTP transfers. * For LDAP, it retrieves data in plain text instead of HTML. * On Windows systems, it will not set STDOUT to binary mode. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_TRANSFERTEXT', 53); /** * TRUE to return the transfer as a string of the return value of {@see curl_exec()} instead of outputting it directly. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_RETURNTRANSFER', 19913); /** * An array of FTP commands to execute on the server prior to the FTP request. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_QUOTE', 10028); /** * An array of FTP commands to execute on the server after the FTP request has been performed. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_POSTQUOTE', 10039); /** * The name of the outgoing network interface to use. This can be an interface name, an IP address or a host name. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_INTERFACE', 10062); /** * The KRB4 (Kerberos 4) security level. * Any of the following values (in order from least to most powerful) are valid: "clear", "safe", "confidential", "private". * If the string does not match one of these, "private" is used. * Setting this option to NULL will disable KRB4 security. Currently KRB4 security only works with FTP transactions. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_KRB4LEVEL', 10063); /** * TRUE to tunnel through a given HTTP proxy. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_HTTPPROXYTUNNEL', 61); /** * TRUE to attempt to retrieve the modification date of the remote document. * This value can be retrieved using the CURLINFO_FILETIME option with {@see curl_getinfo()}. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FILETIME', 69); /** * A callback accepting two parameters. The first is the cURL resource, and the second is a string with the data to be written. * The data must be saved by this callback. It must return the exact number of bytes written or the transfer will be aborted with an error. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_WRITEFUNCTION', 20011); /** * A callback accepting three parameters. * The first is the cURL resource, * the second is a stream resource provided to cURL through the option CURLOPT_INFILE, * and the third is the maximum amount of data to be read. * The callback must return a string with a length equal or smaller than the amount of data requested, typically by reading it from the passed stream resource. * It should return an empty string to signal EOF. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_READFUNCTION', 20012); /** * A callback accepting two parameters. The first is the cURL resource, the second is a string with the header data to be written. * The header data must be written by this callback. Return the number of bytes written. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_HEADERFUNCTION', 20079); /** * The maximum amount of HTTP redirections to follow. Use this option alongside CURLOPT_FOLLOWLOCATION. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_MAXREDIRS', 68); /** * The maximum amount of persistent connections that are allowed. * When the limit is reached, CURLOPT_CLOSEPOLICY is used to determine which connection to close. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_MAXCONNECTS', 71); /** * This option is deprecated, as it was never implemented in cURL and never had any effect. * @link https://www.php.net/manual/en/function.curl-setopt.php * @removed 5.6 */ define('CURLOPT_CLOSEPOLICY', 72); /** * TRUE to force the use of a new connection instead of a cached one. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FRESH_CONNECT', 74); /** * TRUE to force the connection to explicitly close when it has finished processing, and not be pooled for reuse. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FORBID_REUSE', 75); /** * A filename to be used to seed the random number generator for SSL. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_RANDOM_FILE', 10076); /** * Like CURLOPT_RANDOM_FILE, except a filename to an Entropy Gathering Daemon socket. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_EGDSOCKET', 10077); /** * The number of seconds to wait while trying to connect. Use 0 to wait indefinitely. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_CONNECTTIMEOUT', 78); /** * The number of milliseconds to wait while trying to connect. Use 0 to wait indefinitely. * If libcurl is built to use the standard system name resolver, that portion of the connect * will still use full-second resolution for timeouts with a minimum timeout allowed of one second. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.2.3 */ define('CURLOPT_CONNECTTIMEOUT_MS', 156); /** * FALSE to stop cURL from verifying the peer's certificate. * Alternate certificates to verify against can be specified with the CURLOPT_CAINFO option or * a certificate directory can be specified with the CURLOPT_CAPATH option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSL_VERIFYPEER', 64); /** * The name of a file holding one or more certificates to verify the peer with. * This only makes sense when used in combination with CURLOPT_SSL_VERIFYPEER. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_CAINFO', 10065); /** * A directory that holds multiple CA certificates. Use this option alongside CURLOPT_SSL_VERIFYPEER. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_CAPATH', 10097); /** * The name of a file to save all internal cookies to when the handle is closed, e.g. after a call to curl_close. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_COOKIEJAR', 10082); /** * A list of ciphers to use for SSL. For example, RC4-SHA and TLSv1 are valid cipher lists. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSL_CIPHER_LIST', 10083); /** * TRUE to return the raw output when CURLOPT_RETURNTRANSFER is used. * @link https://www.php.net/manual/en/function.curl-setopt.php * @deprecated 5.1.3 */ define('CURLOPT_BINARYTRANSFER', 19914); /** * TRUE to ignore any cURL function that causes a signal to be sent to the PHP process. * This is turned on by default in multi-threaded SAPIs so timeout options can still be used. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_NOSIGNAL', 99); /** * Either CURLPROXY_HTTP (default), CURLPROXY_SOCKS4, CURLPROXY_SOCKS5, CURLPROXY_SOCKS4A or CURLPROXY_SOCKS5_HOSTNAME. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_PROXYTYPE', 101); /** * The size of the buffer to use for each read. There is no guarantee this request will be fulfilled, however. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_BUFFERSIZE', 98); /** * TRUE to reset the HTTP request method to GET. Since GET is the default, this is only necessary if the request method has been changed. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_HTTPGET', 80); /** * CURL_HTTP_VERSION_NONE (default, lets CURL decide which version to use), * CURL_HTTP_VERSION_1_0 (forces HTTP/1.0), CURL_HTTP_VERSION_1_1 (forces HTTP/1.1), CURL_HTTP_VERSION_2_0 (attempts HTTP 2), * CURL_HTTP_VERSION_2 (alias of CURL_HTTP_VERSION_2_0), CURL_HTTP_VERSION_2TLS (attempts HTTP 2 over TLS (HTTPS) only) or * CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE (issues non-TLS HTTP requests using HTTP/2 without HTTP/1.1 Upgrade). * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_HTTP_VERSION', 84); /** * The name of a file containing a private SSL key. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSLKEY', 10087); /** * The key type of the private SSL key specified in CURLOPT_SSLKEY. * Supported key types are "PEM" (default), "DER", and "ENG". * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSLKEYTYPE', 10088); /** * The secret password needed to use the private SSL key specified in CURLOPT_SSLKEY. * (Since this option contains a sensitive password, remember to keep the PHP script it is contained within safe) * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSLKEYPASSWD', 10026); /** * The identifier for the crypto engine of the private SSL key specified in CURLOPT_SSLKEY. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSLENGINE', 10089); /** * The identifier for the crypto engine used for asymmetric crypto operations. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSLENGINE_DEFAULT', 90); /** * The format of the certificate. * Supported formats are "PEM" (default), "DER", and "ENG". As of OpenSSL 0.9.3, "P12" (for PKCS#12-encoded files) is also supported. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_SSLCERTTYPE', 10086); /** * TRUE to convert Unix newlines to CRLF newlines on transfers. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_CRLF', 27); /** * The contents of the "Accept-Encoding: " header. This enables decoding of the response. * Supported encodings are "identity", "deflate", and "gzip". * If an empty string, "", is set, a header containing all supported encoding types is sent. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_ENCODING', 10102); /** * The port number of the proxy to connect to. This port number can also be set in CURLOPT_PROXY. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_PROXYPORT', 59); /** * TRUE to keep sending the username and password when following locations * (using CURLOPT_FOLLOWLOCATION), even when the hostname has changed. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_UNRESTRICTED_AUTH', 105); /** * TRUE to use EPRT (and LPRT) when doing active FTP downloads. Use FALSE to disable EPRT and LPRT and use PORT only. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FTP_USE_EPRT', 106); /** * TRUE to disable TCP's Nagle algorithm, which tries to minimize the number of small packets on the network. * @link https://php.net/manual/en/curl.constants.php * @since 5.2.1 */ define('CURLOPT_TCP_NODELAY', 121); /** * An array of HTTP 200 responses that will be treated as valid responses and not as errors. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_HTTP200ALIASES', 10104); /** * Value for the CURLOPT_TIMECONDITION option. * Return the page only if it has been modified since the time specified in CURLOPT_TIMEVALUE. * @link https://www.php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_TIMECONDITION.html */ define('CURL_TIMECOND_IFMODSINCE', 1); /** * Value for the CURLOPT_TIMECONDITION option. * Return the page if it hasn't been modified since the time specified in CURLOPT_TIMEVALUE. * @link https://www.php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_TIMECONDITION.html */ define('CURL_TIMECOND_IFUNMODSINCE', 2); /** * Value for the CURLOPT_TIMECONDITION option. * @link https://www.php.net/manual/en/curl.constants.php */ define('CURL_TIMECOND_LASTMOD', 3); /** * The HTTP authentication method(s) to use. * The options are: CURLAUTH_BASIC, CURLAUTH_DIGEST, CURLAUTH_GSSNEGOTIATE, CURLAUTH_NTLM, CURLAUTH_ANY, and CURLAUTH_ANYSAFE. * The bitwise | (or) operator can be used to combine more than one method. * If this is done, cURL will poll the server to see what methods it supports and pick the best one. * CURLAUTH_ANY is an alias for CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM. * CURLAUTH_ANYSAFE is an alias for CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_HTTPAUTH', 107); /** * Value for the CURLOPT_HTTPAUTH option. * Allows username/password authentication. * @link https://curl.haxx.se/libcurl/c/CURLOPT_HTTPAUTH.html */ define('CURLAUTH_BASIC', 1); /** * Value for the CURLOPT_HTTPAUTH option. * @link https://www.php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_HTTPAUTH.html */ define('CURLAUTH_DIGEST', 2); /** * Value for the CURLOPT_HTTPAUTH option. * @link https://www.php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_HTTPAUTH.html */ define('CURLAUTH_GSSNEGOTIATE', 4); /** * Value for the CURLOPT_HTTPAUTH option. * @link https://www.php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_HTTPAUTH.html */ define('CURLAUTH_NTLM', 8); /** * Value for the CURLOPT_HTTPAUTH option. * Is an alias for CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM. * @link https://www.php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_HTTPAUTH.html */ define('CURLAUTH_ANY', -17); /** * Value for the CURLOPT_HTTPAUTH option. * Is an alias for CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM. * @link https://www.php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_HTTPAUTH.html */ define('CURLAUTH_ANYSAFE', -18); /** * The HTTP authentication method(s) to use for the proxy connection. * Use the same bitmasks as described in CURLOPT_HTTPAUTH. * For proxy authentication, only CURLAUTH_BASIC and CURLAUTH_NTLM are currently supported. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_PROXYAUTH', 111); /** * TRUE to create missing directories when an FTP operation encounters a path that currently doesn't exist. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_FTP_CREATE_MISSING_DIRS', 110); /** * Any data that should be associated with this cURL handle. * This data can subsequently be retrieved with the CURLINFO_PRIVATE option of {@see curl_getinfo()}. cURL does nothing with this data. * When using a cURL multi handle, this private data is typically a unique key to identify a standard cURL handle. * @link https://php.net/manual/en/curl.constants.php * @since 5.2.4 */ define('CURLOPT_PRIVATE', 10103); /** * The last response code * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_RESPONSE_CODE', 2097154); /** * The CONNECT response code * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_HTTP_CONNECTCODE', 2097174); /** * Bitmask indicating the authentication method(s) available according to the previous response * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_HTTPAUTH_AVAIL', 2097175); /** * Bitmask indicating the proxy authentication method(s) available according to the previous response * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_PROXYAUTH_AVAIL', 2097176); /** * Errno from a connect failure. The number is OS and system specific. * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_OS_ERRNO', 2097177); /** * Number of connections curl had to create to achieve the previous transfer * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_NUM_CONNECTS', 2097178); /** * OpenSSL crypto-engines supported * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_SSL_ENGINES', 4194331); /** * All known cookies * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_COOKIELIST', 4194332); /** * Entry path in FTP server * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_FTP_ENTRY_PATH', 1048606); /** * Time in seconds it took from the start until the SSL/SSH connect/handshake to the remote host was completed * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_APPCONNECT_TIME', 3145761); /** * TLS certificate chain * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_CERTINFO', 4194338); /** * Info on unmet time conditional * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_CONDITION_UNMET', 2097187); /** * Next RTSP client CSeq * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_RTSP_CLIENT_CSEQ', 2097189); /** * Recently received CSeq * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_RTSP_CSEQ_RECV', 2097191); /** * Next RTSP server CSeq * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_RTSP_SERVER_CSEQ', 2097190); /** * RTSP session ID * @link https://php.net/manual/en/function.curl-getinfo.php * @since 5.5 */ define('CURLINFO_RTSP_SESSION_ID', 1048612); /** * Value for the CURLOPT_CLOSEPOLICY option. * @link https://www.php.net/manual/en/curl.constants.php * @removed 5.6 */ define('CURLCLOSEPOLICY_LEAST_RECENTLY_USED', 2); /** * Value for the CURLOPT_CLOSEPOLICY option. * @link https://www.php.net/manual/en/curl.constants.php * @removed 5.6 */ define('CURLCLOSEPOLICY_LEAST_TRAFFIC', 3); /** * Value for the CURLOPT_CLOSEPOLICY option. * @link https://www.php.net/manual/en/curl.constants.php * @removed 5.6 */ define('CURLCLOSEPOLICY_SLOWEST', 4); /** * Value for the CURLOPT_CLOSEPOLICY option. * @link https://www.php.net/manual/en/curl.constants.php * @removed 5.6 */ define('CURLCLOSEPOLICY_CALLBACK', 5); /** * Value for the CURLOPT_CLOSEPOLICY option. * @link https://www.php.net/manual/en/curl.constants.php * @removed 5.6 */ define('CURLCLOSEPOLICY_OLDEST', 1); /** * Last effective URL * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_EFFECTIVE_URL', 1048577); /** * As of PHP 5.5.0 and cURL 7.10.8, this is a legacy alias of CURLINFO_RESPONSE_CODE. * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_HTTP_CODE', 2097154); /** * Total size of all headers received * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_HEADER_SIZE', 2097163); /** * Total size of issued requests, currently only for HTTP requests * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_REQUEST_SIZE', 2097164); /** * Total transaction time in seconds for last transfer * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_TOTAL_TIME', 3145731); /** * Time in seconds until name resolving was complete * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_NAMELOOKUP_TIME', 3145732); /** * Time in seconds it took to establish the connection * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_CONNECT_TIME', 3145733); /** * Time in seconds from start until just before file transfer begins * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_PRETRANSFER_TIME', 3145734); /** * Total number of bytes uploaded * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_SIZE_UPLOAD', 3145735); /** * Total number of bytes downloaded * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_SIZE_DOWNLOAD', 3145736); /** * Average download speed * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_SPEED_DOWNLOAD', 3145737); /** * Average upload speed * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_SPEED_UPLOAD', 3145738); /** * Remote time of the retrieved document, with the CURLOPT_FILETIME enabled; * if -1 is returned the time of the document is unknown * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_FILETIME', 2097166); /** * Result of SSL certification verification requested by setting CURLOPT_SSL_VERIFYPEER * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_SSL_VERIFYRESULT', 2097165); /** * Content length of download, read from Content-Length: field * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_CONTENT_LENGTH_DOWNLOAD', 3145743); /** * Specified size of upload * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_CONTENT_LENGTH_UPLOAD', 3145744); /** * Time in seconds until the first byte is about to be transferred * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_STARTTRANSFER_TIME', 3145745); /** * Content-Type: of the requested document. NULL indicates server did not send valid Content-Type: header * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_CONTENT_TYPE', 1048594); /** * Time in seconds of all redirection steps before final transaction was started, * with the CURLOPT_FOLLOWLOCATION option enabled * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_REDIRECT_TIME', 3145747); /** * Number of redirects, with the CURLOPT_FOLLOWLOCATION option enabled * @link https://www.php.net/manual/en/function.curl-getinfo.php */ define('CURLINFO_REDIRECT_COUNT', 2097172); /** * TRUE to track the handle's request string * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 5.1.3 */ define('CURLINFO_HEADER_OUT', 2); /** * Private data associated with this cURL handle, previously set with the CURLOPT_PRIVATE option of {@see curl_getinfo()} * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 5.2.4 */ define('CURLINFO_PRIVATE', 1048597); /** * @since 8.3 */ define('CURLINFO_CAPATH', 1048638); /** * @since 8.3 */ define('CURLINFO_CAINFO', 1048637); /** * Supports IPv6 * @link https://php.net/manual/en/curl.constants.php */ define('CURL_VERSION_IPV6', 1); /** * Supports Kerberos V4 (when using FTP) * @link https://php.net/manual/en/curl.constants.php */ define('CURL_VERSION_KERBEROS4', 2); /** * Supports SSL (HTTPS/FTPS) * @link https://php.net/manual/en/curl.constants.php */ define('CURL_VERSION_SSL', 4); /** * Supports HTTP deflate using libz * @link https://php.net/manual/en/curl.constants.php */ define('CURL_VERSION_LIBZ', 8); /** * Will be the most recent age value for the libcurl. * @link https://php.net/manual/en/curl.constants.php */ define('CURLVERSION_NOW', 10); /** * All fine. Proceed as usual. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_OK', 0); /** * @since 8.3 */ define('CURLKHMATCH_OK', 0); /** * @since 8.3 */ define('CURLKHMATCH_MISMATCH', 1); /** * @since 8.3 */ define('CURLKHMATCH_MISSING', 2); /** * @since 8.3 */ define('CURLKHMATCH_LAST', 3); /** * @since 8.3 */ define('CURLOPT_MIME_OPTIONS', 315); /** * @since 8.3 */ define('CURLMIMEOPT_FORMESCAPE', 1); /** * The URL you passed to libcurl used a protocol that this libcurl does not support. * The support might be a compile-time option that you didn't use, * it can be a misspelled protocol string or just a protocol libcurl has no code for. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_UNSUPPORTED_PROTOCOL', 1); /** * Very early initialization code failed. * This is likely to be an internal error or problem, * or a resource problem where something fundamental couldn't get done at init time. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FAILED_INIT', 2); /** * The URL was not properly formatted. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_URL_MALFORMAT', 3); /** * A requested feature, protocol or option was not found built-in in this libcurl due to a build-time decision. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_URL_MALFORMAT_USER', 4); /** * Couldn't resolve proxy. The given proxy host could not be resolved. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_COULDNT_RESOLVE_PROXY', 5); /** * Couldn't resolve host. The given remote host was not resolved. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_COULDNT_RESOLVE_HOST', 6); /** * Failed to connect to host or proxy. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_COULDNT_CONNECT', 7); /** * The server sent data libcurl couldn't parse. * This error code was known as as CURLE_FTP_WEIRD_SERVER_REPLY before 7.51.0. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_WEIRD_SERVER_REPLY', 8); /** * We were denied access to the resource given in the URL. * For FTP, this occurs while trying to change to the remote directory. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_ACCESS_DENIED', 9); /** * While waiting for the server to connect back when an active FTP session is used, * an error code was sent over the control connection or similar. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_USER_PASSWORD_INCORRECT', 10); /** * After having sent the FTP password to the server, libcurl expects a proper reply. * This error code indicates that an unexpected code was returned. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_WEIRD_PASS_REPLY', 11); /** * During an active FTP session while waiting for the server to connect, * the CURLOPT_ACCEPTTIMEOUT_MS (or the internal default) timeout expired. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_WEIRD_USER_REPLY', 12); /** * Libcurl failed to get a sensible result back from the server as a response to either a PASV or a EPSV command. * The server is flawed. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_WEIRD_PASV_REPLY', 13); /** * FTP servers return a 227-line as a response to a PASV command. * If libcurl fails to parse that line, this return code is passed back. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_WEIRD_227_FORMAT', 14); /** * An internal failure to lookup the host used for the new connection. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_CANT_GET_HOST', 15); /** * A problem was detected in the HTTP2 framing layer. * This is somewhat generic and can be one out of several problems, see the error buffer for details. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_CANT_RECONNECT', 16); /** * Received an error when trying to set the transfer mode to binary or ASCII. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_COULDNT_SET_BINARY', 17); /** * A file transfer was shorter or larger than expected. * This happens when the server first reports an expected transfer size, and then delivers data * that doesn't match the previously given size. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_PARTIAL_FILE', 18); /** * This was either a weird reply to a 'RETR' command or a zero byte transfer complete. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_COULDNT_RETR_FILE', 19); /** * After a completed file transfer, the FTP server did not respond a proper * @link https://php.net/manual/en/curl.constants.php */ define('CURLE_FTP_WRITE_ERROR', 20); /** * When sending custom "QUOTE" commands to the remote server, * one of the commands returned an error code that was 400 or higher (for FTP) or otherwise indicated unsuccessful completion of the command. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_QUOTE_ERROR', 21); /** * This is returned if CURLOPT_FAILONERROR is set TRUE and the HTTP server returns an error code that is >= 400. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_HTTP_NOT_FOUND', 22); /** * An error occurred when writing received data to a local file, or an error was returned to libcurl from a write callback. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_WRITE_ERROR', 23); /** * @link https://php.net/manual/en/curl.constants.php */ define('CURLE_MALFORMAT_USER', 24); /** * Failed starting the upload. For FTP, the server typically denied the STOR command. * The error buffer usually contains the server's explanation for this. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_COULDNT_STOR_FILE', 25); /** * There was a problem reading a local file or an error returned by the read callback. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_READ_ERROR', 26); /** * A memory allocation request failed. This is serious badness and things are severely screwed up if this ever occurs. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_OUT_OF_MEMORY', 27); /** * Operation timeout. The specified time-out period was reached according to the conditions. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_OPERATION_TIMEOUTED', 28); /** * libcurl failed to set ASCII transfer type (TYPE A). * @link https://php.net/manual/en/curl.constants.php */ define('CURLE_FTP_COULDNT_SET_ASCII', 29); /** * The FTP PORT command returned error. * This mostly happens when you haven't specified a good enough address for libcurl to use. See CURLOPT_FTPPORT. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_PORT_FAILED', 30); /** * The FTP REST command returned error. This should never happen if the server is sane. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_COULDNT_USE_REST', 31); /** * The FTP SIZE command returned error. SIZE is not a kosher FTP command, * it is an extension and not all servers support it. * @link https://php.net/manual/en/curl.constants.php */ define('CURLE_FTP_COULDNT_GET_SIZE', 32); /** * The server does not support or accept range requests. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_HTTP_RANGE_ERROR', 33); /** * This is an odd error that mainly occurs due to internal confusion. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_HTTP_POST_ERROR', 34); /** * A problem occurred somewhere in the SSL/TLS handshake. * You really want the error buffer and read the message there as it pinpoints the problem slightly more. * Could be certificates (file formats, paths, permissions), passwords, and others. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_SSL_CONNECT_ERROR', 35); /** * The download could not be resumed because the specified offset was out of the file boundary. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_BAD_DOWNLOAD_RESUME', 36); /** * A file given with FILE:// couldn't be opened. * Most likely because the file path doesn't identify an existing file. Did you check file permissions? * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FILE_COULDNT_READ_FILE', 37); /** * LDAP cannot bind. LDAP bind operation failed. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_LDAP_CANNOT_BIND', 38); /** * LDAP search failed. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_LDAP_SEARCH_FAILED', 39); /** * Library not found. The LDAP library was not found. * @link https://php.net/manual/en/curl.constants.php */ define('CURLE_LIBRARY_NOT_FOUND', 40); /** * Function not found. A required zlib function was not found. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FUNCTION_NOT_FOUND', 41); /** * Aborted by callback. A callback returned "abort" to libcurl. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_ABORTED_BY_CALLBACK', 42); /** * A function was called with a bad parameter. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_BAD_FUNCTION_ARGUMENT', 43); /** * This is never returned * @link https://php.net/manual/en/curl.constants.php */ define('CURLE_BAD_CALLING_ORDER', 44); /** * Interface error. A specified outgoing interface could not be used. * Set which interface to use for outgoing connections' source IP address with CURLOPT_INTERFACE. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_HTTP_PORT_FAILED', 45); /** * This is never returned * @link https://php.net/manual/en/curl.constants.php */ define('CURLE_BAD_PASSWORD_ENTERED', 46); /** * Too many redirects. When following redirects, libcurl hit the maximum amount. * Set your limit with CURLOPT_MAXREDIRS. * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_TOO_MANY_REDIRECTS', 47); /** * An option passed to libcurl is not recognized/known. Refer to the appropriate documentation. * This is most likely a problem in the program that uses libcurl. * The error buffer might contain more specific information about which exact option it concerns. * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_UNKNOWN_TELNET_OPTION', 48); /** * A telnet option string was Illegally formatted. * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_TELNET_OPTION_SYNTAX', 49); /** * Currently unused. * @link https://php.net/manual/en/curl.constants.php */ define('CURLE_OBSOLETE', 50); /** * The remote server's SSL certificate or SSH md5 fingerprint was deemed not OK. * This error code has been unified with CURLE_SSL_CACERT since 7.62.0. Its previous value was 51. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_SSL_PEER_CERTIFICATE', 60); /** * Nothing was returned from the server, and under the circumstances, getting nothing is considered an error. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_GOT_NOTHING', 52); /** * The specified crypto engine wasn't found. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_SSL_ENGINE_NOTFOUND', 53); /** * Failed setting the selected SSL crypto engine as default! * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_SSL_ENGINE_SETFAILED', 54); /** * Failed sending network data. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_SEND_ERROR', 55); /** * Failure with receiving network data. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_RECV_ERROR', 56); /** * The share object is currently in use. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_SHARE_IN_USE', 57); /** * Problem with the local client certificate. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_SSL_CERTPROBLEM', 58); /** * Couldn't use specified cipher. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_SSL_CIPHER', 59); /** * The remote server's SSL certificate or SSH md5 fingerprint was deemed not OK. * This error code has been unified with CURLE_SSL_PEER_CERTIFICATE since 7.62.0. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_SSL_CACERT', 60); /** * Unrecognized transfer encoding. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_BAD_CONTENT_ENCODING', 61); /** * Invalid LDAP URL. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_LDAP_INVALID_URL', 62); /** * Maximum file size exceeded. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FILESIZE_EXCEEDED', 63); /** * Requested FTP SSL level failed. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLE_FTP_SSL_FAILED', 64); /** * Value for the CURLOPT_PROXYTYPE option. * @link https://php.net/manual/en/curl.constants.php */ define('CURLPROXY_HTTP', 0); /** * Value for the CURLOPT_PROXYTYPE option. * @link https://php.net/manual/en/curl.constants.php */ define('CURLPROXY_SOCKS4', 4); /** * Value for the CURLOPT_PROXYTYPE option. * @link https://php.net/manual/en/curl.constants.php */ define('CURLPROXY_SOCKS5', 5); /** * Value for the CURLOPT_NETRC option. * The use of the ~/.netrc file is optional, and information in the URL is to be preferred. * The file will be scanned for the host and user name (to find the password only) or for the host only, * to find the first user name and password after that machine, which ever information is not specified. * @link https://curl.haxx.se/libcurl/c/CURLOPT_NETRC.html */ define('CURL_NETRC_OPTIONAL', 1); /** * Value for the CURLOPT_NETRC option. * The library will ignore the ~/.netrc file. This is the default. * @link https://curl.haxx.se/libcurl/c/CURLOPT_NETRC.html */ define('CURL_NETRC_IGNORED', 0); /** * Value for the CURLOPT_NETRC option. * The use of the ~/.netrc file is required, and information in the URL is to be ignored. * The file will be scanned for the host and user name (to find the password only) or for the host only, * to find the first user name and password after that machine, which ever information is not specified. * @link https://curl.haxx.se/libcurl/c/CURLOPT_NETRC.html */ define('CURL_NETRC_REQUIRED', 2); /** * Value for the CURLOPT_HTTP_VERSION option. * Let's CURL decide which version to use. * @link https://php.net/manual/en/curl.constants.php */ define('CURL_HTTP_VERSION_NONE', 0); /** * Value for the CURLOPT_HTTP_VERSION option. * Forces HTTP/1.0. * @link https://php.net/manual/en/curl.constants.php */ define('CURL_HTTP_VERSION_1_0', 1); /** * Value for the CURLOPT_HTTP_VERSION option. * Forces HTTP/1.1. * @link https://php.net/manual/en/curl.constants.php */ define('CURL_HTTP_VERSION_1_1', 2); /** * Value for the CURLOPT_HTTP_VERSION option. * Attempts HTTP 2. * @link https://php.net/manual/en/curl.constants.php */ define('CURL_HTTP_VERSION_2_0', 3); /** * This is not really an error. It means you should call {@see curl_multi_exec()} again without doing select() or similar in between. * Before version 7.20.0 this could be returned by {@see curl_multi_exec()}, but in later versions this return code is never used. * @link https://www.php.net/manual/en/function.curl-multi-exec.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLM_CALL_MULTI_PERFORM', -1); /** * Things are fine. * @link https://www.php.net/manual/en/function.curl-multi-exec.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLM_OK', 0); /** * The passed-in handle is not a valid CURLM handle. * @link https://www.php.net/manual/en/function.curl-multi-exec.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLM_BAD_HANDLE', 1); /** * An easy handle was not good/valid. It could mean that it isn't an easy handle at all, * or possibly that the handle already is in use by this or another multi handle. * @link https://www.php.net/manual/en/function.curl-multi-exec.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLM_BAD_EASY_HANDLE', 2); /** * Out of memory error. * @link https://www.php.net/manual/en/function.curl-multi-exec.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLM_OUT_OF_MEMORY', 3); /** * libcurl' internal error. * @link https://www.php.net/manual/en/function.curl-multi-exec.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define('CURLM_INTERNAL_ERROR', 4); /** * The message identifies a transfer that is done, and then result contains the return code for the easy handle that just completed. * Other return values are currently not available. * @link https://www.php.net/manual/en/function.curl-multi-info-read.php * @link https://curl.haxx.se/libcurl/c/curl_multi_info_read.html */ define('CURLMSG_DONE', 1); /** * The FTP authentication method (when is activated): * CURLFTPAUTH_SSL (try SSL first), CURLFTPAUTH_TLS (try TLS first), or CURLFTPAUTH_DEFAULT (let cURL decide). * @link https://php.net/manual/en/curl.constants.php */ define('CURLOPT_FTPSSLAUTH', 129); /** * Value for the CURLOPT_FTPSSLAUTH option. * Let cURL decide FTP authentication method. * @link https://php.net/manual/en/curl.constants.php */ define('CURLFTPAUTH_DEFAULT', 0); /** * Value for the CURLOPT_FTPSSLAUTH option. * Try SSL first as FTP authentication method. * @link https://php.net/manual/en/curl.constants.php */ define('CURLFTPAUTH_SSL', 1); /** * Value for the CURLOPT_FTPSSLAUTH option. * Try TLS first as FTP authentication method. * @link https://php.net/manual/en/curl.constants.php */ define('CURLFTPAUTH_TLS', 2); /** * @link https://php.net/manual/en/curl.constants.php * @deprecated use CURLOPT_USE_SSL instead. */ define('CURLOPT_FTP_SSL', 119); /** * Value for the CURLOPT_FTP_SSL option. * Don't attempt to use SSL. * @link https://php.net/manual/en/curl.constants.php */ define('CURLFTPSSL_NONE', 0); /** * Value for the CURLOPT_FTP_SSL option. * Try using SSL, proceed as normal otherwise. * @link https://php.net/manual/en/curl.constants.php */ define('CURLFTPSSL_TRY', 1); /** * Value for the CURLOPT_FTP_SSL option. * Require SSL for the control connection or fail. * @link https://php.net/manual/en/curl.constants.php */ define('CURLFTPSSL_CONTROL', 2); /** * Value for the CURLOPT_FTP_SSL option. * Require SSL for all communication or fail. * @link https://php.net/manual/en/curl.constants.php */ define('CURLFTPSSL_ALL', 3); /** * Tell curl which method to use to reach a file on a FTP(S) server. * Possible values are CURLFTPMETHOD_MULTICWD, CURLFTPMETHOD_NOCWD and CURLFTPMETHOD_SINGLECWD. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.3 */ define('CURLOPT_FTP_FILEMETHOD', 138); /** * Ignore the IP address in the PASV response * @link https://curl.haxx.se/libcurl/c/CURLOPT_FTP_SKIP_PASV_IP.html */ define('CURLOPT_FTP_SKIP_PASV_IP', 137); /** * TRUE to disable support for the @ prefix for uploading files in CURLOPT_POSTFIELDS, * which means that values starting with @ can be safely passed as fields. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.5 * @deprecated 7.0 Use CURLFile for uploads instead. */ define('CURLOPT_SAFE_UPLOAD', -1); /** * Value for the CURLOPT_FTP_FILEMETHOD option. * libcurl does a single CWD operation for each path part in the given URL. * For deep hierarchies this means many commands. This is how RFC 1738 says it should be done. This is the default but the slowest behavior. * @link https://www.php.net/manual/en/curl.constants.php */ define('CURLFTPMETHOD_MULTICWD', 1); /** * Value for the CURLOPT_FTP_FILEMETHOD option. * libcurl does no CWD at all. * libcurl will do SIZE, RETR, STOR etc and give a full path to the server for all these commands. This is the fastest behavior. * @link https://www.php.net/manual/en/curl.constants.php */ define('CURLFTPMETHOD_NOCWD', 2); /** * Value for the CURLOPT_FTP_FILEMETHOD option. * libcurl does one CWD with the full target directory and then operates on the file "normally" (like in the multicwd case). * This is somewhat more standards compliant than 'nocwd' but without the full penalty of 'multicwd'. * @link https://www.php.net/manual/en/curl.constants.php */ define('CURLFTPMETHOD_SINGLECWD', 3); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_HTTP', 1); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_HTTPS', 2); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_FTP', 4); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_FTPS', 8); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_SCP', 16); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_SFTP', 32); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_TELNET', 64); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_LDAP', 128); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_LDAPS', 256); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_DICT', 512); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_FILE', 1024); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_TFTP', 2048); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLPROTO_ALL', -1); /** * As of cURL 7.43.0, the value is a bitmask. * Pass 1 to enable or 0 to disable. * Enabling pipelining on a multi handle will make it attempt to perform HTTP Pipelining as far as possible for transfers * using this handle. This means that if you add a second request that can use an already existing connection, * the second request will be "piped" on the same connection. * Pass 2 to try to multiplex the new transfer over an existing HTTP/2 connection if possible. * Pass 3 instructs cURL to ask for pipelining and multiplexing independently of each other. * As of cURL 7.62.0, setting the pipelining bit has no effect. * Instead of integer literals, you can also use the CURLPIPE_* constants if available. * @link https://www.php.net/manual/en/function.curl-multi-setopt.php * @since 5.5 */ define('CURLMOPT_PIPELINING', 3); /** * Pass a number that will be used as the maximum amount of simultaneously open connections that libcurl may cache. * By default the size will be enlarged to fit four times the number of handles added via {@see curl_multi_add_handle()}. * When the cache is full, curl closes the oldest one in the cache to prevent the number of open connections from increasing. * @link https://www.php.net/manual/en/function.curl-multi-setopt.php * @since 5.5 */ define('CURLMOPT_MAXCONNECTS', 6); /** * Specifies a type of data that should be shared. * @link https://www.php.net/manual/en/function.curl-share-setopt.php */ define('CURLSHOPT_SHARE', 1); /** * Specifies a type of data that will be no longer shared. * @link https://www.php.net/manual/en/function.curl-share-setopt.php */ define('CURLSHOPT_UNSHARE', 2); /** * Value for the CURLSHOPT_SHARE option. * Shares cookie data. * @link https://www.php.net/manual/en/function.curl-share-setopt.php */ define('CURL_LOCK_DATA_COOKIE', 2); /** * Value for the CURLSHOPT_SHARE option. * Shares DNS cache. Note that when you use cURL multi handles, * all handles added to the same multi handle will share DNS cache by default. * @link https://www.php.net/manual/en/function.curl-share-setopt.php */ define('CURL_LOCK_DATA_DNS', 3); /** * Value for the CURLSHOPT_SHARE option. * Shares SSL session IDs, reducing the time spent on the SSL handshake when reconnecting to the same server. * Note that SSL session IDs are reused within the same handle by default. * @link https://www.php.net/manual/en/function.curl-share-setopt.php */ define('CURL_LOCK_DATA_SSL_SESSION', 4); /** * The password required to use the CURLOPT_SSLKEY or CURLOPT_SSH_PRIVATE_KEYFILE private key. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define('CURLOPT_KEYPASSWD', 10026); /** * Value for the CURLOPT_FTP_CREATE_MISSING_DIRS option. * libcurl will attempt to create any remote directory that it fails to "move" into. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_FTP_CREATE_MISSING_DIRS.html * @since 7.0.7 */ define('CURLFTP_CREATE_DIR', 1); /** * Value for the CURLOPT_FTP_CREATE_MISSING_DIRS option. * libcurl will not attempt to create any remote directory that it fails to "move" into. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_FTP_CREATE_MISSING_DIRS.html * @since 7.0.7 */ define('CURLFTP_CREATE_DIR_NONE', 0); /** * Value for the CURLOPT_HTTPAUTH option. * NTLM delegating to winbind helper. * Authentication is performed by a separate binary application that is executed when needed. * The name of the application is specified at compile time but is typically /usr/bin/ntlm_auth. * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURLAUTH_NTLM_WB', 32); /** * Value for the CURLOPT_HTTP_VERSION option. * Alias of CURL_HTTP_VERSION_2_0 * Attempts HTTP 2 * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURL_HTTP_VERSION_2', 3); /** * Value for the CURLOPT_HTTP_VERSION option. * Attempts HTTP 2 over TLS (HTTPS) only * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURL_HTTP_VERSION_2TLS', 4); /** * Value for the CURLOPT_HTTP_VERSION option. * Issues non-TLS HTTP requests using HTTP/2 without HTTP/1.1 Upgrade * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE', 5); /** * TRUE to enable sending the initial response in the first packet. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_SASL_IR', 218); /** * Set the name of the network interface that the DNS resolver should bind to. This must be an interface name (not an address). * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_DNS_INTERFACE', 10221); /** * Set the local IPv4 address that the resolver should bind to. The argument should contain a single numerical IPv4 address as a string. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_DNS_LOCAL_IP4', 10222); /** * Set the local IPv6 address that the resolver should bind to. The argument should contain a single numerical IPv6 address as a string. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_DNS_LOCAL_IP6', 10223); /** * Specifies the OAuth 2.0 access token. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_XOAUTH2_BEARER', 10220); /** * Can be used to set protocol specific login options, such as the preferred authentication mechanism via "AUTH=NTLM" or "AUTH=*", * and should be used in conjunction with the CURLOPT_USERNAME option. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_LOGIN_OPTIONS', 10224); /** * The timeout for Expect: 100-continue responses in milliseconds. Defaults to 1000 milliseconds. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_EXPECT_100_TIMEOUT_MS', 227); /** * FALSE to disable ALPN in the SSL handshake (if the SSL backend libcurl is built to use supports it), * which can be used to negotiate http2. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_SSL_ENABLE_ALPN', 226); /** * FALSE to disable NPN in the SSL handshake (if the SSL backend libcurl is built to use supports it), * which can be used to negotiate http2. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_SSL_ENABLE_NPN', 225); /** * Set the pinned public key. The string can be the file name of your pinned public key. The file format expected is "PEM" or "DER". * The string can also be any number of base64 encoded sha256 hashes preceded by "sha256//" and separated by ";". * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_PINNEDPUBLICKEY', 10230); /** * Enables the use of Unix domain sockets as connection endpoint and sets the path to the given string. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_UNIX_SOCKET_PATH', 10231); /** * TRUE to verify the certificate's status. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_SSL_VERIFYSTATUS', 232); /** * TRUE to not handle dot dot sequences. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_PATH_AS_IS', 234); /** * TRUE to enable TLS false start. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_SSL_FALSESTART', 233); /** * TRUE to wait for pipelining/multiplexing. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_PIPEWAIT', 237); /** * The proxy authentication service name. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_PROXY_SERVICE_NAME', 10235); /** * The authentication service name. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_SERVICE_NAME', 10236); /** * @since 8.3 */ define('CURLOPT_SSH_HOSTKEYFUNCTION', 20316); /** * @since 8.3 */ define('CURLOPT_PROTOCOLS_STR', 10318); /** * @since 8.3 */ define('CURLOPT_REDIR_PROTOCOLS_STR', 10319); /** * @since 8.3 */ define('CURLOPT_WS_OPTIONS', 320); /** * @since 8.3 */ define('CURLWS_RAW_MODE', 1); /** * @since 8.3 */ define('CURLOPT_CA_CACHE_TIMEOUT', 321); /** * @since 8.3 */ define('CURLOPT_QUICK_EXIT', 322); /** * Value for the CURLOPT_SSH_AUTH_TYPES option. * libcurl attempts to connect to ssh-agent or pageant and let the agent attempt the authentication. * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURLSSH_AUTH_AGENT', 16); /** * Value for the CURLMOPT_PIPELINING option. * Default, which means doing no attempts at pipelining or multiplexing. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLMOPT_PIPELINING.html * @since 7.0.7 */ define('CURLPIPE_NOTHING', 0); /** * Value for the CURLMOPT_PIPELINING option. * If this bit is set, libcurl will try to pipeline HTTP/1.1 requests on connections that are already established and in use to hosts. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLMOPT_PIPELINING.html * @deprecated 7.4 * @since 7.0.7 */ define('CURLPIPE_HTTP1', 1); /** * Value for the CURLMOPT_PIPELINING option. * If this bit is set, libcurl will try to multiplex the new transfer over an existing connection if possible. This requires HTTP/2. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLMOPT_PIPELINING.html * @since 7.0.7 */ define('CURLPIPE_MULTIPLEX', 2); /** * Value for the CURLOPT_HEADEROPT option. * Makes CURLOPT_HTTPHEADER headers only get sent to a server and not to a proxy. * Proxy headers must be set with CURLOPT_PROXYHEADER to get used. * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURLHEADER_SEPARATE', 1); /** * Value for the CURLOPT_HEADEROPT option. * The headers specified in CURLOPT_HTTPHEADER will be used in requests both to servers and proxies. * With this option enabled, CURLOPT_PROXYHEADER will not have any effect. * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURLHEADER_UNIFIED', 0); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURLPROTO_SMB', 67108864); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURLPROTO_SMBS', 134217728); /** * How to deal with headers. * One of the following constants: * CURLHEADER_UNIFIED: the headers specified in CURLOPT_HTTPHEADER will be used in requests both to servers and proxies. * With this option enabled, CURLOPT_PROXYHEADER will not have any effect. * CURLHEADER_SEPARATE: makes CURLOPT_HTTPHEADER headers only get sent to a server and not to a proxy. * Proxy headers must be set with CURLOPT_PROXYHEADER to get used. * Note that if a non-CONNECT request is sent to a proxy, libcurl will send both server headers and proxy headers. * When doing CONNECT, libcurl will send CURLOPT_PROXYHEADER headers only to the proxy and then CURLOPT_HTTPHEADER headers only to the server. * Defaults to CURLHEADER_SEPARATE as of cURL 7.42.1, and CURLHEADER_UNIFIED before. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_HEADEROPT', 229); /** * An array of custom HTTP headers to pass to proxies. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define('CURLOPT_PROXYHEADER', 10228); /** * Value for the CURLOPT_POSTREDIR option. * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURL_REDIR_POST_301', 1); /** * Value for the CURLOPT_POSTREDIR option. * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURL_REDIR_POST_302', 2); /** * Value for the CURLOPT_POSTREDIR option. * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURL_REDIR_POST_303', 4); /** * Value for the CURLOPT_PROXYTYPE option. * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURLPROXY_HTTP_1_0', 1); /** * Value for the CURLOPT_POSTREDIR option. * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURL_REDIR_POST_ALL', 7); /** * Pass a number that specifies the chunk length threshold for pipelining in bytes. * @link https://www.php.net/manual/en/function.curl-multi-setopt.php * @since 7.0.7 */ define('CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE', 30010); /** * Pass a number that specifies the size threshold for pipelining penalty in bytes. * @link https://www.php.net/manual/en/function.curl-multi-setopt.php * @since 7.0.7 */ define('CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE', 30009); /** * Pass a number that specifies the maximum number of connections to a single host. * @link https://www.php.net/manual/en/function.curl-multi-setopt.php * @since 7.0.7 */ define('CURLMOPT_MAX_HOST_CONNECTIONS', 7); /** * Pass a number that specifies the maximum number of requests in a pipeline. * @link https://www.php.net/manual/en/function.curl-multi-setopt.php * @since 7.0.7 */ define('CURLMOPT_MAX_PIPELINE_LENGTH', 8); /** * Pass a number that specifies the maximum number of simultaneously open connections. * @link https://www.php.net/manual/en/function.curl-multi-setopt.php * @since 7.0.7 */ define('CURLMOPT_MAX_TOTAL_CONNECTIONS', 13); /** * Value for the CURLOPT_FTP_CREATE_MISSING_DIRS option. * libcurl will not attempt to create any remote directory that it fails to "move" into. * Tells libcurl to retry the CWD command again if the subsequent MKD command fails. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_FTP_CREATE_MISSING_DIRS.html * @since 7.0.7 */ define('CURLFTP_CREATE_DIR_RETRY', 2); /** * Value for the CURLOPT_HTTPAUTH option. * HTTP Negotiate (SPNEGO) authentication * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURLAUTH_NEGOTIATE', 4); /** * Pass a callable that will be registered to handle server pushes and should have the following signature: * parent_ch * The parent cURL handle (the request the client made). * pushed_ch * A new cURL handle for the pushed request. * headers * The push promise headers. * The push function is supposed to return either CURL_PUSH_OK if it can handle the push, * or CURL_PUSH_DENY to reject it. * @link https://www.php.net/manual/en/function.curl-multi-setopt.php * @since 7.1 */ define('CURLMOPT_PUSHFUNCTION', 20014); /** * Returned value from the push function - can handle the push. * @link https://www.php.net/manual/en/function.curl-multi-setopt.php * @since 7.1 */ define('CURL_PUSH_OK', 0); /** * Returned value from the push function - can't handle the push. * @link https://www.php.net/manual/en/function.curl-multi-setopt.php * @since 7.1 */ define('CURL_PUSH_DENY', 1); /** * The default buffer size for CURLOPT_BUFFERSIZE * @link https://php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURL_MAX_READ_SIZE', 10485760); /** * Enables the use of an abstract Unix domain socket instead of establishing a TCP connection to a host and sets the path to the given string. * This option shares the same semantics as CURLOPT_UNIX_SOCKET_PATH. * These two options share the same storage and therefore only one of them can be set per handle. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_ABSTRACT_UNIX_SOCKET', 10264); /** * Value for the CURLOPT_SSLVERSION option. * @link https://php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_SSLVERSION_MAX_DEFAULT', 65536); /** * Value for the CURLOPT_SSLVERSION option. * @link https://php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_SSLVERSION_MAX_NONE', 0); /** * Value for the CURLOPT_SSLVERSION option. * @link https://php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_SSLVERSION_MAX_TLSv1_0', 262144); /** * Value for the CURLOPT_SSLVERSION option. * @link https://php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_SSLVERSION_MAX_TLSv1_1', 327680); /** * Value for the CURLOPT_SSLVERSION option. * @link https://php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_SSLVERSION_MAX_TLSv1_2', 393216); /** * Value for the CURLOPT_SSLVERSION option. * @link https://php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_SSLVERSION_MAX_TLSv1_3', 458752); /** * TRUE to suppress proxy CONNECT response headers from the user callback functions * CURLOPT_HEADERFUNCTION and CURLOPT_WRITEFUNCTION, * when CURLOPT_HTTPPROXYTUNNEL is used and a CONNECT request is made. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_SUPPRESS_CONNECT_HEADERS', 265); /** * Value for the CURLOPT_HTTPAUTH option. * Allows GSS-API authentication. * @link https://php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURLAUTH_GSSAPI', 4); /** * The content-length of the download. This is the value read from the Content-Type: field. -1 if the size isn't known * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_CONTENT_LENGTH_DOWNLOAD_T', 6291471); /** * The specified size of the upload. -1 if the size isn't known * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_CONTENT_LENGTH_UPLOAD_T', 6291472); /** * Total number of bytes that were downloaded. * The number is only for the latest transfer and will be reset again for each new transfer * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_SIZE_DOWNLOAD_T', 6291464); /** * Total number of bytes that were uploaded * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_SIZE_UPLOAD_T', 6291463); /** * The average download speed in bytes/second that curl measured for the complete download * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_SPEED_DOWNLOAD_T', 6291465); /** * The average upload speed in bytes/second that curl measured for the complete upload * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_SPEED_UPLOAD_T', 6291466); /** * Specify an alternative target for this request * @link https://www.php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/CURLOPT_REQUEST_TARGET.html * @since 7.3 */ define('CURLOPT_REQUEST_TARGET', 10266); /** * The SOCKS5 authentication method(s) to use. The options are: CURLAUTH_BASIC, CURLAUTH_GSSAPI, CURLAUTH_NONE. * The bitwise | (or) operator can be used to combine more than one method. If this is done, * cURL will poll the server to see what methods it supports and pick the best one. * CURLAUTH_BASIC allows username/password authentication. * CURLAUTH_GSSAPI allows GSS-API authentication. * CURLAUTH_NONE allows no authentication. * Defaults to CURLAUTH_BASIC|CURLAUTH_GSSAPI. * Set the actual username and password with the CURLOPT_PROXYUSERPWD option. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_SOCKS5_AUTH', 267); /** * TRUE to enable built-in SSH compression. This is a request, not an order; the server may or may not do it. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_SSH_COMPRESSION', 268); /** * libcurl was build with multiple ssh backends. * @link https://php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_MULTI_SSL', 4194304); /** * Supports HTTP Brotli content encoding using libbrotlidec * @link https://php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_BROTLI', 8388608); /** * Value for the CURLSHOPT_SHARE option. * Put the connection cache in the share object and make all easy handles using this share object share the connection cache. * Using this, you can for example do multi-threaded libcurl use with one handle in each thread, and yet * have a shared pool of unused connections and this way get way better connection re-use * than if you use one separate pool in each thread. * Connections that are used for HTTP/1.1 Pipelining or HTTP/2 multiplexing only get additional transfers * added to them if the existing connection is held by the same multi or easy handle. * libcurl does not support doing HTTP/2 streams in different threads using a shared connection. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/curl_share_setopt.html * @since 7.3 */ define('CURL_LOCK_DATA_CONNECT', 5); /** * Value for the CURLOPT_SSH_AUTH_TYPES option. * @link https://php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURLSSH_AUTH_GSSAPI', 32); /** * Remote time of the retrieved document (as Unix timestamp), * an alternative to CURLINFO_FILETIME to allow systems with 32 bit long variables to extract dates * outside of the 32bit timestamp range * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_FILETIME_T', 6291470); /** * Head start for ipv6 for the happy eyeballs algorithm. * Happy eyeballs attempts to connect to both IPv4 and IPv6 addresses for dual-stack hosts, * preferring IPv6 first for timeout milliseconds. * Defaults to CURL_HET_DEFAULT, which is currently 200 milliseconds. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS', 271); /** * The time in seconds since January 1st, 1970. * The time will be used by CURLOPT_TIMECONDITION. Defaults to zero. * The difference between this option and CURLOPT_TIMEVALUE is the type of the argument. * On systems where 'long' is only 32 bit wide, this option has to be used to set dates beyond the year 2038. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_TIMEVALUE_LARGE', 30270); /** * TRUE to shuffle the order of all returned addresses so that they will be used in a random order, * when a name is resolved and more than one IP address is returned. * This may cause IPv4 to be used before IPv6 or vice versa. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_DNS_SHUFFLE_ADDRESSES', 275); /** * TRUE to send an HAProxy PROXY protocol v1 header at the start of the connection. * The default action is not to send this header. * @link https://php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURLOPT_HAPROXYPROTOCOL', 274); /** * Value for the CURLSHOPT_SHARE option. * The Public Suffix List stored in the share object is made available to all easy handle bound to the later. * Since the Public Suffix List is periodically refreshed, this avoids updates in too many different contexts. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/curl_share_setopt.html * @since 7.3 */ define('CURL_LOCK_DATA_PSL', 6); /** * Value for the CURLOPT_HTTPAUTH option. * HTTP Bearer token authentication, used primarily in OAuth 2.0 protocol. * @link https://php.net/manual/en/curl.constants.php * https://curl.haxx.se/libcurl/c/CURLOPT_HTTPAUTH.html * @since 7.3 */ define('CURLAUTH_BEARER', 64); /** * Time, in microseconds, it took from the start until the SSL/SSH connect/handshake to the remote host was completed * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_APPCONNECT_TIME_T', 6291512); /** * Total time taken, in microseconds, from the start until the connection to the remote host (or proxy) was completed * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_CONNECT_TIME_T', 6291508); /** * Time in microseconds from the start until the name resolving was completed * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_NAMELOOKUP_TIME_T', 6291507); /** * Time taken from the start until the file transfer is just about to begin, in microseconds * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_PRETRANSFER_TIME_T', 6291509); /** * Total time, in microseconds, * it took for all redirection steps include name lookup, connect, pretransfer and transfer before final transaction was started * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_REDIRECT_TIME_T', 6291511); /** * Time, in microseconds, it took from the start until the first byte is received * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_STARTTRANSFER_TIME_T', 6291510); /** * Total time in microseconds for the previous transfer, including name resolving, TCP connect etc. * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_TOTAL_TIME_T', 6291506); /** * TRUE to not allow URLs that include a username. Usernames are allowed by default (0). * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_DISALLOW_USERNAME_IN_URL', 278); /** * The list of cipher suites to use for the TLS 1.3 connection to a proxy. * The list must be syntactically correct, it consists of one or more cipher suite strings separated by colons. * This option is currently used only when curl is built to use OpenSSL 1.1.1 or later. * If you are using a different SSL backend you can try setting TLS 1.3 cipher suites by using the CURLOPT_PROXY_SSL_CIPHER_LIST option. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_TLS13_CIPHERS', 10277); /** * The list of cipher suites to use for the TLS 1.3 connection. * The list must be syntactically correct, it consists of one or more cipher suite strings separated by colons. * This option is currently used only when curl is built to use OpenSSL 1.1.1 or later. * If you are using a different SSL backend you can try setting TLS 1.3 cipher suites by using the CURLOPT_SSL_CIPHER_LIST option. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_TLS13_CIPHERS', 10276); /** * Time allowed to wait for FTP response. * @link https://curl.haxx.se/libcurl/c/CURLOPT_FTP_RESPONSE_TIMEOUT.html * @since 5.5 */ define('CURLOPT_FTP_RESPONSE_TIMEOUT', 112); /** * Provide a custom address for a specific host and port pair. * An array of hostname, port, and IP address strings, each element separated by a colon. * In the format: array("example.com:80:127.0.0.1") * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.5 */ define('CURLOPT_RESOLVE', 10203); /** * Enable appending to the remote file * @link https://curl.haxx.se/libcurl/c/CURLOPT_APPEND.html * @since 5.5 */ define('CURLOPT_APPEND', 50); /** * Ask for names only in a directory listing * @link https://curl.haxx.se/libcurl/c/CURLOPT_DIRLISTONLY.html * @since 5.5 */ define('CURLOPT_DIRLISTONLY', 48); /** * Permissions for remotely created directories * Pass a long as a parameter, containing the value of the permissions that will be assigned to newly created directories on the remote server. * The default value is 0755, but any valid value can be used. * The only protocols that can use this are sftp://, scp://, and file://. * @link https://curl.haxx.se/libcurl/c/CURLOPT_NEW_DIRECTORY_PERMS.html * @since 5.5 */ define('CURLOPT_NEW_DIRECTORY_PERMS', 160); /** * Permissions for remotely created files. * Pass a long as a parameter, containing the value of the permissions that will be assigned to newly created files on the remote server. * The default value is 0644, but any valid value can be used. * The only protocols that can use this are sftp://, scp://, and file://. * @link https://curl.haxx.se/libcurl/c/CURLOPT_NEW_FILE_PERMS.html * @since 5.5 */ define('CURLOPT_NEW_FILE_PERMS', 159); /** * TRUE to scan the ~/.netrc file to find a username and password for the remote site that a connection is being established with. * @link https://curl.haxx.se/libcurl/c/CURLOPT_NETRC_FILE.html * @since 5.5 */ define('CURLOPT_NETRC_FILE', 10118); /** * Commands to run before an FTP transfer * @link https://curl.haxx.se/libcurl/c/CURLOPT_PREQUOTE.html * @since 5.5 */ define('CURLOPT_PREQUOTE', 10093); /** * Set FTP kerberos security level * @link https://curl.haxx.se/libcurl/c/CURLOPT_KRBLEVEL.html * @since 5.5 */ define('CURLOPT_KRBLEVEL', 10063); /** * Maximum file size allowed to download (in bytes) * @link https://curl.haxx.se/libcurl/c/CURLOPT_MAXFILESIZE.html * @since 5.5 */ define('CURLOPT_MAXFILESIZE', 114); /** * Set account info for FTP * @link https://curl.haxx.se/libcurl/c/CURLOPT_FTP_ACCOUNT.html * @since 5.5 */ define('CURLOPT_FTP_ACCOUNT', 10134); /** * A cookie string (i.e. a single line in Netscape/Mozilla format, or a regular HTTP-style Set-Cookie header) adds that single cookie to the internal cookie store. * "ALL" erases all cookies held in memory. * "SESS" erases all session cookies held in memory. * "FLUSH" writes all known cookies to the file specified by CURLOPT_COOKIEJAR. * "RELOAD" loads all cookies from the files specified by CURLOPT_COOKIEFILE. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.5 */ define('CURLOPT_COOKIELIST', 10135); /** * Set local port number to use for socket * @link https://curl.haxx.se/libcurl/c/CURLOPT_LOCALPORT.html * @since 5.5 */ define('CURLOPT_LOCALPORT', 139); /** * Number of additional local ports to try. * Pass a long. The range argument is the number of attempts libcurl will make to find a working local port number. * It starts with the given CURLOPT_LOCALPORT and adds one to the number for each retry. * @link https://curl.haxx.se/libcurl/c/CURLOPT_LOCALPORTRANGE.html * @since 5.5 */ define('CURLOPT_LOCALPORTRANGE', 140); /** * Command to use instead of USER with FTP. * @link https://curl.haxx.se/libcurl/c/CURLOPT_FTP_ALTERNATIVE_TO_USER.html * @since 5.5 */ define('CURLOPT_FTP_ALTERNATIVE_TO_USER', 10147); /** * Enable/disable use of the SSL session-ID cache. * @link https://curl.haxx.se/libcurl/c/CURLOPT_SSL_SESSIONID_CACHE.html * @since 5.5 */ define('CURLOPT_SSL_SESSIONID_CACHE', 150); /** * Switch off SSL again with FTP after auth. * @link https://curl.haxx.se/libcurl/c/CURLOPT_FTP_SSL_CCC.html * @since 5.5 */ define('CURLOPT_FTP_SSL_CCC', 154); /** * FALSE to get the raw HTTP response body. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.5 */ define('CURLOPT_HTTP_CONTENT_DECODING', 158); /** * Enable/disable HTTP transfer decoding. * @link https://curl.haxx.se/libcurl/c/CURLOPT_HTTP_TRANSFER_DECODING.html * @since 5.5 */ define('CURLOPT_HTTP_TRANSFER_DECODING', 157); /** * Append FTP transfer mode to URL for proxy. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROXY_TRANSFER_MODE.html * @since 5.5 */ define('CURLOPT_PROXY_TRANSFER_MODE', 166); /** * Set scope id for IPv6 addresses. * @link https://curl.haxx.se/libcurl/c/CURLOPT_ADDRESS_SCOPE.html * @since 5.5 */ define('CURLOPT_ADDRESS_SCOPE', 171); /** * Specify a Certificate Revocation List file. * @link https://curl.haxx.se/libcurl/c/CURLOPT_CRLFILE.html * @since 5.5 */ define('CURLOPT_CRLFILE', 10169); /** * Issuer SSL certificate filename. * @link https://curl.haxx.se/libcurl/c/CURLOPT_ISSUERCERT.html * @since 5.5 */ define('CURLOPT_ISSUERCERT', 10170); /** * The user name to use in authentication. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.5 */ define('CURLOPT_USERNAME', 10173); /** * Password to use in authentication. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PASSWORD.html * @since 5.5 */ define('CURLOPT_PASSWORD', 10174); /** * User name to use for proxy authentication. * @since 5.5 */ define('CURLOPT_PROXYUSERNAME', 10175); /** * Password to use for proxy authentication. * @since 5.5 */ define('CURLOPT_PROXYPASSWORD', 10176); /** * Disable proxy use for specific hosts. * @link https://curl.haxx.se/libcurl/c/CURLOPT_NOPROXY.html * @since 5.5 */ define('CURLOPT_NOPROXY', 10177); /** * Set socks proxy gssapi negotiation protection. * @link https://curl.haxx.se/libcurl/c/CURLOPT_SOCKS5_GSSAPI_NEC.html * @since 5.5 */ define('CURLOPT_SOCKS5_GSSAPI_NEC', 180); /** * SOCKS5 proxy authentication service name. * @link https://curl.haxx.se/libcurl/c/CURLOPT_SOCKS5_GSSAPI_SERVICE.html * @deprecated Use CURLOPT_PROXY_SERVICE_NAME instead. * @since 5.5 */ define('CURLOPT_SOCKS5_GSSAPI_SERVICE', 10179); /** * Specify blocksize to use for TFTP data transmission. * @link https://curl.haxx.se/libcurl/c/CURLOPT_TFTP_BLKSIZE.html * @since 5.5 */ define('CURLOPT_TFTP_BLKSIZE', 178); /** * File name holding the SSH known hosts. * @link https://curl.haxx.se/libcurl/c/CURLOPT_SSH_KNOWNHOSTS.html * @since 5.5 */ define('CURLOPT_SSH_KNOWNHOSTS', 10183); /** * Enable the PRET command. * @link https://curl.haxx.se/libcurl/c/CURLOPT_FTP_USE_PRET.html * @since 5.5 */ define('CURLOPT_FTP_USE_PRET', 188); /** * SMTP sender address. * @link https://curl.haxx.se/libcurl/c/CURLOPT_MAIL_FROM.html * @since 5.5 */ define('CURLOPT_MAIL_FROM', 10186); /** * List of SMTP mail recipients. * @link https://curl.haxx.se/libcurl/c/CURLOPT_MAIL_RCPT.html * @since 5.5 */ define('CURLOPT_MAIL_RCPT', 10187); /** * Set the RTSP client CSEQ number. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_CLIENT_CSEQ.html * @since 5.5 */ define('CURLOPT_RTSP_CLIENT_CSEQ', 193); /** * Set the RTSP server CSEQ number. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_SERVER_CSEQ.html * @since 5.5 */ define('CURLOPT_RTSP_SERVER_CSEQ', 194); /** * Set RTSP session ID. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_SESSION_ID.html * @since 5.5 */ define('CURLOPT_RTSP_SESSION_ID', 10190); /** * Set RTSP stream URI. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_STREAM_URI.html * @since 5.5 */ define('CURLOPT_RTSP_STREAM_URI', 10191); /** * Set RTSP Transport: header. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_TRANSPORT.html * @since 5.5 */ define('CURLOPT_RTSP_TRANSPORT', 10192); /** * Specify RTSP request. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_REQUEST.html * @since 5.5 */ define('CURLOPT_RTSP_REQUEST', 189); /** * Ignore content length. * If TRUE, ignore the Content-Length header in the HTTP response and ignore asking for or relying on it for FTP transfers. * This is useful for HTTP with Apache 1.x (and similar servers) which will report incorrect content length for files over 2 gigabytes. * If this option is used, curl will not be able to accurately report progress, and will simply stop the download when the server ends the connection. * It is also useful with FTP when for example the file is growing while the transfer is in progress * which otherwise will unconditionally cause libcurl to report error. * @link https://curl.haxx.se/libcurl/c/CURLOPT_IGNORE_CONTENT_LENGTH.html * @since 5.5 */ define('CURLOPT_IGNORE_CONTENT_LENGTH', 136); /** * Enables automatic decompression of HTTP downloads * @link https://curl.haxx.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html * @since 5.5 */ define('CURLOPT_ACCEPT_ENCODING', 10102); /** * Ask for HTTP Transfer Encoding. * Adds a request for compressed Transfer Encoding in the outgoing HTTP request. * If the server supports this and so desires, it can respond with the HTTP response sent using a compressed Transfer-Encoding * that will be automatically uncompressed by libcurl on reception. * @link https://curl.haxx.se/libcurl/c/CURLOPT_TRANSFER_ENCODING.html * @since 5.5 */ define('CURLOPT_TRANSFER_ENCODING', 207); /** * Set preferred DNS servers: host[:port][,host[:port]]... * @link https://curl.haxx.se/libcurl/c/CURLOPT_DNS_SERVERS.html * @since 5.5 */ define('CURLOPT_DNS_SERVERS', 10211); /** * Request using SSL / TLS for the transfer * @link https://curl.haxx.se/libcurl/c/CURLOPT_USE_SSL.html * @since 5.5 */ define('CURLOPT_USE_SSL', 119); /** * Custom telnet options * @link https://curl.haxx.se/libcurl/c/CURLOPT_TELNETOPTIONS.html */ define("CURLOPT_TELNETOPTIONS", 10070); /** * The download could not be resumed because the specified offset was out of the file boundary. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define("CURLE_BAD_DOWNLOAD_RESUME", 36); /** * A file transfer was shorter or larger than expected. * This happens when the server first reports an expected transfer size, and then delivers data * that doesn't match the previously given size. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define("CURLE_FTP_PARTIAL_FILE", 18); /** * This is returned if CURLOPT_FAILONERROR is set TRUE and the HTTP server returns an error code that is >= 400. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define("CURLE_HTTP_RETURNED_ERROR", 22); /** * Operation timeout. The specified time-out period was reached according to the conditions. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define("CURLE_OPERATION_TIMEDOUT", 28); /** * Failed to match the pinned key specified with CURLOPT_PINNEDPUBLICKEY. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define("CURLE_SSL_PINNEDPUBKEYNOTMATCH", 90); /** * @link https://php.net/manual/en/curl.constants.php */ define("CURLINFO_LASTONE", 64); /** * An easy handle already added to a multi handle was attempted to get added a second time. * @link https://www.php.net/manual/en/function.curl-multi-exec.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define("CURLM_ADDED_ALREADY", 7); /** * @link https://curl.haxx.se/libcurl/c/symbols-in-versions.html */ define("CURLSHOPT_NONE", 0); /** * Default value for the CURLOPT_TIMECONDITION option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_TIMECONDITION.html */ define("CURL_TIMECOND_NONE", 0); /** * Value for the CURLOPT_HTTPAUTH option. * Allows no authentication. * @link https://www.php.net/manual/en/function.curl-setopt.php */ define("CURLAUTH_NONE", 0); /** * Problem with reading the SSL CA cert (path? access rights?) * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define("CURLE_SSL_CACERT_BADFILE", 77); /** * An unspecified error occurred during the SSH session. * @link https://php.net/manual/en/curl.constants.php * @link https://curl.haxx.se/libcurl/c/libcurl-errors.html */ define("CURLE_SSH", 79); /** * Value for the CURLOPT_FTP_SSL_CCC option. * Initiate the shutdown and wait for a reply. * @link https://curl.haxx.se/libcurl/c/CURLOPT_FTP_SSL_CCC.html */ define("CURLFTPSSL_CCC_ACTIVE", 2); /** * Value for the CURLOPT_FTP_SSL_CCC option. * Don't attempt to use CCC. * @link https://curl.haxx.se/libcurl/c/CURLOPT_FTP_SSL_CCC.html */ define("CURLFTPSSL_CCC_NONE", 0); /** * Value for the CURLOPT_FTP_SSL_CCC option. * Do not initiate the shutdown, but wait for the server to do it. Do not send a reply. * @link https://curl.haxx.se/libcurl/c/CURLOPT_FTP_SSL_CCC.html */ define("CURLFTPSSL_CCC_PASSIVE", 1); /** * Value for the CURLOPT_USE_SSL option. * Require SSL for all communication or fail. * @link https://curl.haxx.se/libcurl/c/CURLOPT_USE_SSL.html */ define("CURLUSESSL_ALL", 3); /** * Value for the CURLOPT_USE_SSL option. * Require SSL for the control connection or fail. * @link https://curl.haxx.se/libcurl/c/CURLOPT_USE_SSL.html */ define("CURLUSESSL_CONTROL", 2); /** * Value for the CURLOPT_USE_SSL option. * Don't attempt to use SSL. * @link https://curl.haxx.se/libcurl/c/CURLOPT_USE_SSL.html */ define("CURLUSESSL_NONE", 0); /** * Value for the CURLOPT_USE_SSL option. * Try using SSL, proceed as normal otherwise. * @link https://curl.haxx.se/libcurl/c/CURLOPT_USE_SSL.html */ define("CURLUSESSL_TRY", 1); /** * Convenience define that pauses both directions. * @link https://php.net/manual/en/curl.constants.php * @since 5.5 */ define("CURLPAUSE_ALL", 5); /** * Convenience define that unpauses both directions. * @link https://php.net/manual/en/curl.constants.php * @since 5.5 */ define("CURLPAUSE_CONT", 0); /** * Pause receiving data. There will be no data received on this connection until this function is called again without this bit set. * Thus, the write callback (CURLOPT_WRITEFUNCTION) won't be called. * @link https://php.net/manual/en/curl.constants.php * @since 5.5 */ define("CURLPAUSE_RECV", 1); /** * @link https://php.net/manual/en/curl.constants.php * @since 5.5 */ define("CURLPAUSE_RECV_CONT", 0); /** * Pause sending data. There will be no data sent on this connection until this function is called again without this bit set. * Thus, the read callback (CURLOPT_READFUNCTION) won't be called. * @link https://php.net/manual/en/curl.constants.php * @since 5.5 */ define("CURLPAUSE_SEND", 4); /** * @link https://php.net/manual/en/curl.constants.php * @since 5.5 */ define("CURLPAUSE_SEND_CONT", 0); /** * Read callback for data uploads. * @link https://curl.haxx.se/libcurl/c/CURLOPT_READFUNCTION.html */ define("CURL_READFUNC_PAUSE", 268435457); /** * Set callback for writing received data. * @link https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html */ define("CURL_WRITEFUNC_PAUSE", 268435457); /** * Value for the CURLOPT_PROXYTYPE option. * @link https://www.php.net/manual/en/curl.constants.php * @since 5.5.23 */ define("CURLPROXY_SOCKS4A", 6); /** * Value for the CURLOPT_PROXYTYPE option. * Proxy resolves URL hostname. * @link https://www.php.net/manual/en/curl.constants.php * @since 5.5.23 */ define("CURLPROXY_SOCKS5_HOSTNAME", 7); /** * Value for the CURLOPT_SSH_AUTH_TYPES option. * @link https://www.php.net/manual/en/curl.constants.php */ define("CURLSSH_AUTH_ANY", -1); /** * Value for the CURLOPT_SSH_AUTH_TYPES option. * @link https://www.php.net/manual/en/curl.constants.php */ define("CURLSSH_AUTH_DEFAULT", -1); /** * Value for the CURLOPT_SSH_AUTH_TYPES option. * @link https://www.php.net/manual/en/curl.constants.php */ define("CURLSSH_AUTH_HOST", 4); /** * Value for the CURLOPT_SSH_AUTH_TYPES option. * @link https://www.php.net/manual/en/curl.constants.php */ define("CURLSSH_AUTH_KEYBOARD", 8); /** * Value for the CURLOPT_SSH_AUTH_TYPES option. * @link https://www.php.net/manual/en/curl.constants.php */ define("CURLSSH_AUTH_NONE", 0); /** * Value for the CURLOPT_SSH_AUTH_TYPES option. * @link https://www.php.net/manual/en/curl.constants.php */ define("CURLSSH_AUTH_PASSWORD", 2); /** * Value for the CURLOPT_SSH_AUTH_TYPES option. * @link https://www.php.net/manual/en/curl.constants.php */ define("CURLSSH_AUTH_PUBLICKEY", 1); /** * Value for the CURLOPT_HTTPAUTH option. * HTTP Digest authentication with an IE flavor. * Digest authentication is defined in RFC 2617 and is a more secure way to do authentication over public networks than * the regular old-fashioned Basic method. * The IE flavor is simply that libcurl will use a special "quirk" that IE is known to have used before version 7 * and that some servers require the client to use. * @link https://curl.haxx.se/libcurl/c/CURLOPT_HTTPAUTH.html */ define("CURLAUTH_DIGEST_IE", 16); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_IMAP", 4096); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_IMAPS", 8192); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_POP3", 16384); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_POP3S", 32768); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_RTSP", 262144); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_SMTP", 65536); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_SMTPS", 131072); /** * Value for the CURLOPT_RTSP_REQUEST option. * When sent by a client, this method changes the description of the session. * For example, if a client is using the server to record a meeting, * the client can use Announce to inform the server of all the meta-information about the session. * ANNOUNCE acts like an HTTP PUT or POST * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_REQUEST.html */ define("CURL_RTSPREQ_ANNOUNCE", 3); /** * Value for the CURLOPT_RTSP_REQUEST option. * Used to get the low level description of a stream. * The application should note what formats it understands in the 'Accept:' header. * Unless set manually, libcurl will automatically fill in 'Accept: application/sdp'. * Time-condition headers will be added to Describe requests if the CURLOPT_TIMECONDITION option is active. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_REQUEST.html */ define("CURL_RTSPREQ_DESCRIBE", 2); /** * Value for the CURLOPT_RTSP_REQUEST option. * Retrieve a parameter from the server. * By default, libcurl will automatically include a Content-Type: text/parameters header on all non-empty requests * unless a custom one is set. GET_PARAMETER acts just like an HTTP PUT or POST * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_REQUEST.html */ define("CURL_RTSPREQ_GET_PARAMETER", 8); /** * Value for the CURLOPT_RTSP_REQUEST option. * Used to retrieve the available methods of the server. * The application is responsible for parsing and obeying the response. * The session ID is not needed for this method. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_REQUEST.html */ define("CURL_RTSPREQ_OPTIONS", 1); /** * Value for the CURLOPT_RTSP_REQUEST option. * Send a Pause command to the server. * Use the CURLOPT_RANGE option with a single value to indicate when the stream should be halted. (e.g. npt='25') * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_REQUEST.html */ define("CURL_RTSPREQ_PAUSE", 6); /** * Value for the CURLOPT_RTSP_REQUEST option. * Send a Play command to the server. * Use the CURLOPT_RANGE option to modify the playback time (e.g. 'npt=10-15'). * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_REQUEST.html */ define("CURL_RTSPREQ_PLAY", 5); /** * Value for the CURLOPT_RTSP_REQUEST option. * This is a special request because it does not send any data to the server. * The application may call this function in order to receive interleaved RTP data. * It will return after processing one read buffer of data in order to give the application a chance to run. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_REQUEST.html */ define("CURL_RTSPREQ_RECEIVE", 11); /** * Value for the CURLOPT_RTSP_REQUEST option. * Used to tell the server to record a session. Use the CURLOPT_RANGE option to modify the record time. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_REQUEST.html */ define("CURL_RTSPREQ_RECORD", 10); /** * Value for the CURLOPT_RTSP_REQUEST option. * Set a parameter on the server. * By default, libcurl will automatically include a Content-Type: text/parameters header unless a custom one is set. * The interaction with SET_PARAMETER is much like an HTTP PUT or POST. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_REQUEST.html */ define("CURL_RTSPREQ_SET_PARAMETER", 9); /** * Value for the CURLOPT_RTSP_REQUEST option. * Setup is used to initialize the transport layer for the session. * The application must set the desired Transport options for a session * by using the CURLOPT_RTSP_TRANSPORT option prior to calling setup. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_REQUEST.html */ define("CURL_RTSPREQ_SETUP", 4); /** * Value for the CURLOPT_RTSP_REQUEST option. * This command terminates an RTSP session. * Simply closing a connection does not terminate the RTSP session since it is valid to control an RTSP session over different connections. * @link https://curl.haxx.se/libcurl/c/CURLOPT_RTSP_REQUEST.html */ define("CURL_RTSPREQ_TEARDOWN", 7); /** * Wildcard matching function callback. * @link https://curl.haxx.se/libcurl/c/CURLOPT_FNMATCH_FUNCTION.html */ define("CURLOPT_FNMATCH_FUNCTION", 20200); /** * Enable directory wildcard transfers. * @link https://curl.haxx.se/libcurl/c/CURLOPT_WILDCARDMATCH.html */ define("CURLOPT_WILDCARDMATCH", 197); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_RTMP", 524288); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_RTMPE", 2097152); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_RTMPS", 8388608); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_RTMPT", 1048576); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_RTMPTE", 4194304); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_RTMPTS", 16777216); /** * Return value for the CURLOPT_FNMATCH_FUNCTION if an error was occurred. * @link https://curl.haxx.se/libcurl/c/CURLOPT_FNMATCH_FUNCTION.html */ define("CURL_FNMATCHFUNC_FAIL", 2); /** * Return value for the CURLOPT_FNMATCH_FUNCTION if pattern matches the string. * @link https://curl.haxx.se/libcurl/c/CURLOPT_FNMATCH_FUNCTION.html */ define("CURL_FNMATCHFUNC_MATCH", 0); /** * Return value for the CURLOPT_FNMATCH_FUNCTION if pattern not matches the string. * @link https://curl.haxx.se/libcurl/c/CURLOPT_FNMATCH_FUNCTION.html */ define("CURL_FNMATCHFUNC_NOMATCH", 1); /** * Value for the CURLOPT_PROTOCOLS option. * @link https://curl.haxx.se/libcurl/c/CURLOPT_PROTOCOLS.html */ define("CURLPROTO_GOPHER", 33554432); /** * Value for the CURLOPT_HTTPAUTH option. * This is a meta symbol. * OR this value together with a single specific auth value to force libcurl to probe for un-restricted auth and if not, * only that single auth algorithm is acceptable. * @link https://curl.haxx.se/libcurl/c/CURLOPT_HTTPAUTH.html */ define("CURLAUTH_ONLY", 2147483648); /** * Password to use for TLS authentication. * @link https://curl.haxx.se/libcurl/c/CURLOPT_TLSAUTH_PASSWORD.html */ define("CURLOPT_TLSAUTH_PASSWORD", 10205); /** * Set TLS authentication methods. * @link https://curl.haxx.se/libcurl/c/CURLOPT_TLSAUTH_TYPE.html */ define("CURLOPT_TLSAUTH_TYPE", 10206); /** * User name to use for TLS authentication. * @link https://curl.haxx.se/libcurl/c/CURLOPT_TLSAUTH_USERNAME.html */ define("CURLOPT_TLSAUTH_USERNAME", 10204); /** * Value for the CURLOPT_TLSAUTH_TYPE option. * TLS-SRP authentication. * Secure Remote Password authentication for TLS is defined in RFC 5054 and provides mutual authentication if both sides have a shared secret. * @link https://curl.haxx.se/libcurl/c/CURLOPT_TLSAUTH_TYPE.html */ define("CURL_TLSAUTH_SRP", 1); /** * Value for the CURLOPT_GSSAPI_DELEGATION option. * Allow unconditional GSSAPI credential delegation. * @link https://curl.haxx.se/libcurl/c/CURLOPT_GSSAPI_DELEGATION.html */ define("CURLGSSAPI_DELEGATION_FLAG", 2); /** * Value for the CURLOPT_GSSAPI_DELEGATION option. * Delegate only if the OK-AS-DELEGATE flag is set in the service ticket * in case this feature is supported by the GSS-API implementation. * @link https://curl.haxx.se/libcurl/c/CURLOPT_GSSAPI_DELEGATION.html */ define("CURLGSSAPI_DELEGATION_POLICY_FLAG", 1); /** * Set allowed GSS-API delegation. * @link https://curl.haxx.se/libcurl/c/CURLOPT_GSSAPI_DELEGATION.html */ define("CURLOPT_GSSAPI_DELEGATION", 210); /** * Timeout waiting for FTP server to connect back * @link https://curl.haxx.se/libcurl/c/CURLOPT_ACCEPTTIMEOUT_MS.html */ define("CURLOPT_ACCEPTTIMEOUT_MS", 212); /** * SMTP authentication address * @link https://curl.haxx.se/libcurl/c/CURLOPT_MAIL_AUTH.html */ define("CURLOPT_MAIL_AUTH", 10217); /** * Set SSL behavior options, which is a bitmask of any of the following constants: * CURLSSLOPT_ALLOW_BEAST: do not attempt to use any workarounds for a security flaw in the SSL3 and TLS1.0 protocols. * CURLSSLOPT_NO_REVOKE: disable certificate revocation checks for those SSL backends where such behavior is present. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.6 */ define("CURLOPT_SSL_OPTIONS", 216); /** * If set to 1, TCP keepalive probes will be sent. * The delay and frequency of these probes can be controlled by the CURLOPT_TCP_KEEPIDLE and CURLOPT_TCP_KEEPINTVL options, * provided the operating system supports them. * If set to 0 (default) keepalive probes are disabled. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.5 */ define("CURLOPT_TCP_KEEPALIVE", 213); /** * Sets the delay, in seconds, that the operating system will wait while the connection is idle before sending keepalive probes, * if CURLOPT_TCP_KEEPALIVE is enabled. Not all operating systems support this option. The default is 60. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.5 */ define("CURLOPT_TCP_KEEPIDLE", 214); /** * Sets the interval, in seconds, that the operating system will wait between sending keepalive probes, * if CURLOPT_TCP_KEEPALIVE is enabled. Not all operating systems support this option. The default is 60. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.5 */ define("CURLOPT_TCP_KEEPINTVL", 215); /** * Value for the CURLOPT_SSL_OPTIONS option. * Do not attempt to use any workarounds for a security flaw in the SSL3 and TLS1.0 protocols. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 5.6 */ define("CURLSSLOPT_ALLOW_BEAST", 1); /** * Supports HTTP2. * @link https://www.php.net/manual/en/curl.constants.php * @since 5.5.24 */ define("CURL_VERSION_HTTP2", 65536); /** * Value for the CURLOPT_SSL_OPTIONS option. * Disable certificate revocation checks for those SSL backends where such behavior is present. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define("CURLSSLOPT_NO_REVOKE", 2); /** * The default protocol to use if the URL is missing a scheme name. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define("CURLOPT_DEFAULT_PROTOCOL", 10238); /** * Set the numerical stream weight (a number between 1 and 256). * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define("CURLOPT_STREAM_WEIGHT", 239); /** * TRUE to not send TFTP options requests. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define("CURLOPT_TFTP_NO_OPTIONS", 242); /** * Connect to a specific host and port instead of the URL's host and port. * Accepts an array of strings with the format HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define("CURLOPT_CONNECT_TO", 10243); /** * TRUE to enable TCP Fast Open. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.0.7 */ define("CURLOPT_TCP_FASTOPEN", 244); /** * The server sent data libcurl couldn't parse. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURLE_WEIRD_SERVER_REPLY', 8); /** * TRUE to keep sending the request body if the HTTP code returned is equal to or larger than 300. * The default action would be to stop sending and close the stream or connection. Suitable for manual NTLM authentication. * Most applications do not need this option. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_KEEP_SENDING_ON_ERROR', 245); /** * Value for the CURLOPT_SSLVERSION option. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_SSLVERSION_TLSv1_3', 7); /** * Supports HTTPS proxy. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_HTTPS_PROXY', 2097152); /** * The protocol used in the last HTTP connection. The returned value will be exactly one of the CURLPROTO_* values * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_PROTOCOL', 2097200); /** * Supports asynchronous name lookups. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_ASYNCHDNS', 128); /** * Supports memory tracking debug capabilities. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3.6 */ define('CURL_VERSION_CURLDEBUG', 8192); /** * Supports character conversions. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_CONV', 4096); /** * libcurl was built with debug capabilities * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_DEBUG', 64); /** * Supports HTTP GSS-Negotiate. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_GSSNEGOTIATE', 32); /** * Supports the IDNA. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_IDN', 1024); /** * Supports large files. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_LARGEFILE', 512); /** * Supports HTTP NTLM. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_NTLM', 16); /** * Supports the Mozilla's Public Suffix List. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURL_VERSION_PSL', 1048576); /** * Supports for SPNEGO authentication (RFC 2478). * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_SPNEGO', 256); /** * Supports SSPI. Windows-specific. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_SSPI', 2048); /** * Supports the TLS-SRP. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_TLSAUTH_SRP', 16384); /** * Supports the NTLM delegation to a winbind helper. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_NTLM_WB', 32768); /** * Supports the GSSAPI. This makes libcurl use provided functions for Kerberos and SPNEGO authentication. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_GSSAPI', 131072); /** * Supports Kerberos V5 authentication for FTP, IMAP, POP3, SMTP and SOCKSv5 proxy. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURL_VERSION_KERBEROS5', 262144); /** * The path to proxy Certificate Authority (CA) bundle. * Set the path as a string naming a file holding one or more certificates to verify the HTTPS proxy with. * This option is for connecting to an HTTPS proxy, not an HTTPS server. * Defaults set to the system path where libcurl's cacert bundle is assumed to be stored. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_CAINFO', 10246); /** * The directory holding multiple CA certificates to verify the HTTPS proxy with. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_CAPATH', 10247); /** * Set the file name with the concatenation of CRL (Certificate Revocation List) in PEM format * to use in the certificate validation that occurs during the SSL exchange. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_CRLFILE', 10260); /** * Set the string be used as the password required to use the CURLOPT_PROXY_SSLKEY private key. * You never needed a passphrase to load a certificate but you need one to load your private key. * This option is for connecting to an HTTPS proxy, not an HTTPS server. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_KEYPASSWD', 10258); /** * The format of your client certificate used when connecting to an HTTPS proxy. Supported formats are "PEM" and "DER", except with Secure Transport. * OpenSSL (versions 0.9.3 and later) and Secure Transport (on iOS 5 or later, or OS X 10.7 or later) also support "P12" for PKCS#12-encoded files. * Defaults to "PEM". * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_SSLCERTTYPE', 10255); /** * The format of your private key. Supported formats are "PEM", "DER" and "ENG". * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_SSLKEYTYPE', 10257); /** * One of CURL_SSLVERSION_DEFAULT, CURL_SSLVERSION_TLSv1, CURL_SSLVERSION_TLSv1_0, CURL_SSLVERSION_TLSv1_1, CURL_SSLVERSION_TLSv1_2, * CURL_SSLVERSION_TLSv1_3, CURL_SSLVERSION_MAX_DEFAULT, CURL_SSLVERSION_MAX_TLSv1_0, CURL_SSLVERSION_MAX_TLSv1_1, * CURL_SSLVERSION_MAX_TLSv1_2, CURL_SSLVERSION_MAX_TLSv1_3 or CURL_SSLVERSION_SSLv3. * See also CURLOPT_SSLVERSION. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_SSLVERSION', 250); /** * Tusername to use for the HTTPS proxy TLS authentication method specified with the CURLOPT_PROXY_TLSAUTH_TYPE option. * Requires that the CURLOPT_PROXY_TLSAUTH_PASSWORD option to also be set. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_TLSAUTH_USERNAME', 10251); /** * The password to use for the TLS authentication method specified with the CURLOPT_PROXY_TLSAUTH_TYPE option. * Requires that the CURLOPT_PROXY_TLSAUTH_USERNAME option to also be set. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_TLSAUTH_PASSWORD', 10252); /** * The method of the TLS authentication used for the HTTPS connection. Supported method is "SRP". * Secure Remote Password (SRP) authentication for TLS provides mutual authentication if both sides have a shared secret. * To use TLS-SRP, you must also set the CURLOPT_PROXY_TLSAUTH_USERNAME and CURLOPT_PROXY_TLSAUTH_PASSWORD options. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_TLSAUTH_TYPE', 10253); /** * Value for the CURLOPT_PROXYTYPE option. * Use HTTPS Proxy. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3 */ define('CURLPROXY_HTTPS', 2); /** * Set the pinned public key for HTTPS proxy. The string can be the file name of your pinned public key. The file format expected is "PEM" or "DER". * The string can also be any number of base64 encoded sha256 hashes preceded by "sha256//" and separated by ";" * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_PINNEDPUBLICKEY', 10263); /** * The file name of your private key used for connecting to the HTTPS proxy. * The default format is "PEM" and can be changed with CURLOPT_PROXY_SSLKEYTYPE. * (iOS and Mac OS X only) This option is ignored if curl was built against Secure Transport. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_SSLKEY', 10256); /** * The list of ciphers to use for the connection to the HTTPS proxy. * The list must be syntactically correct, it consists of one or more cipher strings separated by colons. * Commas or spaces are also acceptable separators but colons are normally used, !, - and + can be used as operators. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_SSL_CIPHER_LIST', 10259); /** * Set proxy SSL behavior options, which is a bitmask of any of the following constants: * CURLSSLOPT_ALLOW_BEAST: do not attempt to use any workarounds for a security flaw in the SSL3 and TLS1.0 protocols. * CURLSSLOPT_NO_REVOKE: disable certificate revocation checks for those SSL backends where such behavior is present. (curl >= 7.44.0) * CURLSSLOPT_NO_PARTIALCHAIN: do not accept "partial" certificate chains, which it otherwise does by default. (curl >= 7.68.0) * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_SSL_OPTIONS', 261); /** * Set to 2 to verify in the HTTPS proxy's certificate name fields against the proxy name. * When set to 0 the connection succeeds regardless of the names used in the certificate. * Use that ability with caution! 1 treated as a debug option in curl 7.28.0 and earlier. * From curl 7.28.1 to 7.65.3 CURLE_BAD_FUNCTION_ARGUMENT is returned. * From curl 7.66.0 onwards 1 and 2 is treated as the same value. * In production environments the value of this option should be kept at 2 (default value). * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_SSL_VERIFYHOST', 249); /** * FALSE to stop cURL from verifying the peer's certificate. * Alternate certificates to verify against can be specified with the CURLOPT_CAINFO option or * a certificate directory can be specified with the CURLOPT_CAPATH option. * When set to false, the peer certificate verification succeeds regardless. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_SSL_VERIFYPEER', 248); /** * The file name of your client certificate used to connect to the HTTPS proxy. * The default format is "P12" on Secure Transport and "PEM" on other engines, and can be changed with CURLOPT_PROXY_SSLCERTTYPE. * With NSS or Secure Transport, this can also be the nickname of the certificate you wish to authenticate with as it is named in the security database. * If you want to use a file from the current directory, please precede it with "./" prefix, in order to avoid confusion with a nickname. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PROXY_SSLCERT', 10254); /** * The URL scheme used for the most recent connection * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_SCHEME', 1048625); /** * Supports UNIX sockets. * @link https://www.php.net/manual/en/curl.constants.php * @since 7.0.7 */ define('CURL_VERSION_UNIX_SOCKETS', 524288); /** * The version used in the last HTTP connection. The return value will be one of the defined * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_HTTP_VERSION', 2097198); /** * Set a string holding the host name or dotted numerical IP address to be used as the preproxy that curl connects to before * it connects to the HTTP(S) proxy specified in the CURLOPT_PROXY option for the upcoming request. * The preproxy can only be a SOCKS proxy and it should be prefixed with [scheme]:// to specify which kind of socks is used. * A numerical IPv6 address must be written within [brackets]. Setting the preproxy to an empty string explicitly disables the use of a preproxy. * To specify port number in this string, append :[port] to the end of the host name. * The proxy's port number may optionally be specified with the separate option CURLOPT_PROXYPORT. * Defaults to using port 1080 for proxies if a port is not specified. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_PRE_PROXY', 10262); /** * The result of the certificate verification that was requested (using the CURLOPT_PROXY_SSL_VERIFYPEER option). * Only used for HTTPS proxies * @link https://www.php.net/manual/en/function.curl-getinfo.php * @since 7.3 */ define('CURLINFO_PROXY_SSL_VERIFYRESULT', 2097199); /** * Whether to allow HTTP/0.9 responses. * Defaults to FALSE as of libcurl 7.66.0; formerly it defaulted to TRUE. * @link https://www.php.net/manual/en/function.curl-setopt.php * @since 7.3 */ define('CURLOPT_HTTP09_ALLOWED', 285); /** * @link https://www.php.net/manual/en/curl.constants.php * @since 7.3.6 */ define('CURL_VERSION_ALTSVC', 16777216); /** * @since 8.1 */ define('CURLOPT_DOH_URL', 10279); /** * @since 8.1 */ define('CURLOPT_ISSUERCERT_BLOB', 40295); /** * @since 8.1 */ define('CURLOPT_PROXY_ISSUERCERT', 10296); /** * @since 8.1 */ define('CURLOPT_PROXY_ISSUERCERT_BLOB', 40297); /** * @since 8.1 */ define('CURLOPT_PROXY_SSLCERT_BLOB', 40293); /** * @since 8.1 */ define('CURLOPT_PROXY_SSLKEY_BLOB', 40294); /** * @since 8.1 */ define('CURLOPT_SSLCERT_BLOB', 40291); /** * @since 8.1 */ define('CURLOPT_SSLKEY_BLOB', 40292); /** * @since 8.2 */ define('CURLOPT_XFERINFOFUNCTION', 20219); /** * @since 8.2 */ define('CURLINFO_EFFECTIVE_METHOD', 1048634); /** * @since 8.2 */ define('CURLOPT_MAXFILESIZE_LARGE', 30117); /** * @since 8.2 */ define('CURLFTPMETHOD_DEFAULT', 0); /** * @since 8.2 */ define('CURLOPT_UPKEEP_INTERVAL_MS', 281); /** * @since 8.2 */ define('CURLOPT_UPLOAD_BUFFERSIZE', 280); /** * @since 8.2 */ define('CURLALTSVC_H1', 8); /** * @since 8.2 */ define('CURLALTSVC_H2', 16); /** * @since 8.2 */ define('CURLALTSVC_H3', 32); /** * @since 8.2 */ define('CURLALTSVC_READONLYFILE', 4); /** * @since 8.2 */ define('CURLOPT_ALTSVC', 10287); /** * @since 8.2 */ define('CURLOPT_ALTSVC_CTRL', 286); /** * @since 8.2 */ define('CURLOPT_MAXAGE_CONN', 288); /** * @since 8.2 */ define('CURLOPT_SASL_AUTHZID', 10289); /** * @since 8.2 */ define('CURL_VERSION_HTTP3', 33554432); /** * @since 8.2 */ define('CURLINFO_RETRY_AFTER', 6291513); /** * @since 8.2 */ define('CURLMOPT_MAX_CONCURRENT_STREAMS', 16); /** * @since 8.2 */ define('CURLSSLOPT_NO_PARTIALCHAIN', 4); /** * @since 8.2 */ define('CURLOPT_MAIL_RCPT_ALLLOWFAILS', 290); /** * @since 8.2 */ define('CURLSSLOPT_REVOKE_BEST_EFFORT', 8); /** * @since 8.2 */ define('CURLPROTO_MQTT', 268435456); /** * @since 8.2 */ define('CURLSSLOPT_NATIVE_CA', 16); /** * @since 8.2 */ define('CURL_VERSION_UNICODE', 134217728); /** * @since 8.2 */ define('CURL_VERSION_ZSTD', 67108864); /** * @since 8.2 */ define('CURLE_PROXY', 97); /** * @since 8.2 */ define('CURLINFO_PROXY_ERROR', 2097211); /** * @since 8.2 */ define('CURLOPT_SSL_EC_CURVES', 10298); /** * @since 8.2 */ define('CURLPX_BAD_ADDRESS_TYPE', 1); /** * @since 8.2 */ define('CURLPX_BAD_VERSION', 2); /** * @since 8.2 */ define('CURLPX_CLOSED', 3); /** * @since 8.2 */ define('CURLPX_GSSAPI', 4); /** * @since 8.2 */ define('CURLPX_GSSAPI_PERMSG', 5); /** * @since 8.2 */ define('CURLPX_GSSAPI_PROTECTION', 6); /** * @since 8.2 */ define('CURLPX_IDENTD', 7); /** * @since 8.2 */ define('CURLPX_IDENTD_DIFFER', 8); /** * @since 8.2 */ define('CURLPX_LONG_HOSTNAME', 9); /** * @since 8.2 */ define('CURLPX_LONG_PASSWD', 10); /** * @since 8.2 */ define('CURLPX_LONG_USER', 11); /** * @since 8.2 */ define('CURLPX_NO_AUTH', 12); /** * @since 8.2 */ define('CURLPX_OK', 0); /** * @since 8.2 */ define('CURLPX_RECV_ADDRESS', 13); /** * @since 8.2 */ define('CURLPX_RECV_AUTH', 14); /** * @since 8.2 */ define('CURLPX_RECV_CONNECT', 15); /** * @since 8.2 */ define('CURLPX_RECV_REQACK', 16); /** * @since 8.2 */ define('CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED', 17); /** * @since 8.2 */ define('CURLPX_REPLY_COMMAND_NOT_SUPPORTED', 18); /** * @since 8.2 */ define('CURLPX_REPLY_CONNECTION_REFUSED', 19); /** * @since 8.2 */ define('CURLPX_REPLY_GENERAL_SERVER_FAILURE', 20); /** * @since 8.2 */ define('CURLPX_REPLY_HOST_UNREACHABLE', 21); /** * @since 8.2 */ define('CURLPX_REPLY_NETWORK_UNREACHABLE', 22); /** * @since 8.2 */ define('CURLPX_REPLY_NOT_ALLOWED', 23); /** * @since 8.2 */ define('CURLPX_REPLY_TTL_EXPIRED', 24); /** * @since 8.2 */ define('CURLPX_REPLY_UNASSIGNED', 25); /** * @since 8.2 */ define('CURLPX_REQUEST_FAILED', 26); /** * @since 8.2 */ define('CURLPX_RESOLVE_HOST', 27); /** * @since 8.2 */ define('CURLPX_SEND_CONNECT', 29); /** * @since 8.2 */ define('CURLPX_SEND_AUTH', 28); /** * @since 8.2 */ define('CURLPX_SEND_REQUEST', 30); /** * @since 8.2 */ define('CURLPX_UNKNOWN_FAIL', 31); /** * @since 8.2 */ define('CURLPX_UNKNOWN_MODE', 32); /** * @since 8.2 */ define('CURLPX_USER_REJECTED', 33); /** * @since 8.2 */ define('CURLHSTS_ENABLE', 1); /** * @since 8.2 */ define('CURLHSTS_READONLYFILE', 2); /** * @since 8.2 */ define('CURLOPT_HSTS', 10300); /** * @since 8.2 */ define('CURLOPT_HSTS_CTRL', 299); /** * @since 8.2 */ define('CURL_VERSION_HSTS', 268435456); /** * @since 8.2 */ define('CURLAUTH_AWS_SIGV4', 128); /** * @since 8.2 */ define('CURLOPT_AWS_SIGV4', 10305); /** * @since 8.2 */ define('CURLINFO_REFERER', 1048636); /** * @since 8.2 */ define('CURLOPT_DOH_SSL_VERIFYHOST', 307); /** * @since 8.2 */ define('CURLOPT_DOH_SSL_VERIFYPEER', 306); /** * @since 8.2 */ define('CURLOPT_DOH_SSL_VERIFYSTATUS', 308); /** * @since 8.2 */ define('CURL_VERSION_GSASL', 536870912); /** * @since 8.2 */ define('CURLOPT_CAINFO_BLOB', 40309); /** * @since 8.2 */ define('CURLOPT_PROXY_CAINFO_BLOB', 40310); /** * @since 8.2 */ define('CURLSSLOPT_AUTO_CLIENT_CERT', 32); /** * @since 8.2 */ define('CURLOPT_MAXLIFETIME_CONN', 314); /** * @since 8.2 */ define('CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256', 10311); /** * @since 8.4 */ define('CURL_HTTP_VERSION_3', 30); /** * @since 8.4 */ define('CURL_HTTP_VERSION_3ONLY', 31); /** * @since 8.4 */ define('CURLOPT_PREREQFUNCTION', 20312); /** * @since 8.4 */ define('CURL_PREREQFUNC_OK', 0); /** * @since 8.4 */ define('CURL_PREREQFUNC_ABORT', 1); /** * @since 8.4 */ define('CURLOPT_TCP_KEEPCNT', 326); 'string'], default: '')] public $name; #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $mime; #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $postname; /** * Create a CURLFile object * @link https://secure.php.net/manual/en/curlfile.construct.php * @param string $filename

    Path to the file which will be uploaded.

    * @param string $mime_type [optional]

    Mimetype of the file.

    * @param string $posted_filename [optional]

    Name of the file.

    * @since 5.5 */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $mime_type = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $posted_filename = null ) {} /** * Get file name * @link https://secure.php.net/manual/en/curlfile.getfilename.php * @return string Returns file name. * @since 5.5 */ #[Pure] #[TentativeType] public function getFilename(): string {} /** * Get MIME type * @link https://secure.php.net/manual/en/curlfile.getmimetype.php * @return string Returns MIME type. * @since 5.5 */ #[Pure] #[TentativeType] public function getMimeType(): string {} /** * Get file name for POST * @link https://secure.php.net/manual/en/curlfile.getpostfilename.php * @return string Returns file name for POST. * @since 5.5 */ #[Pure] #[TentativeType] public function getPostFilename(): string {} /** * Set MIME type * @link https://secure.php.net/manual/en/curlfile.setmimetype.php * @param string $mime_type * @since 5.5 */ #[TentativeType] public function setMimeType(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $mime_type): void {} /** * Set file name for POST * https://secure.php.net/manual/en/curlfile.setpostfilename.php * @param string $posted_filename * @since 5.5 */ #[TentativeType] public function setPostFilename(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $posted_filename): void {} /** * @link https://secure.php.net/manual/en/curlfile.wakeup.php * Unserialization handler * @since 5.5 */ public function __wakeup() {} } /** * Initialize a cURL session * @link https://php.net/manual/en/function.curl-init.php * @param string|null $url [optional]

    * If provided, the CURLOPT_URL option will be set * to its value. You can manually set this using the * curl_setopt function. *

    * @return resource|false|CurlHandle a cURL handle on success, false on errors. */ #[LanguageLevelTypeAware(['8.0' => 'CurlHandle|false'], default: 'resource|false')] function curl_init(?string $url) {} /** * Copy a cURL handle along with all of its preferences * @link https://php.net/manual/en/function.curl-copy-handle.php * @param CurlHandle|resource $handle * @return CurlHandle|resource|false a new cURL handle. */ #[Pure] #[LanguageLevelTypeAware(['8.0' => 'CurlHandle|false'], default: 'resource|false')] function curl_copy_handle(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle) {} /** * Gets cURL version information * @link https://php.net/manual/en/function.curl-version.php * @param int $age [optional] Removed since version PHP 8.0. * @return array|false an associative array with the following elements: * * Indice * Value description * * * version_number * cURL 24 bit version number * * * version * cURL version number, as a string * * * ssl_version_number * OpenSSL 24 bit version number * * * ssl_version * OpenSSL version number, as a string * * * libz_version * zlib version number, as a string * * * host * Information about the host where cURL was built * * * age * * * * features * A bitmask of the CURL_VERSION_XXX constants * * * protocols * An array of protocols names supported by cURL * */ #[ArrayShape(["version_number" => "string", "version" => "string", "ssl_version_number" => "int", "ssl_version" => "string", "libz_version" => "string", "host" => "string", "age" => "int", "features" => "int", "protocols" => "array"])] #[Pure] function curl_version(#[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $age = null): array|false {} /** * Set an option for a cURL transfer * @link https://php.net/manual/en/function.curl-setopt.php * @param CurlHandle|resource $handle * @param int $option

    * The CURLOPT_XXX option to set. *

    * @param mixed|callable $value

    * The value to be set on option. *

    *

    * value should be a bool for the * following values of the option parameter:

    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    OptionSet value toNotes
    CURLOPT_AUTOREFERER * TRUE to automatically set the Referer: field in * requests where it follows a Location: redirect. * *
    CURLOPT_BINARYTRANSFER * TRUE to return the raw output when * CURLOPT_RETURNTRANSFER is used. * * From PHP 5.1.3, this option has no effect: the raw output will * always be returned when * CURLOPT_RETURNTRANSFER is used. *
    CURLOPT_COOKIESESSION * TRUE to mark this as a new cookie "session". It will force libcurl * to ignore all cookies it is about to load that are "session cookies" * from the previous session. By default, libcurl always stores and * loads all cookies, independent if they are session cookies or not. * Session cookies are cookies without expiry date and they are meant * to be alive and existing for this "session" only. * *
    CURLOPT_CERTINFO * TRUE to output SSL certification information to STDERR * on secure transfers. * * Added in cURL 7.19.1. * Available since PHP 5.3.2. * Requires CURLOPT_VERBOSE to be on to have an effect. *
    CURLOPT_CONNECT_ONLY * TRUE tells the library to perform all the required proxy authentication * and connection setup, but no data transfer. This option is implemented for * HTTP, SMTP and POP3. * * Added in 7.15.2. * Available since PHP 5.5.0. *
    CURLOPT_CRLF * TRUE to convert Unix newlines to CRLF newlines * on transfers. * *
    CURLOPT_DNS_USE_GLOBAL_CACHE * TRUE to use a global DNS cache. This option is * not thread-safe and is enabled by default. * *
    CURLOPT_FAILONERROR * TRUE to fail verbosely if the HTTP code returned * is greater than or equal to 400. The default behavior is to return * the page normally, ignoring the code. * *
    CURLOPT_FILETIME * TRUE to attempt to retrieve the modification * date of the remote document. This value can be retrieved using * the CURLINFO_FILETIME option with * {@see curl_getinfo()}. * *
    CURLOPT_FOLLOWLOCATION * TRUE to follow any * "Location: " header that the server sends as * part of the HTTP header (note this is recursive, PHP will follow as * many "Location: " headers that it is sent, * unless CURLOPT_MAXREDIRS is set). * *
    CURLOPT_FORBID_REUSE * TRUE to force the connection to explicitly * close when it has finished processing, and not be pooled for reuse. * *
    CURLOPT_FRESH_CONNECT * TRUE to force the use of a new connection * instead of a cached one. * *
    CURLOPT_FTP_USE_EPRT * TRUE to use EPRT (and LPRT) when doing active * FTP downloads. Use FALSE to disable EPRT and LPRT and use PORT * only. * *
    CURLOPT_FTP_USE_EPSV * TRUE to first try an EPSV command for FTP * transfers before reverting back to PASV. Set to FALSE * to disable EPSV. * *
    CURLOPT_FTP_CREATE_MISSING_DIRS * TRUE to create missing directories when an FTP operation * encounters a path that currently doesn't exist. * *
    CURLOPT_FTPAPPEND * TRUE to append to the remote file instead of * overwriting it. * *
    CURLOPT_TCP_NODELAY * TRUE to disable TCP's Nagle algorithm, which tries to minimize * the number of small packets on the network. * * Available since PHP 5.2.1 for versions compiled with libcurl 7.11.2 or * greater. *
    CURLOPT_FTPASCII * An alias of * CURLOPT_TRANSFERTEXT. Use that instead. * *
    CURLOPT_FTPLISTONLY * TRUE to only list the names of an FTP * directory. * *
    CURLOPT_HEADER * TRUE to include the header in the output. * *
    CURLINFO_HEADER_OUT * TRUE to track the handle's request string. * * Available since PHP 5.1.3. The CURLINFO_ * prefix is intentional. *
    CURLOPT_HTTPGET * TRUE to reset the HTTP request method to GET. * Since GET is the default, this is only necessary if the request * method has been changed. * *
    CURLOPT_HTTPPROXYTUNNEL * TRUE to tunnel through a given HTTP proxy. * *
    CURLOPT_MUTE * TRUE to be completely silent with regards to * the cURL functions. * * Removed in cURL 7.15.5 (You can use CURLOPT_RETURNTRANSFER instead) *
    CURLOPT_NETRC * TRUE to scan the ~/.netrc * file to find a username and password for the remote site that * a connection is being established with. * *
    CURLOPT_NOBODY * TRUE to exclude the body from the output. * Request method is then set to HEAD. Changing this to FALSE does * not change it to GET. * *
    CURLOPT_NOPROGRESS

    * TRUE to disable the progress meter for cURL transfers. *

    Note: *

    * PHP automatically sets this option to TRUE, this should only be * changed for debugging purposes. *

    *
    *
    *
    CURLOPT_NOSIGNAL * TRUE to ignore any cURL function that causes a * signal to be sent to the PHP process. This is turned on by default * in multi-threaded SAPIs so timeout options can still be used. * * Added in cURL 7.10. *
    CURLOPT_POST * TRUE to do a regular HTTP POST. This POST is the * normal application/x-www-form-urlencoded kind, * most commonly used by HTML forms. * *
    CURLOPT_PUT * TRUE to HTTP PUT a file. The file to PUT must * be set with CURLOPT_INFILE and * CURLOPT_INFILESIZE. * *
    CURLOPT_RETURNTRANSFER * TRUE to return the transfer as a string of the * return value of {@see curl_exec()} instead of outputting * it out directly. * *
    CURLOPT_SAFE_UPLOAD * TRUE to disable support for the @ prefix for * uploading files in CURLOPT_POSTFIELDS, which * means that values starting with @ can be safely * passed as fields. {@see CURLFile} may be used for * uploads instead. * * Added in PHP 5.5.0 with FALSE as the default value. PHP 5.6.0 * changes the default value to TRUE. *
    CURLOPT_SSL_VERIFYPEER * FALSE to stop cURL from verifying the peer's * certificate. Alternate certificates to verify against can be * specified with the CURLOPT_CAINFO option * or a certificate directory can be specified with the * CURLOPT_CAPATH option. * * TRUE by default as of cURL 7.10. Default bundle installed as of * cURL 7.10. *
    CURLOPT_TRANSFERTEXT * TRUE to use ASCII mode for FTP transfers. * For LDAP, it retrieves data in plain text instead of HTML. On * Windows systems, it will not set STDOUT to binary * mode. * *
    CURLOPT_UNRESTRICTED_AUTH * TRUE to keep sending the username and password * when following locations (using * CURLOPT_FOLLOWLOCATION), even when the * hostname has changed. * *
    CURLOPT_UPLOAD * TRUE to prepare for an upload. * *
    CURLOPT_VERBOSE * TRUE to output verbose information. Writes * output to STDERR, or the file specified using * CURLOPT_STDERR. * *
    * * value should be an integer for the following values of the option parameter: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    OptionSet value toNotes
    CURLOPT_BUFFERSIZE * The size of the buffer to use for each read. There is no guarantee * this request will be fulfilled, however. * * Added in cURL 7.10. *
    CURLOPT_CLOSEPOLICY * One of the CURLCLOSEPOLICY_* values. *

    Note: *

    * This option is deprecated, as it was never implemented in cURL and * never had any effect. *

    *
    *
    * Removed in PHP 5.6.0. *
    CURLOPT_CONNECTTIMEOUT * The number of seconds to wait while trying to connect. Use 0 to * wait indefinitely. * *
    CURLOPT_CONNECTTIMEOUT_MS * The number of milliseconds to wait while trying to connect. Use 0 to * wait indefinitely. * * If libcurl is built to use the standard system name resolver, that * portion of the connect will still use full-second resolution for * timeouts with a minimum timeout allowed of one second. * * Added in cURL 7.16.2. Available since PHP 5.2.3. *
    CURLOPT_DNS_CACHE_TIMEOUT * The number of seconds to keep DNS entries in memory. This * option is set to 120 (2 minutes) by default. * *
    CURLOPT_FTPSSLAUTH * The FTP authentication method (when is activated): * CURLFTPAUTH_SSL (try SSL first), * CURLFTPAUTH_TLS (try TLS first), or * CURLFTPAUTH_DEFAULT (let cURL decide). * * Added in cURL 7.12.2. *
    CURLOPT_HTTP_VERSION * CURL_HTTP_VERSION_NONE (default, lets CURL * decide which version to use), * CURL_HTTP_VERSION_1_0 (forces HTTP/1.0), * or CURL_HTTP_VERSION_1_1 (forces HTTP/1.1). * *
    CURLOPT_HTTPAUTH *

    * The HTTP authentication method(s) to use. The options are: * CURLAUTH_BASIC, * CURLAUTH_DIGEST, * CURLAUTH_GSSNEGOTIATE, * CURLAUTH_NTLM, * CURLAUTH_ANY, and * CURLAUTH_ANYSAFE. *

    *

    * The bitwise | (or) operator can be used to combine * more than one method. If this is done, cURL will poll the server to see * what methods it supports and pick the best one. *

    *

    * CURLAUTH_ANY is an alias for * CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM. *

    *

    * CURLAUTH_ANYSAFE is an alias for * CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM. *

    *
    *
    CURLOPT_INFILESIZE * The expected size, in bytes, of the file when uploading a file to * a remote site. Note that using this option will not stop libcurl * from sending more data, as exactly what is sent depends on * CURLOPT_READFUNCTION. * *
    CURLOPT_LOW_SPEED_LIMIT * The transfer speed, in bytes per second, that the transfer should be * below during the count of CURLOPT_LOW_SPEED_TIME * seconds before PHP considers the transfer too slow and aborts. * *
    CURLOPT_LOW_SPEED_TIME * The number of seconds the transfer speed should be below * CURLOPT_LOW_SPEED_LIMIT before PHP considers * the transfer too slow and aborts. * *
    CURLOPT_MAXCONNECTS * The maximum amount of persistent connections that are allowed. * When the limit is reached, * CURLOPT_CLOSEPOLICY is used to determine * which connection to close. * *
    CURLOPT_MAXREDIRS * The maximum amount of HTTP redirections to follow. Use this option * alongside CURLOPT_FOLLOWLOCATION. * *
    CURLOPT_PORT * An alternative port number to connect to. * *
    CURLOPT_POSTREDIR * A bitmask of 1 (301 Moved Permanently), 2 (302 Found) * vand 4 (303 See Other) if the HTTP POST method should be maintained * when CURLOPT_FOLLOWLOCATION is set and a * specific type of redirect occurs. * * Added in cURL 7.19.1. Available since PHP 5.3.2. *
    CURLOPT_PROTOCOLS *

    * Bitmask of CURLPROTO_* values. If used, this bitmask * limits what protocols libcurl may use in the transfer. This allows you to have * a libcurl built to support a wide range of protocols but still limit specific * transfers to only be allowed to use a subset of them. By default libcurl will * accept all protocols it supports. * See also CURLOPT_REDIR_PROTOCOLS. *

    *

    * Valid protocol options are: * CURLPROTO_HTTP, * CURLPROTO_HTTPS, * CURLPROTO_FTP, * CURLPROTO_FTPS, * CURLPROTO_SCP, * CURLPROTO_SFTP, * CURLPROTO_TELNET, * CURLPROTO_LDAP, * CURLPROTO_LDAPS, * CURLPROTO_DICT, * CURLPROTO_FILE, * CURLPROTO_TFTP, * CURLPROTO_ALL *

    *
    * Added in cURL 7.19.4. *
    CURLOPT_PROXYAUTH * The HTTP authentication method(s) to use for the proxy connection. * Use the same bitmasks as described in * CURLOPT_HTTPAUTH. For proxy authentication, * only CURLAUTH_BASIC and * CURLAUTH_NTLM are currently supported. * * Added in cURL 7.10.7. *
    CURLOPT_PROXYPORT * The port number of the proxy to connect to. This port number can * also be set in CURLOPT_PROXY. * *
    CURLOPT_PROXYTYPE * Either CURLPROXY_HTTP (default), * CURLPROXY_SOCKS4, * CURLPROXY_SOCKS5, * CURLPROXY_SOCKS4A or * CURLPROXY_SOCKS5_HOSTNAME. * * Added in cURL 7.10. *
    CURLOPT_REDIR_PROTOCOLS * Bitmask of CURLPROTO_* values. If used, this bitmask * limits what protocols libcurl may use in a transfer that it follows to in * a redirect when CURLOPT_FOLLOWLOCATION is enabled. * This allows you to limit specific transfers to only be allowed to use a subset * of protocols in redirections. By default libcurl will allow all protocols * except for FILE and SCP. This is a difference compared to pre-7.19.4 versions * which unconditionally would follow to all protocols supported. * See also CURLOPT_PROTOCOLS for protocol constant values. * * Added in cURL 7.19.4. *
    CURLOPT_RESUME_FROM * The offset, in bytes, to resume a transfer from. * *
    CURLOPT_SSL_VERIFYHOST * 1 to check the existence of a common name in the * SSL peer certificate. 2 to check the existence of * a common name and also verify that it matches the hostname * provided. In production environments the value of this option * should be kept at 2 (default value). * * Support for value 1 removed in cURL 7.28.1 *
    CURLOPT_SSLVERSION * One of CURL_SSLVERSION_DEFAULT (0), * CURL_SSLVERSION_TLSv1 (1), * CURL_SSLVERSION_SSLv2 (2), * CURL_SSLVERSION_SSLv3 (3), * CURL_SSLVERSION_TLSv1_0 (4), * CURL_SSLVERSION_TLSv1_1 (5) or * CURL_SSLVERSION_TLSv1_2 (6). *

    Note: *

    * Your best bet is to not set this and let it use the default. * Setting it to 2 or 3 is very dangerous given the known * vulnerabilities in SSLv2 and SSLv3. *

    *
    *
    *
    CURLOPT_TIMECONDITION * How CURLOPT_TIMEVALUE is treated. * Use CURL_TIMECOND_IFMODSINCE to return the * page only if it has been modified since the time specified in * CURLOPT_TIMEVALUE. If it hasn't been modified, * a "304 Not Modified" header will be returned * assuming CURLOPT_HEADER is TRUE. * Use CURL_TIMECOND_IFUNMODSINCE for the reverse * effect. CURL_TIMECOND_IFMODSINCE is the * default. * *
    CURLOPT_TIMEOUT * The maximum number of seconds to allow cURL functions to execute. * *
    CURLOPT_TIMEOUT_MS * The maximum number of milliseconds to allow cURL functions to * execute. * * If libcurl is built to use the standard system name resolver, that * portion of the connect will still use full-second resolution for * timeouts with a minimum timeout allowed of one second. * * Added in cURL 7.16.2. Available since PHP 5.2.3. *
    CURLOPT_TIMEVALUE * The time in seconds since January 1st, 1970. The time will be used * by CURLOPT_TIMECONDITION. By default, * CURL_TIMECOND_IFMODSINCE is used. * *
    CURLOPT_MAX_RECV_SPEED_LARGE * If a download exceeds this speed (counted in bytes per second) on * cumulative average during the transfer, the transfer will pause to * keep the average rate less than or equal to the parameter value. * Defaults to unlimited speed. * * Added in cURL 7.15.5. Available since PHP 5.4.0. *
    CURLOPT_MAX_SEND_SPEED_LARGE * If an upload exceeds this speed (counted in bytes per second) on * cumulative average during the transfer, the transfer will pause to * keep the average rate less than or equal to the parameter value. * Defaults to unlimited speed. * * Added in cURL 7.15.5. Available since PHP 5.4.0. *
    CURLOPT_SSH_AUTH_TYPES * A bitmask consisting of one or more of * CURLSSH_AUTH_PUBLICKEY, * CURLSSH_AUTH_PASSWORD, * CURLSSH_AUTH_HOST, * CURLSSH_AUTH_KEYBOARD. Set to * CURLSSH_AUTH_ANY to let libcurl pick one. * * Added in cURL 7.16.1. *
    CURLOPT_IPRESOLVE * Allows an application to select what kind of IP addresses to use when * resolving host names. This is only interesting when using host names that * resolve addresses using more than one version of IP, possible values are * CURL_IPRESOLVE_WHATEVER, * CURL_IPRESOLVE_V4, * CURL_IPRESOLVE_V6, by default * CURL_IPRESOLVE_WHATEVER. * * Added in cURL 7.10.8. *
    * * value should be a string for the following values of the option parameter: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    OptionSet value toNotes
    CURLOPT_CAINFO * The name of a file holding one or more certificates to verify the * peer with. This only makes sense when used in combination with * CURLOPT_SSL_VERIFYPEER. * * Might require an absolute path. *
    CURLOPT_CAPATH * A directory that holds multiple CA certificates. Use this option * alongside CURLOPT_SSL_VERIFYPEER. * *
    CURLOPT_COOKIE * The contents of the "Cookie: " header to be * used in the HTTP request. * Note that multiple cookies are separated with a semicolon followed * by a space (e.g., "fruit=apple; colour=red") * *
    CURLOPT_COOKIEFILE * The name of the file containing the cookie data. The cookie file can * be in Netscape format, or just plain HTTP-style headers dumped into * a file. * If the name is an empty string, no cookies are loaded, but cookie * handling is still enabled. * *
    CURLOPT_COOKIEJAR * The name of a file to save all internal cookies to when the handle is closed, * e.g. after a call to curl_close. * *
    CURLOPT_CUSTOMREQUEST

    * A custom request method to use instead of * "GET" or "HEAD" when doing * a HTTP request. This is useful for doing * "DELETE" or other, more obscure HTTP requests. * Valid values are things like "GET", * "POST", "CONNECT" and so on; * i.e. Do not enter a whole HTTP request line here. For instance, * entering "GET /index.html HTTP/1.0\r\n\r\n" * would be incorrect. *

    Note: *

    * Don't do this without making sure the server supports the custom * request method first. *

    *
    *
    *
    CURLOPT_EGDSOCKET * Like CURLOPT_RANDOM_FILE, except a filename * to an Entropy Gathering Daemon socket. * *
    CURLOPT_ENCODING * The contents of the "Accept-Encoding: " header. * This enables decoding of the response. Supported encodings are * "identity", "deflate", and * "gzip". If an empty string, "", * is set, a header containing all supported encoding types is sent. * * Added in cURL 7.10. *
    CURLOPT_FTPPORT * The value which will be used to get the IP address to use * for the FTP "PORT" instruction. The "PORT" instruction tells * the remote server to connect to our specified IP address. The * string may be a plain IP address, a hostname, a network * interface name (under Unix), or just a plain '-' to use the * systems default IP address. * *
    CURLOPT_INTERFACE * The name of the outgoing network interface to use. This can be an * interface name, an IP address or a host name. * *
    CURLOPT_KEYPASSWD * The password required to use the CURLOPT_SSLKEY * or CURLOPT_SSH_PRIVATE_KEYFILE private key. * * Added in cURL 7.16.1. *
    CURLOPT_KRB4LEVEL * The KRB4 (Kerberos 4) security level. Any of the following values * (in order from least to most powerful) are valid: * "clear", * "safe", * "confidential", * "private".. * If the string does not match one of these, * "private" is used. Setting this option to NULL * will disable KRB4 security. Currently KRB4 security only works * with FTP transactions. * *
    CURLOPT_POSTFIELDS * * The full data to post in a HTTP "POST" operation. * To post a file, prepend a filename with @ and * use the full path. The filetype can be explicitly specified by * following the filename with the type in the format * ';type=mimetype'. This parameter can either be * passed as a urlencoded string like 'para1=val1&para2=val2&...' * or as an array with the field name as key and field data as value. * If value is an array, the * Content-Type header will be set to * multipart/form-data. * * * As of PHP 5.2.0, value must be an array if * files are passed to this option with the @ prefix. * * * As of PHP 5.5.0, the @ prefix is deprecated and * files can be sent using CURLFile. The * @ prefix can be disabled for safe passing of * values beginning with @ by setting the * CURLOPT_SAFE_UPLOAD option to TRUE. * * *
    CURLOPT_PROXY * The HTTP proxy to tunnel requests through. * *
    CURLOPT_PROXYUSERPWD * A username and password formatted as * "[username]:[password]" to use for the * connection to the proxy. * *
    CURLOPT_RANDOM_FILE * A filename to be used to seed the random number generator for SSL. * *
    CURLOPT_RANGE * Range(s) of data to retrieve in the format * "X-Y" where X or Y are optional. HTTP transfers * also support several intervals, separated with commas in the format * "X-Y,N-M". * *
    CURLOPT_REFERER * The contents of the "Referer: " header to be used * in a HTTP request. * *
    CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 * A string containing 32 hexadecimal digits. The string should be the * MD5 checksum of the remote host's public key, and libcurl will reject * the connection to the host unless the md5sums match. * This option is only for SCP and SFTP transfers. * * Added in cURL 7.17.1. *
    CURLOPT_SSH_PUBLIC_KEYFILE * The file name for your public key. If not used, libcurl defaults to * $HOME/.ssh/id_dsa.pub if the HOME environment variable is set, * and just "id_dsa.pub" in the current directory if HOME is not set. * * Added in cURL 7.16.1. *
    CURLOPT_SSH_PRIVATE_KEYFILE * The file name for your private key. If not used, libcurl defaults to * $HOME/.ssh/id_dsa if the HOME environment variable is set, * and just "id_dsa" in the current directory if HOME is not set. * If the file is password-protected, set the password with * CURLOPT_KEYPASSWD. * * Added in cURL 7.16.1. *
    CURLOPT_SSL_CIPHER_LIST * A list of ciphers to use for SSL. For example, * RC4-SHA and TLSv1 are valid * cipher lists. * *
    CURLOPT_SSLCERT * The name of a file containing a PEM formatted certificate. * *
    CURLOPT_SSLCERTPASSWD * The password required to use the * CURLOPT_SSLCERT certificate. * *
    CURLOPT_SSLCERTTYPE * The format of the certificate. Supported formats are * "PEM" (default), "DER", * and "ENG". * * Added in cURL 7.9.3. *
    CURLOPT_SSLENGINE * The identifier for the crypto engine of the private SSL key * specified in CURLOPT_SSLKEY. * *
    CURLOPT_SSLENGINE_DEFAULT * The identifier for the crypto engine used for asymmetric crypto * operations. * *
    CURLOPT_SSLKEY * The name of a file containing a private SSL key. * *
    CURLOPT_SSLKEYPASSWD

    * The secret password needed to use the private SSL key specified in * CURLOPT_SSLKEY. *

    Note: *

    * Since this option contains a sensitive password, remember to keep * the PHP script it is contained within safe. *

    *
    *
    *
    CURLOPT_SSLKEYTYPE * The key type of the private SSL key specified in * CURLOPT_SSLKEY. Supported key types are * "PEM" (default), "DER", * and "ENG". * *
    CURLOPT_URL * The URL to fetch. This can also be set when initializing a * session with {@see curl_init()}. * *
    CURLOPT_USERAGENT * The contents of the "User-Agent: " header to be * used in a HTTP request. * *
    CURLOPT_USERPWD * A username and password formatted as * "[username]:[password]" to use for the * connection. * *
    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    OptionSet value toNotes
    CURLOPT_CAINFO * The name of a file holding one or more certificates to verify the * peer with. This only makes sense when used in combination with * CURLOPT_SSL_VERIFYPEER. * * Might require an absolute path. *
    CURLOPT_CAPATH * A directory that holds multiple CA certificates. Use this option * alongside CURLOPT_SSL_VERIFYPEER. * *
    CURLOPT_COOKIE * The contents of the "Cookie: " header to be * used in the HTTP request. * Note that multiple cookies are separated with a semicolon followed * by a space (e.g., "fruit=apple; colour=red") * *
    CURLOPT_COOKIEFILE * The name of the file containing the cookie data. The cookie file can * be in Netscape format, or just plain HTTP-style headers dumped into * a file. * If the name is an empty string, no cookies are loaded, but cookie * handling is still enabled. * *
    CURLOPT_COOKIEJAR * The name of a file to save all internal cookies to when the handle is closed, * e.g. after a call to curl_close. * *
    CURLOPT_CUSTOMREQUEST

    * A custom request method to use instead of * "GET" or "HEAD" when doing * a HTTP request. This is useful for doing * "DELETE" or other, more obscure HTTP requests. * Valid values are things like "GET", * "POST", "CONNECT" and so on; * i.e. Do not enter a whole HTTP request line here. For instance, * entering "GET /index.html HTTP/1.0\r\n\r\n" * would be incorrect. *

    Note: *

    * Don't do this without making sure the server supports the custom * request method first. *

    *
    *
    *
    CURLOPT_EGDSOCKET * Like CURLOPT_RANDOM_FILE, except a filename * to an Entropy Gathering Daemon socket. * *
    CURLOPT_ENCODING * The contents of the "Accept-Encoding: " header. * This enables decoding of the response. Supported encodings are * "identity", "deflate", and * "gzip". If an empty string, "", * is set, a header containing all supported encoding types is sent. * * Added in cURL 7.10. *
    CURLOPT_FTPPORT * The value which will be used to get the IP address to use * for the FTP "PORT" instruction. The "PORT" instruction tells * the remote server to connect to our specified IP address. The * string may be a plain IP address, a hostname, a network * interface name (under Unix), or just a plain '-' to use the * systems default IP address. * *
    CURLOPT_INTERFACE * The name of the outgoing network interface to use. This can be an * interface name, an IP address or a host name. * *
    CURLOPT_KEYPASSWD * The password required to use the CURLOPT_SSLKEY * or CURLOPT_SSH_PRIVATE_KEYFILE private key. * * Added in cURL 7.16.1. *
    CURLOPT_KRB4LEVEL * The KRB4 (Kerberos 4) security level. Any of the following values * (in order from least to most powerful) are valid: * "clear", * "safe", * "confidential", * "private".. * If the string does not match one of these, * "private" is used. Setting this option to NULL * will disable KRB4 security. Currently KRB4 security only works * with FTP transactions. * *
    CURLOPT_POSTFIELDS * * The full data to post in a HTTP "POST" operation. * To post a file, prepend a filename with @ and * use the full path. The filetype can be explicitly specified by * following the filename with the type in the format * ';type=mimetype'. This parameter can either be * passed as a urlencoded string like 'para1=val1&para2=val2&...' * or as an array with the field name as key and field data as value. * If value is an array, the * Content-Type header will be set to * multipart/form-data. * * * As of PHP 5.2.0, value must be an array if * files are passed to this option with the @ prefix. * * * As of PHP 5.5.0, the @ prefix is deprecated and * files can be sent using CURLFile. The * @ prefix can be disabled for safe passing of * values beginning with @ by setting the * CURLOPT_SAFE_UPLOAD option to TRUE. * * *
    CURLOPT_PROXY * The HTTP proxy to tunnel requests through. * *
    CURLOPT_PROXYUSERPWD * A username and password formatted as * "[username]:[password]" to use for the * connection to the proxy. * *
    CURLOPT_RANDOM_FILE * A filename to be used to seed the random number generator for SSL. * *
    CURLOPT_RANGE * Range(s) of data to retrieve in the format * "X-Y" where X or Y are optional. HTTP transfers * also support several intervals, separated with commas in the format * "X-Y,N-M". * *
    CURLOPT_REFERER * The contents of the "Referer: " header to be used * in a HTTP request. * *
    CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 * A string containing 32 hexadecimal digits. The string should be the * MD5 checksum of the remote host's public key, and libcurl will reject * the connection to the host unless the md5sums match. * This option is only for SCP and SFTP transfers. * * Added in cURL 7.17.1. *
    CURLOPT_SSH_PUBLIC_KEYFILE * The file name for your public key. If not used, libcurl defaults to * $HOME/.ssh/id_dsa.pub if the HOME environment variable is set, * and just "id_dsa.pub" in the current directory if HOME is not set. * * Added in cURL 7.16.1. *
    CURLOPT_SSH_PRIVATE_KEYFILE * The file name for your private key. If not used, libcurl defaults to * $HOME/.ssh/id_dsa if the HOME environment variable is set, * and just "id_dsa" in the current directory if HOME is not set. * If the file is password-protected, set the password with * CURLOPT_KEYPASSWD. * * Added in cURL 7.16.1. *
    CURLOPT_SSL_CIPHER_LIST * A list of ciphers to use for SSL. For example, * RC4-SHA and TLSv1 are valid * cipher lists. * *
    CURLOPT_SSLCERT * The name of a file containing a PEM formatted certificate. * *
    CURLOPT_SSLCERTPASSWD * The password required to use the * CURLOPT_SSLCERT certificate. * *
    CURLOPT_SSLCERTTYPE * The format of the certificate. Supported formats are * "PEM" (default), "DER", * and "ENG". * * Added in cURL 7.9.3. *
    CURLOPT_SSLENGINE * The identifier for the crypto engine of the private SSL key * specified in CURLOPT_SSLKEY. * *
    CURLOPT_SSLENGINE_DEFAULT * The identifier for the crypto engine used for asymmetric crypto * operations. * *
    CURLOPT_SSLKEY * The name of a file containing a private SSL key. * *
    CURLOPT_SSLKEYPASSWD

    * The secret password needed to use the private SSL key specified in * CURLOPT_SSLKEY. *

    Note: *

    * Since this option contains a sensitive password, remember to keep * the PHP script it is contained within safe. *

    *
    *
    *
    CURLOPT_SSLKEYTYPE * The key type of the private SSL key specified in * CURLOPT_SSLKEY. Supported key types are * "PEM" (default), "DER", * and "ENG". * *
    CURLOPT_URL * The URL to fetch. This can also be set when initializing a * session with curl_init(). * *
    CURLOPT_USERAGENT * The contents of the "User-Agent: " header to be * used in a HTTP request. * *
    CURLOPT_USERPWD * A username and password formatted as * "[username]:[password]" to use for the * connection. * *
    *

    * value should be an array for the following values of the option parameter:

    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    OptionSet value toNotes
    CURLOPT_HTTP200ALIASES * An array of HTTP 200 responses that will be treated as valid * responses and not as errors. * * Added in cURL 7.10.3. *
    CURLOPT_HTTPHEADER * An array of HTTP header fields to set, in the format * * array('Content-type: text/plain', 'Content-length: 100') * * *
    CURLOPT_POSTQUOTE * An array of FTP commands to execute on the server after the FTP * request has been performed. * *
    CURLOPT_QUOTE * An array of FTP commands to execute on the server prior to the FTP * request. * *
    * value should be a stream resource (using {@see fopen()}, for example) for the following values of the option parameter: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    OptionSet value to
    CURLOPT_FILE * The file that the transfer should be written to. The default * is STDOUT (the browser window). *
    CURLOPT_INFILE * The file that the transfer should be read from when uploading. *
    CURLOPT_STDERR * An alternative location to output errors to instead of * STDERR. *
    CURLOPT_WRITEHEADER * The file that the header part of the transfer is written to. *
    * value should be the name of a valid function or a Closure for the following values of the option parameter: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    OptionSet value to
    CURLOPT_HEADERFUNCTION * A callback accepting two parameters. * The first is the cURL resource, the second is a * string with the header data to be written. The header data must * be written by this callback. Return the number of * bytes written. *
    CURLOPT_PASSWDFUNCTION * A callback accepting three parameters. * The first is the cURL resource, the second is a * string containing a password prompt, and the third is the maximum * password length. Return the string containing the password. *
    CURLOPT_PROGRESSFUNCTION *

    * A callback accepting five parameters. * The first is the cURL resource, the second is the total number of * bytes expected to be downloaded in this transfer, the third is * the number of bytes downloaded so far, the fourth is the total * number of bytes expected to be uploaded in this transfer, and the * fifth is the number of bytes uploaded so far. *

    *

    Note: *

    * The callback is only called when the CURLOPT_NOPROGRESS * option is set to FALSE. *

    *
    *

    * Return a non-zero value to abort the transfer. In which case, the * transfer will set a CURLE_ABORTED_BY_CALLBACK * error. *

    *
    CURLOPT_READFUNCTION * A callback accepting three parameters. * The first is the cURL resource, the second is a * stream resource provided to cURL through the option * CURLOPT_INFILE, and the third is the maximum * amount of data to be read. The callback must return a string * with a length equal or smaller than the amount of data requested, * typically by reading it from the passed stream resource. It should * return an empty string to signal EOF. *
    CURLOPT_WRITEFUNCTION * A callback accepting two parameters. * The first is the cURL resource, and the second is a * string with the data to be written. The data must be saved by * this callback. It must return the exact number of bytes written * or the transfer will be aborted with an error. *
    * Other values: * * * * * * * * * * * * * * * * *
    OptionSet value to
    CURLOPT_SHARE * A result of {@see curl_share_init()}. Makes the cURL * handle to use the data from the shared handle. *
    * @return bool true on success or false on failure. */ function curl_setopt(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle, int $option, mixed $value): bool {} /** * Set multiple options for a cURL transfer * @link https://php.net/manual/en/function.curl-setopt-array.php * @param CurlHandle|resource $handle * @param array $options

    * An array specifying which options to set and their values. * The keys should be valid curl_setopt constants or * their integer equivalents. *

    * @return bool true if all options were successfully set. If an option could * not be successfully set, false is immediately returned, ignoring any * future options in the options array. * @since 5.1.3 */ function curl_setopt_array(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle, array $options): bool {} /** * (PHP 5 >=5.5.0)
    * Close a cURL share handle * @link https://secure.php.net/manual/en/function.curl-share-close.php * @param CurlShareHandle|resource $share_handle

    * A cURL share handle returned by {@link https://secure.php.net/manual/en/function.curl-share-init.php curl_share_init()} *

    * @return void * @since 5.5 */ function curl_share_close(#[LanguageLevelTypeAware(['8.0' => 'CurlShareHandle'], default: 'resource')] $share_handle): void {} /** * (PHP 5 >=5.5.0)
    * Initialize a cURL share handle * @link https://secure.php.net/manual/en/function.curl-share-init.php * @return resource|CurlShareHandle Returns resource of type "cURL Share Handle". * @since 5.5 */ #[LanguageLevelTypeAware(['8.0' => 'CurlShareHandle'], default: 'resource')] function curl_share_init() {} /** * (PHP 5 >=5.5.0)
    * Set an option for a cURL share handle. * @link https://secure.php.net/manual/en/function.curl-share-setopt.php * @param CurlShareHandle|resource $share_handle

    * A cURL share handle returned by {@link https://secure.php.net/manual/en/function.curl-share-init.php curl_share_init()}. *

    * @param int $option * * * * * * * * * * * * * * * * * * * * * *
    OptionDescription
    CURLSHOPT_SHARE * Specifies a type of data that should be shared. *
    CURLSHOPT_UNSHARE * Specifies a type of data that will be no longer shared. *
    * @param string $value

    * * * * * * * * * * * * * * * * * * * * * * * * * * *
    ValueDescription
    CURL_LOCK_DATA_COOKIE * Shares cookie data. *
    CURL_LOCK_DATA_DNS * Shares DNS cache. Note that when you use cURL multi handles, * all handles added to the same multi handle will share DNS cache * by default. *
    CURL_LOCK_DATA_SSL_SESSION * Shares SSL session IDs, reducing the time spent on the SSL * handshake when reconnecting to the same server. Note that SSL * session IDs are reused within the same handle by default. *
    *

    * @return bool * Returns TRUE on success or FALSE on failure. * @since 5.5 */ function curl_share_setopt(#[LanguageLevelTypeAware(['8.0' => 'CurlShareHandle'], default: 'resource')] $share_handle, int $option, mixed $value): bool {} /** * (PHP 5 >=5.5.0)
    * Return string describing the given error code * @link https://secure.php.net/manual/en/function.curl-strerror.php * @param int $error_code

    * One of the {@link https://curl.haxx.se/libcurl/c/libcurl-errors.html  cURL error codes} constants. *

    * @return string|null Returns error description or NULL for invalid error code. * @since 5.5 */ #[Pure] function curl_strerror(int $error_code): ?string {} /** * (PHP 5 >=5.5.0)
    * Decodes the given URL encoded string * @link https://secure.php.net/manual/en/function.curl-unescape.php * @param CurlHandle|resource $handle

    A cURL handle returned by * {@link https://secure.php.net/manual/en/function.curl-init.php curl_init()}.

    * @param string $string

    * The URL encoded string to be decoded. *

    * @return string|false Returns decoded string or FALSE on failure. * @since 5.5 */ #[Pure] function curl_unescape(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle, string $string): string|false {} /** * Perform a cURL session * @link https://php.net/manual/en/function.curl-exec.php * @param CurlHandle|resource $handle * @return string|bool true on success or false on failure. However, if the CURLOPT_RETURNTRANSFER * option is set, it will return the result on success, false on failure. */ function curl_exec(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle): string|bool {} /** * Get information regarding a specific transfer * @link https://php.net/manual/en/function.curl-getinfo.php * @param CurlHandle|resource $handle * @param int|null $option [optional]

    * This may be one of the following constants: *

      *
    • * CURLINFO_EFFECTIVE_URL - Last effective URL *
    • *
    • * CURLINFO_HTTP_CODE - The last response code. As of cURL 7.10.8, this is a legacy alias of * CURLINFO_RESPONSE_CODE * *
    • *
    • * CURLINFO_FILETIME - Remote time of the retrieved document, with the * CURLOPT_FILETIME * enabled; if -1 is returned the time of the document is unknown *
    • *
    • * CURLINFO_TOTAL_TIME - Total transaction time in seconds for last transfer *
    • *
    • * CURLINFO_NAMELOOKUP_TIME - Time in seconds until name resolving was complete *
    • *
    • * CURLINFO_CONNECT_TIME - Time in seconds it took to establish the connection *
    • *
    • * CURLINFO_PRETRANSFER_TIME - Time in seconds from start until just before file transfer begins *
    • *
    • * CURLINFO_STARTTRANSFER_TIME - Time in seconds until the first byte is about to be transferred *
    • *
    • * CURLINFO_REDIRECT_COUNT - Number of redirects, with the * CURLOPT_FOLLOWLOCATION * option enabled *
    • *
    • * CURLINFO_REDIRECT_TIME - Time in seconds of all redirection steps before final transaction was started, with the * CURLOPT_FOLLOWLOCATION * option enabled *
    • *
    • * CURLINFO_REDIRECT_URL - With the * CURLOPT_FOLLOWLOCATION * option disabled: redirect URL found in the last transaction, that should be requested manually next. With the * CURLOPT_FOLLOWLOCATION * option enabled: this is empty. The redirect URL in this case is available in * CURLINFO_EFFECTIVE_URL * *
    • *
    • * CURLINFO_PRIMARY_IP - IP address of the most recent connection *
    • *
    • * CURLINFO_PRIMARY_PORT - Destination port of the most recent connection *
    • *
    • * CURLINFO_LOCAL_IP - Local (source) IP address of the most recent connection *
    • *
    • * CURLINFO_LOCAL_PORT - Local (source) port of the most recent connection *
    • *
    • * CURLINFO_SIZE_UPLOAD - Total number of bytes uploaded *
    • *
    • * CURLINFO_SIZE_DOWNLOAD - Total number of bytes downloaded *
    • *
    • * CURLINFO_SPEED_DOWNLOAD - Average download speed *
    • *
    • * CURLINFO_SPEED_UPLOAD - Average upload speed *
    • *
    • * CURLINFO_HEADER_SIZE - Total size of all headers received *
    • *
    • * CURLINFO_HEADER_OUT - The request string sent. For this to work, add the * CURLINFO_HEADER_OUT * option to the handle by calling curl_setopt() *
    • *
    • * CURLINFO_REQUEST_SIZE - Total size of issued requests, currently only for HTTP requests *
    • *
    • * CURLINFO_SSL_VERIFYRESULT - Result of SSL certification verification requested by setting * CURLOPT_SSL_VERIFYPEER * *
    • *
    • * CURLINFO_CONTENT_LENGTH_DOWNLOAD - Content length of download, read from * Content-Length: field *
    • *
    • * CURLINFO_CONTENT_LENGTH_UPLOAD - Specified size of upload *
    • *
    • * CURLINFO_CONTENT_TYPE * - * Content-Type: of the requested document. NULL indicates server did not send valid * Content-Type: header *
    • *
    • * CURLINFO_PRIVATE - Private data associated with this cURL handle, previously set with the * CURLOPT_PRIVATE * option of curl_setopt() *
    • *
    • * CURLINFO_RESPONSE_CODE - The last response code *
    • *
    • * CURLINFO_HTTP_CONNECTCODE - The CONNECT response code *
    • *
    • * CURLINFO_HTTPAUTH_AVAIL - Bitmask indicating the authentication method(s) available according to the previous response *
    • *
    • * CURLINFO_PROXYAUTH_AVAIL - Bitmask indicating the proxy authentication method(s) available according to the previous response *
    • *
    • * CURLINFO_OS_ERRNO - Errno from a connect failure. The number is OS and system specific. *
    • *
    • * CURLINFO_NUM_CONNECTS - Number of connections curl had to create to achieve the previous transfer *
    • *
    • * CURLINFO_SSL_ENGINES - OpenSSL crypto-engines supported *
    • *
    • * CURLINFO_COOKIELIST - All known cookies *
    • *
    • * CURLINFO_FTP_ENTRY_PATH - Entry path in FTP server *
    • *
    • * CURLINFO_APPCONNECT_TIME - Time in seconds it took from the start until the SSL/SSH connect/handshake to the remote host was completed *
    • *
    • * CURLINFO_CERTINFO - TLS certificate chain *
    • *
    • * CURLINFO_CONDITION_UNMET - Info on unmet time conditional *
    • *
    • * CURLINFO_RTSP_CLIENT_CSEQ - Next RTSP client CSeq *
    • *
    • * CURLINFO_RTSP_CSEQ_RECV - Recently received CSeq *
    • *
    • * CURLINFO_RTSP_SERVER_CSEQ - Next RTSP server CSeq *
    • *
    • * CURLINFO_RTSP_SESSION_ID - RTSP session ID *
    • *
    • * CURLINFO_CONTENT_LENGTH_DOWNLOAD_T - The content-length of the download. This is the value read from the * Content-Type: field. -1 if the size isn't known *
    • *
    • * CURLINFO_CONTENT_LENGTH_UPLOAD_T - The specified size of the upload. -1 if the size isn't known *
    • *
    • * CURLINFO_HTTP_VERSION - The version used in the last HTTP connection. The return value will be one of the defined * CURL_HTTP_VERSION_* * constants or 0 if the version can't be determined *
    • *
    • * CURLINFO_PROTOCOL - The protocol used in the last HTTP connection. The returned value will be exactly one of the * CURLPROTO_* * values *
    • *
    • * CURLINFO_PROXY_SSL_VERIFYRESULT - The result of the certificate verification that was requested (using the * CURLOPT_PROXY_SSL_VERIFYPEER * option). Only used for HTTPS proxies *
    • *
    • * CURLINFO_SCHEME - The URL scheme used for the most recent connection *
    • *
    • * CURLINFO_SIZE_DOWNLOAD_T - Total number of bytes that were downloaded. The number is only for the latest transfer and will be reset again for each new transfer *
    • *
    • * CURLINFO_SIZE_UPLOAD_T - Total number of bytes that were uploaded *
    • *
    • * CURLINFO_SPEED_DOWNLOAD_T - The average download speed in bytes/second that curl measured for the complete download *
    • *
    • * CURLINFO_SPEED_UPLOAD_T - The average upload speed in bytes/second that curl measured for the complete upload *
    • *
    • * CURLINFO_APPCONNECT_TIME_T - Time, in microseconds, it took from the start until the SSL/SSH connect/handshake to the remote host was completed *
    • *
    • * CURLINFO_CONNECT_TIME_T - Total time taken, in microseconds, from the start until the connection to the remote host (or proxy) was completed *
    • *
    • * CURLINFO_FILETIME_T - Remote time of the retrieved document (as Unix timestamp), an alternative to * CURLINFO_FILETIME * to allow systems with 32 bit long variables to extract dates outside of the 32bit timestamp range *
    • *
    • * CURLINFO_NAMELOOKUP_TIME_T - Time in microseconds from the start until the name resolving was completed *
    • *
    • * CURLINFO_PRETRANSFER_TIME_T - Time taken from the start until the file transfer is just about to begin, in microseconds *
    • *
    • * CURLINFO_REDIRECT_TIME_T - Total time, in microseconds, it took for all redirection steps include name lookup, connect, pretransfer and transfer before final transaction was started *
    • *
    • * CURLINFO_STARTTRANSFER_TIME_T - Time, in microseconds, it took from the start until the first byte is received *
    • *
    • * CURLINFO_TOTAL_TIME_T - Total time in microseconds for the previous transfer, including name resolving, TCP connect etc. *
    * * @return mixed If $option is given, returns its value as a string. * Otherwise, returns an associative array with the following elements * (which correspond to $option), or false on failure: *
      *
    • url
    • *
    • content_type
    • *
    • http_code
    • *
    • header_size
    • *
    • request_size
    • *
    • filetime
    • *
    • ssl_verify_result
    • *
    • redirect_count
    • *
    • total_time
    • *
    • namelookup_time
    • *
    • connect_time
    • *
    • pretransfer_time
    • *
    • size_upload
    • *
    • size_download
    • *
    • speed_download
    • *
    • speed_upload
    • *
    • download_content_length
    • *
    • upload_content_length
    • *
    • starttransfer_time
    • *
    • redirect_time
    • *
    • certinfo
    • *
    • primary_ip
    • *
    • primary_port
    • *
    • local_ip
    • *
    • local_port
    • *
    • redirect_url
    • *
    • request_header (This is only set if the * CURLINFO_HEADER_OUT * is set by a previous call to curl_setopt() *
    • *
    */ #[Pure(true)] function curl_getinfo(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle, ?int $option): mixed {} /** * Return a string containing the last error for the current session * @link https://php.net/manual/en/function.curl-error.php * @param CurlHandle|resource $handle * @return string the error message or '' (the empty string) if no * error occurred. */ #[Pure(true)] function curl_error(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle): string {} /** * Return the last error number * @link https://php.net/manual/en/function.curl-errno.php * @param CurlHandle|resource $handle * @return int the error number or 0 (zero) if no error * occurred. */ #[Pure(true)] function curl_errno(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle): int {} /** * URL encodes the given string * @link https://secure.php.net/manual/en/function.curl-escape.php * @param CurlHandle|resource $handle

    * A cURL handle returned by * {@link https://secure.php.net/manual/en/function.curl-init.php curl_init()}.

    * @param string $string

    * The string to be encoded.

    * @return string|false Returns escaped string or FALSE on failure. * @since 5.5 */ #[Pure] function curl_escape(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle, string $string): string|false {} /** * (PHP 5 >= 5.5.0)
    * Create a CURLFile object * @link https://secure.php.net/manual/en/curlfile.construct.php * @param string $filename

    Path to the file which will be uploaded.

    * @param string|null $mime_type

    Mimetype of the file.

    * @param string|null $posted_filename

    Name of the file.

    * @return CURLFile * Returns a {@link https://secure.php.net/manual/en/class.curlfile.php CURLFile} object. * @since 5.5 */ #[Pure] function curl_file_create(string $filename, ?string $mime_type = null, ?string $posted_filename = null): CURLFile {} /** * Close a cURL session * @link https://php.net/manual/en/function.curl-close.php * @param CurlHandle|resource $handle * @return void */ function curl_close(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle): void {} /** * Returns a new cURL multi handle * @link https://php.net/manual/en/function.curl-multi-init.php * @return resource|CurlMultiHandle a cURL multi handle resource or object depends on the php version */ #[LanguageLevelTypeAware(['8.0' => 'CurlMultiHandle'], default: 'resource')] function curl_multi_init(): CurlMultiHandle {} /** * Add a normal cURL handle to a cURL multi handle * @link https://php.net/manual/en/function.curl-multi-add-handle.php * @param CurlMultiHandle|resource $multi_handle * @param CurlHandle|resource $handle * @return int 0 on success, or one of the CURLM_XXX errors * code. */ function curl_multi_add_handle(#[LanguageLevelTypeAware(['8.0' => 'CurlMultiHandle'], default: 'resource')] $multi_handle, #[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle): int {} /** * Remove a multi handle from a set of cURL handles * @link https://php.net/manual/en/function.curl-multi-remove-handle.php * @param CurlMultiHandle|resource $multi_handle * @param CurlHandle|resource $handle * @return int|false On success, returns one of the CURLM_XXX error codes, false on failure. */ #[LanguageLevelTypeAware(['8.0' => 'int'], default: 'int|false')] function curl_multi_remove_handle(#[LanguageLevelTypeAware(['8.0' => 'CurlMultiHandle'], default: 'resource')] $multi_handle, #[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle) {} /** * Wait for activity on any curl_multi connection * @link https://php.net/manual/en/function.curl-multi-select.php * @param CurlMultiHandle|resource $multi_handle * @param float $timeout [optional]

    * Time, in seconds, to wait for a response. *

    * @return int On success, returns the number of descriptors contained in, * the descriptor sets. On failure, this function will return -1 on a select failure or timeout (from the underlying select system call). */ function curl_multi_select(#[LanguageLevelTypeAware(['8.0' => 'CurlMultiHandle'], default: 'resource')] $multi_handle, float $timeout = 1.0): int {} /** * (PHP 5 >=5.5.0)
    * Set an option for the cURL multi handle * @link https://secure.php.net/manual/en/function.curl-multi-setopt.php * @param CurlMultiHandle|resource $multi_handle * @param int $option

    * One of the CURLMOPT_* constants. *

    * @param mixed $value

    * The value to be set on option. *

    *

    * value should be an {@link https://php.net/manual/en/language.types.integer.php int} for the * following values of the option parameter: *

    * * * * * * * * * * * * * * * * * * * *
    OptionSet value to
    CURLMOPT_PIPELINING * Pass 1 to enable or 0 to disable. Enabling pipelining on a multi * handle will make it attempt to perform HTTP Pipelining as far as * possible for transfers using this handle. This means that if you add * a second request that can use an already existing connection, the * second request will be "piped" on the same connection rather than * being executed in parallel. *
    CURLMOPT_MAXCONNECTS * Pass a number that will be used as the maximum amount of * simultaneously open connections that libcurl may cache. Default is * 10. When the cache is full, curl closes the oldest one in the cache * to prevent the number of open connections from increasing. *
    * @return bool Returns TRUE on success or FALSE on failure. * @since 5.5 */ function curl_multi_setopt(#[LanguageLevelTypeAware(['8.0' => 'CurlMultiHandle'], default: 'resource')] $multi_handle, int $option, mixed $value): bool {} /** * (PHP 5 >=5.5.0)
    * Return string describing error code * @link https://secure.php.net/manual/en/function.curl-multi-strerror.php * @param int $error_code

    * One of the {@link https://curl.haxx.se/libcurl/c/libcurl-errors.html CURLM error codes} constants. *

    * @return string|null Returns error string for valid error code, NULL otherwise. * @since 5.5 */ function curl_multi_strerror(int $error_code): ?string {} /** * (PHP 5 >=5.5.0)
    * Pause and unpause a connection * @link https://secure.php.net/manual/en/function.curl-pause.php * @param CurlHandle|resource $handle *

    A cURL handle returned by {@link https://secure.php.net/manual/en/function.curl-init.php curl_init()}.

    * @param int $flags

    One of CURLPAUSE_* constants.

    * @return int Returns an error code (CURLE_OK for no error). * @since 5.5 */ function curl_pause(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle, int $flags): int {} /** * (PHP 5 >=5.5.0)
    * Reset all options of a libcurl session handle * @link https://secure.php.net/manual/en/function.curl-reset.php * @param CurlHandle|resource $handle

    A cURL handle returned by * {@link https://secure.php.net/manual/en/function.curl-init.php curl_init()}.

    * @return void * @since 5.5 */ function curl_reset(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle): void {} /** * Run the sub-connections of the current cURL handle * @link https://php.net/manual/en/function.curl-multi-exec.php * @param CurlMultiHandle|resource $multi_handle * @param int &$still_running

    * A reference to a flag to tell whether the operations are still running. *

    * @return int A cURL code defined in the cURL Predefined Constants. *

    * This only returns errors regarding the whole multi stack. There might still have * occurred problems on individual transfers even when this function returns * CURLM_OK. *

    */ function curl_multi_exec( #[LanguageLevelTypeAware(['8.0' => 'CurlMultiHandle'], default: 'resource')] $multi_handle, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] &$still_running = 0, #[PhpStormStubsElementAvailable(from: '8.0')] &$still_running ): int {} /** * Return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set * @link https://php.net/manual/en/function.curl-multi-getcontent.php * @param CurlHandle|resource $handle * @return null|string Return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set. */ #[Pure] function curl_multi_getcontent(#[LanguageLevelTypeAware(['8.0' => 'CurlHandle'], default: 'resource')] $handle): ?string {} /** * Get information about the current transfers * @link https://php.net/manual/en/function.curl-multi-info-read.php * @param CurlMultiHandle|resource $multi_handle * @param int &$queued_messages [optional]

    * Number of messages that are still in the queue *

    * @return array|false On success, returns an associative array for the message, false on failure. */ #[Pure] #[ArrayShape(["msg" => "int", "result" => "int", "handle" => "resource"])] function curl_multi_info_read(#[LanguageLevelTypeAware(['8.0' => 'CurlMultiHandle'], default: 'resource')] $multi_handle, &$queued_messages): array|false {} /** * Close a set of cURL handles * @link https://php.net/manual/en/function.curl-multi-close.php * @param CurlMultiHandle|resource $multi_handle * @return void */ function curl_multi_close(#[LanguageLevelTypeAware(['8.0' => 'CurlMultiHandle'], default: 'resource')] $multi_handle): void {} /** * Return the last multi curl error number * @param CurlMultiHandle|resource $multi_handle * @return int * @since 7.1 */ #[Pure(true)] function curl_multi_errno(#[LanguageLevelTypeAware(['8.0' => 'CurlMultiHandle'], default: 'resource')] $multi_handle): int {} /** * Return the last share curl error number * @param CurlMultiHandle|resource $share_handle * @return int * @since 7.1 */ #[Pure(true)] function curl_share_errno(#[LanguageLevelTypeAware(['8.0' => 'CurlShareHandle'], default: 'resource')] $share_handle): int {} /** * Return string describing the given error code * @param int $error_code * @return string|null * @since 7.1 */ #[Pure] function curl_share_strerror(int $error_code): ?string {} /** * @since 8.2 */ function curl_upkeep(CurlHandle $handle): bool {} /** * @since 8.0 */ final class CurlHandle { /** * Cannot directly construct CurlHandle, use curl_init() instead * @see curl_init() */ private function __construct() {} } /** * @since 8.0 */ final class CurlMultiHandle { /** * Cannot directly construct CurlMultiHandle, use curl_multi_init() instead * @see curl_multi_init() */ private function __construct() {} } /** * @since 8.0 */ final class CurlShareHandle { /** * Cannot directly construct CurlShareHandle, use curl_share_init() instead * @see curl_share_init() */ private function __construct() {} } * Case sensitive regular expression. *

    * @param string $string

    * The input string. *

    * @param null|array &$regs [optional]

    * If matches are found for parenthesized substrings of * pattern and the function is called with the * third argument regs, the matches will be stored * in the elements of the array regs. *

    *

    * $regs[1] will contain the substring which starts at * the first left parenthesis; $regs[2] will contain * the substring starting at the second, and so on. * $regs[0] will contain a copy of the complete string * matched. *

    * @return int the length of the matched string if a match for * pattern was found in string, * or FALSE if no matches were found or an error occurred. *

    *

    * If the optional parameter regs was not passed or * the length of the matched string is 0, this function returns 1. * @removed 7.0 * @see preg_match() */ #[Deprecated(reason: "Use preg_match() instead", since: "5.3")] function ereg($pattern, $string, ?array &$regs = null) {} /** * Replace regular expression * @link https://php.net/manual/en/function.ereg-replace.php * @param string $pattern

    * A POSIX extended regular expression. *

    * @param string $replacement

    * If pattern contains parenthesized substrings, * replacement may contain substrings of the form * \digit, which will be * replaced by the text matching the digit'th parenthesized substring; * \0 will produce the entire contents of string. * Up to nine substrings may be used. Parentheses may be nested, in which * case they are counted by the opening parenthesis. *

    * @param string $string

    * The input string. *

    * @return string The modified string is returned. If no matches are found in * string, then it will be returned unchanged. * @removed 7.0 * @see preg_replace() */ #[Deprecated(reason: "Use preg_replace() instead", since: "5.3")] function ereg_replace($pattern, $replacement, $string) {} /** * Case insensitive regular expression match * @link https://php.net/manual/en/function.eregi.php * @param string $pattern

    * Case insensitive regular expression. *

    * @param string $string

    * The input string. *

    * @param null|array &$regs [optional]

    * If matches are found for parenthesized substrings of * pattern and the function is called with the * third argument regs, the matches will be stored * in the elements of the array regs. *

    *

    * $regs[1] will contain the substring which starts at the first left * parenthesis; $regs[2] will contain the substring starting at the * second, and so on. $regs[0] will contain a copy of the complete string * matched. *

    * @return int the length of the matched string if a match for * pattern was found in string, * or FALSE if no matches were found or an error occurred. *

    *

    * If the optional parameter regs was not passed or * the length of the matched string is 0, this function returns 1. * @removed 7.0 * @see preg_match() */ #[Deprecated(reason: "Use preg_match() instead", since: "5.3")] function eregi($pattern, $string, array &$regs = null) {} /** * Replace regular expression case insensitive * @link https://php.net/manual/en/function.eregi-replace.php * @param string $pattern

    * A POSIX extended regular expression. *

    * @param string $replacement

    * If pattern contains parenthesized substrings, * replacement may contain substrings of the form * \digit, which will be * replaced by the text matching the digit'th parenthesized substring; * \0 will produce the entire contents of string. * Up to nine substrings may be used. Parentheses may be nested, in which * case they are counted by the opening parenthesis. *

    * @param string $string

    * The input string. *

    * @return string The modified string is returned. If no matches are found in * string, then it will be returned unchanged. * @removed 7.0 * @see preg_replace() */ #[Deprecated(reason: "Use preg_replace() instead", since: "5.3")] function eregi_replace($pattern, $replacement, $string) {} /** * Split string into array by regular expression * @link https://php.net/manual/en/function.split.php * @param string $pattern

    * Case sensitive regular expression. *

    *

    * If you want to split on any of the characters which are considered * special by regular expressions, you'll need to escape them first. If * you think split (or any other regex function, for * that matter) is doing something weird, please read the file * regex.7, included in the * regex/ subdirectory of the PHP distribution. It's * in manpage format, so you'll want to do something along the lines of * man /usr/local/src/regex/regex.7 in order to read it. *

    * @param string $string

    * The input string. *

    * @param int $limit [optional]

    * If limit is set, the returned array will * contain a maximum of limit elements with the * last element containing the whole rest of * string. *

    * @return array an array of strings, each of which is a substring of * string formed by splitting it on boundaries formed * by the case-sensitive regular expression pattern. *

    *

    * If there are n occurrences of * pattern, the returned array will contain * n+1 items. For example, if * there is no occurrence of pattern, an array with * only one element will be returned. Of course, this is also true if * string is empty. If an error occurs, * split returns FALSE. * @removed 7.0 * @see preg_split() */ #[Deprecated(reason: "Use preg_split() instead", since: "5.3")] function split($pattern, $string, $limit = -1) {} /** * Split string into array by regular expression case insensitive * @link https://php.net/manual/en/function.spliti.php * @param string $pattern

    * Case insensitive regular expression. *

    *

    * If you want to split on any of the characters which are considered * special by regular expressions, you'll need to escape them first. If * you think spliti (or any other regex function, for * that matter) is doing something weird, please read the file * regex.7, included in the * regex/ subdirectory of the PHP distribution. It's * in manpage format, so you'll want to do something along the lines of * man /usr/local/src/regex/regex.7 in order to read it. *

    * @param string $string

    * The input string. *

    * @param int $limit [optional]

    * If limit is set, the returned array will * contain a maximum of limit elements with the * last element containing the whole rest of * string. *

    * @return array an array of strings, each of which is a substring of * string formed by splitting it on boundaries formed * by the case insensitive regular expression pattern. *

    *

    * If there are n occurrences of * pattern, the returned array will contain * n+1 items. For example, if * there is no occurrence of pattern, an array with * only one element will be returned. Of course, this is also true if * string is empty. If an error occurs, * spliti returns FALSE. * @removed 7.0 * @see preg_split() */ #[Deprecated(reason: "Use preg_split() instead", since: "5.3")] function spliti($pattern, $string, $limit = -1) {} /** * Make regular expression for case insensitive match * @link https://php.net/manual/en/function.sql-regcase.php * @param string $string

    * The input string. *

    * @return string a valid regular expression which will match * string, ignoring case. This expression is * string with each alphabetic character converted to * a bracket expression; this bracket expression contains that character's * uppercase and lowercase form. Other characters remain unchanged. * @removed 7.0 */ #[Deprecated(since: '5.3')] function sql_regcase($string) {} // End of ereg v. * The value of pid can be one of the following: * * possible values for pid * * * * * * * * * * * * * * * * *
    < -1 * wait for any child process whose process group ID is equal to * the absolute value of pid. *
    -1 * wait for any child process; this is the same behaviour that * the wait function exhibits. *
    0 * wait for any child process whose process group ID is equal to * that of the calling process. *
    > 0 * wait for the child whose process ID is equal to the value of * pid. *
    *

    *

    * Specifying -1 as the pid is * equivalent to the functionality pcntl_wait provides * (minus options). *

    * @param int &$status

    * pcntl_waitpid will store status information * in the status parameter which can be * evaluated using the following functions: * pcntl_wifexited, * pcntl_wifstopped, * pcntl_wifsignaled, * pcntl_wexitstatus, * pcntl_wtermsig and * pcntl_wstopsig. *

    * @param int $flags [optional]

    * The value of options is the value of zero * or more of the following two global constants * OR'ed together: *

    * possible values for options * * * * * * * * *
    WNOHANG * return immediately if no child has exited. *
    WUNTRACED * return for children which are stopped, and whose status has * not been reported. *
    *

    * @param array &$resource_usage * @return int pcntl_waitpid returns the process ID of the * child which exited, -1 on error or zero if WNOHANG was used and no * child was available */ function pcntl_waitpid( int $process_id, &$status, int $flags = 0, #[PhpStormStubsElementAvailable(from: '7.0')] &$resource_usage = [] ): int {} /** * Waits on or returns the status of a forked child * @link https://php.net/manual/en/function.pcntl-wait.php * @param int &$status

    * pcntl_wait will store status information * in the status parameter which can be * evaluated using the following functions: * pcntl_wifexited, * pcntl_wifstopped, * pcntl_wifsignaled, * pcntl_wexitstatus, * pcntl_wtermsig and * pcntl_wstopsig. *

    * @param int $flags [optional]

    * If wait3 is available on your system (mostly BSD-style systems), you can * provide the optional flags parameter. If this * parameter is not provided, wait will be used for the system call. If * wait3 is not available, providing a value for flags * will have no effect. The value of flags * is the value of zero or more of the following two constants * OR'ed together: *

    * Possible values for flags * * * * * * * * *
    WNOHANG * Return immediately if no child has exited. *
    WUNTRACED * Return for children which are stopped, and whose status has * not been reported. *
    *

    * @param array &$resource_usage * @return int pcntl_wait returns the process ID of the * child which exited, -1 on error or zero if WNOHANG was provided as an * option (on wait3-available systems) and no child was available. */ function pcntl_wait( &$status, int $flags = 0, #[PhpStormStubsElementAvailable(from: '7.0')] &$resource_usage = [] ): int {} /** * Installs a signal handler * @link https://php.net/manual/en/function.pcntl-signal.php * @param int $signal

    * The signal number. *

    * @param callable|int $handler

    * The signal handler. This may be either a callable, which * will be invoked to handle the signal, or either of the two global * constants SIG_IGN or SIG_DFL, * which will ignore the signal or restore the default signal handler * respectively. *

    *

    * If a callable is given, it must implement the following * signature: *

    *

    * voidhandler * intsigno * signo * The signal being handled.

    * @param bool $restart_syscalls [optional]

    * Specifies whether system call restarting should be used when this * signal arrives. *

    * @return bool TRUE on success or FALSE on failure. */ function pcntl_signal(int $signal, $handler, bool $restart_syscalls = true): bool {} /** * Calls signal handlers for pending signals * @link https://php.net/manual/en/function.pcntl-signal-dispatch.php * @return bool TRUE on success or FALSE on failure. */ function pcntl_signal_dispatch(): bool {} /** * Checks if status code represents a normal exit * @link https://php.net/manual/en/function.pcntl-wifexited.php * @param int $status

    The status * parameter is the status parameter supplied to a successful * call to pcntl_waitpid.

    * @return bool TRUE if the child status code represents a normal exit, FALSE * otherwise. */ #[Pure] function pcntl_wifexited(int $status): bool {} /** * Checks whether the child process is currently stopped * @link https://php.net/manual/en/function.pcntl-wifstopped.php * @param int $status

    The status * parameter is the status parameter supplied to a successful * call to pcntl_waitpid.

    * @return bool TRUE if the child process which caused the return is * currently stopped, FALSE otherwise. */ #[Pure] function pcntl_wifstopped(int $status): bool {} /** * Checks whether the status code represents a termination due to a signal * @link https://php.net/manual/en/function.pcntl-wifsignaled.php * @param int $status

    The status * parameter is the status parameter supplied to a successful * call to pcntl_waitpid.

    * @return bool TRUE if the child process exited because of a signal which was * not caught, FALSE otherwise. */ #[Pure] function pcntl_wifsignaled(int $status): bool {} /** * Returns the return code of a terminated child * @link https://php.net/manual/en/function.pcntl-wexitstatus.php * @param int $status

    The status * parameter is the status parameter supplied to a successful * call to pcntl_waitpid.

    * @return int|false the return code, as an integer. */ #[Pure] function pcntl_wexitstatus(int $status): int|false {} /** * @param int $status * @return bool */ #[Pure] function pcntl_wifcontinued(int $status): bool {} /** * Returns the signal which caused the child to terminate * @link https://php.net/manual/en/function.pcntl-wtermsig.php * @param int $status

    The status * parameter is the status parameter supplied to a successful * call to pcntl_waitpid.

    * @return int|false the signal number, as an integer. */ #[Pure] function pcntl_wtermsig(int $status): int|false {} /** * Returns the signal which caused the child to stop * @link https://php.net/manual/en/function.pcntl-wstopsig.php * @param int $status

    The status * parameter is the status parameter supplied to a successful * call to pcntl_waitpid.

    * @return int|false the signal number. */ #[Pure] function pcntl_wstopsig(int $status): int|false {} /** * Executes specified program in current process space * @link https://php.net/manual/en/function.pcntl-exec.php * @param string $path

    * path must be the path to a binary executable or a * script with a valid path pointing to an executable in the shebang ( * #!/usr/local/bin/perl for example) as the first line. See your system's * man execve(2) page for additional information. *

    * @param array $args

    * args is an array of argument strings passed to the * program. *

    * @param array $env_vars

    * envs is an array of strings which are passed as * environment to the program. The array is in the format of name => value, * the key being the name of the environmental variable and the value being * the value of that variable. *

    * @return bool FALSE on error and does not return on success. */ function pcntl_exec(string $path, array $args = [], array $env_vars = []): bool {} /** * Set an alarm clock for delivery of a signal * @link https://php.net/manual/en/function.pcntl-alarm.php * @param int $seconds

    * The number of seconds to wait. If seconds is * zero, no new alarm is created. *

    * @return int the time in seconds that any previously scheduled alarm had * remaining before it was to be delivered, or 0 if there * was no previously scheduled alarm. */ function pcntl_alarm(int $seconds): int {} /** * Retrieve the error number set by the last pcntl function which failed * @link https://php.net/manual/en/function.pcntl-get-last-error.php * @return int error code. * @since 5.3.4 */ #[Pure(true)] function pcntl_get_last_error(): int {} /** * Alias of pcntl_get_last_error * @link https://php.net/manual/en/function.pcntl-errno.php * @return int error code. * @since 5.3.4 */ #[Pure(true)] function pcntl_errno(): int {} /** * Retrieve the system error message associated with the given errno * @link https://php.net/manual/en/function.pcntl-strerror.php * @param int $error_code

    *

    * @return string|false error description on success or FALSE on failure. * @since 5.3.4 */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "string"], default: "string|false")] function pcntl_strerror(int $error_code): false|string {} /** * Get the priority of any process * @link https://php.net/manual/en/function.pcntl-getpriority.php * @param int|null $process_id [optional]

    * If not specified, the pid of the current process (getmypid()) is used. *

    * @param int $mode [optional]

    * One of PRIO_PGRP, PRIO_USER * or PRIO_PROCESS. *

    * @return int|false pcntl_getpriority returns the priority of the process * or FALSE on error. A lower numerical value causes more favorable * scheduling. */ #[Pure] function pcntl_getpriority(?int $process_id, int $mode = PRIO_PROCESS): int|false {} /** * Change the priority of any process * @link https://php.net/manual/en/function.pcntl-setpriority.php * @param int $priority

    * priority is generally a value in the range * -20 to 20. The default priority * is 0 while a lower numerical value causes more * favorable scheduling. Because priority levels can differ between * system types and kernel versions, please see your system's setpriority(2) * man page for specific details. *

    * @param int|null $process_id [optional]

    * If not specified, the pid of the current process (getmypid()) is used. *

    * @param int $mode [optional]

    * One of PRIO_PGRP, PRIO_USER * or PRIO_PROCESS. *

    * @return bool TRUE on success or FALSE on failure. */ function pcntl_setpriority(int $priority, ?int $process_id, int $mode = PRIO_PROCESS): bool {} /** * Sets and retrieves blocked signals * @link https://php.net/manual/en/function.pcntl-sigprocmask.php * @param int $mode

    * Sets the behavior of pcntl_sigprocmask. Possible * values: * SIG_BLOCK: Add the signals to the * currently blocked signals. * SIG_UNBLOCK: Remove the signals from the * currently blocked signals. * SIG_SETMASK: Replace the currently * blocked signals by the given list of signals. *

    * @param array $signals

    * List of signals. *

    * @param array &$old_signals [optional]

    * The old_signals parameter is set to an array * containing the list of the previously blocked signals. *

    * @return bool TRUE on success or FALSE on failure. */ function pcntl_sigprocmask(int $mode, array $signals, &$old_signals): bool {} /** * Waits for signals * @link https://php.net/manual/en/function.pcntl-sigwaitinfo.php * @param array $signals

    * Array of signals to wait for. *

    * @param array &$info

    * The info parameter is set to an array containing * informations about the signal. *

    *

    * The following elements are set for all signals: * signo: Signal number * errno: An error number * code: Signal code *

    *

    * The following elements may be set for the SIGCHLD signal: * status: Exit value or signal * utime: User time consumed * stime: System time consumed * pid: Sending process ID * uid: Real user ID of sending process *

    *

    * The following elements may be set for the SIGILL, * SIGFPE, SIGSEGV and * SIGBUS signals: * addr: Memory location which caused fault *

    *

    * The following element may be set for the SIGPOLL * signal: * band: Band event * fd: File descriptor number *

    * @return int|false On success, pcntl_sigwaitinfo returns a signal number. */ function pcntl_sigwaitinfo(array $signals, &$info = []): int|false {} /** * Waits for signals, with a timeout * @link https://php.net/manual/en/function.pcntl-sigtimedwait.php * @param array $signals

    * Array of signals to wait for. *

    * @param array &$info

    * The siginfo is set to an array containing * informations about the signal. See * pcntl_sigwaitinfo. *

    * @param int $seconds [optional]

    * Timeout in seconds. *

    * @param int $nanoseconds [optional]

    * Timeout in nanoseconds. *

    * @return int|false On success, pcntl_sigtimedwait returns a signal number. */ function pcntl_sigtimedwait(array $signals, &$info = [], int $seconds = 0, int $nanoseconds = 0): int|false {} /** * Enable/disable asynchronous signal handling or return the old setting.
    * If the enable parameter is omitted, it returns whether asynchronous * signal handling is enabled. * @link https://www.php.net/manual/en/function.pcntl-async-signals.php * * @param bool|null $enable

    * Whether asynchronous signal handling should be enabled. *

    * * @return bool * @since 7.1 */ function pcntl_async_signals( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] ?bool $enable, #[PhpStormStubsElementAvailable(from: '8.0')] ?bool $enable = null ): bool {} /** * Get the current handler for specified signal. * @link https://www.php.net/manual/en/function.pcntl-signal-get-handler.php * * @param int $signal

    * The signal number. *

    * * @return bool|resource * @since 7.1 */ function pcntl_signal_get_handler(int $signal) {} /** * @param int $flags * @return bool * @since 7.4 */ function pcntl_unshare(int $flags): bool {} /** * @since 8.4 */ function pcntl_waitid(int $idtype = P_ALL, ?int $id = null, &$info = [], int $flags = WEXITED): bool {} /** * @since 8.4 */ function pcntl_getcpuaffinity(?int $process_id = null): array|false {} /** * @since 8.4 */ function pcntl_setcpuaffinity(?int $process_id = null, array $cpu_ids = []): bool {} /** * @since 8.4 */ function pcntl_getcpu(): int {} define('WNOHANG', 1); define('WUNTRACED', 2); define('WCONTINUED', 8); define('SIG_IGN', 1); define('SIG_DFL', 0); define('SIG_ERR', -1); define('SIGHUP', 1); define('SIGINT', 2); define('SIGQUIT', 3); define('SIGILL', 4); define('SIGTRAP', 5); define('SIGABRT', 6); define('SIGIOT', 6); define('SIGBUS', 7); define('SIGFPE', 8); define('SIGKILL', 9); define('SIGUSR1', 10); define('SIGSEGV', 11); define('SIGUSR2', 12); define('SIGPIPE', 13); define('SIGALRM', 14); define('SIGTERM', 15); define('SIGSTKFLT', 16); define('SIGCLD', 17); define('SIGCHLD', 17); define('SIGCONT', 18); define('SIGSTOP', 19); define('SIGTSTP', 20); define('SIGTTIN', 21); define('SIGTTOU', 22); define('SIGURG', 23); define('SIGXCPU', 24); define('SIGXFSZ', 25); define('SIGVTALRM', 26); define('SIGPROF', 27); define('SIGWINCH', 28); define('SIGPOLL', 29); define('SIGIO', 29); define('SIGPWR', 30); define('SIGSYS', 31); define('SIGBABY', 31); define('PRIO_PGRP', 1); define('PRIO_USER', 2); define('PRIO_PROCESS', 0); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SIG_BLOCK', 0); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SIG_UNBLOCK', 1); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SIG_SETMASK', 2); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SIGRTMIN', 35); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SIGRTMAX', 64); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SI_USER', 0); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SI_KERNEL', 128); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SI_QUEUE', -1); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SI_TIMER', -2); define('SI_MESGQ', -3); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SI_ASYNCIO', -4); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SI_SIGIO', -5); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SI_TKILL', -6); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('CLD_EXITED', 1); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('CLD_KILLED', 2); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('CLD_DUMPED', 3); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('CLD_TRAPPED', 4); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('CLD_STOPPED', 5); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('CLD_CONTINUED', 6); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('TRAP_BRKPT', 1); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('TRAP_TRACE', 2); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('POLL_IN', 1); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('POLL_OUT', 2); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('POLL_MSG', 3); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('POLL_ERR', 4); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('POLL_PRI', 5); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('POLL_HUP', 6); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('ILL_ILLOPC', 1); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('ILL_ILLOPN', 2); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('ILL_ILLADR', 3); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('ILL_ILLTRP', 4); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('ILL_PRVOPC', 5); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('ILL_PRVREG', 6); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('ILL_COPROC', 7); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('ILL_BADSTK', 8); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('FPE_INTDIV', 1); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('FPE_INTOVF', 2); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('FPE_FLTDIV', 3); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('FPE_FLTOVF', 4); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('FPE_FLTUND', 5); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('FPE_FLTRES', 6); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('FPE_FLTINV', 7); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('FPE_FLTSUB', 8); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SEGV_MAPERR', 1); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('SEGV_ACCERR', 2); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('BUS_ADRALN', 1); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('BUS_ADRERR', 2); /** * @link https://php.net/manual/en/pcntl.constants.php */ define('BUS_OBJERR', 3); define('PCNTL_EINTR', 4); define('PCNTL_ECHILD', 10); define('PCNTL_EINVAL', 22); define('PCNTL_EAGAIN', 11); define('PCNTL_ESRCH', 3); define('PCNTL_EACCES', 13); define('PCNTL_EPERM', 1); define('PCNTL_ENOMEM', 12); define('PCNTL_E2BIG', 7); define('PCNTL_EFAULT', 14); define('PCNTL_EIO', 5); define('PCNTL_EISDIR', 21); define('PCNTL_ELIBBAD', 80); define('PCNTL_ELOOP', 40); define('PCNTL_EMFILE', 24); define('PCNTL_ENAMETOOLONG', 36); define('PCNTL_ENFILE', 23); define('PCNTL_ENOENT', 2); define('PCNTL_ENOEXEC', 8); define('PCNTL_ENOTDIR', 20); define('PCNTL_ETXTBSY', 26); /** * @since 7.4 */ define('PCNTL_ENOSPC', 28); /** * @since 7.4 */ define('PCNTL_EUSERS', 87); /** * @since 7.4 */ define('CLONE_NEWNS', 131072); /** * @since 7.4 */ define('CLONE_NEWIPC', 134217728); /** * @since 7.4 */ define('CLONE_NEWUTS', 67108864); /** * @since 7.4 */ define('CLONE_NEWNET', 1073741824); /** * @since 7.4 */ define('CLONE_NEWPID', 536870912); /** * @since 7.4 */ define('CLONE_NEWUSER', 268435456); /** * @since 7.4 */ define('CLONE_NEWCGROUP', 33554432); /** * @since 8.4 */ define('P_ALL', 0); /** * @since 8.4 */ define('WEXITED', 4); /** * @since 8.4 */ define('WSTOPPED', 2); /** * @since 8.4 */ define('WNOWAIT', 16777216); /** * @since 8.4 */ define('P_PID', 1); /** * @since 8.4 */ define('P_PGID', 2); /** * @since 8.4 */ define('P_PIDFD', 3); // End of pcntl v. * Send the YAML representation of a value to a file * @link https://php.net/manual/en/function.yaml-emit-file.php * @param string $filename Path to the file. * @param mixed $data The data being encoded. Can be any type except a resource. * @param int $encoding Output character encoding chosen from YAML_ANY_ENCODING, YAML_UTF8_ENCODING, YAML_UTF16LE_ENCODING, YAML_UTF16BE_ENCODING. * @param int $linebreak Output linebreak style chosen from YAML_ANY_BREAK, YAML_CR_BREAK, YAML_LN_BREAK, YAML_CRLN_BREAK. * @param array $callbacks [optional] Content handlers for YAML nodes. Associative array of YAML tag => callable mappings. See parse callbacks for more details. * @return bool Returns TRUE on success. */ function yaml_emit_file($filename, $data, $encoding = YAML_ANY_ENCODING, $linebreak = YAML_ANY_BREAK, array $callbacks = []) {} /** * (PHP 5 >= 5.2.0, PECL yaml >= 0.5.0)
    * @link https://php.net/manual/en/function.yaml-emit.php * @param mixed $data The data being encoded. Can be any type except a resource. * @param int $encoding [optional] Output character encoding chosen from YAML_ANY_ENCODING, YAML_UTF8_ENCODING, YAML_UTF16LE_ENCODING, YAML_UTF16BE_ENCODING. * @param int $linebreak [optional] Output linebreak style chosen from YAML_ANY_BREAK, YAML_CR_BREAK, YAML_LN_BREAK, YAML_CRLN_BREAK. * @param array $callbacks [optional] Content handlers for YAML nodes. Associative array of YAML tag => callable mappings. See parse callbacks for more details. * @return string Returns a YAML encoded string on success. */ function yaml_emit($data, $encoding = YAML_ANY_ENCODING, $linebreak = YAML_ANY_BREAK, array $callbacks = []) {} /** * (PHP 5 >= 5.2.0, PECL yaml >= 0.4.0)
    * Parse a YAML stream from a file * @link https://php.net/manual/en/function.yaml-parse-file.php * @param string $filename Path to the file. * @param int $pos [optional] Document to extract from stream (-1 for all documents, 0 for first document, ...). * @param int &$ndocs [optional] If ndocs is provided, then it is filled with the number of documents found in stream. * @param array $callbacks [optional] Content handlers for YAML nodes. Associative array of YAML tag => callable mappings. See parse callbacks for more details. * @return mixed|false Returns the value encoded in input in appropriate PHP type or FALSE on failure. If pos is -1 an array will be returned with one entry for each document found in the stream. */ function yaml_parse_file($filename, $pos = 0, &$ndocs = null, array $callbacks = []) {} /** * (PHP 5 >= 5.2.0, PECL yaml >= 0.4.0)
    * Parse a Yaml stream from a URL * @link https://php.net/manual/en/function.yaml-parse-url.php * @param string $url url should be of the form "scheme://...". PHP will search for a protocol handler (also known as a wrapper) for that scheme. If no wrappers for that protocol are registered, PHP will emit a notice to help you track potential problems in your script and then continue as though filename specifies a regular file. * @param int $pos [optional] Document to extract from stream (-1 for all documents, 0 for first document, ...). * @param int &$ndocs [optional] If ndocs is provided, then it is filled with the number of documents found in stream. * @param array $callbacks [optional] Content handlers for YAML nodes. Associative array of YAML tag => callable mappings. See parse callbacks for more details. * @return mixed|false Returns the value encoded in input in appropriate PHP type or FALSE on failure. If pos is -1 an array will be returned with one entry for each document found in the stream. */ function yaml_parse_url($url, $pos = 0, &$ndocs = null, array $callbacks = []) {} /** * (PHP 5 >= 5.2.0, PECL yaml >= 0.4.0)
    * Parse a YAML stream * @link https://php.net/manual/en/function.yaml-parse.php * @param string $input The string to parse as a YAML document stream. * @param int $pos [optional] Document to extract from stream (-1 for all documents, 0 for first document, ...). * @param int &$ndocs [optional] If ndocs is provided, then it is filled with the number of documents found in stream. * @param array $callbacks [optional] Content handlers for YAML nodes. Associative array of YAML tag => callable mappings. See parse callbacks for more details. * @return mixed|false Returns the value encoded in input in appropriate PHP type or FALSE on failure. If pos is -1 an array will be returned with one entry for each document found in the stream. */ function yaml_parse($input, $pos = 0, &$ndocs = null, array $callbacks = []) {} = 4.0.0) * and the mutation operation succeeded. * * If set, it can be used for enhanced durability requirements, as well as optimized consistency * for N1QL queries. */ public $token; } /** * A fragment of a JSON Document returned by the sub-document API. * * @see \Couchbase\Bucket::mutateIn() * @see \Couchbase\Bucket::lookupIn() */ class DocumentFragment { /** * @var Exception exception object in case of error, or NULL */ public $error; /** * @var mixed The value sub-document command returned. */ public $value; /** * @var string The last known CAS value of the document */ public $cas; /** * @var MutationToken * The optional, opaque mutation token related to updated document the environment. * * Note that the mutation token is always NULL, unless they are explicitly enabled on the * connection string (`?fetch_mutation_tokens=true`), the server version is supported (>= 4.0.0) * and the mutation operation succeeded. * * If set, it can be used for enhanced durability requirements, as well as optimized consistency * for N1QL queries. */ public $token; } /** * Represents a Couchbase Server Cluster. * * It is an entry point to the library, and in charge of opening connections to the Buckets. * In addition it can instantiate \Couchbase\ClusterManager to peform cluster-wide operations. * * @see \Couchbase\Bucket * @see \Couchbase\ClusterManager * @see \Couchbase\Authenticator */ class Cluster { /** * Create cluster object * * @param string $connstr connection string */ public function __construct($connstr) {} /** * Open connection to the Couchbase bucket * * @param string $name Name of the bucket. * @param string $password Password of the bucket to override authenticator. * @return Bucket * * @see \Couchbase\Authenticator */ public function openBucket($name = "default", $password = "") {} /** * Open management connection to the Couchbase cluster. * * @param string $username Name of the administrator to override authenticator or NULL. * @param string $password Password of the administrator to override authenticator or NULL. * @return ClusterManager * * @see \Couchbase\Authenticator */ public function manager($username = null, $password = null) {} /** * Associate authenticator with Cluster * * @param Authenticator $authenticator * @return null * * @see \Couchbase\Authenticator * @see \Couchbase\ClassicAuthenticator * @see \Couchbase\PasswordAuthenticator */ public function authenticate($authenticator) {} /** * Create \Couchbase\PasswordAuthenticator from given credentials and associate it with Cluster * * @param string $username * @param string $password * @return null * * @see \Couchbase\Authenticator * @see \Couchbase\PasswordAuthenticator */ public function authenticateAs($username, $password) {} } /** * Provides management capabilities for a Couchbase Server Cluster * * @see \Couchbase\Cluster */ class ClusterManager { /** * The user account managed by Couchbase Cluster. */ public const RBAC_DOMAIN_LOCAL = 1; /** * The user account managed by external system (e.g. LDAP). */ public const RBAC_DOMAIN_EXTERNAL = 2; final private function __construct() {} /** * Lists all buckets on this cluster. * * @return array */ public function listBuckets() {} /** * Creates new bucket * * @param string $name Name of the bucket * @param array $options Bucket options * * "authType" (default: "sasl") type of the bucket authentication * * "bucketType" (default: "couchbase") type of the bucket * * "ramQuotaMB" (default: 100) memory quota of the bucket * * "replicaNumber" (default: 1) number of replicas. * * @see https://developer.couchbase.com/documentation/server/current/rest-api/rest-bucket-create.html * More options and details */ public function createBucket($name, $options = []) {} /** * Removes a bucket identified by its name. * * @param string $name name of the bucket * * @see https://developer.couchbase.com/documentation/server/current/rest-api/rest-bucket-delete.html * More details */ public function removeBucket($name) {} /** * Provides information about the cluster. * * Returns an associative array of status information as seen on the cluster. The exact structure of the returned * data can be seen in the Couchbase Manual by looking at the cluster /info endpoint. * * @return array * * @see https://developer.couchbase.com/documentation/server/current/rest-api/rest-cluster-get.html * Retrieving Cluster Information */ public function info() {} /** * Lists all users on this cluster. * * @param int $domain RBAC domain * * @return array * * @see \Couchbase\ClusterManager::RBAC_DOMAIN_LOCAL * @see \Couchbase\ClusterManager::RBAC_DOMAIN_EXTERNAL */ public function listUsers($domain = RBAC_DOMAIN_LOCAL) {} /** * Fetch single user by its name * * @param string $username The user's identifier * @param int $domain RBAC domain * * @return array * * @see \Couchbase\ClusterManager::RBAC_DOMAIN_LOCAL * @see \Couchbase\ClusterManager::RBAC_DOMAIN_EXTERNAL */ public function getUser($username, $domain = RBAC_DOMAIN_LOCAL) {} /** * Creates new user * * @param string $name Name of the user * @param \Couchbase\UserSettings $settings settings (credentials and roles) * @param int $domain RBAC domain * * @see https://developer.couchbase.com/documentation/server/5.0/rest-api/rbac.html * More options and details * @see \Couchbase\ClusterManager::RBAC_DOMAIN_LOCAL * @see \Couchbase\ClusterManager::RBAC_DOMAIN_EXTERNAL */ public function upsertUser($name, $settings, $domain = RBAC_DOMAIN_LOCAL) {} /** * Removes a user identified by its name. * * @param string $name name of the bucket * @param int $domain RBAC domain * * @see https://developer.couchbase.com/documentation/server/5.0/rest-api/rbac.html * More details * @see \Couchbase\ClusterManager::RBAC_DOMAIN_LOCAL * @see \Couchbase\ClusterManager::RBAC_DOMAIN_EXTERNAL */ public function removeUser($name, $domain = RBAC_DOMAIN_LOCAL) {} } /** * Represents settings for new/updated user. * * @see https://developer.couchbase.com/documentation/server/5.0/rest-api/rbac.html */ class UserSettings { /** * Sets full name of the user (optional). * * @param string $fullName Full name of the user * * @return \Couchbase\UserSettings * * @see https://developer.couchbase.com/documentation/server/5.0/rest-api/rbac.html * More details */ public function fullName($fullName) {} /** * Sets password of the user. * * @param string $password Password of the user * * @return \Couchbase\UserSettings * * @see https://developer.couchbase.com/documentation/server/5.0/rest-api/rbac.html * More details */ public function password($password) {} /** * Adds role to the list of the accessible roles of the user. * * @param string $role identifier of the role * @param string $bucket the bucket where this role applicable (or `*` for all buckets) * * @return \Couchbase\UserSettings * * @see https://developer.couchbase.com/documentation/server/5.0/rest-api/rbac.html * More details */ public function role($role, $bucket = null) {} } /** * Represents connection to the Couchbase Server * * @property int $operationTimeout * The operation timeout (in microseconds) is the maximum amount of time the * library will wait for an operation to receive a response before invoking * its callback with a failure status. * * An operation may timeout if: * * * A server is taking too long to respond * * An updated cluster configuration has not been promptly received * * @property int $viewTimeout * The I/O timeout (in microseconds) for HTTP requests to Couchbase Views API * * @property int $n1qlTimeout * The I/O timeout (in microseconds) for N1QL queries. * * @property int $httpTimeout * The I/O timeout (in microseconds) for HTTP queries (management API). * * @property int $configTimeout * How long (in microseconds) the client will wait to obtain the initial * configuration. * * @property int $configNodeTimeout * Per-node configuration timeout (in microseconds). * * This timeout sets the amount of time to wait for each node within * the bootstrap/configuration process. This interval is a subset of * the $configTimeout option mentioned above and is intended to ensure * that the bootstrap process does not wait too long for a given node. * Nodes that are physically offline may never respond and it may take * a long time until they are detected as being offline. * * @property int $configDelay * Config refresh throttling * * Modify the amount of time (in microseconds) before the configiration * error threshold will forcefully be set to its maximum number forcing * a configuration refresh. * * Note that if you expect a high number of timeouts in your operations, * you should set this to a high number. If you are using the default * timeout setting, then this value is likely optimal. * * @property int $htconfigIdleTimeout * Idling/Persistence for HTTP bootstrap (in microseconds) * * By default the behavior of the library for HTTP bootstrap is to keep * the stream open at all times (opening a new stream on a different host * if the existing one is broken) in order to proactively receive * configuration updates. * * The default value for this setting is -1. Changing this to another * number invokes the following semantics: * * * The configuration stream is not kept alive indefinitely. It is kept * open for the number of seconds specified in this setting. The socket * is closed after a period of inactivity (indicated by this setting). * * * If the stream is broken (and no current refresh was requested by * the client) then a new stream is not opened. * * @property int $durabilityInterval * The time (in microseconds) the client will wait between repeated probes * to a given server. * * @property int $durabilityTimeout * The time (in microseconds) the client will spend sending repeated probes * to a given key's vBucket masters and replicas before they are deemed not * to have satisfied the durability requirements * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/start-using-sdk.html * Start Using SDK */ class Bucket { /** Ping data (Key/Value) service. */ public const PINGSVC_KV = 0x01; /** Ping query (N1QL) service. */ public const PINGSVC_N1QL = 0x02; /** Ping views (Map/Reduce) service. */ public const PINGSVC_VIEWS = 0x04; /** Ping full text search (FTS) service. */ public const PINGSVC_FTS = 0x08; final private function __construct() {} /** * @param string $name * @return int */ final private function __get($name) {} /** * @param string $name * @param int $value * @return int */ final private function __set($name, $value) {} /** * Returns the name of the bucket for current connection * * @return string */ public function getName() {} /** * Returns an instance of a CouchbaseBucketManager for performing management operations against a bucket. * * @return BucketManager */ public function manager() {} /** * Sets custom encoder and decoder functions for handling serialization. * * @param callable $encoder * @param callable $decoder * * @see \Couchbase\defaultEncoder * @see \Couchbase\defaultDecoder * @see \Couchbase\passthruEncoder * @see \Couchbase\passthruDecoder */ public function setTranscoder($encoder, $decoder) {} /** * Retrieves a document * * @param string|array $ids one or more IDs * @param array $options options * * "lockTime" non zero if the documents have to be locked * * "expiry" non zero if the expiration time should be updated * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see \Couchbase\Bucket::getAndLock() * @see \Couchbase\Bucket::getAndTouch() * @see \Couchbase\Bucket::unlock() * @see \Couchbase\Bucket::touch() * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK */ public function get($ids, $options = []) {} /** * Retrieves a document and locks it. * * After the document has been locked on the server, its CAS would be masked, * and all mutations of it will be rejected until the server unlocks the document * automatically or it will be done manually with \Couchbase\Bucket::unlock() operation. * * @param string|array $ids one or more IDs * @param int $lockTime time to lock the documents * @param array $options options * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see \Couchbase\Bucket::unlock() * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK * @see https://forums.couchbase.com/t/is-there-a-way-to-do-pessimistic-locking-for-more-than-30-seconds/10666/3 * Forum post about getting server defaults for the $lockTime */ public function getAndLock($ids, $lockTime, $options = []) {} /** * Retrieves a document and updates its expiration time. * * @param string|array $ids one or more IDs * @param int $expiry time after which the document will not be accessible. * If larger than 30 days (60*60*24*30), it will be interpreted by the * server as absolute UNIX time (seconds from epoch 1970-01-01T00:00:00). * @param array $options options * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK */ public function getAndTouch($ids, $expiry, $options = []) {} /** * Retrieves a document from a replica. * * @param string|array $ids one or more IDs * @param array $options options * * "index" the replica index. If the index is zero, it will return * first successful replica, otherwise it will read only selected node. * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK * @see https://developer.couchbase.com/documentation/server/current/sdk/php/failure-considerations.html * More about failure considerations. */ public function getFromReplica($ids, $options = []) {} /** * Inserts or updates a document, depending on whether the document already exists on the cluster. * * @param string|array $ids one or more IDs * @param mixed $value value of the document * @param array $options options * * "expiry" document expiration time in seconds. If larger than 30 days (60*60*24*30), * it will be interpreted by the server as absolute UNIX time (seconds from epoch * 1970-01-01T00:00:00). * * "persist_to" how many nodes the key should be persisted to (including master). * If set to 0 then persistence will not be checked. If set to a negative * number, will be set to the maximum number of nodes to which persistence * is possible (which will always contain at least the master node). * * "replicate_to" how many nodes the key should be persisted to (excluding master). * If set to 0 then replication will not be checked. If set to a negative * number, will be set to the maximum number of nodes to which replication * is possible (which may be 0 if the bucket is not configured for replicas). * * "flags" override flags (not recommended to use) * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK */ public function upsert($ids, $value, $options = []) {} /** * Inserts a document. This operation will fail if the document already exists on the cluster. * * @param string|array $ids one or more IDs * @param mixed $value value of the document * @param array $options options * * "expiry" document expiration time in seconds. If larger than 30 days (60*60*24*30), * it will be interpreted by the server as absolute UNIX time (seconds from epoch * 1970-01-01T00:00:00). * * "persist_to" how many nodes the key should be persisted to (including master). * If set to 0 then persistence will not be checked. If set to a negative * number, will be set to the maximum number of nodes to which persistence * is possible (which will always contain at least the master node). * * "replicate_to" how many nodes the key should be persisted to (excluding master). * If set to 0 then replication will not be checked. If set to a negative * number, will be set to the maximum number of nodes to which replication * is possible (which may be 0 if the bucket is not configured for replicas). * * "flags" override flags (not recommended to use) * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK */ public function insert($ids, $value, $options = []) {} /** * Replaces a document. This operation will fail if the document does not exists on the cluster. * * @param string|array $ids one or more IDs * @param mixed $value value of the document * @param array $options options * * "cas" last known document CAS, which serves for optimistic locking. * * "expiry" document expiration time in seconds. If larger than 30 days (60*60*24*30), * it will be interpreted by the server as absolute UNIX time (seconds from epoch * 1970-01-01T00:00:00). * * "persist_to" how many nodes the key should be persisted to (including master). * If set to 0 then persistence will not be checked. If set to a negative * number, will be set to the maximum number of nodes to which persistence * is possible (which will always contain at least the master node). * * "replicate_to" how many nodes the key should be persisted to (excluding master). * If set to 0 then replication will not be checked. If set to a negative * number, will be set to the maximum number of nodes to which replication * is possible (which may be 0 if the bucket is not configured for replicas). * * "flags" override flags (not recommended to use) * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK */ public function replace($ids, $value, $options = []) {} /** * Appends content to a document. * * On the server side it just contatenate passed value to the existing one. * Note that this might make the value un-decodable. Consider sub-document API * for partial updates of the JSON documents. * * @param string|array $ids one or more IDs * @param mixed $value value of the document * @param array $options options * * "cas" last known document CAS, which serves for optimistic locking. * * "expiry" document expiration time in seconds. If larger than 30 days (60*60*24*30), * it will be interpreted by the server as absolute UNIX time (seconds from epoch * 1970-01-01T00:00:00). * * "persist_to" how many nodes the key should be persisted to (including master). * If set to 0 then persistence will not be checked. If set to a negative * number, will be set to the maximum number of nodes to which persistence * is possible (which will always contain at least the master node). * * "replicate_to" how many nodes the key should be persisted to (excluding master). * If set to 0 then replication will not be checked. If set to a negative * number, will be set to the maximum number of nodes to which replication * is possible (which may be 0 if the bucket is not configured for replicas). * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see \Couchbase\Bucket::mutateIn() * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK */ public function append($ids, $value, $options = []) {} /** * Prepends content to a document. * * On the server side it just contatenate existing value to the passed one. * Note that this might make the value un-decodable. Consider sub-document API * for partial updates of the JSON documents. * * @param string|array $ids one or more IDs * @param mixed $value value of the document * @param array $options options * * "cas" last known document CAS, which serves for optimistic locking. * * "expiry" document expiration time in seconds. If larger than 30 days (60*60*24*30), * it will be interpreted by the server as absolute UNIX time (seconds from epoch * 1970-01-01T00:00:00). * * "persist_to" how many nodes the key should be persisted to (including master). * If set to 0 then persistence will not be checked. If set to a negative * number, will be set to the maximum number of nodes to which persistence * is possible (which will always contain at least the master node). * * "replicate_to" how many nodes the key should be persisted to (excluding master). * If set to 0 then replication will not be checked. If set to a negative * number, will be set to the maximum number of nodes to which replication * is possible (which may be 0 if the bucket is not configured for replicas). * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see \Couchbase\Bucket::mutateIn() * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK */ public function prepend($ids, $value, $options = []) {} /** * Removes the document. * * @param string|array $ids one or more IDs * @param array $options options * * "cas" last known document CAS, which serves for optimistic locking. * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK */ public function remove($ids, $options = []) {} /** * Unlocks previously locked document * * @param string|array $ids one or more IDs * @param array $options options * * "cas" last known document CAS, which has been returned by locking command. * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see \Couchbase\Bucket::get() * @see \Couchbase\Bucket::getAndLock() * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK */ public function unlock($ids, $options = []) {} /** * Updates document's expiration time. * * @param string|array $ids one or more IDs * @param int $expiry time after which the document will not be accessible. * If larger than 30 days (60*60*24*30), it will be interpreted by the * server as absolute UNIX time (seconds from epoch 1970-01-01T00:00:00). * @param array $options options * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK */ public function touch($ids, $expiry, $options = []) {} /** * Increments or decrements a key (based on $delta) * * @param string|array $ids one or more IDs * @param int $delta the number whih determines the sign (positive/negative) and the value of the increment * @param array $options options * * "initial" initial value of the counter if it does not exist * * "expiry" time after which the document will not be accessible. * If larger than 30 days (60*60*24*30), it will be interpreted by the * server as absolute UNIX time (seconds from epoch 1970-01-01T00:00:00). * * "groupid" override value for hashing (not recommended to use) * @return \Couchbase\Document|array document or list of the documents * * @see https://developer.couchbase.com/documentation/server/current/sdk/core-operations.html * Overview of K/V operations * @see https://developer.couchbase.com/documentation/server/current/sdk/php/document-operations.html * More details about K/V operations for PHP SDK */ public function counter($ids, $delta = 1, $options = []) {} /** * Returns a builder for reading subdocument API. * * @param string $id The ID of the JSON document * @return LookupInBuilder * * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function lookupIn($id) {} /** * Retrieves specified paths in JSON document * * This is essentially a shortcut for `lookupIn($id)->get($paths)->execute()`. * * @param string $id The ID of the JSON document * @param string ...$paths List of the paths inside JSON documents (see "Path syntax" section of the * "Sub-Document Operations" documentation). * @return \Couchbase\DocumentFragment * * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function retrieveIn($id, ...$paths) {} /** * Returns a builder for writing subdocument API. * * @param string $id The ID of the JSON document * @param string $cas Last known document CAS value for optimisti locking * @return MutateInBuilder * * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function mutateIn($id, $cas) {} /** * Performs a query to Couchbase Server * * @param N1qlQuery|ViewQuery|SpatialViewQuery|SearchQuery|AnalyticsQuery $query * @param bool $jsonAsArray if true, the values in the result rows (or hits) will be represented as * PHP arrays, otherwise they will be instances of the `stdClass` * @return object Query-specific result object. * * @see \Couchbase\N1qlQuery * @see \Couchbase\SearchQuery * @see \Couchbase\ViewQuery * @see \Couchbase\SpatialViewQuery */ public function query($query, $jsonAsArray = false) {} /** * Returns size of the map * * @param string $id ID of the document * @return int number of the key-value pairs * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function mapSize($id) {} /** * Add key to the map * * @param string $id ID of the document * @param string $key key * @param mixed $value value * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function mapAdd($id, $key, $value) {} /** * Removes key from the map * * @param string $id ID of the document * @param string $key key * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function mapRemove($id, $key) {} /** * Get an item from a map * * @param string $id ID of the document * @param string $key key * @return mixed value associated with the key * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function mapGet($id, $key) {} /** * Returns size of the set * * @param string $id ID of the document * @return int number of the elements * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function setSize($id) {} /** * Add value to the set * * Note, that currently only primitive values could be stored in the set (strings, integers and booleans). * * @param string $id ID of the document * @param string|int|float|bool $value new value * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function setAdd($id, $value) {} /** * Check if the value exists in the set * * @param string $id ID of the document * @param string|int|float|bool $value value to check * @return bool true if the value exists in the set * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function setExists($id, $value) {} /** * Remove value from the set * * @param string $id ID of the document * @param string|int|float|bool $value value to remove * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function setRemove($id, $value) {} /** * Returns size of the list * * @param string $id ID of the document * @return int number of the elements * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function listSize($id) {} /** * Add an element to the end of the list * * @param string $id ID of the document * @param mixed $value new value * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function listPush($id, $value) {} /** * Add an element to the beginning of the list * * @param string $id ID of the document * @param mixed $value new value * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function listShift($id, $value) {} /** * Remove an element at the given position * * @param string $id ID of the document * @param int $index index of the element to be removed * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function listRemove($id, $index) {} /** * Get an element at the given position * * @param string $id ID of the document * @param int $index index of the element * @return mixed the value * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function listGet($id, $index) {} /** * Set an element at the given position * * @param string $id ID of the document * @param int $index index of the element * @param mixed $value new value * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function listSet($id, $index, $value) {} /** * Check if the list contains specified value * * @param string $id ID of the document * @param mixed $value value to look for * @return bool true if the list contains the value * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function listExists($id, $value) {} /** * Returns size of the queue * * @param string $id ID of the document * @return int number of the elements in the queue * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function queueSize($id) {} /** * Checks if the queue contains specified value * * @param string $id ID of the document * @param mixed $value value to look for * @return bool true if the queue contains the value * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function queueExists($id, $value) {} /** * Add an element to the beginning of the queue * * @param string $id ID of the document * @param mixed $value new value * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function queueAdd($id, $value) {} /** * Remove the element at the end of the queue and return it * * @param string $id ID of the document * @return mixed removed value * * @see https://developer.couchbase.com/documentation/server/current/sdk/php/datastructures.html * More details on Data Structures * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Overview of Sub-Document Operations */ public function queueRemove($id) {} /** * Try to reach specified services, and measure network latency. * * @param int $services bitwise mask of required services (and all services when zero) * @param string $reportId custom identifier, which will be appended to "id" property in report * @return array the report object * * @see \Couchbase\Bucket::PINGSVC_KV * @see \Couchbase\Bucket::PINGSVC_N1QL * @see \Couchbase\Bucket::PINGSVC_VIEWS * @see \Couchbase\Bucket::PINGSVC_FTS * * @see https://github.com/couchbaselabs/sdk-rfcs/blob/master/rfc/0034-health-check.md * SDK RFC #34, which describes the feature and report layout. */ public function ping($services = 0, $reportId = null) {} /** * Collect and return information about state of internal network connections. * * @param string $reportId custom identifier, which will be appended to "id" property in report * @return array the report object * * @see https://github.com/couchbaselabs/sdk-rfcs/blob/master/rfc/0034-health-check.md * SDK RFC #34, which describes the feature and report layout. */ public function diag($reportId = null) {} /** * Encrypt fields inside specified document. * * @param array $document document structure * @param array $fieldOptions specification for fields needed to be encrypted. Where 'alg' contains * a string with alias of the registed crypto provider, and 'name' contains the name of the field. * @param string $prefix optional prefix for modified field (when null, the library will use "__crypt") * * @return array where the fields encrypted * * @see https://github.com/couchbase/php-couchbase-encryption */ public function encryptFields($document, $fieldOptions, $prefix = null) {} /** * Decrypt fields inside specified document. * * @param array $document document structure * @param array $fieldOptions specification for fields needed to be decrypted. Where 'alg' contains * a string with alias of the registed crypto provider, and 'name' contains the name of the field. * @param string $prefix optional prefix for modified field (when null, the library will use "__crypt") * * @return array where the fields decrypted * * @see https://github.com/couchbase/php-couchbase-encryption */ public function decryptFields($document, $fieldOptions, $prefix = null) {} } /** * Provides management capabilities for the Couchbase Bucket */ class BucketManager { final private function __construct() {} /** * Returns information about the bucket * * Returns an associative array of status information as seen by the cluster for * this bucket. The exact structure of the returned data can be seen in the Couchbase * Manual by looking at the bucket /info endpoint. * * @return array * * @see https://developer.couchbase.com/documentation/server/current/rest-api/rest-bucket-info.html * Getting Single Bucket Information */ public function info() {} /** * Flushes the bucket (clears all data) */ public function flush() {} /** * Returns all design documents of the bucket. * * @return array */ public function listDesignDocuments() {} /** * Get design document by its name * * @param string $name name of the design document (without _design/ prefix) * @return array */ public function getDesignDocument($name) {} /** * Removes design document by its name * * @param string $name name of the design document (without _design/ prefix) */ public function removeDesignDocument($name) {} /** * Creates or replaces design document. * * @param string $name name of the design document (without _design/ prefix) * @param array $document */ public function upsertDesignDocument($name, $document) {} /** * Inserts design document and fails if it is exist already. * * @param string $name name of the design document (without _design/ prefix) * @param array $document */ public function insertDesignDocument($name, $document) {} /** * List all N1QL indexes that are registered for the current bucket. * * @return array */ public function listN1qlIndexes() {} /** * Create a primary N1QL index. * * @param string $customName the custom name for the primary index. * @param bool $ignoreIfExist if a primary index already exists, an exception * will be thrown unless this is set to true. * @param bool $defer true to defer index building. */ public function createN1qlPrimaryIndex($customName = '', $ignoreIfExist = false, $defer = false) {} /** * Create secondary N1QL index. * * @param string $name name of the index * @param array $fields list of JSON fields to index * @param string $whereClause the WHERE clause of the index. * @param bool $ignoreIfExist if a secondary index already exists, an exception * will be thrown unless this is set to true. * @param bool $defer true to defer index building. */ public function createN1qlIndex($name, $fields, $whereClause = '', $ignoreIfExist = false, $defer = false) {} /** * Drop the given primary index * * @param string $customName the custom name for the primary index * @param bool $ignoreIfNotExist if a primary index does not exist, an exception * will be thrown unless this is set to true. */ public function dropN1qlPrimaryIndex($customName = '', $ignoreIfNotExist = false) {} /** * Drop the given secondary index * * @param string $name the index name * @param bool $ignoreIfNotExist if a secondary index does not exist, an exception * will be thrown unless this is set to true. */ public function dropN1qlIndex($name, $ignoreIfNotExist = false) {} } /** * Interface of authentication containers. * * @see \Couchbase\Cluster::authenticate() * @see \Couchbase\ClassicAuthenticator * @see \Couchbase\PasswordAuthenticator */ interface Authenticator {} /** * Authenticator based on login/password credentials. * * This authenticator uses separate credentials for Cluster management interface * as well as for each bucket. * * * * @see \Couchbase\Cluster::authenticate() * @see \Couchbase\Authenticator */ class ClassicAuthenticator implements Authenticator { /** * Registers cluster management credentials in the container * * @param string $username admin username * @param string $password admin password */ public function cluster($username, $password) {} /** * Registers bucket credentials in the container * * @param string $name bucket name * @param string $password bucket password */ public function bucket($name, $password) {} } /** * Authenticator based on RBAC feature of Couchbase Server 5+. * * This authenticator uses single credentials for all operations (data and management). * * @see \Couchbase\Cluster::authenticate() * @see \Couchbase\Authenticator */ class PasswordAuthenticator implements Authenticator { /** * Sets username * * @param string $username username * @return \Couchbase\PasswordAuthenticator */ public function username($username) {} /** * Sets password * * @param string $password password * @return \Couchbase\PasswordAuthenticator */ public function password($password) {} } /** * An object which contains meta information of the document needed to enforce query consistency. */ class MutationToken { final private function __construct() {} /** * Creates new mutation token * * @param string $bucketName name of the bucket * @param int $vbucketId partition number * @param string $vbucketUuid UUID of the partition * @param string $sequenceNumber sequence number inside partition */ public static function from($bucketName, $vbucketId, $vbucketUuid, $sequenceNumber) {} /** * Returns bucket name * * @return string */ public function bucketName() {} /** * Returns partition number * * @return int */ public function vbucketId() {} /** * Returns UUID of the partition * * @return string */ public function vbucketUuid() {} /** * Returns the sequence number inside partition * * @return string */ public function sequenceNumber() {} } /** * Container for mutation tokens. */ class MutationState { final private function __construct() {} /** * Create container from the given mutation token holders. * * @param array|Document|DocumentFragment $source anything that can have attached MutationToken * @return MutationState * * @see \Couchbase\MutationToken */ public static function from($source) {} /** * Update container with the given mutation token holders. * * @param array|Document|DocumentFragment $source anything that can have attached MutationToken * * @see \Couchbase\MutationToken */ public function add($source) {} } /** * Common interface for all View queries * * @see \Couchbase\ViewQuery * @see \Couchbase\SpatialViewQuery */ interface ViewQueryEncodable { /** * Returns associative array, representing the View query. * * @return array object which is ready to be serialized. */ public function encode(); } /** * Represents regular Couchbase Map/Reduce View query * * @see \Couchbase\Bucket::query() * @see \Couchbase\SpatialViewQuery * @see https://developer.couchbase.com/documentation/server/current/sdk/php/view-queries-with-sdk.html * MapReduce Views * @see https://developer.couchbase.com/documentation/server/current/architecture/querying-data-with-views.html * Querying Data with Views * @see https://developer.couchbase.com/documentation/server/current/rest-api/rest-views-get.html * Getting Views Information */ class ViewQuery implements ViewQueryEncodable { /** Force a view update before returning data */ public const UPDATE_BEFORE = 1; /** Allow stale views */ public const UPDATE_NONE = 2; /** Allow stale view, update view after it has been accessed. */ public const UPDATE_AFTER = 3; public const ORDER_ASCENDING = 1; public const ORDER_DESCENDING = 2; final private function __construct() {} /** * Creates a new Couchbase ViewQuery instance for performing a view query. * * @param string $designDocumentName the name of the design document to query * @param string $viewName the name of the view to query * @return ViewQuery */ public static function from($designDocumentName, $viewName) {} /** * Creates a new Couchbase ViewQuery instance for performing a spatial query. * @param string $designDocumentName the name of the design document to query * @param string $viewName the name of the view to query * @return SpatialViewQuery */ public static function fromSpatial($designDocumentName, $viewName) {} /** * Returns associative array, representing the View query. * * @return array object which is ready to be serialized. */ public function encode() {} /** * Limits the result set to a specified number rows. * * @param int $limit maximum number of records in the response * @return ViewQuery */ public function limit($limit) {} /** * Skips a number o records rom the beginning of the result set * * @param int $skip number of records to skip * @return ViewQuery */ public function skip($skip) {} /** * Specifies the mode of updating to perorm before and after executing the query * * @param int $consistency use constants UPDATE_BEFORE, UPDATE_NONE, UPDATE_AFTER * @return ViewQuery * * @see \Couchbase\ViewQuery::UPDATE_BEFORE * @see \Couchbase\ViewQuery::UPDATE_NONE * @see \Couchbase\ViewQuery::UPDATE_AFTER */ public function consistency($consistency) {} /** * Orders the results by key as specified * * @param int $order use contstants ORDER_ASCENDING, ORDER_DESCENDING * @return ViewQuery */ public function order($order) {} /** * Specifies whether the reduction function should be applied to results of the query. * * @param bool $reduce * @return ViewQuery */ public function reduce($reduce) {} /** * Group the results using the reduce function to a group or single row. * * Important: this setter and groupLevel should not be used together in the * same ViewQuery. It is sufficient to only set the grouping level only and * use this setter in cases where you always want the highest group level * implictly. * * @param bool $group * @return ViewQuery * * @see \Couchbase\ViewQuery::groupLevel */ public function group($group) {} /** * Specify the group level to be used. * * Important: group() and this setter should not be used together in the * same ViewQuery. It is sufficient to only use this setter and use group() * in cases where you always want the highest group level implictly. * * @param int $groupLevel the number of elements in the keys to use * @return ViewQuery * * @see \Couchbase\ViewQuery::group */ public function groupLevel($groupLevel) {} /** * Restict results of the query to the specified key * * @param mixed $key key * @return ViewQuery */ public function key($key) {} /** * Restict results of the query to the specified set of keys * * @param array $keys set of keys * @return ViewQuery */ public function keys($keys) {} /** * Specifies a range of the keys to return from the index. * * @param mixed $startKey * @param mixed $endKey * @param bool $inclusiveEnd * @return ViewQuery */ public function range($startKey, $endKey, $inclusiveEnd = false) {} /** * Specifies start and end document IDs in addition to range limits. * * This might be needed for more precise pagination with a lot of documents * with the same key selected into the same page. * * @param string $startKeyDocumentId document ID * @param string $endKeyDocumentId document ID * @return ViewQuery */ public function idRange($startKeyDocumentId, $endKeyDocumentId) {} /** * Specifies custom options to pass to the server. * * Note that these options are expected to be already encoded. * * @param array $customParameters parameters * @return ViewQuery * * @see https://developer.couchbase.com/documentation/server/current/rest-api/rest-views-get.html * Getting Views Information */ public function custom($customParameters) {} } /** * Represents spatial Couchbase Map/Reduce View query * * @see \Couchbase\Bucket::query() * @see \Couchbase\ViewQuery * @see https://developer.couchbase.com/documentation/server/current/architecture/querying-geo-data-spatial-views.html * Querying Geographic Data with Spatial Views * @see https://developer.couchbase.com/documentation/server/current/rest-api/rest-views-get.html * Getting Views Information * @see https://developer.couchbase.com/documentation/server/current/views/sv-query-parameters.html * Querying spatial views */ class SpatialViewQuery implements ViewQueryEncodable { final private function __construct() {} /** * Returns associative array, representing the View query. * * @return array object which is ready to be serialized. */ public function encode() {} /** * Limits the result set to a specified number rows. * * @param int $limit maximum number of records in the response * @return SpatialViewQuery */ public function limit($limit) {} /** * Skips a number o records rom the beginning of the result set * * @param int $skip number of records to skip * @return SpatialViewQuery */ public function skip($skip) {} /** * Specifies the mode of updating to perorm before and after executing the query * * @param int $consistency use constants UPDATE_BEFORE, UPDATE_NONE, UPDATE_AFTER * @return SpatialViewQuery * * @see \Couchbase\ViewQuery::UPDATE_BEFORE * @see \Couchbase\ViewQuery::UPDATE_NONE * @see \Couchbase\ViewQuery::UPDATE_AFTER */ public function consistency($consistency) {} /** * Orders the results by key as specified * * @param int $order use contstants ORDER_ASCENDING, ORDER_DESCENDING * @return SpatialViewQuery */ public function order($order) {} /** * Specifies the bounding box to search within. * * Note, using bbox() is discouraged, startRange/endRange is more flexible and should be preferred. * * @param array $bbox bounding box coordinates expressed as a list of numeric values * @return SpatialViewQuery * * @see \Couchbase\SpatialViewQuery::startRange() * @see \Couchbase\SpatialViewQuery::endRange() */ public function bbox($bbox) {} /** * Specify start range for query * * @param array $range * @return SpatialViewQuery * * @see https://developer.couchbase.com/documentation/server/current/views/sv-query-parameters.html * Querying spatial views */ public function startRange($range) {} /** * Specify end range for query * * @param array $range * @return SpatialViewQuery * * @see https://developer.couchbase.com/documentation/server/current/views/sv-query-parameters.html * Querying spatial views */ public function endRange($range) {} /** * Specifies custom options to pass to the server. * * Note that these options are expected to be already encoded. * * @param array $customParameters parameters * * @see https://developer.couchbase.com/documentation/server/current/rest-api/rest-views-get.html * Getting Views Information * @see https://developer.couchbase.com/documentation/server/current/views/sv-query-parameters.html * Querying spatial views */ public function custom($customParameters) {} } /** * Represents a N1QL query * * @see https://developer.couchbase.com/documentation/server/current/sdk/n1ql-query.html * Querying with N1QL * @see https://developer.couchbase.com/documentation/server/current/sdk/php/n1ql-queries-with-sdk.html * N1QL from the SDKs * @see https://developer.couchbase.com/documentation/server/current/n1ql/n1ql-rest-api/index.html * N1QL REST API * @see https://developer.couchbase.com/documentation/server/current/performance/index-scans.html * Understanding Index Scans * @see https://developer.couchbase.com/documentation/server/current/performance/indexing-and-query-perf.html * Indexing JSON Documents and Query Performance */ class N1qlQuery { /** * This is the default (for single-statement requests). * No timestamp vector is used in the index scan. * This is also the fastest mode, because we avoid the cost of obtaining the vector, * and we also avoid any wait for the index to catch up to the vector. */ public const NOT_BOUNDED = 1; /** * This implements strong consistency per request. * Before processing the request, a current vector is obtained. * The vector is used as a lower bound for the statements in the request. * If there are DML statements in the request, RYOW is also applied within the request. */ public const REQUEST_PLUS = 2; /** * This implements strong consistency per statement. * Before processing each statement, a current vector is obtained * and used as a lower bound for that statement. */ public const STATEMENT_PLUS = 3; /** * Disables profiling. This is the default */ public const PROFILE_NONE = 'off'; /** * Enables phase profiling. */ public const PROFILE_PHASES = 'phases'; /** * Enables general timing profiling. */ public const PROFILE_TIMINGS = 'timings'; final private function __construct() {} /** * Creates new N1qlQuery instance directly from the N1QL string. * * @param string $statement N1QL string * @return N1qlQuery */ public static function fromString($statement) {} /** * Allows to specify if this query is adhoc or not. * * If it is not adhoc (so performed often), the client will try to perform optimizations * transparently based on the server capabilities, like preparing the statement and * then executing a query plan instead of the raw query. * * @param bool $adhoc if query is adhoc, default is true (plain execution) * @return N1qlQuery */ public function adhoc($adhoc) {} /** * Allows to pull credentials from the Authenticator * * @param bool $crossBucket if query includes joins for multiple buckets (default is false) * @return N1qlQuery * * * @see \Couchbase\Authenticator * @see \Couchbase\ClassicAuthenticator */ public function crossBucket($crossBucket) {} /** * Specify array of positional parameters * * Previously specified positional parameters will be replaced. * Note: carefully choose type of quotes for the query string, because PHP also uses `$` * (dollar sign) for variable interpolation. If you are using double quotes, make sure * that N1QL parameters properly escaped. * * @param array $params * @return N1qlQuery */ public function positionalParams($params) {} /** * Specify associative array of named parameters * * The supplied array of key/value pairs will be merged with already existing named parameters. * Note: carefully choose type of quotes for the query string, because PHP also uses `$` * (dollar sign) for variable interpolation. If you are using double quotes, make sure * that N1QL parameters properly escaped. * * @param array $params * @return N1qlQuery */ public function namedParams($params) {} /** * Specifies the consistency level for this query * * @param int $consistency consistency level * @return N1qlQuery * * @see \Couchbase\N1qlQuery::NOT_BOUNDED * @see \Couchbase\N1qlQuery::REQUEST_PLUS * @see \Couchbase\N1qlQuery::STATEMENT_PLUS * @see \Couchbase\N1qlQuery::consistentWith() */ public function consistency($consistency) {} /** * Controls the profiling mode used during query execution * * @param string $profileType * @return N1qlQuery * @see \Couchbase\N1qlQuery::PROFILE_NONE * @see \Couchbase\N1qlQuery::PROFILE_PHASES * @see \Couchbase\N1qlQuery::PROFILE_TIMINGS */ public function profile($profileType) {} /** * Sets mutation state the query should be consistent with * * @param MutationState $state the container of mutation tokens * @return N1qlQuery * * @see \Couchbase\MutationState */ public function consistentWith($state) {} /** * If set to true, it will signal the query engine on the server that only non-data modifying requests * are allowed. Note that this rule is enforced on the server and not the SDK side. * * Controls whether a query can change a resulting record set. * * If readonly is true, then the following statements are not allowed: * - CREATE INDEX * - DROP INDEX * - INSERT * - MERGE * - UPDATE * - UPSERT * - DELETE * * @param bool $readonly true if readonly should be forced, false is the default and will use the server side default. * @return N1qlQuery */ public function readonly($readonly) {} /** * Advanced: Maximum buffered channel size between the indexer client and the query service for index scans. * * This parameter controls when to use scan backfill. Use 0 or a negative number to disable. * * @param int $scanCap the scan_cap param, use 0 or negative number to disable. * @return N1qlQuery */ public function scanCap($scanCap) {} /** * Advanced: Controls the number of items execution operators can batch for Fetch from the KV. * * @param int $pipelineBatch the pipeline_batch param. * @return N1qlQuery */ public function pipelineBatch($pipelineBatch) {} /** * Advanced: Maximum number of items each execution operator can buffer between various operators. * * @param int $pipelineCap the pipeline_cap param. * @return N1qlQuery */ public function pipelineCap($pipelineCap) {} /** * Allows to override the default maximum parallelism for the query execution on the server side. * * @param int $maxParallelism the maximum parallelism for this query, 0 or negative values disable it. * @return N1qlQuery */ public function maxParallelism($maxParallelism) {} } /** * Represents N1QL index definition * * @see https://developer.couchbase.com/documentation/server/current/performance/indexing-and-query-perf.html * Indexing JSON Documents and Query Performance */ class N1qlIndex { public const UNSPECIFIED = 0; public const GSI = 1; public const VIEW = 2; final private function __construct() {} /** * Name of the index * * @var string */ public $name; /** * Is it primary index * * @var bool */ public $isPrimary; /** * Type of the index * * @var int * * @see \Couchbase\N1qlIndex::UNSPECIFIED * @see \Couchbase\N1qlIndex::GSI * @see \Couchbase\N1qlIndex::VIEW */ public $type; /** * The descriptive state of the index * * @var string */ public $state; /** * The keyspace for the index, typically the bucket name * @var string */ public $keyspace; /** * The namespace for the index. A namespace is a resource pool that contains multiple keyspaces * @var string */ public $namespace; /** * The fields covered by index * @var array */ public $fields; /** * Return the string representation of the index's condition (the WHERE clause * of the index), or an empty String if no condition was set. * * Note that the query service can present the condition in a slightly different * manner from when you declared the index: for instance it will wrap expressions * with parentheses and show the fields in an escaped format (surrounded by backticks). * * @var string */ public $condition; } /** * A builder for subdocument lookups. In order to perform the final set of operations, use the * execute() method. * * Instances of this builder should be obtained through \Couchbase\Bucket->lookupIn() * * @see \Couchbase\Bucket::lookupIn * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Sub-Document Operations */ class LookupInBuilder { final private function __construct() {} /** * Get a value inside the JSON document. * * @param string $path the path inside the document where to get the value from. * @param array $options the array with command modificators. Supported values are * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return LookupInBuilder */ public function get($path, $options = []) {} /** * Get a count of values inside the JSON document. * * This method is only available with Couchbase Server 5.0 and later. * * @param string $path the path inside the document where to get the count from. * @param array $options the array with command modificators. Supported values are * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return LookupInBuilder */ public function getCount($path, $options = []) {} /** * Check if a value exists inside the document. * * This doesn't transmit the value on the wire if it exists, saving the corresponding byte overhead. * * @param string $path the path inside the document to check for existence * @param array $options the array with command modificators. Supported values are * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return LookupInBuilder */ public function exists($path, $options = []) {} /** * Perform several lookup operations inside a single existing JSON document, using a specific timeout * @return DocumentFragment */ public function execute() {} } /** * A builder for subdocument mutations. In order to perform the final set of operations, use the * execute() method. * * Instances of this builder should be obtained through \Couchbase\Bucket->mutateIn() * * @see \Couchbase\Bucket::mutateIn * @see https://developer.couchbase.com/documentation/server/current/sdk/subdocument-operations.html * Sub-Document Operations */ class MutateInBuilder { public const FULLDOC_REPLACE = 0; public const FULLDOC_UPSERT = 1; public const FULLDOC_INSERT = 2; final private function __construct() {} /** * Insert a fragment provided the last element of the path doesn't exists. * * @param string $path the path where to insert a new dictionary value. * @param mixed $value the new dictionary value to insert. * @param array|bool $options the array with command modificators. * The boolean value, controls "createPath" option. Supported values are: * * "createPath" (default: false) true to create missing intermediary nodes. * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return MutateInBuilder */ public function insert($path, $value, $options = []) {} /** * Select mode for new full-document operations. * * It defines behaviour of MutateInBuilder#upsert() method. The $mode * could take one of three modes: * * FULLDOC_REPLACE: complain when document does not exist * * FULLDOC_INSERT: complain when document does exist * * FULLDOC_UPSERT: unconditionally set value for the document * * @param int $mode operation mode */ public function modeDocument($mode) {} /** * Insert a fragment, replacing the old value if the path exists. * * When only one argument supplied, the library will handle it as full-document * upsert, and treat this argument as value. See MutateInBuilder#modeDocument() * * @param string $path the path where to insert (or replace) a dictionary value * @param mixed $value the new dictionary value to be applied. * @param array|bool $options the array with command modificators. * The boolean value, controls "createPath" option. Supported values are: * * "createPath" (default: false) true to create missing intermediary nodes. * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return MutateInBuilder */ public function upsert($path, $value, $options = []) {} /** * Replace an existing value by the given fragment * * @param string $path the path where the value to replace is * @param mixed $value the new value * @param array $options the array with command modificators. Supported values are: * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return MutateInBuilder */ public function replace($path, $value, $options = []) {} /** * Remove an entry in a JSON document. * * Scalar, array element, dictionary entry, whole array or dictionary, depending on the path. * * @param string $path the path to remove * @param array $options the array with command modificators. Supported values are: * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return MutateInBuilder */ public function remove($path, $options = []) {} /** * Prepend to an existing array, pushing the value to the front/first position in the array. * * @param string $path the path of the array * @param mixed $value the value to insert at the front of the array * @param array|bool $options the array with command modificators. * The boolean value, controls "createPath" option. Supported values are: * * "createPath" (default: false) true to create missing intermediary nodes. * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return MutateInBuilder */ public function arrayPrepend($path, $value, $options = []) {} /** * Prepend multiple values at once in an existing array. * * Push all values in the collection's iteration order to the front/start of the array. * For example given an array [A, B, C], prepending the values X and Y yields [X, Y, A, B, C] * and not [[X, Y], A, B, C]. * * @param string $path the path of the array * @param array $values the values to insert at the front of the array as individual elements * @param array|bool $options the array with command modificators. * The boolean value, controls "createPath" option. Supported values are: * * "createPath" (default: false) true to create missing intermediary nodes. * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return MutateInBuilder */ public function arrayPrependAll($path, $values, $options = []) {} /** * Append to an existing array, pushing the value to the back/last position in the array. * * @param string $path the path of the array * @param mixed $value the value to insert at the back of the array * @param array|bool $options the array with command modificators. * The boolean value, controls "createPath" option. Supported values are: * * "createPath" (default: false) true to create missing intermediary nodes. * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return MutateInBuilder */ public function arrayAppend($path, $value, $options = []) {} /** * Append multiple values at once in an existing array. * * Push all values in the collection's iteration order to the back/end of the array. * For example given an array [A, B, C], appending the values X and Y yields [A, B, C, X, Y] * and not [A, B, C, [X, Y]]. * * @param string $path the path of the array * @param array $values the values to individually insert at the back of the array * @param array|bool $options the array with command modificators. * The boolean value, controls "createPath" option. Supported values are: * * "createPath" (default: false) true to create missing intermediary nodes. * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return MutateInBuilder */ public function arrayAppendAll($path, $values, $options = []) {} /** * Insert into an existing array at a specific position * * Position denoted in the path, eg. "sub.array[2]". * * @param string $path the path (including array position) where to insert the value * @param mixed $value the value to insert in the array * @param array $options the array with command modificators. Supported values are: * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return MutateInBuilder */ public function arrayInsert($path, $value, $options = []) {} /** * Insert multiple values at once in an existing array at a specified position. * * Position denoted in the path, eg. "sub.array[2]"), inserting all values in the collection's iteration order * at the given position and shifting existing values beyond the position by the number of elements in the * collection. * * For example given an array [A, B, C], inserting the values X and Y at position 1 yields [A, B, X, Y, C] * and not [A, B, [X, Y], C]. * @param string $path the path of the array * @param array $values the values to insert at the specified position of the array, each value becoming * an entry at or after the insert position. * @param array $options the array with command modificators. Supported values are: * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return MutateInBuilder */ public function arrayInsertAll($path, $values, $options = []) {} /** * Insert a value in an existing array only if the value * isn't already contained in the array (by way of string comparison). * * @param string $path the path to mutate in the JSON * @param mixed $value the value to insert * @param array|bool $options the array with command modificators. * The boolean value, controls "createPath" option. Supported values are: * * "createPath" (default: false) true to create missing intermediary nodes. * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return MutateInBuilder */ public function arrayAddUnique($path, $value, $options = []) {} /** * Increment/decrement a numerical fragment in a JSON document. * * If the value (last element of the path) doesn't exist the counter * is created and takes the value of the delta. * * @param string $path the path to the counter (must be containing a number). * @param int $delta the value to increment or decrement the counter by * @param array|bool $options the array with command modificators. * The boolean value, controls "createPath" option. Supported values are: * * "createPath" (default: false) true to create missing intermediary nodes. * * "xattr" (default: false) if true, the path refers to a location * within the document's extended attributes, not the document body. * @return MutateInBuilder */ public function counter($path, $delta, $options = []) {} /** * Change the expiry of the enclosing document as part of the mutation. * * @param mixed $expiry the new expiry to apply (or 0 to avoid changing the expiry) * @return MutateInBuilder */ public function withExpiry($expiry) {} /** * Perform several mutation operations inside a single existing JSON document. * @return DocumentFragment */ public function execute() {} } /** * Represents full text search query * * @see https://developer.couchbase.com/documentation/server/4.6/sdk/php/full-text-searching-with-sdk.html * Searching from the SDK */ class SearchQuery implements \JsonSerializable { public const HIGHLIGHT_HTML = 'html'; public const HIGHLIGHT_ANSI = 'ansi'; public const HIGHLIGHT_SIMPLE = 'simple'; /** * Prepare boolean search query * * @return BooleanSearchQuery */ public static function boolean() {} /** * Prepare date range search query * * @return DateRangeSearchQuery */ public static function dateRange() {} /** * Prepare numeric range search query * * @return NumericRangeSearchQuery */ public static function numericRange() {} /** * Prepare term range search query * * @return TermRangeSearchQuery */ public static function termRange() {} /** * Prepare boolean field search query * * @param bool $value * @return BooleanFieldSearchQuery */ public static function booleanField($value) {} /** * Prepare compound conjunction search query * * @param SearchQueryPart ...$queries list of inner query parts * @return ConjunctionSearchQuery */ public static function conjuncts(...$queries) {} /** * Prepare compound disjunction search query * * @param SearchQueryPart ...$queries list of inner query parts * @return DisjunctionSearchQuery */ public static function disjuncts(...$queries) {} /** * Prepare document ID search query * * @param string ...$documentIds * @return DocIdSearchQuery */ public static function docId(...$documentIds) {} /** * Prepare match search query * * @param string $match * @return MatchSearchQuery */ public static function match($match) {} /** * Prepare match all search query * * @return MatchAllSearchQuery */ public static function matchAll() {} /** * Prepare match non search query * * @return MatchNoneSearchQuery */ public static function matchNone() {} /** * Prepare phrase search query * * @param string ...$terms * @return MatchPhraseSearchQuery */ public static function matchPhrase(...$terms) {} /** * Prepare prefix search query * * @param string $prefix * @return PrefixSearchQuery */ public static function prefix($prefix) {} /** * Prepare query string search query * * @param string $queryString * @return QueryStringSearchQuery */ public static function queryString($queryString) {} /** * Prepare regexp search query * * @param string $regexp * @return RegexpSearchQuery */ public static function regexp($regexp) {} /** * Prepare term search query * * @param string $term * @return TermSearchQuery */ public static function term($term) {} /** * Prepare wildcard search query * * @param string $wildcard * @return WildcardSearchQuery */ public static function wildcard($wildcard) {} /** * Prepare geo distance search query * * @param float $longitude * @param float $latitude * @param string $distance e.g. "10mi" * @return GeoDistanceSearchQuery */ public static function geoDistance($longitude, $latitude, $distance) {} /** * Prepare geo bounding box search query * * @param float $topLeftLongitude * @param float $topLeftLatitude * @param float $bottomRightLongitude * @param float $bottomRightLatitude * @return GeoBoundingBoxSearchQuery */ public static function geoBoundingBox($topLeftLongitude, $topLeftLatitude, $bottomRightLongitude, $bottomRightLatitude) {} /** * Prepare term search facet * * @param string $field * @param int $limit * @return TermSearchFacet */ public static function termFacet($field, $limit) {} /** * Prepare date range search facet * * @param string $field * @param int $limit * @return DateRangeSearchFacet */ public static function dateRangeFacet($field, $limit) {} /** * Prepare numeric range search facet * * @param string $field * @param int $limit * @return NumericRangeSearchFacet */ public static function numericRangeFacet($field, $limit) {} /** * Prepare an FTS SearchQuery on an index. * * Top level query parameters can be set after that by using the fluent API. * * @param string $indexName the FTS index to search in * @param SearchQueryPart $queryPart the body of the FTS query (e.g. a match phrase query) */ public function __construct($indexName, $queryPart) {} /** * @return array */ public function jsonSerialize() {} /** * Add a limit to the query on the number of hits it can return * * @param int $limit the maximum number of hits to return * @return SearchQuery */ public function limit($limit) {} /** * Set the number of hits to skip (eg. for pagination). * * @param int $skip the number of results to skip * @return SearchQuery */ public function skip($skip) {} /** * Activates the explanation of each result hit in the response * * @param bool $explain * @return SearchQuery */ public function explain($explain) {} /** * Sets the server side timeout in milliseconds * * @param int $serverSideTimeout the server side timeout to apply * @return SearchQuery */ public function serverSideTimeout($serverSideTimeout) {} /** * Sets the consistency to consider for this FTS query to AT_PLUS and * uses the MutationState to parameterize the consistency. * * This replaces any consistency tuning previously set. * * @param MutationState $state the mutation state information to work with * @return SearchQuery */ public function consistentWith($state) {} /** * Configures the list of fields for which the whole value should be included in the response. * * If empty, no field values are included. This drives the inclusion of the fields in each hit. * Note that to be highlighted, the fields must be stored in the FTS index. * * @param string ...$fields * @return SearchQuery */ public function fields(...$fields) {} /** * Configures the highlighting of matches in the response * * @param string $style highlight style to apply. Use constants HIGHLIGHT_HTML, * HIGHLIGHT_ANSI, HIGHLIGHT_SIMPLE. * @param string ...$fields the optional fields on which to highlight. * If none, all fields where there is a match are highlighted. * @return SearchQuery * * @see \Couchbase\SearchQuery::HIGHLIGHT_HTML * @see \Couchbase\SearchQuery::HIGHLIGHT_ANSI * @see \Couchbase\SearchQuery::HIGHLIGHT_SIMPLE */ public function highlight($style, ...$fields) {} /** * Configures the list of fields (including special fields) which are used for sorting purposes. * If empty, the default sorting (descending by score) is used by the server. * * The list of sort fields can include actual fields (like "firstname" but then they must be stored in the * index, configured in the server side mapping). Fields provided first are considered first and in a "tie" case * the next sort field is considered. So sorting by "firstname" and then "lastname" will first sort ascending by * the firstname and if the names are equal then sort ascending by lastname. Special fields like "_id" and * "_score" can also be used. If prefixed with "-" the sort order is set to descending. * * If no sort is provided, it is equal to sort("-_score"), since the server will sort it by score in descending * order. * * @param mixed $sort the fields that should take part in the sorting. * @return SearchQuery */ public function sort(...$sort) {} /** * Adds one SearchFacet to the query * * This is an additive operation (the given facets are added to any facet previously requested), * but if an existing facet has the same name it will be replaced. * * Note that to be faceted, a field's value must be stored in the FTS index. * * @param string $name * @param SearchFacet $facet * @return SearchQuery * * @see \Couchbase\SearchFacet * @see \Couchbase\TermSearchFacet * @see \Couchbase\NumericRangeSearchFacet * @see \Couchbase\DateRangeSearchFacet */ public function addFacet($name, $facet) {} } /** * Common interface for all classes, which could be used as a body of SearchQuery * * @see \Couchbase\SearchQuery::__construct() */ interface SearchQueryPart {} /** * A FTS query that queries fields explicitly indexed as boolean. */ class BooleanFieldSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return BooleanFieldSearchQuery */ public function boost($boost) {} /** * @param string $field * @return BooleanFieldSearchQuery */ public function field($field) {} } /** * A compound FTS query that allows various combinations of sub-queries. */ class BooleanSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return BooleanSearchQuery */ public function boost($boost) {} /** * @param SearchQueryPart ...$queries * @return BooleanSearchQuery */ public function must(...$queries) {} /** * @param SearchQueryPart ...$queries * @return BooleanSearchQuery */ public function mustNot(...$queries) {} /** * @param SearchQueryPart ...$queries * @return BooleanSearchQuery */ public function should(...$queries) {} } /** * A compound FTS query that performs a logical AND between all its sub-queries (conjunction). */ class ConjunctionSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return ConjunctionSearchQuery */ public function boost($boost) {} /** * @param SearchQueryPart ...$queries * @return ConjunctionSearchQuery */ public function every(...$queries) {} } /** * A compound FTS query that performs a logical OR between all its sub-queries (disjunction). It requires that a * minimum of the queries match. The minimum is configurable (default 1). */ class DisjunctionSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return DisjunctionSearchQuery */ public function boost($boost) {} /** * @param SearchQueryPart ...$queries * @return DisjunctionSearchQuery */ public function either(...$queries) {} /** * @param int $min * @return DisjunctionSearchQuery */ public function min($min) {} } /** * A FTS query that matches documents on a range of values. At least one bound is required, and the * inclusiveness of each bound can be configured. */ class DateRangeSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return DateRangeSearchQuery */ public function boost($boost) {} /** * @param string $field * @return DateRangeSearchQuery */ public function field($field) {} /** * @param int|string $start The strings will be taken verbatim and supposed to be formatted with custom date * time formatter (see dateTimeParser). Integers interpreted as unix timestamps and represented as RFC3339 * strings. * @param bool $inclusive * @return DateRangeSearchQuery */ public function start($start, $inclusive = true) {} /** * @param int|string $end The strings will be taken verbatim and supposed to be formatted with custom date * time formatter (see dateTimeParser). Integers interpreted as unix timestamps and represented as RFC3339 * strings. * @param bool $inclusive * @return DateRangeSearchQuery */ public function end($end, $inclusive = false) {} /** * @param string $dateTimeParser * @return DateRangeSearchQuery */ public function dateTimeParser($dateTimeParser) {} } /** * A FTS query that matches documents on a range of values. At least one bound is required, and the * inclusiveness of each bound can be configured. */ class NumericRangeSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return NumericRangeSearchQuery */ public function boost($boost) {} /** * @param string $field * @return NumericRangeSearchQuery */ public function field($field) {} /** * @param float $min * @param bool $inclusive * @return NumericRangeSearchQuery */ public function min($min, $inclusive = true) {} /** * @param float $max * @param bool $inclusive * @return NumericRangeSearchQuery */ public function max($max, $inclusive = false) {} } /** * A FTS query that matches on Couchbase document IDs. Useful to restrict the search space to a list of keys (by using * this in a compound query). */ class DocIdSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return DocIdSearchQuery */ public function boost($boost) {} /** * @param string $field * @return DocIdSearchQuery */ public function field($field) {} /** * @param string ...$documentIds * @return DocIdSearchQuery */ public function docIds(...$documentIds) {} } /** * A FTS query that matches all indexed documents (usually for debugging purposes). */ class MatchAllSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return MatchAllSearchQuery */ public function boost($boost) {} } /** * A FTS query that matches 0 document (usually for debugging purposes). */ class MatchNoneSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return MatchNoneSearchQuery */ public function boost($boost) {} } /** * A FTS query that matches several given terms (a "phrase"), applying further processing * like analyzers to them. */ class MatchPhraseSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return MatchPhraseSearchQuery */ public function boost($boost) {} /** * @param string $field * @return MatchPhraseSearchQuery */ public function field($field) {} /** * @param string $analyzer * @return MatchPhraseSearchQuery */ public function analyzer($analyzer) {} } /** * A FTS query that matches a given term, applying further processing to it * like analyzers, stemming and even #fuzziness(int). */ class MatchSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return MatchSearchQuery */ public function boost($boost) {} /** * @param string $field * @return MatchSearchQuery */ public function field($field) {} /** * @param string $analyzer * @return MatchSearchQuery */ public function analyzer($analyzer) {} /** * @param int $prefixLength * @return MatchSearchQuery */ public function prefixLength($prefixLength) {} /** * @param int $fuzziness * @return MatchSearchQuery */ public function fuzziness($fuzziness) {} } /** * A FTS query that matches several terms (a "phrase") as is. The order of the terms mater and no further processing is * applied to them, so they must appear in the index exactly as provided. Usually for debugging purposes, prefer * MatchPhraseQuery. */ class PhraseSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return PhraseSearchQuery */ public function boost($boost) {} /** * @param string $field * @return PhraseSearchQuery */ public function field($field) {} } /** * A FTS query that allows for simple matching of regular expressions. */ class RegexpSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return RegexpSearchQuery */ public function boost($boost) {} /** * @param string $field * @return RegexpSearchQuery */ public function field($field) {} } /** * A FTS query that allows for simple matching using wildcard characters (* and ?). */ class WildcardSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return WildcardSearchQuery */ public function boost($boost) {} /** * @param string $field * @return WildcardSearchQuery */ public function field($field) {} } /** * A FTS query that allows for simple matching on a given prefix. */ class PrefixSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return PrefixSearchQuery */ public function boost($boost) {} /** * @param string $field * @return PrefixSearchQuery */ public function field($field) {} } /** * A FTS query that performs a search according to the "string query" syntax. */ class QueryStringSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return QueryStringSearchQuery */ public function boost($boost) {} } /** * A facet that gives the number of occurrences of the most recurring terms in all hits. */ class TermSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return TermSearchQuery */ public function boost($boost) {} /** * @param string $field * @return TermSearchQuery */ public function field($field) {} /** * @param int $prefixLength * @return TermSearchQuery */ public function prefixLength($prefixLength) {} /** * @param int $fuzziness * @return TermSearchQuery */ public function fuzziness($fuzziness) {} } /** * A FTS query that matches documents on a range of values. At least one bound is required, and the * inclusiveness of each bound can be configured. */ class TermRangeSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return TermRangeSearchQuery */ public function boost($boost) {} /** * @param string $field * @return TermRangeSearchQuery */ public function field($field) {} /** * @param string $min * @param bool $inclusive * @return TermRangeSearchQuery */ public function min($min, $inclusive = true) {} /** * @param string $max * @param bool $inclusive * @return TermRangeSearchQuery */ public function max($max, $inclusive = false) {} } /** * A FTS query that finds all matches from a given location (point) within the given distance. * * Both the point and the distance are required. */ class GeoDistanceSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return GeoDistanceSearchQuery */ public function boost($boost) {} /** * @param string $field * @return GeoDistanceSearchQuery */ public function field($field) {} } /** * A FTS query which allows to match geo bounding boxes. */ class GeoBoundingBoxSearchQuery implements \JsonSerializable, SearchQueryPart { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param float $boost * @return GeoBoundingBoxSearchQuery */ public function boost($boost) {} /** * @param string $field * @return GeoBoundingBoxSearchQuery */ public function field($field) {} } /** * Common interface for all search facets * * @see \Couchbase\SearchQuery::addFacet() * @see \Couchbase\TermSearchFacet * @see \Couchbase\DateRangeSearchFacet * @see \Couchbase\NumericRangeSearchFacet */ interface SearchFacet {} /** * A facet that gives the number of occurrences of the most recurring terms in all hits. */ class TermSearchFacet implements \JsonSerializable, SearchFacet { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} } /** * A facet that categorizes hits inside date ranges (or buckets) provided by the user. */ class DateRangeSearchFacet implements \JsonSerializable, SearchFacet { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param string $name * @param int|string $start * @param int|string $end * @return DateSearchFacet */ public function addRange($name, $start, $end) {} } /** * A facet that categorizes hits into numerical ranges (or buckets) provided by the user. */ class NumericRangeSearchFacet implements \JsonSerializable, SearchFacet { final private function __construct() {} /** * @return array */ public function jsonSerialize() {} /** * @param string $name * @param float $min * @param float $max * @return NumericSearchFacet */ public function addRange($name, $min, $max) {} } /** * Base class for all FTS sort options in querying. */ class SearchSort { private function __construct() {} /** * Sort by the document identifier. * * @return SearchSortId */ public static function id() {} /** * Sort by the hit score. * * @return SearchSortScore */ public static function score() {} /** * Sort by a field in the hits. * * @param string $field the field name * * @return SearchSortField */ public static function field($field) {} /** * Sort by geo location. * * @param string $field the field name * @param float $longitude the longitude of the location * @param float $latitude the latitude of the location * * @return SearchSortGeoDistance */ public static function geoDistance($field, $longitude, $latitude) {} } /** * Sort by the document identifier. */ class SearchSortId extends SearchSort implements \JsonSerializable { private function __construct() {} /** * Direction of the sort * * @param bool $descending * * @return SearchSortId */ public function descending($descending) {} } /** * Sort by the hit score. */ class SearchSortScore extends SearchSort implements \JsonSerializable { private function __construct() {} /** * Direction of the sort * * @param bool $descending * * @return SearchSortScore */ public function descending($descending) {} } /** * Sort by a field in the hits. */ class SearchSortField extends SearchSort implements \JsonSerializable { public const TYPE_AUTO = "auto"; public const TYPE_STRING = "string"; public const TYPE_NUMBER = "number"; public const TYPE_DATE = "date"; public const MODE_DEFAULT = "default"; public const MODE_MIN = "min"; public const MODE_MAX = "max"; public const MISSING_FIRST = "first"; public const MISSING_LAST = "last"; private function __construct() {} /** * Direction of the sort * * @param bool $descending * * @return SearchSortField */ public function descending($descending) {} /** * Set type of the field * * @param string $type the type * * @see SearchSortField::TYPE_AUTO * @see SearchSortField::TYPE_STRING * @see SearchSortField::TYPE_NUMBER * @see SearchSortField::TYPE_DATE */ public function type($type) {} /** * Set mode of the sort * * @param string $mode the mode * * @see SearchSortField::MODE_MIN * @see SearchSortField::MODE_MAX */ public function mode($mode) {} /** * Set where the hits with missing field will be inserted * * @param string $missing strategy for hits with missing fields * * @see SearchSortField::MISSING_FIRST * @see SearchSortField::MISSING_LAST */ public function missing($missing) {} } /** * Sort by a location and unit in the hits. */ class SearchSortGeoDistance extends SearchSort implements \JsonSerializable { private function __construct() {} /** * Direction of the sort * * @param bool $descending * * @return SearchSortGeoDistance */ public function descending($descending) {} /** * Name of the units * * @param string $unit * * @return SearchSortGeoDistance */ public function unit($unit) {} } /** * Represents a Analytics query (currently experimental support). * * @see https://developer.couchbase.com/documentation/server/4.5/analytics/quick-start.html * Analytics quick start */ class AnalyticsQuery { final private function __construct() {} /** * Creates new AnalyticsQuery instance directly from the string. * * @param string $statement statement string * @return AnalyticsQuery */ public static function fromString($statement) {} } * Cookie name. *

    * @param string $value

    * Cookie value. *

    * @return string|false the encrypted string or false on failure. */ function suhosin_encrypt_cookie($name, $value) {} /** * Returns an array containing the raw cookie values * @link https://php.net/manual/en/function.suhosin-get-raw-cookies.php * @return array an array containing the raw cookie values. */ function suhosin_get_raw_cookies() {} = 1.0.1 are `tlsv1.2`, `tlsv1.1` and `tlsv1`. * @param string|null $ciphers A string describing the ciphers available for use. See the `openssl ciphers` tool for more information. If `null`, the default set will be used. * @return int */ public function setTlsOptions($certReqs, $tlsVersion = null, $ciphers = null) {} /** * Configure the client for pre-shared-key based TLS support. Must be called before `connect`. Cannot be used in * conjunction with setTlsCertificates. * * @param string $psk The pre-shared key in hex format with no leading "0x". * @param string $identity The identity of this client. May be used as the username depending on server settings. * @param string|null $ciphers Optional. A string describing the ciphers available for use. See the `openssl ciphers` tool for more information. If `null`, the default set will be used. * @return int */ public function setTlsPSK($psk, $identity, $ciphers = null) {} /** * Set the client “last will and testament”, which will be sent on an unclean disconnection from the broker. * Must be called before `connect`. * * @param string $topic The topic on which to publish the will. * @param string $payload The data to send. * @param int $qos Optional. Default 0. Integer 0, 1, or 2 indicating the Quality of Service to be used. * @param bool $retain Optional. Default false. If true, the message will be retained. */ public function setWill($topic, $payload, $qos = 0, $retain = false) {} /** * Remove a previously-set will. No parameters. */ public function clearWill() {} /** * Control the behaviour of the client when it has unexpectedly disconnected in Client::loopForever(). * The default behaviour if this method is not used is to repeatedly attempt to reconnect with a delay of 1 second * until the connection succeeds. * * @param int $reconnectDelay Set delay between successive reconnection attempts. * @param int $exponentialDelay Set max delay between successive reconnection attempts when exponential backoff is enabled * @param bool $exponentialBackoff Pass `true` to enable exponential backoff */ public function setReconnectDelay($reconnectDelay, $exponentialDelay = 0, $exponentialBackoff = false) {} /** * Connect to an MQTT broker. * * @param string $host Hostname to connect to * @param int $port Optional. Port number to connect to. Defaults to 1883. * @param int $keepalive Optional. Number of sections after which the broker should PING the client if no messages have been received. * @param string|null $interface Optional. The address or hostname of a local interface to bind to for this connection. * @return int */ public function connect($host, $port = 1883, $keepalive = 60, $interface = null) {} /** * Disconnect from the broker. No parameters. */ public function disconnect() {} /** * Set the connect callback. This is called when the broker sends a CONNACK message in response to a connection. * * (int) $rc, (string) $message * function ($rc, $message) {} * * Response codes: * 0 = Success * 1 = Connection refused (unacceptable protocol version) * 2 = Connection refused (identifier rejected) * 3 = Connection refused (broker unavailable) * 4-255 = Reserved for future use * * @param callable $callback */ public function onConnect($callback) {} /** * Set the disconnect callback. This is called when the broker has received the DISCONNECT command and has * disconnected the client. * * (int) $rc * function ($rc) {} * * Response codes: * 0 = requested by client * <0 = indicates an unexpected disconnection. * * @param callable $callback */ public function onDisconnect($callback) {} /** * Set the logging callback. * * (int) $level, (string) $str * function ($level, $str) {} * * Log levels: * Client::LOG_DEBUG * Client::LOG_INFO * Client::LOG_NOTICE * Client::LOG_WARNING * Client::LOG_ERR * * @param callable $callback */ public function onLog($callback) {} /** * Set the subscribe callback. This is called when the broker responds to a subscription request. * * (int) $mid, (int) $qosCount * function ($mid, $qosCount) {} * * @param callable $callback */ public function onSubscribe($callback) {} /** * Set the unsubscribe callback. This is called when the broker responds to a unsubscribe request. * * (int) $mid * function ($mid) {} * * @param callable $callback */ public function onUnsubscribe($callback) {} /** * Set the message callback. This is called when a message is received from the broker. * * (object) $message * function (Mosquitto\Message $message) {} * * @param callable $callback */ public function onMessage($callback) {} /** * Set the publish callback. This is called when a message is published by the client itself. * * Warning: this may be called before the method publish returns the message id, so, you need to create a queue to * deal with the MID list. * * (int) $mid - the message id returned by `publish` * function ($mid) {} * * @param callable $callback */ public function onPublish($callback) {} /** * Set the number of QoS 1 and 2 messages that can be “in flight” at one time. An in flight message is part way * through its delivery flow. Attempts to send further messages with publish will result in the messages * being queued until the number of in flight messages reduces. * * Set to 0 for no maximum. * * @param int $maxInFlightMessages */ public function setMaxInFlightMessages($maxInFlightMessages) {} /** * Set the number of seconds to wait before retrying messages. This applies to publishing messages with QoS > 0. * May be called at any time. * * @param int $messageRetryPeriod The retry period */ public function setMessageRetry($messageRetryPeriod) {} /** * Publish a message on a given topic. * Return the message ID returned by the broker. Warning: the message ID is not unique. * * @param string $topic The topic to publish on * @param string $payload The message payload * @param int $qos Integer value 0, 1 or 2 indicating the QoS for this message * @param bool $retain If true, retain this message * @return int */ public function publish($topic, $payload, $qos = 0, $retain = false) {} /** * Subscribe to a topic. * Return the message ID of the subscription message, so this can be matched up in the `onSubscribe` callback. * * @param string $topic * @param int $qos * @return int */ public function subscribe($topic, $qos) {} /** * Unsubscribe from a topic. * Return the message ID of the subscription message, so this can be matched up in the `onUnsubscribe` callback. * * @param string $topic * @param int $qos * @return int */ public function unsubscribe($topic, $qos) {} /** * The main network loop for the client. You must call this frequently in order to keep communications between * the client and broker working. If incoming data is present it will then be processed. Outgoing commands, * from e.g. `publish`, are normally sent immediately that their function is called, but this is not always possible. * `loop` will also attempt to send any remaining outgoing messages, which also includes commands that are part * of the flow for messages with QoS > 0. * * @param int $timeout Optional. Number of milliseconds to wait for network activity. Pass 0 for instant timeout. */ public function loop($timeout = 1000) {} /** * Call loop() in an infinite blocking loop. Callbacks will be called as required. This will handle reconnecting * if the connection is lost. Call `disconnect` in a callback to disconnect and return from the loop. Alternatively, * call `exitLoop` to exit the loop without disconnecting. You will need to re-enter the loop again afterwards * to maintain the connection. * * @param int $timeout Optional. Number of milliseconds to wait for network activity. Pass 0 for instant timeout. */ public function loopForever($timeout = 1000) {} /** * Exit the `loopForever` event loop without disconnecting. You will need to re-enter the loop afterwards * in order to maintain the connection. */ public function exitLoop() {} } /** * @link https://mosquitto-php.readthedocs.io/en/latest/message.html */ class Message { /** @var string */ public $topic; /** @var string */ public $payload; /** @var int */ public $mid; /** @var int */ public $qos; /** @var bool */ public $retain; /** * Returns true if the supplied topic matches the supplied description, and otherwise false. * * @param string $topic The topic to match * @param string $subscription The subscription to match * @return bool */ public static function topicMatchesSub($topic, $subscription) {} /** * Tokenise a topic or subscription string into an array of strings representing the topic hierarchy. * * @param string $topic * @return array */ public static function tokeniseTopic($topic) {} } /** * @link https://mosquitto-php.readthedocs.io/en/latest/exception.html */ class Exception extends \Exception {} * Start xhprof profiler. * * @link https://php.net/manual/en/function.xhprof-enable.php * * @param int $flags

    Optional flags to add additional information to the profiling. See the a * href="https://secure.php.net/manual/en/xhprof.constants.php">XHprof constants for further * information about these flags, e.g., XHPROF_FLAGS_MEMORY to enable memory * profiling.

    * @param array $options [optional]

    An array of optional options, namely, the 'ignored_functions' option to pass in functions * to be ignored during profiling.

    * * @return null */ function xhprof_enable($flags = 0, array $options = []) {} /** * (PHP >= 5.2.0, PECL xhprof >= 0.9.0)
    * Stops the profiler, and returns xhprof data from the run. * * @link https://php.net/manual/en/function.xhprof-disable.php * @return array an array of xhprof data, from the run. */ function xhprof_disable() {} /** * (PHP >= 5.2.0, PECL xhprof >= 0.9.0)
    * Starts profiling in sample mode, which is a lighter weight version of {@see xhprof_enable()}. The sampling interval * is 0.1 seconds, and samples record the full function call stack. The main use case is when lower overhead is * required when doing performance monitoring and diagnostics. * * @link https://php.net/manual/en/function.xhprof-sample-enable.php * @return null */ function xhprof_sample_enable() {} /** * (PHP >= 5.2.0, PECL xhprof >= 0.9.0)
    * Stops the sample mode xhprof profiler, and returns xhprof data from the run. * * @link https://php.net/manual/en/function.xhprof-sample-disable.php * @return array an array of xhprof sample data, from the run. */ function xhprof_sample_disable() {} /** * @link https://php.net/manual/en/xhprof.constants.php#constant.xhprof-flags-no-builtins */ const XHPROF_FLAGS_NO_BUILTINS = 1; /** * @link https://php.net/manual/en/xhprof.constants.php#constant.xhprof-flags-cpu */ const XHPROF_FLAGS_CPU = 2; /** * @link https://php.net/manual/en/xhprof.constants.php##constant.xhprof-flags-memory */ const XHPROF_FLAGS_MEMORY = 4; // End of xhprof v.0.9.4 'FTP\Connection'], default: 'resource')] $ftp, string $remote_filename, string $local_filename, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '5.3', to: '7.2')] int $mode, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '7.3')] int $mode = FTP_BINARY ): bool {} /** * returns a list of files in the given directory * @param resource $ftp * @param string $directory * @return array|false * @since 7.2 */ function ftp_mlsd(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $directory): array|false {} /** * Opens an FTP connection * @link https://php.net/manual/en/function.ftp-connect.php * @param string $hostname

    * The FTP server address. This parameter shouldn't have any trailing * slashes and shouldn't be prefixed with ftp://. *

    * @param int $port [optional]

    * This parameter specifies an alternate port to connect to. If it is * omitted or set to zero, then the default FTP port, 21, will be used. *

    * @param int $timeout [optional]

    * This parameter specifies the timeout for all subsequent network operations. * If omitted, the default value is 90 seconds. The timeout can be changed and * queried at any time with ftp_set_option and * ftp_get_option. *

    * @return resource|false a FTP stream on success or FALSE on error. */ #[LanguageLevelTypeAware(['8.1' => 'FTP\Connection|false'], default: 'resource|false')] function ftp_connect(string $hostname, int $port = 21, int $timeout = 90) {} /** * Opens a Secure SSL-FTP connection * @link https://php.net/manual/en/function.ftp-ssl-connect.php * @param string $hostname

    * The FTP server address. This parameter shouldn't have any trailing * slashes and shouldn't be prefixed with ftp://. *

    * @param int $port [optional]

    * This parameter specifies an alternate port to connect to. If it is * omitted or set to zero, then the default FTP port, 21, will be used. *

    * @param int $timeout [optional]

    * This parameter specifies the timeout for all subsequent network operations. * If omitted, the default value is 90 seconds. The timeout can be changed and * queried at any time with ftp_set_option and * ftp_get_option. *

    * @return resource|false a SSL-FTP stream on success or FALSE on error. */ #[LanguageLevelTypeAware(['8.1' => 'FTP\Connection|false'], default: 'resource|false')] function ftp_ssl_connect(string $hostname, int $port = 21, int $timeout = 90) {} /** * Logs in to an FTP connection * @link https://php.net/manual/en/function.ftp-login.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $username

    * The username (USER). *

    * @param string $password

    * The password (PASS). *

    * @return bool TRUE on success or FALSE on failure. * If login fails, PHP will also throw a warning. */ function ftp_login(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $username, string $password): bool {} /** * Returns the current directory name * @link https://php.net/manual/en/function.ftp-pwd.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @return string|false the current directory name or FALSE on error. */ function ftp_pwd(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp): string|false {} /** * Changes to the parent directory * @link https://php.net/manual/en/function.ftp-cdup.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @return bool TRUE on success or FALSE on failure. */ function ftp_cdup(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp): bool {} /** * Changes the current directory on a FTP server * @link https://php.net/manual/en/function.ftp-chdir.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $directory

    * The target directory. *

    * @return bool TRUE on success or FALSE on failure. * If changing directory fails, PHP will also throw a warning. */ function ftp_chdir(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $directory): bool {} /** * Requests execution of a command on the FTP server * @link https://php.net/manual/en/function.ftp-exec.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $command

    * The command to execute. *

    * @return bool TRUE if the command was successful (server sent response code: * 200); otherwise returns FALSE. */ function ftp_exec(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $command): bool {} /** * Sends an arbitrary command to an FTP server * @link https://php.net/manual/en/function.ftp-raw.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $command

    * The command to execute. *

    * @return string[] the server's response as an array of strings. * No parsing is performed on the response string, nor does * ftp_raw determine if the command succeeded. */ #[LanguageLevelTypeAware(['8.0' => 'array|null'], default: 'array')] function ftp_raw(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $command) {} /** * Creates a directory * @link https://php.net/manual/en/function.ftp-mkdir.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $directory

    * The name of the directory that will be created. *

    * @return string|false the newly created directory name on success or FALSE on error. */ function ftp_mkdir(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $directory): string|false {} /** * Removes a directory * @link https://php.net/manual/en/function.ftp-rmdir.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $directory

    * The directory to delete. This must be either an absolute or relative * path to an empty directory. *

    * @return bool TRUE on success or FALSE on failure. */ function ftp_rmdir(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $directory): bool {} /** * Set permissions on a file via FTP * @link https://php.net/manual/en/function.ftp-chmod.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param int $permissions

    * The new permissions, given as an octal value. *

    * @param string $filename

    * The remote file. *

    * @return int|false the new file permissions on success or FALSE on error. */ function ftp_chmod(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, int $permissions, string $filename): int|false {} /** * Allocates space for a file to be uploaded * @link https://php.net/manual/en/function.ftp-alloc.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param int $size

    * The number of bytes to allocate. *

    * @param string &$response [optional]

    * A textual representation of the servers response will be returned by * reference in result if a variable is provided. *

    * @return bool TRUE on success or FALSE on failure. */ function ftp_alloc(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, int $size, &$response): bool {} /** * Returns a list of files in the given directory * @link https://php.net/manual/en/function.ftp-nlist.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $directory

    * The directory to be listed. This parameter can also include arguments, eg. * ftp_nlist($conn_id, "-la /your/dir"); * Note that this parameter isn't escaped so there may be some issues with * filenames containing spaces and other characters. *

    * @return string[]|false an array of filenames from the specified directory on success or * FALSE on error. */ function ftp_nlist(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $directory): array|false {} /** * Returns a detailed list of files in the given directory * @link https://php.net/manual/en/function.ftp-rawlist.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $directory

    * The directory path. May include arguments for the LIST * command. *

    * @param bool $recursive [optional]

    * If set to TRUE, the issued command will be LIST -R. *

    * @return string[]|false an array where each element corresponds to one line of text. *

    * The output is not parsed in any way. The system type identifier returned by * ftp_systype can be used to determine how the results * should be interpreted. *

    */ function ftp_rawlist(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $directory, bool $recursive = false): array|false {} /** * Returns the system type identifier of the remote FTP server * @link https://php.net/manual/en/function.ftp-systype.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @return string|false the remote system type, or FALSE on error. */ function ftp_systype(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp): string|false {} /** * Turns passive mode on or off * @link https://php.net/manual/en/function.ftp-pasv.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param bool $enable

    * If TRUE, the passive mode is turned on, else it's turned off. *

    * @return bool TRUE on success or FALSE on failure. */ function ftp_pasv(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, bool $enable): bool {} /** * Downloads a file from the FTP server * @link https://php.net/manual/en/function.ftp-get.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $local_filename

    * The local file path (will be overwritten if the file already exists). *

    * @param string $remote_filename

    * The remote file path. *

    * @param int $mode

    * The transfer mode. Must be either FTP_ASCII or FTP_BINARY. Optional since PHP 7.3 *

    * @param int $offset [optional]

    * The position in the remote file to start downloading from. *

    * @return bool TRUE on success or FALSE on failure. */ function ftp_get( #[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $local_filename, string $remote_filename, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '5.3', to: '7.2')] int $mode, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '7.3')] int $mode = FTP_BINARY, int $offset = 0 ): bool {} /** * Downloads a file from the FTP server and saves to an open file * @link https://php.net/manual/en/function.ftp-fget.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param resource $stream

    * An open file pointer in which we store the data. *

    * @param string $remote_filename

    * The remote file path. *

    * @param int $mode

    * The transfer mode. Must be either FTP_ASCII or FTP_BINARY. Since PHP 7.3 parameter is optional *

    * @param int $offset [optional]

    * The position in the remote file to start downloading from. *

    * @return bool TRUE on success or FALSE on failure. */ function ftp_fget( #[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, $stream, string $remote_filename, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '5.3', to: '7.2')] int $mode, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '7.3')] int $mode = FTP_BINARY, int $offset = 0 ): bool {} /** * Uploads a file to the FTP server * @link https://php.net/manual/en/function.ftp-put.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $remote_filename

    * The remote file path. *

    * @param string $local_filename

    * The local file path. *

    * @param int $mode

    * The transfer mode. Must be either FTP_ASCII or FTP_BINARY. Optional since PHP 7.3 *

    * @param int $offset [optional]

    The position in the remote file to start uploading to.

    * @return bool TRUE on success or FALSE on failure. */ function ftp_put( #[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $remote_filename, string $local_filename, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '5.3', to: '7.2')] int $mode, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '7.3')] int $mode = FTP_BINARY, int $offset = 0 ): bool {} /** * Uploads from an open file to the FTP server * @link https://php.net/manual/en/function.ftp-fput.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $remote_filename

    * The remote file path. *

    * @param resource $stream

    * An open file pointer on the local file. Reading stops at end of file. *

    * @param int $mode

    * The transfer mode. Must be either FTP_ASCII or FTP_BINARY. Optional since PHP 7.3 *

    * @param int $offset [optional]

    The position in the remote file to start uploading to.

    * @return bool TRUE on success or FALSE on failure. */ function ftp_fput( #[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $remote_filename, $stream, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '5.3', to: '7.2')] int $mode, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '7.3')] int $mode = FTP_BINARY, int $offset = 0 ): bool {} /** * Returns the size of the given file * @link https://php.net/manual/en/function.ftp-size.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $filename

    * The remote file. *

    * @return int the file size on success, or -1 on error. */ function ftp_size(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $filename): int {} /** * Returns the last modified time of the given file * @link https://php.net/manual/en/function.ftp-mdtm.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $filename

    * The file from which to extract the last modification time. *

    * @return int the last modified time as a Unix timestamp on success, or -1 on * error. */ function ftp_mdtm(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $filename): int {} /** * Renames a file or a directory on the FTP server * @link https://php.net/manual/en/function.ftp-rename.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $from

    * The old file/directory name. *

    * @param string $to

    * The new name. *

    * @return bool TRUE on success or FALSE on failure. */ function ftp_rename(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $from, string $to): bool {} /** * Deletes a file on the FTP server * @link https://php.net/manual/en/function.ftp-delete.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $filename

    * The file to delete. *

    * @return bool TRUE on success or FALSE on failure. */ function ftp_delete(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $filename): bool {} /** * Sends a SITE command to the server * @link https://php.net/manual/en/function.ftp-site.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $command

    * The SITE command. Note that this parameter isn't escaped so there may * be some issues with filenames containing spaces and other characters. *

    * @return bool TRUE on success or FALSE on failure. */ function ftp_site(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $command): bool {} /** * Closes an FTP connection * @link https://php.net/manual/en/function.ftp-close.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @return bool TRUE on success or FALSE on failure. */ function ftp_close(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp): bool {} /** * Set miscellaneous runtime FTP options * @link https://php.net/manual/en/function.ftp-set-option.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param int $option

    * Currently, the following options are supported: *

    * Supported runtime FTP options * * * * * * * * *
    FTP_TIMEOUT_SEC * Changes the timeout in seconds used for all network related * functions. value must be an integer that * is greater than 0. The default timeout is 90 seconds. *
    FTP_AUTOSEEK * When enabled, GET or PUT requests with a * resumepos or startpos * parameter will first seek to the requested position within the file. * This is enabled by default. *
    *

    * @param mixed $value

    * This parameter depends on which option is chosen * to be altered. *

    * @return bool TRUE if the option could be set; FALSE if not. A warning * message will be thrown if the option is not * supported or the passed value doesn't match the * expected value for the given option. */ function ftp_set_option(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, #[EV(flags: [FTP_TIMEOUT_SEC, FTP_AUTOSEEK, FTP_USEPASVADDRESS])] int $option, $value): bool {} /** * Retrieves various runtime behaviours of the current FTP stream * @link https://php.net/manual/en/function.ftp-get-option.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param int $option

    * Currently, the following options are supported: *

    * Supported runtime FTP options * * * * * * * * *
    FTP_TIMEOUT_SEC * Returns the current timeout used for network related operations. *
    FTP_AUTOSEEK * Returns TRUE if this option is on, FALSE otherwise. *
    *

    * @return int|bool the value on success or FALSE if the given * option is not supported. In the latter case, a * warning message is also thrown. */ function ftp_get_option(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, #[EV(flags: [FTP_TIMEOUT_SEC, FTP_AUTOSEEK])] int $option): int|bool {} /** * Retrieves a file from the FTP server and writes it to an open file (non-blocking) * @link https://php.net/manual/en/function.ftp-nb-fget.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param resource $stream

    * An open file pointer in which we store the data. *

    * @param string $remote_filename

    * The remote file path. *

    * @param int $mode

    * The transfer mode. Must be either FTP_ASCII or FTP_BINARY. Optional since PHP 7.3 *

    * @param int $offset [optional]

    The position in the remote file to start downloading from.

    * @return int FTP_FAILED or FTP_FINISHED * or FTP_MOREDATA. */ #[EV([FTP_FAILED, FTP_FINISHED, FTP_MOREDATA])] function ftp_nb_fget( #[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, $stream, string $remote_filename, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '5.3', to: '7.2')] int $mode, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '7.3')] int $mode = FTP_BINARY, int $offset = 0 ): int {} /** * Retrieves a file from the FTP server and writes it to a local file (non-blocking) * @link https://php.net/manual/en/function.ftp-nb-get.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $local_filename

    * The local file path (will be overwritten if the file already exists). *

    * @param string $remote_filename

    * The remote file path. *

    * @param int $mode

    * The transfer mode. Must be either FTP_ASCII or FTP_BINARY. Optional since PHP 7.3 *

    * @param int $offset [optional]

    The position in the remote file to start downloading from.

    * @return int|false FTP_FAILED or FTP_FINISHED * or FTP_MOREDATA. */ #[EV([FTP_FAILED, FTP_FINISHED, FTP_MOREDATA])] #[LanguageLevelTypeAware(["8.1" => "int|false"], default: "int")] function ftp_nb_get( #[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $local_filename, string $remote_filename, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '5.3', to: '7.2')] int $mode, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '7.3')] int $mode = FTP_BINARY, int $offset = 0 ) {} /** * Continues retrieving/sending a file (non-blocking) * @link https://php.net/manual/en/function.ftp-nb-continue.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @return int FTP_FAILED or FTP_FINISHED * or FTP_MOREDATA. */ #[EV([FTP_FAILED, FTP_FINISHED, FTP_MOREDATA])] function ftp_nb_continue(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp): int {} /** * Stores a file on the FTP server (non-blocking) * @link https://php.net/manual/en/function.ftp-nb-put.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $remote_filename

    * The remote file path. *

    * @param string $local_filename

    * The local file path. *

    * @param int $mode

    * The transfer mode. Must be either FTP_ASCII or FTP_BINARY. Optional since PHP 7.3 *

    * @param int $offset [optional]

    The position in the remote file to start uploading to.

    * @return int|false FTP_FAILED or FTP_FINISHED * or FTP_MOREDATA. */ #[EV([FTP_FAILED, FTP_FINISHED, FTP_MOREDATA])] function ftp_nb_put( #[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $remote_filename, string $local_filename, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '5.3', to: '7.2')] int $mode, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '7.3')] int $mode = FTP_BINARY, int $offset = 0 ): int|false {} /** * Stores a file from an open file to the FTP server (non-blocking) * @link https://php.net/manual/en/function.ftp-nb-fput.php * @param resource $ftp

    * The link identifier of the FTP connection. *

    * @param string $remote_filename

    * The remote file path. *

    * @param resource $stream

    * An open file pointer on the local file. Reading stops at end of file. *

    * @param int $mode

    * The transfer mode. Must be either FTP_ASCII or FTP_BINARY. Optional since PHP 7.3 *

    * @param int $offset [optional]

    The position in the remote file to start uploading to.

    * @return int FTP_FAILED or FTP_FINISHED * or FTP_MOREDATA. */ #[EV([FTP_FAILED, FTP_FINISHED, FTP_MOREDATA])] function ftp_nb_fput( #[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp, string $remote_filename, $stream, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '5.3', to: '7.2')] int $mode, #[EV([FTP_ASCII, FTP_BINARY])] #[PhpStormStubsElementAvailable(from: '7.3')] int $mode = FTP_BINARY, int $offset = 0 ): int {} /** * Alias of ftp_close * @link https://php.net/manual/en/function.ftp-quit.php * @param resource $ftp * @return bool TRUE on success or FALSE on failure. */ function ftp_quit(#[LanguageLevelTypeAware(['8.1' => 'FTP\Connection'], default: 'resource')] $ftp): bool {} /** *

    * @link https://php.net/manual/en/ftp.constants.php */ define('FTP_ASCII', 1); /** *

    * @link https://php.net/manual/en/ftp.constants.php */ define('FTP_TEXT', 1); /** *

    * @link https://php.net/manual/en/ftp.constants.php */ define('FTP_BINARY', 2); /** *

    * @link https://php.net/manual/en/ftp.constants.php */ define('FTP_IMAGE', 2); /** *

    * Automatically determine resume position and start position for GET and PUT requests * (only works if FTP_AUTOSEEK is enabled) *

    * @link https://php.net/manual/en/ftp.constants.php */ define('FTP_AUTORESUME', -1); /** *

    * See ftp_set_option for information. *

    * @link https://php.net/manual/en/ftp.constants.php */ define('FTP_TIMEOUT_SEC', 0); /** *

    * See ftp_set_option for information. *

    * @link https://php.net/manual/en/ftp.constants.php */ define('FTP_AUTOSEEK', 1); define('FTP_USEPASVADDRESS', 2); /** *

    * Asynchronous transfer has failed *

    * @link https://php.net/manual/en/ftp.constants.php */ define('FTP_FAILED', 0); /** *

    * Asynchronous transfer has finished *

    * @link https://php.net/manual/en/ftp.constants.php */ define('FTP_FINISHED', 1); /** *

    * Asynchronous transfer is still active *

    * @link https://php.net/manual/en/ftp.constants.php */ define('FTP_MOREDATA', 2); // End of ftp v. * The Threshold. Lower is more accurate, hence larger file size. *

    * @return void */ function ming_setcubicthreshold($threshold) {} /** * Set the global scaling factor. * @link https://php.net/manual/en/function.ming-setscale.php * @param float $scale

    * The scale to be set. *

    * @return void */ function ming_setscale($scale) {} /** * Sets the SWF version * @link https://php.net/manual/en/function.ming-useswfversion.php * @param int $version

    * SWF version to use. *

    * @return void */ function ming_useswfversion($version) {} /** * Returns the action flag for keyPress(char) * @link https://php.net/manual/en/function.ming-keypress.php * @param string $char * @return int What the function returns, first on success, then on failure. See * also the &return.success; entity */ function ming_keypress($char) {} /** * Use constant pool * @link https://php.net/manual/en/function.ming-useconstants.php * @param int $use

    * Its description *

    * @return void */ function ming_useconstants($use) {} /** * Sets the SWF output compression * @link https://php.net/manual/en/function.ming-setswfcompression.php * @param int $level

    * The new compression level. Should be a value between 1 and 9 * inclusive. *

    * @return void */ function ming_setswfcompression($level) {} define('MING_NEW', 1); define('MING_ZLIB', 1); define('SWFBUTTON_HIT', 8); define('SWFBUTTON_DOWN', 4); define('SWFBUTTON_OVER', 2); define('SWFBUTTON_UP', 1); define('SWFBUTTON_MOUSEUPOUTSIDE', 64); define('SWFBUTTON_DRAGOVER', 160); define('SWFBUTTON_DRAGOUT', 272); define('SWFBUTTON_MOUSEUP', 8); define('SWFBUTTON_MOUSEDOWN', 4); define('SWFBUTTON_MOUSEOUT', 2); define('SWFBUTTON_MOUSEOVER', 1); define('SWFFILL_RADIAL_GRADIENT', 18); define('SWFFILL_LINEAR_GRADIENT', 16); define('SWFFILL_TILED_BITMAP', 64); define('SWFFILL_CLIPPED_BITMAP', 65); define('SWFTEXTFIELD_HASLENGTH', 2); define('SWFTEXTFIELD_NOEDIT', 8); define('SWFTEXTFIELD_PASSWORD', 16); define('SWFTEXTFIELD_MULTILINE', 32); define('SWFTEXTFIELD_WORDWRAP', 64); define('SWFTEXTFIELD_DRAWBOX', 2048); define('SWFTEXTFIELD_NOSELECT', 4096); define('SWFTEXTFIELD_HTML', 512); define('SWFTEXTFIELD_USEFONT', 256); define('SWFTEXTFIELD_AUTOSIZE', 16384); define('SWFTEXTFIELD_ALIGN_LEFT', 0); define('SWFTEXTFIELD_ALIGN_RIGHT', 1); define('SWFTEXTFIELD_ALIGN_CENTER', 2); define('SWFTEXTFIELD_ALIGN_JUSTIFY', 3); define('SWFACTION_ONLOAD', 1); define('SWFACTION_ENTERFRAME', 2); define('SWFACTION_UNLOAD', 4); define('SWFACTION_MOUSEMOVE', 8); define('SWFACTION_MOUSEDOWN', 16); define('SWFACTION_MOUSEUP', 32); define('SWFACTION_KEYDOWN', 64); define('SWFACTION_KEYUP', 128); define('SWFACTION_DATA', 256); define('SWF_SOUND_NOT_COMPRESSED', 0); define('SWF_SOUND_ADPCM_COMPRESSED', 16); define('SWF_SOUND_MP3_COMPRESSED', 32); define('SWF_SOUND_NOT_COMPRESSED_LE', 48); define('SWF_SOUND_NELLY_COMPRESSED', 96); define('SWF_SOUND_5KHZ', 0); define('SWF_SOUND_11KHZ', 4); define('SWF_SOUND_22KHZ', 8); define('SWF_SOUND_44KHZ', 12); define('SWF_SOUND_8BITS', 0); define('SWF_SOUND_16BITS', 2); define('SWF_SOUND_MONO', 0); define('SWF_SOUND_STEREO', 1); // End of ming v. * A Pool is a container for, and controller of, an adjustable number of * Workers.
    * Pooling provides a higher level abstraction of the Worker functionality, * including the management of references in the way required by pthreads. * @link https://secure.php.net/manual/en/class.pool.php */ class Pool { /** * Maximum number of Workers this Pool can use * @var int */ protected $size; /** * The class of the Worker * @var string */ protected $class; /** * The arguments for constructor of new Workers * @var array */ protected $ctor; /** * References to Workers * @var array */ protected $workers; /** * Offset in workers of the last Worker used * @var int */ protected $last; /** * (PECL pthreads >= 2.0.0)
    * Construct a new pool of workers. Pools lazily create their threads, which means * new threads will only be spawned when they are required to execute tasks. * @link https://secure.php.net/manual/en/pool.construct.php * @param int $size

    The maximum number of workers for this pool to create

    * @param string $class [optional]

    The class for new Workers. If no class is * given, then it defaults to the {@link Worker} class.

    * @param array $ctor [optional]

    An array of arguments to be passed to new * Workers

    */ public function __construct(int $size, string $class = 'Worker', array $ctor = []) {} /** * (PECL pthreads >= 2.0.0)
    * Allows the pool to collect references determined to be garbage by the * optionally given collector * @link https://secure.php.net/manual/en/pool.collect.php * @param null|callable $collector [optional]

    A Callable collector that returns a * boolean on whether the task can be collected or not. Only in rare cases should * a custom collector need to be used.

    * @return int

    The number of remaining tasks in the pool to be collected

    */ public function collect(?callable $collector = null) {} /** * (PECL pthreads >= 2.0.0)
    * Resize the Pool * @link https://secure.php.net/manual/en/pool.resize.php * @param int $size

    The maximum number of Workers this Pool can create

    * @return void */ public function resize(int $size) {} /** * (PECL pthreads >= 2.0.0)
    * Shuts down all of the workers in the pool. This will block until all submitted * tasks have been executed. * @link https://secure.php.net/manual/en/pool.shutdown.php * @return void */ public function shutdown() {} /** * (PECL pthreads >= 2.0.0)
    * Submit the task to the next Worker in the Pool * @link https://secure.php.net/manual/en/pool.submit.php * @param Threaded $task

    The task for execution

    * @return int

    the identifier of the Worker executing the object

    */ public function submit(Threaded $task) {} /** * (PECL pthreads >= 2.0.0)
    * Submit a task to the specified worker in the pool. The workers are indexed * from 0, and will only exist if the pool has needed to create them (since * threads are lazily spawned). * @link https://secure.php.net/manual/en/pool.submitTo.php * @param int $worker

    The worker to stack the task onto, indexed from 0

    * @param Threaded $task

    The task for execution

    * @return int

    The identifier of the worker that accepted the task

    */ public function submitTo(int $worker, Threaded $task) {} } /** * Threaded objects form the basis of pthreads ability to execute user code * in parallel; they expose synchronization methods and various useful * interfaces.
    * Threaded objects, most importantly, provide implicit safety for the programmer; * all operations on the object scope are safe. * * @link https://secure.php.net/manual/en/class.threaded.php */ class Threaded implements Collectable, Traversable, Countable, ArrayAccess { /** * Worker object in which this Threaded is being executed * @var Worker */ protected $worker; /** * (PECL pthreads >= 3.0.0)
    * Increments the internal number of references to a Threaded object * @return void */ public function addRef() {} /** * (PECL pthreads >= 2.0.0)
    * Fetches a chunk of the objects property table of the given size, * optionally preserving keys * @link https://secure.php.net/manual/en/threaded.chunk.php * @param int $size

    The number of items to fetch

    * @param bool $preserve [optional]

    Preserve the keys of members, by default false

    * @return array

    An array of items from the objects property table

    */ public function chunk($size, $preserve = false) {} /** * (PECL pthreads >= 2.0.0)
    * Returns the number of properties for this object * @link https://secure.php.net/manual/en/threaded.count.php * @return int

    The number of properties for this object

    */ public function count() {} /** * (PECL pthreads >= 3.0.0)
    * Decrements the internal number of references to a Threaded object * @return void */ public function delRef() {} /** * (PECL pthreads >= 2.0.8)
    * Makes thread safe standard class at runtime * @link https://secure.php.net/manual/en/threaded.extend.php * @param string $class

    The class to extend

    * @return bool

    A boolean indication of success

    */ public static function extend($class) {} /** * (PECL pthreads >= 3.0.0)
    * Retrieves the internal number of references to a Threaded object * @return int

    The number of references to the Threaded object

    */ public function getRefCount() {} /** * (PECL pthreads >= 2.0.0)
    * Tell if the referenced object is executing * @link https://secure.php.net/manual/en/thread.isrunning.php * @return bool

    A boolean indication of state

    */ public function isRunning() {} /** * (PECL pthreads >= 3.1.0)
    * @inheritdoc * @see Collectable::isGarbage() */ public function isGarbage(): bool {} /** * (PECL pthreads >= 2.0.0)
    * Tell if the referenced object was terminated during execution; suffered * fatal errors, or threw uncaught exceptions * @link https://secure.php.net/manual/en/threaded.isterminated.php * @return bool

    A boolean indication of state

    */ public function isTerminated() {} /** * (PECL pthreads >= 2.0.0)
    * Merges data into the current object * @link https://secure.php.net/manual/en/threaded.merge.php * @var mixed

    The data to merge

    * @var bool [optional]

    Overwrite existing keys, by default true

    * @return bool

    A boolean indication of success

    */ public function merge($from, $overwrite = true) {} /** * (PECL pthreads >= 2.0.0)
    * Send notification to the referenced object * @link https://secure.php.net/manual/en/threaded.notify.php * @return bool

    A boolean indication of success

    */ public function notify() {} /** * (PECL pthreads >= 3.0.0)
    * Send notification to the referenced object. This unblocks at least one * of the blocked threads (as opposed to unblocking all of them, as seen with * Threaded::notify()). * @link https://secure.php.net/manual/en/threaded.notifyone.php * @return bool

    A boolean indication of success

    */ public function notifyOne() {} /** * (PECL pthreads >= 2.0.0)
    * Pops an item from the objects property table * @link https://secure.php.net/manual/en/threaded.pop.php * @return mixed

    The last item from the objects property table

    */ public function pop() {} /** * (PECL pthreads >= 2.0.0)
    * The programmer should always implement the run method for objects * that are intended for execution. * @link https://secure.php.net/manual/en/threaded.run.php * @return void */ public function run() {} /** * (PECL pthreads >= 2.0.0)
    * Shifts an item from the objects property table * @link https://secure.php.net/manual/en/threaded.shift.php * @return mixed

    The first item from the objects property table

    */ public function shift() {} /** * (PECL pthreads >= 2.0.0)
    * Executes the block while retaining the referenced objects * synchronization lock for the calling context * @link https://secure.php.net/manual/en/threaded.synchronized.php * @param Closure $block

    The block of code to execute

    * @param mixed ...$_ [optional]

    Variable length list of arguments * to use as function arguments to the block

    * @return mixed

    The return value from the block

    */ public function synchronized(Closure $block, ...$_) {} /** * (PECL pthreads >= 2.0.0)
    * Will cause the calling context to wait for notification from the * referenced object * @link https://secure.php.net/manual/en/threaded.wait.php * @param int $timeout [optional]

    An optional timeout in microseconds

    * @return bool

    A boolean indication of success

    */ public function wait(int $timeout = 0) {} /** * @inheritdoc * @see ArrayAccess::offsetExists() */ public function offsetExists($offset) {} /** * @inheritdoc * @see ArrayAccess::offsetGet() */ public function offsetGet($offset) {} /** * @inheritdoc * @see ArrayAccess::offsetSet() */ public function offsetSet($offset, $value) {} /** * @inheritdoc * @see ArrayAccess::offsetUnset() */ public function offsetUnset($offset) {} } /** * (PECL pthreads >= 2.0.0)
    * When the start method of a Thread is invoked, the run method code will be * executed in separate Thread, in parallel.
    * After the run method is executed the Thread will exit immediately, it will * be joined with the creating Thread at the appropriate time. * * @link https://secure.php.net/manual/en/class.thread.php */ class Thread extends Threaded implements Countable, Traversable, ArrayAccess { /** * (PECL pthreads >= 2.0.0)
    * Will return the identity of the Thread that created the referenced Thread * @link https://secure.php.net/manual/en/thread.getcreatorid.php * @return int

    A numeric identity

    */ public function getCreatorId() {} /** * (PECL pthreads >= 2.0.0)
    * Return a reference to the currently executing Thread * @link https://secure.php.net/manual/en/thread.getcurrentthread.php * @return Thread

    An object representing the currently executing Thread

    */ public static function getCurrentThread() {} /** * (PECL pthreads >= 2.0.0)
    * Will return the identity of the currently executing Thread * @link https://secure.php.net/manual/en/thread.getcurrentthreadid.php * @return int

    A numeric identity

    */ public static function getCurrentThreadId() {} /** * (PECL pthreads >= 2.0.0)
    * Will return the identity of the referenced Thread * @link https://secure.php.net/manual/en/thread.getthreadid.php * @return int

    A numeric identity

    */ public function getThreadId() {} /** * (PECL pthreads >= 2.0.0)
    * Tell if the referenced Thread has been joined * @link https://secure.php.net/manual/en/thread.isjoined.php * @return bool

    A boolean indication of state

    */ public function isJoined() {} /** * (PECL pthreads >= 2.0.0)
    * Tell if the referenced Thread was started * @link https://secure.php.net/manual/en/thread.isstarted.php * @return bool

    A boolean indication of state

    */ public function isStarted() {} /** * (PECL pthreads >= 2.0.0)
    * Causes the calling context to wait for the referenced Thread to finish executing * @link https://secure.php.net/manual/en/thread.join.php * @return bool

    A boolean indication of success

    */ public function join() {} /** * (PECL pthreads >= 2.0.0)
    * Will start a new Thread to execute the implemented run method * @link https://secure.php.net/manual/en/thread.start.php * @param int $options [optional]

    An optional mask of inheritance * constants, by default {@link PTHREADS_INHERIT_ALL}

    * @return bool

    A boolean indication of success

    */ public function start(int $options = PTHREADS_INHERIT_ALL) {} } /** * (PECL pthreads >= 2.0.0)
    * Worker Threads have a persistent context, as such should be used over * Threads in most cases.
    * When a Worker is started, the run method will be executed, but the Thread will * not leave until one of the following conditions are met:
      *
    • the Worker goes out of scope (no more references remain)
    • *
    • the programmer calls shutdown
    • *
    • the script dies
    * This means the programmer can reuse the context throughout execution; placing * objects on the stack of the Worker will cause the Worker to execute the stacked * objects run method. * @link https://secure.php.net/manual/en/class.worker.php */ class Worker extends Thread implements Traversable, Countable, ArrayAccess { /** * (PECL pthreads >= 3.0.0)
    * Allows the worker to collect references determined to be garbage by the * optionally given collector * @link https://secure.php.net/manual/en/worker.collect.php * @param null|callable $collector [optional]

    A Callable collector that returns * a boolean on whether the task can be collected or not. Only in rare cases * should a custom collector need to be used

    * @return int

    The number of remaining tasks on the worker's stack to be * collected

    */ public function collect(?callable $collector = null) {} /** * (PECL pthreads >= 2.0.0)
    * Returns the number of tasks left on the stack * @link https://secure.php.net/manual/en/worker.getstacked.php * @return int

    Returns the number of tasks currently waiting to be * executed by the worker

    */ public function getStacked() {} /** * (PECL pthreads >= 2.0.0)
    * Whether the worker has been shutdown or not * @link https://secure.php.net/manual/en/worker.isshutdown.php * @return bool

    Returns whether the worker has been shutdown or not

    */ public function isShutdown() {} /** * (PECL pthreads >= 2.0.0)
    * Shuts down the Worker after executing all of the stacked tasks * @link https://secure.php.net/manual/en/worker.shutdown.php * @return bool

    Whether the worker was successfully shutdown or not

    */ public function shutdown() {} /** * (PECL pthreads >= 2.0.0)
    * Appends the new work to the stack of the referenced worker * @link https://secure.php.net/manual/en/worker.stack.php * @param Threaded $work

    A Threaded object to be executed by the Worker

    * @return int

    The new size of the stack

    */ public function stack(Threaded $work) {} /** * (PECL pthreads >= 2.0.0)
    * Removes the first task (the oldest one) in the stack * @link https://secure.php.net/manual/en/worker.unstack.php * @return Threaded|null

    The item removed from the stack

    */ public function unstack() {} } /** * (PECL pthreads >= 2.0.8)
    * Represents a garbage-collectable object. * @link https://secure.php.net/manual/en/class.collectable.php */ interface Collectable { /** * (PECL pthreads >= 2.0.8)
    * Can be called in {@link Pool::collect()} to determine if this object is garbage * @link https://secure.php.net/manual/en/collectable.isgarbage.php * @return bool

    Whether this object is garbage or not

    */ public function isGarbage(): bool; } /** * (PECL pthreads >= 3.0.0)
    * The Volatile class is new to pthreads v3. Its introduction is a consequence of * the new immutability semantics of Threaded members of Threaded classes. The * Volatile class enables for mutability of its Threaded members, and is also * used to store PHP arrays in Threaded contexts. * @see Threaded * @link https://secure.php.net/manual/en/class.volatile.php */ class Volatile extends Threaded implements Collectable, Traversable {} * Returns large object's contents * @link https://php.net/manual/en/oci-lob.load.php * @return string|false The contents of the object, or FALSE on errors. */ public function load() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the current position of internal pointer of large object * @link https://php.net/manual/en/oci-lob.tell.php * @return int|false Current position of a LOB's internal pointer or FALSE if an * error occurred. */ public function tell() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Truncates large object * @link https://php.net/manual/en/oci-lob.truncate.php * @param int $length [optional]

    * If provided, this method will truncate the LOB to * length bytes. Otherwise, it will completely * purge the LOB. *

    * @return bool TRUE on success or FALSE on failure. */ public function truncate($length = 0) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Erases a specified portion of the internal LOB data * @link https://php.net/manual/en/oci-lob.erase.php * @param int $offset [optional] * @param int $length [optional] * @return int|false The actual number of characters/bytes erased or FALSE on failure. */ public function erase($offset = null, $length = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Flushes/writes buffer of the LOB to the server * @link https://php.net/manual/en/oci-lob.flush.php * @param int $flag [optional]

    * By default, resources are not freed, but using flag * OCI_LOB_BUFFER_FREE you can do it explicitly. * Be sure you know what you're doing - next read/write operation to the * same part of LOB will involve a round-trip to the server and initialize * new buffer resources. It is recommended to use * OCI_LOB_BUFFER_FREE flag only when you are not * going to work with the LOB anymore. *

    * @return bool TRUE on success or FALSE on failure. *

    *

    * Returns FALSE if buffering was not enabled or an error occurred. */ public function flush($flag = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Changes current state of buffering for the large object * @link https://php.net/manual/en/oci-lob.setbuffering.php * @param bool $on_off

    * TRUE for on and FALSE for off. *

    * @return bool TRUE on success or FALSE on failure. Repeated calls to this method with the same flag will * return TRUE. */ public function setbuffering($on_off) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns current state of buffering for the large object * @link https://php.net/manual/en/oci-lob.getbuffering.php * @return bool FALSE if buffering for the large object is off and TRUE if * buffering is used. */ public function getbuffering() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Moves the internal pointer to the beginning of the large object * @link https://php.net/manual/en/oci-lob.rewind.php * @return bool TRUE on success or FALSE on failure. */ public function rewind() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Reads part of the large object * @link https://php.net/manual/en/oci-lob.read.php * @param int $length

    * The length of data to read, in bytes. Large values will be rounded down to 1 MB. *

    * @return string|false The contents as a string, or FALSE on failure. */ public function read($length) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Tests for end-of-file on a large object's descriptor * @link https://php.net/manual/en/oci-lob.eof.php * @return bool TRUE if internal pointer of large object is at the end of LOB. * Otherwise returns FALSE. */ public function eof() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Sets the internal pointer of the large object * @link https://php.net/manual/en/oci-lob.seek.php * @param int $offset

    * Indicates the amount of bytes, on which internal pointer should be * moved from the position, pointed by whence. *

    * @param int $whence [optional]

    * May be one of: * OCI_SEEK_SET - sets the position equal to * offset * OCI_SEEK_CUR - adds offset * bytes to the current position * OCI_SEEK_END - adds offset * bytes to the end of large object (use negative value to move to a position * before the end of large object) *

    * @return bool TRUE on success or FALSE on failure. */ public function seek($offset, $whence = OCI_SEEK_SET) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Writes data to the large object * @link https://php.net/manual/en/oci-lob.write.php * @param string $data

    * The data to write in the LOB. *

    * @param int $length [optional]

    * If this parameter is given, writing will stop after * length bytes have been written or the end of * data is reached, whichever comes first. *

    * @return int|false The number of bytes written or FALSE on failure. */ public function write($data, $length = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Appends data from the large object to another large object * @link https://php.net/manual/en/oci-lob.append.php * @param OCILob $lob_from

    * The copied LOB. *

    * @return bool TRUE on success or FALSE on failure. */ public function append(OCILob $lob_from) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns size of large object * @link https://php.net/manual/en/oci-lob.size.php * @return int|false Length of large object value or FALSE on failure. * Empty objects have zero length. */ public function size() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Alias of {@see OCILob::export} * @link https://php.net/manual/en/oci-lob.writetofile.php * @param $filename * @param $start [optional] * @param $length [optional] * @return bool TRUE on success or FALSE on failure. */ public function writetofile($filename, $start, $length) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Exports LOB's contents to a file * @link https://php.net/manual/en/oci-lob.export.php * @param string $filename

    * Path to the file. *

    * @param int $start [optional]

    * Indicates from where to start exporting. *

    * @param int $length [optional]

    * Indicates the length of data to be exported. *

    * @return bool TRUE on success or FALSE on failure. */ public function export($filename, $start = null, $length = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Imports file data to the LOB * @link https://php.net/manual/en/oci-lob.import.php * @param string $filename

    * Path to the file. *

    * @return bool TRUE on success or FALSE on failure. */ public function import($filename) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Writes a temporary large object * @link https://php.net/manual/en/oci-lob.writetemporary.php * @param string $data

    * The data to write. *

    * @param int $lob_type [optional]

    * Can be one of the following: * OCI_TEMP_BLOB is used to create temporary BLOBs * OCI_TEMP_CLOB is used to create * temporary CLOBs *

    * @return bool TRUE on success or FALSE on failure. */ public function writeTemporary($data, $lob_type = OCI_TEMP_CLOB) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Closes LOB descriptor * @link https://php.net/manual/en/oci-lob.close.php * @return bool TRUE on success or FALSE on failure. */ public function close() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Saves data to the large object * @link https://php.net/manual/en/oci-lob.save.php * @param string $data

    * The data to be saved. *

    * @param int $offset [optional]

    * Can be used to indicate offset from the beginning of the large object. *

    * @return bool TRUE on success or FALSE on failure. */ public function save($data, $offset = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Alias of {@see OCILob::import} * @link https://php.net/manual/en/oci-lob.savefile.php * @param $filename * @return bool Return true on success and false on failure */ public function savefile($filename) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Frees resources associated with the LOB descriptor * @link https://php.net/manual/en/oci-lob.free.php * @return bool TRUE on success or FALSE on failure. */ public function free() {} } /** * OCI8 Collection functionality. * @link https://php.net/manual/en/class.OCICollection.php * @since 8.0 */ class OCICollection { /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Appends element to the collection * @link https://php.net/manual/en/oci-collection.append.php * @param mixed $value

    * The value to be added to the collection. Can be a string or a number. *

    * @return bool TRUE on success or FALSE on failure. */ public function append($value) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns value of the element * @link https://php.net/manual/en/oci-collection.getelem.php * @param int $index

    * The element index. First index is 0. *

    * @return mixed FALSE if such element doesn't exist; NULL if element is NULL; * string if element is column of a string datatype or number if element is * numeric field. */ public function getelem($index) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Assigns a value to the element of the collection * @link https://php.net/manual/en/oci-collection.assignelem.php * @param int $index

    * The element index. First index is 0. *

    * @param mixed $value

    * Can be a string or a number. *

    * @return bool TRUE on success or FALSE on failure. */ public function assignelem($index, $value) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Assigns a value to the collection from another existing collection * @link https://php.net/manual/en/oci-collection.assign.php * @param OCICollection $from

    * An instance of OCICollection. *

    * @return bool TRUE on success or FALSE on failure. */ public function assign(OCICollection $from) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns size of the collection * @link https://php.net/manual/en/oci-collection.size.php * @return int|false The number of elements in the collection or FALSE on error. */ public function size() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the maximum number of elements in the collection * @link https://php.net/manual/en/oci-collection.max.php * @return int|false The maximum number as an integer, or FALSE on errors. *

    *

    * If the returned value is 0, then the number of elements is not limited. */ public function max() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Trims elements from the end of the collection * @link https://php.net/manual/en/oci-collection.trim.php * @param int $num

    * The number of elements to be trimmed. *

    * @return bool TRUE on success or FALSE on failure. */ public function trim($num) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Frees the resources associated with the collection object * @link https://php.net/manual/en/oci-collection.free.php * @return bool TRUE on success or FALSE on failure. */ public function free() {} } /** * (PHP 7.2 >= 7.2.14, PHP 8, PHP 7 >= 7.3.1, PHP 8, PECL OCI8 >= 2.2.0)
    * Sets a millisecond timeout for database calls * @link https://php.net/manual/en/function.oci-set-call-timout.php * @param resource $connection

    An Oracle connection identifier, * returned by {@see oci_connect}, {@see oci_pconnect}, * or {@see oci_new_connect}.

    * @param int $time_out

    The maximum time in milliseconds that any * single round-trip between PHP and Oracle Database may take. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_set_call_timeout($connection, int $time_out) {} /** * (PHP 7 >== 7.2.14, PHP 8, PHP 7 >= 7.3.1, PHP 8, PECL OCI8 >= 2.2.0) * Sets the database operation * @link https://www.php.net/manual/en/function.oci-set-db-operation.php * @param resource $connection

    An Oracle connection identifier, * returned by {@see oci_connect}, {@see oci_pconnect}, * or {@see oci_new_connect}.

    * @param string $dbop

    User chosen string.

    * @return bool TRUE on success or FALSE on failure. */ function oci_set_db_operation($connection, string $dbop) {} /** * Sets the size of the LOB column that will be prefetched by OCI8 when executing a query. * This can improve performance when working with large LOB data. * * @param resource $statement The OCI8 statement resource. * @param int $prefetch_lob_size The size of the LOB column, in bytes, to be prefetched. * @return bool Returns TRUE on success or FALSE on failure. * @link https://php.net/manual/en/function.oci-set-prefetch-lob.php * @since 8.2 */ function oci_set_prefetch_lob($statement, int $prefetch_lob_size): bool {} * Returns large object's contents * @link https://php.net/manual/en/oci-lob.load.php * @return string|false The contents of the object, or FALSE on errors. */ public function load() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the current position of internal pointer of large object * @link https://php.net/manual/en/oci-lob.tell.php * @return int|false Current position of a LOB's internal pointer or FALSE if an * error occurred. */ public function tell() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Truncates large object * @link https://php.net/manual/en/oci-lob.truncate.php * @param int $length [optional]

    * If provided, this method will truncate the LOB to * length bytes. Otherwise, it will completely * purge the LOB. *

    * @return bool TRUE on success or FALSE on failure. */ public function truncate($length = 0) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Erases a specified portion of the internal LOB data * @link https://php.net/manual/en/oci-lob.erase.php * @param int $offset [optional] * @param int $length [optional] * @return int|false The actual number of characters/bytes erased or FALSE on failure. */ public function erase($offset = null, $length = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Flushes/writes buffer of the LOB to the server * @link https://php.net/manual/en/oci-lob.flush.php * @param int $flag [optional]

    * By default, resources are not freed, but using flag * OCI_LOB_BUFFER_FREE you can do it explicitly. * Be sure you know what you're doing - next read/write operation to the * same part of LOB will involve a round-trip to the server and initialize * new buffer resources. It is recommended to use * OCI_LOB_BUFFER_FREE flag only when you are not * going to work with the LOB anymore. *

    * @return bool TRUE on success or FALSE on failure. *

    *

    * Returns FALSE if buffering was not enabled or an error occurred. */ public function flush($flag = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Changes current state of buffering for the large object * @link https://php.net/manual/en/oci-lob.setbuffering.php * @param bool $on_off

    * TRUE for on and FALSE for off. *

    * @return bool TRUE on success or FALSE on failure. Repeated calls to this method with the same flag will * return TRUE. */ public function setbuffering($on_off) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns current state of buffering for the large object * @link https://php.net/manual/en/oci-lob.getbuffering.php * @return bool FALSE if buffering for the large object is off and TRUE if * buffering is used. */ public function getbuffering() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Moves the internal pointer to the beginning of the large object * @link https://php.net/manual/en/oci-lob.rewind.php * @return bool TRUE on success or FALSE on failure. */ public function rewind() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Reads part of the large object * @link https://php.net/manual/en/oci-lob.read.php * @param int $length

    * The length of data to read, in bytes. Large values will be rounded down to 1 MB. *

    * @return string|false The contents as a string, or FALSE on failure. */ public function read($length) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Tests for end-of-file on a large object's descriptor * @link https://php.net/manual/en/oci-lob.eof.php * @return bool TRUE if internal pointer of large object is at the end of LOB. * Otherwise returns FALSE. */ public function eof() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Sets the internal pointer of the large object * @link https://php.net/manual/en/oci-lob.seek.php * @param int $offset

    * Indicates the amount of bytes, on which internal pointer should be * moved from the position, pointed by whence. *

    * @param int $whence [optional]

    * May be one of: * OCI_SEEK_SET - sets the position equal to * offset * OCI_SEEK_CUR - adds offset * bytes to the current position * OCI_SEEK_END - adds offset * bytes to the end of large object (use negative value to move to a position * before the end of large object) *

    * @return bool TRUE on success or FALSE on failure. */ public function seek($offset, $whence = OCI_SEEK_SET) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Writes data to the large object * @link https://php.net/manual/en/oci-lob.write.php * @param string $data

    * The data to write in the LOB. *

    * @param int $length [optional]

    * If this parameter is given, writing will stop after * length bytes have been written or the end of * data is reached, whichever comes first. *

    * @return int|false The number of bytes written or FALSE on failure. */ public function write($data, $length = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Appends data from the large object to another large object * @link https://php.net/manual/en/oci-lob.append.php * @param OCI_Lob $lob_from

    * The copied LOB. *

    * @return bool TRUE on success or FALSE on failure. */ public function append(#[LanguageLevelTypeAware(['8.0' => 'OCILob'], default: 'OCI_Lob')] $lob_from) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns size of large object * @link https://php.net/manual/en/oci-lob.size.php * @return int|false Length of large object value or FALSE on failure. * Empty objects have zero length. */ public function size() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Alias of {@see OCI_Lob::export} * @link https://php.net/manual/en/oci-lob.writetofile.php * @param $filename * @param $start [optional] * @param $length [optional] * @return bool TRUE on success or FALSE on failure. */ public function writetofile($filename, $start, $length) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Exports LOB's contents to a file * @link https://php.net/manual/en/oci-lob.export.php * @param string $filename

    * Path to the file. *

    * @param int $start [optional]

    * Indicates from where to start exporting. *

    * @param int $length [optional]

    * Indicates the length of data to be exported. *

    * @return bool TRUE on success or FALSE on failure. */ public function export($filename, $start = null, $length = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Imports file data to the LOB * @link https://php.net/manual/en/oci-lob.import.php * @param string $filename

    * Path to the file. *

    * @return bool TRUE on success or FALSE on failure. */ public function import($filename) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Writes a temporary large object * @link https://php.net/manual/en/oci-lob.writetemporary.php * @param string $data

    * The data to write. *

    * @param int $lob_type [optional]

    * Can be one of the following: * OCI_TEMP_BLOB is used to create temporary BLOBs * OCI_TEMP_CLOB is used to create * temporary CLOBs *

    * @return bool TRUE on success or FALSE on failure. */ public function writeTemporary($data, $lob_type = OCI_TEMP_CLOB) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Closes LOB descriptor * @link https://php.net/manual/en/oci-lob.close.php * @return bool TRUE on success or FALSE on failure. */ public function close() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Saves data to the large object * @link https://php.net/manual/en/oci-lob.save.php * @param string $data

    * The data to be saved. *

    * @param int $offset [optional]

    * Can be used to indicate offset from the beginning of the large object. *

    * @return bool TRUE on success or FALSE on failure. */ public function save($data, $offset = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Alias of {@see OCI_Lob::import} * @link https://php.net/manual/en/oci-lob.savefile.php * @param $filename * @return bool Return true on success and false on failure */ public function savefile($filename) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Frees resources associated with the LOB descriptor * @link https://php.net/manual/en/oci-lob.free.php * @return bool TRUE on success or FALSE on failure. */ public function free() {} } /** * OCI8 Collection functionality. * @link https://php.net/manual/en/class.OCI-Collection.php * @removed 8.0 */ class OCI_Collection { /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Appends element to the collection * @link https://php.net/manual/en/oci-collection.append.php * @param mixed $value

    * The value to be added to the collection. Can be a string or a number. *

    * @return bool TRUE on success or FALSE on failure. */ public function append($value) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns value of the element * @link https://php.net/manual/en/oci-collection.getelem.php * @param int $index

    * The element index. First index is 0. *

    * @return mixed FALSE if such element doesn't exist; NULL if element is NULL; * string if element is column of a string datatype or number if element is * numeric field. */ public function getelem($index) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Assigns a value to the element of the collection * @link https://php.net/manual/en/oci-collection.assignelem.php * @param int $index

    * The element index. First index is 0. *

    * @param mixed $value

    * Can be a string or a number. *

    * @return bool TRUE on success or FALSE on failure. */ public function assignelem($index, $value) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Assigns a value to the collection from another existing collection * @link https://php.net/manual/en/oci-collection.assign.php * @param OCI_Collection $from

    * An instance of OCI-Collection. *

    * @return bool TRUE on success or FALSE on failure. */ public function assign(#[LanguageLevelTypeAware(['8.0' => 'OCICollection'], default: 'OCI_Collection')] $from) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns size of the collection * @link https://php.net/manual/en/oci-collection.size.php * @return int|false The number of elements in the collection or FALSE on error. */ public function size() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the maximum number of elements in the collection * @link https://php.net/manual/en/oci-collection.max.php * @return int|false The maximum number as an integer, or FALSE on errors. *

    *

    * If the returned value is 0, then the number of elements is not limited. */ public function max() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Trims elements from the end of the collection * @link https://php.net/manual/en/oci-collection.trim.php * @param int $num

    * The number of elements to be trimmed. *

    * @return bool TRUE on success or FALSE on failure. */ public function trim($num) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Frees the resources associated with the collection object * @link https://php.net/manual/en/oci-collection.free.php * @return bool TRUE on success or FALSE on failure. */ public function free() {} } /** * Register a user-defined callback function for Oracle Database TAF. * @link https://www.php.net/manual/en/function.oci-register-taf-callback.php * @param resource $connection

    * An Oracle connection identifier. *

    * @param mixed $callbackFn [optional]

    * A user-defined callback to register for Oracle TAF. It can be a string of the function name or a Closure (anonymous function).
    * The interface of a TAF user-defined callback function is as follows:
    * userCallbackFn ( resource $connection , int $event , int $type ) : int
    * See the parameter description and an example on OCI8 Transparent Application Failover (TAF) Support page. *

    * @return bool TRUE on success or FALSE on failure. * @since 7.2 */ function oci_register_taf_callback($connection, $callbackFn) {} /** * Unregister a user-defined callback function for Oracle Database TAF. * @link https://www.php.net/manual/en/function.oci-unregister-taf-callback.php * @param resource $connection

    * An Oracle connection identifier. *

    * @return bool TRUE on success or FALSE on failure. * @since 7.2 */ function oci_unregister_taf_callback($connection) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Associates a PHP variable with a column for query fetches * @link https://php.net/manual/en/function.oci-define-by-name.php * @param resource $statement

    A valid OCI8 statement * identifier created by {@see oci_parse} and executed * by {@see oci_execute}, or a REF * CURSOR statement identifier.

    * @param string $column_name

    * The column name used in the query. *

    *

    * Use uppercase for Oracle's default, non-case sensitive column * names. Use the exact column name case for case-sensitive * column names. *

    * @param mixed &$variable

    * The PHP variable that will contain the returned column value. *

    * @param int $type [optional]

    * The data type to be returned. Generally not needed. Note that * Oracle-style data conversions are not performed. For example, * SQLT_INT will be ignored and the returned * data type will still be SQLT_CHR. *

    *

    * You can optionally use {@see oci_new_descriptor} * to allocate LOB/ROWID/BFILE descriptors. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_define_by_name($statement, $column_name, &$variable, $type = SQLT_CHR) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Binds a PHP variable to an Oracle placeholder * @link https://php.net/manual/en/function.oci-bind-by-name.php * @param resource $statement

    * A valid OCI8 statement identifier. *

    * @param string $bv_name

    * The colon-prefixed bind variable placeholder used in the * statement. The colon is optional * in bv_name. Oracle does not use question * marks for placeholders. *

    * @param mixed &$variable

    * The PHP variable to be associated with bv_name *

    * @param int $maxlength [optional]

    * Sets the maximum length for the data. If you set it to -1, this * function will use the current length * of variable to set the maximum * length. In this case the variable must * exist and contain data * when {@see oci_bind_by_name} is called. *

    * @param int $type [optional]

    * The datatype that Oracle will treat the data as. The * default type used * is SQLT_CHR. Oracle will convert the data * between this type and the database column (or PL/SQL variable * type), when possible. *

    *

    * If you need to bind an abstract datatype (LOB/ROWID/BFILE) you * need to allocate it first using the * {@see oci_new_descriptor} function. The * length is not used for abstract datatypes * and should be set to -1. *

    *

    * Possible values for type are: *

    *

    * SQLT_BFILEE or OCI_B_BFILE * - for BFILEs; *

    * @return bool TRUE on success or FALSE on failure. */ function oci_bind_by_name($statement, $bv_name, &$variable, $maxlength = -1, $type = SQLT_CHR) {} /** * (PHP 5 >= 5.1.2, PECL OCI8 >= 1.2.0)
    * Binds a PHP array to an Oracle PL/SQL array parameter * @link https://php.net/manual/en/function.oci-bind-array-by-name.php * @param resource $statement

    * A valid OCI statement identifier. *

    * @param string $name

    * The Oracle placeholder. *

    * @param array &$var_array

    * An array. *

    * @param int $max_table_length

    * Sets the maximum length both for incoming and result arrays. *

    * @param int $max_item_length [optional]

    * Sets maximum length for array items. If not specified or equals to -1, * {@see oci_bind_array_by_name} will find the longest * element in the incoming array and will use it as the maximum length. *

    * @param int $type [optional]

    * Should be used to set the type of PL/SQL array items. See list of * available types below: *

    *

    * SQLT_NUM - for arrays of NUMBER. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_bind_array_by_name($statement, $name, array &$var_array, $max_table_length, $max_item_length = -1, $type = SQLT_AFC) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Checks if a field in the currently fetched row NULL * @link https://php.net/manual/en/function.oci-field-is-null.php * @param resource $statement

    * A valid OCI statement identifier. *

    * @param mixed $field

    * Can be a field's index or a field's name (uppercased). *

    * @return bool TRUE if field is NULL, FALSE otherwise. */ function oci_field_is_null($statement, $field) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the name of a field from the statement * @link https://php.net/manual/en/function.oci-field-name.php * @param resource $statement

    * A valid OCI statement identifier. *

    * @param string|int $field

    * Can be the field's index (1-based) or name. *

    * @return string|false The name as a string, or FALSE on errors. */ function oci_field_name($statement, $field) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns field's size * @link https://php.net/manual/en/function.oci-field-size.php * @param resource $statement

    * A valid OCI statement identifier. *

    * @param mixed $field

    * Can be the field's index (1-based) or name. *

    * @return int|false The size of a field in bytes, or FALSE on * errors. */ function oci_field_size($statement, $field) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Tell the scale of the field * @link https://php.net/manual/en/function.oci-field-scale.php * @param resource $statement

    * A valid OCI statement identifier. *

    * @param string|int $field

    * Can be the field's index (1-based) or name. *

    * @return int|false The scale as an integer, or FALSE on errors. */ function oci_field_scale($statement, $field) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Tell the precision of a field * @link https://php.net/manual/en/function.oci-field-precision.php * @param resource $statement

    * A valid OCI statement identifier. *

    * @param string|int $field

    * Can be the field's index (1-based) or name. *

    * @return int|false The precision as an integer, or FALSE on errors. */ function oci_field_precision($statement, $field) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns field's data type * @link https://php.net/manual/en/function.oci-field-type.php * @param resource $statement

    * A valid OCI statement identifier. *

    * @param string|int $field

    * Can be the field's index (1-based) or name. *

    * @return mixed the field data type as a string, or FALSE on errors. */ function oci_field_type($statement, $field) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Tell the raw Oracle data type of the field * @link https://php.net/manual/en/function.oci-field-type-raw.php * @param resource $statement

    * A valid OCI statement identifier. *

    * @param int $field

    * Can be the field's index (1-based) or name. *

    * @return int|false Oracle's raw data type as a string, or FALSE on errors. */ function oci_field_type_raw($statement, $field) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Executes a statement * @link https://php.net/manual/en/function.oci-execute.php * @param resource $statement

    * A valid OCI statement identifier. *

    * @param int $mode [optional]

    * An optional second parameter can be one of the following constants: *

    * Execution Modes * * * * * * * * * * * * * * * * *
    ConstantDescription
    OCI_COMMIT_ON_SUCCESSAutomatically commit all outstanding changes for * this connection when the statement has succeeded. This * is the default.
    OCI_DESCRIBE_ONLYMake query meta data available to functions * like {@see oci_field_name} but do not * create a result set. Any subsequent fetch call such * as {@see oci_fetch_array} will * fail.
    OCI_NO_AUTO_COMMITDo not automatically commit changes. Prior to PHP * 5.3.2 (PECL OCI8 1.4) * use OCI_DEFAULT which is equivalent * to OCI_NO_AUTO_COMMIT.
    *

    *

    * Using OCI_NO_AUTO_COMMIT mode starts or continues a * transaction. Transactions are automatically rolled back when * the connection is closed, or when the script ends. Explicitly * call {@see oci_commit} to commit a transaction, * or {@see oci_rollback} to abort it. *

    *

    * When inserting or updating data, using transactions is * recommended for relational data consistency and for performance * reasons. *

    *

    * If OCI_NO_AUTO_COMMIT mode is used for any * statement including queries, and * {@see oci_commit} * or {@see oci_rollback} is not subsequently * called, then OCI8 will perform a rollback at the end of the * script even if no data was changed. To avoid an unnecessary * rollback, many scripts do not * use OCI_NO_AUTO_COMMIT mode for queries or * PL/SQL. Be careful to ensure the appropriate transactional * consistency for the application when * using {@see oci_execute} with different modes in * the same script. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_execute($statement, $mode = OCI_COMMIT_ON_SUCCESS) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Cancels reading from cursor * @link https://php.net/manual/en/function.oci-cancel.php * @param resource $statement

    * An OCI statement. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_cancel($statement) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Fetches the next row from a query into internal buffers * @link https://php.net/manual/en/function.oci-fetch.php * @param resource $statement

    A valid OCI8 statement * identifier created by {@see oci_parse} and executed * by {@see oci_execute}, or a REF * CURSOR statement identifier.

    * @return bool TRUE on success or FALSE if there are no more rows in the * statement. */ function oci_fetch($statement) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the next row from a query as an object * @link https://php.net/manual/en/function.oci-fetch-object.php * @param resource $statement

    A valid OCI8 statement * identifier created by {@see oci_parse} and executed * by {@see oci_execute}, or a REF * CURSOR statement identifier.

    * @return object|false

    An object. Each attribute of the object corresponds to a * column of the row. If there are no more rows in * the statement then FALSE is returned. *

    *

    * Any LOB columns are returned as LOB descriptors. *

    *

    * DATE columns are returned as strings formatted * to the current date format. The default format can be changed with * Oracle environment variables such as NLS_LANG or * by a previously executed ALTER SESSION SET * NLS_DATE_FORMAT command. *

    *

    * Oracle's default, non-case sensitive column names will have * uppercase attribute names. Case-sensitive column names will have * attribute names using the exact column case. * Use var_dump on the result object to verify * the appropriate case for attribute access. *

    *

    * Attribute values will be NULL for any NULL * data fields. *

    */ function oci_fetch_object($statement) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the next row from a query as a numeric array * @link https://php.net/manual/en/function.oci-fetch-row.php * @param resource $statement

    A valid OCI8 statement * identifier created by {@see oci_parse} and executed * by {@see oci_execute}, or a REF * CURSOR statement identifier.

    * @return array|false A numerically indexed array. If there are no more rows in * the statement then FALSE is returned. */ function oci_fetch_row($statement) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the next row from a query as an associative array * @link https://php.net/manual/en/function.oci-fetch-assoc.php * @param resource $statement

    A valid OCI8 statement * identifier created by {@see oci_parse} and executed * by {@see oci_execute}, or a REF * CURSOR statement identifier.

    * @return array|false An associative array. If there are no more rows in * the statement then FALSE is returned. */ function oci_fetch_assoc($statement) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the next row from a query as an associative or numeric array * @link https://php.net/manual/en/function.oci-fetch-array.php * @param resource $statement

    A valid OCI8 statement * identifier created by {@see oci_parse} and executed * by {@see oci_execute}, or a REF * CURSOR statement identifier.

    *

    * Can also be a statement identifier returned by {@see oci_get_implicit_resultset}. *

    * @param int $mode [optional]

    * An optional second parameter can be any combination of the following * constants: *

    * {@see oci_fetch_array} Modes * * * * * * * * * * * * * * * * * * * * * * * * *
    ConstantDescription
    OCI_BOTHReturns an array with both associative and numeric * indices. This is the same * as OCI_ASSOC * + OCI_NUM and is the default * behavior.
    OCI_ASSOCReturns an associative array.
    OCI_NUMReturns a numeric array.
    OCI_RETURN_NULLSCreates elements for NULL fields. The element * values will be a PHP NULL. *
    OCI_RETURN_LOBSReturns the contents of LOBs instead of the LOB * descriptors.
    *

    *

    * The default mode is OCI_BOTH. *

    *

    * Use the addition operator "+" to specify more than * one mode at a time. *

    * @return array|false

    An array with associative and/or numeric indices. If there * are no more rows in the statement then * FALSE is returned. *

    *

    * By default, LOB columns are returned as LOB descriptors. *

    *

    * DATE columns are returned as strings formatted * to the current date format. The default format can be changed with * Oracle environment variables such as NLS_LANG or * by a previously executed ALTER SESSION SET * NLS_DATE_FORMAT command. *

    *

    * Oracle's default, non-case sensitive column names will have * uppercase associative indices in the result array. Case-sensitive * column names will have array indices using the exact column case. * Use var_dump on the result array to verify the * appropriate case to use for each query. *

    *

    * The table name is not included in the array index. If your query * contains two different columns with the same name, * use OCI_NUM or add a column alias to the query * to ensure name uniqueness, see example #7. Otherwise only one * column will be returned via PHP. *

    */ function oci_fetch_array($statement, $mode = null) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Obsolete variant of {@see oci_fetch_array}, {@see oci_fetch_object}, * {@see oci_fetch_assoc} and * {@see oci_fetch_row} * @link https://php.net/manual/en/function.ocifetchinto.php * @param resource $statement_resource * @param array &$result * @param int $mode [optional] * @return int|bool */ #[Deprecated(since: "5.4")] function ocifetchinto($statement_resource, &$result, $mode = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Fetches multiple rows from a query into a two-dimensional array * @link https://php.net/manual/en/function.oci-fetch-all.php * @param resource $statement

    A valid OCI8 statement * identifier created by {@see oci_parse} and executed * by {@see oci_execute}, or a REF * CURSOR statement identifier.

    * @param array &$output

    * The variable to contain the returned rows. *

    *

    * LOB columns are returned as strings, where Oracle supports * conversion. *

    *

    * See {@see oci_fetch_array} for more information * on how data and types are fetched. *

    * @param int $skip [optional]

    * The number of initial rows to discard when fetching the * result. The default value is 0, so the first row onwards is * returned. *

    * @param int $maxrows [optional]

    * The number of rows to return. The default is -1 meaning return * all the rows from skip + 1 onwards. *

    * @param int $flags [optional]

    * Parameter flags indicates the array * structure and whether associative arrays should be used. *

    * {@see oci_fetch_all} Array Structure Modes * * * * * * * * * * * * *
    ConstantDescription
    OCI_FETCHSTATEMENT_BY_ROWThe outer array will contain one sub-array per query * row.
    OCI_FETCHSTATEMENT_BY_COLUMNThe outer array will contain one sub-array per query * column. This is the default.
    *

    *

    * Arrays can be indexed by column heading or numerically. *

    * {@see oci_fetch_all} Array Index Modes * * * * * * * * * * * * *
    ConstantDescription
    OCI_NUMNumeric indexes are used for each column's array.
    OCI_ASSOCAssociative indexes are used for each column's * array. This is the default.
    *

    *

    * Use the addition operator "+" to choose a combination * of array structure and index modes. *

    *

    * Oracle's default, non-case sensitive column names will have * uppercase array keys. Case-sensitive column names will have * array keys using the exact column case. * Use var_dump * on output to verify the appropriate case * to use for each query. *

    *

    * Queries that have more than one column with the same name * should use column aliases. Otherwise only one of the columns * will appear in an associative array. *

    * @return int|false The number of rows in output, which * may be 0 or more, or FALSE on failure. */ function oci_fetch_all($statement, array &$output, $skip = 0, $maxrows = -1, $flags = OCI_FETCHSTATEMENT_BY_COLUMN|OCI_ASSOC) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Frees all resources associated with statement or cursor * @link https://php.net/manual/en/function.oci-free-statement.php * @param resource $statement

    * A valid OCI statement identifier. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_free_statement($statement) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Enables or disables internal debug output * @link https://php.net/manual/en/function.oci-internal-debug.php * @param bool $onoff

    * Set this to FALSE to turn debug output off or TRUE to turn it on. *

    * @removed 8.0 * @return void No value is returned. */ function oci_internal_debug($onoff) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the number of result columns in a statement * @link https://php.net/manual/en/function.oci-num-fields.php * @param resource $statement

    * A valid OCI statement identifier. *

    * @return int|false The number of columns as an integer, or FALSE on errors. */ function oci_num_fields($statement) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Prepares an Oracle statement for execution * @link https://php.net/manual/en/function.oci-parse.php * @param resource $connection

    * An Oracle connection identifier, returned by * {@see oci_connect}, {@see oci_pconnect}, or {@see oci_new_connect}. *

    * @param string $sql_text

    * The SQL or PL/SQL statement. *

    *

    * SQL statements should not end with a * semi-colon (";"). PL/SQL * statements should end with a semi-colon * (";"). *

    * @return resource|false A statement handle on success, or FALSE on error. */ function oci_parse($connection, $sql_text) {} /** * (PECL OCI8 >= 2.0.0)
    * Returns the next child statement resource from a parent statement resource that has Oracle Database 12c Implicit Result Sets * @link https://php.net/manual/en/function.oci-get-implicit-resultset.php * @param resource $statement

    A valid OCI8 statement identifier created * by {@see oci_parse} and executed * by {@see oci_execute}. The statement * identifier may or may not be associated with a SQL statement * that returns Implicit Result Sets. *

    * @return resource|false A statement handle for the next child statement available * on statement. Returns FALSE when child * statements do not exist, or all child statements have been returned * by previous calls * to {@see oci_get_implicit_resultset}. */ function oci_get_implicit_resultset($statement) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Allocates and returns a new cursor (statement handle) * @link https://php.net/manual/en/function.oci-new-cursor.php * @param resource $connection

    * An Oracle connection identifier, returned by * {@see oci_connect} or {@see oci_pconnect}. *

    * @return resource|false A new statement handle, or FALSE on error. */ function oci_new_cursor($connection) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns field's value from the fetched row * @link https://php.net/manual/en/function.oci-result.php * @param resource $statement * @param mixed $field

    * Can be either use the column number (1-based) or the column name. * The case of the column name must be the case that Oracle meta data * describes the column as, which is uppercase for columns created * case insensitively. *

    * @return mixed everything as strings except for abstract types (ROWIDs, LOBs and * FILEs). Returns FALSE on error. */ function oci_result($statement, $field) {} /** * (PHP 5.3.7, PECL OCI8 >= 1.4.6)
    * Returns the Oracle client library version * @link https://php.net/manual/en/function.oci-client-version.php * @return string the version number as a string. */ function oci_client_version() {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the Oracle Database version * @link https://php.net/manual/en/function.oci-server-version.php * @param resource $connection * @return string|false The version information as a string or FALSE on error. */ function oci_server_version($connection) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the type of a statement * @link https://php.net/manual/en/function.oci-statement-type.php * @param resource $statement

    * A valid OCI8 statement identifier from {@see oci_parse}. *

    * @return string|false The type of statement as one of the * following strings. * * Statement type * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    Return StringNotes
    ALTER
    BEGIN
    CALLIntroduced in PHP 5.2.1 (PECL OCI8 1.2.3)
    CREATE
    DECLARE
    DELETE
    DROP
    INSERT
    SELECT
    UPDATE
    UNKNOWN
    *

    *

    * Returns FALSE on error. */ function oci_statement_type($statement) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns number of rows affected during statement execution * @link https://php.net/manual/en/function.oci-num-rows.php * @param resource $statement

    * A valid OCI statement identifier. *

    * @return int|false The number of rows affected as an integer, or FALSE on errors. */ function oci_num_rows($statement) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Closes an Oracle connection * @link https://php.net/manual/en/function.oci-close.php * @param resource $connection

    * An Oracle connection identifier returned by * {@see oci_connect}, {@see oci_pconnect}, * or {@see oci_new_connect}. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_close($connection) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Connect to an Oracle database * @link https://php.net/manual/en/function.oci-connect.php * @param string $username

    * The Oracle user name. *

    * @param string $password

    * The password for username. *

    * @param string $connection_string [optional]

    Contains * the Oracle instance to connect to. It can be * an Easy Connect * string, or a Connect Name from * the tnsnames.ora file, or the name of a local * Oracle instance. *

    *

    * If not specified, PHP uses * environment variables such as TWO_TASK (on Linux) * or LOCAL (on Windows) * and ORACLE_SID to determine the * Oracle instance to connect to. *

    *

    * To use the Easy Connect naming method, PHP must be linked with Oracle * 10g or greater Client libraries. The Easy Connect string for Oracle * 10g is of the form: * [//]host_name[:port][/service_name]. From Oracle * 11g, the syntax is: * [//]host_name[:port][/service_name][:server_type][/instance_name]. * Service names can be found by running the Oracle * utility lsnrctl status on the database server * machine. *

    *

    * The tnsnames.ora file can be in the Oracle Net * search path, which * includes $ORACLE_HOME/network/admin * and /etc. Alternatively * set TNS_ADMIN so * that $TNS_ADMIN/tnsnames.ora is read. Make sure * the web daemon has read access to the file. *

    * @param string $character_set [optional]

    Determines * the character set used by the Oracle Client libraries. The character * set does not need to match the character set used by the database. If * it doesn't match, Oracle will do its best to convert data to and from * the database character set. Depending on the character sets this may * not give usable results. Conversion also adds some time overhead. *

    *

    * If not specified, the * Oracle Client libraries determine a character set from * the NLS_LANG environment variable. *

    *

    * Passing this parameter can * reduce the time taken to connect. *

    *

    * @param int $session_mode [optional] This * parameter is available since version PHP 5 (PECL OCI8 1.1) and accepts the * following values: OCI_DEFAULT, * OCI_SYSOPER and OCI_SYSDBA. * If either OCI_SYSOPER or * OCI_SYSDBA were specified, this function will try * to establish privileged connection using external credentials. * Privileged connections are disabled by default. To enable them you * need to set oci8.privileged_connect * to On. *

    *

    * PHP 5.3 (PECL OCI8 1.3.4) introduced the * OCI_CRED_EXT mode value. This tells Oracle to use * External or OS authentication, which must be configured in the * database. The OCI_CRED_EXT flag can only be used * with username of "/" and a empty password. * oci8.privileged_connect * may be On or Off. *

    *

    * OCI_CRED_EXT may be combined with the * OCI_SYSOPER or * OCI_SYSDBA modes. *

    *

    * OCI_CRED_EXT is not supported on Windows for * security reasons. *

    * @return resource|false A connection identifier or FALSE on error. */ function oci_connect($username, $password, $connection_string = null, $character_set = null, $session_mode = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Connect to the Oracle server using a unique connection * @link https://php.net/manual/en/function.oci-new-connect.php * @param string $username

    * The Oracle user name. *

    * @param string $password

    * The password for username. *

    * @param string $connection_string [optional]

    Contains * the Oracle instance to connect to. It can be * an Easy Connect * string, or a Connect Name from * the tnsnames.ora file, or the name of a local * Oracle instance. *

    *

    * If not specified, PHP uses * environment variables such as TWO_TASK (on Linux) * or LOCAL (on Windows) * and ORACLE_SID to determine the * Oracle instance to connect to. *

    *

    * To use the Easy Connect naming method, PHP must be linked with Oracle * 10g or greater Client libraries. The Easy Connect string for Oracle * 10g is of the form: * [//]host_name[:port][/service_name]. From Oracle * 11g, the syntax is: * [//]host_name[:port][/service_name][:server_type][/instance_name]. * Service names can be found by running the Oracle * utility lsnrctl status on the database server * machine. *

    *

    * The tnsnames.ora file can be in the Oracle Net * search path, which * includes $ORACLE_HOME/network/admin * and /etc. Alternatively * set TNS_ADMIN so * that $TNS_ADMIN/tnsnames.ora is read. Make sure * the web daemon has read access to the file. *

    * @param string $character_set [optional]

    Determines * the character set used by the Oracle Client libraries. The character * set does not need to match the character set used by the database. If * it doesn't match, Oracle will do its best to convert data to and from * the database character set. Depending on the character sets this may * not give usable results. Conversion also adds some time overhead. *

    *

    * If not specified, the * Oracle Client libraries determine a character set from * the NLS_LANG environment variable. *

    *

    * Passing this parameter can * reduce the time taken to connect. *

    * @param int $session_mode [optional]

    This * parameter is available since version PHP 5 (PECL OCI8 1.1) and accepts the * following values: OCI_DEFAULT, * OCI_SYSOPER and OCI_SYSDBA. * If either OCI_SYSOPER or * OCI_SYSDBA were specified, this function will try * to establish privileged connection using external credentials. * Privileged connections are disabled by default. To enable them you * need to set oci8.privileged_connect * to On. *

    *

    * PHP 5.3 (PECL OCI8 1.3.4) introduced the * OCI_CRED_EXT mode value. This tells Oracle to use * External or OS authentication, which must be configured in the * database. The OCI_CRED_EXT flag can only be used * with username of "/" and a empty password. * oci8.privileged_connect * may be On or Off. *

    *

    * OCI_CRED_EXT may be combined with the * OCI_SYSOPER or * OCI_SYSDBA modes. *

    *

    * OCI_CRED_EXT is not supported on Windows for * security reasons. *

    * @return resource|false A connection identifier or FALSE on error. */ function oci_new_connect($username, $password, $connection_string = null, $character_set = null, $session_mode = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Connect to an Oracle database using a persistent connection * @link https://php.net/manual/en/function.oci-pconnect.php * @param string $username

    * The Oracle user name. *

    * @param string $password

    * The password for username. *

    * @param string $connection_string [optional]

    Contains * the Oracle instance to connect to. It can be * an Easy Connect * string, or a Connect Name from * the tnsnames.ora file, or the name of a local * Oracle instance. *

    *

    * If not specified, PHP uses * environment variables such as TWO_TASK (on Linux) * or LOCAL (on Windows) * and ORACLE_SID to determine the * Oracle instance to connect to. *

    *

    * To use the Easy Connect naming method, PHP must be linked with Oracle * 10g or greater Client libraries. The Easy Connect string for Oracle * 10g is of the form: * [//]host_name[:port][/service_name]. From Oracle * 11g, the syntax is: * [//]host_name[:port][/service_name][:server_type][/instance_name]. * Service names can be found by running the Oracle * utility lsnrctl status on the database server * machine. *

    *

    * The tnsnames.ora file can be in the Oracle Net * search path, which * includes $ORACLE_HOME/network/admin * and /etc. Alternatively * set TNS_ADMIN so * that $TNS_ADMIN/tnsnames.ora is read. Make sure * the web daemon has read access to the file. *

    * @param string $character_set [optional]

    Determines * the character set used by the Oracle Client libraries. The character * set does not need to match the character set used by the database. If * it doesn't match, Oracle will do its best to convert data to and from * the database character set. Depending on the character sets this may * not give usable results. Conversion also adds some time overhead. *

    *

    * If not specified, the * Oracle Client libraries determine a character set from * the NLS_LANG environment variable. *

    *

    * Passing this parameter can * reduce the time taken to connect. *

    * @param int $session_mode [optional]

    This * parameter is available since version PHP 5 (PECL OCI8 1.1) and accepts the * following values: OCI_DEFAULT, * OCI_SYSOPER and OCI_SYSDBA. * If either OCI_SYSOPER or * OCI_SYSDBA were specified, this function will try * to establish privileged connection using external credentials. * Privileged connections are disabled by default. To enable them you * need to set oci8.privileged_connect * to On. *

    *

    * PHP 5.3 (PECL OCI8 1.3.4) introduced the * OCI_CRED_EXT mode value. This tells Oracle to use * External or OS authentication, which must be configured in the * database. The OCI_CRED_EXT flag can only be used * with username of "/" and a empty password. * oci8.privileged_connect * may be On or Off. *

    *

    * OCI_CRED_EXT may be combined with the * OCI_SYSOPER or * OCI_SYSDBA modes. *

    *

    * OCI_CRED_EXT is not supported on Windows for * security reasons. *

    * @return resource|false A connection identifier or FALSE on error. */ function oci_pconnect($username, $password, $connection_string = null, $character_set = null, $session_mode = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Returns the last error found * @link https://php.net/manual/en/function.oci-error.php * @param resource $resource [optional]

    * For most errors, resource is the * resource handle that was passed to the failing function call. * For connection errors with {@see oci_connect}, * {@see oci_new_connect} or * {@see oci_pconnect} do not pass resource. *

    * @return array|false If no error is found, {@see oci_error} returns * FALSE. Otherwise, {@see oci_error} returns the * error information as an associative array. *

    *

    *

    * {@see oci_error} Array Description * * * * * * * * * * * * * * * * * * * * * * * * * *
    Array keyTypeDescription
    codeinteger * The Oracle error number. *
    messagestring * The Oracle error text. *
    offsetinteger * The byte position of an error in the SQL statement. If there * was no statement, this is 0 *
    sqltextstring * The SQL statement text. If there was no statement, this is * an empty string. *
    */ #[ArrayShape(["code" => "int", "message" => "string", "offset" => "int", "sqltext" => "string"])] function oci_error($resource = null) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Frees a descriptor * @link https://php.net/manual/en/function.oci-free-descriptor.php * @param resource $descriptor * @return bool TRUE on success or FALSE on failure. */ function oci_free_descriptor($descriptor) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Compares two LOB/FILE locators for equality * @link https://php.net/manual/en/function.oci-lob-is-equal.php * @param OCI_Lob $lob1

    * A LOB identifier. *

    * @param OCI_Lob $lob2

    * A LOB identifier. *

    * @return bool TRUE if these objects are equal, FALSE otherwise. */ function oci_lob_is_equal( #[LanguageLevelTypeAware(['8.0' => 'OCILob'], default: 'OCI_Lob')] $lob1, #[LanguageLevelTypeAware(['8.0' => 'OCILob'], default: 'OCI_Lob')] $lob2 ) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Copies large object * @link https://php.net/manual/en/function.oci-lob-copy.php * @param OCI_Lob $lob_to

    * The destination LOB. *

    * @param OCI_Lob $lob_from

    * The copied LOB. *

    * @param int $length [optional]

    * Indicates the length of data to be copied. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_lob_copy( #[LanguageLevelTypeAware(['8.0' => 'OCILob'], default: 'OCI_Lob')] $lob_to, #[LanguageLevelTypeAware(['8.0' => 'OCILob'], default: 'OCI_Lob')] $lob_from, $length = 0 ) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Commits the outstanding database transaction * @link https://php.net/manual/en/function.oci-commit.php * @param resource $connection

    * An Oracle connection identifier, returned by * {@see oci_connect}, {@see oci_pconnect}, or {@see oci_new_connect}. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_commit($connection) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Rolls back the outstanding database transaction * @link https://php.net/manual/en/function.oci-rollback.php * @param resource $connection

    * An Oracle connection identifier, returned by * {@see oci_connect}, {@see oci_pconnect} * or {@see oci_new_connect}. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_rollback($connection) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Initializes a new empty LOB or FILE descriptor * @link https://php.net/manual/en/function.oci-new-descriptor.php * @param resource $connection

    * An Oracle connection identifier, returned by * {@see oci_connect} or {@see oci_pconnect}. *

    * @param int $type [optional]

    * Valid values for type are: * OCI_DTYPE_FILE, OCI_DTYPE_LOB and * OCI_DTYPE_ROWID. *

    * @return OCI_Lob|OCILob|false A new LOB or FILE descriptor on success, FALSE on error. */ #[LanguageLevelTypeAware(['8.0' => 'OCILob|false'], default: 'OCI_Lob|false')] function oci_new_descriptor($connection, $type = OCI_DTYPE_LOB) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Sets number of rows to be prefetched by queries * @link https://php.net/manual/en/function.oci-set-prefetch.php * @param resource $statement

    A valid OCI8 statement * identifier created by {@see oci_parse} and executed * by {@see oci_execute}, or a REF * CURSOR statement identifier.

    * @param int $rows

    * The number of rows to be prefetched, >= 0 *

    * @return bool TRUE on success or FALSE on failure. */ function oci_set_prefetch($statement, $rows) {} /** * (PHP 5.3.2, PECL OCI8 >= 1.4.0)
    * Sets the client identifier * @link https://php.net/manual/en/function.oci-set-client-identifier.php * @param resource $connection

    An Oracle connection identifier, * returned by {@see oci_connect}, {@see oci_pconnect}, * or {@see oci_new_connect}.

    * @param string $client_identifier

    * User chosen string up to 64 bytes long. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_set_client_identifier($connection, $client_identifier) {} /** * (PHP 5.3.2, PECL OCI8 >= 1.4.0)
    * Sets the database edition * @link https://php.net/manual/en/function.oci-set-edition.php * @param string $edition

    * Oracle Database edition name previously created with the SQL * "CREATE EDITION" command. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_set_edition($edition) {} /** * (PHP 5.3.2, PECL OCI8 >= 1.4.0)
    * Sets the module name * @link https://php.net/manual/en/function.oci-set-module-name.php * @param resource $connection

    An Oracle connection identifier, * returned by {@see oci_connect}, {@see oci_pconnect}, * or {@see oci_new_connect}.

    * @param string $module_name

    * User chosen string up to 48 bytes long. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_set_module_name($connection, $module_name) {} /** * (PHP 5.3.2, PECL OCI8 >= 1.4.0)
    * Sets the action name * @link https://php.net/manual/en/function.oci-set-action.php * @param resource $connection

    An Oracle connection identifier, * returned by {@see oci_connect}, {@see oci_pconnect}, * or {@see oci_new_connect}.

    * @param string $action_name

    * User chosen string up to 32 bytes long. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_set_action($connection, $action_name) {} /** * (PHP 5.3.2, PECL OCI8 >= 1.4.0)
    * Sets the client information * @link https://php.net/manual/en/function.oci-set-client-info.php * @param resource $connection

    An Oracle connection identifier, * returned by {@see oci_connect}, {@see oci_pconnect}, * or {@see oci_new_connect}.

    * @param string $client_info

    * User chosen string up to 64 bytes long. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_set_client_info($connection, $client_info) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Changes password of Oracle's user * @link https://php.net/manual/en/function.oci-password-change.php * @param resource $connection

    * An Oracle connection identifier, returned by * {@see oci_connect} or {@see oci_pconnect}. *

    * @param string $username

    * The Oracle user name. *

    * @param string $old_password

    * The old password. *

    * @param string $new_password

    * The new password to be set. *

    * @return bool TRUE on success or FALSE on failure. */ function oci_password_change($connection, $username, $old_password, $new_password) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Allocates new collection object * @link https://php.net/manual/en/function.oci-new-collection.php * @param resource $connection

    * An Oracle connection identifier, returned by * {@see oci_connect} or {@see oci_pconnect}. *

    * @param string $tdo

    * Should be a valid named type (uppercase). *

    * @param string $schema [optional]

    * Should point to the scheme, where the named type was created. The name * of the current user is the default value. *

    * @return OCI_Collection|false A new OCICollection object or FALSE on * error. */ #[LanguageLevelTypeAware(['8.0' => 'OCICollection|false'], default: 'OCI_Collection|false')] function oci_new_collection($connection, $tdo, $schema = null) {} /** * Alias of {@see oci_free_statement()} * @link https://php.net/manual/en/function.ocifreecursor.php * @param $statement_resource * @return bool Returns TRUE on success or FALSE on failure. */ function oci_free_cursor($statement_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see oci_free_statement} * @link https://php.net/manual/en/function.ocifreecursor.php * @param resource $statement_resource * @return bool TRUE on success or FALSE on failure. */ #[Deprecated(replacement: "oci_free_statement", since: "5.4")] function ocifreecursor($statement_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_bind_by_name} * @link https://php.net/manual/en/function.ocibindbyname.php * @param resource $statement * @param string $column_name * @param mixed &$variable * @param int $maximum_length [optional] * @param int $type [optional] * @return bool Returns TRUE on success or FALSE on failure. */ #[Deprecated(replacement: "oci_bind_by_name", since: "5.4")] function ocibindbyname($statement, $column_name, &$variable, $maximum_length = -1, $type = SQLT_CHR) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_define_by_name} * @link https://php.net/manual/en/function.ocidefinebyname.php * @param resource $statement

    A valid OCI8 statement identifier created by {@see oci_parse()} and executed by {@see oci_execute()}, or a REF CURSOR statement identifier.

    * @param string $column_name

    The column name used in the query. Use uppercase for Oracle's default, non-case sensitive column names. Use the exact column name case for case-sensitive column names.

    * @param mixed &$variable

    The PHP variable that will contain the returned column value.

    * @param int $type [optional]

    The data type to be returned. Generally not needed. Note that Oracle-style data conversions are not performed. For example, SQLT_INT will be ignored and the returned data type will still be SQLT_CHR. * You can optionally use {@see oci_new_descriptor()} to allocate LOB/ROWID/BFILE descriptors.

    * @return bool Returns TRUE on success or FALSE on failure. */ #[Deprecated(replacement: "oci_define_by_name", since: "5.4")] function ocidefinebyname($statement, $column_name, &$variable, $type = SQLT_CHR) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_field_is_null} * @link https://php.net/manual/en/function.ocicolumnisnull.php * @param resource $statement * @param mixed $column_number_or_name * @return bool Returns TRUE if field is NULL, FALSE otherwise. */ #[Deprecated(replacement: "oci_field_is_null", since: "5.4")] function ocicolumnisnull($statement, $column_number_or_name) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_field_name} * @link https://php.net/manual/en/function.ocicolumnname.php * @param resource $statement * @param mixed $column_number * @return string|false Returns the name as a string, or FALSE on errors. */ #[Deprecated(replacement: "oci_field_name", since: "5.4")] function ocicolumnname($statement, $column_number) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_field_size} * @link https://php.net/manual/en/function.ocicolumnsize.php * @param resource $statement * @param mixed $column_number_or_name * @return int|false Returns the size of a field in bytes, or FALSE on errors. */ #[Deprecated(replacement: "oci_field_size", since: "5.4")] function ocicolumnsize($statement, $column_number_or_name) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_field_scale} * @link https://php.net/manual/en/function.ocicolumnscale.php * @param resource $statement_resource * @param $column_number * @return int|false Returns the scale as an integer, or FALSE on errors. */ #[Deprecated(replacement: "oci_field_scale", since: "5.4")] function ocicolumnscale($statement_resource, $column_number) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_field_precision} * @link https://php.net/manual/en/function.ocicolumnprecision.php * @param resource $statement_resource * @param string|int $column_number * @return int|false Returns the precision as an integer, or FALSE on errors. */ #[Deprecated(replacement: "oci_field_precision", since: "5.4")] function ocicolumnprecision($statement_resource, $column_number) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_field_type} * @link https://php.net/manual/en/function.ocicolumntype.php * @param resource $statement_resource * @param string|int $column_number * @return mixed|false Returns the field data type as a string, or FALSE on errors. */ #[Deprecated(replacement: "oci_field_type", since: "5.4")] function ocicolumntype($statement_resource, $column_number) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_field_type_raw} * @link https://php.net/manual/en/function.ocicolumntyperaw.php * @param resource $statement_resource * @param string|int $column_number * @return int|false Returns Oracle's raw data type as a number, or FALSE on errors. */ #[Deprecated(replacement: "oci_field_type_raw", since: "5.4")] function ocicolumntyperaw($statement_resource, $column_number) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_execute} * @link https://php.net/manual/en/function.ociexecute.php * @param $statement_resource * @param $mode [optional] * @return bool Returns TRUE on success or FALSE on failure */ #[Deprecated(replacement: "oci_execute", since: "5.4")] function ociexecute($statement_resource, $mode = OCI_COMMIT_ON_SUCCESS) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_cancel} * @link https://php.net/manual/en/function.ocicancel.php * @param resource $statement_resource * @return bool Returns TRUE on success or FALSE on failure */ #[Deprecated(replacement: 'oci_cancel', since: "5.4")] function ocicancel($statement_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_fetch} * @link https://php.net/manual/en/function.ocifetch.php * @param resource $statement_resource * @return bool Returns TRUE on success or FALSE if there are no more rows in the statement. */ #[Deprecated(replacement: "oci_fetch", since: "5.4")] function ocifetch($statement_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_fetch_all} * @link https://php.net/manual/en/function.ocifetchstatement.php * @param resource $statement_resource * @param array &$output * @param int $skip [optional] * @param int $maximum_rows [optional] * @param int $flags [optional] * @return int|false Returns the number of rows in output, which may be 0 or more, or FALSE on failure. */ #[Deprecated(replacement: "oci_fetch_all", since: "5.4")] function ocifetchstatement($statement_resource, &$output, $skip, $maximum_rows, $flags) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_free_statement} * @link https://php.net/manual/en/function.ocifreestatement.php * @param resource $statement_resource * @return bool Returns TRUE on success or FALSE on failure. */ #[Deprecated(replacement: "oci_free_statement", since: "5.4")] function ocifreestatement($statement_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_internal_debug} * @link https://php.net/manual/en/function.ociinternaldebug.php * @param bool $mode * @removed 8.0 */ #[Deprecated(replacement: "oci_internal_debug", since: "5.4")] function ociinternaldebug($mode) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_num_fields} * @link https://php.net/manual/en/function.ocinumcols.php * @param resource $statement_resource * @return int|false Returns the number of columns as an integer, or FALSE on errors. */ #[Deprecated(replacement: "oci_num_fields", since: "5.4")] function ocinumcols($statement_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_parse} * @link https://php.net/manual/en/function.ociparse.php * @param resource $connection_resource * @param string $sql_text * @return resource|false Returns a statement handle on success, or FALSE on error. */ #[Deprecated(replacement: "oci_parse", since: "5.4")] function ociparse($connection_resource, $sql_text) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_new_cursor} * @link https://php.net/manual/en/function.ocinewcursor.php * @param resource $connection_resource * @return resource|false Returns a new statement handle, or FALSE on error. */ #[Deprecated(replacement: "oci_new_cursor", since: "5.4")] function ocinewcursor($connection_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_result} * @link https://php.net/manual/en/function.ociresult.php * @param resource $statement_resource * @param $column_number_or_name * @return false|mixed Returns everything as strings except for abstract types (ROWIDs, LOBs and FILEs). Returns FALSE on error. */ #[Deprecated(replacement: "oci_result", since: "5.4")] function ociresult($statement_resource, $column_number_or_name) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_server_version} * @link https://php.net/manual/en/function.ociserverversion.php * @param $connection_resource * @return string|false Returns the version information as a string or FALSE on error. */ #[Deprecated(replacement: "oci_server_version", since: "5.4")] function ociserverversion($connection_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_statement_type} * @link https://php.net/manual/en/function.ocistatementtype.php * @param resource $statement_resource * @return string|false Returns everything as strings except for abstract types (ROWIDs, LOBs and FILEs). Returns FALSE on error. */ #[Deprecated(replacement: "oci_statement_type", since: "5.4")] function ocistatementtype($statement_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_num_rows} * @link https://php.net/manual/en/function.ocirowcount.php * @param resource $statement_resource * @return int|false Returns the number of rows affected as an integer, or FALSE on errors. */ #[Deprecated(replacement: "oci_num_rows", since: "5.4")] function ocirowcount($statement_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_close} * @link https://php.net/manual/en/function.ocilogoff.php * @param resource $connection_resource * @return bool Returns TRUE on success or FALSE on failure. */ #[Deprecated(replacement: "oci_close", since: "5.4")] function ocilogoff($connection_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_connect} * @link https://php.net/manual/en/function.ocilogon.php * @param string $username * @param string $password * @param string $connection_string [optional] * @param string $character_set [optional] * @param int $session_mode [optional] * @return resource|false Returns a connection identifier or FALSE on error. */ #[Deprecated(replacement: "oci_connect", since: "5.4")] function ocilogon($username, $password, $connection_string, $character_set, $session_mode) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see oci_new_connect} * @link https://php.net/manual/en/function.ocinlogon.php * @param $username * @param $password * @param $connection_string [optional] * @param $character_set [optional] * @param $session_mode [optional] * @return resource|false

    Returns a connection identifier or FALSE on error.

    */ #[Deprecated(replacement: "oci_new_connect", since: "5.4")] function ocinlogon($username, $password, $connection_string, $character_set, $session_mode) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see oci_pconnect} * @link https://php.net/manual/en/function.ociplogon.php * @param string $username

    The Oracle user name.

    * @param string $password

    The password for username

    * @param $connection_string [optional] * @param $character_set [optional] * @param $session_mode [optional] * @return resource|false

    Returns a connection identifier or FALSE on error.

    */ #[Deprecated(replacement: "oci_pconnect", since: "5.4")] function ociplogon($username, $password, $connection_string, $character_set, $session_mode) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see oci_error} * @link https://php.net/manual/en/function.ocierror.php * @param resource $connection_or_statement_resource [optional] For most errors, resource is the resource handle that was passed to the failing function call. * For connection errors with oci_connect(), oci_new_connect() or oci_pconnect() do not pass resource. * @return array|false If no error is found, oci_error() returns FALSE. Otherwise, oci_error() returns the error information as an associative array. */ #[Deprecated(replacement: "oci_error", since: "5.4")] function ocierror($connection_or_statement_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see OCI-Lob::free} * @link https://php.net/manual/en/function.ocifreedesc.php * @param $lob_descriptor * @return bool

    Returns TRUE on success or FALSE on failure.

    */ #[Deprecated(replacement: "OCI-Lob::free", since: "5.4")] function ocifreedesc($lob_descriptor) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see OCI-Lob::save} * @link https://php.net/manual/en/function.ocisavelob.php * @param OCI_Lob|OCILob $lob_descriptor * @param string $data * @param int $offset [optional] * @return bool */ #[Deprecated(replacement: "OCI-Lob::save", since: "5.4")] function ocisavelob(#[LanguageLevelTypeAware(['8.0' => 'OCILob'], default: 'OCI_Lob')] $lob_descriptor, $data, $offset) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see OCI_Lob::import} * @link https://php.net/manual/en/function.ocisavelobfile.php * @param OCI_Lob|OCILob $lob_descriptor * @param string $filename * @return bool */ #[Deprecated(replacement: "OCI_Lob::import", since: "5.4")] function ocisavelobfile(#[LanguageLevelTypeAware(['8.0' => 'OCILob'], default: 'OCI_Lob')] $lob_descriptor, $filename) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see OCI_Lob::export} * @link https://php.net/manual/en/function.ociwritelobtofile.php * @param OCI_Lob|OCILob $lob_descriptor * @param string $filename

    Path to the file.

    * @param int $start [optional]

    Indicates from where to start exporting.

    * @param int $length [optional]

    Indicates the length of data to be exported.

    * @return bool Returns TRUE on success or FALSE on failure. */ #[Deprecated(replacement: "OCI_Lob::export", since: "5.4")] function ociwritelobtofile( #[LanguageLevelTypeAware(['8.0' => 'OCILob'], default: 'OCI_Lob')] $lob_descriptor, $filename, $start, $length ) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see OCI_Lob::load} * @link https://php.net/manual/en/function.ociloadlob.php * @param OCI_Lob|OCILob $lob_descriptor * @return string|false

    Returns the contents of the object, or FALSE on errors.

    */ #[Deprecated(replacement: "OCI_Lob::load", since: "5.4")] function ociloadlob(#[LanguageLevelTypeAware(['8.0' => 'OCILob'], default: 'OCI_Lob')] $lob_descriptor) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see oci_commit} * @link https://php.net/manual/en/function.ocicommit.php * @param $connection_resource

    * An Oracle connection identifier, returned by * {@see oci_connect()}, * {@see oci_pconnect()}, or * {@see oci_new_connect()}. *

    * @return bool

    Returns TRUE on success or FALSE on failure.

    */ #[Deprecated(replacement: "oci_commit", since: "5.4")] function ocicommit($connection_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see oci_rollback} * @link https://php.net/manual/en/function.ocirollback.php * @param resource $connection_resource * @return bool

    Returns TRUE on success or FALSE on failure.

    */ #[Deprecated(replacement: "oci_rollback", since: "5.4")] function ocirollback($connection_resource) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see oci_new_descriptor} * @link https://php.net/manual/en/function.ocinewdescriptor.php * @param resource $connection_resource

    * An Oracle connection identifier, returned by * {@see oci_connect()} or {@see oci_pconnect()}. *

    * @param $type [optional]

    Valid values for type are: OCI_DTYPE_FILE, OCI_DTYPE_LOB and OCI_DTYPE_ROWID.

    * @return OCI_LOB|false Returns a new LOB or FILE descriptor on success, FALSE on error. */ #[Deprecated(replacement: "oci_new_descriptor", since: "5.4")] #[LanguageLevelTypeAware(['8.0' => 'OCILob|false'], default: 'OCI_Lob|false')] function ocinewdescriptor($connection_resource, $type = OCI_DTYPE_LOB) {} /** * (PHP 4, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see oci_set_prefetch} * @link https://php.net/manual/en/function.ocisetprefetch.php * @param resource $statement_resource

    A valid OCI8 statement * identifier created by * {@see oci_parse()} and executed * by * {@see oci_execute()}, or a REF CURSOR statement identifier.

    * @param $number_of_rows * @return bool

    Returns TRUE on success or FALSE on failure.

    */ #[Deprecated(replacement: "oci_set_prefetch", since: "5.4")] function ocisetprefetch($statement_resource, $number_of_rows) {} /** * (PHP 5, PECL OCI8 >= 1.1.0)
    * Changes password of Oracle's user * @param resource|string $connection_resource_or_connection_string_or_dbname

    An Oracle connection identifier, returned by * {@see oci_connect()} or * {@see oci_pconnect()}.

    * @param string $username

    The Oracle user name.

    * @param string $old_password

    The new password to be set.

    * @param string $new_password

    The new password to be set.

    * @return resource|bool

    Returns TRUE on success or FALSE on failure or resource, depending on the function parameters.

    */ function ocipasswordchange($connection_resource_or_connection_string_or_dbname, $username, $old_password, $new_password) {} /** * (PHP 4 >= 4.0.7, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see OCI_Collection::free} * @link https://php.net/manual/en/function.ocifreecollection.php * @param OCI_Collection|OCICollection $collection * @return bool Returns TRUE on success or FALSE on failure. */ #[Deprecated(replacement: "OCI_Collection::free", since: "5.4")] function ocifreecollection(#[LanguageLevelTypeAware(['8.0' => 'OCICollection'], default: 'OCI_Collection')] $collection) {} /** * (PHP 4 >= 4.0.6, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see oci_new_collection} * @link https://php.net/manual/en/function.ocinewcollection.php * @param $connection_resource

    * An Oracle connection identifier, returned by * {@see oci_connect()} or * {@see oci_pconnect()}. * @param $tdo

    Should be a valid named type (uppercase).

    * @param $schema

    Should point to the scheme, where the named type was created. The name of the current user is the default value.

    *

    * @return OCI_Collection|false

    Returns a new OCI_Collection object or FALSE on error.

    */ #[Deprecated(replacement: "oci_new_collection", since: "5.4")] #[LanguageLevelTypeAware(['8.0' => 'OCICollection|false'], default: 'OCI_Collection|false')] function ocinewcollection($connection_resource, $tdo, $schema = null) {} /** * (PHP 4 >= 4.0.6, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * (@see OCI_Collection::append) * @link https://php.net/manual/en/function.ocicollappend.php * @param OCI_Collection $collection * @param mixed $value

    The value to be added to the collection. Can be a string or a number.

    * @return bool

    Returns TRUE on success or FALSE on failure.

    */ #[Deprecated(replacement: "OCI_Collection::append", since: "5.4")] function ocicollappend(#[LanguageLevelTypeAware(['8.0' => 'OCICollection'], default: 'OCI_Collection')] $collection, $value) {} /** * (PHP 4 >= 4.0.6, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see OCI_COLLection::getElem} * @link https://php.net/manual/en/function.ocicollgetelem.php * @param OCI_Collection $collection * @param int $index

    The element index. First index is 0.

    * @return mixed

    Returns FALSE if such element doesn't exist; NULL if element is NULL; string if element is column of a string datatype or number if element is numeric field.

    */ #[Deprecated(replacement: "OCI_COLLection::getElem", since: "5.4")] function ocicollgetelem(#[LanguageLevelTypeAware(['8.0' => 'OCICollection'], default: 'OCI_Collection')] $collection, $index) {} /** * (PHP 4 >= 4.0.6, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of {@see OCI_Collection::assignElem} * @link https://php.net/manual/en/function.ocicollassignelem.php * @param OCI_Collection $collection * @param $index

    The element index. First index is 0.

    * @param $value

    Can be a string or a number.

    * @return bool

    Returns TRUE on success or FALSE on failure.

    */ #[Deprecated(replacement: "OCI_Collection::assignElem", since: "5.4")] function ocicollassignelem(#[LanguageLevelTypeAware(['8.0' => 'OCICollection'], default: 'OCI_Collection')] $collection, $index, $value) {} /** * (PHP 4 >= 4.0.6, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see OCI_COLLection::size} * @link https://php.net/manual/en/function.ocicollsize.php * @param OCI_Collection $collection * @return int|false

    Returns the number of elements in the collection or FALSE on error.

    */ #[Deprecated(replacement: "OCI_COLLection::size", since: "5.4")] function ocicollsize(#[LanguageLevelTypeAware(['8.0' => 'OCICollection'], default: 'OCI_Collection')] $collection) {} /** * (PHP 4 >= 4.0.6, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see OCI_COLLection::max} * @link https://php.net/manual/en/function.ocicollmax.php * @param OCI_Collection $collection * @return int|false

    Returns the maximum number as an integer, or FALSE on errors. * If the returned value is 0, then the number of elements is not limited.

    */ #[Deprecated(replacement: "OCI_COLLection::max", since: "5.4")] function ocicollmax(#[LanguageLevelTypeAware(['8.0' => 'OCICollection'], default: 'OCI_Collection')] $collection) {} /** * (PHP 4 >= 4.0.6, PHP 5, PECL OCI8 >= 1.0.0)
    * Alias of * {@see OCI_Collection::trim} * @link https://php.net/manual/en/function.ocicolltrim.php * @param OCI_Collection $collection * @param int|float $number * @return bool Returns TRUE or FALSE on failure. */ #[Deprecated(replacement: "OCI_Collection::trim", since: "5.4")] function ocicolltrim(#[LanguageLevelTypeAware(['8.0' => 'OCICollection'], default: 'OCI_Collection')] $collection, $number) {} /** * (PHP 4 >= 4.0.6, PECL OCI8 1.0) * Writes a temporary large object * Alias of {@see OCI-Lob::writeTemporary()} * @link https://php.net/manual/en/function.ociwritetemporarylob.php * @param OCI_Lob|OCILob $lob_descriptor * @param string $data

    The data to write.

    * @param int $lob_type

    * Can be one of the following: *

      *
    • * OCI_TEMP_BLOB is used to create temporary BLOBs *
    • *
    • * OCI_TEMP_CLOB is used to create * temporary CLOBs *
    • *
    * @return bool

    Returns TRUE on success or FALSE on failure.

    */ #[Deprecated(replacement: "OCI-Lob::writeTemporary", since: "5.4")] function ociwritetemporarylob( #[LanguageLevelTypeAware(['8.0' => 'OCILob'], default: 'OCI_Lob')] $lob_descriptor, $data, $lob_type = OCI_TEMP_CLOB ) {} /** * (PHP 4 >= 4.0.6, PECL OCI8 1.0) * Alias of {@see OCI-Lob::close()} * @link https://php.net/manual/en/function.ocicloselob.php * @param OCI_Lob|OCILob $lob_descriptor * @return bool

    Returns TRUE on success or FALSE on failure.

    */ #[Deprecated(replacement: "OCI-Lob::close()", since: "5.4")] function ocicloselob(#[LanguageLevelTypeAware(['8.0' => 'OCILob'], default: 'OCI_Lob')] $lob_descriptor) {} /** * (PHP 4 >= 4.0.6, PECL OCI8 1.0) * Alias of {@see OCI-Collection::assign()} * Assigns a value to the collection from another existing collection * @link https://php.net/manual/en/function.ocicollassign.php * @param OCI_Collection $to * @param OCI_Collection $from An instance of OCI-Collection. * @return bool

    Returns TRUE on success or FALSE on failure.

    */ #[Deprecated(replacement: "OCI-Collection::assign", since: "5.4")] function ocicollassign( #[LanguageLevelTypeAware(['8.0' => 'OCICollection'], default: 'OCI_Collection')] $to, #[LanguageLevelTypeAware(['8.0' => 'OCICollection'], default: 'OCI_Collection')] $from ) {} /** * See OCI_NO_AUTO_COMMIT. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_DEFAULT', 0); /** * Used with {@see oci_connect} to connect with * the SYSOPER privilege. The php.ini setting * oci8.privileged_connect * should be enabled to use this. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_SYSOPER', 4); /** * Used with {@see oci_connect} to connect with * the SYSDBA privilege. The php.ini setting * oci8.privileged_connect * should be enabled to use this. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_SYSDBA', 2); /** * Used with {@see oci_connect} for using * Oracles' External or OS authentication. Introduced in PHP * 5.3 and PECL OCI8 1.3.4. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_CRED_EXT', -2147483648); /** * Statement execution mode * for {@see oci_execute}. Use this mode if you * want meta data such as the column names but don't want to * fetch rows from the query. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_DESCRIBE_ONLY', 16); /** * Statement execution mode for {@see oci_execute} * call. Automatically commit changes when the statement has * succeeded. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_COMMIT_ON_SUCCESS', 32); /** * Statement execution mode * for {@see oci_execute}. The transaction is not * automatically committed when using this mode. For * readability in new code, use this value instead of the * older, equivalent OCI_DEFAULT constant. * Introduced in PHP 5.3.2 (PECL OCI8 1.4). * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_NO_AUTO_COMMIT', 0); /** * Obsolete. Statement fetch mode. Used when the application * knows in advance exactly how many rows it will be fetching. * This mode turns prefetching off for Oracle release 8 or * later mode. The cursor is canceled after the desired rows * are fetched which may result in reduced server-side * resource usage. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_EXACT_FETCH', 2); /** * Used with to set the seek position. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_SEEK_SET', 0); /** * Used with to set the seek position. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_SEEK_CUR', 1); /** * Used with to set the seek position. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_SEEK_END', 2); /** * Used with to free * buffers used. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_LOB_BUFFER_FREE', 1); /** * The same as OCI_B_BFILE. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_BFILEE', 114); /** * The same as OCI_B_CFILEE. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_CFILEE', 115); /** * The same as OCI_B_CLOB. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_CLOB', 112); /** * The same as OCI_B_BLOB. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_BLOB', 113); /** * The same as OCI_B_ROWID. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_RDD', 104); /** * The same as OCI_B_INT. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_INT', 3); /** * The same as OCI_B_NUM. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_NUM', 2); /** * The same as OCI_B_CURSOR. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_RSET', 116); /** * Used with {@see oci_bind_array_by_name} to bind arrays of * CHAR. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_AFC', 96); /** * Used with {@see oci_bind_array_by_name} to bind arrays of * VARCHAR2. * Also used with {@see oci_bind_by_name}. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_CHR', 1); /** * Used with {@see oci_bind_array_by_name} to bind arrays of * VARCHAR. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_VCS', 9); /** * Used with {@see oci_bind_array_by_name} to bind arrays of * VARCHAR2. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_AVC', 97); /** * Used with {@see oci_bind_array_by_name} to bind arrays of * STRING. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_STR', 5); /** * Used with {@see oci_bind_array_by_name} to bind arrays of * LONG VARCHAR. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_LVC', 94); /** * Used with {@see oci_bind_array_by_name} to bind arrays of * FLOAT. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_FLT', 4); /** * Not supported. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_UIN', 68); /** * Used with {@see oci_bind_by_name} to bind LONG values. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_LNG', 8); /** * Used with {@see oci_bind_by_name} to bind LONG RAW values. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_LBI', 24); /** * The same as OCI_B_BIN. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_BIN', 23); /** * Used with {@see oci_bind_array_by_name} to bind arrays of * LONG. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_ODT', 156); /** * Not supported. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_BDOUBLE', 22); /** * Not supported. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_BFLOAT', 21); /** * Used with {@see oci_bind_by_name} when binding * named data types. Note: in PHP < 5.0 it was called * OCI_B_SQLT_NTY. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_B_NTY', 108); /** * The same as OCI_B_NTY. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_NTY', 108); /** * Obsolete. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_SYSDATE', "SYSDATE"); /** * Used with {@see oci_bind_by_name} when binding * BFILEs. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_B_BFILE', 114); /** * Used with {@see oci_bind_by_name} when binding * CFILEs. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_B_CFILEE', 115); /** * Used with {@see oci_bind_by_name} when binding * CLOBs. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_B_CLOB', 112); /** * Used with {@see oci_bind_by_name} when * binding BLOBs. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_B_BLOB', 113); /** * Used with {@see oci_bind_by_name} when binding * ROWIDs. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_B_ROWID', 104); /** * Used with {@see oci_bind_by_name} when binding * cursors, previously allocated * with {@see oci_new_descriptor}. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_B_CURSOR', 116); /** * Used with {@see oci_bind_by_name} to bind RAW values. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_B_BIN', 23); /** * Used with {@see oci_bind_array_by_name} to bind arrays of * INTEGER. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_B_INT', 3); /** * Used with {@see oci_bind_array_by_name} to bind arrays of * NUMBER. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_B_NUM', 2); /** * Default mode of {@see oci_fetch_all}. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_FETCHSTATEMENT_BY_COLUMN', 16); /** * Alternative mode of {@see oci_fetch_all}. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_FETCHSTATEMENT_BY_ROW', 32); /** * Used with {@see oci_fetch_all} and * {@see oci_fetch_array} to get results as an associative * array. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_ASSOC', 1); /** * Used with {@see oci_fetch_all} and * {@see oci_fetch_array} to get results as an * enumerated array. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_NUM', 2); /** * Used with {@see oci_fetch_all} and * {@see oci_fetch_array} to get results as an * array with both associative and number indices. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_BOTH', 3); /** * Used with {@see oci_fetch_array} to get empty * array elements if the row items value is NULL. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_RETURN_NULLS', 4); /** * Used with {@see oci_fetch_array} to get the * data value of the LOB instead of the descriptor. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_RETURN_LOBS', 8); /** * This flag tells {@see oci_new_descriptor} to * initialize a new FILE descriptor. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_DTYPE_FILE', 56); /** * This flag tells {@see oci_new_descriptor} to * initialize a new LOB descriptor. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_DTYPE_LOB', 50); /** * This flag tells {@see oci_new_descriptor} to * initialize a new ROWID descriptor. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_DTYPE_ROWID', 54); /** * The same as OCI_DTYPE_FILE. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_D_FILE', 56); /** * The same as OCI_DTYPE_LOB. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_D_LOB', 50); /** * The same as OCI_DTYPE_ROWID. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_D_ROWID', 54); /** * Used with * to indicate that a temporary CLOB should be created. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_TEMP_CLOB', 2); /** * Used with * to indicate that a temporary BLOB should be created. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_TEMP_BLOB', 1); /** * (PECL OCI8 >= 2.0.7)
    * The same as OCI_B_BOL. * @link https://php.net/manual/en/oci8.constants.php */ define('SQLT_BOL', 252); /** * (PECL OCI8 >= 2.0.7)
    * Used with {@see oci_bind_by_name} when * binding PL/SQL BOOLEAN. * @link https://php.net/manual/en/oci8.constants.php */ define('OCI_B_BOL', 252); // End of oci8 v.2.0.7 'true'], default: 'bool')] function sodium_crypto_generichash_update(string &$state, string $message): bool {} /** * Get the final hash * BLAKE2b * @link https://www.php.net/manual/en/function.sodium-crypto-generichash-final.php * @param string &$state * @param int $length * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_generichash_final( string &$state, int $length = 32 ): string {} /** * Secure password-based key derivation function * Argon2i * @link https://www.php.net/manual/en/function.sodium-crypto-pwhash.php * @param int $length * @param string $password * @param string $salt * @param int $opslimit * @param int $memlimit * @param int $algo [optional] * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_pwhash(int $length, string $password, string $salt, int $opslimit, int $memlimit, int $algo = SODIUM_CRYPTO_PWHASH_ALG_DEFAULT): string {} /** * Get a formatted password hash (for storage) * Argon2i * @link https://www.php.net/manual/en/function.sodium-crypto-pwhash-str.php * @param string $password * @param int $opslimit * @param int $memlimit * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_pwhash_str(string $password, int $opslimit, int $memlimit): string {} /** * Verify a password against a hash * Argon2i * @link https://www.php.net/manual/en/function.sodium-crypto-pwhash-str-verify.php * @param string $hash * @param string $password * @return bool * @throws SodiumException * @since 7.2 */ function sodium_crypto_pwhash_str_verify(string $hash, string $password): bool {} /** * Secure password-based key derivation function * Scrypt * @link https://www.php.net/manual/en/function.sodium-crypto-pwhash-scryptsalsa208sha256.php * @param int $length * @param string $password * @param string $salt * @param int $opslimit * @param int $memlimit * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_pwhash_scryptsalsa208sha256( int $length, string $password, string $salt, int $opslimit, int $memlimit, #[PhpStormStubsElementAvailable(from: '7.2', to: '7.4')] $alg = null ): string {} /** * Get a formatted password hash (for storage) * Scrypt * @link https://www.php.net/manual/en/function.sodium-crypto-pwhash-scryptsalsa208sha256-str.php * @param string $password * @param int $opslimit * @param int $memlimit * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_pwhash_scryptsalsa208sha256_str(string $password, int $opslimit, int $memlimit): string {} /** * Verify a password against a hash * Scrypt * @link https://www.php.net/manual/en/function.sodium-crypto-pwhash-scryptsalsa208sha256-str-verify * @param string $hash * @param string $password * @return bool * @since 7.2 */ function sodium_crypto_pwhash_scryptsalsa208sha256_str_verify(string $hash, string $password): bool {} /** * Elliptic Curve Diffie Hellman over Curve25519 * X25519 * @link https://www.php.net/manual/en/function.sodium-crypto-scalarmult.php * @param string $n * @param string $p * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_scalarmult(string $n, string $p): string {} /** * Authenticated secret-key encryption (encrypt) * Xsals20 + Poly1305 * @link https://www.php.net/manual/en/function.sodium-crypto-secretbox.php * @param string $message * @param string $nonce * @param string $key * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_secretbox(string $message, string $nonce, string $key): string {} /** * Authenticated secret-key encryption (decrypt) * Xsals20 + Poly1305 * @link https://www.php.net/manual/en/function.sodium-crypto-secretbox-open.php * @param string $ciphertext * @param string $nonce * @param string $key * @return string|false * @throws SodiumException * @since 7.2 */ function sodium_crypto_secretbox_open(string $ciphertext, string $nonce, string $key): string|false {} /** * A short keyed hash suitable for data structures * SipHash-2-4 * @link https://www.php.net/manual/en/function.sodium-crypto-shorthash.php * @param string $message * @param string $key * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_shorthash(string $message, string $key): string {} /** * Digital Signature * Ed25519 * @link https://www.php.net/manual/en/function.sodium-crypto-sign.php * @param string $message * @param string $secret_key * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_sign(string $message, string $secret_key): string {} /** * Digital Signature (detached) * Ed25519 * @link https://www.php.net/manual/en/function.sodium-crypto-sign-detached.php * @param string $message * @param string $secret_key * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_sign_detached(string $message, string $secret_key): string {} /** * Convert an Ed25519 public key to an X25519 public key * @link https://www.php.net/manual/en/function.sodium-crypto-sign-ed25519-pk-to-curve25519.php * @param string $public_key * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_sign_ed25519_pk_to_curve25519(string $public_key): string {} /** * Convert an Ed25519 secret key to an X25519 secret key * @link https://www.php.net/manual/en/function.sodium-crypto-sign-ed25519-sk-to-curve25519.php * @param string $secret_key * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_sign_ed25519_sk_to_curve25519(string $secret_key): string {} /** * Generate an Ed25519 keypair for use with the crypto_sign API * @link https://www.php.net/manual/en/function.sodium-crypto-sign-keypair.php * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_sign_keypair(): string {} /** * Create an Ed25519 keypair from an Ed25519 secret key + Ed25519 public key * @link https://www.php.net/manual/en/function.sodium-crypto-sign-keypair-from-secretkey-and-publickey.php * @param string $secret_key * @param string $public_key * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_sign_keypair_from_secretkey_and_publickey( string $secret_key, string $public_key ): string {} /** * Verify a signed message and return the plaintext * @link https://www.php.net/manual/en/function.sodium-crypto-sign-open.php * @param string $signed_message * @param string $public_key * @return string|false * @throws SodiumException * @since 7.2 */ function sodium_crypto_sign_open(string $signed_message, string $public_key): string|false {} /** * Get the public key from an Ed25519 keypair * @link https://www.php.net/manual/en/function.sodium-crypto-sign-publickey.php * @param string $key_pair * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_sign_publickey(string $key_pair): string {} /** * Get the secret key from an Ed25519 keypair * @link https://www.php.net/manual/en/function.sodium-crypto-sign-secretkey.php * @param string $key_pair * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_sign_secretkey(string $key_pair): string {} /** * Derive an Ed25519 public key from an Ed25519 secret key * @link https://www.php.net/manual/en/function.sodium-crypto-sign-publickey-from-secretkey.php * @param string $secret_key * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_sign_publickey_from_secretkey(string $secret_key): string {} /** * Derive an Ed25519 keypair for use with the crypto_sign API from a seed * @link https://www.php.net/manual/en/function.sodium-crypto-sign-seed-keypair.php * @param string $seed * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_sign_seed_keypair(string $seed): string {} /** * Verify a detached signature * @link https://www.php.net/manual/en/function.sodium-crypto-sign-verify-detached.php * @param string $signature * @param string $message * @param string $public_key * @return bool * @throws SodiumException * @since 7.2 */ function sodium_crypto_sign_verify_detached(string $signature, string $message, string $public_key): bool {} /** * Create a keystream from a key and nonce * Xsalsa20 * @link https://www.php.net/manual/en/function.sodium-crypto-stream.php * @param int $length * @param string $nonce * @param string $key * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_stream( int $length, string $nonce, string $key ): string {} /** * Encrypt a message using a stream cipher * Xsalsa20 * @link https://www.php.net/manual/en/function.sodium-crypto-stream-xor.php * @param string $message * @param string $nonce * @param string $key * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_stream_xor( string $message, string $nonce, string $key ): string {} /** * Generate a string of random bytes * /dev/urandom * * @param int $length * @return string|false * @since 7.2 */ function sodium_randombytes_buf(int $length): string {} /** * Generate a 16-bit integer * /dev/urandom * * @return int * @since 7.2 */ function sodium_randombytes_random16(): int {} /** * Generate an unbiased random integer between 0 and a specified value * /dev/urandom * * @param int $upperBoundNonInclusive * @return int * @since 7.2 */ function sodium_randombytes_uniform(int $upperBoundNonInclusive): int {} /** * Convert to hex without side-chanels * @link https://www.php.net/manual/en/function.sodium-bin2hex.php * @param string $string * @return string * @throws SodiumException * @since 7.2 */ function sodium_bin2hex(string $string): string {} /** * Compare two strings in constant time * @link https://www.php.net/manual/en/function.sodium-compare.php * @param string $string1 * @param string $string2 * @return int * @throws SodiumException * @since 7.2 */ function sodium_compare(string $string1, string $string2): int {} /** * Convert from hex without side-chanels * @link https://www.php.net/manual/en/function.sodium-hex2bin.php * @param string $string * @param string $ignore * @return string * @throws SodiumException * @since 7.2 */ function sodium_hex2bin(string $string, string $ignore = ''): string {} /** * Increment a string in little-endian * @link https://www.php.net/manual/en/function.sodium-increment.php * @param string &$string * @return void * @throws SodiumException * @since 7.2 */ function sodium_increment(string &$string): void {} /** * Add the right operand to the left * @link https://www.php.net/manual/en/function.sodium-add.php * @param string &$string1 * @param string $string2 * @throws SodiumException * @since 7.2 */ function sodium_add(string &$string1, string $string2): void {} /** * Get the true major version of libsodium * @return int * @since 7.2 */ function sodium_library_version_major(): int {} /** * Get the true minor version of libsodium * @return int * @since 7.2 */ function sodium_library_version_minor(): int {} /** * Compare two strings in constant time * @link https://www.php.net/manual/en/function.sodium-memcmp.php * @param string $string1 * @param string $string2 * @return int * @throws SodiumException * @since 7.2 */ function sodium_memcmp(string $string1, string $string2): int {} /** * Wipe a buffer * @link https://www.php.net/manual/en/function.sodium-memzero.php * @param string &$string * @throws SodiumException * @since 7.2 */ function sodium_memzero(string &$string): void {} /** * Get the version string * * @return string * @since 7.2 */ function sodium_version_string(): string {} /** * Scalar multiplication of the base point and your key * @link https://www.php.net/manual/en/function.sodium-crypto-scalarmult-base * @param string $secret_key * @return string * @throws SodiumException * @since 7.2 */ function sodium_crypto_scalarmult_base( string $secret_key, #[PhpStormStubsElementAvailable(from: '7.2', to: '7.4')] $string_2 ): string {} /** * Creates a random key * * It is equivalent to calling random_bytes() but improves code clarity and can * prevent misuse by ensuring that the provided key length is always be correct. * * @since 7.2 * @see https://secure.php.net/manual/en/function.sodium-crypto-secretbox-keygen.php */ function sodium_crypto_secretbox_keygen(): string {} /** * Creates a random key * * It is equivalent to calling random_bytes() but improves code clarity and can * prevent misuse by ensuring that the provided key length is always be correct. * * @since 7.2 * @see https://secure.php.net/manual/en/function.sodium-crypto-aead-aes256gcm-keygen.php */ function sodium_crypto_aead_aes256gcm_keygen(): string {} /** * Creates a random key * It is equivalent to calling random_bytes() but improves code clarity and can * prevent misuse by ensuring that the provided key length is always be correct. * * @since 7.2 * @see https://secure.php.net/manual/en/function.sodium-crypto-aead-chacha20poly1305-keygen.php */ function sodium_crypto_aead_chacha20poly1305_keygen(): string {} /** * Creates a random key * * It is equivalent to calling random_bytes() but improves code clarity and can * prevent misuse by ensuring that the provided key length is always be correct. * * @since 7.2 * @see https://secure.php.net/manual/en/function.sodium-crypto-aead-chacha20poly1305-ietf-keygen.php */ function sodium_crypto_aead_chacha20poly1305_ietf_keygen(): string {} /** * @param string $ciphertext * @param string $additional_data * @param string $nonce * @param string $key * @return string|false * @throws SodiumException * @since 7.2 * @see https://www.php.net/manual/en/function.sodium-crypto-aead-xchacha20poly1305-ietf-decrypt.php */ function sodium_crypto_aead_xchacha20poly1305_ietf_decrypt(string $ciphertext, string $additional_data, string $nonce, string $key): string|false {} /** * @param string $message * @param string $additional_data * @param string $nonce * @param string $key * @return string * @throws SodiumException * @since 7.2 * https://www.php.net/manual/en/function.sodium-crypto-aead-xchacha20poly1305-ietf-encrypt.php */ function sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(string $message, string $additional_data, string $nonce, string $key): string {} /** * @since 7.2 * @see https://www.php.net/manual/en/function.sodium-crypto-aead-xchacha20poly1305-ietf-keygen.php */ function sodium_crypto_aead_xchacha20poly1305_ietf_keygen(): string {} /** * @param string $password * @param int $opslimit * @param int $memlimit * @return bool * @since 7.2 * @see https://www.php.net/manual/en/function.sodium-crypto-pwhash-str-needs-rehash.php */ function sodium_crypto_pwhash_str_needs_rehash(string $password, int $opslimit, int $memlimit): bool {} /** * @since 7.2 * @see https://www.php.net/manual/en/function.sodium-crypto-secretstream-xchacha20poly1305-keygen.php */ function sodium_crypto_secretstream_xchacha20poly1305_keygen(): string {} /** * @param string $key * @return array * @throws SodiumException * @since 7.2 * @see https://www.php.net/manual/en/function.sodium-crypto-secretstream-xchacha20poly1305-init-push.php */ function sodium_crypto_secretstream_xchacha20poly1305_init_push(string $key): array {} #[PhpStormStubsElementAvailable('7.2')] function sodium_crypto_secretstream_xchacha20poly1305_push(string &$state, #[\SensitiveParameter] string $message, string $additional_data = "", int $tag = SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE): string {} /** * @param string $header * @param string $key * @return string * @throws SodiumException * @since 7.2 * @see https://www.php.net/manual/en/function.sodium-crypto-secretstream-xchacha20poly1305-init-pull.php */ function sodium_crypto_secretstream_xchacha20poly1305_init_pull(string $header, string $key): string {} #[PhpStormStubsElementAvailable('7.2')] function sodium_crypto_secretstream_xchacha20poly1305_pull(string &$state, string $ciphertext, string $additional_data = ""): array|false {} /** * @param string &$state * @throws SodiumException * @since 7.2 * @see https://www.php.net/manual/en/function.sodium-crypto-secretstream-xchacha20poly1305-rekey.php */ function sodium_crypto_secretstream_xchacha20poly1305_rekey(string &$state): void {} /** * @param string $string * @param int $id * @return string * @throws SodiumException * @since 7.2 * @see https://www.php.net/manual/en/function.sodium-bin2base64.php */ function sodium_bin2base64(string $string, int $id): string {} /** * @param string $string * @param int $id * @param string $ignore * @throws SodiumException * @since 7.2 * @see https://www.php.net/manual/en/function.sodium-base642bin.php * @return string */ function sodium_base642bin(string $string, int $id, string $ignore = ''): string {} class SodiumException extends Exception {} 'int'], default: '')] $revents) {} /** * Returns the loop responsible for the watcher. * * @return EvLoop Event loop object responsible for the watcher. */ public function getLoop() {} /** * Invokes the watcher callback with the given received events bit mask. * * @param int $revents Bit mask of watcher received events. */ public function invoke(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $revents) {} /** * Configures whether to keep the loop from returning. * * Configures whether to keep the loop from returning. With keepalive value set to FALSE the watcher won't keep * Ev::run() / EvLoop::run() from returning even though the watcher is active. * * Watchers have keepalive value TRUE by default. * * Clearing keepalive status is useful when returning from Ev::run() / EvLoop::run() just because of the watcher * is undesirable. It could be a long running UDP socket watcher or so. * * @param bool $value With keepalive value set to FALSE the watcher won't keep Ev::run() / EvLoop::run() from * returning even though the watcher is active. */ public function keepalive(#[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $value = true) {} /** * Sets new callback for the watcher. * * @param callable $callback void callback ([ object $watcher = NULL [, int $revents = NULL ]] ) */ public function setCallback(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $callback) {} /** * Starts the watcher. * * Marks the watcher as active. Note that only active watchers will receive events. */ public function start() {} /** * Stops the watcher. * * Marks the watcher as inactive. Note that only active watchers will receive events. */ public function stop() {} } /** * Class EvCheck * * EvPrepare and EvCheck watchers are usually used in pairs. EvPrepare watchers get invoked before the process blocks, * EvCheck afterwards. * * It is not allowed to call EvLoop::run() or similar methods or functions that enter the current event loop from either * EvPrepare or EvCheck watchers. Other loops than the current one are fine, however. The rationale behind this is that * one don't need to check for recursion in those watchers, i.e. the sequence will always be: EvPrepare -> blocking -> * EvCheck , so having a watcher of each kind they will always be called in pairs bracketing the blocking call. * * The main purpose is to integrate other event mechanisms into libev and their use is somewhat advanced. They could be * used, for example, to track variable changes, implement custom watchers, integrate net-snmp or a coroutine library * and lots more. They are also occasionally useful to cache some data and want to flush it before blocking. * * It is recommended to give EvCheck watchers highest( Ev::MAXPRI ) priority, to ensure that they are being run before * any other watchers after the poll (this doesn’t matter for EvPrepare watchers). * * Also, EvCheck watchers should not activate/feed events. While libev fully supports this, they might get executed * before other EvCheck watchers did their job. */ final class EvCheck extends EvWatcher { /** * @param callable $callback * @param mixed $data * @param int $priority */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $callback, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $data = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $priority = 0 ) {} /** * @param callable $callback * @param mixed $data * @param int $priority * @return EvCheck */ final public static function createStopped(mixed $callback, mixed $data = null, int $priority = 0) {} } /** * Class EvChild * * EvChild watchers trigger when the process receives a SIGCHLD in response to some child status changes (most typically * when a child dies or exits). It is permissible to install an EvChild watcher after the child has been forked (which * implies it might have already exited), as long as the event loop isn't entered(or is continued from a watcher), i.e. * forking and then immediately registering a watcher for the child is fine, but forking and registering a watcher a few * event loop iterations later or in the next callback invocation is not. * * It is allowed to register EvChild watchers in the default loop only. */ final class EvChild extends EvWatcher { /** * @var int The process ID this watcher watches out for, or 0, meaning any process ID. */ #[Immutable] public $pid; /** * @var int The process ID that detected a status change. */ #[Immutable] public $rpid; /** * @var int The process exit status caused by rpid. */ #[Immutable] public $rstatus; /** * Constructs the EvChild watcher object. * * Call the callback when a status change for process ID pid (or any PID if pid is 0) has been received (a status * change happens when the process terminates or is killed, or, when trace is TRUE, additionally when it is stopped * or continued). In other words, when the process receives a SIGCHLD, Ev will fetch the outstanding exit/wait * status for all changed/zombie children and call the callback. * * It is valid to install a child watcher after an EvChild has exited but before the event loop has started its next * iteration. For example, first one calls fork , then the new child process might exit, and only then an EvChild * watcher is installed in the parent for the new PID . * * You can access both exit/tracing status and pid by using the rstatus and rpid properties of the watcher object. * * The number of PID watchers per PID is unlimited. All of them will be called. * * The EvChild::createStopped() method doesn't start(activate) the newly created watcher. * * @param int $pid Wait for status changes of process PID(or any process if PID is specified as 0 ). * @param bool $trace If FALSE, only activate the watcher when the process terminates. Otherwise(TRUE) additionally * activate the watcher when the process is stopped or continued. * @param callable $callback * @param mixed $data * @param int $priority */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $pid, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $trace, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $callback, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $data = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $priority = 0 ) {} /** * Create instance of a stopped EvCheck watcher. * * The same as EvChild::__construct() , but doesn't start the watcher automatically. * * @param int $pid Wait for status changes of process PID(or any process if PID is specified as 0 ). * @param bool $trace If FALSE, only activate the watcher when the process terminates. Otherwise(TRUE) additionally * activate the watcher when the process is stopped or continued. * @param callable $callback * @param mixed $data * @param int $priority * * @return EvChild */ final public static function createStopped(int $pid, bool $trace, mixed $callback, mixed $data = null, int $priority = 0) {} /** * Configures the watcher * * @param int $pid Wait for status changes of process PID(or any process if PID is specified as 0 ). * @param bool $trace If FALSE, only activate the watcher when the process terminates. Otherwise(TRUE) additionally * activate the watcher when the process is stopped or continued. */ public function set( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $pid, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $trace ) {} } /** * Class EvEmbed * * Used to embed one event loop into another. */ final class EvEmbed extends EvWatcher { /** * @var EvLoop The embedded loop */ #[Immutable] public $embed; /** * Constructs the EvEmbed object. * * This is a rather advanced watcher type that lets to embed one event loop into another(currently only IO events * are supported in the embedded loop, other types of watchers might be handled in a delayed or incorrect fashion * and must not be used). * * See the libev documentation for details. * * This watcher is most useful on BSD systems without working kqueue to still be able to handle a large number of * sockets. * * @param EvLoop $other The loop to embed, this loop must be embeddable(see Ev::embeddableBackends()). * @param callable $callback * @param mixed $data * @param int $priority */ public function __construct( EvLoop $other, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $callback, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $data = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $priority = 0 ) {} /** * Configures the watcher. * * @param EvLoop $other The loop to embed, this loop must be embeddable(see Ev::embeddableBackends()). */ public function set(EvLoop $other) {} /** * Make a single, non-blocking sweep over the embedded loop. */ public function sweep() {} /** * Create stopped EvEmbed watcher object * * The same as EvEmbed::__construct() , but doesn't start the watcher automatically. * * @param EvLoop $other The loop to embed, this loop must be embeddable(see Ev::embeddableBackends()). * @param callable $callback * @param mixed $data * @param int $priority * * @return EvEmbed */ final public static function createStopped(EvLoop $other, mixed $callback, mixed $data = null, int $priority = 0) {} } /** * Class EvIo * * EvIo watchers check whether a file descriptor(or socket, or a stream castable to numeric file descriptor) is readable * or writable in each iteration of the event loop, or, more precisely, when reading would not block the process and * writing would at least be able to write some data. This behaviour is called level-triggering because events are kept * receiving as long as the condition persists. To stop receiving events just stop the watcher. * * The number of read and/or write event watchers per fd is unlimited. Setting all file descriptors to non-blocking mode * is also usually a good idea (but not required). * * Another thing to watch out for is that it is quite easy to receive false readiness notifications, i.e. the callback * might be called with Ev::READ but a subsequent read() will actually block because there is no data. It is very easy * to get into this situation. Thus it is best to always use non-blocking I/O: An extra read() returning EAGAIN (or * similar) is far preferable to a program hanging until some data arrives. * * If for some reason it is impossible to run the fd in non-blocking mode, then separately re-test whether a file * descriptor is really ready. Some people additionally use SIGALRM and an interval timer, just to be sure they won't * block infinitely. * * Always consider using non-blocking mode. */ final class EvIo extends EvWatcher { /** * @var resource A stream opened with fopen() or similar functions, numeric file descriptor, or socket. */ #[Immutable] public $fd; /** * @var int Ev::READ and/or Ev::WRITE. See the bit masks. */ #[Immutable] #[ExpectedValues(flags: [Ev::READ, Ev::WRITE])] public $events; /** * Constructs EvIo watcher object. * * Constructs EvIo watcher object and starts the watcher automatically. * * @param resource $fd A stream opened with fopen() or similar functions, numeric file descriptor, or socket. * @param int $events Ev::READ and/or Ev::WRITE. See the bit masks. * @param callable $callback * @param mixed $data * @param int $priority */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $fd, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $events, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $callback, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $data = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $priority = 0 ) {} /** * Configures the watcher. * * @param resource $fd A stream opened with fopen() or similar functions, numeric file descriptor, or socket. * @param int $events Ev::READ and/or Ev::WRITE. See the bit masks. */ public function set( #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $fd, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $events ) {} /** * Create stopped EvIo watcher object. * * The same as EvIo::__construct() , but doesn't start the watcher automatically. * * @param resource $fd A stream opened with fopen() or similar functions, numeric file descriptor, or socket. * @param int $events Ev::READ and/or Ev::WRITE. See the bit masks. * @param callable $callback * @param mixed $data * @param int $priority * * @return EvIo */ final public static function createStopped(mixed $fd, int $events, mixed $callback, mixed $data = null, int $priority = 0) {} } /** * Class EvPeriodic * * Periodic watchers are also timers of a kind, but they are very versatile. * * Unlike EvTimer, EvPeriodic watchers are not based on real time (or relative time, the physical time that passes) but * on wall clock time (absolute time, calendar or clock). The difference is that wall clock time can run faster or * slower than real time, and time jumps are not uncommon (e.g. when adjusting it). * * EvPeriodic watcher can be configured to trigger after some specific point in time. For example, if an EvPeriodic * watcher is configured to trigger "in 10 seconds" (e.g. EvLoop::now() + 10.0 , i.e. an absolute time, not a delay), * and the system clock is reset to January of the previous year , then it will take a year or more to trigger the event * (unlike an EvTimer , which would still trigger roughly 10 seconds after starting it as it uses a relative timeout). * * As with timers, the callback is guaranteed to be invoked only when the point in time where it is supposed to trigger * has passed. If multiple timers become ready during the same loop iteration then the ones with earlier time-out values * are invoked before ones with later time-out values (but this is no longer true when a callback calls EvLoop::run() * recursively). */ final class EvPeriodic extends EvWatcher { /** * @var float When repeating, this contains the offset value, otherwise this is the absolute point in time (the * offset value passed to EvPeriodic::set(), although libev might modify this value for better numerical * stability). */ public $offset; /** * @var float The current interval value. Can be modified any time, but changes only take effect when the periodic * timer fires or EvPeriodic::again() is being called. */ public $interval; /** * Constructs EvPeriodic watcher object. * * Constructs EvPeriodic watcher object and starts it automatically. EvPeriodic::createStopped() method creates * stopped periodic watcher. * * @param float $offset When repeating, this contains the offset value, otherwise this is the absolute point in * time (the offset value passed to EvPeriodic::set(), although libev might modify this value for better * numerical stability). * @param float $interval The current interval value. Can be modified any time, but changes only take effect when * the periodic timer fires or EvPeriodic::again() is being called. * @param null|callable $reschedule_cb If set, tt must return the next time to trigger, based on the passed time value * (that is, the lowest time value larger than or equal to the second argument). It will usually be called just * before the callback will be triggered, but might be called at other times, too. * @param callable $callback * @param mixed $data * @param int $priority */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'float'], default: '')] $offset, #[LanguageLevelTypeAware(['8.0' => 'float'], default: '')] $interval, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $reschedule_cb, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $callback, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $data = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $priority = 0 ) {} /** * Simply stops and restarts the periodic watcher again. * * Simply stops and restarts the periodic watcher again. This is only useful when attributes are changed. * * @return void */ public function again() {} /** * Returns the absolute time that this watcher is supposed to trigger next. * * When the watcher is active, returns the absolute time that this watcher is supposed to trigger next. This is not * the same as the offset argument to EvPeriodic::set() or EvPeriodic::__construct(), but indeed works even in * interval mode. * * @return float Rhe absolute time this watcher is supposed to trigger next in seconds. */ public function at() {} /** * Create a stopped EvPeriodic watcher * * Create EvPeriodic object. Unlike EvPeriodic::__construct() this method doesn't start the watcher automatically. * * @param float $offset When repeating, this contains the offset value, otherwise this is the absolute point in * time (the offset value passed to EvPeriodic::set(), although libev might modify this value for better * numerical stability). * @param float $interval The current interval value. Can be modified any time, but changes only take effect when * the periodic timer fires or EvPeriodic::again() is being called. * @param null|callable $reschedule_cb If set, tt must return the next time to trigger, based on the passed time value * (that is, the lowest time value larger than or equal to the second argument). It will usually be called just * before the callback will be triggered, but might be called at other times, too. * @param callable $callback * @param mixed $data * @param int $priority * * @return EvPeriodic */ final public static function createStopped(float $offset, float $interval, mixed $reschedule_cb, mixed $callback, mixed $data = null, int $priority = 0) {} /** * Configures the watcher * @param float $offset The same meaning as for {@see EvPeriodic::__construct} * @param float $interval The same meaning as for {@see EvPeriodic::__construct} * @param null|callable $reschedule_cb The same meaning as for {@see EvPeriodic::__construct} * @return void */ public function set( #[LanguageLevelTypeAware(['8.0' => 'float'], default: '')] $offset, #[LanguageLevelTypeAware(['8.0' => 'float'], default: '')] $interval, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $reschedule_cb = null ) {} } /** * Class EvPrepare * * EvPrepare and EvCheck watchers are usually used in pairs. EvPrepare watchers get invoked before the process blocks, * EvCheck afterwards. * * It is not allowed to call EvLoop::run() or similar methods or functions that enter the current event loop from either * EvPrepare or EvCheck watchers. Other loops than the current one are fine, however. The rationale behind this is that * one don't need to check for recursion in those watchers, i.e. the sequence will always be: EvPrepare -> blocking -> * EvCheck, so having a watcher of each kind they will always be called in pairs bracketing the blocking call. * * The main purpose is to integrate other event mechanisms into libev and their use is somewhat advanced. They could be * used, for example, to track variable changes, implement custom watchers, integrate net-snmp or a coroutine library * and lots more. They are also occasionally useful to cache some data and want to flush it before blocking. * * It is recommended to give EvCheck watchers highest (Ev::MAXPRI) priority, to ensure that they are being run before * any other watchers after the poll (this doesn’t matter for EvPrepare watchers). * * Also, EvCheck watchers should not activate/feed events. While libev fully supports this, they might get executed * before other EvCheck watchers did their job. */ final class EvPrepare extends EvWatcher { /** * Constructs EvPrepare watcher object. * * Constructs EvPrepare watcher object and starts the watcher automatically. If you need a stopped watcher, consider * using EvPrepare::createStopped(). * * @param callable $callback * @param mixed $data * @param int $priority */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $callback, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $data = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $priority = 0 ) {} /** * Creates a stopped instance of EvPrepare watcher. * * Creates a stopped instance of EvPrepare watcher. Unlike EvPrepare::__construct(), this method doesn't start the * watcher automatically. * * @param callable $callback * @param mixed $data * @param int $priority * * @return EvPrepare */ final public static function createStopped(mixed $callback, mixed $data = null, int $priority = 0) {} } /** * Class EvSignal * * EvSignal watchers will trigger an event when the process receives a specific signal one or more times. Even though * signals are very asynchronous, libev will try its best to deliver signals synchronously, i.e. as part of the normal * event processing, like any other event. * * There is no limit for the number of watchers for the same signal, but only within the same loop, i.e. one can watch * for SIGINT in the default loop and for SIGIO in another loop, but it is not allowed to watch for SIGINT in both the * default loop and another loop at the same time. At the moment, SIGCHLD is permanently tied to the default loop. * * If possible and supported, libev will install its handlers with SA_RESTART (or equivalent) behaviour enabled, so * system calls should not be unduly interrupted. In case of a problem with system calls getting interrupted by signals, * all the signals can be blocked in an EvCheck watcher and unblocked in a EvPrepare watcher. */ final class EvSignal extends EvWatcher { /** * @var int Signal number. See the constants exported by pcntl extension. See also signal(7) man page. */ #[Immutable] public $signum; /** * Constructs EvSignal watcher object * * @param int $signum Signal number. See the constants exported by pcntl extension. See also signal(7) man page. * @param callable $callback * @param mixed $data * @param int $priority */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $signum, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $callback, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $data = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $priority = 0 ) {} /** * Configures the watcher. * * @param int $signum Signal number. See the constants exported by pcntl extension. See also signal(7) man page. */ public function set(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $signum) {} /** * Creates a stopped instance of EvSignal watcher. * * Creates a stopped instance of EvSignal watcher. Unlike EvPrepare::__construct(), this method doesn't start the * watcher automatically. * * @param int $signum Signal number. See the constants exported by pcntl extension. See also signal(7) man page. * @param callable $callback * @param mixed $data * @param int $priority * * @return EvSignal */ final public static function createStopped(int $signum, mixed $callback, mixed $data = null, int $priority = 0) {} } /** * Class EvStat * * EvStat monitors a file system path for attribute changes. It calls stat() on that path in regular intervals (or when * the OS signals it changed) and sees if it changed compared to the last time, invoking the callback if it did. * * The path does not need to exist: changing from "path exists" to "path does not exist" is a status change like any * other. The condition "path does not exist" is signified by the 'nlink' item being 0 (returned by EvStat::attr() * method). * * The path must not end in a slash or contain special components such as '.' or '..'. The path should be absolute: if * it is relative and the working directory changes, then the behaviour is undefined. * * Since there is no portable change notification interface available, the portable implementation simply calls stat() * regularly on the path to see if it changed somehow. For this case a recommended polling interval can be specified. If * one specifies a polling interval of 0.0 (highly recommended) then a suitable, unspecified default value will be used * (which could be expected to be around 5 seconds, although this might change dynamically). libev will also impose a * minimum interval which is currently around 0.1 , but that’s usually overkill. * * This watcher type is not meant for massive numbers of EvStat watchers, as even with OS-supported change * notifications, this can be resource-intensive. */ final class EvStat extends EvWatcher { /** * @var float Hint on how quickly a change is expected to be detected and should normally be * specified as 0.0 to let libev choose a suitable value. */ #[Immutable] public $interval; /** * @var string The path to wait for status changes on. */ #[Immutable] public $path; /** * Constructs EvStat watcher object. * * Constructs EvStat watcher object and starts the watcher automatically. * * @param string $path The path to wait for status changes on. * @param float $interval Hint on how quickly a change is expected to be detected and should normally be specified * as 0.0 to let libev choose a suitable value. * @param callable $callback * @param mixed $data * @param int $priority */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $path, #[LanguageLevelTypeAware(['8.0' => 'float'], default: '')] $interval, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $callback, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $data = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $priority = 0 ) {} /** * @return array The values most recently detect by Ev (without actual stat'ing). See stat(2) man page for details. */ public function attr() {} /** * @return array Just like EvStat::attr() , but returns the previous set of values. */ public function prev() {} /** * Configures the watcher. * * @param string $path The path to wait for status changes on. * @param float $interval Hint on how quickly a change is expected to be detected and should normally be specified * as 0.0 to let libev choose a suitable value. */ public function set( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $path, #[LanguageLevelTypeAware(['8.0' => 'float'], default: '')] $interval ) {} /** * Initiates the stat call. * * Initiates the stat call(updates internal cache). It stats (using lstat) the path specified in the watcher and * sets the internal cache to the values found. * * @return bool TRUE if path exists. Otherwise FALSE. */ public function stat() {} /** * Create a stopped EvStat watcher object. * * Creates EvStat watcher object, but doesn't start it automatically (unlike EvStat::__construct()). * * @param string $path The path to wait for status changes on. * @param float $interval Hint on how quickly a change is expected to be detected and should normally be specified * as 0.0 to let libev choose a suitable value. * @param callable $callback * @param mixed $data * @param int $priority * * @return EvStat */ final public static function createStopped(string $path, float $interval, mixed $callback, mixed $data = null, int $priority = 0) {} } /** * Class EvTimer * * EvTimer watchers are simple relative timers that generate an event after a given time, and optionally repeating in * regular intervals after that. * * The timers are based on real time, that is, if one registers an event that times out after an hour and resets the * system clock to January last year, it will still time out after( roughly) one hour. "Roughly" because detecting time * jumps is hard, and some inaccuracies are unavoidable. * * The callback is guaranteed to be invoked only after its timeout has passed (not at, so on systems with very * low-resolution clocks this might introduce a small delay). If multiple timers become ready during the same loop * iteration then the ones with earlier time-out values are invoked before ones of the same priority with later time-out * values (but this is no longer true when a callback calls EvLoop::run() recursively). * * The timer itself will do a best-effort at avoiding drift, that is, if a timer is configured to trigger every 10 * seconds, then it will normally trigger at exactly 10 second intervals. If, however, the script cannot keep up with * the timer (because it takes longer than those 10 seconds to do) the timer will not fire more than once per event loop * iteration. */ final class EvTimer extends EvWatcher { /** * @var float If repeat is 0.0, then it will automatically be stopped once the timeout is reached. If it is * positive, then the timer will automatically be configured to trigger again every repeat seconds later, until * stopped manually. */ public $repeat; /** * @var float The remaining time until a timer fires. If the timer is active, then this time is relative to the * current event loop time, otherwise it's the timeout value currently configured. * * That is, after instantiating an EvTimer with an after value of 5.0 and repeat value of 7.0, remaining * returns 5.0. When the timer is started and one second passes, remaining will return 4.0 . When the timer * expires and is restarted, it will return roughly 7.0 (likely slightly less as callback invocation takes some * time too), and so on. */ public $remaining; /** * Constructs an EvTimer watcher object. * * @param float $after Configures the timer to trigger after $after seconds. * @param float $repeat If repeat is 0.0, then it will automatically be stopped once the timeout is reached. If it * is positive, then the timer will automatically be configured to trigger again every repeat seconds later, * until stopped manually. * @param callable $callback * @param mixed $data * @param int $priority */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'float'], default: '')] $after, #[LanguageLevelTypeAware(['8.0' => 'float'], default: '')] $repeat, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $callback, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $data = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $priority = 0 ) {} /** * Restarts the timer watcher. * * This will act as if the timer timed out and restart it again if it is repeating. The exact semantics are: * * - if the timer is pending, its pending status is cleared. * - if the timer is started but non-repeating, stop it (as if it timed out). * - if the timer is repeating, either start it if necessary (with the repeat value), or reset the running timer to * the repeat value. */ public function again() {} /** * Configures the watcher. * * @param float $after Configures the timer to trigger after $after seconds. * @param float $repeat If repeat is 0.0, then it will automatically be stopped once the timeout is reached. If it * is positive, then the timer will automatically be configured to trigger again every repeat seconds later, * until stopped manually. */ public function set( #[LanguageLevelTypeAware(['8.0' => 'float'], default: '')] $after, #[LanguageLevelTypeAware(['8.0' => 'float'], default: '')] $repeat ) {} /** * Creates a stopped EvTimer watcher object. * * @param float $after Configures the timer to trigger after $after seconds. * @param float $repeat If repeat is 0.0, then it will automatically be stopped once the timeout is reached. If it * is positive, then the timer will automatically be configured to trigger again every repeat seconds later, * until stopped manually. * @param callable $callback * @param mixed $data * @param int $priority * * @return EvTimer */ final public static function createStopped(float $after, float $repeat, mixed $callback, mixed $data = null, int $priority = 0) {} } /** * Class EvIdle * * EvIdle watchers trigger events when no other events of the same or higher priority are pending (EvPrepare, EvCheck * and other EvIdle watchers do not count as receiving events). * * Thus, as long as the process is busy handling sockets or timeouts (or even signals) of the same or higher priority it * will not be triggered. But when the process is idle (or only lower-priority watchers are pending), the EvIdle * watchers are being called once per event loop iteration - until stopped, that is, or the process receives more events * and becomes busy again with higher priority stuff. * * Apart from keeping the process non-blocking (which is a useful on its own sometimes), EvIdle watchers are a good * place to do "pseudo-background processing", or delay processing stuff to after the event loop has handled all * outstanding events. * * The most noticeable effect is that as long as any idle watchers are active, the process will not block when waiting * for new events. */ final class EvIdle extends EvWatcher { /** * Constructs an EvIdle instance. * * @param callable $callback * @param mixed $data * @param int $priority */ public function __construct(mixed $callback, mixed $data = null, int $priority = 0) {} /** * Creates a stopped EvIdle instance. * * @param callable $callback * @param mixed $data * @param int $priority * * @return EvIdle */ final public static function createStopped(mixed $callback, mixed $data = null, int $priority = 0) {} } /** * Class EvFork * * Fork watchers are called when a fork() was detected (usually because whoever signalled libev about it by calling * EvLoop::fork()). The invocation is done before the event loop blocks next and before EvCheck watchers are being * called, and only in the child after the fork. Note that if someone calls EvLoop::fork() in the wrong process, the * fork handlers will be invoked, too. */ final class EvFork extends EvWatcher { /** * Constructs an EvFork instance. * * @param callable $callback * @param mixed $data * @param int $priority */ public function __construct(EvLoop $loop, mixed $callback, mixed $data = null, int $priority = 0) {} /** * Creates a stopped EvFork instance. * * @param callable $callback * @param mixed $data * @param int $priority * * @return EvFork */ final public static function createStopped(EvLoop $loop, mixed $callback, mixed $data = null, int $priority = 0) {} } /** * Class EvLoop * * Represents an event loop that is always distinct from the default loop. Unlike the default loop, it cannot handle * EvChild watchers. * * Having threads we have to create a loop per thread, and use the the default loop in the parent thread. * * The default event loop is initialized automatically by Ev. It is accessible via methods of the Ev class, or via * EvLoop::defaultLoop() method. */ final class EvLoop { /** * @var int The Ev::BACKEND_* flag indicating the event backend in use. */ #[Immutable] #[ExpectedValues(flags: [Ev::BACKEND_ALL, Ev::BACKEND_DEVPOLL, Ev::BACKEND_EPOLL, Ev::BACKEND_KQUEUE, Ev::BACKEND_MASK, Ev::BACKEND_POLL, Ev::BACKEND_PORT, Ev::BACKEND_SELECT])] public $backend; /** * @var bool TRUE if it is the default event loop. */ #[Immutable] public $is_default_loop; /** * @var mixed Custom data attached to the loop. */ public $data; /** * @var int The current iteration count of the loop. See Ev::iteration(). */ public $iteration; /** * @var int The number of pending watchers. 0 indicates that there are no watchers pending. */ public $pending; /** * @var float Higher io_interval allows libev to spend more time collecting EvIo events, so more events can be * handled per iteration, at the cost of increasing latency. Timeouts (both EvPeriodic and EvTimer) will not be * affected. Setting this to a non-zero value will introduce an additional sleep() call into most loop * iterations. The sleep time ensures that libev will not poll for EvIo events more often than once per this * interval, on average. Many programs can usually benefit by setting the io_interval to a value near 0.1, * which is often enough for interactive servers (not for games). It usually doesn't make much sense to set it * to a lower value than 0.01, as this approaches the timing granularity of most systems. */ public $io_interval; /** * @var float Higher timeout_interval allows libev to spend more time collecting timeouts, at the expense of * increased latency/jitter/inexactness (the watcher callback will be called later). EvIo watchers will not be * affected. Setting this to a non-null value will not introduce any overhead in libev. */ public $timeout_interval; /** * @var int The recursion depth. */ public $depth; /** * @param int $flags * @param mixed $data * @param float $io_interval * @param float $timeout_interval */ public function __construct(int $flags = Ev::FLAG_AUTO, mixed $data = null, float $io_interval = 0.0, float $timeout_interval = 0.0) {} /** * Returns an integer describing the backend used by libev. * * @return int An integer describing the backend used by libev. See Ev::backend(). */ public function backend() {} /** * Creates EvCheck object associated with the current event loop instance. * * @param callable $callback * @param mixed $data * @param int $priority * @return EvCheck */ final public function check(callable $callback, $data = null, $priority = 0) {} /** * Creates EvChild object associated with the current event loop instance; * @link https://www.php.net/manual/en/evloop.child.php * @param int $pid * @param bool $trace * @param callable $callback * @param mixed $data * @param int $priority * @return EvChild */ final public function child(int $pid, bool $trace, mixed $callback, mixed $data = null, int $priority = 0) {} /** * Creates EvEmbed object associated with the current event loop instance. * * @param EvLoop $other * @param callable $callback * @param mixed $data * @param int $priority * @return EvEmbed */ final public function embed(EvLoop $other, callable $callback, $data = null, $priority = 0) {} /** * Creates EvFork object associated with the current event loop instance. * * @param callable $callback * @param mixed $data * @param int $priority * @return EvFork */ final public function fork(callable $callback, $data = null, $priority = 0) {} /** * Creates EvIdle object associated with the current event loop instance. * * @param callable $callback * @param null $data * @param int $priority * @return EvIdle */ final public function idle(mixed $callback, mixed $data = null, int $priority = 0) {} /** * Invoke all pending watchers while resetting their pending state. */ public function invokePending() {} /** * Creates EvIo object associated with the current event loop instance. * * @param resource $fd * @param int $events * @param callable $callback * @param mixed $data * @param int $priority * @return EvIo */ final public function io(mixed $fd, int $events, mixed $callback, mixed $data = null, int $priority = 0) {} /** * Must be called after a fork. * * Must be called after a fork in the child, before entering or continuing the event loop. An alternative is to use * Ev::FLAG_FORKCHECK which calls this function automatically, at some performance loss (refer to the libev * documentation). */ public function loopFork() {} /** * Returns the current "event loop time". * * Returns the current "event loop time", which is the time the event loop received events and started processing * them. This timestamp does not change as long as callbacks are being processed, and this is also the base time * used for relative timers. You can treat it as the timestamp of the event occurring (or more correctly, libev * finding out about it). * * @return float Time of the event loop in (fractional) seconds. */ public function now() {} /** * Establishes the current time by querying the kernel, updating the time returned by Ev::now in the progress. * * Establishes the current time by querying the kernel, updating the time returned by Ev::now() in the progress. * This is a costly operation and is usually done automatically within Ev::run(). * * This method is rarely useful, but when some event callback runs for a very long time without entering the event * loop, updating libev's consideration of the current time is a good idea. */ public function nowUpdate() {} /** * Creates EvPeriodic object associated with the current event loop instance. * * @param float $offset * @param float $interval * @param callable $reschedule_cb * @param callable $callback * @param mixed $data * @param int $priority */ final public function periodic(float $offset, float $interval, mixed $reschedule_cb, mixed $callback, mixed $data = null, int $priority = 0) {} /** * Creates EvPrepare object associated with the current event loop instance. * * @param callable $callback * @param mixed $data * @param int $priority */ final public function prepare(callable $callback, $data = null, $priority = 0) {} /** * Resume previously suspended default event loop. * * EvLoop::suspend() and EvLoop::resume() methods suspend and resume a loop correspondingly. */ public function resume() {} /** * Begin checking for events and calling callbacks for the loop. * * Begin checking for events and calling callbacks for the current event loop. Returns when a callback calls * Ev::stop() method, or the flags are nonzero (in which case the return value is true) or when there are no active * watchers which reference the loop (EvWatcher::keepalive() is TRUE), in which case the return value will be FALSE. * The return value can generally be interpreted as if TRUE, there is more work left to do. * * @param int $flags One of the Ev::RUN_* flags. */ public function run(int $flags = Ev::FLAG_AUTO) {} /** * Creates EvSignal object associated with the current event loop instance. * * @param int $signum * @param callable $callback * @param mixed $data * @param int $priority * @return EvSignal */ final public function signal(int $signum, mixed $callback, mixed $data = null, int $priority = 0) {} /** * Creates EvStats object associated with the current event loop instance. * * @param string $path * @param float $interval * @param callable $callback * @param mixed $data * @param int $priority * @return EvStat */ final public function stat(string $path, float $interval, mixed $callback, mixed $data = null, int $priority = 0) {} /** * Stops the event loop. * * @param int $how One of the Ev::BREAK_* flags. */ public function stop(int $how = Ev::BREAK_ALL) {} /** * Suspend the loop. * * EvLoop::suspend() and EvLoop::resume() methods suspend and resume a loop correspondingly. */ public function suspend() {} /** * Creates EvTimer object associated with the current event loop instance. * * @param float $after * @param float $repeat * @param callable $callback * @param mixed $data * @param int $priority * @return EvTimer */ final public function timer(float $after, float $repeat, mixed $callback, mixed $data = null, int $priority = 0) {} /** * Performs internal consistency checks (for debugging). * * Performs internal consistency checks (for debugging libev) and abort the program if any data structures were * found to be corrupted. */ public function verify() {} /** * Returns or creates the default event loop. * * If the default event loop is not created, EvLoop::defaultLoop() creates it with the specified parameters. * Otherwise, it just returns the object representing previously created instance ignoring all the parameters. * * @param int $flags * @param mixed $data * @param float $io_interval * @param float $timeout_interval * @return EvLoop */ public static function defaultLoop( int $flags = Ev::FLAG_AUTO, mixed $data = null, float $io_interval = 0.0, float $timeout_interval = 0.0 ): EvLoop {} } version: 1.0 failThreshold: 100 profile: path: Inspections.xml exclude: - name: PhpInconsistentReturnPointsInspection - name: PhpTooManyParametersInspection - name: PhpUnnecessaryDoubleQuotesInspection - name: PhpMissingParentCallCommonInspection - name: PhpMissingParentCallMagicInspection - name: PhpMissingParentConstructorInspection - name: PhpMissingReturnTypeInspection - name: PhpMissingParamTypeInspection - name: PhpDefineCanBeReplacedWithConstInspection - name: PhpReturnDocTypeMismatchInspection - name: PhpDocRedundantThrowsInspection - name: PhpMissingStrictTypesDeclarationInspection - name: PhpUnused paths: - aerospike - amqp - apache - apcu - ast - bcmath - blackfire - bz2 - calendar - cassandra - com_dotnet - Core - couchbase - couchbase_v2 - crypto - ctype - cubrid - curl - date - dba - decimal - dio - dom - ds - enchant - Ev - event - exif - expect - fann - FFI - ffmpeg - fileinfo - filter - fpm - ftp - gd - gearman - geoip - geos - gettext - gmagick - gmp - gnupg - grpc - hash - http - ibm_db2 - iconv - igbinary - imagick - imap - inotify - interbase - intl - json - judy - ldap - leveldb - libevent - libsodium - libvirt-php - libxml - lua - LuaSandbox - lzf - mailparse - mapscript - mbstring - mcrypt - memcache - memcached - meminfo - meta - ming - mongo - mongodb - mosquitto-php - mqseries - msgpack - mssql - mysql - mysql_xdevapi - mysqli - ncurses - newrelic - oauth - oci8 - odbc - openssl - parallel - Parle - pcntl - pcov - pcre - pdflib - PDO - pdo_ibm - pdo_mysql - pdo_pgsql - pdo_sqlite - pgsql - Phar - phpdbg - posix - pq - pspell - pthreads - radius - rar - rdkafka - readline - recode - redis - Reflection - regex - rpminfo - rrd - SaxonC - session - shmop - SimpleXML - snmp - soap - sockets - sodium - solr - SPL - SplType - SQLite - sqlite3 - sqlsrv - ssh2 - standard - stats - stomp - suhosin - superglobals - svm - svn - sybase - sync - sysvmsg - sysvsem - sysvshm - tidy - tokenizer - uopz - uuid - uv - v8js - vendor - wddx - win32service - winbinder - wincache - xcache - xdebug - xdiff - xhprof - xlswriter - xml - xmlreader - xmlrpc - xmlwriter - xsl - xxtea - yaf - yaml - yar - zend - Zend OPcache - ZendCache - ZendDebugger - ZendUtils - zip - zlib - zmp - zmq - zookeeper - zstd Enables or disables payload compression. When enabled, * item values longer than a certain threshold (currently 100 bytes) will be * compressed during storage and decompressed during retrieval * transparently.

    *

    Type: boolean, default: TRUE.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_COMPRESSION = -1001; public const OPT_COMPRESSION_TYPE = -1004; /** *

    This can be used to create a "domain" for your item keys. The value * specified here will be prefixed to each of the keys. It cannot be * longer than 128 characters and will reduce the * maximum available key size. The prefix is applied only to the item keys, * not to the server keys.

    *

    Type: string, default: "".

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_PREFIX_KEY = -1002; /** *

    * Specifies the serializer to use for serializing non-scalar values. * The valid serializers are Memcached::SERIALIZER_PHP * or Memcached::SERIALIZER_IGBINARY. The latter is * supported only when memcached is configured with * --enable-memcached-igbinary option and the * igbinary extension is loaded. *

    *

    Type: integer, default: Memcached::SERIALIZER_PHP.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_SERIALIZER = -1003; /** *

    Indicates whether igbinary serializer support is available.

    *

    Type: boolean.

    * @link https://php.net/manual/en/memcached.constants.php */ public const HAVE_IGBINARY = false; /** *

    Indicates whether JSON serializer support is available.

    *

    Type: boolean.

    * @link https://php.net/manual/en/memcached.constants.php */ public const HAVE_JSON = false; /** *

    Indicates whether msgpack serializer support is available.

    *

    Type: boolean.

    * Available as of Memcached 3.0.0. * @since 3.0.0 * @link https://php.net/manual/en/memcached.constants.php */ public const HAVE_MSGPACK = false; /** *

    Indicate whether set_encoding_key is available

    *

    Type: boolean.

    * @link https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/memcached-api.php, https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/php_memcached.c#L4387 */ public const HAVE_ENCODING = false; /** * Feature support */ public const HAVE_SESSION = true; public const HAVE_SASL = false; /** *

    Specifies the hashing algorithm used for the item keys. The valid * values are supplied via Memcached::HASH_* constants. * Each hash algorithm has its advantages and its disadvantages. Go with the * default if you don't know or don't care.

    *

    Type: integer, default: Memcached::HASH_DEFAULT

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_HASH = 2; /** *

    The default (Jenkins one-at-a-time) item key hashing algorithm.

    * @link https://php.net/manual/en/memcached.constants.php */ public const HASH_DEFAULT = 0; /** *

    MD5 item key hashing algorithm.

    * @link https://php.net/manual/en/memcached.constants.php */ public const HASH_MD5 = 1; /** *

    CRC item key hashing algorithm.

    * @link https://php.net/manual/en/memcached.constants.php */ public const HASH_CRC = 2; /** *

    FNV1_64 item key hashing algorithm.

    * @link https://php.net/manual/en/memcached.constants.php */ public const HASH_FNV1_64 = 3; /** *

    FNV1_64A item key hashing algorithm.

    * @link https://php.net/manual/en/memcached.constants.php */ public const HASH_FNV1A_64 = 4; /** *

    FNV1_32 item key hashing algorithm.

    * @link https://php.net/manual/en/memcached.constants.php */ public const HASH_FNV1_32 = 5; /** *

    FNV1_32A item key hashing algorithm.

    * @link https://php.net/manual/en/memcached.constants.php */ public const HASH_FNV1A_32 = 6; /** *

    Hsieh item key hashing algorithm.

    * @link https://php.net/manual/en/memcached.constants.php */ public const HASH_HSIEH = 7; /** *

    Murmur item key hashing algorithm.

    * @link https://php.net/manual/en/memcached.constants.php */ public const HASH_MURMUR = 8; /** *

    Specifies the method of distributing item keys to the servers. * Currently supported methods are modulo and consistent hashing. Consistent * hashing delivers better distribution and allows servers to be added to * the cluster with minimal cache losses.

    *

    Type: integer, default: Memcached::DISTRIBUTION_MODULA.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_DISTRIBUTION = 9; /** *

    Modulo-based key distribution algorithm.

    * @link https://php.net/manual/en/memcached.constants.php */ public const DISTRIBUTION_MODULA = 0; /** *

    Consistent hashing key distribution algorithm (based on libketama).

    * @link https://php.net/manual/en/memcached.constants.php */ public const DISTRIBUTION_CONSISTENT = 1; public const DISTRIBUTION_VIRTUAL_BUCKET = 6; /** *

    Enables or disables compatibility with libketama-like behavior. When * enabled, the item key hashing algorithm is set to MD5 and distribution is * set to be weighted consistent hashing distribution. This is useful * because other libketama-based clients (Python, Ruby, etc.) with the same * server configuration will be able to access the keys transparently. *

    *

    * It is highly recommended to enable this option if you want to use * consistent hashing, and it may be enabled by default in future * releases. *

    *

    Type: boolean, default: FALSE.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_LIBKETAMA_COMPATIBLE = 16; public const OPT_LIBKETAMA_HASH = 17; public const OPT_TCP_KEEPALIVE = 32; /** *

    Enables or disables buffered I/O. Enabling buffered I/O causes * storage commands to "buffer" instead of being sent. Any action that * retrieves data causes this buffer to be sent to the remote connection. * Quitting the connection or closing down the connection will also cause * the buffered data to be pushed to the remote connection.

    *

    Type: boolean, default: FALSE.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_BUFFER_WRITES = 10; /** *

    Enable the use of the binary protocol. Please note that you cannot * toggle this option on an open connection.

    *

    Type: boolean, default: FALSE.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_BINARY_PROTOCOL = 18; /** *

    Enables or disables asynchronous I/O. This is the fastest transport * available for storage functions.

    *

    Type: boolean, default: FALSE.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_NO_BLOCK = 0; /** *

    Enables or disables the no-delay feature for connecting sockets (may * be faster in some environments).

    *

    Type: boolean, default: FALSE.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_TCP_NODELAY = 1; /** *

    The maximum socket send buffer in bytes.

    *

    Type: integer, default: varies by platform/kernel * configuration.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_SOCKET_SEND_SIZE = 4; /** *

    The maximum socket receive buffer in bytes.

    *

    Type: integer, default: varies by platform/kernel * configuration.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_SOCKET_RECV_SIZE = 5; /** *

    In non-blocking mode this set the value of the timeout during socket * connection, in milliseconds.

    *

    Type: integer, default: 1000.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_CONNECT_TIMEOUT = 14; /** *

    The amount of time, in seconds, to wait until retrying a failed * connection attempt.

    *

    Type: integer, default: 0.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_RETRY_TIMEOUT = 15; /** *

    Socket sending timeout, in microseconds. In cases where you cannot * use non-blocking I/O this will allow you to still have timeouts on the * sending of data.

    *

    Type: integer, default: 0.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_SEND_TIMEOUT = 19; /** *

    Socket reading timeout, in microseconds. In cases where you cannot * use non-blocking I/O this will allow you to still have timeouts on the * reading of data.

    *

    Type: integer, default: 0.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_RECV_TIMEOUT = 20; /** *

    Timeout for connection polling, in milliseconds.

    *

    Type: integer, default: 1000.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_POLL_TIMEOUT = 8; /** *

    Enables or disables caching of DNS lookups.

    *

    Type: boolean, default: FALSE.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_CACHE_LOOKUPS = 6; /** *

    Specifies the failure limit for server connection attempts. The * server will be removed after this many continuous connection * failures.

    *

    Type: integer, default: 0.

    * @link https://php.net/manual/en/memcached.constants.php */ public const OPT_SERVER_FAILURE_LIMIT = 21; public const OPT_AUTO_EJECT_HOSTS = 28; public const OPT_HASH_WITH_PREFIX_KEY = 25; public const OPT_NOREPLY = 26; public const OPT_SORT_HOSTS = 12; public const OPT_VERIFY_KEY = 13; public const OPT_USE_UDP = 27; public const OPT_NUMBER_OF_REPLICAS = 29; public const OPT_RANDOMIZE_REPLICA_READ = 30; public const OPT_CORK = 31; public const OPT_REMOVE_FAILED_SERVERS = 35; public const OPT_DEAD_TIMEOUT = 36; public const OPT_SERVER_TIMEOUT_LIMIT = 37; public const OPT_MAX = 38; public const OPT_IO_BYTES_WATERMARK = 23; public const OPT_IO_KEY_PREFETCH = 24; public const OPT_IO_MSG_WATERMARK = 22; public const OPT_LOAD_FROM_FILE = 34; public const OPT_SUPPORT_CAS = 7; public const OPT_TCP_KEEPIDLE = 33; public const OPT_USER_DATA = 11; /** * libmemcached result codes */ /** *

    The operation was successful.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_SUCCESS = 0; /** *

    The operation failed in some fashion.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_FAILURE = 1; /** *

    DNS lookup failed.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_HOST_LOOKUP_FAILURE = 2; /** *

    Failed to read network data.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_UNKNOWN_READ_FAILURE = 7; /** *

    Bad command in memcached protocol.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_PROTOCOL_ERROR = 8; /** *

    Error on the client side.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_CLIENT_ERROR = 9; /** *

    Error on the server side.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_SERVER_ERROR = 10; /** *

    Failed to write network data.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_WRITE_FAILURE = 5; /** *

    Failed to do compare-and-swap: item you are trying to store has been * modified since you last fetched it.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_DATA_EXISTS = 12; /** *

    Item was not stored: but not because of an error. This normally * means that either the condition for an "add" or a "replace" command * wasn't met, or that the item is in a delete queue.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_NOTSTORED = 14; /** *

    Item with this key was not found (with "get" operation or "cas" * operations).

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_NOTFOUND = 16; /** *

    Partial network data read error.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_PARTIAL_READ = 18; /** *

    Some errors occurred during multi-get.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_SOME_ERRORS = 19; /** *

    Server list is empty.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_NO_SERVERS = 20; /** *

    End of result set.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_END = 21; /** *

    System error.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_ERRNO = 26; /** *

    The operation was buffered.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_BUFFERED = 32; /** *

    The operation timed out.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_TIMEOUT = 31; /** *

    Bad key.

    * @link https://php.net/manual/en/memcached.constants.php, http://docs.libmemcached.org/index.html */ /** *

    MEMCACHED_BAD_KEY_PROVIDED: The key provided is not a valid key.

    */ public const RES_BAD_KEY_PROVIDED = 33; /** *

    MEMCACHED_STORED: The requested object has been successfully stored on the server.

    */ public const RES_STORED = 15; /** *

    MEMCACHED_DELETED: The object requested by the key has been deleted.

    */ public const RES_DELETED = 22; /** *

    MEMCACHED_STAT: A “stat” command has been returned in the protocol.

    */ public const RES_STAT = 24; /** *

    MEMCACHED_ITEM: An item has been fetched (this is an internal error only).

    */ public const RES_ITEM = 25; /** *

    MEMCACHED_NOT_SUPPORTED: The given method is not supported in the server.

    */ public const RES_NOT_SUPPORTED = 28; /** *

    MEMCACHED_FETCH_NOTFINISHED: A request has been made, but the server has not finished the fetch of the last request.

    */ public const RES_FETCH_NOTFINISHED = 30; /** *

    MEMCACHED_SERVER_MARKED_DEAD: The requested server has been marked dead.

    */ public const RES_SERVER_MARKED_DEAD = 35; /** *

    MEMCACHED_UNKNOWN_STAT_KEY: The server you are communicating with has a stat key which has not be defined in the protocol.

    */ public const RES_UNKNOWN_STAT_KEY = 36; /** *

    MEMCACHED_INVALID_HOST_PROTOCOL: The server you are connecting too has an invalid protocol. Most likely you are connecting to an older server that does not speak the binary protocol.

    */ public const RES_INVALID_HOST_PROTOCOL = 34; /** *

    MEMCACHED_MEMORY_ALLOCATION_FAILURE: An error has occurred while trying to allocate memory.

    */ public const RES_MEMORY_ALLOCATION_FAILURE = 17; /** *

    MEMCACHED_E2BIG: Item is too large for the server to store.

    */ public const RES_E2BIG = 37; /** *

    MEMCACHED_KEY_TOO_BIG: The key that has been provided is too large for the given server.

    */ public const RES_KEY_TOO_BIG = 39; /** *

    MEMCACHED_SERVER_TEMPORARILY_DISABLED

    */ public const RES_SERVER_TEMPORARILY_DISABLED = 47; /** *

    MEMORY_ALLOCATION_FAILURE: An error has occurred while trying to allocate memory. * * #if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000008

    */ public const RES_SERVER_MEMORY_ALLOCATION_FAILURE = 48; /** *

    MEMCACHED_AUTH_PROBLEM: An unknown issue has occured during authentication.

    */ public const RES_AUTH_PROBLEM = 40; /** *

    MEMCACHED_AUTH_FAILURE: The credentials provided are not valid for this server.

    */ public const RES_AUTH_FAILURE = 41; /** *

    MEMCACHED_AUTH_CONTINUE: Authentication has been paused.

    */ public const RES_AUTH_CONTINUE = 42; /** *

    MEMCACHED_CONNECTION_FAILURE: A unknown error has occured while trying to connect to a server.

    */ public const RES_CONNECTION_FAILURE = 3; /** * MEMCACHED_CONNECTION_BIND_FAILURE: We were not able to bind() to the socket. */ #[Deprecated('Deprecated since version 0.30(libmemcached)')] public const RES_CONNECTION_BIND_FAILURE = 4; /** *

    MEMCACHED_READ_FAILURE: A read failure has occurred.

    */ public const RES_READ_FAILURE = 6; /** *

    MEMCACHED_DATA_DOES_NOT_EXIST: The data requested with the key given was not found.

    */ public const RES_DATA_DOES_NOT_EXIST = 13; /** *

    MEMCACHED_VALUE: A value has been returned from the server (this is an internal condition only).

    */ public const RES_VALUE = 23; /** *

    MEMCACHED_FAIL_UNIX_SOCKET: A connection was not established with the server via a unix domain socket.

    */ public const RES_FAIL_UNIX_SOCKET = 27; /** * No key was provided.

    */ #[Deprecated('Deprecated since version 0.30 (libmemcached). Use MEMCACHED_BAD_KEY_PROVIDED instead.')] public const RES_NO_KEY_PROVIDED = 29; /** *

    MEMCACHED_INVALID_ARGUMENTS: The arguments supplied to the given function were not valid.

    */ public const RES_INVALID_ARGUMENTS = 38; /** *

    MEMCACHED_PARSE_ERROR: An error has occurred while trying to parse the configuration string. You should use memparse to determine what the error was.

    */ public const RES_PARSE_ERROR = 43; /** *

    MEMCACHED_PARSE_USER_ERROR: An error has occurred in parsing the configuration string.

    */ public const RES_PARSE_USER_ERROR = 44; /** *

    MEMCACHED_DEPRECATED: The method that was requested has been deprecated.

    */ public const RES_DEPRECATED = 45; //unknow public const RES_IN_PROGRESS = 46; /** *

    MEMCACHED_MAXIMUM_RETURN: This in an internal only state.

    */ public const RES_MAXIMUM_RETURN = 49; /** * Server callbacks, if compiled with --memcached-protocol * @link https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/memcached-api.php */ public const ON_CONNECT = 0; public const ON_ADD = 1; public const ON_APPEND = 2; public const ON_DECREMENT = 3; public const ON_DELETE = 4; public const ON_FLUSH = 5; public const ON_GET = 6; public const ON_INCREMENT = 7; public const ON_NOOP = 8; public const ON_PREPEND = 9; public const ON_QUIT = 10; public const ON_REPLACE = 11; public const ON_SET = 12; public const ON_STAT = 13; public const ON_VERSION = 14; /** * Constants used when compiled with --memcached-protocol * @link https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/memcached-api.php */ public const RESPONSE_SUCCESS = 0; public const RESPONSE_KEY_ENOENT = 1; public const RESPONSE_KEY_EEXISTS = 2; public const RESPONSE_E2BIG = 3; public const RESPONSE_EINVAL = 4; public const RESPONSE_NOT_STORED = 5; public const RESPONSE_DELTA_BADVAL = 6; public const RESPONSE_NOT_MY_VBUCKET = 7; public const RESPONSE_AUTH_ERROR = 32; public const RESPONSE_AUTH_CONTINUE = 33; public const RESPONSE_UNKNOWN_COMMAND = 129; public const RESPONSE_ENOMEM = 130; public const RESPONSE_NOT_SUPPORTED = 131; public const RESPONSE_EINTERNAL = 132; public const RESPONSE_EBUSY = 133; public const RESPONSE_ETMPFAIL = 134; /** *

    Failed to create network socket.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_CONNECTION_SOCKET_CREATE_FAILURE = 11; /** *

    Payload failure: could not compress/decompress or serialize/unserialize the value.

    * @link https://php.net/manual/en/memcached.constants.php */ public const RES_PAYLOAD_FAILURE = -1001; /** *

    The default PHP serializer.

    * @link https://php.net/manual/en/memcached.constants.php */ public const SERIALIZER_PHP = 1; /** *

    The igbinary serializer. * Instead of textual representation it stores PHP data structures in a * compact binary form, resulting in space and time gains.

    * @link https://php.net/manual/en/memcached.constants.php */ public const SERIALIZER_IGBINARY = 2; /** *

    The JSON serializer. Requires PHP 5.2.10+.

    * @link https://php.net/manual/en/memcached.constants.php */ public const SERIALIZER_JSON = 3; public const SERIALIZER_JSON_ARRAY = 4; /** *

    The msgpack serializer.

    * @link https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/memcached-api.php */ public const SERIALIZER_MSGPACK = 5; public const COMPRESSION_FASTLZ = 2; public const COMPRESSION_ZLIB = 1; /** *

    A flag for Memcached::getMulti and * Memcached::getMultiByKey to ensure that the keys are * returned in the same order as they were requested in. Non-existing keys * get a default value of NULL.

    * @link https://php.net/manual/en/memcached.constants.php */ public const GET_PRESERVE_ORDER = 1; /** * A flag for Memcached::get(), Memcached::getMulti() and * Memcached::getMultiByKey() to ensure that the CAS token values are returned as well. * @link https://php.net/manual/en/memcached.constants.php * @since 3.0.0 */ public const GET_EXTENDED = 2; public const GET_ERROR_RETURN_VALUE = false; /** * (PECL memcached >= 0.1.0)
    * Create a Memcached instance * @link https://php.net/manual/en/memcached.construct.php, https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/php_memcached.c * @param string $persistent_id [optional] * @param callable $on_new_object_cb [optional] * @param string $connection_str [optional] */ public function __construct($persistent_id = '', $on_new_object_cb = null, $connection_str = '') {} /** * (PECL memcached >= 0.1.0)
    * Return the result code of the last operation * @link https://php.net/manual/en/memcached.getresultcode.php * @return int Result code of the last Memcached operation. */ public function getResultCode() {} /** * (PECL memcached >= 1.0.0)
    * Return the message describing the result of the last operation * @link https://php.net/manual/en/memcached.getresultmessage.php * @return string Message describing the result of the last Memcached operation. */ public function getResultMessage() {} /** * (PECL memcached >= 0.1.0)
    * Retrieve an item * @link https://php.net/manual/en/memcached.get.php * @param string $key

    * The key of the item to retrieve. *

    * @param callable $cache_cb [optional]

    * Read-through caching callback or NULL. *

    * @param int $flags [optional]

    * The flags for the get operation. *

    * @return mixed the value stored in the cache or FALSE otherwise. * The Memcached::getResultCode will return * Memcached::RES_NOTFOUND if the key does not exist. */ public function get($key, callable $cache_cb = null, $flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Retrieve an item from a specific server * @link https://php.net/manual/en/memcached.getbykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param string $key

    * The key of the item to fetch. *

    * @param callable $cache_cb [optional]

    * Read-through caching callback or NULL *

    * @param int $flags [optional]

    * The flags for the get operation. *

    * @return mixed the value stored in the cache or FALSE otherwise. * The Memcached::getResultCode will return * Memcached::RES_NOTFOUND if the key does not exist. */ public function getByKey($server_key, $key, callable $cache_cb = null, $flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Retrieve multiple items * @link https://php.net/manual/en/memcached.getmulti.php * @param array $keys

    * Array of keys to retrieve. *

    * @param int $flags [optional]

    * The flags for the get operation. *

    * @return mixed the array of found items or FALSE on failure. * Use Memcached::getResultCode if necessary. */ public function getMulti(array $keys, $flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Retrieve multiple items from a specific server * @link https://php.net/manual/en/memcached.getmultibykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param array $keys

    * Array of keys to retrieve. *

    * @param int $flags [optional]

    * The flags for the get operation. *

    * @return array|false the array of found items or FALSE on failure. * Use Memcached::getResultCode if necessary. */ public function getMultiByKey($server_key, array $keys, $flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Request multiple items * @link https://php.net/manual/en/memcached.getdelayed.php * @param array $keys

    * Array of keys to request. *

    * @param bool $with_cas [optional]

    * Whether to request CAS token values also. *

    * @param callable $value_cb [optional]

    * The result callback or NULL. *

    * @return bool TRUE on success or FALSE on failure. * Use Memcached::getResultCode if necessary. */ public function getDelayed(array $keys, $with_cas = null, callable $value_cb = null) {} /** * (PECL memcached >= 0.1.0)
    * Request multiple items from a specific server * @link https://php.net/manual/en/memcached.getdelayedbykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param array $keys

    * Array of keys to request. *

    * @param bool $with_cas [optional]

    * Whether to request CAS token values also. *

    * @param callable $value_cb [optional]

    * The result callback or NULL. *

    * @return bool TRUE on success or FALSE on failure. * Use Memcached::getResultCode if necessary. */ public function getDelayedByKey($server_key, array $keys, $with_cas = null, callable $value_cb = null) {} /** * (PECL memcached >= 0.1.0)
    * Fetch the next result * @link https://php.net/manual/en/memcached.fetch.php * @return array|false the next result or FALSE otherwise. * The Memcached::getResultCode will return * Memcached::RES_END if result set is exhausted. */ public function fetch() {} /** * (PECL memcached >= 0.1.0)
    * Fetch all the remaining results * @link https://php.net/manual/en/memcached.fetchall.php * @return array|false the results or FALSE on failure. * Use Memcached::getResultCode if necessary. */ public function fetchAll() {} /** * (PECL memcached >= 0.1.0)
    * Store an item * @link https://php.net/manual/en/memcached.set.php * @param string $key

    * The key under which to store the value. *

    * @param mixed $value

    * The value to store. *

    * @param int $expiration [optional]

    * The expiration time, defaults to 0. See Expiration Times for more info. *

    * @param int $udf_flags [optional] * @return bool TRUE on success or FALSE on failure. * Use Memcached::getResultCode if necessary. */ public function set($key, $value, $expiration = 0, $udf_flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Store an item on a specific server * @link https://php.net/manual/en/memcached.setbykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param string $key

    * The key under which to store the value. *

    * @param mixed $value

    * The value to store. *

    * @param int $expiration [optional]

    * The expiration time, defaults to 0. See Expiration Times for more info. *

    * @param int $udf_flags [optional] * @return bool TRUE on success or FALSE on failure. * Use Memcached::getResultCode if necessary. */ public function setByKey($server_key, $key, $value, $expiration = 0, $udf_flags = 0) {} /** * (PECL memcached >= 2.0.0)
    * Set a new expiration on an item * @link https://php.net/manual/en/memcached.touch.php * @param string $key

    * The key under which to store the value. *

    * @param int $expiration

    * The expiration time, defaults to 0. See Expiration Times for more info. *

    * @return bool TRUE on success or FALSE on failure. * Use Memcached::getResultCode if necessary. */ public function touch($key, $expiration = 0) {} /** * (PECL memcached >= 2.0.0)
    * Set a new expiration on an item on a specific server * @link https://php.net/manual/en/memcached.touchbykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param string $key

    * The key under which to store the value. *

    * @param int $expiration

    * The expiration time, defaults to 0. See Expiration Times for more info. *

    * @return bool TRUE on success or FALSE on failure. * Use Memcached::getResultCode if necessary. */ public function touchByKey($server_key, $key, $expiration) {} /** * (PECL memcached >= 0.1.0)
    * Store multiple items * @link https://php.net/manual/en/memcached.setmulti.php * @param array $items

    * An array of key/value pairs to store on the server. *

    * @param int $expiration [optional]

    * The expiration time, defaults to 0. See Expiration Times for more info. *

    * @param int $udf_flags [optional] * @return bool TRUE on success or FALSE on failure. * Use Memcached::getResultCode if necessary. */ public function setMulti(array $items, $expiration = 0, $udf_flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Store multiple items on a specific server * @link https://php.net/manual/en/memcached.setmultibykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param array $items

    * An array of key/value pairs to store on the server. *

    * @param int $expiration [optional]

    * The expiration time, defaults to 0. See Expiration Times for more info. *

    * @param int $udf_flags [optional] * @return bool TRUE on success or FALSE on failure. * Use Memcached::getResultCode if necessary. */ public function setMultiByKey($server_key, array $items, $expiration = 0, $udf_flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Compare and swap an item * @link https://php.net/manual/en/memcached.cas.php * @param float $cas_token

    * Unique value associated with the existing item. Generated by memcache. *

    * @param string $key

    * The key under which to store the value. *

    * @param mixed $value

    * The value to store. *

    * @param int $expiration [optional]

    * The expiration time, defaults to 0. See Expiration Times for more info. *

    * @param int $udf_flags [optional] * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_DATA_EXISTS if the item you are trying * to store has been modified since you last fetched it. */ public function cas($cas_token, $key, $value, $expiration = 0, $udf_flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Compare and swap an item on a specific server * @link https://php.net/manual/en/memcached.casbykey.php * @param float $cas_token

    * Unique value associated with the existing item. Generated by memcache. *

    * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param string $key

    * The key under which to store the value. *

    * @param mixed $value

    * The value to store. *

    * @param int $expiration [optional]

    * The expiration time, defaults to 0. See Expiration Times for more info. *

    * @param int $udf_flags [optional] * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_DATA_EXISTS if the item you are trying * to store has been modified since you last fetched it. */ public function casByKey($cas_token, $server_key, $key, $value, $expiration = 0, $udf_flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Add an item under a new key * @link https://php.net/manual/en/memcached.add.php * @param string $key

    * The key under which to store the value. *

    * @param mixed $value

    * The value to store. *

    * @param int $expiration [optional]

    * The expiration time, defaults to 0. See Expiration Times for more info. *

    * @param int $udf_flags [optional] * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_NOTSTORED if the key already exists. */ public function add($key, $value, $expiration = 0, $udf_flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Add an item under a new key on a specific server * @link https://php.net/manual/en/memcached.addbykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param string $key

    * The key under which to store the value. *

    * @param mixed $value

    * The value to store. *

    * @param int $expiration [optional]

    * The expiration time, defaults to 0. See Expiration Times for more info. *

    * @param int $udf_flags [optional] * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_NOTSTORED if the key already exists. */ public function addByKey($server_key, $key, $value, $expiration = 0, $udf_flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Append data to an existing item * @link https://php.net/manual/en/memcached.append.php * @param string $key

    * The key under which to store the value. *

    * @param string $value

    * The string to append. *

    * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_NOTSTORED if the key does not exist. */ public function append($key, $value) {} /** * (PECL memcached >= 0.1.0)
    * Append data to an existing item on a specific server * @link https://php.net/manual/en/memcached.appendbykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param string $key

    * The key under which to store the value. *

    * @param string $value

    * The string to append. *

    * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_NOTSTORED if the key does not exist. */ public function appendByKey($server_key, $key, $value) {} /** * (PECL memcached >= 0.1.0)
    * Prepend data to an existing item * @link https://php.net/manual/en/memcached.prepend.php * @param string $key

    * The key of the item to prepend the data to. *

    * @param string $value

    * The string to prepend. *

    * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_NOTSTORED if the key does not exist. */ public function prepend($key, $value) {} /** * (PECL memcached >= 0.1.0)
    * Prepend data to an existing item on a specific server * @link https://php.net/manual/en/memcached.prependbykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param string $key

    * The key of the item to prepend the data to. *

    * @param string $value

    * The string to prepend. *

    * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_NOTSTORED if the key does not exist. */ public function prependByKey($server_key, $key, $value) {} /** * (PECL memcached >= 0.1.0)
    * Replace the item under an existing key * @link https://php.net/manual/en/memcached.replace.php * @param string $key

    * The key under which to store the value. *

    * @param mixed $value

    * The value to store. *

    * @param int $expiration [optional]

    * The expiration time, defaults to 0. See Expiration Times for more info. *

    * @param int $udf_flags [optional] * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_NOTSTORED if the key does not exist. */ public function replace($key, $value, $expiration = null, $udf_flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Replace the item under an existing key on a specific server * @link https://php.net/manual/en/memcached.replacebykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param string $key

    * The key under which to store the value. *

    * @param mixed $value

    * The value to store. *

    * @param int $expiration [optional]

    * The expiration time, defaults to 0. See Expiration Times for more info. *

    * @param int $udf_flags [optional] * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_NOTSTORED if the key does not exist. */ public function replaceByKey($server_key, $key, $value, $expiration = null, $udf_flags = 0) {} /** * (PECL memcached >= 0.1.0)
    * Delete an item * @link https://php.net/manual/en/memcached.delete.php * @param string $key

    * The key to be deleted. *

    * @param int $time [optional]

    * The amount of time the server will wait to delete the item. *

    * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_NOTFOUND if the key does not exist. */ public function delete($key, $time = 0) {} /** * (PECL memcached >= 2.0.0)
    * Delete multiple items * @link https://php.net/manual/en/memcached.deletemulti.php * @param array $keys

    * The keys to be deleted. *

    * @param int $time [optional]

    * The amount of time the server will wait to delete the items. *

    * @return array Returns array indexed by keys and where values are indicating whether operation succeeded or not. * The Memcached::getResultCode will return * Memcached::RES_NOTFOUND if the key does not exist. */ public function deleteMulti(array $keys, $time = 0) {} /** * (PECL memcached >= 0.1.0)
    * Delete an item from a specific server * @link https://php.net/manual/en/memcached.deletebykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param string $key

    * The key to be deleted. *

    * @param int $time [optional]

    * The amount of time the server will wait to delete the item. *

    * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_NOTFOUND if the key does not exist. */ public function deleteByKey($server_key, $key, $time = 0) {} /** * (PECL memcached >= 2.0.0)
    * Delete multiple items from a specific server * @link https://php.net/manual/en/memcached.deletemultibykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param array $keys

    * The keys to be deleted. *

    * @param int $time [optional]

    * The amount of time the server will wait to delete the items. *

    * @return bool TRUE on success or FALSE on failure. * The Memcached::getResultCode will return * Memcached::RES_NOTFOUND if the key does not exist. */ public function deleteMultiByKey($server_key, array $keys, $time = 0) {} /** * (PECL memcached >= 0.1.0)
    * Increment numeric item's value * @link https://php.net/manual/en/memcached.increment.php * @param string $key

    * The key of the item to increment. *

    * @param int $offset [optional]

    * The amount by which to increment the item's value. *

    * @param int $initial_value [optional]

    * The value to set the item to if it doesn't currently exist. *

    * @param int $expiry [optional]

    * The expiry time to set on the item. *

    * @return int|false new item's value on success or FALSE on failure. */ public function increment($key, $offset = 1, $initial_value = 0, $expiry = 0) {} /** * (PECL memcached >= 0.1.0)
    * Decrement numeric item's value * @link https://php.net/manual/en/memcached.decrement.php * @param string $key

    * The key of the item to decrement. *

    * @param int $offset [optional]

    * The amount by which to decrement the item's value. *

    * @param int $initial_value [optional]

    * The value to set the item to if it doesn't currently exist. *

    * @param int $expiry [optional]

    * The expiry time to set on the item. *

    * @return int|false item's new value on success or FALSE on failure. */ public function decrement($key, $offset = 1, $initial_value = 0, $expiry = 0) {} /** * (PECL memcached >= 2.0.0)
    * Increment numeric item's value, stored on a specific server * @link https://php.net/manual/en/memcached.incrementbykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param string $key

    * The key of the item to increment. *

    * @param int $offset [optional]

    * The amount by which to increment the item's value. *

    * @param int $initial_value [optional]

    * The value to set the item to if it doesn't currently exist. *

    * @param int $expiry [optional]

    * The expiry time to set on the item. *

    * @return int|false new item's value on success or FALSE on failure. */ public function incrementByKey($server_key, $key, $offset = 1, $initial_value = 0, $expiry = 0) {} /** * (PECL memcached >= 2.0.0)
    * Decrement numeric item's value, stored on a specific server * @link https://php.net/manual/en/memcached.decrementbykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @param string $key

    * The key of the item to decrement. *

    * @param int $offset [optional]

    * The amount by which to decrement the item's value. *

    * @param int $initial_value [optional]

    * The value to set the item to if it doesn't currently exist. *

    * @param int $expiry [optional]

    * The expiry time to set on the item. *

    * @return int|false item's new value on success or FALSE on failure. */ public function decrementByKey($server_key, $key, $offset = 1, $initial_value = 0, $expiry = 0) {} /** * (PECL memcached >= 0.1.0)
    * Add a server to the server pool * @link https://php.net/manual/en/memcached.addserver.php * @param string $host

    * The hostname of the memcache server. If the hostname is invalid, data-related * operations will set * Memcached::RES_HOST_LOOKUP_FAILURE result code. *

    * @param int $port

    * The port on which memcache is running. Usually, this is * 11211. *

    * @param int $weight [optional]

    * The weight of the server relative to the total weight of all the * servers in the pool. This controls the probability of the server being * selected for operations. This is used only with consistent distribution * option and usually corresponds to the amount of memory available to * memcache on that server. *

    * @return bool TRUE on success or FALSE on failure. */ public function addServer($host, $port, $weight = 0) {} /** * (PECL memcached >= 0.1.1)
    * Add multiple servers to the server pool * @link https://php.net/manual/en/memcached.addservers.php * @param array $servers * @return bool TRUE on success or FALSE on failure. */ public function addServers(array $servers) {} /** * (PECL memcached >= 0.1.0)
    * Get the list of the servers in the pool * @link https://php.net/manual/en/memcached.getserverlist.php * @return array The list of all servers in the server pool. */ public function getServerList() {} /** * (PECL memcached >= 0.1.0)
    * Map a key to a server * @link https://php.net/manual/en/memcached.getserverbykey.php * @param string $server_key

    * The key identifying the server to store the value on or retrieve it from. Instead of hashing on the actual key for the item, we hash on the server key when deciding which memcached server to talk to. This allows related items to be grouped together on a single server for efficiency with multi operations. *

    * @return array an array containing three keys of host, * port, and weight on success or FALSE * on failure. * Use Memcached::getResultCode if necessary. */ public function getServerByKey($server_key) {} /** * (PECL memcached >= 2.0.0)
    * Clears all servers from the server list * @link https://php.net/manual/en/memcached.resetserverlist.php * @return bool TRUE on success or FALSE on failure. */ public function resetServerList() {} /** * (PECL memcached >= 2.0.0)
    * Close any open connections * @link https://php.net/manual/en/memcached.quit.php * @return bool TRUE on success or FALSE on failure. */ public function quit() {} /** * (PECL memcached >= 0.1.0)
    * Get server pool statistics * @link https://php.net/manual/en/memcached.getstats.php * @param string $type

    items, slabs, sizes ...

    * @return array|false Array of server statistics, one entry per server. */ public function getStats($type = null) {} /** * (PECL memcached >= 0.1.5)
    * Get server pool version info * @link https://php.net/manual/en/memcached.getversion.php * @return array Array of server versions, one entry per server. */ public function getVersion() {} /** * (PECL memcached >= 2.0.0)
    * Gets the keys stored on all the servers * @link https://php.net/manual/en/memcached.getallkeys.php * @return array|false the keys stored on all the servers on success or FALSE on failure. */ public function getAllKeys() {} /** * (PECL memcached >= 0.1.0)
    * Invalidate all items in the cache * @link https://php.net/manual/en/memcached.flush.php * @param int $delay [optional]

    * Numer of seconds to wait before invalidating the items. *

    * @return bool TRUE on success or FALSE on failure. * Use Memcached::getResultCode if necessary. */ public function flush($delay = 0) {} /** * (PECL memcached >= 0.1.0)
    * Retrieve a Memcached option value * @link https://php.net/manual/en/memcached.getoption.php * @param int $option

    * One of the Memcached::OPT_* constants. *

    * @return mixed the value of the requested option, or FALSE on * error. */ public function getOption($option) {} /** * (PECL memcached >= 0.1.0)
    * Set a Memcached option * @link https://php.net/manual/en/memcached.setoption.php * @param int $option * @param mixed $value * @return bool TRUE on success or FALSE on failure. */ public function setOption($option, $value) {} /** * (PECL memcached >= 2.0.0)
    * Set Memcached options * @link https://php.net/manual/en/memcached.setoptions.php * @param array $options

    * An associative array of options where the key is the option to set and * the value is the new value for the option. *

    * @return bool TRUE on success or FALSE on failure. */ public function setOptions(array $options) {} /** * (PECL memcached >= 2.0.0)
    * Set the credentials to use for authentication * @link https://secure.php.net/manual/en/memcached.setsaslauthdata.php * @param string $username

    * The username to use for authentication. *

    * @param string $password

    * The password to use for authentication. *

    * @return void */ public function setSaslAuthData(string $username, string $password) {} /** * (PECL memcached >= 2.0.0)
    * Check if a persitent connection to memcache is being used * @link https://php.net/manual/en/memcached.ispersistent.php * @return bool true if Memcache instance uses a persistent connection, false otherwise. */ public function isPersistent() {} /** * (PECL memcached >= 2.0.0)
    * Check if the instance was recently created * @link https://php.net/manual/en/memcached.ispristine.php * @return bool the true if instance is recently created, false otherwise. */ public function isPristine() {} /** * (PECL memcached >= 3.2.0)
    * Check if the given key is valid. * @param string $key * @return bool */ public function checkKey($key) {} /** * Flush and send buffered commands * @link https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/php_memcached.c * @return bool */ public function flushBuffers() {} /** * Sets AES encryption key (libmemcached 1.0.6 and higher) * @link https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/php_memcached.c * @param string $key * @return bool */ public function setEncodingKey($key) {} /** * Returns the last disconnected server. Was added in 0.34 according to libmemcached's Changelog * @link https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/php_memcached.c * @return array|false */ public function getLastDisconnectedServer() {} /** * Returns the last error errno that occurred * @link https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/php_memcached.c * @return int */ public function getLastErrorErrno() {} /** * Returns the last error code that occurred * @link https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/php_memcached.c * @return int */ public function getLastErrorCode() {} /** * Returns the last error message that occurred * @link https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/php_memcached.c * @return string */ public function getLastErrorMessage() {} /** * Sets the memcached virtual buckets * @link https://github.com/php-memcached-dev/php-memcached/blob/v3.1.5/php_memcached.c * @param array $host_map * @param array $forward_map * @param int $replicas * @return bool */ public function setBucket(array $host_map, array $forward_map, $replicas) {} } /** * @link https://php.net/manual/en/class.memcachedexception.php */ class MemcachedException extends RuntimeException { #[\JetBrains\PhpStorm\Pure] public function __construct($errmsg = "", $errcode = 0) {} } // End of memcached v.3.1.5 value pairs. * The constant_name must follow the normal constant naming rules. Value must evaluate to a scalar value. * @param bool $case_sensitive The default behaviour for constants is to be declared case-sensitive; * i.e. CONSTANT and Constant represent different values. If this parameter evaluates to FALSE * the constants will be declared as case-insensitive symbols. * @return bool Returns TRUE on success or FALSE on failure. */ function apc_define_constants($key, array $constants, $case_sensitive = true) {} /** * Caches a variable in the data store, only if it's not already stored * @link https://php.net/manual/en/function.apc-add.php * @param string $key Store the variable using this name. Keys are cache-unique, * so attempting to use apc_add() to store data with a key that already exists will not * overwrite the existing data, and will instead return FALSE. (This is the only difference * between apc_add() and apc_store().) * @param mixed $var The variable to store * @param int $ttl Time To Live; store var in the cache for ttl seconds. After the ttl has passed, * the stored variable will be expunged from the cache (on the next request). If no ttl is supplied * (or if the ttl is 0), the value will persist until it is removed from the cache manually, * or otherwise fails to exist in the cache (clear, restart, etc.). * @return bool */ function apc_add($key, $var, $ttl = 0) {} /** * Stores a file in the bytecode cache, bypassing all filters * @link https://php.net/manual/en/function.apc-compile-file.php * @param string|string[] $filename Full or relative path to a PHP file that will be * compiled and stored in the bytecode cache. * @param bool $atomic * @return bool Returns TRUE on success or FALSE on failure. */ function apc_compile_file($filename, $atomic = true) {} /** * Loads a set of constants from the cache * @link https://php.net/manual/en/function.apc-load-constants.php * @param string $key The name of the constant set (that was stored * with apc_define_constants()) to be retrieved. * @param bool $case_sensitive The default behaviour for constants is to be declared case-sensitive; * i.e. CONSTANT and Constant represent different values. If this parameter evaluates to FALSE * the constants will be declared as case-insensitive symbols. * @return bool Returns TRUE on success or FALSE on failure. */ function apc_load_constants($key, $case_sensitive = true) {} /** * Checks if APC key exists * @link https://php.net/manual/en/function.apc-exists.php * @param string|string[] $keys A string, or an array of strings, that contain keys. * @return bool|string[] Returns TRUE if the key exists, otherwise FALSE * Or if an array was passed to keys, then an array is returned that * contains all existing keys, or an empty array if none exist. */ function apc_exists($keys) {} /** * Deletes the given files from the opcode cache * * Accepts a string, array of strings, or APCIterator object. * Returns True/False, or for an Array an Array of failed files. * * @link https://php.net/manual/en/function.apc-delete-file.php * @param string|string[]|APCIterator $keys * @return bool|string[] */ function apc_delete_file($keys) {} /** * Increase a stored number * @link https://php.net/manual/en/function.apc-inc.php * @param string $key The key of the value being increased. * @param int $step The step, or value to increase. * @param bool|null &$success Optionally pass the success or fail boolean value to this referenced variable. * @return int|false Returns the current value of key's value on success, or FALSE on failure. */ function apc_inc($key, $step = 1, &$success = null) {} /** * Decrease a stored number * @link https://php.net/manual/en/function.apc-dec.php * @param string $key The key of the value being decreased. * @param int $step The step, or value to decrease. * @param bool|null &$success Optionally pass the success or fail boolean value to this referenced variable. * @return int|false Returns the current value of key's value on success, or FALSE on failure. */ function apc_dec($key, $step = 1, &$success = null) {} /** * Updates an old value with a new value * @link https://php.net/manual/en/function.apc-cas.php * @param string $key * @param int $old * @param int $new * @return bool */ function apc_cas($key, $old, $new) {} /** * Returns a binary dump of the given files and user variables from the APC cache * * A NULL for files or user_vars signals a dump of every entry, while array() will dump nothing. * * @link https://php.net/manual/en/function.apc-bin-dump.php * @param string[]|null $files The files. Passing in NULL signals a dump of every entry, while passing in array() will dump nothing. * @param string[]|null $user_vars The user vars. Passing in NULL signals a dump of every entry, while passing in array() will dump nothing. * @return string|false|null Returns a binary dump of the given files and user variables from the APC cache, FALSE if APC is not enabled, or NULL if an unknown error is encountered. */ function apc_bin_dump($files = null, $user_vars = null) {} /** * Output a binary dump of the given files and user variables from the APC cache to the named file * @link https://php.net/manual/en/function.apc-bin-dumpfile.php * @param string[]|null $files The file names being dumped. * @param string[]|null $user_vars The user variables being dumped. * @param string $filename The filename where the dump is being saved. * @param int $flags Flags passed to the filename stream. See the file_put_contents() documentation for details. * @param resource $context The context passed to the filename stream. See the file_put_contents() documentation for details. * @return int|false The number of bytes written to the file, otherwise FALSE if APC * is not enabled, filename is an invalid file name, filename can't be opened, * the file dump can't be completed (e.g., the hard drive is out of disk space), * or an unknown error was encountered. */ function apc_bin_dumpfile($files, $user_vars, $filename, $flags = 0, $context = null) {} /** * Load the given binary dump into the APC file/user cache * @link https://php.net/manual/en/function.apc-bin-load.php * @param string $data The binary dump being loaded, likely from apc_bin_dump(). * @param int $flags Either APC_BIN_VERIFY_CRC32, APC_BIN_VERIFY_MD5, or both. * @return bool Returns TRUE if the binary dump data was loaded with success, otherwise FALSE is returned. * FALSE is returned if APC is not enabled, or if the data is not a valid APC binary dump (e.g., unexpected size). */ function apc_bin_load($data, $flags = 0) {} /** * Load the given binary dump from the named file into the APC file/user cache * @link https://php.net/manual/en/function.apc-bin-loadfile.php * @param string $filename The file name containing the dump, likely from apc_bin_dumpfile(). * @param resource $context The files context. * @param int $flags Either APC_BIN_VERIFY_CRC32, APC_BIN_VERIFY_MD5, or both. * @return bool Returns TRUE on success, otherwise FALSE Reasons it may return FALSE include APC * is not enabled, filename is an invalid file name or empty, filename can't be opened, * the file dump can't be completed, or if the data is not a valid APC binary dump (e.g., unexpected size). */ function apc_bin_loadfile($filename, $context = null, $flags = 0) {} /** * The APCIterator class * * The APCIterator class makes it easier to iterate over large APC caches. * This is helpful as it allows iterating over large caches in steps, while grabbing a defined number * of entries per lock instance, so it frees the cache locks for other activities rather than hold up * the entire cache to grab 100 (the default) entries. Also, using regular expression matching is more * efficient as it's been moved to the C level. * * @link https://php.net/manual/en/class.apciterator.php */ class APCIterator implements Iterator { /** * Constructs an APCIterator iterator object * @link https://php.net/manual/en/apciterator.construct.php * @param string $cache The cache type, which will be 'user' or 'file'. * @param string|string[]|null $search A PCRE regular expression that matches against APC key names, * either as a string for a single regular expression, or as an array of regular expressions. * Or, optionally pass in NULL to skip the search. * @param int $format The desired format, as configured with one ore more of the APC_ITER_* constants. * @param int $chunk_size The chunk size. Must be a value greater than 0. The default value is 100. * @param int $list The type to list. Either pass in APC_LIST_ACTIVE or APC_LIST_INACTIVE. */ public function __construct($cache, $search = null, $format = APC_ITER_ALL, $chunk_size = 100, $list = APC_LIST_ACTIVE) {} /** * Rewinds back the iterator to the first element * @link https://php.net/manual/en/apciterator.rewind.php */ public function rewind() {} /** * Checks if the current iterator position is valid * @link https://php.net/manual/en/apciterator.valid.php * @return bool Returns TRUE if the current iterator position is valid, otherwise FALSE. */ public function valid() {} /** * Gets the current item from the APCIterator stack * @link https://php.net/manual/en/apciterator.current.php * @return mixed|false Returns the current item on success, or FALSE if no more items or exist, or on failure. */ public function current() {} /** * Gets the current iterator key * @link https://php.net/manual/en/apciterator.key.php * @return string|int|false Returns the key on success, or FALSE upon failure. */ public function key() {} /** * Moves the iterator pointer to the next element * @link https://php.net/manual/en/apciterator.next.php * @return bool Returns TRUE on success or FALSE on failure. */ public function next() {} /** * Gets the total number of cache hits * @link https://php.net/manual/en/apciterator.gettotalhits.php * @return int|false The number of hits on success, or FALSE on failure. */ public function getTotalHits() {} /** * Gets the total cache size * @link https://php.net/manual/en/apciterator.gettotalsize.php * @return int|bool The total cache size. */ public function getTotalSize() {} /** * Get the total count * @link https://php.net/manual/en/apciterator.gettotalcount.php * @return int|bool The total count. */ public function getTotalCount() {} } /** * Stubs for APCu 5.0.0 */ /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_LIST_ACTIVE', 1); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_LIST_DELETED', 2); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_TYPE', 1); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_KEY', 2); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_FILENAME', 4); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_DEVICE', 8); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_INODE', 16); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_VALUE', 32); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_MD5', 64); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_NUM_HITS', 128); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_MTIME', 256); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_CTIME', 512); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_DTIME', 1024); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_ATIME', 2048); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_REFCOUNT', 4096); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_MEM_SIZE', 8192); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_TTL', 16384); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_NONE', 0); /** * @link https://php.net/manual/en/apcu.constants.php */ define('APC_ITER_ALL', -1); /** * Clears the APCu cache * @link https://php.net/manual/en/function.apcu-clear-cache.php * * @return bool Returns TRUE always. */ function apcu_clear_cache() {} /** * Retrieves APCu Shared Memory Allocation information * @link https://php.net/manual/en/function.apcu-sma-info.php * @param bool $limited When set to FALSE (default) apcu_sma_info() will * return a detailed information about each segment. * * @return array|false Array of Shared Memory Allocation data; FALSE on failure. */ function apcu_sma_info($limited = false) {} /** * Cache a variable in the data store * @link https://php.net/manual/en/function.apcu-store.php * @param string|string[] $key String: Store the variable using this name. Keys are cache-unique, * so storing a second value with the same key will overwrite the original value. * Array: Names in key, variables in value. * @param mixed $var [optional] The variable to store * @param int $ttl [optional] Time To Live; store var in the cache for ttl seconds. After the ttl has passed, * the stored variable will be expunged from the cache (on the next request). If no ttl is supplied * (or if the ttl is 0), the value will persist until it is removed from the cache manually, * or otherwise fails to exist in the cache (clear, restart, etc.). * @return bool|array Returns TRUE on success or FALSE on failure | array with error keys. */ function apcu_store($key, $var, $ttl = 0) {} /** * Fetch a stored variable from the cache * @link https://php.net/manual/en/function.apcu-fetch.php * @param string|string[] $key The key used to store the value (with apcu_store()). * If an array is passed then each element is fetched and returned. * @param bool|null &$success Set to TRUE in success and FALSE in failure. * @return mixed|false The stored variable or array of variables on success; FALSE on failure. */ function apcu_fetch($key, &$success = null) {} /** * Removes a stored variable from the cache * @link https://php.net/manual/en/function.apcu-delete.php * @param string|string[]|APCUIterator $key The key used to store the value (with apcu_store()). * @return bool|string[] Returns TRUE on success or FALSE on failure. For array of keys returns list of failed keys. */ function apcu_delete($key) {} /** * Caches a variable in the data store, only if it's not already stored * @link https://php.net/manual/en/function.apcu-add.php * @param string|array $key Store the variable using this name. Keys are cache-unique, * so attempting to use apcu_add() to store data with a key that already exists will not * overwrite the existing data, and will instead return FALSE. (This is the only difference * between apcu_add() and apcu_store().) * Array: Names in key, variables in value. * @param mixed $var The variable to store * @param int $ttl Time To Live; store var in the cache for ttl seconds. After the ttl has passed, * the stored variable will be expunged from the cache (on the next request). If no ttl is supplied * (or if the ttl is 0), the value will persist until it is removed from the cache manually, * or otherwise fails to exist in the cache (clear, restart, etc.). * @return bool|array Returns TRUE if something has effectively been added into the cache, FALSE otherwise. * Second syntax returns array with error keys. */ function apcu_add($key, $var, $ttl = 0) {} /** * Checks if APCu key exists * @link https://php.net/manual/en/function.apcu-exists.php * @param string|string[] $keys A string, or an array of strings, that contain keys. * @return bool|string[] Returns TRUE if the key exists, otherwise FALSE * Or if an array was passed to keys, then an array is returned that * contains all existing keys, or an empty array if none exist. */ function apcu_exists($keys) {} /** * Increase a stored number * @link https://php.net/manual/en/function.apcu-inc.php * @param string $key The key of the value being increased. * @param int $step The step, or value to increase. * @param int $ttl Time To Live; store var in the cache for ttl seconds. After the ttl has passed, * the stored variable will be expunged from the cache (on the next request). If no ttl is supplied * (or if the ttl is 0), the value will persist until it is removed from the cache manually, * or otherwise fails to exist in the cache (clear, restart, etc.). * @param bool|null &$success Optionally pass the success or fail boolean value to this referenced variable. * @return int|false Returns the current value of key's value on success, or FALSE on failure. */ function apcu_inc($key, $step = 1, &$success = null, $ttl = 0) {} /** * Decrease a stored number * @link https://php.net/manual/en/function.apcu-dec.php * @param string $key The key of the value being decreased. * @param int $step The step, or value to decrease. * @param int $ttl Time To Live; store var in the cache for ttl seconds. After the ttl has passed, * the stored variable will be expunged from the cache (on the next request). If no ttl is supplied * (or if the ttl is 0), the value will persist until it is removed from the cache manually, * or otherwise fails to exist in the cache (clear, restart, etc.). * @param bool|null &$success Optionally pass the success or fail boolean value to this referenced variable. * @return int|false Returns the current value of key's value on success, or FALSE on failure. */ function apcu_dec($key, $step = 1, &$success = null, $ttl = 0) {} /** * Updates an old value with a new value * * apcu_cas() updates an already existing integer value if the old parameter matches the currently stored value * with the value of the new parameter. * * @link https://php.net/manual/en/function.apcu-cas.php * @param string $key The key of the value being updated. * @param int $old The old value (the value currently stored). * @param int $new The new value to update to. * @return bool Returns TRUE on success or FALSE on failure. */ function apcu_cas($key, $old, $new) {} /** * Atomically fetch or generate a cache entry * *

    Atomically attempts to find key in the cache, if it cannot be found generator is called, * passing key as the only argument. The return value of the call is then cached with the optionally * specified ttl, and returned. *

    * *

    Note: When control enters apcu_entry() the lock for the cache is acquired exclusively, it is released when * control leaves apcu_entry(): In effect, this turns the body of generator into a critical section, * disallowing two processes from executing the same code paths concurrently. * In addition, it prohibits the concurrent execution of any other APCu functions, * since they will acquire the same lock. *

    * * @link https://php.net/manual/en/function.apcu-entry.php * * @param string $key Identity of cache entry * @param callable $generator A callable that accepts key as the only argument and returns the value to cache. *

    Warning * The only APCu function that can be called safely by generator is apcu_entry().

    * @param int $ttl [optional] Time To Live; store var in the cache for ttl seconds. * After the ttl has passed, the stored variable will be expunged from the cache (on the next request). * If no ttl is supplied (or if the ttl is 0), the value will persist until it is removed from the cache manually, * or otherwise fails to exist in the cache (clear, restart, etc.). * @return mixed Returns the cached value * @since APCu 5.1.0 */ function apcu_entry($key, callable $generator, $ttl = 0) {} /** * Retrieves cached information from APCu's data store * * @link https://php.net/manual/en/function.apcu-cache-info.php * * @param bool $limited If limited is TRUE, the return value will exclude the individual list of cache entries. * This is useful when trying to optimize calls for statistics gathering. * @return array|false Array of cached data (and meta-data) or FALSE on failure */ function apcu_cache_info($limited = false) {} /** * Whether APCu is usable in the current environment * * @link https://www.php.net/manual/en/function.apcu-enabled.php * * @return bool */ function apcu_enabled() {} /** * @param string $key * @return array|null */ function apcu_key_info($key) {} /** * The APCUIterator class * * The APCUIterator class makes it easier to iterate over large APCu caches. * This is helpful as it allows iterating over large caches in steps, while grabbing a defined number * of entries per lock instance, so it frees the cache locks for other activities rather than hold up * the entire cache to grab 100 (the default) entries. Also, using regular expression matching is more * efficient as it's been moved to the C level. * * @link https://php.net/manual/en/class.apcuiterator.php * @since APCu 5.0.0 */ class APCUIterator implements Iterator { /** * Constructs an APCUIterator iterator object * @link https://php.net/manual/en/apcuiterator.construct.php * @param string|string[]|null $search A PCRE regular expression that matches against APCu key names, * either as a string for a single regular expression, or as an array of regular expressions. * Or, optionally pass in NULL to skip the search. * @param int $format The desired format, as configured with one ore more of the APC_ITER_* constants. * @param int $chunk_size The chunk size. Must be a value greater than 0. The default value is 100. * @param int $list The type to list. Either pass in APC_LIST_ACTIVE or APC_LIST_DELETED. */ public function __construct($search = null, $format = APC_ITER_ALL, $chunk_size = 100, $list = APC_LIST_ACTIVE) {} /** * Rewinds back the iterator to the first element * @link https://php.net/manual/en/apcuiterator.rewind.php */ public function rewind() {} /** * Checks if the current iterator position is valid * @link https://php.net/manual/en/apcuiterator.valid.php * @return bool Returns TRUE if the current iterator position is valid, otherwise FALSE. */ public function valid() {} /** * Gets the current item from the APCUIterator stack * @link https://php.net/manual/en/apcuiterator.current.php * @return mixed|false Returns the current item on success, or FALSE if no more items or exist, or on failure. */ public function current() {} /** * Gets the current iterator key * @link https://php.net/manual/en/apcuiterator.key.php * @return string|int|false Returns the key on success, or FALSE upon failure. */ public function key() {} /** * Moves the iterator pointer to the next element * @link https://php.net/manual/en/apcuiterator.next.php * @return bool Returns TRUE on success or FALSE on failure. */ public function next() {} /** * Gets the total number of cache hits * @link https://php.net/manual/en/apcuiterator.gettotalhits.php * @return int|false The number of hits on success, or FALSE on failure. */ public function getTotalHits() {} /** * Gets the total cache size * @link https://php.net/manual/en/apcuiterator.gettotalsize.php * @return int|false The total cache size. */ public function getTotalSize() {} /** * Get the total count * @link https://php.net/manual/en/apcuiterator.gettotalcount.php * @return int|false The total count. */ public function getTotalCount() {} } * Open MS SQL server connection * @link https://php.net/manual/en/function.mssql-connect.php * @param string $servername [optional]

    * The MS SQL server. It can also include a port number, e.g. * hostname:port (Linux), or * hostname,port (Windows). *

    * @param string $username [optional]

    * The username. *

    * @param string $password [optional]

    * The password. *

    * @param bool $new_link [optional]

    * If a second call is made to mssql_connect with the * same arguments, no new link will be established, but instead, the link * identifier of the already opened link will be returned. This parameter * modifies this behavior and makes mssql_connect * always open a new link, even if mssql_connect was * called before with the same parameters. *

    * @return resource|false a MS SQL link identifier on success, or false on error. * @removed 7.0 */ function mssql_connect($servername = null, $username = null, $password = null, $new_link = false) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Open persistent MS SQL connection * @link https://php.net/manual/en/function.mssql-pconnect.php * @param string $servername [optional]

    * The MS SQL server. It can also include a port number. e.g. * hostname:port. *

    * @param string $username [optional]

    * The username. *

    * @param string $password [optional]

    * The password. *

    * @param bool $new_link [optional]

    * If a second call is made to mssql_pconnect with * the same arguments, no new link will be established, but instead, the * link identifier of the already opened link will be returned. This * parameter modifies this behavior and makes * mssql_pconnect always open a new link, even if * mssql_pconnect was called before with the same * parameters. *

    * @return resource|false a positive MS SQL persistent link identifier on success, or * false on error. * @removed 7.0 */ function mssql_pconnect($servername = null, $username = null, $password = null, $new_link = false) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Close MS SQL Server connection * @link https://php.net/manual/en/function.mssql-close.php * @param resource $link_identifier [optional]

    * A MS SQL link identifier, returned by * mssql_connect. *

    *

    * This function will not close persistent links generated by * mssql_pconnect. *

    * @return bool true on success or false on failure. * @removed 7.0 */ function mssql_close($link_identifier = null) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Select MS SQL database * @link https://php.net/manual/en/function.mssql-select-db.php * @param string $database_name

    * The database name. *

    *

    * To escape the name of a database that contains spaces, hyphens ("-"), * or any other exceptional characters, the database name must be * enclosed in brackets, as is shown in the example, below. This * technique must also be applied when selecting a database name that is * also a reserved word (such as primary). *

    * @param resource $link_identifier [optional]

    * A MS SQL link identifier, returned by * mssql_connect or * mssql_pconnect. *

    *

    * If no link identifier is specified, the last opened link is assumed. * If no link is open, the function will try to establish a link as if * mssql_connect was called, and use it. *

    * @return bool true on success or false on failure. * @removed 7.0 */ function mssql_select_db($database_name, $link_identifier = null) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Send MS SQL query * @link https://php.net/manual/en/function.mssql-query.php * @param string $query

    * An SQL query. *

    * @param resource $link_identifier [optional]

    * A MS SQL link identifier, returned by * mssql_connect or * mssql_pconnect. *

    *

    * If the link identifier isn't specified, the last opened link is * assumed. If no link is open, the function tries to establish a link * as if mssql_connect was called, and use it. *

    * @param int $batch_size [optional]

    * The number of records to batch in the buffer. *

    * @return resource|bool a MS SQL result resource on success, true if no rows were * returned, or false on error. * @removed 7.0 */ function mssql_query($query, $link_identifier = null, $batch_size = 0) {} /** * (PHP 4 >= 4.0.4, PHP 5, PECL odbtp >= 1.1.1)
    * Returns the next batch of records * @link https://php.net/manual/en/function.mssql-fetch-batch.php * @param resource $result

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @return int the batch number as an integer. * @removed 7.0 */ function mssql_fetch_batch($result) {} /** * (PHP 4 >= 4.0.4, PHP 5, PECL odbtp >= 1.1.1)
    * Returns the number of records affected by the query * @link https://php.net/manual/en/function.mssql-rows-affected.php * @param resource $link_identifier

    * A MS SQL link identifier, returned by * mssql_connect or * mssql_pconnect. *

    * @return int the number of records affected by last operation. * @removed 7.0 */ function mssql_rows_affected($link_identifier) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Free result memory * @link https://php.net/manual/en/function.mssql-free-result.php * @param resource $result

    * The result resource that is being freed. This result comes from a * call to mssql_query. *

    * @return bool true on success or false on failure. * @removed 7.0 */ function mssql_free_result($result) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Returns the last message from the server * @link https://php.net/manual/en/function.mssql-get-last-message.php * @return string last error message from server, or an empty string if * no error messages are returned from MSSQL. * @removed 7.0 */ function mssql_get_last_message() {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Gets the number of rows in result * @link https://php.net/manual/en/function.mssql-num-rows.php * @param resource $result

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @return int the number of rows, as an integer. * @removed 7.0 */ function mssql_num_rows($result) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Gets the number of fields in result * @link https://php.net/manual/en/function.mssql-num-fields.php * @param resource $result

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @return int the number of fields, as an integer. * @removed 7.0 */ function mssql_num_fields($result) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Get field information * @link https://php.net/manual/en/function.mssql-fetch-field.php * @param resource $result

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @param int $field_offset [optional]

    * The numerical field offset. If the field offset is not specified, the * next field that was not yet retrieved by this function is retrieved. The * field_offset starts at 0. *

    * @return object an object containing field information. * @removed 7.0 */ function mssql_fetch_field($result, $field_offset = -1) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Get row as enumerated array * @link https://php.net/manual/en/function.mssql-fetch-row.php * @param resource $result

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @return array|false an array that corresponds to the fetched row, or false if there * are no more rows. * @removed 7.0 */ function mssql_fetch_row($result) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Fetch a result row as an associative array, a numeric array, or both * @link https://php.net/manual/en/function.mssql-fetch-array.php * @param resource $result

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @param int $result_type [optional]

    * The type of array that is to be fetched. It's a constant and can take * the following values: MSSQL_ASSOC, * MSSQL_NUM, and * MSSQL_BOTH. *

    * @return array|false an array that corresponds to the fetched row, or false if there * are no more rows. * @removed 7.0 */ function mssql_fetch_array($result, $result_type = MSSQL_BOTH) {} /** * (PHP 4 >= 4.2.0, PHP 5, PECL odbtp >= 1.1.1)
    * Returns an associative array of the current row in the result * @link https://php.net/manual/en/function.mssql-fetch-assoc.php * @param resource $result_id

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @return array an associative array that corresponds to the fetched row, or * false if there are no more rows. * @removed 7.0 */ function mssql_fetch_assoc($result_id) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Fetch row as object * @link https://php.net/manual/en/function.mssql-fetch-object.php * @param resource $result

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @return object an object with properties that correspond to the fetched row, or * false if there are no more rows. * @removed 7.0 */ function mssql_fetch_object($result) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Get the length of a field * @link https://php.net/manual/en/function.mssql-field-length.php * @param resource $result

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @param int $offset [optional]

    * The field offset, starts at 0. If omitted, the current field is used. *

    * @return int|false The length of the specified field index on success or false on failure. * @removed 7.0 */ function mssql_field_length($result, $offset = null) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Get the name of a field * @link https://php.net/manual/en/function.mssql-field-name.php * @param resource $result

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @param int $offset [optional]

    * The field offset, starts at 0. If omitted, the current field is used. *

    * @return string|false The name of the specified field index on success or false on failure. * @removed 7.0 */ function mssql_field_name($result, $offset = -1) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Gets the type of a field * @link https://php.net/manual/en/function.mssql-field-type.php * @param resource $result

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @param int $offset [optional]

    * The field offset, starts at 0. If omitted, the current field is used. *

    * @return string|false The type of the specified field index on success or false on failure. * @removed 7.0 */ function mssql_field_type($result, $offset = -1) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Moves internal row pointer * @link https://php.net/manual/en/function.mssql-data-seek.php * @param resource $result_identifier

    * The result resource that is being evaluated. *

    * @param int $row_number

    * The desired row number of the new result pointer. *

    * @return bool true on success or false on failure. * @removed 7.0 */ function mssql_data_seek($result_identifier, $row_number) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Seeks to the specified field offset * @link https://php.net/manual/en/function.mssql-field-seek.php * @param resource $result

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @param int $field_offset

    * The field offset, starts at 0. *

    * @return bool true on success or false on failure. * @removed 7.0 */ function mssql_field_seek($result, $field_offset) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Get result data * @link https://php.net/manual/en/function.mssql-result.php * @param resource $result

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @param int $row

    * The row number. *

    * @param mixed $field

    * Can be the field's offset, the field's name or the field's table dot * field's name (tablename.fieldname). If the column name has been * aliased ('select foo as bar from...'), it uses the alias instead of * the column name. *

    *

    * Specifying a numeric offset for the field * argument is much quicker than specifying a * fieldname or * tablename.fieldname argument. *

    * @return string the contents of the specified cell. * @removed 7.0 */ function mssql_result($result, $row, $field) {} /** * (PHP 4 >= 4.0.5, PHP 5, PECL odbtp >= 1.1.1)
    * Move the internal result pointer to the next result * @link https://php.net/manual/en/function.mssql-next-result.php * @param resource $result_id

    * The result resource that is being evaluated. This result comes from a * call to mssql_query. *

    * @return bool true if an additional result set was available or false * otherwise. * @removed 7.0 */ function mssql_next_result($result_id) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Sets the minimum error severity * @link https://php.net/manual/en/function.mssql-min-error-severity.php * @param int $severity

    * The new error severity. *

    * @return void * @removed 7.0 */ function mssql_min_error_severity($severity) {} /** * (PHP 4, PHP 5, PECL odbtp >= 1.1.1)
    * Sets the minimum message severity * @link https://php.net/manual/en/function.mssql-min-message-severity.php * @param int $severity

    * The new message severity. *

    * @return void * @removed 7.0 */ function mssql_min_message_severity($severity) {} /** * (PHP 4 >= 4.0.7, PHP 5, PECL odbtp >= 1.1.1)
    * Initializes a stored procedure or a remote stored procedure * @link https://php.net/manual/en/function.mssql-init.php * @param string $sp_name

    * Stored procedure name, like ownew.sp_name or * otherdb.owner.sp_name. *

    * @param resource $link_identifier [optional]

    * A MS SQL link identifier, returned by * mssql_connect. *

    * @return resource|false a resource identifier "statement", used in subsequent calls to * mssql_bind and mssql_execute, * or false on errors. * @removed 7.0 */ function mssql_init($sp_name, $link_identifier = null) {} /** * (PHP 4 >= 4.0.7, PHP 5, PECL odbtp >= 1.1.1)
    * Adds a parameter to a stored procedure or a remote stored procedure * @link https://php.net/manual/en/function.mssql-bind.php * @param resource $stmt

    * Statement resource, obtained with mssql_init. *

    * @param string $param_name

    * The parameter name, as a string. *

    *

    * You have to include the @ character, like in the * T-SQL syntax. See the explanation included in * mssql_execute. *

    * @param mixed &$var

    * The PHP variable you'll bind the MSSQL parameter to. It is passed by * reference, to retrieve OUTPUT and RETVAL values after * the procedure execution. *

    * @param int $type

    * One of: SQLTEXT, * SQLVARCHAR, SQLCHAR, * SQLINT1, SQLINT2, * SQLINT4, SQLBIT, * SQLFLT4, SQLFLT8, * SQLFLTN. *

    * @param bool $is_output [optional]

    * Whether the value is an OUTPUT parameter or not. If it's an OUTPUT * parameter and you don't mention it, it will be treated as a normal * input parameter and no error will be thrown. *

    * @param bool $is_null [optional]

    * Whether the parameter is null or not. Passing the null value as * var will not do the job. *

    * @param int $maxlen [optional]

    * Used with char/varchar values. You have to indicate the length of the * data so if the parameter is a varchar(50), the type must be * SQLVARCHAR and this value 50. *

    * @return bool true on success or false on failure. * @removed 7.0 */ function mssql_bind($stmt, $param_name, &$var, $type, $is_output = false, $is_null = false, $maxlen = -1) {} /** * (PHP 4 >= 4.0.7, PHP 5, PECL odbtp >= 1.1.1)
    * Executes a stored procedure on a MS SQL server database * @link https://php.net/manual/en/function.mssql-execute.php * @param resource $stmt

    * Statement handle obtained with mssql_init. *

    * @param bool $skip_results [optional]

    * Whenever to skip the results or not. *

    * @return mixed * @removed 7.0 */ function mssql_execute($stmt, $skip_results = false) {} /** * (PHP 4 >= 4.3.2, PHP 5, PECL odbtp >= 1.1.1)
    * Free statement memory * @link https://php.net/manual/en/function.mssql-free-statement.php * @param resource $stmt

    * Statement resource, obtained with mssql_init. *

    * @return bool true on success or false on failure. * @removed 7.0 */ function mssql_free_statement($stmt) {} /** * (PHP 4 >= 4.0.7, PHP 5, PECL odbtp >= 1.1.1)
    * Converts a 16 byte binary GUID to a string * @link https://php.net/manual/en/function.mssql-guid-string.php * @param string $binary

    * A 16 byte binary GUID. *

    * @param bool $short_format [optional]

    * Whenever to use short format. *

    * @return string the converted string on success. * @removed 7.0 */ function mssql_guid_string($binary, $short_format = null) {} /** * Return an associative array. Used on * mssql_fetch_array's * result_type parameter. * @link https://php.net/manual/en/mssql.constants.php */ define('MSSQL_ASSOC', 1); /** * Return an array with numeric keys. Used on * mssql_fetch_array's * result_type parameter. * @link https://php.net/manual/en/mssql.constants.php */ define('MSSQL_NUM', 2); /** * Return an array with both numeric keys and * keys with their field name. This is the * default value for mssql_fetch_array's * result_type parameter. * @link https://php.net/manual/en/mssql.constants.php */ define('MSSQL_BOTH', 3); /** * Indicates the 'TEXT' type in MSSQL, used by * mssql_bind's type * parameter. * @link https://php.net/manual/en/mssql.constants.php */ define('SQLTEXT', 35); /** * Indicates the 'VARCHAR' type in MSSQL, used by * mssql_bind's type * parameter. * @link https://php.net/manual/en/mssql.constants.php */ define('SQLVARCHAR', 39); /** * Indicates the 'CHAR' type in MSSQL, used by * mssql_bind's type * parameter. * @link https://php.net/manual/en/mssql.constants.php */ define('SQLCHAR', 47); /** * Represents one byte, with a range of -128 to 127. * @link https://php.net/manual/en/mssql.constants.php */ define('SQLINT1', 48); /** * Represents two bytes, with a range of -32768 * to 32767. * @link https://php.net/manual/en/mssql.constants.php */ define('SQLINT2', 52); /** * Represents four bytes, with a range of -2147483648 * to 2147483647. * @link https://php.net/manual/en/mssql.constants.php */ define('SQLINT4', 56); /** * Indicates the 'BIT' type in MSSQL, used by * mssql_bind's type * parameter. * @link https://php.net/manual/en/mssql.constants.php */ define('SQLBIT', 50); /** * Represents an four byte float. * @link https://php.net/manual/en/mssql.constants.php */ define('SQLFLT4', 59); /** * Represents an eight byte float. * @link https://php.net/manual/en/mssql.constants.php */ define('SQLFLT8', 62); define('SQLFLTN', 109); // End of mssql v. TRUE on success or FALSE on failure. * @since 5.1.2 */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function close() {} /** * Get the value of a named attribute * @link https://php.net/manual/en/xmlreader.getattribute.php * @param string $name

    * The name of the attribute. *

    * @return string|null The value of the attribute, or NULL if no attribute with the given * name is found or not positioned on an element node. * @since 5.1.2 */ #[TentativeType] public function getAttribute(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name): ?string {} /** * Get the value of an attribute by index * @link https://php.net/manual/en/xmlreader.getattributeno.php * @param int $index

    * The position of the attribute. *

    * @return string|null The value of the attribute, or NULL if no attribute exists * at index or not positioned of element. * @since 5.1.2 */ #[TentativeType] public function getAttributeNo(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index): ?string {} /** * Get the value of an attribute by localname and URI * @link https://php.net/manual/en/xmlreader.getattributens.php * @param string $name

    * The local name. *

    * @param string $namespace

    * The namespace URI. *

    * @return string|null The value of the attribute, or NULL if no attribute with the * given localName and * namespaceURI is found or not positioned of element. * @since 5.1.2 */ #[TentativeType] public function getAttributeNs( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $namespace ): ?string {} /** * Indicates if specified property has been set * @link https://php.net/manual/en/xmlreader.getparserproperty.php * @param int $property

    * One of the parser option * constants. *

    * @return bool TRUE on success or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function getParserProperty(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $property): bool {} /** * Indicates if the parsed document is valid * @link https://php.net/manual/en/xmlreader.isvalid.php * @return bool TRUE on success or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function isValid(): bool {} /** * Lookup namespace for a prefix * @link https://php.net/manual/en/xmlreader.lookupnamespace.php * @param string $prefix

    * String containing the prefix. *

    * @return string|null TRUE on success or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function lookupNamespace(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $prefix): ?string {} /** * Move cursor to an attribute by index * @link https://php.net/manual/en/xmlreader.movetoattributeno.php * @param int $index

    * The position of the attribute. *

    * @return bool TRUE on success or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function moveToAttributeNo(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index): bool {} /** * Move cursor to a named attribute * @link https://php.net/manual/en/xmlreader.movetoattribute.php * @param string $name

    * The name of the attribute. *

    * @return bool TRUE on success or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function moveToAttribute(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name): bool {} /** * Move cursor to a named attribute * @link https://php.net/manual/en/xmlreader.movetoattributens.php * @param string $name

    * The local name. *

    * @param string $namespace

    * The namespace URI. *

    * @return bool TRUE on success or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function moveToAttributeNs( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $namespace ): bool {} /** * Position cursor on the parent Element of current Attribute * @link https://php.net/manual/en/xmlreader.movetoelement.php * @return bool TRUE if successful and FALSE if it fails or not positioned on * Attribute when this method is called. * @since 5.1.2 */ #[TentativeType] public function moveToElement(): bool {} /** * Position cursor on the first Attribute * @link https://php.net/manual/en/xmlreader.movetofirstattribute.php * @return bool TRUE on success or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function moveToFirstAttribute(): bool {} /** * Position cursor on the next Attribute * @link https://php.net/manual/en/xmlreader.movetonextattribute.php * @return bool TRUE on success or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function moveToNextAttribute(): bool {} /** * Set the URI containing the XML to parse * @link https://php.net/manual/en/xmlreader.open.php * @param string $uri

    * URI pointing to the document. *

    * @param string $encoding [optional]

    * The document encoding or NULL. *

    * @param int $flags [optional]

    * A bitmask of the LIBXML_* * constants. *

    * @return XMLReader|bool TRUE on success or FALSE on failure. If called statically, returns an * XMLReader or FALSE on failure. * @since 5.1.2 */ public static function open( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $uri, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $encoding = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0 ) {} /** * Move to next node in document * @link https://php.net/manual/en/xmlreader.read.php * @return bool TRUE on success or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function read(): bool {} /** * Move cursor to next node skipping all subtrees * @link https://php.net/manual/en/xmlreader.next.php * @param string $name [optional]

    * The name of the next node to move to. *

    * @return bool TRUE on success or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function next(#[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $name = null): bool {} /** * Retrieve XML from current node * @link https://php.net/manual/en/xmlreader.readinnerxml.php * @return string the contents of the current node as a string. Empty string on failure. */ #[TentativeType] public function readInnerXml(): string {} /** * Retrieve XML from current node, including it self * @link https://php.net/manual/en/xmlreader.readouterxml.php * @return string the contents of current node, including itself, as a string. Empty string on failure. */ #[TentativeType] public function readOuterXml(): string {} /** * Reads the contents of the current node as a string * @link https://php.net/manual/en/xmlreader.readstring.php * @return string the content of the current node as a string. Empty string on * failure. */ #[TentativeType] public function readString(): string {} /** * Validate document against XSD * @link https://php.net/manual/en/xmlreader.setschema.php * @param string $filename

    * The filename of the XSD schema. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function setSchema(#[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $filename): bool {} /** * Set parser options * @link https://php.net/manual/en/xmlreader.setparserproperty.php * @param int $property

    * One of the parser option * constants. *

    * @param bool $value

    * If set to TRUE the option will be enabled otherwise will * be disabled. *

    * @return bool TRUE on success or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function setParserProperty( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $property, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $value ): bool {} /** * Set the filename or URI for a RelaxNG Schema * @link https://php.net/manual/en/xmlreader.setrelaxngschema.php * @param string $filename

    * filename or URI pointing to a RelaxNG Schema. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function setRelaxNGSchema(#[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $filename): bool {} /** * Set the data containing a RelaxNG Schema * @link https://php.net/manual/en/xmlreader.setrelaxngschemasource.php * @param string $source

    * String containing the RelaxNG Schema. *

    * @return bool TRUE on success or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function setRelaxNGSchemaSource(#[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $source): bool {} /** * Set the data containing the XML to parse * @link https://php.net/manual/en/xmlreader.xml.php * @param string $source

    * String containing the XML to be parsed. *

    * @param string $encoding [optional]

    * The document encoding or NULL. *

    * @param int $flags [optional]

    * A bitmask of the LIBXML_* * constants. *

    * @return XMLReader|bool TRUE on success or FALSE on failure. If called statically, returns an * XMLReader or FALSE on failure. * @since 5.1.2 */ public static function XML( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $source, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $encoding = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0 ) {} /** * Returns a copy of the current node as a DOM object * @link https://php.net/manual/en/xmlreader.expand.php * @param null|DOMNode $baseNode [optional] * @return DOMNode|false The resulting DOMNode or FALSE on error. * @since 5.1.2 */ #[TentativeType] public function expand( #[PhpStormStubsElementAvailable(from: '7.0')] #[LanguageLevelTypeAware(['8.0' => 'DOMNode|null'], default: '')] $baseNode = null ): DOMNode|false {} /** * @since 8.4 */ public static function fromUri(string $uri, ?string $encoding = null, int $flags = 0): static {} /** * @since 8.4 */ public static function fromStream($stream, ?string $encoding = null, int $flags = 0, ?string $documentUri = null): static {} /** * @since 8.4 */ public static function fromString(string $source, ?string $encoding = null, int $flags = 0): static {} } // End of xmlreader v.0.2 ' before the name means push. Use the signature without id for either continuation or to * start matching, when a continuation or recursion is required. * If '<' is specified as exit state, it means pop. In that case, the signature containing the id can be used to * identify the match. Note that even in the case an id is specified, the rule will finish first when all the * previous pushes popped. * @return void * @link https://php.net/manual/en/parle-rlexer.push.php */ public function push(string $state, string $regex, int $id, string $newState): void {} /** * Add a lexer rule * * Push a pattern for lexeme recognition. * A 'start state' and 'exit state' can be specified by using a suitable signature. * * @param string $state State name. If '*' is used as start state, then the rule is applied to all lexer states. * @param string $regex Regular expression used for token matching. * @param string $newState * New state name, after the rule was applied. * If '.' is specified as the exit state, then the lexer state is unchanged when that rule matches. * An exit state with '>' before the name means push. Use the signature without id for either continuation or to * start matching, when a continuation or recursion is required. * If '<' is specified as exit state, it means pop. In that case, the signature containing the id can be used to * identify the match. Note that even in the case an id is specified, the rule will finish first when all the * previous pushes popped. * @return void * @link https://php.net/manual/en/parle-rlexer.push.php */ public function push(string $state, string $regex, string $newState): void {} /** * Push a new start state * This lexer type can have more than one state machine. * This allows you to lex different tokens depending on context, thus allowing simple parsing to take place. * Once a state pushed, it can be used with a suitable Parle\RLexer::push() signature variant. * * @see RLexer::push() * @link https://php.net/manual/en/parle-rlexer.pushstate.php * @param string $state Name of the state. * @return int */ public function pushState(string $state): int {} /** * Reset lexer * * Reset lexing optionally supplying the desired offset. * * @param int $pos Reset position. */ public function reset(int $pos): void {} } * The number of processes that can acquire the semaphore simultaneously * is set to max_acquire. *

    * @param int $permissions [optional]

    * The semaphore permissions. Actually this value is * set only if the process finds it is the only process currently * attached to the semaphore. *

    * @param bool $auto_release [optional]

    * Specifies if the semaphore should be automatically released on request * shutdown. *

    * @return resource|false|SysvSemaphore a positive semaphore identifier on success, or FALSE on * error. */ #[LanguageLevelTypeAware(["8.0" => "SysvSemaphore|false"], default: "resource|false")] function sem_get(int $key, int $max_acquire = 1, int $permissions = 0666, bool $auto_release = true) {} /** * Acquire a semaphore * @link https://php.net/manual/en/function.sem-acquire.php * @param SysvSemaphore|resource $semaphore

    * sem_identifier is a semaphore resource, * obtained from sem_get. *

    * @param bool $non_blocking [optional]

    * Specifies if the process shouldn't wait for the semaphore to be acquired. * If set to true, the call will return false immediately if a * semaphore cannot be immediately acquired. *

    * @return bool TRUE on success or FALSE on failure. */ function sem_acquire(#[LanguageLevelTypeAware(["8.0" => "SysvSemaphore"], default: "resource")] $semaphore, bool $non_blocking = false): bool {} /** * Release a semaphore * @link https://php.net/manual/en/function.sem-release.php * @param SysvSemaphore|resource $semaphore

    * A Semaphore resource handle as returned by * sem_get. *

    * @return bool TRUE on success or FALSE on failure. */ function sem_release(#[LanguageLevelTypeAware(["8.0" => "SysvSemaphore"], default: "resource")] $semaphore): bool {} /** * Remove a semaphore * @link https://php.net/manual/en/function.sem-remove.php * @param SysvSemaphore|resource $semaphore

    * A semaphore resource identifier as returned * by sem_get. *

    * @return bool TRUE on success or FALSE on failure. */ function sem_remove(#[LanguageLevelTypeAware(["8.0" => "SysvSemaphore"], default: "resource")] $semaphore): bool {} /** * @since 8.0 */ final class SysvSemaphore { /** * Cannot directly construct SysvSemaphore, use sem_get() instead * @see sem_get() */ private function __construct() {} } // End of sysvsem v. * The string being converted. *

    * @param int $mode

    * The mode of the conversion. It can be one of * MB_CASE_UPPER, * MB_CASE_LOWER, or * MB_CASE_TITLE. *

    * @param string|null $encoding [optional] * @return string A case folded version of string converted in the * way specified by mode. */ #[Pure] function mb_convert_case(string $string, int $mode, ?string $encoding): string {} /** * Make a string uppercase * @link https://php.net/manual/en/function.mb-strtoupper.php * @param string $string

    * The string being uppercased. *

    * @param string|null $encoding [optional] * @return string str with all alphabetic characters converted to uppercase. */ #[Pure] function mb_strtoupper(string $string, ?string $encoding): string {} /** * Make a string lowercase * @link https://php.net/manual/en/function.mb-strtolower.php * @param string $string

    * The string being lowercased. *

    * @param string|null $encoding [optional] * @return string str with all alphabetic characters converted to lowercase. */ #[Pure] function mb_strtolower(string $string, ?string $encoding): string {} /** * Set/Get current language * @link https://php.net/manual/en/function.mb-language.php * @param string|null $language [optional]

    * Used for encoding * e-mail messages. Valid languages are "Japanese", * "ja","English","en" and "uni" * (UTF-8). mb_send_mail uses this setting to * encode e-mail. *

    *

    * Language and its setting is ISO-2022-JP/Base64 for * Japanese, UTF-8/Base64 for uni, ISO-8859-1/quoted printable for * English. *

    * @return bool|string If language is set and * language is valid, it returns * true. Otherwise, it returns false. * When language is omitted, it returns the language * name as a string. If no language is set previously, it then returns * false. */ function mb_language(?string $language): string|bool {} /** * Set/Get internal character encoding * @link https://php.net/manual/en/function.mb-internal-encoding.php * @param string|null $encoding [optional]

    * encoding is the character encoding name * used for the HTTP input character encoding conversion, HTTP output * character encoding conversion, and the default character encoding * for string functions defined by the mbstring module. *

    * @return bool|string If encoding is set, then * true on success or false on failure. * If encoding is omitted, then * the current character encoding name is returned. */ function mb_internal_encoding(?string $encoding): string|bool {} /** * Detect HTTP input character encoding * @link https://php.net/manual/en/function.mb-http-input.php * @param string|null $type [optional]

    * Input string specifies the input type. * "G" for GET, "P" for POST, "C" for COOKIE, "S" for string, "L" for list, and * "I" for the whole list (will return array). * If type is omitted, it returns the last input type processed. *

    * @return array|false|string The character encoding name, as per the type. * If mb_http_input does not process specified * HTTP input, it returns false. */ #[Pure] function mb_http_input(?string $type): array|string|false {} /** * Set/Get HTTP output character encoding * @link https://php.net/manual/en/function.mb-http-output.php * @param string|null $encoding [optional]

    * If encoding is set, * mb_http_output sets the HTTP output character * encoding to encoding. *

    *

    * If encoding is omitted, * mb_http_output returns the current HTTP output * character encoding. *

    * @return bool|string If encoding is omitted, * mb_http_output returns the current HTTP output * character encoding. Otherwise, * true on success or false on failure. */ function mb_http_output(?string $encoding): string|bool {} /** * Set/Get character encoding detection order * @link https://php.net/manual/en/function.mb-detect-order.php * @param array|string|null $encoding [optional]

    * encoding_list is an array or * comma separated list of character encoding. ("auto" is expanded to * "ASCII, JIS, UTF-8, EUC-JP, SJIS") *

    *

    * If encoding_list is omitted, it returns * the current character encoding detection order as array. *

    *

    * This setting affects mb_detect_encoding and * mb_send_mail. *

    *

    * mbstring currently implements the following * encoding detection filters. If there is an invalid byte sequence * for the following encodings, encoding detection will fail. *

    * UTF-8, UTF-7, * ASCII, * EUC-JP,SJIS, * eucJP-win, SJIS-win, * JIS, ISO-2022-JP *

    * For ISO-8859-*, mbstring * always detects as ISO-8859-*. *

    *

    * For UTF-16, UTF-32, * UCS2 and UCS4, encoding * detection will fail always. *

    *

    * Useless detect order example *

    * @return bool|string[] When setting the encoding detection order, * true is returned on success or FALSE on failure. * When getting the encoding detection order, an ordered array * of the encodings is returned. */ #[LanguageLevelTypeAware(['8.2' => 'array|true'], default: 'array|bool')] function mb_detect_order(array|string|null $encoding = null): array|bool {} /** * Set/Get substitution character * @link https://php.net/manual/en/function.mb-substitute-character.php * @param string|int|null $substitute_character [optional]

    * Specify the Unicode value as an integer, * or as one of the following strings:

      *
    • "none" : no output
    • *
    • "long": Output character code value (Example: U+3000, JIS+7E7E)
    • *
    • "entity": Output character entity (Example: Ȁ)
    • *
    * @return bool|int|string If substchar is set, it returns true for success, * otherwise returns false. * If substchar is not set, it returns the Unicode value, * or "none" or "long". */ function mb_substitute_character(string|int|null $substitute_character = null): string|int|bool {} /** * Parse GET/POST/COOKIE data and set global variable * @link https://php.net/manual/en/function.mb-parse-str.php * @param string $string

    * The URL encoded data. *

    * @param array &$result [optional]

    * An array containing decoded and character encoded converted values. *

    * @return bool true on success or false on failure. */ #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] function mb_parse_str(string $string, &$result): bool {} /** * Parse GET/POST/COOKIE data and set global variable * @link https://php.net/manual/en/function.mb-parse-str.php * @param string $string

    * The URL encoded data. *

    * @param array &$result

    * An array containing decoded and character encoded converted values. *

    * @return bool true on success or false on failure. */ #[PhpStormStubsElementAvailable(from: '8.0')] function mb_parse_str(string $string, &$result): bool {} /** * Callback function converts character encoding in output buffer * @link https://php.net/manual/en/function.mb-output-handler.php * @param string $string

    * The contents of the output buffer. *

    * @param int $status

    * The status of the output buffer. *

    * @return string The converted string. */ #[Pure] function mb_output_handler(string $string, int $status): string {} /** * Get MIME charset string * @link https://php.net/manual/en/function.mb-preferred-mime-name.php * @param string $encoding

    * The encoding being checked. *

    * @return string|false The MIME charset string for character encoding * encoding. */ #[Pure] function mb_preferred_mime_name(string $encoding): string|false {} /** * Get string length * @link https://php.net/manual/en/function.mb-strlen.php * @param string $string

    * The string being checked for length. *

    * @param string|null $encoding [optional] * @return int|false the number of characters in * string str having character encoding * encoding. A multi-byte character is * counted as 1. */ #[Pure] #[LanguageLevelTypeAware(['8.0' => 'int'], default: 'int|false')] function mb_strlen(string $string, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $encoding) {} /** * Find position of first occurrence of string in a string * @link https://php.net/manual/en/function.mb-strpos.php * @param string $haystack

    * The string being checked. *

    * @param string $needle

    * The position counted from the beginning of haystack. *

    * @param int<0,max> $offset [optional]

    * The search offset. If it is not specified, 0 is used. *

    * @param string|null $encoding [optional] * @return int<0,max>|false the numeric position of * the first occurrence of needle in the * haystack string. If * needle is not found, it returns false. */ #[Pure] function mb_strpos(string $haystack, string $needle, int $offset = 0, ?string $encoding): int|false {} /** * Find position of last occurrence of a string in a string * @link https://php.net/manual/en/function.mb-strrpos.php * @param string $haystack

    * The string being checked, for the last occurrence * of needle *

    * @param string $needle

    * The string to find in haystack. *

    * @param int $offset [optional] May be specified to begin searching an arbitrary number of characters into * the string. Negative values will stop searching at an arbitrary point * prior to the end of the string. * @param string|null $encoding [optional] * @return int|false the numeric position of * the last occurrence of needle in the * haystack string. If * needle is not found, it returns false. */ #[Pure] function mb_strrpos(string $haystack, string $needle, int $offset = 0, ?string $encoding): int|false {} /** * Finds position of first occurrence of a string within another, case insensitive * @link https://php.net/manual/en/function.mb-stripos.php * @param string $haystack

    * The string from which to get the position of the first occurrence * of needle *

    * @param string $needle

    * The string to find in haystack *

    * @param int $offset [optional]

    * The position in haystack * to start searching *

    * @param string|null $encoding [optional]

    * Character encoding name to use. * If it is omitted, internal character encoding is used. *

    * @return int|false Return the numeric position of the first occurrence of * needle in the haystack * string, or false if needle is not found. */ #[Pure] function mb_stripos(string $haystack, string $needle, int $offset = 0, ?string $encoding): int|false {} /** * Finds position of last occurrence of a string within another, case insensitive * @link https://php.net/manual/en/function.mb-strripos.php * @param string $haystack

    * The string from which to get the position of the last occurrence * of needle *

    * @param string $needle

    * The string to find in haystack *

    * @param int $offset [optional]

    * The position in haystack * to start searching *

    * @param string|null $encoding [optional]

    * Character encoding name to use. * If it is omitted, internal character encoding is used. *

    * @return int|false Return the numeric position of * the last occurrence of needle in the * haystack string, or false * if needle is not found. */ #[Pure] function mb_strripos(string $haystack, string $needle, int $offset = 0, ?string $encoding): int|false {} /** * Finds first occurrence of a string within another * @link https://php.net/manual/en/function.mb-strstr.php * @param string $haystack

    * The string from which to get the first occurrence * of needle *

    * @param string $needle

    * The string to find in haystack *

    * @param bool $before_needle [optional]

    * Determines which portion of haystack * this function returns. * If set to true, it returns all of haystack * from the beginning to the first occurrence of needle. * If set to false, it returns all of haystack * from the first occurrence of needle to the end, *

    * @param string|null $encoding [optional]

    * Character encoding name to use. * If it is omitted, internal character encoding is used. *

    * @return string|false the portion of haystack, * or false if needle is not found. */ #[Pure] function mb_strstr(string $haystack, string $needle, bool $before_needle = false, ?string $encoding): string|false {} /** * Finds the last occurrence of a character in a string within another * @link https://php.net/manual/en/function.mb-strrchr.php * @param string $haystack

    * The string from which to get the last occurrence * of needle *

    * @param string $needle

    * The string to find in haystack *

    * @param bool $before_needle [optional]

    * Determines which portion of haystack * this function returns. * If set to true, it returns all of haystack * from the beginning to the last occurrence of needle. * If set to false, it returns all of haystack * from the last occurrence of needle to the end, *

    * @param string|null $encoding [optional]

    * Character encoding name to use. * If it is omitted, internal character encoding is used. *

    * @return string|false the portion of haystack. * or false if needle is not found. */ #[Pure] function mb_strrchr(string $haystack, string $needle, bool $before_needle = false, ?string $encoding): string|false {} /** * Finds first occurrence of a string within another, case insensitive * @link https://php.net/manual/en/function.mb-stristr.php * @param string $haystack

    * The string from which to get the first occurrence * of needle *

    * @param string $needle

    * The string to find in haystack *

    * @param bool $before_needle [optional]

    * Determines which portion of haystack * this function returns. * If set to true, it returns all of haystack * from the beginning to the first occurrence of needle. * If set to false, it returns all of haystack * from the first occurrence of needle to the end, *

    * @param string|null $encoding [optional]

    * Character encoding name to use. * If it is omitted, internal character encoding is used. *

    * @return string|false the portion of haystack, * or false if needle is not found. */ #[Pure] function mb_stristr(string $haystack, string $needle, bool $before_needle = false, ?string $encoding): string|false {} /** * Finds the last occurrence of a character in a string within another, case insensitive * @link https://php.net/manual/en/function.mb-strrichr.php * @param string $haystack

    * The string from which to get the last occurrence * of needle *

    * @param string $needle

    * The string to find in haystack *

    * @param bool $before_needle [optional]

    * Determines which portion of haystack * this function returns. * If set to true, it returns all of haystack * from the beginning to the last occurrence of needle. * If set to false, it returns all of haystack * from the last occurrence of needle to the end, *

    * @param string|null $encoding [optional]

    * Character encoding name to use. * If it is omitted, internal character encoding is used. *

    * @return string|false the portion of haystack. * or false if needle is not found. */ #[Pure] function mb_strrichr(string $haystack, string $needle, bool $before_needle = false, ?string $encoding): string|false {} /** * Count the number of substring occurrences * @link https://php.net/manual/en/function.mb-substr-count.php * @param string $haystack

    * The string being checked. *

    * @param string $needle

    * The string being found. *

    * @param string|null $encoding [optional] * @return int The number of times the * needle substring occurs in the * haystack string. */ #[Pure] function mb_substr_count(string $haystack, string $needle, ?string $encoding): int {} /** * Get part of string * @link https://php.net/manual/en/function.mb-substr.php * @param string $string

    * The string being checked. *

    * @param int $start

    * The first position used in str. *

    * @param int|null $length [optional]

    * The maximum length of the returned string. *

    * @param string|null $encoding [optional] * @return string mb_substr returns the portion of * str specified by the * start and * length parameters. */ #[Pure] function mb_substr(string $string, int $start, ?int $length, ?string $encoding): string {} /** * Get part of string * @link https://php.net/manual/en/function.mb-strcut.php * @param string $string

    * The string being cut. *

    * @param int $start

    * The position that begins the cut. *

    * @param int|null $length [optional]

    * The string being decoded. *

    * @param string|null $encoding [optional] * @return string mb_strcut returns the portion of * str specified by the * start and * length parameters. */ #[Pure] function mb_strcut(string $string, int $start, ?int $length, ?string $encoding): string {} /** * Return width of string * @link https://php.net/manual/en/function.mb-strwidth.php * @param string $string

    * The string being decoded. *

    * @param string|null $encoding [optional] * @return int The width of string str. */ #[Pure] function mb_strwidth(string $string, ?string $encoding): int {} /** * Get truncated string with specified width * @link https://php.net/manual/en/function.mb-strimwidth.php * @param string $string

    * The string being decoded. *

    * @param int $start

    * The start position offset. Number of * characters from the beginning of string. (First character is 0) *

    * @param int $width

    * The width of the desired trim. *

    * @param string $trim_marker

    * A string that is added to the end of string * when string is truncated. *

    * @param string|null $encoding [optional] * @return string The truncated string. If trimmarker is set, * trimmarker is appended to the return value. */ #[Pure] function mb_strimwidth(string $string, int $start, int $width, string $trim_marker = '', ?string $encoding): string {} /** * Convert character encoding * @link https://php.net/manual/en/function.mb-convert-encoding.php * @param string|array $string

    * The string being encoded. *

    * @param string $to_encoding

    * The type of encoding that str is being converted to. *

    * @param string|string[]|null $from_encoding [optional]

    * Is specified by character code names before conversion. It is either * an array, or a comma separated enumerated list. * If from_encoding is not specified, the internal * encoding will be used. *

    *

    * "auto" may be used, which expands to * "ASCII,JIS,UTF-8,EUC-JP,SJIS". *

    * @return array|string|false The encoded string. */ #[Pure] function mb_convert_encoding(array|string $string, string $to_encoding, array|string|null $from_encoding = null): array|string|false {} /** * Detect character encoding * @link https://php.net/manual/en/function.mb-detect-encoding.php * @param string $string

    * The string being detected. *

    * @param string|string[]|null $encodings [optional]

    * encoding_list is list of character * encoding. Encoding order may be specified by array or comma * separated list string. *

    *

    * If encoding_list is omitted, * detect_order is used. *

    * @param bool $strict [optional]

    * strict specifies whether to use * the strict encoding detection or not. * Default is false. *

    * @return string|false The detected character encoding or false if the encoding cannot be * detected from the given string. */ #[Pure] function mb_detect_encoding(string $string, array|string|null $encodings = null, bool $strict = false): string|false {} /** * Returns an array of all supported encodings * @link https://php.net/manual/en/function.mb-list-encodings.php * @return string[] a numerically indexed array. */ #[Pure] function mb_list_encodings(): array {} /** * Get aliases of a known encoding type * @param string $encoding The encoding type being checked, for aliases. * @return string[]|false a numerically indexed array of encoding aliases on success, or FALSE on failure * @link https://php.net/manual/en/function.mb-encoding-aliases.php */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "array"], default: "array|false")] function mb_encoding_aliases(string $encoding) {} /** * Convert "kana" one from another ("zen-kaku", "han-kaku" and more) * @link https://php.net/manual/en/function.mb-convert-kana.php * @param string $string

    * The string being converted. *

    * @param string $mode [optional]

    * The conversion option. *

    *

    * Specify with a combination of following options. *

    * Applicable Conversion Options * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    OptionMeaning
    r * Convert "zen-kaku" alphabets to "han-kaku" *
    R * Convert "han-kaku" alphabets to "zen-kaku" *
    n * Convert "zen-kaku" numbers to "han-kaku" *
    N * Convert "han-kaku" numbers to "zen-kaku" *
    a * Convert "zen-kaku" alphabets and numbers to "han-kaku" *
    A * Convert "han-kaku" alphabets and numbers to "zen-kaku" * (Characters included in "a", "A" options are * U+0021 - U+007E excluding U+0022, U+0027, U+005C, U+007E) *
    s * Convert "zen-kaku" space to "han-kaku" (U+3000 -> U+0020) *
    S * Convert "han-kaku" space to "zen-kaku" (U+0020 -> U+3000) *
    k * Convert "zen-kaku kata-kana" to "han-kaku kata-kana" *
    K * Convert "han-kaku kata-kana" to "zen-kaku kata-kana" *
    h * Convert "zen-kaku hira-gana" to "han-kaku kata-kana" *
    H * Convert "han-kaku kata-kana" to "zen-kaku hira-gana" *
    c * Convert "zen-kaku kata-kana" to "zen-kaku hira-gana" *
    C * Convert "zen-kaku hira-gana" to "zen-kaku kata-kana" *
    V * Collapse voiced sound notation and convert them into a character. Use with "K","H" *
    *

    * @param string|null $encoding [optional] * @return string The converted string. */ #[Pure] function mb_convert_kana(string $string, string $mode = 'KV', ?string $encoding): string {} /** * Encode string for MIME header * @link https://php.net/manual/en/function.mb-encode-mimeheader.php * @param string $string

    * The string being encoded. *

    * @param string|null $charset [optional]

    * charset specifies the name of the character set * in which str is represented in. The default value * is determined by the current NLS setting (mbstring.language). * mb_internal_encoding should be set to same encoding. *

    * @param string|null $transfer_encoding [optional]

    * transfer_encoding specifies the scheme of MIME * encoding. It should be either "B" (Base64) or * "Q" (Quoted-Printable). Falls back to * "B" if not given. *

    * @param string $newline [optional]

    * linefeed specifies the EOL (end-of-line) marker * with which mb_encode_mimeheader performs * line-folding (a RFC term, * the act of breaking a line longer than a certain length into multiple * lines. The length is currently hard-coded to 74 characters). * Falls back to "\r\n" (CRLF) if not given. *

    * @param int $indent

    * Indentation of the first line (number of characters in the header * before str). *

    * @return string A converted version of the string represented in ASCII. */ #[Pure] function mb_encode_mimeheader(string $string, ?string $charset, ?string $transfer_encoding, string $newline = "\r\n", int $indent = 0): string {} /** * Decode string in MIME header field * @link https://php.net/manual/en/function.mb-decode-mimeheader.php * @param string $string

    * The string being decoded. *

    * @return string The decoded string in internal character encoding. */ #[Pure] function mb_decode_mimeheader(string $string): string {} /** * Convert character code in variable(s) * @link https://php.net/manual/en/function.mb-convert-variables.php * @param string $to_encoding

    * The encoding that the string is being converted to. *

    * @param string|string[] $from_encoding

    * from_encoding is specified as an array * or comma separated string, it tries to detect encoding from * from-coding. When from_encoding * is omitted, detect_order is used. *

    * @param string|array|object &$var var is the reference to the variable being converted. * @param string|array|object &...$vars

    * vars is the other references to the * variables being converted. String, Array and Object are accepted. * mb_convert_variables assumes all parameters * have the same encoding. *

    * @return string|false The character encoding before conversion for success, * or false for failure. */ function mb_convert_variables( string $to_encoding, array|string $from_encoding, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] &$vars, #[PhpStormStubsElementAvailable(from: '8.0')] mixed &$var, mixed &...$vars ): string|false {} /** * Encode character to HTML numeric string reference * @link https://php.net/manual/en/function.mb-encode-numericentity.php * @param string $string

    * The string being encoded. *

    * @param int[] $map

    * convmap is array specifies code area to * convert. *

    * @param null|string $encoding * @param bool $hex [optional] * @return string The converted string. */ #[Pure] function mb_encode_numericentity(string $string, array $map, ?string $encoding = null, bool $hex = false): string {} /** * Decode HTML numeric string reference to character * @link https://php.net/manual/en/function.mb-decode-numericentity.php * @param string $string

    * The string being decoded. *

    * @param int[] $map

    * convmap is an array that specifies * the code area to convert. *

    * @param null|string $encoding * @param bool $is_hex [optional]

    * this parameter is not used. *

    * @return string|false|null The converted string. */ #[Pure] #[LanguageLevelTypeAware(['8.0' => 'string'], default: 'string|false|null')] function mb_decode_numericentity(string $string, array $map, ?string $encoding = null, #[PhpStormStubsElementAvailable(from: '7.2', to: '7.4')] $is_hex = false) {} /** * Send encoded mail * @link https://php.net/manual/en/function.mb-send-mail.php * @param string $to

    * The mail addresses being sent to. Multiple * recipients may be specified by putting a comma between each * address in to. * This parameter is not automatically encoded. *

    * @param string $subject

    * The subject of the mail. *

    * @param string $message

    * The message of the mail. *

    * @param string|array $additional_headers

    * String or array to be inserted at the end of the email header.
    * Since 7.2.0 accepts an array. Its keys are the header names and its values are the respective header values.
    * This is typically used to add extra * headers. Multiple extra headers are separated with a * newline ("\n"). *

    * @param string|null $additional_params [optional]

    * additional_parameter is a MTA command line * parameter. It is useful when setting the correct Return-Path * header when using sendmail. *

    * @return bool true on success or false on failure. */ function mb_send_mail(string $to, string $subject, string $message, array|string $additional_headers = [], ?string $additional_params): bool {} /** * Get internal settings of mbstring * @link https://php.net/manual/en/function.mb-get-info.php * @param string $type [optional]

    * If type isn't specified or is specified to * "all", an array having the elements "internal_encoding", * "http_output", "http_input", "func_overload", "mail_charset", * "mail_header_encoding", "mail_body_encoding" will be returned. *

    *

    * If type is specified as "http_output", * "http_input", "internal_encoding", "func_overload", * the specified setting parameter will be returned. *

    * @return array|string|int|false An array of type information if type * is not specified, otherwise a specific type. */ #[Pure] #[ArrayShape([ 'internal_encoding' => 'string', 'http_input' => 'string', 'http_output' => 'string', 'http_output_conv_mimetypes' => 'string', 'mail_charset' => 'string', 'mail_header_encoding' => 'string', 'mail_body_encoding' => 'string', 'illegal_chars' => 'string', 'encoding_translation' => 'string', 'language' => 'string', 'detect_order' => 'string', 'substitute_character' => 'string', 'strict_detection' => 'string', ])] #[LanguageLevelTypeAware(['8.2' => 'array|string|int|false|null'], default: 'array|string|int|false')] function mb_get_info(string $type = 'all') {} /** * Check if the string is valid for the specified encoding * @link https://php.net/manual/en/function.mb-check-encoding.php * @param string|string[]|null $value [optional]

    * The byte stream to check. If it is omitted, this function checks * all the input from the beginning of the request. *

    * @param string|null $encoding [optional]

    * The expected encoding. *

    * @return bool true on success or false on failure. * @since 5.1.3 */ #[Pure] function mb_check_encoding(array|string|null $value = null, ?string $encoding): bool {} /** * Returns current encoding for multibyte regex as string * @link https://php.net/manual/en/function.mb-regex-encoding.php * @param string|null $encoding [optional] * @return bool|string If encoding is set, then Returns TRUE on success * or FALSE on failure. In this case, the internal character encoding * is NOT changed. If encoding is omitted, then the current character * encoding name for a multibyte regex is returned. */ function mb_regex_encoding(?string $encoding): string|bool {} /** * Set/Get the default options for mbregex functions * @link https://php.net/manual/en/function.mb-regex-set-options.php * @param string|null $options [optional]

    * The options to set. *

    * @return string The previous options. If options is omitted, * it returns the string that describes the current options. */ function mb_regex_set_options(?string $options): string {} /** * Regular expression match with multibyte support * @link https://php.net/manual/en/function.mb-ereg.php * @param string $pattern

    * The search pattern. *

    * @param string $string

    * The search string. *

    * @param string[] &$matches [optional]

    * Contains a substring of the matched string. *

    * @return bool */ function mb_ereg(string $pattern, string $string, &$matches): bool {} /** * Regular expression match ignoring case with multibyte support * @link https://php.net/manual/en/function.mb-eregi.php * @param string $pattern

    * The regular expression pattern. *

    * @param string $string

    * The string being searched. *

    * @param string[] &$matches [optional]

    * Contains a substring of the matched string. *

    * @return bool|int */ #[LanguageLevelTypeAware(["8.0" => "bool"], default: "false|int")] function mb_eregi(string $pattern, string $string, &$matches): bool {} /** * Replace regular expression with multibyte support * @link https://php.net/manual/en/function.mb-ereg-replace.php * @param string $pattern

    * The regular expression pattern. *

    *

    * Multibyte characters may be used in pattern. *

    * @param string $replacement

    * The replacement text. *

    * @param string $string

    * The string being checked. *

    * @param string|null $options Matching condition can be set by option * parameter. If i is specified for this * parameter, the case will be ignored. If x is * specified, white space will be ignored. If m * is specified, match will be executed in multiline mode and line * break will be included in '.'. If p is * specified, match will be executed in POSIX mode, line break * will be considered as normal character. If e * is specified, replacement string will be * evaluated as PHP expression. *

    PHP 7.1: The e modifier has been deprecated.

    * @return string|false|null The resultant string on success, or false on error. */ #[Pure] function mb_ereg_replace(string $pattern, string $replacement, string $string, ?string $options = null): string|false|null {} /** * Perform a regular expresssion seach and replace with multibyte support using a callback * @link https://secure.php.net/manual/en/function.mb-ereg-replace-callback.php * @param string $pattern

    * The regular expression pattern. *

    *

    * Multibyte characters may be used in pattern. *

    * @param callable $callback

    * A callback that will be called and passed an array of matched elements * in the subject string. The callback should * return the replacement string. *

    *

    * You'll often need the callback function * for a mb_ereg_replace_callback() in just one place. * In this case you can use an anonymous function to * declare the callback within the call to * mb_ereg_replace_callback(). By doing it this way * you have all information for the call in one place and do not * clutter the function namespace with a callback function's name * not used anywhere else. *

    * @param string $string

    * The string being checked. *

    * @param string $options

    * Matching condition can be set by option * parameter. If i is specified for this * parameter, the case will be ignored. If x is * specified, white space will be ignored. If m * is specified, match will be executed in multiline mode and line * break will be included in '.'. If p is * specified, match will be executed in POSIX mode, line break * will be considered as normal character. Note that e * cannot be used for mb_ereg_replace_callback(). *

    * @return string|false|null

    * The resultant string on success, or FALSE on error. *

    * @since 5.4.1 */ function mb_ereg_replace_callback(string $pattern, callable $callback, string $string, ?string $options = null): string|false|null {} /** * Replace regular expression with multibyte support ignoring case * @link https://php.net/manual/en/function.mb-eregi-replace.php * @param string $pattern

    * The regular expression pattern. Multibyte characters may be used. The case will be ignored. *

    * @param string $replacement

    * The replacement text. *

    * @param string $string

    * The searched string. *

    * @param string|null $options option has the same meaning as in * mb_ereg_replace. *

    PHP 7.1: The e modifier has been deprecated.

    * @return string|false|null The resultant string or false on error. */ #[Pure] function mb_eregi_replace( string $pattern, string $replacement, string $string, #[PhpStormStubsElementAvailable(from: '7.0')] ?string $options = null ): string|false|null {} /** * Split multibyte string using regular expression * @link https://php.net/manual/en/function.mb-split.php * @param string $pattern

    * The regular expression pattern. *

    * @param string $string

    * The string being split. *

    * @param int $limit [optional] If optional parameter limit is specified, * it will be split in limit elements as * maximum. * @return string[]|false The result as an array. */ #[Pure] function mb_split(string $pattern, string $string, int $limit = -1): array|false {} /** * Regular expression match for multibyte string * @link https://php.net/manual/en/function.mb-ereg-match.php * @param string $pattern

    * The regular expression pattern. *

    * @param string $string

    * The string being evaluated. *

    * @param string|null $options [optional]

    *

    * @return bool */ #[Pure] function mb_ereg_match(string $pattern, string $string, ?string $options): bool {} /** * Multibyte regular expression match for predefined multibyte string * @link https://php.net/manual/en/function.mb-ereg-search.php * @param string|null $pattern [optional]

    * The search pattern. *

    * @param string|null $options [optional]

    * The search option. *

    * @return bool */ #[Pure] function mb_ereg_search(?string $pattern, ?string $options): bool {} /** * Returns position and length of a matched part of the multibyte regular expression for a predefined multibyte string * @link https://php.net/manual/en/function.mb-ereg-search-pos.php * @param string|null $pattern [optional]

    * The search pattern. *

    * @param string|null $options [optional]

    * The search option. *

    * @return int[]|false An array containing two elements. The first * element is the offset, in bytes, where the match begins relative * to the start of the search string, and the second element is the * length in bytes of the match. If an error occurs, FALSE is returned. */ #[Pure] function mb_ereg_search_pos(?string $pattern, ?string $options): array|false {} /** * Returns the matched part of a multibyte regular expression * @link https://php.net/manual/en/function.mb-ereg-search-regs.php * @param string|null $pattern [optional]

    * The search pattern. *

    * @param string|null $options [optional]

    * The search option. *

    * @return string[]|false mb_ereg_search_regs() executes the multibyte * regular expression match, and if there are some matched part, it * returns an array including substring of matched part as first element, * the first grouped part with brackets as second element, the second grouped * part as third element, and so on. It returns FALSE on error. */ #[Pure] function mb_ereg_search_regs(?string $pattern, ?string $options): array|false {} /** * Setup string and regular expression for a multibyte regular expression match * @link https://php.net/manual/en/function.mb-ereg-search-init.php * @param string $string

    * The search string. *

    * @param string|null $pattern [optional]

    * The search pattern. *

    * @param string|null $options [optional]

    * The search option. *

    * @return bool */ function mb_ereg_search_init(string $string, ?string $pattern, ?string $options): bool {} /** * Retrieve the result from the last multibyte regular expression match * @link https://php.net/manual/en/function.mb-ereg-search-getregs.php * @return string[]|false An array including the sub-string of matched * part by last mb_ereg_search(), mb_ereg_search_pos(), mb_ereg_search_regs(). * If there are some matches, the first element will have the matched * sub-string, the second element will have the first part grouped with * brackets, the third element will have the second part grouped with * brackets, and so on. It returns FALSE on error; */ #[Pure] function mb_ereg_search_getregs(): array|false {} /** * Returns start point for next regular expression match * @link https://php.net/manual/en/function.mb-ereg-search-getpos.php * @return int */ #[Pure] function mb_ereg_search_getpos(): int {} /** * Set start point of next regular expression match * @link https://php.net/manual/en/function.mb-ereg-search-setpos.php * @param int $offset

    * The position to set. *

    * @return bool */ #[Pure] function mb_ereg_search_setpos(int $offset): bool {} /** * @param $encoding [optional] * @see mb_regex_encoding * @removed 8.0 */ #[Deprecated(replacement: "mb_regex_encoding(%parametersList%)", since: "7.3")] function mbregex_encoding($encoding) {} /** * @param string $pattern * @param string $string * @param array &$registers [optional] * @see mb_ereg * @removed 8.0 */ #[Deprecated(replacement: 'mb_ereg(%parametersList%)', since: '7.3')] function mbereg(string $pattern, string $string, array &$registers) {} /** * @param string $pattern * @param string $string * @param array &$registers [optional] * @see mb_eregi * @removed 8.0 */ #[Deprecated(replacement: "mb_eregi(%parametersList%)", since: "7.3")] function mberegi(string $pattern, string $string, array &$registers) {} /** * @param $pattern * @param $replacement * @param $string * @param $option [optional] * @see mb_ereg_replace * @removed 8.0 */ #[Deprecated(replacement: 'mb_ereg_replace(%parametersList%)', since: '7.3')] function mbereg_replace($pattern, $replacement, $string, $option) {} /** * @param $pattern * @param $replacement * @param $string * @param string $option * @return string * @see mb_eregi_replace * @removed 8.0 */ #[Deprecated(replacement: "mb_eregi_replace(%parametersList%)", since: "7.3")] function mberegi_replace( $pattern, $replacement, $string, #[PhpStormStubsElementAvailable(from: '7.0')] string $option = "msri" ): string {} /** * @param $pattern * @param $string * @param $limit [optional] * @see mb_split * @removed 8.0 */ #[Deprecated(replacement: 'mb_split(%parametersList%)', since: '7.3')] function mbsplit($pattern, $string, $limit) {} /** * @param $pattern * @param $string * @param $option [optional] * @see mb_ereg_match * @removed 8.0 */ #[Deprecated(replacement: "mb_ereg_match(%parametersList%)", since: "7.3")] function mbereg_match($pattern, $string, $option) {} /** * @param $pattern [optional] * @param $option [optional] * @see mb_ereg_search * @removed 8.0 */ #[Deprecated("use mb_ereg_search instead", replacement: "mb_ereg_search(%parametersList%)", since: "7.3")] function mbereg_search($pattern, $option) {} /** * @param $pattern [optional] * @param $option [optional] * @see mb_ereg_search_pos * @removed 8.0 */ #[Deprecated(replacement: "mb_ereg_search_pos(%parametersList%)", since: "7.3")] function mbereg_search_pos($pattern, $option) {} /** * @param $pattern [optional] * @param $option [optional] * @see mb_ereg_search_regs * @removed 8.0 */ #[Deprecated(replacement: 'mb_ereg_search_regs(%parametersList%)', since: '7.3')] function mbereg_search_regs($pattern, $option) {} /** * @param $string * @param $pattern [optional] * @param $option [optional] * @see mb_ereg_search_init * @removed 8.0 */ #[Deprecated(replacement: "mb_ereg_search_init(%parametersList%)", since: "7.3")] function mbereg_search_init($string, $pattern, $option) {} /** * @see mb_ereg_search_getregs * @removed 8.0 */ #[Deprecated(replacement: 'mb_ereg_search_getregs(%parametersList%)', since: '7.3')] function mbereg_search_getregs() {} /** * @see mb_ereg_search_getpos * @removed 8.0 */ #[Deprecated(replacement: "mb_ereg_search_getpos()", since: "7.3")] function mbereg_search_getpos() {} /** * Get a specific character. * @link https://www.php.net/manual/en/function.mb-chr.php * @param int $codepoint * @param string|null $encoding [optional] * @return string|false specific character or FALSE on failure. * @since 7.2 */ #[Pure] function mb_chr(int $codepoint, ?string $encoding): string|false {} /** * Get code point of character * @link https://www.php.net/manual/en/function.mb-ord.php * @param string $string * @param string|null $encoding [optional] * @return int|false code point of character or FALSE on failure. * @since 7.2 */ #[Pure] function mb_ord(string $string, ?string $encoding): int|false {} /** * Scrub broken multibyte strings. * @link https://www.php.net/manual/en/function.mb-scrub.php * @param string $string * @param string|null $encoding [optional] * @return string|false * @since 7.2 */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "string"], default: "string|false")] function mb_scrub(string $string, ?string $encoding): false|string {} /** * @param $position * @see mb_ereg_search_setpos */ #[Deprecated(replacement: "mb_ereg_search_setpos(%parametersList%)", since: "7.3")] #[Pure] function mbereg_search_setpos($position) {} /** * Function performs string splitting to an array of defined size chunks. * @param string $string

    * The string to split into characters or chunks. *

    * @param int $length [optional]

    * If specified, each element of the returned array will be composed of multiple characters instead of a single character. *

    * @param string|null $encoding [optional]

    * Character encoding name to use. * If it is omitted, internal character encoding is used. *

    * @return string[]|false * @since 7.4 */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "array"], default: "array|false")] function mb_str_split(string $string, int $length = 1, ?string $encoding) {} /** * @since 8.3 */ function mb_str_pad(string $string, int $length, string $pad_string = " ", int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string {} /** * @since 8.4 */ function mb_ucfirst(string $string, ?string $encoding = null): string {} /** * @since 8.4 */ function mb_lcfirst(string $string, ?string $encoding = null): string {} /** * @since 8.4 */ function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string {} /** * @since 8.4 */ function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string {} /** * @since 8.4 */ function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string {} /** * @removed 8.0 */ define('MB_OVERLOAD_MAIL', 1); /** * @removed 8.0 */ define('MB_OVERLOAD_STRING', 2); /** * @removed 8.0 */ define('MB_OVERLOAD_REGEX', 4); define('MB_CASE_UPPER', 0); define('MB_CASE_LOWER', 1); define('MB_CASE_TITLE', 2); /** * @since 7.3 */ define('MB_CASE_FOLD', 3); /** * @since 7.3 */ define('MB_CASE_UPPER_SIMPLE', 4); /** * @since 7.3 */ define('MB_CASE_LOWER_SIMPLE', 5); /** * @since 7.3 */ define('MB_CASE_TITLE_SIMPLE', 6); /** * @since 7.3 */ define('MB_CASE_FOLD_SIMPLE', 7); /** * @since 7.4 */ define('MB_ONIGURUMA_VERSION', '6.9.9'); // End of mbstring v. * the severity of the error (one of the following constants: * LIBXML_ERR_WARNING, * LIBXML_ERR_ERROR or * LIBXML_ERR_FATAL) *

    * @var int */ public int $level; /** *

    * The error's code. *

    * @var int */ public int $code; /** *

    * The column where the error occurred. *

    *

    Note: *

    * This property isn't entirely implemented in libxml and therefore * 0 is often returned. *

    * @var int */ public int $column; /** *

    * The error message, if any. *

    * @var string */ public string $message; /** *

    The filename, or empty if the XML was loaded from a string.

    * @var string */ public string $file; /** *

    * The line where the error occurred. *

    * @var int */ public int $line; } /** * Set the streams context for the next libxml document load or write * @link https://php.net/manual/en/function.libxml-set-streams-context.php * @param resource $context

    * The stream context resource (created with * stream_context_create) *

    * @return void No value is returned. */ function libxml_set_streams_context($context): void {} /** * Disable libxml errors and allow user to fetch error information as needed * @link https://php.net/manual/en/function.libxml-use-internal-errors.php * @param bool|null $use_errors

    * Enable (TRUE) user error handling or disable (FALSE) user error handling. Disabling will also clear any existing libxml errors. *

    * @return bool This function returns the previous value of * use_errors. */ function libxml_use_internal_errors( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] bool $use_errors = false, #[PhpStormStubsElementAvailable(from: '8.0')] ?bool $use_errors = null ): bool {} /** * Retrieve last error from libxml * @link https://php.net/manual/en/function.libxml-get-last-error.php * @return LibXMLError|false a LibXMLError object if there is any error in the * buffer, FALSE otherwise. */ #[Pure(true)] function libxml_get_last_error(): LibXMLError|false {} /** * Clear libxml error buffer * @link https://php.net/manual/en/function.libxml-clear-errors.php * @return void No value is returned. */ function libxml_clear_errors(): void {} /** * Retrieve array of errors * @link https://php.net/manual/en/function.libxml-get-errors.php * @return LibXMLError[] an array with LibXMLError objects if there are any * errors in the buffer, or an empty array otherwise. */ #[Pure(true)] function libxml_get_errors(): array {} /** * Disable the ability to load external entities * @link https://php.net/manual/en/function.libxml-disable-entity-loader.php * @param bool $disable [optional]

    * Disable (TRUE) or enable (FALSE) libxml extensions (such as * , * and ) to load external entities. *

    * @return bool the previous value. * @since 5.2.11 */ #[Deprecated(since: "8.0")] function libxml_disable_entity_loader(bool $disable = true): bool {} /** * Changes the default external entity loader * @link https://php.net/manual/en/function.libxml-set-external-entity-loader.php * @param callable|null $resolver_function

    * A callable that takes three arguments. Two strings, a public id * and system id, and a context (an array with four keys) as the third argument. * This callback should return a resource, a string from which a resource can be * opened, or NULL. *

    * @return bool * @since 5.4 */ function libxml_set_external_entity_loader(?callable $resolver_function): bool {} /** * Returns the currently installed external entity loader, i.e. the value which was passed to * libxml_set_external_entity_loader() or null if no loader was installed and the default entity loader will be used. * This allows libraries to save and restore the loader, controlling entity expansion without interfering with the rest * of the application. * * @return callable|null * @since 8.2 */ function libxml_get_external_entity_loader(): ?callable {} /** * libxml version like 20605 or 20617 * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_VERSION', 20901); /** * libxml version like 2.6.5 or 2.6.17 * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_DOTTED_VERSION', "2.9.1"); define('LIBXML_LOADED_VERSION', 20901); /** * Substitute entities * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_NOENT', 2); /** * Load the external subset * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_DTDLOAD', 4); /** * Default DTD attributes * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_DTDATTR', 8); /** * Validate with the DTD * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_DTDVALID', 16); /** * Suppress error reports * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_NOERROR', 32); /** * Suppress warning reports * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_NOWARNING', 64); /** * Remove blank nodes * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_NOBLANKS', 256); /** * Implement XInclude substitution * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_XINCLUDE', 1024); /** * Remove redundant namespaces declarations * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_NSCLEAN', 8192); /** * Merge CDATA as text nodes * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_NOCDATA', 16384); /** * Disable network access when loading documents * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_NONET', 2048); /** * Sets XML_PARSE_PEDANTIC flag, which enables pedentic error reporting. * @link https://php.net/manual/en/libxml.constants.php * @since 5.4 */ define('LIBXML_PEDANTIC', 128); /** * Activate small nodes allocation optimization. This may speed up your * application without needing to change the code. *

    * Only available in Libxml >= 2.6.21 *

    * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_COMPACT', 65536); /** * Allows line numbers greater than 65535 to be reported correctly. *

    * Only available in Libxml >= 2.9.0 *

    * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_BIGLINES', 65535); /** * Drop the XML declaration when saving a document *

    * Only available in Libxml >= 2.6.21 *

    * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_NOXMLDECL', 2); /** * Sets XML_PARSE_HUGE flag, which relaxes any hardcoded limit from the parser. This affects * limits like maximum depth of a document or the entity recursion, as well as limits of the * size of text nodes. *

    * Only available in Libxml >= 2.7.0 (as of PHP >= 5.3.2 and PHP >= 5.2.12) *

    * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_PARSEHUGE', 524288); /** * Expand empty tags (e.g. <br/> to * <br></br>) *

    * This option is currently just available in the * and * functions. *

    * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_NOEMPTYTAG', 4); /** * Create default/fixed value nodes during XSD schema validation *

    * Only available in Libxml >= 2.6.14 (as of PHP >= 5.5.2) *

    * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_SCHEMA_CREATE', 1); /** * Sets HTML_PARSE_NOIMPLIED flag, which turns off the * automatic adding of implied html/body... elements. *

    * Only available in Libxml >= 2.7.7 (as of PHP >= 5.4.0) *

    * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_HTML_NOIMPLIED', 8192); /** * Sets HTML_PARSE_NODEFDTD flag, which prevents a default doctype * being added when one is not found. *

    * Only available in Libxml >= 2.7.8 (as of PHP >= 5.4.0) *

    * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_HTML_NODEFDTD', 4); /** * No errors * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_ERR_NONE', 0); /** * A simple warning * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_ERR_WARNING', 1); /** * A recoverable error * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_ERR_ERROR', 2); /** * A fatal error * @link https://php.net/manual/en/libxml.constants.php */ define('LIBXML_ERR_FATAL', 3); /** * @since 8.4 */ define('LIBXML_RECOVER', 1); // End of libxml v. * Returns the difference between two DateTime objects * @link https://secure.php.net/manual/en/datetime.diff.php * @param DateTimeInterface $targetObject

    The date to compare to.

    * @param bool $absolute

    Should the interval be forced to be positive?

    * @return DateInterval * The https://secure.php.net/manual/en/class.dateinterval.php DateInterval} object representing the * difference between the two dates. */ #[TentativeType] public function diff( DateTimeInterface $targetObject, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $absolute = false ): DateInterval; /** * (PHP 5 >=5.5.0)
    * Returns date formatted according to given format * @link https://secure.php.net/manual/en/datetime.format.php * @param string $format

    * Format accepted by {@link https://secure.php.net/manual/en/function.date.php date()}. *

    * @return string * Returns the formatted date string on success or FALSE on failure. * Since PHP8, it always returns STRING. */ #[TentativeType] public function format(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $format): string; /** * (PHP 5 >=5.5.0)
    * Returns the timezone offset * @return int|false * Returns the timezone offset in seconds from UTC on success * or FALSE on failure. Since PHP8, it always returns INT. */ #[LanguageLevelTypeAware(["8.0" => "int"], default: "int|false")] #[TentativeType] public function getOffset(): int; /** * (PHP 5 >=5.5.0)
    * Gets the Unix timestamp * @return int * Returns the Unix timestamp representing the date. */ #[TentativeType] #[LanguageLevelTypeAware(['8.1' => 'int'], default: 'int|false')] public function getTimestamp(); /** * (PHP 5 >=5.5.0)
    * Return time zone relative to given DateTime * @link https://secure.php.net/manual/en/datetime.gettimezone.php * @return DateTimeZone|false * Returns a {@link https://secure.php.net/manual/en/class.datetimezone.php DateTimeZone} object on success * or FALSE on failure. */ #[TentativeType] public function getTimezone(): DateTimeZone|false; /** * (PHP 5 >=5.5.0)
    * The __wakeup handler * @link https://secure.php.net/manual/en/datetime.wakeup.php * @return void Initializes a DateTime object. */ #[TentativeType] public function __wakeup(): void; #[PhpStormStubsElementAvailable(from: '8.2')] public function __serialize(): array; #[PhpStormStubsElementAvailable(from: '8.2')] public function __unserialize(array $data): void; /** * @since 8.4 */ public function createFromTimestamp(); /** * @since 8.4 */ public function getMicrosecond(): int; /** * @since 8.4 */ public function setMicrosecond(); } /** * @since 5.5 */ class DateTimeImmutable implements DateTimeInterface { /* Methods */ /** * (PHP 5 >=5.5.0)
    * @link https://secure.php.net/manual/en/datetimeimmutable.construct.php * @param string $datetime [optional] *

    A date/time string. Valid formats are explained in {@link https://secure.php.net/manual/en/datetime.formats.php Date and Time Formats}.

    *

    Enter NULL here to obtain the current time when using the $timezone parameter.

    * @param null|DateTimeZone $timezone [optional]

    * A {@link https://secure.php.net/manual/en/class.datetimezone.php DateTimeZone} object representing the timezone of $datetime. *

    *

    If $timezone is omitted, the current timezone will be used.

    *

    Note:

    * The $timezone parameter and the current timezone are ignored when the $datetime parameter either * is a UNIX timestamp (e.g. @946684800) or specifies a timezone (e.g. 2010-01-28T15:00:00+02:00). *

    * @throws DateMalformedStringException Emits Exception in case of an error. */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $datetime = "now", #[LanguageLevelTypeAware(['8.0' => 'DateTimeZone|null'], default: 'DateTimeZone')] $timezone = null ) {} /** * (PHP 5 >=5.5.0)
    * Adds an amount of days, months, years, hours, minutes and seconds * @param DateInterval $interval * @return static * @link https://secure.php.net/manual/en/datetimeimmutable.add.php */ #[TentativeType] public function add(DateInterval $interval): DateTimeImmutable {} /** * (PHP 5 >=5.5.0)
    * Returns new DateTimeImmutable object formatted according to the specified format * @link https://secure.php.net/manual/en/datetimeimmutable.createfromformat.php * @param string $format * @param string $datetime * @param null|DateTimeZone $timezone [optional] * @return DateTimeImmutable|false */ #[TentativeType] public static function createFromFormat( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $format, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $datetime, #[LanguageLevelTypeAware(['8.0' => 'DateTimeZone|null'], default: 'DateTimeZone')] $timezone = null ): DateTimeImmutable|false {} /** * (PHP 5 >=5.6.0)
    * Returns new DateTimeImmutable object encapsulating the given DateTime object * @link https://secure.php.net/manual/en/datetimeimmutable.createfrommutable.php * @param DateTime $object The mutable DateTime object that you want to convert to an immutable version. This object is not modified, but instead a new DateTimeImmutable object is created containing the same date time and timezone information. * @return DateTimeImmutable returns a new DateTimeImmutable instance. */ #[TentativeType] #[LanguageLevelTypeAware(['8.2' => 'static'], default: 'DateTimeImmutable')] public static function createFromMutable(DateTime $object) {} /** * (PHP 5 >=5.5.0)
    * Returns the warnings and errors * @link https://secure.php.net/manual/en/datetimeimmutable.getlasterrors.php * @return array|false Returns array containing info about warnings and errors. */ #[ArrayShape(["warning_count" => "int", "warnings" => "string[]", "error_count" => "int", "errors" => "string[]"])] #[TentativeType] public static function getLastErrors(): array|false {} /** * (PHP 5 >=5.5.0)
    * Alters the timestamp * @link https://secure.php.net/manual/en/datetimeimmutable.modify.php * @param string $modifier

    A date/time string. Valid formats are explained in * {@link https://secure.php.net/manual/en/datetime.formats.php Date and Time Formats}.

    * @return static|false Returns the newly created object or false on failure. * @throws DateMalformedStringException * Returns the {@link https://secure.php.net/manual/en/class.datetimeimmutable.php DateTimeImmutable} object for method chaining or FALSE on failure. */ #[Pure] #[TentativeType] #[LanguageLevelTypeAware(['8.4' => 'DateTimeImmutable'], default: 'DateTimeImmutable|false')] public function modify(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $modifier) {} /** * (PHP 5 >=5.5.0)
    * The __set_state handler * @link https://secure.php.net/manual/en/datetimeimmutable.set-state.php * @param array $array

    Initialization array.

    * @return DateTimeImmutable * Returns a new instance of a {@link https://secure.php.net/manual/en/class.datetimeimmutable.php DateTimeImmutable} object. */ public static function __set_state(array $array) {} /** * (PHP 5 >=5.5.0)
    * Sets the date * @link https://secure.php.net/manual/en/datetimeimmutable.setdate.php * @param int $year

    Year of the date.

    * @param int $month

    Month of the date.

    * @param int $day

    Day of the date.

    * @return static|false * Returns the {@link https://secure.php.net/manual/en/class.datetimeimmutable.php DateTimeImmutable} object for method chaining or FALSE on failure. */ #[TentativeType] public function setDate( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $year, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $month, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $day ): DateTimeImmutable {} /** * (PHP 5 >=5.5.0)
    * Sets the ISO date * @link https://php.net/manual/en/class.datetimeimmutable.php * @param int $year

    Year of the date.

    * @param int $week

    Week of the date.

    * @param int $dayOfWeek [optional]

    Offset from the first day of the week.

    * @return static|false * Returns the {@link https://secure.php.net/manual/en/class.datetimeimmutable.php DateTimeImmutable} object for method chaining or FALSE on failure. */ #[TentativeType] public function setISODate( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $year, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $week, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $dayOfWeek = 1 ): DateTimeImmutable {} /** * (PHP 5 >=5.5.0)
    * Sets the time * @link https://secure.php.net/manual/en/datetimeimmutable.settime.php * @param int $hour

    Hour of the time.

    * @param int $minute

    Minute of the time.

    * @param int $second [optional]

    Second of the time.

    * @param int $microsecond [optional]

    Microseconds of the time. Added since 7.1

    * @return static|false * Returns the {@link https://secure.php.net/manual/en/class.datetimeimmutable.php DateTimeImmutable} object for method chaining or FALSE on failure. */ #[TentativeType] public function setTime( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $hour, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $minute, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $second = 0, #[PhpStormStubsElementAvailable(from: '7.1')] #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $microsecond = 0 ): DateTimeImmutable {} /** * (PHP 5 >=5.5.0)
    * Sets the date and time based on an Unix timestamp * @link https://secure.php.net/manual/en/datetimeimmutable.settimestamp.php * @param int $timestamp

    Unix timestamp representing the date.

    * @return static * Returns the {@link https://secure.php.net/manual/en/class.datetimeimmutable.php DateTimeImmutable} object for method chaining or FALSE on failure. */ #[TentativeType] public function setTimestamp(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $timestamp): DateTimeImmutable {} /** * (PHP 5 >=5.5.0)
    * Sets the time zone * @link https://secure.php.net/manual/en/datetimeimmutable.settimezone.php * @param DateTimeZone $timezone

    * A {@link https://secure.php.net/manual/en/class.datetimezone.php DateTimeZone} object representing the * desired time zone. *

    * @return static * Returns the {@link https://secure.php.net/manual/en/class.datetimeimmutable.php DateTimeImmutable} object for method chaining or FALSE on failure. */ #[TentativeType] public function setTimezone(DateTimeZone $timezone): DateTimeImmutable {} /** * (PHP 5 >=5.5.0)
    * Subtracts an amount of days, months, years, hours, minutes and seconds * @link https://secure.php.net/manual/en/datetimeimmutable.sub.php * @param DateInterval $interval

    * A {@link https://secure.php.net/manual/en/class.dateinterval.php DateInterval} object *

    * @return static * @throws DateInvalidOperationException * Returns the {@link https://secure.php.net/manual/en/class.datetimeimmutable.php DateTimeImmutable} object for method chaining or FALSE on failure. */ #[TentativeType] public function sub(DateInterval $interval): DateTimeImmutable {} /** * (PHP 5 >=5.5.0)
    * Returns the difference between two DateTime objects * @link https://secure.php.net/manual/en/datetime.diff.php * @param DateTimeInterface $targetObject

    The date to compare to.

    * @param bool $absolute [optional]

    Should the interval be forced to be positive?

    * @return DateInterval|false * The {@link https://secure.php.net/manual/en/class.dateinterval.php DateInterval} object representing the * difference between the two dates or FALSE on failure. */ #[TentativeType] public function diff( #[LanguageLevelTypeAware(['8.0' => 'DateTimeInterface'], default: '')] $targetObject, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $absolute = false ): DateInterval {} /** * (PHP 5 >=5.5.0)
    * Returns date formatted according to given format * @link https://secure.php.net/manual/en/datetime.format.php * @param string $format

    * Format accepted by {@link https://secure.php.net/manual/en/function.date.php date()}. *

    * @return string * Returns the formatted date string on success or FALSE on failure. */ #[TentativeType] public function format(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $format): string {} /** * (PHP 5 >=5.5.0)
    * Returns the timezone offset * @return int * Returns the timezone offset in seconds from UTC on success * or FALSE on failure. */ #[TentativeType] public function getOffset(): int {} /** * (PHP 5 >=5.5.0)
    * Gets the Unix timestamp * @return int * Returns the Unix timestamp representing the date. */ #[TentativeType] public function getTimestamp(): int {} /** * (PHP 5 >=5.5.0)
    * Return time zone relative to given DateTime * @link https://secure.php.net/manual/en/datetime.gettimezone.php * @return DateTimeZone|false * Returns a {@link https://secure.php.net/manual/en/class.datetimezone.php DateTimeZone} object on success * or FALSE on failure. */ #[TentativeType] public function getTimezone(): DateTimeZone|false {} /** * (PHP 5 >=5.5.0)
    * The __wakeup handler * @link https://secure.php.net/manual/en/datetime.wakeup.php * @return void Initializes a DateTime object. */ #[TentativeType] public function __wakeup(): void {} /** * @param DateTimeInterface $object * @return DateTimeImmutable * @since 8.0 */ public static function createFromInterface(DateTimeInterface $object): DateTimeImmutable {} #[PhpStormStubsElementAvailable(from: '8.2')] public function __serialize(): array {} #[PhpStormStubsElementAvailable(from: '8.2')] public function __unserialize(array $data): void {} /** * @since 8.4 */ #[TentativeType] public static function createFromTimestamp(int|float $timestamp): static {} /** * @since 8.4 */ public function getMicrosecond(): int {} /** * @since 8.4 */ public function setMicrosecond(int $microsecond): static {} } /** * Representation of date and time. * @link https://php.net/manual/en/class.datetime.php */ class DateTime implements DateTimeInterface { /** * @removed 7.2 */ public const ATOM = 'Y-m-d\TH:i:sP'; /** * @removed 7.2 */ public const COOKIE = 'l, d-M-Y H:i:s T'; /** * @removed 7.2 */ public const ISO8601 = 'Y-m-d\TH:i:sO'; /** * @removed 7.2 */ public const RFC822 = 'D, d M y H:i:s O'; /** * @removed 7.2 */ public const RFC850 = 'l, d-M-y H:i:s T'; /** * @removed 7.2 */ public const RFC1036 = 'D, d M y H:i:s O'; /** * @removed 7.2 */ public const RFC1123 = 'D, d M Y H:i:s O'; /** * @removed 7.2 */ public const RFC2822 = 'D, d M Y H:i:s O'; /** * @removed 7.2 */ public const RFC3339 = 'Y-m-d\TH:i:sP'; /** * @removed 7.2 */ public const RFC3339_EXTENDED = 'Y-m-d\TH:i:s.vP'; /** * @removed 7.2 */ public const RFC7231 = 'D, d M Y H:i:s \G\M\T'; /** * @removed 7.2 */ public const RSS = 'D, d M Y H:i:s O'; /** * @removed 7.2 */ public const W3C = 'Y-m-d\TH:i:sP'; /** * (PHP 5 >=5.2.0)
    * @link https://php.net/manual/en/datetime.construct.php * @param string $datetime [optional] *

    A date/time string. Valid formats are explained in {@link https://php.net/manual/en/datetime.formats.php Date and Time Formats}.

    *

    * Enter now here to obtain the current time when using * the $timezone parameter. *

    * @param null|DateTimeZone $timezone [optional]

    * A {@link https://php.net/manual/en/class.datetimezone.php DateTimeZone} object representing the * timezone of $datetime. *

    *

    * If $timezone is omitted, * the current timezone will be used. *

    *

    Note: *

    * The $timezone parameter * and the current timezone are ignored when the * $time parameter either * is a UNIX timestamp (e.g. @946684800) * or specifies a timezone * (e.g. 2010-01-28T15:00:00+02:00). *

    * @throws DateMalformedStringException Emits Exception in case of an error. */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $datetime = 'now', #[LanguageLevelTypeAware(['8.0' => 'DateTimeZone|null'], default: 'DateTimeZone')] $timezone = null ) {} /** * @return void * @link https://php.net/manual/en/datetime.wakeup.php */ #[TentativeType] public function __wakeup(): void {} /** * Returns date formatted according to given format. * @param string $format * @return string * @link https://php.net/manual/en/datetime.format.php */ #[TentativeType] public function format(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $format): string {} /** * Alter the timestamp of a DateTime object by incrementing or decrementing * in a format accepted by strtotime(). * @param string $modifier A date/time string. Valid formats are explained in Date and Time Formats. * @return static|false Returns the DateTime object for method chaining or FALSE on failure. * @throws DateMalformedStringException * @link https://php.net/manual/en/datetime.modify.php */ #[TentativeType] #[LanguageLevelTypeAware(['8.4' => 'DateTime'], default: 'DateTime|false')] public function modify(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $modifier) {} /** * Adds an amount of days, months, years, hours, minutes and seconds to a DateTime object * @param DateInterval $interval * @return static * @link https://php.net/manual/en/datetime.add.php */ #[TentativeType] public function add(DateInterval $interval): DateTime {} /** * @param DateTimeImmutable $object * @return DateTime * @since 7.3 */ #[TentativeType] #[LanguageLevelTypeAware(['8.2' => 'static'], default: 'DateTime')] public static function createFromImmutable(DateTimeImmutable $object) {} /** * Subtracts an amount of days, months, years, hours, minutes and seconds from a DateTime object * @param DateInterval $interval * @return static * @link https://php.net/manual/en/datetime.sub.php */ #[TentativeType] public function sub(DateInterval $interval): DateTime {} /** * Get the TimeZone associated with the DateTime * @return DateTimeZone|false * @link https://php.net/manual/en/datetime.gettimezone.php */ #[TentativeType] public function getTimezone(): DateTimeZone|false {} /** * Set the TimeZone associated with the DateTime * @param DateTimeZone $timezone * @return static * @link https://php.net/manual/en/datetime.settimezone.php */ #[TentativeType] public function setTimezone(#[LanguageLevelTypeAware(['8.0' => 'DateTimeZone'], default: '')] $timezone): DateTime {} /** * Returns the timezone offset * @return int * @link https://php.net/manual/en/datetime.getoffset.php */ #[TentativeType] public function getOffset(): int {} /** * Sets the current time of the DateTime object to a different time. * @param int $hour * @param int $minute * @param int $second * @param int $microsecond Added since 7.1 * @return static * @link https://php.net/manual/en/datetime.settime.php */ #[TentativeType] public function setTime( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $hour, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $minute, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $second = 0, #[PhpStormStubsElementAvailable(from: '7.1')] #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $microsecond = 0 ): DateTime {} /** * Sets the current date of the DateTime object to a different date. * @param int $year * @param int $month * @param int $day * @return static * @link https://php.net/manual/en/datetime.setdate.php */ #[TentativeType] public function setDate( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $year, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $month, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $day ): DateTime {} /** * Set a date according to the ISO 8601 standard - using weeks and day offsets rather than specific dates. * @param int $year * @param int $week * @param int $dayOfWeek * @return static * @link https://php.net/manual/en/datetime.setisodate.php */ #[TentativeType] public function setISODate( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $year, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $week, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $dayOfWeek = 1 ): DateTime {} /** * Sets the date and time based on a Unix timestamp. * @param int $timestamp * @return static * @link https://php.net/manual/en/datetime.settimestamp.php */ #[TentativeType] public function setTimestamp(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $timestamp): DateTime {} /** * Gets the Unix timestamp. * @return int * @link https://php.net/manual/en/datetime.gettimestamp.php */ #[TentativeType] public function getTimestamp(): int {} /** * Returns the difference between two DateTime objects represented as a DateInterval. * @param DateTimeInterface $targetObject The date to compare to. * @param bool $absolute [optional] Whether to return absolute difference. * @return DateInterval|false The DateInterval object representing the difference between the two dates. * @link https://php.net/manual/en/datetime.diff.php */ #[TentativeType] public function diff( #[LanguageLevelTypeAware(['8.0' => 'DateTimeInterface'], default: '')] $targetObject, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $absolute = false ): DateInterval {} /** * Parse a string into a new DateTime object according to the specified format * @param string $format Format accepted by date(). * @param string $datetime String representing the time. * @param null|DateTimeZone $timezone A DateTimeZone object representing the desired time zone. * @return DateTime|false * @link https://php.net/manual/en/datetime.createfromformat.php */ #[TentativeType] public static function createFromFormat( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $format, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $datetime, #[LanguageLevelTypeAware(['8.0' => 'DateTimeZone|null'], default: 'DateTimeZone')] $timezone = null ): DateTime|false {} /** * Returns an array of warnings and errors found while parsing a date/time string * @return array|false * @link https://php.net/manual/en/datetime.getlasterrors.php */ #[ArrayShape(["warning_count" => "int", "warnings" => "string[]", "error_count" => "int", "errors" => "string[]"])] #[TentativeType] public static function getLastErrors(): array|false {} /** * The __set_state handler * @link https://php.net/manual/en/datetime.set-state.php * @param array $array

    Initialization array.

    * @return DateTime

    Returns a new instance of a DateTime object.

    */ public static function __set_state($array) {} /** * @param DateTimeInterface $object * @return DateTime * @since 8.0 */ public static function createFromInterface(DateTimeInterface $object): DateTime {} #[PhpStormStubsElementAvailable(from: '8.2')] public function __serialize(): array {} #[PhpStormStubsElementAvailable(from: '8.2')] public function __unserialize(array $data): void {} /** * @since 8.4 */ #[TentativeType] public static function createFromTimestamp(int|float $timestamp): static {} /** * @since 8.4 */ public function getMicrosecond(): int {} /** * @since 8.4 */ public function setMicrosecond(int $microsecond): static {} } /** * Representation of time zone * @link https://php.net/manual/en/class.datetimezone.php */ class DateTimeZone { public const AFRICA = 1; public const AMERICA = 2; public const ANTARCTICA = 4; public const ARCTIC = 8; public const ASIA = 16; public const ATLANTIC = 32; public const AUSTRALIA = 64; public const EUROPE = 128; public const INDIAN = 256; public const PACIFIC = 512; public const UTC = 1024; public const ALL = 2047; public const ALL_WITH_BC = 4095; public const PER_COUNTRY = 4096; /** * @param string $timezone * @link https://php.net/manual/en/datetimezone.construct.php * @throws DateInvalidTimeZoneException Emits Exception in case of an error. */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $timezone) {} /** * Returns the name of the timezone * @return string * @link https://php.net/manual/en/datetimezone.getname.php */ #[TentativeType] public function getName(): string {} /** * Returns location information for a timezone * @return array|false * @link https://php.net/manual/en/datetimezone.getlocation.php */ #[TentativeType] #[ArrayShape([ 'country_code' => 'string', 'latitude' => 'double', 'longitude' => 'double', 'comments' => 'string', ])] public function getLocation(): array|false {} /** * Returns the timezone offset from GMT * @param DateTimeInterface $datetime * @return int * @link https://php.net/manual/en/datetimezone.getoffset.php */ #[TentativeType] public function getOffset(DateTimeInterface $datetime): int {} /** * Returns all transitions for the timezone * @param int $timestampBegin * @param int $timestampEnd * @return array|false * @link https://php.net/manual/en/datetimezone.gettransitions.php */ #[TentativeType] public function getTransitions( #[PhpStormStubsElementAvailable(from: '5.3', to: '5.6')] $timestampBegin, #[PhpStormStubsElementAvailable(from: '5.3', to: '5.6')] $timestampEnd, #[PhpStormStubsElementAvailable(from: '7.0')] #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $timestampBegin = PHP_INT_MIN, #[PhpStormStubsElementAvailable(from: '7.0')] #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $timestampEnd = PHP_INT_MAX ): array|false {} /** * Returns associative array containing dst, offset and the timezone name * @return array> * @link https://php.net/manual/en/datetimezone.listabbreviations.php */ #[TentativeType] public static function listAbbreviations(): array {} /** * Returns a numerically indexed array with all timezone identifiers * @param int $timezoneGroup * @param string $countryCode * @return array|false Returns the array of timezone identifiers, or FALSE on failure. Since PHP8, always returns array. * @link https://php.net/manual/en/datetimezone.listidentifiers.php */ #[LanguageLevelTypeAware(["8.0" => "array"], default: "array|false")] #[TentativeType] public static function listIdentifiers( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $timezoneGroup = DateTimeZone::ALL, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $countryCode = null ): array {} /** * @link https://php.net/manual/en/datetime.wakeup.php */ #[TentativeType] public function __wakeup(): void {} public static function __set_state($an_array) {} #[PhpStormStubsElementAvailable(from: '8.2')] public function __serialize(): array {} #[PhpStormStubsElementAvailable(from: '8.2')] public function __unserialize(array $data): void {} } /** * Representation of date interval. A date interval stores either a fixed amount of * time (in years, months, days, hours etc) or a relative time string in the format * that DateTime's constructor supports. * @link https://php.net/manual/en/class.dateinterval.php */ class DateInterval { /** * Number of years * @var int */ public $y; /** * Number of months * @var int */ public $m; /** * Number of days * @var int */ public $d; /** * Number of hours * @var int */ public $h; /** * Number of minutes * @var int */ public $i; /** * Number of seconds * @var int */ public $s; /** * Number of microseconds * @since 7.1.0 * @var float */ public $f; /** * Is 1 if the interval is inverted and 0 otherwise * @var int */ public $invert; /** * Total number of days the interval spans. If this is unknown, days will be FALSE. * @var int|false */ public $days; /** * @param string $duration * @throws DateMalformedIntervalStringException when the $duration cannot be parsed as an interval. * @link https://php.net/manual/en/dateinterval.construct.php */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $duration) {} /** * Formats the interval * @param string $format * @return string * @link https://php.net/manual/en/dateinterval.format.php */ #[TentativeType] public function format(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $format): string {} /** * Sets up a DateInterval from the relative parts of the string * @param string $datetime * @return DateInterval|false Returns a new {@link https://www.php.net/manual/en/class.dateinterval.php DateInterval} * instance on success, or FALSE on failure. * @link https://php.net/manual/en/dateinterval.createfromdatestring.php */ #[TentativeType] #[LanguageLevelTypeAware(['8.4' => 'DateInterval'], default: 'DateInterval|false')] public static function createFromDateString(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $datetime) {} #[TentativeType] public function __wakeup(): void {} public static function __set_state($an_array) {} #[PhpStormStubsElementAvailable(from: '8.2')] public function __serialize(): array {} #[PhpStormStubsElementAvailable(from: '8.2')] public function __unserialize(array $data): void {} } /** * Representation of date period. * @link https://php.net/manual/en/class.dateperiod.php * @template TDate of DateTimeInterface * @template TEnd of ?DateTimeInterface * @implements \IteratorAggregate */ class DatePeriod implements IteratorAggregate { public const EXCLUDE_START_DATE = 1; /** * @since 8.2 */ public const INCLUDE_END_DATE = 2; /** * Start date * @var DateTimeInterface */ #[LanguageLevelTypeAware(['8.2' => 'DateTimeInterface|null'], default: '')] #[Immutable] public $start; /** * Current iterator value. * @var DateTimeInterface|null */ #[LanguageLevelTypeAware(['8.2' => 'DateTimeInterface|null'], default: '')] public $current; /** * End date. * @var DateTimeInterface|null */ #[LanguageLevelTypeAware(['8.2' => 'DateTimeInterface|null'], default: '')] #[Immutable] public $end; /** * The interval * @var DateInterval */ #[LanguageLevelTypeAware(['8.2' => 'DateInterval|null'], default: '')] #[Immutable] public $interval; /** * Number of recurrences. * @var int */ #[LanguageLevelTypeAware(['8.2' => 'int'], default: '')] #[Immutable] public $recurrences; /** * Start of period. * @var bool */ #[LanguageLevelTypeAware(['8.2' => 'bool'], default: '')] #[Immutable] public $include_start_date; /** * @since 8.2 */ #[Immutable] public bool $include_end_date; /** * @param TDate $start * @param DateInterval $interval * @param TEnd $end * @param int $options Can be set to DatePeriod::EXCLUDE_START_DATE. * @link https://php.net/manual/en/dateperiod.construct.php */ public function __construct(DateTimeInterface $start, DateInterval $interval, DateTimeInterface $end, $options = 0) {} /** * @param TDate $start * @param DateInterval $interval * @param int $recurrences Number of recurrences * @param int $options Can be set to DatePeriod::EXCLUDE_START_DATE. * @link https://php.net/manual/en/dateperiod.construct.php */ public function __construct(DateTimeInterface $start, DateInterval $interval, $recurrences, $options = 0) {} /** * @param string $isostr String containing the ISO interval. * @param int $options Can be set to DatePeriod::EXCLUDE_START_DATE. * @throws DateMalformedPeriodStringException * @link https://php.net/manual/en/dateperiod.construct.php */ public function __construct($isostr, $options = 0) {} /** * Gets the interval * @return DateInterval * @link https://php.net/manual/en/dateperiod.getdateinterval.php * @since 5.6.5 */ #[TentativeType] public function getDateInterval(): DateInterval {} /** * Gets the end date * @return DateTimeInterface|null * @link https://php.net/manual/en/dateperiod.getenddate.php * @since 5.6.5 * @return TEnd */ #[TentativeType] public function getEndDate(): ?DateTimeInterface {} /** * Gets the start date * @return DateTimeInterface * @link https://php.net/manual/en/dateperiod.getstartdate.php * @since 5.6.5 * @return TDate */ #[TentativeType] public function getStartDate(): DateTimeInterface {} #[TentativeType] public static function __set_state(#[PhpStormStubsElementAvailable(from: '7.3')] array $array): DatePeriod {} #[TentativeType] public function __wakeup(): void {} /** * Get the number of recurrences * @return int|null * @link https://php.net/manual/en/dateperiod.getrecurrences.php * @since 7.2.17 */ #[TentativeType] public function getRecurrences(): ?int {} /** * @return \Iterator * @since 8.0 */ public function getIterator(): Iterator {} #[PhpStormStubsElementAvailable(from: '8.2')] public function __serialize(): array {} #[PhpStormStubsElementAvailable(from: '8.2')] public function __unserialize(array $data): void {} /** * @since 8.3 */ public static function createFromISO8601String(string $specification, int $options = 0): static {} } /** * @since 8.3 */ class DateError extends Error {} /** * @since 8.3 */ class DateObjectError extends DateError {} /** * @since 8.3 */ class DateRangeError extends DateError {} /** * @since 8.3 */ class DateException extends Exception {} /** * @since 8.3 */ class DateInvalidTimeZoneException extends DateException {} /** * @since 8.3 */ class DateInvalidOperationException extends DateException {} /** * @since 8.3 */ class DateMalformedStringException extends DateException {} /** * @since 8.3 */ class DateMalformedIntervalStringException extends DateException {} /** * @since 8.3 */ class DateMalformedPeriodStringException extends DateException {} * The string to parse. Before PHP 5.0.0, microseconds weren't allowed in * the time, since PHP 5.0.0 they are allowed but ignored. *

    * @param int|null $baseTimestamp [optional]

    * Default value: null * The timestamp which is used as a base for the calculation of relative * dates. *

    * @return int|false a timestamp on success, false otherwise. Previous to PHP 5.1.0, * this function would return -1 on failure. */ #[Pure(true)] function strtotime(string $datetime, ?int $baseTimestamp): int|false {} /** * Format a local time/date * @link https://php.net/manual/en/function.date.php * @param string $format

    * The format of the outputted date string. See the formatting * options below. There are also several * predefined date constants * that may be used instead, so for example DATE_RSS * contains the format string 'D, d M Y H:i:s'. *

    *

    *
    * The following characters are recognized in the * format parameter string: *

    *

    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    format characterDescriptionExample returned values
    Day------
    dDay of the month, 2 digits with leading zeros01 to 31
    DA textual representation of a day, three lettersMon through Sun
    jDay of the month without leading zeros1 to 31
    l (lowercase 'L')A full textual representation of the day of the weekSunday through Saturday
    NISO-8601 numeric representation of the day of the week (added in * PHP 5.1.0)1 (for Monday) through 7 (for Sunday)
    SEnglish ordinal suffix for the day of the month, 2 characters * st, nd, rd or * th. Works well with j *
    wNumeric representation of the day of the week0 (for Sunday) through 6 (for Saturday)
    zThe day of the year (starting from 0)0 through 365
    Week------
    WISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0)Example: 42 (the 42nd week in the year)
    Month------
    FA full textual representation of a month, such as January or MarchJanuary through December
    mNumeric representation of a month, with leading zeros01 through 12
    MA short textual representation of a month, three lettersJan through Dec
    nNumeric representation of a month, without leading zeros1 through 12
    tNumber of days in the given month28 through 31
    Year------
    LWhether it's a leap year1 if it is a leap year, 0 otherwise.
    oISO-8601 year number. This has the same value as * Y, except that if the ISO week number * (W) belongs to the previous or next year, that year * is used instead. (added in PHP 5.1.0)Examples: 1999 or 2003
    YA full numeric representation of a year, 4 digitsExamples: 1999 or 2003
    yA two digit representation of a yearExamples: 99 or 03
    Time------
    aLowercase Ante meridiem and Post meridiemam or pm
    AUppercase Ante meridiem and Post meridiemAM or PM
    BSwatch Internet time000 through 999
    g12-hour format of an hour without leading zeros1 through 12
    G24-hour format of an hour without leading zeros0 through 23
    h12-hour format of an hour with leading zeros01 through 12
    H24-hour format of an hour with leading zeros00 through 23
    iMinutes with leading zeros00 to 59
    sSeconds, with leading zeros00 through 59
    uMicroseconds (added in PHP 5.2.2)Example: 654321
    Timezone------
    eTimezone identifier (added in PHP 5.1.0)Examples: UTC, GMT, Atlantic/Azores
    I (capital i)Whether or not the date is in daylight saving time1 if Daylight Saving Time, 0 otherwise.
    ODifference to Greenwich time (GMT) in hoursExample: +0200
    PDifference to Greenwich time (GMT) with colon between hours and minutes (added in PHP 5.1.3)Example: +02:00
    TTimezone abbreviationExamples: EST, MDT ...
    ZTimezone offset in seconds. The offset for timezones west of UTC is always * negative, and for those east of UTC is always positive.-43200 through 50400
    Full Date/Time------
    cISO 8601 date (added in PHP 5)2004-02-12T15:19:21+00:00
    rRFC 2822 formatted dateExample: Thu, 21 Dec 2000 16:01:07 +0200
    USeconds since the Unix Epoch (January 1 1970 00:00:00 GMT)See also time
    *

    *

    * Unrecognized characters in the format string will be printed * as-is. The Z format will always return * 0 when using gmdate. *

    *

    * Since this function only accepts integer timestamps the * u format character is only useful when using the * date_format function with user based timestamps * created with date_create. *

    * @param int|null $timestamp [optional] Default value: time(). The optional timestamp parameter is an integer Unix timestamp * that defaults to the current local time if a timestamp is not given. * @return string|false a formatted date string. If a non-numeric value is used for * timestamp, false is returned and an * E_WARNING level error is emitted. */ #[Pure(true)] #[LanguageLevelTypeAware(["8.0" => "string"], default: "string|false")] function date(string $format, ?int $timestamp) {} /** * Format a local time/date as integer * @link https://php.net/manual/en/function.idate.php * @param string $format

    *

    * The following characters are recognized in the * format parameter string * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    format characterDescription
    BSwatch Beat/Internet Time
    dDay of the month
    hHour (12 hour format)
    HHour (24 hour format)
    iMinutes
    I (uppercase i)returns 1 if DST is activated, * 0 otherwise
    L (uppercase l)returns 1 for leap year, * 0 otherwise
    mMonth number
    sSeconds
    tDays in current month
    USeconds since the Unix Epoch - January 1 1970 00:00:00 UTC - * this is the same as time
    wDay of the week (0 on Sunday)
    WISO-8601 week number of year, weeks starting on * Monday
    yYear (1 or 2 digits - check note below)
    YYear (4 digits)
    zDay of the year
    ZTimezone offset in seconds
    *

    * @param int|null $timestamp [optional] Default value: time(). The optional timestamp parameter is an integer Unix timestamp * that defaults to the current local time if a timestamp is not given. * @return int|false an integer. *

    * As idate always returns an integer and * as they can't start with a "0", idate may return * fewer digits than you would expect. See the example below. *

    */ #[Pure(true)] function idate(string $format, ?int $timestamp): int|false {} /** * Format a GMT/UTC date/time * @link https://php.net/manual/en/function.gmdate.php * @param string $format

    * The format of the outputted date string. See the formatting * options for the date function. *

    * @param int|null $timestamp [optional] Default value: time(). The optional timestamp parameter is an integer Unix timestamp * that defaults to the current local time if a timestamp is not given. * @return string|false a formatted date string. If a non-numeric value is used for * timestamp, false is returned and an * E_WARNING level error is emitted. */ #[Pure(true)] #[LanguageLevelTypeAware(["8.0" => "string"], default: "string|false")] function gmdate(string $format, ?int $timestamp) {} /** * Get Unix timestamp for a date * @link https://php.net/manual/en/function.mktime.php * @param int $hour

    * The number of the hour. *

    * @param int|null $minute

    * The number of the minute. *

    * @param int|null $second

    * The number of seconds past the minute. *

    * @param int|null $month

    * The number of the month. *

    * @param int|null $day

    * The number of the day. *

    * @param int|null $year [optional]

    * The number of the year, may be a two or four digit value, * with values between 0-69 mapping to 2000-2069 and 70-100 to * 1970-2000. On systems where time_t is a 32bit signed integer, as * most common today, the valid range for year * is somewhere between 1901 and 2038. However, before PHP 5.1.0 this * range was limited from 1970 to 2038 on some systems (e.g. Windows). *

    * @param int $is_dst [optional]

    * This parameter can be set to 1 if the time is during daylight savings time (DST), * 0 if it is not, or -1 (the default) if it is unknown whether the time is within * daylight savings time or not. If it's unknown, PHP tries to figure it out itself. * This can cause unexpected (but not incorrect) results. * Some times are invalid if DST is enabled on the system PHP is running on or * is_dst is set to 1. If DST is enabled in e.g. 2:00, all times * between 2:00 and 3:00 are invalid and mktime returns an undefined * (usually negative) value. * Some systems (e.g. Solaris 8) enable DST at midnight so time 0:30 of the day when DST * is enabled is evaluated as 23:30 of the previous day. *

    *

    * As of PHP 5.1.0, this parameter became deprecated. As a result, the * new timezone handling features should be used instead. *

    *

    * This parameter has been removed in PHP 7.0.0. *

    * @return int|false mktime returns the Unix timestamp of the arguments * given. * If the arguments are invalid, the function returns false (before PHP 5.1 * it returned -1). */ #[Pure(true)] function mktime( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] int $hour = null, #[PhpStormStubsElementAvailable(from: '8.0')] int $hour, ?int $minute = null, ?int $second = null, ?int $month = null, ?int $day = null, ?int $year = null, #[Deprecated('Use the new timezone handling functions instead', since: '5.3')] #[PhpStormStubsElementAvailable(from: '5.5', to: '5.6')] int $is_dst = -1 ): int|false {} /** * Get Unix timestamp for a GMT date * @link https://php.net/manual/en/function.gmmktime.php * @param int $hour

    * The hour *

    * @param int $minute

    * The minute *

    * @param int $second

    * The second *

    * @param int $month

    * The month *

    * @param int $day

    * The day *

    * @param int $year

    * The year *

    * @param int $is_dst

    * Parameters always represent a GMT date so is_dst * doesn't influence the result. *

    * @return int|false a integer Unix timestamp. */ #[Pure(true)] function gmmktime( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] int $hour = null, #[PhpStormStubsElementAvailable(from: '8.0')] int $hour, ?int $minute = null, ?int $second = null, ?int $month = null, ?int $day = null, ?int $year = null, #[PhpStormStubsElementAvailable(from: '5.5', to: '5.6')] $is_dst = null ): int|false {} /** * Validate a Gregorian date * @link https://php.net/manual/en/function.checkdate.php * @param int $month

    * The month is between 1 and 12 inclusive. *

    * @param int $day

    * The day is within the allowed number of days for the given * month. Leap years * are taken into consideration. *

    * @param int $year

    * The year is between 1 and 32767 inclusive. *

    * @return bool true if the date given is valid; otherwise returns false. */ #[Pure(true)] function checkdate(int $month, int $day, int $year): bool {} /** * Format a local time/date according to locale settings * The following characters are recognized in the * format parameter string * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    formatDescriptionExample returned values * Day
    %aAn abbreviated textual representation of the daySun through Sat
    %AA full textual representation of the daySunday through Saturday
    %dTwo-digit day of the month (with leading zeros)01 to 31
    %eDay of the month, with a space preceding single digits 1 to 31
    %jDay of the year, 3 digits with leading zeros001 to 366
    %uISO-8601 numeric representation of the day of the week1 (for Monday) though 7 (for Sunday)
    %wNumeric representation of the day of the week0 (for Sunday) through 6 (for Saturday)
    Week
    %UWeek number of the given year, starting with the first * Sunday as the first week13 (for the 13th full week of the year)
    %VISO-8601:1988 week number of the given year, starting with * the first week of the year with at least 4 weekdays, with Monday * being the start of the week01 through 53 (where 53 * accounts for an overlapping week)
    %WA numeric representation of the week of the year, starting * with the first Monday as the first week46 (for the 46th week of the year beginning * with a Monday)
    Month
    %bAbbreviated month name, based on the localeJan through Dec
    %BFull month name, based on the localeJanuary through December
    %hAbbreviated month name, based on the locale (an alias of %b)Jan through Dec
    %mTwo digit representation of the month01 (for January) through 12 (for December)
    Year
    %CTwo digit representation of the century (year divided by 100, truncated to an integer)19 for the 20th Century
    %gTwo digit representation of the year going by ISO-8601:1988 standards (see %V)Example: 09 for the week of January 6, 2009
    %GThe full four-digit version of %gExample: 2008 for the week of January 3, 2009
    %yTwo digit representation of the yearExample: 09 for 2009, 79 for 1979
    %YFour digit representation for the yearExample: 2038
    Time
    %HTwo digit representation of the hour in 24-hour format00 through 23
    %ITwo digit representation of the hour in 12-hour format01 through 12
    %l (lower-case 'L')Hour in 12-hour format, with a space preceding single digits 1 through 12
    %MTwo digit representation of the minute00 through 59
    %pUPPER-CASE 'AM' or 'PM' based on the given timeExample: AM for 00:31, PM for 22:23
    %Plower-case 'am' or 'pm' based on the given timeExample: am for 00:31, pm for 22:23
    %rSame as "%I:%M:%S %p"Example: 09:34:17 PM for 21:34:17
    %RSame as "%H:%M"Example: 00:35 for 12:35 AM, 16:44 for 4:44 PM
    %STwo digit representation of the second00 through 59
    %TSame as "%H:%M:%S"Example: 21:34:17 for 09:34:17 PM
    %XPreferred time representation based on locale, without the dateExample: 03:59:16 or 15:59:16
    %zEither the time zone offset from UTC or the abbreviation (depends * on operating system)Example: -0500 or EST for Eastern Time
    %ZThe time zone offset/abbreviation option NOT given by %z (depends * on operating system)Example: -0500 or EST for Eastern Time
    Time and Date Stamps
    %cPreferred date and time stamp based on localExample: Tue Feb 5 00:45:10 2009 for * February 4, 2009 at 12:45:10 AM
    %DSame as "%m/%d/%y"Example: 02/05/09 for February 5, 2009
    %FSame as "%Y-%m-%d" (commonly used in database datestamps)Example: 2009-02-05 for February 5, 2009
    %sUnix Epoch Time timestamp (same as the time * function)Example: 305815200 for September 10, 1979 08:40:00 AM
    %xPreferred date representation based on locale, without the timeExample: 02/05/09 for February 5, 2009
    Miscellaneous
    %nA newline character ("\n")---
    %tA Tab character ("\t")---
    %%A literal percentage character ("%")---
    *

    * Maximum length of this parameter is 1023 characters. *

    * Contrary to ISO-9899:1999, Sun Solaris starts with Sunday as 1. * As a result, %u may not function as described in this manual. * @link https://php.net/manual/en/function.strftime.php * @param string $format * @param int|null $timestamp [optional] defaults to the value of time() * Unix timestamp that defaults to the current local time if a timestamp is not given.. * @return string|false a string formatted according format * using the given timestamp or the current * local time if no timestamp is given. Month and weekday names and * other language-dependent strings respect the current locale set * with setlocale. */ #[Deprecated(since: '8.1')] function strftime(string $format, ?int $timestamp): string|false {} /** * Format a GMT/UTC time/date according to locale settings * @link https://php.net/manual/en/function.gmstrftime.php * @param string $format

    * See description in strftime. *

    * @param int|null $timestamp [optional] * @return string|false a string formatted according to the given format string * using the given timestamp or the current * local time if no timestamp is given. Month and weekday names and * other language dependent strings respect the current locale set * with setlocale. * @deprecated 8.1 */ #[Deprecated(since: '8.1')] function gmstrftime(string $format, ?int $timestamp): string|false {} /** * Return current Unix timestamp * @link https://php.net/manual/en/function.time.php * @return int

    Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT).

    */ function time(): int {} /** * Get the local time * @link https://php.net/manual/en/function.localtime.php * @param int|null $timestamp [optional] * @param bool $associative [optional]

    * If set to false or not supplied then the array is returned as a regular, * numerically indexed array. If the argument is set to true then * localtime returns an associative array containing * all the different elements of the structure returned by the C * function call to localtime. The names of the different keys of * the associative array are as follows: *

    * "tm_sec" - seconds * @return array */ #[Pure(true)] #[ArrayShape([ 'tm_sec' => 'int', 'tm_min' => 'int', 'tm_hour' => 'int', 'tm_mday' => 'int', 'tm_mon' => 'int', 'tm_year' => 'int', 'tm_wday' => 'int', 'tm_yday' => 'int', 'tm_isdst' => 'int', ])] function localtime(?int $timestamp, bool $associative = false): array {} /** * Get date/time information * @link https://php.net/manual/en/function.getdate.php * @param int|null $timestamp [optional] * @return array an associative array of information related to * the timestamp. Elements from the returned * associative array are as follows: *

    *

    *

    * Key elements of the returned associative array * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    KeyDescriptionExample returned values
    "seconds"Numeric representation of seconds0 to 59
    "minutes"Numeric representation of minutes0 to 59
    "hours"Numeric representation of hours0 to 23
    "mday"Numeric representation of the day of the month1 to 31
    "wday"Numeric representation of the day of the week0 (for Sunday) through 6 (for Saturday)
    "mon"Numeric representation of a month1 through 12
    "year"A full numeric representation of a year, 4 digitsExamples: 1999 or 2003
    "yday"Numeric representation of the day of the year0 through 365
    "weekday"A full textual representation of the day of the weekSunday through Saturday
    "month"A full textual representation of a month, such as January or MarchJanuary through December
    0 * Seconds since the Unix Epoch, similar to the values returned by * time and used by date. * * System Dependent, typically -2147483648 through * 2147483647. *
    */ #[Pure(true)] #[ArrayShape([ 'seconds' => 'int', 'minutes' => 'int', 'hours' => 'int', 'mday' => 'int', 'wday' => 'int', 'mon' => 'int', 'year' => 'int', 'yday' => 'int', 'weekday' => 'int', 'month' => 'string', 0 => 'int', ])] function getdate(?int $timestamp): array {} /** * Returns new DateTime object * @link https://php.net/manual/en/function.date-create.php * @param string $datetime [optional]

    * String in a format accepted by strtotime. *

    * @param DateTimeZone|null $timezone [optional]

    * Time zone of the time. *

    * @return DateTime|false DateTime object on success or false on failure. */ #[Pure(true)] function date_create(string $datetime = 'now', ?DateTimeZone $timezone): DateTime|false {} /** * (PHP 5.5)
    * Alias: * {@see DateTimeImmutable::__construct} * Returns new DateTimeImmutable object * @link https://php.net/manual/en/function.date-create-immutable.php * @see DateTimeImmutable::__construct() * @param string $datetime [optional]

    * String in a format accepted by strtotime. *

    * @param DateTimeZone|null $timezone [optional]

    * Time zone of the time. *

    * @return DateTimeImmutable|false DateTime object on success or false on failure. */ #[Pure(true)] function date_create_immutable(string $datetime = 'now', ?DateTimeZone $timezone): DateTimeImmutable|false {} /** * Returns new DateTimeImmutable object formatted according to the specified format * @link https://php.net/manual/en/function.date-create-immutable-from-format.php * @param string $format * @param string $datetime * @param DateTimeZone|null $timezone [optional] * @return DateTimeImmutable|false */ #[Pure(true)] function date_create_immutable_from_format(string $format, string $datetime, ?DateTimeZone $timezone): DateTimeImmutable|false {} /** * Alias: * {@see DateTime::createFromFormat} * @link https://php.net/manual/en/function.date-create-from-format.php * @param string $format Format accepted by date(). *

    If format does not contain the character ! then portions of the generated time which are not specified in format will be set to the current system time.

    *

    If format contains the character !, then portions of the generated time not provided in format, as well as values to the left-hand side of the !, will be set to corresponding values from the Unix epoch.

    *

    The Unix epoch is 1970-01-01 00:00:00 UTC.

    * @param string $datetime String representing the time. * @param DateTimeZone|null $timezone [optional] A DateTimeZone object representing the desired time zone. * @return DateTime|false

    Returns a new * {@see DateTime} instance or FALSE on failure.

    */ #[Pure(true)] function date_create_from_format(string $format, string $datetime, ?DateTimeZone $timezone): DateTime|false {} /** * Returns associative array with detailed info about given date * @link https://php.net/manual/en/function.date-parse.php * @param string $datetime

    * Date in format accepted by strtotime. *

    * @return array|false array with information about the parsed date * on success or false on failure. */ #[Pure(true)] #[LanguageLevelTypeAware(["8.0" => "array"], default: "array|false")] #[ArrayShape([ "year" => "int", "month" => "int", "day" => "int", "hour" => "int", "minute" => "int", "second" => "int", "fraction" => "double", "is_localtime" => "bool", "zone_type" => "int", "zone" => "int", "is_dst" => "bool", "tz_abbr" => "string", "tz_id" => "string", "relative" => "array", "warning_count" => "int", "warnings" => "array", "error_count" => "int", "errors" => "array" ])] function date_parse(string $datetime): false|array {} /** * Get info about given date formatted according to the specified format * @link https://php.net/manual/en/function.date-parse-from-format.php * @param string $format

    * Format accepted by date with some extras. *

    * @param string $datetime

    * String representing the date. *

    * @return array associative array with detailed info about given date. */ #[Pure(true)] #[ArrayShape([ 'year' => 'int', 'month' => 'int', 'day' => 'int', 'hour' => 'int', 'minute' => 'int', 'second' => 'int', 'fraction' => 'double', 'is_localtime' => 'bool', 'zone_type' => 'int', 'zone' => 'int', 'is_dst' => 'bool', 'tz_abbr' => 'string', 'tz_id' => 'string', 'relative' => 'array', 'warning_count' => 'int', 'warnings' => 'array', 'error_count' => 'int', 'errors' => 'array' ])] function date_parse_from_format(string $format, string $datetime): array {} /** * Returns the warnings and errors * Alias: * {@see DateTime::getLastErrors} * @link https://php.net/manual/en/function.date-get-last-errors.php * @return array|false

    Returns array containing info about warnings and errors.

    */ #[ArrayShape(["warning_count" => "int", "warnings" => "string[]", "error_count" => "int", "errors" => "string[]"])] #[Pure(true)] function date_get_last_errors(): array|false {} /** * Alias: * {@see DateTime::format} * @link https://php.net/manual/en/function.date-format.php * @param DateTimeInterface $object * @param string $format * @return string|false formatted date string on success or FALSE on failure. */ #[Pure(true)] #[LanguageLevelTypeAware(["8.0" => "string"], default: "string|false")] function date_format(DateTimeInterface $object, string $format) {} /** * Alter the timestamp of a DateTime object by incrementing or decrementing * in a format accepted by strtotime(). * Alias: * {@see DateTime::modify} * @link https://php.net/manual/en/function.date-modify.php * @param DateTime $object A DateTime object returned by date_create(). The function modifies this object. * @param string $modifier A date/time string. Valid formats are explained in {@link https://secure.php.net/manual/en/datetime.formats.php Date and Time Formats}. * @return DateTime|false Returns the DateTime object for method chaining or FALSE on failure. */ function date_modify(DateTime $object, string $modifier): DateTime|false {} /** * Alias: * {@see DateTime::add} * @link https://php.net/manual/en/function.date-add.php * @param DateTime $object

    Procedural style only: A * {@see DateTime} object returned by * {@see date_create()}. The function modifies this object.

    * @param DateInterval $interval

    A * {@see DateInterval} object

    * @return DateTime|false

    Returns the * {@see DateTime} object for method chaining or FALSE on failure.

    */ #[LanguageLevelTypeAware(["8.0" => "DateTime"], default: "DateTime|false")] function date_add(DateTime $object, DateInterval $interval) {} /** * Subtracts an amount of days, months, years, hours, minutes and seconds from a datetime object * Alias: * {@see DateTime::sub} * @link https://php.net/manual/en/function.date-sub.php * @param DateTime $object Procedural style only: A * {@see DateTime} object returned by * {@see date_create()}. The function modifies this object. * @param DateInterval $interval

    A * {@see DateInterval} object

    * @return DateTime|false

    Returns the * {@see DateTime} object for method chaining or FALSE on failure.

    */ #[LanguageLevelTypeAware(["8.0" => "DateTime"], default: "DateTime|false")] function date_sub(DateTime $object, DateInterval $interval) {} /** * Alias: * {@see DateTime::getTimezone} * @link https://php.net/manual/en/function.date-timezone-get.php * @param DateTimeInterface $object

    Procedural style only: A * {@see DateTime} object * returned by * {@see date_create()}

    * @return DateTimeZone|false *

    * Returns a * {@see DateTimeZone} object on success * or FALSE on failure. *

    */ #[Pure(true)] function date_timezone_get(DateTimeInterface $object): DateTimeZone|false {} /** * Sets the time zone for the datetime object * Alias: * {@see DateTime::setTimezone} * @link https://php.net/manual/en/function.date-timezone-set.php * @param DateTime|DateTimeInterface $object

    A * {@see DateTime} object returned by * {@see date_create()}. The function modifies this object.

    * @param DateTimeZone $timezone

    A * {@see DateTimeZone} object representing the desired time zone.

    * @return DateTime|false

    Returns the * {@see DateTime} object for method chaining or FALSE on failure.

    */ #[LanguageLevelTypeAware(["8.0" => "DateTime"], default: "DateTime|false")] function date_timezone_set(#[LanguageLevelTypeAware(["8.0" => "DateTime"], default: "DateTimeInterface")] $object, DateTimeZone $timezone) {} /** * Alias: * {@see DateTime::getOffset} * @link https://php.net/manual/en/function.date-offset-get.php * @param DateTimeInterface $object

    Procedural style only: A {@see DateTime} object * returned by {@see date_create()}

    * @return int|false

    Returns the timezone offset in seconds from UTC on success or FALSE on failure.

    */ #[Pure(true)] #[LanguageLevelTypeAware(["8.0" => "int"], default: "int|false")] function date_offset_get(DateTimeInterface $object) {} /** * Returns the difference between two datetime objects * Alias: * {@see DateTime::diff} * @link https://php.net/manual/en/function.date-diff.php * @param DateTimeInterface $baseObject * @param DateTimeInterface $targetObject The date to compare to * @param bool $absolute [optional] Whether to return absolute difference. * @return DateInterval|false The DateInterval object representing the difference between the two dates or FALSE on failure. */ #[Pure(true)] #[LanguageLevelTypeAware(["8.0" => "DateInterval"], default: "DateInterval|false")] function date_diff(DateTimeInterface $baseObject, DateTimeInterface $targetObject, bool $absolute = false) {} /** * Alias: * {@see DateTime::setTime} * @link https://php.net/manual/en/function.date-time-set.php * @param DateTime $object * @param int $hour * @param int $minute * @param int $second [optional] * @param int $microsecond [optional] * @return DateTime

    Returns the * {@see DateTime} object for method chaining or FALSE on failure.

    */ function date_time_set( DateTime $object, int $hour, int $minute, int $second = 0, #[PhpStormStubsElementAvailable(from: '7.1')] int $microsecond = 0 ): DateTime {} /** * Alias: * {@see DateTime::setDate} * @link https://php.net/manual/en/function.date-date-set.php * @param DateTime $object

    Procedural style only: A {@see DateTime} object * returned by {@see date_create()}. * The function modifies this object.

    * @param int $year

    Year of the date.

    * @param int $month

    Month of the date.

    * @param int $day

    Day of the date.

    * @return DateTime|false *

    * Returns the * {@see DateTime} object for method chaining or FALSE on failure. *

    */ #[LanguageLevelTypeAware(["8.0" => "DateTime"], default: "DateTime|false")] function date_date_set(DateTime $object, int $year, int $month, int $day): DateTime|false {} /** * Alias: * {@see DateTime::setISODate} * @link https://php.net/manual/en/function.date-isodate-set.php * @param DateTime $object * @param int $year

    Year of the date

    * @param int $week

    Week of the date.

    * @param int $dayOfWeek [optional]

    Offset from the first day of the week.

    * @return DateTime|false

    * Returns the {@see DateTime} object for method chaining or FALSE on failure. *

    */ #[LanguageLevelTypeAware(["8.0" => "DateTime"], default: "DateTime|false")] function date_isodate_set(DateTime $object, int $year, int $week, int $dayOfWeek = 1) {} /** * Sets the date and time based on an unix timestamp * Alias: * {@see DateTime::setTimestamp} * @link https://php.net/manual/en/function.date-timestamp-set.php * @param DateTime $object

    Procedural style only: A * {@see DateTime} object returned by * {@see date_create()}. The function modifies this object.

    * @param int $timestamp

    Unix timestamp representing the date.

    * @return DateTime|false * {@see DateTime} object for call chaining or FALSE on failure */ #[LanguageLevelTypeAware(["8.0" => "DateTime"], default: "DateTime|false")] function date_timestamp_set(DateTime $object, int $timestamp): DateTime|false {} /** * Gets the unix timestamp * Alias: * {@see DateTime::getTimestamp} * @link https://php.net/manual/en/function.date-timestamp-get.php * @param DateTimeInterface $object * @return int

    Returns the Unix timestamp representing the date.

    */ #[Pure(true)] function date_timestamp_get(DateTimeInterface $object): int {} /** * Returns new DateTimeZone object * @link https://php.net/manual/en/function.timezone-open.php * @param string $timezone

    * Time zone identifier as full name (e.g. Europe/Prague) or abbreviation * (e.g. CET). *

    * @return DateTimeZone|false DateTimeZone object on success or false on failure. */ #[Pure(true)] function timezone_open(string $timezone): DateTimeZone|false {} /** * Alias: * {@see DateTimeZone::getName} * @link https://php.net/manual/en/function.timezone-name-get.php * @param DateTimeZone $object

    The * {@see DateTimeZone} for which to get a name.

    * @return string One of the timezone names in the list of timezones. */ #[Pure] function timezone_name_get(DateTimeZone $object): string {} /** * Returns the timezone name from abbreviation * @link https://php.net/manual/en/function.timezone-name-from-abbr.php * @param string $abbr

    * Time zone abbreviation. *

    * @param int $utcOffset [optional]

    * Offset from GMT in seconds. Defaults to -1 which means that first found * time zone corresponding to abbr is returned. * Otherwise exact offset is searched and only if not found then the first * time zone with any offset is returned. *

    * @param int $isDST [optional]

    * Daylight saving time indicator. If abbr doesn't * exist then the time zone is searched solely by * offset and isdst. *

    * @return string|false time zone name on success or false on failure. * @since 5.1.3 */ #[Pure(true)] function timezone_name_from_abbr(string $abbr, int $utcOffset = -1, int $isDST = -1): string|false {} /** * Alias: * {@link DateTimeZone::getOffset} * @link https://php.net/manual/en/function.timezone-offset-get.php * @param DateTimeZone $object

    Procedural style only: A * {@see DateTimeZone} object * returned by * {@see timezone_open()}

    * @param DateTimeInterface $datetime

    DateTime that contains the date/time to compute the offset from.

    * @return int|false

    Returns time zone offset in seconds on success or FALSE on failure.

    */ #[Pure(true)] #[LanguageLevelTypeAware(["8.0" => "int"], default: "int|false")] function timezone_offset_get(DateTimeZone $object, DateTimeInterface $datetime) {} /** * Returns all transitions for the timezone * Alias: * {@see DateTimeZone::getTransitions} * @link https://php.net/manual/en/function.timezone-transitions-get.php * @param DateTimeZone $object

    Procedural style only: A * {@see DateTimeZone} object returned by * {@see timezone_open()}

    * @param int $timestampBegin [optional]

    Begin timestamp

    * @param int $timestampEnd [optional]

    End timestamp

    * @return array|false

    Returns numerically indexed array containing associative array with all transitions on success or FALSE on failure.

    */ #[Pure(true)] function timezone_transitions_get(DateTimeZone $object, int $timestampBegin = PHP_INT_MIN, int $timestampEnd = PHP_INT_MAX): array|false {} /** * Alias: * {@see DateTimeZone::getLocation} * @link https://php.net/manual/en/function.timezone-location-get.php * @param DateTimeZone $object

    Procedural style only: A {@see DateTimeZone} object returned by {@see timezone_open()}

    * @return array|false

    Array containing location information about timezone.

    */ #[Pure(true)] #[ArrayShape([ 'country_code' => 'string', 'latitude' => 'double', 'longitude' => 'double', 'comments' => 'string', ])] function timezone_location_get(DateTimeZone $object): array|false {} /** * Returns a numerically indexed array containing all defined timezone identifiers * Alias: * {@see DateTimeZone::listIdentifiers()} * @link https://php.net/manual/en/function.timezone-identifiers-list.php * @param int $timezoneGroup [optional] One of DateTimeZone class constants. * @param string|null $countryCode [optional] A two-letter ISO 3166-1 compatible country code. * Note: This option is only used when $timezoneGroup is set to DateTimeZone::PER_COUNTRY. * @return array|false Returns array on success or FALSE on failure. */ #[Pure(true)] #[LanguageLevelTypeAware(["8.0" => "array"], default: "array|false")] function timezone_identifiers_list(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode) {} /** * Returns associative array containing dst, offset and the timezone name * Alias: * {@see DateTimeZone::listAbbreviations} * @link https://php.net/manual/en/function.timezone-abbreviations-list.php * @return array>|false Array on success or FALSE on failure. */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "array"], default: "array|false")] function timezone_abbreviations_list() {} /** * Gets the version of the timezonedb * @link https://php.net/manual/en/function.timezone-version-get.php * @return string a string. */ #[Pure] function timezone_version_get(): string {} /** * Alias: * {@see DateInterval::createFromDateString} * @link https://php.net/manual/en/function.date-interval-create-from-date-string.php * @param string $datetime

    A date with relative parts. Specifically, the relative formats supported by the parser used for * {@see strtotime()} and * {@see DateTime} will be used to construct the * {@see DateInterval}.

    * @return DateInterval|false *

    Returns a new DateInterval instance.

    */ #[Pure(true)] function date_interval_create_from_date_string(string $datetime): DateInterval|false {} /** * Alias: * {@see DateInterval::format} * @link https://php.net/manual/en/function.date-interval-format.php * @param DateInterval $object * @param string $format * @return string */ #[Pure(true)] function date_interval_format(DateInterval $object, string $format): string {} /** * Sets the default timezone used by all date/time functions in a script * @link https://php.net/manual/en/function.date-default-timezone-set.php * @param string $timezoneId

    * The timezone identifier, like UTC or * Europe/Lisbon. The list of valid identifiers is * available in the . *

    * @return bool This function returns false if the * timezone_identifier isn't valid, or true * otherwise. */ function date_default_timezone_set(string $timezoneId): bool {} /** * Gets the default timezone used by all date/time functions in a script * @link https://php.net/manual/en/function.date-default-timezone-get.php * @return string a string. */ #[Pure] function date_default_timezone_get(): string {} /** * Returns time of sunrise for a given day and location * @link https://php.net/manual/en/function.date-sunrise.php * @param int $timestamp

    * The timestamp of the day from which the sunrise * time is taken. *

    * @param int $returnFormat [optional]

    *

    * format constants * * * * * * * * * * * * * * * * * * * * *
    constantdescriptionexample
    SUNFUNCS_RET_STRINGreturns the result as string16:46
    SUNFUNCS_RET_DOUBLEreturns the result as float16.78243132
    SUNFUNCS_RET_TIMESTAMPreturns the result as integer (timestamp)1095034606
    *

    * @param float|null $latitude [optional]

    * Defaults to North, pass in a negative value for South. * See also: date.default_latitude *

    * @param float|null $longitude [optional]

    * Defaults to East, pass in a negative value for West. * See also: date.default_longitude *

    * @param float|null $zenith [optional]

    * Default: date.sunrise_zenith *

    * @param float|null $utcOffset [optional] * @return string|int|float|false the sunrise time in a specified format on * success or false on failure. * @deprecated 8.1 * Use {@link date_sun_info} instead */ #[Pure(true)] #[Deprecated(reason: 'in 8.1. Use date_sun_info instead', since: '8.1')] function date_sunrise(int $timestamp, int $returnFormat = SUNFUNCS_RET_STRING, ?float $latitude, ?float $longitude, ?float $zenith, ?float $utcOffset): string|int|float|false {} /** * Returns time of sunset for a given day and location * @link https://php.net/manual/en/function.date-sunset.php * @param int $timestamp

    * The timestamp of the day from which the sunset * time is taken. *

    * @param int $returnFormat [optional]

    *

    * format constants * * * * * * * * * * * * * * * * * * * * *
    constantdescriptionexample
    SUNFUNCS_RET_STRINGreturns the result as string16:46
    SUNFUNCS_RET_DOUBLEreturns the result as float16.78243132
    SUNFUNCS_RET_TIMESTAMPreturns the result as integer (timestamp)1095034606
    *

    * @param float|null $latitude [optional]

    * Defaults to North, pass in a negative value for South. * See also: date.default_latitude *

    * @param float|null $longitude [optional]

    * Defaults to East, pass in a negative value for West. * See also: date.default_longitude *

    * @param float|null $zenith [optional]

    * Default: date.sunset_zenith *

    * @param float|null $utcOffset [optional] * @return string|int|float|false the sunset time in a specified format on * success or false on failure. */ #[Pure(true)] #[Deprecated(reason: 'in 8.1. Use date_sun_info instead', since: '8.1')] function date_sunset(int $timestamp, int $returnFormat = SUNFUNCS_RET_STRING, ?float $latitude, ?float $longitude, ?float $zenith, ?float $utcOffset): string|int|float|false {} /** * Returns an array with information about sunset/sunrise and twilight begin/end * @link https://php.net/manual/en/function.date-sun-info.php * @param int $timestamp

    * Timestamp. *

    * @param float $latitude

    * Latitude in degrees. *

    * @param float $longitude

    * Longitude in degrees. *

    * @return array{ * sunrise: int|bool, * sunset: int|bool, * transit: int|bool, * civil_twilight_begin: int|bool, * civil_twilight_end: int|bool, * nautical_twilight_begin: int|bool, * nautical_twilight_end: int|bool, * astronomical_twilight_begin: int|bool, * astronomical_twilight_end: int|bool, * }|false Returns array on success or false on failure. The structure of the array is detailed in the following list: * * * * * * * * * * *
    sunriseThe timestamp of the sunrise (zenith angle = 90°35').
    sunsetThe timestamp of the sunset (zenith angle = 90°35').
    transitThe timestamp when the sun is at its zenith, i.e. has reached its topmost point.
    civil_twilight_beginThe start of the civil dawn (zenith angle = 96°). It ends at sunrise.
    civil_twilight_endThe end of the civil dusk (zenith angle = 96°). It starts at sunset.
    nautical_twilight_beginThe start of the nautical dawn (zenith angle = 102°). It ends at civil_twilight_begin.
    nautical_twilight_endThe end of the nautical dusk (zenith angle = 102°). It starts at civil_twilight_end.
    astronomical_twilight_beginThe start of the astronomical dawn (zenith angle = 108°). It ends at nautical_twilight_begin.
    astronomical_twilight_endThe end of the astronomical dusk (zenith angle = 108°). It starts at nautical_twilight_end.
    *
    * The values of the array elements are either UNIX timestamps, false if the * sun is below the respective zenith for the whole day, or true if the sun is * above the respective zenith for the whole day. * @since 5.1.2 */ #[Pure(true)] #[LanguageLevelTypeAware(["8.0" => "array"], default: "array|false")] #[ArrayShape([ "sunrise" => "int", "sunset" => "int", "transit" => "int", "civil_twilight_begin" => "int", "civil_twilight_end" => "int", "nautical_twilight_begin" => "int", "nautical_twilight_end" => "int", "astronomical_twilight_begin" => "int", "astronomical_twilight_end" => "int" ])] function date_sun_info(int $timestamp, float $latitude, float $longitude): array|false {} // End of date v.5.3.2-0.dotdeb.1 Create and initialize new event base

    * *

    Returns new event base, which can be used later in {@link event_base_set}(), {@link event_base_loop}() and other functions.

    * * @link https://php.net/event_base_new * * @return resource|false returns valid event base resource on success or FALSE on error. */ function event_base_new() {} /** *

    Destroy event base

    *

    (PECL libevent >= 0.0.1)

    * *

    Destroys the specified event_base and frees all the resources associated. * Note that it's not possible to destroy an event base with events attached to it.

    * * @link https://php.net/event_base_free * * @param resource $event_base Valid event base resource. * * @return void */ function event_base_free($event_base) {} /** *

    Handle events

    *

    (PECL libevent >= 0.0.1)

    * *

    Starts event loop for the specified event base.

    * *

    By default, the {@link event_base_loop}() function runs an event_base until * there are no more events registered in it. To run the loop, it repeatedly * checks whether any of the registered events has triggered (for example, * if a read event's file descriptor is ready to read, or if a timeout event's * timeout is ready to expire). Once this happens, it marks all triggered events * as "active", and starts to run them. *

    * *

    You can change the behavior of event_base_loop() by setting one or more flags * in its flags argument. If EVLOOP_ONCE is set, then the loop will wait until some * events become active, then run active events until there are no more to run, then * return. If EVLOOP_NONBLOCK is set, then the loop will not wait for events to trigger: * it will only check whether any events are ready to trigger immediately, * and run their callbacks if so. *

    * * @link https://php.net/event_base_loop * * @param resource $event_base Valid event base resource. * @param int $flags [optional] Optional parameter, which can take any combination of EVLOOP_ONCE and EVLOOP_NONBLOCK. * * @return int

    * Returns 0 if it exited normally, * -1 if it exited because of some unhandled error in the backend * and 1 if no events were registered. *

    */ function event_base_loop($event_base, $flags = null) {} /** *

    Tells the event_base to exit its loop immediately.

    *

    (PECL libevent >= 0.0.1)

    * *

    It differs from {@link event_base_loopexit}() in that if the event_base is currently * running callbacks for any active events, it will exit immediately after finishing the * one it's currently processing. The behaviour is similar to break statement.

    * * @link https://php.net/event_base_loopbreak * * @param resource $event_base Valid event base resource. * * @return bool returns TRUE on success or FALSE on error. */ function event_base_loopbreak($event_base) {} /** *

    Tells an event_base to stop looping after a given time has elapsed

    *

    (PECL libevent >= 0.0.1)

    * *

    If the event_base is currently running callbacks for any active events, * it will continue running them, and not exit until they have all been run.

    * *

    If event loop isn't running {@link event_base_loopexit}() schedules the next instance * of the event loop to stop right after the next round of callbacks are run (as if it had * been invoked with EVLOOP_ONCE).

    * * @link https://php.net/event_base_loopexit * * @param resource $event_base

    * Valid event base resource. *

    * @param int $timeout [optional]

    * Optional timeout parameter (in microseconds). If lower than 1, * the event_base stops looping without a delay. *

    * * @return bool returns TRUE on success or FALSE on error. */ function event_base_loopexit($event_base, $timeout = -1) {} /** *

    Associate event base with an event

    *

    (PECL libevent >= 0.0.1)

    * *

    Associates the event_base with the event.

    * * @link https://php.net/event_base_set * * @param resource $event Valid event resource. * @param resource $base Valid event base resource. * * @return bool returns TRUE on success or FALSE on error. */ function event_base_set($event, $base) {} /** *

    Set the number of different event priority levels

    *

    (PECL libevent >= 0.0.2)

    * *

    By default all events are scheduled with the same priority (npriorities/2). * Using {@link event_base_priority_init}() you can change the number of event priority * levels and then set a desired priority for each event.

    * * @link https://php.net/event_base_priority_init * * @param resource $event_base Valid event base resource. * @param int $npriorities The number of event priority levels. * * @return bool returns TRUE on success or FALSE on error. */ function event_base_priority_init($event_base, $npriorities) {} /** *

    Creates and returns a new event resource.

    *

    (PECL libevent >= 0.0.1)

    * * @link https://php.net/event_new * * @return resource|false returns a new event resource on success or FALSE on error. */ function event_new() {} /** *

    Free event resource.

    *

    (PECL libevent >= 0.0.1)

    * * @link https://php.net/event_free * * @param resource $event Valid event resource. * * @return void */ function event_free($event) {} /** *

    Add an event to the set of monitored events

    *

    (PECL libevent >= 0.0.1)

    * *

    Schedules the execution of the non-pending event (makes it pending in it's * configured base) when the event specified in {@link event_set}() occurs or in * at least the time specified by the timeout argument. If timeout was not specified, * not timeout is set. The event must be already initialized by * {@link event_set}() and {@link event_base_set}() functions. * If the event already has a timeout set, * it is replaced by the new one.

    * *

    If you call {@link event_add}() on an event that is already pending, * it will leave it pending, and reschedule it with the provided timeout.

    * * @link https://php.net/event_add * * @param resource $event

    * Valid event resource. *

    * @param int $timeout [optional]

    * Optional timeout (in microseconds). *

    * * @return bool returns TRUE on success or FALSE on error. */ function event_add($event, $timeout = -1) {} /** *

    Prepares the event to be used in {@link event_add}().

    *

    (PECL libevent >= 0.0.1)

    * *

    The event is prepared to call the function specified by the callback * on the events specified in parameter events, which is a set of the following * flags: EV_TIMEOUT, EV_SIGNAL, EV_READ, EV_WRITE and EV_PERSIST.

    * *

    EV_SIGNAL support was added in version 0.0.4

    * *

    After initializing the event, use {@link event_base_set}() to associate the event with its event base.

    * *

    In case of matching event, these three arguments are passed to the callback function: *

    * * * * * * * * * * * * *
    $fdSignal number or resource indicating the stream.
    $eventsA flag indicating the event. Consists of the following flags: EV_TIMEOUT, EV_SIGNAL, EV_READ, EV_WRITE and EV_PERSIST.
    $argOptional parameter, previously passed to {@link event_set}() as arg.
    *

    * * @link https://php.net/event_set * * @param resource $event

    * Valid event resource. *

    * @param resource|int $fd

    * Valid PHP stream resource. The stream must be castable to file descriptor, * so you most likely won't be able to use any of filtered streams. *

    * @param int $events

    * A set of flags indicating the desired event, can be EV_READ and/or EV_WRITE. * The additional flag EV_PERSIST makes the event to persist until {@link event_del}() is * called, otherwise the callback is invoked only once. *

    * @param callable $callback

    * Callback function to be called when the matching event occurs. *

    * @param mixed $arg [optional]

    * Optional callback parameter. *

    * * @return bool returns TRUE on success or FALSE on error. */ function event_set($event, $fd, $events, $callback, $arg = null) {} /** *

    Remove an event from the set of monitored events.

    *

    (PECL libevent >= 0.0.1)

    * *

    Calling {@link event_del}() on an initialized event makes it non-pending * and non-active. If the event was not pending or active, there is no effect.

    * * @link https://php.net/event_del * * @param resource $event Valid event resource. * * @return bool returns TRUE on success or FALSE on error. */ function event_del($event) {} /** *

    Create new buffered event

    *

    (PECL libevent >= 0.0.1)

    * *

    Libevent provides an abstraction layer on top of the regular event API. * Using buffered event you don't need to deal with the I/O manually, instead * it provides input and output buffers that get filled and drained automatically.

    * *

    Every bufferevent has two data-related callbacks: a read callback and a write * callback. By default, the read callback is called whenever any data is read from * the underlying transport, and the write callback is called whenever enough data * from the output buffer is emptied to the underlying transport. You can override * the behavior of these functions by adjusting the read and write "watermarks" * of the bufferevent (see {@link event_buffer_watermark_set}()).

    * *

    A bufferevent also has an "error" or "event" callback that gets invoked to tell * the application about non-data-oriented events, like when a connection is closed or * an error occurs.

    * * @link https://php.net/event_buffer_new * * @param resource $stream Valid PHP stream resource. Must be castable to file descriptor. * @param callable|null $readcb Callback to invoke where there is data to read, or NULL if no callback is desired. * @param callable|null $writecb Callback to invoke where the descriptor is ready for writing, or NULL if no callback is desired. * @param callable $errorcb Callback to invoke where there is an error on the descriptor, cannot be NULL. * @param mixed $arg An argument that will be passed to each of the callbacks (optional). * * @return resource|false returns new buffered event resource on success or FALSE on error. */ function event_buffer_new($stream, $readcb, $writecb, $errorcb, $arg = null) {} /** *

    Destroys the specified buffered event and frees all the resources associated.

    *

    (PECL libevent >= 0.0.1)

    * * @link https://php.net/event_buffer_free * * @param resource $bevent Valid buffered event resource. * * @return void */ function event_buffer_free($bevent) {} /** *

    Associate buffered event with an event base

    *

    (PECL libevent >= 0.0.1)

    * *

    Assign the specified bevent to the event_base.

    * * @link https://php.net/event_buffer_base_set * * @param resource $bevent Valid buffered event resource. * @param resource $event_base Valid event base resource. * * @return bool returns TRUE on success or FALSE on error. */ function event_buffer_base_set($bevent, $event_base) {} /** *

    Assign a priority to a buffered event. Use it after * initializing event, but before adding an event to the event_base.

    *

    (PECL libevent >= 0.0.1)

    * *

    When multiple events trigger at the same time, Libevent * does not define any order with respect to when their callbacks * will be executed. You can define some events as more important * than others by using priorities.

    * *

    When multiple events of multiple priorities become active, * the low-priority events are not run. Instead, Libevent runs * the high priority events, then checks for events again. Only * when no high-priority events are active are the low-priority * events run.

    * *

    When you do not set the priority for an event, the default * is the number of queues in the event base, divided by 2.

    * * @link https://php.net/event_buffer_priority_set * * @see event_base_priority_init * * @param resource $bevent

    * Valid buffered event resource. *

    * @param int $priority

    * Priority level. Cannot be less than 0 and cannot exceed * maximum priority level of the event base (see {@link event_base_priority_init}()). *

    * * @return bool returns TRUE on success or FALSE on error. */ function event_buffer_priority_set($bevent, $priority) {} /** *

    Writes data to the specified buffered event.

    *

    (PECL libevent >= 0.0.1)

    * *

    The data is appended to the output buffer and written * to the descriptor when it becomes available for writing.

    * * @link https://php.net/event_buffer_write * * @param resource $bevent Valid buffered event resource. * @param string $data The data to be written. * @param int $data_size Optional size parameter. {@link event_buffer_write}() writes all the data by default * * @return bool returns TRUE on success or FALSE on error. */ function event_buffer_write($bevent, $data, $data_size = -1) {} /** *

    Reads data from the input buffer of the buffered event.

    *

    (PECL libevent >= 0.0.1)

    * * @link https://php.net/event_buffer_read * * @param resource $bevent Valid buffered event resource. * @param int $data_size Data size in bytes. * * @return string */ function event_buffer_read($bevent, $data_size) {} /** *

    Enables the specified buffered event.

    *

    (PECL libevent >= 0.0.1)

    * * @link https://php.net/event_buffer_enable * * @param resource $bevent Valid buffered event resource. * @param int $events Any combination of EV_READ and EV_WRITE. * * @return bool returns TRUE on success or FALSE on error. */ function event_buffer_enable($bevent, $events) {} /** *

    Disable a buffered event

    *

    (PECL libevent >= 0.0.1)

    * *

    Disables the specified buffered event.

    * * @link https://php.net/event_buffer_disable * * @param resource $bevent Valid buffered event resource. * @param int $events Any combination of EV_READ and EV_WRITE. * * @return bool returns TRUE on success or FALSE on error. */ function event_buffer_disable($bevent, $events) {} /** *

    Sets the read and write timeouts for the specified buffered event.

    *

    (PECL libevent >= 0.0.1)

    * * @link https://php.net/event_buffer_timeout_set * * @param resource $bevent Valid buffered event resource. * @param int $read_timeout Read timeout (in seconds). * @param int $write_timeout Write timeout (in seconds). * * @return void */ function event_buffer_timeout_set($bevent, $read_timeout, $write_timeout) {} /** *

    Set the watermarks for read and write events.

    *

    (PECL libevent >= 0.0.1)

    * *

    Every bufferevent has four watermarks:

    * *

    Read low-water mark
    * Whenever a read occurs that leaves the bufferevent's input buffer at this * level or higher, the bufferevent's read callback is invoked. Defaults to 0, * so that every read results in the read callback being invoked.

    * *

    Read high-water mark
    * If the bufferevent's input buffer ever gets to this level, the bufferevent * stops reading until enough data is drained from the input buffer to take us * below it again. Defaults to unlimited, so that we never stop reading because * of the size of the input buffer.

    * *

    Write low-water mark
    * Whenever a write occurs that takes us to this level or below, we invoke the write * callback. Defaults to 0, so that a write callback is not invoked unless the output * buffer is emptied.

    * *

    Write high-water mark
    * Not used by a bufferevent directly, this watermark can have special meaning when * a bufferevent is used as the underlying transport of another bufferevent.

    * *

    Libevent does not invoke read callback unless there is at least lowmark * bytes in the input buffer; if the read buffer is beyond the highmark, * reading is stopped. On output, the write callback is invoked whenever * the buffered data falls below the lowmark.

    * * @link https://php.net/event_buffer_watermark_set * * @param resource $bevent Valid buffered event resource. * @param int $events Any combination of EV_READ and EV_WRITE. * @param int $lowmark Low watermark. * @param int $highmark High watermark. * * @return void */ function event_buffer_watermark_set($bevent, $events, $lowmark, $highmark) {} /** *

    Changes the file descriptor on which the buffered event operates.

    *

    (PECL libevent >= 0.0.1)

    * * @link https://php.net/event_buffer_fd_set * * @param resource $bevent Valid buffered event resource. * @param resource $fd Valid PHP stream, must be castable to file descriptor. * * @return void */ function event_buffer_fd_set($bevent, $fd) {} /** *

    Set or reset callbacks for a buffered event

    *

    (PECL libevent >= 0.0.4)

    * *

    Sets or changes existing callbacks for the buffered event.

    * * @link https://php.net/event_buffer_set_callback * * @param resource $bevent Valid buffered event resource. * @param callable|null $readcb Callback to invoke where there is data to read, or NULL if no callback is desired. * @param callable|null $writecb Callback to invoke where the descriptor is ready for writing, or NULL if no callback is desired. * @param callable $errorcb Callback to invoke where there is an error on the descriptor, cannot be NULL. * @param mixed $arg An argument that will be passed to each of the callbacks (optional). * * @return bool returns TRUE on success or FALSE on error. */ function event_buffer_set_callback($bevent, $readcb, $writecb, $errorcb, $arg = null) {} /** *

    Alias of {@link event_new}().

    * * @return resource|false returns valid event base resource on success or FALSE on error. */ function event_timer_new() {} /** *

    Prepares the timer event to be used in {@link event_add}().

    * *

    The event is prepared to call the function specified by the callback * on the timeout event (EV_TIMEOUT).

    * *

    After initializing the event, use {@link event_base_set}() to associate the event with its event base.

    * *

    In case of matching event, these three arguments are passed to the callback function: *

    * * * * * * * * * * * * *
    $fdnull
    $eventsA flag indicating the event. EV_TIMEOUT.
    $argOptional parameter, previously passed to {@link event_timer_set}() as arg.
    *

    * * @param resource $event

    * Valid event resource. *

    * @param callable $callback

    * Callback function to be called when the matching event occurs. *

    * @param mixed $arg [optional]

    * Optional callback parameter. *

    * * @return void */ function event_timer_set($event, $callback, $arg = null) {} /** *

    Checks if a specific event is pending or scheduled.

    * * @param resource $event

    * Valid event resource. *

    * @param int $timeout [optional]

    * Optional timeout (in microseconds). *

    * * @return bool TRUE if event is not scheduled (added) FALSE otherwise */ function event_timer_pending($event, $timeout = -1) {} /** *

    Alias of {@link event_add}().

    * * @param resource $event

    * Valid event resource. *

    * @param int $timeout [optional]

    * Optional timeout (in microseconds). *

    * * @return bool returns TRUE on success or FALSE on error. */ function event_timer_add($event, $timeout = -1) {} /** *

    Alias of {@link event_del}().

    * * @param resource $event Valid event resource. * * @return bool returns TRUE on success or FALSE on error. */ function event_timer_del($event) {} // End of PECL libevent v.0.0.4 = 0.9.0)
    * Figures out the best way of encoding the content read from the given file pointer. * @link https://php.net/manual/en/function.mailparse-determine-best-xfer-encoding.php * @param resource $fp

    * A valid file pointer, which must be seek-able. *

    * @return string Returns one of the character encodings supported by the * {@link https://php.net/manual/en/ref.mbstring.php mbstring} module. */ function mailparse_determine_best_xfer_encoding($fp) {} /** * (PECL mailparse >= 0.9.0)
    * Create a MIME mail resource. * @link https://php.net/manual/en/function.mailparse-msg-create.php * @return resource Returns a handle that can be used to parse a message. */ function mailparse_msg_create() {} /** * (PECL mailparse >= 0.9.0)
    * Extracts/decodes a message section from the supplied filename. * The contents of the section will be decoded according to their transfer encoding - base64, quoted-printable and * uuencoded text are supported. * @link https://php.net/manual/en/function.mailparse-msg-extract-part-file.php * @param resource $mimemail

    * A valid MIME resource, created with {@link https://php.net/manual/en/function.mailparse-msg-create.php mailparse_msg_create()}. *

    * @param mixed $filename

    * Can be a file name or a valid stream resource. *

    * @param callable $callbackfunc [optional]

    * If set, this must be either a valid callback that will be passed the extracted section, or NULL to make this * function return the extracted section. *

    *

    * If not specified, the contents will be sent to "stdout". *

    * @return string|bool

    * If callbackfunc is not NULL returns TRUE on success. *

    *

    * If callbackfunc is set to NULL, returns the extracted section as a string. *

    *

    * Returns FALSE on error. *

    */ function mailparse_msg_extract_part_file($mimemail, $filename, $callbackfunc) {} /** * (PECL mailparse >= 0.9.0)
    * Extracts/decodes a message section * @link https://php.net/manual/en/function.mailparse-msg-extract-part.php * @param resource $mimemail

    * A valid MIME resource. *

    * @param string $msgbody * @param callable $callbackfunc [optional] * @return void */ function mailparse_msg_extract_part($mimemail, $msgbody, $callbackfunc) {} /** * (PECL mailparse >= 0.9.0)
    * Extracts a message section including headers without decoding the transfer encoding * @link https://php.net/manual/en/function.mailparse-msg-extract-whole-part-file.php * @param resource $mimemail

    * A valid MIME resource *

    * @param string $filename * @param callable $callbackfunc [optional] * @return string */ function mailparse_msg_extract_whole_part_file($mimemail, $filename, $callbackfunc) {} /** * (PECL mailparse >= 0.9.0)
    * Frees a MIME resource. * @link https://php.net/manual/en/function.mailparse-msg-free.php * @param resource $mimemail

    * A valid MIME resource allocated by * {@link https://php.net/manual/en/function.mailparse-msg-create.php mailparse_msg_create()} or * {@link https://php.net/manual/en/function.mailparse-msg-parse-file.php mailparse_msg_parse_file()}. *

    * @return bool Returns TRUE on success or FALSE on failure. */ function mailparse_msg_free($mimemail) {} /** * (PECL mailparse >= 0.9.0)
    * Returns an associative array of info about the message * @link https://php.net/manual/en/function.mailparse-msg-get-part-data.php * @param resource $mimemail

    * A valid MIME resource. *

    * @return array */ function mailparse_msg_get_part_data($mimemail) {} /** * (PECL mailparse >= 0.9.0)
    * Returns a handle on a given section in a mimemessage * @link https://php.net/manual/en/function.mailparse-msg-get-part.php * @param resource $mimemail

    * A valid MIME resource. *

    * @param string $mimesection * @return resource|false */ function mailparse_msg_get_part($mimemail, $mimesection) {} /** * (PECL mailparse >= 0.9.0)
    * Returns an array of mime section names in the supplied message * @link https://php.net/manual/en/function.mailparse-msg-get-structure.php * @param resource $mimemail

    * A valid MIME resource. *

    * @return array */ function mailparse_msg_get_structure($mimemail) {} /** * (PECL mailparse >= 0.9.0)
    * Parses a file. This is the optimal way of parsing a mail file that you have on disk. * @link https://php.net/manual/en/function.mailparse-msg-parse-file.php * @param string $filename

    * Path to the file holding the message. The file is opened and streamed through the parser. *

    * @return resource|false Returns a MIME resource representing the structure, or FALSE on error. */ function mailparse_msg_parse_file($filename) {} /** * (PECL mailparse >= 0.9.0)
    * Incrementally parse data into the supplied mime mail resource. * This function allow you to stream portions of a file at a time, rather than read and parse the whole thing. * @link https://php.net/manual/en/function.mailparse-msg-parse.php * @param resource $mimemail

    * A valid MIME resource. *

    * @param string $data * @return bool Returns TRUE on success or FALSE on failure. */ function mailparse_msg_parse($mimemail, $data) {} /** * (PECL mailparse >= 0.9.0)
    * Parses a {@link http://www.faqs.org/rfcs/rfc822 RFC 822} compliant recipient list, such as that found in the To: header. * @link https://php.net/manual/en/function.mailparse-rfc822-parse-addresses.php * @param string $addresses

    * A string containing addresses, like in:

    Wez Furlong , doe@example.com
    * Note: This string must not include the header name. *

    * @return array

    * Returns an array of associative arrays with the following keys for each recipient: *

    * * * * * * * * * * * * * *
    displayThe recipient name, for display purpose. If this part is not set for a recipient, this key will hold the same value as address.
    addressThe email address
    is_groupTRUE if the recipient is a newsgroup, FALSE otherwise.
    */ function mailparse_rfc822_parse_addresses($addresses) {} /** * (PECL mailparse >= 0.9.0)
    * Streams data from the source file pointer, apply encoding and write to the destination file pointer. * @link https://php.net/manual/en/function.mailparse-stream-encode.php * @param resource $sourcefp

    * A valid file handle. The file is streamed through the parser. *

    * @param resource $destfp

    * The destination file handle in which the encoded data will be written. *

    * @param string $encoding

    * One of the character encodings supported by the {@link https://php.net/manual/en/ref.mbstring.php mbstring} module. *

    * @return bool Returns TRUE on success or FALSE on failure. */ function mailparse_stream_encode($sourcefp, $destfp, $encoding) {} /** * (PECL mailparse >= 0.9.0)
    * Scans the data from the given file pointer and extract each embedded uuencoded file into a temporary file. * @link https://php.net/manual/en/function.mailparse-uudecode-all.php * @param resource $fp

    * A valid file pointer. *

    * @return array

    * Returns an array of associative arrays listing filename information. *

    * * * * * * * * * *
    filenamePath to the temporary file name created
    origfilenameThe original filename, for uuencoded parts only
    *

    * The first filename entry is the message body. The next entries are the decoded uuencoded files. *

    */ function mailparse_uudecode_all($fp) {} define('MAILPARSE_EXTRACT_OUTPUT', 0); define('MAILPARSE_EXTRACT_STREAM', 1); define('MAILPARSE_EXTRACT_RETURN', 2); // End of mailparse v. * Before 7.2.0 checked cookie status and since 7.2.0 checks both cookie and session status to avoid PHP crash. * @link https://php.net/manual/en/function.session-name.php * @param string|null $name [optional]

    * The session name references the name of the session, which is * used in cookies and URLs (e.g. PHPSESSID). It * should contain only alphanumeric characters; it should be short and * descriptive (i.e. for users with enabled cookie warnings). * If name is specified, the name of the current * session is changed to its value. *

    *

    *

    * The session name can't consist of digits only, at least one letter * must be present. Otherwise a new session id is generated every time. *

    *

    * @return string|false the name of the current session. */ #[LanguageLevelTypeAware(['8.0' => 'string|false'], default: 'string')] function session_name(#[LanguageLevelTypeAware(['8.0' => 'null|string'], default: 'string')] $name) {} /** * Get and/or set the current session module.
    * Since 7.2.0 it is forbidden to set the module name to "user". * @link https://php.net/manual/en/function.session-module-name.php * @param string|null $module [optional]

    * If module is specified, that module will be * used instead. *

    * @return string|false the name of the current session module. */ #[LanguageLevelTypeAware(['8.0' => 'string|false'], default: 'string')] function session_module_name(#[LanguageLevelTypeAware(['8.0' => 'null|string'], default: 'string')] $module) {} /** * Get and/or set the current session save path * @link https://php.net/manual/en/function.session-save-path.php * @param string|null $path [optional]

    * Session data path. If specified, the path to which data is saved will * be changed. session_save_path needs to be called * before session_start for that purpose. *

    *

    *

    * On some operating systems, you may want to specify a path on a * filesystem that handles lots of small files efficiently. For example, * on Linux, reiserfs may provide better performance than ext2fs. *

    *

    * @return string|false the path of the current directory used for data storage. */ #[LanguageLevelTypeAware(['8.0' => 'string|false'], default: 'string')] function session_save_path(#[LanguageLevelTypeAware(['8.0' => 'null|string'], default: 'string')] $path) {} /** * Get and/or set the current session id * @link https://php.net/manual/en/function.session-id.php * @param string|null $id [optional]

    * If id is specified, it will replace the current * session id. session_id needs to be called before * session_start for that purpose. Depending on the * session handler, not all characters are allowed within the session id. * For example, the file session handler only allows characters in the * range a-z A-Z 0-9 , (comma) and - (minus)! *

    * When using session cookies, specifying an id * for session_id will always send a new cookie * when session_start is called, regardless if the * current session id is identical to the one being set. * @return string|false session_id returns the session id for the current * session or the empty string ("") if there is no current * session (no current session id exists). */ #[LanguageLevelTypeAware(['8.0' => 'string|false'], default: 'string')] function session_id(#[LanguageLevelTypeAware(['8.0' => 'null|string'], default: 'string')] $id) {} /** * Update the current session id with a newly generated one * @link https://php.net/manual/en/function.session-regenerate-id.php * @param bool $delete_old_session [optional]

    * Whether to delete the old associated session file or not. *

    * @return bool true on success or false on failure. */ function session_regenerate_id(bool $delete_old_session = false): bool {} /** * PHP > 5.4.0
    * Session shutdown function * @link https://secure.php.net/manual/en/function.session-register-shutdown.php * @return void */ function session_register_shutdown(): void {} /** * Decodes session data from a string * @link https://php.net/manual/en/function.session-decode.php * @param string $data

    * The encoded data to be stored. *

    * @return bool true on success or false on failure. */ function session_decode(string $data): bool {} /** * Register one or more global variables with the current session * @link https://php.net/manual/en/function.session-register.php * @param mixed $name

    * A string holding the name of a variable or an array consisting of * variable names or other arrays. *

    * @param mixed ...$_ [optional] * @return bool true on success or false on failure. * @removed 5.4 */ #[Deprecated(since: '5.3')] function session_register(mixed $name, ...$_): bool {} /** * Unregister a global variable from the current session * @link https://php.net/manual/en/function.session-unregister.php * @param string $name

    * The variable name. *

    * @return bool true on success or false on failure. * @removed 5.4 */ #[Deprecated(since: '5.3')] function session_unregister(string $name): bool {} /** * Find out whether a global variable is registered in a session * @link https://php.net/manual/en/function.session-is-registered.php * @param string $name

    * The variable name. *

    * @return bool session_is_registered returns true if there is a * global variable with the name name registered in * the current session, false otherwise. * @removed 5.4 */ #[Deprecated(since: '5.3')] function session_is_registered(string $name): bool {} /** * Encodes the current session data as a string * @link https://php.net/manual/en/function.session-encode.php * @return string|false the contents of the current session encoded. */ #[LanguageLevelTypeAware(["8.0" => "string|false"], default: "string")] function session_encode() {} /** * Initialize session data * @link https://php.net/manual/en/function.session-start.php * @param array $options [optional]

    If provided, this is an associative array of options that will override the currently set session configuration directives. The keys should not include the session. prefix. * In addition to the normal set of configuration directives, a read_and_close option may also be provided. If set to TRUE, this will result in the session being closed immediately after being read, thereby avoiding unnecessary locking if the session data won't be changed.

    * @return bool This function returns true if a session was successfully started, * otherwise false. */ function session_start(#[PhpStormStubsElementAvailable(from: '7.0')] array $options = []): bool {} /** * Create new session id * @link https://www.php.net/manual/en/function.session-create-id.php * @param string $prefix [optional] If prefix is specified, new session id is prefixed by prefix. * Not all characters are allowed within the session id. * Characters in the range a-z A-Z 0-9 , (comma) and - (minus) are allowed. * @return string|false new collision free session id for the current session. * If it is used without active session, it omits collision check. * @since 7.1 */ #[LanguageLevelTypeAware(["8.0" => "string|false"], default: "string")] function session_create_id(string $prefix = '') {} /** * Perform session data garbage collection * @return int|false number of deleted session data for success, false for failure. * @since 7.1 */ #[LanguageLevelTypeAware(["8.0" => "int|false"], default: "int")] function session_gc() {} /** * Destroys all data registered to a session * @link https://php.net/manual/en/function.session-destroy.php * @return bool true on success or false on failure. */ function session_destroy(): bool {} /** * Free all session variables * @link https://php.net/manual/en/function.session-unset.php * @return void|bool since 7.2.0 returns true on success or false on failure. */ #[LanguageLevelTypeAware(["7.2" => "bool"], default: "void")] function session_unset() {} /** * Sets user-level session storage functions * @link https://php.net/manual/en/function.session-set-save-handler.php * @param callable $open

    * Open function, this works like a constructor in classes and is * executed when the session is being opened. The open function * expects two parameters, where the first is the save path and * the second is the session name. *

    * @param callable $close

    * Close function, this works like a destructor in classes and is * executed when the session operation is done. *

    * @param callable $read

    * Read function must return string value always to make save handler * work as expected. Return empty string if there is no data to read. * Return values from other handlers are converted to boolean expression. * true for success, false for failure. *

    * @param callable $write

    * Write function that is called when session data is to be saved. This * function expects two parameters: an identifier and the data associated * with it. *

    *

    * The "write" handler is not executed until after the output stream is * closed. Thus, output from debugging statements in the "write" * handler will never be seen in the browser. If debugging output is * necessary, it is suggested that the debug output be written to a * file instead. *

    * @param callable $destroy

    * The destroy handler, this is executed when a session is destroyed with * session_destroy and takes the session id as its * only parameter. *

    * @param callable $gc

    * The garbage collector, this is executed when the session garbage collector * is executed and takes the max session lifetime as its only parameter. *

    * @param callable|null $create_sid [optional] *

    This callback is executed when a new session ID is required. * No parameters are provided, and the return value should be a string that is a valid * session ID for your handler.

    * @param callable|null $validate_sid [optional] * @param callable|null $update_timestamp [optional] * @return bool true on success or false on failure. */ function session_set_save_handler(callable $open, callable $close, callable $read, callable $write, callable $destroy, callable $gc, ?callable $create_sid = null, ?callable $validate_sid = null, ?callable $update_timestamp = null): bool {} /** * (PHP 5.4)
    * Sets user-level session storage functions * @link https://php.net/manual/en/function.session-set-save-handler.php * @param SessionHandlerInterface $session_handler An instance of a class implementing SessionHandlerInterface, * and optionally SessionIdInterface and/or SessionUpdateTimestampHandlerInterface, such as SessionHandler, * to register as the session handler. Since PHP 5.4 only. * @param bool $register_shutdown [optional] Register session_write_close() as a register_shutdown_function() function. * @return bool true on success or false on failure. */ function session_set_save_handler(SessionHandlerInterface $sessionhandler, bool $register_shutdown = true): bool {} /** * Get and/or set the current cache limiter * @link https://php.net/manual/en/function.session-cache-limiter.php * @param string|null $value [optional]

    * If cache_limiter is specified, the name of the * current cache limiter is changed to the new value. *

    * * Possible values * * * * * * * * * * * * * * * * * * * * *
    ValueHeaders sent
    public *
     * Expires: (sometime in the future, according session.cache_expire)
     * Cache-Control: public, max-age=(sometime in the future, according to session.cache_expire)
     * Last-Modified: (the timestamp of when the session was last saved)
     * 
    *
    private_no_expire *
     * Cache-Control: private, max-age=(session.cache_expire in the future), pre-check=(session.cache_expire in the future)
     * Last-Modified: (the timestamp of when the session was last saved)
     * 
    *
    private *
     * Expires: Thu, 19 Nov 1981 08:52:00 GMT
     * Cache-Control: private, max-age=(session.cache_expire in the future), pre-check=(session.cache_expire in the future)
     * Last-Modified: (the timestamp of when the session was last saved)
     * 
    *
    nocache *
     * Expires: Thu, 19 Nov 1981 08:52:00 GMT
     * Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
     * Pragma: no-cache
     * 
    *
    * @return string|false the name of the current cache limiter. */ #[LanguageLevelTypeAware(["8.0" => "string|false"], default: "string")] function session_cache_limiter(#[LanguageLevelTypeAware(['8.0' => 'null|string'], default: 'string')] $value) {} /** * Return current cache expire * @link https://php.net/manual/en/function.session-cache-expire.php * @param int|null $value [optional]

    * If new_cache_expire is given, the current cache * expire is replaced with new_cache_expire. *

    *

    * Setting new_cache_expire is of value only, if * session.cache_limiter is set to a value * different from nocache. *

    * @return int|false the current setting of session.cache_expire. * The value returned should be read in minutes, defaults to 180. */ #[LanguageLevelTypeAware(["8.0" => "int|false"], default: "int")] function session_cache_expire(#[LanguageLevelTypeAware(['8.0' => 'null|int'], default: 'int')] $value) {} /** * Set the session cookie parameters * @link https://php.net/manual/en/function.session-set-cookie-params.php * @param array $lifetime_or_options

    * An associative array which may have any of the keys lifetime, path, domain, * secure, httponly and samesite. The values have the same meaning as described * for the parameters with the same name. The value of the samesite element * should be either Lax or Strict. If any of the allowed options are not given, * their default values are the same as the default values of the explicit * parameters. If the samesite element is omitted, no SameSite cookie attribute * is set. *

    * @return bool returns true on success or false on failure. * @since 7.3 */ function session_set_cookie_params(array $lifetime_or_options): bool {} /** * Set the session cookie parameters * @link https://php.net/manual/en/function.session-set-cookie-params.php * @param int $lifetime_or_options

    * Lifetime of the * session cookie, defined in seconds. *

    * @param string|null $path [optional]

    * Path on the domain where * the cookie will work. Use a single slash ('/') for all paths on the * domain. *

    * @param string|null $domain [optional]

    * Cookie domain, for * example 'www.php.net'. To make cookies visible on all subdomains then * the domain must be prefixed with a dot like '.php.net'. *

    * @param bool|null $secure [optional]

    * If true cookie will only be sent over * secure connections. *

    * @param bool|null $httponly [optional]

    * If set to true then PHP will attempt to send the * httponly * flag when setting the session cookie. *

    * @return void|bool since 7.2.0 returns true on success or false on failure. */ #[LanguageLevelTypeAware(["7.2" => "bool"], default: "void")] function session_set_cookie_params(int $lifetime_or_options, ?string $path = null, ?string $domain = null, ?bool $secure = null, ?bool $httponly = null) {} /** * Get the session cookie parameters * @link https://php.net/manual/en/function.session-get-cookie-params.php * @return array an array with the current session cookie information, the array * contains the following items: * "lifetime" - The * lifetime of the cookie in seconds. * "path" - The path where * information is stored. * "domain" - The domain * of the cookie. * "secure" - The cookie * should only be sent over secure connections. * "httponly" - The * cookie can only be accessed through the HTTP protocol. */ #[ArrayShape(["lifetime" => "int", "path" => "string", "domain" => "string", "secure" => "bool", "httponly" => "bool", "samesite" => "string"])] function session_get_cookie_params(): array {} /** * Write session data and end session * @link https://php.net/manual/en/function.session-write-close.php * @return void|bool since 7.2.0 returns true on success or false on failure. */ #[LanguageLevelTypeAware(["7.2" => "bool"], default: "void")] function session_write_close() {} /** * Alias of session_write_close * @link https://php.net/manual/en/function.session-commit.php * @return void|bool since 7.2.0 returns true on success or false on failure. */ #[LanguageLevelTypeAware(["7.2" => "bool"], default: "void")] function session_commit() {} /** * (PHP 5 >= 5.4.0)
    * Returns the current session status * @link https://php.net/manual/en/function.session-status.php * @return int PHP_SESSION_DISABLED if sessions are disabled. * PHP_SESSION_NONE if sessions are enabled, but none exists. * PHP_SESSION_ACTIVE if sessions are enabled, and one exists. * @since 5.4 */ function session_status(): int {} /** * (PHP 5 >= 5.6.0)
    * Discard session array changes and finish session * @link https://php.net/manual/en/function.session-abort.php * @return void|bool since 7.2.0 returns true if a session was successfully reinitialized or false on failure. * @since 5.6 */ #[LanguageLevelTypeAware(["7.2" => "bool"], default: "void")] function session_abort() {} /** * (PHP 5 >= 5.6.0)
    * Re-initialize session array with original values * @link https://php.net/manual/en/function.session-reset.php * @return void|bool since 7.2.0 returns true if a session was successfully reinitialized or false on failure. * @since 5.6 */ #[LanguageLevelTypeAware(["7.2" => "bool"], default: "void")] function session_reset() {} // End of session v. SessionHandlerInterface is an interface which defines * a prototype for creating a custom session handler. * In order to pass a custom session handler to * session_set_save_handler() using its OOP invocation, * the class must implement this interface. * @link https://php.net/manual/en/class.sessionhandlerinterface.php * @since 5.4 */ interface SessionHandlerInterface { /** * Close the session * @link https://php.net/manual/en/sessionhandlerinterface.close.php * @return bool

    * The return value (usually TRUE on success, FALSE on failure). * Note this value is returned internally to PHP for processing. *

    * @since 5.4 */ #[TentativeType] public function close(): bool; /** * Destroy a session * @link https://php.net/manual/en/sessionhandlerinterface.destroy.php * @param string $id The session ID being destroyed. * @return bool

    * The return value (usually TRUE on success, FALSE on failure). * Note this value is returned internally to PHP for processing. *

    * @since 5.4 */ #[TentativeType] public function destroy(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $id): bool; /** * Cleanup old sessions * @link https://php.net/manual/en/sessionhandlerinterface.gc.php * @param int $max_lifetime

    * Sessions that have not updated for * the last maxlifetime seconds will be removed. *

    * @return int|false

    * Returns the number of deleted sessions on success, or false on failure. Prior to PHP version 7.1, the function returned true on success. * Note this value is returned internally to PHP for processing. *

    * @since 5.4 */ #[LanguageLevelTypeAware(['7.1' => 'int|false'], default: 'bool')] #[TentativeType] public function gc(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $max_lifetime): int|false; /** * Initialize session * @link https://php.net/manual/en/sessionhandlerinterface.open.php * @param string $path The path where to store/retrieve the session. * @param string $name The session name. * @return bool

    * The return value (usually TRUE on success, FALSE on failure). * Note this value is returned internally to PHP for processing. *

    * @since 5.4 */ #[TentativeType] public function open( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $path, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name ): bool; /** * Read session data * @link https://php.net/manual/en/sessionhandlerinterface.read.php * @param string $id The session id to read data for. * @return string|false

    * Returns an encoded string of the read data. * If nothing was read, it must return false. * Note this value is returned internally to PHP for processing. *

    * @since 5.4 */ #[TentativeType] public function read(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $id): string|false; /** * Write session data * @link https://php.net/manual/en/sessionhandlerinterface.write.php * @param string $id The session id. * @param string $data

    * The encoded session data. This data is the * result of the PHP internally encoding * the $_SESSION superglobal to a serialized * string and passing it as this parameter. * Please note sessions use an alternative serialization method. *

    * @return bool

    * The return value (usually TRUE on success, FALSE on failure). * Note this value is returned internally to PHP for processing. *

    * @since 5.4 */ #[TentativeType] public function write( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $id, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data ): bool; } /** * SessionIdInterface * @link https://php.net/manual/en/class.sessionidinterface.php * @since 5.5.1 */ interface SessionIdInterface { /** * Create session ID * @link https://php.net/manual/en/sessionidinterface.create-sid.php * @return string

    * The new session ID. Note that this value is returned internally to PHP for processing. *

    */ #[TentativeType] public function create_sid(): string; } /** * SessionUpdateTimestampHandlerInterface is an interface which * defines a prototype for updating the life time of an existing session. * In order to use the lazy_write option must be enabled and a custom session * handler must implement this interface. * @since 7.0 */ interface SessionUpdateTimestampHandlerInterface { /** * Validate session id * @link https://www.php.net/manual/sessionupdatetimestamphandlerinterface.validateid * @param string $id The session id * @return bool

    * Note this value is returned internally to PHP for processing. *

    */ #[TentativeType] public function validateId($id): bool; /** * Update timestamp of a session * @link https://www.php.net/manual/sessionupdatetimestamphandlerinterface.updatetimestamp.php * @param string $id The session id * @param string $data

    * The encoded session data. This data is the * result of the PHP internally encoding * the $_SESSION superglobal to a serialized * string and passing it as this parameter. * Please note sessions use an alternative serialization method. *

    * @return bool */ #[TentativeType] public function updateTimestamp($id, $data): bool; } /** * SessionHandler a special class that can * be used to expose the current internal PHP session * save handler by inheritance. There are six methods * which wrap the six internal session save handler * callbacks (open, close, read, write, destroy and gc). * By default, this class will wrap whatever internal * save handler is set as as defined by the * session.save_handler configuration directive which is usually * files by default. Other internal session save handlers are provided by * PHP extensions such as SQLite (as sqlite), * Memcache (as memcache), and Memcached (as memcached). * @link https://php.net/manual/en/class.reflectionzendextension.php * @since 5.4 */ class SessionHandler implements SessionHandlerInterface, SessionIdInterface { /** * Close the session * @link https://php.net/manual/en/sessionhandler.close.php * @return bool

    * The return value (usually TRUE on success, FALSE on failure). * Note this value is returned internally to PHP for processing. *

    * @since 5.4 */ #[TentativeType] public function close(): bool {} /** * Return a new session ID * @link https://php.net/manual/en/sessionhandler.create-sid.php * @return string

    A session ID valid for the default session handler.

    * @since 5.5.1 */ #[TentativeType] public function create_sid(): string {} /** * Destroy a session * @link https://php.net/manual/en/sessionhandler.destroy.php * @param string $id The session ID being destroyed. * @return bool

    * The return value (usually TRUE on success, FALSE on failure). * Note this value is returned internally to PHP for processing. *

    * @since 5.4 */ #[TentativeType] public function destroy(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $id): bool {} /** * Cleanup old sessions * @link https://php.net/manual/en/sessionhandler.gc.php * @param int $max_lifetime

    * Sessions that have not updated for * the last maxlifetime seconds will be removed. *

    * @return int|bool

    * The return value (usually TRUE on success, FALSE on failure). * Note this value is returned internally to PHP for processing. *

    * @since 5.4 */ #[TentativeType] public function gc(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $max_lifetime): int|false {} /** * Initialize session * @link https://php.net/manual/en/sessionhandler.open.php * @param string $path The path where to store/retrieve the session. * @param string $name The session name. * @return bool

    * The return value (usually TRUE on success, FALSE on failure). * Note this value is returned internally to PHP for processing. *

    * @since 5.4 */ #[TentativeType] public function open( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $path, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name ): bool {} /** * Read session data * @link https://php.net/manual/en/sessionhandler.read.php * @param string $id The session id to read data for. * @return string|false

    * Returns an encoded string of the read data. * If nothing was read, it must return an empty string. * Note this value is returned internally to PHP for processing. *

    * @since 5.4 */ #[TentativeType] public function read(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $id): string|false {} /** * Write session data * @link https://php.net/manual/en/sessionhandler.write.php * @param string $id The session id. * @param string $data

    * The encoded session data. This data is the * result of the PHP internally encoding * the $_SESSION superglobal to a serialized * string and passing it as this parameter. * Please note sessions use an alternative serialization method. *

    * @return bool

    * The return value (usually TRUE on success, FALSE on failure). * Note this value is returned internally to PHP for processing. *

    * @since 5.4 */ #[TentativeType] public function write( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $id, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data ): bool {} } * * Elements of array returned by gd_info * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    AttributeMeaning
    GD Versionstring value describing the installed * libgd version.
    FreeType Supportboolean value. TRUE * if FreeType Support is installed.
    FreeType Linkagestring value describing the way in which * FreeType was linked. Expected values are: 'with freetype', * 'with TTF library', and 'with unknown library'. This element will * only be defined if FreeType Support evaluated to * TRUE.
    T1Lib Supportboolean value. TRUE * if T1Lib support is included.
    GIF Read Supportboolean value. TRUE * if support for reading GIF * images is included.
    GIF Create Supportboolean value. TRUE * if support for creating GIF * images is included.
    JPEG Supportboolean value. TRUE * if JPEG support is included.
    PNG Supportboolean value. TRUE * if PNG support is included.
    WBMP Supportboolean value. TRUE * if WBMP support is included.
    XBM Supportboolean value. TRUE * if XBM support is included.
    WebP Supportboolean value. TRUE * if WebP support is included.
    *

    *

    * Previous to PHP 5.3.0, the JPEG Support attribute was named * JPG Support. *

    */ #[Pure] #[ArrayShape([ "GD Version" => "string", "FreeType Support" => "bool", "GIF Read Support" => "bool", "GIF Create Support" => "bool", "JPEG Support" => "bool", "PNG Support" => "bool", "WBMP Support" => "bool", "XPM Support" => "bool", "XBM Support" => "bool", "WebP Support" => "bool", "BMP Support" => "bool", "TGA Read Support" => "bool", "AVIF Support" => "bool", "JIS-mapped Japanese Font Support" => "bool" ])] function gd_info(): array {} /** * Draws an arc * @link https://php.net/manual/en/function.imagearc.php * @param resource|GdImage $image * @param int $center_x

    * x-coordinate of the center. *

    * @param int $center_y

    * y-coordinate of the center. *

    * @param int $width

    * The arc width. *

    * @param int $height

    * The arc height. *

    * @param int $start_angle

    * The arc start angle, in degrees. *

    * @param int $end_angle

    * The arc end angle, in degrees. * 0° is located at the three-o'clock position, and the arc is drawn * clockwise. *

    * @param int $color

    * A color identifier created with * imagecolorallocate. *

    * @return bool TRUE on success or FALSE on failure. */ function imagearc(GdImage $image, int $center_x, int $center_y, int $width, int $height, int $start_angle, int $end_angle, int $color): bool {} /** * Draw an ellipse * @link https://php.net/manual/en/function.imageellipse.php * @param resource|GdImage $image * @param int $center_x

    * x-coordinate of the center. *

    * @param int $center_y

    * y-coordinate of the center. *

    * @param int $width

    * The ellipse width. *

    * @param int $height

    * The ellipse height. *

    * @param int $color

    * The color of the ellipse. A color identifier created with * imagecolorallocate. *

    * @return bool TRUE on success or FALSE on failure. */ function imageellipse(GdImage $image, int $center_x, int $center_y, int $width, int $height, int $color): bool {} /** * Draw a character horizontally * @link https://php.net/manual/en/function.imagechar.php * @param resource|GdImage $image * @param int $font * @param int $x

    * x-coordinate of the start. *

    * @param int $y

    * y-coordinate of the start. *

    * @param string $char

    * The character to draw. *

    * @param int $color

    * A color identifier created with * imagecolorallocate. *

    * @return bool TRUE on success or FALSE on failure. */ function imagechar( GdImage $image, #[LanguageLevelTypeAware(['8.1' => 'GdFont|int'], default: 'int')] $font, int $x, int $y, string $char, int $color ): bool {} /** * Draw a character vertically * @link https://php.net/manual/en/function.imagecharup.php * @param resource|GdImage $image * @param int $font * @param int $x

    * x-coordinate of the start. *

    * @param int $y

    * y-coordinate of the start. *

    * @param string $char

    * The character to draw. *

    * @param int $color

    * A color identifier created with * imagecolorallocate. *

    * @return bool TRUE on success or FALSE on failure. */ function imagecharup( GdImage $image, #[LanguageLevelTypeAware(['8.1' => 'GdFont|int'], default: 'int')] $font, int $x, int $y, string $char, int $color ): bool {} /** * Get the index of the color of a pixel * @link https://php.net/manual/en/function.imagecolorat.php * @param resource|GdImage $image * @param int $x

    * x-coordinate of the point. *

    * @param int $y

    * y-coordinate of the point. *

    * @return int|false the index of the color or FALSE on failure */ #[Pure] function imagecolorat(GdImage $image, int $x, int $y): int|false {} /** * Allocate a color for an image * @link https://php.net/manual/en/function.imagecolorallocate.php * @param resource|GdImage $image * @param int $red

    Value of red component.

    * @param int $green

    Value of green component.

    * @param int $blue

    Value of blue component.

    * @return int|false A color identifier or FALSE if the allocation failed. */ function imagecolorallocate(GdImage $image, int $red, int $green, int $blue): int|false {} /** * Copy the palette from one image to another * @link https://php.net/manual/en/function.imagepalettecopy.php * @param resource|GdImage $dst

    * The destination image resource. *

    * @param resource|GdImage $src

    * The source image resource. *

    * @return void No value is returned. */ function imagepalettecopy(GdImage $dst, GdImage $src): void {} /** * Create a new image from the image stream in the string * @link https://php.net/manual/en/function.imagecreatefromstring.php * @param string $data

    * A string containing the image data. *

    * @return resource|GdImage|false An image resource will be returned on success. FALSE is returned if * the image type is unsupported, the data is not in a recognised format, * or the image is corrupt and cannot be loaded. */ #[Pure] function imagecreatefromstring(string $data): GdImage|false {} /** * Get the index of the closest color to the specified color * @link https://php.net/manual/en/function.imagecolorclosest.php * @param resource|GdImage $image * @param int $red

    Value of red component.

    * @param int $green

    Value of green component.

    * @param int $blue

    Value of blue component.

    * @return int|false the index of the closest color, in the palette of the image, to * the specified one or FALSE on failure */ #[Pure] function imagecolorclosest(GdImage $image, int $red, int $green, int $blue): int {} /** * Get the index of the color which has the hue, white and blackness * @link https://php.net/manual/en/function.imagecolorclosesthwb.php * @param resource|GdImage $image * @param int $red

    Value of red component.

    * @param int $green

    Value of green component.

    * @param int $blue

    Value of blue component.

    * @return int|false an integer with the index of the color which has * the hue, white and blackness nearest the given color or FALSE on failure */ #[Pure] function imagecolorclosesthwb(GdImage $image, int $red, int $green, int $blue): int {} /** * De-allocate a color for an image * @link https://php.net/manual/en/function.imagecolordeallocate.php * @param resource|GdImage $image * @param int $color

    * The color identifier. *

    * @return bool TRUE on success or FALSE on failure. */ function imagecolordeallocate(GdImage $image, int $color): bool {} /** * Get the index of the specified color or its closest possible alternative * @link https://php.net/manual/en/function.imagecolorresolve.php * @param resource|GdImage $image * @param int $red

    Value of red component.

    * @param int $green

    Value of green component.

    * @param int $blue

    Value of blue component.

    * @return int|false a color index or FALSE on failure */ #[Pure] function imagecolorresolve(GdImage $image, int $red, int $green, int $blue): int {} /** * Get the index of the specified color * @link https://php.net/manual/en/function.imagecolorexact.php * @param resource|GdImage $image * @param int $red

    Value of red component.

    * @param int $green

    Value of green component.

    * @param int $blue

    Value of blue component.

    * @return int|false the index of the specified color in the palette, -1 if the * color does not exist, or FALSE on failure */ #[Pure] function imagecolorexact(GdImage $image, int $red, int $green, int $blue): int {} /** * Set the color for the specified palette index * @link https://php.net/manual/en/function.imagecolorset.php * @param resource|GdImage $image * @param int $color

    * An index in the palette. *

    * @param int $red

    Value of red component.

    * @param int $green

    Value of green component.

    * @param int $blue

    Value of blue component.

    * @param int $alpha [optional]

    * Value of alpha component. *

    * @return bool|null */ #[LanguageLevelTypeAware(['8.2' => 'null|false'], default: 'null|bool')] function imagecolorset(GdImage $image, int $color, int $red, int $green, int $blue, int $alpha = 0): ?bool {} /** * Define a color as transparent * @link https://php.net/manual/en/function.imagecolortransparent.php * @param resource|GdImage $image * @param int $color [optional]

    * A color identifier created with * imagecolorallocate. *

    * @return int The identifier of the new (or current, if none is specified) * transparent color is returned. If color * is not specified, and the image has no transparent color, the * returned identifier will be -1. */ function imagecolortransparent(GdImage $image, ?int $color = null): int {} /** * Find out the number of colors in an image's palette * @link https://php.net/manual/en/function.imagecolorstotal.php * @param resource|GdImage $image

    * An image resource, returned by one of the image creation functions, such * as imagecreatefromgif. *

    * @return int|false the number of colors in the specified image's palette, 0 for * truecolor images, or FALSE on failure */ #[Pure] function imagecolorstotal(GdImage $image): int {} /** * Get the colors for an index * @link https://php.net/manual/en/function.imagecolorsforindex.php * @param resource|GdImage $image * @param int $color

    * The color index. *

    * @return array|false an associative array with red, green, blue and alpha keys that * contain the appropriate values for the specified color index or FALSE on failure */ #[Pure] #[LanguageLevelTypeAware(['8.0' => 'array'], default: 'array|false')] #[ArrayShape(["red" => "int", "green" => "int", "blue" => "int", "alpha" => "int"])] function imagecolorsforindex(GdImage $image, int $color) {} /** * Copy part of an image * @link https://php.net/manual/en/function.imagecopy.php * @param resource|GdImage $dst_image

    * Destination image link resource. *

    * @param resource|GdImage $src_image

    * Source image link resource. *

    * @param int $dst_x

    * x-coordinate of destination point. *

    * @param int $dst_y

    * y-coordinate of destination point. *

    * @param int $src_x

    * x-coordinate of source point. *

    * @param int $src_y

    * y-coordinate of source point. *

    * @param int $src_width

    * Source width. *

    * @param int $src_height

    * Source height. *

    * @return bool true on success or false on failure. */ function imagecopy(GdImage $dst_image, GdImage $src_image, int $dst_x, int $dst_y, int $src_x, int $src_y, int $src_width, int $src_height): bool {} /** * Copy and merge part of an image * @link https://php.net/manual/en/function.imagecopymerge.php * @param resource|GdImage $dst_image

    * Destination image link resource. *

    * @param resource|GdImage $src_image

    * Source image link resource. *

    * @param int $dst_x

    * x-coordinate of destination point. *

    * @param int $dst_y

    * y-coordinate of destination point. *

    * @param int $src_x

    * x-coordinate of source point. *

    * @param int $src_y

    * y-coordinate of source point. *

    * @param int $src_width

    * Source width. *

    * @param int $src_height

    * Source height. *

    * @param int $pct

    * The two images will be merged according to pct * which can range from 0 to 100. When pct = 0, * no action is taken, when 100 this function behaves identically * to imagecopy for pallete images, while it * implements alpha transparency for true colour images. *

    * @return bool true on success or false on failure. */ function imagecopymerge(GdImage $dst_image, GdImage $src_image, int $dst_x, int $dst_y, int $src_x, int $src_y, int $src_width, int $src_height, int $pct): bool {} /** * Copy and merge part of an image with gray scale * @link https://php.net/manual/en/function.imagecopymergegray.php * @param resource|GdImage $dst_image

    * Destination image link resource. *

    * @param resource|GdImage $src_image

    * Source image link resource. *

    * @param int $dst_x

    * x-coordinate of destination point. *

    * @param int $dst_y

    * y-coordinate of destination point. *

    * @param int $src_x

    * x-coordinate of source point. *

    * @param int $src_y

    * y-coordinate of source point. *

    * @param int $src_width

    * Source width. *

    * @param int $src_height

    * Source height. *

    * @param int $pct

    * The src_im will be changed to grayscale according * to pct where 0 is fully grayscale and 100 is * unchanged. When pct = 100 this function behaves * identically to imagecopy for pallete images, while * it implements alpha transparency for true colour images. *

    * @return bool true on success or false on failure. */ function imagecopymergegray(GdImage $dst_image, GdImage $src_image, int $dst_x, int $dst_y, int $src_x, int $src_y, int $src_width, int $src_height, int $pct): bool {} /** * Copy and resize part of an image * @link https://php.net/manual/en/function.imagecopyresized.php * @param resource|GdImage $dst_image * @param resource|GdImage $src_image * @param int $dst_x

    * x-coordinate of destination point. *

    * @param int $dst_y

    * y-coordinate of destination point. *

    * @param int $src_x

    * x-coordinate of source point. *

    * @param int $src_y

    * y-coordinate of source point. *

    * @param int $dst_width

    * Destination width. *

    * @param int $dst_height

    * Destination height. *

    * @param int $src_width

    * Source width. *

    * @param int $src_height

    * Source height. *

    * @return bool true on success or false on failure. */ function imagecopyresized(GdImage $dst_image, GdImage $src_image, int $dst_x, int $dst_y, int $src_x, int $src_y, int $dst_width, int $dst_height, int $src_width, int $src_height): bool {} /** * Create a new palette based image * @link https://php.net/manual/en/function.imagecreate.php * @param int $width

    * The image width. *

    * @param int $height

    * The image height. *

    * @return resource|GdImage|false an image resource identifier on success, false on errors. */ #[Pure] function imagecreate(int $width, int $height): GdImage|false {} /** * Create a new true color image * @link https://php.net/manual/en/function.imagecreatetruecolor.php * @param int $width

    * Image width. *

    * @param int $height

    * Image height. *

    * @return resource|GdImage|false an image resource identifier on success, false on errors. */ #[Pure] function imagecreatetruecolor(int $width, int $height): GdImage|false {} /** * Finds whether an image is a truecolor image * @link https://php.net/manual/en/function.imageistruecolor.php * @param resource|GdImage $image * @return bool true if the image is truecolor, false * otherwise. */ #[Pure] function imageistruecolor(GdImage $image): bool {} /** * Convert a true color image to a palette image * @link https://php.net/manual/en/function.imagetruecolortopalette.php * @param resource|GdImage $image * @param bool $dither

    * Indicates if the image should be dithered - if it is true then * dithering will be used which will result in a more speckled image but * with better color approximation. *

    * @param int $num_colors

    * Sets the maximum number of colors that should be retained in the palette. *

    * @return bool true on success or false on failure. */ function imagetruecolortopalette(GdImage $image, bool $dither, int $num_colors): bool {} /** * Set the thickness for line drawing * @link https://php.net/manual/en/function.imagesetthickness.php * @param resource|GdImage $image * @param int $thickness

    * Thickness, in pixels. *

    * @return bool true on success or false on failure. */ function imagesetthickness(GdImage $image, int $thickness): bool {} /** * Draw a partial arc and fill it * @link https://php.net/manual/en/function.imagefilledarc.php * @param resource|GdImage $image * @param int $center_x

    * x-coordinate of the center. *

    * @param int $center_y

    * y-coordinate of the center. *

    * @param int $width

    * The arc width. *

    * @param int $height

    * The arc height. *

    * @param int $start_angle

    * The arc start angle, in degrees. *

    * @param int $end_angle

    * The arc end angle, in degrees. * 0° is located at the three-o'clock position, and the arc is drawn * clockwise. *

    * @param int $color

    * A color identifier created with * imagecolorallocate. *

    * @param int $style

    * A bitwise OR of the following possibilities: * IMG_ARC_PIE

    * @return bool true on success or false on failure. */ function imagefilledarc(GdImage $image, int $center_x, int $center_y, int $width, int $height, int $start_angle, int $end_angle, int $color, int $style): bool {} /** * Draw a filled ellipse * @link https://php.net/manual/en/function.imagefilledellipse.php * @param resource|GdImage $image * @param int $center_x

    * x-coordinate of the center. *

    * @param int $center_y

    * y-coordinate of the center. *

    * @param int $width

    * The ellipse width. *

    * @param int $height

    * The ellipse height. *

    * @param int $color

    * The fill color. A color identifier created with * imagecolorallocate. *

    * @return bool true on success or false on failure. */ function imagefilledellipse(GdImage $image, int $center_x, int $center_y, int $width, int $height, int $color): bool {} /** * Set the blending mode for an image * @link https://php.net/manual/en/function.imagealphablending.php * @param resource|GdImage $image * @param bool $enable

    * Whether to enable the blending mode or not. On true color images * the default value is true otherwise the default value is false *

    * @return bool true on success or false on failure. */ function imagealphablending(GdImage $image, bool $enable): bool {} /** * Set the flag to save full alpha channel information (as opposed to single-color transparency) when saving PNG images * @link https://php.net/manual/en/function.imagesavealpha.php * @param resource|GdImage $image * @param bool $enable

    * Whether to save the alpha channel or not. Default to false. *

    * @return bool true on success or false on failure. */ function imagesavealpha(GdImage $image, bool $enable): bool {} /** * Allocate a color for an image * @link https://php.net/manual/en/function.imagecolorallocatealpha.php * @param resource|GdImage $image * @param int $red

    * Value of red component. *

    * @param int $green

    * Value of green component. *

    * @param int $blue

    * Value of blue component. *

    * @param int $alpha

    * A value between 0 and 127. * 0 indicates completely opaque while * 127 indicates completely transparent. *

    * @return int|false A color identifier or false if the allocation failed. */ function imagecolorallocatealpha(GdImage $image, int $red, int $green, int $blue, int $alpha): int|false {} /** * Get the index of the specified color + alpha or its closest possible alternative * @link https://php.net/manual/en/function.imagecolorresolvealpha.php * @param resource|GdImage $image * @param int $red

    * Value of red component. *

    * @param int $green

    * Value of green component. *

    * @param int $blue

    * Value of blue component. *

    * @param int $alpha

    * A value between 0 and 127. * 0 indicates completely opaque while * 127 indicates completely transparent. *

    * @return int|false a color index or FALSE on failure */ #[Pure] function imagecolorresolvealpha(GdImage $image, int $red, int $green, int $blue, int $alpha): int {} /** * Get the index of the closest color to the specified color + alpha * @link https://php.net/manual/en/function.imagecolorclosestalpha.php * @param resource|GdImage $image * @param int $red

    * Value of red component. *

    * @param int $green

    * Value of green component. *

    * @param int $blue

    * Value of blue component. *

    * @param int $alpha

    * A value between 0 and 127. * 0 indicates completely opaque while * 127 indicates completely transparent. *

    * @return int|false the index of the closest color in the palette or * FALSE on failure */ #[Pure] function imagecolorclosestalpha(GdImage $image, int $red, int $green, int $blue, int $alpha): int {} /** * Get the index of the specified color + alpha * @link https://php.net/manual/en/function.imagecolorexactalpha.php * @param resource|GdImage $image * @param int $red

    * Value of red component. *

    * @param int $green

    * Value of green component. *

    * @param int $blue

    * Value of blue component. *

    * @param int $alpha

    * A value between 0 and 127. * 0 indicates completely opaque while * 127 indicates completely transparent. *

    * @return int|false the index of the specified color+alpha in the palette of the * image, -1 if the color does not exist in the image's palette, or FALSE * on failure */ #[Pure] #[LanguageLevelTypeAware(['8.0' => 'int'], default: 'int|false')] function imagecolorexactalpha(GdImage $image, int $red, int $green, int $blue, int $alpha) {} /** * Copy and resize part of an image with resampling * @link https://php.net/manual/en/function.imagecopyresampled.php * @param resource|GdImage $dst_image * @param resource|GdImage $src_image * @param int $dst_x

    * x-coordinate of destination point. *

    * @param int $dst_y

    * y-coordinate of destination point. *

    * @param int $src_x

    * x-coordinate of source point. *

    * @param int $src_y

    * y-coordinate of source point. *

    * @param int $dst_width

    * Destination width. *

    * @param int $dst_height

    * Destination height. *

    * @param int $src_width

    * Source width. *

    * @param int $src_height

    * Source height. *

    * @return bool true on success or false on failure. */ function imagecopyresampled(GdImage $dst_image, GdImage $src_image, int $dst_x, int $dst_y, int $src_x, int $src_y, int $dst_width, int $dst_height, int $src_width, int $src_height): bool {} /** * Rotate an image with a given angle * @link https://php.net/manual/en/function.imagerotate.php * @param resource|GdImage $image * @param float $angle

    * Rotation angle, in degrees. *

    * @param int $background_color

    * Specifies the color of the uncovered zone after the rotation *

    * @param bool $ignore_transparent [optional]

    * Prior to PHP 8.3 if set and non-zero, transparent colors are ignored (otherwise kept). *

    * @return resource|GdImage|false the rotated image or FALSE on failure */ function imagerotate( GdImage $image, float $angle, int $background_color, #[PhpStormStubsElementAvailable(to: '8.2')] bool $ignore_transparent = false ): GdImage|false {} /** * Should antialias functions be used or not.
    * Before 7.2.0 it's only available if PHP iscompiled with the bundled version of the GD library. * @link https://php.net/manual/en/function.imageantialias.php * @param resource|GdImage $image * @param bool $enable

    * Whether to enable antialiasing or not. *

    * @return bool true on success or false on failure. */ function imageantialias(GdImage $image, bool $enable): bool {} /** * Set the tile image for filling * @link https://php.net/manual/en/function.imagesettile.php * @param resource|GdImage $image * @param resource|GdImage $tile

    * The image resource to be used as a tile. *

    * @return bool true on success or false on failure. */ function imagesettile(GdImage $image, GdImage $tile): bool {} /** * Set the brush image for line drawing * @link https://php.net/manual/en/function.imagesetbrush.php * @param resource|GdImage $image * @param resource|GdImage $brush

    * An image resource. *

    * @return bool true on success or false on failure. */ function imagesetbrush(GdImage $image, GdImage $brush): bool {} /** * Set the style for line drawing * @link https://php.net/manual/en/function.imagesetstyle.php * @param resource|GdImage $image * @param int[] $style

    * An array of pixel colors. You can use the * IMG_COLOR_TRANSPARENT constant to add a * transparent pixel. *

    * @return bool true on success or false on failure. */ function imagesetstyle(GdImage $image, array $style): bool {} /** * Create a new image from file or URL * @link https://php.net/manual/en/function.imagecreatefrompng.php * @param string $filename

    * Path to the PNG image. *

    * @return resource|GdImage|false an image resource identifier on success, false on errors. */ function imagecreatefrompng(string $filename): GdImage|false {} /** * Create a new image from file or URL * @link https://www.php.net/manual/function.imagecreatefromavif.php * @param string $filename Path to the AVIF raster image. * @return GdImage|false returns an image object representing the image obtained from the given filename * @since 8.1 */ function imagecreatefromavif(string $filename): GdImage|false {} /** * Create a new image from file or URL * @link https://php.net/manual/en/function.imagecreatefromgif.php * @param string $filename

    * Path to the GIF image. *

    * @return resource|GdImage|false an image resource identifier on success, false on errors. */ function imagecreatefromgif(string $filename): GdImage|false {} /** * Create a new image from file or URL * @link https://php.net/manual/en/function.imagecreatefromjpeg.php * @param string $filename

    * Path to the JPEG image. *

    * @return resource|GdImage|false an image resource identifier on success, false on errors. */ function imagecreatefromjpeg(string $filename): GdImage|false {} /** * Create a new image from file or URL * @link https://php.net/manual/en/function.imagecreatefromwbmp.php * @param string $filename

    * Path to the WBMP image. *

    * @return resource|GdImage|false an image resource identifier on success, false on errors. */ function imagecreatefromwbmp(string $filename): GdImage|false {} /** * Create a new image from file or URL * @link https://php.net/manual/en/function.imagecreatefromwebp.php * @param string $filename

    * Path to the WebP image. *

    * @return resource|GdImage|false an image resource identifier on success, false on errors. * @since 5.4 */ function imagecreatefromwebp(string $filename): GdImage|false {} /** * Create a new image from file or URL * @link https://php.net/manual/en/function.imagecreatefromxbm.php * @param string $filename

    * Path to the XBM image. *

    * @return resource|GdImage|false an image resource identifier on success, false on errors. */ function imagecreatefromxbm(string $filename): GdImage|false {} /** * Create a new image from file or URL * @link https://php.net/manual/en/function.imagecreatefromxpm.php * @param string $filename

    * Path to the XPM image. *

    * @return resource|GdImage|false an image resource identifier on success, false on errors. */ function imagecreatefromxpm(string $filename): GdImage|false {} /** * Create a new image from GD file or URL * @link https://php.net/manual/en/function.imagecreatefromgd.php * @param string $filename

    * Path to the GD file. *

    * @return resource|GdImage|false an image resource identifier on success, false on errors. */ function imagecreatefromgd(string $filename): GdImage|false {} /** * Create a new image from GD2 file or URL * @link https://php.net/manual/en/function.imagecreatefromgd2.php * @param string $filename

    * Path to the GD2 image. *

    * @return resource|GdImage|false an image resource identifier on success, false on errors. */ function imagecreatefromgd2(string $filename): GdImage|false {} /** * Create a new image from a given part of GD2 file or URL * @link https://php.net/manual/en/function.imagecreatefromgd2part.php * @param string $filename

    * Path to the GD2 image. *

    * @param int $x

    * x-coordinate of source point. *

    * @param int $y

    * y-coordinate of source point. *

    * @param int $width

    * Source width. *

    * @param int $height

    * Source height. *

    * @return resource|GdImage|false an image resource identifier on success, false on errors. */ function imagecreatefromgd2part(string $filename, int $x, int $y, int $width, int $height): GdImage|false {} /** * Output a PNG image to either the browser or a file * @link https://php.net/manual/en/function.imagepng.php * @param resource|GdImage $image * @param string $file [optional]

    * The path to save the file to. If not set or null, the raw image stream * will be outputted directly. *

    *

    * null is invalid if the quality and * filters arguments are not used. *

    * @param int $quality [optional]

    * Compression level: from 0 (no compression) to 9. *

    * @param int $filters [optional]

    * Allows reducing the PNG file size. It is a bitmask field which may be * set to any combination of the PNG_FILTER_XXX * constants. PNG_NO_FILTER or * PNG_ALL_FILTERS may also be used to respectively * disable or activate all filters. *

    * @return bool true on success or false on failure. */ function imagepng(GdImage $image, $file = null, int $quality = -1, int $filters = -1): bool {} /** * Output a WebP image to browser or file * @link https://php.net/manual/en/function.imagewebp.php * @param resource|GdImage $image * @param resource|string|null $file [optional]

    * The path or an open stream resource (which is automatically closed after this function returns) * to save the file to. If not set or null, the raw image stream will be output directly. *

    * @param int $quality [optional]

    * quality ranges from 0 (worst quality, smaller file) to 100 (best quality, biggest file). *

    * @return bool true on success or false on failure. * @since 5.4 */ function imagewebp(GdImage $image, $file = null, int $quality = -1): bool {} /** * Output image to browser or file * @link https://php.net/manual/en/function.imagegif.php * @param resource|GdImage $image * @param string $file [optional]

    * The path to save the file to. If not set or null, the raw image stream * will be outputted directly. *

    * @return bool true on success or false on failure. */ function imagegif(GdImage $image, $file = null): bool {} /** * Output image to browser or file * @link https://php.net/manual/en/function.imagejpeg.php * @param resource|GdImage $image * @param string $file [optional]

    * The path to save the file to. If not set or null, the raw image stream * will be outputted directly. *

    *

    * To skip this argument in order to provide the * quality parameter, use null. *

    * @param int $quality [optional]

    * quality is optional, and ranges from 0 (worst * quality, smaller file) to 100 (best quality, biggest file). The * default is the default IJG quality value (about 75). *

    * @return bool true on success or false on failure. */ function imagejpeg(GdImage $image, $file = null, int $quality = -1): bool {} /** * Output image to browser or file * @link https://php.net/manual/en/function.imagewbmp.php * @param resource|GdImage $image * @param string $file [optional]

    * The path to save the file to. If not set or null, the raw image stream * will be outputted directly. *

    * @param int $foreground_color [optional]

    * You can set the foreground color with this parameter by setting an * identifier obtained from imagecolorallocate. * The default foreground color is black. *

    * @return bool true on success or false on failure. */ function imagewbmp(GdImage $image, $file = null, ?int $foreground_color = null): bool {} /** * Output GD image to browser or file.
    * Since 7.2.0 allows to output truecolor images. * @link https://php.net/manual/en/function.imagegd.php * @param resource|GdImage $image * @param string|null $file [optional]

    * The path to save the file to. If not set or null, the raw image stream * will be outputted directly. *

    * @return bool true on success or false on failure. */ function imagegd(GdImage $image, ?string $file = null): bool {} /** * Output GD2 image to browser or file * @link https://php.net/manual/en/function.imagegd2.php * @param resource|GdImage $image * @param string|null $file [optional]

    * The path to save the file to. If not set or null, the raw image stream * will be outputted directly. *

    * @param int $chunk_size [optional]

    * Chunk size. *

    * @param int $mode [optional]

    * Either IMG_GD2_RAW or * IMG_GD2_COMPRESSED. Default is * IMG_GD2_RAW. *

    * @return bool true on success or false on failure. */ function imagegd2(GdImage $image, ?string $file = null, int $chunk_size = 128, int $mode = IMG_GD2_RAW): bool {} /** * Destroy an image * @link https://php.net/manual/en/function.imagedestroy.php * @param resource|GdImage $image * @return bool true on success or false on failure. */ function imagedestroy(GdImage $image): bool {} /** * Apply a gamma correction to a GD image * @link https://php.net/manual/en/function.imagegammacorrect.php * @param resource|GdImage $image * @param float $input_gamma

    * The input gamma. *

    * @param float $output_gamma

    * The output gamma. *

    * @return bool true on success or false on failure. */ function imagegammacorrect(GdImage $image, float $input_gamma, float $output_gamma): bool {} /** * Flood fill * @link https://php.net/manual/en/function.imagefill.php * @param resource|GdImage $image * @param int $x

    * x-coordinate of start point. *

    * @param int $y

    * y-coordinate of start point. *

    * @param int $color

    * The fill color. A color identifier created with * imagecolorallocate. *

    * @return bool true on success or false on failure. */ function imagefill(GdImage $image, int $x, int $y, int $color): bool {} /** * Draw a filled polygon * @link https://php.net/manual/en/function.imagefilledpolygon.php * @param resource|GdImage $image * @param int[] $points

    * An array containing the x and y * coordinates of the polygons vertices consecutively. *

    * @param int $num_points_or_color

    * Total number of vertices, which must be at least 3. *

    * @param int|null $color

    * A color identifier created with * imagecolorallocate. *

    * @return bool true on success or false on failure. */ function imagefilledpolygon( GdImage $image, array $points, #[Deprecated(since: "8.1")] int $num_points_or_color, ?int $color ): bool {} /** * Draw a filled polygon * @link https://php.net/manual/en/function.imagefilledpolygon.php * @param GdImage $image * @param int[] $points

    * An array containing the x and y * coordinates of the polygons vertices consecutively. *

    * @param int|null $color

    * A color identifier created with * imagecolorallocate. *

    * @return bool true on success or false on failure. */ #[PhpStormStubsElementAvailable(from: '8.0')] function imagefilledpolygon( GdImage $image, array $points, ?int $color ): bool {} /** * Draw a filled rectangle * @link https://php.net/manual/en/function.imagefilledrectangle.php * @param resource|GdImage $image * @param int $x1

    * x-coordinate for point 1. *

    * @param int $y1

    * y-coordinate for point 1. *

    * @param int $x2

    * x-coordinate for point 2. *

    * @param int $y2

    * y-coordinate for point 2. *

    * @param int $color

    * The fill color. A color identifier created with * imagecolorallocate. *

    * @return bool true on success or false on failure. */ function imagefilledrectangle(GdImage $image, int $x1, int $y1, int $x2, int $y2, int $color): bool {} /** * Flood fill to specific color * @link https://php.net/manual/en/function.imagefilltoborder.php * @param resource|GdImage $image * @param int $x

    * x-coordinate of start. *

    * @param int $y

    * y-coordinate of start. *

    * @param int $border_color

    * The border color. A color identifier created with * imagecolorallocate. *

    * @param int $color

    * The fill color. A color identifier created with * imagecolorallocate. *

    * @return bool true on success or false on failure. */ function imagefilltoborder(GdImage $image, int $x, int $y, int $border_color, int $color): bool {} /** * Get font width * @link https://php.net/manual/en/function.imagefontwidth.php * @param int $font * @return int the width of the pixel */ #[Pure] function imagefontwidth(#[LanguageLevelTypeAware(['8.1' => 'GdFont|int'], default: 'int')] $font): int {} /** * Get font height * @link https://php.net/manual/en/function.imagefontheight.php * @param int $font * @return int the height of the pixel. */ #[Pure] function imagefontheight(#[LanguageLevelTypeAware(['8.1' => 'GdFont|int'], default: 'int')] $font): int {} /** * Enable or disable interlace * @link https://php.net/manual/en/function.imageinterlace.php * @param resource|GdImage $image * @param bool|null $enable [optional]

    * If non-zero, the image will be interlaced, else the interlace bit is * turned off. *

    * @return bool 1 if the interlace bit is set for the image, * 0 if it is not */ function imageinterlace(GdImage $image, ?bool $enable = null): bool {} /** * Draw a line * @link https://php.net/manual/en/function.imageline.php * @param resource|GdImage $image * @param int $x1

    * x-coordinate for first point. *

    * @param int $y1

    * y-coordinate for first point. *

    * @param int $x2

    * x-coordinate for second point. *

    * @param int $y2

    * y-coordinate for second point. *

    * @param int $color

    * The line color. A color identifier created with * imagecolorallocate. *

    * @return bool true on success or false on failure. */ function imageline(GdImage $image, int $x1, int $y1, int $x2, int $y2, int $color): bool {} /** * Load a new font * @link https://php.net/manual/en/function.imageloadfont.php * @param string $filename

    * The font file format is currently binary and architecture * dependent. This means you should generate the font files on the * same type of CPU as the machine you are running PHP on. *

    *

    *

    * Font file format * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    byte positionC data typedescription
    byte 0-3intnumber of characters in the font
    byte 4-7int * value of first character in the font (often 32 for space) *
    byte 8-11intpixel width of each character
    byte 12-15intpixel height of each character
    byte 16-char * array with character data, one byte per pixel in each * character, for a total of (nchars*width*height) bytes. *
    *

    * @return int|false The font identifier which is always bigger than 5 to avoid conflicts with * built-in fonts or false on errors. */ #[LanguageLevelTypeAware(['8.1' => 'GdFont|false'], default: 'int|false')] function imageloadfont(string $filename) {} /** * Draws a polygon * @link https://php.net/manual/en/function.imagepolygon.php * @param resource|GdImage $image * @param int[] $points

    * An array containing the polygon's vertices, e.g.: * * points[0] * = x0 * * * points[1] * = y0 * * * points[2] * = x1 * * * points[3] * = y1 * *

    * @param int $num_points_or_color

    * Total number of points (vertices). *

    * @param int|null $color

    * A color identifier created with * imagecolorallocate. *

    * @return bool true on success or false on failure. */ function imagepolygon( GdImage $image, array $points, int $num_points_or_color, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] ?int $color, #[PhpStormStubsElementAvailable(from: '8.0')] ?int $color = null ): bool {} /** * Draw a rectangle * @link https://php.net/manual/en/function.imagerectangle.php * @param resource|GdImage $image * @param int $x1

    * Upper left x coordinate. *

    * @param int $y1

    * Upper left y coordinate * 0, 0 is the top left corner of the image. *

    * @param int $x2

    * Bottom right x coordinate. *

    * @param int $y2

    * Bottom right y coordinate. *

    * @param int $color

    * A color identifier created with * imagecolorallocate. *

    * @return bool true on success or false on failure. */ function imagerectangle(GdImage $image, int $x1, int $y1, int $x2, int $y2, int $color): bool {} /** * Set a single pixel * @link https://php.net/manual/en/function.imagesetpixel.php * @param resource|GdImage $image * @param int $x

    * x-coordinate. *

    * @param int $y

    * y-coordinate. *

    * @param int $color

    * A color identifier created with * imagecolorallocate. *

    * @return bool true on success or false on failure. */ function imagesetpixel(GdImage $image, int $x, int $y, int $color): bool {} /** * Draw a string horizontally * @link https://php.net/manual/en/function.imagestring.php * @param resource|GdImage $image * @param int $font

    * Can be 1, 2, 3, 4, 5 for built-in fonts in latin2 encoding (where higher numbers corresponding to larger fonts) or (since 8.1) GdFont instance *

    * @param int $x

    * x-coordinate of the upper left corner. *

    * @param int $y

    * y-coordinate of the upper left corner. *

    * @param string $string

    * The string to be written. *

    * @param int $color

    * A color identifier created with * imagecolorallocate. *

    * @return bool true on success or false on failure. */ function imagestring( GdImage $image, #[LanguageLevelTypeAware(['8.1' => 'GdFont|int'], default: 'int')] $font, int $x, int $y, string $string, int $color ): bool {} /** * Draw a string vertically * @link https://php.net/manual/en/function.imagestringup.php * @param resource|GdImage $image * @param int $font * @param int $x

    * x-coordinate of the upper left corner. *

    * @param int $y

    * y-coordinate of the upper left corner. *

    * @param string $string

    * The string to be written. *

    * @param int $color

    * A color identifier created with * imagecolorallocate. *

    * @return bool true on success or false on failure. */ function imagestringup( GdImage $image, #[LanguageLevelTypeAware(['8.1' => 'GdFont|int'], default: 'int')] $font, int $x, int $y, string $string, int $color ): bool {} /** * Get image width * @link https://php.net/manual/en/function.imagesx.php * @param resource|GdImage $image * @return int|false Return the width of the image or false on * errors. */ #[Pure] function imagesx(GdImage $image): int {} /** * Get image height * @link https://php.net/manual/en/function.imagesy.php * @param resource|GdImage $image * @return int|false Return the height of the image or false on * errors. */ #[Pure] function imagesy(GdImage $image): int {} /** * Draw a dashed line * @link https://php.net/manual/en/function.imagedashedline.php * @param resource|GdImage $image * @param int $x1

    * Upper left x coordinate. *

    * @param int $y1

    * Upper left y coordinate 0, 0 is the top left corner of the image. *

    * @param int $x2

    * Bottom right x coordinate. *

    * @param int $y2

    * Bottom right y coordinate. *

    * @param int $color

    * The fill color. A color identifier created with * imagecolorallocate. *

    * @return bool TRUE on success or FALSE on failure. */ function imagedashedline(GdImage $image, int $x1, int $y1, int $x2, int $y2, int $color): bool {} /** * Give the bounding box of a text using TrueType fonts * @link https://php.net/manual/en/function.imagettfbbox.php * @param float $size

    * The font size. Depending on your version of GD, this should be * specified as the pixel size (GD1) or point size (GD2). *

    * @param float $angle

    * Angle in degrees in which text will be measured. *

    * @param string $font_filename

    * The name of the TrueType font file (can be a URL). Depending on * which version of the GD library that PHP is using, it may attempt to * search for files that do not begin with a leading '/' by appending * '.ttf' to the filename and searching along a library-defined font path. *

    * @param string $string

    * The string to be measured. *

    * @param array $options [optional] * @return array|false imagettfbbox returns an array with 8 * elements representing four points making the bounding box of the * text on success and false on error. * * key * contents * * * 0 * lower left corner, X position * * * 1 * lower left corner, Y position * * * 2 * lower right corner, X position * * * 3 * lower right corner, Y position * * * 4 * upper right corner, X position * * * 5 * upper right corner, Y position * * * 6 * upper left corner, X position * * * 7 * upper left corner, Y position * *

    *

    * The points are relative to the text regardless of the * angle, so "upper left" means in the top left-hand * corner seeing the text horizontally. */ #[Pure] function imagettfbbox(float $size, float $angle, string $font_filename, string $string, #[PhpStormStubsElementAvailable(from: '8.0')] array $options = []): array|false {} /** * Write text to the image using TrueType fonts * @link https://php.net/manual/en/function.imagettftext.php * @param resource|GdImage $image * @param float $size

    * The font size. Depending on your version of GD, this should be * specified as the pixel size (GD1) or point size (GD2). *

    * @param float $angle

    * The angle in degrees, with 0 degrees being left-to-right reading text. * Higher values represent a counter-clockwise rotation. For example, a * value of 90 would result in bottom-to-top reading text. *

    * @param int $x

    * The coordinates given by x and * y will define the basepoint of the first * character (roughly the lower-left corner of the character). This * is different from the imagestring, where * x and y define the * upper-left corner of the first character. For example, "top left" * is 0, 0. *

    * @param int $y

    * The y-ordinate. This sets the position of the fonts baseline, not the * very bottom of the character. *

    * @param int $color

    * The color index. Using the negative of a color index has the effect of * turning off antialiasing. See imagecolorallocate. *

    * @param string $font_filename

    * The path to the TrueType font you wish to use. *

    *

    * Depending on which version of the GD library PHP is using, when * font_filename does not begin with a leading * / then .ttf will be appended * to the filename and the library will attempt to search for that * filename along a library-defined font path. *

    *

    * When using versions of the GD library lower than 2.0.18, a space character, * rather than a semicolon, was used as the 'path separator' for different font files. * Unintentional use of this feature will result in the warning message: * Warning: Could not find/open font. For these affected versions, the * only solution is moving the font to a path which does not contain spaces. *

    *

    * In many cases where a font resides in the same directory as the script using it * the following trick will alleviate any include problems. *

    *
     * 
     * 
    *

    * Note: * open_basedir does not apply to font_filename. *

    * @param string $text

    * The text string in UTF-8 encoding. *

    *

    * May include decimal numeric character references (of the form: * &#8364;) to access characters in a font beyond position 127. * The hexadecimal format (like &#xA9;) is supported. * Strings in UTF-8 encoding can be passed directly. *

    *

    * Named entities, such as &copy;, are not supported. Consider using * html_entity_decode * to decode these named entities into UTF-8 strings (html_entity_decode() * supports this as of PHP 5.0.0). *

    *

    * If a character is used in the string which is not supported by the * font, a hollow rectangle will replace the character. *

    * @param array $options [optional] * @return array|false an array with 8 elements representing four points making the * bounding box of the text. The order of the points is lower left, lower * right, upper right, upper left. The points are relative to the text * regardless of the angle, so "upper left" means in the top left-hand * corner when you see the text horizontally. * Returns false on error. */ function imagettftext(GdImage $image, float $size, float $angle, int $x, int $y, int $color, string $font_filename, string $text, #[PhpStormStubsElementAvailable(from: '8.0')] array $options = []): array|false {} /** * Give the bounding box of a text using fonts via freetype2 * @link https://php.net/manual/en/function.imageftbbox.php * @param float $size

    * The font size. Depending on your version of GD, this should be * specified as the pixel size (GD1) or point size (GD2). *

    * @param float $angle

    * Angle in degrees in which text will be * measured. *

    * @param string $font_filename

    * The name of the TrueType font file (can be a URL). Depending on * which version of the GD library that PHP is using, it may attempt to * search for files that do not begin with a leading '/' by appending * '.ttf' to the filename and searching along a library-defined font path. *

    * @param string $string

    * The string to be measured. *

    * @param array $options [optional]

    *

    * Possible array indexes for extrainfo * * * * * * * * * * *
    KeyTypeMeaning
    linespacingfloatDefines drawing linespacing
    *

    * @return array|false imageftbbox returns an array with 8 * elements representing four points making the bounding box of the * text: * * 0 * lower left corner, X position * * * 1 * lower left corner, Y position * * * 2 * lower right corner, X position * * * 3 * lower right corner, Y position * * * 4 * upper right corner, X position * * * 5 * upper right corner, Y position * * * 6 * upper left corner, X position * * * 7 * upper left corner, Y position * *

    *

    * The points are relative to the text regardless of the * angle, so "upper left" means in the top left-hand * corner seeing the text horizontally. * Returns false on error. */ #[Pure] function imageftbbox(float $size, float $angle, string $font_filename, string $string, array $options = []): array|false {} /** * Write text to the image using fonts using FreeType 2 * @link https://php.net/manual/en/function.imagefttext.php * @param resource|GdImage $image * @param float $size

    * The font size to use in points. *

    * @param float $angle

    * The angle in degrees, with 0 degrees being left-to-right reading text. * Higher values represent a counter-clockwise rotation. For example, a * value of 90 would result in bottom-to-top reading text. *

    * @param int $x

    * The coordinates given by x and * y will define the basepoint of the first * character (roughly the lower-left corner of the character). This * is different from the imagestring, where * x and y define the * upper-left corner of the first character. For example, "top left" * is 0, 0. *

    * @param int $y

    * The y-ordinate. This sets the position of the fonts baseline, not the * very bottom of the character. *

    * @param int $color

    * The index of the desired color for the text, see * imagecolorexact. *

    * @param string $font_filename

    * The path to the TrueType font you wish to use. *

    *

    * Depending on which version of the GD library PHP is using, when * font_filename does not begin with a leading * / then .ttf will be appended * to the filename and the library will attempt to search for that * filename along a library-defined font path. *

    *

    * When using versions of the GD library lower than 2.0.18, a space character, * rather than a semicolon, was used as the 'path separator' for different font files. * Unintentional use of this feature will result in the warning message: * Warning: Could not find/open font. For these affected versions, the * only solution is moving the font to a path which does not contain spaces. *

    *

    * In many cases where a font resides in the same directory as the script using it * the following trick will alleviate any include problems. *

    *
     * 
     * 
    *

    * Note: * open_basedir does not apply to font_filename. *

    * @param string $text

    * Text to be inserted into image. *

    * @param array $options [optional]

    *

    * Possible array indexes for extrainfo * * * * * * * * * * *
    KeyTypeMeaning
    linespacingfloatDefines drawing linespacing
    *

    * @return array|false This function returns an array defining the four points of the box, starting in the lower left and moving counter-clockwise: * * 0 * lower left x-coordinate * * * 1 * lower left y-coordinate * * * 2 * lower right x-coordinate * * * 3 * lower right y-coordinate * * * 4 * upper right x-coordinate * * * 5 * upper right y-coordinate * * * 6 * upper left x-coordinate * * * 7 * upper left y-coordinate * * Returns false on error. */ function imagefttext(GdImage $image, float $size, float $angle, int $x, int $y, int $color, string $font_filename, string $text, array $options = []): array|false {} /** * Load a PostScript Type 1 font from file * @link https://php.net/manual/en/function.imagepsloadfont.php * @param string $filename

    * Path to the Postscript font file. *

    * @return resource|GdImage|false In the case everything went right, a valid font index will be returned and * can be used for further purposes. Otherwise the function returns false. * @removed 7.0 This function was REMOVED in PHP 7.0.0. */ function imagepsloadfont($filename) {} /** * Free memory used by a PostScript Type 1 font * @link https://php.net/manual/en/function.imagepsfreefont.php * @param resource|GdImage $font_index

    * A font resource, returned by imagepsloadfont. *

    * @return bool true on success or false on failure. * @removed 7.0 */ function imagepsfreefont($font_index) {} /** * Change the character encoding vector of a font * @link https://php.net/manual/en/function.imagepsencodefont.php * @param resource|GdImage $font_index

    * A font resource, returned by imagepsloadfont. *

    * @param string $encodingfile

    * The exact format of this file is described in T1libs documentation. * T1lib comes with two ready-to-use files, * IsoLatin1.enc and * IsoLatin2.enc. *

    * @return bool true on success or false on failure. * @removed 7.0 */ function imagepsencodefont($font_index, $encodingfile) {} /** * Extend or condense a font * @link https://php.net/manual/en/function.imagepsextendfont.php * @param resource|GdImage $font_index

    * A font resource, returned by imagepsloadfont. *

    * @param float $extend

    * Extension value, must be greater than 0. *

    * @return bool true on success or false on failure. * @removed 7.0 */ function imagepsextendfont($font_index, $extend) {} /** * Slant a font * @link https://php.net/manual/en/function.imagepsslantfont.php * @param resource|GdImage $font_index

    * A font resource, returned by imagepsloadfont. *

    * @param float $slant

    * Slant level. *

    * @return bool true on success or false on failure. * @removed 7.0 This function was REMOVED in PHP 7.0.0. */ function imagepsslantfont($font_index, $slant) {} /** * Draws a text over an image using PostScript Type1 fonts * @link https://php.net/manual/en/function.imagepstext.php * @param resource|GdImage $image * @param string $text

    * The text to be written. *

    * @param resource|GdImage $font_index

    * A font resource, returned by imagepsloadfont. *

    * @param int $size

    * size is expressed in pixels. *

    * @param int $foreground

    * The color in which the text will be painted. *

    * @param int $background

    * The color to which the text will try to fade in with antialiasing. * No pixels with the color background are * actually painted, so the background image does not need to be of solid * color. *

    * @param int $x

    * x-coordinate for the lower-left corner of the first character. *

    * @param int $y

    * y-coordinate for the lower-left corner of the first character. *

    * @param int $space [optional]

    * Allows you to change the default value of a space in a font. This * amount is added to the normal value and can also be negative. * Expressed in character space units, where 1 unit is 1/1000th of an * em-square. *

    * @param int $tightness [optional]

    * tightness allows you to control the amount * of white space between characters. This amount is added to the * normal character width and can also be negative. * Expressed in character space units, where 1 unit is 1/1000th of an * em-square. *

    * @param float $angle [optional]

    * angle is in degrees. *

    * @param int $antialias_steps [optional]

    * Allows you to control the number of colours used for antialiasing * text. Allowed values are 4 and 16. The higher value is recommended * for text sizes lower than 20, where the effect in text quality is * quite visible. With bigger sizes, use 4. It's less computationally * intensive. *

    * @return array|false This function returns an array containing the following elements: * * 0 * lower left x-coordinate * * * 1 * lower left y-coordinate * * * 2 * upper right x-coordinate * * * 3 * upper right y-coordinate * * Returns false on error. * @removed 7.0 This function was REMOVED in PHP 7.0.0. */ function imagepstext($image, $text, $font_index, $size, $foreground, $background, $x, $y, $space = null, $tightness = null, $angle = null, $antialias_steps = null) {} /** * Give the bounding box of a text rectangle using PostScript Type1 fonts * @link https://php.net/manual/en/function.imagepsbbox.php * @param string $text

    * The text to be written. *

    * @param resource|GdImage $font * @param int $size

    * size is expressed in pixels. *

    * @return array|false an array containing the following elements: * * 0 * left x-coordinate * * * 1 * upper y-coordinate * * * 2 * right x-coordinate * * * 3 * lower y-coordinate * * Returns false on error. * @removed 7.0 */ function imagepsbbox($text, $font, $size) {} /** * Return the image types supported by this PHP build * @link https://php.net/manual/en/function.imagetypes.php * @return int a bit-field corresponding to the image formats supported by the * version of GD linked into PHP. The following bits are returned, * IMG_BMP | IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP | IMG_XPM | IMG_WEBP */ #[Pure] function imagetypes(): int {} /** * Convert JPEG image file to WBMP image file * @link https://php.net/manual/en/function.jpeg2wbmp.php * @param string $jpegname

    * Path to JPEG file. *

    * @param string $wbmpname

    * Path to destination WBMP file. *

    * @param int $dest_height

    * Destination image height. *

    * @param int $dest_width

    * Destination image width. *

    * @param int $threshold

    * Threshold value, between 0 and 8 (inclusive). *

    * @return bool true on success or false on failure. * @removed 8.0 * @see imagecreatefromjpeg() */ #[Deprecated(reason: "Use imagecreatefromjpeg() and imagewbmp() instead", since: "7.2")] function jpeg2wbmp($jpegname, $wbmpname, $dest_height, $dest_width, $threshold) {} /** * Convert PNG image file to WBMP image file * @link https://php.net/manual/en/function.png2wbmp.php * @param string $pngname

    * Path to PNG file. *

    * @param string $wbmpname

    * Path to destination WBMP file. *

    * @param int $dest_height

    * Destination image height. *

    * @param int $dest_width

    * Destination image width. *

    * @param int $threshold

    * Threshold value, between 0 and 8 (inclusive). *

    * @return bool true on success or false on failure. * @removed 8.0 * @see imagecreatefrompng() * @see imagewbmp() */ #[Deprecated("Use imagecreatefrompng() and imagewbmp() instead", since: "7.2")] function png2wbmp($pngname, $wbmpname, $dest_height, $dest_width, $threshold) {} /** * Output image to browser or file * @link https://php.net/manual/en/function.image2wbmp.php * @param resource|GdImage $image * @param string $filename [optional]

    * Path to the saved file. If not given, the raw image stream will be * outputted directly. *

    * @param int $threshold [optional]

    * Threshold value, between 0 and 255 (inclusive). *

    * @return bool true on success or false on failure. * @removed 8.0 * @see imagewbmp() */ #[Deprecated(replacement: "imagewbmp(%parametersList%)", since: "7.3")] function image2wbmp($image, $filename = null, $threshold = null) {} /** * Set the alpha blending flag to use the bundled libgd layering effects * @link https://php.net/manual/en/function.imagelayereffect.php * @param resource|GdImage $image * @param int $effect

    * One of the following constants: * IMG_EFFECT_REPLACE * Use pixel replacement (equivalent of passing true to * imagealphablending)

    * @return bool true on success or false on failure. */ function imagelayereffect(GdImage $image, int $effect): bool {} /** * Makes the colors of the palette version of an image more closely match the true color version * @link https://php.net/manual/en/function.imagecolormatch.php * @param resource|GdImage $image1

    * A truecolor image link resource. *

    * @param resource|GdImage $image2

    * A palette image link resource pointing to an image that has the same * size as image1. *

    * @return bool true on success or false on failure. */ function imagecolormatch(GdImage $image1, GdImage $image2): bool {} /** * Output XBM image to browser or file * @link https://php.net/manual/en/function.imagexbm.php * @param resource|GdImage $image * @param string|null $filename

    * The path to save the file to. If not set or null, the raw image stream * will be outputted directly. *

    * @param int|null $foreground_color [optional]

    * You can set the foreground color with this parameter by setting an * identifier obtained from imagecolorallocate. * The default foreground color is black. *

    * @return bool true on success or false on failure. */ function imagexbm(GdImage $image, ?string $filename, ?int $foreground_color = null): bool {} /** * Applies a filter to an image * @link https://php.net/manual/en/function.imagefilter.php * @param resource|GdImage $image * @param int $filter

    * filtertype can be one of the following: * IMG_FILTER_NEGATE: Reverses all colors of * the image.

    * @param int ...$args * @return bool true on success or false on failure. */ function imagefilter( GdImage $image, int $filter, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $arg1 = null, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $arg2 = null, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $arg3 = null, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $arg4 = null, #[PhpStormStubsElementAvailable(from: '8.0')] ...$args ): bool {} /** * Apply a 3x3 convolution matrix, using coefficient and offset * @link https://php.net/manual/en/function.imageconvolution.php * @param resource|GdImage $image * @param array $matrix

    * A 3x3 matrix: an array of three arrays of three floats. *

    * @param float $divisor

    * The divisor of the result of the convolution, used for normalization. *

    * @param float $offset

    * Color offset. *

    * @return bool true on success or false on failure. */ function imageconvolution(GdImage $image, array $matrix, float $divisor, float $offset): bool {} /** * @param resource|GdImage $image An image resource, returned by one of the image creation functions, such as {@see imagecreatetruecolor()}. * @param int|null $resolution_x The horizontal resolution in DPI. * @param int|null $resolution_y The vertical resolution in DPI. * @return array|bool When used as getter (that is without the optional parameters), it returns TRUE on success, or FALSE on failure. When used as setter (that is with one or both optional parameters given), it returns an indexed array of the horizontal and vertical resolution on success, or FALSE on failure. * @link https://php.net/manual/en/function.imageresolution.php * @since 7.2 */ #[LanguageLevelTypeAware(['8.2' => 'array|true'], default: 'array|bool')] function imageresolution(GdImage $image, ?int $resolution_x = null, ?int $resolution_y = null): array|bool {} /** * imagesetclip() sets the current clipping rectangle, i.e. the area beyond which no pixels will be drawn. * @param resource|GdImage $image An image resource, returned by one of the image creation functions, such as {@see imagecreatetruecolor()}. * @param int $x1 The x-coordinate of the upper left corner. * @param int $y1 The y-coordinate of the upper left corner. * @param int $x2 The x-coordinate of the lower right corner. * @param int $y2 The y-coordinate of the lower right corner. * @return bool Returns TRUE on success or FALSE on failure. * @link https://php.net/manual/en/function.imagesetclip.php * @see imagegetclip() * @since 7.2 */ function imagesetclip(GdImage $image, int $x1, int $y1, int $x2, int $y2): bool {} /** * imagegetclip() retrieves the current clipping rectangle, i.e. the area beyond which no pixels will be drawn. * @param resource|GdImage $image An image resource, returned by one of the image creation functions, such as {@see imagecreatetruecolor()} * @return array|false an indexed array with the coordinates of the clipping rectangle which has the following entries: *
      *
    • x-coordinate of the upper left corner
    • *
    • y-coordinate of the upper left corner
    • *
    • x-coordinate of the lower right corner
    • *
    • y-coordinate of the lower right corner
    • *
    * Returns FALSE on error. * @link https://php.net/manual/en/function.imagegetclip.php * @see imagesetclip() * @since 7.2 */ function imagegetclip(GdImage $image): array {} /** * imageopenpolygon() draws an open polygon on the given image. Contrary to {@see imagepolygon()}, no line is drawn between the last and the first point. * @param resource|GdImage $image An image resource, returned by one of the image creation functions, such as {@see imagecreatetruecolor()}. * @param int[] $points An array containing the polygon's vertices, e.g.: *
     * points[0]	= x0
     * points[1]	= y0
     * points[2]	= x1
     * points[3]	= y1
     * 
    * @param int $num_points_or_color Total number of points (vertices). * @param int|null $color A color identifier created with {@see imagecolorallocate()}. * @return bool Returns TRUE on success or FALSE on failure. * @link https://php.net/manual/en/function.imageopenpolygon.php * @since 7.2 * @see imageplygon() */ function imageopenpolygon( GdImage $image, array $points, #[Deprecated(since: "8.1")] int $num_points_or_color, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] ?int $color, #[PhpStormStubsElementAvailable(from: '8.0')] ?int $color = null ): bool {} /** * imagecreatefrombmp() returns an image identifier representing the image obtained from the given filename. * TIP A URL can be used as a filename with this function if the fopen wrappers have been enabled. See {@see fopen()} for more details on how to specify the filename. See the Supported Protocols and Wrappers for links to information about what abilities the various wrappers have, notes on their usage, and information on any predefined variables they may provide. * @param string $filename Path to the BMP image. * @return resource|GdImage|false Returns an image resource identifier on success, FALSE on errors. * @link https://php.net/manual/en/function.imagecreatefrombmp.php * @since 7.2 */ function imagecreatefrombmp(string $filename): GdImage|false {} /** * Outputs or saves a BMP version of the given image. * @param resource|GdImage $image An image resource, returned by one of the image creation functions, such as {@see imagecreatetruecolor()}. * @param mixed $file The path or an open stream resource (which is automatically being closed after this function returns) to save the file to. If not set or NULL, the raw image stream will be outputted directly. *
    * Note: NULL is invalid if the compressed arguments is not used. * @param bool $compressed Whether the BMP should be compressed with run-length encoding (RLE), or not. * @return bool Returns TRUE on success or FALSE on failure. *
    * Caution However, if libgd fails to output the image, this function returns TRUE. * @link https://php.net/manual/en/function.imagebmp.php * @since 7.2 */ function imagebmp(GdImage $image, $file = null, bool $compressed = true): bool {} /** * @param string $filename * @return resource|GdImage|false */ function imagecreatefromtga(string $filename): GdImage|false {} /** * Captures the whole screen * * https://www.php.net/manual/en/function.imagegrabscreen.php * * @return resource|GdImage|false */ #[Pure] function imagegrabscreen() {} /** * Captures a window * * @link https://www.php.net/manual/en/function.imagegrabwindow.php * * @param int $handle * @param int|null $client_area * @return resource|GdImage|false */ #[Pure] function imagegrabwindow($handle, $client_area = null) {} /** * Gets the currently set interpolation method of the image. * * @link https://www.php.net/manual/en/function.imagegetinterpolation.php * * @param GdImage $image * @return int */ #[Pure] function imagegetinterpolation(GdImage $image): int {} /** * Used as a return value by {@see imagetypes()} * @link https://php.net/manual/en/image.constants.php#constant.img-gif */ define('IMG_GIF', 1); /** * Used as a return value by {@see imagetypes()} * @link https://php.net/manual/en/image.constants.php#constant.img-jpg */ define('IMG_JPG', 2); /** * Used as a return value by {@see imagetypes()} *

    * This constant has the same value as {@see IMG_JPG} *

    * @link https://php.net/manual/en/image.constants.php#constant.img-jpeg */ define('IMG_JPEG', 2); /** * Used as a return value by {@see imagetypes()} * @link https://php.net/manual/en/image.constants.php#constant.img-png */ define('IMG_PNG', 4); /** * Used as a return value by {@see imagetypes()} * @link https://php.net/manual/en/image.constants.php#constant.img-wbmp */ define('IMG_WBMP', 8); /** * Used as a return value by {@see imagetypes()} * @link https://php.net/manual/en/image.constants.php#constant.img-xpm */ define('IMG_XPM', 16); /** * Used as a return value by {@see imagetypes()} * @since 5.6.25 * @since 7.0.10 * @link https://php.net/manual/en/image.constants.php#constant.img-webp */ define('IMG_WEBP', 32); /** * Used as a return value by {@see imagetypes()} * @since 7.2 * @link https://php.net/manual/en/image.constants.php#constant.img-bmp */ define('IMG_BMP', 64); /** * Special color option which can be used instead of color allocated with * {@see imagecolorallocate()} or {@see imagecolorallocatealpha()} * @link https://php.net/manual/en/image.constants.php#constant.img-color-tiled */ define('IMG_COLOR_TILED', -5); /** * Special color option which can be used instead of color allocated with * {@see imagecolorallocate()} or {@see imagecolorallocatealpha()} * @link https://php.net/manual/en/image.constants.php#constant.img-color-styled */ define('IMG_COLOR_STYLED', -2); /** * Special color option which can be used instead of color allocated with * {@see imagecolorallocate()} or {@see imagecolorallocatealpha()} * @link https://php.net/manual/en/image.constants.php#constant.img-color-brushed */ define('IMG_COLOR_BRUSHED', -3); /** * Special color option which can be used instead of color allocated with * {@see imagecolorallocate()} or {@see imagecolorallocatealpha()} * @link https://php.net/manual/en/image.constants.php#constant.img-color-styledbrushed */ define('IMG_COLOR_STYLEDBRUSHED', -4); /** * Special color option which can be used instead of color allocated with * {@see imagecolorallocate()} or {@see imagecolorallocatealpha()} * @link https://php.net/manual/en/image.constants.php#constant.img-color-transparent */ define('IMG_COLOR_TRANSPARENT', -6); /** * A style constant used by the {@see imagefilledarc()} function. *

    * This constant has the same value as {@see IMG_ARC_PIE} *

    * @link https://php.net/manual/en/image.constants.php#constant.img-arc-rounded */ define('IMG_ARC_ROUNDED', 0); /** * A style constant used by the {@see imagefilledarc()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-arc-pie */ define('IMG_ARC_PIE', 0); /** * A style constant used by the {@see imagefilledarc()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-arc-chord */ define('IMG_ARC_CHORD', 1); /** * A style constant used by the {@see imagefilledarc()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-arc-nofill */ define('IMG_ARC_NOFILL', 2); /** * A style constant used by the {@see imagefilledarc()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-arc-edged */ define('IMG_ARC_EDGED', 4); /** * A type constant used by the {@see imagegd2()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-gd2-raw */ define('IMG_GD2_RAW', 1); /** * A type constant used by the {@see imagegd2()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-gd2-compressed */ define('IMG_GD2_COMPRESSED', 2); /** * Alpha blending effect used by the {@see imagelayereffect()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-effect-replace */ define('IMG_EFFECT_REPLACE', 0); /** * Alpha blending effect used by the {@see imagelayereffect()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-effect-alphablend */ define('IMG_EFFECT_ALPHABLEND', 1); /** * Alpha blending effect used by the {@see imagelayereffect()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-effect-normal */ define('IMG_EFFECT_NORMAL', 2); /** * Alpha blending effect used by the {@see imagelayereffect()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-effect-overlay */ define('IMG_EFFECT_OVERLAY', 3); /** * Alpha blending effect used by the {@see imagelayereffect()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-effect-multiply * @since 7.2 */ define('IMG_EFFECT_MULTIPLY', 4); /** * When the bundled version of GD is used this is 1 otherwise * it's set to 0. * @link https://php.net/manual/en/image.constants.php */ define('GD_BUNDLED', 1); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-negate */ define('IMG_FILTER_NEGATE', 0); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-grayscale */ define('IMG_FILTER_GRAYSCALE', 1); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-brightness */ define('IMG_FILTER_BRIGHTNESS', 2); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-contrast */ define('IMG_FILTER_CONTRAST', 3); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-colorize */ define('IMG_FILTER_COLORIZE', 4); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-edgedetect */ define('IMG_FILTER_EDGEDETECT', 5); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-gaussian-blur */ define('IMG_FILTER_GAUSSIAN_BLUR', 7); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-selective-blur */ define('IMG_FILTER_SELECTIVE_BLUR', 8); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-emboss */ define('IMG_FILTER_EMBOSS', 6); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-mean-removal */ define('IMG_FILTER_MEAN_REMOVAL', 9); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-smooth */ define('IMG_FILTER_SMOOTH', 10); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-pixelate */ define('IMG_FILTER_PIXELATE', 11); /** * Special GD filter used by the {@see imagefilter()} function. * @link https://php.net/manual/en/image.constants.php#constant.img-filter-scatter * @since 7.4 */ define('IMG_FILTER_SCATTER', 12); /** * The GD version PHP was compiled against. * @since 5.2.4 * @link https://php.net/manual/en/image.constants.php#constant.gd-version */ define('GD_VERSION', "2.0.35"); /** * The GD major version PHP was compiled against. * @since 5.2.4 * @link https://php.net/manual/en/image.constants.php#constant.gd-major-version */ define('GD_MAJOR_VERSION', 2); /** * The GD minor version PHP was compiled against. * @since 5.2.4 * @link https://php.net/manual/en/image.constants.php#constant.gd-minor-version */ define('GD_MINOR_VERSION', 0); /** * The GD release version PHP was compiled against. * @since 5.2.4 * @link https://php.net/manual/en/image.constants.php#constant.gd-release-version */ define('GD_RELEASE_VERSION', 35); /** * The GD "extra" version (beta/rc..) PHP was compiled against. * @since 5.2.4 * @link https://php.net/manual/en/image.constants.php#constant.gd-extra-version */ define('GD_EXTRA_VERSION', ""); /** * A special PNG filter, used by the {@see imagepng()} function. * @link https://php.net/manual/en/image.constants.php#constant.png-no-filter */ define('PNG_NO_FILTER', 0); /** * A special PNG filter, used by the {@see imagepng()} function. * @link https://php.net/manual/en/image.constants.php#constant.png-filter-none */ define('PNG_FILTER_NONE', 8); /** * A special PNG filter, used by the {@see imagepng()} function. * @link https://php.net/manual/en/image.constants.php#constant.png-filter-sub */ define('PNG_FILTER_SUB', 16); /** * A special PNG filter, used by the {@see imagepng()} function. * @link https://php.net/manual/en/image.constants.php#constant.png-filter-up */ define('PNG_FILTER_UP', 32); /** * A special PNG filter, used by the {@see imagepng()} function. * @link https://php.net/manual/en/image.constants.php#constant.png-filter-avg */ define('PNG_FILTER_AVG', 64); /** * A special PNG filter, used by the {@see imagepng()} function. * @link https://php.net/manual/en/image.constants.php#constant.png-filter-paeth */ define('PNG_FILTER_PAETH', 128); /** * A special PNG filter, used by the {@see imagepng()} function. * @link https://php.net/manual/en/image.constants.php#constant.png-all-filters */ define('PNG_ALL_FILTERS', 248); /** * An affine transformation type constant used by the {@see imageaffinematrixget()} function. * @since 5.5 * @link https://php.net/manual/en/image.constants.php#constant.img-affine-translate */ define('IMG_AFFINE_TRANSLATE', 0); /** * An affine transformation type constant used by the {@see imageaffinematrixget()} function. * @since 5.5 * @link https://php.net/manual/en/image.constants.php#constant.img-affine-scale */ define('IMG_AFFINE_SCALE', 1); /** * An affine transformation type constant used by the {@see imageaffinematrixget()} function. * @since 5.5 * @link https://php.net/manual/en/image.constants.php#constant.img-affine-rotate */ define('IMG_AFFINE_ROTATE', 2); /** * An affine transformation type constant used by the {@see imageaffinematrixget()} function. * @since 5.5 * @link https://php.net/manual/en/image.constants.php#constant.img-affine-shear-horizontal */ define('IMG_AFFINE_SHEAR_HORIZONTAL', 3); /** * An affine transformation type constant used by the {@see imageaffinematrixget()} function. * @since 5.5 * @link https://php.net/manual/en/image.constants.php#constant.img-affine-shear-vertical */ define('IMG_AFFINE_SHEAR_VERTICAL', 4); /** * Same as {@see IMG_CROP_TRANSPARENT}. Before PHP 7.4.0, the bundled libgd fell back to * {@see IMG_CROP_SIDES}, if the image had no transparent color. * Used together with {@see imagecropauto()}. * @since 5.5 */ define('IMG_CROP_DEFAULT', 0); /** * Crops out a transparent background. * Used together with {@see imagecropauto()}. * @since 5.5 */ define('IMG_CROP_TRANSPARENT', 1); /** * Crops out a black background. * Used together with {@see imagecropauto()}. * @since 5.5 */ define('IMG_CROP_BLACK', 2); /** * Crops out a white background. * Used together with {@see imagecropauto()}. * @since 5.5 */ define('IMG_CROP_WHITE', 3); /** * Uses the 4 corners of the image to attempt to detect the background to crop. * Used together with {@see imagecropauto()}. * @since 5.5 */ define('IMG_CROP_SIDES', 4); /** * Crops an image using the given threshold and color. * Used together with {@see imagecropauto()}. * @since 5.5 */ define('IMG_CROP_THRESHOLD', 5); /** * Used together with {@see imageflip()} * @since 5.5 * @link https://php.net/manual/en/image.constants.php#constant.img-flip-both */ define('IMG_FLIP_BOTH', 3); /** * Used together with {@see imageflip()} * @since 5.5 * @link https://php.net/manual/en/image.constants.php#constant.img-flip-horizontal */ define('IMG_FLIP_HORIZONTAL', 1); /** * Used together with {@see imageflip()} * @since 5.5 * @link https://php.net/manual/en/image.constants.php#constant.img-flip-vertical */ define('IMG_FLIP_VERTICAL', 2); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-bell * @since 5.5 */ define('IMG_BELL', 1); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-bessel * @since 5.5 */ define('IMG_BESSEL', 2); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-bicubic * @since 5.5 */ define('IMG_BICUBIC', 4); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-bicubic-fixed * @since 5.5 */ define('IMG_BICUBIC_FIXED', 5); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-bilinear-fixed * @since 5.5 */ define('IMG_BILINEAR_FIXED', 3); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-blackman * @since 5.5 */ define('IMG_BLACKMAN', 6); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-box * @since 5.5 */ define('IMG_BOX', 7); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-bspline * @since 5.5 */ define('IMG_BSPLINE', 8); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-catmullrom * @since 5.5 */ define('IMG_CATMULLROM', 9); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-gaussian * @since 5.5 */ define('IMG_GAUSSIAN', 10); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-generalized-cubic * @since 5.5 */ define('IMG_GENERALIZED_CUBIC', 11); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-hermite * @since 5.5 */ define('IMG_HERMITE', 12); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-hamming * @since 5.5 */ define('IMG_HAMMING', 13); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-hanning * @since 5.5 */ define('IMG_HANNING', 14); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-mitchell * @since 5.5 */ define('IMG_MITCHELL', 15); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-power * @since 5.5 */ define('IMG_POWER', 17); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-quadratic * @since 5.5 */ define('IMG_QUADRATIC', 18); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-sinc * @since 5.5 */ define('IMG_SINC', 19); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-nearest-neighbour * @since 5.5 */ define('IMG_NEAREST_NEIGHBOUR', 16); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-weighted4 * @since 5.5 */ define('IMG_WEIGHTED4', 21); /** * Used together with {@see imagesetinterpolation()}. * @link https://php.net/manual/en/image.constants.php#constant.img-triangle * @since 5.5 */ define('IMG_TRIANGLE', 20); define('IMG_TGA', 128); /** * @since 8.1 */ define('IMG_AVIF', 256); /** * @since 8.1 */ define('IMG_WEBP_LOSSLESS', 101); /** * Outputs or saves a AVIF Raster image from the given image * @link https://www.php.net/manual/function.imageavif.php * @param GdImage $image A GdImage object, returned by one of the image creation functions, such as imagecreatetruecolor(). * @param resource|string|null $file The path or an open stream resource (which is automatically closed after this function returns) to save the file to. If not set or null, the raw image stream will be output directly. * @param int $quality quality is optional, and ranges from 0 (worst quality, smaller file) to 100 (best quality, larger file). If -1 is provided, the default value 30 is used. * @param int $speed speed is optional, and ranges from 0 (slow, smaller file) to 10 (fast, larger file). If -1 is provided, the default value 6 is used. * @return bool Returns true on success or false on failure. However, if libgd fails to output the image, this function returns true. * @since 8.1 */ function imageavif(GdImage $image, string|null $file = null, int $quality = -1, int $speed = -1): bool {} /** * Return an image containing the affine tramsformed src image, using an optional clipping area * @link https://secure.php.net/manual/en/function.imageaffine.php * @param resource|GdImage $image

    An image resource, returned by one of the image creation functions, * such as {@link https://secure.php.net/manual/en/function.imagecreatetruecolor.php imagecreatetruecolor()}.

    * @param array $affine

    Array with keys 0 to 5.

    * @param array|null $clip [optional]

    Array with keys "x", "y", "width" and "height".

    * @return resource|GdImage|false Return affined image resource on success or FALSE on failure. */ function imageaffine(GdImage $image, array $affine, ?array $clip = null): GdImage|false {} /** * Concat two matrices (as in doing many ops in one go) * @link https://secure.php.net/manual/en/function.imageaffinematrixconcat.php * @param array $matrix1

    Array with keys 0 to 5.

    * @param array $matrix2

    Array with keys 0 to 5.

    * @return float[]|false Array with keys 0 to 5 and float values or FALSE on failure. * @since 5.5 */ function imageaffinematrixconcat(array $matrix1, array $matrix2): array|false {} /** * Return an image containing the affine tramsformed src image, using an optional clipping area * @link https://secure.php.net/manual/en/function.imageaffinematrixget.php * @param int $type

    One of IMG_AFFINE_* constants.

    * @param mixed $options * @return float[]|false Array with keys 0 to 5 and float values or FALSE on failure. * @since 5.5 */ function imageaffinematrixget( int $type, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $options = null, #[PhpStormStubsElementAvailable(from: '8.0')] $options ): array|false {} /** * Crop an image using the given coordinates and size, x, y, width and height * @link https://secure.php.net/manual/en/function.imagecrop.php * @param resource|GdImage $image

    * An image resource, returned by one of the image creation functions, such as {@link https://secure.php.net/manual/en/function.imagecreatetruecolor.php imagecreatetruecolor()}. *

    * @param array $rectangle

    Array with keys "x", "y", "width" and "height".

    * @return resource|GdImage|false Return cropped image resource on success or FALSE on failure. * @since 5.5 */ function imagecrop(GdImage $image, array $rectangle): GdImage|false {} /** * Crop an image automatically using one of the available modes * @link https://secure.php.net/manual/en/function.imagecropauto.php * @param resource|GdImage $image

    * An image resource, returned by one of the image creation functions, such as {@link https://secure.php.net/manual/en/function.imagecreatetruecolor.php imagecreatetruecolor()}. *

    * @param int $mode [optional]

    * One of IMG_CROP_* constants. *

    * @param float $threshold [optional]

    * Used IMG_CROP_THRESHOLD mode. *

    * @param int $color [optional] *

    * Used in IMG_CROP_THRESHOLD mode. *

    * @return resource|GdImage|false Return cropped image resource on success or FALSE on failure. * @since 5.5 */ function imagecropauto(GdImage $image, int $mode = IMG_CROP_DEFAULT, float $threshold = .5, int $color = -1): GdImage|false {} /** * Flips an image using a given mode * @link https://secure.php.net/manual/en/function.imageflip.php * @param resource|GdImage $image

    * An image resource, returned by one of the image creation functions, such as {@link https://secure.php.net/manual/en/function.imagecreatetruecolor.php imagecreatetruecolor()}. *

    * @param int $mode

    * Flip mode, this can be one of the IMG_FLIP_* constants: *

    * * * * * * * * * * * * * * * * * * * * * *
    ConstantMeaning
    IMG_FLIP_HORIZONTAL * Flips the image horizontally. *
    IMG_FLIP_VERTICAL * Flips the image vertically. *
    IMG_FLIP_BOTH * Flips the image both horizontally and vertically. *
    * @return bool Returns TRUE on success or FALSE on failure. * @since 5.5 */ function imageflip(GdImage $image, int $mode): bool {} /** * Converts a palette based image to true color * @link https://secure.php.net/manual/en/function.imagepalettetotruecolor.php * @param resource|GdImage $image

    * An image resource, returnd by one of the image creation functions, such as {@link https://secure.php.net/manual/en/function.imagecreatetruecolor.php imagecreatetruecolor()}. *

    * @return bool Returns TRUE if the convertion was complete, or if the source image already is a true color image, otherwise FALSE is returned. * @since 5.5 */ function imagepalettetotruecolor(GdImage $image): bool {} /** * @param resource|GdImage $image

    * An image resource, returnd by one of the image creation functions, such as {@link https://secure.php.net/manual/en/function.imagecreatetruecolor.php imagecreatetruecolor()}. *

    * @param int $width * @param int $height [optional] * @param int $mode [optional] One of IMG_NEAREST_NEIGHBOUR, IMG_BILINEAR_FIXED, IMG_BICUBIC, IMG_BICUBIC_FIXED or anything else (will use two pass). * @return resource|GdImage|false Return scaled image resource on success or FALSE on failure. *@link https://secure.php.net/manual/en/function.imagescale.php * @since 5.5 * Scale an image using the given new width and height */ function imagescale(GdImage $image, int $width, int $height = -1, int $mode = IMG_BILINEAR_FIXED): GdImage|false {} /** * Set the interpolation method * @link https://secure.php.net/manual/en/function.imagesetinterpolation.php * @param resource|GdImage $image

    * An image resource, returned by one of the image creation functions, such as {@link https://secure.php.net/manual/en/function.imagecreatetruecolor.php imagecreatetruecolor()}. *

    * @param int $method

    * The interpolation method, which can be one of the following: *

      *
    • * IMG_BELL: Bell filter. *
    • *
    • * IMG_BESSEL: Bessel filter. *
    • *
    • * IMG_BICUBIC: Bicubic interpolation. *
    • *
    • * IMG_BICUBIC_FIXED: Fixed point implementation of the bicubic interpolation. *
    • *
    • * IMG_BILINEAR_FIXED: Fixed point implementation of the bilinear interpolation (default (also on image creation)). *
    • *
    • * IMG_BLACKMAN: Blackman window function. *
    • *
    • * IMG_BOX: Box blur filter. *
    • *
    • * IMG_BSPLINE: Spline interpolation. *
    • *
    • * IMG_CATMULLROM: Cubbic Hermite spline interpolation. *
    • *
    • * IMG_GAUSSIAN: Gaussian function. *
    • *
    • * IMG_GENERALIZED_CUBIC: Generalized cubic spline fractal interpolation. *
    • *
    • * IMG_HERMITE: Hermite interpolation. *
    • *
    • * IMG_HAMMING: Hamming filter. *
    • *
    • * IMG_HANNING: Hanning filter. *
    • *
    • * IMG_MITCHELL: Mitchell filter. *
    • *
    • * IMG_POWER: Power interpolation. *
    • *
    • * IMG_QUADRATIC: Inverse quadratic interpolation. *
    • *
    • * IMG_SINC: Sinc function. *
    • *
    • * IMG_NEAREST_NEIGHBOUR: Nearest neighbour interpolation. *
    • *
    • * IMG_WEIGHTED4: Weighting filter. *
    • *
    • * IMG_TRIANGLE: Triangle interpolation. *
    • *
    *

    * @return bool Returns TRUE on success or FALSE on failure. * @since 5.5 */ function imagesetinterpolation(GdImage $image, int $method = IMG_BILINEAR_FIXED): bool {} /** * @since 8.0 */ final class GdImage { /** * You cannot initialize a GdImage object except through helper functions. */ private function __construct() {} private function __clone() {} } * @copyright © 2019 PHP Documentation Group * @license CC-BY 3.0, https://www.php.net/manual/en/cc.license.php */ namespace Ds; use ArrayAccess; use Countable; use IteratorAggregate; use JsonSerializable; use OutOfBoundsException; use OutOfRangeException; use Traversable; use UnderflowException; /** * Collection is the base interface which covers functionality common to all * the data structures in this library. It guarantees that all structures * are traversable, countable, and can be converted to json using * json_encode(). * @package Ds * * @template-covariant TKey * @template-covariant TValue * @extends IteratorAggregate */ interface Collection extends Countable, IteratorAggregate, JsonSerializable { /** * Removes all values from the collection. * @link https://www.php.net/manual/en/ds-collection.clear.php */ public function clear(): void; /** * Returns a shallow copy of the collection. * @link https://www.php.net/manual/en/ds-collection.copy.php * @return Collection */ public function copy(); /** * Returns whether the collection is empty. * @link https://www.php.net/manual/en/ds-collection.isempty.php * @return bool */ public function isEmpty(): bool; /** * Converts the collection to an array. *

    Note: Casting to an array is not supported yet.

    * @link https://www.php.net/manual/en/ds-collection.toarray.php * @return array An array containing all the values in the same order as * the collection. */ public function toArray(): array; } /** * Hashable is an interface which allows objects to be used as keys. It’s * an alternative to spl_object_hash(), which determines an object’s hash * based on its handle: this means that two objects that are considered * equal by an implicit definition would not treated as equal because they * are not the same instance. * * hash() is used to return a scalar value to be used as the object's hash * value, which determines where it goes in the hash table. While this value * does not have to be unique, objects which are equal must have the same * hash value. * * equals() is used to determine if two objects are equal. It's guaranteed * that the comparing object will be an instance of the same class as the * subject. * @package Ds */ interface Hashable { /** * Determines whether another object is equal to the current instance. * * This method allows objects to be used as keys in structures such as * Ds\Map and Ds\Set, or any other lookup structure that honors this * interface. * * Note: It's guaranteed that $obj is an instance of the same class. * * Caution: It's important that objects which are equal also have the * same hash value. * @see https://www.php.net/manual/en/ds-hashable.hash.php * @link https://www.php.net/manual/en/ds-hashable.equals.php * @param object $obj The object to compare the current instance to, * which is always an instance of the same class. * * @return bool True if equal, false otherwise. */ public function equals($obj): bool; /** * Returns a scalar value to be used as the hash value of the objects. * * While the hash value does not define equality, all objects that are * equal according to Ds\Hashable::equals() must have the same hash * value. Hash values of equal objects don't have to be unique, for * example you could just return TRUE for all objects and nothing * would break - the only implication would be that hash tables then * turn into linked lists because all your objects will be hashed to * the same bucket. It's therefore very important that you pick a good * hash value, such as an ID or email address. * * This method allows objects to be used as keys in structures such as * Ds\Map and Ds\Set, or any other lookup structure that honors this * interface. * * Caution: Do not pick a value that might change within the object, * such as a public property. Hash table lookups would fail because * the hash has changed. * * Caution: All objects that are equal must have the same hash value. * * @return mixed A scalar value to be used as this object's hash value. * @link https://www.php.net/manual/en/ds-hashable.hash.php */ public function hash(); } /** * A Sequence describes the behaviour of values arranged in a single, * linear dimension. Some languages refer to this as a "List". It’s * similar to an array that uses incremental integer keys, with the * exception of a few characteristics: *
      *
    • Values will always be indexed as [0, 1, 2, …, size - 1].
    • *
    • Only allowed to access values by index in the range [0, size - 1].
    • *
    *
    * Use cases: *
      *
    • Wherever you would use an array as a list (not concerned with keys).
    • *
    • A more efficient alternative to SplDoublyLinkedList and SplFixedArray.
    • *
    * @package Ds * @template TValue * @extends Collection */ interface Sequence extends Collection, ArrayAccess { /** * Ensures that enough memory is allocated for a required capacity. * This removes the need to reallocate the internal as values are added. * * @param int $capacity The number of values for which capacity should * be allocated.

    Note: Capacity will stay the same if this value is * less than or equal to the current capacity.

    * @link https://www.php.net/manual/en/ds-sequence.allocate.php */ public function allocate(int $capacity): void; /** * Updates all values by applying a callback function to each value in * the sequence. * @param callable(TValue): TValue $callback A callable to apply to each value in the * sequence. The callback should return what the value should be * replaced by. * callback ( mixed $value ) : mixed * @link https://www.php.net/manual/en/ds-sequence.apply.php */ public function apply(callable $callback): void; /** * Returns the current capacity. * @return int The current capacity. * @link https://www.php.net/manual/en/ds-sequence.capacity.php */ public function capacity(): int; /** * Determines if the sequence contains all values. * @param TValue ...$values Values to check. * @return bool FALSE if any of the provided values are not in the * sequence, TRUE otherwise. * @link https://www.php.net/manual/en/ds-sequence.contains.php */ public function contains(...$values): bool; /** * Creates a new sequence using a callable to determine which values * to include. * @param null|callable(TValue): bool $callback Optional callable which returns TRUE if the * value should be included, FALSE otherwise. If a callback is not * provided, only values which are TRUE (see converting to boolean) will * be included. * callback ( mixed $value ) : bool * @return Sequence A new sequence containing all the values for which * either the callback returned TRUE, or all values that convert to * TRUE if a callback was not provided. * @link https://www.php.net/manual/en/ds-sequence.filter.php */ public function filter(?callable $callback = null); /** * Returns the index of the value, or FALSE if not found. * @param TValue $value The value to find. * @return int|false The index of the value, or FALSE if not found. * @link https://www.php.net/manual/en/ds-sequence.find.php */ public function find($value); /** * Returns the first value in the sequence. * @return TValue The first value in the sequence. * @throws UnderflowException if empty. * @link https://www.php.net/manual/en/ds-sequence.first.php */ public function first(); /** * Returns the value at a given index. * @param int $index The index to access, starting at 0. * @return TValue The value at the requested index. * @throws OutOfRangeException if the index is not valid. * @link https://www.php.net/manual/en/ds-sequence.get.php */ public function get(int $index); /** * Inserts values into the sequence at a given index. * * @param int $index The index at which to insert. 0 <= index <= count *

    Note: You can insert at the index equal to the number of values.

    * @param TValue ...$values The value or values to insert. * @throws OutOfRangeException if the index is not valid. * @link https://www.php.net/manual/en/ds-sequence.insert.php */ public function insert(int $index, ...$values): void; /** * Joins all values together as a string using an optional separator * between each value. * @param string $glue An optional string to separate each value. * @return string All values of the sequence joined together as a * string. * @link https://www.php.net/manual/en/ds-sequence.join.php */ public function join(string $glue = ''): string; /** * Returns the last value in the sequence. * @return TValue The last value in the sequence. * @throws UnderflowException if empty. * @link https://www.php.net/manual/en/ds-sequence.last.php */ public function last(); /** * Returns the result of applying a callback function to each value in * the sequence. * @template TNewValue * @param callable(TValue): TNewValue $callback A callable to apply to each value in the * sequence. * The callable should return what the new value will be in the new * sequence. * callback ( mixed $value ) : mixed * @return Sequence The result of applying a callback to each value in * the sequence.

    Note: The values of the current instance won't be * affected.

    * @link https://www.php.net/manual/en/ds-sequence.map.php */ public function map(callable $callback): Sequence; /** * Returns the result of adding all given values to the sequence. * @template TValue2 * @param iterable $values A traversable object or an array. * @return Sequence The result of adding all given values to the * sequence, effectively the same as adding the values to a copy, * then returning that copy. * @link https://www.php.net/manual/en/ds-sequence.merge.php */ public function merge($values): Sequence; /** * Removes and returns the last value. * @return TValue The removed last value. * @throws UnderflowException if empty. * @link https://www.php.net/manual/en/ds-sequence.pop.php */ public function pop(); /** * Adds values to the end of the sequence. * @param TValue ...$values The values to add. */ public function push(...$values): void; /** * Reduces the sequence to a single value using a callback function. * @template TCarry * @param callable(TCarry, TValue): TCarry $callback

    * * callback ( mixed $carry , mixed $value ) : mixed * $carry The return value of the previous callback, or initial if it's * the first iteration.
    * $value The value of the current iteration. *

    * @param TCarry $initial The initial value of the carry value. Can be NULL. * @return TCarry The return value of the final callback. * @link https://www.php.net/manual/en/ds-sequence.reduce.php */ public function reduce(callable $callback, $initial = null); /** * Removes and returns a value by index. * @param int $index The index of the value to remove. * @return TValue The value that was removed. * @link https://www.php.net/manual/en/ds-sequence.remove.php */ public function remove(int $index); /** * Reverses the sequence in-place. * @link https://www.php.net/manual/en/ds-sequence.reverse.php */ public function reverse(): void; /** * Returns a reversed copy of the sequence. * @return Sequence A reversed copy of the sequence. *

    Note: The current instance is not affected.

    */ public function reversed(); /** * Rotates the sequence by a given number of rotations, which is * equivalent to successively calling * $sequence->push($sequence->shift()) if the number of rotations is * positive, or $sequence->unshift($sequence->pop()) if negative. * @param int $rotations The number of times the sequence should be * rotated. * @link https://www.php.net/manual/en/ds-sequence.rotate.php */ public function rotate(int $rotations): void; /** * Updates a value at a given index. * @param int $index The index of the value to update. * @param TValue $value The new value. * @throws OutOfRangeException if the index is not valid. * @link https://www.php.net/manual/en/ds-sequence.set.php */ public function set(int $index, $value): void; /** * Removes and returns the first value. * @return TValue * @throws UnderflowException if empty. * @link https://www.php.net/manual/en/ds-sequence.shift.php */ public function shift(); /** * Creates a sub-sequence of a given range. * @param int $index The index at which the sub-sequence starts. * If positive, the sequence will start at that index in the sequence. * If negative, the sequence will start that far from the end. * @param int|null $length If a length is given and is positive, the * resulting sequence will have up to that many values in it. If the * length results in an overflow, only values up to the end of the * sequence will be included. If a length is given and is negative, * the sequence will stop that many values from the end. If a length * is not provided, the resulting sequence will contain all values * between the index and the end of the sequence. * @return Sequence A sub-sequence of the given range. * @link https://www.php.net/manual/en/ds-sequence.slice.php */ public function slice(int $index, int $length = null); /** * Sorts the sequence in-place, using an optional comparator function. * @param callable(TValue, TValue): int|null $comparator The comparison function must return * an integer less than, equal to, or greater than zero if the first * argument is considered to be respectively less than, equal to, or * greater than the second. Note that before PHP 7.0.0 this integer had * to be in the range from -2147483648 to 2147483647.

    * callback ( mixed $a, mixed $b ) : int

    *

    Caution: Returning non-integer values from the comparison * function, such as float, will result in an internal cast to integer * of the callback's return value. So values such as 0.99 and 0.1 will * both be cast to an integer value of 0, which will compare such * values as equal.

    * @link https://www.php.net/manual/en/ds-sequence.sort.php */ public function sort(?callable $comparator = null): void; /** * Returns a sorted copy, using an optional comparator function. * @param callable(TValue, TValue): int|null $comparator The comparison function must return * an integer less than, equal to, or greater than zero if the first * argument is considered to be respectively less than, equal to, or * greater than the second. Note that before PHP 7.0.0 this integer had * to be in the range from -2147483648 to 2147483647.

    * callback ( mixed $a, mixed $b ) : int

    *

    Caution: Returning non-integer values from the comparison * function, such as float, will result in an internal cast to integer * of the callback's return value. So values such as 0.99 and 0.1 will * both be cast to an integer value of 0, which will compare such * values as equal.

    * @return Sequence Returns a sorted copy of the sequence. * @link https://www.php.net/manual/en/ds-sequence.sort.php */ public function sorted(?callable $comparator = null); /** * Returns the sum of all values in the sequence. *

    Note: Arrays and objects are considered equal to zero when * calculating the sum.

    * @return float|int The sum of all the values in the sequence as * either a float or int depending on the values in the sequence. */ public function sum(): float|int; /** * Adds values to the front of the sequence, moving all the current * values forward to make room for the new values. * @param TValue ...$values The values to add to the front of the sequence. *

    Note: Multiple values will be added in the same order that they * are passed.

    */ public function unshift(...$values): void; } /** * A Vector is a sequence of values in a contiguous buffer that grows and * shrinks automatically. It’s the most efficient sequential structure * because a value’s index is a direct mapping to its index in the buffer, * and the growth factor isn't bound to a specific multiple or exponent. *

    *

    *

    Strengths *
      *
    • Supports array syntax (square brackets).
    • *
    • Uses less overall memory than an array for the same number of values.
    • *
    • Automatically frees allocated memory when its size drops low enough.
    • *
    • Capacity does not have to be a power of 2.
    • *
    • get(), set(), push(), pop() are all O(1)
    • *
    *

    *

    Weaknesses *
      *
    • shift(), unshift(), insert() and remove() are all O(n).
    • *
    * * @link https://www.php.net/manual/en/class.ds-vector.php * * @package Ds * @template TValue * @implements Sequence */ class Vector implements Sequence { public const MIN_CAPACITY = 10; /** * Creates a new instance, using either a traversable object or an array for the initial values. * * @param array $values */ public function __construct($values = []) {} /** * Ensures that enough memory is allocated for a required capacity. * This removes the need to reallocate the internal as values are added. * @param int $capacity The number of values for which capacity should * be allocated. *

    Note: Capacity will stay the same if this value is less than or * equal to the current capacity.

    * @link https://www.php.net/manual/en/ds-vector.allocate.php */ public function allocate(int $capacity): void {} /** * Updates all values by applying a callback function to each value in * the vector. * @param callable(TValue): TValue $callback * callback ( mixed $value ) : mixed * A callable to apply to each value in the vector. The callback should * return what the value should be replaced by. * @link https://www.php.net/manual/en/ds-vector.apply.php */ public function apply(callable $callback): void {} /** * Returns the current capacity. * @return int The current capacity. * @link https://www.php.net/manual/en/ds-vector.capacity.php */ public function capacity(): int {} /** * Removes all values from the vector. * @link https://www.php.net/manual/en/ds-vector.clear.php */ public function clear(): void {} /** * Determines if the vector contains all values. * @param TValue ...$values Values to check. * @return bool FALSE if any of the provided values are not in the * vector, TRUE otherwise. * @link https://www.php.net/manual/en/ds-vector.contains.php */ public function contains(...$values): bool {} /** *Returns a shallow copy of the vector. * @return Vector Returns a shallow copy of the vector. */ public function copy(): Vector {} /** * Creates a new vector using a callable to determine which values to * include. * * @param null|callable(TValue): bool $callback * Optional callable which returns TRUE if the value should be included, * FALSE otherwise. If a callback is not provided, only values which are * TRUE (see converting to boolean) will be included. * callback ( mixed $value ) : bool * @return Vector A new vector containing all the values for which * either the callback returned TRUE, or all values that convert to * TRUE if a callback was not provided. * @link https://www.php.net/manual/en/ds-vector.filter.php */ public function filter(?callable $callback = null): Vector {} /** * Returns the index of the value, or FALSE if not found. * @param TValue $value The value to find. * @return int|false The index of the value, or FALSE if not found. *

    Note: Values will be compared by value and by type.

    * @link https://www.php.net/manual/en/ds-vector.find.php */ public function find($value) {} /** * Returns the first value in the vector. * @return TValue * @throws UnderflowException if empty. * @link https://www.php.net/manual/en/ds-vector.first.php */ public function first() {} /** * Returns the value at a given index. * @param int $index The index to access, starting at 0. * @return TValue * @link https://www.php.net/manual/en/ds-vector.get.php */ public function get(int $index) {} /** * @return Traversable */ public function getIterator(): Traversable {} /** * Inserts values into the sequence at a given index. * * @param int $index The index at which to insert. 0 <= index <= count * Note:
    * You can insert at the index equal to the number of values. * @param array ...$values The value or values to insert. * @link https://www.php.net/manual/en/ds-vector.insert.php */ public function insert(int $index, ...$values): void {} /** * Joins all values together as a string using an optional separator between each value. * * @param string|null $glue An optional string to separate each value. * @return string All values of the sequence joined together as a string. * @link https://www.php.net/manual/en/ds-vector.join.php */ public function join(?string $glue = null): string {} /** * Returns the last value in the sequence. * * @return TValue The last value in the sequence. * @link https://www.php.net/manual/en/ds-vector.last.php */ public function last() {} /** * Returns the result of applying a callback function to each value in the sequence. * * @template TNewValue * @param callable(TValue): TNewValue $callback A callable to apply to each value in the sequence. *
    The callable should return what the new value will be in the new sequence. * * @return Vector * @link https://www.php.net/manual/en/ds-vector.map.php */ public function map(callable $callback): Vector {} /** * Returns the result of adding all given values to the sequence. * * @template TValue2 * @param iterable $values A traversable object or an array. * @return Vector The result of adding all given values to the sequence, effectively the same as adding the * values to a copy, then returning that copy.
    * Note:
    * The current instance won't be affected. * @link https://www.php.net/manual/en/ds-vector.merge.php */ public function merge($values): Vector {} /** * Removes and returns the last value. * * @return TValue * @link https://www.php.net/manual/en/ds-vector.pop.php */ public function pop() {} /** * Adds values to the end of the sequence. * @param TValue ...$values * @link https://www.php.net/manual/en/ds-vector.push.php */ public function push(...$values): void {} /** * Reduces the sequence to a single value using a callback function. * @template TCarry * @param callable(TCarry, TValue): TCarry $callback
    * callback ( mixed $carry , mixed $value ) : mixed
    * carry The return value of the previous callback, or initial if it's the first iteration.
    * value The value of the current iteration. * @param TCarry $initial The initial value of the carry value. Can be NULL. * * @return TCarry The return value of the final callback. * * @link https://www.php.net/manual/en/ds-vector.reduce.php */ public function reduce(callable $callback, $initial = null) {} /** * Removes and returns a value by index. * @param int $index The index of the value to remove. * @return TValue The value that was removed. * @link https://www.php.net/manual/en/ds-vector.remove.php */ public function remove(int $index) {} /** * Reverses the sequence in-place. * @link https://www.php.net/manual/en/ds-vector.reverse.php */ public function reverse(): void {} /** * Returns a reversed copy of the sequence. * @return Vector A reversed copy of the sequence.
    * Note: The current instance is not affected. * @link https://www.php.net/manual/en/ds-vector.reversed.php */ public function reversed(): Vector {} /** * Rotates the sequence by a given number of rotations, which is * equivalent to successively calling $sequence->push($sequence->shift()) * if the number of rotations is positive, or $sequence->unshift($sequence->pop()) * if negative. * * @link https://www.php.net/manual/en/ds-vector.rotate.php * * @param int $rotations The number of times the sequence should be rotated. */ public function rotate(int $rotations): void {} /** * Updates a value at a given index. * * @link https://www.php.net/manual/en/ds-vector.set.php * * @param int $index The index of the value to update. * @param TValue $value The new value. * * @throws OutOfRangeException if the index is not valid. */ public function set(int $index, $value): void {} /** * Removes and returns the first value. * * @link https://www.php.net/manual/en/ds-vector.shift.php * * @return TValue The first value, which was removed. * @throws UnderflowException if empty. */ public function shift() {} /** * Creates a sub-sequence of a given range. * @link https://www.php.net/manual/en/ds-vector.slice.php * @param int $index The index at which the sub-sequence starts. If * positive, the sequence will start at that * index in the sequence. If negative, the sequence will start that * far from the end. * @param int|null $length If a length is given and is positive, the * resulting sequence will have up to that many values in it. If the * length results in an overflow, only values up to the end of the * sequence will be included. If a length is given and is negative, * the sequence will stop that many values from the end. If a length * is not provided, the resulting sequence will contain all values * between the index and the end of the sequence. * @return Vector */ public function slice(int $index, int $length = null): Vector {} /** * Sorts the sequence in-place, using an optional comparator function. * @link https://www.php.net/manual/en/ds-vector.sort.php * @param callable(TValue, TValue): int|null $comparator The comparison function must return an * integer less than, equal to, or greater * than zero if the first argument is considered to be respectively less than, equal to, or greater than the * second. Note that before PHP 7.0.0 this integer had to be in the * range from -2147483648 to 2147483647.
    * callback ( mixed $a, mixed $b ) : int * Caution: Returning non-integer values from the comparison function, * such as float, will result in an * internal cast to integer of the callback's return value. So values * such as 0.99 and 0.1 will both be cast to an integer value of 0, * which will compare such values as equal. */ public function sort(?callable $comparator = null): void {} /** * Returns a sorted copy, using an optional comparator function. * @link https://www.php.net/manual/en/ds-vector.sorted.php * @param callable(TValue, TValue): int|null $comparator The comparison function must return an integer less than, equal to, or * greater than zero if the first argument is considered to be respectively less than, equal to, or greater * than the second. Note that before PHP 7.0.0 this integer had to be in the range from -2147483648 to * 2147483647.
    * callback ( mixed $a, mixed $b ) : int * Caution: Returning non-integer values from the comparison function, such as float, will result in an * internal cast to integer of the callback's return value. So values such as 0.99 and 0.1 will both be cast to * an integer value of 0, which will compare such values as equal. * @return Vector Returns a sorted copy of the sequence. */ public function sorted(?callable $comparator = null): Vector {} /** * Returns the sum of all values in the sequence.
    * Note: Arrays and objects are considered equal to zero when * calculating the sum. * @link https://www.php.net/manual/en/ds-vector.sum.php * @return float */ public function sum(): float {} /** * Adds values to the front of the sequence, moving all the current * values forward to make room for the new values. * @param TValue ...$values The values to add to the front of the sequence.
    * Note: Multiple values will be added in the same order that they are * passed. * @link https://www.php.net/manual/en/ds-vector.unshift.php */ public function unshift($values): void {} /** * Count elements of an object * @link https://php.net/manual/en/ds-vector.count.php * @return int The custom count as an integer. *

    * The return value is cast to an integer. *

    * @since 5.1 */ public function count(): int {} /** * Returns whether the collection is empty. * @link https://www.php.net/manual/en/ds-vector.isempty.php * @return bool */ public function isEmpty(): bool {} /** * Converts the collection to an array. *

    Note: Casting to an array is not supported yet.

    * @link https://www.php.net/manual/en/ds-vector.toarray.php * @return array An array containing all the values in the same order as * the collection. */ public function toArray(): array {} /** * Specify data which should be serialized to JSON * @link https://php.net/manual/en/ds-vector.jsonserialize.php * @return mixed data which can be serialized by json_encode, * which is a value of any type other than a resource. * @since 5.4 */ public function jsonSerialize() {} /** * @param int $offset */ public function offsetExists(mixed $offset): bool {} /** * @param int $offset * * @return TValue */ public function offsetGet(mixed $offset) {} /** * @param int $offset * @param TValue $value */ public function offsetSet(mixed $offset, mixed $value) {} /** * @param int $offset */ public function offsetUnset(mixed $offset): void {} } /** * @template TValue * @implements Sequence */ class Deque implements Sequence { /** * Creates a new instance, using either a traversable object or an array for the initial values. * @param TValue ...$values A traversable object or an array to use for the initial values. * * @link https://www.php.net/manual/en/ds-deque.construct.php */ public function __construct(...$values) {} /** * Count elements of an object * @link https://php.net/manual/en/countable.count.php * @return int The custom count as an integer. *

    * The return value is cast to an integer. *

    * @since 5.1 */ public function count(): int {} /** * Removes all values from the deque. * @link https://www.php.net/manual/en/ds-deque.clear.php */ public function clear(): void {} /** * Returns a shallow copy of the deque. * @link https://www.php.net/manual/en/ds-deque.copy.php * @return Deque */ public function copy(): Collection {} /** * @return Traversable */ public function getIterator(): Traversable {} /** * Returns whether the deque is empty. * @link https://www.php.net/manual/en/ds-deque.isempty.php * @return bool */ public function isEmpty(): bool {} /** * Converts the deque to an array. *

    Note: Casting to an array is not supported yet.

    * @link https://www.php.net/manual/en/ds-deque.toarray.php * @return array An array containing all the values in the same order as * the deque. */ public function toArray(): array {} /** * Ensures that enough memory is allocated for a required capacity. * This removes the need to reallocate the internal as values are added. * * @param int $capacity The number of values for which capacity should * be allocated.

    Note: Capacity will stay the same if this value is * less than or equal to the current capacity.

    *

    Note: Capacity will always be rounded up to the nearest power of 2.

    * @link https://www.php.net/manual/en/ds-deque.allocate.php */ public function allocate(int $capacity): void {} /** * Updates all values by applying a callback function to each value in * the deque. * @param callable(TValue): TValue $callback A callable to apply to each value in the * deque. The callback should return what the value should be * replaced by.

    * callback ( mixed $value ) : mixed *

    * @link https://www.php.net/manual/en/ds-deque.apply.php */ public function apply(callable $callback): void {} /** * Returns the current capacity. * @return int The current capacity. * @link https://www.php.net/manual/en/ds-deque.capacity.php */ public function capacity(): int {} /** * Determines if the deque contains all values. * @param TValue $values Values to check. * @return bool FALSE if any of the provided values are not in the * deque, TRUE otherwise. * @link https://www.php.net/manual/en/ds-deque.contains.php */ public function contains(...$values): bool {} /** * Creates a new deque using a callable to determine which values * to include. * @param null|callable(TValue): bool $callback Optional callable which returns TRUE if the * value should be included, FALSE otherwise. If a callback is not * provided, only values which are TRUE (see converting to boolean) will * be included.

    * callback ( mixed $value ) : bool *

    * @return Deque A new deque containing all the values for which * either the callback returned TRUE, or all values that convert to * TRUE if a callback was not provided. * @link https://www.php.net/manual/en/ds-deque.filter.php */ public function filter(?callable $callback = null): Deque {} /** * Returns the index of the value, or FALSE if not found. * @param TValue $value The value to find. * @return int|false The index of the value, or FALSE if not found. * @link https://www.php.net/manual/en/ds-deque.find.php */ public function find($value) {} /** * Returns the first value in the deque. * @return TValue The first value in the deque. * @throws UnderflowException if empty. * @link https://www.php.net/manual/en/ds-deque.first.php */ public function first() {} /** * Returns the value at a given index. * @param int $index The index to access, starting at 0. * @return TValue The value at the requested index. * @throws OutOfRangeException if the index is not valid. * @link https://www.php.net/manual/en/ds-deque.get.php */ public function get(int $index) {} /** * Inserts values into the deque at a given index. * * @param int $index The index at which to insert. 0 <= index <= count *

    Note: You can insert at the index equal to the number of values.

    * @param TValue ...$values The value or values to insert. * @throws OutOfRangeException if the index is not valid. * @link https://www.php.net/manual/en/ds-deque.insert.php */ public function insert(int $index, ...$values): void {} /** * Joins all values together as a string using an optional separator * between each value. * @param string $glue An optional string to separate each value. * @return string All values of the deque joined together as a * string. * @link https://www.php.net/manual/en/ds-deque.join.php */ public function join(string $glue = ''): string {} /** * Returns the last value in the deque. * @return TValue The last value in the deque. * @throws UnderflowException if empty. * @link https://www.php.net/manual/en/ds-deque.last.php */ public function last() {} /** * Returns the result of applying a callback function to each value in * the deque. * * @template TNewValue * @param callable(TValue): TNewValue $callback A callable to apply to each value in the * deque. * The callable should return what the new value will be in the new * deque. * callback ( mixed $value ) : mixed * * @return Deque The result of applying a callback to each value in * the deque. *

    Note: The values of the current instance won't be * affected.

    * @link https://www.php.net/manual/en/ds-deque.map.php */ public function map(callable $callback): Deque {} /** * Returns the result of adding all given values to the deque. * @template TValue2 * @param iterable $values A traversable object or an array. * @return Deque The result of adding all given values to the * deque, effectively the same as adding the values to a copy, * then returning that copy. * @link https://www.php.net/manual/en/ds-deque.merge.php */ public function merge($values): Deque {} /** * Removes and returns the last value. * @return TValue The removed last value. * @throws UnderflowException if empty. * @link https://www.php.net/manual/en/ds-deque.pop.php */ public function pop() {} /** * Adds values to the end of the deque. * @param TValue ...$values The values to add. */ public function push(...$values): void {} /** * Reduces the deque to a single value using a callback function. * @template TCarry * @param callable(TCarry, TValue): TCarry $callback * callback ( mixed $carry , mixed $value ) : mixed * $carry The return value of the previous callback, or initial if it's * the first iteration.

    * $value The value of the current iteration. *

    * @param TCarry $initial The initial value of the carry value. Can be NULL. * @return TCarry The return value of the final callback. * @link https://www.php.net/manual/en/ds-deque.reduce.php */ public function reduce(callable $callback, $initial = null) {} /** * Removes and returns a value by index. * @param int $index The index of the value to remove. * @return TValue The value that was removed. * @link https://www.php.net/manual/en/ds-deque.remove.php */ public function remove(int $index) {} /** * Reverses the deque in-place. * @link https://www.php.net/manual/en/ds-deque.reverse.php */ public function reverse(): void {} /** * Returns a reversed copy of the deque. * @return Deque A reversed copy of the deque. *

    Note: The current instance is not affected.

    */ public function reversed(): Deque {} /** * Rotates the deque by a given number of rotations, which is * equivalent to successively calling * $deque->push($deque->shift()) if the number of rotations is * positive, or $deque->unshift($deque->pop()) if negative. * @param int $rotations The number of times the deque should be * rotated. * @link https://www.php.net/manual/en/ds-deque.rotate.php */ public function rotate(int $rotations): void {} /** * Updates a value at a given index. * @param int $index The index of the value to update. * @param TValue $value The new value. * @throws OutOfRangeException if the index is not valid. * @link https://www.php.net/manual/en/ds-deque.set.php */ public function set(int $index, $value): void {} /** * Removes and returns the first value. * @return TValue * @throws UnderflowException if empty. * @link https://www.php.net/manual/en/ds-deque.shift.php */ public function shift() {} /** * Creates a sub-deque of a given range. * @param int $index The index at which the sub-deque starts. * If positive, the deque will start at that index in the deque. * If negative, the deque will start that far from the end. * @param int|null $length If a length is given and is positive, the * resulting deque will have up to that many values in it. If the * length results in an overflow, only values up to the end of the * deque will be included. If a length is given and is negative, * the deque will stop that many values from the end. If a length * is not provided, the resulting deque will contain all values * between the index and the end of the deque. * @return Deque A sub-deque of the given range. * @link https://www.php.net/manual/en/ds-deque.slice.php */ public function slice(int $index, int $length = null): Deque {} /** * Sorts the deque in-place, using an optional comparator function. * @param callable(TValue, TValue): int|null $comparator The comparison function must return * an integer less than, equal to, or greater than zero if the first * argument is considered to be respectively less than, equal to, or * greater than the second. Note that before PHP 7.0.0 this integer had * to be in the range from -2147483648 to 2147483647. * callback ( mixed $a, mixed $b ) : int *

    Caution: Returning non-integer values from the comparison * function, such as float, will result in an internal cast to integer * of the callback's return value. So values such as 0.99 and 0.1 will * both be cast to an integer value of 0, which will compare such * values as equal.

    * @link https://www.php.net/manual/en/ds-deque.sort.php */ public function sort(?callable $comparator = null): void {} /** * Returns a sorted copy, using an optional comparator function. * @param callable(TValue, TValue): int|null $comparator The comparison function must return * an integer less than, equal to, or greater than zero if the first * argument is considered to be respectively less than, equal to, or * greater than the second. Note that before PHP 7.0.0 this integer had * to be in the range from -2147483648 to 2147483647. * callback ( mixed $a, mixed $b ) : int *

    Caution: Returning non-integer values from the comparison * function, such as float, will result in an internal cast to integer * of the callback's return value. So values such as 0.99 and 0.1 will * both be cast to an integer value of 0, which will compare such * values as equal.

    * @return Deque Returns a sorted copy of the deque. * @link https://www.php.net/manual/en/ds-deque.sort.php */ public function sorted(?callable $comparator = null): Deque {} /** * Returns the sum of all values in the deque. *

    Note: Arrays and objects are considered equal to zero when * calculating the sum.

    * @return float|int The sum of all the values in the deque as * either a float or int depending on the values in the deque. */ public function sum(): float|int {} /** * Adds values to the front of the deque, moving all the current * values forward to make room for the new values. * @param TValue ...$values The values to add to the front of the deque. *

    Note: Multiple values will be added in the same order that they * are passed.

    */ public function unshift(...$values): void {} /** * Specify data which should be serialized to JSON * @link https://php.net/manual/en/ds-vector.jsonserialize.php * @return mixed data which can be serialized by json_encode, * which is a value of any type other than a resource. * @since 5.4 */ public function jsonSerialize() {} /** * @param int $offset */ public function offsetExists(mixed $offset): bool {} /** * @param int $offset * * @return TValue */ public function offsetGet(mixed $offset) {} /** * @param int $offset * @param TValue $value */ public function offsetSet(mixed $offset, mixed $value) {} /** * @param int $offset */ public function offsetUnset(mixed $offset): void {} } /** * @template TKey * @template TValue * @implements Collection */ class Map implements Collection, ArrayAccess { /** * Creates a new instance, using either a traversable object or an array for the initial values. * @param iterable ...$values A traversable object or an array to use for the initial values. * * @link https://www.php.net/manual/en/ds-map.construct.php */ public function __construct(...$values) {} /** * Allocates enough memory for a required capacity. * * @param int $capacity The number of values for which capacity should be allocated.
    *

    Note: Capacity will stay the same if this value is less than or equal to the current capacity.

    * Capacity will always be rounded up to the nearest power of 2. * * @link https://www.php.net/manual/en/ds-map.allocate.php */ public function allocate(int $capacity) {} /** * Updates all values by applying a callback function to each value in the map. * * @param callable(TKey, TValue): TValue $callback A callable to apply to each value in the map. The callback should return what * the value should be replaced by. * * @link https://www.php.net/manual/en/ds-map.apply.php */ public function apply(callable $callback) {} /** * Returns the current capacity. * * @return int * * @link https://www.php.net/manual/en/ds-map.capacity.php */ public function capacity(): int {} /** * Count elements of an object * @link https://php.net/manual/en/countable.count.php * @return int The custom count as an integer. *

    *

    * The return value is cast to an integer. * @since 5.1 */ public function count(): int {} /** * Removes all values from the collection. * @link https://www.php.net/manual/en/ds-collection.clear.php */ public function clear(): void {} /** * Returns a shallow copy of the collection. * @link https://www.php.net/manual/en/ds-collection.copy.php * @return Map */ public function copy(): Collection {} /** * Returns the result of removing all keys from the current instance that are present in a given map. * * A \ B = {x ∈ A | x ∉ B} * * @template TValue2 * @param Map $map The map containing the keys to exclude in the resulting map. * * @return Map The result of removing all keys from the current instance that are present in a given map. * * @link https://www.php.net/manual/en/ds-map.diff.php */ public function diff(Map $map): Map {} /** * Creates a new map using a callable to determine which pairs to include * * @param null|callable(TKey, TValue): bool $callback Optional callable which returns TRUE if the pair should be included, FALSE * otherwise. If a callback is not provided, only values which are TRUE (see converting to boolean) will be included. * * @return Map * * @link https://www.php.net/manual/en/ds-map.filter.php */ public function filter(?callable $callback = null): Map {} /** * Returns the first pair in the map * * @return Pair The first pair in the map. * * @throws UnderflowException if empty * * @link https://www.php.net/manual/en/ds-map.first.php */ public function first(): Pair {} /** * Returns the value for a given key, or an optional default value if the key could not be found. *

    * Note: Keys of type object are supported. If an object implements Ds\Hashable, equality will be * determined by the object's equals function. If an object does not implement Ds\Hashable, objects must be references to the same instance to be considered equal. *

    *

    * Note: You can also use array syntax to access values by key, eg. $map["key"]. *

    *

    * Caution: Be careful when using array syntax. Scalar keys will be coerced to integers by the engine. For * example, $map["1"] will attempt to access int(1), while $map->get("1") will correctly look up the string key. *

    * * @template TDefault * @param TKey $key The key to look up. * @param TDefault $default The optional default value, returned if the key could not be found. * * @return TValue|TDefault The value mapped to the given key, or the default value if provided and the key could not be found in the map. * * @throws OutOfBoundsException if the key could not be found and a default value was not provided. * * @link https://www.php.net/manual/en/ds-map.get.php */ public function get($key, $default = null) {} /** * @return Traversable */ public function getIterator(): Traversable {} /** * Determines whether the map contains a given key * * @param TKey $key The key to look for. * * @return bool Returns TRUE if the key could found, FALSE otherwise. * * @link https://www.php.net/manual/en/ds-map.hasKey.php */ public function hasKey($key): bool {} /** * Determines whether the map contains a given value * * @param TValue $value The value to look for. * * @return bool Returns TRUE if the value could found, FALSE otherwise. * * @link https://www.php.net/manual/en/ds-map.hasValue.php */ public function hasValue($value): bool {} /** * Creates a new map containing the pairs of the current instance whose * keys are also present in the given map. In other words, returns a * copy of the current instance with all keys removed that are not also * in the other map. * * A ∩ B = {x : x ∈ A ∧ x ∈ B} * *

    Note: Values from the current instance will be kept.

    * * @template TKey2 * @template TValue2 * @param Map $map The other map, containing the keys to intersect with. * * @return Map The key intersection of the current instance and another map. * * @link https://www.php.net/manual/en/ds-map.intersect.php */ public function intersect(Map $map): Map {} /** * Returns whether the collection is empty. * * @link https://www.php.net/manual/en/ds-collection.isempty.php * * @return bool Returns TRUE if the map is empty, FALSE otherwise. * * @link https://www.php.net/manual/en/ds-map.isempty.php */ public function isEmpty(): bool {} /** * Converts the map to an array. *

    Note: Casting to an array is not supported yet.

    *

    Caution: Maps where non-scalar keys are can't be converted to an * array. *

    *

    Caution: An array will treat all numeric keys as integers, eg. * "1" and 1 as keys in the map will only result in 1 being included in * the array. *

    * * @link https://www.php.net/manual/en/ds-map.toarray.php * @return array An array containing all the values in the same order as * the map. */ public function toArray(): array {} /** * Specify data which should be serialized to JSON * @link https://php.net/manual/en/jsonserializable.jsonserialize.php * @return mixed data which can be serialized by json_encode, * which is a value of any type other than a resource. * @since 5.4 */ public function jsonSerialize() {} /** * Returns a set containing all the keys of the map, in the same order. * @link https://www.php.net/manual/en/ds-map.keys.php * @return Set A Ds\Set containing all the keys of the map. */ public function keys(): Set {} /** * Sorts the map in-place by key, using an optional comparator function. * @param callable(TKey, TKey):int|null $comparator The comparison function must return * an integer less than, equal to, or greater than zero if the first * argument is considered to be respectively less than, equal to, or * greater than the second. Note that before PHP 7.0.0 this integer had * to be in the range from -2147483648 to 2147483647. * callback ( mixed $a, mixed $b ) : int *

    Caution: Returning non-integer values from the comparison function, such * as float, will result in an internal cast to integer of the * callback's return value. So values such as 0.99 and 0.1 will both be * cast to an integer value of 0, which will compare such values as * equal.

    * @link https://www.php.net/manual/en/ds-map.ksort.php */ public function ksort(?callable $comparator = null) {} /** * Returns a copy sorted by key, using an optional comparator function. * @param callable(TKey, TKey): int|null $comparator The comparison function must return * an integer less than, equal to, or greater than zero if the first * argument is considered to be respectively less than, equal to, or * greater than the second. Note that before PHP 7.0.0 this integer had * to be in the range from -2147483648 to 2147483647. * callback ( mixed $a, mixed $b ) : int *

    Caution: Returning non-integer values from the comparison function, such * as float, will result in an internal cast to integer of the * callback's return value. So values such as 0.99 and 0.1 will both be * cast to an integer value of 0, which will compare such values as * equal.

    * @return Map Returns a copy of the map, sorted by key. * @link https://www.php.net/manual/en/ds-map.ksorted.php */ public function ksorted(?callable $comparator = null): Map {} /** * Returns the last pair of the map. * @return Pair The last pair of the map. * @throws UnderflowException if empty * @link https://www.php.net/manual/en/ds-map.last.php */ public function last(): Pair {} /** * Returns the result of applying a callback function to each value of * the map. * @template TNewValue * @param callable(TKey, TValue): TNewValue $callback A callable to apply to each value in the * map. The callable should return what the key will be mapped to in the * resulting map. * callback ( mixed $key , mixed $value ) : mixed * @return Map The result of applying a callback to each value in the * map. * * Note: The keys and values of the current instance won't be affected. * * @link https://www.php.net/manual/en/ds-map.map.php */ public function map(callable $callback): Map {} /** * Returns the result of associating all keys of a given traversable * object or array with their corresponding values, combined with the * current instance. * @template TKey2 * @template TValue2 * @param iterable $values A traversable object or an array. * @return Map The result of associating all keys of a given traversable * object or array with their corresponding values, combined with the * current instance. * * Note: The current instance won't be affected. * * @link https://www.php.net/manual/en/ds-map.merge.php */ public function merge($values): Map {} /** * Returns a Ds\Sequence containing all the pairs of the map. * * @return Sequence> Ds\Sequence containing all the pairs of the map. * * @link https://www.php.net/manual/en/ds-map.pairs.php */ public function pairs(): Sequence {} /** * Associates a key with a value, overwriting a previous association if * one exists. * @param TKey $key The key to associate the value with. * @param TValue $value The value to be associated with the key. * * Note: Keys of type object are supported. If an object implements * Ds\Hashable, equality will be determined by the object's equals * function. If an object does not implement Ds\Hashable, objects must * be references to the same instance to be considered equal. * * Note: You can also use array syntax to associate values by key, eg. * $map["key"] = $value. * * Caution: Be careful when using array syntax. Scalar keys will be * coerced to integers by the engine. For example, $map["1"] will * attempt to access int(1), while $map->get("1") will correctly look up * the string key. * * @link https://www.php.net/manual/en/ds-map.put.php */ public function put($key, $value) {} /** * Associates all key-value pairs of a traversable object or array. * * Note: Keys of type object are supported. If an object implements * Ds\Hashable, equality will be determined * by the object's equals function. If an object does not implement * Ds\Hashable, objects must be references to the same instance to be * considered equal. * * @param iterable $pairs traversable object or array. * * @link https://www.php.net/manual/en/ds-map.putall.php */ public function putAll($pairs) {} /** * Reduces the map to a single value using a callback function. * * @template TCarry * @param callable(TCarry, TKey, TValue): TCarry $callback * callback ( mixed $carry , mixed $key , mixed $value ) : mixed * carry The return value of the previous callback, or initial if * it's the first iteration. * key The key of the current iteration. * value The value of the current iteration. * * @param TCarry $initial The initial value of the carry value. Can be * NULL. * * @return TCarry * @link https://www.php.net/manual/en/ds-map.reduce.php */ public function reduce(callable $callback, $initial) {} /** * Removes and returns a value by key, or return an optional default * value if the key could not be found. * * @template TDefault * @param TKey $key The key to remove. * @param TDefault $default The optional default value, returned if the key * could not be found. * * Note: Keys of type object are supported. If an object implements * Ds\Hashable, equality will be determined * by the object's equals function. If an object does not implement * Ds\Hashable, objects must be references to the same instance to be * considered equal. * * Note: You can also use array syntax to access values by key, eg. * $map["key"]. * * Caution: Be careful when using array syntax. Scalar keys will be * coerced to integers by the engine. For example, $map["1"] will * attempt to access int(1), while $map->get("1") will correctly look up * the string key. * * @return TValue|TDefault The value that was removed, or the default value if * provided and the key could not be found in the map. * * @throws OutOfBoundsException if the key could not be found and a * default value was not provided. * * @link https://www.php.net/manual/en/ds-map.remove.php */ public function remove($key, $default = null) {} /** * Reverses the map in-place. * * @link https://www.php.net/manual/en/ds-map.reverse.php */ public function reverse() {} /** * Returns a reversed copy of the map. * * @return Map A reversed copy of the map. * *

    Note: The current instance is not affected.

    * * @link https://www.php.net/manual/en/ds-map.reversed.php */ public function reversed(): Map {} /** * Returns the pair at a given zero-based position. * * @param int $position The zero-based positional index to return. * * @return Pair Returns the Ds\Pair at the given position. * * @throws OutOfRangeException if the position is not valid. * * @link https://www.php.net/manual/en/ds-map.skip.php */ public function skip(int $position): Pair {} /** * Returns a subset of the map defined by a starting index and length. * * @param int $index The index at which the range starts. If positive, * the range will start at that index in the map. If negative, the range * will start that far from the end. * * @param int|null $length If a length is given and is positive, the * resulting map will have up to that many pairs in it. If a length is * given and is negative, the range will stop that many pairs from the * end. If the length results in an overflow, only pairs up to the end * of the map will be included. If a length is not provided, the * resulting map will contain all pairs between the index and the end of * the map. * * @return Map A subset of the map defined by a starting index and * length. * * @link https://www.php.net/manual/en/ds-map.slice.php */ public function slice(int $index, ?int $length = null): Map {} /** * Sorts the map in-place by value, using an optional comparator * function. * * @param callable(TValue, TValue): int|null $comparator The comparison function must return * an integer less than, equal to, or greater than zero if the first * argument is considered to be respectively less than, equal to, or * greater than the second. Note that before PHP 7.0.0 this integer had * to be in the range from -2147483648 to 2147483647. * * callback ( mixed $a, mixed $b ) : int * * Caution: Returning non-integer values from the comparison function, * such as float, will result in an internal cast to integer of the * callback's return value. So values such as 0.99 and 0.1 will both be * cast to an integer value of 0, which will compare such values as * equal. * * @link https://www.php.net/manual/en/ds-map.sort.php */ public function sort(?callable $comparator = null) {} /** * Returns a copy, sorted by value using an optional comparator function. * * @param callable(TValue, TValue): int|null $comparator The comparison function must return * an integer less than, equal to, or greater than zero if the first * argument is considered to be respectively less than, equal to, or * greater than the second. Note that before PHP 7.0.0 this integer had * to be in the range from -2147483648 to 2147483647. * * callback ( mixed $a, mixed $b ) : int * * Caution: Returning non-integer values from the comparison function, * such as float, will result in an internal cast to integer of the * callback's return value. So values such as 0.99 and 0.1 will both be * cast to an integer value of 0, which will compare such values as * equal. * * @return Map * * @link https://www.php.net/manual/en/ds-map.sorted.php */ public function sorted(?callable $comparator = null): Map {} /** * Returns the sum of all values in the map. * * Note: Arrays and objects are considered equal to zero when * calculating the sum. * * @return float|int The sum of all the values in the map as either a * float or int depending on the values in the map. * * @link https://www.php.net/manual/en/ds-map.sum.php */ public function sum(): float|int {} /** * Creates a new map using values from the current instance and another * map. * * A ∪ B = {x: x ∈ A ∨ x ∈ B} * *

    Note: Values of the current instance will be overwritten by those * provided where keys are equal.

    * * @template TKey2 * @template TValue2 * @param Map $map The other map, to combine with the current instance. * * @return Map A new map containing all the pairs of the current * instance as well as another map. * * @link https://www.php.net/manual/en/ds-map.union.php */ public function union(Map $map): Map {} /** * Returns a sequence containing all the values of the map, in the same * order. * * @return Sequence A Ds\Sequence containing all the values of the map. * * @link https://www.php.net/manual/en/ds-map.values.php */ public function values(): Sequence {} /** * Creates a new map containing keys of the current instance as well as * another map, but not of both. * * A ⊖ B = {x : x ∈ (A \ B) ∪ (B \ A)} * * @template TKey2 * @template TValue2 * @param Map $map The other map. * * @return Map A new map containing keys in the current instance as well * as another map, but not in both. * * @link https://www.php.net/manual/en/ds-map.xor.php */ public function xor(Map $map): Map {} /** * @param TKey $offset */ public function offsetExists(mixed $offset): bool {} /** * @param TKey $offset * * @return TValue */ public function offsetGet(mixed $offset) {} /** * @param TKey $offset * @param TValue $value */ public function offsetSet(mixed $offset, mixed $value) {} /** * @param TKey $offset */ public function offsetUnset(mixed $offset): void {} } /** * A pair is used by Ds\Map to pair keys with values. * @package Ds * @template-covariant TKey * @template-covariant TValue */ class Pair implements JsonSerializable { /** * @var TKey */ public $key; /** * @var TValue */ public $value; /** * Creates a new instance using a given key and value. * * @param TKey $key * @param TValue $value * * @link https://php.net/manual/en/ds-pair.construct.php */ public function __construct($key = null, $value = null) {} /** * Removes all values from the pair. * * @link https://php.net/manual/en/ds-pair.clear.php */ public function clear() {} /** * Returns a shallow copy of the pair. * * @return Pair Returns a shallow copy of the pair. * * @link https://php.net/manual/en/ds-pair.copy.php */ public function copy(): Pair {} /** * Returns whether the pair is empty. * * @return bool Returns TRUE if the pair is empty, FALSE otherwise. * * @link https://php.net/manual/en/ds-pair.isempty.php */ public function isEmpty(): bool {} /** * Converts the pair to an array. * *

    Note: Casting to an array is not supported yet.

    * * @return array{key: TKey, value: TValue} An array containing all the values in the same order as * the pair. * * @link https://php.net/manual/en/ds-pair.toarray.php */ public function toArray(): array {} /** * Specify data which should be serialized to JSON * @link https://php.net/manual/en/ds-pair.jsonserialize.php * @return mixed data which can be serialized by json_encode, * which is a value of any type other than a resource. */ public function jsonSerialize() {} } /** * A Set is a sequence of unique values. This implementation uses the same * hash table as Ds\Map, where values are used as keys and the mapped value * is ignored. * * @link https://www.php.net/manual/en/class.ds-set.php * * @package Ds * @template TValue * @implements Collection */ class Set implements Collection, ArrayAccess { /** * Creates a new instance, using either a traversable object or an array * for the initial values. * * @param iterable $values A traversable object of an array to * use the initial values. * * @link https://php.net/manual/en/ds-set.construct.php */ public function __construct(iterable $values = []) {} /** * Adds all given values to the set that haven't already been added. * *

    Note: Values of type object are supported. If an object implements * Ds\Hashable, equality will be determined by the object's equals * function. If an object does not implement Ds\Hashable, objects must * be references to the same instance to be considered equal. * *

    Caution: All comparisons are strict (type and value). * * @param TValue ...$values Values to add to the set. * * @link https://php.net/manual/en/ds-set.add.php */ public function add(...$values) {} /** * Allocates enough memory for a required capacity. * * @param int $capacity The number of values for which capacity should * be allocated. * *

    Note: Capacity will stay the same if this value is less than or * equal to the current capacity. * *

    Capacity will always be rounded up to the nearest power of 2. * * @link https://php.net/manual/en/ds-set.allocate.php */ public function allocate(int $capacity) {} /** * Determines if the set contains all values. * *

    Values of type object are supported. If an object implements * Ds\Hashable, equality will be determined by the object's equals * function. If an object does not implement Ds\Hashable, objects must * be references to the same instance to be considered equal. * *

    Caution: All comparisons are strict (type and value). * * @param TValue ...$values Values to check. * * @return bool * * @link https://php.net/manual/en/ds-set.contains.php */ public function contains(...$values): bool {} /** * Returns the current capacity. * @link https://www.php.net/manual/en/ds-set.capacity.php * * @return int */ public function capacity(): int {} /** * Removes all values from the set. * @link https://www.php.net/manual/en/ds-set.clear.php */ public function clear(): void {} /** * Count elements of an object * @link https://php.net/manual/en/ds-set.count.php * @return int The custom count as an integer. *

    *

    * The return value is cast to an integer. * @since 5.1 */ public function count(): int {} /** * Returns a shallow copy of the set. * @link https://www.php.net/manual/en/ds-set.copy.php * @return Set */ public function copy(): Set {} /** * Creates a new set using values that aren't in another set. * * A \ B = {x ∈ A | x ∉ B} * * @link https://www.php.net/manual/en/ds-set.diff.php * * @template TValue2 * @param Set $set Set containing the values to exclude. * * @return Set A new set containing all values that were not in the * other set. */ public function diff(Set $set): Set {} /** * Creates a new set using a callable to determine which values to * include * * @link https://www.php.net/manual/en/ds-set.filter.php * * @param null|callable(TValue): bool $callback Optional callable which returns TRUE if the * value should be included, FALSE otherwise. * If a callback is not provided, only values which are TRUE (see * converting to boolean) will be included. * * @return Set A new set containing all the values for which either the * callback returned TRUE, or all values that convert to TRUE if a * callback was not provided. */ public function filter(?callable $callback = null): Set {} /** * Returns the first value in the set. * * @link https://www.php.net/manual/en/ds-set.first.php * * @return TValue The first value in the set. */ public function first() {} /** * Returns the value at a given index. * * @link https://www.php.net/manual/en/ds-set.get.php * * @param int $index The index to access, starting at 0. * * @return TValue The value at the requested index. */ public function get(int $index) {} /** * @return Traversable */ public function getIterator(): Traversable {} /** * Creates a new set using values common to both the current instance * and another set. In other words, returns a copy of the current * instance with all values removed that are not in the other set. * * A ∩ B = {x : x ∈ A ∧ x ∈ B} * * @link https://www.php.net/manual/en/ds-set.intersect.php * * @template TValue2 * @param Set $set The other set. * @return Set The intersection of the current instance and another set. */ public function intersect(Set $set): Set {} /** * Returns whether the set is empty. * @link https://www.php.net/manual/en/ds-set.isempty.php * * @return bool */ public function isEmpty(): bool {} /** * Joins all values together as a string using an optional separator * between each value. * * @link https://www.php.net/manual/en/ds-set.join.php * * @param null|string $glue An optional string to separate each value. * * @return string */ public function join(?string $glue = null): string {} /** * Returns the result of applying a callback function to each value in * the set. * @template TNewValue * @param callable(TValue): TNewValue $callback A callable to apply to each value in the * set. * The callable should return what the new value will be in the new * set. * callback ( mixed $value ) : mixed * @return Set The result of applying a callback to each value in * the set. *

    Note: The values of the current instance won't be affected.

    */ public function map(callable $callback): Set {} /** * Returns the result of adding all given values to the set. * *

    Note: The current instance won't be affected.

    * * @link https://www.php.net/manual/en/ds-set.merge.php * * @template TValue2 * @param iterable $values A traversable object or an array. * * @return Set The result of adding all given values to the set, * effectively the same as adding the values to a copy, then returning * that copy. */ public function merge($values): Set {} /** * Reduces the set to a single value using a callback function. * * @link https://www.php.net/manual/en/ds-set.reduce.php * * @template TCarry * @param callable(TCarry, TValue): TCarry $callback * callback ( mixed $carry , mixed $value ) : mixed * $carry The return value of the previous callback, or initial if * it's the first iteration. * $value The value of the current iteration. * * @param TCarry $initial The initial value of the carry value. Can be * NULL. * * @return TCarry The return value of the final callback. */ public function reduce(callable $callback, $initial = null) {} /** * Removes all given values from the set, ignoring any that are not in * the set. * * @link https://www.php.net/manual/en/ds-set.remove.php * * @param TValue ...$values The values to remove. */ public function remove(...$values) {} /** * Reverses the set in-place. * * @link https://www.php.net/manual/en/ds-set.reverse.php */ public function reverse() {} /** * Returns a reversed copy of the set. * * @link https://www.php.net/manual/en/ds-set.reversed.php * *

    Note: The current instance is not affected.

    * * @return Set A reversed copy of the set. */ public function reversed(): Set {} /** * Returns a sub-set of a given range * * @param int $index The index at which the sub-set starts. If positive, * the set will start at that index in * the set. If negative, the set will start that far from the end. * * @param int|null $length If a length is given and is positive, the * resulting set will have up to that many values in it. If the length * results in an overflow, only values up to the end of the set will be * included. If a length is given and is negative, the set will stop * that many values from the end. If a length is not provided, the * resulting set will contain all values between the index and the end * of the set. * * @return Set A sub-set of the given range. */ public function slice(int $index, ?int $length = null): Set {} /** * Returns the last value in the set. * * @link https://www.php.net/manual/en/ds-set.last.php * * @return TValue The last value in the set. * * @throws UnderflowException if empty. */ public function last() {} /** * Sorts the set in-place, using an optional comparator function. * * @param callable(TValue, TValue): int|null $comparator The comparison function must return * an integer less than, equal to, or greater than zero if the first * argument is considered to be respectively less than, equal to, or * greater than the second. Note that before PHP 7.0.0 this integer had * to be in the range from -2147483648 to 2147483647. * callback ( mixed $a, mixed $b ) : int * Caution: Returning non-integer values from the comparison * function, such as float, will result in an internal cast to integer * of the callback's return value. So values such as 0.99 and 0.1 will * both be cast to an integer value of 0, which will compare such values * as equal. * * @link https://www.php.net/manual/en/ds-set.sort.php */ public function sort(?callable $comparator = null) {} /** * Returns a sorted copy, using an optional comparator function. * * @link https://www.php.net/manual/en/ds-set.sorted.php * * @param null|callable(TValue, TValue): int $comparator The comparison function must return an * integer less than, equal to, or greater than zero if the first * argument is considered to be respectively less than, equal to, or * greater than the second. Note that before PHP 7.0.0 this integer had * to be in the range from -2147483648 to 2147483647. * * callback ( mixed $a, mixed $b ) : int * *

    Caution: Returning non-integer values from the comparison * function, such as float, will result in an * internal cast to integer of the callback's return value. So values * such as 0.99 and 0.1 will both be cast to an integer value of 0, * which will compare such values as equal.

    * * @return Set Returns a sorted copy of the set. */ public function sorted(?callable $comparator = null): Set {} /** * Returns the sum of all values in the set. * *

    Note: Arrays and objects are considered equal to zero when * calculating the sum.

    * * @link https://www.php.net/manual/en/ds-set.sum.php * * @return float|int The sum of all the values in the set as either a * float or int depending on the values in the set. */ public function sum(): float|int {} /** * Creates a new set that contains the values of the current instance as * well as the values of another set. * * A ∪ B = {x: x ∈ A ∨ x ∈ B} * * @link https://www.php.net/manual/en/ds-set.union.php * * @template TValue2 * @param Set $set The other set, to combine with the current instance. * * @return Set A new set containing all the values of the current * instance as well as another set. */ public function union(Set $set): Set {} /** * Creates a new set using values in either the current instance or in * another set, but not in both. * * A ⊖ B = {x : x ∈ (A \ B) ∪ (B \ A)} * * @link https://www.php.net/manual/en/ds-set.xor.php * * @template TValue2 * @param Set $set The other set. * * @return Set A new set containing values in the current instance as * well as another set, but not in both. */ public function xor(Set $set): Set {} /** * Converts the set to an array. *

    Note: Casting to an array is not supported yet.

    * @link https://www.php.net/manual/en/ds-set.toarray.php * @return array An array containing all the values in the same order as * the collection. */ public function toArray(): array {} /** * Specify data which should be serialized to JSON * @link https://php.net/manual/en/ds-set.jsonserialize.php * @return mixed data which can be serialized by json_encode, * which is a value of any type other than a resource. * @since 5.4 */ public function jsonSerialize() {} /** * @param int $offset */ public function offsetExists(mixed $offset): bool {} /** * @param int $offset * * @return TValue */ public function offsetGet(mixed $offset) {} /** * @param int $offset * @param TValue $value */ public function offsetSet(mixed $offset, mixed $value) {} /** * @param int $offset */ public function offsetUnset(mixed $offset): void {} } /** * A Stack is a “last in, first out” or “LIFO” collection that only allows * access to the value at the top of the structure and iterates in that * order, destructively. * * @package Ds * @template TValue * @implements Collection * * @link https://www.php.net/manual/en/class.ds-stack.php */ class Stack implements Collection, ArrayAccess { /** * Creates a new instance, using either a traversable object or an array * for the initial values. * * @link https://www.php.net/manual/en/ds-stack.construct.php * * @param iterable $values A traversable object or an * array to use for the initial values. */ public function __construct($values = []) {} /** * Ensures that enough memory is allocated for a required capacity. This * removes the need to reallocate the internal as values are added. * * @link https://www.php.net/manual/en/ds-stack.allocate.php * * @param int $capacity The number of values for which capacity should * be allocated. * *

    Note: Capacity will stay the same if this value is less than or * equal to the current capacity.

    */ public function allocate(int $capacity) {} /** * Returns the current capacity. * * @link https://www.php.net/manual/en/ds-stack.capacity.php * * @return int The current capacity. */ public function capacity(): int {} /** * Removes all values from the stack. * @link https://www.php.net/manual/en/ds-stack.clear.php */ public function clear(): void {} /** * Count elements of an object * @link https://php.net/manual/en/ds-stack.count.php * @return int The custom count as an integer. *

    *

    * The return value is cast to an integer. * @since 5.1 */ public function count(): int {} /** * Returns a shallow copy of the collection. * @link https://www.php.net/manual/en/ds-stack.copy.php * @return Stack */ public function copy(): Stack {} /** * @return Traversable */ public function getIterator(): Traversable {} /** * Returns whether the collection is empty. * @link https://www.php.net/manual/en/ds-stack.isempty.php * @return bool */ public function isEmpty(): bool {} /** * Converts the collection to an array. *

    Note: Casting to an array is not supported yet.

    * @link https://www.php.net/manual/en/ds-stack.toarray.php * @return array An array containing all the values in the same order as * the collection. */ public function toArray(): array {} /** * Specify data which should be serialized to JSON * @link https://php.net/manual/en/jsonserializable.jsonserialize.php * @return mixed data which can be serialized by json_encode, * which is a value of any type other than a resource. * @since 5.4 */ public function jsonSerialize() {} /** * Returns the value at the top of the stack, but does not remove it. * * @link https://www.php.net/manual/en/ds-queue.peek.php * * @return TValue The value at the top of the stack. * * @throws UnderflowException */ public function peek() {} /** * Removes and returns the value at the top of the stack. * * @link https://www.php.net/manual/en/ds-queue.pop.php * * @return TValue The removed value which was at the top of the stack. * * @throws UnderflowException */ public function pop() {} /** * Pushes values onto the stack. * * @link https://www.php.net/manual/en/ds-queue.push.php * * @param TValue ...$values The values to push onto the stack. */ public function push(...$values) {} /** * @param int $offset */ public function offsetExists(mixed $offset): bool {} /** * @param int $offset * * @return TValue */ public function offsetGet(mixed $offset) {} /** * @param int $offset * @param TValue $value */ public function offsetSet(mixed $offset, mixed $value) {} /** * @param int $offset */ public function offsetUnset(mixed $offset): void {} } /** * A Queue is a “first in, first out” or “FIFO” collection that only allows * access to the value at the front of the queue and iterates in that order, * destructively. * * Uses a Ds\Vector internally. * * @package Ds * @template TValue * @implements Collection */ class Queue implements Collection, ArrayAccess { /** * Creates a new instance, using either a traversable object or an array * for the initial values. * * @link https://www.php.net/manual/en/ds-queue.construct.php * * @param iterable $values A traversable object or an * array to use for the initial values. */ public function __construct($values = []) {} /** * Ensures that enough memory is allocated for a required capacity. This * removes the need to reallocate the internal as values are added. * * @link https://www.php.net/manual/en/ds-queue.allocate.php * * @param int $capacity The number of values for which capacity should * be allocated. * *

    Note: Capacity will stay the same if this value is less than or * equal to the current capacity.

    */ public function allocate(int $capacity) {} /** * Returns the current capacity. * * @link https://www.php.net/manual/en/ds-queue.capacity.php * * @return int The current capacity. */ public function capacity(): int {} /** * Removes all values from the queue. * @link https://www.php.net/manual/en/ds-queue.clear.php */ public function clear(): void {} /** * Count elements of an object * @link https://php.net/manual/en/ds-queue.count.php * @return int The custom count as an integer. *

    *

    * The return value is cast to an integer. * @since 5.1 */ public function count(): int {} /** * Returns a shallow copy of the collection. * @link https://www.php.net/manual/en/ds-queue.copy.php * @return Queue */ public function copy(): Queue {} /** * @return Traversable */ public function getIterator(): Traversable {} /** * Returns whether the collection is empty. * @link https://www.php.net/manual/en/ds-queue.isempty.php * @return bool */ public function isEmpty(): bool {} /** * Converts the collection to an array. *

    Note: Casting to an array is not supported yet.

    * @link https://www.php.net/manual/en/ds-queue.toarray.php * @return array An array containing all the values in the same order as * the collection. */ public function toArray(): array {} /** * Specify data which should be serialized to JSON * @link https://php.net/manual/en/jsonserializable.jsonserialize.php * @return mixed data which can be serialized by json_encode, * which is a value of any type other than a resource. * @since 5.4 */ public function jsonSerialize() {} /** * Returns the value at the top of the queue, but does not remove it. * * @link https://www.php.net/manual/en/ds-queue.peek.php * * @return TValue The value at the top of the queue. * * @throws UnderflowException */ public function peek() {} /** * Removes and returns the value at the top of the queue. * * @link https://www.php.net/manual/en/ds-queue.pop.php * * @return TValue The removed value which was at the top of the queue. * * @throws UnderflowException */ public function pop() {} /** * Pushes values onto the queue. * * @link https://www.php.net/manual/en/ds-queue.push.php * * @param TValue ...$values The values to push onto the queue. */ public function push(...$values) {} /** * @param int $offset */ public function offsetExists(mixed $offset): bool {} /** * @param int $offset * * @return TValue */ public function offsetGet(mixed $offset) {} /** * @param int $offset * @param TValue $value */ public function offsetSet(mixed $offset, mixed $value) {} /** * @param int $offset */ public function offsetUnset(mixed $offset): void {} } /** * A PriorityQueue is very similar to a Queue. Values are pushed into the * queue with an assigned priority, and the value with the highest priority * will always be at the front of the queue. * * Implemented using a max heap. * * @package Ds * @template TValue * @implements Collection * * @link https://www.php.net/manual/en/class.ds-priorityqueue.php */ class PriorityQueue implements Collection { public const MIN_CAPACITY = 8; /** * Count elements of an object * @link https://php.net/manual/en/countable.count.php * @return int The custom count as an integer. *

    *

    * The return value is cast to an integer. * @since 5.1 */ public function count(): int {} /** * Allocates enough memory for a required capacity * @link https://www.php.net/manual/en/ds-priorityqueue.allocate.php * * @param int $capacity */ public function allocate(int $capacity): void {} /** * Returns the current capacity * @link https://www.php.net/manual/en/ds-priorityqueue.capacity.php * * @return int */ public function capacity(): int {} /** * Removes all values from the collection. * @link https://www.php.net/manual/en/ds-collection.clear.php */ public function clear(): void {} /** * Returns a shallow copy of the collection. * @link https://www.php.net/manual/en/ds-collection.copy.php * @return PriorityQueue */ public function copy() {} /** * @return Traversable */ public function getIterator(): Traversable {} /** * Returns whether the collection is empty. * @link https://www.php.net/manual/en/ds-collection.isempty.php * @return bool */ public function isEmpty(): bool {} /** * Returns the value at the front of the queue, but does not remove it. * @link https://www.php.net/manual/en/ds-priorityqueue.peek.php * * @return TValue The value at the front of the queue. * @throws UnderflowException if empty. */ public function peek() {} /** * Removes and returns the value with the highest priority * @link https://www.php.net/manual/en/ds-priorityqueue.pop.php * * @return TValue The removed value which was at the front of the queue. * @throws UnderflowException if empty. */ public function pop() {} /** * Pushes a value with a given priority into the queue. * * @param TValue $value * @param int $priority */ public function push($value, int $priority) {} /** * Converts the collection to an array. *

    Note: Casting to an array is not supported yet.

    * @link https://www.php.net/manual/en/ds-collection.toarray.php * @return array An array containing all the values in the same order as * the collection. */ public function toArray(): array {} /** * Specify data which should be serialized to JSON * @link https://php.net/manual/en/jsonserializable.jsonserialize.php * @return mixed data which can be serialized by json_encode, * which is a value of any type other than a resource. * @since 5.4 */ public function jsonSerialize() {} } */ function kafka_get_err_descs(): array {} /** * Returns an offset value that is $offset before the tail of the topic * * @param int $offset * @return int */ function kafka_offset_tail(int $offset): int {} /** * Retrieve the current number of threads in use by librdkafka. * * @return int */ function kafka_thread_cnt(): int {} */ public array $headers; /** * @return string */ public function getErrorString(): string {} } */ public function dump(): array {} /** * @param string $name * @param string $value */ public function set(string $name, string $value): void {} /** * @param callable $callback */ public function setErrorCb(callable $callback): void {} /** * @param callable $callback */ public function setDrMsgCb(callable $callback): void {} /** * @param callable $callback */ public function setStatsCb(callable $callback): void {} /** * @param callable $callback */ public function setRebalanceCb(callable $callback): void {} /** * @param callable $callback */ public function setOffsetCommitCb(callable $callback): void {} /** * @param callable $callback */ public function setLogCb(callable $callback): void {} /** * @param callable $callback */ public function setOAuthBearerTokenRefreshCb(callable $callback): void {} } |null $headers * @param int|null $timestampMs * @throws Exception */ public function producev(int $partition, int $msgFlags, ?string $payload = null, ?string $key = null, ?array $headers = null, ?int $timestampMs = null): void {} } * Get GeoIP Database information * @link https://php.net/manual/en/function.geoip-database-info.php * @param int $database [optional]

    * The database type as an integer. You can use the * various constants defined with * this extension (ie: GEOIP_*_EDITION). *

    * @return string|null the corresponding database version, or NULL on error. */ #[Pure] function geoip_database_info($database = GEOIP_COUNTRY_EDITION) {} /** * (PECL geoip >= 0.2.0)
    * Get the two letter country code * @link https://php.net/manual/en/function.geoip-country-code-by-name.php * @param string $hostname

    * The hostname or IP address whose location is to be looked-up. *

    * @return string|false the two letter ISO country code on success, or FALSE * if the address cannot be found in the database. */ #[Pure] function geoip_country_code_by_name($hostname) {} /** * (PECL geoip >= 0.2.0)
    * Get the three letter country code * @link https://php.net/manual/en/function.geoip-country-code3-by-name.php * @param string $hostname

    * The hostname or IP address whose location is to be looked-up. *

    * @return string|false the three letter country code on success, or FALSE * if the address cannot be found in the database. */ #[Pure] function geoip_country_code3_by_name($hostname) {} /** * (PECL geoip >= 0.2.0)
    * Get the full country name * @link https://php.net/manual/en/function.geoip-country-name-by-name.php * @param string $hostname

    * The hostname or IP address whose location is to be looked-up. *

    * @return string|false the country name on success, or FALSE if the address cannot * be found in the database. */ #[Pure] function geoip_country_name_by_name($hostname) {} /** * (PECL geoip >= 1.0.3)
    * Get the two letter continent code * @link https://php.net/manual/en/function.geoip-continent-code-by-name.php * @param string $hostname

    * The hostname or IP address whose location is to be looked-up. *

    * @return string|false the two letter continent code on success, or FALSE if the * address cannot be found in the database. */ #[Pure] function geoip_continent_code_by_name($hostname) {} /** * (PECL geoip >= 0.2.0)
    * Get the organization name * @link https://php.net/manual/en/function.geoip-org-by-name.php * @param string $hostname

    * The hostname or IP address. *

    * @return string|false the organization name on success, or FALSE if the address * cannot be found in the database. */ #[Pure] function geoip_org_by_name($hostname) {} /** * (PECL geoip >= 0.2.0)
    * Returns the detailed City information found in the GeoIP Database * @link https://php.net/manual/en/function.geoip-record-by-name.php * @param string $hostname

    * The hostname or IP address whose record is to be looked-up. *

    * @return array|false the associative array on success, or FALSE if the address * cannot be found in the database. */ #[Pure] function geoip_record_by_name($hostname) {} /** * (PECL geoip >= 0.2.0)
    * Get the Internet connection type * @link https://php.net/manual/en/function.geoip-id-by-name.php * @param string $hostname

    * The hostname or IP address whose connection type is to be looked-up. *

    * @return int the connection type. */ #[Pure] function geoip_id_by_name($hostname) {} /** * (PECL geoip >= 0.2.0)
    * Get the country code and region * @link https://php.net/manual/en/function.geoip-region-by-name.php * @param string $hostname

    * The hostname or IP address whose region is to be looked-up. *

    * @return array|false the associative array on success, or FALSE if the address * cannot be found in the database. */ #[Pure] function geoip_region_by_name($hostname) {} /** * (PECL geoip >= 1.0.2)
    * Get the Internet Service Provider (ISP) name * @link https://php.net/manual/en/function.geoip-isp-by-name.php * @param string $hostname

    * The hostname or IP address. *

    * @return string|false the ISP name on success, or FALSE if the address * cannot be found in the database. */ #[Pure] function geoip_isp_by_name($hostname) {} /** * (PECL geoip >= 1.0.1)
    * Determine if GeoIP Database is available * @link https://php.net/manual/en/function.geoip-db-avail.php * @param int $database

    * The database type as an integer. You can use the * various constants defined with * this extension (ie: GEOIP_*_EDITION). *

    * @return bool|null TRUE is database exists, FALSE if not found, or NULL on error. */ #[Pure] function geoip_db_avail($database) {} /** * (PECL geoip >= 1.0.1)
    * Returns detailed information about all GeoIP database types * @link https://php.net/manual/en/function.geoip-db-get-all-info.php * @return array the associative array. */ #[Pure] function geoip_db_get_all_info() {} /** * (PECL geoip >= 1.0.1)
    * Returns the filename of the corresponding GeoIP Database * @link https://php.net/manual/en/function.geoip-db-filename.php * @param int $database

    * The database type as an integer. You can use the * various constants defined with * this extension (ie: GEOIP_*_EDITION). *

    * @return string|null the filename of the corresponding database, or NULL on error. */ #[Pure] function geoip_db_filename($database) {} /** * (PECL geoip >= 1.0.4)
    * Returns the region name for some country and region code combo * @link https://php.net/manual/en/function.geoip-region-name-by-code.php * @param string $country_code

    * The two-letter country code (see * geoip_country_code_by_name) *

    * @param string $region_code

    * The two-letter (or digit) region code (see * geoip_region_by_name) *

    * @return string|false the region name on success, or FALSE if the country and region code * combo cannot be found. */ #[Pure] function geoip_region_name_by_code($country_code, $region_code) {} /** * (PECL geoip >= 1.0.4)
    * Returns the time zone for some country and region code combo * @link https://php.net/manual/en/function.geoip-time-zone-by-country-and-region.php * @param string $country_code

    * The two-letter country code (see * geoip_country_code_by_name) *

    * @param string $region_code [optional]

    * The two-letter (or digit) region code (see * geoip_region_by_name) *

    * @return string|false the time zone on success, or FALSE if the country and region code * combo cannot be found. */ #[Pure] function geoip_time_zone_by_country_and_region($country_code, $region_code = null) {} define('GEOIP_COUNTRY_EDITION', 1); define('GEOIP_REGION_EDITION_REV0', 7); define('GEOIP_CITY_EDITION_REV0', 6); define('GEOIP_ORG_EDITION', 5); define('GEOIP_ISP_EDITION', 4); define('GEOIP_CITY_EDITION_REV1', 2); define('GEOIP_REGION_EDITION_REV1', 3); define('GEOIP_PROXY_EDITION', 8); define('GEOIP_ASNUM_EDITION', 9); define('GEOIP_NETSPEED_EDITION', 10); define('GEOIP_DOMAIN_EDITION', 11); define('GEOIP_UNKNOWN_SPEED', 0); define('GEOIP_DIALUP_SPEED', 1); define('GEOIP_CABLEDSL_SPEED', 2); define('GEOIP_CORPORATE_SPEED', 3); /** * (PECL geoip >= 1.1.0)
    *

    * The geoip_asnum_by_name() function will return the Autonomous System Numbers (ASN) associated with an IP address. *

    * @link https://secure.php.net/manual/en/function.geoip-asnum-by-name.php * @param string $hostname The hostname or IP address * * @return string|false Returns the ASN on success, or FALSE if the address cannot be found in the database. * @since 1.1.0 */ function geoip_asnum_by_name($hostname) {} /** * (PECL geoip >= 1.1.0)
    *

    * The geoip_netspeedcell_by_name() function will return the Internet connection type and speed corresponding to a hostname or an IP address.
    *
    * This function is only available if using GeoIP Library version 1.4.8 or newer.
    *
    * This function is currently only available to users who have bought a commercial GeoIP NetSpeedCell Edition. A warning will be issued if the proper database cannot be located.
    *
    * The return value is a string, common values are:
    * - Cable/DSL
    * - Dialup
    * - Cellular
    * - Corporate
    *

    * @link https://secure.php.net/manual/en/function.geoip-netspeedcell-by-name.php * @param string $hostname The hostname or IP address * * @return string|false Returns the connection speed on success, or FALSE if the address cannot be found in the database. * @since 1.1.0 */ function geoip_netspeedcell_by_name($hostname) {} /** * (PECL geoip >= 1.1.0)
    *

    * The geoip_setup_custom_directory() function will change the default directory of the GeoIP database. This is equivalent to changing geoip.custom_directory *

    * @link https://secure.php.net/manual/en/function.geoip-setup-custom-directory.php * @param string $path The full path of where the GeoIP database is on disk. * * @return void * @since 1.1.0 */ function geoip_setup_custom_directory($path) {} // End of geoip v.1.1.0 * PASSWORD_BCRYPT is used to create new password * hashes using the CRYPT_BLOWFISH algorithm. *

    *

    * This will always result in a hash using the "$2y$" crypt format, * which is always 60 characters wide. *

    *

    * Supported Options: *

    *
      *
    • *

      * salt - to manually provide a salt to use when hashing the password. * Note that this will override and prevent a salt from being automatically generated. *

      *

      * If omitted, a random salt will be generated by {@link "https://secure.php.net/manual/en/function.password-hash.php" password_hash()} for * each password hashed. This is the intended mode of operation. *

      *
    • *
    • *

      * cost - which denotes the algorithmic cost that should be used. * Examples of these values can be found on the {@link "https://secure.php.net/manual/en/function.crypt.php crypt()"} page. *

      *

      * If omitted, a default value of 10 will be used. This is a good * baseline cost, but you may want to consider increasing it depending on your hardware. *

      *
    • *
    * @link https://secure.php.net/manual/en/password.constants.php */ use JetBrains\PhpStorm\ArrayShape; use JetBrains\PhpStorm\Internal\LanguageLevelTypeAware; define("PASSWORD_DEFAULT", "2y"); /** *

    * The default cost used for the BCRYPT hashing algorithm. *

    *

    * Values for this constant: *

    *
      *
    • * PHP 5.6.0 - PASSWORD_BCRYPT_DEFAULT_COST *
    • *
    */ define("PASSWORD_BCRYPT_DEFAULT_COST", 10); /** *

    * The default algorithm to use for hashing if no algorithm is provided. * This may change in newer PHP releases when newer, stronger hashing * algorithms are supported. *

    *

    * It is worth noting that over time this constant can (and likely will) * change. Therefore you should be aware that the length of the resulting * hash can change. Therefore, if you use PASSWORD_DEFAULT * you should store the resulting hash in a way that can store more than 60 * characters (255 is the recommended width). *

    *

    * Values for this constant: *

    *
      *
    • * PHP 5.5.0 - PASSWORD_BCRYPT *
    • *
    */ define("PASSWORD_BCRYPT", '2y'); /** * PASSWORD_ARGON2I is used to create new password hashes using the Argon2i algorithm. * * Supported Options: *
      *
    • memory_cost (integer) - Maximum memory (in bytes) that may be used to compute the Argon2 hash. Defaults to PASSWORD_ARGON2_DEFAULT_MEMORY_COST.
    • * *
    • time_cost (integer) - Maximum amount of time it may take to compute the Argon2 hash. Defaults to PASSWORD_ARGON2_DEFAULT_TIME_COST.
    • * *
    • threads (integer) - Number of threads to use for computing the Argon2 hash. Defaults to PASSWORD_ARGON2_DEFAULT_THREADS.
    • *
    * Available as of PHP 7.2.0. * @since 7.2 */ define('PASSWORD_ARGON2I', 'argon2i'); /** * PASSWORD_ARGON2ID is used to create new password hashes using the Argon2id algorithm. * * Supported Options: *
      *
    • memory_cost (integer) - Maximum memory (in bytes) that may be used to compute the Argon2 hash. Defaults to PASSWORD_ARGON2_DEFAULT_MEMORY_COST.
    • * *
    • time_cost (integer) - Maximum amount of time it may take to compute the Argon2 hash. Defaults to PASSWORD_ARGON2_DEFAULT_TIME_COST.
    • * *
    • threads (integer) - Number of threads to use for computing the Argon2 hash. Defaults to PASSWORD_ARGON2_DEFAULT_THREADS.
    • *
    * Available as of PHP 7.3.0. * @since 7.3 */ define('PASSWORD_ARGON2ID', 'argon2id'); /** * Default amount of memory in bytes that Argon2lib will use while trying to compute a hash. * Available as of PHP 7.2.0. * @since 7.2 */ define('PASSWORD_ARGON2_DEFAULT_MEMORY_COST', 65536); /** * Default amount of time that Argon2lib will spend trying to compute a hash. * Available as of PHP 7.2.0. * @since 7.2 */ define('PASSWORD_ARGON2_DEFAULT_TIME_COST', 4); /** * Default number of threads that Argon2lib will use. * Available as of PHP 7.2.0. * @since 7.2 */ define('PASSWORD_ARGON2_DEFAULT_THREADS', 1); /** * @since 7.4 */ define('PASSWORD_ARGON2_PROVIDER', 'standard'); /** * Returns information about the given hash * @link https://secure.php.net/manual/en/function.password-get-info.php * @param string $hash A hash created by password_hash(). * @return array|null Returns an associative array with three elements: *
      *
    • * algo, which will match a * {@link https://secure.php.net/manual/en/password.constants.php password algorithm constant} *
    • *
    • * algoName, which has the human readable name of the algorithm *
    • *
    • * options, which includes the options * provided when calling @link https://secure.php.net/manual/en/function.password-hash.php" password_hash() *
    • *
    * @since 5.5 */ #[ArrayShape(["algo" => "int", "algoName" => "string", "options" => "array"])] #[LanguageLevelTypeAware(['8.0' => 'array'], default: '?array')] function password_get_info(string $hash) {} /** * (PHP 5 >= 5.5.0, PHP 5)
    * * Creates a password hash. * @link https://secure.php.net/manual/en/function.password-hash.php * @param string $password The user's password. * @param string|int|null $algo A password algorithm constant denoting the algorithm to use when hashing the password. * @param array $options [optional]

    An associative array containing options. See the password algorithm constants for documentation on the supported options for each algorithm.

    * If omitted, a random salt will be created and the default cost will be used. * Warning *

    * The salt option has been deprecated as of PHP 7.0.0. It is now * preferred to simply use the salt that is generated by default. *

    * @return string|false|null Returns the hashed password, or FALSE on failure, or null if the algorithm is invalid * @since 5.5 */ #[LanguageLevelTypeAware(["8.0" => "string"], default: "string|false|null")] function password_hash(string $password, string|int|null $algo, array $options = []) {} /** * Checks if the given hash matches the given options. * @link https://secure.php.net/manual/en/function.password-needs-rehash.php * @param string $hash A hash created by password_hash(). * @param string|int|null $algo A password algorithm constant denoting the algorithm to use when hashing the password. * @param array $options [optional]

    An associative array containing options. See the password algorithm constants for documentation on the supported options for each algorithm.

    * @return bool Returns TRUE if the hash should be rehashed to match the given algo and options, or FALSE otherwise. * @since 5.5 */ function password_needs_rehash(string $hash, string|int|null $algo, array $options = []): bool {} /** * Checks if the given hash matches the given options. * @link https://secure.php.net/manual/en/function.password-verify.php * @param string $password The user's password. * @param string $hash A hash created by password_hash(). * @return bool Returns TRUE if the password and hash match, or FALSE otherwise. * @since 5.5 */ function password_verify(string $password, string $hash): bool {} /** * Return a complete list of all registered password hashing algorithms. * @return string[] * @since 7.4 */ function password_algos(): array {} // End of password v. "int", "message" => "string", "file" => "string", "line" => "int"])] #[Pure(true)] function error_get_last(): ?array {} /** * Call the callback given by the first parameter * @link https://php.net/manual/en/function.call-user-func.php * @param callable $callback

    * The function to be called. Class methods may also be invoked * statically using this function by passing * array($classname, $methodname) to this parameter. * Additionally class methods of an object instance may be called by passing * array($objectinstance, $methodname) to this parameter. *

    * @param mixed ...$args [optional]

    * Zero or more parameters to be passed to the function. *

    *

    * Note that the parameters for call_user_func are * not passed by reference. * call_user_func example and references *

    * @return mixed the function result, or false on error. */ function call_user_func(callable $callback, mixed ...$args): mixed {} /** * Call a callback with an array of parameters * @link https://php.net/manual/en/function.call-user-func-array.php * @param callable $callback

    * The function to be called. *

    * @param array $args

    * The parameters to be passed to the function, as an indexed array. *

    * @return mixed the function result, or false on error. */ function call_user_func_array(callable $callback, array $args): mixed {} /** * Call a user method on an specific object * @link https://php.net/manual/en/function.call-user-method.php * @param string $method_name * @param object &$obj * @param mixed ...$parameter [optional] * @return mixed * @removed 7.0 * @see call_user_func() */ #[Deprecated(reason: "use call_user_func() instead", since: "5.3")] function call_user_method(string $method_name, object &$obj, ...$parameter): mixed {} /** * Call a user method given with an array of parameters * @link https://php.net/manual/en/function.call-user-method-array.php * @param string $method_name * @param object &$obj * @param array $params * @return mixed * @removed 7.0 * @see call_user_func() */ #[Deprecated(reason: "use call_user_func() instead", since: "5.3")] function call_user_method_array(string $method_name, object &$obj, array $params): mixed {} /** * Call a static method * @link https://php.net/manual/en/function.forward-static-call.php * @param callable $callback

    * The function or method to be called. This parameter may be an array, * with the name of the class, and the method, or a string, with a function * name. *

    * @param mixed ...$args [optional]

    * Zero or more parameters to be passed to the function. *

    * @return mixed the function result, or false on error. */ function forward_static_call(callable $callback, mixed ...$args): mixed {} /** * Call a static method and pass the arguments as array * @link https://php.net/manual/en/function.forward-static-call-array.php * @param callable $callback

    * The function or method to be called. This parameter may be an array, * with the name of the class, and the method, or a string, with a function * name. *

    * @param array $args * @return mixed the function result, or false on error. */ function forward_static_call_array(callable $callback, array $args): mixed {} /** * Generates a storable representation of a value * @link https://php.net/manual/en/function.serialize.php * @param mixed $value

    * The value to be serialized. serialize * handles all types, except the resource-type. * You can even serialize arrays that contain * references to itself. Circular references inside the array/object you * are serializing will also be stored. Any other * reference will be lost. *

    *

    * When serializing objects, PHP will attempt to call the member function * __sleep prior to serialization. * This is to allow the object to do any last minute clean-up, etc. prior * to being serialized. Likewise, when the object is restored using * unserialize the __wakeup member function is called. *

    *

    * Object's private members have the class name prepended to the member * name; protected members have a '*' prepended to the member name. * These prepended values have null bytes on either side. *

    * @return string a string containing a byte-stream representation of * value that can be stored anywhere. */ function serialize(mixed $value): string {} /** * Creates a PHP value from a stored representation * @link https://php.net/manual/en/function.unserialize.php * @param string $data

    * The serialized string. *

    *

    * If the variable being unserialized is an object, after successfully * reconstructing the object PHP will automatically attempt to call the * __wakeup member function (if it exists). *

    *

    * unserialize_callback_func directive *

    *

    * It's possible to set a callback-function which will be called, * if an undefined class should be instantiated during unserializing. * (to prevent getting an incomplete object "__PHP_Incomplete_Class".) * Use your "php.ini", ini_set or ".htaccess" * to define 'unserialize_callback_func'. Everytime an undefined class * should be instantiated, it'll be called. To disable this feature just * empty this setting. *

    * @param array $options [optional] *

    Any options to be provided to unserialize(), as an associative array.

    *

    * The 'allowed_classes' option key may be set to a value that is * either an array of class names which should be accepted, FALSE to * accept no classes, or TRUE to accept all classes. If this option is defined * and unserialize() encounters an object of a class that isn't to be accepted, * then the object will be instantiated as __PHP_Incomplete_Class instead. * Omitting this option is the same as defining it as TRUE: PHP will attempt * to instantiate objects of any class. *

    * @return mixed

    The converted value is returned, and can be a boolean, * integer, float, string, * array or object. *

    *

    * In case the passed string is not unserializeable, false is returned and * E_NOTICE is issued.

    */ function unserialize(string $data, #[PhpStormStubsElementAvailable(from: '7.0')] array $options = []): mixed {} /** * Dumps information about a variable * @link https://php.net/manual/en/function.var-dump.php * @param mixed $value

    * The variable you want to export. *

    * @param mixed ...$values [optional] * @return void */ #[PhpStormStubsElementAvailable(from: '8.0')] function var_dump(mixed $value, mixed ...$values): void {} /** * Dumps information about a variable * @link https://php.net/manual/en/function.var-dump.php * @param mixed ...$vars

    * The variable you want to export. *

    * @return void */ #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] function var_dump(...$vars): void {} /** * Outputs or returns a parsable string representation of a variable * @link https://php.net/manual/en/function.var-export.php * @param mixed $value

    * The variable you want to export. *

    * @param bool $return [optional]

    * If used and set to true, var_export will return * the variable representation instead of outputting it. *

    * @return string|null the variable representation when the return * parameter is used and evaluates to true. Otherwise, this function will * return null. */ function var_export(mixed $value, bool $return = false): ?string {} /** * Dumps a string representation of an internal zend value to output * @link https://php.net/manual/en/function.debug-zval-dump.php * @param mixed $value The variable being evaluated. * @param mixed ...$values

    * The other variable being evaluated. *

    * @return void */ function debug_zval_dump( #[PhpStormStubsElementAvailable(from: '8.0')] mixed $value, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $values, mixed ...$values ): void {} /** * Prints human-readable information about a variable * @link https://php.net/manual/en/function.print-r.php * @param mixed $value

    * The expression to be printed. *

    * @param bool $return [optional]

    * If you would like to capture the output of print_r, * use the return parameter. If this parameter is set * to true, print_r will return its output, instead of * printing it (which it does by default). *

    * @return string|bool If given a string, integer or float, * the value itself will be printed. If given an array, values * will be presented in a format that shows keys and elements. Similar * notation is used for objects. */ #[LanguageLevelTypeAware(['8.4' => 'string|true'], default: 'string|bool')] function print_r(mixed $value, bool $return = false) {} /** * Returns the amount of memory allocated to PHP * @link https://php.net/manual/en/function.memory-get-usage.php * @param bool $real_usage [optional]

    * Set this to true to get the real size of memory allocated from * system. If not set or false only the memory used by * emalloc() is reported. *

    * @return int the memory amount in bytes. */ #[Pure(true)] function memory_get_usage(bool $real_usage = false): int {} /** * Returns the peak of memory allocated by PHP * @link https://php.net/manual/en/function.memory-get-peak-usage.php * @param bool $real_usage [optional]

    * Set this to true to get the real size of memory allocated from * system. If not set or false only the memory used by * emalloc() is reported. *

    * @return int the memory peak in bytes. */ #[Pure(true)] function memory_get_peak_usage(bool $real_usage = false): int {} /** * @since 8.2 */ function memory_reset_peak_usage(): void {} /** * Register a function for execution on shutdown * @link https://php.net/manual/en/function.register-shutdown-function.php * @param callable $callback

    * The shutdown function to register. *

    *

    * The shutdown functions are called as the part of the request so that * it's possible to send the output from them. There is currently no way * to process the data with output buffering functions in the shutdown * function. *

    *

    * Shutdown functions are called after closing all opened output buffers * thus, for example, its output will not be compressed if zlib.output_compression is * enabled. *

    * @param mixed ...$args [optional]

    * It is possible to pass parameters to the shutdown function by passing * additional parameters. *

    * @return bool|null */ #[LanguageLevelTypeAware(['8.2' => 'void'], default: 'null|bool')] function register_shutdown_function(callable $callback, mixed ...$args): ?bool {} /** * Register a function for execution on each tick * @link https://php.net/manual/en/function.register-tick-function.php * @param callable $callback

    * The function name as a string, or an array consisting of an object and * a method. *

    * @param mixed ...$args [optional]

    *

    * @return bool true on success or false on failure. */ function register_tick_function(callable $callback, mixed ...$args): bool {} /** * De-register a function for execution on each tick * @link https://php.net/manual/en/function.unregister-tick-function.php * @param callable $callback

    * The function name as a string, or an array consisting of an object and * a method. *

    * @return void */ function unregister_tick_function(callable $callback): void {} /** * Syntax highlighting of a file * @link https://php.net/manual/en/function.highlight-file.php * @param string $filename

    * Path to the PHP file to be highlighted. *

    * @param bool $return [optional]

    * Set this parameter to true to make this function return the * highlighted code. *

    * @return string|bool If return is set to true, returns the highlighted * code as a string instead of printing it out. Otherwise, it will return * true on success, false on failure. */ function highlight_file(string $filename, bool $return = false): string|bool {} /** * Alias: * {@see highlight_file} * @link https://php.net/manual/en/function.show-source.php * @param string $filename * @param bool $return [optional] * @return string|bool */ function show_source(string $filename, bool $return = false): string|bool {} /** * Syntax highlighting of a string * @link https://php.net/manual/en/function.highlight-string.php * @param string $string

    * The PHP code to be highlighted. This should include the opening tag. *

    * @param bool $return [optional]

    * Set this parameter to true to make this function return the * highlighted code. *

    * @return string|bool If return is set to true, returns the highlighted * code as a string instead of printing it out. Otherwise, it will return * true on success, false on failure. */ #[LanguageLevelTypeAware(['8.4' => 'string|true'], default: 'string|bool')] function highlight_string(string $string, bool $return = false) {} /** * Get the system's high resolution time * @link https://secure.php.net/manual/en/function.hrtime.php * @param bool $as_number

    Whether the high resolution time should be returned as array or number.

    * @since 7.3 * @return int[]|int|float|false Returns an array of integers in the form [seconds, nanoseconds], if the parameter get_as_number is false. * Otherwise the nanoseconds are returned as integer (64bit platforms) or float (32bit platforms). */ #[Pure(true)] function hrtime(bool $as_number = false): array|int|float|false {} /** * Return source with stripped comments and whitespace * @link https://php.net/manual/en/function.php-strip-whitespace.php * @param string $filename

    * Path to the PHP file. *

    * @return string The stripped source code will be returned on success, or an empty string * on failure. *

    *

    * This function works as described as of PHP 5.0.1. Before this it would * only return an empty string. For more information on this bug and its * prior behavior, see bug report * #29606. */ #[Pure(true)] function php_strip_whitespace(string $filename): string {} /** * Gets the value of a configuration option * @link https://php.net/manual/en/function.ini-get.php * @link https://php.net/manual/en/ini.list.php * @param string $option

    * The configuration option name. *

    * @return string|false the value of the configuration option as a string on success, or * an empty string on failure or for null values. */ #[Pure(true)] function ini_get(string $option): string|false {} /** * Gets all configuration options * @link https://php.net/manual/en/function.ini-get-all.php * @link https://php.net/manual/en/ini.list.php * @param string|null $extension [optional]

    * An optional extension name. If set, the function return only options * specific for that extension. *

    * @param bool $details [optional]

    * Retrieve details settings or only the current value for each setting. * Default is true (retrieve details). *

    * @return array|false an associative array with directive name as the array key. *

    * When details is true (default) the array will * contain global_value (set in * "php.ini"), local_value (perhaps set with * ini_set or ".htaccess"), and * access (the access level). *

    *

    * When details is false the value will be the * current value of the option. *

    *

    * See the manual section * for information on what access levels mean. *

    *

    * It's possible for a directive to have multiple access levels, which is * why access shows the appropriate bitmask values. *

    */ #[Pure(true)] #[ArrayShape(["global_value" => "string", "local_value" => "string", "access" => "int"])] function ini_get_all(?string $extension, #[PhpStormStubsElementAvailable(from: '7.0')] bool $details = true): array|false {} /** * Sets the value of a configuration option * @link https://php.net/manual/en/function.ini-set.php * @link https://php.net/manual/en/ini.list.php * @param string $option

    *

    *

    * Not all the available options can be changed using * ini_set. There is a list of all available options * in the appendix. *

    * @param string $value

    * The new value for the option. *

    * @return string|false the old value on success, false on failure. */ function ini_set(string $option, #[LanguageLevelTypeAware(['8.1' => 'string|int|float|bool|null'], default: 'string')] $value): string|false {} /** * Alias: * {@see ini_set} * @link https://php.net/manual/en/function.ini-alter.php * @link https://php.net/manual/en/ini.list.php * @param string $option * @param string $value * @return string|false */ function ini_alter(string $option, #[LanguageLevelTypeAware(['8.1' => 'string|int|float|bool|null'], default: 'string')] $value): string|false {} /** * Restores the value of a configuration option * @link https://php.net/manual/en/function.ini-restore.php * @link https://php.net/manual/en/ini.list.php * @param string $option

    * The configuration option name. *

    * @return void */ function ini_restore(string $option): void {} /** * @param string $shorthand * @return int * @since 8.2 */ function ini_parse_quantity(string $shorthand): int {} /** * Gets the current include_path configuration option * @link https://php.net/manual/en/function.get-include-path.php * @return string|false the path, as a string. */ #[Pure(true)] function get_include_path(): string|false {} /** * Sets the include_path configuration option * @link https://php.net/manual/en/function.set-include-path.php * @param string $include_path

    * The new value for the include_path *

    * @return string|false the old include_path on * success or false on failure. */ function set_include_path(string $include_path): string|false {} /** * Restores the value of the include_path configuration option * @link https://php.net/manual/en/function.restore-include-path.php * @return void * @removed 8.0 */ #[Deprecated(since: '7.4')] function restore_include_path() {} /** * Send a cookie * @link https://php.net/manual/en/function.setcookie.php * @param string $name

    * The name of the cookie. *

    * @param string $value [optional]

    * The value of the cookie. This value is stored on the clients * computer; do not store sensitive information. * Assuming the name is 'cookiename', this * value is retrieved through $_COOKIE['cookiename'] *

    * @param int $expires_or_options [optional]

    * The time the cookie expires. This is a Unix timestamp so is * in number of seconds since the epoch. In other words, you'll * most likely set this with the time function * plus the number of seconds before you want it to expire. Or * you might use mktime. * time()+60*60*24*30 will set the cookie to * expire in 30 days. If set to 0, or omitted, the cookie will expire at * the end of the session (when the browser closes). *

    *

    *

    * You may notice the expire parameter takes on a * Unix timestamp, as opposed to the date format Wdy, DD-Mon-YYYY * HH:MM:SS GMT, this is because PHP does this conversion * internally. *

    *

    * expire is compared to the client's time which can * differ from server's time. *

    *

    * @param string $path [optional]

    * The path on the server in which the cookie will be available on. * If set to '/', the cookie will be available * within the entire domain. If set to * '/foo/', the cookie will only be available * within the /foo/ directory and all * sub-directories such as /foo/bar/ of * domain. The default value is the * current directory that the cookie is being set in. *

    * @param string $domain [optional]

    * The domain that the cookie is available. * To make the cookie available on all subdomains of example.com * then you'd set it to '.example.com'. The * . is not required but makes it compatible * with more browsers. Setting it to www.example.com * will make the cookie only available in the www * subdomain. Refer to tail matching in the * spec for details. *

    * @param bool $secure [optional]

    * Indicates that the cookie should only be transmitted over a * secure HTTPS connection from the client. When set to true, the * cookie will only be set if a secure connection exists. * On the server-side, it's on the programmer to send this * kind of cookie only on secure connection (e.g. with respect to * $_SERVER["HTTPS"]). *

    * @param bool $httponly [optional]

    * When true the cookie will be made accessible only through the HTTP * protocol. This means that the cookie won't be accessible by * scripting languages, such as JavaScript. This setting can effectively * help to reduce identity theft through XSS attacks (although it is * not supported by all browsers). Added in PHP 5.2.0. * true or false *

    * @return bool If output exists prior to calling this function, * setcookie will fail and return false. If * setcookie successfully runs, it will return true. * This does not indicate whether the user accepted the cookie. */ function setcookie(string $name, string $value = "", int $expires_or_options = 0, string $path = "", string $domain = "", bool $secure = false, bool $httponly = false): bool {} /** * Send a cookie * * @link https://php.net/manual/en/function.setcookie.php * * @param string $name The name of the cookie. * @param string $value [optional] The value of the cookie. This value is stored on the clients * computer; do not store sensitive information. * Assuming the name is 'cookiename', this value is retrieved through $_COOKIE['cookiename'] * @param array $options [optional] An associative array which may have any of the keys expires, path, domain, secure, * httponly and samesite. The values have the same meaning as described for the parameters with * the same name. The value of the samesite element should be either Lax or Strict. * If any of the allowed options are not given, their default values are the same * as the default values of the explicit parameters. If the samesite element is omitted, * no SameSite cookie attribute is set. * * @return bool If output exists prior to calling this function, setcookie will fail and return false. If * setcookie successfully runs, it will return true. * This does not indicate whether the user accepted the cookie. * @since 7.3 */ function setcookie(string $name, string $value = '', array $options = []): bool {} /** * Send a cookie without urlencoding the cookie value * @link https://php.net/manual/en/function.setrawcookie.php * @param string $name * @param string $value [optional] * @param int $expires_or_options [optional] * @param string $path [optional] * @param string $domain [optional] * @param bool $secure [optional] * @param bool $httponly [optional] * @return bool true on success or false on failure. */ function setrawcookie(string $name, $value = '', $expires_or_options = 0, $path = "", $domain = "", $secure = false, $httponly = false): bool {} /** * Send a cookie without urlencoding the cookie value * * @link https://php.net/manual/en/function.setrawcookie.php * * @param string $name The name of the cookie. * @param string $value [optional] The value of the cookie. This value is stored on the clients * computer; do not store sensitive information. * Assuming the name is 'cookiename', this value is retrieved through $_COOKIE['cookiename'] * @param array $options [optional] An associative array which may have any of the keys expires, path, domain, secure, * httponly and samesite. The values have the same meaning as described for the parameters with * the same name. The value of the samesite element should be either Lax or Strict. * If any of the allowed options are not given, their default values are the same * as the default values of the explicit parameters. If the samesite element is omitted, * no SameSite cookie attribute is set. * * @return bool If output exists prior to calling this function, setcookie will fail and return false. If * setcookie successfully runs, it will return true. * This does not indicate whether the user accepted the cookie. * @since 7.3 */ function setrawcookie(string $name, $value = '', array $options = []): bool {} /** * Send a raw HTTP header * @link https://php.net/manual/en/function.header.php * @param string $header

    * The header string. *

    *

    * There are two special-case header calls. The first is a header * that starts with the string "HTTP/" (case is not * significant), which will be used to figure out the HTTP status * code to send. For example, if you have configured Apache to * use a PHP script to handle requests for missing files (using * the ErrorDocument directive), you may want to * make sure that your script generates the proper status code. *

    *

    * The second special case is the "Location:" header. Not only does * it send this header back to the browser, but it also returns a * REDIRECT (302) status code to the browser * unless the 201 or * a 3xx status code has already been set. *

    * @param bool $replace [optional]

    * The optional replace parameter indicates * whether the header should replace a previous similar header, or * add a second header of the same type. By default it will replace, * but if you pass in false as the second argument you can force * multiple headers of the same type. For example: *

    * @param int $response_code

    * Forces the HTTP response code to the specified value. *

    * @return void */ function header(string $header, bool $replace = true, int $response_code = 0): void {} /** * Remove previously set headers * @link https://php.net/manual/en/function.header-remove.php * @param string|null $name [optional]

    * The header name to be removed. *

    * This parameter is case-insensitive. * @return void */ function header_remove(?string $name = null): void {} /** * Checks if or where headers have been sent * @link https://php.net/manual/en/function.headers-sent.php * @param string &$filename [optional]

    * If the optional file and * line parameters are set, * headers_sent will put the PHP source file name * and line number where output started in the file * and line variables. *

    * @param int &$line [optional]

    * The line number where the output started. *

    * @return bool headers_sent will return false if no HTTP headers * have already been sent or true otherwise. */ function headers_sent(&$filename = null, &$line = null): bool {} /** * Returns a list of response headers sent (or ready to send) * @link https://php.net/manual/en/function.headers-list.php * @return array a numerically indexed array of headers. */ #[Pure] function headers_list(): array {} /** * Fetches all HTTP request headers from the current request * @link https://php.net/manual/en/function.apache-request-headers.php * @return array|false An associative array of all the HTTP headers in the current request, or FALSE on failure. */ #[Pure] function apache_request_headers(): false|array {} /** * Fetches all HTTP headers from the current request. * This function is an alias for apache_request_headers(). Please read the apache_request_headers() documentation for more information on how this function works. * @link https://php.net/manual/en/function.getallheaders.php * @return array|false An associative array of all the HTTP headers in the current request, or FALSE on failure. */ #[Pure] function getallheaders(): false|array {} /** * Check whether client disconnected * @link https://php.net/manual/en/function.connection-aborted.php * @return int 1 if client disconnected, 0 otherwise. */ #[Pure(true)] function connection_aborted(): int {} /** * Returns connection status bitfield * @link https://php.net/manual/en/function.connection-status.php * @return int the connection status bitfield, which can be used against the * CONNECTION_XXX constants to determine the connection * status. */ #[Pure(true)] function connection_status(): int {} /** * Set whether a client disconnect should abort script execution * @link https://php.net/manual/en/function.ignore-user-abort.php * @param bool|null $enable [optional]

    * If set, this function will set the ignore_user_abort ini setting * to the given value. If not, this function will * only return the previous setting without changing it. *

    * @return int the previous setting, as an integer. */ function ignore_user_abort(?bool $enable): int {} /** * Parse a configuration file * @link https://php.net/manual/en/function.parse-ini-file.php * @param string $filename

    * The filename of the ini file being parsed. *

    * @param bool $process_sections [optional]

    * By setting the process_sections * parameter to true, you get a multidimensional array, with * the section names and settings included. The default * for process_sections is false *

    * @param int $scanner_mode [optional]

    * Can either be INI_SCANNER_NORMAL (default) or * INI_SCANNER_RAW. If INI_SCANNER_RAW * is supplied, then option values will not be parsed. *

    *

    * As of PHP 5.6.1 can also be specified as INI_SCANNER_TYPED. * In this mode boolean, null and integer types are preserved when possible. * String values "true", "on" and "yes" * are converted to TRUE. "false", "off", "no" * and "none" are considered FALSE. "null" is converted to NULL * in typed mode. Also, all numeric strings are converted to integer type if it is possible. *

    * @return array|false The settings are returned as an associative array on success, * and false on failure. */ #[Pure(true)] function parse_ini_file(string $filename, bool $process_sections = false, int $scanner_mode = INI_SCANNER_NORMAL): array|false {} /** * Parse a configuration string * @link https://php.net/manual/en/function.parse-ini-string.php * @param string $ini_string

    * The contents of the ini file being parsed. *

    * @param bool $process_sections [optional]

    * By setting the process_sections * parameter to true, you get a multidimensional array, with * the section names and settings included. The default * for process_sections is false *

    * @param int $scanner_mode [optional]

    * Can either be INI_SCANNER_NORMAL (default) or * INI_SCANNER_RAW. If INI_SCANNER_RAW * is supplied, then option values will not be parsed. *

    * @return array|false The settings are returned as an associative array on success, * and false on failure. */ #[Pure] function parse_ini_string(string $ini_string, bool $process_sections = false, int $scanner_mode = INI_SCANNER_NORMAL): array|false {} /** * Tells whether the file was uploaded via HTTP POST * @link https://php.net/manual/en/function.is-uploaded-file.php * @param string $filename

    * The filename being checked. *

    * @return bool true on success or false on failure. */ #[Pure(true)] function is_uploaded_file(string $filename): bool {} /** * Moves an uploaded file to a new location * @link https://php.net/manual/en/function.move-uploaded-file.php * @param string $from

    * The filename of the uploaded file. *

    * @param string $to

    * The destination of the moved file. *

    * @return bool If filename is not a valid upload file, * then no action will occur, and * move_uploaded_file will return * false. *

    *

    * If filename is a valid upload file, but * cannot be moved for some reason, no action will occur, and * move_uploaded_file will return * false. Additionally, a warning will be issued. */ function move_uploaded_file(string $from, string $to): bool {} /** * @return array|false * @since 7.3 */ #[Pure] #[ArrayShape(["description" => "string", "mac" => "string", "mtu" => "int", "unicast" => "array", "up" => "bool"])] function net_get_interfaces(): array|false {} /** * Get the Internet host name corresponding to a given IP address * @link https://php.net/manual/en/function.gethostbyaddr.php * @param string $ip

    * The host IP address. *

    * @return string|false the host name or the unmodified ip_address * on failure. */ #[Pure] function gethostbyaddr(string $ip): string|false {} /** * Get the IPv4 address corresponding to a given Internet host name * @link https://php.net/manual/en/function.gethostbyname.php * @param string $hostname

    * The host name. *

    * @return string the IPv4 address or a string containing the unmodified * hostname on failure. */ #[Pure] function gethostbyname(string $hostname): string {} /** * Get a list of IPv4 addresses corresponding to a given Internet host * name * @link https://php.net/manual/en/function.gethostbynamel.php * @param string $hostname

    * The host name. *

    * @return array|false an array of IPv4 addresses or false if * hostname could not be resolved. */ #[Pure] function gethostbynamel(string $hostname): array|false {} /** * Gets the host name * @link https://php.net/manual/en/function.gethostname.php * @return string|false a string with the hostname on success, otherwise false is * returned. */ #[Pure] function gethostname(): string|false {} /** * Alias: * {@see checkdnsrr} * @link https://php.net/manual/en/function.dns-check-record.php * @param string $hostname

    * host may either be the IP address in * dotted-quad notation or the host name. *

    * @param string $type [optional]

    * type may be any one of: A, MX, NS, SOA, * PTR, CNAME, AAAA, A6, SRV, NAPTR, TXT or ANY. *

    * @return bool Returns TRUE if any records are found; returns FALSE if no records were found or if an error occurred. */ function dns_check_record(string $hostname, string $type = 'MX'): bool {} /** * Check DNS records corresponding to a given Internet host name or IP address * @link https://php.net/manual/en/function.checkdnsrr.php * @param string $hostname

    * host may either be the IP address in * dotted-quad notation or the host name. *

    * @param string $type [optional]

    * type may be any one of: A, MX, NS, SOA, * PTR, CNAME, AAAA, A6, SRV, NAPTR, TXT or ANY. *

    * @return bool true if any records are found; returns false if no records * were found or if an error occurred. */ #[Pure] function checkdnsrr(string $hostname, string $type = 'MX'): bool {} /** * Alias: * {@see getmxrr} * @link https://php.net/manual/en/function.dns-get-mx.php * @param string $hostname * @param array &$hosts * @param array &$weights [optional] * @return bool */ function dns_get_mx(string $hostname, &$hosts, &$weights): bool {} /** * Get MX records corresponding to a given Internet host name * @link https://php.net/manual/en/function.getmxrr.php * @param string $hostname

    * The Internet host name. *

    * @param array &$hosts

    * A list of the MX records found is placed into the array * mxhosts. *

    * @param array &$weights [optional]

    * If the weight array is given, it will be filled * with the weight information gathered. *

    * @return bool true if any records are found; returns false if no records * were found or if an error occurred. */ function getmxrr(string $hostname, &$hosts, &$weights): bool {} /** * Fetch DNS Resource Records associated with a hostname * @link https://php.net/manual/en/function.dns-get-record.php * @param string $hostname

    * hostname should be a valid DNS hostname such * as "www.example.com". Reverse lookups can be generated * using in-addr.arpa notation, but * gethostbyaddr is more suitable for * the majority of reverse lookups. *

    *

    * Per DNS standards, email addresses are given in user.host format (for * example: hostmaster.example.com as opposed to hostmaster@example.com), * be sure to check this value and modify if necessary before using it * with a functions such as mail. *

    * @param int $type [optional]

    * By default, dns_get_record will search for any * resource records associated with hostname. * To limit the query, specify the optional type * parameter. May be any one of the following: * DNS_A, DNS_CNAME, * DNS_HINFO, DNS_MX, * DNS_NS, DNS_PTR, * DNS_SOA, DNS_TXT, * DNS_AAAA, DNS_SRV, * DNS_NAPTR, DNS_A6, * DNS_ALL or DNS_ANY. *

    *

    * Because of eccentricities in the performance of libresolv * between platforms, DNS_ANY will not * always return every record, the slower DNS_ALL * will collect all records more reliably. *

    * @param array &$authoritative_name_servers [optional]

    * Passed by reference and, if given, will be populated with Resource * Records for the Authoritative Name Servers. *

    * @param array &$additional_records [optional]

    * Passed by reference and, if given, will be populated with any * Additional Records. *

    * @param bool $raw [optional]

    * In case of raw mode, we query only the requested type * instead of looping type by type before going with the additional info stuff. *

    * @return array|false This function returns an array of associative arrays. Each associative array contains * at minimum the following keys: * * Basic DNS attributes * * * * * * * * * * * * * * * * * * * * *
    AttributeMeaning
    host * The record in the DNS namespace to which the rest of the associated data refers. *
    class * dns_get_record only returns Internet class records and as * such this parameter will always return IN. *
    type * String containing the record type. Additional attributes will also be contained * in the resulting array dependant on the value of type. See table below. *
    ttl * "Time To Live" remaining for this record. This will not equal * the record's original ttl, but will rather equal the original ttl minus whatever * length of time has passed since the authoritative name server was queried. *
    *

    *

    *

    * Other keys in associative arrays dependant on 'type' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    TypeExtra Columns
    A * ip: An IPv4 addresses in dotted decimal notation. *
    MX * pri: Priority of mail exchanger. * Lower numbers indicate greater priority. * target: FQDN of the mail exchanger. * See also dns_get_mx. *
    CNAME * target: FQDN of location in DNS namespace to which * the record is aliased. *
    NS * target: FQDN of the name server which is authoritative * for this hostname. *
    PTR * target: Location within the DNS namespace to which * this record points. *
    TXT * txt: Arbitrary string data associated with this record. *
    HINFO * cpu: IANA number designating the CPU of the machine * referenced by this record. * os: IANA number designating the Operating System on * the machine referenced by this record. * See IANA's Operating System * Names for the meaning of these values. *
    SOA * mname: FQDN of the machine from which the resource * records originated. * rname: Email address of the administrative contain * for this domain. * serial: Serial # of this revision of the requested * domain. * refresh: Refresh interval (seconds) secondary name * servers should use when updating remote copies of this domain. * retry: Length of time (seconds) to wait after a * failed refresh before making a second attempt. * expire: Maximum length of time (seconds) a secondary * DNS server should retain remote copies of the zone data without a * successful refresh before discarding. * minimum-ttl: Minimum length of time (seconds) a * client can continue to use a DNS resolution before it should request * a new resolution from the server. Can be overridden by individual * resource records. *
    AAAA * ipv6: IPv6 address *
    A6(PHP >= 5.1.0) * masklen: Length (in bits) to inherit from the target * specified by chain. * ipv6: Address for this specific record to merge with * chain. * chain: Parent record to merge with * ipv6 data. *
    SRV * pri: (Priority) lowest priorities should be used first. * weight: Ranking to weight which of commonly prioritized * targets should be chosen at random. * target and port: hostname and port * where the requested service can be found. * For additional information see: RFC 2782 *
    NAPTR * order and pref: Equivalent to * pri and weight above. * flags, services, regex, * and replacement: Parameters as defined by * RFC 2915. *
    */ function dns_get_record(string $hostname, int $type = DNS_ANY, &$authoritative_name_servers, &$additional_records, bool $raw = false): array|false {} * The input string. *

    * @return string the uppercased string. */ #[Pure] function strtoupper(string $string): string {} /** * Make a string lowercase * @link https://php.net/manual/en/function.strtolower.php * @param string $string

    * The input string. *

    * @return string the lowercased string. */ #[Pure] function strtolower(string $string): string {} /** * Find the position of the first occurrence of a substring in a string * @link https://php.net/manual/en/function.strpos.php * @param string $haystack

    * The string to search in *

    * @param string $needle

    * If needle is not a string, it is converted * to an integer and applied as the ordinal value of a character. *

    * @param int<0,max> $offset [optional]

    * If specified, search will start this number of characters counted from * the beginning of the string. Unlike {@see strrpos()} and {@see strripos()}, the offset cannot be negative. *

    * @return int<0,max>|false

    * Returns the position where the needle exists relative to the beginning of * the haystack string (independent of search direction * or offset). * Also note that string positions start at 0, and not 1. *

    *

    * Returns FALSE if the needle was not found. *

    */ #[Pure] function strpos(string $haystack, string $needle, int $offset = 0): int|false {} /** * Find position of first occurrence of a case-insensitive string * @link https://php.net/manual/en/function.stripos.php * @param string $haystack

    * The string to search in *

    * @param string $needle

    * Note that the needle may be a string of one or * more characters. *

    *

    * If needle is not a string, it is converted to * an integer and applied as the ordinal value of a character. *

    * @param int $offset

    * The optional offset parameter allows you * to specify which character in haystack to * start searching. The position returned is still relative to the * beginning of haystack. *

    * @return int|false If needle is not found, * stripos will return boolean false. */ #[Pure] function stripos(string $haystack, string $needle, int $offset = 0): int|false {} /** * Find the position of the last occurrence of a substring in a string * @link https://php.net/manual/en/function.strrpos.php * @param string $haystack

    * The string to search in. *

    * @param string $needle

    * If needle is not a string, it is converted to an integer and applied as the ordinal value of a character. *

    * @param int $offset [optional]

    * If specified, search will start this number of characters counted from the beginning of the string. If the value is negative, search will instead start from that many characters from the end of the string, searching backwards. *

    * @return int|false

    * Returns the position where the needle exists relative to the beginning of * the haystack string (independent of search direction * or offset). * Also note that string positions start at 0, and not 1. *

    *

    * Returns FALSE if the needle was not found. *

    */ #[Pure] function strrpos(string $haystack, string $needle, int $offset = 0): int|false {} /** * Find position of last occurrence of a case-insensitive string in a string * @link https://php.net/manual/en/function.strripos.php * @param string $haystack

    * The string to search in *

    * @param string $needle

    * Note that the needle may be a string of one or * more characters. *

    * @param int $offset

    * The offset parameter may be specified to begin * searching an arbitrary number of characters into the string. *

    *

    * Negative offset values will start the search at * offset characters from the * start of the string. *

    * @return int|false the numerical position of the last occurrence of * needle. Also note that string positions start at 0, * and not 1. *

    *

    * If needle is not found, false is returned. */ #[Pure] function strripos(string $haystack, string $needle, int $offset = 0): int|false {} /** * Reverse a string * @link https://php.net/manual/en/function.strrev.php * @param string $string

    * The string to be reversed. *

    * @return string the reversed string. */ #[Pure] function strrev(string $string): string {} /** * Convert logical Hebrew text to visual text * @link https://php.net/manual/en/function.hebrev.php * @param string $string

    * A Hebrew input string. *

    * @param int $max_chars_per_line

    * This optional parameter indicates maximum number of characters per * line that will be returned. *

    * @return string the visual string. */ #[Pure] function hebrev(string $string, int $max_chars_per_line = 0): string {} /** * Convert logical Hebrew text to visual text with newline conversion * @link https://php.net/manual/en/function.hebrevc.php * @param string $hebrew_text

    * A Hebrew input string. *

    * @param int $max_chars_per_line [optional]

    * This optional parameter indicates maximum number of characters per * line that will be returned. *

    * @return string the visual string. * @removed 8.0 */ #[Deprecated(replacement: 'nl2br(hebrev(%parameter0%))', since: '7.4')] function hebrevc(string $hebrew_text, $max_chars_per_line): string {} /** * Inserts HTML line breaks before all newlines in a string * @link https://php.net/manual/en/function.nl2br.php * @param string $string

    * The input string. *

    * @param bool $use_xhtml [optional]

    * Whether to use XHTML compatible line breaks or not. *

    * @return string the altered string. */ #[Pure] function nl2br(string $string, bool $use_xhtml = true): string {} /** * Returns trailing name component of path * @link https://php.net/manual/en/function.basename.php * @param string $path

    * A path. *

    *

    * On Windows, both slash (/) and backslash * (\) are used as directory separator character. In * other environments, it is the forward slash (/). *

    * @param string $suffix

    * If the filename ends in suffix this will also * be cut off. *

    * @return string the base name of the given path. */ #[Pure] function basename(string $path, string $suffix = ''): string {} /** * Returns a parent directory's path * @link https://php.net/manual/en/function.dirname.php * @param string $path

    * A path. *

    *

    * On Windows, both slash (/) and backslash * (\) are used as directory separator character. In * other environments, it is the forward slash (/). *

    * @param int $levels

    * The number of parent directories to go up. * This must be an integer greater than 0. *

    * @return string the name of the directory. If there are no slashes in * path, a dot ('.') is returned, * indicating the current directory. Otherwise, the returned string is * path with any trailing * /component removed. */ #[Pure] function dirname(string $path, #[PhpStormStubsElementAvailable(from: '7.0')] int $levels = 1): string {} /** * Returns information about a file path * @link https://php.net/manual/en/function.pathinfo.php * @param string $path

    * The path being checked. *

    * @param int $flags [optional]

    * You can specify which elements are returned with optional parameter * options. It composes from * PATHINFO_DIRNAME, * PATHINFO_BASENAME, * PATHINFO_EXTENSION and * PATHINFO_FILENAME. It * defaults to return all elements. *

    * @return string|array{dirname: string, basename: string, extension: string, filename: string} The following associative array elements are returned: * dirname, basename, * extension (if any), and filename. *

    *

    * If options is used, this function will return a * string if not all elements are requested. */ #[Pure(true)] #[ArrayShape(['dirname' => 'string', 'basename' => 'string', 'extension' => 'string', 'filename' => 'string'])] function pathinfo(string $path, #[ExpectedValues(flags: [ PATHINFO_DIRNAME, PATHINFO_BASENAME, PATHINFO_EXTENSION, PATHINFO_FILENAME ])] int $flags = PATHINFO_ALL): array|string {} /** * Un-quotes a quoted string * @link https://php.net/manual/en/function.stripslashes.php * @param string $string

    * The input string. *

    * @return string a string with backslashes stripped off. * (\' becomes ' and so on.) * Double backslashes (\\) are made into a single * backslash (\). */ #[Pure] function stripslashes(string $string): string {} /** * Un-quote string quoted with addcslashes * @link https://php.net/manual/en/function.stripcslashes.php * @param string $string

    * The string to be unescaped. *

    * @return string the unescaped string. */ #[Pure] function stripcslashes(string $string): string {} /** * Find the first occurrence of a string * @link https://php.net/manual/en/function.strstr.php * @param string $haystack

    * The input string. *

    * @param string $needle

    * If needle is not a string, it is converted to * an integer and applied as the ordinal value of a character. *

    * @param bool $before_needle [optional]

    * If true, strstr returns * the part of the haystack before the first * occurrence of the needle. *

    * @return string|false the portion of string, or false if needle * is not found. */ #[Pure] function strstr(string $haystack, string $needle, bool $before_needle = false): string|false {} /** * Case-insensitive strstr * @link https://php.net/manual/en/function.stristr.php * @param string $haystack

    * The string to search in *

    * @param string $needle

    * If needle is not a string, it is converted to * an integer and applied as the ordinal value of a character. *

    * @param bool $before_needle [optional]

    * If true, stristr * returns the part of the haystack before the * first occurrence of the needle. *

    * @return string|false the matched substring. If needle is not * found, returns false. */ #[Pure] function stristr(string $haystack, string $needle, bool $before_needle = false): string|false {} /** * Find the last occurrence of a character in a string * @link https://php.net/manual/en/function.strrchr.php * @param string $haystack

    * The string to search in *

    * @param string $needle

    * If needle contains more than one character, * only the first is used. This behavior is different from that of {@see strstr()}. *

    *

    * If needle is not a string, it is converted to * an integer and applied as the ordinal value of a character. *

    * @param bool $before_needle Since 8.3 If true, strrchr() returns the part of the haystack before the last occurrence * of the needle (excluding the needle). * @return string|false

    * This function returns the portion of string, or FALSE if * needle is not found. *

    */ #[Pure] function strrchr(string $haystack, string $needle, #[PhpStormStubsElementAvailable(from: '8.3')] bool $before_needle = false): string|false {} /** * Randomly shuffles a string * @link https://php.net/manual/en/function.str-shuffle.php * @param string $string

    * The input string. *

    * @return string the shuffled string. */ function str_shuffle(string $string): string {} /** * Return information about words used in a string * @link https://php.net/manual/en/function.str-word-count.php * @param string $string

    * The string *

    * @param int $format [optional]

    * Specify the return value of this function. The current supported values * are: * 0 - returns the number of words found *

    * @param string|null $characters [optional]

    * A list of additional characters which will be considered as 'word' *

    * @return string[]|int an array or an integer, depending on the * format chosen. */ #[Pure] function str_word_count(string $string, int $format = 0, ?string $characters): array|int {} /** * Convert a string to an array * @link https://php.net/manual/en/function.str-split.php * @param string $string

    * The input string. *

    * @param int $length [optional]

    * Maximum length of the chunk. *

    * @return string[]|false

    If the optional split_length parameter is * specified, the returned array will be broken down into chunks with each * being split_length in length, otherwise each chunk * will be one character in length. *

    *

    * FALSE is returned if split_length is less than 1. * If the split_length length exceeds the length of * string, the entire string is returned as the first * (and only) array element. *

    */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "array"], default: "array|false")] function str_split(string $string, int $length = 1): array|false {} /** * Search a string for any of a set of characters * @link https://php.net/manual/en/function.strpbrk.php * @param string $string

    * The string where char_list is looked for. *

    * @param string $characters

    * This parameter is case sensitive. *

    * @return string|false a string starting from the character found, or false if it is * not found. */ #[Pure] function strpbrk( string $string, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.0')] $char_list = '', #[PhpStormStubsElementAvailable(from: '7.1')] string $characters ): string|false {} /** * Binary safe comparison of two strings from an offset, up to length characters * @link https://php.net/manual/en/function.substr-compare.php * @param string $haystack

    * The main string being compared. *

    * @param string $needle

    * The secondary string being compared. *

    * @param int $offset

    * The start position for the comparison. If negative, it starts counting * from the end of the string. *

    * @param int|null $length [optional]

    * The length of the comparison. *

    * @param bool $case_insensitive [optional]

    * If case_insensitivity is true, comparison is * case insensitive. *

    * @return int if less than 0 if main_str from position * offset is less than str, > * 0 if it is greater than str, and 0 if they are equal. * If offset is equal to or greater than the length of * main_str or length is set and * is less than 1, substr_compare prints a warning and returns * false. */ #[Pure] function substr_compare(string $haystack, string $needle, int $offset, ?int $length, bool $case_insensitive = false): int {} /** * Locale based string comparison * @link https://php.net/manual/en/function.strcoll.php * @param string $string1

    * The first string. *

    * @param string $string2

    * The second string. *

    * @return int if less than 0 if str1 is less than * str2; > 0 if * str1 is greater than * str2, and 0 if they are equal. */ #[Pure] function strcoll(string $string1, string $string2): int {} /** * Formats a number as a currency string * @link https://php.net/manual/en/function.money-format.php * @param string $format

    * The format specification consists of the following sequence:
    * a % character

    * @param float $number

    * The number to be formatted. *

    * @return string|null the formatted string. Characters before and after the formatting * string will be returned unchanged. * Non-numeric number causes returning null and * emitting E_WARNING. * @removed 8.0 * @see NumberFormatter */ #[Deprecated(reason: 'Use the NumberFormatter functionality', since: '7.4')] function money_format(string $format, float $number): ?string {} /** * Return part of a string or false on failure. For PHP8.0+ only string is returned * @link https://php.net/manual/en/function.substr.php * @param string $string

    * The input string. *

    * @param int $offset

    * If start is non-negative, the returned string * will start at the start'th position in * string, counting from zero. For instance, * in the string 'abcdef', the character at * position 0 is 'a', the * character at position 2 is * 'c', and so forth. *

    *

    * If start is negative, the returned string * will start at the start'th character * from the end of string. *

    *

    * If string is less than or equal to * start characters long, false will be returned. *

    *

    * Using a negative start *

    *
     * 
     * 
    * @param int|null $length [optional]

    * If length is given and is positive, the string * returned will contain at most length characters * beginning from start (depending on the length of * string). *

    *

    * If length is given and is negative, then that many * characters will be omitted from the end of string * (after the start position has been calculated when a * start is negative). If * start denotes a position beyond this truncation, * an empty string will be returned. *

    *

    * If length is given and is 0, * false or null an empty string will be returned. *

    * Using a negative length: *
     * 
     * 
    */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "string"], default: "string|false")] function substr(string $string, int $offset, ?int $length) {} /** * Replace text within a portion of a string * @link https://php.net/manual/en/function.substr-replace.php * @param string[]|string $string

    * The input string. *

    * @param string[]|string $replace

    * The replacement string. *

    * @param int[]|int $offset

    * If start is positive, the replacing will * begin at the start'th offset into * string. *

    *

    * If start is negative, the replacing will * begin at the start'th character from the * end of string. *

    * @param int[]|int $length [optional]

    * If given and is positive, it represents the length of the portion of * string which is to be replaced. If it is * negative, it represents the number of characters from the end of * string at which to stop replacing. If it * is not given, then it will default to strlen( * string ); i.e. end the replacing at the * end of string. Of course, if * length is zero then this function will have the * effect of inserting replacement into * string at the given * start offset. *

    * @return string|string[] The result string is returned. If string is an * array then array is returned. */ #[Pure] function substr_replace(array|string $string, array|string $replace, array|int $offset, array|int|null $length = null): array|string {} /** * Quote meta characters * @link https://php.net/manual/en/function.quotemeta.php * @param string $string

    * The input string. *

    * @return string the string with meta characters quoted. */ #[Pure] function quotemeta(string $string): string {} /** * Make a string's first character uppercase * @link https://php.net/manual/en/function.ucfirst.php * @param string $string

    * The input string. *

    * @return string the resulting string. */ #[Pure] function ucfirst(string $string): string {} /** * Make a string's first character lowercase * @link https://php.net/manual/en/function.lcfirst.php * @param string $string

    * The input string. *

    * @return string the resulting string. */ #[Pure] function lcfirst(string $string): string {} /** * Uppercase the first character of each word in a string * @link https://php.net/manual/en/function.ucwords.php * @param string $string

    * The input string. *

    * @param string $separators [optional]

    * The optional separators contains the word separator characters. *

    * @return string the modified string. */ #[Pure] function ucwords(string $string, string $separators = " \t\r\n\f\v"): string {} /** * Translate characters or replace substrings * @link https://php.net/manual/en/function.strtr.php * @param string $string

    * The string being translated. *

    * @param string $from

    * The string replacing from. *

    * @param string $to

    * The string being translated to to. *

    * @return string This function returns a copy of str, * translating all occurrences of each character in * from to the corresponding character in * to. */ #[Pure] function strtr(string $string, string $from, string $to): string {} /** * Translate certain characters * @link https://php.net/manual/en/function.strtr.php * @param string $str The string being translated. * @param array $replace_pairs The replace_pairs parameter may be used as a substitute for to and from in which case it's an array in the form array('from' => 'to', ...). * @return string A copy of str, translating all occurrences of each character in from to the corresponding character in to. */ #[Pure] function strtr(string $str, array $replace_pairs): string {} /** * Quote string with slashes * @link https://php.net/manual/en/function.addslashes.php * @param string $string

    * The string to be escaped. *

    * @return string the escaped string. */ #[Pure] function addslashes(string $string): string {} /** * Quote string with slashes in a C style * @link https://php.net/manual/en/function.addcslashes.php * @param string $string

    * The string to be escaped. *

    * @param string $characters

    * A list of characters to be escaped. If * charlist contains characters * \n, \r etc., they are * converted in C-like style, while other non-alphanumeric characters * with ASCII codes lower than 32 and higher than 126 converted to * octal representation. *

    *

    * When you define a sequence of characters in the charlist argument * make sure that you know what characters come between the * characters that you set as the start and end of the range. *

    *
     * 
     * 
    *

    * Also, if the first character in a range has a higher ASCII value * than the second character in the range, no range will be * constructed. Only the start, end and period characters will be * escaped. Use the ord function to find the * ASCII value for a character. *

    *
     * 
     * 
    *

    * Be careful if you choose to escape characters 0, a, b, f, n, r, * t and v. They will be converted to \0, \a, \b, \f, \n, \r, \t * and \v. * In PHP \0 (NULL), \r (carriage return), \n (newline), \f (form feed), * \v (vertical tab) and \t (tab) are predefined escape sequences, * while in C all of these are predefined escape sequences. *

    * @return string the escaped string. */ #[Pure] function addcslashes(string $string, string $characters): string {} /** * Strip whitespace (or other characters) from the end of a string. * Without the second parameter, rtrim() will strip these characters: *
      *
    • " " (ASCII 32 (0x20)), an ordinary space. *
    • "\t" (ASCII 9 (0x09)), a tab. *
    • "\n" (ASCII 10 (0x0A)), a new line (line feed). *
    • "\r" (ASCII 13 (0x0D)), a carriage return. *
    • "\0" (ASCII 0 (0x00)), the NUL-byte. *
    • "\x0B" (ASCII 11 (0x0B)), a vertical tab. *
    * @link https://php.net/manual/en/function.rtrim.php * @param string $string

    * The input string. *

    * @param string $characters [optional]

    * You can also specify the characters you want to strip, by means * of the charlist parameter. * Simply list all characters that you want to be stripped. With * .. you can specify a range of characters. *

    * @return string the modified string. */ #[Pure] function rtrim(string $string, string $characters = " \n\r\t\v\0"): string {} /** * Replace all occurrences of the search string with the replacement string * @link https://php.net/manual/en/function.str-replace.php * @param string|string[] $search

    * The value being searched for, otherwise known as the needle. * An array may be used to designate multiple needles. *

    * @param string|string[] $replace

    * The replacement value that replaces found search * values. An array may be used to designate multiple replacements. *

    * @param string|string[] $subject

    * The string or array being searched and replaced on, * otherwise known as the haystack. *

    *

    * If subject is an array, then the search and * replace is performed with every entry of * subject, and the return value is an array as * well. *

    * @param int &$count [optional] If passed, this will hold the number of matched and replaced needles. * @return string|string[] This function returns a string or an array with the replaced values. */ function str_replace(array|string $search, array|string $replace, array|string $subject, &$count): array|string {} /** * Case-insensitive version of str_replace. * @link https://php.net/manual/en/function.str-ireplace.php * @param mixed $search

    * Every replacement with search array is * performed on the result of previous replacement. *

    * @param array|string $replace

    *

    * @param array|string $subject

    * If subject is an array, then the search and * replace is performed with every entry of * subject, and the return value is an array as * well. *

    * @param int &$count [optional]

    * The number of matched and replaced needles will * be returned in count which is passed by * reference. *

    * @return string|string[] a string or an array of replacements. */ function str_ireplace(array|string $search, array|string $replace, array|string $subject, &$count): array|string {} /** * Repeat a string * @link https://php.net/manual/en/function.str-repeat.php * @param string $string

    * The string to be repeated. *

    * @param int $times

    * Number of time the input string should be * repeated. *

    *

    * multiplier has to be greater than or equal to 0. * If the multiplier is set to 0, the function * will return an empty string. *

    * @return string the repeated string. */ #[Pure] function str_repeat(string $string, int $times): string {} /** * Return information about characters used in a string * @link https://php.net/manual/en/function.count-chars.php * @param string $string

    * The examined string. *

    * @param int $mode

    * See return values. *

    * @return int[]|string Depending on mode * count_chars returns one of the following: * 0 - an array with the byte-value as key and the frequency of * every byte as value. * 1 - same as 0 but only byte-values with a frequency greater * than zero are listed. * 2 - same as 0 but only byte-values with a frequency equal to * zero are listed. * 3 - a string containing all unique characters is returned. * 4 - a string containing all not used characters is returned. */ #[Pure] function count_chars(string $string, int $mode = 0): array|string {} /** * Split a string into smaller chunks * @link https://php.net/manual/en/function.chunk-split.php * @param string $string

    * The string to be chunked. *

    * @param int $length [optional]

    * The chunk length. *

    * @param string $separator [optional]

    * The line ending sequence. *

    * @return string the chunked string. */ #[Pure] function chunk_split(string $string, int $length = 76, string $separator = "\r\n"): string {} /** * Strip whitespace (or other characters) from the beginning and end of a string * @link https://php.net/manual/en/function.trim.php * @param string $string

    * The string that will be trimmed. *

    * @param string $characters [optional]

    * Optionally, the stripped characters can also be specified using * the charlist parameter. * Simply list all characters that you want to be stripped. With * .. you can specify a range of characters. *

    * @return string The trimmed string. */ #[Pure] function trim(string $string, string $characters = " \n\r\t\v\0"): string {} /** * Strip whitespace (or other characters) from the beginning of a string * @link https://php.net/manual/en/function.ltrim.php * @param string $string

    * The input string. *

    * @param string $characters [optional]

    * You can also specify the characters you want to strip, by means of the * charlist parameter. * Simply list all characters that you want to be stripped. With * .. you can specify a range of characters. *

    * @return string This function returns a string with whitespace stripped from the * beginning of str. * Without the second parameter, * ltrim will strip these characters: * " " (ASCII 32 * (0x20)), an ordinary space. * "\t" (ASCII 9 * (0x09)), a tab. * "\n" (ASCII 10 * (0x0A)), a new line (line feed). * "\r" (ASCII 13 * (0x0D)), a carriage return. * "\0" (ASCII 0 * (0x00)), the NUL-byte. * "\x0B" (ASCII 11 * (0x0B)), a vertical tab. */ #[Pure] function ltrim(string $string, string $characters = " \n\r\t\v\0"): string {} /** * Strip HTML and PHP tags from a string * @link https://php.net/manual/en/function.strip-tags.php * @param string $string

    * The input string. *

    * @param string[]|string|null $allowed_tags [optional]

    * You can use the optional second parameter to specify tags which should * not be stripped. *

    *

    * HTML comments and PHP tags are also stripped. This is hardcoded and * can not be changed with allowable_tags. *

    * @return string the stripped string. */ #[Pure] function strip_tags(string $string, #[LanguageLevelTypeAware(["7.4" => "string[]|string|null"], default: "string|null")] $allowed_tags = null): string {} /** * Calculate the similarity between two strings * @link https://php.net/manual/en/function.similar-text.php * @param string $string1

    * The first string. *

    * @param string $string2

    * The second string. *

    * @param float &$percent [optional]

    * By passing a reference as third argument, * similar_text will calculate the similarity in * percent for you. *

    * @return int the number of matching chars in both strings. */ function similar_text(string $string1, string $string2, &$percent): int {} /** * Split a string by a string * @link https://php.net/manual/en/function.explode.php * @param string $separator

    * The boundary string. *

    * @param string $string

    * The input string. *

    * @param int $limit [optional]

    * If limit is set and positive, the returned array will contain * a maximum of limit elements with the last * element containing the rest of string. *

    *

    * If the limit parameter is negative, all components * except the last -limit are returned. *

    *

    * If the limit parameter is zero, then this is treated as 1. *

    * @return string[]|false If delimiter is an empty string (""), * explode will return false. * If delimiter contains a value that is not * contained in string and a negative * limit is used, then an empty array will be * returned. For any other limit, an array containing * string will be returned. */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "string[]"], default: "string[]|false")] function explode(string $separator, string $string, int $limit = PHP_INT_MAX) {} /** * Join array elements with a string * @link https://php.net/manual/en/function.implode.php * @param array|string $separator [optional]

    * Defaults to an empty string. This is not the preferred usage of * implode as glue would be * the second parameter and thus, the bad prototype would be used. *

    * @param array|null $array

    * The array of strings to implode. *

    * @return string a string containing a string representation of all the array * elements in the same order, with the glue string between each element. */ #[Pure] function implode(array|string $separator = "", ?array $array): string {} /** * Alias: * {@see implode} * @link https://php.net/manual/en/function.join.php * @param array|string $separator [optional]

    * Defaults to an empty string. This is not the preferred usage of * implode as glue would be * the second parameter and thus, the bad prototype would be used. *

    * @param array|null $array

    * The array of strings to implode. *

    * @return string a string containing a string representation of all the array * elements in the same order, with the glue string between each element. */ #[Pure] function join(array|string $separator = "", ?array $array): string {} /** * Set locale information * @link https://php.net/manual/en/function.setlocale.php * @param int $category

    * category is a named constant specifying the * category of the functions affected by the locale setting: *

      *
    • * LC_ALL for all of the below *
    • *
    • * LC_COLLATE for string comparison, see * {@see strcoll()} *
    • *
    • * LC_CTYPE for character classification and conversion, for * example {@see strtoupper()} *
    • *
    • * LC_MONETARY for {@see localeconv()} *
    • *
    • * LC_NUMERIC for decimal separator (See also * {@see localeconv()}) *
    • *
    • * LC_TIME for date and time formatting with * {@see strftime()} * *
    • *
    • * LC_MESSAGES for system responses (available if PHP was compiled with * libintl) * *
    • *
    * @param string|string[]|int $locales

    * If locale is null or the empty string * "", the locale names will be set from the * values of environment variables with the same names as the above * categories, or from "LANG". *

    *

    * If locale is "0", * the locale setting is not affected, only the current setting is returned. *

    *

    * If locale is an array or followed by additional * parameters then each array element or parameter is tried to be set as * new locale until success. This is useful if a locale is known under * different names on different systems or for providing a fallback * for a possibly not available locale. *

    * @param string|string[] ...$rest * @return string|false

    the new current locale, or false if the locale functionality is * not implemented on your platform, the specified locale does not exist or * the category name is invalid. *

    *

    * An invalid category name also causes a warning message. Category/locale * names can be found in RFC 1766 * and ISO 639. * Different systems have different naming schemes for locales. *

    *

    * The return value of setlocale depends * on the system that PHP is running. It returns exactly * what the system setlocale function returns.

    */ function setlocale( #[ExpectedValues([LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME, LC_MESSAGES])] int $category, #[PhpStormStubsElementAvailable(from: '8.0')] $locales, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $rest, ...$rest ): string|false {} /** * Get numeric formatting information * @link https://php.net/manual/en/function.localeconv.php * @return array localeconv returns data based upon the current locale * as set by setlocale. The associative array that is * returned contains the following fields: * * Array element * Description * * * decimal_point * Decimal point character * * * thousands_sep * Thousands separator * * * grouping * Array containing numeric groupings * * * int_curr_symbol * International currency symbol (i.e. USD) * * * currency_symbol * Local currency symbol (i.e. $) * * * mon_decimal_point * Monetary decimal point character * * * mon_thousands_sep * Monetary thousands separator * * * mon_grouping * Array containing monetary groupings * * * positive_sign * Sign for positive values * * * negative_sign * Sign for negative values * * * int_frac_digits * International fractional digits * * * frac_digits * Local fractional digits * * * p_cs_precedes * * true if currency_symbol precedes a positive value, false * if it succeeds one * * * * p_sep_by_space * * true if a space separates currency_symbol from a positive * value, false otherwise * * * * n_cs_precedes * * true if currency_symbol precedes a negative value, false * if it succeeds one * * * * n_sep_by_space * * true if a space separates currency_symbol from a negative * value, false otherwise * * * p_sign_posn * * 0 - Parentheses surround the quantity and currency_symbol * 1 - The sign string precedes the quantity and currency_symbol * 2 - The sign string succeeds the quantity and currency_symbol * 3 - The sign string immediately precedes the currency_symbol * 4 - The sign string immediately succeeds the currency_symbol * * * n_sign_posn * * 0 - Parentheses surround the quantity and currency_symbol * 1 - The sign string precedes the quantity and currency_symbol * 2 - The sign string succeeds the quantity and currency_symbol * 3 - The sign string immediately precedes the currency_symbol * 4 - The sign string immediately succeeds the currency_symbol * * *

    *

    * The p_sign_posn, and n_sign_posn contain a string * of formatting options. Each number representing one of the above listed conditions. *

    *

    * The grouping fields contain arrays that define the way numbers should be * grouped. For example, the monetary grouping field for the nl_NL locale (in * UTF-8 mode with the euro sign), would contain a 2 item array with the * values 3 and 3. The higher the index in the array, the farther left the * grouping is. If an array element is equal to CHAR_MAX, * no further grouping is done. If an array element is equal to 0, the previous * element should be used. */ #[ArrayShape(["decimal_point" => "string", "thousands_sep" => "string", "grouping" => "array", "int_curr_symbol" => "string", "currency_symbol" => "string", "mon_decimal_point" => "string", "mon_thousands_sep" => "string", "mon_grouping" => "string", "positive_sign" => "string", "negative_sign" => "string", "int_frac_digits" => "string", "frac_digits" => "string", "p_cs_precedes" => "bool", "p_sep_by_space" => "bool", "n_cs_precedes" => "bool", "n_sep_by_space" => "bool", "p_sign_posn" => "int", "n_sign_posn" => "int"])] #[Pure(true)] function localeconv(): array {} 'string'], default: '')] public $filtername; #[LanguageLevelTypeAware(['8.1' => 'mixed'], default: '')] public $params; public $stream; /** * @link https://php.net/manual/en/php-user-filter.filter.php * @param resource $in

    is a resource pointing to a bucket brigadebucket objects containing data to be filtered.

    * @param resource $out

    is a resource pointing to a second bucket brigade into which your modified buckets should be placed.

    * @param int &$consumed

    which must always be declared by reference, should be incremented by the length of the data which your filter reads in and alters. In most cases this means you will increment consumed by $bucket->datalen for each $bucket.

    * @param bool $closing

    If the stream is in the process of closing (and therefore this is the last pass through the filterchain), the closing parameter will be set to TRUE * @return int

    * The filter() method must return one of * three values upon completion. *

    * * * * * * * * * * * * * * * * * * * * * * * * */ #[TentativeType] public function filter( $in, $out, &$consumed, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $closing ): int {} /** * @link https://php.net/manual/en/php-user-filter.oncreate.php * @return bool */ #[TentativeType] public function onCreate(): bool {} /** * @link https://php.net/manual/en/php-user-filter.onclose.php */ #[TentativeType] public function onClose(): void {} } /** * @since 8.4 */ final class StreamBucket { public $bucket; public string $data; public int $datalen; public int $dataLength; } /** * Instances of Directory are created by calling the dir() function, not by the new operator. */ class Directory { /** * @var string The directory that was opened. * @removed 8.1 */ public $path; /** * @var string The directory that was opened. * @since 8.1 */ public readonly string $path; /** * @var resource Can be used with other directory functions such as {@see readdir()}, {@see rewinddir()} and {@see closedir()}. * @removed 8.1 */ public $handle; /** * @var resource Can be used with other directory functions such as {@see readdir()}, {@see rewinddir()} and {@see closedir()}. * @since 8.1 */ public readonly mixed $handle; /** * Close directory handle. * Same as closedir(), only dir_handle defaults to $this. * @param resource $dir_handle [optional] * @link https://secure.php.net/manual/en/directory.close.php */ #[TentativeType] public function close(#[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $dir_handle = null): void {} /** * Rewind directory handle. * Same as rewinddir(), only dir_handle defaults to $this. * @param resource $dir_handle [optional] * @link https://secure.php.net/manual/en/directory.rewind.php */ #[TentativeType] public function rewind(#[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $dir_handle = null): void {} /** * Read entry from directory handle. * Same as readdir(), only dir_handle defaults to $this. * @param resource $dir_handle [optional] * @return string|false * @link https://secure.php.net/manual/en/directory.read.php */ #[TentativeType] public function read(#[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $dir_handle = null): string|false {} } /** * Returns the value of a constant * @link https://php.net/manual/en/function.constant.php * @param string $name

    * The constant name. *

    * @return mixed the value of the constant. * @throws Error If the constant is not defined */ #[Pure(true)] function constant(string $name): mixed {} /** * Convert binary data into hexadecimal representation * @link https://php.net/manual/en/function.bin2hex.php * @param string $string

    * A string. *

    * @return string the hexadecimal representation of the given string. */ #[Pure] function bin2hex(string $string): string {} /** * Delays the program execution for the given number of seconds * @link https://php.net/manual/en/function.sleep.php * @param int<0,max> $seconds

    * Halt time in seconds (must be greater than or equal to 0). *

    * @return int Returns zero on success. *

    * If the call was interrupted by a signal, sleep() returns a * non-zero value. On Windows, this value will always be 192 * (the value of the WAIT_IO_COMPLETION constant within the Windows API). * On other platforms, the return value will be the * number of seconds left to sleep. *

    *

    * As of PHP 8.0, if the specified number of seconds is negative, * this function will throw a ValueError. * Before PHP 8.0, an E_WARNING was raised instead, and the function returned false. *

    */ #[LanguageLevelTypeAware(["8.0" => "int"], default: "int|false")] function sleep(int $seconds) {} /** * Delay execution in microseconds * @link https://php.net/manual/en/function.usleep.php * @param int<0,max> $microseconds

    * Halt time in micro seconds. A micro second is one millionth of a * second. *

    * @return void */ function usleep(int $microseconds): void {} /** * Delay for a number of seconds and nanoseconds * @link https://php.net/manual/en/function.time-nanosleep.php * @param positive-int $seconds

    * Must be a positive integer. *

    * @param positive-int $nanoseconds

    * Must be a positive integer less than 1 billion. *

    * @return bool|array true on success or false on failure. *

    * If the delay was interrupted by a signal, an associative array will be * returned with the components: * seconds - number of seconds remaining in * the delay * nanoseconds - number of nanoseconds * remaining in the delay *

    */ #[ArrayShape(["seconds" => "int", "nanoseconds" => "int"])] function time_nanosleep(int $seconds, int $nanoseconds): array|bool {} /** * Make the script sleep until the specified time * @link https://php.net/manual/en/function.time-sleep-until.php * @param float $timestamp

    * The timestamp when the script should wake. *

    * @return bool true on success or false on failure. */ function time_sleep_until(float $timestamp): bool {} /** * Parse a time/date generated with strftime * @link https://php.net/manual/en/function.strptime.php * @param string $timestamp

    * The string to parse (e.g. returned from strftime) *

    * @param string $format

    * The format used in date (e.g. the same as * used in strftime). *

    *

    * For more information about the format options, read the * strftime page. *

    * @return array|false an array or false on failure. *

    *

    Return ValueMeaning
    PSFS_PASS_ON * Filter processed successfully with data available in the * out bucket brigade. *
    PSFS_FEED_ME * Filter processed successfully, however no data was available to * return. More data is required from the stream or prior filter. *
    PSFS_ERR_FATAL (default) * The filter experienced an unrecoverable error and cannot continue. *
    * The following parameters are returned in the array * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    parametersDescription
    "tm_sec"Seconds after the minute (0-61)
    "tm_min"Minutes after the hour (0-59)
    "tm_hour"Hour since midnight (0-23)
    "tm_mday"Day of the month (1-31)
    "tm_mon"Months since January (0-11)
    "tm_year"Years since 1900
    "tm_wday"Days since Sunday (0-6)
    "tm_yday"Days since January 1 (0-365)
    "unparsed"the date part which was not * recognized using the specified format
    *

    * @deprecated 8.1 */ #[Pure(true)] #[Deprecated(since: '8.1')] #[ArrayShape([ 'tm_sec' => 'int', 'tm_min' => 'int', 'tm_hour' => 'int', 'tm_mday' => 'int', 'tm_mon' => 'int', 'tm_year' => 'int', 'tm_wday' => 'int', 'tm_yday' => 'int', 'unparsed' => 'string' ])] function strptime(string $timestamp, string $format): array|false {} /** * Flush system output buffer * @link https://php.net/manual/en/function.flush.php * @return void */ function flush(): void {} /** * Wraps a string to a given number of characters * @link https://php.net/manual/en/function.wordwrap.php * @param string $string

    * The input string. *

    * @param int $width [optional]

    * The number of characters at which the string will be wrapped. *

    * @param string $break [optional]

    * The line is broken using the optional * break parameter. *

    * @param bool $cut_long_words [optional]

    * If the cut is set to true, the string is * always wrapped at or before the specified width. So if you have * a word that is larger than the given width, it is broken apart. * (See second example). *

    * @return string the given string wrapped at the specified length. */ #[Pure] function wordwrap(string $string, int $width = 75, string $break = "\n", bool $cut_long_words = false): string {} /** * Convert special characters to HTML entities * @link https://php.net/manual/en/function.htmlspecialchars.php * @param string $string

    * The {@link https://secure.php.net/manual/en/language.types.string.php string} being converted. *

    * @param int $flags [optional]

    * A bitmask of one or more of the following flags, which specify how to handle quotes, * invalid code unit sequences and the used document type. The default is * ENT_COMPAT | ENT_HTML401. *

    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    Available flags constants
    Constant NameDescription
    ENT_COMPATWill convert double-quotes and leave single-quotes alone.
    ENT_QUOTESWill convert both double and single quotes.
    ENT_NOQUOTESWill leave both double and single quotes unconverted.
    ENT_IGNORE * Silently discard invalid code unit sequences instead of returning * an empty string. Using this flag is discouraged as it * {@link https://unicode.org/reports/tr36/#Deletion_of_Noncharacters » may have security implications}. *
    ENT_SUBSTITUTE * Replace invalid code unit sequences with a Unicode Replacement Character * U+FFFD (UTF-8) or &#FFFD; (otherwise) instead of returning an empty string. *
    ENT_DISALLOWED * Replace invalid code points for the given document type with a * Unicode Replacement Character U+FFFD (UTF-8) or &#FFFD; * (otherwise) instead of leaving them as is. This may be useful, for * instance, to ensure the well-formedness of XML documents with * embedded external content. *
    ENT_HTML401 * Handle code as HTML 4.01. *
    ENT_XML1 * Handle code as XML 1. *
    ENT_XHTML * Handle code as XHTML. *
    ENT_HTML5 * Handle code as HTML 5. *
    * @param string|null $encoding

    * Defines encoding used in conversion. * If omitted, the default value for this argument is ISO-8859-1 in * versions of PHP prior to 5.4.0, and UTF-8 from PHP 5.4.0 onwards. *

    *

    * For the purposes of this function, the encodings * ISO-8859-1, ISO-8859-15, * UTF-8, cp866, * cp1251, cp1252, and * KOI8-R are effectively equivalent, provided the * string itself is valid for the encoding, as * the characters affected by htmlspecialchars() occupy * the same positions in all of these encodings. *

    * @param bool $double_encode [optional]

    * When double_encode is turned off PHP will not * encode existing html entities, the default is to convert everything. *

    * @return string The converted string. */ #[Pure] function htmlspecialchars(string $string, int $flags = ENT_QUOTES|ENT_SUBSTITUTE, ?string $encoding = null, bool $double_encode = true): string {} /** * Convert all applicable characters to HTML entities * @link https://php.net/manual/en/function.htmlentities.php * @param string $string

    * The input string. *

    * @param int $flags [optional]

    * Like htmlspecialchars, the optional second * quote_style parameter lets you define what will * be done with 'single' and "double" quotes. It takes on one of three * constants with the default being ENT_COMPAT: *

    * Available quote_style constants * * * * * * * * * * * * * * * * *
    Constant NameDescription
    ENT_COMPATWill convert double-quotes and leave single-quotes alone.
    ENT_QUOTESWill convert both double and single quotes.
    ENT_NOQUOTESWill leave both double and single quotes unconverted.
    *

    * @param string|null $encoding [optional]

    * Like htmlspecialchars, it takes an optional * third argument charset which defines character * set used in conversion. * Presently, the ISO-8859-1 character set is used as the default. *

    * @param bool $double_encode [optional]

    * When double_encode is turned off PHP will not * encode existing html entities. The default is to convert everything. *

    * @return string the encoded string. */ #[Pure] function htmlentities(string $string, int $flags = ENT_QUOTES|ENT_SUBSTITUTE, ?string $encoding, bool $double_encode = true): string {} /** * Convert HTML entities to their corresponding characters * @link https://php.net/manual/en/function.html-entity-decode.php * @param string $string

    * The input string. *

    * @param int $flags [optional]

    * The optional second quote_style parameter lets * you define what will be done with 'single' and "double" quotes. It takes * on one of three constants with the default being * ENT_COMPAT: *

    * Available quote_style constants * * * * * * * * * * * * * * * * *
    Constant NameDescription
    ENT_COMPATWill convert double-quotes and leave single-quotes alone.
    ENT_QUOTESWill convert both double and single quotes.
    ENT_NOQUOTESWill leave both double and single quotes unconverted.
    *

    * @param string|null $encoding [optional]

    * The ISO-8859-1 character set is used as default for the optional third * charset. This defines the character set used in * conversion. *

    * @return string the decoded string. */ #[Pure] function html_entity_decode(string $string, int $flags = ENT_QUOTES|ENT_SUBSTITUTE, ?string $encoding): string {} /** * Convert special HTML entities back to characters * @link https://php.net/manual/en/function.htmlspecialchars-decode.php * @param string $string

    * The string to decode *

    * @param int $flags [optional]

    * The quote style. One of the following constants: *

    * quote_style constants * * * * * * * * * * * * * * * * *
    Constant NameDescription
    ENT_COMPATWill convert double-quotes and leave single-quotes alone * (default)
    ENT_QUOTESWill convert both double and single quotes
    ENT_NOQUOTESWill leave both double and single quotes unconverted
    *

    * @return string the decoded string. */ #[Pure] function htmlspecialchars_decode(string $string, int $flags = ENT_QUOTES|ENT_SUBSTITUTE): string {} /** * Returns the translation table used by htmlspecialchars and htmlentities * @link https://php.net/manual/en/function.get-html-translation-table.php * @param int $table

    * There are two new constants (HTML_ENTITIES, * HTML_SPECIALCHARS) that allow you to specify the * table you want. *

    * @param int $flags [optional]

    * Like the htmlspecialchars and * htmlentities functions you can optionally specify * the quote_style you are working with. * See the description * of these modes in htmlspecialchars. *

    * @param string $encoding [optional]

    * Encoding to use. * If omitted, the default value for this argument is ISO-8859-1 in * versions of PHP prior to 5.4.0, and UTF-8 from PHP 5.4.0 onwards. *

    * * *

    * The following character sets are supported: *

    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    Supported charsets
    CharsetAliasesDescription
    ISO-8859-1ISO8859-1 * Western European, Latin-1. *
    ISO-8859-5ISO8859-5 * Little used cyrillic charset (Latin/Cyrillic). *
    ISO-8859-15ISO8859-15 * Western European, Latin-9. Adds the Euro sign, French and Finnish * letters missing in Latin-1 (ISO-8859-1). *
    UTF-8  * ASCII compatible multi-byte 8-bit Unicode. *
    cp866ibm866, 866 * DOS-specific Cyrillic charset. *
    cp1251Windows-1251, win-1251, 1251 * Windows-specific Cyrillic charset. *
    cp1252Windows-1252, 1252 * Windows specific charset for Western European. *
    KOI8-Rkoi8-ru, koi8r * Russian. *
    BIG5950 * Traditional Chinese, mainly used in Taiwan. *
    GB2312936 * Simplified Chinese, national standard character set. *
    BIG5-HKSCS  * Big5 with Hong Kong extensions, Traditional Chinese. *
    Shift_JISSJIS, SJIS-win, cp932, 932 * Japanese *
    EUC-JPEUCJP, eucJP-win * Japanese *
    MacRoman  * Charset that was used by Mac OS. *
    ''  * An empty string activates detection from script encoding (Zend multibyte), * {@link https://php.net/manual/en/ini.core.php#ini.default-charset default_charset} and current * locale {@link https://php.net/manual/en/function.nl-langinfo.php nl_langinfo()} and * {@link https://php.net/manual/en/function.setlocale.php setlocale()}), in this order. Not recommended. *
    * *

    Note: * * Any other character sets are not recognized. The default encoding will be * used instead and a warning will be emitted. * *

    * @return array the translation table as an array. */ #[Pure] function get_html_translation_table( int $table = 0, int $flags = ENT_QUOTES|ENT_SUBSTITUTE, #[PhpStormStubsElementAvailable(from: '7.0')] string $encoding = "UTF-8" ): array {} /** * Calculate the sha1 hash of a string * @link https://php.net/manual/en/function.sha1.php * @param string $string

    * The input string. *

    * @param bool $binary [optional]

    * If the optional binary is set to true, * then the sha1 digest is instead returned in raw binary format with a * length of 20, otherwise the returned value is a 40-character * hexadecimal number. *

    * @return string the sha1 hash as a string. */ #[Pure] function sha1(string $string, bool $binary = false): string {} /** * Calculate the sha1 hash of a file * @link https://php.net/manual/en/function.sha1-file.php * @param string $filename

    * The filename *

    * @param bool $binary [optional]

    * When true, returns the digest in raw binary format with a length of * 20. *

    * @return string|false a string on success, false otherwise. */ #[Pure(true)] function sha1_file(string $filename, bool $binary = false): string|false {} /** * Calculate the md5 hash of a string * @link https://php.net/manual/en/function.md5.php * @param string $string

    * The string. *

    * @param bool $binary [optional]

    * If the optional raw_output is set to true, * then the md5 digest is instead returned in raw binary format with a * length of 16. *

    * @return string the hash as a 32-character hexadecimal number. */ #[Pure] function md5(string $string, bool $binary = false): string {} /** * Calculates the md5 hash of a given file * @link https://php.net/manual/en/function.md5-file.php * @param string $filename

    * The filename *

    * @param bool $binary [optional]

    * When true, returns the digest in raw binary format with a length of * 16. *

    * @return string|false a string on success, false otherwise. */ #[Pure(true)] function md5_file(string $filename, bool $binary = false): string|false {} /** * Calculates the crc32 polynomial of a string * @link https://php.net/manual/en/function.crc32.php * @param string $string

    * The data. *

    * @return int the crc32 checksum of str as an integer..1 */ #[Pure] function crc32(string $string): int {} /** * Parse a binary IPTC block into single tags. * Note: This function does not require the GD image library. * @link https://php.net/manual/en/function.iptcparse.php * @param string $iptc_block

    * A binary IPTC block. *

    * @return array|false an array using the tagmarker as an index and the value as the * value. It returns false on error or if no IPTC data was found. */ #[Pure] function iptcparse(string $iptc_block): array|false {} /** * Embeds binary IPTC data into a JPEG image. * Note: This function does not require the GD image library. * @link https://php.net/manual/en/function.iptcembed.php * @param string $iptc_data

    * The data to be written. *

    * @param string $filename

    * Path to the JPEG image. *

    * @param int $spool

    * Spool flag. If the spool flag is less than 2 then the JPEG will * be returned as a string. Otherwise the JPEG will be printed to * STDOUT. *

    * @return string|bool If spool is less than 2, the JPEG will be returned, or false on * failure. Otherwise returns true on success or false on failure. */ function iptcembed(string $iptc_data, string $filename, int $spool = 0): string|bool {} /** * Get the size of an image * @link https://php.net/manual/en/function.getimagesize.php * @param string $filename

    * This parameter specifies the file you wish to retrieve information * about. It can reference a local file or (configuration permitting) a * remote file using one of the supported streams. *

    * @param array &$image_info [optional]

    * This optional parameter allows you to extract some extended * information from the image file. Currently, this will return the * different JPG APP markers as an associative array. * Some programs use these APP markers to embed text information in * images. A very common one is to embed * IPTC information in the APP13 marker. * You can use the iptcparse function to parse the * binary APP13 marker into something readable. *

    * @return array|false an array with 7 elements. *

    * Index 0 and 1 contains respectively the width and the height of the image. *

    *

    * Some formats may contain no image or may contain multiple images. In these * cases, getimagesize might not be able to properly * determine the image size. getimagesize will return * zero for width and height in these cases. *

    *

    * Index 2 is one of the IMAGETYPE_XXX constants indicating * the type of the image. *

    *

    * Index 3 is a text string with the correct * height="yyy" width="xxx" string that can be used * directly in an IMG tag. *

    *

    * mime is the correspondant MIME type of the image. * This information can be used to deliver images with correct the HTTP * Content-type header: * getimagesize and MIME types *

    *

    * channels will be 3 for RGB pictures and 4 for CMYK * pictures. *

    *

    * bits is the number of bits for each color. *

    *

    * For some image types, the presence of channels and * bits values can be a bit * confusing. As an example, GIF always uses 3 channels * per pixel, but the number of bits per pixel cannot be calculated for an * animated GIF with a global color table. *

    *

    * On failure, false is returned. *

    */ #[ArrayShape([0 => "int", 1 => "int", 2 => "int", 3 => "string", "bits" => "int", "channels" => "int", "mime" => "string"])] function getimagesize(string $filename, &$image_info): array|false {} /** * Get Mime-Type for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype * @link https://php.net/manual/en/function.image-type-to-mime-type.php * @param int $image_type

    * One of the IMAGETYPE_XXX constants. *

    * @return string The returned values are as follows * * Returned values Constants * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    imagetypeReturned value
    IMAGETYPE_GIFimage/gif
    IMAGETYPE_JPEGimage/jpeg
    IMAGETYPE_PNGimage/png
    IMAGETYPE_SWFapplication/x-shockwave-flash
    IMAGETYPE_PSDimage/psd
    IMAGETYPE_BMPimage/bmp
    IMAGETYPE_TIFF_II (intel byte order)image/tiff
    * IMAGETYPE_TIFF_MM (motorola byte order) * image/tiff
    IMAGETYPE_JPCapplication/octet-stream
    IMAGETYPE_JP2image/jp2
    IMAGETYPE_JPXapplication/octet-stream
    IMAGETYPE_JB2application/octet-stream
    IMAGETYPE_SWCapplication/x-shockwave-flash
    IMAGETYPE_IFFimage/iff
    IMAGETYPE_WBMPimage/vnd.wap.wbmp
    IMAGETYPE_XBMimage/xbm
    IMAGETYPE_ICOimage/vnd.microsoft.icon
    */ #[Pure] function image_type_to_mime_type(int $image_type): string {} /** * Get file extension for image type * @link https://php.net/manual/en/function.image-type-to-extension.php * @param int $image_type

    * One of the IMAGETYPE_XXX constant. *

    * @param bool $include_dot [optional]

    * Removed since 8.0. * Whether to prepend a dot to the extension or not. Default to true. *

    * @return string|false A string with the extension corresponding to the given image type, or false on failure. */ #[Pure] function image_type_to_extension(int $image_type, bool $include_dot = true): string|false {} /** * Outputs information about PHP's configuration * @link https://php.net/manual/en/function.phpinfo.php * @param int $flags [optional]

    * The output may be customized by passing one or more of the * following constants bitwise values summed * together in the optional what parameter. * One can also combine the respective constants or bitwise values * together with the or operator. *

    *

    *

    * phpinfo options * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    Name (constant)ValueDescription
    INFO_GENERAL1 * The configuration line, "php.ini" location, build date, Web * Server, System and more. *
    INFO_CREDITS2 * PHP Credits. See also phpcredits. *
    INFO_CONFIGURATION4 * Current Local and Main values for PHP directives. See * also ini_get. *
    INFO_MODULES8 * Loaded modules and their respective settings. See also * get_loaded_extensions. *
    INFO_ENVIRONMENT16 * Environment Variable information that's also available in * $_ENV. *
    INFO_VARIABLES32 * Shows all * predefined variables from EGPCS (Environment, GET, * POST, Cookie, Server). *
    INFO_LICENSE64 * PHP License information. See also the license FAQ. *
    INFO_ALL-1 * Shows all of the above. *
    *

    * @return bool true on success or false on failure. */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function phpinfo(#[ExpectedValues(flags: [INFO_GENERAL, INFO_CREDITS, INFO_CONFIGURATION, INFO_MODULES, INFO_ENVIRONMENT, INFO_VARIABLES, INFO_LICENSE, INFO_ALL])] int $flags = INFO_ALL): bool {} /** * Gets the current PHP version * @link https://php.net/manual/en/function.phpversion.php * @param string|null $extension [optional]

    * An optional extension name. *

    * @return string|false If the optional extension parameter is * specified, phpversion returns the version of that * extension, or false if there is no version information associated or * the extension isn't enabled. */ #[Pure] function phpversion(?string $extension): string|false {} /** * Prints out the credits for PHP * @link https://php.net/manual/en/function.phpcredits.php * @param int $flags [optional]

    * To generate a custom credits page, you may want to use the * flags parameter. *

    *

    *

    * Pre-defined phpcredits flags * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    namedescription
    CREDITS_ALL * All the credits, equivalent to using: CREDITS_DOCS + * CREDITS_GENERAL + CREDITS_GROUP + * CREDITS_MODULES + CREDITS_FULLPAGE. * It generates a complete stand-alone HTML page with the appropriate tags. *
    CREDITS_DOCSThe credits for the documentation team
    CREDITS_FULLPAGE * Usually used in combination with the other flags. Indicates * that a complete stand-alone HTML page needs to be * printed including the information indicated by the other * flags. *
    CREDITS_GENERAL * General credits: Language design and concept, PHP 4.0 * authors and SAPI module. *
    CREDITS_GROUPA list of the core developers
    CREDITS_MODULES * A list of the extension modules for PHP, and their authors *
    CREDITS_SAPI * A list of the server API modules for PHP, and their authors *
    *

    * @return bool true on success or false on failure. */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function phpcredits(int $flags = CREDITS_ALL): bool {} /** * Gets the logo guid * @removed 5.5 * @link https://php.net/manual/en/function.php-logo-guid.php * @return string PHPE9568F34-D428-11d2-A769-00AA001ACF42. */ #[Pure] function php_logo_guid(): string {} /** * @removed 5.5 */ function php_real_logo_guid() {} /** * @removed 5.5 */ function php_egg_logo_guid() {} /** * Gets the Zend guid * @removed 5.5 * @link https://php.net/manual/en/function.zend-logo-guid.php * @return string PHPE9568F35-D428-11d2-A769-00AA001ACF42. */ function zend_logo_guid(): string {} /** * Returns the type of interface between web server and PHP * @link https://php.net/manual/en/function.php-sapi-name.php * @return string|false the interface type, as a lowercase string, or false on failure. *

    * Although not exhaustive, the possible return values include * aolserver, apache, * apache2filter, apache2handler, * caudium, cgi (until PHP 5.3), * cgi-fcgi, cli, * continuity, embed, * isapi, litespeed, * milter, nsapi, * phttpd, pi3web, roxen, * thttpd, tux, and webjames. *

    */ #[Pure] #[ExpectedValues(['cli', 'phpdbg', 'embed', 'apache', 'apache2handler', 'cgi-fcgi', 'cli-server', 'fpm-fcgi', 'litespeed'])] function php_sapi_name(): string|false {} /** * Returns information about the operating system PHP is running on * @link https://php.net/manual/en/function.php-uname.php * @param string $mode [optional]

    * mode is a single character that defines what * information is returned: * 'a': This is the default. Contains all modes in * the sequence "s n r v m".

    * @return string the description, as a string. */ #[Pure(true)] function php_uname(#[PhpStormStubsElementAvailable(from: '7.0')] string $mode = 'a'): string {} /** * Return a list of .ini files parsed from the additional ini dir * @link https://php.net/manual/en/function.php-ini-scanned-files.php * @return string|false a comma-separated string of .ini files on success. Each comma is * followed by a newline. If the directive --with-config-file-scan-dir wasn't set, * false is returned. If it was set and the directory was empty, an * empty string is returned. If a file is unrecognizable, the file will * still make it into the returned string but a PHP error will also result. * This PHP error will be seen both at compile time and while using * php_ini_scanned_files. */ #[Pure] function php_ini_scanned_files(): string|false {} /** * Retrieve a path to the loaded php.ini file * @link https://php.net/manual/en/function.php-ini-loaded-file.php * @return string|false The loaded "php.ini" path, or false if one is not loaded. * @since 5.2.4 */ #[Pure] function php_ini_loaded_file(): string|false {} /** * String comparisons using a "natural order" algorithm * @link https://php.net/manual/en/function.strnatcmp.php * @param string $string1

    * The first string. *

    * @param string $string2

    * The second string. *

    * @return int Similar to other string comparison functions, this one returns < 0 if * str1 is less than str2; > * 0 if str1 is greater than * str2, and 0 if they are equal. */ #[Pure] function strnatcmp(string $string1, string $string2): int {} /** * Case insensitive string comparisons using a "natural order" algorithm * @link https://php.net/manual/en/function.strnatcasecmp.php * @param string $string1

    * The first string. *

    * @param string $string2

    * The second string. *

    * @return int Similar to other string comparison functions, this one returns < 0 if * str1 is less than str2 > * 0 if str1 is greater than * str2, and 0 if they are equal. */ #[Pure] function strnatcasecmp(string $string1, string $string2): int {} /** * Count the number of substring occurrences * @link https://php.net/manual/en/function.substr-count.php * @param string $haystack

    * The string to search in *

    * @param string $needle

    * The substring to search for *

    * @param int $offset

    * The offset where to start counting. If the offset is negative, * counting starts from the end of the string. *

    * @param int|null $length [optional]

    * The maximum length after the specified offset to search for the * substring. It outputs a warning if the offset plus the length is * greater than the haystack length. A negative length counts from * the end of haystack. *

    * @return int<0,max> This functions returns an integer. */ #[Pure] function substr_count(string $haystack, string $needle, int $offset = 0, ?int $length): int {} /** * Finds the length of the initial segment of a string consisting * entirely of characters contained within a given mask. * @link https://php.net/manual/en/function.strspn.php * @param string $string

    * The string to examine. *

    * @param string $characters

    * The list of allowable characters to include in counted segments. *

    * @param int $offset

    * The position in subject to * start searching. *

    *

    * If start is given and is non-negative, * then strspn will begin * examining subject at * the start'th position. For instance, in * the string 'abcdef', the character at * position 0 is 'a', the * character at position 2 is * 'c', and so forth. *

    *

    * If start is given and is negative, * then strspn will begin * examining subject at * the start'th position from the end * of subject. *

    * @param int|null $length [optional]

    * The length of the segment from subject * to examine. *

    *

    * If length is given and is non-negative, * then subject will be examined * for length characters after the starting * position. *

    *

    * If lengthis given and is negative, * then subject will be examined from the * starting position up to length * characters from the end of subject. *

    * @return int the length of the initial segment of str1 * which consists entirely of characters in str2. */ #[Pure] function strspn(string $string, string $characters, int $offset = 0, ?int $length): int {} /** * Find length of initial segment not matching mask * @link https://php.net/manual/en/function.strcspn.php * @param string $string

    * The first string. *

    * @param string $characters

    * The second string. *

    * @param int $offset

    * The start position of the string to examine. *

    * @param int|null $length [optional]

    * The length of the string to examine. *

    * @return int the length of the segment as an integer. */ #[Pure] function strcspn(string $string, string $characters, int $offset = 0, ?int $length): int {} /** * Tokenize string * Note that only the first call to strtok uses the string argument. * Every subsequent call to strtok only needs the token to use, as it keeps track of where it is in the current string. * To start over, or to tokenize a new string you simply call strtok with the string argument again to initialize it. * Note that you may put multiple tokens in the token parameter. * The string will be tokenized when any one of the characters in the argument are found. * @link https://php.net/manual/en/function.strtok.php * @param string $string

    * The string being split up into smaller strings (tokens). *

    * @param string|null $token

    * The delimiter used when splitting up str. *

    * @return string|false A string token. */ function strtok( string $string, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.0')] $token, #[PhpStormStubsElementAvailable(from: '7.1')] ?string $token = null ): string|false {} */ function request_parse_body(?array $options = null): array {} /** * @since 8.4 */ function fpow(float $num1, float $num2): float {} /** * @since 8.4 */ enum RoundingMode implements \UnitEnum { case HalfAwayFromZero; case HalfTowardsZero; case HalfEven; case HalfOdd; case TowardsZero; case AwayFromZero; case NegativeInfinity; case PositiveInfinity; public static function cases(): array {} } * The encoded data. *

    * @param bool $strict [optional]

    * Returns false if input contains character from outside the base64 * alphabet. *

    * @return string|false the original data or false on failure. The returned data may be * binary. */ #[Pure] function base64_decode(string $string, bool $strict = false): string|false {} /** * Encodes data with MIME base64 * @link https://php.net/manual/en/function.base64-encode.php * @param string $string

    * The data to encode. *

    * @return string The encoded data, as a string. */ #[Pure] function base64_encode(string $string): string {} /** * Uuencode a string * @link https://php.net/manual/en/function.convert-uuencode.php * @param string $string

    * The data to be encoded. *

    * @return string the uuencoded data. */ #[Pure] function convert_uuencode(string $string): string {} /** * Decode a uuencoded string * @link https://php.net/manual/en/function.convert-uudecode.php * @param string $string

    * The uuencoded data. *

    * @return string|false the decoded data as a string. */ #[Pure] function convert_uudecode(string $string): string|false {} /** * Absolute value * @link https://php.net/manual/en/function.abs.php * @param int|float $num

    * The numeric value to process *

    * @return float|int The absolute value of number. If the * argument number is * of type float, the return type is also float, * otherwise it is integer (as float usually has a * bigger value range than integer). */ #[Pure] function abs(int|float $num): int|float {} /** * Round fractions up * @link https://php.net/manual/en/function.ceil.php * @param int|float $num

    * The value to round *

    * @return float|false value rounded up to the next highest * integer. * The return value of ceil is still of type * float as the value range of float is * usually bigger than that of integer. */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "float"], default: "float|false")] function ceil(int|float $num) {} /** * Round fractions down * @link https://php.net/manual/en/function.floor.php * @param int|float $num

    * The numeric value to round *

    * @return float|false value rounded to the next lowest integer. * The return value of floor is still of type * float because the value range of float is * usually bigger than that of integer. */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "float"], default: "float|false")] function floor(int|float $num) {} /** * Returns the rounded value of val to specified precision (number of digits after the decimal point). * precision can also be negative or zero (default). * Note: PHP doesn't handle strings like "12,300.2" correctly by default. See converting from strings. * @link https://php.net/manual/en/function.round.php * @param int|float $num

    * The value to round *

    * @param int $precision [optional]

    * The optional number of decimal digits to round to. *

    * @param int $mode [optional]

    * One of PHP_ROUND_HALF_UP, * PHP_ROUND_HALF_DOWN, * PHP_ROUND_HALF_EVEN, or * PHP_ROUND_HALF_ODD. *

    * @return float The rounded value */ #[Pure] function round(int|float $num, int $precision = 0, #[LanguageLevelTypeAware(['8.4' => 'RoundingMode|int'], default: 'int')] $mode = 0): float {} /** * Sine * @link https://php.net/manual/en/function.sin.php * @param float $num

    * A value in radians *

    * @return float The sine of arg */ #[Pure] function sin(float $num): float {} /** * Cosine * @link https://php.net/manual/en/function.cos.php * @param float $num

    * An angle in radians *

    * @return float The cosine of arg */ #[Pure] function cos(float $num): float {} /** * Tangent * @link https://php.net/manual/en/function.tan.php * @param float $num

    * The argument to process in radians *

    * @return float The tangent of arg */ #[Pure] function tan(float $num): float {} /** * Arc sine * @link https://php.net/manual/en/function.asin.php * @param float $num

    * The argument to process *

    * @return float The arc sine of arg in radians */ #[Pure] function asin(float $num): float {} /** * Arc cosine * @link https://php.net/manual/en/function.acos.php * @param float $num

    * The argument to process *

    * @return float The arc cosine of arg in radians. */ #[Pure] function acos(float $num): float {} /** * Arc tangent * @link https://php.net/manual/en/function.atan.php * @param float $num

    * The argument to process *

    * @return float The arc tangent of arg in radians. */ #[Pure] function atan(float $num): float {} /** * Inverse hyperbolic tangent * @link https://php.net/manual/en/function.atanh.php * @param float $num

    * The argument to process *

    * @return float Inverse hyperbolic tangent of arg */ #[Pure] function atanh(float $num): float {} /** * Arc tangent of two variables * @link https://php.net/manual/en/function.atan2.php * @param float $y

    * Dividend parameter *

    * @param float $x

    * Divisor parameter *

    * @return float The arc tangent of y/x * in radians. */ #[Pure] function atan2(float $y, float $x): float {} /** * Hyperbolic sine * @link https://php.net/manual/en/function.sinh.php * @param float $num

    * The argument to process *

    * @return float The hyperbolic sine of arg */ #[Pure] function sinh(float $num): float {} /** * Hyperbolic cosine * @link https://php.net/manual/en/function.cosh.php * @param float $num

    * The argument to process *

    * @return float The hyperbolic cosine of arg */ #[Pure] function cosh(float $num): float {} /** * Hyperbolic tangent * @link https://php.net/manual/en/function.tanh.php * @param float $num

    * The argument to process *

    * @return float The hyperbolic tangent of arg */ #[Pure] function tanh(float $num): float {} /** * Inverse hyperbolic sine * @link https://php.net/manual/en/function.asinh.php * @param float $num

    * The argument to process *

    * @return float The inverse hyperbolic sine of arg */ #[Pure] function asinh(float $num): float {} /** * Inverse hyperbolic cosine * @link https://php.net/manual/en/function.acosh.php * @param float $num

    * The value to process *

    * @return float The inverse hyperbolic cosine of arg */ #[Pure] function acosh(float $num): float {} /** * Returns exp(number) - 1, computed in a way that is accurate even * when the value of number is close to zero * @link https://php.net/manual/en/function.expm1.php * @param float $num

    * The argument to process *

    * @return float 'e' to the power of arg minus one */ #[Pure] function expm1(float $num): float {} /** * Returns log(1 + number), computed in a way that is accurate even when * the value of number is close to zero * @link https://php.net/manual/en/function.log1p.php * @param float $num

    * The argument to process *

    * @return float log(1 + number) */ #[Pure] function log1p(float $num): float {} /** * Get value of pi * @link https://php.net/manual/en/function.pi.php * @return float The value of pi as float. */ #[Pure] function pi(): float {} /** * Finds whether a value is a legal finite number * @link https://php.net/manual/en/function.is-finite.php * @param float $num

    * The value to check *

    * @return bool true if val is a legal finite * number within the allowed range for a PHP float on this platform, * else false. */ #[Pure] function is_finite(float $num): bool {} /** * Finds whether a value is not a number * @link https://php.net/manual/en/function.is-nan.php * @param float $num

    * The value to check *

    * @return bool true if val is 'not a number', * else false. */ #[Pure] function is_nan(float $num): bool {} /** * Integer division * @link https://php.net/manual/en/function.intdiv.php * @param int $num1

    Number to be divided.

    * @param int $num2

    Number which divides the dividend

    * @return int * @since 7.0 * @throws DivisionByZeroError

    if divisor is 0

    * @throws ArithmeticError

    if the dividend is PHP_INT_MIN and the divisor is -1

    */ #[Pure] function intdiv(int $num1, int $num2): int {} /** * Finds whether a value is infinite * @link https://php.net/manual/en/function.is-infinite.php * @param float $num

    * The value to check *

    * @return bool true if val is infinite, else false. */ #[Pure] function is_infinite(float $num): bool {} /** * Exponential expression * @link https://php.net/manual/en/function.pow.php * @param mixed $num

    * The base to use *

    * @param mixed $exponent

    * The exponent *

    * @return object|int|float base raised to the power of exp. * If the result can be represented as integer it will be returned as type * integer, else it will be returned as type float. * If the power cannot be computed false will be returned instead. */ #[Pure] function pow(mixed $num, mixed $exponent): object|int|float {} /** * Calculates the exponent of e * @link https://php.net/manual/en/function.exp.php * @param float $num

    * The argument to process *

    * @return float 'e' raised to the power of arg */ #[Pure] function exp(float $num): float {} /** * Natural logarithm * @link https://php.net/manual/en/function.log.php * @param float $num

    * The value to calculate the logarithm for *

    * @param float $base [optional]

    * The optional logarithmic base to use * (defaults to 'e' and so to the natural logarithm). *

    * @return float The logarithm of arg to * base, if given, or the * natural logarithm. */ #[Pure] function log(float $num, float $base = M_E): float {} /** * Base-10 logarithm * @link https://php.net/manual/en/function.log10.php * @param float $num

    * The argument to process *

    * @return float The base-10 logarithm of arg */ #[Pure] function log10(float $num): float {} /** * Square root * @link https://php.net/manual/en/function.sqrt.php * @param float $num

    * The argument to process *

    * @return float The square root of arg * or the special value NAN for negative numbers. */ #[Pure] function sqrt(float $num): float {} /** * Calculate the length of the hypotenuse of a right-angle triangle * @link https://php.net/manual/en/function.hypot.php * @param float $x

    * Length of first side *

    * @param float $y

    * Length of second side *

    * @return float Calculated length of the hypotenuse */ #[Pure] function hypot(float $x, float $y): float {} /** * Converts the number in degrees to the radian equivalent * @link https://php.net/manual/en/function.deg2rad.php * @param float $num

    * Angular value in degrees *

    * @return float The radian equivalent of number */ #[Pure] function deg2rad(float $num): float {} /** * Converts the radian number to the equivalent number in degrees * @link https://php.net/manual/en/function.rad2deg.php * @param float $num

    * A radian value *

    * @return float The equivalent of number in degrees */ #[Pure] function rad2deg(float $num): float {} /** * Binary to decimal * @link https://php.net/manual/en/function.bindec.php * @param string $binary_string

    * The binary string to convert *

    * @return int|float The decimal value of binary_string */ #[Pure] function bindec(string $binary_string): int|float {} /** * Hexadecimal to decimal * @link https://php.net/manual/en/function.hexdec.php * @param string $hex_string

    * The hexadecimal string to convert *

    * @return int|float The decimal representation of hex_string */ #[Pure] function hexdec(string $hex_string): int|float {} /** * Octal to decimal * @link https://php.net/manual/en/function.octdec.php * @param string $octal_string

    * The octal string to convert *

    * @return int|float The decimal representation of octal_string */ #[Pure] function octdec(string $octal_string): int|float {} /** * Decimal to binary * @link https://php.net/manual/en/function.decbin.php * @param int $num

    * Decimal value to convert *

    * * Range of inputs on 32-bit machines * * * * * * * * * * * * * * * * * * * * * * ... normal progression ... * * * * * * * * * * * * * * * * * * ... normal progression ... * * * * * * * * * * * *
    positive numbernegative numberreturn value
    00
    11
    210
    21474836461111111111111111111111111111110
    2147483647 (largest signed integer)1111111111111111111111111111111 (31 1's)
    2147483648-214748364810000000000000000000000000000000
    4294967294-211111111111111111111111111111110
    4294967295 (largest unsigned integer)-111111111111111111111111111111111 (32 1's)
    * * Range of inputs on 64-bit machines * * * * * * * * * * * * * * * * * * * * * * ... normal progression ... * * * * * * * * * * * * * * * * * * ... normal progression ... * * * * * * * * * * * *
    positive numbernegative numberreturn value
    00
    11
    210
    9223372036854775806111111111111111111111111111111111111111111111111111111111111110
    9223372036854775807 (largest signed integer)111111111111111111111111111111111111111111111111111111111111111 (31 1's)
    -92233720368547758081000000000000000000000000000000000000000000000000000000000000000
    -21111111111111111111111111111111111111111111111111111111111111110
    -11111111111111111111111111111111111111111111111111111111111111111 (64 1's)
    * @return string Binary string representation of number */ #[Pure] function decbin(int $num): string {} /** * Decimal to octal * @link https://php.net/manual/en/function.decoct.php * @param int $num

    * Decimal value to convert *

    * @return string Octal string representation of number */ #[Pure] function decoct(int $num): string {} /** * Decimal to hexadecimal * @link https://php.net/manual/en/function.dechex.php * @param int $num

    * Decimal value to convert *

    * @return string Hexadecimal string representation of number */ #[Pure] function dechex(int $num): string {} /** * Convert a number between arbitrary bases * @link https://php.net/manual/en/function.base-convert.php * @param string $num

    * The number to convert *

    * @param int $from_base

    * The base number is in *

    * @param int $to_base

    * The base to convert number to *

    * @return string number converted to base tobase */ #[Pure] function base_convert(string $num, int $from_base, int $to_base): string {} /** * Format a number with grouped thousands * @link https://php.net/manual/en/function.number-format.php * @param float $num

    * The number being formatted. *

    * @param int $decimals [optional]

    * Sets the number of decimal points. *

    * @param string|null $decimal_separator [optional] * @param string|null $thousands_separator [optional] * @return string A formatted version of number. */ #[Pure] function number_format(float $num, int $decimals = 0, ?string $decimal_separator = '.', ?string $thousands_separator = ','): string {} /** * Returns the floating point remainder (modulo) of the division * of the arguments * @link https://php.net/manual/en/function.fmod.php * @param float $num1

    * The dividend *

    * @param float $num2

    * The divisor *

    * @return float The floating point remainder of * x/y */ #[Pure] function fmod(float $num1, float $num2): float {} /** * Performs a floating-point division under * IEEE 754 semantics. Division by zero is considered well-defined and * will return one of Inf, -Inf or NaN. * @param float $num1 * @param float $num2 * @return float * @since 8.0 */ #[Pure] function fdiv(float $num1, float $num2): float {} /** * Converts a packed internet address to a human readable representation * @link https://php.net/manual/en/function.inet-ntop.php * @param string $ip

    * A 32bit IPv4, or 128bit IPv6 address. *

    * @return string|false a string representation of the address or false on failure. */ #[Pure] function inet_ntop(string $ip): string|false {} /** * Converts a human readable IP address to its packed in_addr representation * @link https://php.net/manual/en/function.inet-pton.php * @param string $ip

    * A human readable IPv4 or IPv6 address. *

    * @return string|false the in_addr representation of the given * address */ #[Pure] function inet_pton(string $ip): string|false {} /** * Converts a string containing an (IPv4) Internet Protocol dotted address into a long integer * @link https://php.net/manual/en/function.ip2long.php * @param string $ip

    * A standard format address. *

    * @return int|false the IPv4 address or false if ip_address * is invalid. */ #[Pure] function ip2long(string $ip): int|false {} /** * Converts an long integer address into a string in (IPv4) internet standard dotted format * @link https://php.net/manual/en/function.long2ip.php * @param int $ip

    * A proper address representation. *

    * @return string|false the Internet IP address as a string. */ #[Pure] #[LanguageLevelTypeAware(['8.4' => 'string'], default: 'string|false')] function long2ip(int $ip) {} /** * Gets the value of an environment variable * @link https://php.net/manual/en/function.getenv.php * @param string|null $name

    * The variable name. *

    * @param bool $local_only [optional]

    * Set to true to only return local environment variables (set by the operating system or putenv). *

    * @return string|array|false the value of the environment variable * varname or an associative array with all environment variables if no variable name * is provided, or false on an error. */ #[Pure(true)] function getenv( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.0')] $varname, #[PhpStormStubsElementAvailable(from: '7.1')] ?string $name = null, #[PhpStormStubsElementAvailable(from: '5.6')] bool $local_only = false ): array|string|false {} /** * Sets the value of an environment variable * @link https://php.net/manual/en/function.putenv.php * @param string $assignment

    * The setting, like "FOO=BAR" *

    * @return bool true on success or false on failure. */ function putenv(string $assignment): bool {} /** * Gets options from the command line argument list * @link https://php.net/manual/en/function.getopt.php * @param string $short_options Each character in this string will be used as option characters and * matched against options passed to the script starting with a single * hyphen (-). * For example, an option string "x" recognizes an * option -x. * Only a-z, A-Z and 0-9 are allowed. * @param array $long_options An array of options. Each element in this array will be used as option * strings and matched against options passed to the script starting with * two hyphens (--). * For example, an longopts element "opt" recognizes an * option --opt. * Prior to PHP5.3.0 this parameter was only available on few systems * @param int &$rest_index [optional] If the optind parameter is present, then the index where argument parsing stopped will be written to this variable. * @return string[]|false[]|false This function will return an array of option / argument pairs or false on * failure. */ function getopt( string $short_options, array $long_options = [], #[PhpStormStubsElementAvailable(from: '7.1')] &$rest_index ): array|false {} /** * Gets system load average * @link https://php.net/manual/en/function.sys-getloadavg.php * @return array|false an array with three samples (last 1, 5 and 15 * minutes). * @since 5.1.3 */ #[Pure(true)] function sys_getloadavg(): array|false {} /** * Return current Unix timestamp with microseconds * @link https://php.net/manual/en/function.microtime.php * @param bool $as_float [optional]

    * When called without the optional argument, this function returns the string * "msec sec" where sec is the current time measured in the number of * seconds since the Unix Epoch (0:00:00 January 1, 1970 GMT), and * msec is the microseconds part. * Both portions of the string are returned in units of seconds. *

    *

    * If the optional get_as_float is set to * true then a float (in seconds) is returned. *

    * @return string|float */ #[Pure(true)] function microtime(#[TypeContract(true: "float", false: "string")] bool $as_float = false): string|float {} /** * Get current time * @link https://php.net/manual/en/function.gettimeofday.php * @param bool $as_float [optional]

    * When set to true, a float instead of an array is returned. *

    * @return int[]|float By default an array is returned. If return_float * is set, then a float is returned. *

    *

    * Array keys: * "sec" - seconds since the Unix Epoch * "usec" - microseconds * "minuteswest" - minutes west of Greenwich * "dsttime" - type of dst correction */ #[Pure(true)] #[ArrayShape(["sec" => "int", "usec" => "int", "minuteswest" => "int", "dsttime" => "int"])] function gettimeofday(#[TypeContract(true: "float", false: "int[]")] bool $as_float = false): array|float {} /** * Gets the current resource usages * @link https://php.net/manual/en/function.getrusage.php * @param int $mode

    * If who is 1, getrusage will be called with * RUSAGE_CHILDREN. *

    * @return array|false an associative array containing the data returned from the system * call. All entries are accessible by using their documented field names. */ #[Pure(true)] function getrusage(int $mode = 0): array|false {} /** * Generate a unique ID * @link https://php.net/manual/en/function.uniqid.php * @param string $prefix [optional]

    * Can be useful, for instance, if you generate identifiers * simultaneously on several hosts that might happen to generate the * identifier at the same microsecond. *

    *

    * With an empty prefix, the returned string will * be 13 characters long. If more_entropy is * true, it will be 23 characters. *

    * @param bool $more_entropy [optional]

    * If set to true, uniqid will add additional * entropy (using the combined linear congruential generator) at the end * of the return value, which should make the results more unique. *

    * @return string the unique identifier, as a string. */ function uniqid(string $prefix = "", bool $more_entropy = false): string {} /** * Convert a quoted-printable string to an 8 bit string * @link https://php.net/manual/en/function.quoted-printable-decode.php * @param string $string

    * The input string. *

    * @return string the 8-bit binary string. */ #[Pure] function quoted_printable_decode(string $string): string {} /** * Convert a 8 bit string to a quoted-printable string * @link https://php.net/manual/en/function.quoted-printable-encode.php * @param string $string

    * The input string. *

    * @return string the encoded string. */ #[Pure] function quoted_printable_encode(string $string): string {} /** * Convert from one Cyrillic character set to another * @link https://php.net/manual/en/function.convert-cyr-string.php * @param string $str

    * The string to be converted. *

    * @param string $from

    * The source Cyrillic character set, as a single character. *

    * @param string $to

    * The target Cyrillic character set, as a single character. *

    * @return string the converted string. * @removed 8.0 * @see mb_convert_string() * @see iconv() * @see UConverter */ #[Pure] #[Deprecated(since: '7.4', reason: 'Us mb_convert_string(), iconv() or UConverter instead.')] function convert_cyr_string(string $str, string $from, string $to): string {} /** * Gets the name of the owner of the current PHP script * @link https://php.net/manual/en/function.get-current-user.php * @return string the username as a string. */ #[Pure(true)] function get_current_user(): string {} /** * Limits the maximum execution time * @link https://php.net/manual/en/function.set-time-limit.php * @param int $seconds

    * The maximum execution time, in seconds. If set to zero, no time limit * is imposed. *

    * @return bool Returns TRUE on success, or FALSE on failure. */ function set_time_limit(int $seconds): bool {} /** * Gets the value of a PHP configuration option * @link https://php.net/manual/en/function.get-cfg-var.php * @param string $option

    * The configuration option name. *

    * @return array|string|false the current value of the PHP configuration variable specified by * option, or false if an error occurs. */ #[Pure] function get_cfg_var(string $option): array|string|false {} /** * Alias: * {@see set_magic_quotes_runtime} * @link https://php.net/manual/en/function.magic-quotes-runtime.php * @param bool $new_setting * @removed 7.0 */ #[Deprecated(since: '5.3')] function magic_quotes_runtime(bool $new_setting) {} /** * Sets the current active configuration setting of magic_quotes_runtime * @link https://php.net/manual/en/function.set-magic-quotes-runtime.php * @param bool $new_setting

    * false for off, true for on. *

    * @return bool true on success or false on failure. * @removed 7.0 */ #[Deprecated(reason: "This function has been DEPRECATED as of PHP 5.4.0. Raises an E_CORE_ERROR", since: "5.3")] function set_magic_quotes_runtime(bool $new_setting): bool {} /** * Gets the current configuration setting of magic quotes gpc * @link https://php.net/manual/en/function.get-magic-quotes-gpc.php * @return int 0 if magic quotes gpc are off, 1 otherwise. * @removed 8.0 */ #[Deprecated(since: '7.4')] function get_magic_quotes_gpc(): int {} /** * Gets the current active configuration setting of magic_quotes_runtime * @link https://php.net/manual/en/function.get-magic-quotes-runtime.php * @return int 0 if magic quotes runtime is off, 1 otherwise. */ #[Deprecated(since: '7.4')] function get_magic_quotes_runtime(): int {} /** * Import GET/POST/Cookie variables into the global scope * @link https://php.net/manual/en/function.import-request-variables.php * @param string $types

    * Using the types parameter, you can specify * which request variables to import. You can use 'G', 'P' and 'C' * characters respectively for GET, POST and Cookie. These characters are * not case sensitive, so you can also use any combination of 'g', 'p' * and 'c'. POST includes the POST uploaded file information. *

    *

    * Note that the order of the letters matters, as when using * "GP", the * POST variables will overwrite GET variables with the same name. Any * other letters than GPC are discarded. *

    * @param string $prefix [optional]

    * Variable name prefix, prepended before all variable's name imported * into the global scope. So if you have a GET value named * "userid", and provide a prefix * "pref_", then you'll get a global variable named * $pref_userid. *

    *

    * Although the prefix parameter is optional, you * will get an E_NOTICE level * error if you specify no prefix, or specify an empty string as a * prefix. This is a possible security hazard. Notice level errors are * not displayed using the default error reporting level. *

    * @return bool true on success or false on failure. * @removed 5.4 */ #[Deprecated(reason: "This function has been DEPRECATED as of PHP 5.3.0", since: "5.3")] function import_request_variables(string $types, $prefix = null): bool {} /** * Send an error message to the defined error handling routines * @link https://php.net/manual/en/function.error-log.php * @param string $message

    * The error message that should be logged. *

    * @param int $message_type

    * Says where the error should go. The possible message types are as * follows: *

    *

    *

    * error_log log types * * * * * * * * * * * * * * * * * * * * *
    0 * message is sent to PHP's system logger, using * the Operating System's system logging mechanism or a file, depending * on what the error_log * configuration directive is set to. This is the default option. *
    1 * message is sent by email to the address in * the destination parameter. This is the only * message type where the fourth parameter, * extra_headers is used. *
    2 * No longer an option. *
    3 * message is appended to the file * destination. A newline is not automatically * added to the end of the message string. *
    4 * message is sent directly to the SAPI logging * handler. *
    *

    * @param string|null $destination [optional]

    * The destination. Its meaning depends on the * message_type parameter as described above. *

    * @param string|null $additional_headers [optional]

    * The extra headers. It's used when the message_type * parameter is set to 1. * This message type uses the same internal function as * mail does. *

    * @return bool true on success or false on failure. */ function error_log(string $message, int $message_type = 0, ?string $destination, ?string $additional_headers): bool {} * This parameter is only the filename of the * extension to load which also depends on your platform. For example, * the sockets extension (if compiled * as a shared module, not the default!) would be called * sockets.so on Unix platforms whereas it is called * php_sockets.dll on the Windows platform. *

    *

    * The directory where the extension is loaded from depends on your * platform: *

    *

    * Windows - If not explicitly set in the php.ini, the extension is * loaded from C:\php4\extensions\ (PHP 4) or * C:\php5\ (PHP 5) by default. *

    *

    * Unix - If not explicitly set in the php.ini, the default extension * directory depends on * whether PHP has been built with --enable-debug * or not

    * @return bool TRUE on success or FALSE on failure. If the functionality of loading modules is not available * or has been disabled (either by setting * enable_dl off or by enabling safe mode * in php.ini) an E_ERROR is emitted * and execution is stopped. If dl fails because the * specified library couldn't be loaded, in addition to FALSE an * E_WARNING message is emitted. * Loads a PHP extension at runtime * @link https://php.net/manual/en/function.dl.php */ function dl(string $extension_filename): bool {} /** * Sets the process title * @link https://php.net/manual/en/function.cli-set-process-title.php * @param string $title

    * The new title. *

    * @return bool TRUE on success or FALSE on failure. * @since 5.5 */ function cli_set_process_title(string $title): bool {} /** * Returns the current process title, as set by cli_set_process_title(). Note that this may not exactly match what is shown in ps or top, depending on your operating system. * * @link https://php.net/manual/en/function.cli-get-process-title.php * @return string|null Return a string with the current process title or NULL on error. * @since 5.5 */ #[Pure(true)] function cli_get_process_title(): ?string {} /** * Verify that the contents of a variable is accepted by the iterable pseudo-type, i.e. that it is an array or an object implementing Traversable * @param mixed $value * @return bool * @since 7.1 * @link https://php.net/manual/en/function.is-iterable.php */ #[Pure] function is_iterable(mixed $value): bool {} /** * Encodes an ISO-8859-1 string to UTF-8 * @link https://php.net/manual/en/function.utf8-encode.php * @param string $string

    * An ISO-8859-1 string. *

    * @return string the UTF-8 translation of data. * @deprecated 8.2 Consider to use {@link mb_convert_encoding}, {@link UConverter::transcode()} or {@link iconv()} */ #[Pure] #[Deprecated(replacement: "mb_convert_encoding(%parameter0%, 'UTF-8', 'ISO-8859-1')", since: "8.2")] function utf8_encode(string $string): string {} /** * Converts a string with ISO-8859-1 characters encoded with UTF-8 * to single-byte ISO-8859-1 * @link https://php.net/manual/en/function.utf8-decode.php * @param string $string

    * An UTF-8 encoded string. *

    * @return string the ISO-8859-1 translation of data. * @deprecated 8.2 Consider to use {@link mb_convert_encoding}, {@link UConverter::transcode()} or {@link iconv()} */ #[Pure] #[Deprecated(replacement: "mb_convert_encoding(%parameter0%, 'ISO-8859-1', 'UTF-8')", since: "8.2")] function utf8_decode(string $string): string {} /** * Clear the most recent error * @link https://php.net/manual/en/function.error-clear-last.php * @return void * @since 7.0 */ function error_clear_last(): void {} /** * Get process codepage * @link https://php.net/manual/en/function.sapi-windows-cp-get * @param string $kind The kind of operating system codepage to get, either 'ansi' or 'oem'. Any other value refers to the current codepage of the process. * @return int

    * If kind is 'ansi', the current ANSI code page of the operating system is returned. * If kind is 'oem', the current OEM code page of the operating system is returned. * Otherwise, the current codepage of the process is returned. *

    * @since 7.1 */ function sapi_windows_cp_get(string $kind = ""): int {} /** * Set process codepage * @link https://php.net/manual/en/function.sapi-windows-cp-set * @param int $codepage A codepage identifier. * @return bool Returns true on success or false on failure. * @since 7.1 */ function sapi_windows_cp_set(int $codepage): bool {} /** * Convert string from one codepage to another * @link https://php.net/manual/en/function.sapi-windows-cp-conv.php * @param int|string $in_codepage The codepage of the subject string. Either the codepage name or identifier. * @param int|string $out_codepage The codepage to convert the subject string to. Either the codepage name or identifier. * @param string $subject The string to convert. * @return string|null The subject string converted to out_codepage, or null on failure. * @since 7.1 */ function sapi_windows_cp_conv(int|string $in_codepage, int|string $out_codepage, string $subject): ?string {} /** * Indicates whether the codepage is utf-8 compatible * @link https://www.php.net/manual/en/function.sapi-windows-cp-is-utf8.php * @return bool * @since 7.1 */ function sapi_windows_cp_is_utf8(): bool {} /** * Get or set VT100 support for the specified stream associated to an output buffer of a Windows console. * * At startup, PHP tries to enable the VT100 feature of the STDOUT/STDERR streams. * By the way, if those streams are redirected to a file, the VT100 features may not be enabled. * * If VT100 support is enabled, it is possible to use control sequences as they are known from the VT100 terminal. * They allow the modification of the terminal's output. On Windows these sequences are called Console Virtual Terminal Sequences. * * Warning This function uses the ENABLE_VIRTUAL_TERMINAL_PROCESSING flag implemented in the Windows 10 API, so the VT100 feature may not be available on older Windows versions. * * @link https://php.net/manual/en/function.sapi-windows-vt100-support.php * @param resource $stream The stream on which the function will operate. * @param bool|null $enable

    * If bool, the VT100 feature will be enabled (if true) or disabled (if false). *

    *

    * If enable is null, the function returns true if the stream stream has VT100 control codes enabled, false otherwise. *

    *

    * If enable is a bool, the function will try to enable or disable the VT100 features of the stream stream. * If the feature has been successfully enabled (or disabled), the function will return true, or false otherwise. *

    * @return bool

    * If enable is null: returns true if the VT100 feature is enabled, false otherwise. *

    *

    * If enable is a bool: Returns true on success or false on failure. *

    * @since 7.2 */ function sapi_windows_vt100_support($stream, ?bool $enable = null): bool {} /** * Set or remove a CTRL event handler, which allows Windows CLI processes to intercept or ignore CTRL+C and CTRL+BREAK events. * Note that in multithreaded environments, this is only possible when called from the main thread. * * @link https://www.php.net/manual/en/function.sapi-windows-set-ctrl-handler.php * @param callable|null $handler

    * A callback function to set or remove. If set, this function will be called whenever a CTRL+C or CTRL+BREAK event occurs. *

    *

    * The function is supposed to have the following signature: * * handler(int $event): void * * event The CTRL event which has been received; either PHP_WINDOWS_EVENT_CTRL_C or PHP_WINDOWS_EVENT_CTRL_BREAK. *

    *

    * Setting a null handler causes the process to ignore CTRL+C events, but not CTRL+BREAK events. *

    * @param bool $add If true, the handler is set. If false, the handler is removed. * @return bool TRUE on success or FALSE on failure. * @since 7.4 */ function sapi_windows_set_ctrl_handler(?callable $handler, bool $add = true): bool {} /** * Send a CTRL event to another process. * * @link https://www.php.net/manual/en/function.sapi-windows-generate-ctrl-event.php * @param int $event The CTRL even to send; either PHP_WINDOWS_EVENT_CTRL_C or PHP_WINDOWS_EVENT_CTRL_BREAK. * @param int $pid [optional] The ID of the process to which to send the event to. If 0 is given, the event is sent to all processes of the process group. * @return bool TRUE on success or FALSE on failure. * @since 7.4 */ function sapi_windows_generate_ctrl_event(int $event, int $pid = 0): bool {} /** * The full path and filename of the file. If used inside an include, * the name of the included file is returned. * Since PHP 4.0.2, __FILE__ always contains an * absolute path with symlinks resolved whereas in older versions it contained relative path * under some circumstances. * @link https://php.net/manual/en/language.constants.predefined.php */ define('__FILE__', '', true); /** * The current line number of the file. * @link https://php.net/manual/en/language.constants.predefined.php */ define('__LINE__', 0, true); /** * The class name. (Added in PHP 4.3.0) As of PHP 5 this constant * returns the class name as it was declared (case-sensitive). In PHP * 4 its value is always lowercased. The class name includes the namespace * it was declared in (e.g. Foo\Bar). * Note that as of PHP 5.4 __CLASS__ works also in traits. When used * in a trait method, __CLASS__ is the name of the class the trait * is used in. * @link https://php.net/manual/en/language.constants.predefined.php */ define('__CLASS__', '', true); /** * The function name. (Added in PHP 4.3.0) As of PHP 5 this constant * returns the function name as it was declared (case-sensitive). In * PHP 4 its value is always lowercased. * @link https://php.net/manual/en/language.constants.predefined.php */ define('__FUNCTION__', '', true); /** * The class method name. (Added in PHP 5.0.0) The method name is * returned as it was declared (case-sensitive). * @link https://php.net/manual/en/language.constants.predefined.php */ define('__METHOD__', '', true); /** * The trait name. (Added in PHP 5.4.0) As of PHP 5.4 this constant * returns the trait as it was declared (case-sensitive). The trait name includes the namespace * it was declared in (e.g. Foo\Bar). * @since 5.4 * @link https://php.net/manual/en/language.constants.predefined.php */ define('__TRAIT__', '', true); /** * The directory of the file. If used inside an include, * the directory of the included file is returned. This is equivalent * to `dirname(__FILE__)`. This directory name * does not have a trailing slash unless it is the root directory. * @link https://php.net/manual/en/language.constants.predefined.php */ define('__DIR__', '', true); /** * The name of the current namespace (case-sensitive). This constant * is defined in compile-time (Added in PHP 5.3.0). * @link https://php.net/manual/en/language.constants.predefined.php */ define('__NAMESPACE__', '', true); e
    constant */ define('M_E', 2.718281828459); /** * {@link log}2e constant */ define('M_LOG2E', 1.442695040889); /** * {@link log}10e constant */ define('M_LOG10E', 0.43429448190325); /** * {@link log}e2 constant */ define('M_LN2', 0.69314718055995); /** * {@link log}e10 constant */ define('M_LN10', 2.302585092994); /** * π constant */ define('M_PI', 3.1415926535898); /** * π/2 constant */ define('M_PI_2', 1.5707963267949); /** * π/4 constant */ define('M_PI_4', 0.78539816339745); /** * 1/π constant */ define('M_1_PI', 0.31830988618379); /** * 2/π constant */ define('M_2_PI', 0.63661977236758); /** * {@link sqrt}(π) constant */ define('M_SQRTPI', 1.7724538509055); /** * 2/{@link sqrt}(π) constant */ define('M_2_SQRTPI', 1.1283791670955); /** * {@link log}eπ constant */ define('M_LNPI', 1.1447298858494); /** * Euler constant */ define('M_EULER', 0.57721566490153); /** * {@link sqrt}(2) constant */ define('M_SQRT2', 1.4142135623731); /** * 1/{@link sqrt}(2) constant */ define('M_SQRT1_2', 0.70710678118655); /** * {@link sqrt}(3) constant */ define('M_SQRT3', 1.7320508075689); /** * The infinite */ define('INF', (float)INF); /** * Not A Number */ define('NAN', (float)NAN); /** * Round halves up * @link https://php.net/manual/en/math.constants.php */ define('PHP_ROUND_HALF_UP', 1); /** * Round halves down * @link https://php.net/manual/en/math.constants.php */ define('PHP_ROUND_HALF_DOWN', 2); /** * Round halves to even numbers * @link https://php.net/manual/en/math.constants.php */ define('PHP_ROUND_HALF_EVEN', 3); /** * Round halves to odd numbers * @link https://php.net/manual/en/math.constants.php */ define('PHP_ROUND_HALF_ODD', 4); define('INFO_GENERAL', 1); /** * PHP Credits. See also phpcredits. * @link https://php.net/manual/en/info.constants.php */ define('INFO_CREDITS', 2); /** * Current Local and Main values for PHP directives. See * also ini_get. * @link https://php.net/manual/en/info.constants.php */ define('INFO_CONFIGURATION', 4); /** * Loaded modules and their respective settings. * @link https://php.net/manual/en/info.constants.php */ define('INFO_MODULES', 8); /** * Environment Variable information that's also available in * $_ENV. * @link https://php.net/manual/en/info.constants.php */ define('INFO_ENVIRONMENT', 16); /** * Shows all * predefined variables from EGPCS (Environment, GET, * POST, Cookie, Server). * @link https://php.net/manual/en/info.constants.php */ define('INFO_VARIABLES', 32); /** * PHP License information. See also the license faq. * @link https://php.net/manual/en/info.constants.php */ define('INFO_LICENSE', 64); define('INFO_ALL', 4294967295); /** * A list of the core developers * @link https://php.net/manual/en/info.constants.php */ define('CREDITS_GROUP', 1); /** * General credits: Language design and concept, PHP * authors and SAPI module. * @link https://php.net/manual/en/info.constants.php */ define('CREDITS_GENERAL', 2); /** * A list of the server API modules for PHP, and their authors. * @link https://php.net/manual/en/info.constants.php */ define('CREDITS_SAPI', 4); /** * A list of the extension modules for PHP, and their authors. * @link https://php.net/manual/en/info.constants.php */ define('CREDITS_MODULES', 8); /** * The credits for the documentation team. * @link https://php.net/manual/en/info.constants.php */ define('CREDITS_DOCS', 16); /** * Usually used in combination with the other flags. Indicates * that a complete stand-alone HTML page needs to be * printed including the information indicated by the other * flags. * @link https://php.net/manual/en/info.constants.php */ define('CREDITS_FULLPAGE', 32); /** * The credits for the quality assurance team. * @link https://php.net/manual/en/info.constants.php */ define('CREDITS_QA', 64); /** * The configuration line, "php.ini" location, build date, Web * Server, System and more. * @link https://php.net/manual/en/info.constants.php */ define('CREDITS_ALL', 4294967295); define('HTML_SPECIALCHARS', 0); define('HTML_ENTITIES', 1); /** * Will convert double-quotes and leave single-quotes alone. * @link https://php.net/manual/en/function.htmlspecialchars.php */ define('ENT_COMPAT', 2); /** * Will convert both double and single quotes. * @link https://php.net/manual/en/function.htmlspecialchars.php */ define('ENT_QUOTES', 3); /** * Will leave both double and single quotes unconverted. * @link https://php.net/manual/en/function.htmlspecialchars.php */ define('ENT_NOQUOTES', 0); /** * Silently discard invalid code unit sequences instead of returning an empty string. * Using this flag is discouraged as it may have security implications. * @link https://php.net/manual/en/function.htmlspecialchars.php */ define('ENT_IGNORE', 4); define('STR_PAD_LEFT', 0); define('STR_PAD_RIGHT', 1); define('STR_PAD_BOTH', 2); define('PATHINFO_DIRNAME', 1); define('PATHINFO_BASENAME', 2); define('PATHINFO_EXTENSION', 4); /** * @link https://php.net/manual/en/filesystem.constants.php */ define('PATHINFO_FILENAME', 8); define('PATHINFO_ALL', 15); define('CHAR_MAX', 127); define('LC_CTYPE', 0); define('LC_NUMERIC', 1); define('LC_TIME', 2); define('LC_COLLATE', 3); define('LC_MONETARY', 4); define('LC_ALL', 6); define('LC_MESSAGES', 5); define('SEEK_SET', 0); define('SEEK_CUR', 1); define('SEEK_END', 2); /** * Acquire a shared lock (reader). * @link https://www.php.net/manual/en/function.flock.php */ define('LOCK_SH', 1); /** * Acquire an exclusive lock (writer). * @link https://www.php.net/manual/en/function.flock.php */ define('LOCK_EX', 2); /** * Release lock (shared or exclusive). * @link https://www.php.net/manual/en/function.flock.php */ define('LOCK_UN', 3); /** * Non-blocking operation while locking. * @link https://www.php.net/manual/en/function.flock.php */ define('LOCK_NB', 4); /** * A connection with an external resource has been established. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_CONNECT', 2); /** * Additional authorization is required to access the specified resource. * Typical issued with severity level of * STREAM_NOTIFY_SEVERITY_ERR. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_AUTH_REQUIRED', 3); /** * Authorization has been completed (with or without success). * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_AUTH_RESULT', 10); /** * The mime-type of resource has been identified, * refer to message for a description of the * discovered type. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_MIME_TYPE_IS', 4); /** * The size of the resource has been discovered. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_FILE_SIZE_IS', 5); /** * The external resource has redirected the stream to an alternate * location. Refer to message. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_REDIRECTED', 6); /** * Indicates current progress of the stream transfer in * bytes_transferred and possibly * bytes_max as well. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_PROGRESS', 7); /** * A generic error occurred on the stream, consult * message and message_code * for details. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_FAILURE', 9); /** * There is no more data available on the stream. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_COMPLETED', 8); /** * A remote address required for this stream has been resolved, or the resolution * failed. See severity for an indication of which happened. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_RESOLVE', 1); /** * Normal, non-error related, notification. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_SEVERITY_INFO', 0); /** * Non critical error condition. Processing may continue. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_SEVERITY_WARN', 1); /** * A critical error occurred. Processing cannot continue. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_NOTIFY_SEVERITY_ERR', 2); /** * Used with stream_filter_append and * stream_filter_prepend to indicate * that the specified filter should only be applied when * reading * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_FILTER_READ', 1); /** * Used with stream_filter_append and * stream_filter_prepend to indicate * that the specified filter should only be applied when * writing * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_FILTER_WRITE', 2); /** * This constant is equivalent to * STREAM_FILTER_READ | STREAM_FILTER_WRITE * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_FILTER_ALL', 3); /** * Client socket opened with stream_socket_client * should remain persistent between page loads. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_CLIENT_PERSISTENT', 1); /** * Open client socket asynchronously. This option must be used * together with the STREAM_CLIENT_CONNECT flag. * Used with stream_socket_client. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_CLIENT_ASYNC_CONNECT', 2); /** * Open client socket connection. Client sockets should always * include this flag. Used with stream_socket_client. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_CLIENT_CONNECT', 4); /** * Used with stream_socket_shutdown to disable * further receptions. * @since 5.2.1 * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_SHUT_RD', 0); /** * Used with stream_socket_shutdown to disable * further transmissions. * @since 5.2.1 * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_SHUT_WR', 1); /** * Used with stream_socket_shutdown to disable * further receptions and transmissions. * @since 5.2.1 * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_SHUT_RDWR', 2); /** * Internet Protocol Version 4 (IPv4). * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_PF_INET', 2); /** * Internet Protocol Version 6 (IPv6). * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_PF_INET6', 10); /** * Unix system internal protocols. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_PF_UNIX', 1); /** * Provides a IP socket. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_IPPROTO_IP', 0); /** * Provides a TCP socket. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_IPPROTO_TCP', 6); /** * Provides a UDP socket. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_IPPROTO_UDP', 17); /** * Provides a ICMP socket. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_IPPROTO_ICMP', 1); /** * Provides a RAW socket. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_IPPROTO_RAW', 255); /** * Provides sequenced, two-way byte streams with a transmission mechanism * for out-of-band data (TCP, for example). * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_SOCK_STREAM', 1); /** * Provides datagrams, which are connectionless messages (UDP, for * example). * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_SOCK_DGRAM', 2); /** * Provides a raw socket, which provides access to internal network * protocols and interfaces. Usually this type of socket is just available * to the root user. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_SOCK_RAW', 3); /** * Provides a sequenced packet stream socket. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_SOCK_SEQPACKET', 5); /** * Provides a RDM (Reliably-delivered messages) socket. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_SOCK_RDM', 4); define('STREAM_PEEK', 2); define('STREAM_OOB', 1); /** * Tells a stream created with stream_socket_server * to bind to the specified target. Server sockets should always include this flag. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_SERVER_BIND', 4); /** * Tells a stream created with stream_socket_server * and bound using the STREAM_SERVER_BIND flag to start * listening on the socket. Connection-orientated transports (such as TCP) * must use this flag, otherwise the server socket will not be enabled. * Using this flag for connect-less transports (such as UDP) is an error. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_SERVER_LISTEN', 8); /** * Search for filename in include_path * @link https://php.net/manual/en/filesystem.constants.php */ define('FILE_USE_INCLUDE_PATH', 1); /** * Strip EOL characters * @link https://php.net/manual/en/filesystem.constants.php */ define('FILE_IGNORE_NEW_LINES', 2); /** * Skip empty lines * @link https://php.net/manual/en/filesystem.constants.php */ define('FILE_SKIP_EMPTY_LINES', 4); /** * Append content to existing file. * @link https://php.net/manual/en/filesystem.constants.php */ define('FILE_APPEND', 8); define('FILE_NO_DEFAULT_CONTEXT', 16); /** *

    * This constant has no effect prior to PHP 6. It is only available for * forward compatibility. *

    * @since 5.2.7 * @link https://php.net/manual/en/filesystem.constants.php * @deprecated 8.1 */ define('FILE_TEXT', 0); /** *

    * This constant has no effect prior to PHP 6. It is only available for * forward compatibility. *

    * @since 5.2.7 * @link https://php.net/manual/en/filesystem.constants.php * @deprecated 8.1 */ define('FILE_BINARY', 0); /** * Disable backslash escaping. * @link https://php.net/manual/en/filesystem.constants.php */ define('FNM_NOESCAPE', 2); /** * Slash in string only matches slash in the given pattern. * @link https://php.net/manual/en/filesystem.constants.php */ define('FNM_PATHNAME', 1); /** * Leading period in string must be exactly matched by period in the given pattern. * @link https://php.net/manual/en/filesystem.constants.php */ define('FNM_PERIOD', 4); /** * Caseless match. Part of the GNU extension. * @link https://php.net/manual/en/filesystem.constants.php */ define('FNM_CASEFOLD', 16); /** * Return Code indicating that the * userspace filter returned buckets in $out. * @link https://php.net/manual/en/stream.constants.php */ define('PSFS_PASS_ON', 2); /** * Return Code indicating that the * userspace filter did not return buckets in $out * (i.e. No data available). * @link https://php.net/manual/en/stream.constants.php */ define('PSFS_FEED_ME', 1); /** * Return Code indicating that the * userspace filter encountered an unrecoverable error * (i.e. Invalid data received). * @link https://php.net/manual/en/stream.constants.php */ define('PSFS_ERR_FATAL', 0); /** * Regular read/write. * @link https://php.net/manual/en/stream.constants.php */ define('PSFS_FLAG_NORMAL', 0); /** * An incremental flush. * @link https://php.net/manual/en/stream.constants.php */ define('PSFS_FLAG_FLUSH_INC', 1); /** * Final flush prior to closing. * @link https://php.net/manual/en/stream.constants.php */ define('PSFS_FLAG_FLUSH_CLOSE', 2); define('ABDAY_1', 131072); define('ABDAY_2', 131073); define('ABDAY_3', 131074); define('ABDAY_4', 131075); define('ABDAY_5', 131076); define('ABDAY_6', 131077); define('ABDAY_7', 131078); define('DAY_1', 131079); define('DAY_2', 131080); define('DAY_3', 131081); define('DAY_4', 131082); define('DAY_5', 131083); define('DAY_6', 131084); define('DAY_7', 131085); define('ABMON_1', 131086); define('ABMON_2', 131087); define('ABMON_3', 131088); define('ABMON_4', 131089); define('ABMON_5', 131090); define('ABMON_6', 131091); define('ABMON_7', 131092); define('ABMON_8', 131093); define('ABMON_9', 131094); define('ABMON_10', 131095); define('ABMON_11', 131096); define('ABMON_12', 131097); define('MON_1', 131098); define('MON_2', 131099); define('MON_3', 131100); define('MON_4', 131101); define('MON_5', 131102); define('MON_6', 131103); define('MON_7', 131104); define('MON_8', 131105); define('MON_9', 131106); define('MON_10', 131107); define('MON_11', 131108); define('MON_12', 131109); define('AM_STR', 131110); define('PM_STR', 131111); define('D_T_FMT', 131112); define('D_FMT', 131113); define('T_FMT', 131114); define('T_FMT_AMPM', 131115); define('ERA', 131116); define('ERA_D_T_FMT', 131120); define('ERA_D_FMT', 131118); define('ERA_T_FMT', 131121); define('ALT_DIGITS', 131119); define('CRNCYSTR', 262159); define('RADIXCHAR', 65536); define('THOUSEP', 65537); define('YESEXPR', 327680); define('NOEXPR', 327681); define('YESSTR', 327682); define('NOSTR', 327683); define('CODESET', 14); define('CRYPT_SALT_LENGTH', 123); define('CRYPT_STD_DES', 1); define('CRYPT_EXT_DES', 1); define('CRYPT_MD5', 1); define('CRYPT_BLOWFISH', 1); define('CRYPT_SHA256', 1); define('CRYPT_SHA512', 1); define('DIRECTORY_SEPARATOR', "/"); define('PATH_SEPARATOR', ":"); define('GLOB_BRACE', 1024); define('GLOB_MARK', 2); define('GLOB_NOSORT', 4); define('GLOB_NOCHECK', 16); define('GLOB_NOESCAPE', 64); define('GLOB_ERR', 1); define('GLOB_ONLYDIR', 1073741824); define('GLOB_AVAILABLE_FLAGS', 1073741911); define('EXTR_OVERWRITE', 0); define('EXTR_SKIP', 1); define('EXTR_PREFIX_SAME', 2); define('EXTR_PREFIX_ALL', 3); define('EXTR_PREFIX_INVALID', 4); define('EXTR_PREFIX_IF_EXISTS', 5); define('EXTR_IF_EXISTS', 6); define('EXTR_REFS', 256); /** * SORT_ASC is used with * array_multisort to sort in ascending order. * @link https://php.net/manual/en/array.constants.php */ define('SORT_ASC', 4); /** * SORT_DESC is used with * array_multisort to sort in descending order. * @link https://php.net/manual/en/array.constants.php */ define('SORT_DESC', 3); /** * SORT_REGULAR is used to compare items normally. * @link https://php.net/manual/en/array.constants.php */ define('SORT_REGULAR', 0); /** * SORT_NUMERIC is used to compare items numerically. * @link https://php.net/manual/en/array.constants.php */ define('SORT_NUMERIC', 1); /** * SORT_STRING is used to compare items as strings. * @link https://php.net/manual/en/array.constants.php */ define('SORT_STRING', 2); /** * SORT_LOCALE_STRING is used to compare items as * strings, based on the current locale. * @since 5.0.2 * @link https://php.net/manual/en/array.constants.php */ define('SORT_LOCALE_STRING', 5); /** * CASE_LOWER is used with * array_change_key_case and is used to convert array * keys to lower case. This is also the default case for * array_change_key_case. * @link https://php.net/manual/en/array.constants.php */ define('CASE_LOWER', 0); /** * CASE_UPPER is used with * array_change_key_case and is used to convert array * keys to upper case. * @link https://php.net/manual/en/array.constants.php */ define('CASE_UPPER', 1); define('COUNT_NORMAL', 0); define('COUNT_RECURSIVE', 1); define('ASSERT_ACTIVE', 1); define('ASSERT_CALLBACK', 2); define('ASSERT_BAIL', 3); define('ASSERT_WARNING', 4); /** * @removed 8.0 */ define('ASSERT_QUIET_EVAL', 5); define('ASSERT_EXCEPTION', 5); /** * Flag indicating if the stream used the include path. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_USE_PATH', 1); define('STREAM_IGNORE_URL', 2); define('STREAM_ENFORCE_SAFE_MODE', 4); /** * Flag indicating if the wrapper * is responsible for raising errors using trigger_error * during opening of the stream. If this flag is not set, you * should not raise any errors. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_REPORT_ERRORS', 8); /** * This flag is useful when your extension really must be able to randomly * seek around in a stream. Some streams may not be seekable in their * native form, so this flag asks the streams API to check to see if the * stream does support seeking. If it does not, it will copy the stream * into temporary storage (which may be a temporary file or a memory * stream) which does support seeking. * Please note that this flag is not useful when you want to seek the * stream and write to it, because the stream you are accessing might * not be bound to the actual resource you requested. * If the requested resource is network based, this flag will cause the * opener to block until the whole contents have been downloaded. * @link https://www.php.net/manual/en/stream.constants.php */ define('STREAM_MUST_SEEK', 16); define('STREAM_URL_STAT_LINK', 1); define('STREAM_URL_STAT_QUIET', 2); define('STREAM_MKDIR_RECURSIVE', 1); define('STREAM_IS_URL', 1); define('STREAM_OPTION_BLOCKING', 1); define('STREAM_OPTION_READ_TIMEOUT', 4); define('STREAM_OPTION_READ_BUFFER', 2); define('STREAM_OPTION_WRITE_BUFFER', 3); define('STREAM_BUFFER_NONE', 0); define('STREAM_BUFFER_LINE', 1); define('STREAM_BUFFER_FULL', 2); /** * Stream casting, when stream_cast is called * otherwise (see above). * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_CAST_AS_STREAM', 0); /** * Stream casting, for when stream_select is * calling stream_cast. * @link https://php.net/manual/en/stream.constants.php */ define('STREAM_CAST_FOR_SELECT', 3); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_GIF', 1); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_JPEG', 2); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_PNG', 3); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_SWF', 4); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_PSD', 5); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_BMP', 6); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_TIFF_II', 7); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_TIFF_MM', 8); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_JPC', 9); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_JP2', 10); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_JPX', 11); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_JB2', 12); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_SWC', 13); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_IFF', 14); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_WBMP', 15); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_JPEG2000', 9); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_XBM', 16); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php */ define('IMAGETYPE_ICO', 17); /** * Image type constant used by the {@link image_type_to_mime_type()} and {@link image_type_to_extension()} functions. * @link https://php.net/manual/en/image.constants.php * @since 7.1 */ define('IMAGETYPE_WEBP', 18); define('IMAGETYPE_UNKNOWN', 0); define('IMAGETYPE_COUNT', 20); /** * @since 8.1 */ define('IMAGETYPE_AVIF', 19); /** * IPv4 Address Resource * @link https://php.net/manual/en/network.constants.php */ define('DNS_A', 1); define('DNS_CAA', 8192); /** * Authoritative Name Server Resource * @link https://php.net/manual/en/network.constants.php */ define('DNS_NS', 2); /** * Alias (Canonical Name) Resource * @link https://php.net/manual/en/network.constants.php */ define('DNS_CNAME', 16); /** * Start of Authority Resource * @link https://php.net/manual/en/network.constants.php */ define('DNS_SOA', 32); /** * Pointer Resource * @link https://php.net/manual/en/network.constants.php */ define('DNS_PTR', 2048); /** * Host Info Resource (See IANA's * Operating System Names * for the meaning of these values) * @link https://php.net/manual/en/network.constants.php */ define('DNS_HINFO', 4096); /** * Mail Exchanger Resource * @link https://php.net/manual/en/network.constants.php */ define('DNS_MX', 16384); /** * Text Resource * @link https://php.net/manual/en/network.constants.php */ define('DNS_TXT', 32768); define('DNS_SRV', 33554432); define('DNS_NAPTR', 67108864); /** * IPv6 Address Resource * @link https://php.net/manual/en/network.constants.php */ define('DNS_AAAA', 134217728); define('DNS_A6', 16777216); /** * Any Resource Record. On most systems * this returns all resource records, however * it should not be counted upon for critical * uses. Try DNS_ALL instead. * @link https://php.net/manual/en/network.constants.php */ define('DNS_ANY', 268435456); /** * Iteratively query the name server for * each available record type. * @link https://php.net/manual/en/network.constants.php */ define('DNS_ALL', 251721779); // End of standard v.5.3.1-0.dotdeb.1 //WI-11084 Constant not defined PHP_QUERY_RFC3986 /** * Encoding is performed per RFC 1738 and the application/x-www-form-urlencoded media type, * which implies that spaces are encoded as plus (+) signs. * @link https://php.net/manual/en/function.http-build-query.php */ define('PHP_QUERY_RFC1738', 1); /** * Encoding is performed according to RFC 3986, and spaces will be percent encoded (%20). * @link https://php.net/manual/en/function.http-build-query.php */ define('PHP_QUERY_RFC3986', 2); //WI-11254 Stubs for missing constants from PHP 5.4 /** * (PHP4, PHP5) *

    Constant containing either the session name and session ID in the form of "name=ID" or * empty string if session ID was set in an appropriate session cookie. * This is the same id as the one returned by session_id().

    * @see session_id() * @link https://php.net/manual/en/session.constants.php */ define('SID', "name=ID"); /** * Return value of session_status() if sessions are disabled. * @since 5.4 * @link https://php.net/manual/en/function.session-status.php */ define('PHP_SESSION_DISABLED', 0); /** * Return value of session_status() if sessions are enabled, but no session exists. * @since 5.4 * @link https://php.net/manual/en/function.session-status.php */ define('PHP_SESSION_NONE', 1); /** * Return value of session_status() if sessions are enabled, and a session exists. * @since 5.4 * @link https://php.net/manual/en/function.session-status.php */ define('PHP_SESSION_ACTIVE', 2); /** * Replace invalid code unit sequences with a Unicode Replacement Character * U+FFFD (UTF-8) or &#FFFD; (otherwise) instead of returning an empty string. * @since 5.4 * @link https://php.net/manual/en/function.htmlspecialchars.php */ define('ENT_SUBSTITUTE', 8); /** * Replace invalid code points for the given document type with * a Unicode Replacement Character U+FFFD (UTF-8) or &#FFFD; * (otherwise) instead of leaving them as is. This may be useful, * for instance, to ensure the well-formedness of XML documents * with embedded external content. * @since 5.4 * @link https://php.net/manual/en/function.htmlspecialchars.php */ define('ENT_DISALLOWED', 128); /** * Handle code as HTML 4.01. * @since 5.4 * @link https://php.net/manual/en/function.htmlspecialchars.php */ define('ENT_HTML401', 0); /** * Handle code as XML 1. * @since 5.4 * @link https://php.net/manual/en/function.htmlspecialchars.php */ define('ENT_XML1', 16); /** * Handle code as XHTML. * @since 5.4 * @link https://php.net/manual/en/function.htmlspecialchars.php */ define('ENT_XHTML', 32); /** * Handle code as HTML 5. * @since 5.4 * @link https://php.net/manual/en/function.htmlspecialchars.php */ define('ENT_HTML5', 48); /** @link https://php.net/manual/en/function.scandir.php */ define('SCANDIR_SORT_ASCENDING', 0); /** @link https://php.net/manual/en/function.scandir.php */ define('SCANDIR_SORT_DESCENDING', 1); /** @link https://php.net/manual/en/function.scandir.php */ define('SCANDIR_SORT_NONE', 2); /** * SORT_NATURAL is used to compare items as strings using "natural ordering" like natsort(). * @since 5.4 * @link https://php.net/manual/en/array.constants.php */ define('SORT_NATURAL', 6); /** * SORT_FLAG_CASE can be combined (bitwise OR) with SORT_STRING or SORT_NATURAL to sort strings case-insensitively. * @since 5.4 * @link https://php.net/manual/en/array.constants.php */ define('SORT_FLAG_CASE', 8); /** @link https://php.net/manual/en/streamwrapper.stream-metadata.php */ define('STREAM_META_TOUCH', 1); /** @link https://php.net/manual/en/streamwrapper.stream-metadata.php */ define('STREAM_META_OWNER', 3); /** @link https://php.net/manual/en/streamwrapper.stream-metadata.php */ define('STREAM_META_OWNER_NAME', 2); /** @link https://php.net/manual/en/streamwrapper.stream-metadata.php */ define('STREAM_META_GROUP', 5); /** @link https://php.net/manual/en/streamwrapper.stream-metadata.php */ define('STREAM_META_GROUP_NAME', 4); /** @link https://php.net/manual/en/streamwrapper.stream-metadata.php */ define('STREAM_META_ACCESS', 6); define('STREAM_CRYPTO_METHOD_SSLv2_CLIENT', 3); define('STREAM_CRYPTO_METHOD_SSLv3_CLIENT', 5); define('STREAM_CRYPTO_METHOD_SSLv23_CLIENT', 57); define('STREAM_CRYPTO_METHOD_TLS_CLIENT', 121); define('STREAM_CRYPTO_METHOD_SSLv2_SERVER', 2); define('STREAM_CRYPTO_METHOD_SSLv3_SERVER', 4); define('STREAM_CRYPTO_METHOD_SSLv23_SERVER', 120); define('STREAM_CRYPTO_METHOD_TLS_SERVER', 120); define("STREAM_CRYPTO_METHOD_ANY_CLIENT", 127); define("STREAM_CRYPTO_METHOD_ANY_SERVER", 126); define("STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT", 9); define("STREAM_CRYPTO_METHOD_TLSv1_0_SERVER", 8); define("STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT", 17); define("STREAM_CRYPTO_METHOD_TLSv1_1_SERVER", 16); define("STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT", 33); define("STREAM_CRYPTO_METHOD_TLSv1_2_SERVER", 32); /** * @since 7.4 */ define("STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT", 65); /** * @since 7.4 */ define("STREAM_CRYPTO_METHOD_TLSv1_3_SERVER", 64); define("STREAM_CRYPTO_PROTO_SSLv3", 4); define("STREAM_CRYPTO_PROTO_TLSv1_0", 8); define("STREAM_CRYPTO_PROTO_TLSv1_1", 16); define("STREAM_CRYPTO_PROTO_TLSv1_2", 32); /** * @since 7.4 */ define("STREAM_CRYPTO_PROTO_TLSv1_3", 64); /** * @since 7.1 */ define("MT_RAND_MT19937", 0); /** * @since 7.1 * @deprecated 8.3 */ define("MT_RAND_PHP", 1); /** * system is unusable * @link https://php.net/manual/en/network.constants.php */ define('LOG_EMERG', 0); /** * action must be taken immediately * @link https://php.net/manual/en/network.constants.php */ define('LOG_ALERT', 1); /** * critical conditions * @link https://php.net/manual/en/network.constants.php */ define('LOG_CRIT', 2); /** * error conditions * @link https://php.net/manual/en/network.constants.php */ define('LOG_ERR', 3); /** * warning conditions * @link https://php.net/manual/en/network.constants.php */ define('LOG_WARNING', 4); /** * normal, but significant, condition * @link https://php.net/manual/en/network.constants.php */ define('LOG_NOTICE', 5); /** * informational message * @link https://php.net/manual/en/network.constants.php */ define('LOG_INFO', 6); /** * debug-level message * @link https://php.net/manual/en/network.constants.php */ define('LOG_DEBUG', 7); /** * kernel messages * @link https://php.net/manual/en/network.constants.php */ define('LOG_KERN', 0); /** * generic user-level messages * @link https://php.net/manual/en/network.constants.php */ define('LOG_USER', 8); /** * mail subsystem * @link https://php.net/manual/en/network.constants.php */ define('LOG_MAIL', 16); /** * other system daemons * @link https://php.net/manual/en/network.constants.php */ define('LOG_DAEMON', 24); /** * security/authorization messages (use LOG_AUTHPRIV instead * in systems where that constant is defined) * @link https://php.net/manual/en/network.constants.php */ define('LOG_AUTH', 32); /** * messages generated internally by syslogd * @link https://php.net/manual/en/network.constants.php */ define('LOG_SYSLOG', 40); /** * line printer subsystem * @link https://php.net/manual/en/network.constants.php */ define('LOG_LPR', 48); /** * USENET news subsystem * @link https://php.net/manual/en/network.constants.php */ define('LOG_NEWS', 56); /** * UUCP subsystem * @link https://php.net/manual/en/network.constants.php */ define('LOG_UUCP', 64); /** * clock daemon (cron and at) * @link https://php.net/manual/en/network.constants.php */ define('LOG_CRON', 72); /** * security/authorization messages (private) * @link https://php.net/manual/en/network.constants.php */ define('LOG_AUTHPRIV', 80); define('LOG_LOCAL0', 128); define('LOG_LOCAL1', 136); define('LOG_LOCAL2', 144); define('LOG_LOCAL3', 152); define('LOG_LOCAL4', 160); define('LOG_LOCAL5', 168); define('LOG_LOCAL6', 176); define('LOG_LOCAL7', 184); /** * include PID with each message * @link https://php.net/manual/en/network.constants.php */ define('LOG_PID', 1); /** * if there is an error while sending data to the system logger, * write directly to the system console * @link https://php.net/manual/en/network.constants.php */ define('LOG_CONS', 2); /** * (default) delay opening the connection until the first * message is logged * @link https://php.net/manual/en/network.constants.php */ define('LOG_ODELAY', 4); /** * open the connection to the logger immediately * @link https://php.net/manual/en/network.constants.php */ define('LOG_NDELAY', 8); define('LOG_NOWAIT', 16); /** * print log message also to standard error * @link https://php.net/manual/en/network.constants.php */ define('LOG_PERROR', 32); /** * @since 8.2 */ define('DECIMAL_POINT', 65536); /** * @since 8.2 */ define('THOUSANDS_SEP', 65537); /** * @since 8.2 */ define('GROUPING', 65538); /** * @since 8.2 */ define('ERA_YEAR', 131117); /** * @since 8.2 */ define('INT_CURR_SYMBOL', 262144); /** * @since 8.2 */ define('CURRENCY_SYMBOL', 262145); /** * @since 8.2 */ define('MON_DECIMAL_POINT', 262146); /** * @since 8.2 */ define('MON_THOUSANDS_SEP', 262147); /** * @since 8.2 */ define('MON_GROUPING', 262148); /** * @since 8.2 */ define('POSITIVE_SIGN', 262149); /** * @since 8.2 */ define('NEGATIVE_SIGN', 262150); /** * @since 8.2 */ define('INT_FRAC_DIGITS', 262151); /** * @since 8.2 */ define('FRAC_DIGITS', 262152); /** * @since 8.2 */ define('P_CS_PRECEDES', 262153); /** * @since 8.2 */ define('P_SEP_BY_SPACE', 262154); /** * @since 8.2 */ define('N_CS_PRECEDES', 262155); /** * @since 8.2 */ define('N_SEP_BY_SPACE', 262156); /** * @since 8.2 */ define('P_SIGN_POSN', 262157); /** * @since 8.2 */ define('N_SIGN_POSN', 262158); * Syntax "index => values", separated by commas, define index and values. * index may be of type string or integer. When index is omitted, an integer index is automatically generated, * starting at 0. If index is an integer, next generated index will be the biggest integer index + 1. * Note that when two identical index are defined, the last overwrite the first. *

    *

    * Having a trailing comma after the last defined array entry, while unusual, is a valid syntax. *

    * @return array an array of the parameters. The parameters can be given an index with the => operator. */ function PS_UNRESERVE_PREFIX_array(...$_) {} /** * Assigns a list of variables in one operation. * @link https://php.net/manual/en/function.list.php * @param mixed $var1

    A variable.

    * @param mixed ...$_ [optional]

    Another variable ...

    * @return array the assigned array. */ function PS_UNRESERVE_PREFIX_list($var1, ...$_) {} /** *

    Terminates execution of the script. Shutdown functions and object destructors will always be executed even if exit is called.

    *

    die is a language construct and it can be called without parentheses if no status is passed.

    * @link https://php.net/manual/en/function.die.php * @param int|string $status [optional]

    * If status is a string, this function prints the status just before exiting. *

    *

    * If status is an integer, that value will be used as the exit status and not printed. Exit statuses should be in the range 0 to 254, * the exit status 255 is reserved by PHP and shall not be used. The status 0 is used to terminate the program successfully. *

    *

    * Note: PHP >= 4.2.0 does NOT print the status if it is an integer. *

    * @return void */ function PS_UNRESERVE_PREFIX_die($status = "") {} /** *

    Terminates execution of the script. Shutdown functions and object destructors will always be executed even if exit is called.

    *

    exit is a language construct and it can be called without parentheses if no status is passed.

    * @link https://php.net/manual/en/function.exit.php * @param int|string $status [optional]

    * If status is a string, this function prints the status just before exiting. *

    *

    * If status is an integer, that value will be used as the exit status and not printed. Exit statuses should be in the range 0 to 254, * the exit status 255 is reserved by PHP and shall not be used. The status 0 is used to terminate the program successfully. *

    *

    * Note: PHP >= 4.2.0 does NOT print the status if it is an integer. *

    * @return void */ function PS_UNRESERVE_PREFIX_exit($status = "") {} /** * Determine whether a variable is considered to be empty. A variable is considered empty if it does not exist or if its value * equals FALSE. empty() does not generate a warning if the variable does not exist. * @link https://php.net/manual/en/function.empty.php * @param mixed $var

    Variable to be checked.

    *

    Note: Prior to PHP 5.5, empty() only supports variables; anything else will result in a parse error. In other words, * the following will not work: empty(trim($name)). Instead, use trim($name) == false. *

    *

    * No warning is generated if the variable does not exist. That means empty() is essentially the concise equivalent * to !isset($var) || $var == false. *

    * @return bool

    FALSE if var exists and has a non-empty, non-zero value. Otherwise returns TRUE.

    *

    * The following things are considered to be empty: *

      *
    • "" (an empty string)
    • *
    • 0 (0 as an integer)
    • *
    • 0.0 (0 as a float)
    • *
    • "0" (0 as a string)
    • *
    • NULL
    • *
    • FALSE
    • *
    • array() (an empty array)
    • *
    • $var; (a variable declared, but without a value)
    • *
    *

    */ function PS_UNRESERVE_PREFIX_empty($var) {} /** *

    Determine if a variable is set and is not NULL.

    *

    If a variable has been unset with unset(), it will no longer be set. isset() will return FALSE if testing a variable * that has been set to NULL. Also note that a null character ("\0") is not equivalent to the PHP NULL constant.

    *

    If multiple parameters are supplied then isset() will return TRUE only if all of the parameters are set. * Evaluation goes from left to right and stops as soon as an unset variable is encountered.

    * @link https://php.net/manual/en/function.isset.php * @param mixed $var

    The variable to be checked.

    * @param mixed ...$_ [optional]

    Another variable ...

    * @return bool Returns TRUE if var exists and has value other than NULL, FALSE otherwise. */ function PS_UNRESERVE_PREFIX_isset($var, ...$_) {} /** *

    Destroys the specified variables.

    *

    The behavior of unset() inside of a function can vary depending on what type of variable you are attempting to destroy.

    * @link https://php.net/manual/en/function.unset.php * @param mixed $var

    The variable to be unset.

    * @param mixed ...$_ [optional]

    Another variable ...

    * @return void */ function PS_UNRESERVE_PREFIX_unset($var, ...$_) {} /** *

    Evaluates the given code as PHP.

    *

    Caution: The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is * discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to * pass any user provided data into it without properly validating it beforehand.

    * @link https://php.net/manual/en/function.eval.php * @param string $code

    * Valid PHP code to be evaluated. *

    *

    * The code must not be wrapped in opening and closing PHP tags, i.e. 'echo "Hi!";' must be passed instead of ''. * It is still possible to leave and re-enter PHP mode though using the appropriate PHP tags, e.g. * 'echo "In PHP mode!"; ?>In HTML mode! *

    * Apart from that the passed code must be valid PHP. This includes that all statements must be properly terminated using a semicolon. * 'echo "Hi!"' for example will cause a parse error, whereas 'echo "Hi!";' will work. *

    *

    * A return statement will immediately terminate the evaluation of the code. *

    *

    * The code will be executed in the scope of the code calling eval(). Thus any variables defined or changed in the eval() * call will remain visible after it terminates. *

    * @return mixed NULL unless return is called in the evaluated code, in which case the value passed to return is returned. * As of PHP 7, if there is a parse error in the evaluated code, eval() throws a ParseError exception. Before PHP 7, in this * case eval() returned FALSE and execution of the following code continued normally. It is not possible to catch a parse * error in eval() using set_error_handler(). */ function PS_UNRESERVE_PREFIX_eval($code) {} /** * Generator objects are returned from generators, cannot be instantiated via new. * @link https://secure.php.net/manual/en/class.generator.php * @link https://wiki.php.net/rfc/generators * * @template-covariant TKey * @template-covariant TYield * @template TSend * @template-covariant TReturn * * @template-implements Iterator */ final class Generator implements Iterator { /** * Throws an exception if the generator is currently after the first yield. * @return void */ public function rewind(): void {} /** * Returns false if the generator has been closed, true otherwise. * @return bool */ public function valid(): bool {} /** * Returns whatever was passed to yield or null if nothing was passed or the generator is already closed. * @return TYield */ public function current(): mixed {} /** * Returns the yielded key or, if none was specified, an auto-incrementing key or null if the generator is already closed. * @return TKey */ #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: 'string|float|int|bool|null')] public function key() {} /** * Resumes the generator (unless the generator is already closed). * @return void */ public function next(): void {} /** * Sets the return value of the yield expression and resumes the generator (unless the generator is already closed). * @param TSend $value * @return TYield|null */ public function send(mixed $value): mixed {} /** * Throws an exception at the current suspension point in the generator. * @param Throwable $exception * @return TYield */ public function PS_UNRESERVE_PREFIX_throw(Throwable $exception): mixed {} /** * Returns whatever was passed to return or null if nothing. * Throws an exception if the generator is still valid. * @link https://wiki.php.net/rfc/generator-return-expressions * @return TReturn * @since 7.0 */ public function getReturn(): mixed {} /** * Serialize callback * Throws an exception as generators can't be serialized. * @link https://php.net/manual/en/generator.wakeup.php * @return void */ public function __wakeup() {} /** * @since 8.4 */ public function __debugInfo(): array {} } class ClosedGeneratorException extends Exception {} } namespace ___PHPSTORM_HELPERS { class PS_UNRESERVE_PREFIX_this {} class PS_UNRESERVE_PREFIX_static {} class object { /** * PHP 5 allows developers to declare constructor methods for classes. * Classes which have a constructor method call this method on each newly-created object, * so it is suitable for any initialization that the object may need before it is used. * * Note: Parent constructors are not called implicitly if the child class defines a constructor. * In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. * * param [ mixed $args [, $... ]] * @link https://php.net/manual/en/language.oop5.decon.php */ public function __construct() {} /** * PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++. * The destructor method will be called as soon as all references to a particular object are removed or * when the object is explicitly destroyed or in any order in shutdown sequence. * * Like constructors, parent destructors will not be called implicitly by the engine. * In order to run a parent destructor, one would have to explicitly call parent::__destruct() in the destructor body. * * Note: Destructors called during the script shutdown have HTTP headers already sent. * The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache). * * Note: Attempting to throw an exception from a destructor (called in the time of script termination) causes a fatal error. * * @return void * @link https://php.net/manual/en/language.oop5.decon.php */ public function __destruct() {} /** * is triggered when invoking inaccessible methods in an object context. * * @param string $name * @param array $arguments * @return mixed * @link https://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods */ public function __call(string $name, array $arguments) {} /** * is triggered when invoking inaccessible methods in a static context. * * @param string $name * @param array $arguments * @return mixed * @link https://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods */ public static function __callStatic(string $name, array $arguments) {} /** * is utilized for reading data from inaccessible members. * * @param string $name * @return mixed * @link https://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members */ public function __get(string $name) {} /** * run when writing data to inaccessible members. * * @param string $name * @param mixed $value * @return void * @link https://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members */ public function __set(string $name, $value): void {} /** * is triggered by calling isset() or empty() on inaccessible members. * * @param string $name * @return bool * @link https://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members */ public function __isset(string $name): bool {} /** * is invoked when unset() is used on inaccessible members. * * @param string $name * @return void * @link https://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members */ public function __unset(string $name): void {} /** * serialize() checks if your class has a function with the magic name __sleep. * If so, that function is executed prior to any serialization. * It can clean up the object and is supposed to return an array with the names of all variables of that object that should be serialized. * If the method doesn't return anything then NULL is serialized and E_NOTICE is issued. * The intended use of __sleep is to commit pending data or perform similar cleanup tasks. * Also, the function is useful if you have very large objects which do not need to be saved completely. * * @return string[] * @link https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.sleep */ public function __sleep(): array {} /** * unserialize() checks for the presence of a function with the magic name __wakeup. * If present, this function can reconstruct any resources that the object may have. * The intended use of __wakeup is to reestablish any database connections that may have been lost during * serialization and perform other reinitialization tasks. * * @return void * @link https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.sleep */ public function __wakeup(): void {} /** * The __toString method allows a class to decide how it will react when it is converted to a string. * * @return string * @link https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.tostring */ public function __toString(): string {} /** * The __invoke method is called when a script tries to call an object as a function. * * @return mixed * @link https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.invoke */ public function __invoke() {} /** * This method is called by var_dump() when dumping an object to get the properties that should be shown. * If the method isn't defined on an object, then all public, protected and private properties will be shown. * * @return array|null * @link https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo */ public function __debugInfo(): ?array {} /** * This static method is called for classes exported by var_export() since PHP 5.1.0. * The only parameter of this method is an array containing exported properties in the form array('property' => value, ...). * * @param array $an_array * @return object * @link https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.set-state */ public static function __set_state(array $an_array): object {} /** * When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties. * Any properties that are references to other variables, will remain references. * Once the cloning is complete, if a __clone() method is defined, * then the newly created object's __clone() method will be called, to allow any necessary properties that need to be changed. * NOT CALLABLE DIRECTLY. * * @return void * @link https://php.net/manual/en/language.oop5.cloning.php */ public function __clone(): void {} /** * Returns array containing all the necessary state of the object. * @since 7.4 * @link https://wiki.php.net/rfc/custom_object_serialization */ public function __serialize(): array {} /** * Restores the object state from the given data array. * @param array $data * @since 7.4 * @link https://wiki.php.net/rfc/custom_object_serialization */ public function __unserialize(array $data): void {} } } * priority is a combination of the facility and * the level. Possible values are: * * syslog Priorities (in descending order) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    ConstantDescription
    LOG_EMERGsystem is unusable
    LOG_ALERTaction must be taken immediately
    LOG_CRITcritical conditions
    LOG_ERRerror conditions
    LOG_WARNINGwarning conditions
    LOG_NOTICEnormal, but significant, condition
    LOG_INFOinformational message
    LOG_DEBUGdebug-level message
    *

    * @param string $message

    * The message to send, except that the two characters * %m will be replaced by the error message string * (strerror) corresponding to the present value of * errno. *

    */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function syslog(int $priority, string $message) {} /** * Close connection to system logger * @link https://php.net/manual/en/function.closelog.php */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function closelog() {} /** * Registers a function that will be called when PHP starts sending output. * The callback is executed just after PHP prepares all headers to be sent,
    * and before any other output is sent, creating a window to manipulate the outgoing headers before being sent. * @link https://secure.php.net/manual/en/function.header-register-callback.php * @param callable $callback Function called just before the headers are sent. * @return bool true on success or false on failure. */ function header_register_callback(callable $callback): bool {} /** * Get the size of an image from a string. * @param string $string The image data, as a string. * @param array &$image_info [optional] This optional parameter allows you to extract
    * some extended information from the image file. Currently, this will
    * return the different JPG APP markers as an associative array.
    * Some programs use these APP markers to embed text information in images.
    * A very common one is to embed » IPTC information in the APP13 marker.
    * You can use the iptcparse() function to parse the binary APP13 marker into something readable. * @return array|false Returns an array with 7 elements.
    * Index 0 and 1 contains respectively the width and the height of the image.
    * Index 2 is one of the IMAGETYPE_XXX constants indicating the type of the image.
    * Index 3 is a text string with the correct height="yyy" width="xxx" string
    * that can be used directly in an IMG tag.
    * On failure, FALSE is returned. * @link https://secure.php.net/manual/en/function.getimagesizefromstring.php * @since 5.4 * @link https://secure.php.net/manual/en/function.getimagesizefromstring.php * @since 5.4 */ #[ArrayShape([0 => 'int', 1 => 'int', 2 => 'int', 3 => 'string', 'bits' => 'int', 'channels' => 'int', 'mime' => 'string'])] function getimagesizefromstring(string $string, &$image_info): array|false {} /** * Set the stream chunk size. * @param resource $stream The target stream. * @param int $size The desired new chunk size. * @return int|false Returns the previous chunk size on success.
    * Will return FALSE if chunk_size is less than 1 or greater than PHP_INT_MAX. * @link https://secure.php.net/manual/en/function.stream-set-chunk-size.php * @since 5.4 */ #[LanguageLevelTypeAware(["8.0" => "int"], default: "int|false")] function stream_set_chunk_size($stream, int $size) {} /** * Initializes all syslog related variables * @link https://php.net/manual/en/function.define-syslog-variables.php * @return void * @removed 5.4 */ #[Deprecated(since: '5.3')] function define_syslog_variables() {} /** * Calculate the metaphone key of a string * @link https://php.net/manual/en/function.metaphone.php * @param string $string

    * The input string. *

    * @param int $max_phonemes [optional]

    * This parameter restricts the returned metaphone key to phonemes characters in length. * The default value of 0 means no restriction. *

    * @return string|false the metaphone key as a string, or FALSE on failure */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "string"], default: "string|false")] function metaphone(string $string, int $max_phonemes = 0) {} /** * Turn on output buffering * @link https://php.net/manual/en/function.ob-start.php * @param callable $callback [optional]

    * An optional output_callback function may be * specified. This function takes a string as a parameter and should * return a string. The function will be called when * the output buffer is flushed (sent) or cleaned (with * ob_flush, ob_clean or similar * function) or when the output buffer * is flushed to the browser at the end of the request. When * output_callback is called, it will receive the * contents of the output buffer as its parameter and is expected to * return a new output buffer as a result, which will be sent to the * browser. If the output_callback is not a * callable function, this function will return false. *

    *

    * If the callback function has two parameters, the second parameter is * filled with a bit-field consisting of * PHP_OUTPUT_HANDLER_START, * PHP_OUTPUT_HANDLER_CONT and * PHP_OUTPUT_HANDLER_END. *

    *

    * If output_callback returns false original * input is sent to the browser. *

    *

    * The output_callback parameter may be bypassed * by passing a null value. *

    *

    * ob_end_clean, ob_end_flush, * ob_clean, ob_flush and * ob_start may not be called from a callback * function. If you call them from callback function, the behavior is * undefined. If you would like to delete the contents of a buffer, * return "" (a null string) from callback function. * You can't even call functions using the output buffering functions like * print_r($expression, true) or * highlight_file($filename, true) from a callback * function. *

    *

    * In PHP 4.0.4, ob_gzhandler was introduced to * facilitate sending gz-encoded data to web browsers that support * compressed web pages. ob_gzhandler determines * what type of content encoding the browser will accept and will return * its output accordingly. *

    * @param int $chunk_size

    * If the optional parameter chunk_size is passed, the * buffer will be flushed after any output call which causes the buffer's * length to equal or exceed chunk_size. * Default value 0 means that the function is called only in the end, * other special value 1 sets chunk_size to 4096. *

    * @param int $flags [optional]

    * The flags parameter is a bitmask that controls the operations that can be performed on the output buffer. * The default is to allow output buffers to be cleaned, flushed and removed, which can be set explicitly via * PHP_OUTPUT_HANDLER_CLEANABLE | PHP_OUTPUT_HANDLER_FLUSHABLE | PHP_OUTPUT_HANDLER_REMOVABLE, or PHP_OUTPUT_HANDLER_STDFLAGS as shorthand. *

    * @return bool true on success or false on failure. */ function ob_start($callback, int $chunk_size = 0, int $flags = PHP_OUTPUT_HANDLER_STDFLAGS): bool {} /** * Flush (send) the output buffer * @link https://php.net/manual/en/function.ob-flush.php * @return bool */ function ob_flush(): bool {} /** * Clean (erase) the output buffer * @link https://php.net/manual/en/function.ob-clean.php * @return bool */ function ob_clean(): bool {} /** * Flush (send) the output buffer and turn off output buffering * @link https://php.net/manual/en/function.ob-end-flush.php * @return bool true on success or false on failure. Reasons for failure are first that you called the * function without an active buffer or that for some reason a buffer could * not be deleted (possible for special buffer). */ function ob_end_flush(): bool {} /** * Clean (erase) the output buffer and turn off output buffering * @link https://php.net/manual/en/function.ob-end-clean.php * @return bool true on success or false on failure. Reasons for failure are first that you called the * function without an active buffer or that for some reason a buffer could * not be deleted (possible for special buffer). */ function ob_end_clean(): bool {} /** * Flush the output buffer, return it as a string and turn off output buffering * @link https://php.net/manual/en/function.ob-get-flush.php * @return string|false the output buffer or false if no buffering is active. */ function ob_get_flush(): string|false {} /** * Get current buffer contents and delete current output buffer * @link https://php.net/manual/en/function.ob-get-clean.php * @return string|false the contents of the output buffer and end output buffering. * If output buffering isn't active then false is returned. */ function ob_get_clean(): string|false {} /** * Return the length of the output buffer * @link https://php.net/manual/en/function.ob-get-length.php * @return int|false the length of the output buffer contents or false if no * buffering is active. */ function ob_get_length(): int|false {} /** * Return the nesting level of the output buffering mechanism * @link https://php.net/manual/en/function.ob-get-level.php * @return int the level of nested output buffering handlers or zero if output * buffering is not active. */ function ob_get_level(): int {} /** * Get status of output buffers * @link https://php.net/manual/en/function.ob-get-status.php * @param bool $full_status [optional]

    * true to return all active output buffer levels. If false or not * set, only the top level output buffer is returned. *

    * @return array If called without the full_status parameter * or with full_status = false a simple array * with the following elements is returned: *
     * Array
     * (
     *     [level] => 2
     *     [type] => 0
     *     [status] => 0
     *     [name] => URL-Rewriter
     *     [del] => 1
     * )
     * 
    * * * * * * * *
    KeyValue
    levelOutput nesting level
    typePHP_OUTPUT_HANDLER_INTERNAL (0) or PHP_OUTPUT_HANDLER_USER (1)
    statusOne of PHP_OUTPUT_HANDLER_START (0), PHP_OUTPUT_HANDLER_CONT (1) or PHP_OUTPUT_HANDLER_END (2)
    nameName of active output handler or ' default output handler' if none is set
    delErase-flag as set by ob_start()
    *

    * If called with full_status = TRUE an array with one element for each active output buffer * level is returned. The output level is used as key of the top level array and each array * element itself is another array holding status information on one active output level. *

    *
     * Array
     * (
     *     [0] => Array
     *         (
     *             [chunk_size] => 0
     *             [size] => 40960
     *             [block_size] => 10240
     *             [type] => 1
     *             [status] => 0
     *             [name] => default output handler
     *             [del] => 1
     *         )
     *
     *     [1] => Array
     *         (
     *             [chunk_size] => 0
     *             [size] => 40960
     *             [block_size] => 10240
     *             [type] => 0
     *             [buffer_size] => 0
     *             [status] => 0
     *             [name] => URL-Rewriter
     *             [del] => 1
     *         )
     *
     * )
     * 
    *

    The full output contains these additional elements:

    * * * * * *
    KeyValue
    chunk_sizeChunk size as set by ob_start()
    size...
    blocksize...
    */ #[ArrayShape([ "level" => "int", "type" => "int", "flags" => "int", "name" => "string", "del" => "int", "chunk_size" => "int", "buffer_size" => "int", "buffer_used" => "int", ])] function ob_get_status(bool $full_status = false): array {} /** * Return the contents of the output buffer * @link https://php.net/manual/en/function.ob-get-contents.php * @return string|false This will return the contents of the output buffer or false, if output * buffering isn't active. */ #[Pure(true)] function ob_get_contents(): string|false {} /** * Turn implicit flush on/off * @link https://php.net/manual/en/function.ob-implicit-flush.php * @param int|bool $enable [optional]

    * 1|TRUE to turn implicit flushing on, 0|FALSE turns it off. *

    default: 1|TRUE *

    * @return void */ function ob_implicit_flush(#[LanguageLevelTypeAware(["8.0" => "bool"], default: "int")] $enable = true): void {} /** * List all output handlers in use * @link https://php.net/manual/en/function.ob-list-handlers.php * @return array This will return an array with the output handlers in use (if any). If * output_buffering is enabled or * an anonymous function was used with ob_start, * ob_list_handlers will return "default output * handler". */ function ob_list_handlers(): array {} /** * Sort an array by key * @link https://php.net/manual/en/function.ksort.php * @param array &$array

    * The input array. *

    * @param int $flags

    * You may modify the behavior of the sort using the optional * parameter sort_flags, for details * see sort. *

    */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function ksort(array &$array, int $flags = SORT_REGULAR) {} /** * Sort an array by key in reverse order * @link https://php.net/manual/en/function.krsort.php * @param array &$array

    * The input array. *

    * @param int $flags

    * You may modify the behavior of the sort using the optional parameter * sort_flags, for details see * sort. *

    */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function krsort(array &$array, int $flags = SORT_REGULAR) {} /** * Sort an array using a "natural order" algorithm * @link https://php.net/manual/en/function.natsort.php * @param array &$array

    * The input array. *

    */ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function natsort(array &$array) {} /** * Sort an array using a case insensitive "natural order" algorithm * @link https://php.net/manual/en/function.natcasesort.php * @param array &$array

    * The input array. *

    */ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function natcasesort(array &$array) {} /** * Sort an array and maintain index association * @link https://php.net/manual/en/function.asort.php * @param array &$array

    * The input array. *

    * @param int $flags

    * You may modify the behavior of the sort using the optional * parameter sort_flags, for details * see sort. *

    */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function asort(array &$array, int $flags = SORT_REGULAR) {} /** * Sort an array in reverse order and maintain index association * @link https://php.net/manual/en/function.arsort.php * @param array &$array

    * The input array. *

    * @param int $flags

    * You may modify the behavior of the sort using the optional parameter * sort_flags, for details see * sort. *

    */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function arsort(array &$array, int $flags = SORT_REGULAR) {} /** * Sort an array * @link https://php.net/manual/en/function.sort.php * @param array &$array

    * The input array. *

    * @param int $flags

    * The optional second parameter sort_flags * may be used to modify the sorting behavior using these values. *

    *

    * Sorting type flags:
    * SORT_REGULAR - compare items normally * (don't change types)

    */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function sort(array &$array, int $flags = SORT_REGULAR) {} /** * Sort an array in reverse order * @link https://php.net/manual/en/function.rsort.php * @param array &$array

    * The input array. *

    * @param int $flags

    * You may modify the behavior of the sort using the optional * parameter sort_flags, for details see * sort. *

    */ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function rsort(array &$array, int $flags = SORT_REGULAR) {} /** * Sort an array by values using a user-defined comparison function * @link https://php.net/manual/en/function.usort.php * @param array &$array

    * The input array. *

    * @param callable $callback

    * The comparison function must return an integer less than, equal to, or * greater than zero if the first argument is considered to be * respectively less than, equal to, or greater than the second. *

    * @return true Always returns true. */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function usort(array &$array, callable $callback) {} /** * Sort an array with a user-defined comparison function and maintain index association * @link https://php.net/manual/en/function.uasort.php * @param array &$array

    * The input array. *

    * @param callable $callback

    * See usort and uksort for * examples of user-defined comparison functions. *

    */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function uasort(array &$array, callable $callback) {} /** * Sort an array by keys using a user-defined comparison function * @link https://php.net/manual/en/function.uksort.php * @param array &$array

    * The input array. *

    * @param callable $callback

    * The callback comparison function. *

    *

    * Function cmp_function should accept two * parameters which will be filled by pairs of array keys. * The comparison function must return an integer less than, equal * to, or greater than zero if the first argument is considered to * be respectively less than, equal to, or greater than the * second. *

    */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function uksort(array &$array, callable $callback) {} /** * Shuffle an array * @link https://php.net/manual/en/function.shuffle.php * @param array &$array

    * The array. *

    */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function shuffle(array &$array) {} /** * Apply a user function to every member of an array * @link https://php.net/manual/en/function.array-walk.php * @param array|object &$array

    * The input array. *

    * @param callable $callback

    * Typically, funcname takes on two parameters. * The array parameter's value being the first, and * the key/index second. *

    *

    * If funcname needs to be working with the * actual values of the array, specify the first parameter of * funcname as a * reference. Then, * any changes made to those elements will be made in the * original array itself. *

    *

    * Users may not change the array itself from the * callback function. e.g. Add/delete elements, unset elements, etc. If * the array that array_walk is applied to is * changed, the behavior of this function is undefined, and unpredictable. *

    * @param mixed $arg [optional]

    * If the optional userdata parameter is supplied, * it will be passed as the third parameter to the callback * funcname. *

    */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function array_walk(object|array &$array, callable $callback, mixed $arg) {} /** * Apply a user function recursively to every member of an array * @link https://php.net/manual/en/function.array-walk-recursive.php * @param array|object &$array

    * The input array. *

    * @param callable $callback

    * Typically, funcname takes on two parameters. * The input parameter's value being the first, and * the key/index second. *

    *

    * If funcname needs to be working with the * actual values of the array, specify the first parameter of * funcname as a * reference. Then, * any changes made to those elements will be made in the * original array itself. *

    * @param mixed $arg [optional]

    * If the optional userdata parameter is supplied, * it will be passed as the third parameter to the callback * funcname. *

    */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function array_walk_recursive(object|array &$array, callable $callback, mixed $arg) {} /** * Counts all elements in an array, or something in an object. *

    For objects, if you have SPL installed, you can hook into count() by implementing interface {@see Countable}. * The interface has exactly one method, {@see Countable::count()}, which returns the return value for the count() function. * Please see the {@see Array} section of the manual for a detailed explanation of how arrays are implemented and used in PHP.

    * @link https://php.net/manual/en/function.count.php * @param array|Countable $value The array or the object. * @param int $mode [optional] If the optional mode parameter is set to * COUNT_RECURSIVE (or 1), count * will recursively count the array. This is particularly useful for * counting all the elements of a multidimensional array. count does not detect infinite recursion. * @return int<0,max> the number of elements in var, which is * typically an array, since anything else will have one * element. *

    * If var is not an array or an object with * implemented Countable interface, * 1 will be returned. * There is one exception, if var is null, * 0 will be returned. *

    *

    * Caution: count may return 0 for a variable that isn't set, * but it may also return 0 for a variable that has been initialized with an * empty array. Use isset to test if a variable is set. *

    */ #[Pure] function count(Countable|array $value, int $mode = COUNT_NORMAL): int {} /** * Set the internal pointer of an array to its last element * @link https://php.net/manual/en/function.end.php * @param array|object &$array

    * The array. This array is passed by reference because it is modified by * the function. This means you must pass it a real variable and not * a function returning an array because only actual variables may be * passed by reference. *

    * @return mixed|false the value of the last element or false for empty array. * @meta */ function end(object|array &$array): mixed {} /** * Rewind the internal array pointer * @link https://php.net/manual/en/function.prev.php * @param array|object &$array

    * The input array. *

    * @return mixed|false the array value in the previous place that's pointed to by * the internal array pointer, or false if there are no more * elements. * @meta */ function prev(object|array &$array): mixed {} /** * Advance the internal array pointer of an array * @link https://php.net/manual/en/function.next.php * @param array|object &$array

    * The array being affected. *

    * @return mixed|false the array value in the next place that's pointed to by the * internal array pointer, or false if there are no more elements. * @meta */ function next(object|array &$array): mixed {} /** * Set the internal pointer of an array to its first element * @link https://php.net/manual/en/function.reset.php * @param array|object &$array

    * The input array. *

    * @return mixed|false the value of the first array element, or false if the array is * empty. * @meta */ function reset(object|array &$array): mixed {} /** * Return the current element in an array * @link https://php.net/manual/en/function.current.php * @param array|object $array

    * The array. *

    * @return mixed|false The current function simply returns the * value of the array element that's currently being pointed to by the * internal pointer. It does not move the pointer in any way. If the * internal pointer points beyond the end of the elements list or the array is * empty, current returns false. * @meta */ #[Pure] function current(object|array $array): mixed {} /** * Fetch a key from an array * @link https://php.net/manual/en/function.key.php * @param array|object $array

    * The array. *

    * @return int|string|null The key function simply returns the * key of the array element that's currently being pointed to by the * internal pointer. It does not move the pointer in any way. If the * internal pointer points beyond the end of the elements list or the array is * empty, key returns null. */ #[Pure] function key(object|array $array): string|int|null {} /** * Find lowest value * @link https://php.net/manual/en/function.min.php * @param array|mixed $value Array to look through or first value to compare * @param mixed ...$values any comparable value * @return mixed min returns the numerically lowest of the * parameter values. */ #[Pure] function min( #[PhpStormStubsElementAvailable(from: '8.0')] mixed $value, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] mixed $values, mixed ...$values ): mixed {} /** * Find highest value * @link https://php.net/manual/en/function.max.php * @param array|mixed $value Array to look through or first value to compare * @param mixed ...$values any comparable value * @return mixed max returns the numerically highest of the * parameter values, either within a arg array or two arguments. */ #[Pure] function max( #[PhpStormStubsElementAvailable(from: '8.0')] mixed $value, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] mixed $values, mixed ...$values ): mixed {} /** * Checks if a value exists in an array * @link https://php.net/manual/en/function.in-array.php * @param mixed $needle

    * The searched value. *

    *

    * If needle is a string, the comparison is done * in a case-sensitive manner. *

    * @param array $haystack

    * The array. *

    * @param bool $strict [optional]

    * If the third parameter strict is set to true * then the in_array function will also check the * types of the * needle in the haystack. *

    * @return bool true if needle is found in the array, * false otherwise. */ #[Pure] function in_array(mixed $needle, array $haystack, bool $strict = false): bool {} /** * Searches the array for a given value and returns the first corresponding key if successful * @link https://php.net/manual/en/function.array-search.php * @param mixed $needle

    * The searched value. *

    *

    * If needle is a string, the comparison is done * in a case-sensitive manner. *

    * @param array $haystack

    * The array. *

    * @param bool $strict [optional]

    * If the third parameter strict is set to true * then the array_search function will also check the * types of the * needle in the haystack. *

    * @return int|string|false the key for needle if it is found in the * array, false otherwise. *

    *

    * If needle is found in haystack * more than once, the first matching key is returned. To return the keys for * all matching values, use array_keys with the optional * search_value parameter instead. */ #[Pure] function array_search(mixed $needle, array $haystack, bool $strict = false): string|int|false {} /** * Import variables into the current symbol table from an array * @link https://php.net/manual/en/function.extract.php * @param array &$array

    * Note that prefix is only required if * extract_type is EXTR_PREFIX_SAME, * EXTR_PREFIX_ALL, EXTR_PREFIX_INVALID * or EXTR_PREFIX_IF_EXISTS. If * the prefixed result is not a valid variable name, it is not * imported into the symbol table. Prefixes are automatically separated from * the array key by an underscore character. *

    * @param int $flags

    * The way invalid/numeric keys and collisions are treated is determined * by the extract_type. It can be one of the * following values: * EXTR_OVERWRITE * If there is a collision, overwrite the existing variable.

    * @param string $prefix

    Only overwrite the variable if it already exists in the * current symbol table, otherwise do nothing. This is useful * for defining a list of valid variables and then extracting * only those variables you have defined out of * $_REQUEST, for example.

    * @return int the number of variables successfully imported into the symbol * table. */ function extract( array &$array, #[ExpectedValues(flags: [ EXTR_OVERWRITE, EXTR_SKIP, EXTR_PREFIX_SAME, EXTR_PREFIX_ALL, EXTR_PREFIX_INVALID, EXTR_IF_EXISTS, EXTR_PREFIX_IF_EXISTS, EXTR_REFS ])] int $flags = EXTR_OVERWRITE, string $prefix = "" ): int {} /** * Create array containing variables and their values * @link https://php.net/manual/en/function.compact.php * @param mixed $var_name

    * compact takes a variable number of parameters. * Each parameter can be either a string containing the name of the * variable, or an array of variable names. The array can contain other * arrays of variable names inside it; compact * handles it recursively. *

    * @param mixed ...$var_names * @return array the output array with all the variables added to it. */ #[Pure] function compact(#[PhpStormStubsElementAvailable(from: '8.0')] $var_name, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $var_names, ...$var_names): array {} /** * Fill an array with values * @link https://php.net/manual/en/function.array-fill.php * @param int $start_index

    * The first index of the returned array. * Supports non-negative indexes only. *

    * @param int $count

    * Number of elements to insert *

    * @param mixed $value

    * Value to use for filling *

    * @return array the filled array */ #[Pure] function array_fill(int $start_index, int $count, mixed $value): array {} /** * Fill an array with values, specifying keys * @link https://php.net/manual/en/function.array-fill-keys.php * @param array $keys

    * Array of values that will be used as keys. Illegal values * for key will be converted to string. *

    * @param mixed $value

    * Value to use for filling *

    * @return array the filled array */ #[Pure] function array_fill_keys(array $keys, mixed $value): array {} /** * Create an array containing a range of elements * @link https://php.net/manual/en/function.range.php * @param mixed $start

    * First value of the sequence. *

    * @param mixed $end

    * The sequence is ended upon reaching the end value. *

    * @param positive-int|float $step [optional]

    * If a step value is given, it will be used as the * increment between elements in the sequence. step * should be given as a positive number. If not specified, * step will default to 1. *

    * @return array an array of elements from start to * end, inclusive. */ #[Pure] function range( #[LanguageLevelTypeAware(['8.3' => 'string|int|float'], default: '')] $start, #[LanguageLevelTypeAware(['8.3' => 'string|int|float'], default: '')] $end, int|float $step = 1 ): array {} /** * Sort multiple or multi-dimensional arrays * @link https://php.net/manual/en/function.array-multisort.php * @param array &$array

    * An array being sorted. *

    * @param &...$rest [optional]

    * More arrays, optionally followed by sort order and flags. * Only elements corresponding to equivalent elements in previous arrays are compared. * In other words, the sort is lexicographical. *

    * @return bool true on success or false on failure. */ function array_multisort( &$array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $sort_order = SORT_ASC, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $sort_flags = SORT_REGULAR, &...$rest ): bool {} /** * Push elements onto the end of array * Since 7.3.0 this function can be called with only one parameter. * For earlier versions at least two parameters are required. * @link https://php.net/manual/en/function.array-push.php * @param array &$array

    * The input array. *

    * @param mixed ...$values

    * The pushed variables. *

    * @return int the number of elements in the array. */ function array_push( array &$array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.2')] $values, mixed ...$values ): int {} /** * Pop the element off the end of array * @link https://php.net/manual/en/function.array-pop.php * @param array &$array

    * The array to get the value from. *

    * @return mixed|null the last value of array. * If array is empty (or is not an array), * null will be returned. * @meta */ function array_pop(array &$array): mixed {} /** * Shift an element off the beginning of array * @link https://php.net/manual/en/function.array-shift.php * @param array &$array

    * The input array. *

    * @return mixed|null the shifted value, or null if array is * empty or is not an array. * @meta */ function array_shift(array &$array): mixed {} /** * Prepend elements to the beginning of an array * Since 7.3.0 this function can be called with only one parameter. * For earlier versions at least two parameters are required. * @link https://php.net/manual/en/function.array-unshift.php * @param array &$array

    * The input array. *

    * @param mixed ...$values

    * The prepended variables. *

    * @return int the number of elements in the array. */ function array_unshift(array &$array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.2')] $values, mixed ...$values): int {} /** * Remove a portion of the array and replace it with something else * @link https://php.net/manual/en/function.array-splice.php * @param array &$array

    * The input array. *

    * @param int $offset

    * If offset is positive then the start of removed * portion is at that offset from the beginning of the * input array. If offset * is negative then it starts that far from the end of the * input array. *

    * @param int|null $length [optional]

    * If length is omitted, removes everything * from offset to the end of the array. If * length is specified and is positive, then * that many elements will be removed. If * length is specified and is negative then * the end of the removed portion will be that many elements from * the end of the array. Tip: to remove everything from * offset to the end of the array when * replacement is also specified, use * count($input) for * length. *

    * @param mixed $replacement

    * If replacement array is specified, then the * removed elements are replaced with elements from this array. *

    *

    * If offset and length * are such that nothing is removed, then the elements from the * replacement array are inserted in the place * specified by the offset. Note that keys in * replacement array are not preserved. *

    *

    * If replacement is just one element it is * not necessary to put array() * around it, unless the element is an array itself. *

    * @return array the array consisting of the extracted elements. */ function array_splice(array &$array, int $offset, ?int $length, mixed $replacement = []): array {} /** * Extract a slice of the array * @link https://php.net/manual/en/function.array-slice.php * @param array $array

    * The input array. *

    * @param int $offset

    * If offset is non-negative, the sequence will * start at that offset in the array. If * offset is negative, the sequence will * start that far from the end of the array. *

    * @param int|null $length [optional]

    * If length is given and is positive, then * the sequence will have that many elements in it. If * length is given and is negative then the * sequence will stop that many elements from the end of the * array. If it is omitted, then the sequence will have everything * from offset up until the end of the * array. *

    * @param bool $preserve_keys [optional]

    * Note that array_slice will reorder and reset the * array indices by default. You can change this behaviour by setting * preserve_keys to true. *

    * @return array the slice. * @meta */ #[Pure] function array_slice(array $array, int $offset, ?int $length, bool $preserve_keys = false): array {} /** * Merges the elements of one or more arrays together (if the input arrays have the same string keys, then the later value for that key will overwrite the previous one; if the arrays contain numeric keys, the later value will be appended) * Since 7.4.0 this function can be called without any parameter, and it will return empty array. * @link https://php.net/manual/en/function.array-merge.php * @param array ...$arrays

    * Variable list of arrays to merge. *

    * @return array the resulting array. * @meta */ #[Pure] function array_merge( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.3')] $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.0')] $arrays, array ...$arrays ): array {} * The streams listed in the read array will be watched to * see if characters become available for reading (more precisely, to see if * a read will not block - in particular, a stream resource is also ready on * end-of-file, in which case an fread will return * a zero length string). *

    * @param array|null &$write

    * The streams listed in the write array will be * watched to see if a write will not block. *

    * @param array|null &$except

    * The streams listed in the except array will be * watched for high priority exceptional ("out-of-band") data arriving. *

    *

    * When stream_select returns, the arrays * read, write and * except are modified to indicate which stream * resource(s) actually changed status. *

    * You do not need to pass every array to * stream_select. You can leave it out and use an * empty array or null instead. Also do not forget that those arrays are * passed by reference and will be modified after * stream_select returns. * @param int|null $seconds

    * The tv_sec and tv_usec * together form the timeout parameter, * tv_sec specifies the number of seconds while * tv_usec the number of microseconds. * The timeout is an upper bound on the amount of time * that stream_select will wait before it returns. * If tv_sec and tv_usec are * both set to 0, stream_select will * not wait for data - instead it will return immediately, indicating the * current status of the streams. *

    *

    * If tv_sec is null stream_select * can block indefinitely, returning only when an event on one of the * watched streams occurs (or if a signal interrupts the system call). *

    *

    * Using a timeout value of 0 allows you to * instantaneously poll the status of the streams, however, it is NOT a * good idea to use a 0 timeout value in a loop as it * will cause your script to consume too much CPU time. *

    *

    * It is much better to specify a timeout value of a few seconds, although * if you need to be checking and running other code concurrently, using a * timeout value of at least 200000 microseconds will * help reduce the CPU usage of your script. *

    *

    * Remember that the timeout value is the maximum time that will elapse; * stream_select will return as soon as the * requested streams are ready for use. *

    * @param int $microseconds [optional]

    * See tv_sec description. *

    * @return int|false On success stream_select returns the number of * stream resources contained in the modified arrays, which may be zero if * the timeout expires before anything interesting happens. On error false * is returned and a warning raised (this can happen if the system call is * interrupted by an incoming signal). */ function stream_select( ?array &$read, ?array &$write, ?array &$except, ?int $seconds, #[LanguageLevelTypeAware(['8.1' => 'int|null'], default: 'int')] $microseconds ): int|false {} /** * Create a stream context * @link https://php.net/manual/en/function.stream-context-create.php * @param null|array $options [optional]

    * Must be an associative array of associative arrays in the format * $arr['wrapper']['option'] = $value. *

    *

    * Default to an empty array. *

    * @param null|array $params [optional]

    * Must be an associative array in the format * $arr['parameter'] = $value. * Refer to context parameters for * a listing of standard stream parameters. *

    * @return resource A stream context resource. */ function stream_context_create(?array $options, ?array $params) {} /** * Set parameters for a stream/wrapper/context * @link https://php.net/manual/en/function.stream-context-set-params.php * @param resource $context

    * The stream or context to apply the parameters too. *

    * @param array $params

    * An array of parameters to set. *

    *

    * params should be an associative array of the structure: * $params['paramname'] = "paramvalue";. *

    * @return bool true on success or false on failure. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] function stream_context_set_params($context, array $params) {} /** * Retrieves parameters from a context * @link https://php.net/manual/en/function.stream-context-get-params.php * @param resource $context

    * A stream resource or a * context resource *

    * @return array an associate array containing all context options and parameters. */ #[ArrayShape(["notification" => "string", "options" => "array"])] function stream_context_get_params($context): array {} /** * Sets an option for a stream/wrapper/context * @link https://php.net/manual/en/function.stream-context-set-option.php * @param resource $context

    * The stream or context resource to apply the options too. *

    * @param string $wrapper_or_options * @param string $option_name * @param mixed $value * @return bool true on success or false on failure. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] function stream_context_set_option($context, string $wrapper_or_options, string $option_name, mixed $value) {} /** * Sets an option for a stream/wrapper/context * @link https://php.net/manual/en/function.stream-context-set-option.php * @param resource $stream_or_context The stream or context resource to apply the options too. * @param array $options The options to set for the default context. * @return bool true on success or false on failure. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] function stream_context_set_option($stream_or_context, array $options) {} /** * @since 8.3 */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] function stream_context_set_options($context, array $options) {} /** * Retrieve options for a stream/wrapper/context * @link https://php.net/manual/en/function.stream-context-get-options.php * @param resource $stream_or_context

    * The stream or context to get options from *

    * @return array an associative array with the options. */ function stream_context_get_options($stream_or_context): array {} /** * Retreive the default stream context * @link https://php.net/manual/en/function.stream-context-get-default.php * @param null|array $options [optional] options must be an associative * array of associative arrays in the format * $arr['wrapper']['option'] = $value. *

    * As of PHP 5.3.0, the stream_context_set_default function * can be used to set the default context. *

    * @return resource A stream context resource. */ function stream_context_get_default(?array $options) {} /** * Set the default stream context * @link https://php.net/manual/en/function.stream-context-set-default.php * @param array $options

    * The options to set for the default context. *

    *

    * options must be an associative * array of associative arrays in the format * $arr['wrapper']['option'] = $value. *

    * @return resource the default stream context. */ function stream_context_set_default(array $options) {} /** * Attach a filter to a stream * @link https://php.net/manual/en/function.stream-filter-prepend.php * @param resource $stream

    * The target stream. *

    * @param string $filter_name

    * The filter name. *

    * @param int $mode

    * By default, stream_filter_prepend will * attach the filter to the read filter chain * if the file was opened for reading (i.e. File Mode: * r, and/or +). The filter * will also be attached to the write filter chain * if the file was opened for writing (i.e. File Mode: * w, a, and/or +). * STREAM_FILTER_READ, * STREAM_FILTER_WRITE, and/or * STREAM_FILTER_ALL can also be passed to the * read_write parameter to override this behavior. * See stream_filter_append for an example of * using this parameter. *

    * @param mixed $params [optional]

    * This filter will be added with the specified params * to the beginning of the list and will therefore be * called first during stream operations. To add a filter to the end of the * list, use stream_filter_append. *

    * @return resource|false a resource which can be used to refer to this filter * instance during a call to stream_filter_remove. */ function stream_filter_prepend($stream, string $filter_name, int $mode = 0, mixed $params) {} /** * Attach a filter to a stream * @link https://php.net/manual/en/function.stream-filter-append.php * @param resource $stream

    * The target stream. *

    * @param string $filter_name

    * The filter name. *

    * @param int $mode

    * By default, stream_filter_append will * attach the filter to the read filter chain * if the file was opened for reading (i.e. File Mode: * r, and/or +). The filter * will also be attached to the write filter chain * if the file was opened for writing (i.e. File Mode: * w, a, and/or +). * STREAM_FILTER_READ, * STREAM_FILTER_WRITE, and/or * STREAM_FILTER_ALL can also be passed to the * read_write parameter to override this behavior. *

    * @param mixed $params [optional]

    * This filter will be added with the specified * params to the end of * the list and will therefore be called last during stream operations. * To add a filter to the beginning of the list, use * stream_filter_prepend. *

    * @return resource|false a resource which can be used to refer to this filter * instance during a call to stream_filter_remove. */ function stream_filter_append($stream, string $filter_name, int $mode = 0, mixed $params) {} /** * Remove a filter from a stream * @link https://php.net/manual/en/function.stream-filter-remove.php * @param resource $stream_filter

    * The stream filter to be removed. *

    * @return bool true on success or false on failure. */ function stream_filter_remove($stream_filter): bool {} /** * Open Internet or Unix domain socket connection * @link https://php.net/manual/en/function.stream-socket-client.php * @param string $address

    * Address to the socket to connect to. *

    * @param int &$error_code [optional]

    * Will be set to the system level error number if connection fails. *

    * @param string &$error_message [optional]

    * Will be set to the system level error message if the connection fails. *

    * @param float|null $timeout [optional]

    * Number of seconds until the connect() system call * should timeout. * This parameter only applies when not making asynchronous * connection attempts. *

    * To set a timeout for reading/writing data over the socket, use the * stream_set_timeout, as the * timeout only applies while making connecting * the socket. *

    *

    * @param int $flags [optional]

    * Bitmask field which may be set to any combination of connection flags. * Currently the select of connection flags is limited to * STREAM_CLIENT_CONNECT (default), * STREAM_CLIENT_ASYNC_CONNECT and * STREAM_CLIENT_PERSISTENT. *

    * @param resource $context [optional]

    * A valid context resource created with stream_context_create. *

    * @return resource|false On success a stream resource is returned which may * be used together with the other file functions (such as * fgets, fgetss, * fwrite, fclose, and * feof), false on failure. */ function stream_socket_client(string $address, &$error_code, &$error_message, ?float $timeout, int $flags = STREAM_CLIENT_CONNECT, $context) {} /** * Create an Internet or Unix domain server socket * @link https://php.net/manual/en/function.stream-socket-server.php * @param string $address

    * The type of socket created is determined by the transport specified * using standard URL formatting: transport://target. *

    *

    * For Internet Domain sockets (AF_INET) such as TCP and UDP, the * target portion of the * remote_socket parameter should consist of a * hostname or IP address followed by a colon and a port number. For * Unix domain sockets, the target portion should * point to the socket file on the filesystem. *

    *

    * Depending on the environment, Unix domain sockets may not be available. * A list of available transports can be retrieved using * stream_get_transports. See * for a list of built-in transports. *

    * @param int &$error_code [optional]

    * If the optional errno and errstr * arguments are present they will be set to indicate the actual system * level error that occurred in the system-level socket(), * bind(), and listen() calls. If * the value returned in errno is * 0 and the function returned false, it is an * indication that the error occurred before the bind() * call. This is most likely due to a problem initializing the socket. * Note that the errno and * errstr arguments will always be passed by reference. *

    * @param string &$error_message [optional]

    * See errno description. *

    * @param int $flags [optional]

    * A bitmask field which may be set to any combination of socket creation * flags. *

    *

    * For UDP sockets, you must use STREAM_SERVER_BIND as * the flags parameter. *

    * @param resource $context [optional]

    *

    * @return resource|false the created stream, or false on error. */ function stream_socket_server(string $address, &$error_code, &$error_message, int $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context) {} /** * Accept a connection on a socket created by {@see stream_socket_server} * @link https://php.net/manual/en/function.stream-socket-accept.php * @param resource $socket * @param float|null $timeout [optional]

    * Override the default socket accept timeout. Time should be given in * seconds. *

    * @param string &$peer_name [optional]

    * Will be set to the name (address) of the client which connected, if * included and available from the selected transport. *

    *

    * Can also be determined later using * stream_socket_get_name. *

    * @return resource|false Returns a stream to the accepted socket connection or FALSE on failure. */ function stream_socket_accept($socket, ?float $timeout, &$peer_name) {} /** * Retrieve the name of the local or remote sockets * @link https://php.net/manual/en/function.stream-socket-get-name.php * @param resource $socket

    * The socket to get the name of. *

    * @param bool $remote

    * If set to true the remote socket name will be returned, if set * to false the local socket name will be returned. *

    * @return string|false The name of the socket or false on error. */ function stream_socket_get_name($socket, bool $remote): string|false {} /** * Receives data from a socket, connected or not * @link https://php.net/manual/en/function.stream-socket-recvfrom.php * @param resource $socket

    * The remote socket. *

    * @param int $length

    * The number of bytes to receive from the socket. *

    * @param int $flags

    * The value of flags can be any combination * of the following: *

    * Possible values for flags * * * * * * * * *
    STREAM_OOB * Process OOB (out-of-band) data. *
    STREAM_PEEK * Retrieve data from the socket, but do not consume the buffer. * Subsequent calls to fread or * stream_socket_recvfrom will see * the same data. *
    *

    * @param string &$address [optional]

    * If address is provided it will be populated with * the address of the remote socket. *

    * @return string|false the read data, as a string, or false on error */ function stream_socket_recvfrom($socket, int $length, int $flags = 0, &$address): string|false {} /** * Sends a message to a socket, whether it is connected or not * @link https://php.net/manual/en/function.stream-socket-sendto.php * @param resource $socket

    * The socket to send data to. *

    * @param string $data

    * The data to be sent. *

    * @param int $flags

    * The value of flags can be any combination * of the following: *

    * possible values for flags * * * * *
    STREAM_OOB * Process OOB (out-of-band) data. *
    *

    * @param string $address

    * The address specified when the socket stream was created will be used * unless an alternate address is specified in address. *

    *

    * If specified, it must be in dotted quad (or [ipv6]) format. *

    * @return int|false a result code, as an integer. */ function stream_socket_sendto($socket, string $data, int $flags = 0, string $address = ''): int|false {} /** * Turns encryption on/off on an already connected socket * @link https://php.net/manual/en/function.stream-socket-enable-crypto.php * @param resource $stream

    * The stream resource. *

    * @param bool $enable

    * Enable/disable cryptography on the stream. *

    * @param int|null $crypto_method [optional]

    * Setup encryption on the stream. * Valid methods are:
    * STREAM_CRYPTO_METHOD_SSLv2_CLIENT

    * @param resource $session_stream [optional]

    * Seed the stream with settings from session_stream. *

    * @return bool|int true on success, false if negotiation has failed or * 0 if there isn't enough data and you should try again * (only for non-blocking sockets). */ function stream_socket_enable_crypto($stream, bool $enable, ?int $crypto_method, $session_stream): int|bool {} /** * Shutdown a full-duplex connection * @link https://php.net/manual/en/function.stream-socket-shutdown.php * @param resource $stream

    * An open stream (opened with stream_socket_client, * for example) *

    * @param int $mode

    * One of the following constants: STREAM_SHUT_RD * (disable further receptions), STREAM_SHUT_WR * (disable further transmissions) or * STREAM_SHUT_RDWR (disable further receptions and * transmissions). *

    * @return bool true on success or false on failure. * @since 5.2.1 */ function stream_socket_shutdown($stream, int $mode): bool {} /** * Creates a pair of connected, indistinguishable socket streams * @link https://php.net/manual/en/function.stream-socket-pair.php * @param int $domain

    * The protocol family to be used: STREAM_PF_INET, * STREAM_PF_INET6 or * STREAM_PF_UNIX *

    * @param int $type

    * The type of communication to be used: * STREAM_SOCK_DGRAM, * STREAM_SOCK_RAW, * STREAM_SOCK_RDM, * STREAM_SOCK_SEQPACKET or * STREAM_SOCK_STREAM *

    * @param int $protocol

    * The protocol to be used: STREAM_IPPROTO_ICMP, * STREAM_IPPROTO_IP, * STREAM_IPPROTO_RAW, * STREAM_IPPROTO_TCP or * STREAM_IPPROTO_UDP *

    * @return array|false an array with the two socket resources on success, or * false on failure. */ function stream_socket_pair(int $domain, int $type, int $protocol): array|false {} /** * Copies data from one stream to another * @link https://php.net/manual/en/function.stream-copy-to-stream.php * @param resource $from

    * The source stream *

    * @param resource $to

    * The destination stream *

    * @param int|null $length [optional]

    * Maximum bytes to copy *

    * @param int $offset

    * The offset where to start to copy data *

    * @return int|false the total count of bytes copied, or false on failure. */ function stream_copy_to_stream($from, $to, ?int $length, int $offset = 0): int|false {} /** * Reads remainder of a stream into a string * @link https://php.net/manual/en/function.stream-get-contents.php * @param resource $stream

    * A stream resource (e.g. returned from fopen) *

    * @param int|null $length

    * The maximum bytes to read. Defaults to -1 (read all the remaining * buffer). *

    * @param int $offset [optional]

    * Seek to the specified offset before reading. *

    * @return string|false a string or false on failure. */ function stream_get_contents($stream, ?int $length = null, int $offset = -1): string|false {} /** * Tells whether the stream supports locking. * @link https://php.net/manual/en/function.stream-supports-lock.php * @param resource $stream

    * The stream to check. *

    * @return bool true on success or false on failure. */ function stream_supports_lock($stream): bool {} /** * Gets line from file pointer and parse for CSV fields * @link https://php.net/manual/en/function.fgetcsv.php * @param resource $stream

    * A valid file pointer to a file successfully opened by * fopen, popen, or * fsockopen. *

    * @param int|null $length

    * Must be greater than the longest line (in characters) to be found in * the CSV file (allowing for trailing line-end characters). It became * optional in PHP 5. Omitting this parameter (or setting it to 0 in PHP * 5.0.4 and later) the maximum line length is not limited, which is * slightly slower. *

    * @param string $separator [optional]

    * Set the field delimiter (one character only). *

    * @param string $enclosure [optional]

    * Set the field enclosure character (one character only). *

    * @param string $escape [optional]

    * Set the escape character (one character only). Defaults as a backslash. *

    * @return array|false|null an indexed array containing the fields read. *

    * A blank line in a CSV file will be returned as an array * comprising a single null field, and will not be treated * as an error. *

    *

    * fgetcsv returns null if an invalid * handle is supplied or false on other errors, * including end of file. *

    */ #[LanguageLevelTypeAware(['8.0' => 'array|false'], default: 'array|false|null')] function fgetcsv($stream, ?int $length = null, string $separator = ',', string $enclosure = '"', string $escape = '\\') {} /** * Format line as CSV and write to file pointer * @link https://php.net/manual/en/function.fputcsv.php * @param resource $stream The file pointer must be valid, and must point to a file successfully opened by fopen() or fsockopen() (and not yet closed by fclose()). * @param array $fields

    * An array of values. *

    * @param string $separator [optional]

    * The optional delimiter parameter sets the field * delimiter (one character only). *

    * @param string $enclosure [optional]

    * The optional enclosure parameter sets the field * enclosure (one character only). *

    * @param string $escape [optional]

    * The optional escape_char parameter sets the escape character (one character only). *

    * @return int|false the length of the written string or false on failure. */ function fputcsv( $stream, array $fields, string $separator = ",", string $enclosure = '"', #[PhpStormStubsElementAvailable(from: '7.0')] string $escape = "\\", #[PhpStormStubsElementAvailable('8.1')] string $eol = PHP_EOL ): int|false {} /** * Portable advisory file locking * @link https://php.net/manual/en/function.flock.php * @param resource $stream

    * An open file pointer. *

    * @param int $operation

    * operation is one of the following: * LOCK_SH to acquire a shared lock (reader).

    * @param int &$would_block [optional]

    * The optional third argument is set to 1 if the lock would block * (EWOULDBLOCK errno condition). *

    * @return bool true on success or false on failure. */ function flock($stream, int $operation, &$would_block): bool {} /** * Extracts all meta tag content attributes from a file and returns an array * @link https://php.net/manual/en/function.get-meta-tags.php * @param string $filename

    * The path to the HTML file, as a string. This can be a local file or an * URL. *

    *

    * What get_meta_tags parses *

    *
     * 
     * 
     * 
     * 
     *  
     * 
    *

    * (pay attention to line endings - PHP uses a native function to * parse the input, so a Mac file won't work on Unix). *

    * @param bool $use_include_path [optional]

    * Setting use_include_path to true will result * in PHP trying to open the file along the standard include path as per * the include_path directive. * This is used for local files, not URLs. *

    * @return array|false an array with all the parsed meta tags. *

    * The value of the name property becomes the key, the value of the content * property becomes the value of the returned array, so you can easily use * standard array functions to traverse it or access single values. * Special characters in the value of the name property are substituted with * '_', the rest is converted to lower case. If two meta tags have the same * name, only the last one is returned. *

    */ #[Pure(true)] function get_meta_tags(string $filename, bool $use_include_path = false): array|false {} /** * Sets write file buffering on the given stream * @link https://php.net/manual/en/function.stream-set-write-buffer.php * @param resource $stream

    * The file pointer. *

    * @param int $size

    * The number of bytes to buffer. If buffer * is 0 then write operations are unbuffered. This ensures that all writes * with fwrite are completed before other processes are * allowed to write to that output stream. *

    * @return int 0 on success, or EOF if the request cannot be honored. * @see stream_set_read_buffer() */ function stream_set_write_buffer($stream, int $size): int {} /** * Sets read file buffering on the given stream * @link https://php.net/manual/en/function.stream-set-read-buffer.php * @param resource $stream

    * The file pointer. *

    * @param int $size

    * The number of bytes to buffer. If buffer * is 0 then write operations are unbuffered. This ensures that all writes * with fwrite are completed before other processes are * allowed to write to that output stream. *

    * @return int 0 on success, or EOF if the request cannot be honored. * @see stream_set_write_buffer() */ function stream_set_read_buffer($stream, int $size): int {} /** * Alias: * {@see stream_set_write_buffer} *

    Sets the buffering for write operations on the given stream to buffer bytes. * Output using fwrite() is normally buffered at 8K. * This means that if there are two processes wanting to write to the same output stream (a file), * each is paused after 8K of data to allow the other to write. *

    * @link https://php.net/manual/en/function.set-file-buffer.php * @param resource $stream The file pointer. * @param int $size The number of bytes to buffer. If buffer is 0 then write operations are unbuffered. * This ensures that all writes with fwrite() are completed before other processes are allowed to write to that output stream. * @return int */ function set_file_buffer($stream, int $size): int {} /** * Alias: * {@see stream_set_blocking} *

    Sets blocking or non-blocking mode on a stream. * This function works for any stream that supports non-blocking mode (currently, regular files and socket streams) *

    * @link https://php.net/manual/en/function.set-socket-blocking.php * @param resource $socket * @param bool $mode If mode is FALSE, the given stream will be switched to non-blocking mode, and if TRUE, it will be switched to blocking mode. * This affects calls like fgets() and fread() that read from the stream. * In non-blocking mode an fgets() call will always return right away while in blocking mode it will wait for data to become available on the stream. * @return bool Returns TRUE on success or FALSE on failure. * @removed 7.0 * @see stream_set_blocking() */ #[Deprecated(replacement: "stream_set_blocking(%parametersList%)", since: 5.3)] function set_socket_blocking($socket, bool $mode): bool {} /** * Set blocking/non-blocking mode on a stream * @link https://php.net/manual/en/function.stream-set-blocking.php * @param resource $stream

    * The stream. *

    * @param bool $enable

    * If mode is FALSE, the given stream * will be switched to non-blocking mode, and if TRUE, it * will be switched to blocking mode. This affects calls like * fgets and fread * that read from the stream. In non-blocking mode an * fgets call will always return right away * while in blocking mode it will wait for data to become available * on the stream. *

    * @return bool true on success or false on failure. */ function stream_set_blocking($stream, bool $enable): bool {} /** * Alias: * {@see stream_set_blocking} * @link https://php.net/manual/en/function.socket-set-blocking.php * @param resource $stream

    * The stream. *

    * @param bool $enable

    * If mode is FALSE, the given stream * will be switched to non-blocking mode, and if TRUE, it * will be switched to blocking mode. This affects calls like * fgets and fread * that read from the stream. In non-blocking mode an * fgets call will always return right away * while in blocking mode it will wait for data to become available * on the stream. *

    * @return bool true on success or false on failure. */ function socket_set_blocking($stream, bool $enable): bool {} /** * Retrieves header/meta data from streams/file pointers * @link https://php.net/manual/en/function.stream-get-meta-data.php * @param resource $stream

    * The stream can be any stream created by fopen, * fsockopen and pfsockopen. *

    * @return array The result array contains the following items: *

    * timed_out (bool) - true if the stream * timed out while waiting for data on the last call to * fread or fgets. *

    *

    * blocked (bool) - true if the stream is * in blocking IO mode. See stream_set_blocking. *

    *

    * eof (bool) - true if the stream has reached * end-of-file. Note that for socket streams this member can be true * even when unread_bytes is non-zero. To * determine if there is more data to be read, use * feof instead of reading this item. *

    *

    * unread_bytes (int) - the number of bytes * currently contained in the PHP's own internal buffer. *

    * You shouldn't use this value in a script. *

    * stream_type (string) - a label describing * the underlying implementation of the stream. *

    *

    * wrapper_type (string) - a label describing * the protocol wrapper implementation layered over the stream. * See for more information about wrappers. *

    *

    * wrapper_data (mixed) - wrapper specific * data attached to this stream. See for * more information about wrappers and their wrapper data. *

    *

    * filters (array) - and array containing * the names of any filters that have been stacked onto this stream. * Documentation on filters can be found in the * Filters appendix. *

    *

    * mode (string) - the type of access required for * this stream (see Table 1 of the fopen() reference) *

    *

    * seekable (bool) - whether the current stream can * be seeked. *

    *

    * uri (string) - the URI/filename associated with this * stream. *

    */ #[ArrayShape(["timed_out" => "bool", "blocked" => "bool", "eof" => "bool", "unread_bytes" => "int", "stream_type" => "string", "wrapper_type" => "string", "wrapper_data" => "mixed", "mode" => "string", "seekable" => "bool", "uri" => "string", "crypto" => "array", "mediatype" => "string"])] function stream_get_meta_data($stream): array {} /** * Gets line from stream resource up to a given delimiter * @link https://php.net/manual/en/function.stream-get-line.php * @param resource $stream

    * A valid file handle. *

    * @param int $length

    * The number of bytes to read from the handle. *

    * @param string $ending

    * An optional string delimiter. *

    * @return string|false a string of up to length bytes read from the file * pointed to by handle. *

    * If an error occurs, returns false. *

    */ function stream_get_line($stream, int $length, string $ending = ''): string|false {} /** * Register a URL wrapper implemented as a PHP class * @link https://php.net/manual/en/function.stream-wrapper-register.php * @param string $protocol

    * The wrapper name to be registered. *

    * @param string $class

    * The classname which implements the protocol. *

    * @param int $flags

    * Should be set to STREAM_IS_URL if * protocol is a URL protocol. Default is 0, local * stream. *

    * @return bool true on success or false on failure. *

    * stream_wrapper_register will return false if the * protocol already has a handler. *

    */ function stream_wrapper_register(string $protocol, string $class, int $flags = 0): bool {} /** * Alias: * {@see stream_wrapper_register} *

    Register a URL wrapper implemented as a PHP class

    * @link https://php.net/manual/en/function.stream-register-wrapper.php * @param string $protocol

    * The wrapper name to be registered. *

    * @param string $class

    * The classname which implements the protocol. *

    * @param int $flags [optional]

    * Should be set to STREAM_IS_URL if * protocol is a URL protocol. Default is 0, local * stream. *

    * @return bool true on success or false on failure. *

    * stream_wrapper_register will return false if the * protocol already has a handler. *

    */ function stream_register_wrapper(string $protocol, string $class, int $flags = 0): bool {} /** * Resolve filename against the include path according to the same rules as fopen()/include(). * @link https://php.net/manual/en/function.stream-resolve-include-path.php * @param string $filename The filename to resolve. * @return string|false containing the resolved absolute filename, or FALSE on failure. * @since 5.3.2 */ function stream_resolve_include_path(string $filename): string|false {} /** * Unregister a URL wrapper * @link https://php.net/manual/en/function.stream-wrapper-unregister.php * @param string $protocol

    *

    * @return bool true on success or false on failure. */ function stream_wrapper_unregister(string $protocol): bool {} /** * Restores a previously unregistered built-in wrapper * @link https://php.net/manual/en/function.stream-wrapper-restore.php * @param string $protocol

    *

    * @return bool true on success or false on failure. */ function stream_wrapper_restore(string $protocol): bool {} /** * Retrieve list of registered streams * @link https://php.net/manual/en/function.stream-get-wrappers.php * @return list an indexed array containing the name of all stream wrappers * available on the running system. */ #[Pure(true)] function stream_get_wrappers(): array {} /** * Retrieve list of registered socket transports * @link https://php.net/manual/en/function.stream-get-transports.php * @return list an indexed array of socket transports names. */ #[Pure(true)] function stream_get_transports(): array {} /** * Checks if a stream is a local stream * @link https://php.net/manual/en/function.stream-is-local.php * @param mixed $stream

    * The stream resource or URL to check. *

    * @return bool true on success or false on failure. * @since 5.2.4 */ #[Pure] function stream_is_local($stream): bool {} /** * Fetches all the headers sent by the server in response to an HTTP request * @link https://php.net/manual/en/function.get-headers.php * @param string $url

    * The target URL. *

    * @param bool $associative [optional]

    * If the optional format parameter is set to true, * get_headers parses the response and sets the * array's keys. *

    * @param resource $context [optional] * @return array|false an indexed or associative array with the headers, or false on * failure. */ #[Pure(true)] function get_headers( string $url, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: 'int')] $associative = false, #[PhpStormStubsElementAvailable(from: '7.1')] $context = null ): array|false {} /** * Set timeout period on a stream * @link https://php.net/manual/en/function.stream-set-timeout.php * @param resource $stream

    * The target stream. *

    * @param int $seconds

    * The seconds part of the timeout to be set. *

    * @param int $microseconds

    * The microseconds part of the timeout to be set. *

    * @return bool true on success or false on failure. */ function stream_set_timeout( $stream, int $seconds, #[PhpStormStubsElementAvailable(from: '5.3', to: '5.6')] int $microseconds, #[PhpStormStubsElementAvailable(from: '7.0')] int $microseconds = 0 ): bool {} /** * Alias: * {@see stream_set_timeout} * Set timeout period on a stream * @link https://php.net/manual/en/function.socket-set-timeout.php * @param resource $stream

    * The target stream. *

    * @param int $seconds

    * The seconds part of the timeout to be set. *

    * @param int $microseconds

    * The microseconds part of the timeout to be set. *

    * @return bool true on success or false on failure. */ function socket_set_timeout( $stream, int $seconds, #[PhpStormStubsElementAvailable(from: '5.3', to: '5.6')] int $microseconds, #[PhpStormStubsElementAvailable(from: '7.0')] int $microseconds = 0 ): bool {} /** * Alias: * {@see stream_get_meta_data} * Retrieves header/meta data from streams/file pointers * @link https://php.net/manual/en/function.socket-get-status.php * @param resource $stream

    * The stream can be any stream created by fopen, * fsockopen and pfsockopen. *

    * @return array The result array contains the following items: *

    * timed_out (bool) - true if the stream * timed out while waiting for data on the last call to * fread or fgets. *

    *

    * blocked (bool) - true if the stream is * in blocking IO mode. See stream_set_blocking. *

    *

    * eof (bool) - true if the stream has reached * end-of-file. Note that for socket streams this member can be true * even when unread_bytes is non-zero. To * determine if there is more data to be read, use * feof instead of reading this item. *

    *

    * unread_bytes (int) - the number of bytes * currently contained in the PHP's own internal buffer. *

    * You shouldn't use this value in a script. *

    * stream_type (string) - a label describing * the underlying implementation of the stream. *

    *

    * wrapper_type (string) - a label describing * the protocol wrapper implementation layered over the stream. * See for more information about wrappers. *

    *

    * wrapper_data (mixed) - wrapper specific * data attached to this stream. See for * more information about wrappers and their wrapper data. *

    *

    * filters (array) - and array containing * the names of any filters that have been stacked onto this stream. * Documentation on filters can be found in the * Filters appendix. *

    *

    * mode (string) - the type of access required for * this stream (see Table 1 of the fopen() reference) *

    *

    * seekable (bool) - whether the current stream can * be seeked. *

    *

    * uri (string) - the URI/filename associated with this * stream. *

    */ function socket_get_status($stream): array {} /** * Returns canonicalized absolute pathname * @link https://php.net/manual/en/function.realpath.php * @param string $path

    * The path being checked. *

    * @return string|false the canonicalized absolute pathname on success. The resulting path * will have no symbolic link, '/./' or '/../' components. *

    * realpath returns false on failure, e.g. if * the file does not exist. *

    */ #[Pure(true)] function realpath(string $path): string|false {} /** * Match filename against a pattern * @link https://php.net/manual/en/function.fnmatch.php * @param string $pattern

    * The shell wildcard pattern. *

    * @param string $filename

    * The tested string. This function is especially useful for filenames, * but may also be used on regular strings. *

    *

    * The average user may be used to shell patterns or at least in their * simplest form to '?' and '*' * wildcards so using fnmatch instead of * preg_match for * frontend search expression input may be way more convenient for * non-programming users. *

    * @param int $flags

    * The value of flags can be any combination of * the following flags, joined with the * binary OR (|) operator. *

    * A list of possible flags for fnmatch * * * * * * * * * * * * * * * * * * * * *
    FlagDescription
    FNM_NOESCAPE * Disable backslash escaping. *
    FNM_PATHNAME * Slash in string only matches slash in the given pattern. *
    FNM_PERIOD * Leading period in string must be exactly matched by period in the given pattern. *
    FNM_CASEFOLD * Caseless match. Part of the GNU extension. *
    *

    * @return bool true if there is a match, false otherwise. */ #[Pure(true)] function fnmatch(string $pattern, string $filename, int $flags = 0): bool {} * item may be an integer value of the element or the * constant name of the element. The following is a list of constant names * for item that may be used and their description. * Some of these constants may not be defined or hold no value for certain * locales.

    * nl_langinfo Constants * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    ConstantDescription
    LC_TIME Category Constants
    ABDAY_(1-7)Abbreviated name of n-th day of the week.
    DAY_(1-7)Name of the n-th day of the week (DAY_1 = Sunday).
    ABMON_(1-12)Abbreviated name of the n-th month of the year.
    MON_(1-12)Name of the n-th month of the year.
    AM_STRString for Ante meridian.
    PM_STRString for Post meridian.
    D_T_FMTString that can be used as the format string for strftime to represent time and date.
    D_FMTString that can be used as the format string for strftime to represent date.
    T_FMTString that can be used as the format string for strftime to represent time.
    T_FMT_AMPMString that can be used as the format string for strftime to represent time in 12-hour format with ante/post meridian.
    ERAAlternate era.
    ERA_YEARYear in alternate era format.
    ERA_D_T_FMTDate and time in alternate era format (string can be used in strftime).
    ERA_D_FMTDate in alternate era format (string can be used in strftime).
    ERA_T_FMTTime in alternate era format (string can be used in strftime).
    LC_MONETARY Category Constants
    INT_CURR_SYMBOLInternational currency symbol.
    CURRENCY_SYMBOLLocal currency symbol.
    CRNCYSTRSame value as CURRENCY_SYMBOL.
    MON_DECIMAL_POINTDecimal point character.
    MON_THOUSANDS_SEPThousands separator (groups of three digits).
    MON_GROUPINGLike "grouping" element.
    POSITIVE_SIGNSign for positive values.
    NEGATIVE_SIGNSign for negative values.
    INT_FRAC_DIGITSInternational fractional digits.
    FRAC_DIGITSLocal fractional digits.
    P_CS_PRECEDESReturns 1 if CURRENCY_SYMBOL precedes a positive value.
    P_SEP_BY_SPACEReturns 1 if a space separates CURRENCY_SYMBOL from a positive value.
    N_CS_PRECEDESReturns 1 if CURRENCY_SYMBOL precedes a negative value.
    N_SEP_BY_SPACEReturns 1 if a space separates CURRENCY_SYMBOL from a negative value.
    P_SIGN_POSNReturns 0 if parentheses surround the quantity and CURRENCY_SYMBOL.
    * @return string|false the element as a string, or false if item * is not valid. */ #[Pure(true)] function nl_langinfo(int $item): string|false {} /** * Calculate the soundex key of a string * @link https://php.net/manual/en/function.soundex.php * @param string $string

    * The input string. *

    * @return string the soundex key as a string. */ #[Pure] function soundex(string $string): string {} /** * Calculate Levenshtein distance between two strings * @link https://php.net/manual/en/function.levenshtein.php * Note: In its simplest form the function will take only the two strings * as parameter and will calculate just the number of insert, replace and * delete operations needed to transform str1 into str2. * Note: A second variant will take three additional parameters that define * the cost of insert, replace and delete operations. This is more general * and adaptive than variant one, but not as efficient. * @param string $string1

    * One of the strings being evaluated for Levenshtein distance. *

    * @param string $string2

    * One of the strings being evaluated for Levenshtein distance. *

    * @param int $insertion_cost [optional]

    * Defines the cost of insertion. *

    * @param int $replacement_cost [optional]

    * Defines the cost of replacement. *

    * @param int $deletion_cost [optional]

    * Defines the cost of deletion. *

    * @return int This function returns the Levenshtein-Distance between the * two argument strings or -1, if one of the argument strings * is longer than the limit of 255 characters. */ function levenshtein(string $string1, string $string2, int $insertion_cost = 1, int $replacement_cost = 1, int $deletion_cost = 1): int {} /** * Generate a single-byte string from a number * @link https://php.net/manual/en/function.chr.php * @param int $codepoint

    * The ascii code. *

    * @return string the specified character. */ #[Pure] function chr(int $codepoint): string {} /** * Convert the first byte of a string to a value between 0 and 255 * @link https://php.net/manual/en/function.ord.php * @param string $character

    * A character. *

    * @return int<0, 255> the ASCII value as an integer. */ #[Pure] function ord(string $character): int {} /** * Parses the string into variables * @link https://php.net/manual/en/function.parse-str.php * @param string $string

    * The input string. *

    * @param array &$result

    * If the second parameter arr is present, * variables are stored in this variable as array elements instead.
    * Since 7.2.0 this parameter is not optional. *

    * @return void */ function parse_str( string $string, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] &$result = [], #[PhpStormStubsElementAvailable(from: '8.0')] &$result ): void {} /** * Parse a CSV string into an array * @link https://php.net/manual/en/function.str-getcsv.php * @param string $string

    * The string to parse. *

    * @param string $separator [optional]

    * Set the field delimiter (one character only). *

    * @param string $enclosure [optional]

    * Set the field enclosure character (one character only). *

    * @param string $escape [optional]

    * Set the escape character (one character only). * Defaults as a backslash (\) *

    * @return array an indexed array containing the fields read. */ #[Pure] function str_getcsv(string $string, string $separator = ",", string $enclosure = '"', string $escape = "\\"): array {} /** * Pad a string to a certain length with another string * @link https://php.net/manual/en/function.str-pad.php * @param string $string

    * The input string. *

    * @param int $length

    * If the value of pad_length is negative, * less than, or equal to the length of the input string, no padding * takes place. *

    * @param string $pad_string [optional]

    * The pad_string may be truncated if the * required number of padding characters can't be evenly divided by the * pad_string's length. *

    * @param int $pad_type [optional]

    * Optional argument pad_type can be * STR_PAD_RIGHT, STR_PAD_LEFT, * or STR_PAD_BOTH. If * pad_type is not specified it is assumed to be * STR_PAD_RIGHT. *

    * @return string the padded string. */ #[Pure] function str_pad(string $string, int $length, string $pad_string = " ", int $pad_type = STR_PAD_RIGHT): string {} /** * Alias: * {@see rtrim} * @param string $string The input string. * @param string $characters [optional] * @return string the modified string. * @link https://php.net/manual/en/function.chop.php * @see rtrim() */ #[Pure] function chop(string $string, string $characters = " \n\r\t\v\0"): string {} /** * Alias: * {@see strstr} * @link https://php.net/manual/en/function.strchr.php * Note: This function is case-sensitive. For case-insensitive searches, use stristr(). * Note: If you only want to determine if a particular needle occurs within haystack, * use the faster and less memory intensive function strpos() instead. * * @param string $haystack The input string. * @param string $needle If needle is not a string, it is converted to an integer and applied as the ordinal value of a character. * @param bool $before_needle [optional] If TRUE, strstr() returns the part of the haystack before the first occurrence of the needle (excluding the needle). * @return string|false Returns the portion of string, or FALSE if needle is not found. */ #[Pure] function strchr(string $haystack, string $needle, bool $before_needle = false): string|false {} /** * Return a formatted string * @link https://php.net/manual/en/function.sprintf.php * @param string $format

    * The format string is composed of zero or more directives: * ordinary characters (excluding %) that are * copied directly to the result, and conversion * specifications, each of which results in fetching its * own parameter. This applies to both sprintf * and printf. *

    *

    * Each conversion specification consists of a percent sign * (%), followed by one or more of these * elements, in order: * An optional sign specifier that forces a sign * (- or +) to be used on a number. By default, only the - sign is used * on a number if it's negative. This specifier forces positive numbers * to have the + sign attached as well, and was added in PHP 4.3.0.

    * @param string|int|float ...$values

    *

    * @return string a string produced according to the formatting string * format. */ #[Pure] function sprintf( string $format, #[PhpStormStubsElementAvailable(from: '5.3', to: '5.6')] $values, mixed ...$values ): string {} /** * Output a formatted string * @link https://php.net/manual/en/function.printf.php * @param string $format

    * See sprintf for a description of * format. *

    * @param string|int|float ...$values [optional]

    *

    * @return int the length of the outputted string. */ function printf(string $format, mixed ...$values): int {} /** * Output a formatted string * @link https://php.net/manual/en/function.vprintf.php * @param string $format

    * See sprintf for a description of * format. *

    * @param array $values

    *

    * @return int the length of the outputted string. */ function vprintf(string $format, array $values): int {} /** * Return a formatted string * @link https://php.net/manual/en/function.vsprintf.php * @param string $format

    * See sprintf for a description of * format. *

    * @param array $values

    *

    * @return string Return array values as a formatted string according to * format (which is described in the documentation * for sprintf). */ #[Pure] function vsprintf(string $format, array $values): string {} /** * Write a formatted string to a stream * @link https://php.net/manual/en/function.fprintf.php * @param resource $stream &fs.file.pointer; * @param string $format

    * See sprintf for a description of * format. *

    * @param mixed ...$values [optional]

    *

    * @return int the length of the string written. */ function fprintf($stream, string $format, mixed ...$values): int {} /** * Write a formatted string to a stream * @link https://php.net/manual/en/function.vfprintf.php * @param resource $stream

    *

    * @param string $format

    * See sprintf for a description of * format. *

    * @param array $values

    *

    * @return int the length of the outputted string. */ function vfprintf($stream, string $format, array $values): int {} /** * Parses input from a string according to a format * @link https://php.net/manual/en/function.sscanf.php * @param string $string

    * The input string being parsed. *

    * @param string $format

    * The interpreted format for str, which is * described in the documentation for sprintf with * following differences: * Function is not locale-aware. * F, g, G and * b are not supported. * D stands for decimal number. * i stands for integer with base detection. * n stands for number of characters processed so far. *

    * @param mixed &...$vars [optional] * @return array|int|null If only * two parameters were passed to this function, the values parsed * will be returned as an array. Otherwise, if optional parameters are passed, * the function will return the number of assigned values. The optional * parameters must be passed by reference. */ function sscanf(string $string, string $format, #[TypeContract(exists: "int|null", notExists: "array|null")] mixed &...$vars): array|int|null {} /** * Parses input from a file according to a format * @link https://php.net/manual/en/function.fscanf.php * @param resource $stream &fs.file.pointer; * @param string $format

    * The specified format as described in the * sprintf documentation. *

    * @param mixed &...$vars [optional] * @return array|int|false|null If only two parameters were passed to this function, the values parsed will be * returned as an array. Otherwise, if optional parameters are passed, the * function will return the number of assigned values. The optional * parameters must be passed by reference. */ function fscanf($stream, string $format, #[TypeContract(exists: "int|false|null", notExists: "array|false|null")] mixed &...$vars): array|int|false|null {} /** * Parse a URL and return its components * @link https://php.net/manual/en/function.parse-url.php * @param string $url

    * The URL to parse. Invalid characters are replaced by * _. *

    * @param int $component [optional]

    * Specify one of PHP_URL_SCHEME, * PHP_URL_HOST, PHP_URL_PORT, * PHP_URL_USER, PHP_URL_PASS, * PHP_URL_PATH, PHP_URL_QUERY * or PHP_URL_FRAGMENT to retrieve just a specific * URL component as a string. *

    * @return array|string|int|null|false On seriously malformed URLs, parse_url() may return FALSE. * If the component parameter is omitted, an associative array is returned. * At least one element will be present within the array. Potential keys within this array are: * scheme - e.g. http * host * port * user * pass * path * query - after the question mark ? * fragment - after the hashmark # *

    *

    * If the component parameter is specified a * string is returned instead of an array. */ #[ArrayShape(["scheme" => "string", "host" => "string", "port" => "int", "user" => "string", "pass" => "string", "query" => "string", "path" => "string", "fragment" => "string"])] #[Pure] function parse_url(string $url, int $component = -1): array|string|int|false|null {} /** * URL-encodes string * @link https://php.net/manual/en/function.urlencode.php * @param string $string

    * The string to be encoded. *

    * @return string a string in which all non-alphanumeric characters except * -_. have been replaced with a percent * (%) sign followed by two hex digits and spaces encoded * as plus (+) signs. It is encoded the same way that the * posted data from a WWW form is encoded, that is the same way as in * application/x-www-form-urlencoded media type. This * differs from the RFC 3986 encoding (see * rawurlencode) in that for historical reasons, spaces * are encoded as plus (+) signs. */ #[Pure] function urlencode(string $string): string {} /** * Decodes URL-encoded string * @link https://php.net/manual/en/function.urldecode.php * @param string $string

    * The string to be decoded. *

    * @return string the decoded string. */ #[Pure] function urldecode(string $string): string {} /** * URL-encode according to RFC 3986 * @link https://php.net/manual/en/function.rawurlencode.php * @param string $string

    * The URL to be encoded. *

    * @return string a string in which all non-alphanumeric characters except * -_. have been replaced with a percent * (%) sign followed by two hex digits. This is the * encoding described in RFC 1738 for * protecting literal characters from being interpreted as special URL * delimiters, and for protecting URLs from being mangled by transmission * media with character conversions (like some email systems). */ #[Pure] function rawurlencode(string $string): string {} /** * Decode URL-encoded strings * @link https://php.net/manual/en/function.rawurldecode.php * @param string $string

    * The URL to be decoded. *

    * @return string the decoded URL, as a string. */ #[Pure] function rawurldecode(string $string): string {} /** * Generate URL-encoded query string * @link https://php.net/manual/en/function.http-build-query.php * @param object|array $data

    * May be an array or object containing properties. *

    *

    * If query_data is an array, it may be a simple one-dimensional structure, * or an array of arrays (which in turn may contain other arrays). *

    *

    * If query_data is an object, then only public properties will be incorporated into the result. *

    * @param string $numeric_prefix [optional]

    * If numeric indices are used in the base array and this parameter is * provided, it will be prepended to the numeric index for elements in * the base array only. *

    *

    * This is meant to allow for legal variable names when the data is * decoded by PHP or another CGI application later on. *

    * @param string|null $arg_separator

    * arg_separator.output * is used to separate arguments, unless this parameter is specified, * and is then used. *

    * @param int $encoding_type By default, PHP_QUERY_RFC1738. *

    If enc_type is PHP_QUERY_RFC1738, then encoding is performed per » RFC 1738 and the application/x-www-form-urlencoded media type, * which implies that spaces are encoded as plus (+) signs. *

    If enc_type is PHP_QUERY_RFC3986, then encoding is performed according to » RFC 3986, and spaces will be percent encoded (%20). * @return string a URL-encoded string. */ #[Pure] function http_build_query(object|array $data, string $numeric_prefix = "", ?string $arg_separator = null, int $encoding_type = PHP_QUERY_RFC1738): string {} /** * Returns the target of a symbolic link * @link https://php.net/manual/en/function.readlink.php * @param string $path

    * The symbolic link path. *

    * @return string|false the contents of the symbolic link path or false on error. */ #[Pure(true)] function readlink(string $path): string|false {} /** * Gets information about a link * @link https://php.net/manual/en/function.linkinfo.php * @param string $path

    * Path to the link. *

    * @return int|false linkinfo returns the st_dev field * of the Unix C stat structure returned by the lstat * system call. Returns 0 or false in case of error. */ #[Pure(true)] function linkinfo(string $path): int|false {} /** * Creates a symbolic link * @link https://php.net/manual/en/function.symlink.php * @param string $target

    * Target of the link. *

    * @param string $link

    * The link name. *

    * @return bool true on success or false on failure. */ function symlink(string $target, string $link): bool {} /** * Create a hard link * @link https://php.net/manual/en/function.link.php * @param string $target Target of the link. * @param string $link The link name. * @return bool true on success or false on failure. */ function link(string $target, string $link): bool {} /** * Deletes a file * @link https://php.net/manual/en/function.unlink.php * @param string $filename

    * Path to the file. *

    * @param resource $context [optional] * @return bool true on success or false on failure. */ function unlink(string $filename, $context): bool {} /** * Execute an external program * @link https://php.net/manual/en/function.exec.php * @param string $command

    * The command that will be executed. *

    * @param array &$output [optional]

    * If the output argument is present, then the * specified array will be filled with every line of output from the * command. Trailing whitespace, such as \n, is not * included in this array. Note that if the array already contains some * elements, exec will append to the end of the array. * If you do not want the function to append elements, call * unset on the array before passing it to * exec. *

    * @param int &$result_code [optional]

    * If the result_code argument is present * along with the output argument, then the * return status of the executed command will be written to this * variable. *

    * @return string|false The last line from the result of the command. If you need to execute a * command and have all the data from the command passed directly back without * any interference, use the passthru function. *

    *

    * To get the output of the executed command, be sure to set and use the * output parameter. */ function exec(string $command, &$output, &$result_code): string|false {} /** * Execute an external program and display the output * @link https://php.net/manual/en/function.system.php * @param string $command

    * The command that will be executed. *

    * @param int &$result_code [optional]

    * If the result_code argument is present, then the * return status of the executed command will be written to this * variable. *

    * @return string|false the last line of the command output on success, and false * on failure. */ function system(string $command, &$result_code): string|false {} /** * Escape shell metacharacters * @link https://php.net/manual/en/function.escapeshellcmd.php * @param string $command

    * The command that will be escaped. *

    * @return string The escaped string. */ #[Pure] function escapeshellcmd(string $command): string {} /** * Escape a string to be used as a shell argument * @link https://php.net/manual/en/function.escapeshellarg.php * @param string $arg

    * The argument that will be escaped. *

    * @return string The escaped string. */ #[Pure] function escapeshellarg(string $arg): string {} /** * Execute an external program and display raw output * @link https://php.net/manual/en/function.passthru.php * @param string $command

    * The command that will be executed. *

    * @param int &$result_code [optional]

    * If the result_code argument is present, the * return status of the Unix command will be placed here. *

    * @return bool|null null on success or false on failure. */ #[LanguageLevelTypeAware(['8.2' => 'null|false'], default: 'null|bool')] function passthru(string $command, &$result_code): ?bool {} /** * Execute command via shell and return the complete output as a string * @link https://php.net/manual/en/function.shell-exec.php * @param string $command

    * The command that will be executed. *

    * @return string|false|null The output from the executed command or NULL if an error occurred or the command produces no output. */ function shell_exec(string $command): string|false|null {} /** * Execute a command and open file pointers for input/output * @link https://php.net/manual/en/function.proc-open.php * @param array|string $command

    * Execute a command and open file pointers for input/output *

    *

    * As of PHP 7.4.0, cmd may be passed as array of command parameters. * In this case the process will be opened directly * (without going through a shell) and PHP will take care of any * necessary argument escaping. *

    * @param array $descriptor_spec

    * An indexed array where the key represents the descriptor number and the * value represents how PHP will pass that descriptor to the child * process. 0 is stdin, 1 is stdout, while 2 is stderr. *

    *

    * Each element can be: * An array describing the pipe to pass to the process. The first * element is the descriptor type and the second element is an option for * the given type. Valid types are pipe (the second * element is either r to pass the read end of the pipe * to the process, or w to pass the write end) and * file (the second element is a filename). * A stream resource representing a real file descriptor (e.g. opened file, * a socket, STDIN). *

    *

    * The file descriptor numbers are not limited to 0, 1 and 2 - you may * specify any valid file descriptor number and it will be passed to the * child process. This allows your script to interoperate with other * scripts that run as "co-processes". In particular, this is useful for * passing passphrases to programs like PGP, GPG and openssl in a more * secure manner. It is also useful for reading status information * provided by those programs on auxiliary file descriptors. *

    * @param array &$pipes

    * Will be set to an indexed array of file pointers that correspond to * PHP's end of any pipes that are created. *

    * @param string|null $cwd [optional]

    * The initial working dir for the command. This must be an * absolute directory path, or null * if you want to use the default value (the working dir of the current * PHP process) *

    * @param array|null $env_vars [optional]

    * An array with the environment variables for the command that will be * run, or null to use the same environment as the current PHP process *

    * @param array|null $options [optional]

    * Allows you to specify additional options. Currently supported options * include: * suppress_errors (windows only): suppresses errors generated by this * function when it's set to TRUE * generated by this function when it's set to true * bypass_shell (windows only): bypass cmd.exe shell when set to TRUE * context: stream context used when opening files * (created with stream_context_create) * blocking_pipes: (windows only): force blocking pipes when set to TRUE * create_process_group (windows only): allow the child process to handle * CTRL events when set to TRUE * create_new_console (windows only): the new process has a new console, * instead of inheriting its parent's console *

    * @return resource|false a resource representing the process, which should be freed using * proc_close when you are finished with it. On failure * returns false. */ function proc_open(array|string $command, array $descriptor_spec, &$pipes, ?string $cwd, ?array $env_vars, ?array $options) {} /** * Close a process opened by {@see proc_open} and return the exit code of that process * @link https://php.net/manual/en/function.proc-close.php * @param resource $process

    * The proc_open resource that will * be closed. *

    * @return int the termination status of the process that was run. */ function proc_close($process): int {} /** * Kills a process opened by proc_open * @link https://php.net/manual/en/function.proc-terminate.php * @param resource $process

    * The proc_open resource that will * be closed. *

    * @param int $signal [optional]

    * This optional parameter is only useful on POSIX * operating systems; you may specify a signal to send to the process * using the kill(2) system call. The default is * SIGTERM. *

    * @return bool the termination status of the process that was run. */ function proc_terminate($process, int $signal = 15): bool {} /** * Get information about a process opened by {@see proc_open} * @link https://php.net/manual/en/function.proc-get-status.php * @param resource $process

    * The proc_open resource that will * be evaluated. *

    * @return array|false An array of collected information on success, and false * on failure. The returned array contains the following elements: *

    *

    * elementtypedescription * * command * string * * The command string that was passed to proc_open. * * * * pid * int * process id * * * running * bool * * true if the process is still running, false if it has * terminated. * * * * signaled * bool * * true if the child process has been terminated by * an uncaught signal. Always set to false on Windows. * * * * stopped * bool * * true if the child process has been stopped by a * signal. Always set to false on Windows. * * * * exitcode * int * * The exit code returned by the process (which is only * meaningful if running is false). * Only first call of this function return real value, next calls return * -1. * * * * termsig * int * * The number of the signal that caused the child process to terminate * its execution (only meaningful if signaled is true). * * * * stopsig * int * * The number of the signal that caused the child process to stop its * execution (only meaningful if stopped is true). * * */ #[ArrayShape(["command" => "string", "pid" => "int", "running" => "bool", "signaled" => "bool", "stopped" => "bool", "exitcode" => "int", "termsig" => "int", "stopsig" => "int"])] #[LanguageLevelTypeAware(["8.0" => "array"], default: "array|false")] function proc_get_status($process) {} /** * Change the priority of the current process.
    * Since 7.2.0 supported on Windows platforms. * @link https://php.net/manual/en/function.proc-nice.php * @param int $priority

    * The increment value of the priority change. *

    * @return bool true on success or false on failure. * If an error occurs, like the user lacks permission to change the priority, * an error of level E_WARNING is also generated. */ function proc_nice(int $priority): bool {} /** * Get port number associated with an Internet service and protocol * @link https://php.net/manual/en/function.getservbyname.php * @param string $service

    * The Internet service name, as a string. *

    * @param string $protocol

    * protocol is either "tcp" * or "udp" (in lowercase). *

    * @return int|false the port number, or false if service or * protocol is not found. */ #[Pure] function getservbyname(string $service, string $protocol): int|false {} /** * Get Internet service which corresponds to port and protocol * @link https://php.net/manual/en/function.getservbyport.php * @param int $port

    * The port number. *

    * @param string $protocol

    * protocol is either "tcp" * or "udp" (in lowercase). *

    * @return string|false the Internet service name as a string. */ #[Pure] function getservbyport(int $port, string $protocol): string|false {} /** * Get protocol number associated with protocol name * @link https://php.net/manual/en/function.getprotobyname.php * @param string $protocol

    * The protocol name. *

    * @return int|false the protocol number or -1 if the protocol is not found. */ #[Pure] function getprotobyname(string $protocol): int|false {} /** * Get protocol name associated with protocol number * @link https://php.net/manual/en/function.getprotobynumber.php * @param int $protocol

    * The protocol number. *

    * @return string|false the protocol name as a string. */ #[Pure] function getprotobynumber(int $protocol): string|false {} /** * Gets PHP script owner's UID * @link https://php.net/manual/en/function.getmyuid.php * @return int|false the user ID of the current script, or false on error. */ #[Pure] function getmyuid(): int|false {} /** * Get PHP script owner's GID * @link https://php.net/manual/en/function.getmygid.php * @return int|false the group ID of the current script, or false on error. */ #[Pure] function getmygid(): int|false {} /** * Gets PHP's process ID * @link https://php.net/manual/en/function.getmypid.php * @return int|false the current PHP process ID, or false on error. */ #[Pure] function getmypid(): int|false {} /** * Gets the inode of the current script * @link https://php.net/manual/en/function.getmyinode.php * @return int|false the current script's inode as an integer, or false on error. */ #[Pure] function getmyinode(): int|false {} * The array in which elements are replaced. *

    * @param array ...$replacements

    * The array from which elements will be extracted. *

    * @return array or null if an error occurs. */ #[Pure] function array_replace( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.0')] $replacements, array ...$replacements ): array {} /** * Replaces elements from passed arrays into the first array recursively * @link https://php.net/manual/en/function.array-replace-recursive.php * @param array $array

    * The array in which elements are replaced. *

    * @param array ...$replacements

    * The array from which elements will be extracted. *

    * @return array an array, or null if an error occurs. */ #[Pure] function array_replace_recursive( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.0')] $replacements, array ...$replacements ): array {} /** * Return all the keys or a subset of the keys of an array * @link https://php.net/manual/en/function.array-keys.php * @param array $array

    * An array containing keys to return. *

    * @param mixed $filter_value [optional]

    * If specified, then only keys containing these values are returned. *

    * @param bool $strict [optional]

    * Determines if strict comparison (===) should be used during the search. *

    * @return int[]|string[] an array of all the keys in input. */ #[Pure] function array_keys(array $array, mixed $filter_value, bool $strict = false): array {} /** * Return all the values of an array * @link https://php.net/manual/en/function.array-values.php * @param array $array

    * The array. *

    * @return array an indexed array of values. * @meta */ #[Pure] function array_values(array $array): array {} /** * Counts all the values of an array * @link https://php.net/manual/en/function.array-count-values.php * @param array $array

    * The array of values to count *

    * @return array an associative array of values from input as * keys and their count as value. */ #[Pure] function array_count_values(array $array): array {} /** * Return the values from a single column in the input array * @link https://secure.php.net/manual/en/function.array-column.php * @param array $array

    A multi-dimensional array (record set) from which to pull a column of values.

    * @param string|int|null $column_key

    The column of values to return. This value may be the integer key of the column you wish to retrieve, or it may be the string key name for an associative array. It may also be NULL to return complete arrays (useful together with index_key to reindex the array).

    * @param string|int|null $index_key [optional]

    The column to use as the index/keys for the returned array. This value may be the integer key of the column, or it may be the string key name.

    * @return array Returns an array of values representing a single column from the input array. * @since 5.5 */ #[Pure] function array_column(array $array, string|int|null $column_key, string|int|null $index_key = null): array {} /** * Return an array with elements in reverse order * @link https://php.net/manual/en/function.array-reverse.php * @param array $array

    * The input array. *

    * @param bool $preserve_keys [optional]

    * If set to true keys are preserved. *

    * @return array the reversed array. * @meta */ #[Pure] function array_reverse(array $array, bool $preserve_keys = false): array {} /** * Iteratively reduce the array to a single value using a callback function * @link https://php.net/manual/en/function.array-reduce.php * @param array $array

    * The input array. *

    * @param callable $callback

    * The callback function. Signature is

    callback ( mixed $carry , mixed $item ) : mixed
    *
    mixed $carry

    The return value of the previous iteration; on the first iteration it holds the value of $initial.

    *
    mixed $item

    Holds the current iteration value of the $input

    *

    * @param mixed $initial [optional]

    * If the optional initial is available, it will * be used at the beginning of the process, or as a final result in case * the array is empty. *

    * @return mixed the resulting value. *

    * If the array is empty and initial is not passed, * array_reduce returns null. *

    *
    *

    * Example use: *

    array_reduce(['2', '3', '4'], function($ax, $dx) { return $ax . ", {$dx}"; }, '1')  // Returns '1, 2, 3, 4'
    *
    array_reduce(['2', '3', '4'], function($ax, $dx) { return $ax + (int)$dx; }, 1)  // Returns 10
    *
    *

    * @meta */ function array_reduce(array $array, callable $callback, mixed $initial = null): mixed {} /** * Pad array to the specified length with a value * @link https://php.net/manual/en/function.array-pad.php * @param array $array

    * Initial array of values to pad. *

    * @param int $length

    * New size of the array. *

    * @param mixed $value

    * Value to pad if input is less than * pad_size. *

    * @return array a copy of the input padded to size specified * by pad_size with value * pad_value. If pad_size is * positive then the array is padded on the right, if it's negative then * on the left. If the absolute value of pad_size is less than or equal to * the length of the input then no padding takes place. */ #[Pure] function array_pad(array $array, int $length, mixed $value): array {} /** * Exchanges all keys with their associated values in an array * @link https://php.net/manual/en/function.array-flip.php * @param int[]|string[] $array

    * An array of key/value pairs to be flipped. *

    * @return int[]|string[] Returns the flipped array. */ #[Pure] function array_flip(array $array): array {} /** * Changes the case of all keys in an array * @link https://php.net/manual/en/function.array-change-key-case.php * @param array $array

    * The array to work on *

    * @param int $case

    * Either CASE_UPPER or * CASE_LOWER (default) *

    * @return array an array with its keys lower or uppercased * @meta */ #[Pure] function array_change_key_case(array $array, int $case = CASE_LOWER): array {} /** * Pick one or more random keys out of an array * @link https://php.net/manual/en/function.array-rand.php * @param array $array

    * The input array. *

    * @param int $num [optional]

    * Specifies how many entries you want to pick. *

    * @return int|string|array If you are picking only one entry, array_rand * returns the key for a random entry. Otherwise, it returns an array * of keys for the random entries. This is done so that you can pick * random keys as well as values out of the array. */ function array_rand(array $array, int $num = 1): array|string|int {} /** * Removes duplicate values from an array * @link https://php.net/manual/en/function.array-unique.php * @param array $array

    * The input array. *

    * @param int $flags [optional]

    * The optional second parameter sort_flags * may be used to modify the sorting behavior using these values: *

    *

    * Sorting type flags: *

      *
    • * SORT_REGULAR - compare items normally * (don't change types) *
    • *
    • * SORT_NUMERIC - compare items numerically *
    • *
    • * SORT_STRING - compare items as strings *
    • *
    • * SORT_LOCALE_STRING - compare items as strings, * based on the current locale *
    • *
    * @return array the filtered array. * @meta */ #[Pure] function array_unique(array $array, int $flags = SORT_STRING): array {} /** * Computes the intersection of arrays * @link https://php.net/manual/en/function.array-intersect.php * @param array $array

    * The array with main values to check. *

    * @param array ...$arrays arrays to compare values against. * @return array an array containing all the values of * array that are present in all the arguments. * Note that keys are preserved. * @meta */ #[Pure] function array_intersect(array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $arrays, array ...$arrays): array {} /** * Computes the intersection of arrays using keys for comparison * @link https://php.net/manual/en/function.array-intersect-key.php * @param array $array

    * The array with main keys to check. *

    * @param array ...$arrays * @return array an array containing all the entries of * array which have keys that are present in all the * arguments. * @meta */ #[Pure] function array_intersect_key(array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $arrays, array ...$arrays): array {} /** * Computes the intersection of arrays using a callback function on the keys for comparison * @link https://php.net/manual/en/function.array-intersect-ukey.php * @param array $array

    * Initial array for comparison of the arrays. *

    * @param array $array2

    * First array to compare keys against. *

    * @param callable $key_compare_func

    * User supplied callback function to do the comparison. *

    * @param ...$rest [optional] * @return array an array containing all the values of * array which have matching keys that are present * in all the arguments. * @meta */ function array_intersect_ukey( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] array $array2, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] callable $key_compare_func, #[PhpStormStubsElementAvailable(from: '8.0')] ...$rest ): array {} /** * Computes the intersection of arrays, compares data by a callback function * @link https://php.net/manual/en/function.array-uintersect.php * @param array $array

    * The first array. *

    * @param array $array2

    * The second array. *

    * @param callable $data_compare_func

    * The callback comparison function. *

    * @param array ...$rest *

    * The user supplied callback function is used for comparison. * It must return an integer less than, equal to, or greater than zero if * the first argument is considered to be respectively less than, equal * to, or greater than the second. *

    * @return array an array containing all the values of array * that are present in all the arguments. * @meta */ function array_uintersect( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] array $array2, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] callable $data_compare_func, #[PhpStormStubsElementAvailable(from: '8.0')] ...$rest ): array {} /** * Computes the intersection of arrays with additional index check * @link https://php.net/manual/en/function.array-intersect-assoc.php * @param array $array

    * The array with main values to check. *

    * @param array $arrays * @return array an associative array containing all the values in * array that are present in all of the arguments. * @meta */ #[Pure] function array_intersect_assoc(array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $arrays, array ...$arrays): array {} /** * Computes the intersection of arrays with additional index check, compares data by a callback function * @link https://php.net/manual/en/function.array-uintersect-assoc.php * @param array $array

    * The first array. *

    * @param array $array2

    * The second array. *

    * @param callable $data_compare_func

    * For comparison is used the user supplied callback function. * It must return an integer less than, equal * to, or greater than zero if the first argument is considered to * be respectively less than, equal to, or greater than the * second. *

    * @param array ...$rest * @return array an array containing all the values of * array that are present in all the arguments. * @meta */ function array_uintersect_assoc( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] array $array2, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] callable $data_compare_func, #[PhpStormStubsElementAvailable(from: '8.0')] ...$rest ): array {} /** * Computes the intersection of arrays with additional index check, compares indexes by a callback function * @link https://php.net/manual/en/function.array-intersect-uassoc.php * @param array $array

    * Initial array for comparison of the arrays. *

    * @param array $array2

    * First array to compare keys against. *

    * @param callable $key_compare_func

    * User supplied callback function to do the comparison. *

    * @param array ...$rest * @return array the values of array whose values exist in all of the arguments. * @meta */ function array_intersect_uassoc( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] array $array2, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] callable $key_compare_func, #[PhpStormStubsElementAvailable(from: '8.0')] ...$rest ): array {} /** * Computes the intersection of arrays with additional index check, compares data and indexes by separate callback functions * @link https://php.net/manual/en/function.array-uintersect-uassoc.php * @param array $array

    * The first array. *

    * @param array $array2

    * The second array. *

    * @param callable $data_compare_func

    * For comparison is used the user supplied callback function. * It must return an integer less than, equal * to, or greater than zero if the first argument is considered to * be respectively less than, equal to, or greater than the * second. *

    * @param callable $key_compare_func

    * Key comparison callback function. *

    * @param array ...$rest * @return array an array containing all the values and keys of * array1 that are present in all the arguments. * @meta */ #[Pure] function array_uintersect_uassoc( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] array $array2, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] callable $data_compare_func, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] callable $key_compare_func, #[PhpStormStubsElementAvailable(from: '8.0')] ...$rest ): array {} /** * Computes the difference of arrays * @link https://php.net/manual/en/function.array-diff.php * @param array $array

    * The array to compare from *

    * @param array ...$arrays * @return array an array containing all the entries from * array that are not present in any of the other * arrays. Keys in the array array are preserved. * @meta */ #[Pure] function array_diff(array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $arrays, array ...$arrays): array {} /** * Computes the difference of arrays using keys for comparison * @link https://php.net/manual/en/function.array-diff-key.php * @param array $array

    * The array to compare from *

    * @param array $arrays

    * An array to compare against *

    * @return array an array containing all the entries from * array whose keys are absent from all of the other arrays. * @meta */ #[Pure] function array_diff_key(array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $arrays, array ...$arrays): array {} /** * Computes the difference of arrays using a callback function on the keys for comparison * @link https://php.net/manual/en/function.array-diff-ukey.php * @param array $array

    * The array to compare from *

    * @param array $array2

    * An array to compare against *

    * @param callable $key_compare_func

    * callback function to use. * The callback function must return an integer less than, equal * to, or greater than zero if the first argument is considered to * be respectively less than, equal to, or greater than the second. *

    * @param array ...$rest [optional] * @return array an array containing all the entries from * array that are not present in any of the other arrays. * @meta */ function array_diff_ukey( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] array $array2, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] callable $key_compare_func, #[PhpStormStubsElementAvailable(from: '8.0')] ...$rest, ): array {} /** * Computes the difference of arrays by using a callback function for data comparison * @link https://php.net/manual/en/function.array-udiff.php * @param array $array

    * The first array. *

    * @param array $array2

    * The second array. *

    * @param callable $data_compare_func

    * The callback comparison function. *

    *

    * The user supplied callback function is used for comparison. * It must return an integer less than, equal to, or greater than zero if * the first argument is considered to be respectively less than, equal * to, or greater than the second. *

    * @param array ...$rest [optional] * @return array an array containing all the values of * array that are not present in any of the other arguments. * @meta */ function array_udiff( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] array $array2, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] callable $data_compare_func, #[PhpStormStubsElementAvailable(from: '8.0')] ...$rest, ): array {} /** * Computes the difference of arrays with additional index check * @link https://php.net/manual/en/function.array-diff-assoc.php * @param array $array

    * The array to compare from *

    * @param array $arrays

    * An array to compare against *

    * @return array an array containing all the values from * array that are not present in any of the other arrays. * @meta */ #[Pure] function array_diff_assoc( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $arrays, array ...$arrays ): array {} /** * Computes the difference of arrays with additional index check, compares data by a callback function * @link https://php.net/manual/en/function.array-udiff-assoc.php * @param array $array

    * The first array. *

    * @param array $array2

    * The second array. *

    * @param callable $data_compare_func

    * The callback comparison function. *

    *

    * The user supplied callback function is used for comparison. * It must return an integer less than, equal to, or greater than zero if * the first argument is considered to be respectively less than, equal * to, or greater than the second. *

    * @param array ...$rest [optional] * @return array returns an array containing all the values from array * that are not present in any of the other arguments. * Note that the keys are used in the comparison unlike * array_diff and array_udiff. * The comparison of arrays' data is performed by using an user-supplied * callback. In this aspect the behaviour is opposite to the behaviour of * array_diff_assoc which uses internal function for * comparison. * @meta */ function array_udiff_assoc( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] array $array2, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] callable $data_compare_func, #[PhpStormStubsElementAvailable(from: '8.0')] ...$rest, ): array {} /** * Computes the difference of arrays with additional index check which is performed by a user supplied callback function * @link https://php.net/manual/en/function.array-diff-uassoc.php * @param array $array

    * The array to compare from *

    * @param array $array2

    * An array to compare against *

    * @param callable $key_compare_func

    * callback function to use. * The callback function must return an integer less than, equal * to, or greater than zero if the first argument is considered to * be respectively less than, equal to, or greater than the second. *

    * @param array ...$rest [optional] * @return array an array containing all the values and keys from * array that are not present in any of the other arrays. * @meta */ function array_diff_uassoc( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] array $array2, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] callable $key_compare_func, #[PhpStormStubsElementAvailable(from: '8.0')] ...$rest, ): array {} /** * Computes the difference of arrays with additional index check, compares data and indexes by a callback function * @link https://php.net/manual/en/function.array-udiff-uassoc.php * @param array $array

    * The first array. *

    * @param array $array2

    * The second array. *

    * @param callable $data_compare_func

    * The callback comparison function. *

    *

    * The user supplied callback function is used for comparison. * It must return an integer less than, equal to, or greater than zero if * the first argument is considered to be respectively less than, equal * to, or greater than the second. *

    *

    * The comparison of arrays' data is performed by using an user-supplied * callback : data_compare_func. In this aspect * the behaviour is opposite to the behaviour of * array_diff_assoc which uses internal function for * comparison. *

    * @param callable $key_compare_func

    * The comparison of keys (indices) is done also by the callback function * key_compare_func. This behaviour is unlike what * array_udiff_assoc does, since the latter compares * the indices by using an internal function. *

    * @param array ...$rest [optional] * @return array an array containing all the values and keys from * array that are not present in any of the other * arguments. * @meta */ function array_udiff_uassoc( array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] array $array2, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] callable $data_compare_func, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] callable $key_compare_func, #[PhpStormStubsElementAvailable(from: '8.0')] ...$rest ): array {} /** * Calculate the sum of values in an array * @link https://php.net/manual/en/function.array-sum.php * @param array $array

    * The input array. *

    * @return int|float the sum of values as an integer or float. */ #[Pure] function array_sum(array $array): int|float {} /** * Calculate the product of values in an array * @link https://php.net/manual/en/function.array-product.php * @param array $array

    * The array. *

    * @return int|float the product as an integer or float. */ #[Pure] function array_product(array $array): int|float {} /** * Iterates over each value in the array * passing them to the callback function. * If the callback function returns true, the * current value from array is returned into * the result array. Array keys are preserved. * @link https://php.net/manual/en/function.array-filter.php * @param array $array

    * The array to iterate over *

    * @param callable|null $callback [optional]

    * The callback function to use *

    *

    * If no callback is supplied, all entries of * input equal to false (see * converting to * boolean) will be removed. *

    * @param int $mode [optional]

    * Flag determining what arguments are sent to callback: *

      *
    • * ARRAY_FILTER_USE_KEY - pass key as the only argument * to callback instead of the value *
    • *
    • * ARRAY_FILTER_USE_BOTH - pass both value and key as * arguments to callback instead of the value *
    • *
    * @return array the filtered array. * @meta */ function array_filter(array $array, ?callable $callback, int $mode = 0): array {} /** * Applies the callback to the elements of the given arrays * @link https://php.net/manual/en/function.array-map.php * @param callable|null $callback

    * Callback function to run for each element in each array. *

    * @param array $array

    * An array to run through the callback function. *

    * @param array ...$arrays * @return array an array containing all the elements of arr1 * after applying the callback function to each one. * @meta */ function array_map( ?callable $callback, #[PhpStormStubsElementAvailable(from: '8.0')] array $array, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $arrays, array ...$arrays ): array {} /** * Split an array into chunks * @link https://php.net/manual/en/function.array-chunk.php * @param array $array

    * The array to work on *

    * @param int $length

    * The size of each chunk *

    * @param bool $preserve_keys [optional]

    * When set to true keys will be preserved. * Default is false which will reindex the chunk numerically *

    * @return array a multidimensional numerically indexed array, starting with zero, * with each dimension containing size elements. */ #[Pure] function array_chunk(array $array, int $length, bool $preserve_keys = false): array {} /** * Creates an array by using one array for keys and another for its values * @link https://php.net/manual/en/function.array-combine.php * @param array $keys

    * Array of keys to be used. Illegal values for key will be * converted to string. *

    * @param array $values

    * Array of values to be used *

    * @return array|false the combined array, false if the number of elements * for each array isn't equal or if the arrays are empty. * @meta */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "array"], default: "array|false")] function array_combine(array $keys, array $values) {} /** * Checks if the given key or index exists in the array * @link https://php.net/manual/en/function.array-key-exists.php * @param int|string $key

    * Value to check. *

    * @param array|ArrayObject $array

    * An array with keys to check. *

    * @return bool true on success or false on failure. */ #[Pure] function array_key_exists($key, #[LanguageLevelTypeAware(["8.0" => "array"], default: "array|ArrayObject")] $array): bool {} /** * Gets the first key of an array * * Get the first key of the given array without affecting the internal array pointer. * * @link https://secure.php.net/array_key_first * @param array $array An array * @return string|int|null Returns the first key of array if the array is not empty; NULL otherwise. * @since 7.3 */ #[Pure] function array_key_first(array $array): string|int|null {} /** * Gets the last key of an array * * Get the last key of the given array without affecting the internal array pointer. * * @link https://secure.php.net/array_key_last * @param array $array An array * @return string|int|null Returns the last key of array if the array is not empty; NULL otherwise. * @since 7.3 */ #[Pure] function array_key_last(array $array): string|int|null {} /** * @link https://secure.php.net/array_is_list * @param array $array An array * @return bool return true if the array keys are 0 .. count($array)-1 in that order. * For other arrays, it returns false. For non-arrays, it throws a TypeError. * @since 8.1 */ #[Pure] function array_is_list(array $array): bool {} /** * Alias: * {@see current} * @link https://php.net/manual/en/function.pos.php * @param array|ArrayAccess $array * @return mixed */ #[Pure] function pos(object|array $array): mixed {} /** * Alias: * {@see \count} * @link https://php.net/manual/en/function.sizeof.php * @param array|Countable $value * @param int $mode [optional] * @return int<0, max> */ #[Pure] function sizeof(Countable|array $value, int $mode = COUNT_NORMAL): int {} /** * Checks if the given key or index exists in the array. The name of this function is array_key_exists() in PHP > 4.0.6. * @link https://php.net/manual/en/function.array-key-exists.php * @param int|string $key

    * Value to check. *

    * @param array $array

    * An array with keys to check. *

    * @return bool true on success or false on failure. */ #[Pure] function key_exists($key, array $array): bool {} /** * Checks if assertion is FALSE * @link https://php.net/manual/en/function.assert.php * @param Throwable|string|null $assertion

    * The assertion. * In PHP 5, this must be either a string to be evaluated or a boolean to be tested. * In PHP 7, this may also be any expression that returns a value, * which will be executed and the result used to indicate whether the assertion succeeded or failed.
    * Since 7.2.0 using string is deprecated. *

    * @param string $description [optional] *

    An optional description that will be included in the failure message if the assertion fails.

    * @return bool false if the assertion is false, true otherwise. */ function assert( mixed $assertion, #[PhpStormStubsElementAvailable(from: '7.0')] #[LanguageLevelTypeAware(['7.0' => 'Throwable|string|null'], default: 'string')] $description = null ): bool {} /** * AssertionError is thrown when an assertion made via {@see assert()} fails. * @link https://php.net/manual/en/class.assertionerror.php * @since 7.0 */ class AssertionError extends Error {} /** * Set/get the various assert flags * @link https://php.net/manual/en/function.assert-options.php * @param int $option

    *

    * Assert Options * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    OptionINI SettingDefault valueDescription
    ASSERT_ACTIVEassert.active1enable assert evaluation
    ASSERT_WARNINGassert.warning1issue a PHP warning for each failed assertion
    ASSERT_BAILassert.bail0terminate execution on failed assertions
    ASSERT_QUIET_EVALassert.quiet_eval0 * disable error_reporting during assertion expression * evaluation *
    ASSERT_CALLBACKassert.callbacknullCallback to call on failed assertions
    *

    * @param mixed $value [optional]

    * An optional new value for the option. *

    * @return mixed The original setting of any option. */ #[Deprecated(since: "8.3")] function assert_options(int $option, mixed $value): mixed {} /** * Compares two "PHP-standardized" version number strings * @link https://php.net/manual/en/function.version-compare.php * @param string $version1

    * First version number. *

    * @param string $version2

    * Second version number. *

    * @param string|null $operator [optional]

    * If you specify the third optional operator * argument, you can test for a particular relationship. The * possible operators are: <, * lt, <=, * le, >, * gt, >=, * ge, ==, * =, eq, * !=, <>, * ne respectively. *

    *

    * This parameter is case-sensitive, so values should be lowercase. *

    * @return int|bool By default, version_compare returns * -1 if the first version is lower than the second, * 0 if they are equal, and * 1 if the second is lower. *

    *

    * When using the optional operator argument, the * function will return true if the relationship is the one specified * by the operator, false otherwise. */ #[ExpectedValues([-1, 0, 1, false, true])] function version_compare( string $version1, string $version2, #[ExpectedValues(values: [ "<", "lt", "<=", "le", ">", "gt", ">=", "ge", "==", "=", "eq", "!=", "<>", "ne" ])] ?string $operator ): int|bool {} /** * Convert a pathname and a project identifier to a System V IPC key * @link https://php.net/manual/en/function.ftok.php * @param string $filename

    * Path to an accessible file. *

    * @param string $project_id

    * Project identifier. This must be a one character string. *

    * @return int On success the return value will be the created key value, otherwise * -1 is returned. */ #[Pure(true)] function ftok(string $filename, string $project_id): int {} /** * Perform the rot13 transform on a string * @link https://php.net/manual/en/function.str-rot13.php * @param string $string

    * The input string. *

    * @return string the ROT13 version of the given string. */ #[Pure] function str_rot13(string $string): string {} /** * Retrieve list of registered filters * @link https://php.net/manual/en/function.stream-get-filters.php * @return list an indexed array containing the name of all stream filters * available. */ #[Pure(true)] function stream_get_filters(): array {} /** * Check if a stream is a TTY * @link https://php.net/manual/en/function.stream-isatty.php * @param resource $stream * @return bool * @since 7.2 */ #[Pure] function stream_isatty($stream): bool {} /** * Register a user defined stream filter * @link https://php.net/manual/en/function.stream-filter-register.php * @param string $filter_name

    * The filter name to be registered. *

    * @param string $class

    * To implement a filter, you need to define a class as an extension of * php_user_filter with a number of member functions * as defined below. When performing read/write operations on the stream * to which your filter is attached, PHP will pass the data through your * filter (and any other filters attached to that stream) so that the * data may be modified as desired. You must implement the methods * exactly as described below - doing otherwise will lead to undefined * behaviour. *

    * intfilter * resourcein * resourceout * intconsumed * boolclosing *

    * This method is called whenever data is read from or written to * the attached stream (such as with fread or fwrite). * in is a resource pointing to a bucket brigade * which contains one or more bucket objects containing data to be filtered. * out is a resource pointing to a second bucket brigade * into which your modified buckets should be placed. * consumed, which must always * be declared by reference, should be incremented by the length of the data * which your filter reads in and alters. In most cases this means you will * increment consumed by $bucket->datalen * for each $bucket. If the stream is in the process of closing * (and therefore this is the last pass through the filterchain), * the closing parameter will be set to true. * The filter method must return one of * three values upon completion. * * Return Value * Meaning * * * PSFS_PASS_ON * * Filter processed successfully with data available in the * out bucket brigade. * * * * PSFS_FEED_ME * * Filter processed successfully, however no data was available to * return. More data is required from the stream or prior filter. * * * * PSFS_ERR_FATAL (default) * * The filter experienced an unrecoverable error and cannot continue. * * *

    * boolonCreate * This method is called during instantiation of the filter class * object. If your filter allocates or initializes any other resources * (such as a buffer), this is the place to do it. Your implementation of * this method should return false on failure, or true on success. * When your filter is first instantiated, and * yourfilter->onCreate() is called, a number of properties * will be available as shown in the table below. *

    * * Property * Contents * * * FilterClass->filtername * * A string containing the name the filter was instantiated with. * Filters may be registered under multiple names or under wildcards. * Use this property to determine which name was used. * * * * FilterClass->params * * The contents of the params parameter passed * to stream_filter_append * or stream_filter_prepend. * * * * FilterClass->stream * * The stream resource being filtered. Maybe available only during * filter calls when the * closing parameter is set to false. * * *

    * voidonClose *

    * This method is called upon filter shutdown (typically, this is also * during stream shutdown), and is executed after * the flush method is called. If any resources * were allocated or initialized during onCreate() * this would be the time to destroy or dispose of them. *

    * @return bool true on success or false on failure. *

    * stream_filter_register will return false if the * filtername is already defined. *

    */ function stream_filter_register(string $filter_name, string $class): bool {} /** * Return a bucket object from the brigade for operating on * @link https://php.net/manual/en/function.stream-bucket-make-writeable.php * @param resource $brigade * @return object|null */ #[LanguageLevelTypeAware(["8.4" => "StreamBucket|null"], default: "object|null")] function stream_bucket_make_writeable($brigade) {} /** * Prepend bucket to brigade * @link https://php.net/manual/en/function.stream-bucket-prepend.php * @param resource $brigade * @param object $bucket * @return void */ function stream_bucket_prepend($brigade, #[LanguageLevelTypeAware(['8.4' => 'StreamBucket'], default: 'object')] $bucket): void {} /** * Append bucket to brigade * @link https://php.net/manual/en/function.stream-bucket-append.php * @param resource $brigade * @param object $bucket * @return void */ function stream_bucket_append($brigade, #[LanguageLevelTypeAware(['8.4' => 'StreamBucket'], default: 'object')] $bucket): void {} /** * Create a new bucket for use on the current stream * @link https://php.net/manual/en/function.stream-bucket-new.php * @param resource $stream * @param string $buffer * @return object */ #[LanguageLevelTypeAware(["8.4" => "StreamBucket"], default: "object")] function stream_bucket_new($stream, string $buffer) {} /** * Add URL rewriter values * @link https://php.net/manual/en/function.output-add-rewrite-var.php * @param string $name

    * The variable name. *

    * @param string $value

    * The variable value. *

    * @return bool true on success or false on failure. */ function output_add_rewrite_var(string $name, string $value): bool {} /** * Reset URL rewriter values * * * * * * * * * * * * * * * * * *
    VersionDescription
    7.1.0 * Before PHP 7.1.0, rewrite vars set by output_add_rewrite_var() * use the same Session module trans sid output buffer. Since PHP 7.1.0, * dedicated output buffer is used and {@see output_reset_rewrite_vars()} * only removes rewrite vars defined by {@see output_add_rewrite_var()}. *
    * * @link https://php.net/manual/en/function.output-reset-rewrite-vars.php * @return bool true on success or false on failure. */ function output_reset_rewrite_vars(): bool {} /** * Returns directory path used for temporary files * @link https://php.net/manual/en/function.sys-get-temp-dir.php * @return string the path of the temporary directory. * @since 5.2.1 */ function sys_get_temp_dir(): string {} /** * Get the contents of the realpath cache. * @link https://php.net/manual/en/function.realpath-cache-get.php * @return array Returns an array of realpath cache entries. The keys are * original path entries, and the values are arrays of data items, * containing the resolved path, expiration date, and other options kept in * the cache. * @since 5.3.2 */ #[Pure(true)] function realpath_cache_get(): array {} /** * Get the amount of memory used by the realpath cache. * @link https://php.net/manual/en/function.realpath-cache-size.php * @return int Returns how much memory realpath cache is using. * @since 5.3.2 */ #[Pure(true)] function realpath_cache_size(): int {} /** * It returns the same result as (array) $object, with the * exception that it ignores overloaded array casts, such as used by * ArrayObject. * @param object $object * @return array returns the mangled object properties * @since 7.4 */ function get_mangled_object_vars(object $object): array {} /** * Get the type or object name of a variable * * @param mixed $value The variable being type checked. * @return string Possibles values for the returned string are: * - "int" * - "float" * - "bool" * - "string" * - "array" * - "null" * - A class name for named classes * - "class@anonymous" for an anonymous classes * - "resource (xxx)" for any resources where "xxx" is a name of resource * - "resource (closed)" for closed resources * @since 8.0 */ #[Pure] function get_debug_type(mixed $value): string {} /** * A more obvious and type-safe form of "(int) $resource" * * @param resource $resource * @return int * @since 8.0 */ #[Pure] function get_resource_id($resource): int {} * If you have compiled in OpenSSL support, you may prefix the * hostname with either ssl:// * or tls:// to use an SSL or TLS client connection * over TCP/IP to connect to the remote host. *

    * @param int $port

    * The port number. *

    * @param int &$error_code [optional]

    * If provided, holds the system level error number that occurred in the * system-level connect() call. *

    *

    * If the value returned in errno is * 0 and the function returned false, it is an * indication that the error occurred before the * connect() call. This is most likely due to a * problem initializing the socket. *

    * @param string &$error_message [optional]

    * The error message as a string. *

    * @param float|null $timeout [optional]

    * The connection timeout, in seconds. *

    *

    * If you need to set a timeout for reading/writing data over the * socket, use stream_set_timeout, as the * timeout parameter to * fsockopen only applies while connecting the * socket. *

    * @return resource|false fsockopen returns a file pointer which may be used * together with the other file functions (such as * fgets, fgetss, * fwrite, fclose, and * feof). If the call fails, it will return false */ function fsockopen( string $hostname, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.0')] int $port, #[PhpStormStubsElementAvailable(from: '7.1')] int $port = -1, &$error_code, &$error_message, ?float $timeout ) {} /** * Open persistent Internet or Unix domain socket connection * @link https://php.net/manual/en/function.pfsockopen.php * @see fsockopen * @param string $hostname * @param int $port * @param int &$error_code [optional] * @param string &$error_message [optional] * @param float|null $timeout [optional] * @return resource|false */ function pfsockopen( string $hostname, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.0')] int $port, #[PhpStormStubsElementAvailable(from: '7.1')] int $port = -1, &$error_code, &$error_message, ?float $timeout ) {} /** * Pack data into binary string * @link https://php.net/manual/en/function.pack.php * @param string $format

    * The format string consists of format codes * followed by an optional repeater argument. The repeater argument can * be either an integer value or * for repeating to * the end of the input data. For a, A, h, H the repeat count specifies * how many characters of one data argument are taken, for @ it is the * absolute position where to put the next data, for everything else the * repeat count specifies how many data arguments are consumed and packed * into the resulting binary string. *

    *

    * Currently implemented formats are: *

    * pack format characters * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    CodeDescription
    aNUL-padded string
    ASPACE-padded string
    hHex string, low nibble first
    HHex string, high nibble first
    csigned char
    Cunsigned char
    ssigned short (always 16 bit, machine byte order)
    Sunsigned short (always 16 bit, machine byte order)
    nunsigned short (always 16 bit, big endian byte order)
    vunsigned short (always 16 bit, little endian byte order)
    isigned integer (machine dependent size and byte order)
    Iunsigned integer (machine dependent size and byte order)
    lsigned long (always 32 bit, machine byte order)
    Lunsigned long (always 32 bit, machine byte order)
    Nunsigned long (always 32 bit, big endian byte order)
    Vunsigned long (always 32 bit, little endian byte order)
    ffloat (machine dependent size and representation, both little and big endian)
    ddouble (machine dependent size and representation, both little and big endian)
    xNUL byte
    XBack up one byte
    @NUL-fill to absolute position
    *

    * @param mixed ...$values

    *

    * @return string|false a binary string containing data or false if the format string contains errors */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "string"], default: "string|false")] function pack( string $format, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.3')] $values, mixed ...$values ) {} /** * Unpack data from binary string * @link https://php.net/manual/en/function.unpack.php * @param string $format

    * See pack for an explanation of the format codes. *

    * @param string $string

    * The packed data. *

    * @param int $offset [optional] * @return array|false an associative array containing unpacked elements of binary * string or false if the format string contains errors */ #[Pure] function unpack( string $format, string $string, #[PhpStormStubsElementAvailable(from: '7.1')] int $offset = 0 ): array|false {} /** * Tells what the user's browser is capable of * @link https://php.net/manual/en/function.get-browser.php * @param string|null $user_agent [optional]

    * The User Agent to be analyzed. By default, the value of HTTP * User-Agent header is used; however, you can alter this (i.e., look up * another browser's info) by passing this parameter. *

    *

    * You can bypass this parameter with a null value. *

    * @param bool $return_array [optional]

    * If set to true, this function will return an array * instead of an object. *

    * @return array|object|false Returns false if browscap.ini can't be loaded or the user agent can't be found, otherwise the information is returned in an object or an array which will contain * various data elements representing, for instance, the browser's major and * minor version numbers and ID string; true/false values for features * such as frames, JavaScript, and cookies; and so forth. *

    *

    * The cookies value simply means that the browser * itself is capable of accepting cookies and does not mean the user has * enabled the browser to accept cookies or not. The only way to test if * cookies are accepted is to set one with setcookie, * reload, and check for the value. */ #[Pure(true)] function get_browser(?string $user_agent, bool $return_array = false): object|array|false {} /** * One-way string encryption (hashing) * @link https://php.net/manual/en/function.crypt.php * @param string $string

    * The string to be encrypted. *

    * @param string $salt

    * An optional salt string to base the encryption on. If not provided, * one will be randomly generated by PHP each time you call this function. * PHP 5.6 or later raise E_NOTICE error if this parameter is omitted *

    *

    * If you are using the supplied salt, you should be aware that the salt * is generated once. If you are calling this function repeatedly, this * may impact both appearance and security. *

    * @return string|null the encrypted string or NULL if an error occurs */ #[Pure] #[PhpStormStubsElementAvailable(to: '7.4')] function crypt($string, $salt): ?string {} /** * One-way string encryption (hashing) * @link https://php.net/manual/en/function.crypt.php * @param string $string

    * The string to be encrypted. *

    * @param string $salt

    * An optional salt string to base the encryption on. If not provided, * one will be randomly generated by PHP each time you call this function. * PHP 5.6 or later raise E_NOTICE error if this parameter is omitted *

    *

    * If you are using the supplied salt, you should be aware that the salt * is generated once. If you are calling this function repeatedly, this * may impact both appearance and security. *

    * @return string the encrypted string or NULL if an error occurs */ #[Pure] #[PhpStormStubsElementAvailable('8.0')] function crypt(string $string, string $salt): string {} /** * Open directory handle * @link https://php.net/manual/en/function.opendir.php * @param string $directory

    * The directory path that is to be opened *

    * @param resource $context [optional]

    * For a description of the context parameter, * refer to the streams section of * the manual. *

    * @return resource|false a directory handle resource on success, or * false on failure. *

    *

    * If path is not a valid directory or the * directory can not be opened due to permission restrictions or * filesystem errors, opendir returns false and * generates a PHP error of level * E_WARNING. You can suppress the error output of * opendir by prepending * '@' to the * front of the function name. */ function opendir(string $directory, $context) {} /** * Close directory handle * @link https://php.net/manual/en/function.closedir.php * @param resource $dir_handle [optional]

    * The directory handle resource previously opened * with opendir. If the directory handle is * not specified, the last link opened by opendir * is assumed. *

    * @return void */ function closedir($dir_handle): void {} /** * Change directory * @link https://php.net/manual/en/function.chdir.php * @param string $directory

    * The new current directory *

    * @return bool true on success or false on failure. */ function chdir(string $directory): bool {} /** * Change the root directory * @link https://php.net/manual/en/function.chroot.php * @param string $directory

    * The new directory *

    * @return bool true on success or false on failure. */ function chroot(string $directory): bool {} /** * Gets the current working directory * @link https://php.net/manual/en/function.getcwd.php * @return string|false

    * the current working directory on success, or false on * failure.
    *
    * On some Unix variants, getcwd will return * false if any one of the parent directories does not have the * readable or search mode set, even if the current directory * does. See chmod for more information on * modes and permissions. *

    */ #[Pure(true)] function getcwd(): string|false {} /** * Rewind directory handle * @link https://php.net/manual/en/function.rewinddir.php * @param resource $dir_handle [optional]

    * The directory handle resource previously opened * with opendir. If the directory handle is * not specified, the last link opened by opendir * is assumed. *

    * @see https://bugs.php.net/bug.php?id=75485 */ function rewinddir($dir_handle): void {} /** * Read entry from directory handle * @link https://php.net/manual/en/function.readdir.php * @param resource $dir_handle [optional]

    * The directory handle resource previously opened * with opendir. If the directory handle is * not specified, the last link opened by opendir * is assumed. *

    * @return string|false the filename on success or false on failure. */ function readdir($dir_handle): string|false {} /** * Return an instance of the Directory class * @link https://php.net/manual/en/function.dir.php * @param string $directory

    * Directory to open *

    * @param resource $context [optional] * @return Directory|false an instance of Directory, or NULL with wrong * parameters, or FALSE in case of another error */ function dir(string $directory, $context): Directory|false {} /** * Alias of dir() * @param string $directory * @param resource $context * @since 8.0 * @return Directory|false * @see dir() */ function getdir(string $directory, $context = null): Directory|false {} /** * List files and directories inside the specified path * @link https://php.net/manual/en/function.scandir.php * @param string $directory

    * The directory that will be scanned. *

    * @param int $sorting_order

    * By default, the sorted order is alphabetical in ascending order. If * the optional sorting_order is set to non-zero, * then the sort order is alphabetical in descending order. *

    * @param resource $context [optional]

    * For a description of the context parameter, * refer to the streams section of * the manual. *

    * @return array|false an array of filenames on success, or false on * failure. If directory is not a directory, then * boolean false is returned, and an error of level * E_WARNING is generated. */ function scandir(string $directory, int $sorting_order = 0, $context): array|false {} /** * Find pathnames matching a pattern * @link https://php.net/manual/en/function.glob.php * @param string $pattern

    * The pattern. No tilde expansion or parameter substitution is done. *

    * @param int $flags

    * Valid flags: * GLOB_MARK - Adds a slash to each directory returned * GLOB_NOSORT - Return files as they appear in the directory (no sorting). When this flag is not used, the pathnames are sorted alphabetically * GLOB_NOCHECK - Return the search pattern if no files matching it were found * GLOB_NOESCAPE - Backslashes do not quote metacharacters * GLOB_BRACE - Expands {a,b,c} to match 'a', 'b', or 'c' * GLOB_ONLYDIR - Return only directory entries which match the pattern * GLOB_ERR - Stop on read errors (like unreadable directories), by default errors are ignored. * @return array|false an array containing the matched files/directories, an empty array * if no file matched or false on error. *

    *

    * On some systems it is impossible to distinguish between empty match and an * error.

    */ #[Pure(true)] function glob(string $pattern, int $flags = 0): array|false {} /** * Gets last access time of file * @link https://php.net/manual/en/function.fileatime.php * @param string $filename

    * Path to the file. *

    * @return int|false the time the file was last accessed, or false on failure. * The time is returned as a Unix timestamp. */ #[Pure(true)] function fileatime(string $filename): int|false {} /** * Gets inode change time of file * @link https://php.net/manual/en/function.filectime.php * @param string $filename

    * Path to the file. *

    * @return int|false the time the file was last changed, or false on failure. * The time is returned as a Unix timestamp. */ #[Pure(true)] function filectime(string $filename): int|false {} /** * Gets file group * @link https://php.net/manual/en/function.filegroup.php * @param string $filename

    * Path to the file. *

    * @return int|false the group ID of the file, or false in case * of an error. The group ID is returned in numerical format, use * posix_getgrgid to resolve it to a group name. * Upon failure, false is returned. */ #[Pure(true)] function filegroup(string $filename): int|false {} /** * Gets file inode * @link https://php.net/manual/en/function.fileinode.php * @param string $filename

    * Path to the file. *

    * @return int|false the inode number of the file, or false on failure. */ #[Pure(true)] function fileinode(string $filename): int|false {} /** * Gets file modification time * @link https://php.net/manual/en/function.filemtime.php * @param string $filename

    * Path to the file. *

    * @return int|false the time the file was last modified, or false on failure. * The time is returned as a Unix timestamp, which is * suitable for the date function. */ #[Pure(true)] function filemtime(string $filename): int|false {} /** * Gets file owner * @link https://php.net/manual/en/function.fileowner.php * @param string $filename

    * Path to the file. *

    * @return int|false the user ID of the owner of the file, or false on failure. * The user ID is returned in numerical format, use * posix_getpwuid to resolve it to a username. */ #[Pure(true)] function fileowner(string $filename): int|false {} /** * Gets file permissions * @link https://php.net/manual/en/function.fileperms.php * @param string $filename

    * Path to the file. *

    * @return int|false the permissions on the file, or false on failure. */ #[Pure(true)] function fileperms(string $filename): int|false {} /** * Gets file size * @link https://php.net/manual/en/function.filesize.php * @param string $filename

    * Path to the file. *

    * @return int|false the size of the file in bytes, or false (and generates an error * of level E_WARNING) in case of an error. */ #[Pure(true)] function filesize(string $filename): int|false {} /** * Gets file type * @link https://php.net/manual/en/function.filetype.php * @param string $filename

    * Path to the file. *

    * @return string|false the type of the file. Possible values are fifo, char, * dir, block, link, file, socket and unknown. *

    *

    * Returns false if an error occurs. filetype will also * produce an E_NOTICE message if the stat call fails * or if the file type is unknown. */ #[Pure(true)] function filetype(string $filename): string|false {} /** * Checks whether a file or directory exists * @link https://php.net/manual/en/function.file-exists.php * @param string $filename

    * Path to the file or directory. *

    *

    * On windows, use //computername/share/filename or * \\computername\share\filename to check files on * network shares. *

    * @return bool true if the file or directory specified by * filename exists; false otherwise. *

    *

    * This function will return false for symlinks pointing to non-existing * files. *

    *

    * This function returns false for files inaccessible due to safe mode restrictions. However these * files still can be included if * they are located in safe_mode_include_dir. *

    *

    * The check is done using the real UID/GID instead of the effective one. */ #[Pure(true)] function file_exists(string $filename): bool {} /** * Tells whether the filename is writable * @link https://php.net/manual/en/function.is-writable.php * @param string $filename

    * The filename being checked. *

    * @return bool true if the filename exists and is * writable. */ #[Pure(true)] function is_writable(string $filename): bool {} /** * Alias: * {@see is_writable} * @link https://php.net/manual/en/function.is-writeable.php * @param string $filename

    * The filename being checked. *

    * @return bool true if the filename exists and is * writable. */ #[Pure(true)] function is_writeable(string $filename): bool {} /** * Tells whether a file or a directory exists and is readable * @link https://php.net/manual/en/function.is-readable.php * @param string $filename

    * Path to the file or directory. *

    * @return bool true if the file or directory specified by * filename exists and is readable, false otherwise. */ #[Pure(true)] function is_readable(string $filename): bool {} /** * Tells whether the filename is executable * @link https://php.net/manual/en/function.is-executable.php * @param string $filename

    * Path to the file. *

    * @return bool true if the filename exists and is executable, or false on * error. */ #[Pure(true)] function is_executable(string $filename): bool {} /** * Tells whether the filename is a regular file * @link https://php.net/manual/en/function.is-file.php * @param string $filename

    * Path to the file. *

    * @return bool true if the filename exists and is a regular file, false * otherwise. */ #[Pure(true)] function is_file(string $filename): bool {} /** * Tells whether the filename is a directory * @link https://php.net/manual/en/function.is-dir.php * @param string $filename

    * Path to the file. If filename is a relative * filename, it will be checked relative to the current working * directory. If filename is a symbolic or hard link * then the link will be resolved and checked. *

    * @return bool true if the filename exists and is a directory, false * otherwise. */ #[Pure(true)] function is_dir(string $filename): bool {} /** * Tells whether the filename is a symbolic link * @link https://php.net/manual/en/function.is-link.php * @param string $filename

    * Path to the file. *

    * @return bool true if the filename exists and is a symbolic link, false * otherwise. */ #[Pure(true)] function is_link(string $filename): bool {} /** * Gives information about a file * @link https://php.net/manual/en/function.stat.php * @param string $filename

    * Path to the file. *

    * @return array|false * stat and fstat result * format * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    NumericAssociative (since PHP 4.0.6)Description
    0devdevice number
    1inoinode number *
    2modeinode protection mode
    3nlinknumber of links
    4uiduserid of owner *
    5gidgroupid of owner *
    6rdevdevice type, if inode device
    7sizesize in bytes
    8atimetime of last access (Unix timestamp)
    9mtimetime of last modification (Unix timestamp)
    10ctimetime of last inode change (Unix timestamp)
    11blksizeblocksize of filesystem IO **
    12blocksnumber of 512-byte blocks allocated **
    * * On Windows this will always be 0. *

    *

    * ** Only valid on systems supporting the st_blksize type - other * systems (e.g. Windows) return -1. *

    *

    * In case of error, stat returns false. */ #[Pure(true)] #[ArrayShape([ "dev" => "int", "ino" => "int", "mode" => "int", "nlink" => "int", "uid" => "int", "gid" => "int", "rdev" => "int", "size" => "int", "atime" => "int", "mtime" => "int", "ctime" => "int", "blksize" => "int", "blocks" => "int" ])] function stat(string $filename): array|false {} /** * Gives information about a file or symbolic link * @link https://php.net/manual/en/function.lstat.php * @see stat * @param string $filename

    * Path to a file or a symbolic link. *

    * @return array|false See the manual page for stat for information on * the structure of the array that lstat returns. * This function is identical to the stat function * except that if the filename parameter is a symbolic * link, the status of the symbolic link is returned, not the status of the * file pointed to by the symbolic link. */ #[Pure(true)] function lstat(string $filename): array|false {} /** * Changes file owner * @link https://php.net/manual/en/function.chown.php * @param string $filename

    * Path to the file. *

    * @param string|int $user

    * A user name or number. *

    * @return bool true on success or false on failure. */ function chown(string $filename, string|int $user): bool {} /** * Changes file group * @link https://php.net/manual/en/function.chgrp.php * @param string $filename

    * Path to the file. *

    * @param string|int $group

    * A group name or number. *

    * @return bool true on success or false on failure. */ function chgrp(string $filename, string|int $group): bool {} /** * Changes user ownership of symlink * @link https://php.net/manual/en/function.lchown.php * @param string $filename

    * Path to the file. *

    * @param string|int $user

    * User name or number. *

    * @return bool true on success or false on failure. * @since 5.1.2 */ function lchown(string $filename, string|int $user): bool {} /** * Changes group ownership of symlink * @link https://php.net/manual/en/function.lchgrp.php * @param string $filename

    * Path to the symlink. *

    * @param string|int $group

    * The group specified by name or number. *

    * @return bool true on success or false on failure. * @since 5.1.2 */ function lchgrp(string $filename, string|int $group): bool {} /** * Changes file mode * @link https://php.net/manual/en/function.chmod.php * @param string $filename

    * Path to the file. *

    * @param int $permissions

    * Note that mode is not automatically * assumed to be an octal value, so strings (such as "g+w") will * not work properly. To ensure the expected operation, * you need to prefix mode with a zero (0): *

    *
     * 
     * 
    *

    * The mode parameter consists of three octal * number components specifying access restrictions for the owner, * the user group in which the owner is in, and to everybody else in * this order. One component can be computed by adding up the needed * permissions for that target user base. Number 1 means that you * grant execute rights, number 2 means that you make the file * writeable, number 4 means that you make the file readable. Add * up these numbers to specify needed rights. You can also read more * about modes on Unix systems with 'man 1 chmod' * and 'man 2 chmod'. *

    * @return bool true on success or false on failure. */ function chmod(string $filename, int $permissions): bool {} /** * Sets access and modification time of file * @link https://php.net/manual/en/function.touch.php * @param string $filename

    * The name of the file being touched. *

    * @param int|null $mtime [optional]

    * The touch time. If time is not supplied, * the current system time is used. *

    * @param int|null $atime [optional]

    * If present, the access time of the given filename is set to * the value of atime. Otherwise, it is set to * time. *

    * @return bool true on success or false on failure. */ function touch(string $filename, ?int $mtime, ?int $atime): bool {} /** * Clears file status cache * @link https://php.net/manual/en/function.clearstatcache.php * @param bool $clear_realpath_cache [optional]

    * Whenever to clear realpath cache or not. *

    * @param string $filename

    * Clear realpath cache on a specific filename, only used if * clear_realpath_cache is true. *

    * @return void */ function clearstatcache(bool $clear_realpath_cache = false, string $filename = ''): void {} /** * Returns the total size of a filesystem or disk partition * @link https://php.net/manual/en/function.disk-total-space.php * @param string $directory

    * A directory of the filesystem or disk partition. *

    * @return float|false the total number of bytes as a float * or false on failure. */ #[Pure(true)] function disk_total_space(string $directory): float|false {} /** * Returns available space in directory * @link https://php.net/manual/en/function.disk-free-space.php * @param string $directory

    * A directory of the filesystem or disk partition. *

    *

    * Given a file name instead of a directory, the behaviour of the * function is unspecified and may differ between operating systems and * PHP versions. *

    * @return float|false the number of available bytes as a float * or false on failure. */ #[Pure(true)] function disk_free_space(string $directory): float|false {} /** * Alias of {@see disk_free_space} * @link https://php.net/manual/en/function.diskfreespace.php * @see disk_free_space * @param string $directory * @return float|false */ #[Pure(true)] function diskfreespace(string $directory): float|false {} /** * Send mail * @link https://php.net/manual/en/function.mail.php * @param string $to

    * Receiver, or receivers of the mail. *

    *

    * The formatting of this string must comply with * RFC 2822. Some examples are: * user@example.com * user@example.com, anotheruser@example.com * User <user@example.com> * User <user@example.com>, Another User <anotheruser@example.com> *

    * @param string $subject

    * Subject of the email to be sent. *

    *

    * Subject must satisfy RFC 2047. *

    * @param string $message

    * Message to be sent. *

    *

    * Each line should be separated with a LF (\n). Lines should not be larger * than 70 characters. *

    *

    * Caution * (Windows only) When PHP is talking to a SMTP server directly, if a full * stop is found on the start of a line, it is removed. To counter-act this, * replace these occurrences with a double dot. *

    *
     * 
     * 
    * @param string|array $additional_headers

    * String or array to be inserted at the end of the email header.
    * Since 7.2.0 accepts an array. Its keys are the header names and its values are the respective header values. *

    *

    * This is typically used to add extra headers (From, Cc, and Bcc). * Multiple extra headers should be separated with a CRLF (\r\n). *

    *

    * When sending mail, the mail must contain * a From header. This can be set with the * additional_headers parameter, or a default * can be set in "php.ini". *

    *

    * Failing to do this will result in an error * message similar to Warning: mail(): "sendmail_from" not * set in php.ini or custom "From:" header missing. * The From header sets also * Return-Path under Windows. *

    *

    * If messages are not received, try using a LF (\n) only. * Some poor quality Unix mail transfer agents replace LF by CRLF * automatically (which leads to doubling CR if CRLF is used). * This should be a last resort, as it does not comply with * RFC 2822. *

    * @param string $additional_params

    * The additional_parameters parameter * can be used to pass additional flags as command line options to the * program configured to be used when sending mail, as defined by the * sendmail_path configuration setting. For example, * this can be used to set the envelope sender address when using * sendmail with the -f sendmail option. *

    *

    * The user that the webserver runs as should be added as a trusted user to the * sendmail configuration to prevent a 'X-Warning' header from being added * to the message when the envelope sender (-f) is set using this method. * For sendmail users, this file is /etc/mail/trusted-users. *

    * @return bool true if the mail was successfully accepted for delivery, false otherwise. *

    * It is important to note that just because the mail was accepted for delivery, * it does NOT mean the mail will actually reach the intended destination. *

    */ function mail(string $to, string $subject, string $message, array|string $additional_headers = [], string $additional_params = ''): bool {} /** * Calculate the hash value needed by EZMLM * @link https://php.net/manual/en/function.ezmlm-hash.php * @param string $addr

    * The email address that's being hashed. *

    * @return int The hash value of addr. * @removed 8.0 */ #[Deprecated(since: '7.4')] function ezmlm_hash(string $addr): int {} /** * Open connection to system logger * @link https://php.net/manual/en/function.openlog.php * @param string $prefix

    * The string ident is added to each message. *

    * @param int $flags

    * The option argument is used to indicate * what logging options will be used when generating a log message. *

    * openlog Options * * * * * * * * * * * * * * * * * * * * * * * * *
    ConstantDescription
    LOG_CONS * if there is an error while sending data to the system logger, * write directly to the system console *
    LOG_NDELAY * open the connection to the logger immediately *
    LOG_ODELAY * (default) delay opening the connection until the first * message is logged *
    LOG_PERRORprint log message also to standard error
    LOG_PIDinclude PID with each message
    * You can use one or more of this options. When using multiple options * you need to OR them, i.e. to open the connection * immediately, write to the console and include the PID in each message, * you will use: LOG_CONS | LOG_NDELAY | LOG_PID *

    * @param int $facility

    * The facility argument is used to specify what * type of program is logging the message. This allows you to specify * (in your machine's syslog configuration) how messages coming from * different facilities will be handled. *

    * openlog Facilities * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    ConstantDescription
    LOG_AUTH * security/authorization messages (use * LOG_AUTHPRIV instead * in systems where that constant is defined) *
    LOG_AUTHPRIVsecurity/authorization messages (private)
    LOG_CRONclock daemon (cron and at)
    LOG_DAEMONother system daemons
    LOG_KERNkernel messages
    LOG_LOCAL0 ... LOG_LOCAL7reserved for local use, these are not available in Windows
    LOG_LPRline printer subsystem
    LOG_MAILmail subsystem
    LOG_NEWSUSENET news subsystem
    LOG_SYSLOGmessages generated internally by syslogd
    LOG_USERgeneric user-level messages
    LOG_UUCPUUCP subsystem
    *

    *

    * LOG_USER is the only valid log type under Windows * operating systems *

    * @return bool true on success or false on failure. */ #[LanguageLevelTypeAware(["8.2" => "true"], default: "bool")] function openlog(string $prefix, int $flags, int $facility) {} * Halts the execution of the compiler. This can be useful to embed data in PHP scripts, like the installation files. * Byte position of the data start can be determined by the __COMPILER_HALT_OFFSET__ constant * which is defined only if there is a __halt_compiler() presented in the file. *

    Note: __halt_compiler() can only be used from the outermost scope.

    * @link https://php.net/manual/en/function.halt-compiler.php * @return void */ function PS_UNRESERVE_PREFIX___halt_compiler() {} /** * (PHP 5.1)
    * Byte position of the data start, defined only if there is a __halt_compiler() presented in the file. * @link https://php.net/manual/en/function.halt-compiler.php * @return void */ define("__COMPILER_HALT_OFFSET__", 0); /** * Convert hexadecimal string to its binary representation. * * If the hexadecimal input string is of odd length or invalid hexadecimal string an E_WARNING level error is emitted. * * @link https://php.net/manual/en/function.hex2bin.php * @param string $string Hexadecimal string to convert. * @return string|false The binary representation of the given data or FALSE on failure. * @see bin2hex() * @see unpack() * @since 5.4 */ function hex2bin(string $string): string|false {}; /** * Get or Set the HTTP response code * @param int $response_code The optional response_code will set the response code. * @return int|bool The current response code. By default the return value is int(200). */ function http_response_code(int $response_code = 0): int|bool {} * Get the boolean value of a variable * @param mixed $value

    the scalar value being converted to a boolean.

    * @return bool The boolean value of var. * @since 5.5 */ #[Pure] function boolval(mixed $value): bool {} /** * Get the integer value of a variable * @link https://php.net/manual/en/function.intval.php * @param mixed $value

    * The scalar value being converted to an integer *

    * @param int $base [optional]

    * The base for the conversion *

    * @return int The integer value of var on success, or 0 on * failure. Empty arrays and objects return 0, non-empty arrays and * objects return 1. *

    *

    * The maximum value depends on the system. 32 bit systems have a * maximum signed integer range of -2147483648 to 2147483647. So for example * on such a system, intval('1000000000000') will return * 2147483647. The maximum signed integer value for 64 bit systems is * 9223372036854775807. *

    *

    * Strings will most likely return 0 although this depends on the * leftmost characters of the string. The common rules of * integer casting * apply. */ #[Pure] function intval(mixed $value, int $base = 10): int {} /** * Get float value of a variable * @link https://php.net/manual/en/function.floatval.php * @param mixed $value May be any scalar type. should not be used on objects, as doing so will emit an E_NOTICE level error and return 1. * @return float value of the given variable. Empty arrays return 0, non-empty arrays return 1. */ #[Pure] function floatval(mixed $value): float {} /** * (PHP 4.2.0, PHP 5)
    * Alias: * {@see floatval} * Get float value of a variable * @link https://php.net/manual/en/function.doubleval.php * @param mixed $value May be any scalar type. should not be used on objects, as doing so will emit an E_NOTICE level error and return 1. * @return float value of the given variable. Empty arrays return 0, non-empty arrays return 1. */ #[Pure] function doubleval(mixed $value): float {} /** * Get string value of a variable * @link https://php.net/manual/en/function.strval.php * @param mixed $value

    * The variable that is being converted to a string. *

    *

    * $var may be any scalar type or an object that implements the __toString() method. * You cannot use strval() on arrays or objects that do not implement the __toString() method. *

    * @return string The string value of var. */ #[Pure] function strval(mixed $value): string {} /** * Get the type of a variable * @link https://php.net/manual/en/function.gettype.php * @param mixed $value

    * The variable being type checked. *

    * @return string Possibles values for the returned string are: * "boolean" * "integer" * "double" (for historical reasons "double" is * returned in case of a float, and not simply * "float") * "string" * "array" * "object" * "resource" * "NULL" * "unknown type" * "resource (closed)" since 7.2.0 */ #[Pure] #[ExpectedValues([ "boolean", "integer", "double", "string", "array", "object", "resource", "NULL", "unknown type", "resource (closed)" ])] function gettype(mixed $value): string {} /** * Set the type of a variable * @link https://php.net/manual/en/function.settype.php * @param mixed &$var

    * The variable being converted. *

    * @param string $type

    * Possibles values of type are: *

      *
    • * "boolean" (or, since PHP 4.2.0, "bool") *
    • *
    • * "integer" (or, since PHP 4.2.0, "int") *
    • *
    • * "float" (only possible since PHP 4.2.0, for older versions use the * deprecated variant "double") *
    • *
    • * "string" *
    • *
    • * "array" *
    • *
    • * "object" *
    • *
    • * "null" (since PHP 4.2.0) *
    • *
    * @return bool true on success or false on failure. */ function settype(mixed &$var, #[ExpectedValues(["bool", "boolean", "int", "integer", "float", "double", "string", "array", "object", "null"])] string $type): bool {} /** * Finds whether a variable is null. * @link https://php.net/manual/en/function.is-null.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is null, false * otherwise. */ #[Pure] function is_null(mixed $value): bool {} /** * Finds whether a variable is a resource * @link https://php.net/manual/en/function.is-resource.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is a resource, * false otherwise. */ #[Pure] function is_resource(mixed $value): bool {} /** * Finds out whether a variable is a boolean * @link https://php.net/manual/en/function.is-bool.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is a boolean, * false otherwise. */ #[Pure] function is_bool(mixed $value): bool {} /** * Alias: * {@see is_int} * @link https://php.net/manual/en/function.is-long.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is an integer, * false otherwise. */ #[Pure] function is_long(mixed $value): bool {} /** * Finds whether the type of a variable is float * @link https://php.net/manual/en/function.is-float.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is a float, * false otherwise. */ #[Pure] function is_float(mixed $value): bool {} /** * Find whether the type of a variable is integer * @link https://php.net/manual/en/function.is-int.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is an integer, * false otherwise. */ #[Pure] function is_int(mixed $value): bool {} /** * Alias: * {@see is_int} * @link https://php.net/manual/en/function.is-integer.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is an integer, * false otherwise. */ #[Pure] function is_integer(mixed $value): bool {} /** * Alias: * {@see is_float} * @link https://php.net/manual/en/function.is-double.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is a float, * false otherwise. */ #[Pure] function is_double(mixed $value): bool {} /** * Alias: * {@see is_float} * @link https://php.net/manual/en/function.is-real.php * @param mixed $var

    * The variable being evaluated. *

    * @return bool true if var is a float, * false otherwise. */ #[Pure] #[Deprecated(since: '7.4')] function is_real(mixed $var): bool {} /** * Finds whether a variable is a number or a numeric string * @link https://php.net/manual/en/function.is-numeric.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is a number or a numeric * string, false otherwise. */ #[Pure] function is_numeric(mixed $value): bool {} /** * Find whether the type of a variable is string * @link https://php.net/manual/en/function.is-string.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is of type string, * false otherwise. */ #[Pure] function is_string(mixed $value): bool {} /** * Finds whether a variable is an array * @link https://php.net/manual/en/function.is-array.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is an array, * false otherwise. */ #[Pure] function is_array(mixed $value): bool {} /** * Finds whether a variable is an object * @link https://php.net/manual/en/function.is-object.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is an object, false otherwise.
    * Since 7.2.0 returns true for unserialized objects without a class definition (class of __PHP_Incomplete_Class). */ #[Pure] function is_object(mixed $value): bool {} /** * Finds whether a variable is a scalar * @link https://php.net/manual/en/function.is-scalar.php * @param mixed $value

    * The variable being evaluated. *

    * @return bool true if var is a scalar false * otherwise. */ #[Pure] function is_scalar(mixed $value): bool {} /** * Verify that the contents of a variable can be called as a function * @link https://php.net/manual/en/function.is-callable.php * @param callable|mixed $value

    * The value to check *

    * @param bool $syntax_only [optional]

    * If set to TRUE the function only verifies that * name might be a function or method. It will only * reject simple variables that are not strings, or an array that does * not have a valid structure to be used as a callback. The valid ones * are supposed to have only 2 entries, the first of which is an object * or a string, and the second a string. *

    * @param string &$callable_name [optional]

    * Receives the "callable name". In the example below it is * "someClass::someMethod". Note, however, that despite the implication * that someClass::SomeMethod() is a callable static method, this is not * the case. *

    * @return bool TRUE if $var is callable, FALSE * otherwise. */ function is_callable(mixed $value, bool $syntax_only = false, &$callable_name): bool {} /** * Verify that the contents of a variable is a countable value * @link https://secure.php.net/is_countable * * @param mixed $value The value to check * @return bool TRUE if $var is countable, FALSE otherwise. * @since 7.3 */ #[Pure] function is_countable(mixed $value): bool {} /** * Closes process file pointer * @link https://php.net/manual/en/function.pclose.php * @param resource $handle

    * The file pointer must be valid, and must have been returned by a * successful call to popen. *

    * @return int the termination status of the process that was run. In case of an error then -1 is returned. *

    * If PHP has been compiled with --enable-sigchild, the return value of this function is undefined. *

    */ function pclose($handle): int {} /** * Opens process file pointer * @link https://php.net/manual/en/function.popen.php * @param string $command

    * The command *

    * @param string $mode

    * The mode *

    * @return resource|false a file pointer identical to that returned by * fopen, except that it is unidirectional (may * only be used for reading or writing) and must be closed with * pclose. This pointer may be used with * fgets, fgetss, and * fwrite. *

    *

    * If an error occurs, returns false. */ function popen(string $command, string $mode) {} /** * Outputs a file * @link https://php.net/manual/en/function.readfile.php * @param string $filename

    * The filename being read. *

    * @param bool $use_include_path [optional]

    * You can use the optional second parameter and set it to true, if * you want to search for the file in the include_path, too. *

    * @param resource $context [optional]

    * A context stream resource. *

    * @return false|int the number of bytes read from the file, or FALSE on failure */ function readfile(string $filename, bool $use_include_path = false, $context): int|false {} /** * Rewind the position of a file pointer * @link https://php.net/manual/en/function.rewind.php * @param resource $stream

    * The file pointer must be valid, and must point to a file * successfully opened by fopen. *

    * @return bool true on success or false on failure. */ function rewind($stream): bool {} /** * Removes directory * @link https://php.net/manual/en/function.rmdir.php * @param string $directory

    * Path to the directory. *

    * @param resource $context [optional] * @return bool true on success or false on failure. */ function rmdir(string $directory, $context): bool {} /** * Changes the current umask * @link https://php.net/manual/en/function.umask.php * @param int|null $mask [optional]

    * The new umask. *

    * @return int umask without arguments simply returns the * current umask otherwise the old umask is returned. */ function umask(?int $mask): int {} /** * Closes an open file pointer * @link https://php.net/manual/en/function.fclose.php * @param resource $stream

    * The file pointer must be valid, and must point to a file successfully * opened by fopen or fsockopen. *

    * @return bool true on success or false on failure. */ function fclose($stream): bool {} /** * Tests for end-of-file on a file pointer * @link https://php.net/manual/en/function.feof.php * @param resource $stream The file pointer must be valid, and must point to a file successfully opened by fopen() or fsockopen() (and not yet closed by fclose()). * @return bool true if the file pointer is at EOF or an error occurs * (including socket timeout); otherwise returns false. */ #[Pure(true)] function feof($stream): bool {} /** * Gets character from file pointer * @link https://php.net/manual/en/function.fgetc.php * @param resource $stream The file pointer must be valid, and must point to a file successfully opened by fopen() or fsockopen() (and not yet closed by fclose()). * @return string|false a string containing a single character read from the file pointed * to by handle. Returns false on EOF. */ function fgetc($stream): string|false {} /** * Gets line from file pointer * @link https://php.net/manual/en/function.fgets.php * @param resource $stream The file pointer must be valid, and must point to a file successfully opened by fopen() or fsockopen() (and not yet closed by fclose()). * @param int|null $length [optional]

    * Reading ends when length - 1 bytes have been * read, on a newline (which is included in the return value), or on EOF * (whichever comes first). If no length is specified, it will keep * reading from the stream until it reaches the end of the line. *

    *

    * Until PHP 4.3.0, omitting it would assume 1024 as the line length. * If the majority of the lines in the file are all larger than 8KB, * it is more resource efficient for your script to specify the maximum * line length. *

    * @return string|false a string of up to length - 1 bytes read from * the file pointed to by handle. *

    *

    * If an error occurs, returns false. */ function fgets($stream, ?int $length): string|false {} /** * Gets line from file pointer and strip HTML tags * @link https://php.net/manual/en/function.fgetss.php * @param resource $handle The file pointer must be valid, and must point to a file successfully opened by fopen() or fsockopen() (and not yet closed by fclose()). * @param null|int $length [optional]

    * Length of the data to be retrieved. *

    * @param string $allowable_tags [optional]

    * You can use the optional third parameter to specify tags which should * not be stripped. *

    * @return string|false a string of up to length - 1 bytes read from * the file pointed to by handle, with all HTML and PHP * code stripped. *

    *

    * If an error occurs, returns false. * @removed 8.0 */ #[Deprecated(since: '7.3')] function fgetss($handle, ?int $length = null, $allowable_tags = null): false|string {} /** * Binary-safe file read * @link https://php.net/manual/en/function.fread.php * @param resource $stream &fs.file.pointer; * @param int $length

    * Up to length number of bytes read. *

    * @return string|false the read string or false on failure. */ function fread($stream, int $length): string|false {} /** * Opens file or URL * @link https://php.net/manual/en/function.fopen.php * @param string $filename

    * If filename is of the form "scheme://...", it * is assumed to be a URL and PHP will search for a protocol handler * (also known as a wrapper) for that scheme. If no wrappers for that * protocol are registered, PHP will emit a notice to help you track * potential problems in your script and then continue as though * filename specifies a regular file. *

    *

    * If PHP has decided that filename specifies * a local file, then it will try to open a stream on that file. * The file must be accessible to PHP, so you need to ensure that * the file access permissions allow this access. * If you have enabled "safemode", * or open_basedir further * restrictions may apply. *

    *

    * If PHP has decided that filename specifies * a registered protocol, and that protocol is registered as a * network URL, PHP will check to make sure that * allow_url_fopen is * enabled. If it is switched off, PHP will emit a warning and * the fopen call will fail. *

    *

    * The list of supported protocols can be found in . Some protocols (also referred to as * wrappers) support context * and/or "php.ini" options. Refer to the specific page for the * protocol in use for a list of options which can be set. (e.g. * "php.ini" value user_agent used by the * http wrapper). *

    *

    * On the Windows platform, be careful to escape any backslashes * used in the path to the file, or use forward slashes. *

    *
     * 
     * 
    * @param string $mode

    * The mode parameter specifies the type of access * you require to the stream. It may be any of the following: *

    * A list of possible modes for fopen * using mode * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    modeDescription
    'r' * Open for reading only; place the file pointer at the * beginning of the file. *
    'r+' * Open for reading and writing; place the file pointer at * the beginning of the file. *
    'w' * Open for writing only; place the file pointer at the * beginning of the file and truncate the file to zero length. * If the file does not exist, attempt to create it. *
    'w+' * Open for reading and writing; place the file pointer at * the beginning of the file and truncate the file to zero * length. If the file does not exist, attempt to create it. *
    'a' * Open for writing only; place the file pointer at the end of * the file. If the file does not exist, attempt to create it. *
    'a+' * Open for reading and writing; place the file pointer at * the end of the file. If the file does not exist, attempt to * create it. *
    'x' * Create and open for writing only; place the file pointer at the * beginning of the file. If the file already exists, the * fopen call will fail by returning false and * generating an error of level E_WARNING. If * the file does not exist, attempt to create it. This is equivalent * to specifying O_EXCL|O_CREAT flags for the * underlying open(2) system call. *
    'x+' * Create and open for reading and writing; place the file pointer at * the beginning of the file. If the file already exists, the * fopen call will fail by returning false and * generating an error of level E_WARNING. If * the file does not exist, attempt to create it. This is equivalent * to specifying O_EXCL|O_CREAT flags for the * underlying open(2) system call. *
    *

    *

    * Different operating system families have different line-ending * conventions. When you write a text file and want to insert a line * break, you need to use the correct line-ending character(s) for your * operating system. Unix based systems use \n as the * line ending character, Windows based systems use \r\n * as the line ending characters and Macintosh based systems use * \r as the line ending character. *

    *

    * If you use the wrong line ending characters when writing your files, you * might find that other applications that open those files will "look * funny". *

    *

    * Windows offers a text-mode translation flag ('t') * which will transparently translate \n to * \r\n when working with the file. In contrast, you * can also use 'b' to force binary mode, which will not * translate your data. To use these flags, specify either * 'b' or 't' as the last character * of the mode parameter. *

    *

    * The default translation mode depends on the SAPI and version of PHP that * you are using, so you are encouraged to always specify the appropriate * flag for portability reasons. You should use the 't' * mode if you are working with plain-text files and you use * \n to delimit your line endings in your script, but * expect your files to be readable with applications such as notepad. You * should use the 'b' in all other cases. *

    *

    * If you do not specify the 'b' flag when working with binary files, you * may experience strange problems with your data, including broken image * files and strange problems with \r\n characters. *

    *

    * For portability, it is strongly recommended that you always * use the 'b' flag when opening files with fopen. *

    *

    * Again, for portability, it is also strongly recommended that * you re-write code that uses or relies upon the 't' * mode so that it uses the correct line endings and * 'b' mode instead. *

    * @param bool $use_include_path [optional]

    * The optional third use_include_path parameter * can be set to '1' or true if you want to search for the file in the * include_path, too. *

    * @param resource $context [optional] * @return resource|false a file pointer resource on success, or false on error. */ function fopen(string $filename, string $mode, bool $use_include_path = false, $context) {} /** * Output all remaining data on a file pointer * @link https://php.net/manual/en/function.fpassthru.php * @param resource $stream The file pointer must be valid, and must point to a file successfully opened by fopen() or fsockopen() (and not yet closed by fclose()). * @return int|false If an error occurs, fpassthru returns * false. Otherwise, fpassthru returns * the number of characters read from handle * and passed through to the output. */ #[LanguageLevelTypeAware(["8.0" => "int"], default: "int|false")] function fpassthru($stream) {} /** * Truncates a file to a given length * @link https://php.net/manual/en/function.ftruncate.php * @param resource $stream

    * The file pointer. *

    *

    * The handle must be open for writing. *

    * @param int $size

    * The size to truncate to. *

    *

    * If size is larger than the file it is extended * with null bytes. *

    *

    * If size is smaller than the extra data * will be lost. *

    * @return bool true on success or false on failure. */ function ftruncate($stream, int $size): bool {} /** * Gets information about a file using an open file pointer * @link https://php.net/manual/en/function.fstat.php * @param resource $stream &fs.file.pointer; * @return array|false an array with the statistics of the file; the format of the array * is described in detail on the stat manual page. */ #[Pure(true)] function fstat($stream): array|false {} /** * Seeks on a file pointer * @link https://php.net/manual/en/function.fseek.php * @param resource $stream &fs.file.pointer; * @param int $offset

    * The offset. *

    *

    * To move to a position before the end-of-file, you need to pass * a negative value in offset and * set whence * to SEEK_END. *

    * @param int $whence [optional]

    * whence values are: * SEEK_SET - Set position equal to offset bytes. * SEEK_CUR - Set position to current location plus offset. * SEEK_END - Set position to end-of-file plus offset. *

    *

    * If whence is not specified, it is assumed to be * SEEK_SET. *

    * @return int Upon success, returns 0; otherwise, returns -1. Note that seeking * past EOF is not considered an error. */ function fseek($stream, int $offset, int $whence = SEEK_SET): int {} /** * Returns the current position of the file read/write pointer * @link https://php.net/manual/en/function.ftell.php * @param resource $stream

    * The file pointer must be valid, and must point to a file successfully * opened by fopen or popen. * ftell gives undefined results for append-only streams * (opened with "a" flag). *

    * @return int|false the position of the file pointer referenced by * handle as an integer; i.e., its offset into the file stream. *

    *

    * If an error occurs, returns false. */ #[Pure(true)] function ftell($stream): int|false {} /** * Flushes the output to a file * @link https://php.net/manual/en/function.fflush.php * @param resource $stream The file pointer must be valid, and must point to a file successfully opened by fopen() or fsockopen() (and not yet closed by fclose()). * @return bool true on success or false on failure. */ function fflush($stream): bool {} /** * Sync file to storage. Similar to fflush() but blocks until OS buffers have flushed. * @param resource $stream * @since 8.1 */ function fsync($stream): bool {} /** * Sync file data only to storage. Similar to fsync but does not flush modified metadata. POSIX only, aliased to fsync on Win32. * @param resource $stream * @since 8.1 */ function fdatasync($stream): bool {} /** * Binary-safe file write * @link https://php.net/manual/en/function.fwrite.php * @param resource $stream &fs.file.pointer; * @param string $data

    * The string that is to be written. *

    * @param int|null $length [optional]

    * If the length argument is given, writing will * stop after length bytes have been written or * the end of string is reached, whichever comes * first. *

    *

    * Note that if the length argument is given, * then the magic_quotes_runtime * configuration option will be ignored and no slashes will be * stripped from string. *

    * @return int|false the number of bytes written, or FALSE on error. */ function fwrite($stream, string $data, ?int $length): int|false {} /** * Alias: * {@see fwrite} * @param resource $stream A file system pointer resource that is typically created using fopen(). * @param string $data

    * The string that is to be written. *

    * @param int|null $length [optional]

    * If the length argument is given, writing will * stop after length bytes have been written or * the end of string is reached, whichever comes * first. *

    *

    * Note that if the length argument is given, * then the magic_quotes_runtime * configuration option will be ignored and no slashes will be * stripped from string. *

    * @return int|false the number of bytes written, or FALSE on error. * @see fwrite() * @link https://php.net/manual/en/function.fputs.php * Binary-safe file write */ function fputs($stream, string $data, ?int $length): int|false {} /** * Attempts to create the directory specified by pathname. * @link https://php.net/manual/en/function.mkdir.php * @param string $directory

    * The directory path. *

    * @param int $permissions [optional]

    * The mode is 0777 by default, which means the widest possible * access. For more information on modes, read the details * on the chmod page. *

    *

    * mode is ignored on Windows. *

    *

    * Note that you probably want to specify the mode as an octal number, * which means it should have a leading zero. The mode is also modified * by the current umask, which you can change using * umask(). *

    * @param bool $recursive [optional]

    * Allows the creation of nested directories specified in the pathname. Default to false. *

    * @param resource $context [optional] * @return bool true on success or false on failure. */ function mkdir(string $directory, int $permissions = 0777, bool $recursive = false, $context): bool {} /** * Renames a file or directory * @link https://php.net/manual/en/function.rename.php * @param string $from

    *

    *

    * The old name. The wrapper used in oldname * must match the wrapper used in * newname. *

    * @param string $to

    * The new name. *

    * @param resource $context [optional] * @return bool true on success or false on failure. */ function rename(string $from, string $to, $context): bool {} /** * Copies file * @link https://php.net/manual/en/function.copy.php * @param string $from

    * Path to the source file. *

    * @param string $to

    * The destination path. If dest is a URL, the * copy operation may fail if the wrapper does not support overwriting of * existing files. *

    *

    * If the destination file already exists, it will be overwritten. *

    * @param resource $context [optional]

    * A valid context resource created with * stream_context_create. *

    * @return bool true on success or false on failure. */ function copy(string $from, string $to, $context): bool {} /** * Create file with unique file name * @link https://php.net/manual/en/function.tempnam.php * @param string $directory

    * The directory where the temporary filename will be created. *

    * @param string $prefix

    * The prefix of the generated temporary filename. *

    * Windows use only the first three characters of prefix. * @return string|false the new temporary filename, or false on * failure. */ function tempnam(string $directory, string $prefix): string|false {} /** * Creates a temporary file * @link https://php.net/manual/en/function.tmpfile.php * @return resource|false a file handle, similar to the one returned by * fopen, for the new file or false on failure. */ function tmpfile() {} /** * Reads entire file into an array * @link https://php.net/manual/en/function.file.php * @param string $filename

    * Path to the file. *

    * @param int $flags

    * The optional parameter flags can be one, or * more, of the following constants: *

      *
    • FILE_USE_INCLUDE_PATH - Search for the file in the include_path.
    • *
    • FILE_IGNORE_NEW_LINES - Omit newline at the end of each array element
    • *
    • FILE_SKIP_EMPTY_LINES - Skip empty lines
    • *
    *

    * @param resource $context [optional]

    * A context resource created with the * stream_context_create function. *

    * @return array|false the file in an array. Each element of the array corresponds to a * line in the file, with the newline still attached. Upon failure, * file returns false. *

    * Each line in the resulting array will include the line ending, unless * FILE_IGNORE_NEW_LINES is used, so you still need to * use rtrim if you do not want the line ending * present. *

    */ #[Pure(true)] function file(string $filename, int $flags = 0, $context): array|false {} /** * Reads entire file into a string * @link https://php.net/manual/en/function.file-get-contents.php * @param string $filename

    * Name of the file to read. *

    * @param bool $use_include_path [optional]

    * Note: As of PHP 5 the FILE_USE_INCLUDE_PATH constant can be * used to trigger include path search. *

    * @param resource $context [optional]

    * A valid context resource created with * stream_context_create. If you don't need to use a * custom context, you can skip this parameter by null. *

    * @param int $offset [optional]

    * The offset where the reading starts. *

    * @param int|null $length [optional]

    * Maximum length of data read. The default is to read until end * of file is reached. *

    * @return string|false The function returns the read data or false on failure. */ #[Pure(true)] function file_get_contents(string $filename, bool $use_include_path = false, $context, int $offset = 0, ?int $length): string|false {} /** * Write a string to a file * @link https://php.net/manual/en/function.file-put-contents.php * @param string $filename

    * Path to the file where to write the data. *

    * @param mixed $data

    * The data to write. Can be either a string, an * array or a stream resource. *

    *

    * If data is a stream resource, the * remaining buffer of that stream will be copied to the specified file. * This is similar with using stream_copy_to_stream. *

    *

    * You can also specify the data parameter as a single * dimension array. This is equivalent to * file_put_contents($filename, implode('', $array)). *

    * @param int $flags [optional]

    * The value of flags can be any combination of * the following flags (with some restrictions), joined with the binary OR * (|) operator. *

    *

    *

    * Available flags * * * * * * * * * * * * * * * * *
    FlagDescription
    * FILE_USE_INCLUDE_PATH * * Search for filename in the include directory. * See include_path for more * information. *
    * FILE_APPEND * * If file filename already exists, append * the data to the file instead of overwriting it. Mutually * exclusive with LOCK_EX since appends are atomic and thus there * is no reason to lock. *
    * LOCK_EX * * Acquire an exclusive lock on the file while proceeding to the * writing. Mutually exclusive with FILE_APPEND. *
    *

    * @param resource $context [optional]

    * A valid context resource created with * stream_context_create. *

    * @return int|false The function returns the number of bytes that were written to the file, or * false on failure. */ function file_put_contents(string $filename, mixed $data, int $flags = 0, $context): int|false {} FALSE if the server is terminating, giving the opportunity to the worker script to finish cleanly */ function frankenphp_handle_request(callable $callback): bool {} /** * Flushes all response data to the client and finishes the request. * This allows for time-consuming tasks to be performed without leaving the connection to the client open. * * Alias of fastcgi_finish_request. * * @link https://www.php.net/manual/en/function.fastcgi-finish-request.php * * @return bool Returns TRUE on success or FALSE on failure. */ function frankenphp_finish_request(): bool {} /** * Fetches all HTTP request headers from the current request. * * Alias of apache_request_headers. * * @link https://php.net/manual/en/function.apache-request-headers.php * * @return array An associative array of all the HTTP headers in the current request. */ function frankenphp_request_headers(): array {} /** * Fetches all HTTP response headers. * * Alias of apache_response_headers. * * @link https://php.net/manual/en/function.apache-response-headers.php * * @return array|false An array of all FrankenPHP response headers on success or FALSE on failure. */ function frankenphp_response_headers(): array|false {} * The PHP source to parse. *

    * @param int $flags *

    *

    * Valid flags: *

      *
    • * * TOKEN_PARSE - Recognises the ability to use * reserved words in specific contexts. *
    • *
    *

    * @return array An array of token identifiers. Each individual token identifier is either * a single character (i.e.: ;, ., * >, !, etc...), * or a three element array containing the token index in element 0, the string * content of the original token in element 1 and the line number in element 2. */ #[Pure] function token_get_all(string $code, #[PhpStormStubsElementAvailable(from: '7.0')] int $flags = 0): array {} /** * Get the symbolic name of a given PHP token * @link https://php.net/manual/en/function.token-name.php * @param int $id

    * The token value. *

    * @return string The symbolic name of the given token. */ #[Pure] function token_name(int $id): string {} define('TOKEN_PARSE', 1); define('T_REQUIRE_ONCE', 263); define('T_REQUIRE', 262); define('T_EVAL', 323); define('T_INCLUDE_ONCE', 261); define('T_INCLUDE', 260); define('T_LOGICAL_OR', 264); define('T_LOGICAL_XOR', 265); define('T_LOGICAL_AND', 266); define('T_PRINT', 267); define('T_YIELD', 268); define('T_DOUBLE_ARROW', 269); define('T_YIELD_FROM', 270); define('T_POW_EQUAL', 282); define('T_SR_EQUAL', 281); define('T_SL_EQUAL', 280); define('T_XOR_EQUAL', 279); define('T_OR_EQUAL', 278); define('T_AND_EQUAL', 277); define('T_MOD_EQUAL', 276); define('T_CONCAT_EQUAL', 275); define('T_DIV_EQUAL', 274); define('T_MUL_EQUAL', 273); define('T_MINUS_EQUAL', 272); define('T_PLUS_EQUAL', 271); /** * @since 7.4 */ define('T_COALESCE_EQUAL', 283); define('T_COALESCE', 284); define('T_BOOLEAN_OR', 285); define('T_BOOLEAN_AND', 286); define('T_SPACESHIP', 293); define('T_IS_NOT_IDENTICAL', 292); define('T_IS_IDENTICAL', 291); define('T_IS_NOT_EQUAL', 290); define('T_IS_EQUAL', 289); define('T_IS_GREATER_OR_EQUAL', 295); define('T_IS_SMALLER_OR_EQUAL', 294); define('T_SR', 297); define('T_SL', 296); define('T_INSTANCEOF', 298); define('T_UNSET_CAST', 305); define('T_BOOL_CAST', 304); define('T_OBJECT_CAST', 303); define('T_ARRAY_CAST', 302); define('T_STRING_CAST', 301); define('T_DOUBLE_CAST', 300); define('T_INT_CAST', 299); define('T_DEC', 389); define('T_INC', 388); define('T_POW', 306); define('T_CLONE', 307); define('T_NEW', 324); define('T_ELSEIF', 309); define('T_ELSE', 310); define('T_ENDIF', 327); define('T_PUBLIC', 362); define('T_PROTECTED', 361); define('T_PRIVATE', 360); define('T_FINAL', 359); define('T_ABSTRACT', 358); define('T_STATIC', 357); define('T_LNUMBER', 311); define('T_DNUMBER', 312); define('T_STRING', 313); define('T_VARIABLE', 317); define('T_INLINE_HTML', 318); define('T_ENCAPSED_AND_WHITESPACE', 319); define('T_CONSTANT_ENCAPSED_STRING', 320); define('T_STRING_VARNAME', 321); define('T_NUM_STRING', 322); define('T_EXIT', 325); define('T_IF', 326); define('T_ECHO', 328); define('T_DO', 329); define('T_WHILE', 330); define('T_ENDWHILE', 331); define('T_FOR', 332); define('T_ENDFOR', 333); define('T_FOREACH', 334); define('T_ENDFOREACH', 335); define('T_DECLARE', 336); define('T_ENDDECLARE', 337); define('T_AS', 338); define('T_SWITCH', 339); define('T_ENDSWITCH', 340); define('T_CASE', 341); define('T_DEFAULT', 342); define('T_MATCH', 343); define('T_BREAK', 344); define('T_CONTINUE', 345); define('T_GOTO', 346); define('T_FUNCTION', 347); define('T_CONST', 349); define('T_RETURN', 350); define('T_TRY', 351); define('T_CATCH', 352); define('T_FINALLY', 353); define('T_THROW', 258); define('T_USE', 354); define('T_INSTEADOF', 355); define('T_GLOBAL', 356); define('T_VAR', 364); define('T_UNSET', 365); define('T_ISSET', 366); define('T_EMPTY', 367); define('T_HALT_COMPILER', 368); define('T_CLASS', 369); define('T_TRAIT', 370); define('T_INTERFACE', 371); /** * @since 8.1 */ define('T_ENUM', 372); define('T_EXTENDS', 373); define('T_IMPLEMENTS', 374); define('T_OBJECT_OPERATOR', 390); define('T_LIST', 376); define('T_ARRAY', 377); define('T_CALLABLE', 378); define('T_LINE', 379); define('T_FILE', 380); define('T_DIR', 381); define('T_CLASS_C', 382); define('T_TRAIT_C', 383); define('T_METHOD_C', 384); define('T_FUNC_C', 385); define('T_NS_C', 386); /** * @since 8.4 */ define('T_PROPERTY_C', 350); /** * @since 8.0 */ define('T_ATTRIBUTE', 387); define('T_COMMENT', 392); define('T_DOC_COMMENT', 393); define('T_OPEN_TAG', 394); define('T_OPEN_TAG_WITH_ECHO', 395); define('T_CLOSE_TAG', 396); define('T_WHITESPACE', 397); define('T_START_HEREDOC', 398); define('T_END_HEREDOC', 399); define('T_DOLLAR_OPEN_CURLY_BRACES', 400); define('T_CURLY_OPEN', 401); define('T_PAAMAYIM_NEKUDOTAYIM', 402); define('T_NAMESPACE', 375); define('T_NS_SEPARATOR', 403); define('T_ELLIPSIS', 404); define('T_DOUBLE_COLON', 402); /** * @since 7.4 */ define('T_FN', 348); define('T_BAD_CHARACTER', 405); /** * @since 8.0 */ define('T_NAME_FULLY_QUALIFIED', 314); /** * @since 8.0 */ define('T_NAME_RELATIVE', 315); /** * @since 8.0 */ define('T_NAME_QUALIFIED', 316); /** * @since 8.0 */ define('T_NULLSAFE_OBJECT_OPERATOR', 391); /** * @since 8.1 */ define('T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG', 288); /** * @since 8.1 */ define('T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG', 287); /** * @since 8.1 */ define('T_READONLY', 363); /** * @removed 7.0 */ define('T_CHARACTER', 315); /** * @since 8.4 */ define('T_PRIVATE_SET', 327); /** * @since 8.4 */ define('T_PROTECTED_SET', 328); /** * @since 8.4 */ define('T_PUBLIC_SET', 329); * Retrieves information about files cached in the file cache * @link https://secure.php.net/manual/en/function.wincache-fcache-fileinfo.php * @param bool $summaryonly [optional] *

    Controls whether the returned array will contain information about individual * cache entries along with the file cache summary.

    * @return array|false Array of meta data about file cache or FALSE on failure *

    The array returned by this function contains the following elements: *

      *
    • total_cache_uptime - total time in seconds that the file cache has been active
    • *
    • total_file_count - total number of files that are currently in the file cache
    • *
    • total_hit_count - number of times the files have been served from the file cache
    • *
    • total_miss_count - number of times the files have not been found in the file cache
    • *
    • file_entries - an array that contains the information about all the cached files: *
        *
      • file_name - absolute file name of the cached file
      • *
      • add_time - time in seconds since the file has been added to the file cache
      • *
      • use_time - time in seconds since the file has been accessed in the file cache
      • *
      • last_check - time in seconds since the file has been checked for modifications
      • *
      • hit_count - number of times the file has been served from the cache
      • *
      • file_size - size of the cached file in bytes
      • *
    • *

    */ function wincache_fcache_fileinfo($summaryonly = false) {} /** * (PHP 5.2+; PECL wincache >= 1.0.0)
    * Retrieves information about memory usage by file cache. * @link https://secure.php.net/manual/en/function.wincache-fcache-meminfo.php * @return array|false Array of meta data about file cache memory usage or FALSE on failure *

    The array returned by this function contains the following elements: *

      *
    • memory_total - amount of memory in bytes allocated for the file cache
    • *
    • memory_free - amount of free memory in bytes available for the file cache
    • *
    • num_used_blks - number of memory blocks used by the file cache
    • *
    • num_free_blks - number of free memory blocks available for the file cache
    • *
    • memory_overhead - amount of memory in bytes used for the file cache internal structures
    • *

    */ function wincache_fcache_meminfo() {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Obtains an exclusive lock on a given key. *

    The execution of the current script will be blocked until the lock can be * obtained. Once the lock is obtained, the other scripts that try to request the * lock by using the same key will be blocked, until the current script releases * the lock by using wincache_unlock().

    * @link https://secure.php.net/manual/en/function.wincache-lock.php * @param string $key Name of the key in the cache to get the lock on. * @param bool $isglobal [optional] *

    Controls whether the scope of the lock is system-wide or local. Local locks * are scoped to the application pool in IIS FastCGI case or to all php processes * that have the same parent process identifier.

    * @return bool Returns TRUE on success or FALSE on failure. */ function wincache_lock($key, $isglobal = false) {} /** * (PHP 5.2+; PECL wincache >= 1.0.0)
    * Retrieves information about opcode cache content and its usage * @link https://secure.php.net/manual/en/function.wincache-ocache-fileinfo.php * @param bool $summaryonly [optional] *

    Controls whether the returned array will contain information about individual * cache entries along with the opcode cache summary.

    * @return array|false Array of meta data about opcode cache or FALSE on failure *

    The array returned by this function contains the following elements: *

      *
    • total_cache_uptime - total time in seconds that the opcode cache has been active
    • *
    • total_file_count - total number of files that are currently in the opcode cache
    • *
    • total_hit_count - number of times the compiled opcode have been served from the cache
    • *
    • total_miss_count - number of times the compiled opcode have not been found in the cache
    • *
    • is_local_cache - true is the cache metadata is for a local cache instance, false * if the metadata is for the global cache
    • *
    • file_entries - an array that contains the information about all the cached files: *
        *
      • file_name - absolute file name of the cached file
      • *
      • add_time - time in seconds since the file has been added to the opcode cache
      • *
      • use_time - time in seconds since the file has been accessed in the opcode cache
      • *
      • last_check - time in seconds since the file has been checked for modifications
      • *
      • hit_count - number of times the file has been served from the cache
      • *
      • function_count - number of functions in the cached file
      • *
      • class_count - number of classes in the cached file
      • *
    • *

    */ function wincache_ocache_fileinfo($summaryonly = false) {} /** * (PHP 5.2+; PECL wincache >= 1.0.0)
    * Retrieves information about memory usage by opcode cache. * @link https://secure.php.net/manual/en/function.wincache-ocache-meminfo.php * @return array|false Array of meta data about opcode cache memory usage or FALSE on failure *

    The array returned by this function contains the following elements: *

      *
    • memory_total - amount of memory in bytes allocated for the opcode cache
    • *
    • memory_free - amount of free memory in bytes available for the opcode cache
    • *
    • num_used_blks - number of memory blocks used by the opcode cache
    • *
    • num_free_blks - number of free memory blocks available for the opcode cache
    • *
    • memory_overhead - amount of memory in bytes used for the opcode cache internal structures
    • *

    */ function wincache_ocache_meminfo() {} /** * (PHP 5.2+; PECL wincache >= 1.0.0)
    * Refreshes the cache entries for the files, whose names were passed in the input argument. *

    If no argument is specified then refreshes all the entries in the cache.

    * @link https://secure.php.net/manual/en/function.wincache-refresh-if-changed.php * @param array $files [optional] *

    An array of file names for files that need to be refreshed. An absolute * or relative file paths can be used.

    * @return bool Returns TRUE on success or FALSE on failure. */ function wincache_refresh_if_changed(array $files) {} /** * (PHP 5.2+; PECL wincache >= 1.0.0)
    * Retrieves information about cached mappings between relative file paths and * corresponding absolute file paths. * @link https://secure.php.net/manual/en/function.wincache-rplist-fileinfo.php * @return array|false Array of meta data about the resolve file path cache or FALSE on failure *

    The array returned by this function contains the following elements: *

      *
    • total_file_count - total number of file path mappings stored in the cache
    • *
    • rplist_entries - an array that contains the information about all the cached file paths: *
        *
      • resolve_path - path to a file
      • *
      • subkey_data - corresponding absolute path to a file
      • *
    • *

    */ function wincache_rplist_fileinfo() {} /** * (PHP 5.2+; PECL wincache >= 1.0.0)
    * Retrieves information about memory usage by resolve file path cache. * @link https://secure.php.net/manual/en/function.wincache-rplist-meminfo.php * @return array|false Array of meta data that describes memory usage by resolve file path cache. or FALSE on failure *

    The array returned by this function contains the following elements: *

      *
    • memory_total - amount of memory in bytes allocated for the resolve file path cache
    • *
    • memory_free - amount of free memory in bytes available for the resolve file path cache
    • *
    • num_used_blks - number of memory blocks used by the resolve file path cache
    • *
    • num_free_blks - number of free memory blocks available for the resolve file path cache
    • *
    • memory_overhead - amount of memory in bytes used for the internal structures of resolve file path cache
    • *

    */ function wincache_rplist_meminfo() {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Retrieves information about session cache content and its usage. * @link https://secure.php.net/manual/en/function.wincache-scache-info.php * @param bool $summaryonly [optional] *

    Controls whether the returned array will contain information about individual * cache entries along with the session cache summary.

    * @return array|false Array of meta data about session cache or FALSE on failure *

    The array returned by this function contains the following elements: *

      *
    • total_cache_uptime - total time in seconds that the session cache has been active
    • *
    • total_item_count - total number of elements that are currently in the session cache
    • *
    • is_local_cache - true is the cache metadata is for a local cache instance, false * if the metadata is for the global cache
    • *
    • total_hit_count - number of times the data has been served from the cache
    • *
    • total_miss_count - number of times the data has not been found in the cache
    • *
    • scache_entries - an array that contains the information about all the cached items: *
        *
      • key_name - name of the key which is used to store the data
      • *
      • value_type - type of value stored by the key
      • *
      • use_time - time in seconds since the file has been accessed in the opcode cache
      • *
      • last_check - time in seconds since the file has been checked for modifications
      • *
      • ttl_seconds - time remaining for the data to live in the cache, 0 meaning infinite
      • *
      • age_seconds - time elapsed from the time data has been added in the cache
      • *
      • hitcount - number of times data has been served from the cache
      • *
    • *

    */ function wincache_scache_info($summaryonly = false) {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Retrieves information about memory usage by session cache. * @link https://secure.php.net/manual/en/function.wincache-scache-meminfo.php * @return array|false Array of meta data about session cache memory usage or FALSE on failure *

    The array returned by this function contains the following elements: *

      *
    • memory_total - amount of memory in bytes allocated for the session cache
    • *
    • memory_free - amount of free memory in bytes available for the session cache
    • *
    • num_used_blks - number of memory blocks used by the session cache
    • *
    • num_free_blks - number of free memory blocks available for the session cache
    • *
    • memory_overhead - amount of memory in bytes used for the session cache internal structures
    • *

    */ function wincache_scache_meminfo() {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Adds a variable in user cache, only if this variable doesn't already exist in the cache. *

    The added variable remains in the user cache unless its time to live expires * or it is deleted by using wincache_ucache_delete() or wincache_ucache_clear() functions.

    * @link https://secure.php.net/manual/en/function.wincache-ucache-add.php * @param string $key

    Store the variable using this key name. If a variable with * same key is already present the function will fail and return FALSE. key is case * sensitive. To override the value even if key is present use wincache_ucache_set() * function instad. key can also take array of name => value pairs where names will * be used as keys. This can be used to add multiple values in the cache in one * operation, thus avoiding race condition.

    * @param mixed $value

    Value of a variable to store. Value supports all data * types except resources, such as file handles. This parameter is ignored if * first argument is an array. A general guidance is to pass NULL as value while * using array as key.

    * @param int $ttl [optional] *

    Time for the variable to live in the cache in seconds. After the value * specified in ttl has passed the stored variable will be deleted from the * cache. This parameter takes a default value of 0 which means the variable * will stay in the cache unless explicitly deleted by using wincache_ucache_delete() * or wincache_ucache_clear() functions.

    * @return bool If key is string, the function returns TRUE on success and FALSE on failure. *

    If key is an array, the function returns: *

      *
    • If all the name => value pairs in the array can be set, function returns an empty array;
    • *
    • If all the name => value pairs in the array cannot be set, function returns FALSE;
    • *
    • If some can be set while others cannot, function returns an array with name=>value pair * for which the addition failed in the user cache.
    • *

    */ function wincache_ucache_add($key, $value, $ttl = 0) {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Compares the variable associated with the key with old_value * and if it matches then assigns the new_value to it. * @link https://secure.php.net/manual/en/function.wincache-ucache-cas.php * @param string $key The key that is used to store the variable in the cache. key is case sensitive. * @param int $old_value Old value of the variable pointed by key in the user cache. * The value should be of type long, otherwise the function returns FALSE. * @param int $new_value New value which will get assigned to variable pointer by key * if a match is found. The value should be of type long, otherwise the function returns FALSE. * @return bool Returns TRUE on success or FALSE on failure. */ function wincache_ucache_cas($key, $old_value, $new_value) {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Clears/deletes all the values stored in the user cache. * @link https://secure.php.net/manual/en/function.wincache-ucache-clear.php * @return bool Returns TRUE on success or FALSE on failure. */ function wincache_ucache_clear() {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Decrements the value associated with the key by 1 or as specified by dec_by. * @link https://secure.php.net/manual/en/function.wincache-ucache-dec.php * @param string $key

    The key that was used to store the variable in the cache. * key is case sensitive.

    * @param int $dec_by

    The value by which the variable associated with the key will * get decremented. If the argument is a floating point number it will be truncated * to nearest integer. The variable associated with the key should be of type long, * otherwise the function fails and returns FALSE.

    * @param bool|null &$success [optional] *

    Will be set to TRUE on success and FALSE on failure.

    * @return int|false Returns the decremented value on success and FALSE on failure. */ function wincache_ucache_dec($key, $dec_by = 1, &$success) {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Deletes the elements in the user cache pointed by key. * @link https://secure.php.net/manual/en/function.wincache-ucache-delete.php * @param string|string[] $key

    The key that was used to store the variable in the cache. * key is case sensitive. key can be an array of keys.

    * @return bool Returns TRUE on success or FALSE on failure. *

    If key is an array then the function returns FALSE if every element of * the array fails to get deleted from the user cache, otherwise returns an * array which consists of all the keys that are deleted.

    */ function wincache_ucache_delete($key) {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Checks if a variable with the key exists in the user cache or not. * @link https://secure.php.net/manual/en/function.wincache-ucache-exists.php * @param string $key The key that was used to store the variable in the cache. key is case sensitive. * @return bool Returns TRUE if variable with the key exitsts, otherwise returns FALSE. */ function wincache_ucache_exists($key) {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Gets a variable stored in the user cache. * @link https://secure.php.net/manual/en/function.wincache-ucache-get.php * @param string|string[] $key

    The key that was used to store the variable in the cache. * key is case sensitive. key can be an array of keys. In this case the return * value will be an array of values of each element in the key array.

    * @param bool|null &$success [optional] *

    Will be set to TRUE on success and FALSE on failure.

    * @return mixed

    If key is a string, the function returns the value of the variable * stored with that key. The success is set to TRUE on success and to FALSE on failure.

    *

    The key is an array, the parameter success is always set to TRUE. The returned array * (name => value pairs) will contain only those name => value pairs for which the get * operation in user cache was successful. If none of the keys in the key array finds a * match in the user cache an empty array will be returned.

    */ function wincache_ucache_get($key, &$success) {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Increments the value associated with the key by 1 or as specified by inc_by. * @link https://secure.php.net/manual/en/function.wincache-ucache-inc.php * @param string $key

    The key that was used to store the variable in the cache. * key is case sensitive.

    * @param int $inc_by

    The value by which the variable associated with the key will * get incremented. If the argument is a floating point number it will be truncated * to nearest integer. The variable associated with the key should be of type long, * otherwise the function fails and returns FALSE.

    * @param bool|null &$success [optional] *

    Will be set to TRUE on success and FALSE on failure.

    * @return int|false Returns the incremented value on success and FALSE on failure. */ function wincache_ucache_inc($key, $inc_by = 1, &$success) {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Retrieves information about data stored in the user cache. * @link https://secure.php.net/manual/en/function.wincache-ucache-info.php * @param bool $summaryonly [optional] *

    Controls whether the returned array will contain information about * individual cache entries along with the user cache summary.

    * @param null|string $key [optional] *

    The key of an entry in the user cache. If specified then the returned array * will contain information only about that cache entry. If not specified and * summaryonly is set to false then the returned array will contain information * about all entries in the cache.

    * @return array|false Array of meta data about user cache or FALSE on failure *

    The array returned by this function contains the following elements: *

      *
    • total_cache_uptime - total time in seconds that the user cache has been active
    • *
    • total_item_count - total number of elements that are currently in the user cache
    • *
    • is_local_cache - true is the cache metadata is for a local cache instance, false * if the metadata is for the global cache
    • *
    • total_hit_count - number of times the data has been served from the cache
    • *
    • total_miss_count - number of times the data has not been found in the cache
    • *
    • ucache_entries - an array that contains the information about all the cached items: *
        *
      • key_name - name of the key which is used to store the data
      • *
      • value_type - type of value stored by the key
      • *
      • use_time - time in seconds since the file has been accessed in the opcode cache
      • *
      • last_check - time in seconds since the file has been checked for modifications
      • *
      • is_session - indicates if the data is a session variable
      • *
      • ttl_seconds - time remaining for the data to live in the cache, 0 meaning infinite
      • *
      • age_seconds - time elapsed from the time data has been added in the cache
      • *
      • hitcount - number of times data has been served from the cache
      • *
    • *

    */ function wincache_ucache_info(bool $summaryonly = false, $key = null) {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Retrieves information about memory usage by user cache. * @link https://secure.php.net/manual/en/function.wincache-ucache-meminfo.php * @return array|false Array of meta data about user cache memory usage or FALSE on failure *

    The array returned by this function contains the following elements: *

      *
    • memory_total - amount of memory in bytes allocated for the user cache
    • *
    • memory_free - amount of free memory in bytes available for the user cache
    • *
    • num_used_blks - number of memory blocks used by the user cache
    • *
    • num_free_blks - number of free memory blocks available for the user cache
    • *
    • memory_overhead - amount of memory in bytes used for the user cache internal structures
    • *

    */ function wincache_ucache_meminfo() {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Adds a variable in user cache and overwrites a variable if it already exists in the cache. *

    The added or updated variable remains in the user cache unless its time to * live expires or it is deleted by using wincache_ucache_delete() or * wincache_ucache_clear() functions.

    * @link https://secure.php.net/manual/en/function.wincache-ucache-set.php * @param string|string[] $key

    * Store the variable using this key name. If a variable with same key is already * present the function will overwrite the previous value with the new one. key * is case sensitive. key can also take array of name => value pairs where * names will be used as keys. This can be used to add multiple values in the * cache in one operation, thus avoiding race condition.

    * @param mixed $value

    * Value of a variable to store. Value supports all data types except resources, * such as file handles. This parameter is ignored if first argument is an array. * A general guidance is to pass NULL as value while using array as key.

    * @param int $ttl [optional]

    * Time for the variable to live in the cache in seconds. After the value specified * in ttl has passed the stored variable will be deleted from the cache. This * parameter takes a default value of 0 which means the variable will stay in the * cache unless explicitly deleted by using wincache_ucache_delete() or * wincache_ucache_clear() functions.

    * @return bool

    * If key is string, the function returns TRUE on success and FALSE on failure.

    *

    If key is an array, the function returns: *

      *
    • If all the name => value pairs in the array can be set, function * returns an empty array;
    • *
    • If all the name => value pairs in the array cannot be set, function * returns FALSE;
    • *
    • If some can be set while others cannot, function returns an array with * name=>value pair for which the addition failed in the user cache.
    • *

    */ function wincache_ucache_set($key, $value, $ttl = 0) {} /** * (PHP 5.2+; PECL wincache >= 1.1.0)
    * Releases an exclusive lock that was obtained on a given key by using wincache_lock(). *

    If any other process was blocked waiting for the lock on this key, that process will be able to obtain the lock.

    * @link https://secure.php.net/manual/en/function.wincache-unlock.php * @param string $key Name of the key in the cache to release the lock on. * @return bool Returns TRUE on success or FALSE on failure. */ function wincache_unlock($key) {} * Undocumented template parameter *

    * @return mixed */ function msgpack_unserialize($str, $object = null) {} /** * Alias of msgpack_serialize * @param mixed $value * @return string */ function msgpack_pack($value) {} /** * Alias of msgpack_unserialize * @param string $str * @param null|array|string|object $object

    * Undocumented template parameter *

    * @return mixed */ function msgpack_unpack($str, $object = null) {} class MessagePack { public const OPT_PHPONLY = -1001; /** * @param $opt [optional] */ public function __construct($opt) {} public function setOption($option, $value) {} public function pack($value) {} /** * @param $str * @param $object [optional] */ public function unpack($str, $object) {} public function unpacker() {} } class MessagePackUnpacker { /** * @param $opt [optional] */ public function __construct($opt) {} public function __destruct() {} public function setOption($option, $value) {} public function feed($str) {} /** * @param $str [optional] * @param $offset [optional] */ public function execute($str, &$offset) {} /** * @param $object [optional] */ public function data($object) {} public function reset() {} } * The imported style sheet as a DOMDocument or * SimpleXMLElement object. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function importStylesheet(#[LanguageLevelTypeAware(['8.0' => 'object'], default: '')] $stylesheet): bool {} /** * Transform to a DOMDocument * @link https://php.net/manual/en/xsltprocessor.transformtodoc.php * @param object $document The DOMDocument or SimpleXMLElement or libxml-compatible object to be transformed. * @param string|null $returnClass * @return DOMDocument|false The resulting DOMDocument or FALSE on error. */ #[TentativeType] public function transformToDoc( #[LanguageLevelTypeAware(['8.0' => 'object'], default: '')] $document, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $returnClass = null ): object|false {} /** * Transform to URI * @link https://php.net/manual/en/xsltprocessor.transformtouri.php * @param DOMDocument|SimpleXMLElement $document

    * The document to transform. *

    * @param string $uri

    * The target URI for the transformation. *

    * @return int the number of bytes written or FALSE if an error occurred. */ #[TentativeType] public function transformToUri( #[LanguageLevelTypeAware(['8.0' => 'object'], default: '')] $document, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $uri ): int {} /** * Transform to XML * @link https://php.net/manual/en/xsltprocessor.transformtoxml.php * @param DOMDocument|SimpleXMLElement $document

    * The transformed document. *

    * @return string|false|null The result of the transformation as a string or FALSE on error. */ #[TentativeType] public function transformToXml(#[LanguageLevelTypeAware(['8.0' => 'object'], default: '')] $document): string|false|null {} /** * Set value for a parameter * @link https://php.net/manual/en/xsltprocessor.setparameter.php * @param string $namespace

    * The namespace URI of the XSLT parameter. *

    * @param string $name

    * The local name of the XSLT parameter. *

    * @param string $value

    * The new value of the XSLT parameter. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function setParameter( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'array|string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $value = null ):bool {} /** * Get value of a parameter * @link https://php.net/manual/en/xsltprocessor.getparameter.php * @param string $namespace

    * The namespace URI of the XSLT parameter. *

    * @param string $name

    * The local name of the XSLT parameter. *

    * @return string|false The value of the parameter (as a string), or FALSE if it's not set. */ #[TentativeType] public function getParameter( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name ): string|false {} /** * Remove parameter * @link https://php.net/manual/en/xsltprocessor.removeparameter.php * @param string $namespace

    * The namespace URI of the XSLT parameter. *

    * @param string $name

    * The local name of the XSLT parameter. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function removeParameter( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $namespace, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name ): bool {} /** * Determine if PHP has EXSLT support * @link https://php.net/manual/en/xsltprocessor.hasexsltsupport.php * @return bool TRUE on success or FALSE on failure. * @since 5.0.4 */ #[TentativeType] public function hasExsltSupport(): bool {} /** * Enables the ability to use PHP functions as XSLT functions * @link https://php.net/manual/en/xsltprocessor.registerphpfunctions.php * @param array|string|null $functions [optional]

    * Use this parameter to only allow certain functions to be called from * XSLT. *

    *

    * This parameter can be either a string (a function name) or an array of * functions. *

    * @return void No value is returned. * @since 5.0.4 */ #[TentativeType] public function registerPHPFunctions(#[LanguageLevelTypeAware(['8.0' => 'array|string|null'], default: '')] $functions = null): void {} /** * Sets profiling output file * @link https://php.net/manual/en/xsltprocessor.setprofiling.php * @param string $filename

    * Path to the file to dump profiling information. *

    * @return bool TRUE on success or FALSE on failure. */ public function setProfiling(#[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $filename) {} /** * Set security preferences * @link https://php.net/manual/en/xsltprocessor.setsecurityprefs.php * @param int $preferences * @return int * @since 5.4 */ #[TentativeType] public function setSecurityPrefs(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $preferences): int {} /** * Get security preferences * @link https://php.net/manual/en/xsltprocessor.getsecurityprefs.php * @return int * @since 5.4 */ #[TentativeType] public function getSecurityPrefs(): int {} } define('XSL_CLONE_AUTO', 0); define('XSL_CLONE_NEVER', -1); define('XSL_CLONE_ALWAYS', 1); /** @link https://php.net/manual/en/xsl.constants.php */ define('XSL_SECPREF_NONE', 0); /** @link https://php.net/manual/en/xsl.constants.php */ define('XSL_SECPREF_READ_FILE', 2); /** @link https://php.net/manual/en/xsl.constants.php */ define('XSL_SECPREF_WRITE_FILE', 4); /** @link https://php.net/manual/en/xsl.constants.php */ define('XSL_SECPREF_CREATE_DIRECTORY', 8); /** @link https://php.net/manual/en/xsl.constants.php */ define('XSL_SECPREF_READ_NETWORK', 16); /** @link https://php.net/manual/en/xsl.constants.php */ define('XSL_SECPREF_WRITE_NETWORK', 32); /** @link https://php.net/manual/en/xsl.constants.php */ define('XSL_SECPREF_DEFAULT', 44); /** * libxslt version like 10117. Available as of PHP 5.1.2. * @link https://php.net/manual/en/xsl.constants.php */ define('LIBXSLT_VERSION', 10128); /** * libxslt version like 1.1.17. Available as of PHP 5.1.2. * @link https://php.net/manual/en/xsl.constants.php */ define('LIBXSLT_DOTTED_VERSION', "1.1.28"); /** * libexslt version like 813. Available as of PHP 5.1.2. * @link https://php.net/manual/en/xsl.constants.php */ define('LIBEXSLT_VERSION', 817); /** * libexslt version like 1.1.17. Available as of PHP 5.1.2. * @link https://php.net/manual/en/xsl.constants.php */ define('LIBEXSLT_DOTTED_VERSION', "1.1.28"); // End of xsl v.0.1 * The connection_string can be empty to use all default parameters, or it * can contain one or more parameter settings separated by whitespace. * Each parameter setting is in the form keyword = value. Spaces around * the equal sign are optional. To write an empty value or a value * containing spaces, surround it with single quotes, e.g., keyword = * 'a value'. Single quotes and backslashes within the value must be * escaped with a backslash, i.e., \' and \\. *

    *

    * The currently recognized parameter keywords are: * host, hostaddr, port, * dbname (defaults to value of user), * user, * password, connect_timeout, * options, tty (ignored), sslmode, * requiressl (deprecated in favor of sslmode), and * service. Which of these arguments exist depends * on your PostgreSQL version. *

    *

    * The options parameter can be used to set command line parameters * to be invoked by the server. *

    * @param int $flags

    * If PGSQL_CONNECT_FORCE_NEW is passed, then a new connection * is created, even if the connection_string is identical to * an existing connection. *

    * @return resource|false PostgreSQL connection resource on success, FALSE on failure. */ #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|false'], default: 'resource|false')] function pg_connect( string $connection_string, int $flags = 0, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] string $host = '', #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] string $port = '', #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] string $options = '', #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] string $tty = '', #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] string $dbname = '', ) {} /** * Open a persistent PostgreSQL connection * @link https://php.net/manual/en/function.pg-pconnect.php * @param string $connection_string

    * The connection_string can be empty to use all default parameters, or it * can contain one or more parameter settings separated by whitespace. * Each parameter setting is in the form keyword = value. Spaces around * the equal sign are optional. To write an empty value or a value * containing spaces, surround it with single quotes, e.g., keyword = * 'a value'. Single quotes and backslashes within the value must be * escaped with a backslash, i.e., \' and \\. *

    *

    * The currently recognized parameter keywords are: * host, hostaddr, port, * dbname, user, * password, connect_timeout, * options, tty (ignored), sslmode, * requiressl (deprecated in favor of sslmode), and * service. Which of these arguments exist depends * on your PostgreSQL version. *

    * @param int $flags

    * If PGSQL_CONNECT_FORCE_NEW is passed, then a new connection * is created, even if the connection_string is identical to * an existing connection. *

    * @return resource|false PostgreSQL connection resource on success, FALSE on failure. */ #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|false'], default: 'resource|false')] function pg_pconnect( string $connection_string, #[PhpStormStubsElementAvailable(from: '8.0')] int $flags = 0, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] string $host = '', #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] string $port = '', #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] string $options = '', #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] string $tty = '', #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] string $dbname = '', ) {} /** * Closes a PostgreSQL connection * @link https://php.net/manual/en/function.pg-close.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    */ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function pg_close(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null) {} /** * Poll the status of an in-progress asynchronous PostgreSQL connection attempt. * @link https://php.net/manual/en/function.pg-connect-poll.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @return int PGSQL_POLLING_FAILED, PGSQL_POLLING_READING, PGSQL_POLLING_WRITING, * PGSQL_POLLING_OK, or PGSQL_POLLING_ACTIVE. * @since 5.6 */ function pg_connect_poll( #[PhpStormStubsElementAvailable(from: '5.6', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection ): int {} /** * Get connection status * @link https://php.net/manual/en/function.pg-connection-status.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @return int PGSQL_CONNECTION_OK or * PGSQL_CONNECTION_BAD. */ function pg_connection_status(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection): int {} /** * Get connection is busy or not * @link https://php.net/manual/en/function.pg-connection-busy.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @return bool TRUE if the connection is busy, FALSE otherwise. */ function pg_connection_busy(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection): bool {} /** * Reset connection (reconnect) * @link https://php.net/manual/en/function.pg-connection-reset.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @return bool TRUE on success or FALSE on failure. */ function pg_connection_reset(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection): bool {} /** * Get a read only handle to the socket underlying a PostgreSQL connection * @link https://php.net/manual/en/function.pg-socket.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @return resource|false A socket resource on success or FALSE on failure. * @since 5.6 */ function pg_socket(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection) {} /** * Returns the host name associated with the connection * @link https://php.net/manual/en/function.pg-host.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @return string|false A string containing the name of the host the * connection is to, or FALSE on error. */ function pg_host(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null): string {} /** * Get the database name * @link https://php.net/manual/en/function.pg-dbname.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @return string|false A string containing the name of the database the * connection is to, or FALSE on error. */ function pg_dbname(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null): string {} /** * Return the port number associated with the connection * @link https://php.net/manual/en/function.pg-port.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @return string A string containing the port number of the database server the connection is to, or empty string on error. */ function pg_port(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null): string {} /** * Return the TTY name associated with the connection * @link https://php.net/manual/en/function.pg-tty.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @return string A string containing the debug TTY of * the connection, or FALSE on error. */ function pg_tty(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null): string {} /** * Get the options associated with the connection * @link https://php.net/manual/en/function.pg-options.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @return string A string containing the connection * options, or FALSE on error. */ function pg_options(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null): string {} /** * Returns an array with client, protocol and server version (when available) * @link https://php.net/manual/en/function.pg-version.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @return array an array with client, protocol * and server keys and values (if available). Returns * FALSE on error or invalid connection. */ #[ArrayShape(["client" => "string", "protocol" => "int", "server" => "string"])] function pg_version(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null): array {} /** * Ping database connection * @link https://php.net/manual/en/function.pg-ping.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @return bool TRUE on success or FALSE on failure. */ function pg_ping(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null): bool {} /** * Looks up a current parameter setting of the server. * @link https://php.net/manual/en/function.pg-parameter-status.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $name [optional]

    * Possible param_name values include server_version, * server_encoding, client_encoding, * is_superuser, session_authorization, * DateStyle, TimeZone, and * integer_datetimes. *

    * @return string|false A string containing the value of the parameter, FALSE on failure or invalid * param_name. */ function pg_parameter_status(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $name): string|false {} /** * Returns the current in-transaction status of the server. * @link https://php.net/manual/en/function.pg-transaction-status.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @return int The status can be PGSQL_TRANSACTION_IDLE (currently idle), * PGSQL_TRANSACTION_ACTIVE (a command is in progress), * PGSQL_TRANSACTION_INTRANS (idle, in a valid transaction block), * or PGSQL_TRANSACTION_INERROR (idle, in a failed transaction block). * PGSQL_TRANSACTION_UNKNOWN is reported if the connection is bad. * PGSQL_TRANSACTION_ACTIVE is reported only when a query * has been sent to the server and not yet completed. */ function pg_transaction_status(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection): int {} /** * Execute a query * @link https://php.net/manual/en/function.pg-query.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $query [optional]

    * The SQL statement or statements to be executed. When multiple statements are passed to the function, * they are automatically executed as one transaction, unless there are explicit BEGIN/COMMIT commands * included in the query string. However, using multiple transactions in one function call is not recommended. *

    *

    * String interpolation of user-supplied data is extremely dangerous and is * likely to lead to SQL * injection vulnerabilities. In most cases * pg_query_params should be preferred, passing * user-supplied values as parameters rather than substituting them into * the query string. *

    *

    * Any user-supplied data substituted directly into a query string should * be properly escaped. *

    * @return resource|false A query result resource on success or FALSE on failure. */ #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result|false'], default: 'resource|false')] function pg_query( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $query ) {} /** * Submits a command to the server and waits for the result, with the ability to pass parameters separately from the SQL command text. * @link https://php.net/manual/en/function.pg-query-params.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $query

    * The parameterized SQL statement. Must contain only a single statement. * (multiple statements separated by semi-colons are not allowed.) If any parameters * are used, they are referred to as $1, $2, etc. *

    *

    * User-supplied values should always be passed as parameters, not * interpolated into the query string, where they form possible * SQL injection * attack vectors and introduce bugs when handling data containing quotes. * If for some reason you cannot use a parameter, ensure that interpolated * values are properly escaped. *

    * @param array $params [optional]

    * An array of parameter values to substitute for the $1, $2, etc. placeholders * in the original prepared query string. The number of elements in the array * must match the number of placeholders. *

    *

    * Values intended for bytea fields are not supported as * parameters. Use pg_escape_bytea instead, or use the * large object functions. *

    * @return resource|false A query result resource on success or FALSE on failure. */ #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result|false'], default: 'resource|false')] function pg_query_params( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $query = '', #[PhpStormStubsElementAvailable(from: '8.0')] $query, array $params ) {} /** * Submits a request to create a prepared statement with the * given parameters, and waits for completion. * @link https://php.net/manual/en/function.pg-prepare.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $statement_name

    * The name to give the prepared statement. Must be unique per-connection. If * "" is specified, then an unnamed statement is created, overwriting any * previously defined unnamed statement. *

    * @param string $query [optional]

    * The parameterized SQL statement. Must contain only a single statement. * (multiple statements separated by semi-colons are not allowed.) If any parameters * are used, they are referred to as $1, $2, etc. *

    * @return resource|false A query result resource on success or FALSE on failure. */ #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result|false'], default: 'resource|false')] function pg_prepare( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] string $statement_name = '', #[PhpStormStubsElementAvailable(from: '8.0')] string $statement_name, string $query ) {} /** * Sends a request to execute a prepared statement with given parameters, and waits for the result. * @link https://php.net/manual/en/function.pg-execute.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $statement_name

    * The name of the prepared statement to execute. if * "" is specified, then the unnamed statement is executed. The name must have * been previously prepared using pg_prepare, * pg_send_prepare or a PREPARE SQL * command. *

    * @param array $params [optional]

    * An array of parameter values to substitute for the $1, $2, etc. placeholders * in the original prepared query string. The number of elements in the array * must match the number of placeholders. *

    *

    * Elements are converted to strings by calling this function. *

    * @return resource|false A query result resource on success or FALSE on failure. */ #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result|false'], default: 'resource|false')] function pg_execute( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] string $statement_name = '', #[PhpStormStubsElementAvailable(from: '8.0')] $statement_name, array $params ) {} /** * Sends asynchronous query * @link https://php.net/manual/en/function.pg-send-query.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @param string $query

    * The SQL statement or statements to be executed. *

    *

    * Data inside the query should be properly escaped. *

    * @return int|bool TRUE on success or FALSE on failure.

    *

    * Use pg_get_result to determine the query result. */ function pg_send_query( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $query ): int|bool {} /** * Submits a command and separate parameters to the server without waiting for the result(s). * @link https://php.net/manual/en/function.pg-send-query-params.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @param string $query

    * The parameterized SQL statement. Must contain only a single statement. * (multiple statements separated by semi-colons are not allowed.) If any parameters * are used, they are referred to as $1, $2, etc. *

    * @param array $params

    * An array of parameter values to substitute for the $1, $2, etc. placeholders * in the original prepared query string. The number of elements in the array * must match the number of placeholders. *

    * @return int|bool TRUE on success or FALSE on failure.

    *

    * Use pg_get_result to determine the query result. */ function pg_send_query_params( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $query, array $params ): int|bool {} /** * Sends a request to create a prepared statement with the given parameters, without waiting for completion. * @link https://php.net/manual/en/function.pg-send-prepare.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $statement_name

    * The name to give the prepared statement. Must be unique per-connection. If * "" is specified, then an unnamed statement is created, overwriting any * previously defined unnamed statement. *

    * @param string $query

    * The parameterized SQL statement. Must contain only a single statement. * (multiple statements separated by semi-colons are not allowed.) If any parameters * are used, they are referred to as $1, $2, etc. *

    * @return int|bool TRUE on success, FALSE on failure. Use pg_get_result * to determine the query result. */ function pg_send_prepare( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $statement_name, string $query ): int|bool {} /** * Sends a request to execute a prepared statement with given parameters, without waiting for the result(s). * @link https://php.net/manual/en/function.pg-send-execute.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $statement_name

    * The name of the prepared statement to execute. if * "" is specified, then the unnamed statement is executed. The name must have * been previously prepared using pg_prepare, * pg_send_prepare or a PREPARE SQL * command. *

    * @param array $params

    * An array of parameter values to substitute for the $1, $2, etc. placeholders * in the original prepared query string. The number of elements in the array * must match the number of placeholders. *

    * @return int|bool TRUE on success, FALSE on failure. Use pg_get_result * to determine the query result. */ function pg_send_execute( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $statement_name, array $params ): int|bool {} /** * Cancel an asynchronous query * @link https://php.net/manual/en/function.pg-cancel-query.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @return bool TRUE on success or FALSE on failure. */ function pg_cancel_query(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection): bool {} /** * Returns values from a result resource * @link https://php.net/manual/en/function.pg-fetch-result.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $row

    * Row number in result to fetch. Rows are numbered from 0 upwards. If omitted, * next row is fetched. *

    * @param mixed $field [optional]

    * A string representing the name of the field (column) to fetch, otherwise * an int representing the field number to fetch. Fields are * numbered from 0 upwards. *

    * @return string|false|null Boolean is returned as "t" or "f". All * other types, including arrays are returned as strings formatted * in the same default PostgreSQL manner that you would see in the * psql program. Database NULL * values are returned as NULL. *

    *

    * FALSE is returned if row exceeds the number * of rows in the set, or on any other error. */ function pg_fetch_result( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $row = 0, #[PhpStormStubsElementAvailable(from: '8.0')] $row, string|int $field ): string|false|null {} /** * Get a row as an enumerated array * @link https://php.net/manual/en/function.pg-fetch-row.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $row [optional]

    * Row number in result to fetch. Rows are numbered from 0 upwards. If * omitted or NULL, the next row is fetched. *

    * @param int $mode [optional] * @return array|false An array, indexed from 0 upwards, with each value * represented as a string. Database NULL * values are returned as NULL. *

    *

    * FALSE is returned if row exceeds the number * of rows in the set, there are no more rows, or on any other error. */ function pg_fetch_row(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, ?int $row = null, int $mode = 2): array|false {} /** * Fetch a row as an associative array * @link https://php.net/manual/en/function.pg-fetch-assoc.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $row [optional]

    * Row number in result to fetch. Rows are numbered from 0 upwards. If * omitted or NULL, the next row is fetched. *

    * @return array|false An array indexed associatively (by field name). * Each value in the array is represented as a * string. Database NULL * values are returned as NULL. *

    *

    * FALSE is returned if row exceeds the number * of rows in the set, there are no more rows, or on any other error. */ function pg_fetch_assoc(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, ?int $row = null): array|false {} /** * Fetch a row as an array * @link https://php.net/manual/en/function.pg-fetch-array.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $row [optional]

    * Row number in result to fetch. Rows are numbered from 0 upwards. If * omitted or NULL, the next row is fetched. *

    * @param int $mode [optional]

    * An optional parameter that controls * how the returned array is indexed. * result_type is a constant and can take the * following values: PGSQL_ASSOC, * PGSQL_NUM and PGSQL_BOTH. * Using PGSQL_NUM, pg_fetch_array * will return an array with numerical indices, using * PGSQL_ASSOC it will return only associative indices * while PGSQL_BOTH, the default, will return both * numerical and associative indices. *

    * @return array|false An array indexed numerically (beginning with 0) or * associatively (indexed by field name), or both. * Each value in the array is represented as a * string. Database NULL * values are returned as NULL. *

    *

    * FALSE is returned if row exceeds the number * of rows in the set, there are no more rows, or on any other error. */ function pg_fetch_array(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, ?int $row = null, int $mode = PGSQL_BOTH): array|false {} /** * Fetch a row as an object * @link https://php.net/manual/en/function.pg-fetch-object.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int|null $row [optional]

    * Row number in result to fetch. Rows are numbered from 0 upwards. If * omitted or NULL, the next row is fetched. *

    * @param string $class [optional]

    * Ignored and deprecated. *

    * @param array $constructor_args [optional]

    *

    * @return object|false An object with one attribute for each field * name in the result. Database NULL * values are returned as NULL. *

    *

    * FALSE is returned if row exceeds the number * of rows in the set, there are no more rows, or on any other error. */ function pg_fetch_object( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, ?int $row = null, string $class = 'stdClass', #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $l = null, array $constructor_args = [] ): object|false {} /** * Fetches all rows from a result as an array * @link https://php.net/manual/en/function.pg-fetch-all.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $mode [optional]

    * An optional parameter that controls * how the returned array is indexed. * result_type is a constant and can take the * following values: PGSQL_ASSOC, * PGSQL_NUM and PGSQL_BOTH. * Using PGSQL_NUM, pg_fetch_array * will return an array with numerical indices, using * PGSQL_ASSOC it will return only associative indices * while PGSQL_BOTH, the default, will return both * numerical and associative indices. *

    * @return array|false An array with all rows in the result. Each row is an array * of field values indexed by field name. *

    *

    * FALSE is returned if there are no rows in the result, or on any * other error. */ #[LanguageLevelTypeAware(['8.0' => 'array'], default: 'array|false')] function pg_fetch_all(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $mode = PGSQL_ASSOC) {} /** * Fetches all rows in a particular result column as an array * @link https://php.net/manual/en/function.pg-fetch-all-columns.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $field [optional]

    * Column number, zero-based, to be retrieved from the result resource. Defaults * to the first column if not specified. *

    * @return array An array with all values in the result column. *

    * FALSE is returned if column is larger than the number * of columns in the result, or on any other error. *

    */ function pg_fetch_all_columns(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $field = 0): array {} /** * Returns number of affected records (tuples) * @link https://php.net/manual/en/function.pg-affected-rows.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @return int The number of rows affected by the query. If no tuple is * affected, it will return 0. */ function pg_affected_rows(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result): int {} /** * Get asynchronous query result * @link https://php.net/manual/en/function.pg-get-result.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @return resource|false The result resource, or FALSE if no more results are available. */ #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result|false'], default: 'resource|false')] function pg_get_result(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection) {} /** * Set internal row offset in result resource * @link https://php.net/manual/en/function.pg-result-seek.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $row

    * Row to move the internal offset to in the result resource. * Rows are numbered starting from zero. *

    * @return bool TRUE on success or FALSE on failure. */ function pg_result_seek(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $row): bool {} /** * Get status of query result * @link https://php.net/manual/en/function.pg-result-status.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $mode [optional]

    * Either PGSQL_STATUS_LONG to return the numeric status * of the result, or PGSQL_STATUS_STRING * to return the command tag of the result. * If not specified, PGSQL_STATUS_LONG is the default. *

    * @return string|int Possible return values are PGSQL_EMPTY_QUERY, * PGSQL_COMMAND_OK, PGSQL_TUPLES_OK, PGSQL_COPY_OUT, * PGSQL_COPY_IN, PGSQL_BAD_RESPONSE, PGSQL_NONFATAL_ERROR and * PGSQL_FATAL_ERROR if PGSQL_STATUS_LONG is * specified. Otherwise, a string containing the PostgreSQL command tag is returned. */ function pg_result_status(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $mode = PGSQL_STATUS_LONG): string|int {} /** * Free result memory * @link https://php.net/manual/en/function.pg-free-result.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @return bool TRUE on success or FALSE on failure. */ function pg_free_result(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result): bool {} /** * Returns the last row's OID * @link https://php.net/manual/en/function.pg-last-oid.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @return string|int|false A string containing the OID assigned to the most recently inserted * row in the specified connection, or FALSE on error or * no available OID. */ function pg_last_oid(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result): string|int|false {} /** * Returns the number of rows in a result * @link https://php.net/manual/en/function.pg-num-rows.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @return int The number of rows in the result. On error, -1 is returned. */ function pg_num_rows(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result): int {} /** * Returns the number of fields in a result * @link https://php.net/manual/en/function.pg-num-fields.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @return int The number of fields (columns) in the result. On error, -1 is returned. */ function pg_num_fields(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result): int {} /** * Returns the name of a field * @link https://php.net/manual/en/function.pg-field-name.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $field

    * Field number, starting from 0. *

    * @return string|false The field name, or FALSE on error. */ function pg_field_name(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $field): string {} /** * Returns the field number of the named field * @link https://php.net/manual/en/function.pg-field-num.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param string $field

    * The name of the field. *

    * @return int The field number (numbered from 0), or -1 on error. */ function pg_field_num(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, string $field): int {} /** * Returns the internal storage size of the named field * @link https://php.net/manual/en/function.pg-field-size.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $field

    * Field number, starting from 0. *

    * @return int The internal field storage size (in bytes). -1 indicates a variable * length field. FALSE is returned on error. */ function pg_field_size(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $field): int {} /** * Returns the type name for the corresponding field number * @link https://php.net/manual/en/function.pg-field-type.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $field

    * Field number, starting from 0. *

    * @return string|false A string containing the base name of the field's type, or FALSE * on error. */ function pg_field_type(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $field): string {} /** * Returns the type ID (OID) for the corresponding field number * @link https://php.net/manual/en/function.pg-field-type-oid.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $field

    * Field number, starting from 0. *

    * @return string|int The OID of the field's base type. FALSE is returned on error. */ function pg_field_type_oid(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $field): string|int {} /** * Returns the printed length * @link https://php.net/manual/en/function.pg-field-prtlen.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $row * @param mixed $field [optional] * @return int|false The field printed length, or FALSE on error. */ function pg_field_prtlen( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $row = 0, #[PhpStormStubsElementAvailable(from: '8.0')] $row, string|int $field ): int|false {} /** * Test if a field is SQL NULL * @link https://php.net/manual/en/function.pg-field-is-null.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $row

    * Row number in result to fetch. Rows are numbered from 0 upwards. If omitted, * current row is fetched. *

    * @param mixed $field [optional]

    * Field number (starting from 0) as an integer or * the field name as a string. *

    * @return int|false 1 if the field in the given row is SQL NULL, 0 * if not. FALSE is returned if the row is out of range, or upon any other error. */ function pg_field_is_null( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $row = 0, #[PhpStormStubsElementAvailable(from: '8.0')] $row, string|int $field ): int|false {} /** * Returns the name or oid of the tables field * @link https://php.net/manual/en/function.pg-field-table.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @param int $field

    * Field number, starting from 0. *

    * @param bool $oid_only [optional]

    * By default the tables name that field belongs to is returned but * if oid_only is set to TRUE, then the * oid will instead be returned. *

    * @return string|int|false On success either the fields table name or oid. Or, FALSE on failure. */ function pg_field_table(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $field, bool $oid_only = false): string|int|false {} /** * Gets SQL NOTIFY message * @link https://php.net/manual/en/function.pg-get-notify.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @param int $mode [optional]

    * An optional parameter that controls * how the returned array is indexed. * result_type is a constant and can take the * following values: PGSQL_ASSOC, * PGSQL_NUM and PGSQL_BOTH. * Using PGSQL_NUM, pg_get_notify * will return an array with numerical indices, using * PGSQL_ASSOC it will return only associative indices * while PGSQL_BOTH, the default, will return both * numerical and associative indices. *

    * @return array|false An array containing the NOTIFY message name and backend PID. * Otherwise if no NOTIFY is waiting, then FALSE is returned. */ #[ArrayShape(["message" => "string", "pid" => "int", "payload" => "string"])] function pg_get_notify( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, int $mode = 1 ): array|false {} /** * Gets the backend's process ID * @link https://php.net/manual/en/function.pg-get-pid.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @return int The backend database process ID. */ function pg_get_pid( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, ): int {} /** * Get error message associated with result * @link https://php.net/manual/en/function.pg-result-error.php * @param resource $result

    * PostgreSQL query result resource, returned by pg_query, * pg_query_params or pg_execute * (among others). *

    * @return string|false a string if there is an error associated with the * result parameter, FALSE otherwise. */ function pg_result_error(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result): string|false {} /** * Returns an individual field of an error report. * @link https://php.net/manual/en/function.pg-result-error-field.php * @param resource $result

    * A PostgreSQL query result resource from a previously executed * statement. *

    * @param int $field_code

    * Possible fieldcode values are: PGSQL_DIAG_SEVERITY, * PGSQL_DIAG_SQLSTATE, PGSQL_DIAG_MESSAGE_PRIMARY, * PGSQL_DIAG_MESSAGE_DETAIL, * PGSQL_DIAG_MESSAGE_HINT, PGSQL_DIAG_STATEMENT_POSITION, * PGSQL_DIAG_INTERNAL_POSITION (PostgreSQL 8.0+ only), * PGSQL_DIAG_INTERNAL_QUERY (PostgreSQL 8.0+ only), * PGSQL_DIAG_CONTEXT, PGSQL_DIAG_SOURCE_FILE, * PGSQL_DIAG_SOURCE_LINE or * PGSQL_DIAG_SOURCE_FUNCTION. *

    * @return string|null|false A string containing the contents of the error field, NULL if the field does not exist or FALSE * on failure. */ function pg_result_error_field( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $field_code ): string|false|null {} /** * Get the last error message string of a connection * @link https://php.net/manual/en/function.pg-last-error.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @return string A string containing the last error message on the * given connection, or FALSE on error. */ function pg_last_error(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null): string {} /** * Returns the last notice message from PostgreSQL server * @link https://php.net/manual/en/function.pg-last-notice.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @param int $mode [optional]

    * One of PGSQL_NOTICE_LAST (to return last notice), * PGSQL_NOTICE_ALL (to return all notices), or * PGSQL_NOTICE_CLEAR (to clear notices). *

    * @return array|string|bool A string containing the last notice on the * given connection with PGSQL_NOTICE_LAST, * an array with PGSQL_NOTICE_ALL, * a bool with PGSQL_NOTICE_CLEAR, or * FALSE on error. */ function pg_last_notice(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, int $mode = PGSQL_NOTICE_LAST): array|string|bool {} /** * Send a NULL-terminated string to PostgreSQL backend * @link https://php.net/manual/en/function.pg-put-line.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $query [optional]

    * A line of text to be sent directly to the PostgreSQL backend. A NULL * terminator is added automatically. *

    * @return bool TRUE on success or FALSE on failure. */ function pg_put_line( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $query ): bool {} /** * Sync with PostgreSQL backend * @link https://php.net/manual/en/function.pg-end-copy.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @return bool TRUE on success or FALSE on failure. */ function pg_end_copy(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null): bool {} /** * Copy a table to an array * @link https://php.net/manual/en/function.pg-copy-to.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @param string $table_name

    * Name of the table from which to copy the data into rows. *

    * @param string $separator [optional]

    * The token that separates values for each field in each element of * rows. Default is TAB. *

    * @param string $null_as [optional]

    * How SQL NULL values are represented in the * rows. Default is \N ("\\N"). *

    * @return array|false An array with one element for each line of COPY data. * It returns FALSE on failure. */ function pg_copy_to( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $table_name, string $separator = ' ', string $null_as = '\\\\N' ): array|false {} /** * Insert records into a table from an array * @link https://php.net/manual/en/function.pg-copy-from.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @param string $table_name

    * Name of the table into which to copy the rows. *

    * @param array $rows

    * An array of data to be copied into table_name. * Each value in rows becomes a row in table_name. * Each value in rows should be a delimited string of the values * to insert into each field. Values should be linefeed terminated. *

    * @param string $separator [optional]

    * The token that separates values for each field in each element of * rows. Default is TAB. *

    * @param string $null_as [optional]

    * How SQL NULL values are represented in the * rows. Default is \N ("\\N"). *

    * @return bool TRUE on success or FALSE on failure. */ function pg_copy_from( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $table_name, array $rows, string $separator = ' ', string $null_as = '\\\\N' ): bool {} /** * Enable tracing a PostgreSQL connection * @link https://php.net/manual/en/function.pg-trace.php * @param string $filename

    * The full path and file name of the file in which to write the * trace log. Same as in fopen. *

    * @param string $mode [optional]

    * An optional file access mode, same as for fopen. *

    * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param int $trace_mode Since PHP 8.3 optional trace mode * @return bool TRUE on success or FALSE on failure. */ function pg_trace( string $filename, string $mode = "w", #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.3')] int $trace_mode = 0 ): bool {} /** * Disable tracing of a PostgreSQL connection * @link https://php.net/manual/en/function.pg-untrace.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    */ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function pg_untrace(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null) {} /** * Create a large object * @link https://php.net/manual/en/function.pg-lo-create.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param mixed $oid [optional]

    * If an object_id is given the function * will try to create a large object with this id, else a free * object id is assigned by the server. The parameter * was added in PHP 5.3 and relies on functionality that first * appeared in PostgreSQL 8.1. *

    * @return string|int|false A large object OID or FALSE on error. */ function pg_lo_create(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, $oid): string|int|false {} /** * Delete a large object * @link https://php.net/manual/en/function.pg-lo-unlink.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param int $oid [optional]

    * The OID of the large object in the database. *

    * @return bool TRUE on success or FALSE on failure. */ function pg_lo_unlink( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, $oid ): bool {} /** * Open a large object * @link https://php.net/manual/en/function.pg-lo-open.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param int $oid [optional]

    * The OID of the large object in the database. *

    * @param string $mode [optional]

    * Can be either "r" for read-only, "w" for write only or "rw" for read and * write. *

    * @return resource|false A large object resource or FALSE on error. */ #[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob|false'], default: 'resource|false')] function pg_lo_open( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, $oid, string $mode ) {} /** * Close a large object * @link https://php.net/manual/en/function.pg-lo-close.php * @param resource $lob * @return bool TRUE on success or FALSE on failure. */ function pg_lo_close(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob'], default: 'resource')] $lob): bool {} /** * Read a large object * @link https://php.net/manual/en/function.pg-lo-read.php * @param resource $lob

    * PostgreSQL large object (LOB) resource, returned by pg_lo_open. *

    * @param int $length [optional]

    * An optional maximum number of bytes to return. *

    * @return string|false A string containing len bytes from the * large object, or FALSE on error. */ function pg_lo_read(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob'], default: 'resource')] $lob, int $length = 8192): string|false {} /** * Write to a large object * @link https://php.net/manual/en/function.pg-lo-write.php * @param resource $lob

    * PostgreSQL large object (LOB) resource, returned by pg_lo_open. *

    * @param string $data

    * The data to be written to the large object. If len is * specified and is less than the length of data, only * len bytes will be written. *

    * @param int $length [optional]

    * An optional maximum number of bytes to write. Must be greater than zero * and no greater than the length of data. Defaults to * the length of data. *

    * @return int|false The number of bytes written to the large object, or FALSE on error. */ function pg_lo_write(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob'], default: 'resource')] $lob, string $data, ?int $length = null): int|false {} /** * Reads an entire large object and send straight to browser * @link https://php.net/manual/en/function.pg-lo-read-all.php * @param resource $lob

    * PostgreSQL large object (LOB) resource, returned by pg_lo_open. *

    * @return int|false Number of bytes read or FALSE on error. */ function pg_lo_read_all(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob'], default: 'resource')] $lob): int {} /** * Import a large object from file * @link https://php.net/manual/en/function.pg-lo-import.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $pathname

    * The full path and file name of the file on the client * filesystem from which to read the large object data. *

    * @param mixed $object_id [optional]

    * If an object_id is given the function * will try to create a large object with this id, else a free * object id is assigned by the server. The parameter * was added in PHP 5.3 and relies on functionality that first * appeared in PostgreSQL 8.1. *

    * @return string|int|false The OID of the newly created large object, or * FALSE on failure. */ function pg_lo_import( #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, $pathname, $object_id = null ): string|int|false {} /** * Export a large object to file * @link https://php.net/manual/en/function.pg-lo-export.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param int $oid

    * The OID of the large object in the database. *

    * @param string $pathname

    * The full path and file name of the file in which to write the * large object on the client filesystem. *

    * @return bool TRUE on success or FALSE on failure. */ function pg_lo_export( #[PhpStormStubsElementAvailable('8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, $oid, $pathname ): bool {} /** * Seeks position within a large object * @link https://php.net/manual/en/function.pg-lo-seek.php * @param resource $lob

    * PostgreSQL large object (LOB) resource, returned by pg_lo_open. *

    * @param int $offset

    * The number of bytes to seek. *

    * @param int $whence [optional]

    * One of the constants PGSQL_SEEK_SET (seek from object start), * PGSQL_SEEK_CUR (seek from current position) * or PGSQL_SEEK_END (seek from object end) . *

    * @return bool TRUE on success or FALSE on failure. */ function pg_lo_seek(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob'], default: 'resource')] $lob, int $offset, int $whence = PGSQL_SEEK_CUR): bool {} /** * Returns current seek position a of large object * @link https://php.net/manual/en/function.pg-lo-tell.php * @param resource $lob

    * PostgreSQL large object (LOB) resource, returned by pg_lo_open. *

    * @return int The current seek offset (in number of bytes) from the beginning of the large * object. If there is an error, the return value is negative. */ function pg_lo_tell(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob'], default: 'resource')] $lob): int {} /** * Truncates a large object * @link https://www.php.net/manual/en/function.pg-lo-truncate.php * @param resource $lob

    * PostgreSQL large object (LOB) resource, returned by pg_lo_open. *

    * @param int $size The number of bytes to truncate. * @return bool Returns true on success or false on failure. */ function pg_lo_truncate( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob'], default: 'resource')] $lob, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] int $size = 0, #[PhpStormStubsElementAvailable(from: '8.0')] int $size ): bool {} /** * Escape a string for query * @link https://php.net/manual/en/function.pg-escape-string.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $string [optional]

    * A string containing text to be escaped. *

    * @return string A string containing the escaped data. */ function pg_escape_string( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $string ): string {} /** * Escape a string for insertion into a bytea field * @link https://php.net/manual/en/function.pg-escape-bytea.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $string [optional]

    * A string containing text or binary data to be inserted into a bytea * column. *

    * @return string A string containing the escaped data. */ function pg_escape_bytea( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $string ): string {} /** * Escape a identifier for insertion into a text field * @link https://php.net/manual/en/function.pg-escape-identifier.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $string [optional]

    * A string containing text to be escaped. *

    * @return string|false A string containing the escaped data. * @since 5.4.4 */ function pg_escape_identifier( #[PhpStormStubsElementAvailable(from: '5.4', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $string ): string|false {} /** * Escape a literal for insertion into a text field * @link https://php.net/manual/en/function.pg-escape-literal.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $string [optional]

    * A string containing text to be escaped. *

    * @return string|false A string containing the escaped data. * @since 5.4.4 */ function pg_escape_literal( #[PhpStormStubsElementAvailable(from: '5.4', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $string ): string|false {} /** * Unescape binary for bytea type * @link https://php.net/manual/en/function.pg-unescape-bytea.php * @param string $string

    * A string containing PostgreSQL bytea data to be converted into * a PHP binary string. *

    * @return string A string containing the unescaped data. */ function pg_unescape_bytea(string $string): string {} /** * Determines the verbosity of messages returned by pg_last_error * and pg_result_error. * @link https://php.net/manual/en/function.pg-set-error-verbosity.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param int $verbosity [optional]

    * The required verbosity: PGSQL_ERRORS_TERSE, * PGSQL_ERRORS_DEFAULT * or PGSQL_ERRORS_VERBOSE. *

    * @return int|false The previous verbosity level: PGSQL_ERRORS_TERSE, * PGSQL_ERRORS_DEFAULT * or PGSQL_ERRORS_VERBOSE. */ function pg_set_error_verbosity( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, int $verbosity ): int|false {} /** * Gets the client encoding * @link https://php.net/manual/en/function.pg-client-encoding.php * @param resource $connection [optional]

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @return string|false The client encoding, or FALSE on error. */ function pg_client_encoding(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection = null): string {} /** * Set the client encoding * @link https://php.net/manual/en/function.pg-set-client-encoding.php * @param resource $connection

    * PostgreSQL database connection resource. When * connection is not present, the default connection * is used. The default connection is the last connection made by * pg_connect or pg_pconnect. *

    * @param string $encoding [optional]

    * The required client encoding. One of SQL_ASCII, EUC_JP, * EUC_CN, EUC_KR, EUC_TW, * UNICODE, MULE_INTERNAL, LATINX (X=1...9), * KOI8, WIN, ALT, SJIS, * BIG5 or WIN1250. *

    *

    * The exact list of available encodings depends on your PostgreSQL version, so check your * PostgreSQL manual for a more specific list. *

    * @return int 0 on success or -1 on error. */ function pg_set_client_encoding( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $encoding ): int {} /** * Get meta data for table * @link https://php.net/manual/en/function.pg-meta-data.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @param string $table_name

    * The name of the table. *

    * @return array|false An array of the table definition, or FALSE on error. */ function pg_meta_data( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $table_name, #[PhpStormStubsElementAvailable(from: '8.0')] bool $extended = false ): array|false {} /** * Convert associative array values into suitable for SQL statement * @link https://php.net/manual/en/function.pg-convert.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @param string $table_name

    * Name of the table against which to convert types. *

    * @param array $values

    * Data to be converted. *

    * @param int $flags [optional]

    * Any number of PGSQL_CONV_IGNORE_DEFAULT, * PGSQL_CONV_FORCE_NULL or * PGSQL_CONV_IGNORE_NOT_NULL, combined. *

    * @return array|false An array of converted values, or FALSE on error. */ function pg_convert( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $table_name, array $values, int $flags = 0 ): array|false {} /** * Insert array into table * @link https://php.net/manual/en/function.pg-insert.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @param string $table_name

    * Name of the table into which to insert rows. The table table_name must at least * have as many columns as assoc_array has elements. *

    * @param array $values

    * An array whose keys are field names in the table table_name, * and whose values are the values of those fields that are to be inserted. *

    * @param int $flags [optional]

    * Any number of PGSQL_CONV_OPTS, * PGSQL_DML_NO_CONV, * PGSQL_DML_EXEC, * PGSQL_DML_ASYNC or * PGSQL_DML_STRING combined. If PGSQL_DML_STRING is part of the * options then query string is returned. *

    * @return mixed TRUE on success or FALSE on failure. Returns string if PGSQL_DML_STRING is passed * via options. */ #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result|string|bool'], default: 'resource|string|bool')] function pg_insert( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $table_name, array $values, int $flags = PGSQL_DML_EXEC ) {} /** * Update table * @link https://php.net/manual/en/function.pg-update.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @param string $table_name

    * Name of the table into which to update rows. *

    * @param array $values

    * An array whose keys are field names in the table table_name, * and whose values are what matched rows are to be updated to. *

    * @param array $conditions

    * An array whose keys are field names in the table table_name, * and whose values are the conditions that a row must meet to be updated. *

    * @param int $flags [optional]

    * Any number of PGSQL_CONV_OPTS, * PGSQL_DML_NO_CONV, * PGSQL_DML_EXEC or * PGSQL_DML_STRING combined. If PGSQL_DML_STRING is part of the * options then query string is returned. *

    * @return string|bool TRUE on success or FALSE on failure. Returns string if PGSQL_DML_STRING is passed * via options. */ function pg_update( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $table_name, array $values, array $conditions, int $flags = PGSQL_DML_EXEC ): string|bool {} /** * Deletes records * @link https://php.net/manual/en/function.pg-delete.php * @param resource $connection

    * PostgreSQL database connection resource. *

    * @param string $table_name

    * Name of the table from which to delete rows. *

    * @param array $conditions

    * An array whose keys are field names in the table table_name, * and whose values are the values of those fields that are to be deleted. *

    * @param int $flags [optional]

    * Any number of PGSQL_CONV_FORCE_NULL, * PGSQL_DML_NO_CONV, * PGSQL_DML_EXEC or * PGSQL_DML_STRING combined. If PGSQL_DML_STRING is part of the * options then query string is returned. *

    * @return string|bool TRUE on success or FALSE on failure. Returns string if PGSQL_DML_STRING is passed * via options. */ function pg_delete( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC ): string|bool {} /** * Select records * @link https://php.net/manual/en/function.pg-select.php * @param resource|PgSql\Connection $connection

    * PostgreSQL database connection resource. *

    * @param string $table_name

    * Name of the table from which to select rows. *

    * @param array $conditions

    * An array whose keys are field names in the table table_name, * and whose values are the conditions that a row must meet to be retrieved. *

    * @param int $flags [optional]

    * Any number of PGSQL_CONV_FORCE_NULL, * PGSQL_DML_NO_CONV, * PGSQL_DML_EXEC, * PGSQL_DML_ASYNC or * PGSQL_DML_STRING combined. If PGSQL_DML_STRING is part of the * options then query string is returned. *

    * @param int $mode [optional]

    * An optional parameter that controls * how the returned array is indexed. * result_type is a constant and can take the * following values: PGSQL_ASSOC, * PGSQL_NUM and PGSQL_BOTH. * Using PGSQL_NUM, pg_fetch_array * will return an array with numerical indices, using * PGSQL_ASSOC it will return only associative indices * while PGSQL_BOTH, the default, will return both * numerical and associative indices. *

    * @return array|string|false TRUE on success or FALSE on failure. Returns string if PGSQL_DML_STRING is passed * via options. */ function pg_select( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $table_name, array $conditions = [], int $flags = PGSQL_DML_EXEC, int $mode = PGSQL_ASSOC ): array|string|false {} /** * @param $connection * @param $query [optional] * @return mixed */ #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result|false'], default: 'resource|false')] function pg_exec( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $query ) {} /** * @param $result * @return string|int|false * @deprecated 8.0 */ function pg_getlastoid(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result): string|int|false {} /** * @param $result * @return int * @deprecated 8.0 */ function pg_cmdtuples(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result): int {} // TODO remove /** * @param $connection [optional] * @return string * @deprecated 8.0 */ function pg_errormessage(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection): string {} /** * @param $result * @return int * @deprecated 8.0 */ function pg_numrows(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result): int {} /** * @param $result * @return int * @deprecated 8.0 */ function pg_numfields(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result): int {} /** * @param $result * @param $field * @return string * @deprecated 8.0 */ function pg_fieldname(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $field): string {} /** * @param $result * @param $field * @return int * @deprecated 8.0 */ function pg_fieldsize(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $field): int {} /** * @param $result * @param $field * @return string * @deprecated 8.0 */ function pg_fieldtype(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, int $field): string {} /** * @param $result * @param $field * @return int * @deprecated 8.0 */ function pg_fieldnum(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, string $field): int {} /** * @param $result * @param $row * @param $field [optional] * @return int|false * @deprecated 8.0 */ function pg_fieldprtlen( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $row = 0, #[PhpStormStubsElementAvailable(from: '8.0')] $row, string|int $field ): int|false {} /** * @param $result * @param $row * @param $field [optional] * @return int|false * @deprecated 8.0 */ function pg_fieldisnull( #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $row = 0, #[PhpStormStubsElementAvailable(from: '8.0')] $row, string|int $field ): int|false {} /** * @param $result * @return bool * @deprecated 8.0 */ function pg_freeresult(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result): bool {} /** * @param PgSql\Result|resource $result * @param $row * @param $field [optional] * @deprecated 8.0 */ function pg_result( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Result'], default: 'resource')] $result, #[PhpStormStubsElementAvailable(from: '8.0')] $row, #[PhpStormStubsElementAvailable(from: '8.0')] string|int $field ): string|null|false {} /** * @param $lob * @deprecated 8.0 */ function pg_loreadall(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob'], default: 'resource')] $lob): int {} // TODO remove /** * @param $connection [optional] * @param $oid [optional] * @return string|int|false * @deprecated 8.0 */ function pg_locreate(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, $oid): string|int|false {} /** * @param $connection * @param $oid [optional] * @return bool * @deprecated 8.0 */ function pg_lounlink( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, $oid ): bool {} /** * @param $connection * @param $oid [optional] * @param $mode [optional] * @return resource * @deprecated 8.0 */ #[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob|false'], default: 'resource|false')] function pg_loopen( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, $oid, string $mode ) {} /** * @param $lob * @return bool * @deprecated 8.0 */ function pg_loclose(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob'], default: 'resource')] $lob): bool {} /** * @param $lob * @param $length * @return string|false * @deprecated 8.0 */ function pg_loread(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob'], default: 'resource')] $lob, int $length = 8192): string|false {} /** * @param $lob * @param $data * @param $length [optional] * @return int|false * @deprecated 8.0 */ function pg_lowrite(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Lob'], default: 'resource')] $lob, string $data, ?int $length): int|false {} /** * @param $connection * @param $filename [optional] * @param $oid [optional] * @return string|int|false * @deprecated 8.0 */ function pg_loimport( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, $filename, $oid ): string|int|false {} /** * @param $connection * @param $oid [optional] * @param $filename [optional] * @return bool * @deprecated 8.0 */ function pg_loexport( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, $oid, $filename ): bool {} /** * @param $connection [optional] * @return string * @deprecated 8.0 */ function pg_clientencoding(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection|null'], default: 'resource')] $connection): string {} /** * @param $connection * @param $encoding [optional] * @return int * @deprecated 8.0 */ function pg_setclientencoding( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $connection = null, #[PhpStormStubsElementAvailable(from: '8.0')] #[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection, string $encoding ): int {} /** * Reads input on the connection * @link https://www.php.net/manual/en/function.pg-consume-input.php * @param PgSql\Connection|resource $connection * @return bool true if no error occurred, or false if there was an error. * Note that true does not necessarily indicate that input was waiting to be read. */ function pg_consume_input(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection): bool {} /** * Flush outbound query data on the connection * @link https://www.php.net/manual/en/function.pg-flush.php * @param PgSql\Connection|resource $connection * @return int|bool Returns true if the flush was successful or no data was waiting to be flushed, 0 if part of the pending * data was flushed but more remains or false on failure. */ function pg_flush(#[LanguageLevelTypeAware(['8.1' => 'PgSql\Connection'], default: 'resource')] $connection): int|bool {} /** * @since 8.3 */ function pg_set_error_context_visibility(PgSql\Connection $connection, int $visibility): int {} /** * @since 8.3 */ function pg_pipeline_status(PgSql\Connection $connection): int {} /** * @since 8.3 */ function pg_pipeline_sync(PgSql\Connection $connection): bool {} /** * @since 8.3 */ function pg_exit_pipeline_mode(PgSql\Connection $connection): bool {} /** * @since 8.3 */ function pg_enter_pipeline_mode(PgSql\Connection $connection): bool {} /** * @since 8.4 */ function pg_result_memory_size(PgSql\Result $result): int {} /** * @since 8.4 */ function pg_change_password(PgSql\Connection $connection, string $user, #[\SensitiveParameter] string $password): bool {} /** * @since 8.4 */ function pg_put_copy_data(PgSql\Connection $connection, string $cmd): int {} /** * @since 8.4 * @param resource $socket */ function pg_socket_poll($socket, int $read, int $write, int $timeout = -1): int {} /** * @since 8.4 */ function pg_put_copy_end(PgSql\Connection $connection, ?string $error = null): int {} /** * @since 8.4 * @return array */ function pg_jit(?PgSql\Connection $connection = null): array {} define('PGSQL_LIBPQ_VERSION', "16.2"); define('PGSQL_LIBPQ_VERSION_STR', "16.2"); /** * Passed to pg_connect to force the creation of a new connection, * rather than re-using an existing identical connection. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_CONNECT_FORCE_NEW', 2); /** * Passed to pg_fetch_array. Return an associative array of field * names and values. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_ASSOC', 1); /** * Passed to pg_fetch_array. Return a numerically indexed array of field * numbers and values. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_NUM', 2); /** * Passed to pg_fetch_array. Return an array of field values * that is both numerically indexed (by field number) and associated (by field name). * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_BOTH', 3); /** * Returned by pg_connection_status indicating that the database * connection is in an invalid state. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_CONNECTION_BAD', 1); /** * Returned by pg_connection_status indicating that the database * connection is in a valid state. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_CONNECTION_OK', 0); /** * Returned by pg_transaction_status. Connection is * currently idle, not in a transaction. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_TRANSACTION_IDLE', 0); /** * Returned by pg_transaction_status. A command * is in progress on the connection. A query has been sent via the connection * and not yet completed. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_TRANSACTION_ACTIVE', 1); /** * Returned by pg_transaction_status. The connection * is idle, in a transaction block. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_TRANSACTION_INTRANS', 2); /** * Returned by pg_transaction_status. The connection * is idle, in a failed transaction block. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_TRANSACTION_INERROR', 3); /** * Returned by pg_transaction_status. The connection * is bad. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_TRANSACTION_UNKNOWN', 4); /** * Passed to pg_set_error_verbosity. * Specified that returned messages include severity, primary text, * and position only; this will normally fit on a single line. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_ERRORS_TERSE', 0); /** * Passed to pg_set_error_verbosity. * The default mode produces messages that include the above * plus any detail, hint, or context fields (these may span * multiple lines). * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_ERRORS_DEFAULT', 1); /** * Passed to pg_set_error_verbosity. * The verbose mode includes all available fields. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_ERRORS_VERBOSE', 2); /** * Passed to pg_lo_seek. Seek operation is to begin * from the start of the object. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_SEEK_SET', 0); /** * Passed to pg_lo_seek. Seek operation is to begin * from the current position. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_SEEK_CUR', 1); /** * Passed to pg_lo_seek. Seek operation is to begin * from the end of the object. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_SEEK_END', 2); /** * Passed to pg_result_status. Indicates that * numerical result code is desired. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_STATUS_LONG', 1); /** * Passed to pg_result_status. Indicates that * textual result command tag is desired. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_STATUS_STRING', 2); /** * Returned by pg_result_status. The string sent to the server * was empty. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_EMPTY_QUERY', 0); /** * Returned by pg_result_status. Successful completion of a * command returning no data. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_COMMAND_OK', 1); /** * Returned by pg_result_status. Successful completion of a command * returning data (such as a SELECT or SHOW). * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_TUPLES_OK', 2); /** * Returned by pg_result_status. Copy Out (from server) data * transfer started. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_COPY_OUT', 3); /** * Returned by pg_result_status. Copy In (to server) data * transfer started. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_COPY_IN', 4); /** * Returned by pg_result_status. The server's response * was not understood. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_BAD_RESPONSE', 5); /** * Returned by pg_result_status. A nonfatal error * (a notice or warning) occurred. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_NONFATAL_ERROR', 6); /** * Returned by pg_result_status. A fatal error * occurred. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_FATAL_ERROR', 7); /** * Passed to pg_result_error_field. * The severity; the field contents are ERROR, * FATAL, or PANIC (in an error message), or * WARNING, NOTICE, DEBUG, * INFO, or LOG (in a notice message), or a localized * translation of one of these. Always present. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_DIAG_SEVERITY', 83); /** * Passed to pg_result_error_field. * The SQLSTATE code for the error. The SQLSTATE code identifies the type of error * that has occurred; it can be used by front-end applications to perform specific * operations (such as error handling) in response to a particular database error. * This field is not localizable, and is always present. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_DIAG_SQLSTATE', 67); /** * Passed to pg_result_error_field. * The primary human-readable error message (typically one line). Always present. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_DIAG_MESSAGE_PRIMARY', 77); /** * Passed to pg_result_error_field. * Detail: an optional secondary error message carrying more detail about the problem. May run to multiple lines. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_DIAG_MESSAGE_DETAIL', 68); /** * Passed to pg_result_error_field. * Hint: an optional suggestion what to do about the problem. This is intended to differ from detail in that it * offers advice (potentially inappropriate) rather than hard facts. May run to multiple lines. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_DIAG_MESSAGE_HINT', 72); /** * Passed to pg_result_error_field. * A string containing a decimal integer indicating an error cursor position as an index into the original * statement string. The first character has index 1, and positions are measured in characters not bytes. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_DIAG_STATEMENT_POSITION', 80); /** * Passed to pg_result_error_field. * This is defined the same as the PG_DIAG_STATEMENT_POSITION field, but * it is used when the cursor position refers to an internally generated * command rather than the one submitted by the client. The * PG_DIAG_INTERNAL_QUERY field will always appear when this * field appears. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_DIAG_INTERNAL_POSITION', 112); /** * Passed to pg_result_error_field. * The text of a failed internally-generated command. This could be, for example, a * SQL query issued by a PL/pgSQL function. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_DIAG_INTERNAL_QUERY', 113); /** * Passed to pg_result_error_field. * An indication of the context in which the error occurred. Presently * this includes a call stack traceback of active procedural language * functions and internally-generated queries. The trace is one entry * per line, most recent first. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_DIAG_CONTEXT', 87); /** * Passed to pg_result_error_field. * The file name of the PostgreSQL source-code location where the error * was reported. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_DIAG_SOURCE_FILE', 70); /** * Passed to pg_result_error_field. * The line number of the PostgreSQL source-code location where the * error was reported. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_DIAG_SOURCE_LINE', 76); /** * Passed to pg_result_error_field. * The name of the PostgreSQL source-code function reporting the error. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_DIAG_SOURCE_FUNCTION', 82); /** * Passed to pg_convert. * Ignore default values in the table during conversion. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_CONV_IGNORE_DEFAULT', 2); /** * Passed to pg_convert. * Use SQL NULL in place of an empty string. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_CONV_FORCE_NULL', 4); /** * Passed to pg_convert. * Ignore conversion of NULL into SQL NOT NULL columns. * @link https://php.net/manual/en/pgsql.constants.php */ define('PGSQL_CONV_IGNORE_NOT_NULL', 8); define('PGSQL_DML_NO_CONV', 256); define('PGSQL_DML_EXEC', 512); define('PGSQL_DML_ASYNC', 1024); define('PGSQL_DML_STRING', 2048); /** * @link https://php.net/manual/en/function.pg-last-notice.php * @since 7.1 */ define('PGSQL_NOTICE_LAST', 1); /** * @link https://php.net/manual/en/function.pg-last-notice.php * @since 7.1 */ define('PGSQL_NOTICE_ALL', 2); /** * @link https://php.net/manual/en/function.pg-last-notice.php * @since 7.1 */ define('PGSQL_NOTICE_CLEAR', 3); const PGSQL_CONNECT_ASYNC = 4; const PGSQL_CONNECTION_AUTH_OK = 5; const PGSQL_CONNECTION_AWAITING_RESPONSE = 4; const PGSQL_CONNECTION_MADE = 3; const PGSQL_CONNECTION_SETENV = 6; const PGSQL_CONNECTION_STARTED = 2; const PGSQL_DML_ESCAPE = 4096; const PGSQL_POLLING_ACTIVE = 4; const PGSQL_POLLING_FAILED = 0; const PGSQL_POLLING_OK = 3; const PGSQL_POLLING_READING = 1; const PGSQL_POLLING_WRITING = 2; const PGSQL_DIAG_SCHEMA_NAME = 115; const PGSQL_DIAG_TABLE_NAME = 116; const PGSQL_DIAG_COLUMN_NAME = 99; const PGSQL_DIAG_DATATYPE_NAME = 100; const PGSQL_DIAG_CONSTRAINT_NAME = 110; const PGSQL_DIAG_SEVERITY_NONLOCALIZED = 86; const PGSQL_ERRORS_SQLSTATE = 0; const PGSQL_TRACE_REGRESS_MODE = 2; const PGSQL_PIPELINE_SYNC = 10; const PGSQL_PIPELINE_ON = 1; const PGSQL_PIPELINE_OFF = 0; const PGSQL_PIPELINE_ABORTED = 2; const PGSQL_SHOW_CONTEXT_NEVER = 0; const PGSQL_SHOW_CONTEXT_ERRORS = 1; const PGSQL_SHOW_CONTEXT_ALWAYS = 2; // End of pgsql v. 'string'], default: '')] protected $sqlstate; /** * The error code * * @var int */ protected $code; /** * @since 8.1 */ public function getSqlState(): string {} } /** * MySQLi Driver. * @link https://php.net/manual/en/class.mysqli-driver.php */ final class mysqli_driver { /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $client_info; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $client_version; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $driver_version; /** * @var string */ public $embedded; /** * @var bool */ #[LanguageLevelTypeAware(['8.1' => 'bool'], default: '')] public $reconnect; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $report_mode; } /** * Represents a connection between PHP and a MySQL database. * @link https://php.net/manual/en/class.mysqli.php */ class mysqli { /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'string|int'], default: '')] public $affected_rows; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $client_info; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $client_version; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $connect_errno; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $connect_error; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $errno; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $error; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $field_count; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $host_info; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $info; /** * @var int|string */ #[LanguageLevelTypeAware(['8.1' => 'int|string'], default: '')] public $insert_id; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $server_info; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $server_version; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $sqlstate; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $protocol_version; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $thread_id; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $warning_count; /** * @var array A list of errors, each as an associative array containing the errno, error, and sqlstate. * @link https://secure.php.net/manual/en/mysqli.error-list.php */ #[LanguageLevelTypeAware(['8.1' => 'array'], default: '')] public $error_list; public $stat; /** * Open a new connection to the MySQL server * @link https://php.net/manual/en/mysqli.construct.php * @param string $hostname [optional] Can be either a host name or an IP address. Passing the NULL value or the string "localhost" to this parameter, the local host is assumed. When possible, pipes will be used instead of the TCP/IP protocol. Prepending host by p: opens a persistent connection. mysqli_change_user() is automatically called on connections opened from the connection pool. Defaults to ini_get("mysqli.default_host") * @param string $username [optional] The MySQL user name. Defaults to ini_get("mysqli.default_user") * @param string $password [optional] If not provided or NULL, the MySQL server will attempt to authenticate the user against those user records which have no password only. This allows one username to be used with different permissions (depending on if a password as provided or not). Defaults to ini_get("mysqli.default_pw") * @param string $database [optional] If provided will specify the default database to be used when performing queries. Defaults to "" * @param int $port [optional] Specifies the port number to attempt to connect to the MySQL server. Defaults to ini_get("mysqli.default_port") * @param string $socket [optional] Specifies the socket or named pipe that should be used. Defaults to ini_get("mysqli.default_socket") */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $hostname = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $username = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $password = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $database = null, #[LanguageLevelTypeAware(['8.0' => 'int|null'], default: '')] $port = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $socket = null ) {} /** * Turns on or off auto-committing database modifications * @link https://php.net/manual/en/mysqli.autocommit.php * @param bool $enable

    * Whether to turn on auto-commit or not. *

    * @return bool true on success or false on failure. */ #[TentativeType] public function autocommit(#[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $enable): bool {} /** * Starts a transaction * @link https://secure.php.net/manual/en/mysqli.begin-transaction.php * @param int $flags [optional] * @param string $name [optional] * @return bool true on success or false on failure. * @since 5.5 */ #[TentativeType] public function begin_transaction( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $name = null ): bool {} /** * Changes the user of the specified database connection * @link https://php.net/manual/en/mysqli.change-user.php * @param string $username

    * The MySQL user name. *

    * @param string $password

    * The MySQL password. *

    * @param string|null $database

    * The database to change to. *

    *

    * If desired, the null value may be passed resulting in only changing * the user and not selecting a database. To select a database in this * case use the mysqli_select_db function. *

    * @return bool true on success or false on failure. */ #[TentativeType] public function change_user( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $username, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $password, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $database ): bool {} /** * Returns the current character set of the database connection * @link https://php.net/manual/en/mysqli.character-set-name.php * @return string The current character set of the connection */ #[TentativeType] public function character_set_name(): string {} /** * @removed 5.4 */ #[Deprecated(since: '5.3')] public function client_encoding() {} /** * Closes a previously opened database connection * @link https://php.net/manual/en/mysqli.close.php * @return bool true on success or false on failure. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function close() {} /** * Commits the current transaction * @link https://php.net/manual/en/mysqli.commit.php * @param int $flags A bitmask of MYSQLI_TRANS_COR_* constants. * @param string|null $name If provided then COMMIT $name is executed. * @return bool true on success or false on failure. */ #[TentativeType] public function commit( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $name = null ): bool {} /** * @link https://php.net/manual/en/function.mysqli-connect.php * @param string|null $hostname [optional] * @param string|null $username [optional] * @param string|null $password [optional] * @param string|null $database [optional] * @param int|null $port [optional] * @param string|null $socket [optional] * @return bool */ #[TentativeType] public function connect( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $hostname = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $username = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $password = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $database = null, #[LanguageLevelTypeAware(['8.0' => 'int|null'], default: '')] $port = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $socket = null ): bool {} /** * Dump debugging information into the log * @link https://php.net/manual/en/mysqli.dump-debug-info.php * @return bool true on success or false on failure. */ #[TentativeType] public function dump_debug_info(): bool {} /** * Performs debugging operations * @link https://php.net/manual/en/mysqli.debug.php * @param string $options

    * A string representing the debugging operation to perform *

    * @return bool true. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function debug(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $options) {} /** * Returns a character set object * @link https://php.net/manual/en/mysqli.get-charset.php * @return object|null The function returns a character set object with the following properties: * charset *

    Character set name

    * collation *

    Collation name

    * dir *

    Directory the charset description was fetched from (?) or "" for built-in character sets

    * min_length *

    Minimum character length in bytes

    * max_length *

    Maximum character length in bytes

    * number *

    Internal character set number

    * state *

    Character set status (?)

    */ #[TentativeType] public function get_charset(): ?object {} /** * @param mysqli $mysql * @param string $query * @param array|null $params * @return mysqli_result|bool * @see mysqli_execute_query * @since 8.2 */ public function execute_query(string $query, ?array $params = null): mysqli_result|bool {} /** * Returns the MySQL client version as a string * @link https://php.net/manual/en/mysqli.get-client-info.php * @return string A string that represents the MySQL client library version */ #[TentativeType] public function get_client_info(): string {} /** * Returns statistics about the client connection * @link https://php.net/manual/en/mysqli.get-connection-stats.php * @return array an array with connection stats. */ #[TentativeType] public function get_connection_stats(): array {} /** * Returns the version of the MySQL server * @link https://php.net/manual/en/mysqli.get-server-info.php * @return string A character string representing the server version. */ #[TentativeType] public function get_server_info(): string {} /** * Get result of SHOW WARNINGS * @link https://php.net/manual/en/mysqli.get-warnings.php * @return mysqli_warning|false */ #[TentativeType] public function get_warnings(): mysqli_warning|false {} /** * Initializes MySQLi object * @link https://php.net/manual/en/mysqli.init.php * @return bool|null * @deprecated 8.1 */ public function init() {} /** * Asks the server to kill a MySQL thread * @link https://php.net/manual/en/mysqli.kill.php * @param int $process_id * @return bool true on success or false on failure. */ #[TentativeType] public function kill(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $process_id): bool {} /** * Performs one or more queries on the database * @link https://php.net/manual/en/mysqli.multi-query.php * @param string $query

    * A string containing the queries to be executed. * Multiple queries must be separated by a semicolon. *

    *

    * If the query contains any variable input then parameterized * prepared statements should be used instead. Alternatively, * the data must be properly formatted and all strings must be * escaped using the mysqli_real_escape_string function. *

    * @return bool false if the first statement failed. * To retrieve subsequent errors from other statements you have to call * mysqli_next_result first. */ #[TentativeType] public function multi_query(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $query): bool {} /** * @link https://php.net/manual/en/mysqli.construct.php * @param string $host [optional] * @param string $username [optional] * @param string $password [optional] * @param string $database [optional] * @param int $port [optional] * @param string $socket [optional] * * @removed 8.0 */ public function mysqli($host = null, $username = null, $password = null, $database = null, $port = null, $socket = null) {} /** * Check if there are any more query results from a multi query * @link https://php.net/manual/en/mysqli.more-results.php * @return bool true on success or false on failure. */ #[TentativeType] public function more_results(): bool {} /** * Prepare next result from multi_query * @link https://php.net/manual/en/mysqli.next-result.php * @return bool true on success or false on failure. */ #[TentativeType] public function next_result(): bool {} /** * Set options * @link https://php.net/manual/en/mysqli.options.php * @param int $option

    * The option that you want to set. It can be one of the following values: *

    * Valid options * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    NameDescription
    MYSQLI_OPT_CONNECT_TIMEOUTconnection timeout in seconds (supported on Windows with TCP/IP since PHP 5.3.1)
    MYSQLI_OPT_LOCAL_INFILEenable/disable use of LOAD LOCAL INFILE
    MYSQLI_INIT_COMMANDcommand to execute after when connecting to MySQL server
    MYSQLI_READ_DEFAULT_FILE * Read options from named option file instead of my.cnf *
    MYSQLI_READ_DEFAULT_GROUP * Read options from the named group from my.cnf * or the file specified with MYSQL_READ_DEFAULT_FILE *
    MYSQLI_SERVER_PUBLIC_KEY * RSA public key file used with the SHA-256 based authentication. *
    *

    * @param string|int $value

    * The value for the option. *

    * @return bool true on success or false on failure. */ #[TentativeType] public function options(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $option, $value): bool {} /** * Pings a server connection, or tries to reconnect if the connection has gone down * @link https://php.net/manual/en/mysqli.ping.php * @return bool true on success or false on failure. */ #[TentativeType] public function ping(): bool {} /** * Prepares an SQL statement for execution * @link https://php.net/manual/en/mysqli.prepare.php * @param string $query

    * The query, as a string. It must consist of a single SQL statement. *

    *

    * The SQL statement may contain zero or more parameter markers * represented by question mark (?) characters * at the appropriate positions. *

    *

    * The markers are legal only in certain places in SQL statements. * For example, they are permitted in the VALUES() * list of an INSERT statement (to specify column * values for a row), or in a comparison with a column in a * WHERE clause to specify a comparison value. *

    *

    * However, they are not permitted for identifiers (such as table or * column names), or to specify both operands of a binary operator such as the = equal * sign. The latter restriction is necessary because it would be * impossible to determine the parameter type. * In general, parameters are legal * only in Data Manipulation Language (DML) statements, and not in Data * Definition Language (DDL) statements. *

    * @return mysqli_stmt|false mysqli_prepare returns a statement object or false if an error occurred. */ #[TentativeType] public function prepare(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $query): mysqli_stmt|false {} /** * Performs a query on the database * @link https://php.net/manual/en/mysqli.query.php * @param string $query

    * The query string. *

    *

    * If the query contains any variable input then parameterized * prepared statements should be used instead. Alternatively, * the data must be properly formatted and all strings must be * escaped using the mysqli_real_escape_string function. *

    * @param int $result_mode [optional]

    * The result mode can be one of 3 constants indicating * how the result will be returned from the MySQL server. *

    *

    * MYSQLI_STORE_RESULT (default) - returns a mysqli_result * object with buffered result set. *

    *

    * MYSQLI_USE_RESULT - returns a mysqli_result object * with unbuffered result set. As long as there are pending records * waiting to be fetched, the connection line will be busy and all * subsequent calls will return error Commands out of sync. To avoid * the error all records must be fetched from the server or the result * set must be discarded by calling mysqli_free_result. *

    *

    * MYSQLI_ASYNC (available with mysqlnd) - the query is performed * asynchronously and no result set is immediately returned. * mysqli_poll is then used to get results from such queries. * Used in combination with either * MYSQLI_STORE_RESULT or MYSQLI_USE_RESULT constant. *

    * @return mysqli_result|bool Returns false on failure. * For successful queries which produce a result set, * such as SELECT, SHOW, DESCRIBE or EXPLAIN, * mysqli_query will return a mysqli_result object. * For other successful queries mysqli_query will * return true. */ #[TentativeType] public function query( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $query, #[PhpStormStubsElementAvailable(from: '7.1')] int $result_mode = MYSQLI_STORE_RESULT ): mysqli_result|bool {} /** * Opens a connection to a mysql server * @link https://php.net/manual/en/mysqli.real-connect.php * @param string $hostname [optional]

    * Can be either a host name or an IP address. Passing the null value * or the string "localhost" to this parameter, the local host is * assumed. When possible, pipes will be used instead of the TCP/IP * protocol. *

    * @param string $username [optional]

    * The MySQL user name. *

    * @param string $password [optional]

    * If provided or null, the MySQL server will attempt to authenticate * the user against those user records which have no password only. This * allows one username to be used with different permissions (depending * on if a password as provided or not). *

    * @param string $database [optional]

    * If provided will specify the default database to be used when * performing queries. *

    * @param int $port [optional]

    * Specifies the port number to attempt to connect to the MySQL server. *

    * @param string $socket [optional]

    * Specifies the socket or named pipe that should be used. *

    *

    * Specifying the socket parameter will not * explicitly determine the type of connection to be used when * connecting to the MySQL server. How the connection is made to the * MySQL database is determined by the host * parameter. *

    * @param int $flags [optional]

    * With the parameter flags you can set different * connection options: *

    * * Supported flags * * * * * * * * * * * * * * * * * * * * * * * * *
    NameDescription
    MYSQLI_CLIENT_COMPRESSUse compression protocol
    MYSQLI_CLIENT_FOUND_ROWSreturn number of matched rows, not the number of affected rows
    MYSQLI_CLIENT_IGNORE_SPACEAllow spaces after function names. Makes all function names reserved words.
    MYSQLI_CLIENT_INTERACTIVE * Allow interactive_timeout seconds (instead of * wait_timeout seconds) of inactivity before closing the connection *
    MYSQLI_CLIENT_SSLUse SSL (encryption)
    *

    * For security reasons the MULTI_STATEMENT flag is * not supported in PHP. If you want to execute multiple queries use the * mysqli_multi_query function. *

    * @return bool true on success or false on failure. */ #[TentativeType] public function real_connect( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $hostname = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $username = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $password = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $database = null, #[LanguageLevelTypeAware(['8.0' => 'int|null'], default: '')] $port = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $socket = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0 ): bool {} /** * Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection * @link https://php.net/manual/en/mysqli.real-escape-string.php * @param string $string

    * The string to be escaped. *

    *

    * Characters encoded are NUL (ASCII 0), \n, \r, \, ', ", and * Control-Z. *

    * @return string an escaped string. */ #[TentativeType] public function real_escape_string(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $string): string {} /** * Poll connections * @link https://php.net/manual/en/mysqli.poll.php * @param array &$read

    *

    * @param array &$error

    *

    * @param array &$reject

    *

    * @param int $seconds

    * Number of seconds to wait, must be non-negative. *

    * @param int $microseconds [optional]

    * Number of microseconds to wait, must be non-negative. *

    * @return int|false number of ready connections in success, false otherwise. */ #[TentativeType] public static function poll( #[LanguageLevelTypeAware(['8.0' => 'array|null'], default: '')] &$read, #[LanguageLevelTypeAware(['8.0' => 'array|null'], default: '')] &$error, #[LanguageLevelTypeAware(['8.0' => 'array'], default: '')] &$reject, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $seconds, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $microseconds = 0 ): int|false {} /** * Get result from async query * @link https://php.net/manual/en/mysqli.reap-async-query.php * @return mysqli_result|false mysqli_result in success, false otherwise. */ #[TentativeType] public function reap_async_query(): mysqli_result|bool {} /** * Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection * @param string $string The string to be escaped. * Characters encoded are NUL (ASCII 0), \n, \r, \, ', ", and Control-Z. * @return string * @link https://secure.php.net/manual/en/mysqli.real-escape-string.php */ #[TentativeType] public function escape_string(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $string): string {} /** * Execute an SQL query * @link https://php.net/manual/en/mysqli.real-query.php * @param string $query

    * The query, as a string. *

    *

    * If the query contains any variable input then parameterized * prepared statements should be used instead. Alternatively, * the data must be properly formatted and all strings must be * escaped using the mysqli_real_escape_string function. *

    * @return bool true on success or false on failure. */ #[TentativeType] public function real_query(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $query): bool {} /** * Removes the named savepoint from the set of savepoints of the current transaction * @link https://php.net/manual/en/mysqli.release-savepoint.php * @param string $name The identifier of the savepoint. * @return bool Returns TRUE on success or FALSE on failure. * @since 5.5 */ #[TentativeType] public function release_savepoint(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name): bool {} /** * Rolls back current transaction * @link https://php.net/manual/en/mysqli.rollback.php * @param int $flags [optional] A bitmask of MYSQLI_TRANS_COR_* constants. * @param string $name [optional] If provided then ROLLBACK $name is executed. * @return bool true on success or false on failure. * @since 5.5 Added flags and name parameters. */ #[TentativeType] public function rollback( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $name = null ): bool {} /** * Set a named transaction savepoint * @link https://secure.php.net/manual/en/mysqli.savepoint.php * @param string $name * @return bool Returns TRUE on success or FALSE on failure. * @since 5.5 */ #[TentativeType] public function savepoint(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name): bool {} /** * Selects the default database for database queries * @link https://php.net/manual/en/mysqli.select-db.php * @param string $database

    * The database name. *

    * @return bool true on success or false on failure. */ #[TentativeType] public function select_db(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $database): bool {} /** * Sets the client character set * @link https://php.net/manual/en/mysqli.set-charset.php * @param string $charset

    * The desired character set. *

    * @return bool true on success or false on failure */ #[TentativeType] public function set_charset(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $charset): bool {} /** * @link https://php.net/manual/en/function.mysqli-set-opt * @param int $option * @param string|int $value */ #[TentativeType] public function set_opt(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $option, $value): bool {} /** * Used for establishing secure connections using SSL * @link https://secure.php.net/manual/en/mysqli.ssl-set.php * @param string|null $key

    * The path name to the key file. *

    * @param string|null $certificate

    * The path name to the certificate file. *

    * @param string|null $ca_certificate

    * The path name to the certificate authority file. *

    * @param string|null $ca_path

    * The pathname to a directory that contains trusted SSL CA certificates in PEM format. *

    * @param string|null $cipher_algos

    * A list of allowable ciphers to use for SSL encryption. *

    * @return bool This function always returns TRUE value. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function ssl_set( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $key, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $certificate, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $ca_certificate, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $ca_path, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $cipher_algos ) {} /** * Gets the current system status * @link https://php.net/manual/en/mysqli.stat.php * @return string|false A string describing the server status. false if an error occurred. */ #[TentativeType] public function stat(): string|false {} /** * Initializes a statement and returns an object for use with mysqli_stmt_prepare * @link https://php.net/manual/en/mysqli.stmt-init.php * @return mysqli_stmt an object. */ #[TentativeType] public function stmt_init(): mysqli_stmt|false {} /** * Transfers a result set from the last query * @link https://php.net/manual/en/mysqli.store-result.php * @param int $mode [optional] The option that you want to set * @return mysqli_result|false a buffered result object or false if an error occurred. *

    *

    * mysqli_store_result returns false in case the query * didn't return a result set (if the query was, for example an INSERT * statement). This function also returns false if the reading of the * result set failed. You can check if you have got an error by checking * if mysqli_error doesn't return an empty string, if * mysqli_errno returns a non zero value, or if * mysqli_field_count returns a non zero value. * Also possible reason for this function returning false after * successful call to mysqli_query can be too large * result set (memory for it cannot be allocated). If * mysqli_field_count returns a non-zero value, the * statement should have produced a non-empty result set. */ #[TentativeType] public function store_result(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $mode = 0): mysqli_result|false {} /** * Returns whether thread safety is given or not * @link https://php.net/manual/en/mysqli.thread-safe.php * @return bool true if the client library is thread-safe, otherwise false. */ #[TentativeType] public function thread_safe(): bool {} /** * Initiate a result set retrieval * @link https://php.net/manual/en/mysqli.use-result.php * @return mysqli_result|false an unbuffered result object or false if an error occurred. */ #[TentativeType] public function use_result(): mysqli_result|false {} /** * @link https://php.net/manual/en/mysqli.refresh * @param int $flags MYSQLI_REFRESH_* * @return bool TRUE if the refresh was a success, otherwise FALSE * @since 5.3 */ #[TentativeType] public function refresh(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags): bool {} } /** * Represents one or more MySQL warnings. * @link https://php.net/manual/en/class.mysqli-warning.php */ final class mysqli_warning { /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $message; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $sqlstate; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $errno; /** * The __construct purpose * @link https://php.net/manual/en/mysqli-warning.construct.php */ #[PhpStormStubsElementAvailable(from: '8.0')] private function __construct() {} /** * The __construct purpose * @link https://php.net/manual/en/mysqli-warning.construct.php */ #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] protected function __construct() {} /** * Move to the next warning * @link https://php.net/manual/en/mysqli-warning.next.php * @return bool True if it successfully moved to the next warning */ public function next(): bool {} } /** * Represents the result set obtained from a query against the database. * Implements Traversable since 5.4 * @link https://php.net/manual/en/class.mysqli-result.php */ class mysqli_result implements IteratorAggregate { /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $current_field; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $field_count; /** * @var array|null */ #[LanguageLevelTypeAware(['8.1' => 'array|null'], default: '')] public $lengths; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int|string'], default: '')] public $num_rows; /** * @var mixed */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $type; /** * Constructor (no docs available) * @param object $mysql * @param int $result_mode [optional] */ public function __construct( #[PhpStormStubsElementAvailable(from: '8.0')] mysqli $mysql, #[PhpStormStubsElementAvailable(from: '8.0')] int $result_mode = MYSQLI_STORE_RESULT ) {} /** * Frees the memory associated with a result * @return void * @link https://php.net/manual/en/mysqli-result.free.php */ #[TentativeType] public function close(): void {} /** * Frees the memory associated with a result * @link https://php.net/manual/en/mysqli-result.free.php * @return void */ #[TentativeType] public function free(): void {} /** * Adjusts the result pointer to an arbitrary row in the result * @link https://php.net/manual/en/mysqli-result.data-seek.php * @param int $offset

    * The field offset. Must be between zero and the total number of rows * minus one (0..mysqli_num_rows - 1). *

    * @return bool true on success or false on failure. */ #[TentativeType] public function data_seek(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset): bool {} /** * Returns the next field in the result set * @link https://php.net/manual/en/mysqli-result.fetch-field.php * @return object|false an object which contains field definition information or false * if no field information is available. *

    *

    *

    * Object properties * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    PropertyDescription
    nameThe name of the column
    orgnameOriginal column name if an alias was specified
    tableThe name of the table this field belongs to (if not calculated)
    orgtableOriginal table name if an alias was specified
    defReserved for default value, currently always ""
    dbDatabase (since PHP 5.3.6)
    catalogThe catalog name, always "def" (since PHP 5.3.6)
    max_lengthThe maximum width of the field for the result set.
    lengthThe width of the field, as specified in the table definition.
    charsetnrThe character set number for the field.
    flagsAn integer representing the bit-flags for the field.
    typeThe data type used for this field
    decimalsThe number of decimals used (for integer fields)
    */ #[TentativeType] public function fetch_field(): object|false {} /** * Returns an array of objects representing the fields in a result set * @link https://php.net/manual/en/mysqli-result.fetch-fields.php * @return array an array of objects containing field definition information. *

    *

    *

    * Object properties * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    PropertyDescription
    nameThe name of the column
    orgnameOriginal column name if an alias was specified
    tableThe name of the table this field belongs to (if not calculated)
    orgtableOriginal table name if an alias was specified
    defThe default value for this field, represented as a string
    max_lengthThe maximum width of the field for the result set.
    lengthThe width of the field, as specified in the table definition.
    charsetnrThe character set number for the field.
    flagsAn integer representing the bit-flags for the field.
    typeThe data type used for this field
    decimalsThe number of decimals used (for integer fields)
    */ #[TentativeType] public function fetch_fields(): array {} /** * Fetch meta-data for a single field * @link https://php.net/manual/en/mysqli-result.fetch-field-direct.php * @param int $index

    * The field number. This value must be in the range from * 0 to number of fields - 1. *

    * @return object|false an object which contains field definition information or false * if no field information for specified fieldnr is * available. *

    *

    *

    * Object attributes * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    AttributeDescription
    nameThe name of the column
    orgnameOriginal column name if an alias was specified
    tableThe name of the table this field belongs to (if not calculated)
    orgtableOriginal table name if an alias was specified
    defThe default value for this field, represented as a string
    max_lengthThe maximum width of the field for the result set.
    lengthThe width of the field, as specified in the table definition.
    charsetnrThe character set number for the field.
    flagsAn integer representing the bit-flags for the field.
    typeThe data type used for this field
    decimalsThe number of decimals used (for integer fields)
    */ #[TentativeType] public function fetch_field_direct(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index): object|false {} /** * Fetches all result rows as an associative array, a numeric array, or both * @link https://php.net/manual/en/mysqli-result.fetch-all.php * @param int $mode [optional]

    * This optional parameter is a constant indicating what type of array * should be produced from the current row data. The possible values for * this parameter are the constants MYSQLI_ASSOC, * MYSQLI_NUM, or MYSQLI_BOTH. *

    * @return array an array of associative or numeric arrays holding result rows. */ #[TentativeType] public function fetch_all(#[PhpStormStubsElementAvailable(from: '7.0')] int $mode = MYSQLI_NUM): array {} /** * Fetch the next row of a result set as an associative, a numeric array, or both * @link https://php.net/manual/en/mysqli-result.fetch-array.php * @param int $mode [optional]

    * This optional parameter is a constant indicating what type of array * should be produced from the current row data. The possible values for * this parameter are the constants MYSQLI_ASSOC, * MYSQLI_NUM, or MYSQLI_BOTH. *

    *

    * By using the MYSQLI_ASSOC constant this function * will behave identically to the mysqli_fetch_assoc, * while MYSQLI_NUM will behave identically to the * mysqli_fetch_row function. The final option * MYSQLI_BOTH will create a single array with the * attributes of both. *

    * @return array|false|null an array representing the fetched row, null if there * are no more rows in the result set, or false on failure. */ #[TentativeType] public function fetch_array(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $mode = MYSQLI_BOTH): array|false|null {} /** * Fetch the next row of a result set as an associative array * @link https://php.net/manual/en/mysqli-result.fetch-assoc.php * @return array|false|null an associative array representing the fetched row, * where each key in the array represents the name of one of the result set's columns, null if there * are no more rows in the result set, or false on failure. */ #[TentativeType] public function fetch_assoc(): array|false|null {} /** * @template T * * Fetch the next row of a result set as an object * @link https://php.net/manual/en/mysqli-result.fetch-object.php * @param class-string $class [optional]

    * The name of the class to instantiate, set the properties of and return. * If not specified, a stdClass object is returned. *

    * @param null|array $constructor_args [optional]

    * An optional array of parameters to pass to the constructor * for class_name objects. *

    * @return T|stdClass|false|null an object representing the fetched row, where each property * represents the name of the result set's column, null if there * are no more rows in the result set, or false on failure. */ #[TentativeType] public function fetch_object(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $class = 'stdClass', array $constructor_args = []): object|false|null {} /** * Fetch the next row of a result set as an enumerated array * @link https://php.net/manual/en/mysqli-result.fetch-row.php * @return array|false|null an enumerated array representing * the fetched row, null if there * are no more rows in the result set, or false on failure. */ #[TentativeType] public function fetch_row(): array|false|null {} /** * Fetch a single column from the next row of a result set * * @param int $column [optional]

    * 0-indexed number of the column you wish to retrieve from the row. * If no value is supplied, the first column will be returned. *

    * @return string|int|float|false|null a single column from * the next row of a result set or false if there are no more rows. */ #[PhpStormStubsElementAvailable('8.1')] public function fetch_column(int $column = 0): string|int|float|false|null {} /** * Set result pointer to a specified field offset * @link https://php.net/manual/en/mysqli-result.field-seek.php * @param int $index

    * The field number. This value must be in the range from * 0 to number of fields - 1. *

    */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function field_seek(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index) {} /** * Frees the memory associated with a result * @return void * @link https://php.net/manual/en/mysqli-result.free.php */ #[TentativeType] public function free_result(): void {} /** * @return Iterator * @since 8.0 */ public function getIterator(): Iterator {} } /** * Represents a prepared statement. * @link https://php.net/manual/en/class.mysqli-stmt.php */ class mysqli_stmt { /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int|string'], default: '')] public $affected_rows; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int|string'], default: '')] public $insert_id; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int|string'], default: '')] public $num_rows; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $param_count; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $field_count; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $errno; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $error; /** * @var array */ #[LanguageLevelTypeAware(['8.1' => 'array'], default: '')] public $error_list; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $sqlstate; /** * @var string */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $id; /** * mysqli_stmt constructor * @param mysqli $mysql * @param string $query [optional] */ public function __construct($mysql, $query) {} /** * Used to get the current value of a statement attribute * @link https://php.net/manual/en/mysqli-stmt.attr-get.php * @param int $attribute The attribute that you want to get. * @return int Returns the value of the attribute. */ #[TentativeType] public function attr_get(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $attribute): int {} /** * Used to modify the behavior of a prepared statement * @link https://php.net/manual/en/mysqli-stmt.attr-set.php * @param int $attribute

    * The attribute that you want to set. It can have one of the following values: *

    * Attribute values * * * * * * * * * * * * * * * * *
    CharacterDescription
    MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH * If set to 1, causes mysqli_stmt_store_result to * update the metadata MYSQL_FIELD->max_length value. *
    MYSQLI_STMT_ATTR_CURSOR_TYPE * Type of cursor to open for statement when mysqli_stmt_execute * is invoked. mode can be MYSQLI_CURSOR_TYPE_NO_CURSOR * (the default) or MYSQLI_CURSOR_TYPE_READ_ONLY. *
    MYSQLI_STMT_ATTR_PREFETCH_ROWS * Number of rows to fetch from server at a time when using a cursor. * mode can be in the range from 1 to the maximum * value of unsigned long. The default is 1. *
    *

    *

    * If you use the MYSQLI_STMT_ATTR_CURSOR_TYPE option with * MYSQLI_CURSOR_TYPE_READ_ONLY, a cursor is opened for the * statement when you invoke mysqli_stmt_execute. If there * is already an open cursor from a previous mysqli_stmt_execute call, * it closes the cursor before opening a new one. mysqli_stmt_reset * also closes any open cursor before preparing the statement for re-execution. * mysqli_stmt_free_result closes any open cursor. *

    *

    * If you open a cursor for a prepared statement, mysqli_stmt_store_result * is unnecessary. *

    * @param int $value

    The value to assign to the attribute.

    * @return bool */ #[TentativeType] public function attr_set( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $attribute, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $value ): bool {} /** * Binds variables to a prepared statement as parameters * @link https://php.net/manual/en/mysqli-stmt.bind-param.php * @param string $types

    * A string that contains one or more characters which specify the types * for the corresponding bind variables: *

    * Type specification chars * * * * * * * * * * * * * * * * * * * * *
    CharacterDescription
    icorresponding variable has type integer
    dcorresponding variable has type double
    scorresponding variable has type string
    bcorresponding variable is a blob and will be sent in packets
    *

    * @param mixed &$var1

    * The number of variables and length of string * types must match the parameters in the statement. *

    * @param mixed &...$_ [optional] * @return bool true on success or false on failure. */ public function bind_param($types, &$var1, &...$_) {} /** * Binds variables to a prepared statement for result storage * @link https://php.net/manual/en/mysqli-stmt.bind-result.php * @param mixed &$var1 The variable to be bound. * @param mixed &...$_ The variables to be bound. * @return bool true on success or false on failure. */ public function bind_result(&$var1, &...$_) {} /** * Closes a prepared statement * @link https://php.net/manual/en/mysqli-stmt.close.php * @return bool true on success or false on failure. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function close() {} /** * Seeks to an arbitrary row in statement result set * @link https://php.net/manual/en/mysqli-stmt.data-seek.php * @param int $offset

    * Must be between zero and the total number of rows minus one (0.. * mysqli_stmt_num_rows - 1). *

    * @return void */ #[TentativeType] public function data_seek(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset): void {} /** * Executes a prepared statement * @link https://php.net/manual/en/mysqli-stmt.execute.php * @param array|null $params [optional] An optional list array with as many elements * as there are bound parameters in the SQL statement being executed. Each value is treated as a string. * @return bool true on success or false on failure. */ #[TentativeType] public function execute(#[PhpStormStubsElementAvailable('8.1')] ?array $params = null): bool {} /** * Fetch results from a prepared statement into the bound variables * @link https://php.net/manual/en/mysqli-stmt.fetch.php * @return bool|null */ #[TentativeType] public function fetch(): ?bool {} /** * Get result of SHOW WARNINGS * @link https://php.net/manual/en/mysqli-stmt.get-warnings.php * @return object|false */ #[TentativeType] public function get_warnings(): mysqli_warning|false {} /** * Returns result set metadata from a prepared statement * @link https://php.net/manual/en/mysqli-stmt.result-metadata.php * @return mysqli_result|false a result object or false if an error occurred. */ #[TentativeType] public function result_metadata(): mysqli_result|false {} /** * Check if there are more query results from a multiple query * @link https://php.net/manual/en/mysqli-stmt.more-results.php * @return bool */ #[TentativeType] public function more_results(): bool {} /** * Reads the next result from a multiple query * @link https://php.net/manual/en/mysqli-stmt.next-result.php * @return bool */ #[TentativeType] public function next_result(): bool {} /** * Return the number of rows in statements result set * @link https://php.net/manual/en/mysqli-stmt.num-rows.php * @return string|int An integer representing the number of rows in result set. */ #[TentativeType] public function num_rows(): string|int {} /** * Send data in blocks * @link https://php.net/manual/en/mysqli-stmt.send-long-data.php * @param int $param_num

    * Indicates which parameter to associate the data with. Parameters are * numbered beginning with 0. *

    * @param string $data

    * A string containing data to be sent. *

    * @return bool true on success or false on failure. */ #[TentativeType] public function send_long_data( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $param_num, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data ): bool {} /** * No documentation available * @removed 5.4 */ #[Deprecated(since: '5.3')] public function stmt() {} /** * Frees stored result memory for the given statement handle * @link https://php.net/manual/en/mysqli-stmt.free-result.php * @return void */ #[TentativeType] public function free_result(): void {} /** * Resets a prepared statement * @link https://php.net/manual/en/mysqli-stmt.reset.php * @return bool true on success or false on failure. */ #[TentativeType] public function reset(): bool {} /** * Prepare an SQL statement for execution * @link https://php.net/manual/en/mysqli-stmt.prepare.php * @param string $query

    * The query, as a string. It must consist of a single SQL statement. *

    *

    * The SQL statement may contain zero or more parameter markers * represented by question mark (?) characters at the appropriate positions. *

    *

    * The markers are legal only in certain places in SQL statements. * For example, they are permitted in the VALUES() list of an INSERT statement * (to specify column values for a row), or in a comparison with a column in * a WHERE clause to specify a comparison value. *

    *

    * However, they are not permitted for identifiers (such as table or column names), * or to specify both operands of a binary operator such as the = * equal sign. The latter restriction is necessary because it would be impossible * to determine the parameter type. In general, parameters are legal only in Data * Manipulation Language (DML) statements, and not in Data Definition Language * (DDL) statements. *

    * @return bool true on success or false on failure. */ #[TentativeType] public function prepare(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $query): bool {} /** * Stores a result set in an internal buffer * @link https://php.net/manual/en/mysqli-stmt.store-result.php * @return bool true on success or false on failure. */ #[TentativeType] public function store_result(): bool {} /** * Gets a result set from a prepared statement as a mysqli_result object * @link https://php.net/manual/en/mysqli-stmt.get-result.php * @return mysqli_result|false Returns a resultset or FALSE on failure */ #[TentativeType] public function get_result(): mysqli_result|false {} } /** * Gets the number of affected rows in a previous MySQL operation * @link https://secure.php.net/manual/en/mysqli.affected-rows.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return string|int An integer greater than zero indicates the number of rows affected or retrieved. * Zero indicates that no records were updated for an UPDATE statement, * no rows matched the WHERE clause in the query or that no query has yet been executed. -1 indicates that the query returned an error * or that mysqli_affected_rows was called for an unbuffered SELECT query. */ function mysqli_affected_rows(mysqli $mysql): string|int {} /** * Turns on or off auto-committing database modifications * @link https://secure.php.net/manual/en/mysqli.autocommit.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param bool $enable Whether to turn on auto-commit or not. * @return bool */ function mysqli_autocommit(mysqli $mysql, bool $enable): bool {} /** * Starts a transaction * @link https://secure.php.net/manual/en/mysqli.begin-transaction.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param int $flags [optional] * @param string|null $name [optional] * @return bool true on success or false on failure. * @since 5.5 */ function mysqli_begin_transaction(mysqli $mysql, int $flags = 0, ?string $name): bool {} /** * Changes the user of the specified database connection * @link https://php.net/manual/en/mysqli.change-user.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string $username The MySQL user name. * @param string $password The MySQL password. * @param string|null $database The database to change to. If desired, the NULL value may be passed resulting in only changing the user and not selecting a database. * @return bool */ function mysqli_change_user(mysqli $mysql, string $username, string $password, ?string $database): bool {} /** * Returns the current character set of the database connection * @link https://php.net/manual/en/mysqli.character-set-name.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return string The current character set of the connection */ function mysqli_character_set_name(mysqli $mysql): string {} /** * Closes a previously opened database connection * @link https://php.net/manual/en/mysqli.close.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return bool */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function mysqli_close(mysqli $mysql): bool {} /** * Commits the current transaction * @link https://php.net/manual/en/mysqli.commit.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param int $flags [optional] A bitmask of MYSQLI_TRANS_COR_* constants * @param string|null $name [optional] If provided then COMMITname is executed * @return bool */ function mysqli_commit(mysqli $mysql, int $flags = 0, ?string $name = null): bool {} /** * Open a new connection to the MySQL server * Alias of mysqli::__construct * @link https://php.net/manual/en/mysqli.construct.php * @param string|null $hostname Can be either a host name or an IP address. Passing the NULL value or the string "localhost" to this parameter, the local host is assumed. When possible, pipes will be used instead of the TCP/IP protocol. * @param string|null $username The MySQL user name. * @param string|null $password If not provided or NULL, the MySQL server will attempt to authenticate the user against those user records which have no password only. * @param string|null $database If provided will specify the default database to be used when performing queries. * @param int|null $port Specifies the port number to attempt to connect to the MySQL server. * @param string|null $socket Specifies the socket or named pipe that should be used. * @return mysqli|false object which represents the connection to a MySQL Server or false if an error occurred. */ function mysqli_connect(?string $hostname = null, ?string $username = null, ?string $password = null, ?string $database = null, ?int $port = null, ?string $socket = null): mysqli|false {} /** * Returns the error code from last connect call * @link https://php.net/manual/en/mysqli.connect-errno.php * @return int Last error code number from the last call to mysqli_connect(). Zero means no error occurred. */ function mysqli_connect_errno(): int {} /** * Returns a string description of the last connect error * @link https://php.net/manual/en/mysqli.connect-error.php * @return string|null Last error message string from the last call to mysqli_connect(). */ function mysqli_connect_error(): ?string {} /** * Adjusts the result pointer to an arbitrary row in the result * @link https://php.net/manual/en/mysqli-result.data-seek.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @param int $offset * @return bool Returns TRUE on success or FALSE on failure. */ function mysqli_data_seek(mysqli_result $result, int $offset): bool {} /** * Dump debugging information into the log * @link https://php.net/manual/en/mysqli.dump-debug-info.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return bool */ function mysqli_dump_debug_info(mysqli $mysql): bool {} /** * Performs debugging operations using the Fred Fish debugging library. * @link https://php.net/manual/en/mysqli.debug.php * @param string $options * @return bool */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function mysqli_debug(string $options): bool {} /** * Returns the error code for the most recent function call * @link https://php.net/manual/en/mysqli.errno.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return int An error code value for the last call, if it failed. zero means no error occurred. */ function mysqli_errno(mysqli $mysql): int {} /** * Returns a list of errors from the last command executed * @link https://php.net/manual/en/mysqli.error-list.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return array A list of errors, each as an associative array containing the errno, error, and sqlstate. * @since 5.4 */ #[ArrayShape([ "errno" => "int", "sqlstate" => "string", "error" => "string", ])] function mysqli_error_list(mysqli $mysql): array {} /** * Returns a list of errors from the last statement executed * @link https://secure.php.net/manual/en/mysqli-stmt.error-list.php * @param mysqli_stmt $statement A statement identifier returned by mysqli_stmt_init(). * @return array A list of errors, each as an associative array containing the errno, error, and sqlstate. * @since 5.4 */ function mysqli_stmt_error_list(mysqli_stmt $statement): array {} /** * Returns a string description of the last error * @link https://secure.php.net/manual/en/mysqli.error.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return string */ function mysqli_error(mysqli $mysql): string {} /** * Executes a prepared statement * @link https://php.net/manual/en/mysqli-stmt.execute.php * @param mysqli_stmt $statement * @param array|null $params [optional] An optional list array with as many elements * as there are bound parameters in the SQL statement being executed. Each value is treated as a string. * @return bool true on success or false on failure. */ function mysqli_stmt_execute(mysqli_stmt $statement, #[PhpStormStubsElementAvailable('8.1')] ?array $params = null): bool {} /** * Executes a prepared statement * Alias for mysqli_stmt_execute * @link https://php.net/manual/en/function.mysqli-execute.php * @param mysqli_stmt $statement * @param array|null $params [optional] An optional list array with as many elements * as there are bound parameters in the SQL statement being executed. Each value is treated as a string. * @return bool */ function mysqli_execute(mysqli_stmt $statement, #[PhpStormStubsElementAvailable('8.1')] ?array $params = null): bool {} /** * @param mysqli $mysql * @param string $query * @param array|null $params * @return mysqli_result|bool * @since 8.2 */ function mysqli_execute_query(mysqli $mysql, string $query, ?array $params = null): mysqli_result|bool {} /** * Returns the next field in the result set * @link https://secure.php.net/manual/en/mysqli-result.fetch-field.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @return object|false Returns an object which contains field definition information or FALSE if no field information is available. */ function mysqli_fetch_field(mysqli_result $result): object|false {} /** * Returns an array of objects representing the fields in a result set * @link https://secure.php.net/manual/en/mysqli-result.fetch-fields.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @return array Returns an array of objects which contains field definition information. */ function mysqli_fetch_fields(mysqli_result $result): array {} /** * Fetch meta-data for a single field * @link https://secure.php.net/manual/en/mysqli-result.fetch-field-direct.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @param int $index The field number. This value must be in the range from 0 to number of fields - 1. * @return object|false Returns an object which contains field definition information or FALSE if no field information for specified fieldnr is available. */ function mysqli_fetch_field_direct(mysqli_result $result, int $index): object|false {} /** * Returns the lengths of the columns of the current row in the result set * @link https://php.net/manual/en/mysqli-result.lengths.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @return int[]|false An array of integers representing the size of each column (not including any terminating null characters). FALSE if an error occurred. */ function mysqli_fetch_lengths(mysqli_result $result): array|false {} /** * Fetch all result rows as an associative array, a numeric array, or both * @link https://php.net/manual/en/mysqli-result.fetch-all.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @param int $mode * @return array Returns an array of associative or numeric arrays holding result rows. */ function mysqli_fetch_all( mysqli_result $result, #[PhpStormStubsElementAvailable(from: '7.0')] int $mode = MYSQLI_NUM ): array {} /** * Fetch the next row of a result set as an associative, a numeric array, or both * @link https://php.net/manual/en/mysqli-result.fetch-array.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @param int $mode * @return array|false|null an array representing the fetched row, * null if there are no more rows in the result set, or false on failure. */ function mysqli_fetch_array(mysqli_result $result, int $mode = MYSQLI_BOTH): array|false|null {} /** * Fetch the next row of a result set as an associative array * @link https://php.net/manual/en/mysqli-result.fetch-assoc.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @return array|false|null an associative array representing the fetched row, * where each key in the array represents the name of one of the result set's columns, * null if there are no more rows in the result set, or false on failure. */ function mysqli_fetch_assoc(mysqli_result $result): array|null|false {} /** * @template T * * Fetch the next row of a result set as an object * @link https://php.net/manual/en/mysqli-result.fetch-object.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @param class-string $class [optional] The name of the class to instantiate, set the properties of and return. If not specified, a stdClass object is returned. * @param array $constructor_args [optional] An optional array of parameters to pass to the constructor for class_name objects. * @return T|stdClass|null|false an object representing the fetched row, * where each property represents the name of the result set's column, * null if there are no more rows in the result set, or false on failure. */ function mysqli_fetch_object(mysqli_result $result, string $class = 'stdClass', array $constructor_args = []): object|null|false {} /** * Fetch the next row of a result set as an enumerated array * @link https://php.net/manual/en/mysqli-result.fetch-row.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @return array|null|false an enumerated array representing the fetched row, * null if there are no more rows in the result set, or false on failure. * @link https://php.net/manual/en/mysqli-result.fetch-row.php */ function mysqli_fetch_row(mysqli_result $result): array|false|null {} /** * Fetch a single column from the next row of a result set * @link https://php.net/manual/en/mysqli-result.fetch-column.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @param int $column [optional]

    * 0-indexed number of the column you wish to retrieve from the row. * If no value is supplied, the first column will be returned. *

    * @return string|int|float|false|null a single column from * the next row of a result set or false if there are no more rows. */ #[PhpStormStubsElementAvailable('8.1')] function mysqli_fetch_column(mysqli_result $result, int $column = 0): string|int|float|false|null {} /** * Returns the number of columns for the most recent query * @link https://php.net/manual/en/mysqli.field-count.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return int An integer representing the number of fields in a result set. */ function mysqli_field_count(mysqli $mysql): int {} /** * Set result pointer to a specified field offset * @link https://php.net/manual/en/mysqli-result.field-seek.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @param int $index The field number. This value must be in the range from 0 to number of fields - 1. */ #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] function mysqli_field_seek(mysqli_result $result, int $index) {} /** * Get current field offset of a result pointer * @link https://php.net/manual/en/mysqli-result.current-field.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @return int */ function mysqli_field_tell(mysqli_result $result): int {} /** * Frees the memory associated with a result * @link https://php.net/manual/en/mysqli-result.free.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @return void */ function mysqli_free_result(mysqli_result $result): void {} /** * Returns client Zval cache statistics * Available only with mysqlnd. * @link https://php.net/manual/en/function.mysqli-get-cache-stats.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return array|false an array with client Zval cache stats if success, false otherwise. * @removed 5.4 */ function mysqli_get_cache_stats(mysqli $mysql) {} /** * Returns statistics about the client connection * @link https://php.net/manual/en/mysqli.get-connection-stats.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return array an array with connection stats. */ function mysqli_get_connection_stats(mysqli $mysql): array {} /** * Returns client per-process statistics * @link https://php.net/manual/en/function.mysqli-get-client-stats.php * @return array an array with client stats. */ function mysqli_get_client_stats(): array {} /** * Returns a character set object * @link https://php.net/manual/en/mysqli.get-charset.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return object|null */ function mysqli_get_charset(mysqli $mysql): ?object {} /** * Get MySQL client info * @link https://php.net/manual/en/mysqli.get-client-info.php * @param mysqli|null $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return string|null A string that represents the MySQL client library version */ #[LanguageLevelTypeAware(['8.0' => 'string'], default: '?string')] function mysqli_get_client_info( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.1')] mysqli $mysql, #[PhpStormStubsElementAvailable(from: '8.0')] ?mysqli $mysql = null ) {} /** * Returns the MySQL client version as an integer * @link https://php.net/manual/en/mysqli.get-client-version.php * @return int */ function mysqli_get_client_version(#[PhpStormStubsElementAvailable(from: '5.3', to: '7.3')] $link): int {} /** * Returns a string representing the type of connection used * @link https://php.net/manual/en/mysqli.get-host-info.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return string A character string representing the server hostname and the connection type. */ function mysqli_get_host_info(mysqli $mysql): string {} /** * Return information about open and cached links * @link https://php.net/manual/en/function.mysqli-get-links-stats.php * @return array mysqli_get_links_stats() returns an associative array with three elements, keyed as follows: *
    *
    * total
    *
    *

    * An integer indicating the total number of open links in * any state. *

    *
    * *
    * active_plinks
    *
    *

    * An integer representing the number of active persistent * connections. *

    *
    * *
    * cached_plinks
    *
    *

    * An integer representing the number of inactive persistent * connections. *

    *
    * *
    * @since 5.6 */ #[ArrayShape(["total" => "int", "active_plinks" => "int", "cached_plinks" => "int"])] function mysqli_get_links_stats(): array {} /** * Returns the version of the MySQL protocol used * @link https://php.net/manual/en/mysqli.get-proto-info.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return int Returns an integer representing the protocol version */ function mysqli_get_proto_info(mysqli $mysql): int {} /** * Returns the version of the MySQL server * @link https://php.net/manual/en/mysqli.get-server-info.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return string A character string representing the server version. */ function mysqli_get_server_info(mysqli $mysql): string {} /** * Returns the version of the MySQL server as an integer * @link https://php.net/manual/en/mysqli.get-server-version.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return int An integer representing the server version. * The form of this version number is main_version * 10000 + minor_version * 100 + sub_version (i.e. version 4.1.0 is 40100). */ function mysqli_get_server_version(mysqli $mysql): int {} /** * Get result of SHOW WARNINGS * @link https://php.net/manual/en/mysqli.get-warnings.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return mysqli_warning|false */ function mysqli_get_warnings(mysqli $mysql): mysqli_warning|false {} /** * Initializes MySQLi and returns a resource for use with mysqli_real_connect() * @link https://php.net/manual/en/mysqli.init.php * @return mysqli|false * @see mysqli_real_connect() */ function mysqli_init(): mysqli|false {} /** * Retrieves information about the most recently executed query * @link https://php.net/manual/en/mysqli.info.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return string|null A character string representing additional information about the most recently executed query. */ function mysqli_info(mysqli $mysql): ?string {} /** * Returns the value generated for an AUTO_INCREMENT column by the last query * @link https://php.net/manual/en/mysqli.insert-id.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return int|string The value of the AUTO_INCREMENT field that was updated by the previous query. Returns zero if there was no previous query on the connection or if the query did not update an AUTO_INCREMENT value. * If the number is greater than the maximum int value, it will be returned as a string. */ function mysqli_insert_id(mysqli $mysql): string|int {} /** * Asks the server to kill a MySQL thread * @link https://php.net/manual/en/mysqli.kill.php * @see mysqli_thread_id() * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param int $process_id * @return bool */ #[Deprecated("The function is deprecated", since: "8.4")] function mysqli_kill(mysqli $mysql, int $process_id): bool {} /** * Unsets user defined handler for load local infile command * @link https://php.net/manual/en/mysqli.set-local-infile-default.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return void * @removed 5.5 */ function mysqli_set_local_infile_default(mysqli $mysql) {} /** * Set callback function for LOAD DATA LOCAL INFILE command * @link https://php.net/manual/en/mysqli.set-local-infile-handler.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param callable $read_func * @return bool * @removed 5.5 */ function mysqli_set_local_infile_handler(mysqli $mysql, callable $read_func): bool {} /** * Check if there are any more query results from a multi query * @link https://php.net/manual/en/mysqli.more-results.php * @see mysqli_multi_query() * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return bool */ function mysqli_more_results(mysqli $mysql): bool {} /** * Performs one or more queries on the database * @link https://php.net/manual/en/mysqli.multi-query.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string $query A string containing the queries to be executed. Multiple queries must be separated by a semicolon. * @return bool Returns FALSE if the first statement failed. To retrieve subsequent errors from other statements you have to call mysqli_next_result() first. */ function mysqli_multi_query( mysqli $mysql, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.0')] string $query, #[PhpStormStubsElementAvailable(from: '7.1', to: '7.4')] string $query = null, #[PhpStormStubsElementAvailable(from: '8.0')] string $query ): bool {} /** * Prepare next result from multi_query * @link https://php.net/manual/en/mysqli.next-result.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return bool */ function mysqli_next_result(mysqli $mysql): bool {} /** * Gets the number of fields in the result set * @link https://php.net/manual/en/mysqli-result.field-count.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @return int */ function mysqli_num_fields(mysqli_result $result): int {} /** * Gets the number of rows in a result * @link https://php.net/manual/en/mysqli-result.num-rows.php * @param mysqli_result $result A mysqli_result object returned by mysqli_query(), * mysqli_store_result(), mysqli_use_result() or mysqli_stmt_get_result(). * @return string|int Returns number of rows in the result set. */ function mysqli_num_rows(mysqli_result $result): string|int {} /** * Set options * @link https://php.net/manual/en/mysqli.options.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param int $option * @param string|int $value * @return bool */ function mysqli_options(mysqli $mysql, int $option, $value): bool {} /** * Pings a server connection, or tries to reconnect if the connection has gone down * @link https://php.net/manual/en/mysqli.ping.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return bool */ #[Deprecated("The function is deprecated", since: "8.4")] function mysqli_ping(mysqli $mysql): bool {} /** * Poll connections * @link https://php.net/manual/en/mysqli.poll.php * @param array|null &$read * @param array|null &$error * @param array &$reject * @param int $seconds * @param int $microseconds [optional] * @return int|false number of ready connections upon success, FALSE otherwise. */ function mysqli_poll(?array &$read, ?array &$error, array &$reject, int $seconds, int $microseconds = 0): int|false {} /** * Prepares an SQL statement for execution * @link https://php.net/manual/en/mysqli.prepare.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string $query The query, as a string. It must consist of a single SQL statement. * The SQL statement may contain zero or more parameter markers represented by question mark (?) characters at the appropriate positions. * @return mysqli_stmt|false A statement object or FALSE if an error occurred. */ function mysqli_prepare(mysqli $mysql, string $query): mysqli_stmt|false {} /** * Enables or disables internal report functions * @link https://php.net/manual/en/function.mysqli-report.php * @param int $flags

    *

    * Supported flags * * * * * * * * * * * * * * * * * * * * * * * * *
    NameDescription
    MYSQLI_REPORT_OFFTurns reporting off
    MYSQLI_REPORT_ERRORReport errors from mysqli function calls
    MYSQLI_REPORT_STRICT * Throw mysqli_sql_exception for errors * instead of warnings *
    MYSQLI_REPORT_INDEXReport if no index or bad index was used in a query
    MYSQLI_REPORT_ALLSet all options (report all)
    *

    * @return bool */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] function mysqli_report(int $flags) {} /** * Performs a query on the database * @link https://php.net/manual/en/mysqli.query.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string $query An SQL query * @param int $result_mode * @return mysqli_result|bool * For successful SELECT, SHOW, DESCRIBE or EXPLAIN queries, mysqli_query() will return a mysqli_result object. * For other successful queries mysqli_query() will return TRUE. * Returns FALSE on failure. */ function mysqli_query( mysqli $mysql, string $query, #[PhpStormStubsElementAvailable(from: '7.1')] int $result_mode = MYSQLI_STORE_RESULT ): mysqli_result|bool {} /** * Opens a connection to a mysql server * @link https://php.net/manual/en/mysqli.real-connect.php * @see mysqli_connect() * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string|null $hostname [optional] * @param string|null $username [optional] * @param string|null $password [optional] * @param string|null $database [optional] * @param int|null $port [optional] * @param string|null $socket [optional] * @param int $flags * @return bool */ function mysqli_real_connect(mysqli $mysql, ?string $hostname, ?string $username, ?string $password, ?string $database, ?int $port, ?string $socket, int $flags = 0): bool {} /** * Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection * @link https://php.net/manual/en/mysqli.real-escape-string.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string $string The string to be escaped. Characters encoded are NUL (ASCII 0), \n, \r, \, ', ", and Control-Z. * @return string */ function mysqli_real_escape_string(mysqli $mysql, string $string): string {} /** * Execute an SQL query * @link https://php.net/manual/en/mysqli.real-query.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string $query * @return bool */ function mysqli_real_query( mysqli $mysql, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.0')] string $query, #[PhpStormStubsElementAvailable(from: '7.1', to: '7.4')] string $query = null, #[PhpStormStubsElementAvailable(from: '8.0')] string $query ): bool {} /** * Get result from async query * Available only with mysqlnd. * @link https://php.net/manual/en/mysqli.reap-async-query.php * @see mysqli_poll() * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return mysqli_result|bool mysqli_result in success, FALSE otherwise. */ function mysqli_reap_async_query(mysqli $mysql): mysqli_result|bool {} /** * Removes the named savepoint from the set of savepoints of the current transaction * @link https://secure.php.net/manual/en/mysqli.release-savepoint.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string $name * @return bool Returns TRUE on success or FALSE on failure. * @since 5.5 */ function mysqli_release_savepoint(mysqli $mysql, string $name): bool {} /** * Rolls back current transaction * @link https://php.net/manual/en/mysqli.rollback.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param int $flags [optional] A bitmask of MYSQLI_TRANS_COR_* constants * @param string|null $name [optional] If provided then ROLLBACKname is executed * @return bool */ function mysqli_rollback(mysqli $mysql, int $flags = 0, ?string $name): bool {} /** * Set a named transaction savepoint * @link https://secure.php.net/manual/en/mysqli.savepoint.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string $name * @return bool Returns TRUE on success or FALSE on failure. * @since 5.5 */ function mysqli_savepoint(mysqli $mysql, string $name): bool {} /** * Selects the default database for database queries * @link https://php.net/manual/en/mysqli.select-db.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string $database * @return bool */ function mysqli_select_db(mysqli $mysql, string $database): bool {} /** * Sets the client character set * @link https://php.net/manual/en/mysqli.set-charset.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string $charset * @return bool */ function mysqli_set_charset(mysqli $mysql, string $charset): bool {} /** * Returns the total number of rows changed, deleted, inserted, or matched by the last statement executed * @link https://php.net/manual/en/mysqli-stmt.affected-rows.php * @param mysqli_stmt $statement * @return int|string If the number of affected rows is greater than maximum PHP int value, the number of affected rows will be returned as a string value. */ function mysqli_stmt_affected_rows(mysqli_stmt $statement): string|int {} /** * Used to get the current value of a statement attribute * @link https://php.net/manual/en/mysqli-stmt.attr-get.php * @param mysqli_stmt $statement * @param int $attribute * @return int|false Returns FALSE if the attribute is not found, otherwise returns the value of the attribute. */ #[LanguageLevelTypeAware(["8.0" => "int"], default: "int|false")] function mysqli_stmt_attr_get(mysqli_stmt $statement, int $attribute): false|int {} /** * Used to modify the behavior of a prepared statement * @link https://php.net/manual/en/mysqli-stmt.attr-set.php * @param mysqli_stmt $statement * @param int $attribute * @param int $value * @return bool */ function mysqli_stmt_attr_set(mysqli_stmt $statement, int $attribute, int $value): bool {} /** * Returns the number of fields in the given statement * @link https://php.net/manual/en/mysqli-stmt.field-count.php * @param mysqli_stmt $statement * @return int */ function mysqli_stmt_field_count(mysqli_stmt $statement): int {} /** * Initializes a statement and returns an object for use with mysqli_stmt_prepare * @link https://php.net/manual/en/mysqli.stmt-init.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return mysqli_stmt|false */ function mysqli_stmt_init(mysqli $mysql): mysqli_stmt|false {} /** * Prepares an SQL statement for execution * @link https://php.net/manual/en/mysqli-stmt.prepare.php * @param mysqli_stmt $statement * @param string $query * @return bool */ function mysqli_stmt_prepare(mysqli_stmt $statement, string $query): bool {} /** * Returns result set metadata from a prepared statement * @link https://php.net/manual/en/mysqli-stmt.result-metadata.php * @param mysqli_stmt $statement * @return mysqli_result|false Returns a result object or FALSE if an error occurred */ function mysqli_stmt_result_metadata(mysqli_stmt $statement): mysqli_result|false {} /** * Send data in blocks * @link https://php.net/manual/en/mysqli-stmt.send-long-data.php * @param mysqli_stmt $statement * @param int $param_num * @param string $data * @return bool */ function mysqli_stmt_send_long_data(mysqli_stmt $statement, int $param_num, string $data): bool {} /** * Binds variables to a prepared statement as parameters * @link https://php.net/manual/en/mysqli-stmt.bind-param.php * @param mysqli_stmt $statement A statement identifier returned by mysqli_stmt_init() * @param string $types

    * A string that contains one or more characters which specify the types * for the corresponding bind variables: *

    * Type specification chars * * * * * * * * * * * * * * * * * * * * *
    CharacterDescription
    icorresponding variable has type integer
    dcorresponding variable has type double
    scorresponding variable has type string
    bcorresponding variable is a blob and will be sent in packets
    *

    * @param mixed &$var1

    * The number of variables and length of string * types must match the parameters in the statement. *

    * @param mixed &...$vars * @return bool true on success or false on failure. */ function mysqli_stmt_bind_param( mysqli_stmt $statement, string $types, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] mixed &$vars, mixed &...$vars ): bool {} /** * Binds variables to a prepared statement for result storage * @link https://php.net/manual/en/mysqli-stmt.bind-result.php * @param mysqli_stmt $statement Statement * @param mixed &...$vars The variables to be bound. * @return bool */ function mysqli_stmt_bind_result( mysqli_stmt $statement, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] mixed &$vars, mixed &...$vars ): bool {} /** * Fetch results from a prepared statement into the bound variables * @link https://php.net/manual/en/mysqli-stmt.fetch.php * @param mysqli_stmt $statement * @return bool|null */ function mysqli_stmt_fetch(mysqli_stmt $statement): ?bool {} /** * Frees stored result memory for the given statement handle * @link https://php.net/manual/en/mysqli-stmt.free-result.php * @param mysqli_stmt $statement * @return void */ function mysqli_stmt_free_result(mysqli_stmt $statement): void {} /** * Gets a result set from a prepared statement as a mysqli_result object * @link https://php.net/manual/en/mysqli-stmt.get-result.php * @param mysqli_stmt $statement * @return mysqli_result|false Returns false on failure. For successful queries which produce a result set, * such as SELECT, SHOW, DESCRIBE or EXPLAIN, mysqli_stmt_get_result() will return a mysqli_result object. * For other successful queries, mysqli_stmt_get_result() will return false. */ function mysqli_stmt_get_result(mysqli_stmt $statement): mysqli_result|false {} /** * Get result of SHOW WARNINGS * @link https://php.net/manual/en/mysqli-stmt.get-warnings.php * @param mysqli_stmt $statement * @return mysqli_warning|false (not documented, but it's probably a mysqli_warning object) */ function mysqli_stmt_get_warnings(mysqli_stmt $statement): mysqli_warning|false {} /** * Get the ID generated from the previous INSERT operation * @link https://php.net/manual/en/mysqli-stmt.insert-id.php * @param mysqli_stmt $statement * @return string|int */ function mysqli_stmt_insert_id(mysqli_stmt $statement): string|int {} /** * Resets a prepared statement * @link https://php.net/manual/en/mysqli-stmt.reset.php * @param mysqli_stmt $statement * @return bool */ function mysqli_stmt_reset(mysqli_stmt $statement): bool {} /** * Returns the number of parameter for the given statement * @link https://php.net/manual/en/mysqli-stmt.param-count.php * @param mysqli_stmt $statement * @return int */ function mysqli_stmt_param_count(mysqli_stmt $statement): int {} /** * Returns the SQLSTATE error from previous MySQL operation * @link https://php.net/manual/en/mysqli.sqlstate.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return string Returns a string containing the SQLSTATE error code for the last error. The error code consists of five characters. '00000' means no error. */ function mysqli_sqlstate(mysqli $mysql): string {} /** * Gets the current system status * @link https://php.net/manual/en/mysqli.stat.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return string|false A string describing the server status. FALSE if an error occurred. */ function mysqli_stat(mysqli $mysql): string|false {} /** * Used for establishing secure connections using SSL * @link https://secure.php.net/manual/en/mysqli.ssl-set.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string|null $key The path name to the key file * @param string|null $certificate The path name to the certificate file * @param string|null $ca_certificate The path name to the certificate authority file * @param string|null $ca_path The pathname to a directory that contains trusted SSL CA certificates in PEM format * @param string|null $cipher_algos A list of allowable ciphers to use for SSL encryption * @return bool This function always returns TRUE value. */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function mysqli_ssl_set( mysqli $mysql, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $key, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $certificate, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $ca_certificate, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $ca_path, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $cipher_algos ): bool {} /** * Closes a prepared statement * @link https://php.net/manual/en/mysqli-stmt.close.php * @param mysqli_stmt $statement * @return bool */ #[LanguageLevelTypeAware(['8.2' => 'true'], default: 'bool')] function mysqli_stmt_close(mysqli_stmt $statement): bool {} /** * Seeks to an arbitrary row in statement result set * @link https://php.net/manual/en/mysqli-stmt.data-seek.php * @param mysqli_stmt $statement * @param int $offset * @return void */ function mysqli_stmt_data_seek(mysqli_stmt $statement, int $offset): void {} /** * Returns the error code for the most recent statement call * @link https://php.net/manual/en/mysqli-stmt.errno.php * @param mysqli_stmt $statement * @return int */ function mysqli_stmt_errno(mysqli_stmt $statement): int {} /** * Returns a string description for last statement error * @link https://php.net/manual/en/mysqli-stmt.error.php * @param mysqli_stmt $statement * @return string */ function mysqli_stmt_error(mysqli_stmt $statement): string {} /** * Check if there are more query results from a multiple query * @link https://php.net/manual/en/mysqli-stmt.more-results.php * @param mysqli_stmt $statement * @return bool */ function mysqli_stmt_more_results(mysqli_stmt $statement): bool {} /** * Reads the next result from a multiple query * @link https://php.net/manual/en/mysqli-stmt.next-result.php * @param mysqli_stmt $statement * @return bool */ function mysqli_stmt_next_result(mysqli_stmt $statement): bool {} /** * Return the number of rows in statements result set * @link https://php.net/manual/en/mysqli-stmt.num-rows.php * @param mysqli_stmt $statement * @return string|int */ function mysqli_stmt_num_rows(mysqli_stmt $statement): string|int {} /** * Returns SQLSTATE error from previous statement operation * @link https://php.net/manual/en/mysqli-stmt.sqlstate.php * @param mysqli_stmt $statement * @return string Returns a string containing the SQLSTATE error code for the last error. The error code consists of five characters. '00000' means no error. */ function mysqli_stmt_sqlstate(mysqli_stmt $statement): string {} /** * Transfers a result set from a prepared statement * @link https://php.net/manual/en/mysqli-stmt.store-result.php * @param mysqli_stmt $statement * @return bool */ function mysqli_stmt_store_result(mysqli_stmt $statement): bool {} /** * Transfers a result set from the last query * @link https://php.net/manual/en/mysqli.store-result.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param int $mode [optional] The option that you want to set * @return mysqli_result|false */ function mysqli_store_result(mysqli $mysql, int $mode = 0): mysqli_result|false {} /** * Returns the thread ID for the current connection * @link https://php.net/manual/en/mysqli.thread-id.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return int Returns the Thread ID for the current connection. */ function mysqli_thread_id(mysqli $mysql): int {} /** * Returns whether thread safety is given or not * @link https://php.net/manual/en/mysqli.thread-safe.php * @return bool */ function mysqli_thread_safe(): bool {} /** * Initiate a result set retrieval * @link https://php.net/manual/en/mysqli.use-result.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return mysqli_result|false */ function mysqli_use_result(mysqli $mysql): mysqli_result|false {} /** * Returns the number of warnings from the last query for the given link * @link https://php.net/manual/en/mysqli.warning-count.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return int */ function mysqli_warning_count(mysqli $mysql): int {} /** * Flushes tables or caches, or resets the replication server information * @link https://php.net/manual/en/mysqli.refresh.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param int $flags * @return bool */ #[Deprecated("The function is deprecated", since: "8.4")] function mysqli_refresh(mysqli $mysql, int $flags): bool {} /** * Alias for mysqli_stmt_bind_param * @link https://php.net/manual/en/function.mysqli-bind-param.php * @param mysqli_stmt $statement * @param string $types * @removed 5.4 */ #[Deprecated(since: '5.3')] function mysqli_bind_param(mysqli_stmt $statement, string $types) {} /** * Alias for mysqli_stmt_bind_result * @link https://php.net/manual/en/function.mysqli-bind-result.php * @param mysqli_stmt $statement * @param string $types * @param mixed &$var1 * @removed 5.4 */ #[Deprecated(since: '5.3')] function mysqli_bind_result(mysqli_stmt $statement, string $types, mixed &$var1) {} /** * Alias of mysqli_character_set_name * @link https://php.net/manual/en/function.mysqli-client-encoding.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @return string * @removed 5.4 */ #[Deprecated(since: '5.3')] function mysqli_client_encoding(mysqli $mysql): string {} /** * Alias of mysqli_real_escape_string * @link https://php.net/manual/en/function.mysqli-escape-string.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param string $string The string to be escaped * @return string */ function mysqli_escape_string( mysqli $mysql, string $string, #[PhpStormStubsElementAvailable(from: '7.1', to: '7.4')] $resultmode = null ): string {} /** * Alias for mysqli_stmt_fetch * @link https://php.net/manual/en/function.mysqli-fetch.php * @param mysqli_stmt $statement * @return bool * @removed 5.4 */ #[Deprecated(since: '5.3')] function mysqli_fetch(mysqli_stmt $statement): bool {} /** * Alias for mysqli_stmt_param_count * @link https://php.net/manual/en/function.mysqli-param-count.php * @param mysqli_stmt $statement * @return int * @removed 5.4 */ #[Deprecated(since: '5.3')] function mysqli_param_count(mysqli_stmt $statement): int {} /** * Alias for mysqli_stmt_result_metadata * @link https://php.net/manual/en/function.mysqli-get-metadata.php * @param mysqli_stmt $statement * @return mysqli_result|false Returns a result object or FALSE if an error occurred * @removed 5.4 */ #[Deprecated(since: '5.3')] function mysqli_get_metadata(mysqli_stmt $statement): false|mysqli_result {} /** * Alias for mysqli_stmt_send_long_data * @link https://php.net/manual/en/function.mysqli-send-long-data.php * @param mysqli_stmt $statement * @param int $param_num * @param string $data * @return bool * @removed 5.4 */ #[Deprecated(since: '5.3')] function mysqli_send_long_data(mysqli_stmt $statement, int $param_num, string $data): bool {} /** * Alias of mysqli_options * @link https://php.net/manual/en/function.mysqli-set-opt.php * @param mysqli $mysql A link identifier returned by mysqli_connect() or mysqli_init() * @param int $option * @param string|int $value * @return bool */ function mysqli_set_opt( #[PhpStormStubsElementAvailable(from: '8.0')] mysqli $mysql, #[PhpStormStubsElementAvailable(from: '8.0')] int $option, #[PhpStormStubsElementAvailable(from: '8.0')] $value ): bool {} /** *

    * Read options from the named group from my.cnf * or the file specified with MYSQLI_READ_DEFAULT_FILE *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_READ_DEFAULT_GROUP', 5); /** *

    * Read options from the named option file instead of from my.cnf *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_READ_DEFAULT_FILE', 4); /** *

    * Connect timeout in seconds *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_OPT_CONNECT_TIMEOUT', 0); /** *

    * Enables command LOAD LOCAL INFILE *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_OPT_LOCAL_INFILE', 8); /** *

    * RSA public key file used with the SHA-256 based authentication. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_SERVER_PUBLIC_KEY', 35); /** *

    * Command to execute when connecting to MySQL server. Will automatically be re-executed when reconnecting. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_INIT_COMMAND', 3); define('MYSQLI_OPT_NET_CMD_BUFFER_SIZE', 202); define('MYSQLI_OPT_NET_READ_BUFFER_SIZE', 203); define('MYSQLI_OPT_INT_AND_FLOAT_NATIVE', 201); /** *

    * Use SSL (encrypted protocol). This option should not be set by application programs; * it is set internally in the MySQL client library *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_CLIENT_SSL', 2048); /** *

    * Use compression protocol *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_CLIENT_COMPRESS', 32); /** *

    * Allow interactive_timeout seconds * (instead of wait_timeout seconds) of inactivity before * closing the connection. The client's session * wait_timeout variable will be set to * the value of the session interactive_timeout variable. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_CLIENT_INTERACTIVE', 1024); /** *

    * Allow spaces after function names. Makes all functions names reserved words. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_CLIENT_IGNORE_SPACE', 256); /** *

    * Don't allow the db_name.tbl_name.col_name syntax. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_CLIENT_NO_SCHEMA', 16); define('MYSQLI_CLIENT_FOUND_ROWS', 2); /** *

    * For using buffered resultsets *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_STORE_RESULT', 0); /** *

    * For using unbuffered resultsets *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_USE_RESULT', 1); define('MYSQLI_ASYNC', 8); /** *

    * Columns are returned into the array having the fieldname as the array index. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_ASSOC', 1); /** *

    * Columns are returned into the array having an enumerated index. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_NUM', 2); /** *

    * Columns are returned into the array having both a numerical index and the fieldname as the associative index. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_BOTH', 3); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH', 0); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_STMT_ATTR_CURSOR_TYPE', 1); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_CURSOR_TYPE_NO_CURSOR', 0); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_CURSOR_TYPE_READ_ONLY', 1); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_CURSOR_TYPE_FOR_UPDATE', 2); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_CURSOR_TYPE_SCROLLABLE', 4); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_STMT_ATTR_PREFETCH_ROWS', 2); /** *

    * Indicates that a field is defined as NOT NULL *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_NOT_NULL_FLAG', 1); /** *

    * Field is part of a primary index *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_PRI_KEY_FLAG', 2); /** *

    * Field is part of a unique index. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_UNIQUE_KEY_FLAG', 4); /** *

    * Field is part of an index. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_MULTIPLE_KEY_FLAG', 8); /** *

    * Field is defined as BLOB *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_BLOB_FLAG', 16); /** *

    * Field is defined as UNSIGNED *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_UNSIGNED_FLAG', 32); /** *

    * Field is defined as ZEROFILL *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_ZEROFILL_FLAG', 64); /** *

    * Field is defined as AUTO_INCREMENT *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_AUTO_INCREMENT_FLAG', 512); /** *

    * Field is defined as TIMESTAMP *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TIMESTAMP_FLAG', 1024); /** *

    * Field is defined as SET *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_SET_FLAG', 2048); /** *

    * Field is defined as NUMERIC *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_NUM_FLAG', 32768); /** *

    * Field is part of an multi-index *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_PART_KEY_FLAG', 16384); /** *

    * Field is part of GROUP BY *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_GROUP_FLAG', 32768); /** *

    * Field is defined as ENUM. Available since PHP 5.3.0. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_ENUM_FLAG', 256); define('MYSQLI_BINARY_FLAG', 128); define('MYSQLI_NO_DEFAULT_VALUE_FLAG', 4096); define('MYSQLI_ON_UPDATE_NOW_FLAG', 8192); define('MYSQLI_TRANS_START_READ_ONLY', 4); define('MYSQLI_TRANS_START_READ_WRITE', 2); define('MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT', 1); /** *

    * Field is defined as DECIMAL *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_DECIMAL', 0); /** *

    * Field is defined as TINYINT *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_TINY', 1); /** *

    * Field is defined as SMALLINT *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_SHORT', 2); /** *

    * Field is defined as INT *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_LONG', 3); /** *

    * Field is defined as FLOAT *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_FLOAT', 4); /** *

    * Field is defined as DOUBLE *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_DOUBLE', 5); /** *

    * Field is defined as DEFAULT NULL *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_NULL', 6); /** *

    * Field is defined as TIMESTAMP *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_TIMESTAMP', 7); /** *

    * Field is defined as BIGINT *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_LONGLONG', 8); /** *

    * Field is defined as MEDIUMINT *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_INT24', 9); /** *

    * Field is defined as DATE *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_DATE', 10); /** *

    * Field is defined as TIME *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_TIME', 11); /** *

    * Field is defined as DATETIME *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_DATETIME', 12); /** *

    * Field is defined as YEAR *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_YEAR', 13); /** *

    * Field is defined as DATE *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_NEWDATE', 14); /** *

    * Field is defined as ENUM *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_ENUM', 247); /** *

    * Field is defined as SET *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_SET', 248); /** *

    * Field is defined as TINYBLOB *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_TINY_BLOB', 249); /** *

    * Field is defined as MEDIUMBLOB *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_MEDIUM_BLOB', 250); /** *

    * Field is defined as LONGBLOB *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_LONG_BLOB', 251); /** *

    * Field is defined as BLOB *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_BLOB', 252); /** *

    * Field is defined as VARCHAR *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_VAR_STRING', 253); /** *

    * Field is defined as STRING *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_STRING', 254); /** *

    * Field is defined as CHAR *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_CHAR', 1); /** *

    * Field is defined as INTERVAL *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_INTERVAL', 247); /** *

    * Field is defined as GEOMETRY *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_GEOMETRY', 255); /** *

    * Precision math DECIMAL or NUMERIC field (MySQL 5.0.3 and up) *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_NEWDECIMAL', 246); /** *

    * Field is defined as BIT (MySQL 5.0.3 and up) *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_TYPE_BIT', 16); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_SET_CHARSET_NAME', 7); /** *

    * No more data available for bind variable *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_NO_DATA', 100); /** *

    * Data truncation occurred. Available since PHP 5.1.0 and MySQL 5.0.5. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_DATA_TRUNCATED', 101); /** *

    * Report if no index or bad index was used in a query. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REPORT_INDEX', 4); /** *

    * Report errors from mysqli function calls. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REPORT_ERROR', 1); /** *

    * Throw a mysqli_sql_exception for errors instead of warnings. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REPORT_STRICT', 2); /** *

    * Set all options on (report all). *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REPORT_ALL', 255); /** *

    * Turns reporting off. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REPORT_OFF', 0); /** *

    * Is set to 1 if mysqli_debug functionality is enabled. *

    * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_DEBUG_TRACE_ENABLED', 0); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED', 16); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_SERVER_QUERY_NO_INDEX_USED', 32); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REFRESH_GRANT', 1); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REFRESH_LOG', 2); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REFRESH_TABLES', 4); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REFRESH_HOSTS', 8); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REFRESH_STATUS', 16); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REFRESH_THREADS', 32); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REFRESH_SLAVE', 64); /** * @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_REFRESH_MASTER', 128); define('MYSQLI_SERVER_QUERY_WAS_SLOW', 2048); define('MYSQLI_REFRESH_BACKUP_LOG', 2097152); // End of mysqli v.0.1 /** @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_OPT_SSL_VERIFY_SERVER_CERT', 21); /** @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_SET_CHARSET_DIR', 6); /** @link https://php.net/manual/en/mysqli.constants.php */ define('MYSQLI_SERVER_PS_OUT_PARAMS', 4096); define('MYSQLI_CLIENT_SSL_VERIFY_SERVER_CERT', 1073741824); define('MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT', 64); define('MYSQLI_CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS', 4194304); define('MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS', 37); define('MYSQLI_OPT_READ_TIMEOUT', 11); define('MYSQLI_STORE_RESULT_COPY_DATA', 16); define('MYSQLI_TYPE_JSON', 245); define('MYSQLI_TRANS_COR_AND_CHAIN', 1); define('MYSQLI_TRANS_COR_AND_NO_CHAIN', 2); define('MYSQLI_TRANS_COR_RELEASE', 4); define('MYSQLI_TRANS_COR_NO_RELEASE', 8); define('MYSQLI_OPT_LOAD_DATA_LOCAL_DIR', 43); define('MYSQLI_REFRESH_REPLICA', 64); /** * @since 8.1 */ define('MYSQLI_IS_MARIADB', 0); /** * @since 8.4 */ define('MYSQLI_TYPE_VECTOR', 242); * Message queue numeric ID *

    * @param int $permissions [optional]

    * Queue permissions. Default to 0666. If the message queue already * exists, the perms will be ignored. *

    * @return resource|SysvMessageQueue|false a resource handle that can be used to access the System V message queue. */ #[LanguageLevelTypeAware(["8.0" => "SysvMessageQueue|false"], default: "resource|false")] function msg_get_queue(int $key, int $permissions = 0666) {} /** * Send a message to a message queue * @link https://php.net/manual/en/function.msg-send.php * @param SysvMessageQueue|resource $queue * @param int $message_type * @param mixed $message * @param bool $serialize [optional]

    * The optional serialize controls how the * message is sent. serialize * defaults to TRUE which means that the message is * serialized using the same mechanism as the session module before being * sent to the queue. This allows complex arrays and objects to be sent to * other PHP scripts, or if you are using the WDDX serializer, to any WDDX * compatible client. *

    * @param bool $blocking [optional]

    * If the message is too large to fit in the queue, your script will wait * until another process reads messages from the queue and frees enough * space for your message to be sent. * This is called blocking; you can prevent blocking by setting the * optional blocking parameter to FALSE, in which * case msg_send will immediately return FALSE if the * message is too big for the queue, and set the optional * errorcode to MSG_EAGAIN, * indicating that you should try to send your message again a little * later on. *

    * @param int &$error_code [optional] * @return bool TRUE on success or FALSE on failure. *

    * Upon successful completion the message queue data structure is updated as * follows: msg_lspid is set to the process-ID of the * calling process, msg_qnum is incremented by 1 and * msg_stime is set to the current time. *

    */ function msg_send(#[LanguageLevelTypeAware(["8.0" => "SysvMessageQueue"], default: "resource")] $queue, int $message_type, $message, bool $serialize = true, bool $blocking = true, &$error_code): bool {} /** * Receive a message from a message queue * @link https://php.net/manual/en/function.msg-receive.php * @param SysvMessageQueue|resource $queue * @param int $desired_message_type

    * If desiredmsgtype is 0, the message from the front * of the queue is returned. If desiredmsgtype is * greater than 0, then the first message of that type is returned. * If desiredmsgtype is less than 0, the first * message on the queue with the lowest type less than or equal to the * absolute value of desiredmsgtype will be read. * If no messages match the criteria, your script will wait until a suitable * message arrives on the queue. You can prevent the script from blocking * by specifying MSG_IPC_NOWAIT in the * flags parameter. *

    * @param int &$received_message_type

    * The type of the message that was received will be stored in this * parameter. *

    * @param int $max_message_size

    * The maximum size of message to be accepted is specified by the * maxsize; if the message in the queue is larger * than this size the function will fail (unless you set * flags as described below). *

    * @param mixed &$message

    * The received message will be stored in message, * unless there were errors receiving the message. *

    * @param bool $unserialize [optional]

    * If set to * TRUE, the message is treated as though it was serialized using the * same mechanism as the session module. The message will be unserialized * and then returned to your script. This allows you to easily receive * arrays or complex object structures from other PHP scripts, or if you * are using the WDDX serializer, from any WDDX compatible source. *

    *

    * If unserialize is FALSE, the message will be * returned as a binary-safe string. *

    * @param int $flags [optional]

    * The optional flags allows you to pass flags to the * low-level msgrcv system call. It defaults to 0, but you may specify one * or more of the following values (by adding or ORing them together). *

    * Flag values for msg_receive * * * * * * * * * * * * *
    MSG_IPC_NOWAITIf there are no messages of the * desiredmsgtype, return immediately and do not * wait. The function will fail and return an integer value * corresponding to MSG_ENOMSG. *
    MSG_EXCEPTUsing this flag in combination with a * desiredmsgtype greater than 0 will cause the * function to receive the first message that is not equal to * desiredmsgtype.
    MSG_NOERROR * If the message is longer than maxsize, * setting this flag will truncate the message to * maxsize and will not signal an error. *
    *

    * @param int $error_code [optional]

    * If the function fails, the optional errorcode * will be set to the value of the system errno variable. *

    * @return bool TRUE on success or FALSE on failure. *

    * Upon successful completion the message queue data structure is updated as * follows: msg_lrpid is set to the process-ID of the * calling process, msg_qnum is decremented by 1 and * msg_rtime is set to the current time. *

    */ function msg_receive(#[LanguageLevelTypeAware(["8.0" => "SysvMessageQueue"], default: "resource")] $queue, int $desired_message_type, &$received_message_type, int $max_message_size, mixed & $message, bool $unserialize = true, int $flags = 0, &$error_code): bool {} /** * Destroy a message queue * @link https://php.net/manual/en/function.msg-remove-queue.php * @param SysvMessageQueue|resource $queue

    * Message queue resource handle *

    * @return bool TRUE on success or FALSE on failure. */ function msg_remove_queue(#[LanguageLevelTypeAware(["8.0" => "SysvMessageQueue"], default: "resource")] $queue): bool {} /** * Returns information from the message queue data structure * @link https://php.net/manual/en/function.msg-stat-queue.php * @param SysvMessageQueue|resource $queue

    * Message queue resource handle *

    * @return array|false The return value is an array whose keys and values have the following * meanings: * * Array structure for msg_stat_queue * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    msg_perm.uid * The uid of the owner of the queue. *
    msg_perm.gid * The gid of the owner of the queue. *
    msg_perm.mode * The file access mode of the queue. *
    msg_stime * The time that the last message was sent to the queue. *
    msg_rtime * The time that the last message was received from the queue. *
    msg_ctime * The time that the queue was last changed. *
    msg_qnum * The number of messages waiting to be read from the queue. *
    msg_qbytes * The maximum number of bytes allowed in one message queue. On * Linux, this value may be read and modified via * /proc/sys/kernel/msgmnb. *
    msg_lspid * The pid of the process that sent the last message to the queue. *
    msg_lrpid * The pid of the process that received the last message from the queue. *
    */ #[ArrayShape([ "msg_perm.uid" => "int", "msg_perm.gid" => "int", "msg_perm.mode" => "int", "msg_stime" => "int", "msg_rtime" => "int", "msg_ctime" => "int", "msg_qnum" => "int", "msg_qbytes" => "int", "msg_lspid" => "int", "msg_lrpid" => "int", ])] function msg_stat_queue(#[LanguageLevelTypeAware(["8.0" => "SysvMessageQueue"], default: "resource")] $queue): array|false {} /** * Set information in the message queue data structure * @link https://php.net/manual/en/function.msg-set-queue.php * @param SysvMessageQueue|resource $queue

    * Message queue resource handle *

    * @param array $data

    * You specify the values you require by setting the value of the keys * that you require in the data array. *

    * @return bool TRUE on success or FALSE on failure. */ function msg_set_queue(#[LanguageLevelTypeAware(["8.0" => "SysvMessageQueue"], default: "resource")] $queue, array $data): bool {} /** * Check whether a message queue exists * @link https://php.net/manual/en/function.msg-queue-exists.php * @param int $key

    * Queue key. *

    * @return bool TRUE on success or FALSE on failure. */ function msg_queue_exists(int $key): bool {} define('MSG_IPC_NOWAIT', 1); define('MSG_EAGAIN', 11); define('MSG_ENOMSG', 42); define('MSG_NOERROR', 2); define('MSG_EXCEPT', 4); /** * @since 8.0 */ final class SysvMessageQueue { /** * Cannot directly construct SysvMessageQueue, use msg_get_queue() instead * @see msg_get_queue() */ private function __construct() {} } // End of sysvmsg v. * You may specify a string with which to prompt the user. *

    * @return string|false a single string from the user. The line returned has the ending newline removed. * If there is no more data to read, then FALSE is returned. */ function readline(?string $prompt): string|false {} /** * Gets/sets various internal readline variables * @link https://php.net/manual/en/function.readline-info.php * @param string|null $var_name [optional]

    * A variable name. *

    * @param string $value [optional]

    * If provided, this will be the new value of the setting. *

    * @return mixed If called with no parameters, this function returns an array of * values for all the setting readline uses. The elements will * be indexed by the following values: done, end, erase_empty_line, * library_version, line_buffer, mark, pending_input, point, prompt, * readline_name, and terminal_name. *

    *

    * If called with one or two parameters, the old value is returned. */ #[ArrayShape([ 'line_buffer' => 'string', 'point' => 'int', 'end' => 'int', 'mark' => 'int', 'done' => 'int', 'pending_input' => 'int', 'prompt' => 'string', 'terminal_name' => 'string', 'completion_append_character' => 'string', 'completion_suppress_append' => 'bool', 'erase_empty_line' => 'int', 'library_version' => 'string', 'readline_name' => 'string', 'attempted_completion_over' => 'int', ])] function readline_info(?string $var_name, $value): mixed {} /** * Adds a line to the history * @link https://php.net/manual/en/function.readline-add-history.php * @param string $prompt

    * The line to be added in the history. *

    * @return bool TRUE on success or FALSE on failure. */ function readline_add_history(string $prompt): bool {} /** * Clears the history * @link https://php.net/manual/en/function.readline-clear-history.php * @return bool TRUE on success or FALSE on failure. */ function readline_clear_history(): bool {} /** * Lists the history * @link https://php.net/manual/en/function.readline-list-history.php * @return array an array of the entire command line history. The elements are * indexed by integers starting at zero. */ function readline_list_history(): array {} /** * Reads the history * @link https://php.net/manual/en/function.readline-read-history.php * @param string|null $filename [optional]

    * Path to the filename containing the command history. *

    * @return bool TRUE on success or FALSE on failure. */ function readline_read_history(?string $filename): bool {} /** * Writes the history * @link https://php.net/manual/en/function.readline-write-history.php * @param string|null $filename [optional]

    * Path to the saved file. *

    * @return bool TRUE on success or FALSE on failure. */ function readline_write_history(?string $filename): bool {} /** * Registers a completion function * @link https://php.net/manual/en/function.readline-completion-function.php * @param callable $callback

    * You must supply the name of an existing function which accepts a * partial command line and returns an array of possible matches. *

    * @return bool TRUE on success or FALSE on failure. */ function readline_completion_function(callable $callback): bool {} /** * Initializes the readline callback interface and terminal, prints the prompt and returns immediately * @link https://php.net/manual/en/function.readline-callback-handler-install.php * @param string $prompt

    * The prompt message. *

    * @param callable $callback

    * The callback function takes one parameter; the * user input returned. *

    * @return bool TRUE on success or FALSE on failure. */ function readline_callback_handler_install(string $prompt, callable $callback): bool {} /** * Reads a character and informs the readline callback interface when a line is received * @link https://php.net/manual/en/function.readline-callback-read-char.php * @return void No value is returned. */ function readline_callback_read_char(): void {} /** * Removes a previously installed callback handler and restores terminal settings * @link https://php.net/manual/en/function.readline-callback-handler-remove.php * @return bool TRUE if a previously installed callback handler was removed, or * FALSE if one could not be found. */ function readline_callback_handler_remove(): bool {} /** * Redraws the display * @link https://php.net/manual/en/function.readline-redisplay.php * @return void No value is returned. */ function readline_redisplay(): void {} /** * Inform readline that the cursor has moved to a new line * @link https://php.net/manual/en/function.readline-on-new-line.php * @return void No value is returned. */ function readline_on_new_line(): void {} define('READLINE_LIB', "readline"); // End of readline v.5.5.3-1ubuntu2.1 'string'], default: '')] $filename) {} /** * Gets the path without filename * @link https://php.net/manual/en/splfileinfo.getpath.php * @return string the path to the file. * @since 5.1.2 */ #[TentativeType] public function getPath(): string {} /** * Gets the filename * @link https://php.net/manual/en/splfileinfo.getfilename.php * @return string The filename. * @since 5.1.2 */ #[TentativeType] public function getFilename(): string {} /** * Gets the file extension * @link https://php.net/manual/en/splfileinfo.getextension.php * @return string a string containing the file extension, or an * empty string if the file has no extension. * @since 5.3.6 */ #[TentativeType] public function getExtension(): string {} /** * Gets the base name of the file * @link https://php.net/manual/en/splfileinfo.getbasename.php * @param string $suffix [optional]

    * Optional suffix to omit from the base name returned. *

    * @return string the base name without path information. * @since 5.2.2 */ #[TentativeType] public function getBasename(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $suffix = ''): string {} /** * Gets the path to the file * @link https://php.net/manual/en/splfileinfo.getpathname.php * @return string The path to the file. * @since 5.1.2 */ #[TentativeType] public function getPathname(): string {} /** * Gets file permissions * @link https://php.net/manual/en/splfileinfo.getperms.php * @return int|false The file permissions on success, or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function getPerms(): int|false {} /** * Gets the inode for the file * @link https://php.net/manual/en/splfileinfo.getinode.php * @return int|false The inode number for the filesystem object on success, or FALSE on failure. * @since 5.1.2 * @throws \RuntimeException on error. */ #[TentativeType] public function getInode(): int|false {} /** * Gets file size * @link https://php.net/manual/en/splfileinfo.getsize.php * @return int|false The filesize in bytes on success, or FALSE on failure. * @since 5.1.2 * @throws \RuntimeException on error. */ #[TentativeType] public function getSize(): int|false {} /** * Gets the owner of the file * @link https://php.net/manual/en/splfileinfo.getowner.php * @return int|false The owner id in numerical format on success, or FALSE on failure. * @since 5.1.2 * @throws \RuntimeException on error. */ #[TentativeType] public function getOwner(): int|false {} /** * Gets the file group * @link https://php.net/manual/en/splfileinfo.getgroup.php * @return int|false The group id in numerical format on success, or FALSE on failure. * @since 5.1.2 * @throws \RuntimeException on error. */ #[TentativeType] public function getGroup(): int|false {} /** * Gets last access time of the file * @link https://php.net/manual/en/splfileinfo.getatime.php * @return int|false The time the file was last accessed on success, or FALSE on failure. * @since 5.1.2 * @throws \RuntimeException on error. */ #[TentativeType] public function getATime(): int|false {} /** * Gets the last modified time * @link https://php.net/manual/en/splfileinfo.getmtime.php * @return int|false The last modified time for the file, in a Unix timestamp on success, or FALSE on failure. * @since 5.1.2 */ #[TentativeType] public function getMTime(): int|false {} /** * Gets the inode change time * @link https://php.net/manual/en/splfileinfo.getctime.php * @return int|false The last change time, in a Unix timestamp on success, or FALSE on failure. * @since 5.1.2 * @throws \RuntimeException on error. */ #[TentativeType] public function getCTime(): int|false {} /** * Gets file type * @link https://php.net/manual/en/splfileinfo.gettype.php * @return string|false A string representing the type of the entry. May be one of file, link, dir, block, fifo, char, socket, or unknown, or FALSE on failure. * May be one of file, link, * or dir * @since 5.1.2 * @throws \RuntimeException on error. */ #[TentativeType] public function getType(): string|false {} /** * Tells if the entry is writable * @link https://php.net/manual/en/splfileinfo.iswritable.php * @return bool true if writable, false otherwise; * @since 5.1.2 */ #[TentativeType] public function isWritable(): bool {} /** * Tells if file is readable * @link https://php.net/manual/en/splfileinfo.isreadable.php * @return bool true if readable, false otherwise. * @since 5.1.2 */ #[TentativeType] public function isReadable(): bool {} /** * Tells if the file is executable * @link https://php.net/manual/en/splfileinfo.isexecutable.php * @return bool true if executable, false otherwise. * @since 5.1.2 */ #[TentativeType] public function isExecutable(): bool {} /** * Tells if the object references a regular file * @link https://php.net/manual/en/splfileinfo.isfile.php * @return bool true if the file exists and is a regular file (not a link), false otherwise. * @since 5.1.2 */ #[TentativeType] public function isFile(): bool {} /** * Tells if the file is a directory * @link https://php.net/manual/en/splfileinfo.isdir.php * @return bool true if a directory, false otherwise. * @since 5.1.2 */ #[TentativeType] public function isDir(): bool {} /** * Tells if the file is a link * @link https://php.net/manual/en/splfileinfo.islink.php * @return bool true if the file is a link, false otherwise. * @since 5.1.2 */ #[TentativeType] public function isLink(): bool {} /** * Gets the target of a link * @link https://php.net/manual/en/splfileinfo.getlinktarget.php * @return string|false The target of the filesystem link on success, or FALSE on failure. * @since 5.2.2 * @throws \RuntimeException on error. */ #[TentativeType] public function getLinkTarget(): string|false {} /** * Gets absolute path to file * @link https://php.net/manual/en/splfileinfo.getrealpath.php * @return string|false the path to the file, or FALSE if the file does not exist. * @since 5.2.2 */ #[TentativeType] public function getRealPath(): string|false {} /** * Gets an SplFileInfo object for the file * @template T of SplFileInfo * @link https://php.net/manual/en/splfileinfo.getfileinfo.php * @param class-string $class [optional]

    * Name of an SplFileInfo derived class to use. *

    * @return T An SplFileInfo object created for the file. * @since 5.1.2 */ #[TentativeType] public function getFileInfo(#[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $class = null): SplFileInfo {} /** * Gets an SplFileInfo object for the path * @template T of SplFileInfo * @link https://php.net/manual/en/splfileinfo.getpathinfo.php * @param class-string $class [optional]

    * Name of an SplFileInfo derived class to use. *

    * @return T|null A SplFileInfo object for the parent path of the file on success, or NULL on failure. * @since 5.1.2 */ #[TentativeType] public function getPathInfo(#[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $class = null): ?SplFileInfo {} /** * Gets an SplFileObject object for the file * @link https://php.net/manual/en/splfileinfo.openfile.php * @param string $mode [optional]

    * The mode for opening the file. See the fopen * documentation for descriptions of possible modes. The default * is read only. *

    * @param bool $useIncludePath [optional]

    *

    * @param resource $context [optional]

    *

    * @return SplFileObject The opened file as an SplFileObject object. * @since 5.1.2 * @throws \RuntimeException If the file cannot be opened (e.g. insufficient access rights). */ #[TentativeType] public function openFile( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $mode = 'r', #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $useIncludePath = false, $context = null ): SplFileObject {} /** * Sets the class name used with SplFileInfo::openFile * @template T of SplFileObject * @link https://php.net/manual/en/splfileinfo.setfileclass.php * @param class-string $class [optional]

    * The class name to use when openFile() is called. *

    * @return void * @since 5.1.2 */ #[TentativeType] public function setFileClass(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $class = SplFileObject::class): void {} /** * Sets the class used with getFileInfo and getPathInfo * @template T of SplFileInfo * @link https://php.net/manual/en/splfileinfo.setinfoclass.php * @param class-string $class [optional]

    * The class name to use. *

    * @return void * @since 5.1.2 */ #[TentativeType] public function setInfoClass(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $class = SplFileInfo::class): void {} /** * Returns the path to the file as a string * @link https://php.net/manual/en/splfileinfo.tostring.php * @return string the path to the file. * @since 5.1.2 */ #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] public function __toString() {} #[TentativeType] final public function _bad_state_ex(): void {} public function __wakeup() {} /** * @return array * @since 7.4 */ #[TentativeType] public function __debugInfo(): array {} } /** * The DirectoryIterator class provides a simple interface for viewing * the contents of filesystem directories. * @link https://php.net/manual/en/class.directoryiterator.php */ class DirectoryIterator extends SplFileInfo implements SeekableIterator { /** * Constructs a new directory iterator from a path * @link https://php.net/manual/en/directoryiterator.construct.php * @param string $directory * @throws UnexpectedValueException if the path cannot be opened. * @throws RuntimeException if the path is an empty string. */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $directory) {} /** * Determine if current DirectoryIterator item is '.' or '..' * @link https://php.net/manual/en/directoryiterator.isdot.php * @return bool true if the entry is . or .., * otherwise false */ #[TentativeType] public function isDot(): bool {} /** * Rewind the DirectoryIterator back to the start * @link https://php.net/manual/en/directoryiterator.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Check whether current DirectoryIterator position is a valid file * @link https://php.net/manual/en/directoryiterator.valid.php * @return bool true if the position is valid, otherwise false */ #[TentativeType] public function valid(): bool {} /** * Return the key for the current DirectoryIterator item * @link https://php.net/manual/en/directoryiterator.key.php * @return string The key for the current DirectoryIterator item. */ #[TentativeType] public function key(): mixed {} /** * Return the current DirectoryIterator item. * @link https://php.net/manual/en/directoryiterator.current.php * @return DirectoryIterator The current DirectoryIterator item. */ #[TentativeType] public function current(): mixed {} /** * Move forward to next DirectoryIterator item * @link https://php.net/manual/en/directoryiterator.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Seek to a DirectoryIterator item * @link https://php.net/manual/en/directoryiterator.seek.php * @param int $offset

    * The zero-based numeric position to seek to. *

    * @return void */ #[TentativeType] public function seek(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset): void {} } /** * The Filesystem iterator * @link https://php.net/manual/en/class.filesystemiterator.php */ class FilesystemIterator extends DirectoryIterator { public const CURRENT_MODE_MASK = 240; public const CURRENT_AS_PATHNAME = 32; public const CURRENT_AS_FILEINFO = 0; public const CURRENT_AS_SELF = 16; public const KEY_MODE_MASK = 3840; public const KEY_AS_PATHNAME = 0; public const FOLLOW_SYMLINKS = 16384; public const KEY_AS_FILENAME = 256; public const NEW_CURRENT_AND_KEY = 256; public const SKIP_DOTS = 4096; public const UNIX_PATHS = 8192; public const OTHER_MODE_MASK = 28672; /** * Constructs a new filesystem iterator * @link https://php.net/manual/en/filesystemiterator.construct.php * @param string $directory * @param int $flags [optional] * @throws UnexpectedValueException if the path cannot be found. */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $directory, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = FilesystemIterator::KEY_AS_PATHNAME|FilesystemIterator::CURRENT_AS_FILEINFO|FilesystemIterator::SKIP_DOTS ) {} /** * Rewinds back to the beginning * @link https://php.net/manual/en/filesystemiterator.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Move to the next file * @link https://php.net/manual/en/filesystemiterator.next.php * @return void */ public function next() {} /** * Retrieve the key for the current file * @link https://php.net/manual/en/filesystemiterator.key.php * @return string the pathname or filename depending on the set flags. * See the FilesystemIterator constants. */ #[TentativeType] public function key(): string {} /** * The current file * @link https://php.net/manual/en/filesystemiterator.current.php * @return string|SplFileInfo|self The filename, file information, or $this depending on the set flags. * See the FilesystemIterator constants. */ #[TentativeType] public function current(): SplFileInfo|FilesystemIterator|string {} /** * Get the handling flags * @link https://php.net/manual/en/filesystemiterator.getflags.php * @return int The integer value of the set flags. */ #[TentativeType] public function getFlags(): int {} /** * Sets handling flags * @link https://php.net/manual/en/filesystemiterator.setflags.php * @param int $flags

    * The handling flags to set. * See the FilesystemIterator constants. *

    * @return void */ #[TentativeType] public function setFlags( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $flags = null, #[PhpStormStubsElementAvailable(from: '8.0')] int $flags ): void {} } /** * The RecursiveDirectoryIterator provides * an interface for iterating recursively over filesystem directories. * @link https://php.net/manual/en/class.recursivedirectoryiterator.php */ class RecursiveDirectoryIterator extends FilesystemIterator implements RecursiveIterator { /** * Constructs a RecursiveDirectoryIterator * @link https://php.net/manual/en/recursivedirectoryiterator.construct.php * @param string $directory * @param int $flags [optional] * @throws UnexpectedValueException if the path cannot be found or is not a directory. * @since 5.1.2 */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $directory, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = FilesystemIterator::KEY_AS_PATHNAME|FilesystemIterator::CURRENT_AS_FILEINFO ) {} /** * Returns whether current entry is a directory and not '.' or '..' * @link https://php.net/manual/en/recursivedirectoryiterator.haschildren.php * @param bool $allowLinks [optional]

    *

    * @return bool whether the current entry is a directory, but not '.' or '..' */ #[TentativeType] public function hasChildren(#[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $allowLinks = false): bool {} /** * Returns an iterator for the current entry if it is a directory * @link https://php.net/manual/en/recursivedirectoryiterator.getchildren.php * @return RecursiveDirectoryIterator An iterator for the current entry, if it is a directory. */ #[TentativeType] public function getChildren(): RecursiveDirectoryIterator {} /** * Get sub path * @link https://php.net/manual/en/recursivedirectoryiterator.getsubpath.php * @return string The sub path (sub directory). */ #[TentativeType] public function getSubPath(): string {} /** * Get sub path and name * @link https://php.net/manual/en/recursivedirectoryiterator.getsubpathname.php * @return string The sub path (sub directory) and filename. */ #[TentativeType] public function getSubPathname(): string {} /** * Rewinds back to the beginning * @link https://php.net/manual/en/filesystemiterator.rewind.php * @return void */ public function rewind() {} /** * Move to the next file * @link https://php.net/manual/en/filesystemiterator.next.php * @return void */ public function next() {} /** * Retrieve the key for the current file * @link https://php.net/manual/en/filesystemiterator.key.php * @return string the pathname or filename depending on the set flags. * See the FilesystemIterator constants. */ public function key() {} /** * The current file * @link https://php.net/manual/en/filesystemiterator.current.php * @return string|SplFileInfo|self The filename, file information, or $this depending on the set flags. * See the FilesystemIterator constants. */ public function current() {} } /** * Iterates through a file system in a similar fashion to * glob. * @link https://php.net/manual/en/class.globiterator.php */ class GlobIterator extends FilesystemIterator implements Countable { /** * Construct a directory using glob * @link https://php.net/manual/en/globiterator.construct.php * @param $pattern * @param int $flags [optional] */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $pattern, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = FilesystemIterator::KEY_AS_PATHNAME|FilesystemIterator::CURRENT_AS_FILEINFO ) {} /** * Get the number of directories and files * @link https://php.net/manual/en/globiterator.count.php * @return int<0,max> The number of returned directories and files, as an * integer. */ #[TentativeType] public function count(): int {} } /** * The SplFileObject class offers an object oriented interface for a file. * @link https://php.net/manual/en/class.splfileobject.php */ class SplFileObject extends SplFileInfo implements RecursiveIterator, SeekableIterator { /** * Drop newlines at the end of a line. */ public const DROP_NEW_LINE = 1; /** * Read on rewind/next. */ public const READ_AHEAD = 2; /** * Skip empty lines in the file. This requires the {@see READ_AHEAD} flag to work as expected. */ public const SKIP_EMPTY = 4; /** * Read lines as CSV rows. */ public const READ_CSV = 8; /** * Construct a new file object. * * @link https://php.net/manual/en/splfileobject.construct.php * * @param string $filename The file to open * @param string $mode [optional] The mode in which to open the file. See {@see fopen} for a list of allowed modes. * @param bool $useIncludePath [optional] Whether to search in the include_path for filename * @param resource $context [optional] A valid context resource created with {@see stream_context_create} * * @throws RuntimeException When the filename cannot be opened * @throws LogicException When the filename is a directory */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $mode = 'r', #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $useIncludePath = false, $context = null ) {} /** * Rewind the file to the first line * @link https://php.net/manual/en/splfileobject.rewind.php * @return void * * @throws RuntimeException If cannot be rewound */ #[TentativeType] public function rewind(): void {} /** * Reached end of file * @link https://php.net/manual/en/splfileobject.eof.php * @return bool true if file is at EOF, false otherwise. */ #[TentativeType] public function eof(): bool {} /** * Not at EOF * @link https://php.net/manual/en/splfileobject.valid.php * @return bool true if not reached EOF, false otherwise. */ #[TentativeType] public function valid(): bool {} /** * Gets line from file * @link https://php.net/manual/en/splfileobject.fgets.php * @return string a string containing the next line from the file. * * @throws RuntimeException If the file cannot be read */ #[TentativeType] public function fgets(): string {} /** * Read from file * @link https://php.net/manual/en/splfileobject.fread.php * @param int $length

    * The number of bytes to read. *

    * @return string|false returns the string read from the file or FALSE on failure. * @since 5.5.11 */ #[TentativeType] public function fread(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $length): string|false {} /** * Gets line from file and parse as CSV fields * @link https://php.net/manual/en/splfileobject.fgetcsv.php * @param string $separator [optional]

    * The field delimiter (one character only). Defaults as a comma or the value set using SplFileObject::setCsvControl. *

    * @param string $enclosure [optional]

    * The field enclosure character (one character only). Defaults as a double quotation mark or the value set using SplFileObject::setCsvControl. *

    * @param string $escape [optional]

    * The escape character (one character only). Defaults as a backslash (\) or the value set using SplFileObject::setCsvControl. *

    * @return array|false|null an indexed array containing the fields read, or false on error. *

    *

    * A blank line in a CSV file will be returned as an array * comprising a single null field unless using SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE, * in which case empty lines are skipped. */ #[TentativeType] #[LanguageLevelTypeAware(['8.1' => 'array|false'], default: 'array|false|null')] public function fgetcsv( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $separator = ",", #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $enclosure = "\"", #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $escape = "\\" ) {} /** * Write a field array as a CSV line * @link https://php.net/manual/en/splfileobject.fputcsv.php * @param array $fields An array of values * @param string $separator [optional]

    * The field delimiter (one character only). Defaults as a comma or the value set using SplFileObject::setCsvControl. *

    * @param string $enclosure [optional]

    * The field enclosure character (one character only). Defaults as a double quotation mark or the value set using SplFileObject::setCsvControl. *

    * @param string $escape The optional escape parameter sets the escape character (one character only). * @return int|false Returns the length of the written string or FALSE on failure. * @since 5.4 */ #[TentativeType] public function fputcsv( array $fields, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $separator = ',', #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $enclosure = '"', #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $escape = "\\", #[PhpStormStubsElementAvailable('8.1')] string $eol = PHP_EOL ): int|false {} /** * Set the delimiter and enclosure character for CSV * @link https://php.net/manual/en/splfileobject.setcsvcontrol.php * @param string $separator [optional]

    * The field delimiter (one character only). *

    * @param string $enclosure [optional]

    * The field enclosure character (one character only). *

    * @param string $escape [optional]

    * The field escape character (one character only). *

    * @return void */ #[TentativeType] public function setCsvControl( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $separator = ",", #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $enclosure = "\"", #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $escape = "\\" ): void {} /** * Get the delimiter and enclosure character for CSV * @link https://php.net/manual/en/splfileobject.getcsvcontrol.php * @return array an indexed array containing the delimiter and enclosure character. */ #[TentativeType] public function getCsvControl(): array {} /** * Portable file locking * @link https://php.net/manual/en/splfileobject.flock.php * @param int $operation

    * operation is one of the following: * LOCK_SH to acquire a shared lock (reader). *

    * @param int &$wouldBlock [optional]

    * Set to 1 if the lock would block (EWOULDBLOCK errno condition). *

    * @return bool true on success or false on failure. */ #[TentativeType] public function flock(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $operation, &$wouldBlock = null): bool {} /** * Flushes the output to the file * @link https://php.net/manual/en/splfileobject.fflush.php * @return bool true on success or false on failure. */ #[TentativeType] public function fflush(): bool {} /** * Return current file position * @link https://php.net/manual/en/splfileobject.ftell.php * @return int|false the position of the file pointer as an integer, or false on error. */ #[TentativeType] public function ftell(): int|false {} /** * Seek to a position * @link https://php.net/manual/en/splfileobject.fseek.php * @param int $offset

    * The offset. A negative value can be used to move backwards through the file which * is useful when SEEK_END is used as the whence value. *

    * @param int $whence [optional]

    * whence values are: * SEEK_SET - Set position equal to offset bytes. * SEEK_CUR - Set position to current location plus offset. * SEEK_END - Set position to end-of-file plus offset. *

    *

    * If whence is not specified, it is assumed to be SEEK_SET. *

    * @return int 0 if the seek was successful, -1 otherwise. Note that seeking * past EOF is not considered an error. */ #[TentativeType] public function fseek( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $whence = SEEK_SET ): int {} /** * Gets character from file * @link https://php.net/manual/en/splfileobject.fgetc.php * @return string|false a string containing a single character read from the file or false on EOF. */ #[TentativeType] public function fgetc(): string|false {} /** * Output all remaining data on a file pointer * @link https://php.net/manual/en/splfileobject.fpassthru.php * @return int the number of characters read from handle * and passed through to the output. */ #[TentativeType] public function fpassthru(): int {} /** * Gets line from file and strip HTML tags * @link https://php.net/manual/en/splfileobject.fgetss.php * @param string $allowable_tags [optional]

    * You can use the optional third parameter to specify tags which should * not be stripped. *

    * @return string|false a string containing the next line of the file with HTML and PHP * code stripped, or false on error. * @removed 8.0 */ #[Deprecated(since: '7.3')] public function fgetss($allowable_tags = null) {} /** * Parses input from file according to a format * @link https://php.net/manual/en/splfileobject.fscanf.php * @param string $format

    * The specified format as described in the sprintf documentation. *

    * @param mixed &...$vars [optional]

    * The optional assigned values. *

    * @return array|int|null If only one parameter is passed to this method, the values parsed will be * returned as an array. Otherwise, if optional parameters are passed, the * function will return the number of assigned values. The optional * parameters must be passed by reference. */ #[TentativeType] public function fscanf( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $format, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] &...$vars ): array|int|null {} /** * Write to file * @link https://php.net/manual/en/splfileobject.fwrite.php * @param string $data

    * The string to be written to the file. *

    * @param int $length [optional]

    * If the length argument is given, writing will * stop after length bytes have been written or * the end of string is reached, whichever comes * first. *

    * @return int|false the number of bytes written, or 0 (false since 7.4) on error. */ #[LanguageLevelTypeAware(['7.4' => 'int|false'], default: 'int')] #[TentativeType] public function fwrite( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $length = 0 ): int|false {} /** * Gets information about the file * @link https://php.net/manual/en/splfileobject.fstat.php * @return array an array with the statistics of the file; the format of the array * is described in detail on the stat manual page. */ #[TentativeType] public function fstat(): array {} /** * Truncates the file to a given length * @link https://php.net/manual/en/splfileobject.ftruncate.php * @param int $size

    * The size to truncate to. *

    *

    * If size is larger than the file it is extended with null bytes. *

    *

    * If size is smaller than the file, the extra data will be lost. *

    * @return bool true on success or false on failure. */ #[TentativeType] public function ftruncate(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $size): bool {} /** * Retrieve current line of file * @link https://php.net/manual/en/splfileobject.current.php * @return string|array|false Retrieves the current line of the file. If the SplFileObject::READ_CSV flag is set, this method returns an array containing the current line parsed as CSV data. */ #[TentativeType] public function current(): string|array|false {} /** * Get line number * @link https://php.net/manual/en/splfileobject.key.php * @return int the current line number. */ #[TentativeType] public function key(): int {} /** * Read next line * @link https://php.net/manual/en/splfileobject.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Sets flags for the SplFileObject * @link https://php.net/manual/en/splfileobject.setflags.php * @param int $flags

    * Bit mask of the flags to set. See * SplFileObject constants * for the available flags. *

    * @return void */ #[TentativeType] public function setFlags(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags): void {} /** * Gets flags for the SplFileObject * @link https://php.net/manual/en/splfileobject.getflags.php * @return int an integer representing the flags. */ #[TentativeType] public function getFlags(): int {} /** * Set maximum line length * @link https://php.net/manual/en/splfileobject.setmaxlinelen.php * @param int $maxLength

    * The maximum length of a line. *

    * @return void * * @throws DomainException When maxLength is less than zero. */ #[TentativeType] public function setMaxLineLen(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $maxLength): void {} /** * Get maximum line length * @link https://php.net/manual/en/splfileobject.getmaxlinelen.php * @return int<0, max> the maximum line length if one has been set with * SplFileObject::setMaxLineLen, default is 0. */ #[TentativeType] public function getMaxLineLen(): int {} /** * SplFileObject does not have children * @link https://php.net/manual/en/splfileobject.haschildren.php * @return bool false * @since 5.1.2 */ #[TentativeType] #[LanguageLevelTypeAware(['8.2' => 'false'], default: 'bool')] public function hasChildren() {} /** * No purpose * @link https://php.net/manual/en/splfileobject.getchildren.php * @return null|RecursiveIterator An SplFileObject does not have children so this method returns NULL. */ #[TentativeType] #[LanguageLevelTypeAware(['8.2' => 'null'], default: 'null|RecursiveIterator')] public function getChildren() {} /** * Seek to specified line * @link https://php.net/manual/en/splfileobject.seek.php * @param int $line

    * The zero-based line number to seek to. *

    * @return void * @throws LogicException If the line is negative */ #[TentativeType] public function seek(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $line): void {} /** * Alias of SplFileObject::fgets * @link https://php.net/manual/en/splfileobject.getcurrentline.php * @return string Returns a string containing the next line from the file. * @since 5.1.2 */ #[TentativeType] public function getCurrentLine(): string {} /** * Alias of SplFileObject::current * @link https://php.net/manual/en/splfileobject.tostring.php */ #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] public function __toString() {} } /** * The SplTempFileObject class offers an object oriented interface for a temporary file. * @link https://php.net/manual/en/class.spltempfileobject.php */ class SplTempFileObject extends SplFileObject { /** * Construct a new temporary file object * @link https://php.net/manual/en/spltempfileobject.construct.php * @param int $maxMemory [optional] * @throws RuntimeException if an error occurs. * @since 5.1.2 */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $maxMemory = 2097152) {} } /** * @template TValue * The SplDoublyLinkedList class provides the main functionalities of a doubly linked list. * @link https://php.net/manual/en/class.spldoublylinkedlist.php * @template-implements Iterator * @template-implements ArrayAccess */ class SplDoublyLinkedList implements Iterator, Countable, ArrayAccess, Serializable { public const IT_MODE_LIFO = 2; public const IT_MODE_FIFO = 0; public const IT_MODE_DELETE = 1; public const IT_MODE_KEEP = 0; /** * Add/insert a new value at the specified index * @param mixed $index The index where the new value is to be inserted. * @param TValue $value The new value for the index. * @return void * @link https://php.net/spldoublylinkedlist.add * @since 5.5 */ #[TentativeType] public function add( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value ): void {} /** * Pops a node from the end of the doubly linked list * @link https://php.net/manual/en/spldoublylinkedlist.pop.php * @return TValue The value of the popped node. */ #[TentativeType] public function pop(): mixed {} /** * Shifts a node from the beginning of the doubly linked list * @link https://php.net/manual/en/spldoublylinkedlist.shift.php * @return TValue The value of the shifted node. */ #[TentativeType] public function shift(): mixed {} /** * Pushes an element at the end of the doubly linked list * @link https://php.net/manual/en/spldoublylinkedlist.push.php * @param TValue $value

    * The value to push. *

    * @return void */ #[TentativeType] public function push(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value): void {} /** * Prepends the doubly linked list with an element * @link https://php.net/manual/en/spldoublylinkedlist.unshift.php * @param TValue $value

    * The value to unshift. *

    * @return void */ #[TentativeType] public function unshift(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value): void {} /** * Peeks at the node from the end of the doubly linked list * @link https://php.net/manual/en/spldoublylinkedlist.top.php * @return TValue The value of the last node. */ #[TentativeType] public function top(): mixed {} /** * Peeks at the node from the beginning of the doubly linked list * @link https://php.net/manual/en/spldoublylinkedlist.bottom.php * @return TValue The value of the first node. */ #[TentativeType] public function bottom(): mixed {} /** * Counts the number of elements in the doubly linked list. * @link https://php.net/manual/en/spldoublylinkedlist.count.php * @return int the number of elements in the doubly linked list. */ #[TentativeType] public function count(): int {} /** * Checks whether the doubly linked list is empty. * @link https://php.net/manual/en/spldoublylinkedlist.isempty.php * @return bool whether the doubly linked list is empty. */ #[TentativeType] public function isEmpty(): bool {} /** * Sets the mode of iteration * @link https://php.net/manual/en/spldoublylinkedlist.setiteratormode.php * @param int $mode

    * There are two orthogonal sets of modes that can be set: *

    * The direction of the iteration (either one or the other): * SplDoublyLinkedList::IT_MODE_LIFO (Stack style) * @return int */ #[TentativeType] public function setIteratorMode(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $mode): int {} /** * Returns the mode of iteration * @link https://php.net/manual/en/spldoublylinkedlist.getiteratormode.php * @return int the different modes and flags that affect the iteration. */ #[TentativeType] public function getIteratorMode(): int {} /** * Returns whether the requested $index exists * @link https://php.net/manual/en/spldoublylinkedlist.offsetexists.php * @param mixed $index

    * The index being checked. *

    * @return bool true if the requested index exists, otherwise false */ #[TentativeType] public function offsetExists($index): bool {} /** * Returns the value at the specified $index * @link https://php.net/manual/en/spldoublylinkedlist.offsetget.php * @param mixed $index

    * The index with the value. *

    * @return TValue The value at the specified index. */ #[TentativeType] public function offsetGet($index): mixed {} /** * Sets the value at the specified $index to $newval * @link https://php.net/manual/en/spldoublylinkedlist.offsetset.php * @param mixed $index

    * The index being set. *

    * @param TValue $value

    * The new value for the index. *

    * @return void */ #[TentativeType] public function offsetSet($index, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value): void {} /** * Unsets the value at the specified $index * @link https://php.net/manual/en/spldoublylinkedlist.offsetunset.php * @param mixed $index

    * The index being unset. *

    * @return void */ #[TentativeType] public function offsetUnset($index): void {} /** * Rewind iterator back to the start * @link https://php.net/manual/en/spldoublylinkedlist.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Return current array entry * @link https://php.net/manual/en/spldoublylinkedlist.current.php * @return TValue The current node value. */ #[TentativeType] public function current(): mixed {} /** * Return current node index * @link https://php.net/manual/en/spldoublylinkedlist.key.php * @return string|float|int|bool|null The current node index. */ #[TentativeType] public function key(): int {} /** * Move to next entry * @link https://php.net/manual/en/spldoublylinkedlist.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Move to previous entry * @link https://php.net/manual/en/spldoublylinkedlist.prev.php * @return void */ #[TentativeType] public function prev(): void {} /** * Check whether the doubly linked list contains more nodes * @link https://php.net/manual/en/spldoublylinkedlist.valid.php * @return bool true if the doubly linked list contains any more nodes, false otherwise. */ #[TentativeType] public function valid(): bool {} /** * Unserializes the storage * @link https://php.net/manual/en/spldoublylinkedlist.serialize.php * @param string $data The serialized string. * @return void * @since 5.4 */ #[TentativeType] public function unserialize(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data): void {} /** * Serializes the storage * @link https://php.net/manual/en/spldoublylinkedlist.unserialize.php * @return string The serialized string. * @since 5.4 */ #[TentativeType] public function serialize(): string {} /** * @return array * @since 7.4 */ #[TentativeType] public function __debugInfo(): array {} /** * @return array * @since 7.4 */ #[TentativeType] public function __serialize(): array {} /** * @param array $data * @since 7.4 */ #[TentativeType] public function __unserialize(array $data): void {} } /** * @template TValue * The SplQueue class provides the main functionalities of a queue implemented using a doubly linked list. * @link https://php.net/manual/en/class.splqueue.php */ class SplQueue extends SplDoublyLinkedList { /** * Adds an element to the queue. * @link https://php.net/manual/en/splqueue.enqueue.php * @param TValue $value

    * The value to enqueue. *

    * @return void */ #[TentativeType] public function enqueue(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value): void {} /** * Dequeues a node from the queue * @link https://php.net/manual/en/splqueue.dequeue.php * @return TValue The value of the dequeued node. */ #[TentativeType] public function dequeue(): mixed {} /** * Sets the mode of iteration * @link https://php.net/manual/en/spldoublylinkedlist.setiteratormode.php * @param int $mode

    * There are two orthogonal sets of modes that can be set: *

    * The direction of the iteration (either one or the other): * SplDoublyLinkedList::IT_MODE_LIFO (Stack style) * @return void */ public function setIteratorMode($mode) {} } /** * @template TValue * The SplStack class provides the main functionalities of a stack implemented using a doubly linked list. * @link https://php.net/manual/en/class.splstack.php * @template-extends SplDoublyLinkedList */ class SplStack extends SplDoublyLinkedList { /** * Sets the mode of iteration * @link https://php.net/manual/en/spldoublylinkedlist.setiteratormode.php * @param int $mode

    * There are two orthogonal sets of modes that can be set: *

    * The direction of the iteration (either one or the other): * SplDoublyLinkedList::IT_MODE_LIFO (Stack style) * @return void */ public function setIteratorMode($mode) {} } /** * @template TValue * The SplHeap class provides the main functionalities of an Heap. * @link https://php.net/manual/en/class.splheap.php * @template-implements Iterator */ abstract class SplHeap implements Iterator, Countable { /** * Extracts a node from top of the heap and sift up. * @link https://php.net/manual/en/splheap.extract.php * @return TValue The value of the extracted node. */ #[TentativeType] public function extract(): mixed {} /** * Inserts an element in the heap by sifting it up. * @link https://php.net/manual/en/splheap.insert.php * @param TValue $value

    * The value to insert. *

    * @return bool */ #[TentativeType] #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] public function insert(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value) {} /** * Peeks at the node from the top of the heap * @link https://php.net/manual/en/splheap.top.php * @return TValue The value of the node on the top. */ #[TentativeType] public function top(): mixed {} /** * Counts the number of elements in the heap. * @link https://php.net/manual/en/splheap.count.php * @return int the number of elements in the heap. */ #[TentativeType] public function count(): int {} /** * Checks whether the heap is empty. * @link https://php.net/manual/en/splheap.isempty.php * @return bool whether the heap is empty. */ #[TentativeType] public function isEmpty(): bool {} /** * Rewind iterator back to the start (no-op) * @link https://php.net/manual/en/splheap.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Return current node pointed by the iterator * @link https://php.net/manual/en/splheap.current.php * @return TValue The current node value. */ #[TentativeType] public function current(): mixed {} /** * Return current node index * @link https://php.net/manual/en/splheap.key.php * @return int The current node index. */ #[TentativeType] public function key(): int {} /** * Move to the next node * @link https://php.net/manual/en/splheap.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Check whether the heap contains more nodes * @link https://php.net/manual/en/splheap.valid.php * @return bool true if the heap contains any more nodes, false otherwise. */ #[TentativeType] public function valid(): bool {} /** * Recover from the corrupted state and allow further actions on the heap. * @link https://php.net/manual/en/splheap.recoverfromcorruption.php * @return bool */ #[TentativeType] #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] public function recoverFromCorruption() {} /** * Compare elements in order to place them correctly in the heap while sifting up. * @link https://php.net/manual/en/splheap.compare.php * @param mixed $value1

    * The value of the first node being compared. *

    * @param mixed $value2

    * The value of the second node being compared. *

    * @return int Result of the comparison, positive integer if value1 is greater than value2, 0 if they are equal, negative integer otherwise. *

    *

    * Having multiple elements with the same value in a Heap is not recommended. They will end up in an arbitrary relative position. */ abstract protected function compare($value1, $value2); /** * @return bool */ #[TentativeType] public function isCorrupted(): bool {} /** * @return array * @since 7.4 */ #[TentativeType] public function __debugInfo(): array {} } /** * @template TValue * The SplMinHeap class provides the main functionalities of a heap, keeping the minimum on the top. * @link https://php.net/manual/en/class.splminheap.php * @template-extends SplHeap */ class SplMinHeap extends SplHeap { /** * Compare elements in order to place them correctly in the heap while sifting up. * @link https://php.net/manual/en/splminheap.compare.php * @param TValue $value1

    * The value of the first node being compared. *

    * @param TValue $value2

    * The value of the second node being compared. *

    * @return int Result of the comparison, positive integer if value1 is lower than value2, 0 if they are equal, negative integer otherwise. *

    *

    * Having multiple elements with the same value in a Heap is not recommended. They will end up in an arbitrary relative position. */ #[TentativeType] protected function compare( #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value1, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value2 ): int {} /** * Extracts a node from top of the heap and sift up. * @link https://php.net/manual/en/splheap.extract.php * @return TValue The value of the extracted node. */ public function extract() {} /** * Inserts an element in the heap by sifting it up. * @link https://php.net/manual/en/splheap.insert.php * @param TValue $value

    * The value to insert. *

    * @return true */ public function insert($value) {} /** * Peeks at the node from the top of the heap * @link https://php.net/manual/en/splheap.top.php * @return TValue The value of the node on the top. */ public function top() {} /** * Counts the number of elements in the heap. * @link https://php.net/manual/en/splheap.count.php * @return int the number of elements in the heap. */ public function count() {} /** * Checks whether the heap is empty. * @link https://php.net/manual/en/splheap.isempty.php * @return bool whether the heap is empty. */ public function isEmpty() {} /** * Rewind iterator back to the start (no-op) * @link https://php.net/manual/en/splheap.rewind.php * @return void */ public function rewind() {} /** * Return current node pointed by the iterator * @link https://php.net/manual/en/splheap.current.php * @return TValue The current node value. */ public function current() {} /** * Return current node index * @link https://php.net/manual/en/splheap.key.php * @return int The current node index. */ public function key() {} /** * Move to the next node * @link https://php.net/manual/en/splheap.next.php * @return void */ public function next() {} /** * Check whether the heap contains more nodes * @link https://php.net/manual/en/splheap.valid.php * @return bool true if the heap contains any more nodes, false otherwise. */ public function valid() {} /** * Recover from the corrupted state and allow further actions on the heap. * @link https://php.net/manual/en/splheap.recoverfromcorruption.php * @return void */ public function recoverFromCorruption() {} } /** * @template TValue * The SplMaxHeap class provides the main functionalities of a heap, keeping the maximum on the top. * @link https://php.net/manual/en/class.splmaxheap.php * @template-extends SplHeap */ class SplMaxHeap extends SplHeap { /** * Compare elements in order to place them correctly in the heap while sifting up. * @link https://php.net/manual/en/splmaxheap.compare.php * @param TValue $value1

    * The value of the first node being compared. *

    * @param TValue $value2

    * The value of the second node being compared. *

    * @return int Result of the comparison, positive integer if value1 is greater than value2, 0 if they are equal, negative integer otherwise. *

    *

    * Having multiple elements with the same value in a Heap is not recommended. They will end up in an arbitrary relative position. */ #[TentativeType] protected function compare( #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value1, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value2 ): int {} } /** * @template TPriority * @template TValue * The SplPriorityQueue class provides the main functionalities of an * prioritized queue, implemented using a heap. * @link https://php.net/manual/en/class.splpriorityqueue.php * @template-implements Iterator */ class SplPriorityQueue implements Iterator, Countable { public const EXTR_BOTH = 3; public const EXTR_PRIORITY = 2; public const EXTR_DATA = 1; /** * Compare priorities in order to place elements correctly in the heap while sifting up. * @link https://php.net/manual/en/splpriorityqueue.compare.php * @param TPriority $priority1

    * The priority of the first node being compared. *

    * @param TPriority $priority2

    * The priority of the second node being compared. *

    * @return int Result of the comparison, positive integer if priority1 is greater than priority2, 0 if they are equal, negative integer otherwise. *

    *

    * Multiple elements with the same priority will get dequeued in no particular order. */ #[TentativeType] public function compare( #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $priority1, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $priority2 ): int {} /** * Inserts an element in the queue by sifting it up. * @link https://php.net/manual/en/splpriorityqueue.insert.php * @param TValue $value

    * The value to insert. *

    * @param TPriority $priority

    * The associated priority. *

    * @return true */ #[TentativeType] public function insert( #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $priority ): true {} /** * Sets the mode of extraction * @link https://php.net/manual/en/splpriorityqueue.setextractflags.php * @param int $flags

    * Defines what is extracted by SplPriorityQueue::current, * SplPriorityQueue::top and * SplPriorityQueue::extract. *

    * SplPriorityQueue::EXTR_DATA (0x00000001): Extract the data * @return int */ #[TentativeType] public function setExtractFlags(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags): int {} /** * Peeks at the node from the top of the queue * @link https://php.net/manual/en/splpriorityqueue.top.php * @return TValue The value or priority (or both) of the top node, depending on the extract flag. */ #[TentativeType] public function top(): mixed {} /** * Extracts a node from top of the heap and sift up. * @link https://php.net/manual/en/splpriorityqueue.extract.php * @return TValue The value or priority (or both) of the extracted node, depending on the extract flag. */ #[TentativeType] public function extract(): mixed {} /** * Counts the number of elements in the queue. * @link https://php.net/manual/en/splpriorityqueue.count.php * @return int the number of elements in the queue. */ #[TentativeType] public function count(): int {} /** * Checks whether the queue is empty. * @link https://php.net/manual/en/splpriorityqueue.isempty.php * @return bool whether the queue is empty. */ #[TentativeType] public function isEmpty(): bool {} /** * Rewind iterator back to the start (no-op) * @link https://php.net/manual/en/splpriorityqueue.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Return current node pointed by the iterator * @link https://php.net/manual/en/splpriorityqueue.current.php * @return TValue The value or priority (or both) of the current node, depending on the extract flag. */ #[TentativeType] public function current(): mixed {} /** * Return current node index * @link https://php.net/manual/en/splpriorityqueue.key.php * @return int The current node index. */ #[TentativeType] public function key(): int {} /** * Move to the next node * @link https://php.net/manual/en/splpriorityqueue.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Check whether the queue contains more nodes * @link https://php.net/manual/en/splpriorityqueue.valid.php * @return bool true if the queue contains any more nodes, false otherwise. */ #[TentativeType] public function valid(): bool {} /** * Recover from the corrupted state and allow further actions on the queue. * @link https://php.net/manual/en/splpriorityqueue.recoverfromcorruption.php */ #[TentativeType] public function recoverFromCorruption(): true {} /** * @return bool */ #[TentativeType] public function isCorrupted(): bool {} /** * @return int */ #[TentativeType] public function getExtractFlags(): int {} /** * @return array * @since 7.4 */ #[TentativeType] public function __debugInfo(): array {} } /** * @template TValue * The SplFixedArray class provides the main functionalities of array. The * main differences between a SplFixedArray and a normal PHP array is that * the SplFixedArray is of fixed length and allows only integers within * the range as indexes. The advantage is that it allows a faster array * implementation. * @link https://php.net/manual/en/class.splfixedarray.php * @template-implements Iterator * @template-implements ArrayAccess * @template-implements IteratorAggregate */ class SplFixedArray implements Iterator, ArrayAccess, Countable, IteratorAggregate, JsonSerializable { /** * Constructs a new fixed array * @link https://php.net/manual/en/splfixedarray.construct.php * @param int $size [optional] */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $size = 0) {} /** * Returns the size of the array * @link https://php.net/manual/en/splfixedarray.count.php * @return int the size of the array. */ #[TentativeType] public function count(): int {} /** * Returns a PHP array from the fixed array * @link https://php.net/manual/en/splfixedarray.toarray.php * @return TValue[] a PHP array, similar to the fixed array. */ #[TentativeType] public function toArray(): array {} /** * Import a PHP array in a SplFixedArray instance * @link https://php.net/manual/en/splfixedarray.fromarray.php * @param array $array

    * The array to import. *

    * @param bool $preserveKeys [optional]

    * Try to save the numeric indexes used in the original array. *

    * @return SplFixedArray an instance of SplFixedArray * containing the array content. */ #[TentativeType] public static function fromArray( #[LanguageLevelTypeAware(['8.0' => 'array'], default: '')] $array, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $preserveKeys = true ): SplFixedArray {} /** * Gets the size of the array * @link https://php.net/manual/en/splfixedarray.getsize.php * @return int the size of the array, as an integer. */ #[TentativeType] public function getSize(): int {} /** * Change the size of an array * @link https://php.net/manual/en/splfixedarray.setsize.php * @param int $size

    * The new array size. *

    * @return bool */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function setSize(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $size) {} /** * Returns whether the requested index exists * @link https://php.net/manual/en/splfixedarray.offsetexists.php * @param int $index

    * The index being checked. *

    * @return bool true if the requested index exists, otherwise false */ #[TentativeType] public function offsetExists($index): bool {} /** * Returns the value at the specified index * @link https://php.net/manual/en/splfixedarray.offsetget.php * @param int $index

    * The index with the value. *

    * @return TValue The value at the specified index. */ #[TentativeType] public function offsetGet($index): mixed {} /** * Sets a new value at a specified index * @link https://php.net/manual/en/splfixedarray.offsetset.php * @param int $index

    * The index being set. *

    * @param TValue $value

    * The new value for the index. *

    * @return void */ #[TentativeType] public function offsetSet($index, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value): void {} /** * Unsets the value at the specified $index * @link https://php.net/manual/en/splfixedarray.offsetunset.php * @param int $index

    * The index being unset. *

    * @return void */ #[TentativeType] public function offsetUnset($index): void {} /** * Rewind iterator back to the start * @link https://php.net/manual/en/splfixedarray.rewind.php * @return void */ public function rewind() {} /** * Return current array entry * @link https://php.net/manual/en/splfixedarray.current.php * @return TValue The current element value. */ public function current() {} /** * Return current array index * @link https://php.net/manual/en/splfixedarray.key.php * @return int The current array index. */ public function key() {} /** * Move to next entry * @link https://php.net/manual/en/splfixedarray.next.php * @return void */ public function next() {} /** * Check whether the array contains more elements * @link https://php.net/manual/en/splfixedarray.valid.php * @return bool true if the array contains any more elements, false otherwise. */ #[TentativeType] public function valid(): bool {} #[TentativeType] public function __wakeup(): void {} #[PhpStormStubsElementAvailable(from: '8.2')] public function __serialize(): array {} #[PhpStormStubsElementAvailable(from: '8.2')] public function __unserialize(array $data): void {} /** * @since 8.0 * @return Iterator */ public function getIterator(): Iterator {} #[PhpStormStubsElementAvailable(from: '8.1')] public function jsonSerialize(): array {} } /** * The SplObserver interface is used alongside * SplSubject to implement the Observer Design Pattern. * @link https://php.net/manual/en/class.splobserver.php */ interface SplObserver { /** * Receive update from subject * @link https://php.net/manual/en/splobserver.update.php * @param SplSubject $subject

    * The SplSubject notifying the observer of an update. *

    * @return void */ #[TentativeType] public function update(SplSubject $subject): void; } /** * The SplSubject interface is used alongside * SplObserver to implement the Observer Design Pattern. * @link https://php.net/manual/en/class.splsubject.php */ interface SplSubject { /** * Attach an SplObserver * @link https://php.net/manual/en/splsubject.attach.php * @param SplObserver $observer

    * The SplObserver to attach. *

    * @return void */ #[TentativeType] public function attach(SplObserver $observer): void; /** * Detach an observer * @link https://php.net/manual/en/splsubject.detach.php * @param SplObserver $observer

    * The SplObserver to detach. *

    * @return void */ #[TentativeType] public function detach(SplObserver $observer): void; /** * Notify an observer * @link https://php.net/manual/en/splsubject.notify.php * @return void */ #[TentativeType] public function notify(): void; } /** * @template TObject of object * @template TValue * The SplObjectStorage class provides a map from objects to data or, by * ignoring data, an object set. This dual purpose can be useful in many * cases involving the need to uniquely identify objects. * @link https://php.net/manual/en/class.splobjectstorage.php * @template-implements Iterator * @template-implements ArrayAccess */ class SplObjectStorage implements Countable, SeekableIterator, Serializable, ArrayAccess { /** * Adds an object in the storage * @link https://php.net/manual/en/splobjectstorage.attach.php * @param TObject $object

    * The object to add. *

    * @param TValue $info [optional]

    * The data to associate with the object. *

    * @return void */ #[TentativeType] public function attach( #[LanguageLevelTypeAware(['8.0' => 'object'], default: '')] $object, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $info = null ): void {} /** * Removes an object from the storage * @link https://php.net/manual/en/splobjectstorage.detach.php * @param TObject $object

    * The object to remove. *

    * @return void */ #[TentativeType] public function detach(#[LanguageLevelTypeAware(['8.0' => 'object'], default: '')] $object): void {} /** * Checks if the storage contains a specific object * @link https://php.net/manual/en/splobjectstorage.contains.php * @param TObject $object

    * The object to look for. *

    * @return bool true if the object is in the storage, false otherwise. */ #[TentativeType] public function contains(#[LanguageLevelTypeAware(['8.0' => 'object'], default: '')] $object): bool {} /** * Adds all objects from another storage * @link https://php.net/manual/en/splobjectstorage.addall.php * @param SplObjectStorage $storage

    * The storage you want to import. *

    * @return int */ #[TentativeType] public function addAll(#[LanguageLevelTypeAware(['8.0' => 'SplObjectStorage'], default: '')] $storage): int {} /** * Removes objects contained in another storage from the current storage * @link https://php.net/manual/en/splobjectstorage.removeall.php * @param SplObjectStorage $storage

    * The storage containing the elements to remove. *

    * @return int */ #[TentativeType] public function removeAll(#[LanguageLevelTypeAware(['8.0' => 'SplObjectStorage'], default: '')] $storage): int {} /** * Removes all objects except for those contained in another storage from the current storage * @link https://php.net/manual/en/splobjectstorage.removeallexcept.php * @param SplObjectStorage $storage

    * The storage containing the elements to retain in the current storage. *

    * @return int * @since 5.3.6 */ #[TentativeType] public function removeAllExcept(#[LanguageLevelTypeAware(['8.0' => 'SplObjectStorage'], default: '')] $storage): int {} /** * Returns the data associated with the current iterator entry * @link https://php.net/manual/en/splobjectstorage.getinfo.php * @return TValue The data associated with the current iterator position. */ #[TentativeType] public function getInfo(): mixed {} /** * Sets the data associated with the current iterator entry * @link https://php.net/manual/en/splobjectstorage.setinfo.php * @param TValue $info

    * The data to associate with the current iterator entry. *

    * @return void */ #[TentativeType] public function setInfo(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $info): void {} /** * Returns the number of objects in the storage * @link https://php.net/manual/en/splobjectstorage.count.php * @param int $mode [optional] * @return int The number of objects in the storage. */ #[TentativeType] public function count(#[PhpStormStubsElementAvailable(from: '8.0')] int $mode = COUNT_NORMAL): int {} /** * Rewind the iterator to the first storage element * @link https://php.net/manual/en/splobjectstorage.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Returns if the current iterator entry is valid * @link https://php.net/manual/en/splobjectstorage.valid.php * @return bool true if the iterator entry is valid, false otherwise. */ #[TentativeType] public function valid(): bool {} /** * Returns the index at which the iterator currently is * @link https://php.net/manual/en/splobjectstorage.key.php * @return int The index corresponding to the position of the iterator. */ #[TentativeType] public function key(): int {} /** * Returns the current storage entry * @link https://php.net/manual/en/splobjectstorage.current.php * @return TObject The object at the current iterator position. */ #[TentativeType] public function current(): object {} /** * Move to the next entry * @link https://php.net/manual/en/splobjectstorage.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Unserializes a storage from its string representation * @link https://php.net/manual/en/splobjectstorage.unserialize.php * @param string $data

    * The serialized representation of a storage. *

    * @return void * @since 5.2.2 */ #[TentativeType] public function unserialize(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data): void {} /** * Serializes the storage * @link https://php.net/manual/en/splobjectstorage.serialize.php * @return string A string representing the storage. * @since 5.2.2 */ #[TentativeType] public function serialize(): string {} /** * Checks whether an object exists in the storage * @link https://php.net/manual/en/splobjectstorage.offsetexists.php * @param TObject $object

    * The object to look for. *

    * @return bool true if the object exists in the storage, * and false otherwise. */ #[TentativeType] public function offsetExists($object): bool {} /** * Associates data to an object in the storage * @link https://php.net/manual/en/splobjectstorage.offsetset.php * @param TObject $object

    * The object to associate data with. *

    * @param TValue $info [optional]

    * The data to associate with the object. *

    * @return void */ #[TentativeType] public function offsetSet( #[LanguageLevelTypeAware(['8.1' => 'mixed'], default: '')] $object, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $info = null ): void {} /** * Removes an object from the storage * @link https://php.net/manual/en/splobjectstorage.offsetunset.php * @param TObject $object

    * The object to remove. *

    * @return void */ #[TentativeType] public function offsetUnset($object): void {} /** * Returns the data associated with an object * @link https://php.net/manual/en/splobjectstorage.offsetget.php * @param TObject $object

    * The object to look for. *

    * @return TValue The data previously associated with the object in the storage. */ #[TentativeType] public function offsetGet($object): mixed {} /** * Calculate a unique identifier for the contained objects * @link https://php.net/manual/en/splobjectstorage.gethash.php * @param TObject $object

    * object whose identifier is to be calculated. *

    * @return string A string with the calculated identifier. * @since 5.4 */ #[TentativeType] public function getHash(#[LanguageLevelTypeAware(['8.0' => 'object'], default: '')] $object): string {} /** * @return array * @since 7.4 */ #[TentativeType] public function __serialize(): array {} /** * @param array $data * @since 7.4 */ #[TentativeType] public function __unserialize(array $data): void {} /** * @return array * @since 7.4 */ #[TentativeType] public function __debugInfo(): array {} /** * @since 8.4 */ public function seek(int $offset): void {} } /** * An Iterator that sequentially iterates over all attached iterators * @link https://php.net/manual/en/class.multipleiterator.php */ class MultipleIterator implements Iterator { public const MIT_NEED_ANY = 0; public const MIT_NEED_ALL = 1; public const MIT_KEYS_NUMERIC = 0; public const MIT_KEYS_ASSOC = 2; /** * Constructs a new MultipleIterator * @link https://php.net/manual/en/multipleiterator.construct.php * @param int $flags Defaults to MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC */ public function __construct( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $flags, #[PhpStormStubsElementAvailable(from: '8.0')] int $flags = MultipleIterator::MIT_NEED_ALL|MultipleIterator::MIT_KEYS_NUMERIC ) {} /** * Gets the flag information * @link https://php.net/manual/en/multipleiterator.getflags.php * @return int Information about the flags, as an integer. */ #[TentativeType] public function getFlags(): int {} /** * Sets flags * @link https://php.net/manual/en/multipleiterator.setflags.php * @param int $flags

    * The flags to set, according to the * Flag Constants *

    * @return void */ #[TentativeType] public function setFlags(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags): void {} /** * Attaches iterator information * @link https://php.net/manual/en/multipleiterator.attachiterator.php * @param Iterator $iterator

    * The new iterator to attach. *

    * @param int|string|null $info [optional]

    * The associative information for the Iterator, which must be an * integer, a string, or null. *

    * @return void Description... */ #[TentativeType] public function attachIterator(Iterator $iterator, #[LanguageLevelTypeAware(['8.0' => 'int|string|null'], default: '')] $info = null): void {} /** * Detaches an iterator * @link https://php.net/manual/en/multipleiterator.detachiterator.php * @param Iterator $iterator

    * The iterator to detach. *

    * @return void */ #[TentativeType] public function detachIterator(Iterator $iterator): void {} /** * Checks if an iterator is attached * @link https://php.net/manual/en/multipleiterator.containsiterator.php * @param Iterator $iterator

    * The iterator to check. *

    * @return bool true on success or false on failure. */ #[TentativeType] public function containsIterator(Iterator $iterator): bool {} /** * Gets the number of attached iterator instances * @link https://php.net/manual/en/multipleiterator.countiterators.php * @return int The number of attached iterator instances (as an integer). */ #[TentativeType] public function countIterators(): int {} /** * Rewinds all attached iterator instances * @link https://php.net/manual/en/multipleiterator.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Checks the validity of sub iterators * @link https://php.net/manual/en/multipleiterator.valid.php * @return bool true if one or all sub iterators are valid depending on flags, * otherwise false */ #[TentativeType] public function valid(): bool {} /** * Gets the registered iterator instances * @link https://php.net/manual/en/multipleiterator.key.php * @return array An array of all registered iterator instances, * or false if no sub iterator is attached. */ #[TentativeType] public function key(): array {} /** * Gets the registered iterator instances * @link https://php.net/manual/en/multipleiterator.current.php * @return array An array containing the current values of each attached iterator, * or false if no iterators are attached. * @throws RuntimeException if mode MIT_NEED_ALL is set and at least one attached iterator is not valid. * @throws InvalidArgumentException if a key is NULL and MIT_KEYS_ASSOC is set. */ #[TentativeType] public function current(): array {} /** * Moves all attached iterator instances forward * @link https://php.net/manual/en/multipleiterator.next.php * @return void */ #[TentativeType] public function next(): void {} /** * @return array * @since 7.4 */ #[TentativeType] public function __debugInfo(): array {} } DomainException. * @link https://php.net/manual/en/class.rangeexception.php */ class RangeException extends RuntimeException {} /** * Exception thrown when performing an invalid operation on an empty container, such as removing an element. * @link https://php.net/manual/en/class.underflowexception.php */ class UnderflowException extends RuntimeException {} /** * Exception thrown if a value does not match with a set of values. Typically * this happens when a function calls another function and expects the return * value to be of a certain type or value not including arithmetic or buffer * related errors. * @link https://php.net/manual/en/class.unexpectedvalueexception.php */ class UnexpectedValueException extends RuntimeException {} /** * The EmptyIterator class for an empty iterator. * @link https://secure.php.net/manual/en/class.emptyiterator.php */ class EmptyIterator implements Iterator { /** * Return the current element * @link https://php.net/manual/en/iterator.current.php * @return mixed Can return any type. */ #[TentativeType] public function current(): never {} /** * Move forward to next element * @link https://php.net/manual/en/iterator.next.php * @return void Any returned value is ignored. */ #[TentativeType] public function next(): void {} /** * Return the key of the current element * @link https://php.net/manual/en/iterator.key.php * @return mixed The key of the current element. */ #[TentativeType] public function key(): never {} /** * Checks if current position is valid * @link https://php.net/manual/en/iterator.valid.php * @return bool The return value will be casted to boolean and then evaluated. * Returns true on success or false on failure. */ #[TentativeType] #[LanguageLevelTypeAware(['8.2' => 'false'], default: 'bool')] public function valid() {} /** * Rewind the Iterator to the first element * @link https://php.net/manual/en/iterator.rewind.php * @return void Any returned value is ignored. */ #[TentativeType] public function rewind(): void {} } /** * Filtered iterator using the callback to determine which items are accepted or rejected. * @link https://secure.php.net/manual/en/class.callbackfilteriterator.php * @since 5.4 */ class CallbackFilterIterator extends FilterIterator { /** * Creates a filtered iterator using the callback to determine which items are accepted or rejected. * @param Iterator $iterator The iterator to be filtered. * @param callable $callback The callback, which should return TRUE to accept the current item or FALSE otherwise. * May be any valid callable value. * The callback should accept up to three arguments: the current item, the current key and the iterator, respectively. * function my_callback($current, $key, $iterator) * @link https://secure.php.net/manual/en/callbackfilteriterator.construct.php */ public function __construct(Iterator $iterator, callable $callback) {} /** * This method calls the callback with the current value, current key and the inner iterator. * The callback is expected to return TRUE if the current item is to be accepted, or FALSE otherwise. * @link https://secure.php.net/manual/en/callbackfilteriterator.accept.php * @return bool true if the current element is acceptable, otherwise false. */ #[TentativeType] public function accept(): bool {} } /** * (PHP 5 >= 5.4.0)
    * RecursiveCallbackFilterIterator from a RecursiveIterator * @link https://secure.php.net/manual/en/class.recursivecallbackfilteriterator.php * @since 5.4 */ class RecursiveCallbackFilterIterator extends CallbackFilterIterator implements RecursiveIterator { /** * Create a RecursiveCallbackFilterIterator from a RecursiveIterator * @param RecursiveIterator $iterator The recursive iterator to be filtered. * @param callable $callback The callback, which should return TRUE to accept the current item or FALSE otherwise. See Examples. * May be any valid callable value. * @link https://www.php.net/manual/en/recursivecallbackfilteriterator.construct.php */ public function __construct( RecursiveIterator $iterator, #[LanguageLevelTypeAware(['8.0' => 'callable'], default: '')] $callback ) {} /** * Check whether the inner iterator's current element has children * @link https://php.net/manual/en/recursiveiterator.haschildren.php * @return bool Returns TRUE if the current element has children, FALSE otherwise. */ #[TentativeType] public function hasChildren(): bool {} /** * Returns an iterator for the current entry. * @link https://secure.php.net/manual/en/recursivecallbackfilteriterator.haschildren.php * @return RecursiveCallbackFilterIterator containing the children. */ #[TentativeType] public function getChildren(): RecursiveCallbackFilterIterator {} } /** * Classes implementing RecursiveIterator can be used to iterate * over iterators recursively. * @link https://php.net/manual/en/class.recursiveiterator.php */ interface RecursiveIterator extends Iterator { /** * Returns if an iterator can be created for the current entry. * @link https://php.net/manual/en/recursiveiterator.haschildren.php * @return bool true if the current entry can be iterated over, otherwise returns false. */ #[TentativeType] public function hasChildren(): bool; /** * Returns an iterator for the current entry. * @link https://php.net/manual/en/recursiveiterator.getchildren.php * @return RecursiveIterator|null An iterator for the current entry. */ #[TentativeType] public function getChildren(): ?RecursiveIterator; } /** * Can be used to iterate through recursive iterators. * @link https://php.net/manual/en/class.recursiveiteratoriterator.php */ class RecursiveIteratorIterator implements OuterIterator { /** * The default. Lists only leaves in iteration. */ public const LEAVES_ONLY = 0; /** * Lists leaves and parents in iteration with parents coming first. */ public const SELF_FIRST = 1; /** * Lists leaves and parents in iteration with leaves coming first. */ public const CHILD_FIRST = 2; /** * Special flag: Ignore exceptions thrown in accessing children. */ public const CATCH_GET_CHILD = 16; /** * Construct a RecursiveIteratorIterator * @link https://php.net/manual/en/recursiveiteratoriterator.construct.php * @param Traversable $iterator * @param int $mode [optional] The operation mode. See class constants for details. * @param int $flags [optional] A bitmask of special flags. See class constants for details. * @since 5.1.3 */ public function __construct( Traversable $iterator, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $mode = self::LEAVES_ONLY, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0 ) {} /** * Rewind the iterator to the first element of the top level inner iterator * @link https://php.net/manual/en/recursiveiteratoriterator.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Check whether the current position is valid * @link https://php.net/manual/en/recursiveiteratoriterator.valid.php * @return bool true if the current position is valid, otherwise false */ #[TentativeType] public function valid(): bool {} /** * Access the current key * @link https://php.net/manual/en/recursiveiteratoriterator.key.php * @return mixed The key of the current element. */ #[TentativeType] public function key(): mixed {} /** * Access the current element value * @link https://php.net/manual/en/recursiveiteratoriterator.current.php * @return mixed The current elements value. */ #[TentativeType] public function current(): mixed {} /** * Move forward to the next element * @link https://php.net/manual/en/recursiveiteratoriterator.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Get the current depth of the recursive iteration * @link https://php.net/manual/en/recursiveiteratoriterator.getdepth.php * @return int The current depth of the recursive iteration. */ #[TentativeType] public function getDepth(): int {} /** * The current active sub iterator * @link https://php.net/manual/en/recursiveiteratoriterator.getsubiterator.php * @param int $level [optional] * @return RecursiveIterator|null The current active sub iterator. */ #[TentativeType] public function getSubIterator(#[LanguageLevelTypeAware(['8.0' => 'int|null'], default: '')] $level): ?RecursiveIterator {} /** * Get inner iterator * @link https://php.net/manual/en/recursiveiteratoriterator.getinneriterator.php * @return RecursiveIterator The current active sub iterator. */ #[TentativeType] public function getInnerIterator(): RecursiveIterator {} /** * Begin Iteration * @link https://php.net/manual/en/recursiveiteratoriterator.beginiteration.php * @return void */ #[TentativeType] public function beginIteration(): void {} /** * End Iteration * @link https://php.net/manual/en/recursiveiteratoriterator.enditeration.php * @return void */ #[TentativeType] public function endIteration(): void {} /** * Has children * @link https://php.net/manual/en/recursiveiteratoriterator.callhaschildren.php * @return bool true if the element has children, otherwise false */ #[TentativeType] public function callHasChildren(): bool {} /** * Get children * @link https://php.net/manual/en/recursiveiteratoriterator.callgetchildren.php * @return RecursiveIterator|null A RecursiveIterator. */ #[TentativeType] public function callGetChildren(): ?RecursiveIterator {} /** * Begin children * @link https://php.net/manual/en/recursiveiteratoriterator.beginchildren.php * @return void */ #[TentativeType] public function beginChildren(): void {} /** * End children * @link https://php.net/manual/en/recursiveiteratoriterator.endchildren.php * @return void */ #[TentativeType] public function endChildren(): void {} /** * Next element * @link https://php.net/manual/en/recursiveiteratoriterator.nextelement.php * @return void */ #[TentativeType] public function nextElement(): void {} /** * Set max depth * @link https://php.net/manual/en/recursiveiteratoriterator.setmaxdepth.php * @param int $maxDepth [optional]

    * The maximum allowed depth. Default -1 is used * for any depth. *

    * @return void */ #[TentativeType] public function setMaxDepth(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $maxDepth = -1): void {} /** * Get max depth * @link https://php.net/manual/en/recursiveiteratoriterator.getmaxdepth.php * @return int|false The maximum accepted depth, or false if any depth is allowed. */ #[TentativeType] public function getMaxDepth(): int|false {} } /** * Classes implementing OuterIterator can be used to iterate * over iterators. * @link https://php.net/manual/en/class.outeriterator.php */ interface OuterIterator extends Iterator { /** * Returns the inner iterator for the current entry. * @link https://php.net/manual/en/outeriterator.getinneriterator.php * @return Iterator|null The inner iterator for the current entry. */ #[TentativeType] public function getInnerIterator(): ?Iterator; } /** * This iterator wrapper allows the conversion of anything that is * Traversable into an Iterator. * It is important to understand that most classes that do not implement * Iterators have reasons as most likely they do not allow the full * Iterator feature set. If so, techniques should be provided to prevent * misuse, otherwise expect exceptions or fatal errors. * @link https://php.net/manual/en/class.iteratoriterator.php */ class IteratorIterator implements OuterIterator { /** * Create an iterator from anything that is traversable * @link https://php.net/manual/en/iteratoriterator.construct.php * @param Traversable $iterator * @param string|null $class [optional] */ public function __construct(Traversable $iterator, #[PhpStormStubsElementAvailable(from: '8.0')] ?string $class = null) {} /** * Get the inner iterator * @link https://php.net/manual/en/iteratoriterator.getinneriterator.php * @return Iterator|null The inner iterator as passed to IteratorIterator::__construct. */ #[TentativeType] public function getInnerIterator(): ?Iterator {} /** * Rewind to the first element * @link https://php.net/manual/en/iteratoriterator.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Checks if the iterator is valid * @link https://php.net/manual/en/iteratoriterator.valid.php * @return bool true if the iterator is valid, otherwise false */ #[TentativeType] public function valid(): bool {} /** * Get the key of the current element * @link https://php.net/manual/en/iteratoriterator.key.php * @return mixed The key of the current element. */ #[TentativeType] public function key(): mixed {} /** * Get the current value * @link https://php.net/manual/en/iteratoriterator.current.php * @return mixed The value of the current element. */ #[TentativeType] public function current(): mixed {} /** * Forward to the next element * @link https://php.net/manual/en/iteratoriterator.next.php * @return void */ #[TentativeType] public function next(): void {} } /** * This abstract iterator filters out unwanted values. This class should be extended to * implement custom iterator filters. The FilterIterator::accept * must be implemented in the subclass. * @link https://php.net/manual/en/class.filteriterator.php */ abstract class FilterIterator extends IteratorIterator { /** * Check whether the current element of the iterator is acceptable * @link https://php.net/manual/en/filteriterator.accept.php * @return bool true if the current element is acceptable, otherwise false. */ #[TentativeType] abstract public function accept(): bool; /** * Construct a filterIterator * @link https://php.net/manual/en/filteriterator.construct.php * @param Iterator $iterator */ public function __construct(Iterator $iterator) {} /** * Rewind the iterator * @link https://php.net/manual/en/filteriterator.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Check whether the current element is valid * @link https://php.net/manual/en/filteriterator.valid.php * @return bool true if the current element is valid, otherwise false */ public function valid() {} /** * Get the current key * @link https://php.net/manual/en/filteriterator.key.php * @return mixed The key of the current element. */ public function key() {} /** * Get the current element value * @link https://php.net/manual/en/filteriterator.current.php * @return mixed The current element value. */ public function current() {} /** * Move the iterator forward * @link https://php.net/manual/en/filteriterator.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Get the inner iterator * @link https://php.net/manual/en/filteriterator.getinneriterator.php * @return Iterator The inner iterator. */ public function getInnerIterator() {} } /** * This abstract iterator filters out unwanted values for a RecursiveIterator. * This class should be extended to implement custom filters. * The RecursiveFilterIterator::accept must be implemented in the subclass. * @link https://php.net/manual/en/class.recursivefilteriterator.php */ abstract class RecursiveFilterIterator extends FilterIterator implements RecursiveIterator { /** * Create a RecursiveFilterIterator from a RecursiveIterator * @link https://php.net/manual/en/recursivefilteriterator.construct.php * @param RecursiveIterator $iterator */ public function __construct(RecursiveIterator $iterator) {} /** * Check whether the inner iterator's current element has children * @link https://php.net/manual/en/recursivefilteriterator.haschildren.php * @return bool true if the inner iterator has children, otherwise false */ #[TentativeType] public function hasChildren(): bool {} /** * Return the inner iterator's children contained in a RecursiveFilterIterator * @link https://php.net/manual/en/recursivefilteriterator.getchildren.php * @return RecursiveFilterIterator|null containing the inner iterator's children. */ #[TentativeType] public function getChildren(): ?RecursiveFilterIterator {} } /** * This extended FilterIterator allows a recursive iteration using RecursiveIteratorIterator that only shows those elements which have children. * @link https://php.net/manual/en/class.parentiterator.php */ class ParentIterator extends RecursiveFilterIterator { /** * Determines acceptability * @link https://php.net/manual/en/parentiterator.accept.php * @return bool true if the current element is acceptable, otherwise false. */ #[TentativeType] public function accept(): bool {} /** * Constructs a ParentIterator * @link https://php.net/manual/en/parentiterator.construct.php * @param RecursiveIterator $iterator */ public function __construct(RecursiveIterator $iterator) {} /** * Check whether the inner iterator's current element has children * @link https://php.net/manual/en/recursivefilteriterator.haschildren.php * @return bool true if the inner iterator has children, otherwise false */ public function hasChildren() {} /** * Return the inner iterator's children contained in a RecursiveFilterIterator * @link https://php.net/manual/en/recursivefilteriterator.getchildren.php * @return ParentIterator containing the inner iterator's children. */ public function getChildren() {} } /** * The Seekable iterator. * @link https://php.net/manual/en/class.seekableiterator.php */ interface SeekableIterator extends Iterator { /** * Seeks to a position * @link https://php.net/manual/en/seekableiterator.seek.php * @param int $offset

    * The position to seek to. *

    * @return void */ #[TentativeType] public function seek(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset): void; } /** * The LimitIterator class allows iteration over * a limited subset of items in an Iterator. * @link https://php.net/manual/en/class.limititerator.php */ class LimitIterator extends IteratorIterator { /** * Construct a LimitIterator * @link https://php.net/manual/en/limititerator.construct.php * @param Iterator $iterator The iterator to limit. * @param int $offset [optional] The offset to start at. Must be zero or greater. * @param int $limit [optional] The number of items to iterate. Must be -1 or greater. -1, the default, means no limit. */ public function __construct( Iterator $iterator, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset = 0, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $limit = -1 ) {} /** * Rewind the iterator to the specified starting offset * @link https://php.net/manual/en/limititerator.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Check whether the current element is valid * @link https://php.net/manual/en/limititerator.valid.php * @return bool true on success or false on failure. */ #[TentativeType] public function valid(): bool {} /** * Get current key * @link https://php.net/manual/en/limititerator.key.php * @return mixed The key of the current element. */ public function key() {} /** * Get current element * @link https://php.net/manual/en/limititerator.current.php * @return mixed the current element or null if there is none. */ public function current() {} /** * Move the iterator forward * @link https://php.net/manual/en/limititerator.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Seek to the given position * @link https://php.net/manual/en/limititerator.seek.php * @param int $offset

    * The position to seek to. *

    * @return int the offset position after seeking. */ #[TentativeType] public function seek(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset): int {} /** * Return the current position * @link https://php.net/manual/en/limititerator.getposition.php * @return int The current position. */ #[TentativeType] public function getPosition(): int {} /** * Get inner iterator * @link https://php.net/manual/en/limititerator.getinneriterator.php * @return Iterator The inner iterator passed to LimitIterator::__construct. */ public function getInnerIterator() {} } /** * This object supports cached iteration over another iterator. * @link https://php.net/manual/en/class.cachingiterator.php */ class CachingIterator extends IteratorIterator implements ArrayAccess, Countable, Stringable { /** * String conversion flag (mutually exclusive): Uses the current element for the iterator's string conversion. * This converts the current element to a string only once, regardless of whether it is needed or not. */ public const CALL_TOSTRING = 1; /** * String conversion flag (mutually exclusive). Uses the current key for the iterator's string conversion. */ public const TOSTRING_USE_KEY = 2; /** * String conversion flag (mutually exclusive). Uses the current element for the iterator's string conversion. * This converts the current element to a string only when (and every time) it is needed. */ public const TOSTRING_USE_CURRENT = 4; /** * String conversion flag (mutually exclusive). Forwards the string conversion to the inner iterator. * This converts the inner iterator to a string only once, regardless of whether it is needed or not. */ public const TOSTRING_USE_INNER = 8; /** * Ignore exceptions thrown in accessing children. Only used with {@see RecursiveCachingIterator}. */ public const CATCH_GET_CHILD = 16; /** * Cache all read data. This is needed to use {@see CachingIterator::getCache}, and ArrayAccess and Countable methods. */ public const FULL_CACHE = 256; /** * Constructs a new CachingIterator. * @link https://php.net/manual/en/cachingiterator.construct.php * @param Iterator $iterator The iterator to cache. * @param int $flags [optional] A bitmask of flags. See CachingIterator class constants for details. */ public function __construct(Iterator $iterator, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = self::CALL_TOSTRING) {} /** * Rewind the iterator * @link https://php.net/manual/en/cachingiterator.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Check whether the current element is valid * @link https://php.net/manual/en/cachingiterator.valid.php * @return bool true on success or false on failure. */ #[TentativeType] public function valid(): bool {} /** * Return the key for the current element * @link https://php.net/manual/en/cachingiterator.key.php * @return mixed The key of the current element. */ public function key() {} /** * Return the current element * @link https://php.net/manual/en/cachingiterator.current.php * @return mixed */ public function current() {} /** * Move the iterator forward * @link https://php.net/manual/en/cachingiterator.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Check whether the inner iterator has a valid next element * @link https://php.net/manual/en/cachingiterator.hasnext.php * @return bool true on success or false on failure. */ #[TentativeType] public function hasNext(): bool {} /** * Return the string representation of the current iteration based on the flag being used. * @link https://php.net/manual/en/cachingiterator.tostring.php * @return string The string representation of the current iteration based on the flag being used. */ #[TentativeType] public function __toString(): string {} /** * Returns the inner iterator * @link https://php.net/manual/en/cachingiterator.getinneriterator.php * @return Iterator an object implementing the Iterator interface. */ public function getInnerIterator() {} /** * Get flags used * @link https://php.net/manual/en/cachingiterator.getflags.php * @return int Bitmask of the flags */ #[TentativeType] public function getFlags(): int {} /** * The setFlags purpose * @link https://php.net/manual/en/cachingiterator.setflags.php * @param int $flags Bitmask of the flags to set. * @return void */ #[TentativeType] public function setFlags(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags): void {} /** * Internal cache array index to retrieve. * @link https://php.net/manual/en/cachingiterator.offsetget.php * @param string $key The index of the element to retrieve. * @return mixed * @throws BadMethodCallException when the {@see CachingIterator::FULL_CACHE} flag is not being used. */ #[TentativeType] public function offsetGet($key): mixed {} /** * Set an element on the internal cache array. * @link https://php.net/manual/en/cachingiterator.offsetset.php * @param string $key The index of the element to be set. * @param string $value The new value for the index. * @return void * @throws BadMethodCallException when the {@see CachingIterator::FULL_CACHE} flag is not being used. */ #[TentativeType] public function offsetSet($key, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value): void {} /** * Remove an element from the internal cache array. * @link https://php.net/manual/en/cachingiterator.offsetunset.php * @param string $key The index of the element to be unset. * @return void * @throws BadMethodCallException when the {@see CachingIterator::FULL_CACHE} flag is not being used. */ #[TentativeType] public function offsetUnset($key): void {} /** * Return whether an element at the index exists on the internal cache array. * @link https://php.net/manual/en/cachingiterator.offsetexists.php * @param string $key The index being checked. * @return bool true if an entry referenced by the offset exists, false otherwise. * @throws BadMethodCallException when the {@see CachingIterator::FULL_CACHE} flag is not being used. */ #[TentativeType] public function offsetExists($key): bool {} /** * Retrieve the contents of the cache * @link https://php.net/manual/en/cachingiterator.getcache.php * @return array An array containing the cache items. * @throws BadMethodCallException when the {@see CachingIterator::FULL_CACHE} flag is not being used. */ #[TentativeType] public function getCache(): array {} /** * The number of elements in the iterator * @link https://php.net/manual/en/cachingiterator.count.php * @return int The count of the elements iterated over. * @throws BadMethodCallException when the {@see CachingIterator::FULL_CACHE} flag is not being used. * @since 5.2.2 */ #[TentativeType] public function count(): int {} } /** * ... * @link https://php.net/manual/en/class.recursivecachingiterator.php */ class RecursiveCachingIterator extends CachingIterator implements RecursiveIterator { /** * Constructs a new RecursiveCachingIterator. * @link https://php.net/manual/en/recursivecachingiterator.construct.php * @param Iterator $iterator The iterator to cache. * @param int $flags [optional] A bitmask of flags. See CachingIterator class constants for details. */ public function __construct(Iterator $iterator, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = CachingIterator::CALL_TOSTRING) {} /** * Check whether the current element of the inner iterator has children * @link https://php.net/manual/en/recursivecachingiterator.haschildren.php * @return bool true if the inner iterator has children, otherwise false */ #[TentativeType] public function hasChildren(): bool {} /** * Return the inner iterator's children as a RecursiveCachingIterator * @link https://php.net/manual/en/recursivecachingiterator.getchildren.php * @return RecursiveCachingIterator|null The inner iterator's children, as a RecursiveCachingIterator. */ #[TentativeType] public function getChildren(): ?RecursiveCachingIterator {} } /** * This iterator cannot be rewinded. * @link https://php.net/manual/en/class.norewinditerator.php */ class NoRewindIterator extends IteratorIterator { /** * Construct a NoRewindIterator * @link https://php.net/manual/en/norewinditerator.construct.php * @param Iterator $iterator */ public function __construct(Iterator $iterator) {} /** * Prevents the rewind operation on the inner iterator. * @link https://php.net/manual/en/norewinditerator.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Validates the iterator * @link https://php.net/manual/en/norewinditerator.valid.php * @return bool true on success or false on failure. */ #[TentativeType] public function valid(): bool {} /** * Get the current key * @link https://php.net/manual/en/norewinditerator.key.php * @return mixed The key of the current element. */ #[TentativeType] public function key(): mixed {} /** * Get the current value * @link https://php.net/manual/en/norewinditerator.current.php * @return mixed The current value. */ #[TentativeType] public function current(): mixed {} /** * Forward to the next element * @link https://php.net/manual/en/norewinditerator.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Get the inner iterator * @link https://php.net/manual/en/norewinditerator.getinneriterator.php * @return Iterator The inner iterator, as passed to NoRewindIterator::__construct. */ public function getInnerIterator() {} } /** * An Iterator that iterates over several iterators one after the other. * @link https://php.net/manual/en/class.appenditerator.php */ class AppendIterator extends IteratorIterator { /** * Constructs an AppendIterator * @link https://php.net/manual/en/appenditerator.construct.php */ public function __construct() {} /** * Appends an iterator * @link https://php.net/manual/en/appenditerator.append.php * @param Iterator $iterator

    * The iterator to append. *

    * @return void */ #[TentativeType] public function append(Iterator $iterator): void {} /** * Rewinds the Iterator * @link https://php.net/manual/en/appenditerator.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Checks validity of the current element * @link https://php.net/manual/en/appenditerator.valid.php * @return bool true on success or false on failure. */ #[TentativeType] public function valid(): bool {} /** * Gets the current key * @link https://php.net/manual/en/appenditerator.key.php * @return mixed The key of the current element. */ public function key() {} /** * Gets the current value * @link https://php.net/manual/en/appenditerator.current.php * @return mixed The current value if it is valid or null otherwise. */ #[TentativeType] public function current(): mixed {} /** * Moves to the next element * @link https://php.net/manual/en/appenditerator.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Gets an inner iterator * @link https://php.net/manual/en/appenditerator.getinneriterator.php * @return Iterator the current inner Iterator. */ public function getInnerIterator() {} /** * Gets an index of iterators * @link https://php.net/manual/en/appenditerator.getiteratorindex.php * @return int|null The index of iterators. */ #[TentativeType] public function getIteratorIndex(): ?int {} /** * The getArrayIterator method * @link https://php.net/manual/en/appenditerator.getarrayiterator.php * @return ArrayIterator containing the appended iterators. */ #[TentativeType] public function getArrayIterator(): ArrayIterator {} } /** * The InfiniteIterator allows one to * infinitely iterate over an iterator without having to manually * rewind the iterator upon reaching its end. * @link https://php.net/manual/en/class.infiniteiterator.php */ class InfiniteIterator extends IteratorIterator { /** * Constructs an InfiniteIterator * @link https://php.net/manual/en/infiniteiterator.construct.php * @param Iterator $iterator */ public function __construct(Iterator $iterator) {} /** * Moves the inner Iterator forward or rewinds it * @link https://php.net/manual/en/infiniteiterator.next.php * @return void */ #[TentativeType] public function next(): void {} } /** * This iterator can be used to filter another iterator based on a regular expression. * @link https://php.net/manual/en/class.regexiterator.php */ class RegexIterator extends FilterIterator { /** * Return all matches for the current entry @see preg_match_all */ public const ALL_MATCHES = 2; /** * Return the first match for the current entry @see preg_match */ public const GET_MATCH = 1; /** * Only execute match (filter) for the current entry @see preg_match */ public const MATCH = 0; /** * Replace the current entry (Not fully implemented yet) @see preg_replace */ public const REPLACE = 4; /** * Returns the split values for the current entry @see preg_split */ public const SPLIT = 3; /** * Special flag: Match the entry key instead of the entry value. */ public const USE_KEY = 1; public const INVERT_MATCH = 2; #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $replacement; /** * Create a new RegexIterator * @link https://php.net/manual/en/regexiterator.construct.php * @param Iterator $iterator The iterator to apply this regex filter to. * @param string $pattern The regular expression to match. * @param int $mode [optional] Operation mode, see RegexIterator::setMode() for a list of modes. * @param int $flags [optional] Special flags, see RegexIterator::setFlags() for a list of available flags. * @param int $pregFlags [optional] The regular expression flags. These flags depend on the operation mode parameter */ public function __construct( Iterator $iterator, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $pattern, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $mode = self::MATCH, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $pregFlags = 0 ) {} /** * Get accept status * @link https://php.net/manual/en/regexiterator.accept.php * @return bool true if a match, false otherwise. */ #[TentativeType] public function accept(): bool {} /** * Returns operation mode. * @link https://php.net/manual/en/regexiterator.getmode.php * @return int the operation mode. */ #[TentativeType] public function getMode(): int {} /** * Sets the operation mode. * @link https://php.net/manual/en/regexiterator.setmode.php * @param int $mode

    * The operation mode. *

    *

    * The available modes are listed below. The actual * meanings of these modes are described in the * predefined constants. *

    * RegexIterator modes * * * * * * * * * * * * * * * * * * * * * * * * *
    valueconstant
    0 * RegexIterator::MATCH *
    1 * RegexIterator::GET_MATCH *
    2 * RegexIterator::ALL_MATCHES *
    3 * RegexIterator::SPLIT *
    4 * RegexIterator::REPLACE *
    *

    * @return void */ #[TentativeType] public function setMode(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $mode): void {} /** * Get flags * @link https://php.net/manual/en/regexiterator.getflags.php * @return int the set flags. */ #[TentativeType] public function getFlags(): int {} /** * Sets the flags. * @link https://php.net/manual/en/regexiterator.setflags.php * @param int $flags

    * The flags to set, a bitmask of class constants. *

    *

    * The available flags are listed below. The actual * meanings of these flags are described in the * predefined constants. *

    * RegexIterator flags * * * * * * * * *
    valueconstant
    1 * RegexIterator::USE_KEY *
    *

    * @return void */ #[TentativeType] public function setFlags(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags): void {} /** * Returns current regular expression * @link https://secure.php.net/manual/en/regexiterator.getregex.php * @return string * @since 5.4 */ #[TentativeType] public function getRegex(): string {} /** * Returns the regular expression flags. * @link https://php.net/manual/en/regexiterator.getpregflags.php * @return int a bitmask of the regular expression flags. */ #[TentativeType] public function getPregFlags(): int {} /** * Sets the regular expression flags. * @link https://php.net/manual/en/regexiterator.setpregflags.php * @param int $pregFlags

    * The regular expression flags. See RegexIterator::__construct * for an overview of available flags. *

    * @return void */ #[TentativeType] public function setPregFlags(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $pregFlags): void {} } /** * This recursive iterator can filter another recursive iterator via a regular expression. * @link https://php.net/manual/en/class.recursiveregexiterator.php */ class RecursiveRegexIterator extends RegexIterator implements RecursiveIterator { /** * Creates a new RecursiveRegexIterator. * @link https://php.net/manual/en/recursiveregexiterator.construct.php * @param RecursiveIterator $iterator The iterator to apply this regex filter to. * @param string $pattern The regular expression to match. * @param int $mode [optional] Operation mode, see RegexIterator::setMode() for a list of modes. * @param int $flags [optional] Special flags, see RegexIterator::setFlags() for a list of available flags. * @param int $pregFlags [optional] The regular expression flags. These flags depend on the operation mode parameter */ public function __construct( RecursiveIterator $iterator, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $pattern, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $mode = RegexIterator::MATCH, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $pregFlags = 0 ) {} /** * Returns whether an iterator can be obtained for the current entry. * @link https://php.net/manual/en/recursiveregexiterator.haschildren.php * @return bool true if an iterator can be obtained for the current entry, otherwise returns false. */ #[TentativeType] public function hasChildren(): bool {} /** * Returns an iterator for the current entry. * @link https://php.net/manual/en/recursiveregexiterator.getchildren.php * @return RecursiveRegexIterator An iterator for the current entry, if it can be iterated over by the inner iterator. */ #[TentativeType] public function getChildren(): RecursiveRegexIterator {} } /** * Allows iterating over a RecursiveIterator to generate an ASCII graphic tree. * @link https://php.net/manual/en/class.recursivetreeiterator.php */ class RecursiveTreeIterator extends RecursiveIteratorIterator { public const BYPASS_CURRENT = 4; public const BYPASS_KEY = 8; public const PREFIX_LEFT = 0; public const PREFIX_MID_HAS_NEXT = 1; public const PREFIX_MID_LAST = 2; public const PREFIX_END_HAS_NEXT = 3; public const PREFIX_END_LAST = 4; public const PREFIX_RIGHT = 5; /** * Construct a RecursiveTreeIterator * @link https://php.net/manual/en/recursivetreeiterator.construct.php * @param RecursiveIterator|IteratorAggregate $iterator * @param int $flags [optional] Flags to control the behavior of the RecursiveTreeIterator object. * @param int $cachingIteratorFlags [optional] Flags to affect the behavior of the {@see RecursiveCachingIterator} used internally. * @param int $mode [optional] Flags to affect the behavior of the {@see RecursiveIteratorIterator} used internally. */ public function __construct( $iterator, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = self::BYPASS_KEY, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $cachingIteratorFlags = CachingIterator::CATCH_GET_CHILD, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $mode = RecursiveIteratorIterator::SELF_FIRST ) {} /** * Rewind iterator * @link https://php.net/manual/en/recursivetreeiterator.rewind.php * @return void */ public function rewind() {} /** * Check validity * @link https://php.net/manual/en/recursivetreeiterator.valid.php * @return bool true if the current position is valid, otherwise false */ public function valid() {} /** * Get the key of the current element * @link https://php.net/manual/en/recursivetreeiterator.key.php * @return string the current key prefixed and postfixed. */ #[TentativeType] public function key(): mixed {} /** * Get current element * @link https://php.net/manual/en/recursivetreeiterator.current.php * @return string the current element prefixed and postfixed. */ #[TentativeType] public function current(): mixed {} /** * Move to next element * @link https://php.net/manual/en/recursivetreeiterator.next.php * @return void */ public function next() {} /** * Begin iteration * @link https://php.net/manual/en/recursivetreeiterator.beginiteration.php * @return RecursiveIterator A RecursiveIterator. */ public function beginIteration() {} /** * End iteration * @link https://php.net/manual/en/recursivetreeiterator.enditeration.php * @return void */ public function endIteration() {} /** * Has children * @link https://php.net/manual/en/recursivetreeiterator.callhaschildren.php * @return bool true if there are children, otherwise false */ public function callHasChildren() {} /** * Get children * @link https://php.net/manual/en/recursivetreeiterator.callgetchildren.php * @return RecursiveIterator A RecursiveIterator. */ public function callGetChildren() {} /** * Begin children * @link https://php.net/manual/en/recursivetreeiterator.beginchildren.php * @return void */ public function beginChildren() {} /** * End children * @link https://php.net/manual/en/recursivetreeiterator.endchildren.php * @return void */ public function endChildren() {} /** * Next element * @link https://php.net/manual/en/recursivetreeiterator.nextelement.php * @return void */ public function nextElement() {} /** * Get the prefix * @link https://php.net/manual/en/recursivetreeiterator.getprefix.php * @return string the string to place in front of current element */ #[TentativeType] public function getPrefix(): string {} /** * @param string $postfix */ #[TentativeType] public function setPostfix(#[PhpStormStubsElementAvailable(from: '7.3')] string $postfix): void {} /** * Set a part of the prefix * @link https://php.net/manual/en/recursivetreeiterator.setprefixpart.php * @param int $part

    * One of the RecursiveTreeIterator::PREFIX_* constants. *

    * @param string $value

    * The value to assign to the part of the prefix specified in part. *

    * @return void */ #[TentativeType] public function setPrefixPart( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $part, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $value ): void {} /** * Get current entry * @link https://php.net/manual/en/recursivetreeiterator.getentry.php * @return string the part of the tree built for the current element. */ #[TentativeType] public function getEntry(): string {} /** * Get the postfix * @link https://php.net/manual/en/recursivetreeiterator.getpostfix.php * @return string to place after the current element. */ #[TentativeType] public function getPostfix(): string {} } /** * This class allows objects to work as arrays. * @link https://php.net/manual/en/class.arrayobject.php * @template TKey * @template TValue * @template-implements IteratorAggregate * @template-implements ArrayAccess */ class ArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Countable { /** * Properties of the object have their normal functionality when accessed as list (var_dump, foreach, etc.). */ public const STD_PROP_LIST = 1; /** * Entries can be accessed as properties (read and write). */ public const ARRAY_AS_PROPS = 2; /** * Construct a new array object * @link https://php.net/manual/en/arrayobject.construct.php * @param array|object $array The input parameter accepts an array or an Object. * @param int $flags Flags to control the behaviour of the ArrayObject object. * @param class-string $iteratorClass Specify the class that will be used for iteration of the ArrayObject object. ArrayIterator is the default class used. */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'object|array'], default: '')] $array = [], #[PhpStormStubsElementAvailable(from: '5.3')] #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0, #[PhpStormStubsElementAvailable(from: '5.3')] #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $iteratorClass = "ArrayIterator" ) {} /** * Returns whether the requested index exists * @link https://php.net/manual/en/arrayobject.offsetexists.php * @param TKey $key

    * The index being checked. *

    * @return bool true if the requested index exists, otherwise false */ #[TentativeType] public function offsetExists(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $key): bool {} /** * Returns the value at the specified index * @link https://php.net/manual/en/arrayobject.offsetget.php * @param TKey $key

    * The index with the value. *

    * @return TValue|null The value at the specified index or null. */ #[TentativeType] public function offsetGet(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $key): mixed {} /** * Sets the value at the specified index to newval * @link https://php.net/manual/en/arrayobject.offsetset.php * @param TKey $key

    * The index being set. *

    * @param TValue $value

    * The new value for the index. *

    * @return void */ #[TentativeType] public function offsetSet( #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $key, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value ): void {} /** * Unsets the value at the specified index * @link https://php.net/manual/en/arrayobject.offsetunset.php * @param TKey $key

    * The index being unset. *

    * @return void */ #[TentativeType] public function offsetUnset(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $key): void {} /** * Appends the value * @link https://php.net/manual/en/arrayobject.append.php * @param TValue $value

    * The value being appended. *

    * @return void */ #[TentativeType] public function append(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value): void {} /** * Creates a copy of the ArrayObject. * @link https://php.net/manual/en/arrayobject.getarraycopy.php * @return array a copy of the array. When the ArrayObject refers to an object * an array of the public properties of that object will be returned. */ #[TentativeType] public function getArrayCopy(): array {} /** * Get the number of public properties in the ArrayObject * When the ArrayObject is constructed from an array all properties are public. * @link https://php.net/manual/en/arrayobject.count.php * @return int The number of public properties in the ArrayObject. */ #[TentativeType] public function count(): int {} /** * Gets the behavior flags. * @link https://php.net/manual/en/arrayobject.getflags.php * @return int the behavior flags of the ArrayObject. */ #[TentativeType] public function getFlags(): int {} /** * Sets the behavior flags. * @link https://php.net/manual/en/arrayobject.setflags.php * @param int $flags

    * The new ArrayObject behavior. * It takes on either a bitmask, or named constants. Using named * constants is strongly encouraged to ensure compatibility for future * versions. *

    *

    * The available behavior flags are listed below. The actual * meanings of these flags are described in the * predefined constants. *

    * ArrayObject behavior flags * * * * * * * * * * * * *
    valueconstant
    1 * ArrayObject::STD_PROP_LIST *
    2 * ArrayObject::ARRAY_AS_PROPS *
    *

    * @return void */ #[TentativeType] public function setFlags(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags): void {} /** * Sort the entries by value * @link https://php.net/manual/en/arrayobject.asort.php */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function asort(#[PhpStormStubsElementAvailable(from: '8.0')] int $flags = SORT_REGULAR) {} /** * Sort the entries by key * @link https://php.net/manual/en/arrayobject.ksort.php */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function ksort(#[PhpStormStubsElementAvailable(from: '8.0')] int $flags = SORT_REGULAR) {} /** * Sort the entries with a user-defined comparison function and maintain key association * @link https://php.net/manual/en/arrayobject.uasort.php * @param callable(TValue, TValue):int $callback

    * Function cmp_function should accept two * parameters which will be filled by pairs of entries. * The comparison function must return an integer less than, equal * to, or greater than zero if the first argument is considered to * be respectively less than, equal to, or greater than the * second. *

    */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function uasort(#[LanguageLevelTypeAware(['8.0' => 'callable'], default: '')] $callback) {} /** * Sort the entries by keys using a user-defined comparison function * @link https://php.net/manual/en/arrayobject.uksort.php * @param callable(TValue, TValue):int $callback

    * The callback comparison function. *

    *

    * Function cmp_function should accept two * parameters which will be filled by pairs of entry keys. * The comparison function must return an integer less than, equal * to, or greater than zero if the first argument is considered to * be respectively less than, equal to, or greater than the * second. *

    */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function uksort(#[LanguageLevelTypeAware(['8.0' => 'callable'], default: '')] $callback) {} /** * Sort entries using a "natural order" algorithm * @link https://php.net/manual/en/arrayobject.natsort.php */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function natsort() {} /** * Sort an array using a case insensitive "natural order" algorithm * @link https://php.net/manual/en/arrayobject.natcasesort.php */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function natcasesort() {} /** * Unserialize an ArrayObject * @link https://php.net/manual/en/arrayobject.unserialize.php * @param string $data

    * The serialized ArrayObject. *

    * @return void */ #[TentativeType] public function unserialize(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data): void {} /** * Serialize an ArrayObject * @link https://php.net/manual/en/arrayobject.serialize.php * @return string The serialized representation of the ArrayObject. */ #[TentativeType] public function serialize(): string {} /** * @return array * @since 7.4 */ #[TentativeType] public function __debugInfo(): array {} /** * @return array * @since 7.4 */ #[TentativeType] public function __serialize(): array {} /** * @param array $data * @since 7.4 */ #[TentativeType] public function __unserialize(array $data): void {} /** * Create a new iterator from an ArrayObject instance * @link https://php.net/manual/en/arrayobject.getiterator.php * @return ArrayIterator An iterator from an ArrayObject. */ #[TentativeType] public function getIterator(): Iterator {} /** * Exchange the array for another one. * @link https://php.net/manual/en/arrayobject.exchangearray.php * @param mixed $array

    * The new array or object to exchange with the current array. *

    * @return array the old array. */ #[TentativeType] public function exchangeArray(#[LanguageLevelTypeAware(['8.0' => 'object|array'], default: '')] $array): array {} /** * Sets the iterator classname for the ArrayObject. * @link https://php.net/manual/en/arrayobject.setiteratorclass.php * @param class-string $iteratorClass

    * The classname of the array iterator to use when iterating over this object. *

    * @return void */ #[TentativeType] public function setIteratorClass(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $iteratorClass): void {} /** * Gets the iterator classname for the ArrayObject. * @link https://php.net/manual/en/arrayobject.getiteratorclass.php * @return class-string the iterator class name that is used to iterate over this object. */ #[TentativeType] public function getIteratorClass(): string {} } /** * This iterator allows to unset and modify values and keys while iterating * over Arrays and Objects. * @link https://php.net/manual/en/class.arrayiterator.php */ class ArrayIterator implements SeekableIterator, ArrayAccess, Serializable, Countable { public const STD_PROP_LIST = 1; public const ARRAY_AS_PROPS = 2; /** * Construct an ArrayIterator * @link https://php.net/manual/en/arrayiterator.construct.php * @param array $array The array or object to be iterated on. * @param int $flags Flags to control the behaviour of the ArrayObject object. * @see ArrayObject::setFlags() */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'object|array'], default: '')] $array = [], #[PhpStormStubsElementAvailable(from: '7.0')] #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0, #[PhpStormStubsElementAvailable(from: '7.0', to: '7.1')] $iterator_class = null ) {} /** * Check if offset exists * @link https://php.net/manual/en/arrayiterator.offsetexists.php * @param string $key

    * The offset being checked. *

    * @return bool true if the offset exists, otherwise false */ #[TentativeType] public function offsetExists(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $key): bool {} /** * Get value for an offset * @link https://php.net/manual/en/arrayiterator.offsetget.php * @param string $key

    * The offset to get the value from. *

    * @return mixed The value at offset index. */ #[TentativeType] public function offsetGet(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $key): mixed {} /** * Set value for an offset * @link https://php.net/manual/en/arrayiterator.offsetset.php * @param string $key

    * The index to set for. *

    * @param string $value

    * The new value to store at the index. *

    * @return void */ #[TentativeType] public function offsetSet( #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $key, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value ): void {} /** * Unset value for an offset * @link https://php.net/manual/en/arrayiterator.offsetunset.php * @param string $key

    * The offset to unset. *

    * @return void */ #[TentativeType] public function offsetUnset(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $key): void {} /** * Append an element * @link https://php.net/manual/en/arrayiterator.append.php * @param mixed $value

    * The value to append. *

    * @return void */ #[TentativeType] public function append(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value): void {} /** * Get array copy * @link https://php.net/manual/en/arrayiterator.getarraycopy.php * @return array A copy of the array, or array of public properties * if ArrayIterator refers to an object. */ #[TentativeType] public function getArrayCopy(): array {} /** * Count elements * @link https://php.net/manual/en/arrayiterator.count.php * @return int<0,max> The number of elements or public properties in the associated * array or object, respectively. */ #[TentativeType] public function count(): int {} /** * Get flags * @link https://php.net/manual/en/arrayiterator.getflags.php * @return int The current flags. */ #[TentativeType] public function getFlags(): int {} /** * Set behaviour flags * @link https://php.net/manual/en/arrayiterator.setflags.php * @param string $flags

    * A bitmask as follows: * 0 = Properties of the object have their normal functionality * when accessed as list (var_dump, foreach, etc.). * 1 = Array indices can be accessed as properties in read/write. *

    * @return void */ #[TentativeType] public function setFlags(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags): void {} /** * Sort array by values * @link https://php.net/manual/en/arrayiterator.asort.php */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function asort(#[PhpStormStubsElementAvailable(from: '8.0')] int $flags = SORT_REGULAR) {} /** * Sort array by keys * @link https://php.net/manual/en/arrayiterator.ksort.php */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function ksort(#[PhpStormStubsElementAvailable(from: '8.0')] int $flags = SORT_REGULAR) {} /** * User defined sort * @link https://php.net/manual/en/arrayiterator.uasort.php * @param callable $callback

    * The compare function used for the sort. *

    */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function uasort(#[LanguageLevelTypeAware(['8.0' => 'callable'], default: '')] $callback) {} /** * User defined sort * @link https://php.net/manual/en/arrayiterator.uksort.php * @param callable $callback

    * The compare function used for the sort. *

    */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function uksort(#[LanguageLevelTypeAware(['8.0' => 'callable'], default: '')] $callback) {} /** * Sort an array naturally * @link https://php.net/manual/en/arrayiterator.natsort.php */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function natsort() {} /** * Sort an array naturally, case insensitive * @link https://php.net/manual/en/arrayiterator.natcasesort.php */ #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'true'], default: 'bool')] public function natcasesort() {} /** * Unserialize * @link https://php.net/manual/en/arrayiterator.unserialize.php * @param string $data

    * The serialized ArrayIterator object to be unserialized. *

    * @return void */ #[TentativeType] public function unserialize(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $data): void {} /** * Serialize * @link https://php.net/manual/en/arrayiterator.serialize.php * @return string The serialized ArrayIterator. */ #[TentativeType] public function serialize(): string {} /** * Rewind array back to the start * @link https://php.net/manual/en/arrayiterator.rewind.php * @return void */ #[TentativeType] public function rewind(): void {} /** * Return current array entry * @link https://php.net/manual/en/arrayiterator.current.php * @return mixed The current array entry. */ #[TentativeType] public function current(): mixed {} /** * Return current array key * @link https://php.net/manual/en/arrayiterator.key.php * @return string|int|null The key of the current element. */ #[TentativeType] public function key(): string|int|null {} /** * Move to next entry * @link https://php.net/manual/en/arrayiterator.next.php * @return void */ #[TentativeType] public function next(): void {} /** * Check whether array contains more entries * @link https://php.net/manual/en/arrayiterator.valid.php * @return bool */ #[TentativeType] public function valid(): bool {} /** * Seek to position * @link https://php.net/manual/en/arrayiterator.seek.php * @param int $offset

    * The position to seek to. *

    * @return void */ #[TentativeType] public function seek(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $offset): void {} /** * @return array * @since 7.4 */ #[TentativeType] public function __debugInfo(): array {} /** * @return array * @since 7.4 */ #[TentativeType] public function __serialize(): array {} /** * @param array $data * @since 7.4 */ #[TentativeType] public function __unserialize(array $data): void {} } /** * This iterator allows to unset and modify values and keys while iterating over Arrays and Objects * in the same way as the ArrayIterator. Additionally it is possible to iterate * over the current iterator entry. * @link https://php.net/manual/en/class.recursivearrayiterator.php */ class RecursiveArrayIterator extends ArrayIterator implements RecursiveIterator { public const CHILD_ARRAYS_ONLY = 4; /** * Returns whether current entry is an array or an object. * @link https://php.net/manual/en/recursivearrayiterator.haschildren.php * @return bool true if the current entry is an array or an object, * otherwise false is returned. */ #[TentativeType] public function hasChildren(): bool {} /** * Returns an iterator for the current entry if it is an array or an object. * @link https://php.net/manual/en/recursivearrayiterator.getchildren.php * @return RecursiveArrayIterator|null An iterator for the current entry, if it is an array or object. */ #[TentativeType] public function getChildren(): ?RecursiveArrayIterator {} } *

    * @param string|null $file_extensions [optional]

    * By default it checks all include paths to * contain filenames built up by the lowercase class name appended by the * filename extensions .inc and .php. *

    * @return void * @since 5.1.2 */ function spl_autoload(string $class, ?string $file_extensions): void {} /** * Register and return default file extensions for spl_autoload * @link https://php.net/manual/en/function.spl-autoload-extensions.php * @param string|null $file_extensions [optional]

    * When calling without an argument, it simply returns the current list * of extensions each separated by comma. To modify the list of file * extensions, simply invoke the functions with the new list of file * extensions to use in a single string with each extensions separated * by comma. *

    * @return string A comma delimited list of default file extensions for * spl_autoload. * @since 5.1.2 */ function spl_autoload_extensions(?string $file_extensions): string {} /** * Register given function as __autoload() implementation * @link https://php.net/manual/en/function.spl-autoload-register.php * @param callable|null $callback [optional]

    * The autoload function being registered. * If no parameter is provided, then the default implementation of * spl_autoload will be registered. *

    * @param bool $throw This parameter specifies whether spl_autoload_register() should throw exceptions when the * autoload_function cannot be registered. Ignored since since 8.0. * @param bool $prepend If true, spl_autoload_register() will prepend the autoloader on the autoload stack instead of * appending it. * @return bool true on success or false on failure. * @throws TypeError Since 8.0. * @since 5.1.2 */ function spl_autoload_register(?callable $callback, bool $throw = true, bool $prepend = false): bool {} /** * Unregister given function as __autoload() implementation * @link https://php.net/manual/en/function.spl-autoload-unregister.php * @param callable $callback

    * The autoload function being unregistered. *

    * @return bool true on success or false on failure. * @since 5.1.2 */ function spl_autoload_unregister(callable $callback): bool {} /** * Return all registered __autoload() functions * @link https://php.net/manual/en/function.spl-autoload-functions.php * @return array|false An array of all registered __autoload functions. * If the autoload stack is not activated then the return value is false. * If no function is registered the return value will be an empty array. * @since 5.1.2 */ #[LanguageLevelTypeAware(["8.0" => "array"], default: "array|false")] function spl_autoload_functions() {} /** * Try all registered __autoload() functions to load the requested class * @link https://php.net/manual/en/function.spl-autoload-call.php * @param string $class

    * The class name being searched. *

    * @return void * @since 5.1.2 */ function spl_autoload_call(string $class): void {} /** * Return the parent classes of the given class * @link https://php.net/manual/en/function.class-parents.php * @param object|string $object_or_class

    * An object (class instance) or a string (class name). *

    * @param bool $autoload [optional]

    * Whether to allow this function to load the class automatically through * the __autoload magic * method. *

    * @return string[]|false An array on success, or false on error. */ #[Pure] function class_parents($object_or_class, bool $autoload = true): array|false {} /** * Return the interfaces which are implemented by the given class * @link https://php.net/manual/en/function.class-implements.php * @param object|string $object_or_class

    * An object (class instance) or a string (class name). *

    * @param bool $autoload [optional]

    * Whether to allow this function to load the class automatically through * the __autoload magic * method. *

    * @return string[]|false An array on success, or false on error. */ #[Pure] function class_implements($object_or_class, bool $autoload = true): array|false {} /** * Return hash id for given object * @link https://php.net/manual/en/function.spl-object-hash.php * @param object $object * @return string A string that is unique for each object and is always the same for * the same object. */ #[Pure] function spl_object_hash(object $object): string {} /** * Copy the iterator into an array * @link https://php.net/manual/en/function.iterator-to-array.php * @param Traversable $iterator

    * The iterator being copied. *

    * @param bool $preserve_keys [optional]

    * Whether to use the iterator element keys as index. *

    * @return array An array containing the elements of the iterator. */ function iterator_to_array(#[LanguageLevelTypeAware(['8.2' => 'Traversable|array'], default: 'Traversable')] $iterator, bool $preserve_keys = true): array {} /** * Count the elements in an iterator * @link https://php.net/manual/en/function.iterator-count.php * @param Traversable $iterator

    * The iterator being counted. *

    * @return int The number of elements in iterator. */ #[Pure] function iterator_count(#[LanguageLevelTypeAware(['8.2' => 'Traversable|array'], default: 'Traversable')] $iterator): int {} /** * Call a function for every element in an iterator * @link https://php.net/manual/en/function.iterator-apply.php * @param Traversable $iterator

    * The class to iterate over. *

    * @param callable $callback

    * The callback function to call on every element. * The function must return true in order to * continue iterating over the iterator. *

    * @param array|null $args [optional]

    * Arguments to pass to the callback function. *

    * @return int the iteration count. */ function iterator_apply(Traversable $iterator, callable $callback, ?array $args): int {} // End of SPL v.0.2 /** * Return the traits used by the given class * @param object|string $object_or_class An object (class instance) or a string (class name). * @param bool $autoload Whether to allow this function to load the class automatically through the __autoload() magic method. * @return string[]|false An array on success, or false on error. * @link https://php.net/manual/en/function.class-uses.php * @see class_parents() * @see get_declared_traits() * @since 5.4 */ function class_uses($object_or_class, bool $autoload = true): array|false {} /** * return the integer object handle for given object * @param object $object * @return int * @since 7.2 */ function spl_object_id(object $object): int {} 'ReflectionNamedType[]|ReflectionIntersectionType[]' ], default: 'ReflectionNamedType[]' )] public function getTypes(): array {} } ReflectionFunction class reports * information about a function. * * @link https://php.net/manual/en/class.reflectionfunction.php */ class ReflectionFunction extends ReflectionFunctionAbstract { /** * @var string Function name, same as calling the {@see ReflectionFunction::getName()} method */ #[Immutable] public $name; /** * Indicates deprecated functions. * * @link https://www.php.net/manual/en/class.reflectionfunction.php#reflectionfunction.constants.is-deprecated */ public const IS_DEPRECATED = 2048; /** * Constructs a ReflectionFunction object * * @link https://php.net/manual/en/reflectionfunction.construct.php * @param string|Closure $function The name of the function to reflect or a closure. * @throws ReflectionException if the function does not exist. */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'Closure|string'], default: '')] $function) {} /** * Returns the string representation of the ReflectionFunction object. * * @link https://php.net/manual/en/reflectionfunction.tostring.php */ #[TentativeType] public function __toString(): string {} /** * Exports function * * @link https://php.net/manual/en/reflectionfunction.export.php * @param string $name The reflection to export. * @param bool $return Setting to {@see true} will return the * export, as opposed to emitting it. Setting to {@see false} (the default) * will do the opposite. * @return string|null If the $return parameter is set to {@see true}, then * the export is returned as a string, otherwise {@see null} is returned. * @removed 8.0 */ #[Deprecated(since: '7.4')] public static function export($name, $return = false) {} /** * Checks if function is disabled * * @link https://php.net/manual/en/reflectionfunction.isdisabled.php * @return bool {@see true} if it's disable, otherwise {@see false} */ #[Deprecated(since: '8.0')] #[Pure] #[TentativeType] public function isDisabled(): bool {} /** * Invokes function * * @link https://www.php.net/manual/en/reflectionfunction.invoke.php * @param mixed ...$args [optional] The passed in argument list. It accepts a * variable number of arguments which are passed to the function much * like {@see call_user_func} is. * @return mixed Returns the result of the invoked function call. */ #[TentativeType] public function invoke(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] ...$args): mixed {} /** * Invokes function args * * @link https://php.net/manual/en/reflectionfunction.invokeargs.php * @param array $args The passed arguments to the function as an array, much * like {@see call_user_func_array} works. * @return mixed the result of the invoked function */ #[TentativeType] public function invokeArgs(array $args): mixed {} /** * Returns a dynamically created closure for the function * * @link https://php.net/manual/en/reflectionfunction.getclosure.php * @return Closure|null Returns {@see Closure} or {@see null} in case of an error. */ #[Pure] #[TentativeType] public function getClosure(): Closure {} #[PhpStormStubsElementAvailable(from: '8.2')] public function isAnonymous(): bool {} } ReflectionExtension class reports information about an extension. * * @link https://php.net/manual/en/class.reflectionextension.php */ class ReflectionExtension implements Reflector { /** * @var string Name of the extension, same as calling the {@see ReflectionExtension::getName()} method */ #[Immutable] #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $name; /** * Constructs a ReflectionExtension * * @link https://php.net/manual/en/reflectionextension.construct.php * @param string $name Name of the extension. * @throws ReflectionException if the extension does not exist. */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name) {} /** * Exports a reflected extension. * The output format of this function is the same as the CLI argument --re [extension]. * * @link https://php.net/manual/en/reflectionextension.export.php * @param string $name The reflection to export. * @param bool $return Setting to {@see true} will return the * export, as opposed to emitting it. Setting to {@see false} (the default) * will do the opposite. * @return string|null If the $return parameter is set to {@see true}, then * the export is returned as a string, otherwise {@see null} is returned. * @removed 8.0 */ #[Deprecated(since: '7.4')] public static function export($name, $return = false) {} /** * To string * * @link https://php.net/manual/en/reflectionextension.tostring.php * @return string the exported extension as a string, in the same way as * the {@see ReflectionExtension::export()}. */ #[TentativeType] public function __toString(): string {} /** * Gets extension name * * @link https://php.net/manual/en/reflectionextension.getname.php * @return string The extensions name. */ #[Pure] #[TentativeType] public function getName(): string {} /** * Gets extension version * * @link https://php.net/manual/en/reflectionextension.getversion.php * @return string|null The version of the extension. */ #[Pure] #[TentativeType] public function getVersion(): ?string {} /** * Gets extension functions * * @link https://php.net/manual/en/reflectionextension.getfunctions.php * @return ReflectionFunction[] An associative array of {@see ReflectionFunction} objects, * for each function defined in the extension with the keys being the function * names. If no function are defined, an empty array is returned. */ #[Pure] #[TentativeType] public function getFunctions(): array {} /** * Gets constants * * @link https://php.net/manual/en/reflectionextension.getconstants.php * @return array An associative array with constant names as keys. */ #[Pure] #[TentativeType] public function getConstants(): array {} /** * Gets extension ini entries * * @link https://php.net/manual/en/reflectionextension.getinientries.php * @return array An associative array with the ini entries as keys, * with their defined values as values. */ #[Pure] #[TentativeType] public function getINIEntries(): array {} /** * Gets classes * * @link https://php.net/manual/en/reflectionextension.getclasses.php * @return ReflectionClass[] An array of {@see ReflectionClass} objects, one * for each class within the extension. If no classes are defined, * an empty array is returned. */ #[Pure] #[TentativeType] public function getClasses(): array {} /** * Gets class names * * @link https://php.net/manual/en/reflectionextension.getclassnames.php * @return string[] An array of class names, as defined in the extension. * If no classes are defined, an empty array is returned. */ #[Pure] #[TentativeType] public function getClassNames(): array {} /** * Gets dependencies * * @link https://php.net/manual/en/reflectionextension.getdependencies.php * @return string[] An associative array with dependencies as keys and * either Required, Optional or Conflicts as the values. */ #[Pure] #[TentativeType] public function getDependencies(): array {} /** * Print extension info * * @link https://php.net/manual/en/reflectionextension.info.php * @return void Print extension info */ #[TentativeType] public function info(): void {} /** * Returns whether this extension is persistent * * @link https://php.net/manual/en/reflectionextension.ispersistent.php * @return bool Returns {@see true} for extensions loaded by extension, {@see false} otherwise. * @since 5.4 */ #[Pure] #[TentativeType] public function isPersistent(): bool {} /** * Returns whether this extension is temporary * * @link https://php.net/manual/en/reflectionextension.istemporary.php * @return bool Returns {@see true} for extensions loaded by {@see dl()}, {@see false} otherwise. * @since 5.4 */ #[Pure] #[TentativeType] public function isTemporary(): bool {} /** * Clones * * @link https://php.net/manual/en/reflectionextension.clone.php * @return void No value is returned, if called a fatal error will occur. */ #[PhpStormStubsElementAvailable(from: "5.4", to: "8.0")] final private function __clone(): void {} /** * Clones * * @link https://php.net/manual/en/reflectionextension.clone.php * @return void No value is returned, if called a fatal error will occur. */ #[PhpStormStubsElementAvailable(from: "8.1")] private function __clone(): void {} } ReflectionClass class reports information about a class. * * @link https://php.net/manual/en/class.reflectionclass.php */ class ReflectionClass implements Reflector { /** * @var class-string Name of the class, same as calling the {@see ReflectionClass::getName()} method */ #[Immutable] #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $name; /** * Indicates class that is abstract because it has some abstract methods. * * @link https://www.php.net/manual/en/class.reflectionclass.php#reflectionclass.constants.is-implicit-abstract */ public const IS_IMPLICIT_ABSTRACT = 16; /** * Indicates class that is abstract because of its definition. * * @link https://www.php.net/manual/en/class.reflectionclass.php#reflectionclass.constants.is-explicit-abstract */ public const IS_EXPLICIT_ABSTRACT = 64; /** * Indicates final class. * * @link https://www.php.net/manual/en/class.reflectionclass.php#reflectionclass.constants.is-final */ public const IS_FINAL = 32; /** * @since 8.2 */ public const IS_READONLY = 65536; /** * Constructs a ReflectionClass * * @link https://php.net/manual/en/reflectionclass.construct.php * @param class-string|T $objectOrClass Either a string containing the name of * the class to reflect, or an object. * @throws ReflectionException if the class does not exist. */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'object|string'], default: '')] $objectOrClass) {} /** * Exports a reflected class * * @link https://php.net/manual/en/reflectionclass.export.php * @param mixed $argument The reflection to export. * @param bool $return Setting to {@see true} will return the export, as * opposed to emitting it. Setting to {@see false} (the default) will do the opposite. * @return string|null If the $return parameter is set to {@see true}, then the * export is returned as a string, otherwise {@see null} is returned. * @removed 8.0 */ #[Deprecated(since: '7.4')] public static function export($argument, $return = false) {} /** * Returns the string representation of the ReflectionClass object. * * @link https://php.net/manual/en/reflectionclass.tostring.php * @return string A string representation of this {@see ReflectionClass} instance. */ #[TentativeType] public function __toString(): string {} /** * Gets class name * * @link https://php.net/manual/en/reflectionclass.getname.php * @return string The class name. */ #[Pure] #[TentativeType] public function getName(): string {} /** * Checks if class is defined internally by an extension, or the core * * @link https://php.net/manual/en/reflectionclass.isinternal.php * @return bool Returns {@see true} on success or {@see false} on failure. */ #[Pure] #[TentativeType] public function isInternal(): bool {} /** * Checks if user defined * * @link https://php.net/manual/en/reflectionclass.isuserdefined.php * @return bool Returns {@see true} on success or {@see false} on failure. */ #[Pure] #[TentativeType] public function isUserDefined(): bool {} /** * Checks if the class is instantiable * * @link https://php.net/manual/en/reflectionclass.isinstantiable.php * @return bool Returns {@see true} on success or {@see false} on failure. */ #[Pure] #[TentativeType] public function isInstantiable(): bool {} /** * Returns whether this class is cloneable * * @link https://php.net/manual/en/reflectionclass.iscloneable.php * @return bool Returns {@see true} if the class is cloneable, {@see false} otherwise. * @since 5.4 */ #[Pure] #[TentativeType] public function isCloneable(): bool {} /** * Gets the filename of the file in which the class has been defined * * @link https://php.net/manual/en/reflectionclass.getfilename.php * @return string|false the filename of the file in which the class has been defined. * If the class is defined in the PHP core or in a PHP extension, {@see false} * is returned. */ #[Pure] #[TentativeType] public function getFileName(): string|false {} /** * Gets starting line number * * @link https://php.net/manual/en/reflectionclass.getstartline.php * @return int The starting line number, as an integer. */ #[Pure] #[TentativeType] public function getStartLine(): int|false {} /** * Gets end line * * @link https://php.net/manual/en/reflectionclass.getendline.php * @return int|false The ending line number of the user defined class, or * {@see false} if unknown. */ #[Pure] #[TentativeType] public function getEndLine(): int|false {} /** * Gets doc comments * * @link https://php.net/manual/en/reflectionclass.getdoccomment.php * @return string|false The doc comment if it exists, otherwise {@see false} */ #[Pure] #[TentativeType] public function getDocComment(): string|false {} /** * Gets the constructor of the class * * @link https://php.net/manual/en/reflectionclass.getconstructor.php * @return ReflectionMethod|null A {@see ReflectionMethod} object reflecting * the class' constructor, or {@see null} if the class has no constructor. */ #[Pure] #[TentativeType] public function getConstructor(): ?ReflectionMethod {} /** * Checks if method is defined * * @link https://php.net/manual/en/reflectionclass.hasmethod.php * @param string $name Name of the method being checked for. * @return bool Returns {@see true} if it has the method, otherwise {@see false} */ #[TentativeType] public function hasMethod(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name): bool {} /** * Gets a ReflectionMethod for a class method. * * @link https://php.net/manual/en/reflectionclass.getmethod.php * @param string $name The method name to reflect. * @return ReflectionMethod A {@see ReflectionMethod} * @throws ReflectionException if the method does not exist. */ #[Pure] #[TentativeType] public function getMethod(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name): ReflectionMethod {} /** * Gets an array of methods for the class. * * @link https://php.net/manual/en/reflectionclass.getmethods.php * @param int|null $filter Filter the results to include only methods * with certain attributes. Defaults to no filtering. * @return ReflectionMethod[] An array of {@see ReflectionMethod} objects * reflecting each method. */ #[Pure] #[TentativeType] public function getMethods(#[LanguageLevelTypeAware(['8.0' => 'int|null'], default: '')] $filter = null): array {} /** * Checks if property is defined * * @link https://php.net/manual/en/reflectionclass.hasproperty.php * @param string $name Name of the property being checked for. * @return bool Returns {@see true} if it has the property, otherwise {@see false} */ #[TentativeType] public function hasProperty(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name): bool {} /** * Gets a ReflectionProperty for a class's property * * @link https://php.net/manual/en/reflectionclass.getproperty.php * @param string $name The property name. * @return ReflectionProperty A {@see ReflectionProperty} * @throws ReflectionException If no property exists by that name. */ #[Pure] #[TentativeType] public function getProperty(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name): ReflectionProperty {} /** * Gets properties * * @link https://php.net/manual/en/reflectionclass.getproperties.php * @param int|null $filter The optional filter, for filtering desired * property types. It's configured using the {@see ReflectionProperty} constants, * and defaults to all property types. * @return ReflectionProperty[] */ #[Pure] #[TentativeType] public function getProperties(#[LanguageLevelTypeAware(['8.0' => 'int|null'], default: '')] $filter = null): array {} /** * Gets a ReflectionClassConstant for a class's property * * @link https://php.net/manual/en/reflectionclass.getreflectionconstant.php * @param string $name The class constant name. * @return ReflectionClassConstant|false A {@see ReflectionClassConstant}. * @since 7.1 */ #[Pure] #[TentativeType] public function getReflectionConstant(string $name): ReflectionClassConstant|false {} /** * Gets class constants * * @link https://php.net/manual/en/reflectionclass.getreflectionconstants.php * @param int|null $filter [optional] allows the filtering of constants defined in a class by their visibility. Since 8.0. * @return ReflectionClassConstant[] An array of ReflectionClassConstant objects. * @since 7.1 */ #[Pure] #[TentativeType] public function getReflectionConstants(#[PhpStormStubsElementAvailable(from: '8.0')] ?int $filter = null): array {} /** * Checks if constant is defined * * @link https://php.net/manual/en/reflectionclass.hasconstant.php * @param string $name The name of the constant being checked for. * @return bool Returns {@see true} if the constant is defined, otherwise {@see false} */ #[TentativeType] public function hasConstant(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name): bool {} /** * Gets constants * * @link https://php.net/manual/en/reflectionclass.getconstants.php * @param int|null $filter [optional] allows the filtering of constants defined in a class by their visibility. Since 8.0. * @return array An array of constants, where the keys hold the name and * the values the value of the constants. */ #[Pure] #[TentativeType] public function getConstants(#[PhpStormStubsElementAvailable(from: '8.0')] ?int $filter = null): array {} /** * Gets defined constant * * @link https://php.net/manual/en/reflectionclass.getconstant.php * @param string $name Name of the constant. * @return mixed|false Value of the constant with the name name. * Returns {@see false} if the constant was not found in the class. */ #[Pure] #[TentativeType] public function getConstant(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name): mixed {} /** * Gets the interfaces * * @link https://php.net/manual/en/reflectionclass.getinterfaces.php * @return ReflectionClass[] An associative array of interfaces, with keys as interface * names and the array values as {@see ReflectionClass} objects. */ #[Pure] #[TentativeType] public function getInterfaces(): array {} /** * Gets the interface names * * @link https://php.net/manual/en/reflectionclass.getinterfacenames.php * @return string[] A numerical array with interface names as the values. */ #[Pure] #[TentativeType] public function getInterfaceNames(): array {} /** * Checks if the class is anonymous * * @link https://php.net/manual/en/reflectionclass.isanonymous.php * @return bool Returns {@see true} on success or {@see false} on failure. * @since 7.0 */ #[Pure] #[TentativeType] public function isAnonymous(): bool {} /** * Checks if the class is an interface * * @link https://php.net/manual/en/reflectionclass.isinterface.php * @return bool Returns {@see true} on success or {@see false} on failure. */ #[Pure] #[TentativeType] public function isInterface(): bool {} /** * Returns an array of traits used by this class * * @link https://php.net/manual/en/reflectionclass.gettraits.php * @return ReflectionClass[] an array with trait names in keys and * instances of trait's {@see ReflectionClass} in values. * @since 5.4 */ #[Pure] #[TentativeType] public function getTraits(): array {} /** * Returns an array of names of traits used by this class * * @link https://php.net/manual/en/reflectionclass.gettraitnames.php * @return string[] An array with trait names in values. * Returns {@see null} in case of an error. * @since 5.4 */ #[Pure] #[TentativeType] public function getTraitNames(): array {} /** * Returns an array of trait aliases * * @link https://php.net/manual/en/reflectionclass.gettraitaliases.php * @return string[] an array with new method names in keys and original * names (in the format "TraitName::original") in values. * Returns {@see null} in case of an error. * @since 5.4 */ #[Pure] #[TentativeType] public function getTraitAliases(): array {} /** * Returns whether this is a trait * * @link https://php.net/manual/en/reflectionclass.istrait.php * @return bool Returns {@see true} if this is a trait, {@see false} otherwise. * Returns {@see null} in case of an error. * @since 5.4 */ #[Pure] #[TentativeType] public function isTrait(): bool {} /** * Checks if class is abstract * * @link https://php.net/manual/en/reflectionclass.isabstract.php * @return bool Returns {@see true} on success or {@see false} on failure. */ #[Pure] #[TentativeType] public function isAbstract(): bool {} /** * Checks if class is final * * @link https://php.net/manual/en/reflectionclass.isfinal.php * @return bool Returns {@see true} on success or {@see false} on failure. */ #[Pure] #[TentativeType] public function isFinal(): bool {} /** * @return bool */ #[Pure] #[PhpStormStubsElementAvailable(from: '8.2')] public function isReadOnly(): bool {} /** * Gets modifiers * * @link https://php.net/manual/en/reflectionclass.getmodifiers.php * @return int bitmask of modifier constants. */ #[Pure] #[TentativeType] public function getModifiers(): int {} /** * Checks class for instance * * @link https://php.net/manual/en/reflectionclass.isinstance.php * @param object $object The object being compared to. * @return bool Returns {@see true} on success or {@see false} on failure. */ #[Pure] #[TentativeType] public function isInstance(#[LanguageLevelTypeAware(['8.0' => 'object'], default: '')] $object): bool {} /** * Creates a new class instance from given arguments. * * @link https://php.net/manual/en/reflectionclass.newinstance.php * @param mixed ...$args Accepts a variable number of arguments which are * passed to the class constructor, much like {@see call_user_func} * @return T a new instance of the class. * @throws ReflectionException if the class constructor is not public or if * the class does not have a constructor and the $args parameter contains * one or more parameters. */ public function newInstance(...$args) {} /** * Creates a new class instance without invoking the constructor. * * @link https://php.net/manual/en/reflectionclass.newinstancewithoutconstructor.php * @return T a new instance of the class. * @throws ReflectionException if the class is an internal class that * cannot be instantiated without invoking the constructor. In PHP 5.6.0 * onwards, this exception is limited only to internal classes that are final. * @since 5.4 */ #[TentativeType] public function newInstanceWithoutConstructor(): object {} /** * Creates a new class instance from given arguments. * * @link https://php.net/manual/en/reflectionclass.newinstanceargs.php * @param array $args The parameters to be passed to the class constructor as an array. * @return T|null a new instance of the class. * @throws ReflectionException if the class constructor is not public or if * the class does not have a constructor and the $args parameter contains * one or more parameters. * @since 5.1.3 */ #[TentativeType] public function newInstanceArgs(array $args = []): ?object {} /** * Gets parent class * * @link https://php.net/manual/en/reflectionclass.getparentclass.php * @return ReflectionClass|false A {@see ReflectionClass} or {@see false} * if there's no parent. */ #[Pure] #[TentativeType] public function getParentClass(): ReflectionClass|false {} /** * Checks if a subclass * * @link https://php.net/manual/en/reflectionclass.issubclassof.php * @param string|ReflectionClass $class Either the name of the class as * string or a {@see ReflectionClass} object of the class to check against. * @return bool {@see true} on success or {@see false} on failure. */ #[Pure] #[TentativeType] public function isSubclassOf(#[LanguageLevelTypeAware(['8.0' => 'ReflectionClass|string'], default: '')] $class): bool {} /** * Gets static properties * * @link https://php.net/manual/en/reflectionclass.getstaticproperties.php * @return array|null The static properties, as an array where the keys hold * the name and the values the value of the properties. */ #[Pure] #[TentativeType] #[LanguageLevelTypeAware(['8.3' => 'array'], default: 'array|null')] public function getStaticProperties() {} /** * Gets static property value * * @link https://php.net/manual/en/reflectionclass.getstaticpropertyvalue.php * @param string $name The name of the static property for which to return a value. * @param mixed $default [optional] A default value to return in case the class does * not declare a static property with the given name. If the property does * not exist and this argument is omitted, a {@see ReflectionException} is thrown. * @return mixed The value of the static property. */ #[Pure] #[TentativeType] public function getStaticPropertyValue( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $default ): mixed {} /** * Sets static property value * * @link https://php.net/manual/en/reflectionclass.setstaticpropertyvalue.php * @param string $name Property name. * @param mixed $value New property value. * @return void No value is returned. */ #[TentativeType] public function setStaticPropertyValue( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value ): void {} /** * Gets default properties * * @link https://php.net/manual/en/reflectionclass.getdefaultproperties.php * @return mixed[] An array of default properties, with the key being the name * of the property and the value being the default value of the property * or {@see null} if the property doesn't have a default value. The function * does not distinguish between static and non static properties and does * not take visibility modifiers into account. */ #[Pure] #[TentativeType] public function getDefaultProperties(): array {} /** * An alias of {@see ReflectionClass::isIterable} method. * * @link https://php.net/manual/en/reflectionclass.isiterateable.php * @return bool Returns {@see true} on success or {@see false} on failure. */ #[Pure] #[TentativeType] public function isIterateable(): bool {} /** * Check whether this class is iterable * * @link https://php.net/manual/en/reflectionclass.isiterable.php * @return bool Returns {@see true} on success or {@see false} on failure. * @since 7.2 */ #[Pure] #[TentativeType] public function isIterable(): bool {} /** * Checks whether it implements an interface. * * @link https://php.net/manual/en/reflectionclass.implementsinterface.php * @param string $interface The interface name. * @return bool Returns {@see true} on success or {@see false} on failure. */ #[TentativeType] public function implementsInterface(#[LanguageLevelTypeAware(['8.0' => 'ReflectionClass|string'], default: '')] $interface): bool {} /** * Gets a ReflectionExtension object for the extension which defined the class * * @link https://php.net/manual/en/reflectionclass.getextension.php * @return ReflectionExtension|null A {@see ReflectionExtension} object representing * the extension which defined the class, or {@see null} for user-defined classes. */ #[Pure] #[TentativeType] public function getExtension(): ?ReflectionExtension {} /** * Gets the name of the extension which defined the class * * @link https://php.net/manual/en/reflectionclass.getextensionname.php * @return string|false The name of the extension which defined the class, * or {@see false} for user-defined classes. */ #[Pure] #[TentativeType] public function getExtensionName(): string|false {} /** * Checks if in namespace * * @link https://php.net/manual/en/reflectionclass.innamespace.php * @return bool {@see true} on success or {@see false} on failure. */ #[TentativeType] public function inNamespace(): bool {} /** * Gets namespace name * * @link https://php.net/manual/en/reflectionclass.getnamespacename.php * @return string The namespace name. */ #[Pure] #[TentativeType] public function getNamespaceName(): string {} /** * Gets short name * * @link https://php.net/manual/en/reflectionclass.getshortname.php * @return string The class short name. */ #[Pure] #[TentativeType] public function getShortName(): string {} /** * @template T * * Returns an array of class attributes. * * @param class-string|null $name Name of an attribute class * @param int $flags Сriteria by which the attribute is searched. * @return ReflectionAttribute[] * @since 8.0 */ #[Pure] public function getAttributes(?string $name = null, int $flags = 0): array {} /** * Clones object * * @link https://php.net/manual/en/reflectionclass.clone.php * @return void */ #[PhpStormStubsElementAvailable(from: "5.4", to: "8.0")] final private function __clone(): void {} /** * Clones object * * @link https://php.net/manual/en/reflectionclass.clone.php * @return void */ #[PhpStormStubsElementAvailable(from: "8.1")] private function __clone(): void {} #[PhpStormStubsElementAvailable('8.1')] public function isEnum(): bool {} } Reflector is an interface implemented by all * exportable Reflection classes. * * @link https://php.net/manual/en/class.reflector.php */ interface Reflector extends Stringable { /** * Exports a class. * * @link https://php.net/manual/en/reflector.export.php * @return string|null * @removed 7.4 */ public static function export(); /** * Returns the string representation of any Reflection object. * * Please note that since PHP 8.0 this method is absent in this interface * and inherits from the {@see Stringable} parent. * * @return string */ public function __toString(); } ReflectionMethod class reports * information about a method. * * @link https://php.net/manual/en/class.reflectionmethod.php */ class ReflectionMethod extends ReflectionFunctionAbstract { /** * @var string Name of the method, same as calling the {@see ReflectionMethod::getName()} method */ #[Immutable] public $name; /** * @var string Fully qualified class name where this method was defined */ #[Immutable] #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $class; /** * Indicates that the method is static. */ public const IS_STATIC = 16; /** * Indicates that the method is public. */ public const IS_PUBLIC = 1; /** * Indicates that the method is protected. */ public const IS_PROTECTED = 2; /** * Indicates that the method is private. */ public const IS_PRIVATE = 4; /** * Indicates that the method is abstract. */ public const IS_ABSTRACT = 64; /** * Indicates that the method is final. */ public const IS_FINAL = 32; /** * Constructs a ReflectionMethod * * * $reflection = new ReflectionMethod(new Example(), 'method'); * $reflection = new ReflectionMethod(Example::class, 'method'); * $reflection = new ReflectionMethod('Example::method'); * * * @link https://php.net/manual/en/reflectionmethod.construct.php * @param string|object $objectOrMethod Classname, object * (instance of the class) that contains the method or class name and * method name delimited by ::. * @param string|null $method Name of the method if the first argument is a * classname or an object. * @throws ReflectionException if the class or method does not exist. */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'object|string'], default: '')] $objectOrMethod, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $method = null ) {} /** * Export a reflection method. * * @link https://php.net/manual/en/reflectionmethod.export.php * @param string $class The class name. * @param string $name The name of the method. * @param bool $return Setting to {@see true} will return the export, * as opposed to emitting it. Setting to {@see false} (the default) will do the * opposite. * @return string|null If the $return parameter is set to {@see true}, then * the export is returned as a string, otherwise {@see null} is returned. * @removed 8.0 */ #[Deprecated(since: '7.4')] public static function export($class, $name, $return = false) {} /** * Returns the string representation of the ReflectionMethod object. * * @link https://php.net/manual/en/reflectionmethod.tostring.php * @return string A string representation of this {@see ReflectionMethod} instance. */ #[TentativeType] public function __toString(): string {} /** * Checks if method is public * * @link https://php.net/manual/en/reflectionmethod.ispublic.php * @return bool Returns {@see true} if the method is public, otherwise {@see false} */ #[Pure] #[TentativeType] public function isPublic(): bool {} /** * Checks if method is private * * @link https://php.net/manual/en/reflectionmethod.isprivate.php * @return bool Returns {@see true} if the method is private, otherwise {@see false} */ #[Pure] #[TentativeType] public function isPrivate(): bool {} /** * Checks if method is protected * * @link https://php.net/manual/en/reflectionmethod.isprotected.php * @return bool Returns {@see true} if the method is protected, otherwise {@see false} */ #[Pure] #[TentativeType] public function isProtected(): bool {} /** * Checks if method is abstract * * @link https://php.net/manual/en/reflectionmethod.isabstract.php * @return bool Returns {@see true} if the method is abstract, otherwise {@see false} */ #[Pure] #[TentativeType] public function isAbstract(): bool {} /** * Checks if method is final * * @link https://php.net/manual/en/reflectionmethod.isfinal.php * @return bool Returns {@see true} if the method is final, otherwise {@see false} */ #[Pure] #[TentativeType] public function isFinal(): bool {} /** * Checks if method is static * * @link https://php.net/manual/en/reflectionmethod.isstatic.php * @return bool Returns {@see true} if the method is static, otherwise {@see false} */ #[Pure] #[TentativeType] public function isStatic(): bool {} /** * Checks if method is a constructor * * @link https://php.net/manual/en/reflectionmethod.isconstructor.php * @return bool Returns {@see true} if the method is a constructor, otherwise {@see false} */ #[Pure] #[TentativeType] public function isConstructor(): bool {} /** * Checks if method is a destructor * * @link https://php.net/manual/en/reflectionmethod.isdestructor.php * @return bool Returns {@see true} if the method is a destructor, otherwise {@see false} */ #[Pure] #[TentativeType] public function isDestructor(): bool {} /** * Returns a dynamically created closure for the method * * @link https://php.net/manual/en/reflectionmethod.getclosure.php * @param object|null $object Forbidden for static methods, required for other methods or nothing. * @return Closure Returns the newly created {@see Closure}. * @throws ValueError if object is null but the method is non-static. * @throws ReflectionException if object is not an instance of the class this method was declared in. * @since 5.4 */ #[Pure] #[TentativeType] public function getClosure( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.3')] $object, #[PhpStormStubsElementAvailable(from: '7.4')] #[LanguageLevelTypeAware(['8.0' => 'object|null'], default: '')] $object = null ): Closure {} /** * Gets the method modifiers * * @link https://php.net/manual/en/reflectionmethod.getmodifiers.php * @return int A numeric representation of the modifiers. The modifiers are * listed below. The actual meanings of these modifiers are described in the * predefined constants. * * ReflectionMethod modifiers: * * - {@see ReflectionMethod::IS_STATIC} - Indicates that the method is static. * - {@see ReflectionMethod::IS_PUBLIC} - Indicates that the method is public. * - {@see ReflectionMethod::IS_PROTECTED} - Indicates that the method is protected. * - {@see ReflectionMethod::IS_PRIVATE} - Indicates that the method is private. * - {@see ReflectionMethod::IS_ABSTRACT} - Indicates that the method is abstract. * - {@see ReflectionMethod::IS_FINAL} - Indicates that the method is final. */ #[Pure] #[TentativeType] public function getModifiers(): int {} /** * Invokes a reflected method. * * @link https://php.net/manual/en/reflectionmethod.invoke.php * @param object|null $object The object to invoke the method on. For static * methods, pass {@see null} to this parameter. * @param mixed ...$args Zero or more parameters to be passed to the * method. It accepts a variable number of parameters which are passed to * the method. * @return mixed Returns the method result. * @throws ReflectionException if the object parameter does not contain an * instance of the class that this method was declared in or the method * invocation failed. */ public function invoke($object, ...$args) {} /** * Invokes the reflected method and pass its arguments as array. * * @link https://php.net/manual/en/reflectionmethod.invokeargs.php * @param object|null $object The object to invoke the method on. In case * of static methods, you can pass {@see null} to this parameter. * @param array $args The parameters to be passed to the function, as an {@see array}. * @return mixed the method result. * @throws ReflectionException if the object parameter does not contain an * instance of the class that this method was declared in or the method * invocation failed. */ #[TentativeType] public function invokeArgs(#[LanguageLevelTypeAware(['8.0' => 'object|null'], default: '')] $object, array $args): mixed {} /** * Gets declaring class for the reflected method. * * @link https://php.net/manual/en/reflectionmethod.getdeclaringclass.php * @return ReflectionClass A {@see ReflectionClass} object of the class that the * reflected method is part of. */ #[Pure] #[TentativeType] public function getDeclaringClass(): ReflectionClass {} /** * Gets the method prototype (if there is one). * * @link https://php.net/manual/en/reflectionmethod.getprototype.php * @return ReflectionMethod A {@see ReflectionMethod} instance of the method prototype. * @throws ReflectionException if the method does not have a prototype */ #[Pure] #[TentativeType] public function getPrototype(): ReflectionMethod {} /** * Set method accessibility * * @link https://php.net/manual/en/reflectionmethod.setaccessible.php * @param bool $accessible {@see true} to allow accessibility, or {@see false} * @return void No value is returned. */ #[PhpStormStubsElementAvailable(from: "5.3", to: "8.0")] #[TentativeType] public function setAccessible(#[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $accessible): void {} /** * Set method accessibility * This method is no-op starting from PHP 8.1 * * @link https://php.net/manual/en/reflectionmethod.setaccessible.php * @param bool $accessible {@see true} to allow accessibility, or {@see false} * @return void No value is returned. */ #[Pure] #[PhpStormStubsElementAvailable(from: "8.1")] #[TentativeType] public function setAccessible(bool $accessible): void {} #[PhpStormStubsElementAvailable(from: '8.2')] public function hasPrototype(): bool {} /** * @since 8.3 */ public static function createFromMethodName(string $method): static {} } ReflectionObject class reports * information about an object. * * @link https://php.net/manual/en/class.reflectionobject.php */ class ReflectionObject extends ReflectionClass { /** * Constructs a ReflectionObject * * @link https://php.net/manual/en/reflectionobject.construct.php * @param object $object An object instance. */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'object'], default: '')] $object) {} /** * Export * * @link https://php.net/manual/en/reflectionobject.export.php * @param string $argument The reflection to export. * @param bool $return Setting to {@see true} will return the export, * as opposed to emitting it. Setting to {@see false} (the default) will do * the opposite. * @return string|null If the $return parameter is set to {@see true}, then * the export is returned as a string, otherwise {@see null} is returned. * @removed 8.0 */ #[Deprecated(since: '7.4')] public static function export($argument, $return = false) {} } ReflectionParameter class retrieves * information about function's or method's parameters. * * @link https://php.net/manual/en/class.reflectionparameter.php */ class ReflectionParameter implements Reflector { /** * @var string Name of the parameter, same as calling the {@see ReflectionParameter::getName()} method */ #[Immutable] #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $name; /** * Construct * * @link https://php.net/manual/en/reflectionparameter.construct.php * @param callable $function The function to reflect parameters from. * @param string|int $param Either an integer specifying the position * of the parameter (starting with zero), or a the parameter name as string. * @throws ReflectionException if the function or parameter does not exist. */ public function __construct($function, #[LanguageLevelTypeAware(['8.0' => 'string|int'], default: '')] $param) {} /** * Exports * * @link https://php.net/manual/en/reflectionparameter.export.php * @param string $function The function name. * @param string $parameter The parameter name. * @param bool $return Setting to {@see true} will return the export, * as opposed to emitting it. Setting to {@see false} (the default) will do the * opposite. * @return string|null The exported reflection. * @removed 8.0 */ #[Deprecated(since: '7.4')] public static function export($function, $parameter, $return = false) {} /** * Returns the string representation of the ReflectionParameter object. * * @link https://php.net/manual/en/reflectionparameter.tostring.php * @return string */ #[TentativeType] public function __toString(): string {} /** * Gets parameter name * * @link https://php.net/manual/en/reflectionparameter.getname.php * @return string The name of the reflected parameter. */ #[Pure] #[TentativeType] public function getName(): string {} /** * Checks if passed by reference * * @link https://php.net/manual/en/reflectionparameter.ispassedbyreference.php * @return bool {@see true} if the parameter is passed in by reference, otherwise {@see false} */ #[Pure] #[TentativeType] public function isPassedByReference(): bool {} /** * Returns whether this parameter can be passed by value * * @link https://php.net/manual/en/reflectionparameter.canbepassedbyvalue.php * @return bool|null {@see true} if the parameter can be passed by value, {@see false} otherwise. * Returns {@see null} in case of an error. * @since 5.4 */ #[TentativeType] public function canBePassedByValue(): bool {} /** * Gets declaring function * * @link https://php.net/manual/en/reflectionparameter.getdeclaringfunction.php * @return ReflectionFunctionAbstract A {@see ReflectionFunctionAbstract} object. * @since 5.2.3 */ #[Pure] #[TentativeType] public function getDeclaringFunction(): ReflectionFunctionAbstract {} /** * Gets declaring class * * @link https://php.net/manual/en/reflectionparameter.getdeclaringclass.php * @return ReflectionClass|null A {@see ReflectionClass} object or {@see null} if * called on function. */ #[Pure] #[TentativeType] public function getDeclaringClass(): ?ReflectionClass {} /** * Gets the class type hinted for the parameter as a ReflectionClass object. * * @link https://php.net/manual/en/reflectionparameter.getclass.php * @return ReflectionClass|null A {@see ReflectionClass} object. * @see ReflectionParameter::getType() */ #[Deprecated(reason: "Use ReflectionParameter::getType() and the ReflectionType APIs should be used instead.", since: "8.0")] #[Pure] #[TentativeType] public function getClass(): ?ReflectionClass {} /** * Checks if the parameter has a type associated with it. * * @link https://php.net/manual/en/reflectionparameter.hastype.php * @return bool {@see true} if a type is specified, {@see false} otherwise. * @since 7.0 */ #[TentativeType] public function hasType(): bool {} /** * Gets a parameter's type * * @link https://php.net/manual/en/reflectionparameter.gettype.php * @return ReflectionType|null Returns a {@see ReflectionType} object if a * parameter type is specified, {@see null} otherwise. * @since 7.0 */ #[Pure] #[LanguageLevelTypeAware( [ '7.1' => 'ReflectionNamedType|null', '8.0' => 'ReflectionNamedType|ReflectionUnionType|null', '8.1' => 'ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null' ], default: 'ReflectionType|null' )] #[TentativeType] public function getType(): ?ReflectionType {} /** * Checks if parameter expects an array * * @link https://php.net/manual/en/reflectionparameter.isarray.php * @return bool {@see true} if an array is expected, {@see false} otherwise. * @see ReflectionParameter::getType() */ #[Deprecated(reason: "Use ReflectionParameter::getType() and the ReflectionType APIs should be used instead.", since: "8.0")] #[Pure] #[TentativeType] public function isArray(): bool {} /** * Returns whether parameter MUST be callable * * @link https://php.net/manual/en/reflectionparameter.iscallable.php * @return bool|null Returns {@see true} if the parameter is callable, {@see false} * if it is not or {@see null} on failure. * @since 5.4 * @see ReflectionParameter::getType() */ #[Deprecated(reason: "Use ReflectionParameter::getType() and the ReflectionType APIs should be used instead.", since: "8.0")] #[Pure] #[TentativeType] public function isCallable(): bool {} /** * Checks if null is allowed * * @link https://php.net/manual/en/reflectionparameter.allowsnull.php * @return bool Returns {@see true} if {@see null} is allowed, * otherwise {@see false} */ #[TentativeType] public function allowsNull(): bool {} /** * Gets parameter position * * @link https://php.net/manual/en/reflectionparameter.getposition.php * @return int The position of the parameter, left to right, starting at position #0. * @since 5.2.3 */ #[Pure] #[TentativeType] public function getPosition(): int {} /** * Checks if optional * * @link https://php.net/manual/en/reflectionparameter.isoptional.php * @return bool Returns {@see true} if the parameter is optional, otherwise {@see false} * @since 5.0.3 */ #[Pure] #[TentativeType] public function isOptional(): bool {} /** * Checks if a default value is available * * @link https://php.net/manual/en/reflectionparameter.isdefaultvalueavailable.php * @return bool Returns {@see true} if a default value is available, otherwise {@see false} * @since 5.0.3 */ #[Pure] #[TentativeType] public function isDefaultValueAvailable(): bool {} /** * Gets default parameter value * * @link https://php.net/manual/en/reflectionparameter.getdefaultvalue.php * @return mixed The parameters default value. * @throws ReflectionException if the parameter is not optional * @since 5.0.3 */ #[Pure] #[TentativeType] public function getDefaultValue(): mixed {} /** * Returns whether the default value of this parameter is constant * * @link https://php.net/manual/en/reflectionparameter.isdefaultvalueconstant.php * @return bool Returns {@see true} if the default value is constant, and {@see false} otherwise. * @since 5.4.6 */ #[Pure] #[TentativeType] public function isDefaultValueConstant(): bool {} /** * Returns the default value's constant name if default value is constant or null * * @link https://php.net/manual/en/reflectionparameter.getdefaultvalueconstantname.php * @return string|null Returns string on success or {@see null} on failure. * @throws ReflectionException if the parameter is not optional * @since 5.4.6 */ #[Pure] #[TentativeType] public function getDefaultValueConstantName(): ?string {} /** * Returns whether this function is variadic * * @link https://php.net/manual/en/reflectionparameter.isvariadic.php * @return bool Returns {@see true} if the function is variadic, otherwise {@see false} * @since 5.6 */ #[Pure] #[TentativeType] public function isVariadic(): bool {} /** * Returns information about whether the parameter is a promoted. * * @return bool Returns {@see true} if the parameter promoted or {@see false} instead * @since 8.0 */ #[Pure] public function isPromoted(): bool {} /** * @template T * * Returns an array of parameter attributes. * * @param class-string|null $name Name of an attribute class * @param int $flags Сriteria by which the attribute is searched. * @return ReflectionAttribute[] * @since 8.0 */ #[Pure] public function getAttributes(?string $name = null, int $flags = 0): array {} /** * Clone * * @link https://php.net/manual/en/reflectionparameter.clone.php * @return void */ #[PhpStormStubsElementAvailable(from: "5.4", to: "8.0")] final private function __clone(): void {} /** * Clone * * @link https://php.net/manual/en/reflectionparameter.clone.php * @return void */ #[PhpStormStubsElementAvailable(from: "8.1")] private function __clone(): void {} } ReflectionFunction, read its * description for details. * * @link https://php.net/manual/en/class.reflectionfunctionabstract.php */ abstract class ReflectionFunctionAbstract implements Reflector { /** * @var string Name of the function, same as calling the {@see ReflectionFunctionAbstract::getName()} method */ #[Immutable] #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $name; /** * Clones function * * @link https://php.net/manual/en/reflectionfunctionabstract.clone.php * @return void */ #[PhpStormStubsElementAvailable(from: "5.4", to: "8.0")] final private function __clone(): void {} /** * Clones function * * @link https://php.net/manual/en/reflectionfunctionabstract.clone.php * @return void */ #[PhpStormStubsElementAvailable(from: "8.1")] private function __clone(): void {} /** * Checks if function in namespace * * @link https://php.net/manual/en/reflectionfunctionabstract.innamespace.php * @return bool {@see true} if it's in a namespace, otherwise {@see false} */ #[TentativeType] public function inNamespace(): bool {} /** * Checks if closure * * @link https://php.net/manual/en/reflectionfunctionabstract.isclosure.php * @return bool {@see true} if it's a closure, otherwise {@see false} */ #[Pure] #[TentativeType] public function isClosure(): bool {} /** * Checks if deprecated * * @link https://php.net/manual/en/reflectionfunctionabstract.isdeprecated.php * @return bool {@see true} if it's deprecated, otherwise {@see false} */ #[Pure] #[TentativeType] public function isDeprecated(): bool {} /** * Checks if is internal * * @link https://php.net/manual/en/reflectionfunctionabstract.isinternal.php * @return bool {@see true} if it's internal, otherwise {@see false} */ #[Pure] #[TentativeType] public function isInternal(): bool {} /** * Checks if user defined * * @link https://php.net/manual/en/reflectionfunctionabstract.isuserdefined.php * @return bool {@see true} if it's user-defined, otherwise {@see false} */ #[Pure] #[TentativeType] public function isUserDefined(): bool {} /** * Returns whether this function is a generator * * @link https://php.net/manual/en/reflectionfunctionabstract.isgenerator.php * @return bool {@see true} if the function is generator, otherwise {@see false} * @since 5.5 */ #[Pure] #[TentativeType] public function isGenerator(): bool {} /** * Returns whether this function is variadic * * @link https://php.net/manual/en/reflectionfunctionabstract.isvariadic.php * @return bool {@see true} if the function is variadic, otherwise {@see false} * @since 5.6 */ #[Pure] #[TentativeType] public function isVariadic(): bool {} /** * Returns this pointer bound to closure * * @link https://php.net/manual/en/reflectionfunctionabstract.getclosurethis.php * @return object|null Returns $this pointer or {@see null} in case of an error. */ #[Pure] #[TentativeType] public function getClosureThis(): ?object {} /** * Returns the scope associated to the closure * * @link https://php.net/manual/en/reflectionfunctionabstract.getclosurescopeclass.php * @return ReflectionClass|null Returns the class on success or {@see null} * on failure. * @since 5.4 */ #[Pure] #[TentativeType] public function getClosureScopeClass(): ?ReflectionClass {} /** * @return ReflectionClass|null Returns the class on success or {@see null} * on failure. * @since 8.0 */ #[Pure] #[TentativeType] public function getClosureCalledClass(): ?ReflectionClass {} /** * Gets doc comment * * @link https://php.net/manual/en/reflectionfunctionabstract.getdoccomment.php * @return string|false The doc comment if it exists, otherwise {@see false} */ #[Pure] #[TentativeType] public function getDocComment(): string|false {} /** * Gets end line number * * @link https://php.net/manual/en/reflectionfunctionabstract.getendline.php * @return int|false The ending line number of the user defined function, * or {@see false} if unknown. */ #[Pure] #[TentativeType] public function getEndLine(): int|false {} /** * Gets extension info * * @link https://php.net/manual/en/reflectionfunctionabstract.getextension.php * @return ReflectionExtension|null The extension information, as a * {@see ReflectionExtension} object or {@see null} instead. */ #[Pure] #[TentativeType] public function getExtension(): ?ReflectionExtension {} /** * Gets extension name * * @link https://php.net/manual/en/reflectionfunctionabstract.getextensionname.php * @return string|false The extension's name or {@see false} instead. */ #[Pure] #[TentativeType] public function getExtensionName(): string|false {} /** * Gets file name * * @link https://php.net/manual/en/reflectionfunctionabstract.getfilename.php * @return string|false The file name or {@see false} in case of error. */ #[Pure] #[TentativeType] public function getFileName(): string|false {} /** * Gets function name * * @link https://php.net/manual/en/reflectionfunctionabstract.getname.php * @return string The name of the function. */ #[Pure] #[TentativeType] public function getName(): string {} /** * Gets namespace name * * @link https://php.net/manual/en/reflectionfunctionabstract.getnamespacename.php * @return string The namespace name. */ #[Pure] #[TentativeType] public function getNamespaceName(): string {} /** * Gets number of parameters * * @link https://php.net/manual/en/reflectionfunctionabstract.getnumberofparameters.php * @return int The number of parameters. * @since 5.0.3 */ #[Pure] #[TentativeType] public function getNumberOfParameters(): int {} /** * Gets number of required parameters * * @link https://php.net/manual/en/reflectionfunctionabstract.getnumberofrequiredparameters.php * @return int The number of required parameters. * @since 5.0.3 */ #[Pure] #[TentativeType] public function getNumberOfRequiredParameters(): int {} /** * Gets parameters * * @link https://php.net/manual/en/reflectionfunctionabstract.getparameters.php * @return ReflectionParameter[] The parameters, as a ReflectionParameter objects. */ #[Pure] #[TentativeType] public function getParameters(): array {} /** * Gets the specified return type of a function * * @link https://php.net/manual/en/reflectionfunctionabstract.getreturntype.php * @return ReflectionType|null Returns a {@see ReflectionType} object if a * return type is specified, {@see null} otherwise. * @since 7.0 */ #[Pure] #[LanguageLevelTypeAware( [ '7.1' => 'ReflectionNamedType|null', '8.0' => 'ReflectionNamedType|ReflectionUnionType|null', '8.1' => 'ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null' ], default: 'ReflectionType|null' )] #[TentativeType] public function getReturnType(): ?ReflectionType {} /** * Gets function short name * * @link https://php.net/manual/en/reflectionfunctionabstract.getshortname.php * @return string The short name of the function. */ #[Pure] #[TentativeType] public function getShortName(): string {} /** * Gets starting line number * * @link https://php.net/manual/en/reflectionfunctionabstract.getstartline.php * @return int|false The starting line number or {@see false} if unknown. */ #[Pure] #[TentativeType] public function getStartLine(): int|false {} /** * Gets static variables * * @link https://php.net/manual/en/reflectionfunctionabstract.getstaticvariables.php * @return array An array of static variables. */ #[Pure] #[TentativeType] public function getStaticVariables(): array {} /** * Checks if returns reference * * @link https://php.net/manual/en/reflectionfunctionabstract.returnsreference.php * @return bool {@see true} if it returns a reference, otherwise {@see false} */ #[TentativeType] public function returnsReference(): bool {} /** * Checks if the function has a specified return type * * @link https://php.net/manual/en/reflectionfunctionabstract.hasreturntype.php * @return bool Returns {@see true} if the function is a specified return * type, otherwise {@see false}. * @since 7.0 */ #[TentativeType] public function hasReturnType(): bool {} /** * @template T * * Returns an array of function attributes. * * @param class-string|null $name Name of an attribute class * @param int $flags Сriteria by which the attribute is searched. * @return ReflectionAttribute[] * @since 8.0 */ #[Pure] public function getAttributes(?string $name = null, int $flags = 0): array {} #[PhpStormStubsElementAvailable('8.1')] #[Pure] public function getClosureUsedVariables(): array {} #[PhpStormStubsElementAvailable('8.1')] #[Pure] public function hasTentativeReturnType(): bool {} #[PhpStormStubsElementAvailable('8.1')] #[Pure] public function getTentativeReturnType(): ?ReflectionType {} #[PhpStormStubsElementAvailable('8.1')] #[Pure] #[TentativeType] public function isStatic(): bool {} public function __toString() {} } 'string'], default: '')] public $name; /** * Constructs a ReflectionZendExtension object * * @link https://php.net/manual/en/reflectionzendextension.construct.php * @param string $name * @throws ReflectionException if the extension does not exist. * @since 5.4 */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name) {} /** * Exports a reflected zend extension. * * @link https://php.net/manual/en/reflectionzendextension.export.php * @param string $name The reflection to export. * @param bool $return Setting to {@see true} will return the * export, as opposed to emitting it. Setting to {@see false} (the default) * will do the opposite. * @return string|null If the $return parameter is set to {@see true}, then * the export is returned as a string, otherwise {@see null} is returned. */ public static function export($name, $return = false) {} /** * To string handler * * @link https://php.net/manual/en/reflectionzendextension.tostring.php * @return string * @since 5.4 */ #[TentativeType] public function __toString(): string {} /** * Gets name * * @link https://php.net/manual/en/reflectionzendextension.getname.php * @return string * @since 5.4 */ #[Pure] #[TentativeType] public function getName(): string {} /** * Gets version * * @link https://php.net/manual/en/reflectionzendextension.getversion.php * @return string * @since 5.4 */ #[Pure] #[TentativeType] public function getVersion(): string {} /** * Gets author * * @link https://php.net/manual/en/reflectionzendextension.getauthor.php * @return string * @since 5.4 */ #[Pure] #[TentativeType] public function getAuthor(): string {} /** * Gets URL * * @link https://php.net/manual/en/reflectionzendextension.geturl.php * @return string * @since 5.4 */ #[Pure] #[TentativeType] public function getURL(): string {} /** * Gets copyright * * @link https://php.net/manual/en/reflectionzendextension.getcopyright.php * @return string * @since 5.4 */ #[Pure] #[TentativeType] public function getCopyright(): string {} /** * Clone handler * * @link https://php.net/manual/en/reflectionzendextension.clone.php * @return void * @since 5.4 */ #[PhpStormStubsElementAvailable(from: "5.4", to: "8.0")] final private function __clone(): void {} /** * Clone handler * * @link https://php.net/manual/en/reflectionzendextension.clone.php * @return void * @since 5.4 */ #[PhpStormStubsElementAvailable(from: "8.1")] private function __clone(): void {} } 'string|int'], default: '')] $key ): ?ReflectionReference {} /** * Returns unique identifier for the reference. The return value format is unspecified * * @link https://php.net/manual/en/reflectionreference.getid.php * @return int|string Returns an integer or string of unspecified format. */ #[Pure] public function getId(): string {} /** * ReflectionReference cannot be cloned * * @return void */ private function __clone(): void {} } 'null|ReflectionNamedType'], default: 'null|ReflectionType')] public function getBackingType() {} } ReflectionProperty class reports information about a classes * properties. * * @link https://php.net/manual/en/class.reflectionproperty.php */ class ReflectionProperty implements Reflector { /** * @since 8.4 */ public const IS_ABSTRACT = 64; /** * @var string Name of the property, same as calling the {@see ReflectionProperty::getName()} method */ #[Immutable] #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $name; /** * @var string Fully qualified class name where this property was defined */ #[Immutable] #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $class; /** * Indicates that the property is static. * * @link https://www.php.net/manual/en/class.reflectionproperty.php#reflectionproperty.constants.is-static */ public const IS_STATIC = 16; /** * Indicates that the property is public. * * @link https://www.php.net/manual/en/class.reflectionproperty.php#reflectionproperty.constants.is-public */ public const IS_PUBLIC = 1; /** * Indicates that the property is protected. * * @link https://www.php.net/manual/en/class.reflectionproperty.php#reflectionproperty.constants.is-protected */ public const IS_PROTECTED = 2; /** * Indicates that the property is private. * * @link https://www.php.net/manual/en/class.reflectionproperty.php#reflectionproperty.constants.is-private */ public const IS_PRIVATE = 4; /** * @since 8.1 */ public const IS_READONLY = 128; /** * @since 8.4 */ public const IS_PROTECTED_SET = 2048; /** * @since 8.4 */ public const IS_PRIVATE_SET = 4096; /** * Construct a ReflectionProperty object * * @link https://php.net/manual/en/reflectionproperty.construct.php * @param string|object $class The class name, that contains the property. * @param string $property The name of the property being reflected. * @throws ReflectionException if the class or property does not exist. */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'object|string'], default: '')] $class, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $property ) {} /** * Export * * @link https://php.net/manual/en/reflectionproperty.export.php * @param mixed $class The reflection to export. * @param string $name The property name. * @param bool $return Setting to {@see true} will return the export, as * opposed to emitting it. Setting to {@see false} (the default) will do the * opposite. * @return string|null * @removed 8.0 */ #[Deprecated(since: '7.4')] public static function export($class, $name, $return = false) {} /** * To string * * @link https://php.net/manual/en/reflectionproperty.tostring.php * @return string */ #[TentativeType] public function __toString(): string {} /** * Gets property name * * @link https://php.net/manual/en/reflectionproperty.getname.php * @return string The name of the reflected property. */ #[Pure] #[TentativeType] public function getName(): string {} /** * Gets value * * @link https://php.net/manual/en/reflectionproperty.getvalue.php * @param object|null $object If the property is non-static an object must be * provided to fetch the property from. If you want to fetch the default * property without providing an object use {@see ReflectionClass::getDefaultProperties} * instead. * @return mixed The current value of the property. */ #[Pure] #[TentativeType] public function getValue(#[LanguageLevelTypeAware(['8.0' => 'object|null'], default: '')] $object = null): mixed {} /** * Set property value * * @link https://php.net/manual/en/reflectionproperty.setvalue.php * @param mixed $objectOrValue If the property is non-static an object must * be provided to change the property on. If the property is static this * parameter is left out and only $value needs to be provided. * @param mixed $value [optional] The new value. * @return void No value is returned. */ #[TentativeType] public function setValue( #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $objectOrValue, #[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $value ): void {} /** * Checks if property is public * * @link https://php.net/manual/en/reflectionproperty.ispublic.php * @return bool Return {@see true} if the property is public, {@see false} otherwise. */ #[Pure] #[TentativeType] public function isPublic(): bool {} /** * Checks if property is private * * @link https://php.net/manual/en/reflectionproperty.isprivate.php * @return bool Return {@see true} if the property is private, {@see false} otherwise. */ #[Pure] #[TentativeType] public function isPrivate(): bool {} /** * Checks if property is protected * * @link https://php.net/manual/en/reflectionproperty.isprotected.php * @return bool Returns {@see true} if the property is protected, {@see false} otherwise. */ #[Pure] #[TentativeType] public function isProtected(): bool {} /** * Checks if property is static * * @link https://php.net/manual/en/reflectionproperty.isstatic.php * @return bool Returns {@see true} if the property is static, {@see false} otherwise. */ #[Pure] #[TentativeType] public function isStatic(): bool {} /** * Checks if default value * * @link https://php.net/manual/en/reflectionproperty.isdefault.php * @return bool Returns {@see true} if the property was declared at * compile-time, or {@see false} if it was created at run-time. */ #[Pure] #[TentativeType] public function isDefault(): bool {} /** * Gets modifiers * * @link https://php.net/manual/en/reflectionproperty.getmodifiers.php * @return int A numeric representation of the modifiers. */ #[Pure] #[TentativeType] public function getModifiers(): int {} /** * Gets declaring class * * @link https://php.net/manual/en/reflectionproperty.getdeclaringclass.php * @return ReflectionClass A {@see ReflectionClass} object. */ #[Pure] #[TentativeType] public function getDeclaringClass(): ReflectionClass {} /** * Gets doc comment * * @link https://php.net/manual/en/reflectionproperty.getdoccomment.php * @return string|false The doc comment if it exists, otherwise {@see false} */ #[Pure] #[TentativeType] public function getDocComment(): string|false {} /** * Set property accessibility * * @link https://php.net/manual/en/reflectionproperty.setaccessible.php * @param bool $accessible A boolean {@see true} to allow accessibility, or {@see false} * @return void No value is returned. */ #[PhpStormStubsElementAvailable(to: "8.0")] #[TentativeType] public function setAccessible(#[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $accessible): void {} /** * Set property accessibility * This method is no-op starting from PHP 8.1 * * @link https://php.net/manual/en/reflectionproperty.setaccessible.php * @param bool $accessible A boolean {@see true} to allow accessibility, or {@see false} * @return void No value is returned. */ #[Pure] #[PhpStormStubsElementAvailable(from: "8.1")] #[TentativeType] public function setAccessible(bool $accessible): void {} /** * Gets property type * * @link https://php.net/manual/en/reflectionproperty.gettype.php * @return ReflectionType|null Returns a {@see ReflectionType} if the * property has a type, and {@see null} otherwise. * @since 7.4 */ #[Pure] #[LanguageLevelTypeAware( [ '8.0' => 'ReflectionNamedType|ReflectionUnionType|null', '8.1' => 'ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null' ], default: 'ReflectionNamedType|null' )] #[TentativeType] public function getType(): ?ReflectionType {} /** * Checks if property has type * * @link https://php.net/manual/en/reflectionproperty.hastype.php * @return bool Returns {@see true} if a type is specified, {@see false} otherwise. * @since 7.4 */ #[TentativeType] public function hasType(): bool {} /** * Checks if property is initialized * * @link https://php.net/manual/en/reflectionproperty.isinitialized.php * @param object|null $object If the property is non-static an object must be provided to fetch the property from. * @return bool Returns {@see false} for typed properties prior to initialization, and for properties that have * been explicitly {@see unset()}. For all other properties {@see true} will be returned. * @since 7.4 */ #[Pure] #[TentativeType] public function isInitialized(?object $object = null): bool {} /** * Returns information about whether the property was promoted. * * @return bool Returns {@see true} if the property was promoted or {@see false} instead. * @since 8.0 */ #[Pure] public function isPromoted(): bool {} /** * Clone * * @link https://php.net/manual/en/reflectionproperty.clone.php * @return void */ #[PhpStormStubsElementAvailable(from: "5.4", to: "8.0")] final private function __clone(): void {} /** * Clone * * @link https://php.net/manual/en/reflectionproperty.clone.php * @return void */ #[PhpStormStubsElementAvailable(from: "8.1")] private function __clone(): void {} /** * @return bool * @since 8.0 */ public function hasDefaultValue(): bool {} /** * @return mixed * @since 8.0 */ #[Pure] #[TentativeType] public function getDefaultValue(): mixed {} /** * @template T * * Returns an array of property attributes. * * @param class-string|null $name Name of an attribute class * @param int $flags Сriteria by which the attribute is searched. * @return ReflectionAttribute[] * @since 8.0 */ #[Pure] public function getAttributes(?string $name = null, int $flags = 0): array {} /** * @return bool * @since 8.1 */ public function isReadOnly(): bool {} /** * @since 8.4 */ public function getRawValue(object $object): mixed {} /** * @since 8.4 */ public function setRawValue(object $object, mixed $value): void {} /** * @since 8.4 */ public function isAbstract(): bool {} /** * @since 8.4 */ public function isVirtual(): bool {} /** * @since 8.4 */ public function getSettableType(): ?ReflectionType {} /** * @since 8.4 */ public function getHooks(): array {} /** * @since 8.4 */ public function getHook(PropertyHookType $type): ?ReflectionMethod {} /** * @since 8.4 */ public function isPrivateSet(): bool {} /** * @since 8.4 */ public function isProtectedSet(): bool {} } 'int'], default: '')] $modifiers): array {} /** * Exports * * @link https://php.net/manual/en/reflection.export.php * @param Reflector $reflector The reflection to export. * @param bool $return Setting to {@see true} will return the export, as * opposed to emitting it. Setting to {@see false} (the default) will do the opposite. * @return string|null If the return parameter is set to {@see true}, then the * export is returned as a string, otherwise {@see null} is returned. * @removed 8.0 */ #[Deprecated(since: '7.4')] public static function export(Reflector $reflector, $return = false) {} } options can be any of the following the following flags. * * Available options: * * {@see DEBUG_BACKTRACE_PROVIDE_OBJECT} - Default * * {@see DEBUG_BACKTRACE_IGNORE_ARGS} - Don't include the argument * information for functions in the stack trace. * * @return array Returns the trace of the currently executing generator. * @since 7.0 */ #[Pure] #[TentativeType] public function getTrace(int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT): array {} /** * Gets the function name of the generator * * @link https://php.net/manual/en/reflectiongenerator.getfunction.php * @return ReflectionFunctionAbstract Returns a {@see ReflectionFunctionAbstract} * class. This will be {@see ReflectionFunction} for functions, * or {@see ReflectionMethod} for methods. * @since 7.0 */ #[Pure] #[TentativeType] public function getFunction(): ReflectionFunctionAbstract {} /** * Gets the function name of the generator * * @link https://php.net/manual/en/reflectiongenerator.getthis.php * @return object|null Returns the $this value, or {@see null} if the * generator was not created in a class context. * @since 7.0 */ #[Pure] #[TentativeType] public function getThis(): ?object {} /** * Gets the executing Generator object * * @link https://php.net/manual/en/reflectiongenerator.construct.php * @return Generator Returns the currently executing Generator object. * @since 7.0 */ #[Pure] #[TentativeType] public function getExecutingGenerator(): Generator {} /** * @since 8.4 */ public function isClosed(): bool {} } 'string'], default: '')] public $name; /** * @var string Fully qualified class name where this constant was defined */ #[Immutable] #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $class; /** * @var bool * @since 8.1 */ #[Immutable] public bool $isFinal; /** * Indicates that the constant is public. * * @since 8.0 */ public const IS_PUBLIC = 1; /** * Indicates that the constant is protected. * * @since 8.0 */ public const IS_PROTECTED = 2; /** * Indicates that the constant is private. * * @since 8.0 */ public const IS_PRIVATE = 4; /** * @since 8.1 */ public const IS_FINAL = 5; /** * ReflectionClassConstant constructor. * * @param string|object $class Either a string containing the name of the class to reflect, or an object. * @param string $constant The name of the class constant. * @since 7.1 * @link https://php.net/manual/en/reflectionclassconstant.construct.php */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'string|object'], default: '')] $class, string $constant) {} /** * @link https://php.net/manual/en/reflectionclassconstant.export.php * @param string|object $class The reflection to export. * @param string $name The class constant name. * @param bool $return Setting to {@see true} will return the export, as opposed to emitting it. Setting * to {@see false} (the default) will do the opposite. * @return string|null * @since 7.1 * @removed 8.0 */ #[Deprecated(since: '7.4')] public static function export($class, $name, $return = false) {} /** * Gets declaring class * * @return ReflectionClass * @link https://php.net/manual/en/reflectionclassconstant.getdeclaringclass.php * @since 7.1 */ #[Pure] #[TentativeType] public function getDeclaringClass(): ReflectionClass {} /** * Gets doc comments * * @return string|false The doc comment if it exists, otherwise {@see false} * @link https://php.net/manual/en/reflectionclassconstant.getdoccomment.php * @since 7.1 */ #[Pure] #[TentativeType] public function getDocComment(): string|false {} /** * Gets the class constant modifiers * * @return int A numeric representation of the modifiers. The actual meanings of these modifiers are described in * the predefined constants. * @link https://php.net/manual/en/reflectionclassconstant.getmodifiers.php * @since 7.1 */ #[Pure] #[TentativeType] public function getModifiers(): int {} /** * Get name of the constant * * @link https://php.net/manual/en/reflectionclassconstant.getname.php * @return string Returns the constant's name. * @since 7.1 */ #[Pure] #[TentativeType] public function getName(): string {} /** * Gets value * * @link https://php.net/manual/en/reflectionclassconstant.getvalue.php * @return mixed The value of the class constant. * @since 7.1 */ #[Pure] #[TentativeType] public function getValue(): mixed {} /** * Checks if class constant is private * * @link https://php.net/manual/en/reflectionclassconstant.isprivate.php * @return bool * @since 7.1 */ #[Pure] #[TentativeType] public function isPrivate(): bool {} /** * Checks if class constant is protected * * @link https://php.net/manual/en/reflectionclassconstant.isprotected.php * @return bool * @since 7.1 */ #[Pure] #[TentativeType] public function isProtected(): bool {} /** * Checks if class constant is public * * @link https://php.net/manual/en/reflectionclassconstant.ispublic.php * @return bool * @since 7.1 */ #[Pure] #[TentativeType] public function isPublic(): bool {} /** * Returns the string representation of the ReflectionClassConstant object. * * @link https://php.net/manual/en/reflectionclassconstant.tostring.php * @return string * @since 7.1 */ public function __toString(): string {} /** * @template T * * Returns an array of constant attributes. * * @param class-string|null $name Name of an attribute class * @param int $flags Сriteria by which the attribute is searched. * @return ReflectionAttribute[] * @since 8.0 */ #[Pure] public function getAttributes(?string $name = null, int $flags = 0): array {} /** * ReflectionClassConstant cannot be cloned * * @return void */ #[PhpStormStubsElementAvailable(from: "5.4", to: "8.0")] final private function __clone(): void {} /** * ReflectionClassConstant cannot be cloned * * @return void */ #[PhpStormStubsElementAvailable(from: "8.1")] private function __clone(): void {} #[PhpStormStubsElementAvailable('8.1')] public function isEnumCase(): bool {} /** * @return bool * @since 8.1 */ public function isFinal(): bool {} /** * @since 8.3 */ public function hasType(): bool {} /** * @since 8.3 */ public function getType(): ?ReflectionType {} /** * @since 8.4 */ public function isDeprecated(): bool {} } * The name of the file to open, or an existing stream resource. *

    * @param string $mode

    * Similar to the fopen function, only 'r' (read) * and 'w' (write) are supported. Everything else will cause bzopen * to return FALSE. *

    * @return resource|false If the open fails, bzopen returns FALSE, otherwise * it returns a pointer to the newly opened file. */ #[Pure] function bzopen($file, string $mode) {} /** * Binary safe bzip2 file read * @link https://php.net/manual/en/function.bzread.php * @param resource $bz

    * The file pointer. It must be valid and must point to a file * successfully opened by bzopen. *

    * @param int<1024, 8192> $length [optional]

    * If not specified, bzread will read 1024 * (uncompressed) bytes at a time. A maximum of 8192 * uncompressed bytes will be read at a time. *

    * @return string|false the uncompressed data, or FALSE on error. */ function bzread($bz, int $length = 1024): string|false {} /** * Binary safe bzip2 file write * @link https://php.net/manual/en/function.bzwrite.php * @param resource $bz

    * The file pointer. It must be valid and must point to a file * successfully opened by bzopen. *

    * @param string $data

    * The written data. *

    * @param int|null $length [optional]

    * If supplied, writing will stop after length * (uncompressed) bytes have been written or the end of * data is reached, whichever comes first. *

    * @return int|false the number of bytes written, or FALSE on error. */ function bzwrite($bz, string $data, ?int $length): int|false {} /** * Force a write of all buffered data * @link https://php.net/manual/en/function.bzflush.php * @param resource $bz

    * The file pointer. It must be valid and must point to a file * successfully opened by bzopen. *

    * @return bool TRUE on success or FALSE on failure. */ function bzflush($bz): bool {} /** * Close a bzip2 file * @link https://php.net/manual/en/function.bzclose.php * @param resource $bz

    * The file pointer. It must be valid and must point to a file * successfully opened by bzopen. *

    * @return bool TRUE on success or FALSE on failure. */ function bzclose($bz): bool {} /** * Returns a bzip2 error number * @link https://php.net/manual/en/function.bzerrno.php * @param resource $bz

    * The file pointer. It must be valid and must point to a file * successfully opened by bzopen. *

    * @return int the error number as an integer. */ #[Pure] #[LanguageLevelTypeAware(['8.1' => 'int', '8.0' => 'int|false'], default: 'int')] function bzerrno($bz) {} /** * Returns a bzip2 error string * @link https://php.net/manual/en/function.bzerrstr.php * @param resource $bz

    * The file pointer. It must be valid and must point to a file * successfully opened by bzopen. *

    * @return string a string containing the error message. */ #[Pure] #[LanguageLevelTypeAware(['8.1' => 'string', '8.0' => 'string|false'], default: 'string')] function bzerrstr($bz) {} /** * Returns the bzip2 error number and error string in an array * @link https://php.net/manual/en/function.bzerror.php * @param resource $bz

    * The file pointer. It must be valid and must point to a file * successfully opened by bzopen. *

    * @return array an associative array, with the error code in the * errno entry, and the error message in the * errstr entry. */ #[Pure] #[LanguageLevelTypeAware(['8.1' => 'array', '8.0' => 'array|false'], default: 'array')] #[ArrayShape(["errno" => "int", "errstr" => "string"])] function bzerror($bz) {} /** * Compress a string into bzip2 encoded data * @link https://php.net/manual/en/function.bzcompress.php * @param string $data

    * The string to compress. *

    * @param int $block_size

    * Specifies the blocksize used during compression and should be a number * from 1 to 9 with 9 giving the best compression, but using more * resources to do so. *

    * @param int $work_factor [optional]

    * Controls how the compression phase behaves when presented with worst * case, highly repetitive, input data. The value can be between 0 and * 250 with 0 being a special case. *

    *

    * Regardless of the workfactor, the generated * output is the same. *

    * @return string|int The compressed string, or an error number if an error occurred. */ #[Pure] function bzcompress( string $data, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.0')] int $blocksize, #[PhpStormStubsElementAvailable(from: '7.1')] int $block_size = 4, int $work_factor = 0 ): string|int {} /** * Decompresses bzip2 encoded data * @link https://php.net/manual/en/function.bzdecompress.php * @param string $data

    * The string to decompress. *

    * @param bool $use_less_memory [optional]

    * If TRUE, an alternative decompression algorithm will be used which * uses less memory (the maximum memory requirement drops to around 2300K) * but works at roughly half the speed. *

    *

    * See the bzip2 documentation for more * information about this feature. *

    * @return string|int|false The decompressed string, or an error number if an error occurred. */ #[Pure] function bzdecompress(string $data, bool $use_less_memory = false): string|int|false {} distributedTracingHeaderExtractor() instead * * @return TransactionInterface New transaction * * @see TransactionInterface::setName() For the description. * @see TransactionInterface::setType() For the description. * @see TransactionInterface::getTimestamp() For the description. */ public static function beginCurrentTransaction( string $name, string $type, ?float $timestamp = null, ?string $serializedDistTracingData = null ): TransactionInterface {} /** * Begins a new transaction, sets as the current transaction, * runs the provided callback as the new transaction and automatically ends the new transaction. * * @param string $name New transaction's name * @param string $type New transaction's type * @param \Closure $callback Callback to execute as the new transaction * @param float|null $timestamp Start time of the new transaction * @param string|null $serializedDistTracingData - DEPRECATED since version 1.3 - * use newTransaction()->distributedTracingHeaderExtractor() instead * * @return mixed The return value of $callback * * @see TransactionInterface::setName() For the description. * @see TransactionInterface::setType() For the description. * @see TransactionInterface::getTimestamp() For the description. */ public static function captureCurrentTransaction( string $name, string $type, \Closure $callback, ?float $timestamp = null, ?string $serializedDistTracingData = null ) {} /** * Returns the current transaction. * * @return TransactionInterface The current transaction */ public static function getCurrentTransaction(): TransactionInterface {} /** * If there is the current span then it returns the current span. * Otherwise if there is the current transaction then it returns the current transaction. * Otherwise it returns the noop execution segment. * * @return ExecutionSegmentInterface The current execution segment */ public static function getCurrentExecutionSegment(): ExecutionSegmentInterface {} /** * Begins a new transaction. * * @param string $name New transaction's name * @param string $type New transaction's type * @param float|null $timestamp Start time of the new transaction * @param string|null $serializedDistTracingData - DEPRECATED since version 1.3 - * use newTransaction()->distributedTracingHeaderExtractor() instead * * @return TransactionInterface New transaction * * @see TransactionInterface::setName() For the description. * @see TransactionInterface::setType() For the description. * @see TransactionInterface::getTimestamp() For the description. */ public static function beginTransaction( string $name, string $type, ?float $timestamp = null, ?string $serializedDistTracingData = null ): TransactionInterface {} /** * Begins a new transaction, * runs the provided callback as the new transaction and automatically ends the new transaction. * * @param string $name New transaction's name * @param string $type New transaction's type * @param \Closure $callback Callback to execute as the new transaction * @param float|null $timestamp Start time of the new transaction * @param string|null $serializedDistTracingData - DEPRECATED since version 1.3 - * use newTransaction()->distributedTracingHeaderExtractor() instead * * @return mixed The return value of $callback * * @see TransactionInterface::setName() For the description. * @see TransactionInterface::setType() For the description. * @see TransactionInterface::getTimestamp() For the description. */ public static function captureTransaction( string $name, string $type, \Closure $callback, ?float $timestamp = null, ?string $serializedDistTracingData = null ) {} /** * Advanced API to begin a new transaction * * @param string $name New transaction's name * @param string $type New transaction's type * * @return TransactionBuilderInterface New transaction builder * * @see TransactionInterface::setName() For the description. * @see TransactionInterface::setType() For the description. */ public static function newTransaction(string $name, string $type): TransactionBuilderInterface {} /** * Creates an error based on the given Throwable instance * with the current execution segment (if there is one) as the parent. * * @param \Throwable $throwable * * @return string|null ID of the reported error event or null if no event was reported * (for example, because recording is disabled) * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/errors/error.json */ public static function createErrorFromThrowable(\Throwable $throwable): ?string {} /** * Creates an error based on the given data * with the current execution segment (if there is one) as the parent. * * @param CustomErrorData $customErrorData * * @return string|null ID of the reported error event or null if no event was reported * (for example, because recording is disabled) * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/errors/error.json */ public static function createCustomError(CustomErrorData $customErrorData): ?string {} /** * Pauses recording */ public static function pauseRecording(): void {} /** * Resumes recording */ public static function resumeRecording(): void {} /** * @deprecated Deprecated since version 1.3 - use injectDistributedTracingHeaders() instead * @see injectDistributedTracingHeaders() Use it instead of this method * * Returns distributed tracing data for the current span/transaction */ public static function getSerializedCurrentDistributedTracingData(): string {} } /** * Class to gather optional parameters to start a new transaction * * @see ElasticApm::beginCurrentTransaction() * @see ElasticApm::captureCurrentTransaction() */ interface TransactionBuilderInterface { /** * New transaction will be set as the current one * * @return TransactionBuilderInterface */ public function asCurrent(): self; /** * Set start time of the new transaction * * @param float $timestamp * * @return TransactionBuilderInterface */ public function timestamp(float $timestamp): self; /** * @param \Closure $headerExtractor * * @return TransactionBuilderInterface */ public function distributedTracingHeaderExtractor(\Closure $headerExtractor): self; /** * Begins a new transaction. * * @return TransactionInterface New transaction */ public function begin(): TransactionInterface; /** * Begins a new transaction, * runs the provided callback as the new transaction and automatically ends the new transaction. * * @param \Closure $callback * * @return mixed The return value of $callback */ public function capture(\Closure $callback); } interface TransactionInterface extends ExecutionSegmentInterface { /** * Transactions that are 'sampled' will include all available information * Transactions that are not sampled will not have 'spans' or 'context'. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/transactions/transaction.json#L72 */ public function isSampled(): bool; /** * Hex encoded 64 random bits ID of the parent transaction or span. * Only a root transaction of a trace does not have a parent ID, otherwise it needs to be set. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/transactions/transaction.json#L19 */ public function getParentId(): ?string; /** * Begins a new span with the current execution segment * as the new span's parent and sets as the new span as the current span for this transaction. * The current execution segment is the current span if there is one or this transaction itself otherwise. * * @param string $name New span's name. * @param string $type New span's type * @param string|null $subtype New span's subtype * @param string|null $action New span's action * @param float|null $timestamp Start time of the new span * * @see SpanInterface::setName() For the description. * @see SpanInterface::setType() For the description. * @see SpanInterface::setSubtype() For the description. * @see SpanInterface::setAction() For the description. * @see SpanInterface::getTimestamp() For the description. * * @return SpanInterface New span */ public function beginCurrentSpan( string $name, string $type, ?string $subtype = null, ?string $action = null, ?float $timestamp = null ): SpanInterface; /** * Begins a new span with the current execution segment as the new span's parent and * sets the new span as the current span for this transaction. * The current execution segment is the current span if there is one or this transaction itself otherwise. * * @param string $name New span's name * @param string $type New span's type * @param \Closure $callback Callback to execute as the new span * @param string|null $subtype New span's subtype * @param string|null $action New span's action * @param float|null $timestamp Start time of the new span * * @see SpanInterface::setName() For the description. * @see SpanInterface::setType() For the description. * @see SpanInterface::setSubtype() For the description. * @see SpanInterface::setAction() For the description. * @see SpanInterface::getTimestamp() For the description. * * @return mixed The return value of $callback */ public function captureCurrentSpan( string $name, string $type, \Closure $callback, ?string $subtype = null, ?string $action = null, ?float $timestamp = null ); /** * Returns the current span. * * @return SpanInterface The current span */ public function getCurrentSpan(): SpanInterface; /** * Returns context (context allows to set labels, etc.) */ public function context(): TransactionContextInterface; /** * The result of the transaction. * For HTTP-related transactions, this should be the status code formatted like 'HTTP 2xx'. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/transactions/transaction.json#L52 * * @param string|null $result * * @return void */ public function setResult(?string $result): void; /** * @see setResult() For the description */ public function getResult(): ?string; /** * If the transaction does not have a parent ID yet, * calling this method generates a new ID, * sets it as the parent ID of this transaction, and returns it as a string. * * @return string */ public function ensureParentId(): string; } interface SpanInterface extends ExecutionSegmentInterface { /** * Hex encoded 64 random bits ID of the correlated transaction. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L14 */ public function getTransactionId(): string; /** * Hex encoded 64 random bits ID of the parent. * If this span is the root span of the correlated transaction the its parent is the correlated transaction * otherwise its parent is the parent span. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L24 */ public function getParentId(): string; /** * The specific kind of event within the sub-type represented by the span * e.g., 'query' for type/sub-type 'db'/'mysql', 'connect' for type/sub-type 'db'/'cassandra' * * The length of this string is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L38 * * @param string|null $action * * @return void */ public function setAction(?string $action): void; /** * A further sub-division of the type * e.g., 'mysql', 'postgresql' or 'elasticsearch' for type 'db', 'http' for type 'external', etc. * * The length of this string is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L33 * * @param string|null $subtype */ public function setSubtype(?string $subtype): void; /** * Returns context (context allows to set labels, etc.) */ public function context(): SpanContextInterface; /** * Extended version of ExecutionSegmentInterface::end() * * @param int $numberOfStackFramesToSkip Number of stack frames to skip when capturing stack trace. * @param float|null $duration In milliseconds with 3 decimal points. * * @see ExecutionSegmentInterface::end() For the description */ public function endSpanEx(int $numberOfStackFramesToSkip, ?float $duration = null): void; } interface SpanContextInterface extends ExecutionSegmentContextInterface { /** * Returns an object containing contextual data for database spans * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L47 */ public function db(): SpanContextDbInterface; /** * Returns an object containing contextual data of the related http request * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L69 */ public function http(): SpanContextHttpInterface; /** * Returns an object containing contextual data about the destination for spans * * @link https://github.com/elastic/apm-server/blob/7.6/docs/spec/spans/span.json#L44 */ public function destination(): SpanContextDestinationInterface; } interface SpanContextDbInterface { /** * A database statement (e.g. query) for the given database type * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L55 * * @param string|null $statement * * @return void */ public function setStatement(?string $statement): void; } interface SpanContextHttpInterface { /** * The raw url of the correlating http request * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L73 * * @param string|null $url * * @return void */ public function setUrl(?string $url): void; /** * The status code of the http request * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L77 * * @param int|null $statusCode * * @return void */ public function setStatusCode(?int $statusCode): void; /** * The method of the http request * * The length of a value is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L81 * * @param string|null $method * * @return void */ public function setMethod(?string $method): void; } /** * An object containing contextual data about the destination for spans * * @link https://github.com/elastic/apm-server/blob/7.6/docs/spec/spans/span.json#L44 */ interface SpanContextDestinationInterface { /** * Sets destination service context * * @link https://github.com/elastic/apm-server/blob/v7.11.0/docs/spec/v2/span.json#L106 * * @param string $name * @param string $resource * @param string $type */ public function setService(string $name, string $resource, string $type): void; } /** * This interface has functionality shared between Transaction and Span. */ interface ExecutionSegmentInterface { /** * Hex encoded 64 random bits (== 8 bytes == 16 hex digits) ID. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/transactions/transaction.json#L9 * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L9 */ public function getId(): string; /** * Hex encoded 128 random bits (== 16 bytes == 32 hex digits) ID of the correlated trace. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/transactions/transaction.json#L14 * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L19 */ public function getTraceId(): string; /** * Recorded time of the event. * For events that have non-zero duration this time corresponds to the start of the event. * UTC based and in microseconds since Unix epoch. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/transactions/transaction.json#L6 * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L6 * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/timestamp_epoch.json#L7 */ public function getTimestamp(): float; /** * Begins a new span with this execution segment as the new span's parent. * * @param string $name New span's name * @param string $type New span's type * @param string|null $subtype New span's subtype * @param string|null $action New span's action * @param float|null $timestamp Start time of the new span * * @see SpanInterface::setName() For the description. * @see SpanInterface::setType() For the description. * @see SpanInterface::setSubtype() For the description. * @see SpanInterface::setAction() For the description. * @see SpanInterface::setTimestamp() For the description. * * @return SpanInterface New span */ public function beginChildSpan( string $name, string $type, ?string $subtype = null, ?string $action = null, ?float $timestamp = null ): SpanInterface; /** * Begins a new span with this execution segment as the new span's parent, * runs the provided callback as the new span and automatically ends the new span. * * @param string $name New span's name * @param string $type New span's type * @param \Closure $callback Callback to execute as the new span * @param string|null $subtype New span's subtype * @param string|null $action New span's action * @param float|null $timestamp Start time of the new span * * @see SpanInterface::setName() For the description. * @see SpanInterface::setType() For the description. * @see SpanInterface::setSubtype() For the description. * @see SpanInterface::setAction() For the description. * @see SpanInterface::setTimestamp() For the description. * * @return mixed The return value of $callback */ public function captureChildSpan( string $name, string $type, \Closure $callback, ?string $subtype = null, ?string $action = null, ?float $timestamp = null ); /** * - For transactions: * The name of this transaction. * Generic designation of a transaction in the scope of a single service (eg: 'GET /users/:id'). * * - For spans: * Generic designation of a span in the scope of a transaction. * * The length of this string is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/transactions/transaction.json#L47 * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L136 * * @param string $name */ public function setName(string $name): void; /** * Type is a keyword of specific relevance in the service's domain * e.g., * - For transaction: 'db', 'external' for a span and 'request', 'backgroundjob' for a transaction, etc. * - For span: 'db.postgresql.query', 'template.erb', etc. * * The length of this string is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/transactions/transaction.json#L57 * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L149 * * @param string $type */ public function setType(string $type): void; /** * @deprecated Deprecated since version 1.3 - use injectDistributedTracingHeaders() instead * @see injectDistributedTracingHeaders() Use it instead of this method * * Returns distributed tracing data */ public function getDistributedTracingData(): ?DistributedTracingData; /** * Returns distributed tracing data for the current span/transaction * * $headerInjector is callback to inject headers with signature * * (string $headerName, string $headerValue): void * * @param \Closure $headerInjector Callback that actually injects header(s) for the underlying transport */ public function injectDistributedTracingHeaders(\Closure $headerInjector): void; /** * Sets the end timestamp and finalizes this object's state. * * If any mutating method (for example any `set...` method is a mutating method) * is called on a instance which has already then a warning is logged. * For example, end() is a mutating method as well. * * @param float|null $duration In milliseconds with 3 decimal points. */ public function end(?float $duration = null): void; /** * Returns true if this execution segment has already ended. */ public function hasEnded(): bool; /** * Creates an error based on the given Throwable instance with this execution segment as the parent. * * @param \Throwable $throwable * * @return string|null ID of the reported error event or null if no event was reported * (for example, because recording is disabled) * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/errors/error.json */ public function createErrorFromThrowable(\Throwable $throwable): ?string; /** * Creates an error based on the given Throwable instance with this execution segment as the parent. * * @param CustomErrorData $customErrorData * * @return string|null ID of the reported error event or null if no event was reported * (for example, because recording is disabled) * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/errors/error.json */ public function createCustomError(CustomErrorData $customErrorData): ?string; /** * The outcome of the transaction/span: success, failure, or unknown. * Outcome may be one of a limited set of permitted values * describing the success or failure of the transaction/span. * This field can be used for calculating error rates for incoming/outgoing requests. * * @link https://github.com/elastic/apm-server/blob/v7.10.0/docs/spec/transactions/transaction.json#L59 * @link https://github.com/elastic/apm-server/blob/v7.10.0/docs/spec/spans/span.json#L54 * @link https://github.com/elastic/apm-server/blob/v7.10.0/docs/spec/outcome.json * * @param string|null $outcome * * @return void */ public function setOutcome(?string $outcome): void; /** * @see setOutcome() For the description */ public function getOutcome(): ?string; /** * Returns true if this execution segment is a no-op (for example when recording is disabled). */ public function isNoop(): bool; /** * Discards this execution segment. */ public function discard(): void; } final class DistributedTracingData { /** @var string */ public $traceId; /** @var string */ public $parentId; /** @var bool */ public $isSampled; /** * @deprecated Deprecated since version 1.3 - use injectHeaders() instead * @see injectHeaders() Use it instead of this method * * Returns distributed tracing data for the current span/transaction */ public function serializeToString(): string {} /** * Gets distributed tracing data for the current span/transaction * * $headerInjector is callback to inject headers with signature * * (string $headerName, string $headerValue): void * * @param \Closure $headerInjector Callback that actually injects header(s) for the underlying transport */ public function injectHeaders(\Closure $headerInjector): void {} } /** * Data to create custom error event * * @see ElasticApm::createCustomError * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/errors/error.json#L53 * * Code in this file is part of implementation internals and thus it is not covered by the backward compatibility. */ class CustomErrorData { /** * @var int|string|null * * The error code set when the error happened, e.g. database error code * * The length of a string value is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/errors/error.json#L56 */ public $code = null; /** * @var string|null * * The original error message * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/errors/error.json#L61 */ public $message = null; /** * @var string|null * * Describes the exception type's module namespace * * The length of a value is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/errors/error.json#L65 */ public $module = null; /** * @var string|null * * The length of a value is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/errors/error.json#L80 */ public $type = null; } interface TransactionContextInterface extends ExecutionSegmentContextInterface { /** * Returns an object that can be used to collect information about HTTP request * * @link https://github.com/elastic/apm-server/blob/v7.0.0/docs/spec/context.json#L43 * @link https://github.com/elastic/apm-server/blob/v7.0.0/docs/spec/request.json */ public function request(): TransactionContextRequestInterface; } /** * This interface has functionality shared between Transaction and Span contexts'. */ interface ExecutionSegmentContextInterface { /** * @param string $key * @param string|bool|int|float|null $value * * Labels is a flat mapping of user-defined labels with string keys and null, string, boolean or number values. * * The length of a key and a string value is limited to 1024. * * @return void * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/transactions/transaction.json#L40 * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/context.json#L46 * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/spans/span.json#L88 * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/tags.json */ public function setLabel(string $key, $value): void; } interface TransactionContextRequestInterface { /** * HTTP method * * The length of a value is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/v7.0.0/docs/spec/request.json#L33 * * @param string $method * * @return void */ public function setMethod(string $method): void; /** * Returns an object that can be used to collect information about HTTP request's URL * * @link https://github.com/elastic/apm-server/blob/7.0/docs/spec/request.json#L50 */ public function url(): TransactionContextRequestUrlInterface; } interface TransactionContextRequestUrlInterface { /** * The domain of the request, e.g. 'example.com' * * The length of a value is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/v7.0.0/docs/spec/request.json#L69 * * @param ?string $domain * * @return void */ public function setDomain(?string $domain): void; /** * The full, possibly agent-assembled URL of the request * * The length of a value is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/v7.0.0/docs/spec/request.json#L64 * * @param ?string $full * * @return void */ public function setFull(?string $full): void; /** * The raw, unparsed URL of the HTTP request line, e.g https://example.com:443/search?q=elasticsearch. * This URL may be absolute or relative. * For more details, see https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2 * * The length of a value is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/v7.0.0/docs/spec/request.json#L54 * * @param ?string $original * * @return void */ public function setOriginal(?string $original): void; /** * The path of the request, e.g. '/search' * * The length of a value is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/v7.0.0/docs/spec/request.json#L79 * * @param ?string $path * * @return void */ public function setPath(?string $path): void; /** * The port of the request, e.g. 443 * * @link https://github.com/elastic/apm-server/blob/v7.0.0/docs/spec/request.json#L74 * * @param ?int $port * * @return void */ public function setPort(?int $port): void; /** * The protocol of the request, e.g. 'http' * * The length of a value is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/v7.0.0/docs/spec/request.json#L59 * * @param ?string $protocol * * @return void */ public function setProtocol(?string $protocol): void; /** * Sets the query string information of the request. * It is expected to have values delimited by ampersands. * * The length of a value is limited to 1024. * * @link https://github.com/elastic/apm-server/blob/v7.0.0/docs/spec/request.json#L84 * * @param ?string $query * * @return void */ public function setQuery(?string $query): void; } 'amqp/amqp.stub', 'AMQPChannel' => 'amqp/amqp.stub', 'AMQPChannelException' => 'amqp/amqp.stub', 'AMQPConnection' => 'amqp/amqp.stub', 'AMQPConnectionException' => 'amqp/amqp.stub', 'AMQPDecimal' => 'amqp/amqp.stub', 'AMQPEnvelope' => 'amqp/amqp.stub', 'AMQPEnvelopeException' => 'amqp/amqp.stub', 'AMQPException' => 'amqp/amqp.stub', 'AMQPExchange' => 'amqp/amqp.stub', 'AMQPExchangeException' => 'amqp/amqp.stub', 'AMQPExchangeValue' => 'amqp/amqp.stub', 'AMQPQueue' => 'amqp/amqp.stub', 'AMQPQueueException' => 'amqp/amqp.stub', 'AMQPTimestamp' => 'amqp/amqp.stub', 'AMQPValue' => 'amqp/amqp.stub', 'AMQPValueException' => 'amqp/amqp.stub', 'APCIterator' => 'apcu/apcu.stub', 'APCUIterator' => 'apcu/apcu.stub', 'AddressInfo' => 'sockets/sockets.stub', 'Aerospike' => 'aerospike/aerospike.stub', 'Aerospike\\Bytes' => 'aerospike/Bytes.stub', 'AllowDynamicProperties' => 'Core/Core_c.stub', 'AppendIterator' => 'SPL/SPL.stub', 'ArgumentCountError' => 'Core/Core_c.stub', 'ArithmeticError' => 'Core/Core_c.stub', 'ArrayAccess' => 'Core/Core_c.stub', 'ArrayIterator' => 'SPL/SPL.stub', 'ArrayObject' => 'SPL/SPL.stub', 'AssertionError' => 'standard/standard_9.stub', 'Attribute' => 'Core/Core_c.stub', 'BackedEnum' => 'Core/Core_c.stub', 'BadFunctionCallException' => 'SPL/SPL.stub', 'BadMethodCallException' => 'SPL/SPL.stub', 'BlackfireProbe' => 'blackfire/blackfire.stub', 'COM' => 'com_dotnet/com_dotnet.stub', 'CURLFile' => 'curl/curl.stub', 'CURLStringFile' => 'curl/CURLStringFile.stub', 'CachingIterator' => 'SPL/SPL.stub', 'CallbackFilterIterator' => 'SPL/SPL.stub', 'Cassandra' => 'cassandra/cassandra.stub', 'Cassandra\\Aggregate' => 'cassandra/cassandra.stub', 'Cassandra\\BatchStatement' => 'cassandra/cassandra.stub', 'Cassandra\\Bigint' => 'cassandra/cassandra.stub', 'Cassandra\\Blob' => 'cassandra/cassandra.stub', 'Cassandra\\Cluster' => 'cassandra/cassandra.stub', 'Cassandra\\Cluster\\Builder' => 'cassandra/cassandra.stub', 'Cassandra\\Collection' => 'cassandra/cassandra.stub', 'Cassandra\\Column' => 'cassandra/cassandra.stub', 'Cassandra\\Custom' => 'cassandra/cassandra.stub', 'Cassandra\\Date' => 'cassandra/cassandra.stub', 'Cassandra\\Decimal' => 'cassandra/cassandra.stub', 'Cassandra\\DefaultAggregate' => 'cassandra/cassandra.stub', 'Cassandra\\DefaultCluster' => 'cassandra/cassandra.stub', 'Cassandra\\DefaultColumn' => 'cassandra/cassandra.stub', 'Cassandra\\DefaultFunction' => 'cassandra/cassandra.stub', 'Cassandra\\DefaultIndex' => 'cassandra/cassandra.stub', 'Cassandra\\DefaultKeyspace' => 'cassandra/cassandra.stub', 'Cassandra\\DefaultMaterializedView' => 'cassandra/cassandra.stub', 'Cassandra\\DefaultSchema' => 'cassandra/cassandra.stub', 'Cassandra\\DefaultSession' => 'cassandra/cassandra.stub', 'Cassandra\\DefaultTable' => 'cassandra/cassandra.stub', 'Cassandra\\Duration' => 'cassandra/cassandra.stub', 'Cassandra\\Exception' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\AlreadyExistsException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\AuthenticationException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\ConfigurationException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\DivideByZeroException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\DomainException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\ExecutionException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\InvalidArgumentException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\InvalidQueryException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\InvalidSyntaxException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\IsBootstrappingException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\LogicException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\OverloadedException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\ProtocolException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\RangeException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\ReadTimeoutException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\RuntimeException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\ServerException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\TimeoutException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\TruncateException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\UnauthorizedException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\UnavailableException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\UnpreparedException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\ValidationException' => 'cassandra/cassandra.stub', 'Cassandra\\Exception\\WriteTimeoutException' => 'cassandra/cassandra.stub', 'Cassandra\\ExecutionOptions' => 'cassandra/cassandra.stub', 'Cassandra\\Float_' => 'cassandra/cassandra.stub', 'Cassandra\\Function_' => 'cassandra/cassandra.stub', 'Cassandra\\Future' => 'cassandra/cassandra.stub', 'Cassandra\\FutureClose' => 'cassandra/cassandra.stub', 'Cassandra\\FuturePreparedStatement' => 'cassandra/cassandra.stub', 'Cassandra\\FutureRows' => 'cassandra/cassandra.stub', 'Cassandra\\FutureSession' => 'cassandra/cassandra.stub', 'Cassandra\\FutureValue' => 'cassandra/cassandra.stub', 'Cassandra\\Index' => 'cassandra/cassandra.stub', 'Cassandra\\Inet' => 'cassandra/cassandra.stub', 'Cassandra\\Keyspace' => 'cassandra/cassandra.stub', 'Cassandra\\Map' => 'cassandra/cassandra.stub', 'Cassandra\\MaterializedView' => 'cassandra/cassandra.stub', 'Cassandra\\Numeric' => 'cassandra/cassandra.stub', 'Cassandra\\PreparedStatement' => 'cassandra/cassandra.stub', 'Cassandra\\RetryPolicy' => 'cassandra/cassandra.stub', 'Cassandra\\RetryPolicy\\DefaultPolicy' => 'cassandra/cassandra.stub', 'Cassandra\\RetryPolicy\\DowngradingConsistency' => 'cassandra/cassandra.stub', 'Cassandra\\RetryPolicy\\Fallthrough' => 'cassandra/cassandra.stub', 'Cassandra\\RetryPolicy\\Logging' => 'cassandra/cassandra.stub', 'Cassandra\\Rows' => 'cassandra/cassandra.stub', 'Cassandra\\SSLOptions' => 'cassandra/cassandra.stub', 'Cassandra\\SSLOptions\\Builder' => 'cassandra/cassandra.stub', 'Cassandra\\Schema' => 'cassandra/cassandra.stub', 'Cassandra\\Session' => 'cassandra/cassandra.stub', 'Cassandra\\Set' => 'cassandra/cassandra.stub', 'Cassandra\\SimpleStatement' => 'cassandra/cassandra.stub', 'Cassandra\\Smallint' => 'cassandra/cassandra.stub', 'Cassandra\\Statement' => 'cassandra/cassandra.stub', 'Cassandra\\Table' => 'cassandra/cassandra.stub', 'Cassandra\\Time' => 'cassandra/cassandra.stub', 'Cassandra\\Timestamp' => 'cassandra/cassandra.stub', 'Cassandra\\TimestampGenerator' => 'cassandra/cassandra.stub', 'Cassandra\\TimestampGenerator\\Monotonic' => 'cassandra/cassandra.stub', 'Cassandra\\TimestampGenerator\\ServerSide' => 'cassandra/cassandra.stub', 'Cassandra\\Timeuuid' => 'cassandra/cassandra.stub', 'Cassandra\\Tinyint' => 'cassandra/cassandra.stub', 'Cassandra\\Tuple' => 'cassandra/cassandra.stub', 'Cassandra\\Type' => 'cassandra/cassandra.stub', 'Cassandra\\Type\\Collection' => 'cassandra/cassandra.stub', 'Cassandra\\Type\\Custom' => 'cassandra/cassandra.stub', 'Cassandra\\Type\\Map' => 'cassandra/cassandra.stub', 'Cassandra\\Type\\Scalar' => 'cassandra/cassandra.stub', 'Cassandra\\Type\\Set' => 'cassandra/cassandra.stub', 'Cassandra\\Type\\Tuple' => 'cassandra/cassandra.stub', 'Cassandra\\Type\\UserType' => 'cassandra/cassandra.stub', 'Cassandra\\UserTypeValue' => 'cassandra/cassandra.stub', 'Cassandra\\Uuid' => 'cassandra/cassandra.stub', 'Cassandra\\UuidInterface' => 'cassandra/cassandra.stub', 'Cassandra\\Value' => 'cassandra/cassandra.stub', 'Cassandra\\Varint' => 'cassandra/cassandra.stub', 'ClosedGeneratorException' => 'standard/_types.stub', 'Closure' => 'Core/Core_c.stub', 'Collator' => 'intl/intl.stub', 'Collectable' => 'pthreads/pthreads.stub', 'CompileError' => 'Core/Core_c.stub', 'Couchbase\\AnalyticsEncryptionLevel' => 'couchbase/couchbase.stub', 'Couchbase\\AnalyticsException' => 'couchbase/couchbase.stub', 'Couchbase\\AnalyticsIndexManager' => 'couchbase/couchbase.stub', 'Couchbase\\AnalyticsLink' => 'couchbase/couchbase.stub', 'Couchbase\\AnalyticsLinkType' => 'couchbase/couchbase.stub', 'Couchbase\\AnalyticsOptions' => 'couchbase/couchbase.stub', 'Couchbase\\AnalyticsResult' => 'couchbase/couchbase.stub', 'Couchbase\\AppendOptions' => 'couchbase/couchbase.stub', 'Couchbase\\AuthenticationException' => 'couchbase/couchbase.stub', 'Couchbase\\AzureBlobExternalAnalyticsLink' => 'couchbase/couchbase.stub', 'Couchbase\\BadInputException' => 'couchbase/couchbase.stub', 'Couchbase\\BaseException' => 'couchbase/couchbase.stub', 'Couchbase\\BinaryCollection' => 'couchbase/couchbase.stub', 'Couchbase\\BindingsException' => 'couchbase/couchbase.stub', 'Couchbase\\BooleanFieldSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\BooleanSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\Bucket' => 'couchbase/couchbase.stub', 'Couchbase\\BucketManager' => 'couchbase/couchbase.stub', 'Couchbase\\BucketMissingException' => 'couchbase/couchbase.stub', 'Couchbase\\BucketSettings' => 'couchbase/couchbase.stub', 'Couchbase\\CasMismatchException' => 'couchbase/couchbase.stub', 'Couchbase\\Cluster' => 'couchbase/couchbase.stub', 'Couchbase\\ClusterOptions' => 'couchbase/couchbase.stub', 'Couchbase\\Collection' => 'couchbase/couchbase.stub', 'Couchbase\\CollectionManager' => 'couchbase/couchbase.stub', 'Couchbase\\CollectionMissingException' => 'couchbase/couchbase.stub', 'Couchbase\\CollectionSpec' => 'couchbase/couchbase.stub', 'Couchbase\\ConjunctionSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\ConnectAnalyticsLinkOptions' => 'couchbase/couchbase.stub', 'Couchbase\\Coordinate' => 'couchbase/couchbase.stub', 'Couchbase\\CouchbaseRemoteAnalyticsLink' => 'couchbase/couchbase.stub', 'Couchbase\\CounterResult' => 'couchbase/couchbase.stub', 'Couchbase\\CreateAnalyticsDatasetOptions' => 'couchbase/couchbase.stub', 'Couchbase\\CreateAnalyticsDataverseOptions' => 'couchbase/couchbase.stub', 'Couchbase\\CreateAnalyticsIndexOptions' => 'couchbase/couchbase.stub', 'Couchbase\\CreateAnalyticsLinkOptions' => 'couchbase/couchbase.stub', 'Couchbase\\CreateQueryIndexOptions' => 'couchbase/couchbase.stub', 'Couchbase\\CreateQueryPrimaryIndexOptions' => 'couchbase/couchbase.stub', 'Couchbase\\DateRangeFacetResult' => 'couchbase/couchbase.stub', 'Couchbase\\DateRangeSearchFacet' => 'couchbase/couchbase.stub', 'Couchbase\\DateRangeSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\DecrementOptions' => 'couchbase/couchbase.stub', 'Couchbase\\DesignDocument' => 'couchbase/couchbase.stub', 'Couchbase\\DisconnectAnalyticsLinkOptions' => 'couchbase/couchbase.stub', 'Couchbase\\DisjunctionSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\DmlFailureException' => 'couchbase/couchbase.stub', 'Couchbase\\DocIdSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\DocumentNotFoundException' => 'couchbase/couchbase.stub', 'Couchbase\\DropAnalyticsDatasetOptions' => 'couchbase/couchbase.stub', 'Couchbase\\DropAnalyticsDataverseOptions' => 'couchbase/couchbase.stub', 'Couchbase\\DropAnalyticsIndexOptions' => 'couchbase/couchbase.stub', 'Couchbase\\DropAnalyticsLinkOptions' => 'couchbase/couchbase.stub', 'Couchbase\\DropQueryIndexOptions' => 'couchbase/couchbase.stub', 'Couchbase\\DropQueryPrimaryIndexOptions' => 'couchbase/couchbase.stub', 'Couchbase\\DropUserOptions' => 'couchbase/couchbase.stub', 'Couchbase\\DurabilityException' => 'couchbase/couchbase.stub', 'Couchbase\\DurabilityLevel' => 'couchbase/couchbase.stub', 'Couchbase\\EncryptionSettings' => 'couchbase/couchbase.stub', 'Couchbase\\EvictionPolicy' => 'couchbase/couchbase.stub', 'Couchbase\\ExistsOptions' => 'couchbase/couchbase.stub', 'Couchbase\\ExistsResult' => 'couchbase/couchbase.stub', 'Couchbase\\GeoBoundingBoxSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\GeoDistanceSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\GeoPolygonQuery' => 'couchbase/couchbase.stub', 'Couchbase\\GetAllReplicasOptions' => 'couchbase/couchbase.stub', 'Couchbase\\GetAllUsersOptions' => 'couchbase/couchbase.stub', 'Couchbase\\GetAnalyticsLinksOptions' => 'couchbase/couchbase.stub', 'Couchbase\\GetAndLockOptions' => 'couchbase/couchbase.stub', 'Couchbase\\GetAndTouchOptions' => 'couchbase/couchbase.stub', 'Couchbase\\GetAnyReplicaOptions' => 'couchbase/couchbase.stub', 'Couchbase\\GetOptions' => 'couchbase/couchbase.stub', 'Couchbase\\GetReplicaResult' => 'couchbase/couchbase.stub', 'Couchbase\\GetResult' => 'couchbase/couchbase.stub', 'Couchbase\\GetUserOptions' => 'couchbase/couchbase.stub', 'Couchbase\\Group' => 'couchbase/couchbase.stub', 'Couchbase\\HttpException' => 'couchbase/couchbase.stub', 'Couchbase\\IncrementOptions' => 'couchbase/couchbase.stub', 'Couchbase\\IndexFailureException' => 'couchbase/couchbase.stub', 'Couchbase\\IndexNotFoundException' => 'couchbase/couchbase.stub', 'Couchbase\\InsertOptions' => 'couchbase/couchbase.stub', 'Couchbase\\InvalidConfigurationException' => 'couchbase/couchbase.stub', 'Couchbase\\InvalidRangeException' => 'couchbase/couchbase.stub', 'Couchbase\\InvalidStateException' => 'couchbase/couchbase.stub', 'Couchbase\\KeyDeletedException' => 'couchbase/couchbase.stub', 'Couchbase\\KeyExistsException' => 'couchbase/couchbase.stub', 'Couchbase\\KeyLockedException' => 'couchbase/couchbase.stub', 'Couchbase\\KeyValueException' => 'couchbase/couchbase.stub', 'Couchbase\\KeyspaceNotFoundException' => 'couchbase/couchbase.stub', 'Couchbase\\LoggingMeter' => 'couchbase/couchbase.stub', 'Couchbase\\LookupCountSpec' => 'couchbase/couchbase.stub', 'Couchbase\\LookupExistsSpec' => 'couchbase/couchbase.stub', 'Couchbase\\LookupGetFullSpec' => 'couchbase/couchbase.stub', 'Couchbase\\LookupGetSpec' => 'couchbase/couchbase.stub', 'Couchbase\\LookupInOptions' => 'couchbase/couchbase.stub', 'Couchbase\\LookupInResult' => 'couchbase/couchbase.stub', 'Couchbase\\LookupInSpec' => 'couchbase/couchbase.stub', 'Couchbase\\MatchAllSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\MatchNoneSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\MatchPhraseSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\MatchSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\Meter' => 'couchbase/couchbase.stub', 'Couchbase\\MutateArrayAddUniqueSpec' => 'couchbase/couchbase.stub', 'Couchbase\\MutateArrayAppendSpec' => 'couchbase/couchbase.stub', 'Couchbase\\MutateArrayInsertSpec' => 'couchbase/couchbase.stub', 'Couchbase\\MutateArrayPrependSpec' => 'couchbase/couchbase.stub', 'Couchbase\\MutateCounterSpec' => 'couchbase/couchbase.stub', 'Couchbase\\MutateInOptions' => 'couchbase/couchbase.stub', 'Couchbase\\MutateInResult' => 'couchbase/couchbase.stub', 'Couchbase\\MutateInSpec' => 'couchbase/couchbase.stub', 'Couchbase\\MutateInsertSpec' => 'couchbase/couchbase.stub', 'Couchbase\\MutateRemoveSpec' => 'couchbase/couchbase.stub', 'Couchbase\\MutateReplaceSpec' => 'couchbase/couchbase.stub', 'Couchbase\\MutateUpsertSpec' => 'couchbase/couchbase.stub', 'Couchbase\\MutationResult' => 'couchbase/couchbase.stub', 'Couchbase\\MutationState' => 'couchbase/couchbase.stub', 'Couchbase\\MutationToken' => 'couchbase/couchbase.stub', 'Couchbase\\NetworkException' => 'couchbase/couchbase.stub', 'Couchbase\\NoopMeter' => 'couchbase/couchbase.stub', 'Couchbase\\NoopTracer' => 'couchbase/couchbase.stub', 'Couchbase\\NumericRangeFacetResult' => 'couchbase/couchbase.stub', 'Couchbase\\NumericRangeSearchFacet' => 'couchbase/couchbase.stub', 'Couchbase\\NumericRangeSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\Origin' => 'couchbase/couchbase.stub', 'Couchbase\\ParsingFailureException' => 'couchbase/couchbase.stub', 'Couchbase\\PartialViewException' => 'couchbase/couchbase.stub', 'Couchbase\\PathExistsException' => 'couchbase/couchbase.stub', 'Couchbase\\PathNotFoundException' => 'couchbase/couchbase.stub', 'Couchbase\\PhraseSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\PlanningFailureException' => 'couchbase/couchbase.stub', 'Couchbase\\PrefixSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\PreparedStatementException' => 'couchbase/couchbase.stub', 'Couchbase\\PrependOptions' => 'couchbase/couchbase.stub', 'Couchbase\\QueryErrorException' => 'couchbase/couchbase.stub', 'Couchbase\\QueryException' => 'couchbase/couchbase.stub', 'Couchbase\\QueryIndex' => 'couchbase/couchbase.stub', 'Couchbase\\QueryIndexManager' => 'couchbase/couchbase.stub', 'Couchbase\\QueryMetaData' => 'couchbase/couchbase.stub', 'Couchbase\\QueryOptions' => 'couchbase/couchbase.stub', 'Couchbase\\QueryProfile' => 'couchbase/couchbase.stub', 'Couchbase\\QueryResult' => 'couchbase/couchbase.stub', 'Couchbase\\QueryScanConsistency' => 'couchbase/couchbase.stub', 'Couchbase\\QueryServiceException' => 'couchbase/couchbase.stub', 'Couchbase\\QueryStringSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\QuotaLimitedException' => 'couchbase/couchbase.stub', 'Couchbase\\RateLimitedException' => 'couchbase/couchbase.stub', 'Couchbase\\RegexpSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\RemoveOptions' => 'couchbase/couchbase.stub', 'Couchbase\\ReplaceAnalyticsLinkOptions' => 'couchbase/couchbase.stub', 'Couchbase\\ReplaceOptions' => 'couchbase/couchbase.stub', 'Couchbase\\RequestCanceledException' => 'couchbase/couchbase.stub', 'Couchbase\\RequestSpan' => 'couchbase/couchbase.stub', 'Couchbase\\RequestTracer' => 'couchbase/couchbase.stub', 'Couchbase\\Result' => 'couchbase/couchbase.stub', 'Couchbase\\Role' => 'couchbase/couchbase.stub', 'Couchbase\\RoleAndDescription' => 'couchbase/couchbase.stub', 'Couchbase\\RoleAndOrigin' => 'couchbase/couchbase.stub', 'Couchbase\\S3ExternalAnalyticsLink' => 'couchbase/couchbase.stub', 'Couchbase\\Scope' => 'couchbase/couchbase.stub', 'Couchbase\\ScopeMissingException' => 'couchbase/couchbase.stub', 'Couchbase\\ScopeSpec' => 'couchbase/couchbase.stub', 'Couchbase\\SearchException' => 'couchbase/couchbase.stub', 'Couchbase\\SearchFacet' => 'couchbase/couchbase.stub', 'Couchbase\\SearchFacetResult' => 'couchbase/couchbase.stub', 'Couchbase\\SearchHighlightMode' => 'couchbase/couchbase.stub', 'Couchbase\\SearchIndex' => 'couchbase/couchbase.stub', 'Couchbase\\SearchIndexManager' => 'couchbase/couchbase.stub', 'Couchbase\\SearchMetaData' => 'couchbase/couchbase.stub', 'Couchbase\\SearchOptions' => 'couchbase/couchbase.stub', 'Couchbase\\SearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\SearchResult' => 'couchbase/couchbase.stub', 'Couchbase\\SearchSort' => 'couchbase/couchbase.stub', 'Couchbase\\SearchSortField' => 'couchbase/couchbase.stub', 'Couchbase\\SearchSortGeoDistance' => 'couchbase/couchbase.stub', 'Couchbase\\SearchSortId' => 'couchbase/couchbase.stub', 'Couchbase\\SearchSortMissing' => 'couchbase/couchbase.stub', 'Couchbase\\SearchSortMode' => 'couchbase/couchbase.stub', 'Couchbase\\SearchSortScore' => 'couchbase/couchbase.stub', 'Couchbase\\SearchSortType' => 'couchbase/couchbase.stub', 'Couchbase\\ServiceMissingException' => 'couchbase/couchbase.stub', 'Couchbase\\StorageBackend' => 'couchbase/couchbase.stub', 'Couchbase\\StoreSemantics' => 'couchbase/couchbase.stub', 'Couchbase\\SubdocumentException' => 'couchbase/couchbase.stub', 'Couchbase\\TempFailException' => 'couchbase/couchbase.stub', 'Couchbase\\TermFacetResult' => 'couchbase/couchbase.stub', 'Couchbase\\TermRangeSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\TermSearchFacet' => 'couchbase/couchbase.stub', 'Couchbase\\TermSearchQuery' => 'couchbase/couchbase.stub', 'Couchbase\\ThresholdLoggingTracer' => 'couchbase/couchbase.stub', 'Couchbase\\TimeoutException' => 'couchbase/couchbase.stub', 'Couchbase\\TouchOptions' => 'couchbase/couchbase.stub', 'Couchbase\\UnlockOptions' => 'couchbase/couchbase.stub', 'Couchbase\\UpsertOptions' => 'couchbase/couchbase.stub', 'Couchbase\\UpsertUserOptions' => 'couchbase/couchbase.stub', 'Couchbase\\User' => 'couchbase/couchbase.stub', 'Couchbase\\UserAndMetadata' => 'couchbase/couchbase.stub', 'Couchbase\\UserManager' => 'couchbase/couchbase.stub', 'Couchbase\\ValueRecorder' => 'couchbase/couchbase.stub', 'Couchbase\\ValueTooBigException' => 'couchbase/couchbase.stub', 'Couchbase\\View' => 'couchbase/couchbase.stub', 'Couchbase\\ViewConsistency' => 'couchbase/couchbase.stub', 'Couchbase\\ViewException' => 'couchbase/couchbase.stub', 'Couchbase\\ViewIndexManager' => 'couchbase/couchbase.stub', 'Couchbase\\ViewMetaData' => 'couchbase/couchbase.stub', 'Couchbase\\ViewOptions' => 'couchbase/couchbase.stub', 'Couchbase\\ViewOrdering' => 'couchbase/couchbase.stub', 'Couchbase\\ViewResult' => 'couchbase/couchbase.stub', 'Couchbase\\ViewRow' => 'couchbase/couchbase.stub', 'Couchbase\\WatchQueryIndexesOptions' => 'couchbase/couchbase.stub', 'Couchbase\\WildcardSearchQuery' => 'couchbase/couchbase.stub', 'Countable' => 'Core/Core_c.stub', 'Crypto\\Base64' => 'crypto/crypto.stub', 'Crypto\\Base64Exception' => 'crypto/crypto.stub', 'Crypto\\CMAC' => 'crypto/crypto.stub', 'Crypto\\Cipher' => 'crypto/crypto.stub', 'Crypto\\CipherException' => 'crypto/crypto.stub', 'Crypto\\HMAC' => 'crypto/crypto.stub', 'Crypto\\Hash' => 'crypto/crypto.stub', 'Crypto\\HashException' => 'crypto/crypto.stub', 'Crypto\\KDF' => 'crypto/crypto.stub', 'Crypto\\KDFException' => 'crypto/crypto.stub', 'Crypto\\MAC' => 'crypto/crypto.stub', 'Crypto\\MACException' => 'crypto/crypto.stub', 'Crypto\\PBKDF2' => 'crypto/crypto.stub', 'Crypto\\PBKDF2Exception' => 'crypto/crypto.stub', 'Crypto\\Rand' => 'crypto/crypto.stub', 'Crypto\\RandException' => 'crypto/crypto.stub', 'CurlHandle' => 'curl/curl.stub', 'CurlMultiHandle' => 'curl/curl.stub', 'CurlShareHandle' => 'curl/curl.stub', 'DOMAttr' => 'dom/dom_c.stub', 'DOMCdataSection' => 'dom/dom_c.stub', 'DOMCharacterData' => 'dom/dom_c.stub', 'DOMChildNode' => 'dom/dom_c.stub', 'DOMComment' => 'dom/dom_c.stub', 'DOMConfiguration' => 'dom/dom_c.stub', 'DOMDocument' => 'dom/dom_c.stub', 'DOMDocumentFragment' => 'dom/dom_c.stub', 'DOMDocumentType' => 'dom/dom_c.stub', 'DOMDomError' => 'dom/dom_c.stub', 'DOMElement' => 'dom/dom_c.stub', 'DOMEntity' => 'dom/dom_c.stub', 'DOMEntityReference' => 'dom/dom_c.stub', 'DOMErrorHandler' => 'dom/dom_c.stub', 'DOMException' => 'dom/dom_c.stub', 'DOMImplementation' => 'dom/dom_c.stub', 'DOMImplementationList' => 'dom/dom_c.stub', 'DOMImplementationSource' => 'dom/dom_c.stub', 'DOMLocator' => 'dom/dom_c.stub', 'DOMNameList' => 'dom/dom_c.stub', 'DOMNameSpaceNode' => 'dom/dom_c.stub', 'DOMNamedNodeMap' => 'dom/dom_c.stub', 'DOMNode' => 'dom/dom_c.stub', 'DOMNodeList' => 'dom/dom_c.stub', 'DOMNotation' => 'dom/dom_c.stub', 'DOMParentNode' => 'dom/dom_c.stub', 'DOMProcessingInstruction' => 'dom/dom_c.stub', 'DOMStringExtend' => 'dom/dom_c.stub', 'DOMStringList' => 'dom/dom_c.stub', 'DOMText' => 'dom/dom_c.stub', 'DOMTypeinfo' => 'dom/dom_c.stub', 'DOMUserDataHandler' => 'dom/dom_c.stub', 'DOMXPath' => 'dom/dom_c.stub', 'DOTNET' => 'com_dotnet/com_dotnet.stub', 'DateError' => 'date/date_c.stub', 'DateException' => 'date/date_c.stub', 'DateInterval' => 'date/date_c.stub', 'DateInvalidOperationException' => 'date/date_c.stub', 'DateInvalidTimeZoneException' => 'date/date_c.stub', 'DateMalformedIntervalStringException' => 'date/date_c.stub', 'DateMalformedPeriodStringException' => 'date/date_c.stub', 'DateMalformedStringException' => 'date/date_c.stub', 'DateObjectError' => 'date/date_c.stub', 'DatePeriod' => 'date/date_c.stub', 'DateRangeError' => 'date/date_c.stub', 'DateTime' => 'date/date_c.stub', 'DateTimeImmutable' => 'date/date_c.stub', 'DateTimeInterface' => 'date/date_c.stub', 'DateTimeZone' => 'date/date_c.stub', 'Dba\\Connection' => 'dba/Connection.stub', 'Decimal\\Decimal' => 'decimal/decimal.stub', 'DeflateContext' => 'zlib/zlib.stub', 'Deprecated' => 'Core/Core_c.stub', 'Directory' => 'standard/standard_0.stub', 'DirectoryIterator' => 'SPL/SPL_c1.stub', 'DivisionByZeroError' => 'Core/Core_c.stub', 'Dom\\AdjacentPosition' => 'dom/dom_n.stub', 'Dom\\Attr' => 'dom/dom_n.stub', 'Dom\\BrokenRandomEngineError' => 'dom/dom_n.stub', 'Dom\\CDATASection' => 'dom/dom_n.stub', 'Dom\\CharacterData' => 'dom/dom_n.stub', 'Dom\\ChildNode' => 'dom/dom_n.stub', 'Dom\\Comment' => 'dom/dom_n.stub', 'Dom\\Document' => 'dom/dom_n.stub', 'Dom\\DocumentFragment' => 'dom/dom_n.stub', 'Dom\\DocumentType' => 'dom/dom_n.stub', 'Dom\\DtdNamedNodeMap' => 'dom/dom_n.stub', 'Dom\\Element' => 'dom/dom_n.stub', 'Dom\\Entity' => 'dom/dom_n.stub', 'Dom\\EntityReference' => 'dom/dom_n.stub', 'Dom\\HTMLCollection' => 'dom/dom_n.stub', 'Dom\\HTMLDocument' => 'dom/dom_n.stub', 'Dom\\HTMLElement' => 'dom/dom_n.stub', 'Dom\\Implementation' => 'dom/dom_n.stub', 'Dom\\Mysql' => 'dom/dom_n.stub', 'Dom\\NamedNodeMap' => 'dom/dom_n.stub', 'Dom\\NamespaceInfo' => 'dom/dom_n.stub', 'Dom\\Node' => 'dom/dom_n.stub', 'Dom\\NodeList' => 'dom/dom_n.stub', 'Dom\\Notation' => 'dom/dom_n.stub', 'Dom\\ParentNode' => 'dom/dom_n.stub', 'Dom\\ProcessingInstruction' => 'dom/dom_n.stub', 'Dom\\RandomError' => 'dom/dom_n.stub', 'Dom\\RandomException' => 'dom/dom_n.stub', 'Dom\\Sqlite' => 'dom/dom_n.stub', 'Dom\\Text' => 'dom/dom_n.stub', 'Dom\\TokenList' => 'dom/dom_n.stub', 'Dom\\XMLDocument' => 'dom/dom_n.stub', 'Dom\\XPath' => 'dom/dom_n.stub', 'DomainException' => 'SPL/SPL.stub', 'Ds\\Collection' => 'ds/ds.stub', 'Ds\\Deque' => 'ds/ds.stub', 'Ds\\Hashable' => 'ds/ds.stub', 'Ds\\Map' => 'ds/ds.stub', 'Ds\\Pair' => 'ds/ds.stub', 'Ds\\PriorityQueue' => 'ds/ds.stub', 'Ds\\Queue' => 'ds/ds.stub', 'Ds\\Sequence' => 'ds/ds.stub', 'Ds\\Set' => 'ds/ds.stub', 'Ds\\Stack' => 'ds/ds.stub', 'Ds\\Vector' => 'ds/ds.stub', 'Elastic\\Apm\\CustomErrorData' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\DistributedTracingData' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\ElasticApm' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\ExecutionSegmentContextInterface' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\ExecutionSegmentInterface' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\SpanContextDbInterface' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\SpanContextDestinationInterface' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\SpanContextHttpInterface' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\SpanContextInterface' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\SpanInterface' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\TransactionBuilderInterface' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\TransactionContextInterface' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\TransactionContextRequestInterface' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\TransactionContextRequestUrlInterface' => 'elastic_apm/elastic_apm.stub', 'Elastic\\Apm\\TransactionInterface' => 'elastic_apm/elastic_apm.stub', 'EmptyIterator' => 'SPL/SPL.stub', 'EnchantBroker' => 'enchant/enchant.stub', 'EnchantDictionary' => 'enchant/enchant.stub', 'Error' => 'Core/Core_c.stub', 'ErrorException' => 'Core/Core_c.stub', 'Ev' => 'Ev/Ev.stub', 'EvCheck' => 'Ev/Ev.stub', 'EvChild' => 'Ev/Ev.stub', 'EvEmbed' => 'Ev/Ev.stub', 'EvFork' => 'Ev/Ev.stub', 'EvIdle' => 'Ev/Ev.stub', 'EvIo' => 'Ev/Ev.stub', 'EvLoop' => 'Ev/Ev.stub', 'EvPeriodic' => 'Ev/Ev.stub', 'EvPrepare' => 'Ev/Ev.stub', 'EvSignal' => 'Ev/Ev.stub', 'EvStat' => 'Ev/Ev.stub', 'EvTimer' => 'Ev/Ev.stub', 'EvWatcher' => 'Ev/Ev.stub', 'Event' => 'event/event.stub', 'EventBase' => 'event/event.stub', 'EventBuffer' => 'event/event.stub', 'EventBufferEvent' => 'event/event.stub', 'EventConfig' => 'event/event.stub', 'EventDnsBase' => 'event/event.stub', 'EventHttp' => 'event/event.stub', 'EventHttpConnection' => 'event/event.stub', 'EventHttpRequest' => 'event/event.stub', 'EventListener' => 'event/event.stub', 'EventSslContext' => 'event/event.stub', 'EventUtil' => 'event/event.stub', 'Exception' => 'Core/Core_c.stub', 'FANNConnection' => 'fann/fann.stub', 'FFI' => 'FFI/FFI.stub', 'FFI\\CData' => 'FFI/FFI.stub', 'FFI\\CType' => 'FFI/FFI.stub', 'FFI\\Exception' => 'FFI/FFI.stub', 'FFI\\ParserException' => 'FFI/FFI.stub', 'FTP\\Connection' => 'ftp/Connection.stub', 'Fiber' => 'Core/Core_c.stub', 'FiberError' => 'Core/Core_c.stub', 'FilesystemIterator' => 'SPL/SPL_c1.stub', 'FilterIterator' => 'SPL/SPL.stub', 'GEOSGeometry' => 'geos/geos.stub', 'GEOSWKBReader' => 'geos/geos.stub', 'GEOSWKBWriter' => 'geos/geos.stub', 'GEOSWKTReader' => 'geos/geos.stub', 'GEOSWKTWriter' => 'geos/geos.stub', 'GMP' => 'gmp/gmp.stub', 'GdFont' => 'gd/GdFont.stub', 'GdImage' => 'gd/gd.stub', 'GearmanClient' => 'gearman/gearman.stub', 'GearmanException' => 'gearman/gearman.stub', 'GearmanJob' => 'gearman/gearman.stub', 'GearmanTask' => 'gearman/gearman.stub', 'GearmanWorker' => 'gearman/gearman.stub', 'Generator' => 'standard/_types.stub', 'GlobIterator' => 'SPL/SPL_c1.stub', 'Gmagick' => 'gmagick/gmagick.stub', 'GmagickDraw' => 'gmagick/gmagick.stub', 'GmagickException' => 'gmagick/gmagick.stub', 'GmagickPixel' => 'gmagick/gmagick.stub', 'GmagickPixelException' => 'gmagick/gmagick.stub', 'Grpc\\Call' => 'grpc/grpc.stub', 'Grpc\\CallCredentials' => 'grpc/grpc.stub', 'Grpc\\Channel' => 'grpc/grpc.stub', 'Grpc\\ChannelCredentials' => 'grpc/grpc.stub', 'Grpc\\Server' => 'grpc/grpc.stub', 'Grpc\\ServerCredentials' => 'grpc/grpc.stub', 'Grpc\\Timeval' => 'grpc/grpc.stub', 'HashContext' => 'hash/hash.stub', 'HttpDeflateStream' => 'http/http.stub', 'HttpEncodingException' => 'http/http.stub', 'HttpException' => 'http/http.stub', 'HttpHeaderException' => 'http/http.stub', 'HttpInflateStream' => 'http/http.stub', 'HttpInvalidParamException' => 'http/http.stub', 'HttpMalformedHeadersException' => 'http/http.stub', 'HttpMessage' => 'http/http.stub', 'HttpMessageTypeException' => 'http/http.stub', 'HttpQueryString' => 'http/http.stub', 'HttpQueryStringException' => 'http/http.stub', 'HttpRequest' => 'http/http.stub', 'HttpRequestDataShare' => 'http/http.stub', 'HttpRequestException' => 'http/http.stub', 'HttpRequestMethodException' => 'http/http.stub', 'HttpRequestPool' => 'http/http.stub', 'HttpRequestPoolException' => 'http/http.stub', 'HttpResponse' => 'http/http.stub', 'HttpResponseException' => 'http/http.stub', 'HttpRuntimeException' => 'http/http.stub', 'HttpSocketException' => 'http/http.stub', 'HttpUrlException' => 'http/http.stub', 'HttpUtil' => 'http/http.stub', 'IMAP\\Connection' => 'imap/Connection.stub', 'Imagick' => 'imagick/imagick.stub', 'ImagickDraw' => 'imagick/imagick.stub', 'ImagickDrawException' => 'imagick/imagick.stub', 'ImagickException' => 'imagick/imagick.stub', 'ImagickKernel' => 'imagick/imagick.stub', 'ImagickKernelException' => 'imagick/imagick.stub', 'ImagickPixel' => 'imagick/imagick.stub', 'ImagickPixelException' => 'imagick/imagick.stub', 'ImagickPixelIterator' => 'imagick/imagick.stub', 'ImagickPixelIteratorException' => 'imagick/imagick.stub', 'InfiniteIterator' => 'SPL/SPL.stub', 'InflateContext' => 'zlib/zlib.stub', 'InternalIterator' => 'Core/Core_c.stub', 'IntlBreakIterator' => 'intl/intl.stub', 'IntlCalendar' => 'intl/intl.stub', 'IntlChar' => 'intl/IntlChar.stub', 'IntlCodePointBreakIterator' => 'intl/intl.stub', 'IntlDateFormatter' => 'intl/intl.stub', 'IntlDatePatternGenerator' => 'intl/IntlDatePatternGenerator.stub', 'IntlException' => 'intl/intl.stub', 'IntlGregorianCalendar' => 'intl/intl.stub', 'IntlIterator' => 'intl/intl.stub', 'IntlPartsIterator' => 'intl/intl.stub', 'IntlRuleBasedBreakIterator' => 'intl/intl.stub', 'IntlTimeZone' => 'intl/intl.stub', 'InvalidArgumentException' => 'SPL/SPL.stub', 'Iterator' => 'Core/Core_c.stub', 'IteratorAggregate' => 'Core/Core_c.stub', 'IteratorIterator' => 'SPL/SPL.stub', 'JavaException' => 'zend/zend.stub', 'JsonException' => 'json/json.stub', 'JsonIncrementalParser' => 'json/json.stub', 'JsonSerializable' => 'json/json.stub', 'Judy' => 'judy/judy.stub', 'LDAP\\Connection' => 'ldap/Connection.stub', 'LDAP\\Result' => 'ldap/Result.stub', 'LDAP\\ResultEntry' => 'ldap/ResultEntry.stub', 'LengthException' => 'SPL/SPL.stub', 'LevelDB' => 'leveldb/LevelDB.stub', 'LevelDBException' => 'leveldb/LevelDB.stub', 'LevelDBIterator' => 'leveldb/LevelDB.stub', 'LevelDBSnapshot' => 'leveldb/LevelDB.stub', 'LevelDBWriteBatch' => 'leveldb/LevelDB.stub', 'LibXMLError' => 'libxml/libxml.stub', 'LimitIterator' => 'SPL/SPL.stub', 'Locale' => 'intl/intl.stub', 'LogicException' => 'SPL/SPL.stub', 'Lua' => 'lua/lua.stub', 'LuaSandbox' => 'LuaSandbox/LuaSandbox.stub', 'LuaSandboxError' => 'LuaSandbox/LuaSandbox.stub', 'LuaSandboxErrorError' => 'LuaSandbox/LuaSandbox.stub', 'LuaSandboxFatalError' => 'LuaSandbox/LuaSandbox.stub', 'LuaSandboxFunction' => 'LuaSandbox/LuaSandbox.stub', 'LuaSandboxMemoryError' => 'LuaSandbox/LuaSandbox.stub', 'LuaSandboxRuntimeError' => 'LuaSandbox/LuaSandbox.stub', 'LuaSandboxSyntaxError' => 'LuaSandbox/LuaSandbox.stub', 'LuaSandboxTimeoutError' => 'LuaSandbox/LuaSandbox.stub', 'Memcache' => 'memcache/memcache.stub', 'MemcachePool' => 'memcache/memcache.stub', 'Memcached' => 'memcached/memcached.stub', 'MemcachedException' => 'memcached/memcached.stub', 'MessageFormatter' => 'intl/intl.stub', 'MessagePack' => 'msgpack/msgpack.stub', 'MessagePackUnpacker' => 'msgpack/msgpack.stub', 'Mongo' => 'mongo/mongo.stub', 'MongoBinData' => 'mongo/mongo.stub', 'MongoClient' => 'mongo/mongo.stub', 'MongoCode' => 'mongo/mongo.stub', 'MongoCollection' => 'mongo/mongo.stub', 'MongoCommandCursor' => 'mongo/mongo.stub', 'MongoConnectionException' => 'mongo/mongo.stub', 'MongoCursor' => 'mongo/mongo.stub', 'MongoCursorException' => 'mongo/mongo.stub', 'MongoCursorInterface' => 'mongo/mongo.stub', 'MongoCursorTimeoutException' => 'mongo/mongo.stub', 'MongoDB' => 'mongo/mongo.stub', 'MongoDBRef' => 'mongo/mongo.stub', 'MongoDB\\BSON\\Binary' => 'mongodb/BSON/Binary.stub', 'MongoDB\\BSON\\BinaryInterface' => 'mongodb/BSON/BinaryInterface.stub', 'MongoDB\\BSON\\DBPointer' => 'mongodb/BSON/DBPointer.stub', 'MongoDB\\BSON\\Decimal128' => 'mongodb/BSON/Decimal128.stub', 'MongoDB\\BSON\\Decimal128Interface' => 'mongodb/BSON/Decimal128Interface.stub', 'MongoDB\\BSON\\Document' => 'mongodb/BSON/Document.stub', 'MongoDB\\BSON\\Int64' => 'mongodb/BSON/Int64.stub', 'MongoDB\\BSON\\Iterator' => 'mongodb/BSON/Iterator.stub', 'MongoDB\\BSON\\Javascript' => 'mongodb/BSON/Javascript.stub', 'MongoDB\\BSON\\JavascriptInterface' => 'mongodb/BSON/JavascriptInterface.stub', 'MongoDB\\BSON\\MaxKey' => 'mongodb/BSON/MaxKey.stub', 'MongoDB\\BSON\\MaxKeyInterface' => 'mongodb/BSON/MaxKeyInterface.stub', 'MongoDB\\BSON\\MinKey' => 'mongodb/BSON/MinKey.stub', 'MongoDB\\BSON\\MinKeyInterface' => 'mongodb/BSON/MinKeyInterface.stub', 'MongoDB\\BSON\\ObjectId' => 'mongodb/BSON/ObjectId.stub', 'MongoDB\\BSON\\ObjectIdInterface' => 'mongodb/BSON/ObjectIdInterface.stub', 'MongoDB\\BSON\\PackedArray' => 'mongodb/BSON/PackedArray.stub', 'MongoDB\\BSON\\Persistable' => 'mongodb/BSON/Persistable.stub', 'MongoDB\\BSON\\Regex' => 'mongodb/BSON/Regex.stub', 'MongoDB\\BSON\\RegexInterface' => 'mongodb/BSON/RegexInterface.stub', 'MongoDB\\BSON\\Serializable' => 'mongodb/BSON/Serializable.stub', 'MongoDB\\BSON\\Symbol' => 'mongodb/BSON/Symbol.stub', 'MongoDB\\BSON\\Timestamp' => 'mongodb/BSON/Timestamp.stub', 'MongoDB\\BSON\\TimestampInterface' => 'mongodb/BSON/TimestampInterface.stub', 'MongoDB\\BSON\\Type' => 'mongodb/BSON/Type.stub', 'MongoDB\\BSON\\UTCDateTime' => 'mongodb/BSON/UTCDateTime.stub', 'MongoDB\\BSON\\UTCDateTimeInterface' => 'mongodb/BSON/UTCDateTimeInterface.stub', 'MongoDB\\BSON\\Undefined' => 'mongodb/BSON/Undefined.stub', 'MongoDB\\BSON\\Unserializable' => 'mongodb/BSON/Unserializable.stub', 'MongoDB\\Driver\\BulkWrite' => 'mongodb/BulkWrite.stub', 'MongoDB\\Driver\\ClientEncryption' => 'mongodb/ClientEncryption.stub', 'MongoDB\\Driver\\Command' => 'mongodb/Command.stub', 'MongoDB\\Driver\\Cursor' => 'mongodb/Cursor.stub', 'MongoDB\\Driver\\CursorId' => 'mongodb/CursorId.stub', 'MongoDB\\Driver\\CursorInterface' => 'mongodb/CursorInterface.stub', 'MongoDB\\Driver\\Exception\\AuthenticationException' => 'mongodb/Exception/AuthenticationException.stub', 'MongoDB\\Driver\\Exception\\BulkWriteException' => 'mongodb/Exception/BulkWriteException.stub', 'MongoDB\\Driver\\Exception\\CommandException' => 'mongodb/Exception/CommandException.stub', 'MongoDB\\Driver\\Exception\\ConnectionException' => 'mongodb/Exception/ConnectionException.stub', 'MongoDB\\Driver\\Exception\\ConnectionTimeoutException' => 'mongodb/Exception/ConnectionTimeoutException.stub', 'MongoDB\\Driver\\Exception\\EncryptionException' => 'mongodb/Exception/EncryptionException.stub', 'MongoDB\\Driver\\Exception\\Exception' => 'mongodb/Exception/Exception.stub', 'MongoDB\\Driver\\Exception\\ExecutionTimeoutException' => 'mongodb/Exception/ExecutionTimeoutException.stub', 'MongoDB\\Driver\\Exception\\InvalidArgumentException' => 'mongodb/Exception/InvalidArgumentException.stub', 'MongoDB\\Driver\\Exception\\LogicException' => 'mongodb/Exception/LogicException.stub', 'MongoDB\\Driver\\Exception\\RuntimeException' => 'mongodb/Exception/RuntimeException.stub', 'MongoDB\\Driver\\Exception\\SSLConnectionException' => 'mongodb/Exception/SSLConnectionException.stub', 'MongoDB\\Driver\\Exception\\ServerException' => 'mongodb/Exception/ServerException.stub', 'MongoDB\\Driver\\Exception\\UnexpectedValueException' => 'mongodb/Exception/UnexpectedValueException.stub', 'MongoDB\\Driver\\Exception\\WriteConcernException' => 'mongodb/Exception/WriteConcernException.stub', 'MongoDB\\Driver\\Exception\\WriteException' => 'mongodb/Exception/WriteException.stub', 'MongoDB\\Driver\\Manager' => 'mongodb/Manager.stub', 'MongoDB\\Driver\\Monitoring\\CommandFailedEvent' => 'mongodb/Monitoring/CommandFailedEvent.stub', 'MongoDB\\Driver\\Monitoring\\CommandStartedEvent' => 'mongodb/Monitoring/CommandStartedEvent.stub', 'MongoDB\\Driver\\Monitoring\\CommandSubscriber' => 'mongodb/Monitoring/CommandSubscriber.stub', 'MongoDB\\Driver\\Monitoring\\CommandSucceededEvent' => 'mongodb/Monitoring/CommandSucceededEvent.stub', 'MongoDB\\Driver\\Monitoring\\LogSubscriber' => 'mongodb/Monitoring/LogSubscriber.stub', 'MongoDB\\Driver\\Monitoring\\SDAMSubscriber' => 'mongodb/Monitoring/SDAMSubscriber.stub', 'MongoDB\\Driver\\Monitoring\\ServerChangedEvent' => 'mongodb/Monitoring/ServerChangedEvent.stub', 'MongoDB\\Driver\\Monitoring\\ServerClosedEvent' => 'mongodb/Monitoring/ServerClosedEvent.stub', 'MongoDB\\Driver\\Monitoring\\ServerHeartbeatFailedEvent' => 'mongodb/Monitoring/ServerHeartbeatFailedEvent.stub', 'MongoDB\\Driver\\Monitoring\\ServerHeartbeatStartedEvent' => 'mongodb/Monitoring/ServerHeartbeatStartedEvent.stub', 'MongoDB\\Driver\\Monitoring\\ServerHeartbeatSucceededEvent' => 'mongodb/Monitoring/ServerHeartbeatSucceededEvent.stub', 'MongoDB\\Driver\\Monitoring\\ServerOpeningEvent' => 'mongodb/Monitoring/ServerOpeningEvent.stub', 'MongoDB\\Driver\\Monitoring\\Subscriber' => 'mongodb/Monitoring/Subscriber.stub', 'MongoDB\\Driver\\Monitoring\\TopologyChangedEvent' => 'mongodb/Monitoring/TopologyChangedEvent.stub', 'MongoDB\\Driver\\Monitoring\\TopologyClosedEvent' => 'mongodb/Monitoring/TopologyClosedEvent.stub', 'MongoDB\\Driver\\Monitoring\\TopologyOpeningEvent' => 'mongodb/Monitoring/TopologyOpeningEvent.stub', 'MongoDB\\Driver\\Query' => 'mongodb/Query.stub', 'MongoDB\\Driver\\ReadConcern' => 'mongodb/ReadConcern.stub', 'MongoDB\\Driver\\ReadPreference' => 'mongodb/ReadPreference.stub', 'MongoDB\\Driver\\Server' => 'mongodb/Server.stub', 'MongoDB\\Driver\\ServerApi' => 'mongodb/ServerApi.stub', 'MongoDB\\Driver\\ServerDescription' => 'mongodb/ServerDescription.stub', 'MongoDB\\Driver\\Session' => 'mongodb/Session.stub', 'MongoDB\\Driver\\TopologyDescription' => 'mongodb/TopologyDescription.stub', 'MongoDB\\Driver\\WriteConcern' => 'mongodb/WriteConcern.stub', 'MongoDB\\Driver\\WriteConcernError' => 'mongodb/WriteConcernError.stub', 'MongoDB\\Driver\\WriteError' => 'mongodb/WriteError.stub', 'MongoDB\\Driver\\WriteResult' => 'mongodb/WriteResult.stub', 'MongoDate' => 'mongo/mongo.stub', 'MongoDuplicateKeyException' => 'mongo/mongo.stub', 'MongoException' => 'mongo/mongo.stub', 'MongoExecutionTimeoutException' => 'mongo/mongo.stub', 'MongoGridFS' => 'mongo/mongo.stub', 'MongoGridFSCursor' => 'mongo/mongo.stub', 'MongoGridFSException' => 'mongo/mongo.stub', 'MongoGridFSFile' => 'mongo/mongo.stub', 'MongoId' => 'mongo/mongo.stub', 'MongoInt32' => 'mongo/mongo.stub', 'MongoInt64' => 'mongo/mongo.stub', 'MongoLog' => 'mongo/mongo.stub', 'MongoMaxKey' => 'mongo/mongo.stub', 'MongoMinKey' => 'mongo/mongo.stub', 'MongoPool' => 'mongo/mongo.stub', 'MongoProtocolException' => 'mongo/mongo.stub', 'MongoRegex' => 'mongo/mongo.stub', 'MongoResultException' => 'mongo/mongo.stub', 'MongoTimestamp' => 'mongo/mongo.stub', 'MongoUpdateBatch' => 'mongo/mongo.stub', 'MongoWriteBatch' => 'mongo/mongo.stub', 'MongoWriteConcernException' => 'mongo/mongo.stub', 'Mosquitto\\Client' => 'mosquitto-php/mosquitto-php.stub', 'Mosquitto\\Exception' => 'mosquitto-php/mosquitto-php.stub', 'Mosquitto\\Message' => 'mosquitto-php/mosquitto-php.stub', 'MultipleIterator' => 'SPL/SPL_c1.stub', 'NoRewindIterator' => 'SPL/SPL.stub', 'Normalizer' => 'intl/intl.stub', 'NumberFormatter' => 'intl/intl.stub', 'OAuth' => 'oauth/oauth.stub', 'OAuthException' => 'oauth/oauth.stub', 'OAuthProvider' => 'oauth/oauth.stub', 'OCICollection' => 'oci8/oci8v3.stub', 'OCILob' => 'oci8/oci8v3.stub', 'OCI_Collection' => 'oci8/oci8.stub', 'OCI_Lob' => 'oci8/oci8.stub', 'OpenSSLAsymmetricKey' => 'openssl/openssl.stub', 'OpenSSLCertificate' => 'openssl/openssl.stub', 'OpenSSLCertificateSigningRequest' => 'openssl/openssl.stub', 'OutOfBoundsException' => 'SPL/SPL.stub', 'OutOfRangeException' => 'SPL/SPL.stub', 'OuterIterator' => 'SPL/SPL.stub', 'OverflowException' => 'SPL/SPL.stub', 'Override' => 'Core/Core_c.stub', 'OwsrequestObj' => 'mapscript/mapscript.stub', 'PDFlib' => 'pdflib/PDFlib.stub', 'PDFlibException' => 'pdflib/PDFlib.stub', 'PDO' => 'PDO/PDO.stub', 'PDOException' => 'PDO/PDO.stub', 'PDORow' => 'PDO/PDO.stub', 'PDOStatement' => 'PDO/PDO.stub', 'PSpell\\Config' => 'pspell/pspell_c.stub', 'PSpell\\Dictionary' => 'pspell/pspell_c.stub', 'ParentIterator' => 'SPL/SPL.stub', 'Parle\\ErrorInfo' => 'Parle/ErrorInfo.stub', 'Parle\\Lexer' => 'Parle/Lexer.stub', 'Parle\\LexerException' => 'Parle/LexerException.stub', 'Parle\\Parser' => 'Parle/Parser.stub', 'Parle\\ParserException' => 'Parle/ParserException.stub', 'Parle\\RLexer' => 'Parle/RLexer.stub', 'Parle\\RParser' => 'Parle/RParser.stub', 'Parle\\Stack' => 'Parle/Stack.stub', 'Parle\\Token' => 'Parle/Token.stub', 'ParseError' => 'Core/Core_c.stub', 'Pcntl\\QosClass' => 'pcntl/pcntl_c.stub', 'Pdo\\Mysql' => 'PDO/PDO.stub', 'Pdo\\Sqlite' => 'PDO/PDO.stub', 'PgSql\\Connection' => 'pgsql/pgsql_c.stub', 'PgSql\\Lob' => 'pgsql/pgsql_c.stub', 'PgSql\\Result' => 'pgsql/pgsql_c.stub', 'Phar' => 'Phar/Phar.stub', 'PharData' => 'Phar/Phar.stub', 'PharException' => 'Phar/Phar.stub', 'PharFileInfo' => 'Phar/Phar.stub', 'PhpToken' => 'tokenizer/PhpToken.stub', 'Pool' => 'pthreads/pthreads.stub', 'PropertyHookType' => 'Reflection/PropertyHookType.stub', 'RRDCreator' => 'rrd/rrd.stub', 'RRDGraph' => 'rrd/rrd.stub', 'RRDUpdater' => 'rrd/rrd.stub', 'Random\\BrokenRandomEngineError' => 'random/random.stub', 'Random\\CryptoSafeEngine' => 'random/random.stub', 'Random\\Engine' => 'random/random.stub', 'Random\\Engine\\Mt19937' => 'random/random.stub', 'Random\\Engine\\PcgOneseq128XslRr64' => 'random/random.stub', 'Random\\Engine\\Secure' => 'random/random.stub', 'Random\\Engine\\Xoshiro256StarStar' => 'random/random.stub', 'Random\\IntervalBoundary' => 'random/random.stub', 'Random\\RandomError' => 'random/random.stub', 'Random\\RandomException' => 'random/random.stub', 'Random\\Randomizer' => 'random/random.stub', 'RangeException' => 'SPL/SPL.stub', 'RarArchive' => 'rar/rar.stub', 'RarEntry' => 'rar/rar.stub', 'RarException' => 'rar/rar.stub', 'RdKafka' => 'rdkafka/RdKafka.stub', 'RdKafka\\Conf' => 'rdkafka/RdKafka/Conf.stub', 'RdKafka\\Consumer' => 'rdkafka/RdKafka/Consumer.stub', 'RdKafka\\ConsumerTopic' => 'rdkafka/RdKafka/ConsumerTopic.stub', 'RdKafka\\Exception' => 'rdkafka/RdKafka/Exception.stub', 'RdKafka\\KafkaConsumer' => 'rdkafka/RdKafka/KafkaConsumer.stub', 'RdKafka\\KafkaConsumerTopic' => 'rdkafka/RdKafka/KafkaConsumerTopic.stub', 'RdKafka\\KafkaErrorException' => 'rdkafka/RdKafka/KafkaErrorException.stub', 'RdKafka\\Message' => 'rdkafka/RdKafka/Message.stub', 'RdKafka\\Metadata' => 'rdkafka/RdKafka/Metadata.stub', 'RdKafka\\Metadata\\Broker' => 'rdkafka/RdKafka/Metadata/Broker.stub', 'RdKafka\\Metadata\\Collection' => 'rdkafka/RdKafka/Metadata/Collection.stub', 'RdKafka\\Metadata\\Partition' => 'rdkafka/RdKafka/Metadata/Partition.stub', 'RdKafka\\Metadata\\Topic' => 'rdkafka/RdKafka/Metadata/Topic.stub', 'RdKafka\\Producer' => 'rdkafka/RdKafka/Producer.stub', 'RdKafka\\ProducerTopic' => 'rdkafka/RdKafka/ProducerTopic.stub', 'RdKafka\\Queue' => 'rdkafka/RdKafka/Queue.stub', 'RdKafka\\Topic' => 'rdkafka/RdKafka/Topic.stub', 'RdKafka\\TopicConf' => 'rdkafka/RdKafka/TopicConf.stub', 'RdKafka\\TopicPartition' => 'rdkafka/RdKafka/TopicPartition.stub', 'RecursiveArrayIterator' => 'SPL/SPL.stub', 'RecursiveCachingIterator' => 'SPL/SPL.stub', 'RecursiveCallbackFilterIterator' => 'SPL/SPL.stub', 'RecursiveDirectoryIterator' => 'SPL/SPL_c1.stub', 'RecursiveFilterIterator' => 'SPL/SPL.stub', 'RecursiveIterator' => 'SPL/SPL.stub', 'RecursiveIteratorIterator' => 'SPL/SPL.stub', 'RecursiveRegexIterator' => 'SPL/SPL.stub', 'RecursiveTreeIterator' => 'SPL/SPL.stub', 'Redis' => 'redis/Redis.stub', 'RedisArray' => 'redis/RedisArray.stub', 'RedisCluster' => 'redis/RedisCluster.stub', 'RedisClusterException' => 'redis/RedisCluster.stub', 'RedisException' => 'redis/Redis.stub', 'RedisSentinel' => 'redis/RedisSentinel.stub', 'Reflection' => 'Reflection/Reflection.stub', 'ReflectionAttribute' => 'Reflection/ReflectionAttribute.stub', 'ReflectionClass' => 'Reflection/ReflectionClass.stub', 'ReflectionClassConstant' => 'Reflection/ReflectionClassConstant.stub', 'ReflectionConstant' => 'Reflection/ReflectionConstant.stub', 'ReflectionEnum' => 'Reflection/ReflectionEnum.stub', 'ReflectionEnumBackedCase' => 'Reflection/ReflectionEnumBackedCase.stub', 'ReflectionEnumUnitCase' => 'Reflection/ReflectionEnumUnitCase.stub', 'ReflectionException' => 'Reflection/ReflectionException.stub', 'ReflectionExtension' => 'Reflection/ReflectionExtension.stub', 'ReflectionFiber' => 'Reflection/ReflectionFiber.stub', 'ReflectionFunction' => 'Reflection/ReflectionFunction.stub', 'ReflectionFunctionAbstract' => 'Reflection/ReflectionFunctionAbstract.stub', 'ReflectionGenerator' => 'Reflection/ReflectionGenerator.stub', 'ReflectionIntersectionType' => 'Reflection/ReflectionIntersectionType.stub', 'ReflectionMethod' => 'Reflection/ReflectionMethod.stub', 'ReflectionNamedType' => 'Reflection/ReflectionNamedType.stub', 'ReflectionObject' => 'Reflection/ReflectionObject.stub', 'ReflectionParameter' => 'Reflection/ReflectionParameter.stub', 'ReflectionProperty' => 'Reflection/ReflectionProperty.stub', 'ReflectionReference' => 'Reflection/ReflectionReference.stub', 'ReflectionType' => 'Reflection/ReflectionType.stub', 'ReflectionUnionType' => 'Reflection/ReflectionUnionType.stub', 'ReflectionZendExtension' => 'Reflection/ReflectionZendExtension.stub', 'Reflector' => 'Reflection/Reflector.stub', 'RegexIterator' => 'SPL/SPL.stub', 'Relay\\Cluster' => 'relay/Cluster.stub', 'Relay\\Event' => 'relay/Event.stub', 'Relay\\Event\\Flushed' => 'relay/Events.stub', 'Relay\\Event\\Invalidated' => 'relay/Events.stub', 'Relay\\Exception' => 'relay/Exception.stub', 'Relay\\KeyType' => 'relay/KeyType.stub', 'Relay\\Relay' => 'relay/Relay.stub', 'Relay\\Sentinel' => 'relay/Sentinel.stub', 'Relay\\Table' => 'relay/Table.stub', 'RequestParseBodyException' => 'Core/Core_c.stub', 'ResourceBundle' => 'intl/intl.stub', 'ReturnTypeWillChange' => 'Core/Core_c.stub', 'RoundingMode' => 'standard/standard_10.stub', 'RuntimeException' => 'SPL/SPL.stub', 'SNMP' => 'snmp/snmp.stub', 'SNMPException' => 'snmp/snmp.stub', 'SQLite3' => 'sqlite3/sqlite3.stub', 'SQLite3Exception' => 'sqlite3/sqlite3.stub', 'SQLite3Result' => 'sqlite3/sqlite3.stub', 'SQLite3Stmt' => 'sqlite3/sqlite3.stub', 'SQLiteDatabase' => 'SQLite/SQLite.stub', 'SQLiteException' => 'SQLite/SQLite.stub', 'SQLiteResult' => 'SQLite/SQLite.stub', 'SQLiteUnbuffered' => 'SQLite/SQLite.stub', 'SVM' => 'svm/SVM.stub', 'SVMModel' => 'svm/SVMModel.stub', 'SWFAction' => 'ming/ming.stub', 'SWFBitmap' => 'ming/ming.stub', 'SWFButton' => 'ming/ming.stub', 'SWFDisplayItem' => 'ming/ming.stub', 'SWFFill' => 'ming/ming.stub', 'SWFFont' => 'ming/ming.stub', 'SWFFontChar' => 'ming/ming.stub', 'SWFGradient' => 'ming/ming.stub', 'SWFMorph' => 'ming/ming.stub', 'SWFMovie' => 'ming/ming.stub', 'SWFShape' => 'ming/ming.stub', 'SWFSound' => 'ming/ming.stub', 'SWFSoundInstance' => 'ming/ming.stub', 'SWFSprite' => 'ming/ming.stub', 'SWFText' => 'ming/ming.stub', 'SWFTextField' => 'ming/ming.stub', 'SWFVideoStream' => 'ming/ming.stub', 'Saxon\\SaxonProcessor' => 'SaxonC/SaxonC.stub', 'Saxon\\SchemaValidator' => 'SaxonC/SaxonC.stub', 'Saxon\\XPathProcessor' => 'SaxonC/SaxonC.stub', 'Saxon\\XQueryProcessor' => 'SaxonC/SaxonC.stub', 'Saxon\\XdmAtomicValue' => 'SaxonC/SaxonC.stub', 'Saxon\\XdmItem' => 'SaxonC/SaxonC.stub', 'Saxon\\XdmNode' => 'SaxonC/SaxonC.stub', 'Saxon\\XdmValue' => 'SaxonC/SaxonC.stub', 'Saxon\\Xslt30Processor' => 'SaxonC/SaxonC.stub', 'Saxon\\XsltProcessor' => 'SaxonC/SaxonC.stub', 'SeekableIterator' => 'SPL/SPL.stub', 'SensitiveParameter' => 'Core/Core_c.stub', 'SensitiveParameterValue' => 'Core/Core_c.stub', 'Serializable' => 'Core/Core_c.stub', 'SessionHandler' => 'session/SessionHandler.stub', 'SessionHandlerInterface' => 'session/SessionHandler.stub', 'SessionIdInterface' => 'session/SessionHandler.stub', 'SessionUpdateTimestampHandlerInterface' => 'session/SessionHandler.stub', 'Shmop' => 'shmop/shmop.stub', 'SimdJsonException' => 'simdjson/simdjson.stub', 'SimdJsonValueError' => 'simdjson/simdjson.stub', 'SimpleKafkaClient' => 'simple_kafka_client/SimpleKafkaClient.stub', 'SimpleKafkaClient\\Configuration' => 'simple_kafka_client/SimpleKafkaClient/Configuration.stub', 'SimpleKafkaClient\\Consumer' => 'simple_kafka_client/SimpleKafkaClient/Consumer.stub', 'SimpleKafkaClient\\ConsumerTopic' => 'simple_kafka_client/SimpleKafkaClient/Topic.stub', 'SimpleKafkaClient\\Exception' => 'simple_kafka_client/SimpleKafkaClient/Exception.stub', 'SimpleKafkaClient\\KafkaErrorException' => 'simple_kafka_client/SimpleKafkaClient/KafkaErrorException.stub', 'SimpleKafkaClient\\Message' => 'simple_kafka_client/SimpleKafkaClient/Message.stub', 'SimpleKafkaClient\\Metadata' => 'simple_kafka_client/SimpleKafkaClient/Metadata.stub', 'SimpleKafkaClient\\Metadata\\Broker' => 'simple_kafka_client/SimpleKafkaClient/Metadata/Broker.stub', 'SimpleKafkaClient\\Metadata\\Collection' => 'simple_kafka_client/SimpleKafkaClient/Metadata/Collection.stub', 'SimpleKafkaClient\\Metadata\\Partition' => 'simple_kafka_client/SimpleKafkaClient/Metadata/Partition.stub', 'SimpleKafkaClient\\Metadata\\Topic' => 'simple_kafka_client/SimpleKafkaClient/Metadata/Topic.stub', 'SimpleKafkaClient\\Producer' => 'simple_kafka_client/SimpleKafkaClient/Producer.stub', 'SimpleKafkaClient\\ProducerTopic' => 'simple_kafka_client/SimpleKafkaClient/Topic.stub', 'SimpleKafkaClient\\Topic' => 'simple_kafka_client/SimpleKafkaClient/Topic.stub', 'SimpleKafkaClient\\TopicPartition' => 'simple_kafka_client/SimpleKafkaClient/TopicPartition.stub', 'SimpleXMLElement' => 'SimpleXML/SimpleXML.stub', 'SimpleXMLIterator' => 'SimpleXML/SimpleXML.stub', 'SoapClient' => 'soap/soap.stub', 'SoapFault' => 'soap/soap.stub', 'SoapHeader' => 'soap/soap.stub', 'SoapParam' => 'soap/soap.stub', 'SoapServer' => 'soap/soap.stub', 'SoapVar' => 'soap/soap.stub', 'Soap\\Sdl' => 'soap/soap_n.stub', 'Soap\\Url' => 'soap/soap_n.stub', 'Socket' => 'sockets/sockets.stub', 'SodiumException' => 'sodium/sodium.stub', 'SolrClient' => 'solr/SolrClient.stub', 'SolrClientException' => 'solr/Exceptions/SolrClientException.stub', 'SolrCollapseFunction' => 'solr/Queries/SolrCollapseFunction.stub', 'SolrDisMaxQuery' => 'solr/Queries/SolrDisMaxQuery.stub', 'SolrDocument' => 'solr/Documents/SolrDocument.stub', 'SolrDocumentField' => 'solr/Documents/SolrDocumentField.stub', 'SolrException' => 'solr/Exceptions/SolrException.stub', 'SolrGenericResponse' => 'solr/Responses/SolrGenericResponse.stub', 'SolrIllegalArgumentException' => 'solr/Exceptions/SolrIllegalArgumentException.stub', 'SolrIllegalOperationException' => 'solr/Exceptions/SolrIllegalOperationException.stub', 'SolrInputDocument' => 'solr/Documents/SolrInputDocument.stub', 'SolrMissingMandatoryParameterException' => 'solr/Exceptions/SolrMissingMandatoryParameterException.stub', 'SolrModifiableParams' => 'solr/Queries/SolrModifiableParams.stub', 'SolrObject' => 'solr/Utils/SolrObject.stub', 'SolrParams' => 'solr/Queries/SolrParams.stub', 'SolrPingResponse' => 'solr/Responses/SolrPingResponse.stub', 'SolrQuery' => 'solr/Queries/SolrQuery.stub', 'SolrQueryResponse' => 'solr/Responses/SolrQueryResponse.stub', 'SolrResponse' => 'solr/Responses/SolrResponse.stub', 'SolrServerException' => 'solr/Exceptions/SolrServerException.stub', 'SolrUpdateResponse' => 'solr/Responses/SolrUpdateResponse.stub', 'SolrUtils' => 'solr/Utils/SolrUtils.stub', 'SplBool' => 'SplType/SplType.stub', 'SplDoublyLinkedList' => 'SPL/SPL_c1.stub', 'SplEnum' => 'SplType/SplType.stub', 'SplFileInfo' => 'SPL/SPL_c1.stub', 'SplFileObject' => 'SPL/SPL_c1.stub', 'SplFixedArray' => 'SPL/SPL_c1.stub', 'SplFloat' => 'SplType/SplType.stub', 'SplHeap' => 'SPL/SPL_c1.stub', 'SplInt' => 'SplType/SplType.stub', 'SplMaxHeap' => 'SPL/SPL_c1.stub', 'SplMinHeap' => 'SPL/SPL_c1.stub', 'SplObjectStorage' => 'SPL/SPL_c1.stub', 'SplObserver' => 'SPL/SPL_c1.stub', 'SplPriorityQueue' => 'SPL/SPL_c1.stub', 'SplQueue' => 'SPL/SPL_c1.stub', 'SplStack' => 'SPL/SPL_c1.stub', 'SplString' => 'SplType/SplType.stub', 'SplSubject' => 'SPL/SPL_c1.stub', 'SplTempFileObject' => 'SPL/SPL_c1.stub', 'SplType' => 'SplType/SplType.stub', 'Spoofchecker' => 'intl/intl.stub', 'Stomp' => 'stomp/stomp.stub', 'StompException' => 'stomp/stomp.stub', 'StompFrame' => 'stomp/stomp.stub', 'StreamBucket' => 'standard/standard_0.stub', 'Stringable' => 'Core/Core_c.stub', 'Svn' => 'svn/svn.stub', 'SvnNode' => 'svn/svn.stub', 'SvnWc' => 'svn/svn.stub', 'SvnWcSchedule' => 'svn/svn.stub', 'Swoole\\Atomic' => 'swoole/Swoole/Atomic.stub', 'Swoole\\Atomic\\Long' => 'swoole/Swoole/Atomic/Long.stub', 'Swoole\\Client' => 'swoole/Swoole/Client.stub', 'Swoole\\Client\\Exception' => 'swoole/Swoole/Client/Exception.stub', 'Swoole\\Connection\\Iterator' => 'swoole/Swoole/Connection/Iterator.stub', 'Swoole\\Coroutine' => 'swoole/Swoole/Coroutine.stub', 'Swoole\\Coroutine\\Channel' => 'swoole/Swoole/Coroutine/Channel.stub', 'Swoole\\Coroutine\\Client' => 'swoole/Swoole/Coroutine/Client.stub', 'Swoole\\Coroutine\\Context' => 'swoole/Swoole/Coroutine/Context.stub', 'Swoole\\Coroutine\\Curl\\Exception' => 'swoole/Swoole/Coroutine/Curl/Exception.stub', 'Swoole\\Coroutine\\Http2\\Client' => 'swoole/Swoole/Coroutine/Http2/Client.stub', 'Swoole\\Coroutine\\Http2\\Client\\Exception' => 'swoole/Swoole/Coroutine/Http2/Client/Exception.stub', 'Swoole\\Coroutine\\Http\\Client' => 'swoole/Swoole/Coroutine/Http/Client.stub', 'Swoole\\Coroutine\\Http\\Client\\Exception' => 'swoole/Swoole/Coroutine/Http/Client/Exception.stub', 'Swoole\\Coroutine\\Http\\Server' => 'swoole/Swoole/Coroutine/Http/Server.stub', 'Swoole\\Coroutine\\Iterator' => 'swoole/Swoole/Coroutine/Iterator.stub', 'Swoole\\Coroutine\\MySQL' => 'swoole/Swoole/Coroutine/MySQL.stub', 'Swoole\\Coroutine\\MySQL\\Exception' => 'swoole/Swoole/Coroutine/MySQL/Exception.stub', 'Swoole\\Coroutine\\MySQL\\Statement' => 'swoole/Swoole/Coroutine/MySQL/Statement.stub', 'Swoole\\Coroutine\\Redis' => 'swoole/Swoole/Coroutine/Redis.stub', 'Swoole\\Coroutine\\Scheduler' => 'swoole/Swoole/Coroutine/Scheduler.stub', 'Swoole\\Coroutine\\Socket' => 'swoole/Swoole/Coroutine/Socket.stub', 'Swoole\\Coroutine\\Socket\\Exception' => 'swoole/Swoole/Coroutine/Socket/Exception.stub', 'Swoole\\Coroutine\\System' => 'swoole/Swoole/Coroutine/System.stub', 'Swoole\\Error' => 'swoole/Swoole/Error.stub', 'Swoole\\Event' => 'swoole/Swoole/Event.stub', 'Swoole\\Exception' => 'swoole/Swoole/Exception.stub', 'Swoole\\ExitException' => 'swoole/Swoole/ExitException.stub', 'Swoole\\Http2\\Request' => 'swoole/Swoole/Http2/Request.stub', 'Swoole\\Http2\\Response' => 'swoole/Swoole/Http2/Response.stub', 'Swoole\\Http\\Request' => 'swoole/Swoole/Http/Request.stub', 'Swoole\\Http\\Response' => 'swoole/Swoole/Http/Response.stub', 'Swoole\\Http\\Server' => 'swoole/Swoole/Http/Server.stub', 'Swoole\\Lock' => 'swoole/Swoole/Lock.stub', 'Swoole\\Process' => 'swoole/Swoole/Process.stub', 'Swoole\\Process\\Pool' => 'swoole/Swoole/Process/Pool.stub', 'Swoole\\Redis\\Server' => 'swoole/Swoole/Redis/Server.stub', 'Swoole\\Runtime' => 'swoole/Swoole/Runtime.stub', 'Swoole\\Server' => 'swoole/Swoole/Server.stub', 'Swoole\\Server\\Event' => 'swoole/Swoole/Server/Event.stub', 'Swoole\\Server\\Packet' => 'swoole/Swoole/Server/Packet.stub', 'Swoole\\Server\\PipeMessage' => 'swoole/Swoole/Server/PipeMessage.stub', 'Swoole\\Server\\Port' => 'swoole/Swoole/Server/Port.stub', 'Swoole\\Server\\StatusInfo' => 'swoole/Swoole/Server/StatusInfo.stub', 'Swoole\\Server\\Task' => 'swoole/Swoole/Server/Task.stub', 'Swoole\\Server\\TaskResult' => 'swoole/Swoole/Server/TaskResult.stub', 'Swoole\\Table' => 'swoole/Swoole/Table.stub', 'Swoole\\Timer' => 'swoole/Swoole/Timer.stub', 'Swoole\\Timer\\Iterator' => 'swoole/Swoole/Timer/Iterator.stub', 'Swoole\\WebSocket\\CloseFrame' => 'swoole/Swoole/WebSocket/CloseFrame.stub', 'Swoole\\WebSocket\\Frame' => 'swoole/Swoole/WebSocket/Frame.stub', 'Swoole\\WebSocket\\Server' => 'swoole/Swoole/WebSocket/Server.stub', 'SyncEvent' => 'sync/sync.stub', 'SyncMutex' => 'sync/sync.stub', 'SyncReaderWriter' => 'sync/sync.stub', 'SyncSemaphore' => 'sync/sync.stub', 'SyncSharedMemory' => 'sync/sync.stub', 'SysvMessageQueue' => 'sysvmsg/sysvmsg.stub', 'SysvSemaphore' => 'sysvsem/sysvsem.stub', 'SysvSharedMemory' => 'sysvshm/sysvshm.stub', 'Thread' => 'pthreads/pthreads.stub', 'Threaded' => 'pthreads/pthreads.stub', 'Throwable' => 'Core/Core_c.stub', 'Transliterator' => 'intl/intl.stub', 'Traversable' => 'Core/Core_c.stub', 'TypeError' => 'Core/Core_c.stub', 'UConverter' => 'intl/intl.stub', 'UV' => 'uv/UV.stub', 'UVAddrinfo' => 'uv/UV.stub', 'UVAsync' => 'uv/UV.stub', 'UVCheck' => 'uv/UV.stub', 'UVFs' => 'uv/UV.stub', 'UVFsEvent' => 'uv/UV.stub', 'UVFsPoll' => 'uv/UV.stub', 'UVIdle' => 'uv/UV.stub', 'UVLock' => 'uv/UV.stub', 'UVLoop' => 'uv/UV.stub', 'UVPipe' => 'uv/UV.stub', 'UVPoll' => 'uv/UV.stub', 'UVPrepare' => 'uv/UV.stub', 'UVProcess' => 'uv/UV.stub', 'UVSignal' => 'uv/UV.stub', 'UVSockAddr' => 'uv/UV.stub', 'UVSockAddrIPv4' => 'uv/UV.stub', 'UVSockAddrIPv6' => 'uv/UV.stub', 'UVStdio' => 'uv/UV.stub', 'UVStream' => 'uv/UV.stub', 'UVTcp' => 'uv/UV.stub', 'UVTimer' => 'uv/UV.stub', 'UVTty' => 'uv/UV.stub', 'UVUdp' => 'uv/UV.stub', 'UVWork' => 'uv/UV.stub', 'UnderflowException' => 'SPL/SPL.stub', 'UnexpectedValueException' => 'SPL/SPL.stub', 'UnhandledMatchError' => 'Core/Core_c.stub', 'UnitEnum' => 'Core/Core_c.stub', 'V8Js' => 'v8js/v8js.stub', 'V8JsMemoryLimitException' => 'v8js/v8js.stub', 'V8JsScriptException' => 'v8js/v8js.stub', 'V8JsTimeLimitException' => 'v8js/v8js.stub', 'VARIANT' => 'com_dotnet/com_dotnet.stub', 'ValueError' => 'Core/Core_c.stub', 'Volatile' => 'pthreads/pthreads.stub', 'Vtiful\\Kernel\\Excel' => 'xlswriter/xlswriter.stub', 'Vtiful\\Kernel\\Format' => 'xlswriter/xlswriter.stub', 'WeakMap' => 'Core/Core_c.stub', 'WeakReference' => 'Core/Core_c.stub', 'Worker' => 'pthreads/pthreads.stub', 'XMLParser' => 'xml/xml.stub', 'XMLReader' => 'xmlreader/xmlreader.stub', 'XMLWriter' => 'xmlwriter/xmlwriter.stub', 'XSLTProcessor' => 'xsl/xsl.stub', 'XXTEA' => 'xxtea/xxtea.stub', 'Yaf\\Action_Abstract' => 'yaf/yaf_namespace.stub', 'Yaf\\Application' => 'yaf/yaf_namespace.stub', 'Yaf\\Bootstrap_Abstract' => 'yaf/yaf_namespace.stub', 'Yaf\\Config\\Ini' => 'yaf/yaf_namespace.stub', 'Yaf\\Config\\Simple' => 'yaf/yaf_namespace.stub', 'Yaf\\Config_Abstract' => 'yaf/yaf_namespace.stub', 'Yaf\\Controller_Abstract' => 'yaf/yaf_namespace.stub', 'Yaf\\Dispatcher' => 'yaf/yaf_namespace.stub', 'Yaf\\Exception' => 'yaf/yaf_namespace.stub', 'Yaf\\Exception\\DispatchFailed' => 'yaf/yaf_namespace.stub', 'Yaf\\Exception\\LoadFailed' => 'yaf/yaf_namespace.stub', 'Yaf\\Exception\\LoadFailed\\Action' => 'yaf/yaf_namespace.stub', 'Yaf\\Exception\\LoadFailed\\Controller' => 'yaf/yaf_namespace.stub', 'Yaf\\Exception\\LoadFailed\\Module' => 'yaf/yaf_namespace.stub', 'Yaf\\Exception\\LoadFailed\\View' => 'yaf/yaf_namespace.stub', 'Yaf\\Exception\\RouterFailed' => 'yaf/yaf_namespace.stub', 'Yaf\\Exception\\StartupError' => 'yaf/yaf_namespace.stub', 'Yaf\\Exception\\TypeError' => 'yaf/yaf_namespace.stub', 'Yaf\\Loader' => 'yaf/yaf_namespace.stub', 'Yaf\\Plugin_Abstract' => 'yaf/yaf_namespace.stub', 'Yaf\\Registry' => 'yaf/yaf_namespace.stub', 'Yaf\\Request\\Http' => 'yaf/yaf_namespace.stub', 'Yaf\\Request\\Simple' => 'yaf/yaf_namespace.stub', 'Yaf\\Request_Abstract' => 'yaf/yaf_namespace.stub', 'Yaf\\Response\\Cli' => 'yaf/yaf_namespace.stub', 'Yaf\\Response\\Http' => 'yaf/yaf_namespace.stub', 'Yaf\\Response_Abstract' => 'yaf/yaf_namespace.stub', 'Yaf\\Route\\Map' => 'yaf/yaf_namespace.stub', 'Yaf\\Route\\Regex' => 'yaf/yaf_namespace.stub', 'Yaf\\Route\\Rewrite' => 'yaf/yaf_namespace.stub', 'Yaf\\Route\\Simple' => 'yaf/yaf_namespace.stub', 'Yaf\\Route\\Supervar' => 'yaf/yaf_namespace.stub', 'Yaf\\Route_Interface' => 'yaf/yaf_namespace.stub', 'Yaf\\Route_Static' => 'yaf/yaf_namespace.stub', 'Yaf\\Router' => 'yaf/yaf_namespace.stub', 'Yaf\\Session' => 'yaf/yaf_namespace.stub', 'Yaf\\View\\Simple' => 'yaf/yaf_namespace.stub', 'Yaf\\View_Interface' => 'yaf/yaf_namespace.stub', 'Yaf_Action_Abstract' => 'yaf/yaf.stub', 'Yaf_Application' => 'yaf/yaf.stub', 'Yaf_Bootstrap_Abstract' => 'yaf/yaf.stub', 'Yaf_Config_Abstract' => 'yaf/yaf.stub', 'Yaf_Config_Ini' => 'yaf/yaf.stub', 'Yaf_Config_Simple' => 'yaf/yaf.stub', 'Yaf_Controller_Abstract' => 'yaf/yaf.stub', 'Yaf_Dispatcher' => 'yaf/yaf.stub', 'Yaf_Exception' => 'yaf/yaf.stub', 'Yaf_Exception_DispatchFailed' => 'yaf/yaf.stub', 'Yaf_Exception_LoadFailed' => 'yaf/yaf.stub', 'Yaf_Exception_LoadFailed_Action' => 'yaf/yaf.stub', 'Yaf_Exception_LoadFailed_Controller' => 'yaf/yaf.stub', 'Yaf_Exception_LoadFailed_Module' => 'yaf/yaf.stub', 'Yaf_Exception_LoadFailed_View' => 'yaf/yaf.stub', 'Yaf_Exception_RouterFailed' => 'yaf/yaf.stub', 'Yaf_Exception_StartupError' => 'yaf/yaf.stub', 'Yaf_Exception_TypeError' => 'yaf/yaf.stub', 'Yaf_Loader' => 'yaf/yaf.stub', 'Yaf_Plugin_Abstract' => 'yaf/yaf.stub', 'Yaf_Registry' => 'yaf/yaf.stub', 'Yaf_Request_Abstract' => 'yaf/yaf.stub', 'Yaf_Request_Http' => 'yaf/yaf.stub', 'Yaf_Request_Simple' => 'yaf/yaf.stub', 'Yaf_Response_Abstract' => 'yaf/yaf.stub', 'Yaf_Response_Cli' => 'yaf/yaf.stub', 'Yaf_Response_Http' => 'yaf/yaf.stub', 'Yaf_Route_Interface' => 'yaf/yaf.stub', 'Yaf_Route_Map' => 'yaf/yaf.stub', 'Yaf_Route_Regex' => 'yaf/yaf.stub', 'Yaf_Route_Rewrite' => 'yaf/yaf.stub', 'Yaf_Route_Simple' => 'yaf/yaf.stub', 'Yaf_Route_Static' => 'yaf/yaf.stub', 'Yaf_Route_Supervar' => 'yaf/yaf.stub', 'Yaf_Router' => 'yaf/yaf.stub', 'Yaf_Session' => 'yaf/yaf.stub', 'Yaf_View_Interface' => 'yaf/yaf.stub', 'Yaf_View_Simple' => 'yaf/yaf.stub', 'Yar_Client' => 'yar/yar.stub', 'Yar_Client_Exception' => 'yar/yar.stub', 'Yar_Client_Packager_Exception' => 'yar/yar.stub', 'Yar_Client_Protocol_Exception' => 'yar/yar.stub', 'Yar_Client_Transport_Exception' => 'yar/yar.stub', 'Yar_Concurrent_Client' => 'yar/yar.stub', 'Yar_Server' => 'yar/yar.stub', 'Yar_Server_Exception' => 'yar/yar.stub', 'Yar_Server_Output_Exception' => 'yar/yar.stub', 'Yar_Server_Packager_Exception' => 'yar/yar.stub', 'Yar_Server_Protocol_Exception' => 'yar/yar.stub', 'Yar_Server_Request_Exception' => 'yar/yar.stub', 'ZMQ' => 'zmq/zmq.stub', 'ZMQContext' => 'zmq/zmq.stub', 'ZMQContextException' => 'zmq/zmq.stub', 'ZMQDevice' => 'zmq/zmq.stub', 'ZMQDeviceException' => 'zmq/zmq.stub', 'ZMQException' => 'zmq/zmq.stub', 'ZMQPoll' => 'zmq/zmq.stub', 'ZMQPollException' => 'zmq/zmq.stub', 'ZMQSocket' => 'zmq/zmq.stub', 'ZMQSocketException' => 'zmq/zmq.stub', 'ZendAPI_Job' => 'zend/zend.stub', 'ZendAPI_Queue' => 'zend/zend.stub', 'ZipArchive' => 'zip/zip.stub', 'Zookeeper' => 'zookeeper/zookeeper.stub', 'ZookeeperAuthenticationException' => 'zookeeper/zookeeper.stub', 'ZookeeperConnectionException' => 'zookeeper/zookeeper.stub', 'ZookeeperException' => 'zookeeper/zookeeper.stub', 'ZookeeperMarshallingException' => 'zookeeper/zookeeper.stub', 'ZookeeperNoNodeException' => 'zookeeper/zookeeper.stub', 'ZookeeperOperationTimeoutException' => 'zookeeper/zookeeper.stub', 'ZookeeperSessionException' => 'zookeeper/zookeeper.stub', '__PHP_Incomplete_Class' => 'standard/standard_0.stub', '___PHPSTORM_HELPERS\\PS_UNRESERVE_PREFIX_static' => 'standard/_types.stub', '___PHPSTORM_HELPERS\\PS_UNRESERVE_PREFIX_this' => 'standard/_types.stub', '___PHPSTORM_HELPERS\\object' => 'standard/_types.stub', 'ast\\Metadata' => 'ast/ast.stub', 'ast\\Node' => 'ast/ast.stub', 'classObj' => 'mapscript/mapscript.stub', 'clusterObj' => 'mapscript/mapscript.stub', 'colorObj' => 'mapscript/mapscript.stub', 'com_exception' => 'com_dotnet/com_dotnet.stub', 'errorObj' => 'mapscript/mapscript.stub', 'ffmpeg_animated_gif' => 'ffmpeg/ffmpeg.stub', 'ffmpeg_frame' => 'ffmpeg/ffmpeg.stub', 'ffmpeg_movie' => 'ffmpeg/ffmpeg.stub', 'finfo' => 'fileinfo/fileinfo.stub', 'gnupg' => 'gnupg/gnupg.stub', 'gnupg_keylistiterator' => 'gnupg/gnupg.stub', 'gridObj' => 'mapscript/mapscript.stub', 'hashTableObj' => 'mapscript/mapscript.stub', 'http\\Client' => 'http/http3.stub', 'http\\Client\\Curl\\User' => 'http/http3.stub', 'http\\Client\\Request' => 'http/http3.stub', 'http\\Client\\Response' => 'http/http3.stub', 'http\\Cookie' => 'http/http3.stub', 'http\\Encoding\\Stream' => 'http/http3.stub', 'http\\Encoding\\Stream\\Debrotli' => 'http/http3.stub', 'http\\Encoding\\Stream\\Dechunk' => 'http/http3.stub', 'http\\Encoding\\Stream\\Deflate' => 'http/http3.stub', 'http\\Encoding\\Stream\\Enbrotli' => 'http/http3.stub', 'http\\Encoding\\Stream\\Inflate' => 'http/http3.stub', 'http\\Env' => 'http/http3.stub', 'http\\Env\\Request' => 'http/http3.stub', 'http\\Env\\Response' => 'http/http3.stub', 'http\\Env\\Url' => 'http/http3.stub', 'http\\Exception' => 'http/http3.stub', 'http\\Exception\\BadConversionException' => 'http/http3.stub', 'http\\Exception\\BadHeaderException' => 'http/http3.stub', 'http\\Exception\\BadMessageException' => 'http/http3.stub', 'http\\Exception\\BadMethodCallException' => 'http/http3.stub', 'http\\Exception\\BadQueryStringException' => 'http/http3.stub', 'http\\Exception\\BadUrlException' => 'http/http3.stub', 'http\\Exception\\InvalidArgumentException' => 'http/http3.stub', 'http\\Exception\\RuntimeException' => 'http/http3.stub', 'http\\Exception\\UnexpectedValueException' => 'http/http3.stub', 'http\\Header' => 'http/http3.stub', 'http\\Header\\Parser' => 'http/http3.stub', 'http\\Message' => 'http/http3.stub', 'http\\Message\\Body' => 'http/http3.stub', 'http\\Message\\Parser' => 'http/http3.stub', 'http\\Params' => 'http/http3.stub', 'http\\QueryString' => 'http/http3.stub', 'http\\Url' => 'http/http3.stub', 'imageObj' => 'mapscript/mapscript.stub', 'iterable' => 'Core/Core_c.stub', 'java' => 'zend/zend.stub', 'labelObj' => 'mapscript/mapscript.stub', 'labelcacheMemberObj' => 'mapscript/mapscript.stub', 'labelcacheObj' => 'mapscript/mapscript.stub', 'layerObj' => 'mapscript/mapscript.stub', 'legendObj' => 'mapscript/mapscript.stub', 'lineObj' => 'mapscript/mapscript.stub', 'mapObj' => 'mapscript/mapscript.stub', 'mysql_xdevapi\\BaseResult' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\Collection' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\CollectionAdd' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\CollectionFind' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\CollectionModify' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\CollectionRemove' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\ColumnResult' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\CrudOperationBindable' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\CrudOperationLimitable' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\CrudOperationSkippable' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\CrudOperationSortable' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\DatabaseObject' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\DocResult' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\Exception' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\Executable' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\ExecutionStatus' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\Expression' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\Result' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\RowResult' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\Schema' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\SchemaObject' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\Session' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\SqlStatement' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\SqlStatementResult' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\Statement' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\Table' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\TableDelete' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\TableInsert' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\TableSelect' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\TableUpdate' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\Warning' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\XSession' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysqli' => 'mysqli/mysqli.stub', 'mysqli_driver' => 'mysqli/mysqli.stub', 'mysqli_result' => 'mysqli/mysqli.stub', 'mysqli_sql_exception' => 'mysqli/mysqli.stub', 'mysqli_stmt' => 'mysqli/mysqli.stub', 'mysqli_warning' => 'mysqli/mysqli.stub', 'newrelic\\DistributedTracePayload' => 'newrelic/newrelic.stub', 'outputformatObj' => 'mapscript/mapscript.stub', 'parallel\\Channel' => 'parallel/parallel/Channel.stub', 'parallel\\Channel\\Error' => 'parallel/parallel/Channel/Error.stub', 'parallel\\Channel\\Error\\Closed' => 'parallel/parallel/Channel/Error/Closed.stub', 'parallel\\Channel\\Error\\Existence' => 'parallel/parallel/Channel/Error/Existence.stub', 'parallel\\Channel\\Error\\IllegalValue' => 'parallel/parallel/Channel/Error/IllegalValue.stub', 'parallel\\Error' => 'parallel/parallel/Error.stub', 'parallel\\Events' => 'parallel/parallel/Events.stub', 'parallel\\Events\\Error' => 'parallel/parallel/Events/Error.stub', 'parallel\\Events\\Error\\Existence' => 'parallel/parallel/Events/Error/Existence.stub', 'parallel\\Events\\Error\\Timeout' => 'parallel/parallel/Events/Error/Timeout.stub', 'parallel\\Events\\Event' => 'parallel/parallel/Events/Event.stub', 'parallel\\Events\\Event\\Error' => 'parallel/parallel/Events/Event/Error.stub', 'parallel\\Events\\Event\\Type' => 'parallel/parallel/Events/Event/Type.stub', 'parallel\\Events\\Input' => 'parallel/parallel/Events/Input.stub', 'parallel\\Events\\Input\\Error' => 'parallel/parallel/Events/Input/Error.stub', 'parallel\\Events\\Input\\Error\\Existence' => 'parallel/parallel/Events/Input/Error/Existence.stub', 'parallel\\Events\\Input\\Error\\IllegalValue' => 'parallel/parallel/Events/Input/Error/IllegalValue.stub', 'parallel\\Future' => 'parallel/parallel/Future.stub', 'parallel\\Future\\Error' => 'parallel/parallel/Future/Error.stub', 'parallel\\Future\\Error\\Cancelled' => 'parallel/parallel/Future/Error/Cancelled.stub', 'parallel\\Future\\Error\\Foreign' => 'parallel/parallel/Future/Error/Foreign.stub', 'parallel\\Future\\Error\\Killed' => 'parallel/parallel/Future/Error/Killed.stub', 'parallel\\Runtime' => 'parallel/parallel/Runtime.stub', 'parallel\\Runtime\\Error' => 'parallel/parallel/Runtime/Error.stub', 'parallel\\Runtime\\Error\\Bootstrap' => 'parallel/parallel/Runtime/Error/Bootstrap.stub', 'parallel\\Runtime\\Error\\Closed' => 'parallel/parallel/Runtime/Error/Closed.stub', 'parallel\\Runtime\\Error\\IllegalFunction' => 'parallel/parallel/Runtime/Error/IllegalFunction.stub', 'parallel\\Runtime\\Error\\IllegalInstruction' => 'parallel/parallel/Runtime/Error/IllegalInstruction.stub', 'parallel\\Runtime\\Error\\IllegalParameter' => 'parallel/parallel/Runtime/Error/IllegalParameter.stub', 'parallel\\Runtime\\Error\\IllegalReturn' => 'parallel/parallel/Runtime/Error/IllegalReturn.stub', 'parallel\\Runtime\\Error\\IllegalVariable' => 'parallel/parallel/Runtime/Error/IllegalVariable.stub', 'parallel\\Runtime\\Error\\Killed' => 'parallel/parallel/Runtime/Error/Killed.stub', 'parallel\\Runtime\\Object\\Unavailable' => 'parallel/parallel/Runtime/Object/Unavailable.stub', 'parallel\\Runtime\\Type\\Unavailable' => 'parallel/parallel/Runtime/Type/Unavailable.stub', 'parallel\\Sync' => 'parallel/parallel/Sync.stub', 'parallel\\Sync\\Error' => 'parallel/parallel/Sync/Error.stub', 'parallel\\Sync\\Error\\IllegalValue' => 'parallel/parallel/Sync/Error/IllegalValue.stub', 'php_user_filter' => 'standard/standard_0.stub', 'pointObj' => 'mapscript/mapscript.stub', 'pq\\COPY' => 'pq/pq.stub', 'pq\\Cancel' => 'pq/pq.stub', 'pq\\Connection' => 'pq/pq.stub', 'pq\\Converter' => 'pq/pq.stub', 'pq\\Cursor' => 'pq/pq.stub', 'pq\\DateTime' => 'pq/pq.stub', 'pq\\Exception' => 'pq/pq.stub', 'pq\\Exception\\BadMethodCallException' => 'pq/pq.stub', 'pq\\Exception\\DomainException' => 'pq/pq.stub', 'pq\\Exception\\InvalidArgumentException' => 'pq/pq.stub', 'pq\\Exception\\RuntimeException' => 'pq/pq.stub', 'pq\\LOB' => 'pq/pq.stub', 'pq\\Result' => 'pq/pq.stub', 'pq\\Statement' => 'pq/pq.stub', 'pq\\Transaction' => 'pq/pq.stub', 'pq\\Types' => 'pq/pq.stub', 'projectionObj' => 'mapscript/mapscript.stub', 'querymapObj' => 'mapscript/mapscript.stub', 'rectObj' => 'mapscript/mapscript.stub', 'referenceMapObj' => 'mapscript/mapscript.stub', 'resultObj' => 'mapscript/mapscript.stub', 'scalebarObj' => 'mapscript/mapscript.stub', 'shapeObj' => 'mapscript/mapscript.stub', 'shapefileObj' => 'mapscript/mapscript.stub', 'stdClass' => 'Core/Core_c.stub', 'styleObj' => 'mapscript/mapscript.stub', 'symbolObj' => 'mapscript/mapscript.stub', 'tidy' => 'tidy/tidy.stub', 'tidyNode' => 'tidy/tidy.stub', 'webObj' => 'mapscript/mapscript.stub'); const FUNCTIONS = array('Brotli\\compress' => 'brotli/brotli.stub', 'Brotli\\compress_add' => 'brotli/brotli.stub', 'Brotli\\compress_init' => 'brotli/brotli.stub', 'Brotli\\uncompress' => 'brotli/brotli.stub', 'Brotli\\uncompress_add' => 'brotli/brotli.stub', 'Brotli\\uncompress_init' => 'brotli/brotli.stub', 'Dom\\import_simplexml' => 'dom/dom_n.stub', 'GEOSLineMerge' => 'geos/geos.stub', 'GEOSPolygonize' => 'geos/geos.stub', 'GEOSRelateMatch' => 'geos/geos.stub', 'GEOSSharedPaths' => 'geos/geos.stub', 'GEOSVersion' => 'geos/geos.stub', 'MongoDB\\BSON\\fromJSON' => 'mongodb/BSON/functions.stub', 'MongoDB\\BSON\\fromPHP' => 'mongodb/BSON/functions.stub', 'MongoDB\\BSON\\toCanonicalExtendedJSON' => 'mongodb/BSON/functions.stub', 'MongoDB\\BSON\\toJSON' => 'mongodb/BSON/functions.stub', 'MongoDB\\BSON\\toPHP' => 'mongodb/BSON/functions.stub', 'MongoDB\\BSON\\toRelaxedExtendedJSON' => 'mongodb/BSON/functions.stub', 'MongoDB\\Driver\\Monitoring\\addSubscriber' => 'mongodb/Monitoring/functions.stub', 'MongoDB\\Driver\\Monitoring\\removeSubscriber' => 'mongodb/Monitoring/functions.stub', 'OpenTelemetry\\Instrumentation\\hook' => 'opentelemetry/opentelemetry.stub', 'PDF_activate_item' => 'pdflib/PDFlib.stub', 'PDF_add_launchlink' => 'pdflib/PDFlib.stub', 'PDF_add_locallink' => 'pdflib/PDFlib.stub', 'PDF_add_nameddest' => 'pdflib/PDFlib.stub', 'PDF_add_note' => 'pdflib/PDFlib.stub', 'PDF_add_pdflink' => 'pdflib/PDFlib.stub', 'PDF_add_table_cell' => 'pdflib/PDFlib.stub', 'PDF_add_textflow' => 'pdflib/PDFlib.stub', 'PDF_add_thumbnail' => 'pdflib/PDFlib.stub', 'PDF_add_weblink' => 'pdflib/PDFlib.stub', 'PDF_arc' => 'pdflib/PDFlib.stub', 'PDF_arcn' => 'pdflib/PDFlib.stub', 'PDF_attach_file' => 'pdflib/PDFlib.stub', 'PDF_begin_document' => 'pdflib/PDFlib.stub', 'PDF_begin_font' => 'pdflib/PDFlib.stub', 'PDF_begin_glyph' => 'pdflib/PDFlib.stub', 'PDF_begin_item' => 'pdflib/PDFlib.stub', 'PDF_begin_layer' => 'pdflib/PDFlib.stub', 'PDF_begin_page' => 'pdflib/PDFlib.stub', 'PDF_begin_page_ext' => 'pdflib/PDFlib.stub', 'PDF_begin_pattern' => 'pdflib/PDFlib.stub', 'PDF_begin_template' => 'pdflib/PDFlib.stub', 'PDF_begin_template_ext' => 'pdflib/PDFlib.stub', 'PDF_circle' => 'pdflib/PDFlib.stub', 'PDF_clip' => 'pdflib/PDFlib.stub', 'PDF_close' => 'pdflib/PDFlib.stub', 'PDF_close_image' => 'pdflib/PDFlib.stub', 'PDF_close_pdi' => 'pdflib/PDFlib.stub', 'PDF_close_pdi_document' => 'pdflib/PDFlib.stub', 'PDF_close_pdi_page' => 'pdflib/PDFlib.stub', 'PDF_closepath' => 'pdflib/PDFlib.stub', 'PDF_closepath_fill_stroke' => 'pdflib/PDFlib.stub', 'PDF_closepath_stroke' => 'pdflib/PDFlib.stub', 'PDF_concat' => 'pdflib/PDFlib.stub', 'PDF_continue_text' => 'pdflib/PDFlib.stub', 'PDF_create_3dview' => 'pdflib/PDFlib.stub', 'PDF_create_action' => 'pdflib/PDFlib.stub', 'PDF_create_annotation' => 'pdflib/PDFlib.stub', 'PDF_create_bookmark' => 'pdflib/PDFlib.stub', 'PDF_create_field' => 'pdflib/PDFlib.stub', 'PDF_create_fieldgroup' => 'pdflib/PDFlib.stub', 'PDF_create_gstate' => 'pdflib/PDFlib.stub', 'PDF_create_pvf' => 'pdflib/PDFlib.stub', 'PDF_create_textflow' => 'pdflib/PDFlib.stub', 'PDF_curveto' => 'pdflib/PDFlib.stub', 'PDF_define_layer' => 'pdflib/PDFlib.stub', 'PDF_delete' => 'pdflib/PDFlib.stub', 'PDF_delete_pvf' => 'pdflib/PDFlib.stub', 'PDF_delete_table' => 'pdflib/PDFlib.stub', 'PDF_delete_textflow' => 'pdflib/PDFlib.stub', 'PDF_encoding_set_char' => 'pdflib/PDFlib.stub', 'PDF_end_document' => 'pdflib/PDFlib.stub', 'PDF_end_font' => 'pdflib/PDFlib.stub', 'PDF_end_glyph' => 'pdflib/PDFlib.stub', 'PDF_end_item' => 'pdflib/PDFlib.stub', 'PDF_end_layer' => 'pdflib/PDFlib.stub', 'PDF_end_page' => 'pdflib/PDFlib.stub', 'PDF_end_page_ext' => 'pdflib/PDFlib.stub', 'PDF_end_pattern' => 'pdflib/PDFlib.stub', 'PDF_end_template' => 'pdflib/PDFlib.stub', 'PDF_endpath' => 'pdflib/PDFlib.stub', 'PDF_fill' => 'pdflib/PDFlib.stub', 'PDF_fill_imageblock' => 'pdflib/PDFlib.stub', 'PDF_fill_pdfblock' => 'pdflib/PDFlib.stub', 'PDF_fill_stroke' => 'pdflib/PDFlib.stub', 'PDF_fill_textblock' => 'pdflib/PDFlib.stub', 'PDF_findfont' => 'pdflib/PDFlib.stub', 'PDF_fit_image' => 'pdflib/PDFlib.stub', 'PDF_fit_pdi_page' => 'pdflib/PDFlib.stub', 'PDF_fit_table' => 'pdflib/PDFlib.stub', 'PDF_fit_textflow' => 'pdflib/PDFlib.stub', 'PDF_fit_textline' => 'pdflib/PDFlib.stub', 'PDF_get_apiname' => 'pdflib/PDFlib.stub', 'PDF_get_buffer' => 'pdflib/PDFlib.stub', 'PDF_get_errmsg' => 'pdflib/PDFlib.stub', 'PDF_get_errnum' => 'pdflib/PDFlib.stub', 'PDF_get_majorversion' => 'pdflib/PDFlib.stub', 'PDF_get_minorversion' => 'pdflib/PDFlib.stub', 'PDF_get_option' => 'pdflib/PDFlib.stub', 'PDF_get_parameter' => 'pdflib/PDFlib.stub', 'PDF_get_pdi_parameter' => 'pdflib/PDFlib.stub', 'PDF_get_pdi_value' => 'pdflib/PDFlib.stub', 'PDF_get_string' => 'pdflib/PDFlib.stub', 'PDF_get_value' => 'pdflib/PDFlib.stub', 'PDF_info_font' => 'pdflib/PDFlib.stub', 'PDF_info_graphics' => 'pdflib/PDFlib.stub', 'PDF_info_image' => 'pdflib/PDFlib.stub', 'PDF_info_matchbox' => 'pdflib/PDFlib.stub', 'PDF_info_path' => 'pdflib/PDFlib.stub', 'PDF_info_pdi_page' => 'pdflib/PDFlib.stub', 'PDF_info_pvf' => 'pdflib/PDFlib.stub', 'PDF_info_table' => 'pdflib/PDFlib.stub', 'PDF_info_textflow' => 'pdflib/PDFlib.stub', 'PDF_info_textline' => 'pdflib/PDFlib.stub', 'PDF_initgraphics' => 'pdflib/PDFlib.stub', 'PDF_lineto' => 'pdflib/PDFlib.stub', 'PDF_load_3ddata' => 'pdflib/PDFlib.stub', 'PDF_load_font' => 'pdflib/PDFlib.stub', 'PDF_load_iccprofile' => 'pdflib/PDFlib.stub', 'PDF_load_image' => 'pdflib/PDFlib.stub', 'PDF_makespotcolor' => 'pdflib/PDFlib.stub', 'PDF_moveto' => 'pdflib/PDFlib.stub', 'PDF_new' => 'pdflib/PDFlib.stub', 'PDF_open_ccitt' => 'pdflib/PDFlib.stub', 'PDF_open_file' => 'pdflib/PDFlib.stub', 'PDF_open_image' => 'pdflib/PDFlib.stub', 'PDF_open_image_file' => 'pdflib/PDFlib.stub', 'PDF_open_memory_image' => 'pdflib/PDFlib.stub', 'PDF_open_pdi' => 'pdflib/PDFlib.stub', 'PDF_open_pdi_document' => 'pdflib/PDFlib.stub', 'PDF_open_pdi_page' => 'pdflib/PDFlib.stub', 'PDF_pcos_get_number' => 'pdflib/PDFlib.stub', 'PDF_pcos_get_stream' => 'pdflib/PDFlib.stub', 'PDF_pcos_get_string' => 'pdflib/PDFlib.stub', 'PDF_place_image' => 'pdflib/PDFlib.stub', 'PDF_place_pdi_page' => 'pdflib/PDFlib.stub', 'PDF_process_pdi' => 'pdflib/PDFlib.stub', 'PDF_rect' => 'pdflib/PDFlib.stub', 'PDF_restore' => 'pdflib/PDFlib.stub', 'PDF_resume_page' => 'pdflib/PDFlib.stub', 'PDF_rotate' => 'pdflib/PDFlib.stub', 'PDF_save' => 'pdflib/PDFlib.stub', 'PDF_scale' => 'pdflib/PDFlib.stub', 'PDF_set_border_color' => 'pdflib/PDFlib.stub', 'PDF_set_border_dash' => 'pdflib/PDFlib.stub', 'PDF_set_border_style' => 'pdflib/PDFlib.stub', 'PDF_set_gstate' => 'pdflib/PDFlib.stub', 'PDF_set_info' => 'pdflib/PDFlib.stub', 'PDF_set_layer_dependency' => 'pdflib/PDFlib.stub', 'PDF_set_option' => 'pdflib/PDFlib.stub', 'PDF_set_parameter' => 'pdflib/PDFlib.stub', 'PDF_set_text_option' => 'pdflib/PDFlib.stub', 'PDF_set_text_pos' => 'pdflib/PDFlib.stub', 'PDF_set_value' => 'pdflib/PDFlib.stub', 'PDF_setcolor' => 'pdflib/PDFlib.stub', 'PDF_setdash' => 'pdflib/PDFlib.stub', 'PDF_setdashpattern' => 'pdflib/PDFlib.stub', 'PDF_setflat' => 'pdflib/PDFlib.stub', 'PDF_setfont' => 'pdflib/PDFlib.stub', 'PDF_setgray' => 'pdflib/PDFlib.stub', 'PDF_setgray_fill' => 'pdflib/PDFlib.stub', 'PDF_setgray_stroke' => 'pdflib/PDFlib.stub', 'PDF_setlinecap' => 'pdflib/PDFlib.stub', 'PDF_setlinejoin' => 'pdflib/PDFlib.stub', 'PDF_setlinewidth' => 'pdflib/PDFlib.stub', 'PDF_setmatrix' => 'pdflib/PDFlib.stub', 'PDF_setmiterlimit' => 'pdflib/PDFlib.stub', 'PDF_setrgbcolor' => 'pdflib/PDFlib.stub', 'PDF_setrgbcolor_fill' => 'pdflib/PDFlib.stub', 'PDF_setrgbcolor_stroke' => 'pdflib/PDFlib.stub', 'PDF_shading' => 'pdflib/PDFlib.stub', 'PDF_shading_pattern' => 'pdflib/PDFlib.stub', 'PDF_shfill' => 'pdflib/PDFlib.stub', 'PDF_show' => 'pdflib/PDFlib.stub', 'PDF_show_boxed' => 'pdflib/PDFlib.stub', 'PDF_show_xy' => 'pdflib/PDFlib.stub', 'PDF_skew' => 'pdflib/PDFlib.stub', 'PDF_stringwidth' => 'pdflib/PDFlib.stub', 'PDF_stroke' => 'pdflib/PDFlib.stub', 'PDF_suspend_page' => 'pdflib/PDFlib.stub', 'PDF_translate' => 'pdflib/PDFlib.stub', 'PDF_utf16_to_utf8' => 'pdflib/PDFlib.stub', 'PDF_utf32_to_utf16' => 'pdflib/PDFlib.stub', 'PDF_utf8_to_utf16' => 'pdflib/PDFlib.stub', 'PS_UNRESERVE_PREFIX___halt_compiler' => 'standard/_standard_manual.stub', 'PS_UNRESERVE_PREFIX_array' => 'standard/_types.stub', 'PS_UNRESERVE_PREFIX_die' => 'standard/_types.stub', 'PS_UNRESERVE_PREFIX_empty' => 'standard/_types.stub', 'PS_UNRESERVE_PREFIX_eval' => 'standard/_types.stub', 'PS_UNRESERVE_PREFIX_exit' => 'standard/_types.stub', 'PS_UNRESERVE_PREFIX_isset' => 'standard/_types.stub', 'PS_UNRESERVE_PREFIX_list' => 'standard/_types.stub', 'PS_UNRESERVE_PREFIX_unset' => 'standard/_types.stub', 'SQLSRV_PHPTYPE_STREAM' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_PHPTYPE_STRING' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_BINARY' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_CHAR' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_DECIMAL' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_NCHAR' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_NUMERIC' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_NVARCHAR' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_VARBINARY' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_VARCHAR' => 'sqlsrv/sqlsrv.stub', 'Sodium\\add' => 'libsodium/libsodium.stub', 'Sodium\\bin2hex' => 'libsodium/libsodium.stub', 'Sodium\\compare' => 'libsodium/libsodium.stub', 'Sodium\\crypto_aead_aes256gcm_decrypt' => 'libsodium/libsodium.stub', 'Sodium\\crypto_aead_aes256gcm_encrypt' => 'libsodium/libsodium.stub', 'Sodium\\crypto_aead_aes256gcm_is_available' => 'libsodium/libsodium.stub', 'Sodium\\crypto_aead_chacha20poly1305_decrypt' => 'libsodium/libsodium.stub', 'Sodium\\crypto_aead_chacha20poly1305_encrypt' => 'libsodium/libsodium.stub', 'Sodium\\crypto_auth' => 'libsodium/libsodium.stub', 'Sodium\\crypto_auth_verify' => 'libsodium/libsodium.stub', 'Sodium\\crypto_box' => 'libsodium/libsodium.stub', 'Sodium\\crypto_box_keypair' => 'libsodium/libsodium.stub', 'Sodium\\crypto_box_keypair_from_secretkey_and_publickey' => 'libsodium/libsodium.stub', 'Sodium\\crypto_box_open' => 'libsodium/libsodium.stub', 'Sodium\\crypto_box_publickey' => 'libsodium/libsodium.stub', 'Sodium\\crypto_box_publickey_from_secretkey' => 'libsodium/libsodium.stub', 'Sodium\\crypto_box_seal' => 'libsodium/libsodium.stub', 'Sodium\\crypto_box_seal_open' => 'libsodium/libsodium.stub', 'Sodium\\crypto_box_secretkey' => 'libsodium/libsodium.stub', 'Sodium\\crypto_box_seed_keypair' => 'libsodium/libsodium.stub', 'Sodium\\crypto_generichash' => 'libsodium/libsodium.stub', 'Sodium\\crypto_generichash_final' => 'libsodium/libsodium.stub', 'Sodium\\crypto_generichash_init' => 'libsodium/libsodium.stub', 'Sodium\\crypto_generichash_update' => 'libsodium/libsodium.stub', 'Sodium\\crypto_kx' => 'libsodium/libsodium.stub', 'Sodium\\crypto_pwhash' => 'libsodium/libsodium.stub', 'Sodium\\crypto_pwhash_scryptsalsa208sha256' => 'libsodium/libsodium.stub', 'Sodium\\crypto_pwhash_scryptsalsa208sha256_str' => 'libsodium/libsodium.stub', 'Sodium\\crypto_pwhash_scryptsalsa208sha256_str_verify' => 'libsodium/libsodium.stub', 'Sodium\\crypto_pwhash_str' => 'libsodium/libsodium.stub', 'Sodium\\crypto_pwhash_str_verify' => 'libsodium/libsodium.stub', 'Sodium\\crypto_scalarmult' => 'libsodium/libsodium.stub', 'Sodium\\crypto_scalarmult_base' => 'libsodium/libsodium.stub', 'Sodium\\crypto_secretbox' => 'libsodium/libsodium.stub', 'Sodium\\crypto_secretbox_open' => 'libsodium/libsodium.stub', 'Sodium\\crypto_shorthash' => 'libsodium/libsodium.stub', 'Sodium\\crypto_sign' => 'libsodium/libsodium.stub', 'Sodium\\crypto_sign_detached' => 'libsodium/libsodium.stub', 'Sodium\\crypto_sign_ed25519_pk_to_curve25519' => 'libsodium/libsodium.stub', 'Sodium\\crypto_sign_ed25519_sk_to_curve25519' => 'libsodium/libsodium.stub', 'Sodium\\crypto_sign_keypair' => 'libsodium/libsodium.stub', 'Sodium\\crypto_sign_keypair_from_secretkey_and_publickey' => 'libsodium/libsodium.stub', 'Sodium\\crypto_sign_open' => 'libsodium/libsodium.stub', 'Sodium\\crypto_sign_publickey' => 'libsodium/libsodium.stub', 'Sodium\\crypto_sign_publickey_from_secretkey' => 'libsodium/libsodium.stub', 'Sodium\\crypto_sign_secretkey' => 'libsodium/libsodium.stub', 'Sodium\\crypto_sign_seed_keypair' => 'libsodium/libsodium.stub', 'Sodium\\crypto_sign_verify_detached' => 'libsodium/libsodium.stub', 'Sodium\\crypto_stream' => 'libsodium/libsodium.stub', 'Sodium\\crypto_stream_xor' => 'libsodium/libsodium.stub', 'Sodium\\hex2bin' => 'libsodium/libsodium.stub', 'Sodium\\increment' => 'libsodium/libsodium.stub', 'Sodium\\library_version_major' => 'libsodium/libsodium.stub', 'Sodium\\library_version_minor' => 'libsodium/libsodium.stub', 'Sodium\\memcmp' => 'libsodium/libsodium.stub', 'Sodium\\memzero' => 'libsodium/libsodium.stub', 'Sodium\\randombytes_buf' => 'libsodium/libsodium.stub', 'Sodium\\randombytes_random16' => 'libsodium/libsodium.stub', 'Sodium\\randombytes_uniform' => 'libsodium/libsodium.stub', 'Sodium\\version_string' => 'libsodium/libsodium.stub', 'Zstd\\compress' => 'zstd/zstd.stub', 'Zstd\\compress_dict' => 'zstd/zstd.stub', 'Zstd\\uncompress' => 'zstd/zstd.stub', 'Zstd\\uncompress_dict' => 'zstd/zstd.stub', '_' => 'gettext/gettext.stub', 'abs' => 'standard/standard_3.stub', 'accelerator_set_status' => 'zend/zend.stub', 'acos' => 'standard/standard_3.stub', 'acosh' => 'standard/standard_3.stub', 'addcslashes' => 'standard/standard_1.stub', 'addslashes' => 'standard/standard_1.stub', 'apache_child_terminate' => 'apache/apache.stub', 'apache_get_modules' => 'apache/apache.stub', 'apache_get_version' => 'apache/apache.stub', 'apache_getenv' => 'apache/apache.stub', 'apache_lookup_uri' => 'apache/apache.stub', 'apache_note' => 'apache/apache.stub', 'apache_request_headers' => 'standard/standard_4.stub', 'apache_reset_timeout' => 'apache/apache.stub', 'apache_response_headers' => 'apache/apache.stub', 'apache_setenv' => 'apache/apache.stub', 'apc_add' => 'apcu/apcu.stub', 'apc_bin_dump' => 'apcu/apcu.stub', 'apc_bin_dumpfile' => 'apcu/apcu.stub', 'apc_bin_load' => 'apcu/apcu.stub', 'apc_bin_loadfile' => 'apcu/apcu.stub', 'apc_cache_info' => 'apcu/apcu.stub', 'apc_cas' => 'apcu/apcu.stub', 'apc_clear_cache' => 'apcu/apcu.stub', 'apc_compile_file' => 'apcu/apcu.stub', 'apc_dec' => 'apcu/apcu.stub', 'apc_define_constants' => 'apcu/apcu.stub', 'apc_delete' => 'apcu/apcu.stub', 'apc_delete_file' => 'apcu/apcu.stub', 'apc_exists' => 'apcu/apcu.stub', 'apc_fetch' => 'apcu/apcu.stub', 'apc_inc' => 'apcu/apcu.stub', 'apc_load_constants' => 'apcu/apcu.stub', 'apc_sma_info' => 'apcu/apcu.stub', 'apc_store' => 'apcu/apcu.stub', 'apcu_add' => 'apcu/apcu.stub', 'apcu_cache_info' => 'apcu/apcu.stub', 'apcu_cas' => 'apcu/apcu.stub', 'apcu_clear_cache' => 'apcu/apcu.stub', 'apcu_dec' => 'apcu/apcu.stub', 'apcu_delete' => 'apcu/apcu.stub', 'apcu_enabled' => 'apcu/apcu.stub', 'apcu_entry' => 'apcu/apcu.stub', 'apcu_exists' => 'apcu/apcu.stub', 'apcu_fetch' => 'apcu/apcu.stub', 'apcu_inc' => 'apcu/apcu.stub', 'apcu_key_info' => 'apcu/apcu.stub', 'apcu_sma_info' => 'apcu/apcu.stub', 'apcu_store' => 'apcu/apcu.stub', 'array_all' => 'standard/standard_10.stub', 'array_any' => 'standard/standard_10.stub', 'array_change_key_case' => 'standard/standard_9.stub', 'array_chunk' => 'standard/standard_9.stub', 'array_column' => 'standard/standard_9.stub', 'array_combine' => 'standard/standard_9.stub', 'array_count_values' => 'standard/standard_9.stub', 'array_diff' => 'standard/standard_9.stub', 'array_diff_assoc' => 'standard/standard_9.stub', 'array_diff_key' => 'standard/standard_9.stub', 'array_diff_uassoc' => 'standard/standard_9.stub', 'array_diff_ukey' => 'standard/standard_9.stub', 'array_fill' => 'standard/standard_8.stub', 'array_fill_keys' => 'standard/standard_8.stub', 'array_filter' => 'standard/standard_9.stub', 'array_find' => 'standard/standard_10.stub', 'array_find_key' => 'standard/standard_10.stub', 'array_flip' => 'standard/standard_9.stub', 'array_intersect' => 'standard/standard_9.stub', 'array_intersect_assoc' => 'standard/standard_9.stub', 'array_intersect_key' => 'standard/standard_9.stub', 'array_intersect_uassoc' => 'standard/standard_9.stub', 'array_intersect_ukey' => 'standard/standard_9.stub', 'array_is_list' => 'standard/standard_9.stub', 'array_key_exists' => 'standard/standard_9.stub', 'array_key_first' => 'standard/standard_9.stub', 'array_key_last' => 'standard/standard_9.stub', 'array_keys' => 'standard/standard_9.stub', 'array_map' => 'standard/standard_9.stub', 'array_merge' => 'standard/standard_8.stub', 'array_merge_recursive' => 'standard/standard_9.stub', 'array_multisort' => 'standard/standard_8.stub', 'array_pad' => 'standard/standard_9.stub', 'array_pop' => 'standard/standard_8.stub', 'array_product' => 'standard/standard_9.stub', 'array_push' => 'standard/standard_8.stub', 'array_rand' => 'standard/standard_9.stub', 'array_reduce' => 'standard/standard_9.stub', 'array_replace' => 'standard/standard_9.stub', 'array_replace_recursive' => 'standard/standard_9.stub', 'array_reverse' => 'standard/standard_9.stub', 'array_search' => 'standard/standard_8.stub', 'array_shift' => 'standard/standard_8.stub', 'array_slice' => 'standard/standard_8.stub', 'array_splice' => 'standard/standard_8.stub', 'array_sum' => 'standard/standard_9.stub', 'array_udiff' => 'standard/standard_9.stub', 'array_udiff_assoc' => 'standard/standard_9.stub', 'array_udiff_uassoc' => 'standard/standard_9.stub', 'array_uintersect' => 'standard/standard_9.stub', 'array_uintersect_assoc' => 'standard/standard_9.stub', 'array_uintersect_uassoc' => 'standard/standard_9.stub', 'array_unique' => 'standard/standard_9.stub', 'array_unshift' => 'standard/standard_8.stub', 'array_values' => 'standard/standard_9.stub', 'array_walk' => 'standard/standard_8.stub', 'array_walk_recursive' => 'standard/standard_8.stub', 'arsort' => 'standard/standard_8.stub', 'asin' => 'standard/standard_3.stub', 'asinh' => 'standard/standard_3.stub', 'asort' => 'standard/standard_8.stub', 'assert' => 'standard/standard_9.stub', 'assert_options' => 'standard/standard_9.stub', 'ast\\get_kind_name' => 'ast/ast.stub', 'ast\\get_metadata' => 'ast/ast.stub', 'ast\\get_supported_versions' => 'ast/ast.stub', 'ast\\kind_uses_flags' => 'ast/ast.stub', 'ast\\parse_code' => 'ast/ast.stub', 'ast\\parse_file' => 'ast/ast.stub', 'atan' => 'standard/standard_3.stub', 'atan2' => 'standard/standard_3.stub', 'atanh' => 'standard/standard_3.stub', 'base64_decode' => 'standard/standard_3.stub', 'base64_encode' => 'standard/standard_3.stub', 'base_convert' => 'standard/standard_3.stub', 'basename' => 'standard/standard_1.stub', 'bcadd' => 'bcmath/bcmath.stub', 'bcceil' => 'bcmath/bcmath.stub', 'bccomp' => 'bcmath/bcmath.stub', 'bcdiv' => 'bcmath/bcmath.stub', 'bcfloor' => 'bcmath/bcmath.stub', 'bcmod' => 'bcmath/bcmath.stub', 'bcmul' => 'bcmath/bcmath.stub', 'bcpow' => 'bcmath/bcmath.stub', 'bcpowmod' => 'bcmath/bcmath.stub', 'bcround' => 'bcmath/bcmath.stub', 'bcscale' => 'bcmath/bcmath.stub', 'bcsqrt' => 'bcmath/bcmath.stub', 'bcsub' => 'bcmath/bcmath.stub', 'bin2hex' => 'standard/standard_0.stub', 'bind_textdomain_codeset' => 'gettext/gettext.stub', 'bindec' => 'standard/standard_3.stub', 'bindtextdomain' => 'gettext/gettext.stub', 'boolval' => 'standard/standard_5.stub', 'brotli_compress' => 'brotli/brotli.stub', 'brotli_compress_add' => 'brotli/brotli.stub', 'brotli_compress_init' => 'brotli/brotli.stub', 'brotli_uncompress' => 'brotli/brotli.stub', 'brotli_uncompress_add' => 'brotli/brotli.stub', 'brotli_uncompress_init' => 'brotli/brotli.stub', 'bzclose' => 'bz2/bz2.stub', 'bzcompress' => 'bz2/bz2.stub', 'bzdecompress' => 'bz2/bz2.stub', 'bzerrno' => 'bz2/bz2.stub', 'bzerror' => 'bz2/bz2.stub', 'bzerrstr' => 'bz2/bz2.stub', 'bzflush' => 'bz2/bz2.stub', 'bzopen' => 'bz2/bz2.stub', 'bzread' => 'bz2/bz2.stub', 'bzwrite' => 'bz2/bz2.stub', 'cal_days_in_month' => 'calendar/calendar.stub', 'cal_from_jd' => 'calendar/calendar.stub', 'cal_info' => 'calendar/calendar.stub', 'cal_to_jd' => 'calendar/calendar.stub', 'call_user_func' => 'standard/standard_4.stub', 'call_user_func_array' => 'standard/standard_4.stub', 'call_user_method' => 'standard/standard_4.stub', 'call_user_method_array' => 'standard/standard_4.stub', 'ceil' => 'standard/standard_3.stub', 'chdir' => 'standard/standard_7.stub', 'checkdate' => 'date/date.stub', 'checkdnsrr' => 'standard/standard_4.stub', 'chgrp' => 'standard/standard_7.stub', 'chmod' => 'standard/standard_7.stub', 'chop' => 'standard/standard_2.stub', 'chown' => 'standard/standard_7.stub', 'chr' => 'standard/standard_2.stub', 'chroot' => 'standard/standard_7.stub', 'chunk_split' => 'standard/standard_1.stub', 'class_alias' => 'Core/Core.stub', 'class_exists' => 'Core/Core.stub', 'class_implements' => 'SPL/SPL_f.stub', 'class_parents' => 'SPL/SPL_f.stub', 'class_uses' => 'SPL/SPL_f.stub', 'clearstatcache' => 'standard/standard_7.stub', 'cli_get_process_title' => 'standard/basic.stub', 'cli_set_process_title' => 'standard/basic.stub', 'closedir' => 'standard/standard_7.stub', 'closelog' => 'standard/standard_8.stub', 'collator_asort' => 'intl/intl.stub', 'collator_compare' => 'intl/intl.stub', 'collator_create' => 'intl/intl.stub', 'collator_get_attribute' => 'intl/intl.stub', 'collator_get_error_code' => 'intl/intl.stub', 'collator_get_error_message' => 'intl/intl.stub', 'collator_get_locale' => 'intl/intl.stub', 'collator_get_sort_key' => 'intl/intl.stub', 'collator_get_strength' => 'intl/intl.stub', 'collator_set_attribute' => 'intl/intl.stub', 'collator_set_strength' => 'intl/intl.stub', 'collator_sort' => 'intl/intl.stub', 'collator_sort_with_sort_keys' => 'intl/intl.stub', 'com_create_guid' => 'com_dotnet/com_dotnet.stub', 'com_event_sink' => 'com_dotnet/com_dotnet.stub', 'com_get_active_object' => 'com_dotnet/com_dotnet.stub', 'com_load_typelib' => 'com_dotnet/com_dotnet.stub', 'com_message_pump' => 'com_dotnet/com_dotnet.stub', 'com_print_typeinfo' => 'com_dotnet/com_dotnet.stub', 'compact' => 'standard/standard_8.stub', 'config_get_hash' => 'xdebug/xdebug.stub', 'confirm_pdo_ibm_compiled' => 'PDO/PDO.stub', 'connection_aborted' => 'standard/standard_4.stub', 'connection_status' => 'standard/standard_4.stub', 'constant' => 'standard/standard_0.stub', 'convert_cyr_string' => 'standard/standard_3.stub', 'convert_uudecode' => 'standard/standard_3.stub', 'convert_uuencode' => 'standard/standard_3.stub', 'copy' => 'standard/standard_5.stub', 'cos' => 'standard/standard_3.stub', 'cosh' => 'standard/standard_3.stub', 'count' => 'standard/standard_8.stub', 'count_chars' => 'standard/standard_1.stub', 'crc32' => 'standard/standard_0.stub', 'create_function' => 'Core/Core.stub', 'crypt' => 'standard/standard_7.stub', 'ctype_alnum' => 'ctype/ctype.stub', 'ctype_alpha' => 'ctype/ctype.stub', 'ctype_cntrl' => 'ctype/ctype.stub', 'ctype_digit' => 'ctype/ctype.stub', 'ctype_graph' => 'ctype/ctype.stub', 'ctype_lower' => 'ctype/ctype.stub', 'ctype_print' => 'ctype/ctype.stub', 'ctype_punct' => 'ctype/ctype.stub', 'ctype_space' => 'ctype/ctype.stub', 'ctype_upper' => 'ctype/ctype.stub', 'ctype_xdigit' => 'ctype/ctype.stub', 'cubrid_affected_rows' => 'cubrid/cubrid.stub', 'cubrid_bind' => 'cubrid/cubrid.stub', 'cubrid_client_encoding' => 'cubrid/cubrid.stub', 'cubrid_close' => 'cubrid/cubrid.stub', 'cubrid_close_prepare' => 'cubrid/cubrid.stub', 'cubrid_close_request' => 'cubrid/cubrid.stub', 'cubrid_col_get' => 'cubrid/cubrid.stub', 'cubrid_col_size' => 'cubrid/cubrid.stub', 'cubrid_column_names' => 'cubrid/cubrid.stub', 'cubrid_column_types' => 'cubrid/cubrid.stub', 'cubrid_commit' => 'cubrid/cubrid.stub', 'cubrid_connect' => 'cubrid/cubrid.stub', 'cubrid_connect_with_url' => 'cubrid/cubrid.stub', 'cubrid_current_oid' => 'cubrid/cubrid.stub', 'cubrid_data_seek' => 'cubrid/cubrid.stub', 'cubrid_db_name' => 'cubrid/cubrid.stub', 'cubrid_db_parameter' => 'cubrid/cubrid.stub', 'cubrid_disconnect' => 'cubrid/cubrid.stub', 'cubrid_drop' => 'cubrid/cubrid.stub', 'cubrid_errno' => 'cubrid/cubrid.stub', 'cubrid_error' => 'cubrid/cubrid.stub', 'cubrid_error_code' => 'cubrid/cubrid.stub', 'cubrid_error_code_facility' => 'cubrid/cubrid.stub', 'cubrid_error_msg' => 'cubrid/cubrid.stub', 'cubrid_execute' => 'cubrid/cubrid.stub', 'cubrid_fetch' => 'cubrid/cubrid.stub', 'cubrid_fetch_array' => 'cubrid/cubrid.stub', 'cubrid_fetch_assoc' => 'cubrid/cubrid.stub', 'cubrid_fetch_field' => 'cubrid/cubrid.stub', 'cubrid_fetch_lengths' => 'cubrid/cubrid.stub', 'cubrid_fetch_object' => 'cubrid/cubrid.stub', 'cubrid_fetch_row' => 'cubrid/cubrid.stub', 'cubrid_field_flags' => 'cubrid/cubrid.stub', 'cubrid_field_len' => 'cubrid/cubrid.stub', 'cubrid_field_name' => 'cubrid/cubrid.stub', 'cubrid_field_seek' => 'cubrid/cubrid.stub', 'cubrid_field_table' => 'cubrid/cubrid.stub', 'cubrid_field_type' => 'cubrid/cubrid.stub', 'cubrid_free_result' => 'cubrid/cubrid.stub', 'cubrid_get' => 'cubrid/cubrid.stub', 'cubrid_get_autocommit' => 'cubrid/cubrid.stub', 'cubrid_get_charset' => 'cubrid/cubrid.stub', 'cubrid_get_class_name' => 'cubrid/cubrid.stub', 'cubrid_get_client_info' => 'cubrid/cubrid.stub', 'cubrid_get_db_parameter' => 'cubrid/cubrid.stub', 'cubrid_get_query_timeout' => 'cubrid/cubrid.stub', 'cubrid_get_server_info' => 'cubrid/cubrid.stub', 'cubrid_insert_id' => 'cubrid/cubrid.stub', 'cubrid_is_instance' => 'cubrid/cubrid.stub', 'cubrid_list_dbs' => 'cubrid/cubrid.stub', 'cubrid_lob2_bind' => 'cubrid/cubrid.stub', 'cubrid_lob2_close' => 'cubrid/cubrid.stub', 'cubrid_lob2_export' => 'cubrid/cubrid.stub', 'cubrid_lob2_import' => 'cubrid/cubrid.stub', 'cubrid_lob2_new' => 'cubrid/cubrid.stub', 'cubrid_lob2_read' => 'cubrid/cubrid.stub', 'cubrid_lob2_seek' => 'cubrid/cubrid.stub', 'cubrid_lob2_seek64' => 'cubrid/cubrid.stub', 'cubrid_lob2_size' => 'cubrid/cubrid.stub', 'cubrid_lob2_size64' => 'cubrid/cubrid.stub', 'cubrid_lob2_tell' => 'cubrid/cubrid.stub', 'cubrid_lob2_tell64' => 'cubrid/cubrid.stub', 'cubrid_lob2_write' => 'cubrid/cubrid.stub', 'cubrid_lob_close' => 'cubrid/cubrid.stub', 'cubrid_lob_export' => 'cubrid/cubrid.stub', 'cubrid_lob_get' => 'cubrid/cubrid.stub', 'cubrid_lob_send' => 'cubrid/cubrid.stub', 'cubrid_lob_size' => 'cubrid/cubrid.stub', 'cubrid_lock_read' => 'cubrid/cubrid.stub', 'cubrid_lock_write' => 'cubrid/cubrid.stub', 'cubrid_move_cursor' => 'cubrid/cubrid.stub', 'cubrid_next_result' => 'cubrid/cubrid.stub', 'cubrid_num_cols' => 'cubrid/cubrid.stub', 'cubrid_num_fields' => 'cubrid/cubrid.stub', 'cubrid_num_rows' => 'cubrid/cubrid.stub', 'cubrid_pconnect' => 'cubrid/cubrid.stub', 'cubrid_pconnect_with_url' => 'cubrid/cubrid.stub', 'cubrid_ping' => 'cubrid/cubrid.stub', 'cubrid_prepare' => 'cubrid/cubrid.stub', 'cubrid_put' => 'cubrid/cubrid.stub', 'cubrid_query' => 'cubrid/cubrid.stub', 'cubrid_real_escape_string' => 'cubrid/cubrid.stub', 'cubrid_result' => 'cubrid/cubrid.stub', 'cubrid_rollback' => 'cubrid/cubrid.stub', 'cubrid_schema' => 'cubrid/cubrid.stub', 'cubrid_seq_add' => 'cubrid/cubrid.stub', 'cubrid_seq_drop' => 'cubrid/cubrid.stub', 'cubrid_seq_insert' => 'cubrid/cubrid.stub', 'cubrid_seq_put' => 'cubrid/cubrid.stub', 'cubrid_set_add' => 'cubrid/cubrid.stub', 'cubrid_set_autocommit' => 'cubrid/cubrid.stub', 'cubrid_set_db_parameter' => 'cubrid/cubrid.stub', 'cubrid_set_drop' => 'cubrid/cubrid.stub', 'cubrid_set_query_timeout' => 'cubrid/cubrid.stub', 'cubrid_unbuffered_query' => 'cubrid/cubrid.stub', 'cubrid_version' => 'cubrid/cubrid.stub', 'curl_close' => 'curl/curl.stub', 'curl_copy_handle' => 'curl/curl.stub', 'curl_errno' => 'curl/curl.stub', 'curl_error' => 'curl/curl.stub', 'curl_escape' => 'curl/curl.stub', 'curl_exec' => 'curl/curl.stub', 'curl_file_create' => 'curl/curl.stub', 'curl_getinfo' => 'curl/curl.stub', 'curl_init' => 'curl/curl.stub', 'curl_multi_add_handle' => 'curl/curl.stub', 'curl_multi_close' => 'curl/curl.stub', 'curl_multi_errno' => 'curl/curl.stub', 'curl_multi_exec' => 'curl/curl.stub', 'curl_multi_getcontent' => 'curl/curl.stub', 'curl_multi_info_read' => 'curl/curl.stub', 'curl_multi_init' => 'curl/curl.stub', 'curl_multi_remove_handle' => 'curl/curl.stub', 'curl_multi_select' => 'curl/curl.stub', 'curl_multi_setopt' => 'curl/curl.stub', 'curl_multi_strerror' => 'curl/curl.stub', 'curl_pause' => 'curl/curl.stub', 'curl_reset' => 'curl/curl.stub', 'curl_setopt' => 'curl/curl.stub', 'curl_setopt_array' => 'curl/curl.stub', 'curl_share_close' => 'curl/curl.stub', 'curl_share_errno' => 'curl/curl.stub', 'curl_share_init' => 'curl/curl.stub', 'curl_share_setopt' => 'curl/curl.stub', 'curl_share_strerror' => 'curl/curl.stub', 'curl_strerror' => 'curl/curl.stub', 'curl_unescape' => 'curl/curl.stub', 'curl_upkeep' => 'curl/curl.stub', 'curl_version' => 'curl/curl.stub', 'current' => 'standard/standard_8.stub', 'date' => 'date/date.stub', 'date_add' => 'date/date.stub', 'date_create' => 'date/date.stub', 'date_create_from_format' => 'date/date.stub', 'date_create_immutable' => 'date/date.stub', 'date_create_immutable_from_format' => 'date/date.stub', 'date_date_set' => 'date/date.stub', 'date_default_timezone_get' => 'date/date.stub', 'date_default_timezone_set' => 'date/date.stub', 'date_diff' => 'date/date.stub', 'date_format' => 'date/date.stub', 'date_get_last_errors' => 'date/date.stub', 'date_interval_create_from_date_string' => 'date/date.stub', 'date_interval_format' => 'date/date.stub', 'date_isodate_set' => 'date/date.stub', 'date_modify' => 'date/date.stub', 'date_offset_get' => 'date/date.stub', 'date_parse' => 'date/date.stub', 'date_parse_from_format' => 'date/date.stub', 'date_sub' => 'date/date.stub', 'date_sun_info' => 'date/date.stub', 'date_sunrise' => 'date/date.stub', 'date_sunset' => 'date/date.stub', 'date_time_set' => 'date/date.stub', 'date_timestamp_get' => 'date/date.stub', 'date_timestamp_set' => 'date/date.stub', 'date_timezone_get' => 'date/date.stub', 'date_timezone_set' => 'date/date.stub', 'datefmt_create' => 'intl/intl.stub', 'datefmt_format' => 'intl/intl.stub', 'datefmt_format_object' => 'intl/intl.stub', 'datefmt_get_calendar' => 'intl/intl.stub', 'datefmt_get_calendar_object' => 'intl/intl.stub', 'datefmt_get_datetype' => 'intl/intl.stub', 'datefmt_get_error_code' => 'intl/intl.stub', 'datefmt_get_error_message' => 'intl/intl.stub', 'datefmt_get_locale' => 'intl/intl.stub', 'datefmt_get_pattern' => 'intl/intl.stub', 'datefmt_get_timetype' => 'intl/intl.stub', 'datefmt_get_timezone' => 'intl/intl.stub', 'datefmt_get_timezone_id' => 'intl/intl.stub', 'datefmt_is_lenient' => 'intl/intl.stub', 'datefmt_localtime' => 'intl/intl.stub', 'datefmt_parse' => 'intl/intl.stub', 'datefmt_set_calendar' => 'intl/intl.stub', 'datefmt_set_lenient' => 'intl/intl.stub', 'datefmt_set_pattern' => 'intl/intl.stub', 'datefmt_set_timezone' => 'intl/intl.stub', 'datefmt_set_timezone_id' => 'intl/intl.stub', 'db2_autocommit' => 'ibm_db2/ibm_db2.stub', 'db2_bind_param' => 'ibm_db2/ibm_db2.stub', 'db2_client_info' => 'ibm_db2/ibm_db2.stub', 'db2_close' => 'ibm_db2/ibm_db2.stub', 'db2_column_privileges' => 'ibm_db2/ibm_db2.stub', 'db2_columnprivileges' => 'ibm_db2/ibm_db2.stub', 'db2_columns' => 'ibm_db2/ibm_db2.stub', 'db2_commit' => 'ibm_db2/ibm_db2.stub', 'db2_conn_error' => 'ibm_db2/ibm_db2.stub', 'db2_conn_errormsg' => 'ibm_db2/ibm_db2.stub', 'db2_connect' => 'ibm_db2/ibm_db2.stub', 'db2_cursor_type' => 'ibm_db2/ibm_db2.stub', 'db2_escape_string' => 'ibm_db2/ibm_db2.stub', 'db2_exec' => 'ibm_db2/ibm_db2.stub', 'db2_execute' => 'ibm_db2/ibm_db2.stub', 'db2_fetch_array' => 'ibm_db2/ibm_db2.stub', 'db2_fetch_assoc' => 'ibm_db2/ibm_db2.stub', 'db2_fetch_both' => 'ibm_db2/ibm_db2.stub', 'db2_fetch_object' => 'ibm_db2/ibm_db2.stub', 'db2_fetch_row' => 'ibm_db2/ibm_db2.stub', 'db2_field_display_size' => 'ibm_db2/ibm_db2.stub', 'db2_field_name' => 'ibm_db2/ibm_db2.stub', 'db2_field_num' => 'ibm_db2/ibm_db2.stub', 'db2_field_precision' => 'ibm_db2/ibm_db2.stub', 'db2_field_scale' => 'ibm_db2/ibm_db2.stub', 'db2_field_type' => 'ibm_db2/ibm_db2.stub', 'db2_field_width' => 'ibm_db2/ibm_db2.stub', 'db2_foreign_keys' => 'ibm_db2/ibm_db2.stub', 'db2_foreignkeys' => 'ibm_db2/ibm_db2.stub', 'db2_free_result' => 'ibm_db2/ibm_db2.stub', 'db2_free_stmt' => 'ibm_db2/ibm_db2.stub', 'db2_get_option' => 'ibm_db2/ibm_db2.stub', 'db2_last_insert_id' => 'ibm_db2/ibm_db2.stub', 'db2_lob_read' => 'ibm_db2/ibm_db2.stub', 'db2_next_result' => 'ibm_db2/ibm_db2.stub', 'db2_num_fields' => 'ibm_db2/ibm_db2.stub', 'db2_num_rows' => 'ibm_db2/ibm_db2.stub', 'db2_pclose' => 'ibm_db2/ibm_db2.stub', 'db2_pconnect' => 'ibm_db2/ibm_db2.stub', 'db2_prepare' => 'ibm_db2/ibm_db2.stub', 'db2_primary_keys' => 'ibm_db2/ibm_db2.stub', 'db2_primarykeys' => 'ibm_db2/ibm_db2.stub', 'db2_procedure_columns' => 'ibm_db2/ibm_db2.stub', 'db2_procedurecolumns' => 'ibm_db2/ibm_db2.stub', 'db2_procedures' => 'ibm_db2/ibm_db2.stub', 'db2_result' => 'ibm_db2/ibm_db2.stub', 'db2_rollback' => 'ibm_db2/ibm_db2.stub', 'db2_server_info' => 'ibm_db2/ibm_db2.stub', 'db2_set_option' => 'ibm_db2/ibm_db2.stub', 'db2_setoption' => 'ibm_db2/ibm_db2.stub', 'db2_special_columns' => 'ibm_db2/ibm_db2.stub', 'db2_specialcolumns' => 'ibm_db2/ibm_db2.stub', 'db2_statistics' => 'ibm_db2/ibm_db2.stub', 'db2_stmt_error' => 'ibm_db2/ibm_db2.stub', 'db2_stmt_errormsg' => 'ibm_db2/ibm_db2.stub', 'db2_table_privileges' => 'ibm_db2/ibm_db2.stub', 'db2_tableprivileges' => 'ibm_db2/ibm_db2.stub', 'db2_tables' => 'ibm_db2/ibm_db2.stub', 'dba_close' => 'dba/dba.stub', 'dba_delete' => 'dba/dba.stub', 'dba_exists' => 'dba/dba.stub', 'dba_fetch' => 'dba/dba.stub', 'dba_firstkey' => 'dba/dba.stub', 'dba_handlers' => 'dba/dba.stub', 'dba_insert' => 'dba/dba.stub', 'dba_key_split' => 'dba/dba.stub', 'dba_list' => 'dba/dba.stub', 'dba_nextkey' => 'dba/dba.stub', 'dba_open' => 'dba/dba.stub', 'dba_optimize' => 'dba/dba.stub', 'dba_popen' => 'dba/dba.stub', 'dba_replace' => 'dba/dba.stub', 'dba_sync' => 'dba/dba.stub', 'dcgettext' => 'gettext/gettext.stub', 'dcngettext' => 'gettext/gettext.stub', 'debug_backtrace' => 'Core/Core.stub', 'debug_print_backtrace' => 'Core/Core.stub', 'debug_zval_dump' => 'standard/standard_4.stub', 'debugger_connect' => 'ZendDebugger/ZendDebugger.stub', 'debugger_connector_pid' => 'ZendDebugger/ZendDebugger.stub', 'debugger_get_server_start_time' => 'ZendDebugger/ZendDebugger.stub', 'debugger_print' => 'ZendDebugger/ZendDebugger.stub', 'debugger_start_debug' => 'ZendDebugger/ZendDebugger.stub', 'decbin' => 'standard/standard_3.stub', 'dechex' => 'standard/standard_3.stub', 'decoct' => 'standard/standard_3.stub', 'defer' => 'swoole/functions.stub', 'define' => 'Core/Core.stub', 'define_syslog_variables' => 'standard/standard_8.stub', 'defined' => 'Core/Core.stub', 'deflate_add' => 'zlib/zlib.stub', 'deflate_init' => 'zlib/zlib.stub', 'deg2rad' => 'standard/standard_3.stub', 'dgettext' => 'gettext/gettext.stub', 'dio_close' => 'dio/dio.stub', 'dio_fcntl' => 'dio/dio.stub', 'dio_open' => 'dio/dio.stub', 'dio_raw' => 'dio/dio.stub', 'dio_read' => 'dio/dio.stub', 'dio_seek' => 'dio/dio.stub', 'dio_serial' => 'dio/dio.stub', 'dio_stat' => 'dio/dio.stub', 'dio_tcsetattr' => 'dio/dio.stub', 'dio_truncate' => 'dio/dio.stub', 'dio_write' => 'dio/dio.stub', 'dir' => 'standard/standard_7.stub', 'dirname' => 'standard/standard_1.stub', 'disk_free_space' => 'standard/standard_7.stub', 'disk_total_space' => 'standard/standard_7.stub', 'diskfreespace' => 'standard/standard_7.stub', 'dl' => 'standard/basic.stub', 'dngettext' => 'gettext/gettext.stub', 'dns_check_record' => 'standard/standard_4.stub', 'dns_get_mx' => 'standard/standard_4.stub', 'dns_get_record' => 'standard/standard_4.stub', 'dom_import_simplexml' => 'dom/dom.stub', 'doubleval' => 'standard/standard_5.stub', 'each' => 'Core/Core.stub', 'easter_date' => 'calendar/calendar.stub', 'easter_days' => 'calendar/calendar.stub', 'eio_busy' => 'eio/eio.stub', 'eio_cancel' => 'eio/eio.stub', 'eio_chmod' => 'eio/eio.stub', 'eio_chown' => 'eio/eio.stub', 'eio_close' => 'eio/eio.stub', 'eio_custom' => 'eio/eio.stub', 'eio_dup2' => 'eio/eio.stub', 'eio_event_loop' => 'eio/eio.stub', 'eio_fallocate' => 'eio/eio.stub', 'eio_fchmod' => 'eio/eio.stub', 'eio_fchown' => 'eio/eio.stub', 'eio_fdatasync' => 'eio/eio.stub', 'eio_fstat' => 'eio/eio.stub', 'eio_fstatvfs' => 'eio/eio.stub', 'eio_fsync' => 'eio/eio.stub', 'eio_ftruncate' => 'eio/eio.stub', 'eio_futime' => 'eio/eio.stub', 'eio_get_event_stream' => 'eio/eio.stub', 'eio_get_last_error' => 'eio/eio.stub', 'eio_grp' => 'eio/eio.stub', 'eio_grp_add' => 'eio/eio.stub', 'eio_grp_cancel' => 'eio/eio.stub', 'eio_grp_limit' => 'eio/eio.stub', 'eio_link' => 'eio/eio.stub', 'eio_lstat' => 'eio/eio.stub', 'eio_mkdir' => 'eio/eio.stub', 'eio_mknod' => 'eio/eio.stub', 'eio_nop' => 'eio/eio.stub', 'eio_npending' => 'eio/eio.stub', 'eio_nready' => 'eio/eio.stub', 'eio_nreqs' => 'eio/eio.stub', 'eio_nthreads' => 'eio/eio.stub', 'eio_open' => 'eio/eio.stub', 'eio_poll' => 'eio/eio.stub', 'eio_read' => 'eio/eio.stub', 'eio_readahead' => 'eio/eio.stub', 'eio_readdir' => 'eio/eio.stub', 'eio_readlink' => 'eio/eio.stub', 'eio_realpath' => 'eio/eio.stub', 'eio_rename' => 'eio/eio.stub', 'eio_rmdir' => 'eio/eio.stub', 'eio_seek' => 'eio/eio.stub', 'eio_sendfile' => 'eio/eio.stub', 'eio_set_max_idle' => 'eio/eio.stub', 'eio_set_max_parallel' => 'eio/eio.stub', 'eio_set_max_poll_reqs' => 'eio/eio.stub', 'eio_set_max_poll_time' => 'eio/eio.stub', 'eio_set_min_parallel' => 'eio/eio.stub', 'eio_stat' => 'eio/eio.stub', 'eio_statvfs' => 'eio/eio.stub', 'eio_symlink' => 'eio/eio.stub', 'eio_sync' => 'eio/eio.stub', 'eio_sync_file_range' => 'eio/eio.stub', 'eio_syncfs' => 'eio/eio.stub', 'eio_truncate' => 'eio/eio.stub', 'eio_unlink' => 'eio/eio.stub', 'eio_utime' => 'eio/eio.stub', 'eio_write' => 'eio/eio.stub', 'enchant_broker_describe' => 'enchant/enchant.stub', 'enchant_broker_dict_exists' => 'enchant/enchant.stub', 'enchant_broker_free' => 'enchant/enchant.stub', 'enchant_broker_free_dict' => 'enchant/enchant.stub', 'enchant_broker_get_dict_path' => 'enchant/enchant.stub', 'enchant_broker_get_error' => 'enchant/enchant.stub', 'enchant_broker_init' => 'enchant/enchant.stub', 'enchant_broker_list_dicts' => 'enchant/enchant.stub', 'enchant_broker_request_dict' => 'enchant/enchant.stub', 'enchant_broker_request_pwl_dict' => 'enchant/enchant.stub', 'enchant_broker_set_dict_path' => 'enchant/enchant.stub', 'enchant_broker_set_ordering' => 'enchant/enchant.stub', 'enchant_dict_add' => 'enchant/enchant.stub', 'enchant_dict_add_to_personal' => 'enchant/enchant.stub', 'enchant_dict_add_to_session' => 'enchant/enchant.stub', 'enchant_dict_check' => 'enchant/enchant.stub', 'enchant_dict_describe' => 'enchant/enchant.stub', 'enchant_dict_get_error' => 'enchant/enchant.stub', 'enchant_dict_is_added' => 'enchant/enchant.stub', 'enchant_dict_is_in_session' => 'enchant/enchant.stub', 'enchant_dict_quick_check' => 'enchant/enchant.stub', 'enchant_dict_store_replacement' => 'enchant/enchant.stub', 'enchant_dict_suggest' => 'enchant/enchant.stub', 'end' => 'standard/standard_8.stub', 'enum_exists' => 'Core/Core.stub', 'ereg' => 'regex/ereg.stub', 'ereg_replace' => 'regex/ereg.stub', 'eregi' => 'regex/ereg.stub', 'eregi_replace' => 'regex/ereg.stub', 'error_clear_last' => 'standard/basic.stub', 'error_get_last' => 'standard/standard_4.stub', 'error_log' => 'standard/standard_3.stub', 'error_reporting' => 'Core/Core.stub', 'escapeshellarg' => 'standard/standard_2.stub', 'escapeshellcmd' => 'standard/standard_2.stub', 'event_add' => 'libevent/libevent.stub', 'event_base_free' => 'libevent/libevent.stub', 'event_base_loop' => 'libevent/libevent.stub', 'event_base_loopbreak' => 'libevent/libevent.stub', 'event_base_loopexit' => 'libevent/libevent.stub', 'event_base_new' => 'libevent/libevent.stub', 'event_base_priority_init' => 'libevent/libevent.stub', 'event_base_set' => 'libevent/libevent.stub', 'event_buffer_base_set' => 'libevent/libevent.stub', 'event_buffer_disable' => 'libevent/libevent.stub', 'event_buffer_enable' => 'libevent/libevent.stub', 'event_buffer_fd_set' => 'libevent/libevent.stub', 'event_buffer_free' => 'libevent/libevent.stub', 'event_buffer_new' => 'libevent/libevent.stub', 'event_buffer_priority_set' => 'libevent/libevent.stub', 'event_buffer_read' => 'libevent/libevent.stub', 'event_buffer_set_callback' => 'libevent/libevent.stub', 'event_buffer_timeout_set' => 'libevent/libevent.stub', 'event_buffer_watermark_set' => 'libevent/libevent.stub', 'event_buffer_write' => 'libevent/libevent.stub', 'event_del' => 'libevent/libevent.stub', 'event_free' => 'libevent/libevent.stub', 'event_new' => 'libevent/libevent.stub', 'event_set' => 'libevent/libevent.stub', 'event_timer_add' => 'libevent/libevent.stub', 'event_timer_del' => 'libevent/libevent.stub', 'event_timer_new' => 'libevent/libevent.stub', 'event_timer_pending' => 'libevent/libevent.stub', 'event_timer_set' => 'libevent/libevent.stub', 'exec' => 'standard/standard_2.stub', 'exif_imagetype' => 'exif/exif.stub', 'exif_read_data' => 'exif/exif.stub', 'exif_tagname' => 'exif/exif.stub', 'exif_thumbnail' => 'exif/exif.stub', 'exp' => 'standard/standard_3.stub', 'expect_expectl' => 'expect/expect.stub', 'expect_popen' => 'expect/expect.stub', 'explode' => 'standard/standard_1.stub', 'expm1' => 'standard/standard_3.stub', 'extension_loaded' => 'Core/Core.stub', 'extract' => 'standard/standard_8.stub', 'ezmlm_hash' => 'standard/standard_7.stub', 'fann_cascadetrain_on_data' => 'fann/fann.stub', 'fann_cascadetrain_on_file' => 'fann/fann.stub', 'fann_clear_scaling_params' => 'fann/fann.stub', 'fann_copy' => 'fann/fann.stub', 'fann_create_from_file' => 'fann/fann.stub', 'fann_create_shortcut' => 'fann/fann.stub', 'fann_create_shortcut_array' => 'fann/fann.stub', 'fann_create_sparse' => 'fann/fann.stub', 'fann_create_sparse_array' => 'fann/fann.stub', 'fann_create_standard' => 'fann/fann.stub', 'fann_create_standard_array' => 'fann/fann.stub', 'fann_create_train' => 'fann/fann.stub', 'fann_create_train_from_callback' => 'fann/fann.stub', 'fann_descale_input' => 'fann/fann.stub', 'fann_descale_output' => 'fann/fann.stub', 'fann_descale_train' => 'fann/fann.stub', 'fann_destroy' => 'fann/fann.stub', 'fann_destroy_train' => 'fann/fann.stub', 'fann_duplicate_train_data' => 'fann/fann.stub', 'fann_get_MSE' => 'fann/fann.stub', 'fann_get_activation_function' => 'fann/fann.stub', 'fann_get_activation_steepness' => 'fann/fann.stub', 'fann_get_bias_array' => 'fann/fann.stub', 'fann_get_bit_fail' => 'fann/fann.stub', 'fann_get_bit_fail_limit' => 'fann/fann.stub', 'fann_get_cascade_activation_functions' => 'fann/fann.stub', 'fann_get_cascade_activation_functions_count' => 'fann/fann.stub', 'fann_get_cascade_activation_steepnesses' => 'fann/fann.stub', 'fann_get_cascade_activation_steepnesses_count' => 'fann/fann.stub', 'fann_get_cascade_candidate_change_fraction' => 'fann/fann.stub', 'fann_get_cascade_candidate_limit' => 'fann/fann.stub', 'fann_get_cascade_candidate_stagnation_epochs' => 'fann/fann.stub', 'fann_get_cascade_max_cand_epochs' => 'fann/fann.stub', 'fann_get_cascade_max_out_epochs' => 'fann/fann.stub', 'fann_get_cascade_min_cand_epochs' => 'fann/fann.stub', 'fann_get_cascade_min_out_epochs' => 'fann/fann.stub', 'fann_get_cascade_num_candidate_groups' => 'fann/fann.stub', 'fann_get_cascade_num_candidates' => 'fann/fann.stub', 'fann_get_cascade_output_change_fraction' => 'fann/fann.stub', 'fann_get_cascade_output_stagnation_epochs' => 'fann/fann.stub', 'fann_get_cascade_weight_multiplier' => 'fann/fann.stub', 'fann_get_connection_array' => 'fann/fann.stub', 'fann_get_connection_rate' => 'fann/fann.stub', 'fann_get_errno' => 'fann/fann.stub', 'fann_get_errstr' => 'fann/fann.stub', 'fann_get_layer_array' => 'fann/fann.stub', 'fann_get_learning_momentum' => 'fann/fann.stub', 'fann_get_learning_rate' => 'fann/fann.stub', 'fann_get_network_type' => 'fann/fann.stub', 'fann_get_num_input' => 'fann/fann.stub', 'fann_get_num_layers' => 'fann/fann.stub', 'fann_get_num_output' => 'fann/fann.stub', 'fann_get_quickprop_decay' => 'fann/fann.stub', 'fann_get_quickprop_mu' => 'fann/fann.stub', 'fann_get_rprop_decrease_factor' => 'fann/fann.stub', 'fann_get_rprop_delta_max' => 'fann/fann.stub', 'fann_get_rprop_delta_min' => 'fann/fann.stub', 'fann_get_rprop_delta_zero' => 'fann/fann.stub', 'fann_get_rprop_increase_factor' => 'fann/fann.stub', 'fann_get_sarprop_step_error_shift' => 'fann/fann.stub', 'fann_get_sarprop_step_error_threshold_factor' => 'fann/fann.stub', 'fann_get_sarprop_temperature' => 'fann/fann.stub', 'fann_get_sarprop_weight_decay_shift' => 'fann/fann.stub', 'fann_get_total_connections' => 'fann/fann.stub', 'fann_get_total_neurons' => 'fann/fann.stub', 'fann_get_train_error_function' => 'fann/fann.stub', 'fann_get_train_stop_function' => 'fann/fann.stub', 'fann_get_training_algorithm' => 'fann/fann.stub', 'fann_init_weights' => 'fann/fann.stub', 'fann_length_train_data' => 'fann/fann.stub', 'fann_merge_train_data' => 'fann/fann.stub', 'fann_num_input_train_data' => 'fann/fann.stub', 'fann_num_output_train_data' => 'fann/fann.stub', 'fann_print_error' => 'fann/fann.stub', 'fann_randomize_weights' => 'fann/fann.stub', 'fann_read_train_from_file' => 'fann/fann.stub', 'fann_reset_MSE' => 'fann/fann.stub', 'fann_reset_errno' => 'fann/fann.stub', 'fann_reset_errstr' => 'fann/fann.stub', 'fann_run' => 'fann/fann.stub', 'fann_save' => 'fann/fann.stub', 'fann_save_train' => 'fann/fann.stub', 'fann_scale_input' => 'fann/fann.stub', 'fann_scale_input_train_data' => 'fann/fann.stub', 'fann_scale_output' => 'fann/fann.stub', 'fann_scale_output_train_data' => 'fann/fann.stub', 'fann_scale_train' => 'fann/fann.stub', 'fann_scale_train_data' => 'fann/fann.stub', 'fann_set_activation_function' => 'fann/fann.stub', 'fann_set_activation_function_hidden' => 'fann/fann.stub', 'fann_set_activation_function_layer' => 'fann/fann.stub', 'fann_set_activation_function_output' => 'fann/fann.stub', 'fann_set_activation_steepness' => 'fann/fann.stub', 'fann_set_activation_steepness_hidden' => 'fann/fann.stub', 'fann_set_activation_steepness_layer' => 'fann/fann.stub', 'fann_set_activation_steepness_output' => 'fann/fann.stub', 'fann_set_bit_fail_limit' => 'fann/fann.stub', 'fann_set_callback' => 'fann/fann.stub', 'fann_set_cascade_activation_functions' => 'fann/fann.stub', 'fann_set_cascade_activation_steepnesses' => 'fann/fann.stub', 'fann_set_cascade_candidate_change_fraction' => 'fann/fann.stub', 'fann_set_cascade_candidate_limit' => 'fann/fann.stub', 'fann_set_cascade_candidate_stagnation_epochs' => 'fann/fann.stub', 'fann_set_cascade_max_cand_epochs' => 'fann/fann.stub', 'fann_set_cascade_max_out_epochs' => 'fann/fann.stub', 'fann_set_cascade_min_cand_epochs' => 'fann/fann.stub', 'fann_set_cascade_min_out_epochs' => 'fann/fann.stub', 'fann_set_cascade_num_candidate_groups' => 'fann/fann.stub', 'fann_set_cascade_output_change_fraction' => 'fann/fann.stub', 'fann_set_cascade_output_stagnation_epochs' => 'fann/fann.stub', 'fann_set_cascade_weight_multiplier' => 'fann/fann.stub', 'fann_set_error_log' => 'fann/fann.stub', 'fann_set_input_scaling_params' => 'fann/fann.stub', 'fann_set_learning_momentum' => 'fann/fann.stub', 'fann_set_learning_rate' => 'fann/fann.stub', 'fann_set_output_scaling_params' => 'fann/fann.stub', 'fann_set_quickprop_decay' => 'fann/fann.stub', 'fann_set_quickprop_mu' => 'fann/fann.stub', 'fann_set_rprop_decrease_factor' => 'fann/fann.stub', 'fann_set_rprop_delta_max' => 'fann/fann.stub', 'fann_set_rprop_delta_min' => 'fann/fann.stub', 'fann_set_rprop_delta_zero' => 'fann/fann.stub', 'fann_set_rprop_increase_factor' => 'fann/fann.stub', 'fann_set_sarprop_step_error_shift' => 'fann/fann.stub', 'fann_set_sarprop_step_error_threshold_factor' => 'fann/fann.stub', 'fann_set_sarprop_temperature' => 'fann/fann.stub', 'fann_set_sarprop_weight_decay_shift' => 'fann/fann.stub', 'fann_set_scaling_params' => 'fann/fann.stub', 'fann_set_train_error_function' => 'fann/fann.stub', 'fann_set_train_stop_function' => 'fann/fann.stub', 'fann_set_training_algorithm' => 'fann/fann.stub', 'fann_set_weight' => 'fann/fann.stub', 'fann_set_weight_array' => 'fann/fann.stub', 'fann_shuffle_train_data' => 'fann/fann.stub', 'fann_subset_train_data' => 'fann/fann.stub', 'fann_test' => 'fann/fann.stub', 'fann_test_data' => 'fann/fann.stub', 'fann_train' => 'fann/fann.stub', 'fann_train_epoch' => 'fann/fann.stub', 'fann_train_on_data' => 'fann/fann.stub', 'fann_train_on_file' => 'fann/fann.stub', 'fastcgi_finish_request' => 'fpm/fpm.stub', 'fbird_add_user' => 'interbase/interbase.stub', 'fbird_affected_rows' => 'interbase/interbase.stub', 'fbird_backup' => 'interbase/interbase.stub', 'fbird_blob_add' => 'interbase/interbase.stub', 'fbird_blob_cancel' => 'interbase/interbase.stub', 'fbird_blob_close' => 'interbase/interbase.stub', 'fbird_blob_create' => 'interbase/interbase.stub', 'fbird_blob_echo' => 'interbase/interbase.stub', 'fbird_blob_get' => 'interbase/interbase.stub', 'fbird_blob_import' => 'interbase/interbase.stub', 'fbird_blob_info' => 'interbase/interbase.stub', 'fbird_blob_open' => 'interbase/interbase.stub', 'fbird_close' => 'interbase/interbase.stub', 'fbird_commit' => 'interbase/interbase.stub', 'fbird_commit_ret' => 'interbase/interbase.stub', 'fbird_connect' => 'interbase/interbase.stub', 'fbird_db_info' => 'interbase/interbase.stub', 'fbird_delete_user' => 'interbase/interbase.stub', 'fbird_drop_db' => 'interbase/interbase.stub', 'fbird_errcode' => 'interbase/interbase.stub', 'fbird_errmsg' => 'interbase/interbase.stub', 'fbird_execute' => 'interbase/interbase.stub', 'fbird_fetch_assoc' => 'interbase/interbase.stub', 'fbird_fetch_object' => 'interbase/interbase.stub', 'fbird_fetch_row' => 'interbase/interbase.stub', 'fbird_field_info' => 'interbase/interbase.stub', 'fbird_free_event_handler' => 'interbase/interbase.stub', 'fbird_free_query' => 'interbase/interbase.stub', 'fbird_free_result' => 'interbase/interbase.stub', 'fbird_gen_id' => 'interbase/interbase.stub', 'fbird_maintain_db' => 'interbase/interbase.stub', 'fbird_modify_user' => 'interbase/interbase.stub', 'fbird_name_result' => 'interbase/interbase.stub', 'fbird_num_fields' => 'interbase/interbase.stub', 'fbird_num_params' => 'interbase/interbase.stub', 'fbird_param_info' => 'interbase/interbase.stub', 'fbird_pconnect' => 'interbase/interbase.stub', 'fbird_prepare' => 'interbase/interbase.stub', 'fbird_query' => 'interbase/interbase.stub', 'fbird_restore' => 'interbase/interbase.stub', 'fbird_rollback' => 'interbase/interbase.stub', 'fbird_rollback_ret' => 'interbase/interbase.stub', 'fbird_server_info' => 'interbase/interbase.stub', 'fbird_service_attach' => 'interbase/interbase.stub', 'fbird_service_detach' => 'interbase/interbase.stub', 'fbird_set_event_handler' => 'interbase/interbase.stub', 'fbird_trans' => 'interbase/interbase.stub', 'fbird_wait_event' => 'interbase/interbase.stub', 'fclose' => 'standard/standard_5.stub', 'fdatasync' => 'standard/standard_5.stub', 'fdiv' => 'standard/standard_3.stub', 'feof' => 'standard/standard_5.stub', 'fflush' => 'standard/standard_5.stub', 'fgetc' => 'standard/standard_5.stub', 'fgetcsv' => 'standard/standard_6.stub', 'fgets' => 'standard/standard_5.stub', 'fgetss' => 'standard/standard_5.stub', 'file' => 'standard/standard_5.stub', 'file_exists' => 'standard/standard_7.stub', 'file_get_contents' => 'standard/standard_5.stub', 'file_put_contents' => 'standard/standard_5.stub', 'fileatime' => 'standard/standard_7.stub', 'filectime' => 'standard/standard_7.stub', 'filegroup' => 'standard/standard_7.stub', 'fileinode' => 'standard/standard_7.stub', 'filemtime' => 'standard/standard_7.stub', 'fileowner' => 'standard/standard_7.stub', 'fileperms' => 'standard/standard_7.stub', 'filesize' => 'standard/standard_7.stub', 'filetype' => 'standard/standard_7.stub', 'filter_has_var' => 'filter/filter.stub', 'filter_id' => 'filter/filter.stub', 'filter_input' => 'filter/filter.stub', 'filter_input_array' => 'filter/filter.stub', 'filter_list' => 'filter/filter.stub', 'filter_var' => 'filter/filter.stub', 'filter_var_array' => 'filter/filter.stub', 'finfo_buffer' => 'fileinfo/fileinfo.stub', 'finfo_close' => 'fileinfo/fileinfo.stub', 'finfo_file' => 'fileinfo/fileinfo.stub', 'finfo_open' => 'fileinfo/fileinfo.stub', 'finfo_set_flags' => 'fileinfo/fileinfo.stub', 'floatval' => 'standard/standard_5.stub', 'flock' => 'standard/standard_6.stub', 'floor' => 'standard/standard_3.stub', 'flush' => 'standard/standard_0.stub', 'fmod' => 'standard/standard_3.stub', 'fnmatch' => 'standard/standard_6.stub', 'fopen' => 'standard/standard_5.stub', 'forward_static_call' => 'standard/standard_4.stub', 'forward_static_call_array' => 'standard/standard_4.stub', 'fpassthru' => 'standard/standard_5.stub', 'fpm_get_status' => 'fpm/fpm.stub', 'fpow' => 'standard/standard_10.stub', 'fprintf' => 'standard/standard_2.stub', 'fputcsv' => 'standard/standard_6.stub', 'fputs' => 'standard/standard_5.stub', 'frankenphp_finish_request' => 'frankenphp/frankenphp.stub', 'frankenphp_handle_request' => 'frankenphp/frankenphp.stub', 'frankenphp_request_headers' => 'frankenphp/frankenphp.stub', 'frankenphp_response_headers' => 'frankenphp/frankenphp.stub', 'fread' => 'standard/standard_5.stub', 'frenchtojd' => 'calendar/calendar.stub', 'fscanf' => 'standard/standard_2.stub', 'fseek' => 'standard/standard_5.stub', 'fsockopen' => 'standard/standard_7.stub', 'fstat' => 'standard/standard_5.stub', 'fsync' => 'standard/standard_5.stub', 'ftell' => 'standard/standard_5.stub', 'ftok' => 'standard/standard_9.stub', 'ftp_alloc' => 'ftp/ftp.stub', 'ftp_append' => 'ftp/ftp.stub', 'ftp_cdup' => 'ftp/ftp.stub', 'ftp_chdir' => 'ftp/ftp.stub', 'ftp_chmod' => 'ftp/ftp.stub', 'ftp_close' => 'ftp/ftp.stub', 'ftp_connect' => 'ftp/ftp.stub', 'ftp_delete' => 'ftp/ftp.stub', 'ftp_exec' => 'ftp/ftp.stub', 'ftp_fget' => 'ftp/ftp.stub', 'ftp_fput' => 'ftp/ftp.stub', 'ftp_get' => 'ftp/ftp.stub', 'ftp_get_option' => 'ftp/ftp.stub', 'ftp_login' => 'ftp/ftp.stub', 'ftp_mdtm' => 'ftp/ftp.stub', 'ftp_mkdir' => 'ftp/ftp.stub', 'ftp_mlsd' => 'ftp/ftp.stub', 'ftp_nb_continue' => 'ftp/ftp.stub', 'ftp_nb_fget' => 'ftp/ftp.stub', 'ftp_nb_fput' => 'ftp/ftp.stub', 'ftp_nb_get' => 'ftp/ftp.stub', 'ftp_nb_put' => 'ftp/ftp.stub', 'ftp_nlist' => 'ftp/ftp.stub', 'ftp_pasv' => 'ftp/ftp.stub', 'ftp_put' => 'ftp/ftp.stub', 'ftp_pwd' => 'ftp/ftp.stub', 'ftp_quit' => 'ftp/ftp.stub', 'ftp_raw' => 'ftp/ftp.stub', 'ftp_rawlist' => 'ftp/ftp.stub', 'ftp_rename' => 'ftp/ftp.stub', 'ftp_rmdir' => 'ftp/ftp.stub', 'ftp_set_option' => 'ftp/ftp.stub', 'ftp_site' => 'ftp/ftp.stub', 'ftp_size' => 'ftp/ftp.stub', 'ftp_ssl_connect' => 'ftp/ftp.stub', 'ftp_systype' => 'ftp/ftp.stub', 'ftruncate' => 'standard/standard_5.stub', 'func_get_arg' => 'Core/Core.stub', 'func_get_args' => 'Core/Core.stub', 'func_num_args' => 'Core/Core.stub', 'function_exists' => 'Core/Core.stub', 'fwrite' => 'standard/standard_5.stub', 'gc_collect_cycles' => 'Core/Core.stub', 'gc_disable' => 'Core/Core.stub', 'gc_enable' => 'Core/Core.stub', 'gc_enabled' => 'Core/Core.stub', 'gc_mem_caches' => 'Core/Core.stub', 'gc_status' => 'Core/Core.stub', 'gd_info' => 'gd/gd.stub', 'gearman_bugreport' => 'gearman/gearman.stub', 'gearman_client_add_options' => 'gearman/gearman.stub', 'gearman_client_add_server' => 'gearman/gearman.stub', 'gearman_client_add_servers' => 'gearman/gearman.stub', 'gearman_client_add_task' => 'gearman/gearman.stub', 'gearman_client_add_task_background' => 'gearman/gearman.stub', 'gearman_client_add_task_high' => 'gearman/gearman.stub', 'gearman_client_add_task_high_background' => 'gearman/gearman.stub', 'gearman_client_add_task_low' => 'gearman/gearman.stub', 'gearman_client_add_task_low_background' => 'gearman/gearman.stub', 'gearman_client_add_task_status' => 'gearman/gearman.stub', 'gearman_client_clear_fn' => 'gearman/gearman.stub', 'gearman_client_clone' => 'gearman/gearman.stub', 'gearman_client_context' => 'gearman/gearman.stub', 'gearman_client_create' => 'gearman/gearman.stub', 'gearman_client_do' => 'gearman/gearman.stub', 'gearman_client_do_background' => 'gearman/gearman.stub', 'gearman_client_do_high' => 'gearman/gearman.stub', 'gearman_client_do_high_background' => 'gearman/gearman.stub', 'gearman_client_do_job_handle' => 'gearman/gearman.stub', 'gearman_client_do_low' => 'gearman/gearman.stub', 'gearman_client_do_low_background' => 'gearman/gearman.stub', 'gearman_client_do_normal' => 'gearman/gearman.stub', 'gearman_client_do_status' => 'gearman/gearman.stub', 'gearman_client_echo' => 'gearman/gearman.stub', 'gearman_client_errno' => 'gearman/gearman.stub', 'gearman_client_error' => 'gearman/gearman.stub', 'gearman_client_job_status' => 'gearman/gearman.stub', 'gearman_client_options' => 'gearman/gearman.stub', 'gearman_client_remove_options' => 'gearman/gearman.stub', 'gearman_client_return_code' => 'gearman/gearman.stub', 'gearman_client_run_tasks' => 'gearman/gearman.stub', 'gearman_client_set_complete_fn' => 'gearman/gearman.stub', 'gearman_client_set_context' => 'gearman/gearman.stub', 'gearman_client_set_created_fn' => 'gearman/gearman.stub', 'gearman_client_set_data_fn' => 'gearman/gearman.stub', 'gearman_client_set_exception_fn' => 'gearman/gearman.stub', 'gearman_client_set_fail_fn' => 'gearman/gearman.stub', 'gearman_client_set_options' => 'gearman/gearman.stub', 'gearman_client_set_status_fn' => 'gearman/gearman.stub', 'gearman_client_set_timeout' => 'gearman/gearman.stub', 'gearman_client_set_warning_fn' => 'gearman/gearman.stub', 'gearman_client_set_workload_fn' => 'gearman/gearman.stub', 'gearman_client_timeout' => 'gearman/gearman.stub', 'gearman_client_wait' => 'gearman/gearman.stub', 'gearman_job_function_name' => 'gearman/gearman.stub', 'gearman_job_handle' => 'gearman/gearman.stub', 'gearman_job_return_code' => 'gearman/gearman.stub', 'gearman_job_send_complete' => 'gearman/gearman.stub', 'gearman_job_send_data' => 'gearman/gearman.stub', 'gearman_job_send_exception' => 'gearman/gearman.stub', 'gearman_job_send_fail' => 'gearman/gearman.stub', 'gearman_job_send_status' => 'gearman/gearman.stub', 'gearman_job_send_warning' => 'gearman/gearman.stub', 'gearman_job_unique' => 'gearman/gearman.stub', 'gearman_job_workload' => 'gearman/gearman.stub', 'gearman_job_workload_size' => 'gearman/gearman.stub', 'gearman_task_data' => 'gearman/gearman.stub', 'gearman_task_data_size' => 'gearman/gearman.stub', 'gearman_task_denominator' => 'gearman/gearman.stub', 'gearman_task_function_name' => 'gearman/gearman.stub', 'gearman_task_is_known' => 'gearman/gearman.stub', 'gearman_task_is_running' => 'gearman/gearman.stub', 'gearman_task_job_handle' => 'gearman/gearman.stub', 'gearman_task_numerator' => 'gearman/gearman.stub', 'gearman_task_recv_data' => 'gearman/gearman.stub', 'gearman_task_return_code' => 'gearman/gearman.stub', 'gearman_task_send_workload' => 'gearman/gearman.stub', 'gearman_task_unique' => 'gearman/gearman.stub', 'gearman_verbose_name' => 'gearman/gearman.stub', 'gearman_version' => 'gearman/gearman.stub', 'gearman_worker_add_function' => 'gearman/gearman.stub', 'gearman_worker_add_options' => 'gearman/gearman.stub', 'gearman_worker_add_server' => 'gearman/gearman.stub', 'gearman_worker_add_servers' => 'gearman/gearman.stub', 'gearman_worker_clone' => 'gearman/gearman.stub', 'gearman_worker_create' => 'gearman/gearman.stub', 'gearman_worker_echo' => 'gearman/gearman.stub', 'gearman_worker_errno' => 'gearman/gearman.stub', 'gearman_worker_error' => 'gearman/gearman.stub', 'gearman_worker_grab_job' => 'gearman/gearman.stub', 'gearman_worker_options' => 'gearman/gearman.stub', 'gearman_worker_register' => 'gearman/gearman.stub', 'gearman_worker_remove_options' => 'gearman/gearman.stub', 'gearman_worker_return_code' => 'gearman/gearman.stub', 'gearman_worker_set_options' => 'gearman/gearman.stub', 'gearman_worker_set_timeout' => 'gearman/gearman.stub', 'gearman_worker_timeout' => 'gearman/gearman.stub', 'gearman_worker_unregister' => 'gearman/gearman.stub', 'gearman_worker_unregister_all' => 'gearman/gearman.stub', 'gearman_worker_wait' => 'gearman/gearman.stub', 'gearman_worker_work' => 'gearman/gearman.stub', 'geoip_asnum_by_name' => 'geoip/geoip.stub', 'geoip_continent_code_by_name' => 'geoip/geoip.stub', 'geoip_country_code3_by_name' => 'geoip/geoip.stub', 'geoip_country_code_by_name' => 'geoip/geoip.stub', 'geoip_country_name_by_name' => 'geoip/geoip.stub', 'geoip_database_info' => 'geoip/geoip.stub', 'geoip_db_avail' => 'geoip/geoip.stub', 'geoip_db_filename' => 'geoip/geoip.stub', 'geoip_db_get_all_info' => 'geoip/geoip.stub', 'geoip_id_by_name' => 'geoip/geoip.stub', 'geoip_isp_by_name' => 'geoip/geoip.stub', 'geoip_netspeedcell_by_name' => 'geoip/geoip.stub', 'geoip_org_by_name' => 'geoip/geoip.stub', 'geoip_record_by_name' => 'geoip/geoip.stub', 'geoip_region_by_name' => 'geoip/geoip.stub', 'geoip_region_name_by_code' => 'geoip/geoip.stub', 'geoip_setup_custom_directory' => 'geoip/geoip.stub', 'geoip_time_zone_by_country_and_region' => 'geoip/geoip.stub', 'get_browser' => 'standard/standard_7.stub', 'get_call_stack' => 'ZendDebugger/ZendDebugger.stub', 'get_called_class' => 'Core/Core.stub', 'get_cfg_var' => 'standard/standard_3.stub', 'get_class' => 'Core/Core.stub', 'get_class_methods' => 'Core/Core.stub', 'get_class_vars' => 'Core/Core.stub', 'get_current_user' => 'standard/standard_3.stub', 'get_debug_type' => 'standard/standard_9.stub', 'get_declared_classes' => 'Core/Core.stub', 'get_declared_interfaces' => 'Core/Core.stub', 'get_declared_traits' => 'Core/Core.stub', 'get_defined_constants' => 'Core/Core.stub', 'get_defined_functions' => 'Core/Core.stub', 'get_defined_vars' => 'Core/Core.stub', 'get_extension_funcs' => 'Core/Core.stub', 'get_headers' => 'standard/standard_6.stub', 'get_html_translation_table' => 'standard/standard_0.stub', 'get_include_path' => 'standard/standard_4.stub', 'get_included_files' => 'Core/Core.stub', 'get_loaded_extensions' => 'Core/Core.stub', 'get_magic_quotes_gpc' => 'standard/standard_3.stub', 'get_magic_quotes_runtime' => 'standard/standard_3.stub', 'get_mangled_object_vars' => 'standard/standard_9.stub', 'get_meta_tags' => 'standard/standard_6.stub', 'get_object_vars' => 'Core/Core.stub', 'get_parent_class' => 'Core/Core.stub', 'get_required_files' => 'Core/Core.stub', 'get_resource_id' => 'standard/standard_9.stub', 'get_resource_type' => 'Core/Core.stub', 'get_resources' => 'Core/Core.stub', 'getallheaders' => 'standard/standard_4.stub', 'getcwd' => 'standard/standard_7.stub', 'getdate' => 'date/date.stub', 'getdir' => 'standard/standard_7.stub', 'getenv' => 'standard/standard_3.stub', 'gethostbyaddr' => 'standard/standard_4.stub', 'gethostbyname' => 'standard/standard_4.stub', 'gethostbynamel' => 'standard/standard_4.stub', 'gethostname' => 'standard/standard_4.stub', 'getimagesize' => 'standard/standard_0.stub', 'getimagesizefromstring' => 'standard/standard_8.stub', 'getlastmod' => 'standard/standard_3.stub', 'getmxrr' => 'standard/standard_4.stub', 'getmygid' => 'standard/standard_2.stub', 'getmyinode' => 'standard/standard_2.stub', 'getmypid' => 'standard/standard_2.stub', 'getmyuid' => 'standard/standard_2.stub', 'getopt' => 'standard/standard_3.stub', 'getprotobyname' => 'standard/standard_2.stub', 'getprotobynumber' => 'standard/standard_2.stub', 'getrandmax' => 'random/random.stub', 'getrusage' => 'standard/standard_3.stub', 'getservbyname' => 'standard/standard_2.stub', 'getservbyport' => 'standard/standard_2.stub', 'gettext' => 'gettext/gettext.stub', 'gettimeofday' => 'standard/standard_3.stub', 'gettype' => 'standard/standard_5.stub', 'glob' => 'standard/standard_7.stub', 'gmdate' => 'date/date.stub', 'gmmktime' => 'date/date.stub', 'gmp_abs' => 'gmp/gmp.stub', 'gmp_add' => 'gmp/gmp.stub', 'gmp_and' => 'gmp/gmp.stub', 'gmp_binomial' => 'gmp/gmp.stub', 'gmp_clrbit' => 'gmp/gmp.stub', 'gmp_cmp' => 'gmp/gmp.stub', 'gmp_com' => 'gmp/gmp.stub', 'gmp_div' => 'gmp/gmp.stub', 'gmp_div_q' => 'gmp/gmp.stub', 'gmp_div_qr' => 'gmp/gmp.stub', 'gmp_div_r' => 'gmp/gmp.stub', 'gmp_divexact' => 'gmp/gmp.stub', 'gmp_export' => 'gmp/gmp.stub', 'gmp_fact' => 'gmp/gmp.stub', 'gmp_gcd' => 'gmp/gmp.stub', 'gmp_gcdext' => 'gmp/gmp.stub', 'gmp_hamdist' => 'gmp/gmp.stub', 'gmp_import' => 'gmp/gmp.stub', 'gmp_init' => 'gmp/gmp.stub', 'gmp_intval' => 'gmp/gmp.stub', 'gmp_invert' => 'gmp/gmp.stub', 'gmp_jacobi' => 'gmp/gmp.stub', 'gmp_kronecker' => 'gmp/gmp.stub', 'gmp_lcm' => 'gmp/gmp.stub', 'gmp_legendre' => 'gmp/gmp.stub', 'gmp_mod' => 'gmp/gmp.stub', 'gmp_mul' => 'gmp/gmp.stub', 'gmp_neg' => 'gmp/gmp.stub', 'gmp_nextprime' => 'gmp/gmp.stub', 'gmp_or' => 'gmp/gmp.stub', 'gmp_perfect_power' => 'gmp/gmp.stub', 'gmp_perfect_square' => 'gmp/gmp.stub', 'gmp_popcount' => 'gmp/gmp.stub', 'gmp_pow' => 'gmp/gmp.stub', 'gmp_powm' => 'gmp/gmp.stub', 'gmp_prob_prime' => 'gmp/gmp.stub', 'gmp_random' => 'gmp/gmp.stub', 'gmp_random_bits' => 'gmp/gmp.stub', 'gmp_random_range' => 'gmp/gmp.stub', 'gmp_random_seed' => 'gmp/gmp.stub', 'gmp_root' => 'gmp/gmp.stub', 'gmp_rootrem' => 'gmp/gmp.stub', 'gmp_scan0' => 'gmp/gmp.stub', 'gmp_scan1' => 'gmp/gmp.stub', 'gmp_setbit' => 'gmp/gmp.stub', 'gmp_sign' => 'gmp/gmp.stub', 'gmp_sqrt' => 'gmp/gmp.stub', 'gmp_sqrtrem' => 'gmp/gmp.stub', 'gmp_strval' => 'gmp/gmp.stub', 'gmp_sub' => 'gmp/gmp.stub', 'gmp_testbit' => 'gmp/gmp.stub', 'gmp_xor' => 'gmp/gmp.stub', 'gmstrftime' => 'date/date.stub', 'gnupg_adddecryptkey' => 'gnupg/gnupg.stub', 'gnupg_addencryptkey' => 'gnupg/gnupg.stub', 'gnupg_addsignkey' => 'gnupg/gnupg.stub', 'gnupg_cleardecryptkeys' => 'gnupg/gnupg.stub', 'gnupg_clearencryptkeys' => 'gnupg/gnupg.stub', 'gnupg_clearsignkeys' => 'gnupg/gnupg.stub', 'gnupg_decrypt' => 'gnupg/gnupg.stub', 'gnupg_decryptverify' => 'gnupg/gnupg.stub', 'gnupg_deletekey' => 'gnupg/gnupg.stub', 'gnupg_encrypt' => 'gnupg/gnupg.stub', 'gnupg_encryptsign' => 'gnupg/gnupg.stub', 'gnupg_export' => 'gnupg/gnupg.stub', 'gnupg_getengineinfo' => 'gnupg/gnupg.stub', 'gnupg_geterror' => 'gnupg/gnupg.stub', 'gnupg_geterrorinfo' => 'gnupg/gnupg.stub', 'gnupg_getprotocol' => 'gnupg/gnupg.stub', 'gnupg_gettrustlist' => 'gnupg/gnupg.stub', 'gnupg_import' => 'gnupg/gnupg.stub', 'gnupg_init' => 'gnupg/gnupg.stub', 'gnupg_keyinfo' => 'gnupg/gnupg.stub', 'gnupg_listsignatures' => 'gnupg/gnupg.stub', 'gnupg_setarmor' => 'gnupg/gnupg.stub', 'gnupg_seterrormode' => 'gnupg/gnupg.stub', 'gnupg_setsignmode' => 'gnupg/gnupg.stub', 'gnupg_sign' => 'gnupg/gnupg.stub', 'gnupg_verify' => 'gnupg/gnupg.stub', 'go' => 'swoole/functions.stub', 'grapheme_extract' => 'intl/intl.stub', 'grapheme_str_split' => 'intl/intl.stub', 'grapheme_stripos' => 'intl/intl.stub', 'grapheme_stristr' => 'intl/intl.stub', 'grapheme_strlen' => 'intl/intl.stub', 'grapheme_strpos' => 'intl/intl.stub', 'grapheme_strripos' => 'intl/intl.stub', 'grapheme_strrpos' => 'intl/intl.stub', 'grapheme_strstr' => 'intl/intl.stub', 'grapheme_substr' => 'intl/intl.stub', 'gregoriantojd' => 'calendar/calendar.stub', 'gzclose' => 'zlib/zlib.stub', 'gzcompress' => 'zlib/zlib.stub', 'gzdecode' => 'zlib/zlib.stub', 'gzdeflate' => 'zlib/zlib.stub', 'gzencode' => 'zlib/zlib.stub', 'gzeof' => 'zlib/zlib.stub', 'gzfile' => 'zlib/zlib.stub', 'gzgetc' => 'zlib/zlib.stub', 'gzgets' => 'zlib/zlib.stub', 'gzgetss' => 'zlib/zlib.stub', 'gzinflate' => 'zlib/zlib.stub', 'gzopen' => 'zlib/zlib.stub', 'gzpassthru' => 'zlib/zlib.stub', 'gzputs' => 'zlib/zlib.stub', 'gzread' => 'zlib/zlib.stub', 'gzrewind' => 'zlib/zlib.stub', 'gzseek' => 'zlib/zlib.stub', 'gztell' => 'zlib/zlib.stub', 'gzuncompress' => 'zlib/zlib.stub', 'gzwrite' => 'zlib/zlib.stub', 'hash' => 'hash/hash.stub', 'hash_algos' => 'hash/hash.stub', 'hash_copy' => 'hash/hash.stub', 'hash_equals' => 'hash/hash.stub', 'hash_file' => 'hash/hash.stub', 'hash_final' => 'hash/hash.stub', 'hash_hkdf' => 'hash/hash.stub', 'hash_hmac' => 'hash/hash.stub', 'hash_hmac_algos' => 'hash/hash.stub', 'hash_hmac_file' => 'hash/hash.stub', 'hash_init' => 'hash/hash.stub', 'hash_pbkdf2' => 'hash/hash.stub', 'hash_update' => 'hash/hash.stub', 'hash_update_file' => 'hash/hash.stub', 'hash_update_stream' => 'hash/hash.stub', 'header' => 'standard/standard_4.stub', 'header_register_callback' => 'standard/standard_8.stub', 'header_remove' => 'standard/standard_4.stub', 'headers_list' => 'standard/standard_4.stub', 'headers_send' => 'frankenphp/frankenphp.stub', 'headers_sent' => 'standard/standard_4.stub', 'hebrev' => 'standard/standard_1.stub', 'hebrevc' => 'standard/standard_1.stub', 'hex2bin' => 'standard/_standard_manual.stub', 'hexdec' => 'standard/standard_3.stub', 'highlight_file' => 'standard/standard_4.stub', 'highlight_string' => 'standard/standard_4.stub', 'hrtime' => 'standard/standard_4.stub', 'html_entity_decode' => 'standard/standard_0.stub', 'htmlentities' => 'standard/standard_0.stub', 'htmlspecialchars' => 'standard/standard_0.stub', 'htmlspecialchars_decode' => 'standard/standard_0.stub', 'http_build_cookie' => 'http/http.stub', 'http_build_query' => 'standard/standard_2.stub', 'http_build_str' => 'http/http.stub', 'http_build_url' => 'http/http.stub', 'http_cache_etag' => 'http/http.stub', 'http_cache_last_modified' => 'http/http.stub', 'http_chunked_decode' => 'http/http.stub', 'http_clear_last_response_headers' => 'standard/standard_10.stub', 'http_date' => 'http/http.stub', 'http_deflate' => 'http/http.stub', 'http_get' => 'http/http.stub', 'http_get_last_response_headers' => 'standard/standard_10.stub', 'http_get_request_body' => 'http/http.stub', 'http_get_request_body_stream' => 'http/http.stub', 'http_get_request_headers' => 'http/http.stub', 'http_head' => 'http/http.stub', 'http_inflate' => 'http/http.stub', 'http_match_etag' => 'http/http.stub', 'http_match_modified' => 'http/http.stub', 'http_match_request_header' => 'http/http.stub', 'http_negotiate_charset' => 'http/http.stub', 'http_negotiate_content_type' => 'http/http.stub', 'http_negotiate_language' => 'http/http.stub', 'http_parse_cookie' => 'http/http.stub', 'http_parse_headers' => 'http/http.stub', 'http_parse_message' => 'http/http.stub', 'http_parse_params' => 'http/http.stub', 'http_persistent_handles_clean' => 'http/http.stub', 'http_persistent_handles_count' => 'http/http.stub', 'http_persistent_handles_ident' => 'http/http.stub', 'http_post_data' => 'http/http.stub', 'http_post_fields' => 'http/http.stub', 'http_put_data' => 'http/http.stub', 'http_put_file' => 'http/http.stub', 'http_put_stream' => 'http/http.stub', 'http_redirect' => 'http/http.stub', 'http_request' => 'http/http.stub', 'http_request_body_encode' => 'http/http.stub', 'http_request_method_exists' => 'http/http.stub', 'http_request_method_name' => 'http/http.stub', 'http_request_method_register' => 'http/http.stub', 'http_request_method_unregister' => 'http/http.stub', 'http_response_code' => 'standard/_standard_manual.stub', 'http_send_content_disposition' => 'http/http.stub', 'http_send_content_type' => 'http/http.stub', 'http_send_data' => 'http/http.stub', 'http_send_file' => 'http/http.stub', 'http_send_last_modified' => 'http/http.stub', 'http_send_status' => 'http/http.stub', 'http_send_stream' => 'http/http.stub', 'http_support' => 'http/http.stub', 'http_throttle' => 'http/http.stub', 'hypot' => 'standard/standard_3.stub', 'ibase_add_user' => 'interbase/interbase.stub', 'ibase_affected_rows' => 'interbase/interbase.stub', 'ibase_backup' => 'interbase/interbase.stub', 'ibase_blob_add' => 'interbase/interbase.stub', 'ibase_blob_cancel' => 'interbase/interbase.stub', 'ibase_blob_close' => 'interbase/interbase.stub', 'ibase_blob_create' => 'interbase/interbase.stub', 'ibase_blob_echo' => 'interbase/interbase.stub', 'ibase_blob_get' => 'interbase/interbase.stub', 'ibase_blob_import' => 'interbase/interbase.stub', 'ibase_blob_info' => 'interbase/interbase.stub', 'ibase_blob_open' => 'interbase/interbase.stub', 'ibase_close' => 'interbase/interbase.stub', 'ibase_commit' => 'interbase/interbase.stub', 'ibase_commit_ret' => 'interbase/interbase.stub', 'ibase_connect' => 'interbase/interbase.stub', 'ibase_db_info' => 'interbase/interbase.stub', 'ibase_delete_user' => 'interbase/interbase.stub', 'ibase_drop_db' => 'interbase/interbase.stub', 'ibase_errcode' => 'interbase/interbase.stub', 'ibase_errmsg' => 'interbase/interbase.stub', 'ibase_execute' => 'interbase/interbase.stub', 'ibase_fetch_assoc' => 'interbase/interbase.stub', 'ibase_fetch_object' => 'interbase/interbase.stub', 'ibase_fetch_row' => 'interbase/interbase.stub', 'ibase_field_info' => 'interbase/interbase.stub', 'ibase_free_event_handler' => 'interbase/interbase.stub', 'ibase_free_query' => 'interbase/interbase.stub', 'ibase_free_result' => 'interbase/interbase.stub', 'ibase_gen_id' => 'interbase/interbase.stub', 'ibase_maintain_db' => 'interbase/interbase.stub', 'ibase_modify_user' => 'interbase/interbase.stub', 'ibase_name_result' => 'interbase/interbase.stub', 'ibase_num_fields' => 'interbase/interbase.stub', 'ibase_num_params' => 'interbase/interbase.stub', 'ibase_param_info' => 'interbase/interbase.stub', 'ibase_pconnect' => 'interbase/interbase.stub', 'ibase_prepare' => 'interbase/interbase.stub', 'ibase_query' => 'interbase/interbase.stub', 'ibase_restore' => 'interbase/interbase.stub', 'ibase_rollback' => 'interbase/interbase.stub', 'ibase_rollback_ret' => 'interbase/interbase.stub', 'ibase_server_info' => 'interbase/interbase.stub', 'ibase_service_attach' => 'interbase/interbase.stub', 'ibase_service_detach' => 'interbase/interbase.stub', 'ibase_set_event_handler' => 'interbase/interbase.stub', 'ibase_trans' => 'interbase/interbase.stub', 'ibase_wait_event' => 'interbase/interbase.stub', 'iconv' => 'iconv/iconv.stub', 'iconv_get_encoding' => 'iconv/iconv.stub', 'iconv_mime_decode' => 'iconv/iconv.stub', 'iconv_mime_decode_headers' => 'iconv/iconv.stub', 'iconv_mime_encode' => 'iconv/iconv.stub', 'iconv_set_encoding' => 'iconv/iconv.stub', 'iconv_strlen' => 'iconv/iconv.stub', 'iconv_strpos' => 'iconv/iconv.stub', 'iconv_strrpos' => 'iconv/iconv.stub', 'iconv_substr' => 'iconv/iconv.stub', 'idate' => 'date/date.stub', 'idn_to_ascii' => 'intl/intl.stub', 'idn_to_utf8' => 'intl/intl.stub', 'igbinary_serialize' => 'igbinary/igbinary.stub', 'igbinary_unserialize' => 'igbinary/igbinary.stub', 'ignore_user_abort' => 'standard/standard_4.stub', 'image2wbmp' => 'gd/gd.stub', 'image_type_to_extension' => 'standard/standard_0.stub', 'image_type_to_mime_type' => 'standard/standard_0.stub', 'imageaffine' => 'gd/gd.stub', 'imageaffinematrixconcat' => 'gd/gd.stub', 'imageaffinematrixget' => 'gd/gd.stub', 'imagealphablending' => 'gd/gd.stub', 'imageantialias' => 'gd/gd.stub', 'imagearc' => 'gd/gd.stub', 'imageavif' => 'gd/gd.stub', 'imagebmp' => 'gd/gd.stub', 'imagechar' => 'gd/gd.stub', 'imagecharup' => 'gd/gd.stub', 'imagecolorallocate' => 'gd/gd.stub', 'imagecolorallocatealpha' => 'gd/gd.stub', 'imagecolorat' => 'gd/gd.stub', 'imagecolorclosest' => 'gd/gd.stub', 'imagecolorclosestalpha' => 'gd/gd.stub', 'imagecolorclosesthwb' => 'gd/gd.stub', 'imagecolordeallocate' => 'gd/gd.stub', 'imagecolorexact' => 'gd/gd.stub', 'imagecolorexactalpha' => 'gd/gd.stub', 'imagecolormatch' => 'gd/gd.stub', 'imagecolorresolve' => 'gd/gd.stub', 'imagecolorresolvealpha' => 'gd/gd.stub', 'imagecolorset' => 'gd/gd.stub', 'imagecolorsforindex' => 'gd/gd.stub', 'imagecolorstotal' => 'gd/gd.stub', 'imagecolortransparent' => 'gd/gd.stub', 'imageconvolution' => 'gd/gd.stub', 'imagecopy' => 'gd/gd.stub', 'imagecopymerge' => 'gd/gd.stub', 'imagecopymergegray' => 'gd/gd.stub', 'imagecopyresampled' => 'gd/gd.stub', 'imagecopyresized' => 'gd/gd.stub', 'imagecreate' => 'gd/gd.stub', 'imagecreatefromavif' => 'gd/gd.stub', 'imagecreatefrombmp' => 'gd/gd.stub', 'imagecreatefromgd' => 'gd/gd.stub', 'imagecreatefromgd2' => 'gd/gd.stub', 'imagecreatefromgd2part' => 'gd/gd.stub', 'imagecreatefromgif' => 'gd/gd.stub', 'imagecreatefromjpeg' => 'gd/gd.stub', 'imagecreatefrompng' => 'gd/gd.stub', 'imagecreatefromstring' => 'gd/gd.stub', 'imagecreatefromtga' => 'gd/gd.stub', 'imagecreatefromwbmp' => 'gd/gd.stub', 'imagecreatefromwebp' => 'gd/gd.stub', 'imagecreatefromxbm' => 'gd/gd.stub', 'imagecreatefromxpm' => 'gd/gd.stub', 'imagecreatetruecolor' => 'gd/gd.stub', 'imagecrop' => 'gd/gd.stub', 'imagecropauto' => 'gd/gd.stub', 'imagedashedline' => 'gd/gd.stub', 'imagedestroy' => 'gd/gd.stub', 'imageellipse' => 'gd/gd.stub', 'imagefill' => 'gd/gd.stub', 'imagefilledarc' => 'gd/gd.stub', 'imagefilledellipse' => 'gd/gd.stub', 'imagefilledpolygon' => 'gd/gd.stub', 'imagefilledrectangle' => 'gd/gd.stub', 'imagefilltoborder' => 'gd/gd.stub', 'imagefilter' => 'gd/gd.stub', 'imageflip' => 'gd/gd.stub', 'imagefontheight' => 'gd/gd.stub', 'imagefontwidth' => 'gd/gd.stub', 'imageftbbox' => 'gd/gd.stub', 'imagefttext' => 'gd/gd.stub', 'imagegammacorrect' => 'gd/gd.stub', 'imagegd' => 'gd/gd.stub', 'imagegd2' => 'gd/gd.stub', 'imagegetclip' => 'gd/gd.stub', 'imagegetinterpolation' => 'gd/gd.stub', 'imagegif' => 'gd/gd.stub', 'imagegrabscreen' => 'gd/gd.stub', 'imagegrabwindow' => 'gd/gd.stub', 'imageinterlace' => 'gd/gd.stub', 'imageistruecolor' => 'gd/gd.stub', 'imagejpeg' => 'gd/gd.stub', 'imagelayereffect' => 'gd/gd.stub', 'imageline' => 'gd/gd.stub', 'imageloadfont' => 'gd/gd.stub', 'imageopenpolygon' => 'gd/gd.stub', 'imagepalettecopy' => 'gd/gd.stub', 'imagepalettetotruecolor' => 'gd/gd.stub', 'imagepng' => 'gd/gd.stub', 'imagepolygon' => 'gd/gd.stub', 'imagepsbbox' => 'gd/gd.stub', 'imagepsencodefont' => 'gd/gd.stub', 'imagepsextendfont' => 'gd/gd.stub', 'imagepsfreefont' => 'gd/gd.stub', 'imagepsloadfont' => 'gd/gd.stub', 'imagepsslantfont' => 'gd/gd.stub', 'imagepstext' => 'gd/gd.stub', 'imagerectangle' => 'gd/gd.stub', 'imageresolution' => 'gd/gd.stub', 'imagerotate' => 'gd/gd.stub', 'imagesavealpha' => 'gd/gd.stub', 'imagescale' => 'gd/gd.stub', 'imagesetbrush' => 'gd/gd.stub', 'imagesetclip' => 'gd/gd.stub', 'imagesetinterpolation' => 'gd/gd.stub', 'imagesetpixel' => 'gd/gd.stub', 'imagesetstyle' => 'gd/gd.stub', 'imagesetthickness' => 'gd/gd.stub', 'imagesettile' => 'gd/gd.stub', 'imagestring' => 'gd/gd.stub', 'imagestringup' => 'gd/gd.stub', 'imagesx' => 'gd/gd.stub', 'imagesy' => 'gd/gd.stub', 'imagetruecolortopalette' => 'gd/gd.stub', 'imagettfbbox' => 'gd/gd.stub', 'imagettftext' => 'gd/gd.stub', 'imagetypes' => 'gd/gd.stub', 'imagewbmp' => 'gd/gd.stub', 'imagewebp' => 'gd/gd.stub', 'imagexbm' => 'gd/gd.stub', 'imap_8bit' => 'imap/imap.stub', 'imap_alerts' => 'imap/imap.stub', 'imap_append' => 'imap/imap.stub', 'imap_base64' => 'imap/imap.stub', 'imap_binary' => 'imap/imap.stub', 'imap_body' => 'imap/imap.stub', 'imap_bodystruct' => 'imap/imap.stub', 'imap_check' => 'imap/imap.stub', 'imap_clearflag_full' => 'imap/imap.stub', 'imap_close' => 'imap/imap.stub', 'imap_create' => 'imap/imap.stub', 'imap_createmailbox' => 'imap/imap.stub', 'imap_delete' => 'imap/imap.stub', 'imap_deletemailbox' => 'imap/imap.stub', 'imap_errors' => 'imap/imap.stub', 'imap_expunge' => 'imap/imap.stub', 'imap_fetch_overview' => 'imap/imap.stub', 'imap_fetchbody' => 'imap/imap.stub', 'imap_fetchheader' => 'imap/imap.stub', 'imap_fetchmime' => 'imap/imap.stub', 'imap_fetchstructure' => 'imap/imap.stub', 'imap_fetchtext' => 'imap/imap.stub', 'imap_gc' => 'imap/imap.stub', 'imap_get_quota' => 'imap/imap.stub', 'imap_get_quotaroot' => 'imap/imap.stub', 'imap_getacl' => 'imap/imap.stub', 'imap_getannotation' => 'imap/imap.stub', 'imap_getmailboxes' => 'imap/imap.stub', 'imap_getsubscribed' => 'imap/imap.stub', 'imap_header' => 'imap/imap.stub', 'imap_headerinfo' => 'imap/imap.stub', 'imap_headers' => 'imap/imap.stub', 'imap_is_open' => 'imap/imap.stub', 'imap_last_error' => 'imap/imap.stub', 'imap_list' => 'imap/imap.stub', 'imap_listmailbox' => 'imap/imap.stub', 'imap_listscan' => 'imap/imap.stub', 'imap_listsubscribed' => 'imap/imap.stub', 'imap_lsub' => 'imap/imap.stub', 'imap_mail' => 'imap/imap.stub', 'imap_mail_compose' => 'imap/imap.stub', 'imap_mail_copy' => 'imap/imap.stub', 'imap_mail_move' => 'imap/imap.stub', 'imap_mailboxmsginfo' => 'imap/imap.stub', 'imap_mime_header_decode' => 'imap/imap.stub', 'imap_msgno' => 'imap/imap.stub', 'imap_mutf7_to_utf8' => 'imap/imap.stub', 'imap_myrights' => 'imap/imap.stub', 'imap_num_msg' => 'imap/imap.stub', 'imap_num_recent' => 'imap/imap.stub', 'imap_open' => 'imap/imap.stub', 'imap_ping' => 'imap/imap.stub', 'imap_qprint' => 'imap/imap.stub', 'imap_rename' => 'imap/imap.stub', 'imap_renamemailbox' => 'imap/imap.stub', 'imap_reopen' => 'imap/imap.stub', 'imap_rfc822_parse_adrlist' => 'imap/imap.stub', 'imap_rfc822_parse_headers' => 'imap/imap.stub', 'imap_rfc822_write_address' => 'imap/imap.stub', 'imap_savebody' => 'imap/imap.stub', 'imap_scan' => 'imap/imap.stub', 'imap_scanmailbox' => 'imap/imap.stub', 'imap_search' => 'imap/imap.stub', 'imap_set_quota' => 'imap/imap.stub', 'imap_setacl' => 'imap/imap.stub', 'imap_setannotation' => 'imap/imap.stub', 'imap_setflag_full' => 'imap/imap.stub', 'imap_sort' => 'imap/imap.stub', 'imap_status' => 'imap/imap.stub', 'imap_status_current' => 'imap/imap.stub', 'imap_subscribe' => 'imap/imap.stub', 'imap_thread' => 'imap/imap.stub', 'imap_timeout' => 'imap/imap.stub', 'imap_uid' => 'imap/imap.stub', 'imap_undelete' => 'imap/imap.stub', 'imap_unsubscribe' => 'imap/imap.stub', 'imap_utf7_decode' => 'imap/imap.stub', 'imap_utf7_encode' => 'imap/imap.stub', 'imap_utf8' => 'imap/imap.stub', 'imap_utf8_to_mutf7' => 'imap/imap.stub', 'implode' => 'standard/standard_1.stub', 'import_request_variables' => 'standard/standard_3.stub', 'in_array' => 'standard/standard_8.stub', 'inet_ntop' => 'standard/standard_3.stub', 'inet_pton' => 'standard/standard_3.stub', 'inflate_add' => 'zlib/zlib.stub', 'inflate_get_read_len' => 'zlib/zlib.stub', 'inflate_get_status' => 'zlib/zlib.stub', 'inflate_init' => 'zlib/zlib.stub', 'ini_alter' => 'standard/standard_4.stub', 'ini_get' => 'standard/standard_4.stub', 'ini_get_all' => 'standard/standard_4.stub', 'ini_parse_quantity' => 'standard/standard_4.stub', 'ini_restore' => 'standard/standard_4.stub', 'ini_set' => 'standard/standard_4.stub', 'inotify_add_watch' => 'inotify/inotify.stub', 'inotify_init' => 'inotify/inotify.stub', 'inotify_queue_len' => 'inotify/inotify.stub', 'inotify_read' => 'inotify/inotify.stub', 'inotify_rm_watch' => 'inotify/inotify.stub', 'intcal_get_maximum' => 'intl/intl.stub', 'intdiv' => 'standard/standard_3.stub', 'interface_exists' => 'Core/Core.stub', 'intl_error_name' => 'intl/intl.stub', 'intl_get' => 'intl/intl.stub', 'intl_get_error_code' => 'intl/intl.stub', 'intl_get_error_message' => 'intl/intl.stub', 'intl_is_failure' => 'intl/intl.stub', 'intlcal_add' => 'intl/intl.stub', 'intlcal_after' => 'intl/intl.stub', 'intlcal_before' => 'intl/intl.stub', 'intlcal_clear' => 'intl/intl.stub', 'intlcal_create_instance' => 'intl/intl.stub', 'intlcal_equals' => 'intl/intl.stub', 'intlcal_field_difference' => 'intl/intl.stub', 'intlcal_from_date_time' => 'intl/intl.stub', 'intlcal_get' => 'intl/intl.stub', 'intlcal_get_actual_maximum' => 'intl/intl.stub', 'intlcal_get_actual_minimum' => 'intl/intl.stub', 'intlcal_get_available_locales' => 'intl/intl.stub', 'intlcal_get_day_of_week_type' => 'intl/intl.stub', 'intlcal_get_error_code' => 'intl/intl.stub', 'intlcal_get_error_message' => 'intl/intl.stub', 'intlcal_get_first_day_of_week' => 'intl/intl.stub', 'intlcal_get_greatest_minimum' => 'intl/intl.stub', 'intlcal_get_keyword_values_for_locale' => 'intl/intl.stub', 'intlcal_get_least_maximum' => 'intl/intl.stub', 'intlcal_get_locale' => 'intl/intl.stub', 'intlcal_get_maximum' => 'intl/intl.stub', 'intlcal_get_minimal_days_in_first_week' => 'intl/intl.stub', 'intlcal_get_minimum' => 'intl/intl.stub', 'intlcal_get_now' => 'intl/intl.stub', 'intlcal_get_repeated_wall_time_option' => 'intl/intl.stub', 'intlcal_get_skipped_wall_time_option' => 'intl/intl.stub', 'intlcal_get_time' => 'intl/intl.stub', 'intlcal_get_time_zone' => 'intl/intl.stub', 'intlcal_get_type' => 'intl/intl.stub', 'intlcal_get_weekend_transition' => 'intl/intl.stub', 'intlcal_greates_minimum' => 'intl/intl.stub', 'intlcal_in_daylight_time' => 'intl/intl.stub', 'intlcal_is_equivalent_to' => 'intl/intl.stub', 'intlcal_is_lenient' => 'intl/intl.stub', 'intlcal_is_set' => 'intl/intl.stub', 'intlcal_is_weekend' => 'intl/intl.stub', 'intlcal_roll' => 'intl/intl.stub', 'intlcal_set' => 'intl/intl.stub', 'intlcal_set_first_day_of_week' => 'intl/intl.stub', 'intlcal_set_lenient' => 'intl/intl.stub', 'intlcal_set_minimal_days_in_first_week' => 'intl/intl.stub', 'intlcal_set_repeated_wall_time_option' => 'intl/intl.stub', 'intlcal_set_skipped_wall_time_option' => 'intl/intl.stub', 'intlcal_set_time' => 'intl/intl.stub', 'intlcal_set_time_zone' => 'intl/intl.stub', 'intlcal_to_date_time' => 'intl/intl.stub', 'intlgregcal_create_instance' => 'intl/intl.stub', 'intlgregcal_get_gregorian_change' => 'intl/intl.stub', 'intlgregcal_is_leap_year' => 'intl/intl.stub', 'intlgregcal_set_gregorian_change' => 'intl/intl.stub', 'intltz_count_equivalent_ids' => 'intl/intl.stub', 'intltz_create_default' => 'intl/intl.stub', 'intltz_create_enumeration' => 'intl/intl.stub', 'intltz_create_time_zone' => 'intl/intl.stub', 'intltz_create_time_zone_id_enumeration' => 'intl/intl.stub', 'intltz_from_date_time_zone' => 'intl/intl.stub', 'intltz_getGMT' => 'intl/intl.stub', 'intltz_get_canonical_id' => 'intl/intl.stub', 'intltz_get_display_name' => 'intl/intl.stub', 'intltz_get_dst_savings' => 'intl/intl.stub', 'intltz_get_equivalent_id' => 'intl/intl.stub', 'intltz_get_error_code' => 'intl/intl.stub', 'intltz_get_error_message' => 'intl/intl.stub', 'intltz_get_gmt' => 'intl/intl.stub', 'intltz_get_iana_id' => 'intl/intl.stub', 'intltz_get_id' => 'intl/intl.stub', 'intltz_get_id_for_windows_id' => 'intl/intl.stub', 'intltz_get_offset' => 'intl/intl.stub', 'intltz_get_raw_offset' => 'intl/intl.stub', 'intltz_get_region' => 'intl/intl.stub', 'intltz_get_tz_data_version' => 'intl/intl.stub', 'intltz_get_unknown' => 'intl/intl.stub', 'intltz_get_windows_id' => 'intl/intl.stub', 'intltz_has_same_rules' => 'intl/intl.stub', 'intltz_to_date_time_zone' => 'intl/intl.stub', 'intltz_use_daylight_time' => 'intl/intl.stub', 'intlz_create_default' => 'intl/intl.stub', 'intval' => 'standard/standard_5.stub', 'ip2long' => 'standard/standard_3.stub', 'iptcembed' => 'standard/standard_0.stub', 'iptcparse' => 'standard/standard_0.stub', 'is_a' => 'Core/Core.stub', 'is_array' => 'standard/standard_5.stub', 'is_bool' => 'standard/standard_5.stub', 'is_callable' => 'standard/standard_5.stub', 'is_countable' => 'standard/standard_5.stub', 'is_dir' => 'standard/standard_7.stub', 'is_double' => 'standard/standard_5.stub', 'is_executable' => 'standard/standard_7.stub', 'is_file' => 'standard/standard_7.stub', 'is_finite' => 'standard/standard_3.stub', 'is_float' => 'standard/standard_5.stub', 'is_infinite' => 'standard/standard_3.stub', 'is_int' => 'standard/standard_5.stub', 'is_integer' => 'standard/standard_5.stub', 'is_iterable' => 'standard/basic.stub', 'is_link' => 'standard/standard_7.stub', 'is_long' => 'standard/standard_5.stub', 'is_nan' => 'standard/standard_3.stub', 'is_null' => 'standard/standard_5.stub', 'is_numeric' => 'standard/standard_5.stub', 'is_object' => 'standard/standard_5.stub', 'is_readable' => 'standard/standard_7.stub', 'is_real' => 'standard/standard_5.stub', 'is_resource' => 'standard/standard_5.stub', 'is_scalar' => 'standard/standard_5.stub', 'is_soap_fault' => 'soap/soap.stub', 'is_string' => 'standard/standard_5.stub', 'is_subclass_of' => 'Core/Core.stub', 'is_uploaded_file' => 'standard/standard_4.stub', 'is_writable' => 'standard/standard_7.stub', 'is_writeable' => 'standard/standard_7.stub', 'iterator_apply' => 'SPL/SPL_f.stub', 'iterator_count' => 'SPL/SPL_f.stub', 'iterator_to_array' => 'SPL/SPL_f.stub', 'java' => 'zend/zend_f.stub', 'java_last_exception_clear' => 'zend/zend_f.stub', 'java_last_exception_get' => 'zend/zend_f.stub', 'java_reload' => 'zend/zend_f.stub', 'java_require' => 'zend/zend_f.stub', 'java_set_encoding' => 'zend/zend_f.stub', 'java_set_ignore_case' => 'zend/zend_f.stub', 'java_throw_exceptions' => 'zend/zend_f.stub', 'jddayofweek' => 'calendar/calendar.stub', 'jdmonthname' => 'calendar/calendar.stub', 'jdtofrench' => 'calendar/calendar.stub', 'jdtogregorian' => 'calendar/calendar.stub', 'jdtojewish' => 'calendar/calendar.stub', 'jdtojulian' => 'calendar/calendar.stub', 'jdtounix' => 'calendar/calendar.stub', 'jewishtojd' => 'calendar/calendar.stub', 'jobqueue_license_info' => 'zend/zend_f.stub', 'join' => 'standard/standard_1.stub', 'jpeg2wbmp' => 'gd/gd.stub', 'json_decode' => 'json/json.stub', 'json_encode' => 'json/json.stub', 'json_last_error' => 'json/json.stub', 'json_last_error_msg' => 'json/json.stub', 'json_validate' => 'json/json.stub', 'juliantojd' => 'calendar/calendar.stub', 'kafka_err2name' => 'simple_kafka_client/functions.stub', 'kafka_err2str' => 'simple_kafka_client/functions.stub', 'kafka_get_err_descs' => 'simple_kafka_client/functions.stub', 'kafka_offset_tail' => 'simple_kafka_client/functions.stub', 'kafka_thread_cnt' => 'simple_kafka_client/functions.stub', 'key' => 'standard/standard_8.stub', 'key_exists' => 'standard/standard_9.stub', 'krsort' => 'standard/standard_8.stub', 'ksort' => 'standard/standard_8.stub', 'lcfirst' => 'standard/standard_1.stub', 'lcg_value' => 'random/random.stub', 'lchgrp' => 'standard/standard_7.stub', 'lchown' => 'standard/standard_7.stub', 'ldap_8859_to_t61' => 'ldap/ldap.stub', 'ldap_add' => 'ldap/ldap.stub', 'ldap_add_ext' => 'ldap/ldap.stub', 'ldap_bind' => 'ldap/ldap.stub', 'ldap_bind_ext' => 'ldap/ldap.stub', 'ldap_close' => 'ldap/ldap.stub', 'ldap_compare' => 'ldap/ldap.stub', 'ldap_connect' => 'ldap/ldap.stub', 'ldap_control_paged_result' => 'ldap/ldap.stub', 'ldap_control_paged_result_response' => 'ldap/ldap.stub', 'ldap_count_entries' => 'ldap/ldap.stub', 'ldap_count_references' => 'ldap/ldap.stub', 'ldap_delete' => 'ldap/ldap.stub', 'ldap_delete_ext' => 'ldap/ldap.stub', 'ldap_dn2ufn' => 'ldap/ldap.stub', 'ldap_err2str' => 'ldap/ldap.stub', 'ldap_errno' => 'ldap/ldap.stub', 'ldap_error' => 'ldap/ldap.stub', 'ldap_escape' => 'ldap/ldap.stub', 'ldap_exop' => 'ldap/ldap.stub', 'ldap_exop_passwd' => 'ldap/ldap.stub', 'ldap_exop_refresh' => 'ldap/ldap.stub', 'ldap_exop_sync' => 'ldap/ldap.stub', 'ldap_exop_whoami' => 'ldap/ldap.stub', 'ldap_explode_dn' => 'ldap/ldap.stub', 'ldap_first_attribute' => 'ldap/ldap.stub', 'ldap_first_entry' => 'ldap/ldap.stub', 'ldap_first_reference' => 'ldap/ldap.stub', 'ldap_free_result' => 'ldap/ldap.stub', 'ldap_get_attributes' => 'ldap/ldap.stub', 'ldap_get_dn' => 'ldap/ldap.stub', 'ldap_get_entries' => 'ldap/ldap.stub', 'ldap_get_option' => 'ldap/ldap.stub', 'ldap_get_values' => 'ldap/ldap.stub', 'ldap_get_values_len' => 'ldap/ldap.stub', 'ldap_list' => 'ldap/ldap.stub', 'ldap_mod_add' => 'ldap/ldap.stub', 'ldap_mod_add_ext' => 'ldap/ldap.stub', 'ldap_mod_del' => 'ldap/ldap.stub', 'ldap_mod_del_ext' => 'ldap/ldap.stub', 'ldap_mod_replace' => 'ldap/ldap.stub', 'ldap_mod_replace_ext' => 'ldap/ldap.stub', 'ldap_modify' => 'ldap/ldap.stub', 'ldap_modify_batch' => 'ldap/ldap.stub', 'ldap_next_attribute' => 'ldap/ldap.stub', 'ldap_next_entry' => 'ldap/ldap.stub', 'ldap_next_reference' => 'ldap/ldap.stub', 'ldap_parse_exop' => 'ldap/ldap.stub', 'ldap_parse_reference' => 'ldap/ldap.stub', 'ldap_parse_result' => 'ldap/ldap.stub', 'ldap_read' => 'ldap/ldap.stub', 'ldap_rename' => 'ldap/ldap.stub', 'ldap_rename_ext' => 'ldap/ldap.stub', 'ldap_sasl_bind' => 'ldap/ldap.stub', 'ldap_search' => 'ldap/ldap.stub', 'ldap_set_option' => 'ldap/ldap.stub', 'ldap_set_rebind_proc' => 'ldap/ldap.stub', 'ldap_sort' => 'ldap/ldap.stub', 'ldap_start_tls' => 'ldap/ldap.stub', 'ldap_t61_to_8859' => 'ldap/ldap.stub', 'ldap_unbind' => 'ldap/ldap.stub', 'levenshtein' => 'standard/standard_2.stub', 'libvirt_check_version' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_all_domain_stats' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_capabilities' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_emulator' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_encrypted' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_hostname' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_hypervisor' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_information' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_machine_types' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_maxvcpus' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_nic_models' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_secure' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_soundhw_models' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_sysinfo' => 'libvirt-php/libvirt-php.stub', 'libvirt_connect_get_uri' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_attach_device' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_block_commit' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_block_job_abort' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_block_job_info' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_block_job_set_speed' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_block_resize' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_block_stats' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_change_boot_devices' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_change_memory' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_change_vcpus' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_core_dump' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_create' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_create_xml' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_define_xml' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_destroy' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_detach_device' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_disk_add' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_disk_remove' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_autostart' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_block_info' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_connect' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_counts' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_disk_devices' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_id' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_info' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_interface_devices' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_job_info' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_metadata' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_name' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_network_info' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_next_dev_ids' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_screen_dimensions' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_screenshot' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_screenshot_api' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_uuid' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_uuid_string' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_get_xml_desc' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_has_current_snapshot' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_interface_addresses' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_interface_stats' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_is_active' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_is_persistent' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_lookup_by_id' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_lookup_by_name' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_lookup_by_uuid' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_lookup_by_uuid_string' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_managedsave' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_memory_peek' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_memory_stats' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_migrate' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_migrate_to_uri' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_migrate_to_uri2' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_new' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_new_get_vnc' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_nic_add' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_nic_remove' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_qemu_agent_command' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_reboot' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_reset' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_resume' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_send_key_api' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_send_keys' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_send_pointer_event' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_set_autostart' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_set_max_memory' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_set_memory' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_set_memory_flags' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_set_metadata' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_shutdown' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_snapshot_create' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_snapshot_current' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_snapshot_delete' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_snapshot_get_xml' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_snapshot_lookup_by_name' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_snapshot_revert' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_suspend' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_undefine' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_undefine_flags' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_update_device' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_xml_from_native' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_xml_to_native' => 'libvirt-php/libvirt-php.stub', 'libvirt_domain_xml_xpath' => 'libvirt-php/libvirt-php.stub', 'libvirt_get_iso_images' => 'libvirt-php/libvirt-php.stub', 'libvirt_get_last_error' => 'libvirt-php/libvirt-php.stub', 'libvirt_get_last_error_code' => 'libvirt-php/libvirt-php.stub', 'libvirt_get_last_error_domain' => 'libvirt-php/libvirt-php.stub', 'libvirt_has_feature' => 'libvirt-php/libvirt-php.stub', 'libvirt_image_create' => 'libvirt-php/libvirt-php.stub', 'libvirt_image_remove' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_active_domain_ids' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_active_domains' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_active_storagepools' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_all_networks' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_all_nwfilters' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_domain_resources' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_domain_snapshots' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_domains' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_inactive_domains' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_inactive_storagepools' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_networks' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_nodedevs' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_nwfilters' => 'libvirt-php/libvirt-php.stub', 'libvirt_list_storagepools' => 'libvirt-php/libvirt-php.stub', 'libvirt_logfile_set' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_define_xml' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_get' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_get_active' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_get_autostart' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_get_bridge' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_get_information' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_get_name' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_get_uuid' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_get_uuid_string' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_get_xml_desc' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_set_active' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_set_autostart' => 'libvirt-php/libvirt-php.stub', 'libvirt_network_undefine' => 'libvirt-php/libvirt-php.stub', 'libvirt_node_get_cpu_stats' => 'libvirt-php/libvirt-php.stub', 'libvirt_node_get_cpu_stats_for_each_cpu' => 'libvirt-php/libvirt-php.stub', 'libvirt_node_get_free_memory' => 'libvirt-php/libvirt-php.stub', 'libvirt_node_get_info' => 'libvirt-php/libvirt-php.stub', 'libvirt_node_get_mem_stats' => 'libvirt-php/libvirt-php.stub', 'libvirt_nodedev_capabilities' => 'libvirt-php/libvirt-php.stub', 'libvirt_nodedev_get' => 'libvirt-php/libvirt-php.stub', 'libvirt_nodedev_get_information' => 'libvirt-php/libvirt-php.stub', 'libvirt_nodedev_get_xml_desc' => 'libvirt-php/libvirt-php.stub', 'libvirt_nwfilter_define_xml' => 'libvirt-php/libvirt-php.stub', 'libvirt_nwfilter_get_name' => 'libvirt-php/libvirt-php.stub', 'libvirt_nwfilter_get_uuid' => 'libvirt-php/libvirt-php.stub', 'libvirt_nwfilter_get_uuid_string' => 'libvirt-php/libvirt-php.stub', 'libvirt_nwfilter_get_xml_desc' => 'libvirt-php/libvirt-php.stub', 'libvirt_nwfilter_lookup_by_name' => 'libvirt-php/libvirt-php.stub', 'libvirt_nwfilter_lookup_by_uuid_string' => 'libvirt-php/libvirt-php.stub', 'libvirt_nwfilter_undefine' => 'libvirt-php/libvirt-php.stub', 'libvirt_print_binding_resources' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_build' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_create' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_define_xml' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_delete' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_destroy' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_get_autostart' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_get_info' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_get_name' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_get_uuid_string' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_get_volume_count' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_get_xml_desc' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_is_active' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_list_volumes' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_lookup_by_name' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_lookup_by_uuid_string' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_lookup_by_volume' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_refresh' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_set_autostart' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagepool_undefine' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagevolume_create_xml' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagevolume_create_xml_from' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagevolume_delete' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagevolume_download' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagevolume_get_info' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagevolume_get_name' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagevolume_get_path' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagevolume_get_xml_desc' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagevolume_lookup_by_name' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagevolume_lookup_by_path' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagevolume_resize' => 'libvirt-php/libvirt-php.stub', 'libvirt_storagevolume_upload' => 'libvirt-php/libvirt-php.stub', 'libvirt_stream_abort' => 'libvirt-php/libvirt-php.stub', 'libvirt_stream_close' => 'libvirt-php/libvirt-php.stub', 'libvirt_stream_create' => 'libvirt-php/libvirt-php.stub', 'libvirt_stream_finish' => 'libvirt-php/libvirt-php.stub', 'libvirt_stream_recv' => 'libvirt-php/libvirt-php.stub', 'libvirt_stream_send' => 'libvirt-php/libvirt-php.stub', 'libvirt_version' => 'libvirt-php/libvirt-php.stub', 'libxml_clear_errors' => 'libxml/libxml.stub', 'libxml_disable_entity_loader' => 'libxml/libxml.stub', 'libxml_get_errors' => 'libxml/libxml.stub', 'libxml_get_external_entity_loader' => 'libxml/libxml.stub', 'libxml_get_last_error' => 'libxml/libxml.stub', 'libxml_set_external_entity_loader' => 'libxml/libxml.stub', 'libxml_set_streams_context' => 'libxml/libxml.stub', 'libxml_use_internal_errors' => 'libxml/libxml.stub', 'link' => 'standard/standard_2.stub', 'linkinfo' => 'standard/standard_2.stub', 'locale_accept_from_http' => 'intl/intl.stub', 'locale_canonicalize' => 'intl/intl.stub', 'locale_compose' => 'intl/intl.stub', 'locale_filter_matches' => 'intl/intl.stub', 'locale_get_all_variants' => 'intl/intl.stub', 'locale_get_default' => 'intl/intl.stub', 'locale_get_display_language' => 'intl/intl.stub', 'locale_get_display_name' => 'intl/intl.stub', 'locale_get_display_region' => 'intl/intl.stub', 'locale_get_display_script' => 'intl/intl.stub', 'locale_get_display_variant' => 'intl/intl.stub', 'locale_get_keywords' => 'intl/intl.stub', 'locale_get_primary_language' => 'intl/intl.stub', 'locale_get_region' => 'intl/intl.stub', 'locale_get_script' => 'intl/intl.stub', 'locale_lookup' => 'intl/intl.stub', 'locale_parse' => 'intl/intl.stub', 'locale_set_default' => 'intl/intl.stub', 'localeconv' => 'standard/standard_1.stub', 'localtime' => 'date/date.stub', 'log' => 'standard/standard_3.stub', 'log10' => 'standard/standard_3.stub', 'log1p' => 'standard/standard_3.stub', 'long2ip' => 'standard/standard_3.stub', 'lstat' => 'standard/standard_7.stub', 'ltrim' => 'standard/standard_1.stub', 'lzf_compress' => 'lzf/lzf.stub', 'lzf_decompress' => 'lzf/lzf.stub', 'lzf_optimized_for' => 'lzf/lzf.stub', 'magic_quotes_runtime' => 'standard/standard_3.stub', 'mail' => 'standard/standard_7.stub', 'mailparse_determine_best_xfer_encoding' => 'mailparse/mailparse.stub', 'mailparse_msg_create' => 'mailparse/mailparse.stub', 'mailparse_msg_extract_part' => 'mailparse/mailparse.stub', 'mailparse_msg_extract_part_file' => 'mailparse/mailparse.stub', 'mailparse_msg_extract_whole_part_file' => 'mailparse/mailparse.stub', 'mailparse_msg_free' => 'mailparse/mailparse.stub', 'mailparse_msg_get_part' => 'mailparse/mailparse.stub', 'mailparse_msg_get_part_data' => 'mailparse/mailparse.stub', 'mailparse_msg_get_structure' => 'mailparse/mailparse.stub', 'mailparse_msg_parse' => 'mailparse/mailparse.stub', 'mailparse_msg_parse_file' => 'mailparse/mailparse.stub', 'mailparse_rfc822_parse_addresses' => 'mailparse/mailparse.stub', 'mailparse_stream_encode' => 'mailparse/mailparse.stub', 'mailparse_uudecode_all' => 'mailparse/mailparse.stub', 'max' => 'standard/standard_8.stub', 'mb_check_encoding' => 'mbstring/mbstring.stub', 'mb_chr' => 'mbstring/mbstring.stub', 'mb_convert_case' => 'mbstring/mbstring.stub', 'mb_convert_encoding' => 'mbstring/mbstring.stub', 'mb_convert_kana' => 'mbstring/mbstring.stub', 'mb_convert_variables' => 'mbstring/mbstring.stub', 'mb_decode_mimeheader' => 'mbstring/mbstring.stub', 'mb_decode_numericentity' => 'mbstring/mbstring.stub', 'mb_detect_encoding' => 'mbstring/mbstring.stub', 'mb_detect_order' => 'mbstring/mbstring.stub', 'mb_encode_mimeheader' => 'mbstring/mbstring.stub', 'mb_encode_numericentity' => 'mbstring/mbstring.stub', 'mb_encoding_aliases' => 'mbstring/mbstring.stub', 'mb_ereg' => 'mbstring/mbstring.stub', 'mb_ereg_match' => 'mbstring/mbstring.stub', 'mb_ereg_replace' => 'mbstring/mbstring.stub', 'mb_ereg_replace_callback' => 'mbstring/mbstring.stub', 'mb_ereg_search' => 'mbstring/mbstring.stub', 'mb_ereg_search_getpos' => 'mbstring/mbstring.stub', 'mb_ereg_search_getregs' => 'mbstring/mbstring.stub', 'mb_ereg_search_init' => 'mbstring/mbstring.stub', 'mb_ereg_search_pos' => 'mbstring/mbstring.stub', 'mb_ereg_search_regs' => 'mbstring/mbstring.stub', 'mb_ereg_search_setpos' => 'mbstring/mbstring.stub', 'mb_eregi' => 'mbstring/mbstring.stub', 'mb_eregi_replace' => 'mbstring/mbstring.stub', 'mb_get_info' => 'mbstring/mbstring.stub', 'mb_http_input' => 'mbstring/mbstring.stub', 'mb_http_output' => 'mbstring/mbstring.stub', 'mb_internal_encoding' => 'mbstring/mbstring.stub', 'mb_language' => 'mbstring/mbstring.stub', 'mb_lcfirst' => 'mbstring/mbstring.stub', 'mb_list_encodings' => 'mbstring/mbstring.stub', 'mb_ltrim' => 'mbstring/mbstring.stub', 'mb_ord' => 'mbstring/mbstring.stub', 'mb_output_handler' => 'mbstring/mbstring.stub', 'mb_parse_str' => 'mbstring/mbstring.stub', 'mb_preferred_mime_name' => 'mbstring/mbstring.stub', 'mb_regex_encoding' => 'mbstring/mbstring.stub', 'mb_regex_set_options' => 'mbstring/mbstring.stub', 'mb_rtrim' => 'mbstring/mbstring.stub', 'mb_scrub' => 'mbstring/mbstring.stub', 'mb_send_mail' => 'mbstring/mbstring.stub', 'mb_split' => 'mbstring/mbstring.stub', 'mb_str_pad' => 'mbstring/mbstring.stub', 'mb_str_split' => 'mbstring/mbstring.stub', 'mb_strcut' => 'mbstring/mbstring.stub', 'mb_strimwidth' => 'mbstring/mbstring.stub', 'mb_stripos' => 'mbstring/mbstring.stub', 'mb_stristr' => 'mbstring/mbstring.stub', 'mb_strlen' => 'mbstring/mbstring.stub', 'mb_strpos' => 'mbstring/mbstring.stub', 'mb_strrchr' => 'mbstring/mbstring.stub', 'mb_strrichr' => 'mbstring/mbstring.stub', 'mb_strripos' => 'mbstring/mbstring.stub', 'mb_strrpos' => 'mbstring/mbstring.stub', 'mb_strstr' => 'mbstring/mbstring.stub', 'mb_strtolower' => 'mbstring/mbstring.stub', 'mb_strtoupper' => 'mbstring/mbstring.stub', 'mb_strwidth' => 'mbstring/mbstring.stub', 'mb_substitute_character' => 'mbstring/mbstring.stub', 'mb_substr' => 'mbstring/mbstring.stub', 'mb_substr_count' => 'mbstring/mbstring.stub', 'mb_trim' => 'mbstring/mbstring.stub', 'mb_ucfirst' => 'mbstring/mbstring.stub', 'mbereg' => 'mbstring/mbstring.stub', 'mbereg_match' => 'mbstring/mbstring.stub', 'mbereg_replace' => 'mbstring/mbstring.stub', 'mbereg_search' => 'mbstring/mbstring.stub', 'mbereg_search_getpos' => 'mbstring/mbstring.stub', 'mbereg_search_getregs' => 'mbstring/mbstring.stub', 'mbereg_search_init' => 'mbstring/mbstring.stub', 'mbereg_search_pos' => 'mbstring/mbstring.stub', 'mbereg_search_regs' => 'mbstring/mbstring.stub', 'mbereg_search_setpos' => 'mbstring/mbstring.stub', 'mberegi' => 'mbstring/mbstring.stub', 'mberegi_replace' => 'mbstring/mbstring.stub', 'mbregex_encoding' => 'mbstring/mbstring.stub', 'mbsplit' => 'mbstring/mbstring.stub', 'mcrypt_cbc' => 'mcrypt/mcrypt.stub', 'mcrypt_cfb' => 'mcrypt/mcrypt.stub', 'mcrypt_create_iv' => 'mcrypt/mcrypt.stub', 'mcrypt_decrypt' => 'mcrypt/mcrypt.stub', 'mcrypt_ecb' => 'mcrypt/mcrypt.stub', 'mcrypt_enc_get_algorithms_name' => 'mcrypt/mcrypt.stub', 'mcrypt_enc_get_block_size' => 'mcrypt/mcrypt.stub', 'mcrypt_enc_get_iv_size' => 'mcrypt/mcrypt.stub', 'mcrypt_enc_get_key_size' => 'mcrypt/mcrypt.stub', 'mcrypt_enc_get_modes_name' => 'mcrypt/mcrypt.stub', 'mcrypt_enc_get_supported_key_sizes' => 'mcrypt/mcrypt.stub', 'mcrypt_enc_is_block_algorithm' => 'mcrypt/mcrypt.stub', 'mcrypt_enc_is_block_algorithm_mode' => 'mcrypt/mcrypt.stub', 'mcrypt_enc_is_block_mode' => 'mcrypt/mcrypt.stub', 'mcrypt_enc_self_test' => 'mcrypt/mcrypt.stub', 'mcrypt_encrypt' => 'mcrypt/mcrypt.stub', 'mcrypt_generic' => 'mcrypt/mcrypt.stub', 'mcrypt_generic_deinit' => 'mcrypt/mcrypt.stub', 'mcrypt_generic_end' => 'mcrypt/mcrypt.stub', 'mcrypt_generic_init' => 'mcrypt/mcrypt.stub', 'mcrypt_get_block_size' => 'mcrypt/mcrypt.stub', 'mcrypt_get_cipher_name' => 'mcrypt/mcrypt.stub', 'mcrypt_get_iv_size' => 'mcrypt/mcrypt.stub', 'mcrypt_get_key_size' => 'mcrypt/mcrypt.stub', 'mcrypt_list_algorithms' => 'mcrypt/mcrypt.stub', 'mcrypt_list_modes' => 'mcrypt/mcrypt.stub', 'mcrypt_module_close' => 'mcrypt/mcrypt.stub', 'mcrypt_module_get_algo_block_size' => 'mcrypt/mcrypt.stub', 'mcrypt_module_get_algo_key_size' => 'mcrypt/mcrypt.stub', 'mcrypt_module_get_supported_key_sizes' => 'mcrypt/mcrypt.stub', 'mcrypt_module_is_block_algorithm' => 'mcrypt/mcrypt.stub', 'mcrypt_module_is_block_algorithm_mode' => 'mcrypt/mcrypt.stub', 'mcrypt_module_is_block_mode' => 'mcrypt/mcrypt.stub', 'mcrypt_module_open' => 'mcrypt/mcrypt.stub', 'mcrypt_module_self_test' => 'mcrypt/mcrypt.stub', 'mcrypt_ofb' => 'mcrypt/mcrypt.stub', 'md5' => 'standard/standard_0.stub', 'md5_file' => 'standard/standard_0.stub', 'mdecrypt_generic' => 'mcrypt/mcrypt.stub', 'memcache_add' => 'memcache/memcache.stub', 'memcache_add_server' => 'memcache/memcache.stub', 'memcache_append' => 'memcache/memcache.stub', 'memcache_cas' => 'memcache/memcache.stub', 'memcache_close' => 'memcache/memcache.stub', 'memcache_connect' => 'memcache/memcache.stub', 'memcache_debug' => 'memcache/memcache.stub', 'memcache_decrement' => 'memcache/memcache.stub', 'memcache_delete' => 'memcache/memcache.stub', 'memcache_flush' => 'memcache/memcache.stub', 'memcache_get' => 'memcache/memcache.stub', 'memcache_get_extended_stats' => 'memcache/memcache.stub', 'memcache_get_server_status' => 'memcache/memcache.stub', 'memcache_get_stats' => 'memcache/memcache.stub', 'memcache_get_version' => 'memcache/memcache.stub', 'memcache_increment' => 'memcache/memcache.stub', 'memcache_pconnect' => 'memcache/memcache.stub', 'memcache_prepend' => 'memcache/memcache.stub', 'memcache_replace' => 'memcache/memcache.stub', 'memcache_set' => 'memcache/memcache.stub', 'memcache_set_compress_threshold' => 'memcache/memcache.stub', 'memcache_set_failure_callback' => 'memcache/memcache.stub', 'memcache_set_server_params' => 'memcache/memcache.stub', 'meminfo_dump' => 'meminfo/meminfo.stub', 'memory_get_peak_usage' => 'standard/standard_4.stub', 'memory_get_usage' => 'standard/standard_4.stub', 'memory_reset_peak_usage' => 'standard/standard_4.stub', 'metaphone' => 'standard/standard_8.stub', 'method_exists' => 'Core/Core.stub', 'mhash' => 'hash/hash.stub', 'mhash_count' => 'hash/hash.stub', 'mhash_get_block_size' => 'hash/hash.stub', 'mhash_get_hash_name' => 'hash/hash.stub', 'mhash_keygen_s2k' => 'hash/hash.stub', 'microtime' => 'standard/standard_3.stub', 'mime_content_type' => 'fileinfo/fileinfo.stub', 'min' => 'standard/standard_8.stub', 'ming_keypress' => 'ming/ming.stub', 'ming_setcubicthreshold' => 'ming/ming.stub', 'ming_setscale' => 'ming/ming.stub', 'ming_setswfcompression' => 'ming/ming.stub', 'ming_useconstants' => 'ming/ming.stub', 'ming_useswfversion' => 'ming/ming.stub', 'mkdir' => 'standard/standard_5.stub', 'mktime' => 'date/date.stub', 'money_format' => 'standard/standard_1.stub', 'monitor_custom_event' => 'zend/zend.stub', 'monitor_httperror_event' => 'zend/zend.stub', 'monitor_license_info' => 'zend/zend.stub', 'monitor_pass_error' => 'zend/zend.stub', 'monitor_set_aggregation_hint' => 'zend/zend.stub', 'move_uploaded_file' => 'standard/standard_4.stub', 'mqseries_back' => 'mqseries/mqseries.stub', 'mqseries_begin' => 'mqseries/mqseries.stub', 'mqseries_close' => 'mqseries/mqseries.stub', 'mqseries_cmit' => 'mqseries/mqseries.stub', 'mqseries_conn' => 'mqseries/mqseries.stub', 'mqseries_connx' => 'mqseries/mqseries.stub', 'mqseries_disc' => 'mqseries/mqseries.stub', 'mqseries_get' => 'mqseries/mqseries.stub', 'mqseries_inq' => 'mqseries/mqseries.stub', 'mqseries_open' => 'mqseries/mqseries.stub', 'mqseries_put' => 'mqseries/mqseries.stub', 'mqseries_put1' => 'mqseries/mqseries.stub', 'mqseries_set' => 'mqseries/mqseries.stub', 'mqseries_strerror' => 'mqseries/mqseries.stub', 'ms_GetErrorObj' => 'mapscript/mapscript.stub', 'ms_GetVersion' => 'mapscript/mapscript.stub', 'ms_GetVersionInt' => 'mapscript/mapscript.stub', 'ms_ResetErrorList' => 'mapscript/mapscript.stub', 'ms_TokenizeMap' => 'mapscript/mapscript.stub', 'ms_iogetStdoutBufferBytes' => 'mapscript/mapscript.stub', 'ms_iogetstdoutbufferstring' => 'mapscript/mapscript.stub', 'ms_ioinstallstdinfrombuffer' => 'mapscript/mapscript.stub', 'ms_ioinstallstdouttobuffer' => 'mapscript/mapscript.stub', 'ms_ioresethandlers' => 'mapscript/mapscript.stub', 'ms_iostripstdoutbuffercontentheaders' => 'mapscript/mapscript.stub', 'ms_iostripstdoutbuffercontenttype' => 'mapscript/mapscript.stub', 'msg_get_queue' => 'sysvmsg/sysvmsg.stub', 'msg_queue_exists' => 'sysvmsg/sysvmsg.stub', 'msg_receive' => 'sysvmsg/sysvmsg.stub', 'msg_remove_queue' => 'sysvmsg/sysvmsg.stub', 'msg_send' => 'sysvmsg/sysvmsg.stub', 'msg_set_queue' => 'sysvmsg/sysvmsg.stub', 'msg_stat_queue' => 'sysvmsg/sysvmsg.stub', 'msgfmt_create' => 'intl/intl.stub', 'msgfmt_format' => 'intl/intl.stub', 'msgfmt_format_message' => 'intl/intl.stub', 'msgfmt_get_error_code' => 'intl/intl.stub', 'msgfmt_get_error_message' => 'intl/intl.stub', 'msgfmt_get_locale' => 'intl/intl.stub', 'msgfmt_get_pattern' => 'intl/intl.stub', 'msgfmt_parse' => 'intl/intl.stub', 'msgfmt_parse_message' => 'intl/intl.stub', 'msgfmt_set_pattern' => 'intl/intl.stub', 'msgpack_pack' => 'msgpack/msgpack.stub', 'msgpack_serialize' => 'msgpack/msgpack.stub', 'msgpack_unpack' => 'msgpack/msgpack.stub', 'msgpack_unserialize' => 'msgpack/msgpack.stub', 'mssql_bind' => 'mssql/mssql.stub', 'mssql_close' => 'mssql/mssql.stub', 'mssql_connect' => 'mssql/mssql.stub', 'mssql_data_seek' => 'mssql/mssql.stub', 'mssql_execute' => 'mssql/mssql.stub', 'mssql_fetch_array' => 'mssql/mssql.stub', 'mssql_fetch_assoc' => 'mssql/mssql.stub', 'mssql_fetch_batch' => 'mssql/mssql.stub', 'mssql_fetch_field' => 'mssql/mssql.stub', 'mssql_fetch_object' => 'mssql/mssql.stub', 'mssql_fetch_row' => 'mssql/mssql.stub', 'mssql_field_length' => 'mssql/mssql.stub', 'mssql_field_name' => 'mssql/mssql.stub', 'mssql_field_seek' => 'mssql/mssql.stub', 'mssql_field_type' => 'mssql/mssql.stub', 'mssql_free_result' => 'mssql/mssql.stub', 'mssql_free_statement' => 'mssql/mssql.stub', 'mssql_get_last_message' => 'mssql/mssql.stub', 'mssql_guid_string' => 'mssql/mssql.stub', 'mssql_init' => 'mssql/mssql.stub', 'mssql_min_error_severity' => 'mssql/mssql.stub', 'mssql_min_message_severity' => 'mssql/mssql.stub', 'mssql_next_result' => 'mssql/mssql.stub', 'mssql_num_fields' => 'mssql/mssql.stub', 'mssql_num_rows' => 'mssql/mssql.stub', 'mssql_pconnect' => 'mssql/mssql.stub', 'mssql_query' => 'mssql/mssql.stub', 'mssql_result' => 'mssql/mssql.stub', 'mssql_rows_affected' => 'mssql/mssql.stub', 'mssql_select_db' => 'mssql/mssql.stub', 'mt_getrandmax' => 'random/random.stub', 'mt_rand' => 'random/random.stub', 'mt_srand' => 'random/random.stub', 'mysql' => 'mysql/mysql.stub', 'mysql_affected_rows' => 'mysql/mysql.stub', 'mysql_client_encoding' => 'mysql/mysql.stub', 'mysql_close' => 'mysql/mysql.stub', 'mysql_connect' => 'mysql/mysql.stub', 'mysql_data_seek' => 'mysql/mysql.stub', 'mysql_db_name' => 'mysql/mysql.stub', 'mysql_db_query' => 'mysql/mysql.stub', 'mysql_dbname' => 'mysql/mysql.stub', 'mysql_errno' => 'mysql/mysql.stub', 'mysql_error' => 'mysql/mysql.stub', 'mysql_escape_string' => 'mysql/mysql.stub', 'mysql_fetch_array' => 'mysql/mysql.stub', 'mysql_fetch_assoc' => 'mysql/mysql.stub', 'mysql_fetch_field' => 'mysql/mysql.stub', 'mysql_fetch_lengths' => 'mysql/mysql.stub', 'mysql_fetch_object' => 'mysql/mysql.stub', 'mysql_fetch_row' => 'mysql/mysql.stub', 'mysql_field_flags' => 'mysql/mysql.stub', 'mysql_field_len' => 'mysql/mysql.stub', 'mysql_field_name' => 'mysql/mysql.stub', 'mysql_field_seek' => 'mysql/mysql.stub', 'mysql_field_table' => 'mysql/mysql.stub', 'mysql_field_type' => 'mysql/mysql.stub', 'mysql_fieldflags' => 'mysql/mysql.stub', 'mysql_fieldlen' => 'mysql/mysql.stub', 'mysql_fieldname' => 'mysql/mysql.stub', 'mysql_fieldtable' => 'mysql/mysql.stub', 'mysql_fieldtype' => 'mysql/mysql.stub', 'mysql_free_result' => 'mysql/mysql.stub', 'mysql_freeresult' => 'mysql/mysql.stub', 'mysql_get_client_info' => 'mysql/mysql.stub', 'mysql_get_host_info' => 'mysql/mysql.stub', 'mysql_get_proto_info' => 'mysql/mysql.stub', 'mysql_get_server_info' => 'mysql/mysql.stub', 'mysql_info' => 'mysql/mysql.stub', 'mysql_insert_id' => 'mysql/mysql.stub', 'mysql_list_dbs' => 'mysql/mysql.stub', 'mysql_list_fields' => 'mysql/mysql.stub', 'mysql_list_processes' => 'mysql/mysql.stub', 'mysql_list_tables' => 'mysql/mysql.stub', 'mysql_listdbs' => 'mysql/mysql.stub', 'mysql_listfields' => 'mysql/mysql.stub', 'mysql_listtables' => 'mysql/mysql.stub', 'mysql_num_fields' => 'mysql/mysql.stub', 'mysql_num_rows' => 'mysql/mysql.stub', 'mysql_numfields' => 'mysql/mysql.stub', 'mysql_numrows' => 'mysql/mysql.stub', 'mysql_pconnect' => 'mysql/mysql.stub', 'mysql_ping' => 'mysql/mysql.stub', 'mysql_query' => 'mysql/mysql.stub', 'mysql_real_escape_string' => 'mysql/mysql.stub', 'mysql_result' => 'mysql/mysql.stub', 'mysql_select_db' => 'mysql/mysql.stub', 'mysql_selectdb' => 'mysql/mysql.stub', 'mysql_set_charset' => 'mysql/mysql.stub', 'mysql_stat' => 'mysql/mysql.stub', 'mysql_table_name' => 'mysql/mysql.stub', 'mysql_tablename' => 'mysql/mysql.stub', 'mysql_thread_id' => 'mysql/mysql.stub', 'mysql_unbuffered_query' => 'mysql/mysql.stub', 'mysql_xdevapi\\expression' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysql_xdevapi\\getSession' => 'mysql_xdevapi/mysql_xdevapi.stub', 'mysqli_affected_rows' => 'mysqli/mysqli.stub', 'mysqli_autocommit' => 'mysqli/mysqli.stub', 'mysqli_begin_transaction' => 'mysqli/mysqli.stub', 'mysqli_bind_param' => 'mysqli/mysqli.stub', 'mysqli_bind_result' => 'mysqli/mysqli.stub', 'mysqli_change_user' => 'mysqli/mysqli.stub', 'mysqli_character_set_name' => 'mysqli/mysqli.stub', 'mysqli_client_encoding' => 'mysqli/mysqli.stub', 'mysqli_close' => 'mysqli/mysqli.stub', 'mysqli_commit' => 'mysqli/mysqli.stub', 'mysqli_connect' => 'mysqli/mysqli.stub', 'mysqli_connect_errno' => 'mysqli/mysqli.stub', 'mysqli_connect_error' => 'mysqli/mysqli.stub', 'mysqli_data_seek' => 'mysqli/mysqli.stub', 'mysqli_debug' => 'mysqli/mysqli.stub', 'mysqli_dump_debug_info' => 'mysqli/mysqli.stub', 'mysqli_errno' => 'mysqli/mysqli.stub', 'mysqli_error' => 'mysqli/mysqli.stub', 'mysqli_error_list' => 'mysqli/mysqli.stub', 'mysqli_escape_string' => 'mysqli/mysqli.stub', 'mysqli_execute' => 'mysqli/mysqli.stub', 'mysqli_execute_query' => 'mysqli/mysqli.stub', 'mysqli_fetch' => 'mysqli/mysqli.stub', 'mysqli_fetch_all' => 'mysqli/mysqli.stub', 'mysqli_fetch_array' => 'mysqli/mysqli.stub', 'mysqli_fetch_assoc' => 'mysqli/mysqli.stub', 'mysqli_fetch_column' => 'mysqli/mysqli.stub', 'mysqli_fetch_field' => 'mysqli/mysqli.stub', 'mysqli_fetch_field_direct' => 'mysqli/mysqli.stub', 'mysqli_fetch_fields' => 'mysqli/mysqli.stub', 'mysqli_fetch_lengths' => 'mysqli/mysqli.stub', 'mysqli_fetch_object' => 'mysqli/mysqli.stub', 'mysqli_fetch_row' => 'mysqli/mysqli.stub', 'mysqli_field_count' => 'mysqli/mysqli.stub', 'mysqli_field_seek' => 'mysqli/mysqli.stub', 'mysqli_field_tell' => 'mysqli/mysqli.stub', 'mysqli_free_result' => 'mysqli/mysqli.stub', 'mysqli_get_cache_stats' => 'mysqli/mysqli.stub', 'mysqli_get_charset' => 'mysqli/mysqli.stub', 'mysqli_get_client_info' => 'mysqli/mysqli.stub', 'mysqli_get_client_stats' => 'mysqli/mysqli.stub', 'mysqli_get_client_version' => 'mysqli/mysqli.stub', 'mysqli_get_connection_stats' => 'mysqli/mysqli.stub', 'mysqli_get_host_info' => 'mysqli/mysqli.stub', 'mysqli_get_links_stats' => 'mysqli/mysqli.stub', 'mysqli_get_metadata' => 'mysqli/mysqli.stub', 'mysqli_get_proto_info' => 'mysqli/mysqli.stub', 'mysqli_get_server_info' => 'mysqli/mysqli.stub', 'mysqli_get_server_version' => 'mysqli/mysqli.stub', 'mysqli_get_warnings' => 'mysqli/mysqli.stub', 'mysqli_info' => 'mysqli/mysqli.stub', 'mysqli_init' => 'mysqli/mysqli.stub', 'mysqli_insert_id' => 'mysqli/mysqli.stub', 'mysqli_kill' => 'mysqli/mysqli.stub', 'mysqli_more_results' => 'mysqli/mysqli.stub', 'mysqli_multi_query' => 'mysqli/mysqli.stub', 'mysqli_next_result' => 'mysqli/mysqli.stub', 'mysqli_num_fields' => 'mysqli/mysqli.stub', 'mysqli_num_rows' => 'mysqli/mysqli.stub', 'mysqli_options' => 'mysqli/mysqli.stub', 'mysqli_param_count' => 'mysqli/mysqli.stub', 'mysqli_ping' => 'mysqli/mysqli.stub', 'mysqli_poll' => 'mysqli/mysqli.stub', 'mysqli_prepare' => 'mysqli/mysqli.stub', 'mysqli_query' => 'mysqli/mysqli.stub', 'mysqli_real_connect' => 'mysqli/mysqli.stub', 'mysqli_real_escape_string' => 'mysqli/mysqli.stub', 'mysqli_real_query' => 'mysqli/mysqli.stub', 'mysqli_reap_async_query' => 'mysqli/mysqli.stub', 'mysqli_refresh' => 'mysqli/mysqli.stub', 'mysqli_release_savepoint' => 'mysqli/mysqli.stub', 'mysqli_report' => 'mysqli/mysqli.stub', 'mysqli_rollback' => 'mysqli/mysqli.stub', 'mysqli_savepoint' => 'mysqli/mysqli.stub', 'mysqli_select_db' => 'mysqli/mysqli.stub', 'mysqli_send_long_data' => 'mysqli/mysqli.stub', 'mysqli_set_charset' => 'mysqli/mysqli.stub', 'mysqli_set_local_infile_default' => 'mysqli/mysqli.stub', 'mysqli_set_local_infile_handler' => 'mysqli/mysqli.stub', 'mysqli_set_opt' => 'mysqli/mysqli.stub', 'mysqli_sqlstate' => 'mysqli/mysqli.stub', 'mysqli_ssl_set' => 'mysqli/mysqli.stub', 'mysqli_stat' => 'mysqli/mysqli.stub', 'mysqli_stmt_affected_rows' => 'mysqli/mysqli.stub', 'mysqli_stmt_attr_get' => 'mysqli/mysqli.stub', 'mysqli_stmt_attr_set' => 'mysqli/mysqli.stub', 'mysqli_stmt_bind_param' => 'mysqli/mysqli.stub', 'mysqli_stmt_bind_result' => 'mysqli/mysqli.stub', 'mysqli_stmt_close' => 'mysqli/mysqli.stub', 'mysqli_stmt_data_seek' => 'mysqli/mysqli.stub', 'mysqli_stmt_errno' => 'mysqli/mysqli.stub', 'mysqli_stmt_error' => 'mysqli/mysqli.stub', 'mysqli_stmt_error_list' => 'mysqli/mysqli.stub', 'mysqli_stmt_execute' => 'mysqli/mysqli.stub', 'mysqli_stmt_fetch' => 'mysqli/mysqli.stub', 'mysqli_stmt_field_count' => 'mysqli/mysqli.stub', 'mysqli_stmt_free_result' => 'mysqli/mysqli.stub', 'mysqli_stmt_get_result' => 'mysqli/mysqli.stub', 'mysqli_stmt_get_warnings' => 'mysqli/mysqli.stub', 'mysqli_stmt_init' => 'mysqli/mysqli.stub', 'mysqli_stmt_insert_id' => 'mysqli/mysqli.stub', 'mysqli_stmt_more_results' => 'mysqli/mysqli.stub', 'mysqli_stmt_next_result' => 'mysqli/mysqli.stub', 'mysqli_stmt_num_rows' => 'mysqli/mysqli.stub', 'mysqli_stmt_param_count' => 'mysqli/mysqli.stub', 'mysqli_stmt_prepare' => 'mysqli/mysqli.stub', 'mysqli_stmt_reset' => 'mysqli/mysqli.stub', 'mysqli_stmt_result_metadata' => 'mysqli/mysqli.stub', 'mysqli_stmt_send_long_data' => 'mysqli/mysqli.stub', 'mysqli_stmt_sqlstate' => 'mysqli/mysqli.stub', 'mysqli_stmt_store_result' => 'mysqli/mysqli.stub', 'mysqli_store_result' => 'mysqli/mysqli.stub', 'mysqli_thread_id' => 'mysqli/mysqli.stub', 'mysqli_thread_safe' => 'mysqli/mysqli.stub', 'mysqli_use_result' => 'mysqli/mysqli.stub', 'mysqli_warning_count' => 'mysqli/mysqli.stub', 'natcasesort' => 'standard/standard_8.stub', 'natsort' => 'standard/standard_8.stub', 'ncurses_addch' => 'ncurses/ncurses.stub', 'ncurses_addchnstr' => 'ncurses/ncurses.stub', 'ncurses_addchstr' => 'ncurses/ncurses.stub', 'ncurses_addnstr' => 'ncurses/ncurses.stub', 'ncurses_addstr' => 'ncurses/ncurses.stub', 'ncurses_assume_default_colors' => 'ncurses/ncurses.stub', 'ncurses_attroff' => 'ncurses/ncurses.stub', 'ncurses_attron' => 'ncurses/ncurses.stub', 'ncurses_attrset' => 'ncurses/ncurses.stub', 'ncurses_baudrate' => 'ncurses/ncurses.stub', 'ncurses_beep' => 'ncurses/ncurses.stub', 'ncurses_bkgd' => 'ncurses/ncurses.stub', 'ncurses_bkgdset' => 'ncurses/ncurses.stub', 'ncurses_border' => 'ncurses/ncurses.stub', 'ncurses_bottom_panel' => 'ncurses/ncurses.stub', 'ncurses_can_change_color' => 'ncurses/ncurses.stub', 'ncurses_cbreak' => 'ncurses/ncurses.stub', 'ncurses_clear' => 'ncurses/ncurses.stub', 'ncurses_clrtobot' => 'ncurses/ncurses.stub', 'ncurses_clrtoeol' => 'ncurses/ncurses.stub', 'ncurses_color_content' => 'ncurses/ncurses.stub', 'ncurses_color_set' => 'ncurses/ncurses.stub', 'ncurses_curs_set' => 'ncurses/ncurses.stub', 'ncurses_def_prog_mode' => 'ncurses/ncurses.stub', 'ncurses_def_shell_mode' => 'ncurses/ncurses.stub', 'ncurses_define_key' => 'ncurses/ncurses.stub', 'ncurses_del_panel' => 'ncurses/ncurses.stub', 'ncurses_delay_output' => 'ncurses/ncurses.stub', 'ncurses_delch' => 'ncurses/ncurses.stub', 'ncurses_deleteln' => 'ncurses/ncurses.stub', 'ncurses_delwin' => 'ncurses/ncurses.stub', 'ncurses_doupdate' => 'ncurses/ncurses.stub', 'ncurses_echo' => 'ncurses/ncurses.stub', 'ncurses_echochar' => 'ncurses/ncurses.stub', 'ncurses_end' => 'ncurses/ncurses.stub', 'ncurses_erase' => 'ncurses/ncurses.stub', 'ncurses_erasechar' => 'ncurses/ncurses.stub', 'ncurses_filter' => 'ncurses/ncurses.stub', 'ncurses_flash' => 'ncurses/ncurses.stub', 'ncurses_flushinp' => 'ncurses/ncurses.stub', 'ncurses_getch' => 'ncurses/ncurses.stub', 'ncurses_getmaxyx' => 'ncurses/ncurses.stub', 'ncurses_getmouse' => 'ncurses/ncurses.stub', 'ncurses_getyx' => 'ncurses/ncurses.stub', 'ncurses_halfdelay' => 'ncurses/ncurses.stub', 'ncurses_has_colors' => 'ncurses/ncurses.stub', 'ncurses_has_ic' => 'ncurses/ncurses.stub', 'ncurses_has_il' => 'ncurses/ncurses.stub', 'ncurses_has_key' => 'ncurses/ncurses.stub', 'ncurses_hide_panel' => 'ncurses/ncurses.stub', 'ncurses_hline' => 'ncurses/ncurses.stub', 'ncurses_inch' => 'ncurses/ncurses.stub', 'ncurses_init' => 'ncurses/ncurses.stub', 'ncurses_init_color' => 'ncurses/ncurses.stub', 'ncurses_init_pair' => 'ncurses/ncurses.stub', 'ncurses_insch' => 'ncurses/ncurses.stub', 'ncurses_insdelln' => 'ncurses/ncurses.stub', 'ncurses_insertln' => 'ncurses/ncurses.stub', 'ncurses_insstr' => 'ncurses/ncurses.stub', 'ncurses_instr' => 'ncurses/ncurses.stub', 'ncurses_isendwin' => 'ncurses/ncurses.stub', 'ncurses_keyok' => 'ncurses/ncurses.stub', 'ncurses_keypad' => 'ncurses/ncurses.stub', 'ncurses_killchar' => 'ncurses/ncurses.stub', 'ncurses_longname' => 'ncurses/ncurses.stub', 'ncurses_meta' => 'ncurses/ncurses.stub', 'ncurses_mouse_trafo' => 'ncurses/ncurses.stub', 'ncurses_mouseinterval' => 'ncurses/ncurses.stub', 'ncurses_mousemask' => 'ncurses/ncurses.stub', 'ncurses_move' => 'ncurses/ncurses.stub', 'ncurses_move_panel' => 'ncurses/ncurses.stub', 'ncurses_mvaddch' => 'ncurses/ncurses.stub', 'ncurses_mvaddchnstr' => 'ncurses/ncurses.stub', 'ncurses_mvaddchstr' => 'ncurses/ncurses.stub', 'ncurses_mvaddnstr' => 'ncurses/ncurses.stub', 'ncurses_mvaddstr' => 'ncurses/ncurses.stub', 'ncurses_mvcur' => 'ncurses/ncurses.stub', 'ncurses_mvdelch' => 'ncurses/ncurses.stub', 'ncurses_mvgetch' => 'ncurses/ncurses.stub', 'ncurses_mvhline' => 'ncurses/ncurses.stub', 'ncurses_mvinch' => 'ncurses/ncurses.stub', 'ncurses_mvwaddstr' => 'ncurses/ncurses.stub', 'ncurses_napms' => 'ncurses/ncurses.stub', 'ncurses_new_panel' => 'ncurses/ncurses.stub', 'ncurses_newpad' => 'ncurses/ncurses.stub', 'ncurses_newwin' => 'ncurses/ncurses.stub', 'ncurses_nl' => 'ncurses/ncurses.stub', 'ncurses_nocbreak' => 'ncurses/ncurses.stub', 'ncurses_noecho' => 'ncurses/ncurses.stub', 'ncurses_nonl' => 'ncurses/ncurses.stub', 'ncurses_noqiflush' => 'ncurses/ncurses.stub', 'ncurses_noraw' => 'ncurses/ncurses.stub', 'ncurses_pair_content' => 'ncurses/ncurses.stub', 'ncurses_panel_above' => 'ncurses/ncurses.stub', 'ncurses_panel_below' => 'ncurses/ncurses.stub', 'ncurses_panel_window' => 'ncurses/ncurses.stub', 'ncurses_pnoutrefresh' => 'ncurses/ncurses.stub', 'ncurses_prefresh' => 'ncurses/ncurses.stub', 'ncurses_putp' => 'ncurses/ncurses.stub', 'ncurses_qiflush' => 'ncurses/ncurses.stub', 'ncurses_raw' => 'ncurses/ncurses.stub', 'ncurses_refresh' => 'ncurses/ncurses.stub', 'ncurses_replace_panel' => 'ncurses/ncurses.stub', 'ncurses_reset_prog_mode' => 'ncurses/ncurses.stub', 'ncurses_reset_shell_mode' => 'ncurses/ncurses.stub', 'ncurses_resetty' => 'ncurses/ncurses.stub', 'ncurses_savetty' => 'ncurses/ncurses.stub', 'ncurses_scr_dump' => 'ncurses/ncurses.stub', 'ncurses_scr_init' => 'ncurses/ncurses.stub', 'ncurses_scr_restore' => 'ncurses/ncurses.stub', 'ncurses_scr_set' => 'ncurses/ncurses.stub', 'ncurses_scrl' => 'ncurses/ncurses.stub', 'ncurses_show_panel' => 'ncurses/ncurses.stub', 'ncurses_slk_attr' => 'ncurses/ncurses.stub', 'ncurses_slk_attroff' => 'ncurses/ncurses.stub', 'ncurses_slk_attron' => 'ncurses/ncurses.stub', 'ncurses_slk_attrset' => 'ncurses/ncurses.stub', 'ncurses_slk_clear' => 'ncurses/ncurses.stub', 'ncurses_slk_color' => 'ncurses/ncurses.stub', 'ncurses_slk_init' => 'ncurses/ncurses.stub', 'ncurses_slk_noutrefresh' => 'ncurses/ncurses.stub', 'ncurses_slk_refresh' => 'ncurses/ncurses.stub', 'ncurses_slk_restore' => 'ncurses/ncurses.stub', 'ncurses_slk_set' => 'ncurses/ncurses.stub', 'ncurses_slk_touch' => 'ncurses/ncurses.stub', 'ncurses_standend' => 'ncurses/ncurses.stub', 'ncurses_standout' => 'ncurses/ncurses.stub', 'ncurses_start_color' => 'ncurses/ncurses.stub', 'ncurses_termattrs' => 'ncurses/ncurses.stub', 'ncurses_termname' => 'ncurses/ncurses.stub', 'ncurses_timeout' => 'ncurses/ncurses.stub', 'ncurses_top_panel' => 'ncurses/ncurses.stub', 'ncurses_typeahead' => 'ncurses/ncurses.stub', 'ncurses_ungetch' => 'ncurses/ncurses.stub', 'ncurses_ungetmouse' => 'ncurses/ncurses.stub', 'ncurses_update_panels' => 'ncurses/ncurses.stub', 'ncurses_use_default_colors' => 'ncurses/ncurses.stub', 'ncurses_use_env' => 'ncurses/ncurses.stub', 'ncurses_use_extended_names' => 'ncurses/ncurses.stub', 'ncurses_vidattr' => 'ncurses/ncurses.stub', 'ncurses_vline' => 'ncurses/ncurses.stub', 'ncurses_waddch' => 'ncurses/ncurses.stub', 'ncurses_waddstr' => 'ncurses/ncurses.stub', 'ncurses_wattroff' => 'ncurses/ncurses.stub', 'ncurses_wattron' => 'ncurses/ncurses.stub', 'ncurses_wattrset' => 'ncurses/ncurses.stub', 'ncurses_wborder' => 'ncurses/ncurses.stub', 'ncurses_wclear' => 'ncurses/ncurses.stub', 'ncurses_wcolor_set' => 'ncurses/ncurses.stub', 'ncurses_werase' => 'ncurses/ncurses.stub', 'ncurses_wgetch' => 'ncurses/ncurses.stub', 'ncurses_whline' => 'ncurses/ncurses.stub', 'ncurses_wmouse_trafo' => 'ncurses/ncurses.stub', 'ncurses_wmove' => 'ncurses/ncurses.stub', 'ncurses_wnoutrefresh' => 'ncurses/ncurses.stub', 'ncurses_wrefresh' => 'ncurses/ncurses.stub', 'ncurses_wstandend' => 'ncurses/ncurses.stub', 'ncurses_wstandout' => 'ncurses/ncurses.stub', 'ncurses_wvline' => 'ncurses/ncurses.stub', 'net_get_interfaces' => 'standard/standard_4.stub', 'newrelic_accept_distributed_trace_headers' => 'newrelic/newrelic.stub', 'newrelic_accept_distributed_trace_payload' => 'newrelic/newrelic.stub', 'newrelic_accept_distributed_trace_payload_httpsafe' => 'newrelic/newrelic.stub', 'newrelic_add_custom_parameter' => 'newrelic/newrelic.stub', 'newrelic_add_custom_span_parameter' => 'newrelic/newrelic.stub', 'newrelic_add_custom_tracer' => 'newrelic/newrelic.stub', 'newrelic_background_job' => 'newrelic/newrelic.stub', 'newrelic_capture_params' => 'newrelic/newrelic.stub', 'newrelic_create_distributed_trace_payload' => 'newrelic/newrelic.stub', 'newrelic_custom_metric' => 'newrelic/newrelic.stub', 'newrelic_disable_autorum' => 'newrelic/newrelic.stub', 'newrelic_enable_params' => 'newrelic/newrelic.stub', 'newrelic_end_of_transaction' => 'newrelic/newrelic.stub', 'newrelic_end_transaction' => 'newrelic/newrelic.stub', 'newrelic_get_browser_timing_footer' => 'newrelic/newrelic.stub', 'newrelic_get_browser_timing_header' => 'newrelic/newrelic.stub', 'newrelic_get_linking_metadata' => 'newrelic/newrelic.stub', 'newrelic_get_trace_metadata' => 'newrelic/newrelic.stub', 'newrelic_ignore_apdex' => 'newrelic/newrelic.stub', 'newrelic_ignore_transaction' => 'newrelic/newrelic.stub', 'newrelic_insert_distributed_trace_headers' => 'newrelic/newrelic.stub', 'newrelic_is_sampled' => 'newrelic/newrelic.stub', 'newrelic_name_transaction' => 'newrelic/newrelic.stub', 'newrelic_notice_error' => 'newrelic/newrelic.stub', 'newrelic_record_custom_event' => 'newrelic/newrelic.stub', 'newrelic_record_datastore_segment' => 'newrelic/newrelic.stub', 'newrelic_set_appname' => 'newrelic/newrelic.stub', 'newrelic_set_user_attributes' => 'newrelic/newrelic.stub', 'newrelic_set_user_id' => 'newrelic/newrelic.stub', 'newrelic_start_transaction' => 'newrelic/newrelic.stub', 'next' => 'standard/standard_8.stub', 'ngettext' => 'gettext/gettext.stub', 'nl2br' => 'standard/standard_1.stub', 'nl_langinfo' => 'standard/standard_2.stub', 'normalizer_get_raw_decomposition' => 'intl/intl.stub', 'normalizer_is_normalized' => 'intl/intl.stub', 'normalizer_normalize' => 'intl/intl.stub', 'number_format' => 'standard/standard_3.stub', 'numfmt_create' => 'intl/intl.stub', 'numfmt_format' => 'intl/intl.stub', 'numfmt_format_currency' => 'intl/intl.stub', 'numfmt_get_attribute' => 'intl/intl.stub', 'numfmt_get_error_code' => 'intl/intl.stub', 'numfmt_get_error_message' => 'intl/intl.stub', 'numfmt_get_locale' => 'intl/intl.stub', 'numfmt_get_pattern' => 'intl/intl.stub', 'numfmt_get_symbol' => 'intl/intl.stub', 'numfmt_get_text_attribute' => 'intl/intl.stub', 'numfmt_parse' => 'intl/intl.stub', 'numfmt_parse_currency' => 'intl/intl.stub', 'numfmt_set_attribute' => 'intl/intl.stub', 'numfmt_set_pattern' => 'intl/intl.stub', 'numfmt_set_symbol' => 'intl/intl.stub', 'numfmt_set_text_attribute' => 'intl/intl.stub', 'oauth_get_sbs' => 'oauth/oauth.stub', 'oauth_urlencode' => 'oauth/oauth.stub', 'ob_clean' => 'standard/standard_8.stub', 'ob_deflatehandler' => 'http/http.stub', 'ob_end_clean' => 'standard/standard_8.stub', 'ob_end_flush' => 'standard/standard_8.stub', 'ob_etaghandler' => 'http/http.stub', 'ob_flush' => 'standard/standard_8.stub', 'ob_get_clean' => 'standard/standard_8.stub', 'ob_get_contents' => 'standard/standard_8.stub', 'ob_get_flush' => 'standard/standard_8.stub', 'ob_get_length' => 'standard/standard_8.stub', 'ob_get_level' => 'standard/standard_8.stub', 'ob_get_status' => 'standard/standard_8.stub', 'ob_gzhandler' => 'zlib/zlib.stub', 'ob_iconv_handler' => 'iconv/iconv.stub', 'ob_implicit_flush' => 'standard/standard_8.stub', 'ob_inflatehandler' => 'http/http.stub', 'ob_list_handlers' => 'standard/standard_8.stub', 'ob_start' => 'standard/standard_8.stub', 'ob_tidyhandler' => 'tidy/tidy.stub', 'oci_bind_array_by_name' => 'oci8/oci8.stub', 'oci_bind_by_name' => 'oci8/oci8.stub', 'oci_cancel' => 'oci8/oci8.stub', 'oci_client_version' => 'oci8/oci8.stub', 'oci_close' => 'oci8/oci8.stub', 'oci_commit' => 'oci8/oci8.stub', 'oci_connect' => 'oci8/oci8.stub', 'oci_define_by_name' => 'oci8/oci8.stub', 'oci_error' => 'oci8/oci8.stub', 'oci_execute' => 'oci8/oci8.stub', 'oci_fetch' => 'oci8/oci8.stub', 'oci_fetch_all' => 'oci8/oci8.stub', 'oci_fetch_array' => 'oci8/oci8.stub', 'oci_fetch_assoc' => 'oci8/oci8.stub', 'oci_fetch_object' => 'oci8/oci8.stub', 'oci_fetch_row' => 'oci8/oci8.stub', 'oci_field_is_null' => 'oci8/oci8.stub', 'oci_field_name' => 'oci8/oci8.stub', 'oci_field_precision' => 'oci8/oci8.stub', 'oci_field_scale' => 'oci8/oci8.stub', 'oci_field_size' => 'oci8/oci8.stub', 'oci_field_type' => 'oci8/oci8.stub', 'oci_field_type_raw' => 'oci8/oci8.stub', 'oci_free_cursor' => 'oci8/oci8.stub', 'oci_free_descriptor' => 'oci8/oci8.stub', 'oci_free_statement' => 'oci8/oci8.stub', 'oci_get_implicit_resultset' => 'oci8/oci8.stub', 'oci_internal_debug' => 'oci8/oci8.stub', 'oci_lob_copy' => 'oci8/oci8.stub', 'oci_lob_is_equal' => 'oci8/oci8.stub', 'oci_new_collection' => 'oci8/oci8.stub', 'oci_new_connect' => 'oci8/oci8.stub', 'oci_new_cursor' => 'oci8/oci8.stub', 'oci_new_descriptor' => 'oci8/oci8.stub', 'oci_num_fields' => 'oci8/oci8.stub', 'oci_num_rows' => 'oci8/oci8.stub', 'oci_parse' => 'oci8/oci8.stub', 'oci_password_change' => 'oci8/oci8.stub', 'oci_pconnect' => 'oci8/oci8.stub', 'oci_register_taf_callback' => 'oci8/oci8.stub', 'oci_result' => 'oci8/oci8.stub', 'oci_rollback' => 'oci8/oci8.stub', 'oci_server_version' => 'oci8/oci8.stub', 'oci_set_action' => 'oci8/oci8.stub', 'oci_set_call_timeout' => 'oci8/oci8v3.stub', 'oci_set_client_identifier' => 'oci8/oci8.stub', 'oci_set_client_info' => 'oci8/oci8.stub', 'oci_set_db_operation' => 'oci8/oci8v3.stub', 'oci_set_edition' => 'oci8/oci8.stub', 'oci_set_module_name' => 'oci8/oci8.stub', 'oci_set_prefetch' => 'oci8/oci8.stub', 'oci_set_prefetch_lob' => 'oci8/oci8v3.stub', 'oci_statement_type' => 'oci8/oci8.stub', 'oci_unregister_taf_callback' => 'oci8/oci8.stub', 'ocibindbyname' => 'oci8/oci8.stub', 'ocicancel' => 'oci8/oci8.stub', 'ocicloselob' => 'oci8/oci8.stub', 'ocicollappend' => 'oci8/oci8.stub', 'ocicollassign' => 'oci8/oci8.stub', 'ocicollassignelem' => 'oci8/oci8.stub', 'ocicollgetelem' => 'oci8/oci8.stub', 'ocicollmax' => 'oci8/oci8.stub', 'ocicollsize' => 'oci8/oci8.stub', 'ocicolltrim' => 'oci8/oci8.stub', 'ocicolumnisnull' => 'oci8/oci8.stub', 'ocicolumnname' => 'oci8/oci8.stub', 'ocicolumnprecision' => 'oci8/oci8.stub', 'ocicolumnscale' => 'oci8/oci8.stub', 'ocicolumnsize' => 'oci8/oci8.stub', 'ocicolumntype' => 'oci8/oci8.stub', 'ocicolumntyperaw' => 'oci8/oci8.stub', 'ocicommit' => 'oci8/oci8.stub', 'ocidefinebyname' => 'oci8/oci8.stub', 'ocierror' => 'oci8/oci8.stub', 'ociexecute' => 'oci8/oci8.stub', 'ocifetch' => 'oci8/oci8.stub', 'ocifetchinto' => 'oci8/oci8.stub', 'ocifetchstatement' => 'oci8/oci8.stub', 'ocifreecollection' => 'oci8/oci8.stub', 'ocifreecursor' => 'oci8/oci8.stub', 'ocifreedesc' => 'oci8/oci8.stub', 'ocifreestatement' => 'oci8/oci8.stub', 'ociinternaldebug' => 'oci8/oci8.stub', 'ociloadlob' => 'oci8/oci8.stub', 'ocilogoff' => 'oci8/oci8.stub', 'ocilogon' => 'oci8/oci8.stub', 'ocinewcollection' => 'oci8/oci8.stub', 'ocinewcursor' => 'oci8/oci8.stub', 'ocinewdescriptor' => 'oci8/oci8.stub', 'ocinlogon' => 'oci8/oci8.stub', 'ocinumcols' => 'oci8/oci8.stub', 'ociparse' => 'oci8/oci8.stub', 'ocipasswordchange' => 'oci8/oci8.stub', 'ociplogon' => 'oci8/oci8.stub', 'ociresult' => 'oci8/oci8.stub', 'ocirollback' => 'oci8/oci8.stub', 'ocirowcount' => 'oci8/oci8.stub', 'ocisavelob' => 'oci8/oci8.stub', 'ocisavelobfile' => 'oci8/oci8.stub', 'ociserverversion' => 'oci8/oci8.stub', 'ocisetprefetch' => 'oci8/oci8.stub', 'ocistatementtype' => 'oci8/oci8.stub', 'ociwritelobtofile' => 'oci8/oci8.stub', 'ociwritetemporarylob' => 'oci8/oci8.stub', 'octdec' => 'standard/standard_3.stub', 'odbc_autocommit' => 'odbc/odbc.stub', 'odbc_binmode' => 'odbc/odbc.stub', 'odbc_close' => 'odbc/odbc.stub', 'odbc_close_all' => 'odbc/odbc.stub', 'odbc_columnprivileges' => 'odbc/odbc.stub', 'odbc_columns' => 'odbc/odbc.stub', 'odbc_commit' => 'odbc/odbc.stub', 'odbc_connect' => 'odbc/odbc.stub', 'odbc_connection_string_is_quoted' => 'odbc/odbc.stub', 'odbc_connection_string_quote' => 'odbc/odbc.stub', 'odbc_connection_string_should_quote' => 'odbc/odbc.stub', 'odbc_cursor' => 'odbc/odbc.stub', 'odbc_data_source' => 'odbc/odbc.stub', 'odbc_do' => 'odbc/odbc.stub', 'odbc_error' => 'odbc/odbc.stub', 'odbc_errormsg' => 'odbc/odbc.stub', 'odbc_exec' => 'odbc/odbc.stub', 'odbc_execute' => 'odbc/odbc.stub', 'odbc_fetch_array' => 'odbc/odbc.stub', 'odbc_fetch_into' => 'odbc/odbc.stub', 'odbc_fetch_object' => 'odbc/odbc.stub', 'odbc_fetch_row' => 'odbc/odbc.stub', 'odbc_field_len' => 'odbc/odbc.stub', 'odbc_field_name' => 'odbc/odbc.stub', 'odbc_field_num' => 'odbc/odbc.stub', 'odbc_field_precision' => 'odbc/odbc.stub', 'odbc_field_scale' => 'odbc/odbc.stub', 'odbc_field_type' => 'odbc/odbc.stub', 'odbc_foreignkeys' => 'odbc/odbc.stub', 'odbc_free_result' => 'odbc/odbc.stub', 'odbc_gettypeinfo' => 'odbc/odbc.stub', 'odbc_longreadlen' => 'odbc/odbc.stub', 'odbc_next_result' => 'odbc/odbc.stub', 'odbc_num_fields' => 'odbc/odbc.stub', 'odbc_num_rows' => 'odbc/odbc.stub', 'odbc_pconnect' => 'odbc/odbc.stub', 'odbc_prepare' => 'odbc/odbc.stub', 'odbc_primarykeys' => 'odbc/odbc.stub', 'odbc_procedurecolumns' => 'odbc/odbc.stub', 'odbc_procedures' => 'odbc/odbc.stub', 'odbc_result' => 'odbc/odbc.stub', 'odbc_result_all' => 'odbc/odbc.stub', 'odbc_rollback' => 'odbc/odbc.stub', 'odbc_setoption' => 'odbc/odbc.stub', 'odbc_specialcolumns' => 'odbc/odbc.stub', 'odbc_statistics' => 'odbc/odbc.stub', 'odbc_tableprivileges' => 'odbc/odbc.stub', 'odbc_tables' => 'odbc/odbc.stub', 'opcache_compile_file' => 'Zend OPcache/OPcache.stub', 'opcache_get_configuration' => 'Zend OPcache/OPcache.stub', 'opcache_get_status' => 'Zend OPcache/OPcache.stub', 'opcache_invalidate' => 'Zend OPcache/OPcache.stub', 'opcache_is_script_cached' => 'Zend OPcache/OPcache.stub', 'opcache_reset' => 'Zend OPcache/OPcache.stub', 'opendir' => 'standard/standard_7.stub', 'openlog' => 'standard/standard_7.stub', 'openssl_cipher_iv_length' => 'openssl/openssl.stub', 'openssl_cipher_key_length' => 'openssl/openssl.stub', 'openssl_cms_decrypt' => 'openssl/openssl.stub', 'openssl_cms_encrypt' => 'openssl/openssl.stub', 'openssl_cms_read' => 'openssl/openssl.stub', 'openssl_cms_sign' => 'openssl/openssl.stub', 'openssl_cms_verify' => 'openssl/openssl.stub', 'openssl_csr_export' => 'openssl/openssl.stub', 'openssl_csr_export_to_file' => 'openssl/openssl.stub', 'openssl_csr_get_public_key' => 'openssl/openssl.stub', 'openssl_csr_get_subject' => 'openssl/openssl.stub', 'openssl_csr_new' => 'openssl/openssl.stub', 'openssl_csr_sign' => 'openssl/openssl.stub', 'openssl_decrypt' => 'openssl/openssl.stub', 'openssl_dh_compute_key' => 'openssl/openssl.stub', 'openssl_digest' => 'openssl/openssl.stub', 'openssl_encrypt' => 'openssl/openssl.stub', 'openssl_error_string' => 'openssl/openssl.stub', 'openssl_free_key' => 'openssl/openssl.stub', 'openssl_get_cert_locations' => 'openssl/openssl.stub', 'openssl_get_cipher_methods' => 'openssl/openssl.stub', 'openssl_get_curve_names' => 'openssl/openssl.stub', 'openssl_get_md_methods' => 'openssl/openssl.stub', 'openssl_get_privatekey' => 'openssl/openssl.stub', 'openssl_get_publickey' => 'openssl/openssl.stub', 'openssl_open' => 'openssl/openssl.stub', 'openssl_pbkdf2' => 'openssl/openssl.stub', 'openssl_pkcs12_export' => 'openssl/openssl.stub', 'openssl_pkcs12_export_to_file' => 'openssl/openssl.stub', 'openssl_pkcs12_read' => 'openssl/openssl.stub', 'openssl_pkcs7_decrypt' => 'openssl/openssl.stub', 'openssl_pkcs7_encrypt' => 'openssl/openssl.stub', 'openssl_pkcs7_read' => 'openssl/openssl.stub', 'openssl_pkcs7_sign' => 'openssl/openssl.stub', 'openssl_pkcs7_verify' => 'openssl/openssl.stub', 'openssl_pkey_derive' => 'openssl/openssl.stub', 'openssl_pkey_export' => 'openssl/openssl.stub', 'openssl_pkey_export_to_file' => 'openssl/openssl.stub', 'openssl_pkey_free' => 'openssl/openssl.stub', 'openssl_pkey_get_details' => 'openssl/openssl.stub', 'openssl_pkey_get_private' => 'openssl/openssl.stub', 'openssl_pkey_get_public' => 'openssl/openssl.stub', 'openssl_pkey_new' => 'openssl/openssl.stub', 'openssl_private_decrypt' => 'openssl/openssl.stub', 'openssl_private_encrypt' => 'openssl/openssl.stub', 'openssl_public_decrypt' => 'openssl/openssl.stub', 'openssl_public_encrypt' => 'openssl/openssl.stub', 'openssl_random_pseudo_bytes' => 'openssl/openssl.stub', 'openssl_seal' => 'openssl/openssl.stub', 'openssl_sign' => 'openssl/openssl.stub', 'openssl_spki_export' => 'openssl/openssl.stub', 'openssl_spki_export_challenge' => 'openssl/openssl.stub', 'openssl_spki_new' => 'openssl/openssl.stub', 'openssl_spki_verify' => 'openssl/openssl.stub', 'openssl_verify' => 'openssl/openssl.stub', 'openssl_x509_check_private_key' => 'openssl/openssl.stub', 'openssl_x509_checkpurpose' => 'openssl/openssl.stub', 'openssl_x509_export' => 'openssl/openssl.stub', 'openssl_x509_export_to_file' => 'openssl/openssl.stub', 'openssl_x509_fingerprint' => 'openssl/openssl.stub', 'openssl_x509_free' => 'openssl/openssl.stub', 'openssl_x509_parse' => 'openssl/openssl.stub', 'openssl_x509_read' => 'openssl/openssl.stub', 'openssl_x509_verify' => 'openssl/openssl.stub', 'ord' => 'standard/standard_2.stub', 'output_add_rewrite_var' => 'standard/standard_9.stub', 'output_cache_disable' => 'zend/zend.stub', 'output_cache_disable_compression' => 'zend/zend.stub', 'output_cache_exists' => 'zend/zend.stub', 'output_cache_fetch' => 'zend/zend.stub', 'output_cache_get' => 'zend/zend.stub', 'output_cache_output' => 'zend/zend.stub', 'output_cache_put' => 'zend/zend.stub', 'output_cache_remove' => 'zend/zend.stub', 'output_cache_remove_key' => 'zend/zend.stub', 'output_cache_remove_url' => 'zend/zend.stub', 'output_cache_stop' => 'zend/zend.stub', 'output_reset_rewrite_vars' => 'standard/standard_9.stub', 'pack' => 'standard/standard_7.stub', 'pam_auth' => 'pam/pam.stub', 'pam_chpass' => 'pam/pam.stub', 'parallel\\bootstrap' => 'parallel/parallel.stub', 'parallel\\count' => 'parallel/parallel.stub', 'parallel\\run' => 'parallel/parallel.stub', 'parse_ini_file' => 'standard/standard_4.stub', 'parse_ini_string' => 'standard/standard_4.stub', 'parse_str' => 'standard/standard_2.stub', 'parse_url' => 'standard/standard_2.stub', 'passthru' => 'standard/standard_2.stub', 'password_algos' => 'standard/password.stub', 'password_get_info' => 'standard/password.stub', 'password_hash' => 'standard/password.stub', 'password_needs_rehash' => 'standard/password.stub', 'password_verify' => 'standard/password.stub', 'pathinfo' => 'standard/standard_1.stub', 'pclose' => 'standard/standard_5.stub', 'pcntl_alarm' => 'pcntl/pcntl.stub', 'pcntl_async_signals' => 'pcntl/pcntl.stub', 'pcntl_errno' => 'pcntl/pcntl.stub', 'pcntl_exec' => 'pcntl/pcntl.stub', 'pcntl_fork' => 'pcntl/pcntl.stub', 'pcntl_get_last_error' => 'pcntl/pcntl.stub', 'pcntl_getcpu' => 'pcntl/pcntl.stub', 'pcntl_getcpuaffinity' => 'pcntl/pcntl.stub', 'pcntl_getpriority' => 'pcntl/pcntl.stub', 'pcntl_setcpuaffinity' => 'pcntl/pcntl.stub', 'pcntl_setpriority' => 'pcntl/pcntl.stub', 'pcntl_signal' => 'pcntl/pcntl.stub', 'pcntl_signal_dispatch' => 'pcntl/pcntl.stub', 'pcntl_signal_get_handler' => 'pcntl/pcntl.stub', 'pcntl_sigprocmask' => 'pcntl/pcntl.stub', 'pcntl_sigtimedwait' => 'pcntl/pcntl.stub', 'pcntl_sigwaitinfo' => 'pcntl/pcntl.stub', 'pcntl_strerror' => 'pcntl/pcntl.stub', 'pcntl_unshare' => 'pcntl/pcntl.stub', 'pcntl_wait' => 'pcntl/pcntl.stub', 'pcntl_waitid' => 'pcntl/pcntl.stub', 'pcntl_waitpid' => 'pcntl/pcntl.stub', 'pcntl_wexitstatus' => 'pcntl/pcntl.stub', 'pcntl_wifcontinued' => 'pcntl/pcntl.stub', 'pcntl_wifexited' => 'pcntl/pcntl.stub', 'pcntl_wifsignaled' => 'pcntl/pcntl.stub', 'pcntl_wifstopped' => 'pcntl/pcntl.stub', 'pcntl_wstopsig' => 'pcntl/pcntl.stub', 'pcntl_wtermsig' => 'pcntl/pcntl.stub', 'pcov\\clear' => 'pcov/pcov.stub', 'pcov\\collect' => 'pcov/pcov.stub', 'pcov\\memory' => 'pcov/pcov.stub', 'pcov\\start' => 'pcov/pcov.stub', 'pcov\\stop' => 'pcov/pcov.stub', 'pcov\\waiting' => 'pcov/pcov.stub', 'pdo_drivers' => 'PDO/PDO.stub', 'pfsockopen' => 'standard/standard_7.stub', 'pg_affected_rows' => 'pgsql/pgsql.stub', 'pg_cancel_query' => 'pgsql/pgsql.stub', 'pg_change_password' => 'pgsql/pgsql.stub', 'pg_client_encoding' => 'pgsql/pgsql.stub', 'pg_clientencoding' => 'pgsql/pgsql.stub', 'pg_close' => 'pgsql/pgsql.stub', 'pg_cmdtuples' => 'pgsql/pgsql.stub', 'pg_connect' => 'pgsql/pgsql.stub', 'pg_connect_poll' => 'pgsql/pgsql.stub', 'pg_connection_busy' => 'pgsql/pgsql.stub', 'pg_connection_reset' => 'pgsql/pgsql.stub', 'pg_connection_status' => 'pgsql/pgsql.stub', 'pg_consume_input' => 'pgsql/pgsql.stub', 'pg_convert' => 'pgsql/pgsql.stub', 'pg_copy_from' => 'pgsql/pgsql.stub', 'pg_copy_to' => 'pgsql/pgsql.stub', 'pg_dbname' => 'pgsql/pgsql.stub', 'pg_delete' => 'pgsql/pgsql.stub', 'pg_end_copy' => 'pgsql/pgsql.stub', 'pg_enter_pipeline_mode' => 'pgsql/pgsql.stub', 'pg_errormessage' => 'pgsql/pgsql.stub', 'pg_escape_bytea' => 'pgsql/pgsql.stub', 'pg_escape_identifier' => 'pgsql/pgsql.stub', 'pg_escape_literal' => 'pgsql/pgsql.stub', 'pg_escape_string' => 'pgsql/pgsql.stub', 'pg_exec' => 'pgsql/pgsql.stub', 'pg_execute' => 'pgsql/pgsql.stub', 'pg_exit_pipeline_mode' => 'pgsql/pgsql.stub', 'pg_fetch_all' => 'pgsql/pgsql.stub', 'pg_fetch_all_columns' => 'pgsql/pgsql.stub', 'pg_fetch_array' => 'pgsql/pgsql.stub', 'pg_fetch_assoc' => 'pgsql/pgsql.stub', 'pg_fetch_object' => 'pgsql/pgsql.stub', 'pg_fetch_result' => 'pgsql/pgsql.stub', 'pg_fetch_row' => 'pgsql/pgsql.stub', 'pg_field_is_null' => 'pgsql/pgsql.stub', 'pg_field_name' => 'pgsql/pgsql.stub', 'pg_field_num' => 'pgsql/pgsql.stub', 'pg_field_prtlen' => 'pgsql/pgsql.stub', 'pg_field_size' => 'pgsql/pgsql.stub', 'pg_field_table' => 'pgsql/pgsql.stub', 'pg_field_type' => 'pgsql/pgsql.stub', 'pg_field_type_oid' => 'pgsql/pgsql.stub', 'pg_fieldisnull' => 'pgsql/pgsql.stub', 'pg_fieldname' => 'pgsql/pgsql.stub', 'pg_fieldnum' => 'pgsql/pgsql.stub', 'pg_fieldprtlen' => 'pgsql/pgsql.stub', 'pg_fieldsize' => 'pgsql/pgsql.stub', 'pg_fieldtype' => 'pgsql/pgsql.stub', 'pg_flush' => 'pgsql/pgsql.stub', 'pg_free_result' => 'pgsql/pgsql.stub', 'pg_freeresult' => 'pgsql/pgsql.stub', 'pg_get_notify' => 'pgsql/pgsql.stub', 'pg_get_pid' => 'pgsql/pgsql.stub', 'pg_get_result' => 'pgsql/pgsql.stub', 'pg_getlastoid' => 'pgsql/pgsql.stub', 'pg_host' => 'pgsql/pgsql.stub', 'pg_insert' => 'pgsql/pgsql.stub', 'pg_jit' => 'pgsql/pgsql.stub', 'pg_last_error' => 'pgsql/pgsql.stub', 'pg_last_notice' => 'pgsql/pgsql.stub', 'pg_last_oid' => 'pgsql/pgsql.stub', 'pg_lo_close' => 'pgsql/pgsql.stub', 'pg_lo_create' => 'pgsql/pgsql.stub', 'pg_lo_export' => 'pgsql/pgsql.stub', 'pg_lo_import' => 'pgsql/pgsql.stub', 'pg_lo_open' => 'pgsql/pgsql.stub', 'pg_lo_read' => 'pgsql/pgsql.stub', 'pg_lo_read_all' => 'pgsql/pgsql.stub', 'pg_lo_seek' => 'pgsql/pgsql.stub', 'pg_lo_tell' => 'pgsql/pgsql.stub', 'pg_lo_truncate' => 'pgsql/pgsql.stub', 'pg_lo_unlink' => 'pgsql/pgsql.stub', 'pg_lo_write' => 'pgsql/pgsql.stub', 'pg_loclose' => 'pgsql/pgsql.stub', 'pg_locreate' => 'pgsql/pgsql.stub', 'pg_loexport' => 'pgsql/pgsql.stub', 'pg_loimport' => 'pgsql/pgsql.stub', 'pg_loopen' => 'pgsql/pgsql.stub', 'pg_loread' => 'pgsql/pgsql.stub', 'pg_loreadall' => 'pgsql/pgsql.stub', 'pg_lounlink' => 'pgsql/pgsql.stub', 'pg_lowrite' => 'pgsql/pgsql.stub', 'pg_meta_data' => 'pgsql/pgsql.stub', 'pg_num_fields' => 'pgsql/pgsql.stub', 'pg_num_rows' => 'pgsql/pgsql.stub', 'pg_numfields' => 'pgsql/pgsql.stub', 'pg_numrows' => 'pgsql/pgsql.stub', 'pg_options' => 'pgsql/pgsql.stub', 'pg_parameter_status' => 'pgsql/pgsql.stub', 'pg_pconnect' => 'pgsql/pgsql.stub', 'pg_ping' => 'pgsql/pgsql.stub', 'pg_pipeline_status' => 'pgsql/pgsql.stub', 'pg_pipeline_sync' => 'pgsql/pgsql.stub', 'pg_port' => 'pgsql/pgsql.stub', 'pg_prepare' => 'pgsql/pgsql.stub', 'pg_put_copy_data' => 'pgsql/pgsql.stub', 'pg_put_copy_end' => 'pgsql/pgsql.stub', 'pg_put_line' => 'pgsql/pgsql.stub', 'pg_query' => 'pgsql/pgsql.stub', 'pg_query_params' => 'pgsql/pgsql.stub', 'pg_result' => 'pgsql/pgsql.stub', 'pg_result_error' => 'pgsql/pgsql.stub', 'pg_result_error_field' => 'pgsql/pgsql.stub', 'pg_result_memory_size' => 'pgsql/pgsql.stub', 'pg_result_seek' => 'pgsql/pgsql.stub', 'pg_result_status' => 'pgsql/pgsql.stub', 'pg_select' => 'pgsql/pgsql.stub', 'pg_send_execute' => 'pgsql/pgsql.stub', 'pg_send_prepare' => 'pgsql/pgsql.stub', 'pg_send_query' => 'pgsql/pgsql.stub', 'pg_send_query_params' => 'pgsql/pgsql.stub', 'pg_set_client_encoding' => 'pgsql/pgsql.stub', 'pg_set_error_context_visibility' => 'pgsql/pgsql.stub', 'pg_set_error_verbosity' => 'pgsql/pgsql.stub', 'pg_setclientencoding' => 'pgsql/pgsql.stub', 'pg_socket' => 'pgsql/pgsql.stub', 'pg_socket_poll' => 'pgsql/pgsql.stub', 'pg_trace' => 'pgsql/pgsql.stub', 'pg_transaction_status' => 'pgsql/pgsql.stub', 'pg_tty' => 'pgsql/pgsql.stub', 'pg_unescape_bytea' => 'pgsql/pgsql.stub', 'pg_untrace' => 'pgsql/pgsql.stub', 'pg_update' => 'pgsql/pgsql.stub', 'pg_version' => 'pgsql/pgsql.stub', 'php_egg_logo_guid' => 'standard/standard_0.stub', 'php_ini_loaded_file' => 'standard/standard_0.stub', 'php_ini_scanned_files' => 'standard/standard_0.stub', 'php_logo_guid' => 'standard/standard_0.stub', 'php_real_logo_guid' => 'standard/standard_0.stub', 'php_sapi_name' => 'standard/standard_0.stub', 'php_strip_whitespace' => 'standard/standard_4.stub', 'php_uname' => 'standard/standard_0.stub', 'phpcredits' => 'standard/standard_0.stub', 'phpdbg_break_file' => 'phpdbg/phpdbg.stub', 'phpdbg_break_function' => 'phpdbg/phpdbg.stub', 'phpdbg_break_method' => 'phpdbg/phpdbg.stub', 'phpdbg_break_next' => 'phpdbg/phpdbg.stub', 'phpdbg_clear' => 'phpdbg/phpdbg.stub', 'phpdbg_color' => 'phpdbg/phpdbg.stub', 'phpdbg_end_oplog' => 'phpdbg/phpdbg.stub', 'phpdbg_exec' => 'phpdbg/phpdbg.stub', 'phpdbg_get_executable' => 'phpdbg/phpdbg.stub', 'phpdbg_prompt' => 'phpdbg/phpdbg.stub', 'phpdbg_start_oplog' => 'phpdbg/phpdbg.stub', 'phpinfo' => 'standard/standard_0.stub', 'phpversion' => 'standard/standard_0.stub', 'pi' => 'standard/standard_3.stub', 'png2wbmp' => 'gd/gd.stub', 'popen' => 'standard/standard_5.stub', 'pos' => 'standard/standard_9.stub', 'posix_access' => 'posix/posix.stub', 'posix_ctermid' => 'posix/posix.stub', 'posix_eaccess' => 'posix/posix.stub', 'posix_errno' => 'posix/posix.stub', 'posix_get_last_error' => 'posix/posix.stub', 'posix_getcwd' => 'posix/posix.stub', 'posix_getegid' => 'posix/posix.stub', 'posix_geteuid' => 'posix/posix.stub', 'posix_getgid' => 'posix/posix.stub', 'posix_getgrgid' => 'posix/posix.stub', 'posix_getgrnam' => 'posix/posix.stub', 'posix_getgroups' => 'posix/posix.stub', 'posix_getlogin' => 'posix/posix.stub', 'posix_getpgid' => 'posix/posix.stub', 'posix_getpgrp' => 'posix/posix.stub', 'posix_getpid' => 'posix/posix.stub', 'posix_getppid' => 'posix/posix.stub', 'posix_getpwnam' => 'posix/posix.stub', 'posix_getpwuid' => 'posix/posix.stub', 'posix_getrlimit' => 'posix/posix.stub', 'posix_getsid' => 'posix/posix.stub', 'posix_getuid' => 'posix/posix.stub', 'posix_initgroups' => 'posix/posix.stub', 'posix_isatty' => 'posix/posix.stub', 'posix_kill' => 'posix/posix.stub', 'posix_mkfifo' => 'posix/posix.stub', 'posix_mknod' => 'posix/posix.stub', 'posix_setegid' => 'posix/posix.stub', 'posix_seteuid' => 'posix/posix.stub', 'posix_setgid' => 'posix/posix.stub', 'posix_setpgid' => 'posix/posix.stub', 'posix_setrlimit' => 'posix/posix.stub', 'posix_setsid' => 'posix/posix.stub', 'posix_setuid' => 'posix/posix.stub', 'posix_strerror' => 'posix/posix.stub', 'posix_sysconf' => 'posix/posix.stub', 'posix_times' => 'posix/posix.stub', 'posix_ttyname' => 'posix/posix.stub', 'posix_uname' => 'posix/posix.stub', 'pow' => 'standard/standard_3.stub', 'preg_filter' => 'pcre/pcre.stub', 'preg_grep' => 'pcre/pcre.stub', 'preg_last_error' => 'pcre/pcre.stub', 'preg_last_error_msg' => 'pcre/pcre.stub', 'preg_match' => 'pcre/pcre.stub', 'preg_match_all' => 'pcre/pcre.stub', 'preg_quote' => 'pcre/pcre.stub', 'preg_replace' => 'pcre/pcre.stub', 'preg_replace_callback' => 'pcre/pcre.stub', 'preg_replace_callback_array' => 'pcre/pcre.stub', 'preg_split' => 'pcre/pcre.stub', 'prev' => 'standard/standard_8.stub', 'print_r' => 'standard/standard_4.stub', 'printf' => 'standard/standard_2.stub', 'proc_close' => 'standard/standard_2.stub', 'proc_get_status' => 'standard/standard_2.stub', 'proc_nice' => 'standard/standard_2.stub', 'proc_open' => 'standard/standard_2.stub', 'proc_terminate' => 'standard/standard_2.stub', 'property_exists' => 'Core/Core.stub', 'pspell_add_to_personal' => 'pspell/pspell.stub', 'pspell_add_to_session' => 'pspell/pspell.stub', 'pspell_check' => 'pspell/pspell.stub', 'pspell_clear_session' => 'pspell/pspell.stub', 'pspell_config_create' => 'pspell/pspell.stub', 'pspell_config_data_dir' => 'pspell/pspell.stub', 'pspell_config_dict_dir' => 'pspell/pspell.stub', 'pspell_config_ignore' => 'pspell/pspell.stub', 'pspell_config_mode' => 'pspell/pspell.stub', 'pspell_config_personal' => 'pspell/pspell.stub', 'pspell_config_repl' => 'pspell/pspell.stub', 'pspell_config_runtogether' => 'pspell/pspell.stub', 'pspell_config_save_repl' => 'pspell/pspell.stub', 'pspell_new' => 'pspell/pspell.stub', 'pspell_new_config' => 'pspell/pspell.stub', 'pspell_new_personal' => 'pspell/pspell.stub', 'pspell_save_wordlist' => 'pspell/pspell.stub', 'pspell_store_replacement' => 'pspell/pspell.stub', 'pspell_suggest' => 'pspell/pspell.stub', 'putenv' => 'standard/standard_3.stub', 'quoted_printable_decode' => 'standard/standard_3.stub', 'quoted_printable_encode' => 'standard/standard_3.stub', 'quotemeta' => 'standard/standard_1.stub', 'rad2deg' => 'standard/standard_3.stub', 'radius_acct_open' => 'radius/radius.stub', 'radius_add_server' => 'radius/radius.stub', 'radius_auth_open' => 'radius/radius.stub', 'radius_close' => 'radius/radius.stub', 'radius_config' => 'radius/radius.stub', 'radius_create_request' => 'radius/radius.stub', 'rand' => 'random/random.stub', 'random_bytes' => 'random/random.stub', 'random_int' => 'random/random.stub', 'range' => 'standard/standard_8.stub', 'rawurldecode' => 'standard/standard_2.stub', 'rawurlencode' => 'standard/standard_2.stub', 'rd_kafka_err2str' => 'rdkafka/functions.stub', 'rd_kafka_errno' => 'rdkafka/functions.stub', 'rd_kafka_errno2err' => 'rdkafka/functions.stub', 'rd_kafka_get_err_descs' => 'rdkafka/functions.stub', 'rd_kafka_offset_tail' => 'rdkafka/functions.stub', 'rd_kafka_thread_cnt' => 'rdkafka/functions.stub', 'read_exif_data' => 'exif/exif.stub', 'readdir' => 'standard/standard_7.stub', 'readfile' => 'standard/standard_5.stub', 'readgzfile' => 'zlib/zlib.stub', 'readline' => 'readline/readline.stub', 'readline_add_history' => 'readline/readline.stub', 'readline_callback_handler_install' => 'readline/readline.stub', 'readline_callback_handler_remove' => 'readline/readline.stub', 'readline_callback_read_char' => 'readline/readline.stub', 'readline_clear_history' => 'readline/readline.stub', 'readline_completion_function' => 'readline/readline.stub', 'readline_info' => 'readline/readline.stub', 'readline_list_history' => 'readline/readline.stub', 'readline_on_new_line' => 'readline/readline.stub', 'readline_read_history' => 'readline/readline.stub', 'readline_redisplay' => 'readline/readline.stub', 'readline_write_history' => 'readline/readline.stub', 'readlink' => 'standard/standard_2.stub', 'realpath' => 'standard/standard_6.stub', 'realpath_cache_get' => 'standard/standard_9.stub', 'realpath_cache_size' => 'standard/standard_9.stub', 'recode' => 'recode/recode.stub', 'recode_file' => 'recode/recode.stub', 'recode_string' => 'recode/recode.stub', 'register_event_handler' => 'zend/zend.stub', 'register_shutdown_function' => 'standard/standard_4.stub', 'register_tick_function' => 'standard/standard_4.stub', 'rename' => 'standard/standard_5.stub', 'request_parse_body' => 'standard/standard_10.stub', 'reset' => 'standard/standard_8.stub', 'resourcebundle_count' => 'intl/intl.stub', 'resourcebundle_create' => 'intl/intl.stub', 'resourcebundle_get' => 'intl/intl.stub', 'resourcebundle_get_error_code' => 'intl/intl.stub', 'resourcebundle_get_error_message' => 'intl/intl.stub', 'resourcebundle_locales' => 'intl/intl.stub', 'restore_error_handler' => 'Core/Core.stub', 'restore_exception_handler' => 'Core/Core.stub', 'restore_include_path' => 'standard/standard_4.stub', 'rewind' => 'standard/standard_5.stub', 'rewinddir' => 'standard/standard_7.stub', 'rmdir' => 'standard/standard_5.stub', 'round' => 'standard/standard_3.stub', 'rpmaddtag' => 'rpminfo/rpminfo.stub', 'rpmdbinfo' => 'rpminfo/rpminfo.stub', 'rpmdbsearch' => 'rpminfo/rpminfo.stub', 'rpminfo' => 'rpminfo/rpminfo.stub', 'rpmvercmp' => 'rpminfo/rpminfo.stub', 'rrd_create' => 'rrd/rrd.stub', 'rrd_disconnect' => 'rrd/rrd.stub', 'rrd_error' => 'rrd/rrd.stub', 'rrd_fetch' => 'rrd/rrd.stub', 'rrd_first' => 'rrd/rrd.stub', 'rrd_graph' => 'rrd/rrd.stub', 'rrd_info' => 'rrd/rrd.stub', 'rrd_last' => 'rrd/rrd.stub', 'rrd_lastupdate' => 'rrd/rrd.stub', 'rrd_restore' => 'rrd/rrd.stub', 'rrd_tune' => 'rrd/rrd.stub', 'rrd_update' => 'rrd/rrd.stub', 'rrd_version' => 'rrd/rrd.stub', 'rrd_xport' => 'rrd/rrd.stub', 'rrdc_disconnect' => 'rrd/rrd.stub', 'rsort' => 'standard/standard_8.stub', 'rtrim' => 'standard/standard_1.stub', 'sapi_windows_cp_conv' => 'standard/basic.stub', 'sapi_windows_cp_get' => 'standard/basic.stub', 'sapi_windows_cp_is_utf8' => 'standard/basic.stub', 'sapi_windows_cp_set' => 'standard/basic.stub', 'sapi_windows_generate_ctrl_event' => 'standard/basic.stub', 'sapi_windows_set_ctrl_handler' => 'standard/basic.stub', 'sapi_windows_vt100_support' => 'standard/basic.stub', 'scandir' => 'standard/standard_7.stub', 'sem_acquire' => 'sysvsem/sysvsem.stub', 'sem_get' => 'sysvsem/sysvsem.stub', 'sem_release' => 'sysvsem/sysvsem.stub', 'sem_remove' => 'sysvsem/sysvsem.stub', 'serialize' => 'standard/standard_4.stub', 'session_abort' => 'session/session.stub', 'session_cache_expire' => 'session/session.stub', 'session_cache_limiter' => 'session/session.stub', 'session_commit' => 'session/session.stub', 'session_create_id' => 'session/session.stub', 'session_decode' => 'session/session.stub', 'session_destroy' => 'session/session.stub', 'session_encode' => 'session/session.stub', 'session_gc' => 'session/session.stub', 'session_get_cookie_params' => 'session/session.stub', 'session_id' => 'session/session.stub', 'session_is_registered' => 'session/session.stub', 'session_module_name' => 'session/session.stub', 'session_name' => 'session/session.stub', 'session_regenerate_id' => 'session/session.stub', 'session_register' => 'session/session.stub', 'session_register_shutdown' => 'session/session.stub', 'session_reset' => 'session/session.stub', 'session_save_path' => 'session/session.stub', 'session_set_cookie_params' => 'session/session.stub', 'session_set_save_handler' => 'session/session.stub', 'session_start' => 'session/session.stub', 'session_status' => 'session/session.stub', 'session_unregister' => 'session/session.stub', 'session_unset' => 'session/session.stub', 'session_write_close' => 'session/session.stub', 'set_error_handler' => 'Core/Core.stub', 'set_exception_handler' => 'Core/Core.stub', 'set_file_buffer' => 'standard/standard_6.stub', 'set_include_path' => 'standard/standard_4.stub', 'set_job_failed' => 'zend/zend_f.stub', 'set_magic_quotes_runtime' => 'standard/standard_3.stub', 'set_socket_blocking' => 'standard/standard_6.stub', 'set_time_limit' => 'standard/standard_3.stub', 'setcookie' => 'standard/standard_4.stub', 'setlocale' => 'standard/standard_1.stub', 'setrawcookie' => 'standard/standard_4.stub', 'settype' => 'standard/standard_5.stub', 'sha1' => 'standard/standard_0.stub', 'sha1_file' => 'standard/standard_0.stub', 'shell_exec' => 'standard/standard_2.stub', 'shm_attach' => 'sysvshm/sysvshm.stub', 'shm_detach' => 'sysvshm/sysvshm.stub', 'shm_get_var' => 'sysvshm/sysvshm.stub', 'shm_has_var' => 'sysvshm/sysvshm.stub', 'shm_put_var' => 'sysvshm/sysvshm.stub', 'shm_remove' => 'sysvshm/sysvshm.stub', 'shm_remove_var' => 'sysvshm/sysvshm.stub', 'shmop_close' => 'shmop/shmop.stub', 'shmop_delete' => 'shmop/shmop.stub', 'shmop_open' => 'shmop/shmop.stub', 'shmop_read' => 'shmop/shmop.stub', 'shmop_size' => 'shmop/shmop.stub', 'shmop_write' => 'shmop/shmop.stub', 'show_source' => 'standard/standard_4.stub', 'shuffle' => 'standard/standard_8.stub', 'simdjson_decode' => 'simdjson/simdjson.stub', 'simdjson_is_valid' => 'simdjson/simdjson.stub', 'simdjson_key_count' => 'simdjson/simdjson.stub', 'simdjson_key_exists' => 'simdjson/simdjson.stub', 'simdjson_key_value' => 'simdjson/simdjson.stub', 'similar_text' => 'standard/standard_1.stub', 'simplexml_import_dom' => 'SimpleXML/SimpleXML.stub', 'simplexml_load_file' => 'SimpleXML/SimpleXML.stub', 'simplexml_load_string' => 'SimpleXML/SimpleXML.stub', 'sin' => 'standard/standard_3.stub', 'sinh' => 'standard/standard_3.stub', 'sizeof' => 'standard/standard_9.stub', 'sleep' => 'standard/standard_0.stub', 'snappy_compress' => 'snappy/snappy/snappy.stub', 'snappy_uncompress' => 'snappy/snappy/snappy.stub', 'snmp2_get' => 'snmp/snmp.stub', 'snmp2_getnext' => 'snmp/snmp.stub', 'snmp2_real_walk' => 'snmp/snmp.stub', 'snmp2_set' => 'snmp/snmp.stub', 'snmp2_walk' => 'snmp/snmp.stub', 'snmp3_get' => 'snmp/snmp.stub', 'snmp3_getnext' => 'snmp/snmp.stub', 'snmp3_real_walk' => 'snmp/snmp.stub', 'snmp3_set' => 'snmp/snmp.stub', 'snmp3_walk' => 'snmp/snmp.stub', 'snmp_get_quick_print' => 'snmp/snmp.stub', 'snmp_get_valueretrieval' => 'snmp/snmp.stub', 'snmp_read_mib' => 'snmp/snmp.stub', 'snmp_set_enum_print' => 'snmp/snmp.stub', 'snmp_set_oid_numeric_print' => 'snmp/snmp.stub', 'snmp_set_oid_output_format' => 'snmp/snmp.stub', 'snmp_set_quick_print' => 'snmp/snmp.stub', 'snmp_set_valueretrieval' => 'snmp/snmp.stub', 'snmpget' => 'snmp/snmp.stub', 'snmpgetnext' => 'snmp/snmp.stub', 'snmprealwalk' => 'snmp/snmp.stub', 'snmpset' => 'snmp/snmp.stub', 'snmpwalk' => 'snmp/snmp.stub', 'snmpwalkoid' => 'snmp/snmp.stub', 'socket_accept' => 'sockets/sockets.stub', 'socket_addrinfo_bind' => 'sockets/sockets.stub', 'socket_addrinfo_connect' => 'sockets/sockets.stub', 'socket_addrinfo_explain' => 'sockets/sockets.stub', 'socket_addrinfo_lookup' => 'sockets/sockets.stub', 'socket_atmark' => 'sockets/sockets.stub', 'socket_bind' => 'sockets/sockets.stub', 'socket_clear_error' => 'sockets/sockets.stub', 'socket_close' => 'sockets/sockets.stub', 'socket_cmsg_space' => 'sockets/sockets.stub', 'socket_connect' => 'sockets/sockets.stub', 'socket_create' => 'sockets/sockets.stub', 'socket_create_listen' => 'sockets/sockets.stub', 'socket_create_pair' => 'sockets/sockets.stub', 'socket_export_stream' => 'sockets/sockets.stub', 'socket_get_option' => 'sockets/sockets.stub', 'socket_get_status' => 'standard/standard_6.stub', 'socket_getopt' => 'sockets/sockets.stub', 'socket_getpeername' => 'sockets/sockets.stub', 'socket_getsockname' => 'sockets/sockets.stub', 'socket_import_stream' => 'sockets/sockets.stub', 'socket_last_error' => 'sockets/sockets.stub', 'socket_listen' => 'sockets/sockets.stub', 'socket_read' => 'sockets/sockets.stub', 'socket_recv' => 'sockets/sockets.stub', 'socket_recvfrom' => 'sockets/sockets.stub', 'socket_recvmsg' => 'sockets/sockets.stub', 'socket_select' => 'sockets/sockets.stub', 'socket_send' => 'sockets/sockets.stub', 'socket_sendmsg' => 'sockets/sockets.stub', 'socket_sendto' => 'sockets/sockets.stub', 'socket_set_block' => 'sockets/sockets.stub', 'socket_set_blocking' => 'standard/standard_6.stub', 'socket_set_nonblock' => 'sockets/sockets.stub', 'socket_set_option' => 'sockets/sockets.stub', 'socket_set_timeout' => 'standard/standard_6.stub', 'socket_setopt' => 'sockets/sockets.stub', 'socket_shutdown' => 'sockets/sockets.stub', 'socket_strerror' => 'sockets/sockets.stub', 'socket_write' => 'sockets/sockets.stub', 'socket_wsaprotocol_info_export' => 'sockets/sockets.stub', 'socket_wsaprotocol_info_import' => 'sockets/sockets.stub', 'socket_wsaprotocol_info_release' => 'sockets/sockets.stub', 'sodium_add' => 'sodium/sodium.stub', 'sodium_base642bin' => 'sodium/sodium.stub', 'sodium_bin2base64' => 'sodium/sodium.stub', 'sodium_bin2hex' => 'sodium/sodium.stub', 'sodium_compare' => 'sodium/sodium.stub', 'sodium_crypto_aead_aegis128l_decrypt' => 'libsodium/libsodium_f.stub', 'sodium_crypto_aead_aegis128l_encrypt' => 'libsodium/libsodium_f.stub', 'sodium_crypto_aead_aegis128l_keygen' => 'libsodium/libsodium_f.stub', 'sodium_crypto_aead_aegis256_decrypt' => 'libsodium/libsodium_f.stub', 'sodium_crypto_aead_aegis256_encrypt' => 'libsodium/libsodium_f.stub', 'sodium_crypto_aead_aegis256_keygen' => 'libsodium/libsodium_f.stub', 'sodium_crypto_aead_aes256gcm_decrypt' => 'sodium/sodium.stub', 'sodium_crypto_aead_aes256gcm_encrypt' => 'sodium/sodium.stub', 'sodium_crypto_aead_aes256gcm_is_available' => 'sodium/sodium.stub', 'sodium_crypto_aead_aes256gcm_keygen' => 'sodium/sodium.stub', 'sodium_crypto_aead_chacha20poly1305_decrypt' => 'sodium/sodium.stub', 'sodium_crypto_aead_chacha20poly1305_encrypt' => 'sodium/sodium.stub', 'sodium_crypto_aead_chacha20poly1305_ietf_decrypt' => 'sodium/sodium.stub', 'sodium_crypto_aead_chacha20poly1305_ietf_encrypt' => 'sodium/sodium.stub', 'sodium_crypto_aead_chacha20poly1305_ietf_keygen' => 'sodium/sodium.stub', 'sodium_crypto_aead_chacha20poly1305_keygen' => 'sodium/sodium.stub', 'sodium_crypto_aead_xchacha20poly1305_ietf_decrypt' => 'sodium/sodium.stub', 'sodium_crypto_aead_xchacha20poly1305_ietf_encrypt' => 'sodium/sodium.stub', 'sodium_crypto_aead_xchacha20poly1305_ietf_keygen' => 'sodium/sodium.stub', 'sodium_crypto_auth' => 'sodium/sodium.stub', 'sodium_crypto_auth_keygen' => 'sodium/sodium.stub', 'sodium_crypto_auth_verify' => 'sodium/sodium.stub', 'sodium_crypto_box' => 'sodium/sodium.stub', 'sodium_crypto_box_keypair' => 'sodium/sodium.stub', 'sodium_crypto_box_keypair_from_secretkey_and_publickey' => 'sodium/sodium.stub', 'sodium_crypto_box_open' => 'sodium/sodium.stub', 'sodium_crypto_box_publickey' => 'sodium/sodium.stub', 'sodium_crypto_box_publickey_from_secretkey' => 'sodium/sodium.stub', 'sodium_crypto_box_seal' => 'sodium/sodium.stub', 'sodium_crypto_box_seal_open' => 'sodium/sodium.stub', 'sodium_crypto_box_secretkey' => 'sodium/sodium.stub', 'sodium_crypto_box_seed_keypair' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_add' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_from_hash' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_is_valid_point' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_random' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_scalar_add' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_scalar_complement' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_scalar_invert' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_scalar_mul' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_scalar_negate' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_scalar_random' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_scalar_reduce' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_scalar_sub' => 'sodium/sodium.stub', 'sodium_crypto_core_ristretto255_sub' => 'sodium/sodium.stub', 'sodium_crypto_generichash' => 'sodium/sodium.stub', 'sodium_crypto_generichash_final' => 'sodium/sodium.stub', 'sodium_crypto_generichash_init' => 'sodium/sodium.stub', 'sodium_crypto_generichash_keygen' => 'sodium/sodium.stub', 'sodium_crypto_generichash_update' => 'sodium/sodium.stub', 'sodium_crypto_kdf_derive_from_key' => 'sodium/sodium.stub', 'sodium_crypto_kdf_keygen' => 'sodium/sodium.stub', 'sodium_crypto_kx' => 'sodium/sodium.stub', 'sodium_crypto_kx_client_session_keys' => 'sodium/sodium.stub', 'sodium_crypto_kx_keypair' => 'sodium/sodium.stub', 'sodium_crypto_kx_publickey' => 'sodium/sodium.stub', 'sodium_crypto_kx_secretkey' => 'sodium/sodium.stub', 'sodium_crypto_kx_seed_keypair' => 'sodium/sodium.stub', 'sodium_crypto_kx_server_session_keys' => 'sodium/sodium.stub', 'sodium_crypto_pwhash' => 'sodium/sodium.stub', 'sodium_crypto_pwhash_scryptsalsa208sha256' => 'sodium/sodium.stub', 'sodium_crypto_pwhash_scryptsalsa208sha256_str' => 'sodium/sodium.stub', 'sodium_crypto_pwhash_scryptsalsa208sha256_str_verify' => 'sodium/sodium.stub', 'sodium_crypto_pwhash_str' => 'sodium/sodium.stub', 'sodium_crypto_pwhash_str_needs_rehash' => 'sodium/sodium.stub', 'sodium_crypto_pwhash_str_verify' => 'sodium/sodium.stub', 'sodium_crypto_scalarmult' => 'sodium/sodium.stub', 'sodium_crypto_scalarmult_base' => 'sodium/sodium.stub', 'sodium_crypto_scalarmult_ristretto255' => 'sodium/sodium.stub', 'sodium_crypto_scalarmult_ristretto255_base' => 'sodium/sodium.stub', 'sodium_crypto_secretbox' => 'sodium/sodium.stub', 'sodium_crypto_secretbox_keygen' => 'sodium/sodium.stub', 'sodium_crypto_secretbox_open' => 'sodium/sodium.stub', 'sodium_crypto_secretstream_xchacha20poly1305_init_pull' => 'sodium/sodium.stub', 'sodium_crypto_secretstream_xchacha20poly1305_init_push' => 'sodium/sodium.stub', 'sodium_crypto_secretstream_xchacha20poly1305_keygen' => 'sodium/sodium.stub', 'sodium_crypto_secretstream_xchacha20poly1305_pull' => 'sodium/sodium.stub', 'sodium_crypto_secretstream_xchacha20poly1305_push' => 'sodium/sodium.stub', 'sodium_crypto_secretstream_xchacha20poly1305_rekey' => 'sodium/sodium.stub', 'sodium_crypto_shorthash' => 'sodium/sodium.stub', 'sodium_crypto_shorthash_keygen' => 'sodium/sodium.stub', 'sodium_crypto_sign' => 'sodium/sodium.stub', 'sodium_crypto_sign_detached' => 'sodium/sodium.stub', 'sodium_crypto_sign_ed25519_pk_to_curve25519' => 'sodium/sodium.stub', 'sodium_crypto_sign_ed25519_sk_to_curve25519' => 'sodium/sodium.stub', 'sodium_crypto_sign_keypair' => 'sodium/sodium.stub', 'sodium_crypto_sign_keypair_from_secretkey_and_publickey' => 'sodium/sodium.stub', 'sodium_crypto_sign_open' => 'sodium/sodium.stub', 'sodium_crypto_sign_publickey' => 'sodium/sodium.stub', 'sodium_crypto_sign_publickey_from_secretkey' => 'sodium/sodium.stub', 'sodium_crypto_sign_secretkey' => 'sodium/sodium.stub', 'sodium_crypto_sign_seed_keypair' => 'sodium/sodium.stub', 'sodium_crypto_sign_verify_detached' => 'sodium/sodium.stub', 'sodium_crypto_stream' => 'sodium/sodium.stub', 'sodium_crypto_stream_keygen' => 'sodium/sodium.stub', 'sodium_crypto_stream_xchacha20' => 'sodium/sodium.stub', 'sodium_crypto_stream_xchacha20_keygen' => 'sodium/sodium.stub', 'sodium_crypto_stream_xchacha20_xor' => 'sodium/sodium.stub', 'sodium_crypto_stream_xchacha20_xor_ic' => 'sodium/sodium.stub', 'sodium_crypto_stream_xor' => 'sodium/sodium.stub', 'sodium_hex2bin' => 'sodium/sodium.stub', 'sodium_increment' => 'sodium/sodium.stub', 'sodium_library_version_major' => 'sodium/sodium.stub', 'sodium_library_version_minor' => 'sodium/sodium.stub', 'sodium_memcmp' => 'sodium/sodium.stub', 'sodium_memzero' => 'sodium/sodium.stub', 'sodium_pad' => 'sodium/sodium.stub', 'sodium_randombytes_buf' => 'sodium/sodium.stub', 'sodium_randombytes_random16' => 'sodium/sodium.stub', 'sodium_randombytes_uniform' => 'sodium/sodium.stub', 'sodium_unpad' => 'sodium/sodium.stub', 'sodium_version_string' => 'sodium/sodium.stub', 'solr_get_version' => 'solr/functions.stub', 'sort' => 'standard/standard_8.stub', 'soundex' => 'standard/standard_2.stub', 'spl_autoload' => 'SPL/SPL_f.stub', 'spl_autoload_call' => 'SPL/SPL_f.stub', 'spl_autoload_extensions' => 'SPL/SPL_f.stub', 'spl_autoload_functions' => 'SPL/SPL_f.stub', 'spl_autoload_register' => 'SPL/SPL_f.stub', 'spl_autoload_unregister' => 'SPL/SPL_f.stub', 'spl_classes' => 'SPL/SPL_f.stub', 'spl_object_hash' => 'SPL/SPL_f.stub', 'spl_object_id' => 'SPL/SPL_f.stub', 'split' => 'regex/ereg.stub', 'spliti' => 'regex/ereg.stub', 'sprintf' => 'standard/standard_2.stub', 'sql_regcase' => 'regex/ereg.stub', 'sqlite_array_query' => 'SQLite/SQLite.stub', 'sqlite_busy_timeout' => 'SQLite/SQLite.stub', 'sqlite_changes' => 'SQLite/SQLite.stub', 'sqlite_close' => 'SQLite/SQLite.stub', 'sqlite_column' => 'SQLite/SQLite.stub', 'sqlite_create_aggregate' => 'SQLite/SQLite.stub', 'sqlite_create_function' => 'SQLite/SQLite.stub', 'sqlite_current' => 'SQLite/SQLite.stub', 'sqlite_error_string' => 'SQLite/SQLite.stub', 'sqlite_escape_string' => 'SQLite/SQLite.stub', 'sqlite_exec' => 'SQLite/SQLite.stub', 'sqlite_factory' => 'SQLite/SQLite.stub', 'sqlite_fetch_all' => 'SQLite/SQLite.stub', 'sqlite_fetch_array' => 'SQLite/SQLite.stub', 'sqlite_fetch_column_types' => 'SQLite/SQLite.stub', 'sqlite_fetch_object' => 'SQLite/SQLite.stub', 'sqlite_fetch_single' => 'SQLite/SQLite.stub', 'sqlite_fetch_string' => 'SQLite/SQLite.stub', 'sqlite_field_name' => 'SQLite/SQLite.stub', 'sqlite_has_more' => 'SQLite/SQLite.stub', 'sqlite_has_prev' => 'SQLite/SQLite.stub', 'sqlite_last_error' => 'SQLite/SQLite.stub', 'sqlite_last_insert_rowid' => 'SQLite/SQLite.stub', 'sqlite_libencoding' => 'SQLite/SQLite.stub', 'sqlite_libversion' => 'SQLite/SQLite.stub', 'sqlite_next' => 'SQLite/SQLite.stub', 'sqlite_num_fields' => 'SQLite/SQLite.stub', 'sqlite_num_rows' => 'SQLite/SQLite.stub', 'sqlite_open' => 'SQLite/SQLite.stub', 'sqlite_popen' => 'SQLite/SQLite.stub', 'sqlite_prev' => 'SQLite/SQLite.stub', 'sqlite_query' => 'SQLite/SQLite.stub', 'sqlite_rewind' => 'SQLite/SQLite.stub', 'sqlite_seek' => 'SQLite/SQLite.stub', 'sqlite_single_query' => 'SQLite/SQLite.stub', 'sqlite_udf_decode_binary' => 'SQLite/SQLite.stub', 'sqlite_udf_encode_binary' => 'SQLite/SQLite.stub', 'sqlite_unbuffered_query' => 'SQLite/SQLite.stub', 'sqlite_valid' => 'SQLite/SQLite.stub', 'sqlsrv_begin_transaction' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_cancel' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_client_info' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_close' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_commit' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_configure' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_connect' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_errors' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_execute' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_fetch' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_fetch_array' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_fetch_object' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_field_metadata' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_free_stmt' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_get_config' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_get_field' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_has_rows' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_next_result' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_num_fields' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_num_rows' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_prepare' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_query' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_rollback' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_rows_affected' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_send_stream_data' => 'sqlsrv/sqlsrv.stub', 'sqlsrv_server_info' => 'sqlsrv/sqlsrv.stub', 'sqrt' => 'standard/standard_3.stub', 'srand' => 'random/random.stub', 'sscanf' => 'standard/standard_2.stub', 'ssh2_auth_agent' => 'ssh2/ssh2.stub', 'ssh2_auth_hostbased_file' => 'ssh2/ssh2.stub', 'ssh2_auth_none' => 'ssh2/ssh2.stub', 'ssh2_auth_password' => 'ssh2/ssh2.stub', 'ssh2_auth_pubkey_file' => 'ssh2/ssh2.stub', 'ssh2_connect' => 'ssh2/ssh2.stub', 'ssh2_disconnect' => 'ssh2/ssh2.stub', 'ssh2_exec' => 'ssh2/ssh2.stub', 'ssh2_fetch_stream' => 'ssh2/ssh2.stub', 'ssh2_fingerprint' => 'ssh2/ssh2.stub', 'ssh2_forward_accept' => 'ssh2/ssh2.stub', 'ssh2_forward_listen' => 'ssh2/ssh2.stub', 'ssh2_methods_negotiated' => 'ssh2/ssh2.stub', 'ssh2_poll' => 'ssh2/ssh2.stub', 'ssh2_publickey_add' => 'ssh2/ssh2.stub', 'ssh2_publickey_init' => 'ssh2/ssh2.stub', 'ssh2_publickey_list' => 'ssh2/ssh2.stub', 'ssh2_publickey_remove' => 'ssh2/ssh2.stub', 'ssh2_scp_recv' => 'ssh2/ssh2.stub', 'ssh2_scp_send' => 'ssh2/ssh2.stub', 'ssh2_send_eof' => 'ssh2/ssh2.stub', 'ssh2_sftp' => 'ssh2/ssh2.stub', 'ssh2_sftp_chmod' => 'ssh2/ssh2.stub', 'ssh2_sftp_lstat' => 'ssh2/ssh2.stub', 'ssh2_sftp_mkdir' => 'ssh2/ssh2.stub', 'ssh2_sftp_readlink' => 'ssh2/ssh2.stub', 'ssh2_sftp_realpath' => 'ssh2/ssh2.stub', 'ssh2_sftp_rename' => 'ssh2/ssh2.stub', 'ssh2_sftp_rmdir' => 'ssh2/ssh2.stub', 'ssh2_sftp_stat' => 'ssh2/ssh2.stub', 'ssh2_sftp_symlink' => 'ssh2/ssh2.stub', 'ssh2_sftp_unlink' => 'ssh2/ssh2.stub', 'ssh2_shell' => 'ssh2/ssh2.stub', 'ssh2_tunnel' => 'ssh2/ssh2.stub', 'stat' => 'standard/standard_7.stub', 'stats_absolute_deviation' => 'stats/stats.stub', 'stats_cdf_beta' => 'stats/stats.stub', 'stats_cdf_binomial' => 'stats/stats.stub', 'stats_cdf_cauchy' => 'stats/stats.stub', 'stats_cdf_chisquare' => 'stats/stats.stub', 'stats_cdf_exponential' => 'stats/stats.stub', 'stats_cdf_f' => 'stats/stats.stub', 'stats_cdf_gamma' => 'stats/stats.stub', 'stats_cdf_laplace' => 'stats/stats.stub', 'stats_cdf_logistic' => 'stats/stats.stub', 'stats_cdf_negative_binomial' => 'stats/stats.stub', 'stats_cdf_noncentral_chisquare' => 'stats/stats.stub', 'stats_cdf_noncentral_f' => 'stats/stats.stub', 'stats_cdf_noncentral_t' => 'stats/stats.stub', 'stats_cdf_normal' => 'stats/stats.stub', 'stats_cdf_poisson' => 'stats/stats.stub', 'stats_cdf_t' => 'stats/stats.stub', 'stats_cdf_uniform' => 'stats/stats.stub', 'stats_cdf_weibull' => 'stats/stats.stub', 'stats_covariance' => 'stats/stats.stub', 'stats_dens_beta' => 'stats/stats.stub', 'stats_dens_cauchy' => 'stats/stats.stub', 'stats_dens_chisquare' => 'stats/stats.stub', 'stats_dens_exponential' => 'stats/stats.stub', 'stats_dens_f' => 'stats/stats.stub', 'stats_dens_gamma' => 'stats/stats.stub', 'stats_dens_laplace' => 'stats/stats.stub', 'stats_dens_logistic' => 'stats/stats.stub', 'stats_dens_normal' => 'stats/stats.stub', 'stats_dens_pmf_binomial' => 'stats/stats.stub', 'stats_dens_pmf_hypergeometric' => 'stats/stats.stub', 'stats_dens_pmf_negative_binomial' => 'stats/stats.stub', 'stats_dens_pmf_poisson' => 'stats/stats.stub', 'stats_dens_t' => 'stats/stats.stub', 'stats_dens_uniform' => 'stats/stats.stub', 'stats_dens_weibull' => 'stats/stats.stub', 'stats_harmonic_mean' => 'stats/stats.stub', 'stats_kurtosis' => 'stats/stats.stub', 'stats_rand_gen_beta' => 'stats/stats.stub', 'stats_rand_gen_chisquare' => 'stats/stats.stub', 'stats_rand_gen_exponential' => 'stats/stats.stub', 'stats_rand_gen_f' => 'stats/stats.stub', 'stats_rand_gen_funiform' => 'stats/stats.stub', 'stats_rand_gen_gamma' => 'stats/stats.stub', 'stats_rand_gen_ibinomial' => 'stats/stats.stub', 'stats_rand_gen_ibinomial_negative' => 'stats/stats.stub', 'stats_rand_gen_int' => 'stats/stats.stub', 'stats_rand_gen_ipoisson' => 'stats/stats.stub', 'stats_rand_gen_iuniform' => 'stats/stats.stub', 'stats_rand_gen_noncentral_f' => 'stats/stats.stub', 'stats_rand_gen_noncentral_t' => 'stats/stats.stub', 'stats_rand_gen_normal' => 'stats/stats.stub', 'stats_rand_gen_t' => 'stats/stats.stub', 'stats_rand_get_seeds' => 'stats/stats.stub', 'stats_rand_phrase_to_seeds' => 'stats/stats.stub', 'stats_rand_ranf' => 'stats/stats.stub', 'stats_rand_setall' => 'stats/stats.stub', 'stats_skew' => 'stats/stats.stub', 'stats_standard_deviation' => 'stats/stats.stub', 'stats_stat_binomial_coef' => 'stats/stats.stub', 'stats_stat_correlation' => 'stats/stats.stub', 'stats_stat_factorial' => 'stats/stats.stub', 'stats_stat_independent_t' => 'stats/stats.stub', 'stats_stat_innerproduct' => 'stats/stats.stub', 'stats_stat_paired_t' => 'stats/stats.stub', 'stats_stat_percentile' => 'stats/stats.stub', 'stats_stat_powersum' => 'stats/stats.stub', 'stats_variance' => 'stats/stats.stub', 'stomp_abort' => 'stomp/stomp.stub', 'stomp_ack' => 'stomp/stomp.stub', 'stomp_begin' => 'stomp/stomp.stub', 'stomp_close' => 'stomp/stomp.stub', 'stomp_commit' => 'stomp/stomp.stub', 'stomp_connect' => 'stomp/stomp.stub', 'stomp_error' => 'stomp/stomp.stub', 'stomp_get_session_id' => 'stomp/stomp.stub', 'stomp_get_timeout' => 'stomp/stomp.stub', 'stomp_has_frame' => 'stomp/stomp.stub', 'stomp_read_frame' => 'stomp/stomp.stub', 'stomp_send' => 'stomp/stomp.stub', 'stomp_set_timeout' => 'stomp/stomp.stub', 'stomp_subscribe' => 'stomp/stomp.stub', 'stomp_unsubscribe' => 'stomp/stomp.stub', 'stomp_version' => 'stomp/stomp.stub', 'str_contains' => 'Core/Core.stub', 'str_decrement' => 'Core/Core.stub', 'str_ends_with' => 'Core/Core.stub', 'str_getcsv' => 'standard/standard_2.stub', 'str_increment' => 'Core/Core.stub', 'str_ireplace' => 'standard/standard_1.stub', 'str_pad' => 'standard/standard_2.stub', 'str_repeat' => 'standard/standard_1.stub', 'str_replace' => 'standard/standard_1.stub', 'str_rot13' => 'standard/standard_9.stub', 'str_shuffle' => 'standard/standard_1.stub', 'str_split' => 'standard/standard_1.stub', 'str_starts_with' => 'Core/Core.stub', 'str_word_count' => 'standard/standard_1.stub', 'strcasecmp' => 'Core/Core.stub', 'strchr' => 'standard/standard_2.stub', 'strcmp' => 'Core/Core.stub', 'strcoll' => 'standard/standard_1.stub', 'strcspn' => 'standard/standard_0.stub', 'stream_bucket_append' => 'standard/standard_9.stub', 'stream_bucket_make_writeable' => 'standard/standard_9.stub', 'stream_bucket_new' => 'standard/standard_9.stub', 'stream_bucket_prepend' => 'standard/standard_9.stub', 'stream_context_create' => 'standard/standard_6.stub', 'stream_context_get_default' => 'standard/standard_6.stub', 'stream_context_get_options' => 'standard/standard_6.stub', 'stream_context_get_params' => 'standard/standard_6.stub', 'stream_context_set_default' => 'standard/standard_6.stub', 'stream_context_set_option' => 'standard/standard_6.stub', 'stream_context_set_options' => 'standard/standard_6.stub', 'stream_context_set_params' => 'standard/standard_6.stub', 'stream_copy_to_stream' => 'standard/standard_6.stub', 'stream_filter_append' => 'standard/standard_6.stub', 'stream_filter_prepend' => 'standard/standard_6.stub', 'stream_filter_register' => 'standard/standard_9.stub', 'stream_filter_remove' => 'standard/standard_6.stub', 'stream_get_contents' => 'standard/standard_6.stub', 'stream_get_filters' => 'standard/standard_9.stub', 'stream_get_line' => 'standard/standard_6.stub', 'stream_get_meta_data' => 'standard/standard_6.stub', 'stream_get_transports' => 'standard/standard_6.stub', 'stream_get_wrappers' => 'standard/standard_6.stub', 'stream_is_local' => 'standard/standard_6.stub', 'stream_isatty' => 'standard/standard_9.stub', 'stream_register_wrapper' => 'standard/standard_6.stub', 'stream_resolve_include_path' => 'standard/standard_6.stub', 'stream_select' => 'standard/standard_6.stub', 'stream_set_blocking' => 'standard/standard_6.stub', 'stream_set_chunk_size' => 'standard/standard_8.stub', 'stream_set_read_buffer' => 'standard/standard_6.stub', 'stream_set_timeout' => 'standard/standard_6.stub', 'stream_set_write_buffer' => 'standard/standard_6.stub', 'stream_socket_accept' => 'standard/standard_6.stub', 'stream_socket_client' => 'standard/standard_6.stub', 'stream_socket_enable_crypto' => 'standard/standard_6.stub', 'stream_socket_get_name' => 'standard/standard_6.stub', 'stream_socket_pair' => 'standard/standard_6.stub', 'stream_socket_recvfrom' => 'standard/standard_6.stub', 'stream_socket_sendto' => 'standard/standard_6.stub', 'stream_socket_server' => 'standard/standard_6.stub', 'stream_socket_shutdown' => 'standard/standard_6.stub', 'stream_supports_lock' => 'standard/standard_6.stub', 'stream_wrapper_register' => 'standard/standard_6.stub', 'stream_wrapper_restore' => 'standard/standard_6.stub', 'stream_wrapper_unregister' => 'standard/standard_6.stub', 'strftime' => 'date/date.stub', 'strip_tags' => 'standard/standard_1.stub', 'stripcslashes' => 'standard/standard_1.stub', 'stripos' => 'standard/standard_1.stub', 'stripslashes' => 'standard/standard_1.stub', 'stristr' => 'standard/standard_1.stub', 'strlen' => 'Core/Core.stub', 'strnatcasecmp' => 'standard/standard_0.stub', 'strnatcmp' => 'standard/standard_0.stub', 'strncasecmp' => 'Core/Core.stub', 'strncmp' => 'Core/Core.stub', 'strpbrk' => 'standard/standard_1.stub', 'strpos' => 'standard/standard_1.stub', 'strptime' => 'standard/standard_0.stub', 'strrchr' => 'standard/standard_1.stub', 'strrev' => 'standard/standard_1.stub', 'strripos' => 'standard/standard_1.stub', 'strrpos' => 'standard/standard_1.stub', 'strspn' => 'standard/standard_0.stub', 'strstr' => 'standard/standard_1.stub', 'strtok' => 'standard/standard_0.stub', 'strtolower' => 'standard/standard_1.stub', 'strtotime' => 'date/date.stub', 'strtoupper' => 'standard/standard_1.stub', 'strtr' => 'standard/standard_1.stub', 'strval' => 'standard/standard_5.stub', 'substr' => 'standard/standard_1.stub', 'substr_compare' => 'standard/standard_1.stub', 'substr_count' => 'standard/standard_0.stub', 'substr_replace' => 'standard/standard_1.stub', 'suhosin_encrypt_cookie' => 'suhosin/suhosin.stub', 'suhosin_get_raw_cookies' => 'suhosin/suhosin.stub', 'svn_add' => 'svn/svn.stub', 'svn_auth_get_parameter' => 'svn/svn.stub', 'svn_auth_set_parameter' => 'svn/svn.stub', 'svn_blame' => 'svn/svn.stub', 'svn_cat' => 'svn/svn.stub', 'svn_checkout' => 'svn/svn.stub', 'svn_cleanup' => 'svn/svn.stub', 'svn_client_version' => 'svn/svn.stub', 'svn_commit' => 'svn/svn.stub', 'svn_config_ensure' => 'svn/svn.stub', 'svn_copy' => 'svn/svn.stub', 'svn_delete' => 'svn/svn.stub', 'svn_diff' => 'svn/svn.stub', 'svn_export' => 'svn/svn.stub', 'svn_fs_abort_txn' => 'svn/svn.stub', 'svn_fs_apply_text' => 'svn/svn.stub', 'svn_fs_begin_txn2' => 'svn/svn.stub', 'svn_fs_change_node_prop' => 'svn/svn.stub', 'svn_fs_check_path' => 'svn/svn.stub', 'svn_fs_contents_changed' => 'svn/svn.stub', 'svn_fs_copy' => 'svn/svn.stub', 'svn_fs_delete' => 'svn/svn.stub', 'svn_fs_dir_entries' => 'svn/svn.stub', 'svn_fs_file_contents' => 'svn/svn.stub', 'svn_fs_file_length' => 'svn/svn.stub', 'svn_fs_is_dir' => 'svn/svn.stub', 'svn_fs_is_file' => 'svn/svn.stub', 'svn_fs_make_dir' => 'svn/svn.stub', 'svn_fs_make_file' => 'svn/svn.stub', 'svn_fs_node_created_rev' => 'svn/svn.stub', 'svn_fs_node_prop' => 'svn/svn.stub', 'svn_fs_props_changed' => 'svn/svn.stub', 'svn_fs_revision_prop' => 'svn/svn.stub', 'svn_fs_revision_root' => 'svn/svn.stub', 'svn_fs_txn_root' => 'svn/svn.stub', 'svn_fs_youngest_rev' => 'svn/svn.stub', 'svn_import' => 'svn/svn.stub', 'svn_info' => 'svn/svn.stub', 'svn_lock' => 'svn/svn.stub', 'svn_log' => 'svn/svn.stub', 'svn_ls' => 'svn/svn.stub', 'svn_mkdir' => 'svn/svn.stub', 'svn_move' => 'svn/svn.stub', 'svn_propget' => 'svn/svn.stub', 'svn_proplist' => 'svn/svn.stub', 'svn_repos_create' => 'svn/svn.stub', 'svn_repos_fs' => 'svn/svn.stub', 'svn_repos_fs_begin_txn_for_commit' => 'svn/svn.stub', 'svn_repos_fs_commit_txn' => 'svn/svn.stub', 'svn_repos_hotcopy' => 'svn/svn.stub', 'svn_repos_open' => 'svn/svn.stub', 'svn_repos_recover' => 'svn/svn.stub', 'svn_resolved' => 'svn/svn.stub', 'svn_revert' => 'svn/svn.stub', 'svn_status' => 'svn/svn.stub', 'svn_switch' => 'svn/svn.stub', 'svn_unlock' => 'svn/svn.stub', 'svn_update' => 'svn/svn.stub', 'swoole_async_dns_lookup_coro' => 'swoole/functions.stub', 'swoole_async_set' => 'swoole/functions.stub', 'swoole_clear_dns_cache' => 'swoole/functions.stub', 'swoole_clear_error' => 'swoole/functions.stub', 'swoole_client_select' => 'swoole/functions.stub', 'swoole_coroutine_create' => 'swoole/functions.stub', 'swoole_coroutine_defer' => 'swoole/functions.stub', 'swoole_coroutine_socketpair' => 'swoole/functions.stub', 'swoole_cpu_num' => 'swoole/functions.stub', 'swoole_errno' => 'swoole/functions.stub', 'swoole_error_log' => 'swoole/functions.stub', 'swoole_error_log_ex' => 'swoole/functions.stub', 'swoole_event_add' => 'swoole/functions.stub', 'swoole_event_cycle' => 'swoole/functions.stub', 'swoole_event_defer' => 'swoole/functions.stub', 'swoole_event_del' => 'swoole/functions.stub', 'swoole_event_dispatch' => 'swoole/functions.stub', 'swoole_event_exit' => 'swoole/functions.stub', 'swoole_event_isset' => 'swoole/functions.stub', 'swoole_event_set' => 'swoole/functions.stub', 'swoole_event_wait' => 'swoole/functions.stub', 'swoole_event_write' => 'swoole/functions.stub', 'swoole_get_local_ip' => 'swoole/functions.stub', 'swoole_get_local_mac' => 'swoole/functions.stub', 'swoole_get_mime_type' => 'swoole/functions.stub', 'swoole_get_object_by_handle' => 'swoole/functions.stub', 'swoole_get_objects' => 'swoole/functions.stub', 'swoole_get_vm_status' => 'swoole/functions.stub', 'swoole_hashcode' => 'swoole/functions.stub', 'swoole_ignore_error' => 'swoole/functions.stub', 'swoole_internal_call_user_shutdown_begin' => 'swoole/functions.stub', 'swoole_last_error' => 'swoole/functions.stub', 'swoole_mime_type_add' => 'swoole/functions.stub', 'swoole_mime_type_delete' => 'swoole/functions.stub', 'swoole_mime_type_exists' => 'swoole/functions.stub', 'swoole_mime_type_get' => 'swoole/functions.stub', 'swoole_mime_type_list' => 'swoole/functions.stub', 'swoole_mime_type_set' => 'swoole/functions.stub', 'swoole_select' => 'swoole/functions.stub', 'swoole_set_process_name' => 'swoole/functions.stub', 'swoole_strerror' => 'swoole/functions.stub', 'swoole_substr_json_decode' => 'swoole/functions.stub', 'swoole_substr_unserialize' => 'swoole/functions.stub', 'swoole_test_kernel_coroutine' => 'swoole/functions.stub', 'swoole_timer_after' => 'swoole/functions.stub', 'swoole_timer_clear' => 'swoole/functions.stub', 'swoole_timer_clear_all' => 'swoole/functions.stub', 'swoole_timer_exists' => 'swoole/functions.stub', 'swoole_timer_info' => 'swoole/functions.stub', 'swoole_timer_list' => 'swoole/functions.stub', 'swoole_timer_set' => 'swoole/functions.stub', 'swoole_timer_stats' => 'swoole/functions.stub', 'swoole_timer_tick' => 'swoole/functions.stub', 'swoole_version' => 'swoole/functions.stub', 'sybase_affected_rows' => 'sybase/sybase_ct.stub', 'sybase_close' => 'sybase/sybase_ct.stub', 'sybase_connect' => 'sybase/sybase_ct.stub', 'sybase_data_seek' => 'sybase/sybase_ct.stub', 'sybase_deadlock_retry_count' => 'sybase/sybase_ct.stub', 'sybase_fetch_array' => 'sybase/sybase_ct.stub', 'sybase_fetch_assoc' => 'sybase/sybase_ct.stub', 'sybase_fetch_field' => 'sybase/sybase_ct.stub', 'sybase_fetch_object' => 'sybase/sybase_ct.stub', 'sybase_fetch_row' => 'sybase/sybase_ct.stub', 'sybase_field_seek' => 'sybase/sybase_ct.stub', 'sybase_free_result' => 'sybase/sybase_ct.stub', 'sybase_get_last_message' => 'sybase/sybase_ct.stub', 'sybase_min_client_severity' => 'sybase/sybase_ct.stub', 'sybase_min_server_severity' => 'sybase/sybase_ct.stub', 'sybase_num_fields' => 'sybase/sybase_ct.stub', 'sybase_num_rows' => 'sybase/sybase_ct.stub', 'sybase_pconnect' => 'sybase/sybase_ct.stub', 'sybase_query' => 'sybase/sybase_ct.stub', 'sybase_result' => 'sybase/sybase_ct.stub', 'sybase_select_db' => 'sybase/sybase_ct.stub', 'sybase_set_message_handler' => 'sybase/sybase_ct.stub', 'sybase_unbuffered_query' => 'sybase/sybase_ct.stub', 'symlink' => 'standard/standard_2.stub', 'sys_get_temp_dir' => 'standard/standard_9.stub', 'sys_getloadavg' => 'standard/standard_3.stub', 'syslog' => 'standard/standard_8.stub', 'system' => 'standard/standard_2.stub', 'tan' => 'standard/standard_3.stub', 'tanh' => 'standard/standard_3.stub', 'tempnam' => 'standard/standard_5.stub', 'textdomain' => 'gettext/gettext.stub', 'tidy_access_count' => 'tidy/tidy.stub', 'tidy_clean_repair' => 'tidy/tidy.stub', 'tidy_config_count' => 'tidy/tidy.stub', 'tidy_diagnose' => 'tidy/tidy.stub', 'tidy_error_count' => 'tidy/tidy.stub', 'tidy_get_body' => 'tidy/tidy.stub', 'tidy_get_config' => 'tidy/tidy.stub', 'tidy_get_error_buffer' => 'tidy/tidy.stub', 'tidy_get_head' => 'tidy/tidy.stub', 'tidy_get_html' => 'tidy/tidy.stub', 'tidy_get_html_ver' => 'tidy/tidy.stub', 'tidy_get_opt_doc' => 'tidy/tidy.stub', 'tidy_get_output' => 'tidy/tidy.stub', 'tidy_get_release' => 'tidy/tidy.stub', 'tidy_get_root' => 'tidy/tidy.stub', 'tidy_get_status' => 'tidy/tidy.stub', 'tidy_getopt' => 'tidy/tidy.stub', 'tidy_is_xhtml' => 'tidy/tidy.stub', 'tidy_is_xml' => 'tidy/tidy.stub', 'tidy_parse_file' => 'tidy/tidy.stub', 'tidy_parse_string' => 'tidy/tidy.stub', 'tidy_repair_file' => 'tidy/tidy.stub', 'tidy_repair_string' => 'tidy/tidy.stub', 'tidy_warning_count' => 'tidy/tidy.stub', 'time' => 'date/date.stub', 'time_nanosleep' => 'standard/standard_0.stub', 'time_sleep_until' => 'standard/standard_0.stub', 'timezone_abbreviations_list' => 'date/date.stub', 'timezone_identifiers_list' => 'date/date.stub', 'timezone_location_get' => 'date/date.stub', 'timezone_name_from_abbr' => 'date/date.stub', 'timezone_name_get' => 'date/date.stub', 'timezone_offset_get' => 'date/date.stub', 'timezone_open' => 'date/date.stub', 'timezone_transitions_get' => 'date/date.stub', 'timezone_version_get' => 'date/date.stub', 'tmpfile' => 'standard/standard_5.stub', 'token_get_all' => 'tokenizer/tokenizer.stub', 'token_name' => 'tokenizer/tokenizer.stub', 'touch' => 'standard/standard_7.stub', 'trait_exists' => 'Core/Core.stub', 'transliterator_create' => 'intl/intl.stub', 'transliterator_create_from_rules' => 'intl/intl.stub', 'transliterator_create_inverse' => 'intl/intl.stub', 'transliterator_get_error_code' => 'intl/intl.stub', 'transliterator_get_error_message' => 'intl/intl.stub', 'transliterator_list_ids' => 'intl/intl.stub', 'transliterator_transliterate' => 'intl/intl.stub', 'trigger_error' => 'Core/Core.stub', 'trim' => 'standard/standard_1.stub', 'uasort' => 'standard/standard_8.stub', 'ucfirst' => 'standard/standard_1.stub', 'ucwords' => 'standard/standard_1.stub', 'uksort' => 'standard/standard_8.stub', 'umask' => 'standard/standard_5.stub', 'uniqid' => 'standard/standard_3.stub', 'unixtojd' => 'calendar/calendar.stub', 'unlink' => 'standard/standard_2.stub', 'unpack' => 'standard/standard_7.stub', 'unregister_event_handler' => 'zend/zend.stub', 'unregister_tick_function' => 'standard/standard_4.stub', 'unserialize' => 'standard/standard_4.stub', 'uopz_add_function' => 'uopz/uopz.stub', 'uopz_allow_exit' => 'uopz/uopz.stub', 'uopz_call_user_func' => 'uopz/uopz.stub', 'uopz_call_user_func_array' => 'uopz/uopz.stub', 'uopz_del_function' => 'uopz/uopz.stub', 'uopz_extend' => 'uopz/uopz.stub', 'uopz_flags' => 'uopz/uopz.stub', 'uopz_get_exit_status' => 'uopz/uopz.stub', 'uopz_get_hook' => 'uopz/uopz.stub', 'uopz_get_mock' => 'uopz/uopz.stub', 'uopz_get_property' => 'uopz/uopz.stub', 'uopz_get_return' => 'uopz/uopz.stub', 'uopz_get_static' => 'uopz/uopz.stub', 'uopz_implement' => 'uopz/uopz.stub', 'uopz_redefine' => 'uopz/uopz.stub', 'uopz_set_hook' => 'uopz/uopz.stub', 'uopz_set_mock' => 'uopz/uopz.stub', 'uopz_set_property' => 'uopz/uopz.stub', 'uopz_set_return' => 'uopz/uopz.stub', 'uopz_set_static' => 'uopz/uopz.stub', 'uopz_undefine' => 'uopz/uopz.stub', 'uopz_unset_hook' => 'uopz/uopz.stub', 'uopz_unset_mock' => 'uopz/uopz.stub', 'uopz_unset_return' => 'uopz/uopz.stub', 'uploadprogress_get_contents' => 'uploadprogress/uploadprogress.stub', 'uploadprogress_get_info' => 'uploadprogress/uploadprogress.stub', 'urldecode' => 'standard/standard_2.stub', 'urlencode' => 'standard/standard_2.stub', 'use_soap_error_handler' => 'soap/soap.stub', 'user_error' => 'Core/Core.stub', 'usleep' => 'standard/standard_0.stub', 'usort' => 'standard/standard_8.stub', 'utf8_decode' => 'standard/basic.stub', 'utf8_encode' => 'standard/basic.stub', 'uuid_compare' => 'uuid/uuid_c.stub', 'uuid_create' => 'uuid/uuid_c.stub', 'uuid_generate_md5' => 'uuid/uuid_c.stub', 'uuid_generate_sha1' => 'uuid/uuid_c.stub', 'uuid_is_null' => 'uuid/uuid_c.stub', 'uuid_is_valid' => 'uuid/uuid_c.stub', 'uuid_mac' => 'uuid/uuid_c.stub', 'uuid_parse' => 'uuid/uuid_c.stub', 'uuid_time' => 'uuid/uuid_c.stub', 'uuid_type' => 'uuid/uuid_c.stub', 'uuid_unparse' => 'uuid/uuid_c.stub', 'uuid_variant' => 'uuid/uuid_c.stub', 'uv_accept' => 'uv/uv_functions.stub', 'uv_async_init' => 'uv/uv_functions.stub', 'uv_async_send' => 'uv/uv_functions.stub', 'uv_chdir' => 'uv/uv_functions.stub', 'uv_check_init' => 'uv/uv_functions.stub', 'uv_check_start' => 'uv/uv_functions.stub', 'uv_check_stop' => 'uv/uv_functions.stub', 'uv_close' => 'uv/uv_functions.stub', 'uv_cpu_info' => 'uv/uv_functions.stub', 'uv_default_loop' => 'uv/uv_functions.stub', 'uv_err_name' => 'uv/uv_functions.stub', 'uv_exepath' => 'uv/uv_functions.stub', 'uv_fs_chmod' => 'uv/uv_functions.stub', 'uv_fs_chown' => 'uv/uv_functions.stub', 'uv_fs_close' => 'uv/uv_functions.stub', 'uv_fs_event_init' => 'uv/uv_functions.stub', 'uv_fs_fchmod' => 'uv/uv_functions.stub', 'uv_fs_fchown' => 'uv/uv_functions.stub', 'uv_fs_fdatasync' => 'uv/uv_functions.stub', 'uv_fs_fstat' => 'uv/uv_functions.stub', 'uv_fs_fsync' => 'uv/uv_functions.stub', 'uv_fs_ftruncate' => 'uv/uv_functions.stub', 'uv_fs_futime' => 'uv/uv_functions.stub', 'uv_fs_link' => 'uv/uv_functions.stub', 'uv_fs_lstat' => 'uv/uv_functions.stub', 'uv_fs_mkdir' => 'uv/uv_functions.stub', 'uv_fs_open' => 'uv/uv_functions.stub', 'uv_fs_poll_init' => 'uv/uv_functions.stub', 'uv_fs_poll_start' => 'uv/uv_functions.stub', 'uv_fs_poll_stop' => 'uv/uv_functions.stub', 'uv_fs_read' => 'uv/uv_functions.stub', 'uv_fs_readdir' => 'uv/uv_functions.stub', 'uv_fs_readlink' => 'uv/uv_functions.stub', 'uv_fs_rename' => 'uv/uv_functions.stub', 'uv_fs_rmdir' => 'uv/uv_functions.stub', 'uv_fs_sendfile' => 'uv/uv_functions.stub', 'uv_fs_stat' => 'uv/uv_functions.stub', 'uv_fs_symlink' => 'uv/uv_functions.stub', 'uv_fs_unlink' => 'uv/uv_functions.stub', 'uv_fs_utime' => 'uv/uv_functions.stub', 'uv_fs_write' => 'uv/uv_functions.stub', 'uv_get_free_memory' => 'uv/uv_functions.stub', 'uv_get_total_memory' => 'uv/uv_functions.stub', 'uv_getaddrinfo' => 'uv/uv_functions.stub', 'uv_guess_handle' => 'uv/uv_functions.stub', 'uv_hrtime' => 'uv/uv_functions.stub', 'uv_idle_init' => 'uv/uv_functions.stub', 'uv_idle_start' => 'uv/uv_functions.stub', 'uv_idle_stop' => 'uv/uv_functions.stub', 'uv_interface_addresses' => 'uv/uv_functions.stub', 'uv_ip4_addr' => 'uv/uv_functions.stub', 'uv_ip4_name' => 'uv/uv_functions.stub', 'uv_ip6_addr' => 'uv/uv_functions.stub', 'uv_ip6_name' => 'uv/uv_functions.stub', 'uv_is_active' => 'uv/uv_functions.stub', 'uv_is_closing' => 'uv/uv_functions.stub', 'uv_is_readable' => 'uv/uv_functions.stub', 'uv_is_writable' => 'uv/uv_functions.stub', 'uv_kill' => 'uv/uv_functions.stub', 'uv_last_error' => 'uv/uv_functions.stub', 'uv_listen' => 'uv/uv_functions.stub', 'uv_loadavg' => 'uv/uv_functions.stub', 'uv_loop_delete' => 'uv/uv_functions.stub', 'uv_loop_new' => 'uv/uv_functions.stub', 'uv_mutex_init' => 'uv/uv_functions.stub', 'uv_mutex_lock' => 'uv/uv_functions.stub', 'uv_mutex_trylock' => 'uv/uv_functions.stub', 'uv_now' => 'uv/uv_functions.stub', 'uv_pipe_bind' => 'uv/uv_functions.stub', 'uv_pipe_connect' => 'uv/uv_functions.stub', 'uv_pipe_init' => 'uv/uv_functions.stub', 'uv_pipe_open' => 'uv/uv_functions.stub', 'uv_pipe_pending_instances' => 'uv/uv_functions.stub', 'uv_poll_init' => 'uv/uv_functions.stub', 'uv_poll_start' => 'uv/uv_functions.stub', 'uv_poll_stop' => 'uv/uv_functions.stub', 'uv_prepare_init' => 'uv/uv_functions.stub', 'uv_prepare_start' => 'uv/uv_functions.stub', 'uv_prepare_stop' => 'uv/uv_functions.stub', 'uv_process_kill' => 'uv/uv_functions.stub', 'uv_queue_work' => 'uv/uv_functions.stub', 'uv_read_start' => 'uv/uv_functions.stub', 'uv_read_stop' => 'uv/uv_functions.stub', 'uv_ref' => 'uv/uv_functions.stub', 'uv_resident_set_memory' => 'uv/uv_functions.stub', 'uv_run' => 'uv/uv_functions.stub', 'uv_run_once' => 'uv/uv_functions.stub', 'uv_rwlock_init' => 'uv/uv_functions.stub', 'uv_rwlock_rdlock' => 'uv/uv_functions.stub', 'uv_rwlock_rdunlock' => 'uv/uv_functions.stub', 'uv_rwlock_tryrdlock' => 'uv/uv_functions.stub', 'uv_rwlock_trywrlock' => 'uv/uv_functions.stub', 'uv_rwlock_wrlock' => 'uv/uv_functions.stub', 'uv_rwlock_wrunlock' => 'uv/uv_functions.stub', 'uv_sem_init' => 'uv/uv_functions.stub', 'uv_sem_post' => 'uv/uv_functions.stub', 'uv_sem_trywait' => 'uv/uv_functions.stub', 'uv_sem_wait' => 'uv/uv_functions.stub', 'uv_shutdown' => 'uv/uv_functions.stub', 'uv_signal_stop' => 'uv/uv_functions.stub', 'uv_spawn' => 'uv/uv_functions.stub', 'uv_stdio_new' => 'uv/uv_functions.stub', 'uv_stop' => 'uv/uv_functions.stub', 'uv_strerror' => 'uv/uv_functions.stub', 'uv_tcp_bind' => 'uv/uv_functions.stub', 'uv_tcp_bind6' => 'uv/uv_functions.stub', 'uv_tcp_connect' => 'uv/uv_functions.stub', 'uv_tcp_connect6' => 'uv/uv_functions.stub', 'uv_tcp_getpeername' => 'uv/uv_functions.stub', 'uv_tcp_getsockname' => 'uv/uv_functions.stub', 'uv_tcp_init' => 'uv/uv_functions.stub', 'uv_tcp_nodelay' => 'uv/uv_functions.stub', 'uv_timer_again' => 'uv/uv_functions.stub', 'uv_timer_get_repeat' => 'uv/uv_functions.stub', 'uv_timer_init' => 'uv/uv_functions.stub', 'uv_timer_set_repeat' => 'uv/uv_functions.stub', 'uv_timer_start' => 'uv/uv_functions.stub', 'uv_timer_stop' => 'uv/uv_functions.stub', 'uv_tty_get_winsize' => 'uv/uv_functions.stub', 'uv_tty_init' => 'uv/uv_functions.stub', 'uv_tty_reset_mode' => 'uv/uv_functions.stub', 'uv_tty_set_mode' => 'uv/uv_functions.stub', 'uv_udp_bind' => 'uv/uv_functions.stub', 'uv_udp_bind6' => 'uv/uv_functions.stub', 'uv_udp_getsockname' => 'uv/uv_functions.stub', 'uv_udp_init' => 'uv/uv_functions.stub', 'uv_udp_recv_start' => 'uv/uv_functions.stub', 'uv_udp_recv_stop' => 'uv/uv_functions.stub', 'uv_udp_send' => 'uv/uv_functions.stub', 'uv_udp_send6' => 'uv/uv_functions.stub', 'uv_udp_set_broadcast' => 'uv/uv_functions.stub', 'uv_udp_set_membership' => 'uv/uv_functions.stub', 'uv_udp_set_multicast_loop' => 'uv/uv_functions.stub', 'uv_udp_set_multicast_ttl' => 'uv/uv_functions.stub', 'uv_unref' => 'uv/uv_functions.stub', 'uv_update_time' => 'uv/uv_functions.stub', 'uv_uptime' => 'uv/uv_functions.stub', 'uv_walk' => 'uv/uv_functions.stub', 'uv_write' => 'uv/uv_functions.stub', 'uv_write2' => 'uv/uv_functions.stub', 'var_dump' => 'standard/standard_4.stub', 'var_export' => 'standard/standard_4.stub', 'variant_abs' => 'com_dotnet/com_dotnet.stub', 'variant_add' => 'com_dotnet/com_dotnet.stub', 'variant_and' => 'com_dotnet/com_dotnet.stub', 'variant_cast' => 'com_dotnet/com_dotnet.stub', 'variant_cat' => 'com_dotnet/com_dotnet.stub', 'variant_cmp' => 'com_dotnet/com_dotnet.stub', 'variant_date_from_timestamp' => 'com_dotnet/com_dotnet.stub', 'variant_date_to_timestamp' => 'com_dotnet/com_dotnet.stub', 'variant_div' => 'com_dotnet/com_dotnet.stub', 'variant_eqv' => 'com_dotnet/com_dotnet.stub', 'variant_fix' => 'com_dotnet/com_dotnet.stub', 'variant_get_type' => 'com_dotnet/com_dotnet.stub', 'variant_idiv' => 'com_dotnet/com_dotnet.stub', 'variant_imp' => 'com_dotnet/com_dotnet.stub', 'variant_int' => 'com_dotnet/com_dotnet.stub', 'variant_mod' => 'com_dotnet/com_dotnet.stub', 'variant_mul' => 'com_dotnet/com_dotnet.stub', 'variant_neg' => 'com_dotnet/com_dotnet.stub', 'variant_not' => 'com_dotnet/com_dotnet.stub', 'variant_or' => 'com_dotnet/com_dotnet.stub', 'variant_pow' => 'com_dotnet/com_dotnet.stub', 'variant_round' => 'com_dotnet/com_dotnet.stub', 'variant_set' => 'com_dotnet/com_dotnet.stub', 'variant_set_type' => 'com_dotnet/com_dotnet.stub', 'variant_sub' => 'com_dotnet/com_dotnet.stub', 'variant_xor' => 'com_dotnet/com_dotnet.stub', 'version_compare' => 'standard/standard_9.stub', 'vfprintf' => 'standard/standard_2.stub', 'virtual' => 'apache/apache.stub', 'vprintf' => 'standard/standard_2.stub', 'vsprintf' => 'standard/standard_2.stub', 'wb_call_function' => 'winbinder/winbinder.stub', 'wb_create_font' => 'winbinder/winbinder.stub', 'wb_create_image' => 'winbinder/winbinder.stub', 'wb_create_mask' => 'winbinder/winbinder.stub', 'wb_create_timer' => 'winbinder/winbinder.stub', 'wb_create_window' => 'winbinder/winbinder.stub', 'wb_delete_items' => 'winbinder/winbinder.stub', 'wb_destroy_control' => 'winbinder/winbinder.stub', 'wb_destroy_font' => 'winbinder/winbinder.stub', 'wb_destroy_image' => 'winbinder/winbinder.stub', 'wb_destroy_timer' => 'winbinder/winbinder.stub', 'wb_destroy_window' => 'winbinder/winbinder.stub', 'wb_draw_ellipse' => 'winbinder/winbinder.stub', 'wb_draw_image' => 'winbinder/winbinder.stub', 'wb_draw_line' => 'winbinder/winbinder.stub', 'wb_draw_point' => 'winbinder/winbinder.stub', 'wb_draw_rect' => 'winbinder/winbinder.stub', 'wb_draw_text' => 'winbinder/winbinder.stub', 'wb_exec' => 'winbinder/winbinder.stub', 'wb_find_file' => 'winbinder/winbinder.stub', 'wb_get_address' => 'winbinder/winbinder.stub', 'wb_get_class' => 'winbinder/winbinder.stub', 'wb_get_control' => 'winbinder/winbinder.stub', 'wb_get_enabled' => 'winbinder/winbinder.stub', 'wb_get_enum_callback' => 'winbinder/winbinder.stub', 'wb_get_focus' => 'winbinder/winbinder.stub', 'wb_get_function_address' => 'winbinder/winbinder.stub', 'wb_get_hook_callback' => 'winbinder/winbinder.stub', 'wb_get_id' => 'winbinder/winbinder.stub', 'wb_get_image_data' => 'winbinder/winbinder.stub', 'wb_get_instance' => 'winbinder/winbinder.stub', 'wb_get_item_count' => 'winbinder/winbinder.stub', 'wb_get_item_list' => 'winbinder/winbinder.stub', 'wb_get_level' => 'winbinder/winbinder.stub', 'wb_get_midi_callback' => 'winbinder/winbinder.stub', 'wb_get_parent' => 'winbinder/winbinder.stub', 'wb_get_pixel' => 'winbinder/winbinder.stub', 'wb_get_position' => 'winbinder/winbinder.stub', 'wb_get_registry_key' => 'winbinder/winbinder.stub', 'wb_get_selected' => 'winbinder/winbinder.stub', 'wb_get_size' => 'winbinder/winbinder.stub', 'wb_get_state' => 'winbinder/winbinder.stub', 'wb_get_system_info' => 'winbinder/winbinder.stub', 'wb_get_value' => 'winbinder/winbinder.stub', 'wb_get_visible' => 'winbinder/winbinder.stub', 'wb_load_image' => 'winbinder/winbinder.stub', 'wb_load_library' => 'winbinder/winbinder.stub', 'wb_main_loop' => 'winbinder/winbinder.stub', 'wb_message_box' => 'winbinder/winbinder.stub', 'wb_peek' => 'winbinder/winbinder.stub', 'wb_play_sound' => 'winbinder/winbinder.stub', 'wb_poke' => 'winbinder/winbinder.stub', 'wb_refresh' => 'winbinder/winbinder.stub', 'wb_release_library' => 'winbinder/winbinder.stub', 'wb_save_image' => 'winbinder/winbinder.stub', 'wb_send_message' => 'winbinder/winbinder.stub', 'wb_set_area' => 'winbinder/winbinder.stub', 'wb_set_cursor' => 'winbinder/winbinder.stub', 'wb_set_enabled' => 'winbinder/winbinder.stub', 'wb_set_focus' => 'winbinder/winbinder.stub', 'wb_set_font' => 'winbinder/winbinder.stub', 'wb_set_handler' => 'winbinder/winbinder.stub', 'wb_set_image' => 'winbinder/winbinder.stub', 'wb_set_item_image' => 'winbinder/winbinder.stub', 'wb_set_location' => 'winbinder/winbinder.stub', 'wb_set_position' => 'winbinder/winbinder.stub', 'wb_set_range' => 'winbinder/winbinder.stub', 'wb_set_registry_key' => 'winbinder/winbinder.stub', 'wb_set_size' => 'winbinder/winbinder.stub', 'wb_set_state' => 'winbinder/winbinder.stub', 'wb_set_style' => 'winbinder/winbinder.stub', 'wb_set_visible' => 'winbinder/winbinder.stub', 'wb_sort' => 'winbinder/winbinder.stub', 'wb_stop_sound' => 'winbinder/winbinder.stub', 'wb_sys_dlg_color' => 'winbinder/winbinder.stub', 'wb_sys_dlg_path' => 'winbinder/winbinder.stub', 'wb_wait' => 'winbinder/winbinder.stub', 'wbtemp_clear_listview_columns' => 'winbinder/winbinder.stub', 'wbtemp_create_control' => 'winbinder/winbinder.stub', 'wbtemp_create_item' => 'winbinder/winbinder.stub', 'wbtemp_create_listview_column' => 'winbinder/winbinder.stub', 'wbtemp_create_listview_item' => 'winbinder/winbinder.stub', 'wbtemp_create_menu' => 'winbinder/winbinder.stub', 'wbtemp_create_statusbar_items' => 'winbinder/winbinder.stub', 'wbtemp_create_toolbar' => 'winbinder/winbinder.stub', 'wbtemp_create_treeview_item' => 'winbinder/winbinder.stub', 'wbtemp_get_listview_columns' => 'winbinder/winbinder.stub', 'wbtemp_get_listview_item_checked' => 'winbinder/winbinder.stub', 'wbtemp_get_listview_text' => 'winbinder/winbinder.stub', 'wbtemp_get_menu_item_checked' => 'winbinder/winbinder.stub', 'wbtemp_get_text' => 'winbinder/winbinder.stub', 'wbtemp_get_treeview_item_text' => 'winbinder/winbinder.stub', 'wbtemp_select_all_listview_items' => 'winbinder/winbinder.stub', 'wbtemp_select_listview_item' => 'winbinder/winbinder.stub', 'wbtemp_select_tab' => 'winbinder/winbinder.stub', 'wbtemp_set_accel_table' => 'winbinder/winbinder.stub', 'wbtemp_set_listview_item_checked' => 'winbinder/winbinder.stub', 'wbtemp_set_listview_item_text' => 'winbinder/winbinder.stub', 'wbtemp_set_menu_item_checked' => 'winbinder/winbinder.stub', 'wbtemp_set_menu_item_image' => 'winbinder/winbinder.stub', 'wbtemp_set_menu_item_selected' => 'winbinder/winbinder.stub', 'wbtemp_set_text' => 'winbinder/winbinder.stub', 'wbtemp_set_treeview_item_selected' => 'winbinder/winbinder.stub', 'wbtemp_set_treeview_item_text' => 'winbinder/winbinder.stub', 'wbtemp_set_treeview_item_value' => 'winbinder/winbinder.stub', 'wbtemp_set_value' => 'winbinder/winbinder.stub', 'wbtemp_sys_dlg_open' => 'winbinder/winbinder.stub', 'wbtemp_sys_dlg_save' => 'winbinder/winbinder.stub', 'wddx_add_vars' => 'wddx/wddx.stub', 'wddx_deserialize' => 'wddx/wddx.stub', 'wddx_packet_end' => 'wddx/wddx.stub', 'wddx_packet_start' => 'wddx/wddx.stub', 'wddx_serialize_value' => 'wddx/wddx.stub', 'wddx_serialize_vars' => 'wddx/wddx.stub', 'win32_continue_service' => 'win32service/win32service.stub', 'win32_create_service' => 'win32service/win32service.stub', 'win32_delete_service' => 'win32service/win32service.stub', 'win32_get_last_control_message' => 'win32service/win32service.stub', 'win32_pause_service' => 'win32service/win32service.stub', 'win32_query_service_status' => 'win32service/win32service.stub', 'win32_set_service_status' => 'win32service/win32service.stub', 'win32_start_service' => 'win32service/win32service.stub', 'win32_start_service_ctrl_dispatcher' => 'win32service/win32service.stub', 'win32_stop_service' => 'win32service/win32service.stub', 'wincache_fcache_fileinfo' => 'wincache/wincache.stub', 'wincache_fcache_meminfo' => 'wincache/wincache.stub', 'wincache_lock' => 'wincache/wincache.stub', 'wincache_ocache_fileinfo' => 'wincache/wincache.stub', 'wincache_ocache_meminfo' => 'wincache/wincache.stub', 'wincache_refresh_if_changed' => 'wincache/wincache.stub', 'wincache_rplist_fileinfo' => 'wincache/wincache.stub', 'wincache_rplist_meminfo' => 'wincache/wincache.stub', 'wincache_scache_info' => 'wincache/wincache.stub', 'wincache_scache_meminfo' => 'wincache/wincache.stub', 'wincache_ucache_add' => 'wincache/wincache.stub', 'wincache_ucache_cas' => 'wincache/wincache.stub', 'wincache_ucache_clear' => 'wincache/wincache.stub', 'wincache_ucache_dec' => 'wincache/wincache.stub', 'wincache_ucache_delete' => 'wincache/wincache.stub', 'wincache_ucache_exists' => 'wincache/wincache.stub', 'wincache_ucache_get' => 'wincache/wincache.stub', 'wincache_ucache_inc' => 'wincache/wincache.stub', 'wincache_ucache_info' => 'wincache/wincache.stub', 'wincache_ucache_meminfo' => 'wincache/wincache.stub', 'wincache_ucache_set' => 'wincache/wincache.stub', 'wincache_unlock' => 'wincache/wincache.stub', 'wordwrap' => 'standard/standard_0.stub', 'xcache_asm' => 'xcache/xcache.stub', 'xcache_clear_cache' => 'xcache/xcache.stub', 'xcache_coredump' => 'xcache/xcache.stub', 'xcache_count' => 'xcache/xcache.stub', 'xcache_coverager_decode' => 'xcache/xcache.stub', 'xcache_coverager_get' => 'xcache/xcache.stub', 'xcache_coverager_start' => 'xcache/xcache.stub', 'xcache_coverager_stop' => 'xcache/xcache.stub', 'xcache_dasm_file' => 'xcache/xcache.stub', 'xcache_dasm_string' => 'xcache/xcache.stub', 'xcache_dec' => 'xcache/xcache.stub', 'xcache_decode' => 'xcache/xcache.stub', 'xcache_encode' => 'xcache/xcache.stub', 'xcache_get' => 'xcache/xcache.stub', 'xcache_get_data_type' => 'xcache/xcache.stub', 'xcache_get_op_spec' => 'xcache/xcache.stub', 'xcache_get_op_type' => 'xcache/xcache.stub', 'xcache_get_opcode' => 'xcache/xcache.stub', 'xcache_get_opcode_spec' => 'xcache/xcache.stub', 'xcache_inc' => 'xcache/xcache.stub', 'xcache_info' => 'xcache/xcache.stub', 'xcache_is_autoglobal' => 'xcache/xcache.stub', 'xcache_isset' => 'xcache/xcache.stub', 'xcache_list' => 'xcache/xcache.stub', 'xcache_set' => 'xcache/xcache.stub', 'xcache_unset' => 'xcache/xcache.stub', 'xcache_unset_by_prefix' => 'xcache/xcache.stub', 'xdebug_break' => 'xdebug/xdebug.stub', 'xdebug_call_class' => 'xdebug/xdebug.stub', 'xdebug_call_file' => 'xdebug/xdebug.stub', 'xdebug_call_function' => 'xdebug/xdebug.stub', 'xdebug_call_line' => 'xdebug/xdebug.stub', 'xdebug_clear_aggr_profiling_data' => 'xdebug/xdebug.stub', 'xdebug_code_coverage_started' => 'xdebug/xdebug.stub', 'xdebug_connect_to_client' => 'xdebug/xdebug.stub', 'xdebug_debug_zval' => 'xdebug/xdebug.stub', 'xdebug_debug_zval_stdout' => 'xdebug/xdebug.stub', 'xdebug_disable' => 'xdebug/xdebug.stub', 'xdebug_dump_aggr_profiling_data' => 'xdebug/xdebug.stub', 'xdebug_dump_superglobals' => 'xdebug/xdebug.stub', 'xdebug_enable' => 'xdebug/xdebug.stub', 'xdebug_get_code_coverage' => 'xdebug/xdebug.stub', 'xdebug_get_collected_errors' => 'xdebug/xdebug.stub', 'xdebug_get_declared_vars' => 'xdebug/xdebug.stub', 'xdebug_get_formatted_function_stack' => 'xdebug/xdebug.stub', 'xdebug_get_function_count' => 'xdebug/xdebug.stub', 'xdebug_get_function_stack' => 'xdebug/xdebug.stub', 'xdebug_get_gc_run_count' => 'xdebug/xdebug.stub', 'xdebug_get_gc_total_collected_roots' => 'xdebug/xdebug.stub', 'xdebug_get_gcstats_filename' => 'xdebug/xdebug.stub', 'xdebug_get_headers' => 'xdebug/xdebug.stub', 'xdebug_get_monitored_functions' => 'xdebug/xdebug.stub', 'xdebug_get_profiler_filename' => 'xdebug/xdebug.stub', 'xdebug_get_stack_depth' => 'xdebug/xdebug.stub', 'xdebug_get_tracefile_name' => 'xdebug/xdebug.stub', 'xdebug_info' => 'xdebug/xdebug.stub', 'xdebug_is_debugger_active' => 'xdebug/xdebug.stub', 'xdebug_is_enabled' => 'xdebug/xdebug.stub', 'xdebug_memory_usage' => 'xdebug/xdebug.stub', 'xdebug_notify' => 'xdebug/xdebug.stub', 'xdebug_peak_memory_usage' => 'xdebug/xdebug.stub', 'xdebug_print_function_stack' => 'xdebug/xdebug.stub', 'xdebug_set_filter' => 'xdebug/xdebug.stub', 'xdebug_start_code_coverage' => 'xdebug/xdebug.stub', 'xdebug_start_error_collection' => 'xdebug/xdebug.stub', 'xdebug_start_function_monitor' => 'xdebug/xdebug.stub', 'xdebug_start_gcstats' => 'xdebug/xdebug.stub', 'xdebug_start_trace' => 'xdebug/xdebug.stub', 'xdebug_stop_code_coverage' => 'xdebug/xdebug.stub', 'xdebug_stop_error_collection' => 'xdebug/xdebug.stub', 'xdebug_stop_function_monitor' => 'xdebug/xdebug.stub', 'xdebug_stop_gcstats' => 'xdebug/xdebug.stub', 'xdebug_stop_trace' => 'xdebug/xdebug.stub', 'xdebug_time_index' => 'xdebug/xdebug.stub', 'xdebug_var_dump' => 'xdebug/xdebug.stub', 'xdiff_file_bdiff' => 'xdiff/xdiff.stub', 'xdiff_file_bdiff_size' => 'xdiff/xdiff.stub', 'xdiff_file_bpatch' => 'xdiff/xdiff.stub', 'xdiff_file_diff' => 'xdiff/xdiff.stub', 'xdiff_file_diff_binary' => 'xdiff/xdiff.stub', 'xdiff_file_merge3' => 'xdiff/xdiff.stub', 'xdiff_file_patch' => 'xdiff/xdiff.stub', 'xdiff_file_patch_binary' => 'xdiff/xdiff.stub', 'xdiff_file_rabdiff' => 'xdiff/xdiff.stub', 'xdiff_string_bdiff' => 'xdiff/xdiff.stub', 'xdiff_string_bdiff_size' => 'xdiff/xdiff.stub', 'xdiff_string_bpatch' => 'xdiff/xdiff.stub', 'xdiff_string_diff' => 'xdiff/xdiff.stub', 'xdiff_string_diff_binary' => 'xdiff/xdiff.stub', 'xdiff_string_merge3' => 'xdiff/xdiff.stub', 'xdiff_string_patch' => 'xdiff/xdiff.stub', 'xdiff_string_patch_binary' => 'xdiff/xdiff.stub', 'xdiff_string_rabdiff' => 'xdiff/xdiff.stub', 'xhprof_disable' => 'xhprof/xhprof.stub', 'xhprof_enable' => 'xhprof/xhprof.stub', 'xhprof_sample_disable' => 'xhprof/xhprof.stub', 'xhprof_sample_enable' => 'xhprof/xhprof.stub', 'xml_error_string' => 'xml/xml.stub', 'xml_get_current_byte_index' => 'xml/xml.stub', 'xml_get_current_column_number' => 'xml/xml.stub', 'xml_get_current_line_number' => 'xml/xml.stub', 'xml_get_error_code' => 'xml/xml.stub', 'xml_parse' => 'xml/xml.stub', 'xml_parse_into_struct' => 'xml/xml.stub', 'xml_parser_create' => 'xml/xml.stub', 'xml_parser_create_ns' => 'xml/xml.stub', 'xml_parser_free' => 'xml/xml.stub', 'xml_parser_get_option' => 'xml/xml.stub', 'xml_parser_set_option' => 'xml/xml.stub', 'xml_set_character_data_handler' => 'xml/xml.stub', 'xml_set_default_handler' => 'xml/xml.stub', 'xml_set_element_handler' => 'xml/xml.stub', 'xml_set_end_namespace_decl_handler' => 'xml/xml.stub', 'xml_set_external_entity_ref_handler' => 'xml/xml.stub', 'xml_set_notation_decl_handler' => 'xml/xml.stub', 'xml_set_object' => 'xml/xml.stub', 'xml_set_processing_instruction_handler' => 'xml/xml.stub', 'xml_set_start_namespace_decl_handler' => 'xml/xml.stub', 'xml_set_unparsed_entity_decl_handler' => 'xml/xml.stub', 'xmlrpc_decode' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_decode_request' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_encode' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_encode_request' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_get_type' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_is_fault' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_parse_method_descriptions' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_server_add_introspection_data' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_server_call_method' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_server_create' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_server_destroy' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_server_register_introspection_callback' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_server_register_method' => 'xmlrpc/xmlrpc.stub', 'xmlrpc_set_type' => 'xmlrpc/xmlrpc.stub', 'xmlwriter_end_attribute' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_end_cdata' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_end_comment' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_end_document' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_end_dtd' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_end_dtd_attlist' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_end_dtd_element' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_end_dtd_entity' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_end_element' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_end_pi' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_flush' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_full_end_element' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_open_memory' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_open_uri' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_output_memory' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_set_indent' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_set_indent_string' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_start_attribute' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_start_attribute_ns' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_start_cdata' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_start_comment' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_start_document' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_start_dtd' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_start_dtd_attlist' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_start_dtd_element' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_start_dtd_entity' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_start_element' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_start_element_ns' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_start_pi' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_text' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_write_attribute' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_write_attribute_ns' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_write_cdata' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_write_comment' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_write_dtd' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_write_dtd_attlist' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_write_dtd_element' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_write_dtd_entity' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_write_element' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_write_element_ns' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_write_pi' => 'xmlwriter/xmlwriter.stub', 'xmlwriter_write_raw' => 'xmlwriter/xmlwriter.stub', 'xxtea_decrypt' => 'xxtea/xxtea.stub', 'xxtea_encrypt' => 'xxtea/xxtea.stub', 'yaml_emit' => 'yaml/yaml.stub', 'yaml_emit_file' => 'yaml/yaml.stub', 'yaml_parse' => 'yaml/yaml.stub', 'yaml_parse_file' => 'yaml/yaml.stub', 'yaml_parse_url' => 'yaml/yaml.stub', 'zem_get_extension_info_by_id' => 'ZendUtils/ZendUtils.stub', 'zem_get_extension_info_by_name' => 'ZendUtils/ZendUtils.stub', 'zem_get_extensions_info' => 'ZendUtils/ZendUtils.stub', 'zem_get_license_info' => 'ZendUtils/ZendUtils.stub', 'zend_current_obfuscation_level' => 'zend/zend_f.stub', 'zend_disk_cache_clear' => 'ZendCache/ZendCache.stub', 'zend_disk_cache_delete' => 'ZendCache/ZendCache.stub', 'zend_disk_cache_fetch' => 'ZendCache/ZendCache.stub', 'zend_disk_cache_info' => 'ZendCache/ZendCache.stub', 'zend_disk_cache_store' => 'ZendCache/ZendCache.stub', 'zend_get_id' => 'zend/zend_f.stub', 'zend_is_configuration_changed' => 'ZendUtils/ZendUtils.stub', 'zend_loader_current_file' => 'zend/zend_f.stub', 'zend_loader_enabled' => 'zend/zend_f.stub', 'zend_loader_file_encoded' => 'zend/zend_f.stub', 'zend_loader_file_licensed' => 'zend/zend_f.stub', 'zend_loader_install_license' => 'zend/zend_f.stub', 'zend_logo_guid' => 'standard/standard_0.stub', 'zend_obfuscate_class_name' => 'zend/zend_f.stub', 'zend_obfuscate_function_name' => 'zend/zend_f.stub', 'zend_optimizer_version' => 'zend/zend_f.stub', 'zend_runtime_obfuscate' => 'zend/zend_f.stub', 'zend_send_buffer' => 'zend/zend.stub', 'zend_send_file' => 'zend/zend.stub', 'zend_set_configuration_changed' => 'ZendUtils/ZendUtils.stub', 'zend_shm_cache_clear' => 'ZendCache/ZendCache.stub', 'zend_shm_cache_delete' => 'ZendCache/ZendCache.stub', 'zend_shm_cache_fetch' => 'ZendCache/ZendCache.stub', 'zend_shm_cache_info' => 'ZendCache/ZendCache.stub', 'zend_shm_cache_store' => 'ZendCache/ZendCache.stub', 'zend_version' => 'Core/Core.stub', 'zip_close' => 'zip/zip.stub', 'zip_entry_close' => 'zip/zip.stub', 'zip_entry_compressedsize' => 'zip/zip.stub', 'zip_entry_compressionmethod' => 'zip/zip.stub', 'zip_entry_filesize' => 'zip/zip.stub', 'zip_entry_name' => 'zip/zip.stub', 'zip_entry_open' => 'zip/zip.stub', 'zip_entry_read' => 'zip/zip.stub', 'zip_open' => 'zip/zip.stub', 'zip_read' => 'zip/zip.stub', 'zlib_decode' => 'zlib/zlib.stub', 'zlib_encode' => 'zlib/zlib.stub', 'zlib_get_coding_type' => 'zlib/zlib.stub', 'zstd_compress' => 'zstd/zstd.stub', 'zstd_compress_dict' => 'zstd/zstd.stub', 'zstd_compress_usingcdict' => 'zstd/zstd.stub', 'zstd_decompress_dict' => 'zstd/zstd.stub', 'zstd_decompress_usingcdict' => 'zstd/zstd.stub', 'zstd_uncompress' => 'zstd/zstd.stub', 'zstd_uncompress_dict' => 'zstd/zstd.stub', 'zstd_uncompress_usingcdict' => 'zstd/zstd.stub'); const CONSTANTS = array('ABDAY_1' => 'standard/standard_defines.stub', 'ABDAY_2' => 'standard/standard_defines.stub', 'ABDAY_3' => 'standard/standard_defines.stub', 'ABDAY_4' => 'standard/standard_defines.stub', 'ABDAY_5' => 'standard/standard_defines.stub', 'ABDAY_6' => 'standard/standard_defines.stub', 'ABDAY_7' => 'standard/standard_defines.stub', 'ABMON_1' => 'standard/standard_defines.stub', 'ABMON_10' => 'standard/standard_defines.stub', 'ABMON_11' => 'standard/standard_defines.stub', 'ABMON_12' => 'standard/standard_defines.stub', 'ABMON_2' => 'standard/standard_defines.stub', 'ABMON_3' => 'standard/standard_defines.stub', 'ABMON_4' => 'standard/standard_defines.stub', 'ABMON_5' => 'standard/standard_defines.stub', 'ABMON_6' => 'standard/standard_defines.stub', 'ABMON_7' => 'standard/standard_defines.stub', 'ABMON_8' => 'standard/standard_defines.stub', 'ABMON_9' => 'standard/standard_defines.stub', 'AF_INET' => 'sockets/sockets.stub', 'AF_INET6' => 'sockets/sockets.stub', 'AF_UNIX' => 'sockets/sockets.stub', 'AI_ADDRCONFIG' => 'sockets/sockets.stub', 'AI_ALL' => 'sockets/sockets.stub', 'AI_CANONNAME' => 'sockets/sockets.stub', 'AI_NUMERICHOST' => 'sockets/sockets.stub', 'AI_NUMERICSERV' => 'sockets/sockets.stub', 'AI_PASSIVE' => 'sockets/sockets.stub', 'AI_V4MAPPED' => 'sockets/sockets.stub', 'ALT_DIGITS' => 'standard/standard_defines.stub', 'AMQP_AUTOACK' => 'amqp/amqp.stub', 'AMQP_AUTODELETE' => 'amqp/amqp.stub', 'AMQP_DELIVERY_MODE_PERSISTENT' => 'amqp/amqp.stub', 'AMQP_DELIVERY_MODE_TRANSIENT' => 'amqp/amqp.stub', 'AMQP_DURABLE' => 'amqp/amqp.stub', 'AMQP_EXCLUSIVE' => 'amqp/amqp.stub', 'AMQP_EXTENSION_VERSION' => 'amqp/amqp.stub', 'AMQP_EXTENSION_VERSION_EXTRA' => 'amqp/amqp.stub', 'AMQP_EXTENSION_VERSION_ID' => 'amqp/amqp.stub', 'AMQP_EXTENSION_VERSION_MAJOR' => 'amqp/amqp.stub', 'AMQP_EXTENSION_VERSION_MINOR' => 'amqp/amqp.stub', 'AMQP_EXTENSION_VERSION_PATCH' => 'amqp/amqp.stub', 'AMQP_EX_TYPE_DIRECT' => 'amqp/amqp.stub', 'AMQP_EX_TYPE_FANOUT' => 'amqp/amqp.stub', 'AMQP_EX_TYPE_HEADERS' => 'amqp/amqp.stub', 'AMQP_EX_TYPE_TOPIC' => 'amqp/amqp.stub', 'AMQP_IFEMPTY' => 'amqp/amqp.stub', 'AMQP_IFUNUSED' => 'amqp/amqp.stub', 'AMQP_IMMEDIATE' => 'amqp/amqp.stub', 'AMQP_INTERNAL' => 'amqp/amqp.stub', 'AMQP_JUST_CONSUME' => 'amqp/amqp.stub', 'AMQP_MANDATORY' => 'amqp/amqp.stub', 'AMQP_MULTIPLE' => 'amqp/amqp.stub', 'AMQP_NOLOCAL' => 'amqp/amqp.stub', 'AMQP_NOPARAM' => 'amqp/amqp.stub', 'AMQP_NOWAIT' => 'amqp/amqp.stub', 'AMQP_OS_SOCKET_TIMEOUT_ERRNO' => 'amqp/amqp.stub', 'AMQP_PASSIVE' => 'amqp/amqp.stub', 'AMQP_REQUEUE' => 'amqp/amqp.stub', 'AMQP_SASL_METHOD_EXTERNAL' => 'amqp/amqp.stub', 'AMQP_SASL_METHOD_PLAIN' => 'amqp/amqp.stub', 'AM_STR' => 'standard/standard_defines.stub', 'APACHE_MAP' => 'soap/soap.stub', 'APC_BIN_VERIFY_CRC32' => 'apcu/apcu.stub', 'APC_BIN_VERIFY_MD5' => 'apcu/apcu.stub', 'APC_ITER_ALL' => 'apcu/apcu.stub', 'APC_ITER_ATIME' => 'apcu/apcu.stub', 'APC_ITER_CTIME' => 'apcu/apcu.stub', 'APC_ITER_DEVICE' => 'apcu/apcu.stub', 'APC_ITER_DTIME' => 'apcu/apcu.stub', 'APC_ITER_FILENAME' => 'apcu/apcu.stub', 'APC_ITER_INODE' => 'apcu/apcu.stub', 'APC_ITER_KEY' => 'apcu/apcu.stub', 'APC_ITER_MD5' => 'apcu/apcu.stub', 'APC_ITER_MEM_SIZE' => 'apcu/apcu.stub', 'APC_ITER_MTIME' => 'apcu/apcu.stub', 'APC_ITER_NONE' => 'apcu/apcu.stub', 'APC_ITER_NUM_HITS' => 'apcu/apcu.stub', 'APC_ITER_REFCOUNT' => 'apcu/apcu.stub', 'APC_ITER_TTL' => 'apcu/apcu.stub', 'APC_ITER_TYPE' => 'apcu/apcu.stub', 'APC_ITER_VALUE' => 'apcu/apcu.stub', 'APC_LIST_ACTIVE' => 'apcu/apcu.stub', 'APC_LIST_DELETED' => 'apcu/apcu.stub', 'ARRAY_FILTER_USE_BOTH' => 'standard/standard_9.stub', 'ARRAY_FILTER_USE_KEY' => 'standard/standard_9.stub', 'ASSERT_ACTIVE' => 'standard/standard_defines.stub', 'ASSERT_BAIL' => 'standard/standard_defines.stub', 'ASSERT_CALLBACK' => 'standard/standard_defines.stub', 'ASSERT_EXCEPTION' => 'standard/standard_defines.stub', 'ASSERT_QUIET_EVAL' => 'standard/standard_defines.stub', 'ASSERT_WARNING' => 'standard/standard_defines.stub', 'Accel' => 'winbinder/winbinder.stub', 'AppWindow' => 'winbinder/winbinder.stub', 'BLACK' => 'winbinder/winbinder.stub', 'BLUE' => 'winbinder/winbinder.stub', 'BROTLI_COMPRESS_LEVEL_DEFAULT' => 'brotli/brotli.stub', 'BROTLI_COMPRESS_LEVEL_MAX' => 'brotli/brotli.stub', 'BROTLI_COMPRESS_LEVEL_MIN' => 'brotli/brotli.stub', 'BROTLI_FINISH' => 'brotli/brotli.stub', 'BROTLI_FLUSH' => 'brotli/brotli.stub', 'BROTLI_FONT' => 'brotli/brotli.stub', 'BROTLI_GENERIC' => 'brotli/brotli.stub', 'BROTLI_PROCESS' => 'brotli/brotli.stub', 'BROTLI_TEXT' => 'brotli/brotli.stub', 'BUS_ADRALN' => 'pcntl/pcntl.stub', 'BUS_ADRERR' => 'pcntl/pcntl.stub', 'BUS_OBJERR' => 'pcntl/pcntl.stub', 'CAL_DOW_DAYNO' => 'calendar/calendar.stub', 'CAL_DOW_LONG' => 'calendar/calendar.stub', 'CAL_DOW_SHORT' => 'calendar/calendar.stub', 'CAL_EASTER_ALWAYS_GREGORIAN' => 'calendar/calendar.stub', 'CAL_EASTER_ALWAYS_JULIAN' => 'calendar/calendar.stub', 'CAL_EASTER_DEFAULT' => 'calendar/calendar.stub', 'CAL_EASTER_ROMAN' => 'calendar/calendar.stub', 'CAL_FRENCH' => 'calendar/calendar.stub', 'CAL_GREGORIAN' => 'calendar/calendar.stub', 'CAL_JEWISH' => 'calendar/calendar.stub', 'CAL_JEWISH_ADD_ALAFIM' => 'calendar/calendar.stub', 'CAL_JEWISH_ADD_ALAFIM_GERESH' => 'calendar/calendar.stub', 'CAL_JEWISH_ADD_GERESHAYIM' => 'calendar/calendar.stub', 'CAL_JULIAN' => 'calendar/calendar.stub', 'CAL_MONTH_FRENCH' => 'calendar/calendar.stub', 'CAL_MONTH_GREGORIAN_LONG' => 'calendar/calendar.stub', 'CAL_MONTH_GREGORIAN_SHORT' => 'calendar/calendar.stub', 'CAL_MONTH_JEWISH' => 'calendar/calendar.stub', 'CAL_MONTH_JULIAN_LONG' => 'calendar/calendar.stub', 'CAL_MONTH_JULIAN_SHORT' => 'calendar/calendar.stub', 'CAL_NUM_CALS' => 'calendar/calendar.stub', 'CASE_LOWER' => 'standard/standard_defines.stub', 'CASE_UPPER' => 'standard/standard_defines.stub', 'CHAR_MAX' => 'standard/standard_defines.stub', 'CLD_CONTINUED' => 'pcntl/pcntl.stub', 'CLD_DUMPED' => 'pcntl/pcntl.stub', 'CLD_EXITED' => 'pcntl/pcntl.stub', 'CLD_KILLED' => 'pcntl/pcntl.stub', 'CLD_STOPPED' => 'pcntl/pcntl.stub', 'CLD_TRAPPED' => 'pcntl/pcntl.stub', 'CLONE_NEWCGROUP' => 'pcntl/pcntl.stub', 'CLONE_NEWIPC' => 'pcntl/pcntl.stub', 'CLONE_NEWNET' => 'pcntl/pcntl.stub', 'CLONE_NEWNS' => 'pcntl/pcntl.stub', 'CLONE_NEWPID' => 'pcntl/pcntl.stub', 'CLONE_NEWUSER' => 'pcntl/pcntl.stub', 'CLONE_NEWUTS' => 'pcntl/pcntl.stub', 'CLSCTX_ALL' => 'com_dotnet/com_dotnet.stub', 'CLSCTX_INPROC_HANDLER' => 'com_dotnet/com_dotnet.stub', 'CLSCTX_INPROC_SERVER' => 'com_dotnet/com_dotnet.stub', 'CLSCTX_LOCAL_SERVER' => 'com_dotnet/com_dotnet.stub', 'CLSCTX_REMOTE_SERVER' => 'com_dotnet/com_dotnet.stub', 'CLSCTX_SERVER' => 'com_dotnet/com_dotnet.stub', 'CL_EXPUNGE' => 'imap/imap.stub', 'CODESET' => 'standard/standard_defines.stub', 'CONNECTION_ABORTED' => 'standard/standard_defines.stub', 'CONNECTION_NORMAL' => 'standard/standard_defines.stub', 'CONNECTION_TIMEOUT' => 'standard/standard_defines.stub', 'COUNT_NORMAL' => 'standard/standard_defines.stub', 'COUNT_RECURSIVE' => 'standard/standard_defines.stub', 'CP_ACP' => 'com_dotnet/com_dotnet.stub', 'CP_MACCP' => 'com_dotnet/com_dotnet.stub', 'CP_MOVE' => 'imap/imap.stub', 'CP_OEMCP' => 'com_dotnet/com_dotnet.stub', 'CP_SYMBOL' => 'com_dotnet/com_dotnet.stub', 'CP_THREAD_ACP' => 'com_dotnet/com_dotnet.stub', 'CP_UID' => 'imap/imap.stub', 'CP_UTF7' => 'com_dotnet/com_dotnet.stub', 'CP_UTF8' => 'com_dotnet/com_dotnet.stub', 'CREDITS_ALL' => 'standard/standard_defines.stub', 'CREDITS_DOCS' => 'standard/standard_defines.stub', 'CREDITS_FULLPAGE' => 'standard/standard_defines.stub', 'CREDITS_GENERAL' => 'standard/standard_defines.stub', 'CREDITS_GROUP' => 'standard/standard_defines.stub', 'CREDITS_MODULES' => 'standard/standard_defines.stub', 'CREDITS_QA' => 'standard/standard_defines.stub', 'CREDITS_SAPI' => 'standard/standard_defines.stub', 'CRNCYSTR' => 'standard/standard_defines.stub', 'CRYPT_BLOWFISH' => 'standard/standard_defines.stub', 'CRYPT_EXT_DES' => 'standard/standard_defines.stub', 'CRYPT_MD5' => 'standard/standard_defines.stub', 'CRYPT_SALT_LENGTH' => 'standard/standard_defines.stub', 'CRYPT_SHA256' => 'standard/standard_defines.stub', 'CRYPT_SHA512' => 'standard/standard_defines.stub', 'CRYPT_STD_DES' => 'standard/standard_defines.stub', 'CUBRID_ASSOC' => 'cubrid/cubrid.stub', 'CUBRID_ASYNC' => 'cubrid/cubrid.stub', 'CUBRID_AUTOCOMMIT_FALSE' => 'cubrid/cubrid.stub', 'CUBRID_AUTOCOMMIT_TRUE' => 'cubrid/cubrid.stub', 'CUBRID_BOTH' => 'cubrid/cubrid.stub', 'CUBRID_CURSOR_CURRENT' => 'cubrid/cubrid.stub', 'CUBRID_CURSOR_ERROR' => 'cubrid/cubrid.stub', 'CUBRID_CURSOR_FIRST' => 'cubrid/cubrid.stub', 'CUBRID_CURSOR_LAST' => 'cubrid/cubrid.stub', 'CUBRID_CURSOR_SUCCESS' => 'cubrid/cubrid.stub', 'CUBRID_EXEC_QUERY_ALL' => 'cubrid/cubrid.stub', 'CUBRID_INCLUDE_OID' => 'cubrid/cubrid.stub', 'CUBRID_NO_MORE_DATA' => 'cubrid/cubrid.stub', 'CUBRID_NUM' => 'cubrid/cubrid.stub', 'CUBRID_OBJECT' => 'cubrid/cubrid.stub', 'CURLALTSVC_H1' => 'curl/curl_d.stub', 'CURLALTSVC_H2' => 'curl/curl_d.stub', 'CURLALTSVC_H3' => 'curl/curl_d.stub', 'CURLALTSVC_READONLYFILE' => 'curl/curl_d.stub', 'CURLAUTH_ANY' => 'curl/curl_d.stub', 'CURLAUTH_ANYSAFE' => 'curl/curl_d.stub', 'CURLAUTH_AWS_SIGV4' => 'curl/curl_d.stub', 'CURLAUTH_BASIC' => 'curl/curl_d.stub', 'CURLAUTH_BEARER' => 'curl/curl_d.stub', 'CURLAUTH_DIGEST' => 'curl/curl_d.stub', 'CURLAUTH_DIGEST_IE' => 'curl/curl_d.stub', 'CURLAUTH_GSSAPI' => 'curl/curl_d.stub', 'CURLAUTH_GSSNEGOTIATE' => 'curl/curl_d.stub', 'CURLAUTH_NEGOTIATE' => 'curl/curl_d.stub', 'CURLAUTH_NONE' => 'curl/curl_d.stub', 'CURLAUTH_NTLM' => 'curl/curl_d.stub', 'CURLAUTH_NTLM_WB' => 'curl/curl_d.stub', 'CURLAUTH_ONLY' => 'curl/curl_d.stub', 'CURLCLOSEPOLICY_CALLBACK' => 'curl/curl_d.stub', 'CURLCLOSEPOLICY_LEAST_RECENTLY_USED' => 'curl/curl_d.stub', 'CURLCLOSEPOLICY_LEAST_TRAFFIC' => 'curl/curl_d.stub', 'CURLCLOSEPOLICY_OLDEST' => 'curl/curl_d.stub', 'CURLCLOSEPOLICY_SLOWEST' => 'curl/curl_d.stub', 'CURLE_ABORTED_BY_CALLBACK' => 'curl/curl_d.stub', 'CURLE_BAD_CALLING_ORDER' => 'curl/curl_d.stub', 'CURLE_BAD_CONTENT_ENCODING' => 'curl/curl_d.stub', 'CURLE_BAD_DOWNLOAD_RESUME' => 'curl/curl_d.stub', 'CURLE_BAD_FUNCTION_ARGUMENT' => 'curl/curl_d.stub', 'CURLE_BAD_PASSWORD_ENTERED' => 'curl/curl_d.stub', 'CURLE_COULDNT_CONNECT' => 'curl/curl_d.stub', 'CURLE_COULDNT_RESOLVE_HOST' => 'curl/curl_d.stub', 'CURLE_COULDNT_RESOLVE_PROXY' => 'curl/curl_d.stub', 'CURLE_FAILED_INIT' => 'curl/curl_d.stub', 'CURLE_FILESIZE_EXCEEDED' => 'curl/curl_d.stub', 'CURLE_FILE_COULDNT_READ_FILE' => 'curl/curl_d.stub', 'CURLE_FTP_ACCESS_DENIED' => 'curl/curl_d.stub', 'CURLE_FTP_BAD_DOWNLOAD_RESUME' => 'curl/curl_d.stub', 'CURLE_FTP_CANT_GET_HOST' => 'curl/curl_d.stub', 'CURLE_FTP_CANT_RECONNECT' => 'curl/curl_d.stub', 'CURLE_FTP_COULDNT_GET_SIZE' => 'curl/curl_d.stub', 'CURLE_FTP_COULDNT_RETR_FILE' => 'curl/curl_d.stub', 'CURLE_FTP_COULDNT_SET_ASCII' => 'curl/curl_d.stub', 'CURLE_FTP_COULDNT_SET_BINARY' => 'curl/curl_d.stub', 'CURLE_FTP_COULDNT_STOR_FILE' => 'curl/curl_d.stub', 'CURLE_FTP_COULDNT_USE_REST' => 'curl/curl_d.stub', 'CURLE_FTP_PARTIAL_FILE' => 'curl/curl_d.stub', 'CURLE_FTP_PORT_FAILED' => 'curl/curl_d.stub', 'CURLE_FTP_QUOTE_ERROR' => 'curl/curl_d.stub', 'CURLE_FTP_SSL_FAILED' => 'curl/curl_d.stub', 'CURLE_FTP_USER_PASSWORD_INCORRECT' => 'curl/curl_d.stub', 'CURLE_FTP_WEIRD_227_FORMAT' => 'curl/curl_d.stub', 'CURLE_FTP_WEIRD_PASS_REPLY' => 'curl/curl_d.stub', 'CURLE_FTP_WEIRD_PASV_REPLY' => 'curl/curl_d.stub', 'CURLE_FTP_WEIRD_SERVER_REPLY' => 'curl/curl_d.stub', 'CURLE_FTP_WEIRD_USER_REPLY' => 'curl/curl_d.stub', 'CURLE_FTP_WRITE_ERROR' => 'curl/curl_d.stub', 'CURLE_FUNCTION_NOT_FOUND' => 'curl/curl_d.stub', 'CURLE_GOT_NOTHING' => 'curl/curl_d.stub', 'CURLE_HTTP_NOT_FOUND' => 'curl/curl_d.stub', 'CURLE_HTTP_PORT_FAILED' => 'curl/curl_d.stub', 'CURLE_HTTP_POST_ERROR' => 'curl/curl_d.stub', 'CURLE_HTTP_RANGE_ERROR' => 'curl/curl_d.stub', 'CURLE_HTTP_RETURNED_ERROR' => 'curl/curl_d.stub', 'CURLE_LDAP_CANNOT_BIND' => 'curl/curl_d.stub', 'CURLE_LDAP_INVALID_URL' => 'curl/curl_d.stub', 'CURLE_LDAP_SEARCH_FAILED' => 'curl/curl_d.stub', 'CURLE_LIBRARY_NOT_FOUND' => 'curl/curl_d.stub', 'CURLE_MALFORMAT_USER' => 'curl/curl_d.stub', 'CURLE_OBSOLETE' => 'curl/curl_d.stub', 'CURLE_OK' => 'curl/curl_d.stub', 'CURLE_OPERATION_TIMEDOUT' => 'curl/curl_d.stub', 'CURLE_OPERATION_TIMEOUTED' => 'curl/curl_d.stub', 'CURLE_OUT_OF_MEMORY' => 'curl/curl_d.stub', 'CURLE_PARTIAL_FILE' => 'curl/curl_d.stub', 'CURLE_PROXY' => 'curl/curl_d.stub', 'CURLE_READ_ERROR' => 'curl/curl_d.stub', 'CURLE_RECV_ERROR' => 'curl/curl_d.stub', 'CURLE_SEND_ERROR' => 'curl/curl_d.stub', 'CURLE_SHARE_IN_USE' => 'curl/curl_d.stub', 'CURLE_SSH' => 'curl/curl_d.stub', 'CURLE_SSL_CACERT' => 'curl/curl_d.stub', 'CURLE_SSL_CACERT_BADFILE' => 'curl/curl_d.stub', 'CURLE_SSL_CERTPROBLEM' => 'curl/curl_d.stub', 'CURLE_SSL_CIPHER' => 'curl/curl_d.stub', 'CURLE_SSL_CONNECT_ERROR' => 'curl/curl_d.stub', 'CURLE_SSL_ENGINE_NOTFOUND' => 'curl/curl_d.stub', 'CURLE_SSL_ENGINE_SETFAILED' => 'curl/curl_d.stub', 'CURLE_SSL_PEER_CERTIFICATE' => 'curl/curl_d.stub', 'CURLE_SSL_PINNEDPUBKEYNOTMATCH' => 'curl/curl_d.stub', 'CURLE_TELNET_OPTION_SYNTAX' => 'curl/curl_d.stub', 'CURLE_TOO_MANY_REDIRECTS' => 'curl/curl_d.stub', 'CURLE_UNKNOWN_TELNET_OPTION' => 'curl/curl_d.stub', 'CURLE_UNSUPPORTED_PROTOCOL' => 'curl/curl_d.stub', 'CURLE_URL_MALFORMAT' => 'curl/curl_d.stub', 'CURLE_URL_MALFORMAT_USER' => 'curl/curl_d.stub', 'CURLE_WEIRD_SERVER_REPLY' => 'curl/curl_d.stub', 'CURLE_WRITE_ERROR' => 'curl/curl_d.stub', 'CURLFTPAUTH_DEFAULT' => 'curl/curl_d.stub', 'CURLFTPAUTH_SSL' => 'curl/curl_d.stub', 'CURLFTPAUTH_TLS' => 'curl/curl_d.stub', 'CURLFTPMETHOD_DEFAULT' => 'curl/curl_d.stub', 'CURLFTPMETHOD_MULTICWD' => 'curl/curl_d.stub', 'CURLFTPMETHOD_NOCWD' => 'curl/curl_d.stub', 'CURLFTPMETHOD_SINGLECWD' => 'curl/curl_d.stub', 'CURLFTPSSL_ALL' => 'curl/curl_d.stub', 'CURLFTPSSL_CCC_ACTIVE' => 'curl/curl_d.stub', 'CURLFTPSSL_CCC_NONE' => 'curl/curl_d.stub', 'CURLFTPSSL_CCC_PASSIVE' => 'curl/curl_d.stub', 'CURLFTPSSL_CONTROL' => 'curl/curl_d.stub', 'CURLFTPSSL_NONE' => 'curl/curl_d.stub', 'CURLFTPSSL_TRY' => 'curl/curl_d.stub', 'CURLFTP_CREATE_DIR' => 'curl/curl_d.stub', 'CURLFTP_CREATE_DIR_NONE' => 'curl/curl_d.stub', 'CURLFTP_CREATE_DIR_RETRY' => 'curl/curl_d.stub', 'CURLGSSAPI_DELEGATION_FLAG' => 'curl/curl_d.stub', 'CURLGSSAPI_DELEGATION_POLICY_FLAG' => 'curl/curl_d.stub', 'CURLHEADER_SEPARATE' => 'curl/curl_d.stub', 'CURLHEADER_UNIFIED' => 'curl/curl_d.stub', 'CURLHSTS_ENABLE' => 'curl/curl_d.stub', 'CURLHSTS_READONLYFILE' => 'curl/curl_d.stub', 'CURLINFO_APPCONNECT_TIME' => 'curl/curl_d.stub', 'CURLINFO_APPCONNECT_TIME_T' => 'curl/curl_d.stub', 'CURLINFO_CAINFO' => 'curl/curl_d.stub', 'CURLINFO_CAPATH' => 'curl/curl_d.stub', 'CURLINFO_CERTINFO' => 'curl/curl_d.stub', 'CURLINFO_CONDITION_UNMET' => 'curl/curl_d.stub', 'CURLINFO_CONNECT_TIME' => 'curl/curl_d.stub', 'CURLINFO_CONNECT_TIME_T' => 'curl/curl_d.stub', 'CURLINFO_CONTENT_LENGTH_DOWNLOAD' => 'curl/curl_d.stub', 'CURLINFO_CONTENT_LENGTH_DOWNLOAD_T' => 'curl/curl_d.stub', 'CURLINFO_CONTENT_LENGTH_UPLOAD' => 'curl/curl_d.stub', 'CURLINFO_CONTENT_LENGTH_UPLOAD_T' => 'curl/curl_d.stub', 'CURLINFO_CONTENT_TYPE' => 'curl/curl_d.stub', 'CURLINFO_COOKIELIST' => 'curl/curl_d.stub', 'CURLINFO_EFFECTIVE_METHOD' => 'curl/curl_d.stub', 'CURLINFO_EFFECTIVE_URL' => 'curl/curl_d.stub', 'CURLINFO_FILETIME' => 'curl/curl_d.stub', 'CURLINFO_FILETIME_T' => 'curl/curl_d.stub', 'CURLINFO_FTP_ENTRY_PATH' => 'curl/curl_d.stub', 'CURLINFO_HEADER_OUT' => 'curl/curl_d.stub', 'CURLINFO_HEADER_SIZE' => 'curl/curl_d.stub', 'CURLINFO_HTTPAUTH_AVAIL' => 'curl/curl_d.stub', 'CURLINFO_HTTP_CODE' => 'curl/curl_d.stub', 'CURLINFO_HTTP_CONNECTCODE' => 'curl/curl_d.stub', 'CURLINFO_HTTP_VERSION' => 'curl/curl_d.stub', 'CURLINFO_LASTONE' => 'curl/curl_d.stub', 'CURLINFO_LOCAL_IP' => 'curl/curl_d.stub', 'CURLINFO_LOCAL_PORT' => 'curl/curl_d.stub', 'CURLINFO_NAMELOOKUP_TIME' => 'curl/curl_d.stub', 'CURLINFO_NAMELOOKUP_TIME_T' => 'curl/curl_d.stub', 'CURLINFO_NUM_CONNECTS' => 'curl/curl_d.stub', 'CURLINFO_OS_ERRNO' => 'curl/curl_d.stub', 'CURLINFO_PRETRANSFER_TIME' => 'curl/curl_d.stub', 'CURLINFO_PRETRANSFER_TIME_T' => 'curl/curl_d.stub', 'CURLINFO_PRIMARY_IP' => 'curl/curl_d.stub', 'CURLINFO_PRIMARY_PORT' => 'curl/curl_d.stub', 'CURLINFO_PRIVATE' => 'curl/curl_d.stub', 'CURLINFO_PROTOCOL' => 'curl/curl_d.stub', 'CURLINFO_PROXYAUTH_AVAIL' => 'curl/curl_d.stub', 'CURLINFO_PROXY_ERROR' => 'curl/curl_d.stub', 'CURLINFO_PROXY_SSL_VERIFYRESULT' => 'curl/curl_d.stub', 'CURLINFO_REDIRECT_COUNT' => 'curl/curl_d.stub', 'CURLINFO_REDIRECT_TIME' => 'curl/curl_d.stub', 'CURLINFO_REDIRECT_TIME_T' => 'curl/curl_d.stub', 'CURLINFO_REDIRECT_URL' => 'curl/curl_d.stub', 'CURLINFO_REFERER' => 'curl/curl_d.stub', 'CURLINFO_REQUEST_SIZE' => 'curl/curl_d.stub', 'CURLINFO_RESPONSE_CODE' => 'curl/curl_d.stub', 'CURLINFO_RETRY_AFTER' => 'curl/curl_d.stub', 'CURLINFO_RTSP_CLIENT_CSEQ' => 'curl/curl_d.stub', 'CURLINFO_RTSP_CSEQ_RECV' => 'curl/curl_d.stub', 'CURLINFO_RTSP_SERVER_CSEQ' => 'curl/curl_d.stub', 'CURLINFO_RTSP_SESSION_ID' => 'curl/curl_d.stub', 'CURLINFO_SCHEME' => 'curl/curl_d.stub', 'CURLINFO_SIZE_DOWNLOAD' => 'curl/curl_d.stub', 'CURLINFO_SIZE_DOWNLOAD_T' => 'curl/curl_d.stub', 'CURLINFO_SIZE_UPLOAD' => 'curl/curl_d.stub', 'CURLINFO_SIZE_UPLOAD_T' => 'curl/curl_d.stub', 'CURLINFO_SPEED_DOWNLOAD' => 'curl/curl_d.stub', 'CURLINFO_SPEED_DOWNLOAD_T' => 'curl/curl_d.stub', 'CURLINFO_SPEED_UPLOAD' => 'curl/curl_d.stub', 'CURLINFO_SPEED_UPLOAD_T' => 'curl/curl_d.stub', 'CURLINFO_SSL_ENGINES' => 'curl/curl_d.stub', 'CURLINFO_SSL_VERIFYRESULT' => 'curl/curl_d.stub', 'CURLINFO_STARTTRANSFER_TIME' => 'curl/curl_d.stub', 'CURLINFO_STARTTRANSFER_TIME_T' => 'curl/curl_d.stub', 'CURLINFO_TOTAL_TIME' => 'curl/curl_d.stub', 'CURLINFO_TOTAL_TIME_T' => 'curl/curl_d.stub', 'CURLKHMATCH_LAST' => 'curl/curl_d.stub', 'CURLKHMATCH_MISMATCH' => 'curl/curl_d.stub', 'CURLKHMATCH_MISSING' => 'curl/curl_d.stub', 'CURLKHMATCH_OK' => 'curl/curl_d.stub', 'CURLMIMEOPT_FORMESCAPE' => 'curl/curl_d.stub', 'CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE' => 'curl/curl_d.stub', 'CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE' => 'curl/curl_d.stub', 'CURLMOPT_MAXCONNECTS' => 'curl/curl_d.stub', 'CURLMOPT_MAX_CONCURRENT_STREAMS' => 'curl/curl_d.stub', 'CURLMOPT_MAX_HOST_CONNECTIONS' => 'curl/curl_d.stub', 'CURLMOPT_MAX_PIPELINE_LENGTH' => 'curl/curl_d.stub', 'CURLMOPT_MAX_TOTAL_CONNECTIONS' => 'curl/curl_d.stub', 'CURLMOPT_PIPELINING' => 'curl/curl_d.stub', 'CURLMOPT_PUSHFUNCTION' => 'curl/curl_d.stub', 'CURLMSG_DONE' => 'curl/curl_d.stub', 'CURLM_ADDED_ALREADY' => 'curl/curl_d.stub', 'CURLM_BAD_EASY_HANDLE' => 'curl/curl_d.stub', 'CURLM_BAD_HANDLE' => 'curl/curl_d.stub', 'CURLM_CALL_MULTI_PERFORM' => 'curl/curl_d.stub', 'CURLM_INTERNAL_ERROR' => 'curl/curl_d.stub', 'CURLM_OK' => 'curl/curl_d.stub', 'CURLM_OUT_OF_MEMORY' => 'curl/curl_d.stub', 'CURLOPT_ABSTRACT_UNIX_SOCKET' => 'curl/curl_d.stub', 'CURLOPT_ACCEPTTIMEOUT_MS' => 'curl/curl_d.stub', 'CURLOPT_ACCEPT_ENCODING' => 'curl/curl_d.stub', 'CURLOPT_ADDRESS_SCOPE' => 'curl/curl_d.stub', 'CURLOPT_ALTSVC' => 'curl/curl_d.stub', 'CURLOPT_ALTSVC_CTRL' => 'curl/curl_d.stub', 'CURLOPT_APPEND' => 'curl/curl_d.stub', 'CURLOPT_AUTOREFERER' => 'curl/curl_d.stub', 'CURLOPT_AWS_SIGV4' => 'curl/curl_d.stub', 'CURLOPT_BINARYTRANSFER' => 'curl/curl_d.stub', 'CURLOPT_BUFFERSIZE' => 'curl/curl_d.stub', 'CURLOPT_CAINFO' => 'curl/curl_d.stub', 'CURLOPT_CAINFO_BLOB' => 'curl/curl_d.stub', 'CURLOPT_CAPATH' => 'curl/curl_d.stub', 'CURLOPT_CA_CACHE_TIMEOUT' => 'curl/curl_d.stub', 'CURLOPT_CERTINFO' => 'curl/curl_d.stub', 'CURLOPT_CLOSEPOLICY' => 'curl/curl_d.stub', 'CURLOPT_CONNECTTIMEOUT' => 'curl/curl_d.stub', 'CURLOPT_CONNECTTIMEOUT_MS' => 'curl/curl_d.stub', 'CURLOPT_CONNECT_ONLY' => 'curl/curl_d.stub', 'CURLOPT_CONNECT_TO' => 'curl/curl_d.stub', 'CURLOPT_COOKIE' => 'curl/curl_d.stub', 'CURLOPT_COOKIEFILE' => 'curl/curl_d.stub', 'CURLOPT_COOKIEJAR' => 'curl/curl_d.stub', 'CURLOPT_COOKIELIST' => 'curl/curl_d.stub', 'CURLOPT_COOKIESESSION' => 'curl/curl_d.stub', 'CURLOPT_CRLF' => 'curl/curl_d.stub', 'CURLOPT_CRLFILE' => 'curl/curl_d.stub', 'CURLOPT_CUSTOMREQUEST' => 'curl/curl_d.stub', 'CURLOPT_DEFAULT_PROTOCOL' => 'curl/curl_d.stub', 'CURLOPT_DIRLISTONLY' => 'curl/curl_d.stub', 'CURLOPT_DISALLOW_USERNAME_IN_URL' => 'curl/curl_d.stub', 'CURLOPT_DNS_CACHE_TIMEOUT' => 'curl/curl_d.stub', 'CURLOPT_DNS_INTERFACE' => 'curl/curl_d.stub', 'CURLOPT_DNS_LOCAL_IP4' => 'curl/curl_d.stub', 'CURLOPT_DNS_LOCAL_IP6' => 'curl/curl_d.stub', 'CURLOPT_DNS_SERVERS' => 'curl/curl_d.stub', 'CURLOPT_DNS_SHUFFLE_ADDRESSES' => 'curl/curl_d.stub', 'CURLOPT_DNS_USE_GLOBAL_CACHE' => 'curl/curl_d.stub', 'CURLOPT_DOH_SSL_VERIFYHOST' => 'curl/curl_d.stub', 'CURLOPT_DOH_SSL_VERIFYPEER' => 'curl/curl_d.stub', 'CURLOPT_DOH_SSL_VERIFYSTATUS' => 'curl/curl_d.stub', 'CURLOPT_DOH_URL' => 'curl/curl_d.stub', 'CURLOPT_EGDSOCKET' => 'curl/curl_d.stub', 'CURLOPT_ENCODING' => 'curl/curl_d.stub', 'CURLOPT_EXPECT_100_TIMEOUT_MS' => 'curl/curl_d.stub', 'CURLOPT_FAILONERROR' => 'curl/curl_d.stub', 'CURLOPT_FILE' => 'curl/curl_d.stub', 'CURLOPT_FILETIME' => 'curl/curl_d.stub', 'CURLOPT_FNMATCH_FUNCTION' => 'curl/curl_d.stub', 'CURLOPT_FOLLOWLOCATION' => 'curl/curl_d.stub', 'CURLOPT_FORBID_REUSE' => 'curl/curl_d.stub', 'CURLOPT_FRESH_CONNECT' => 'curl/curl_d.stub', 'CURLOPT_FTPAPPEND' => 'curl/curl_d.stub', 'CURLOPT_FTPASCII' => 'curl/curl_d.stub', 'CURLOPT_FTPLISTONLY' => 'curl/curl_d.stub', 'CURLOPT_FTPPORT' => 'curl/curl_d.stub', 'CURLOPT_FTPSSLAUTH' => 'curl/curl_d.stub', 'CURLOPT_FTP_ACCOUNT' => 'curl/curl_d.stub', 'CURLOPT_FTP_ALTERNATIVE_TO_USER' => 'curl/curl_d.stub', 'CURLOPT_FTP_CREATE_MISSING_DIRS' => 'curl/curl_d.stub', 'CURLOPT_FTP_FILEMETHOD' => 'curl/curl_d.stub', 'CURLOPT_FTP_RESPONSE_TIMEOUT' => 'curl/curl_d.stub', 'CURLOPT_FTP_SKIP_PASV_IP' => 'curl/curl_d.stub', 'CURLOPT_FTP_SSL' => 'curl/curl_d.stub', 'CURLOPT_FTP_SSL_CCC' => 'curl/curl_d.stub', 'CURLOPT_FTP_USE_EPRT' => 'curl/curl_d.stub', 'CURLOPT_FTP_USE_EPSV' => 'curl/curl_d.stub', 'CURLOPT_FTP_USE_PRET' => 'curl/curl_d.stub', 'CURLOPT_GSSAPI_DELEGATION' => 'curl/curl_d.stub', 'CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS' => 'curl/curl_d.stub', 'CURLOPT_HAPROXYPROTOCOL' => 'curl/curl_d.stub', 'CURLOPT_HEADER' => 'curl/curl_d.stub', 'CURLOPT_HEADERFUNCTION' => 'curl/curl_d.stub', 'CURLOPT_HEADEROPT' => 'curl/curl_d.stub', 'CURLOPT_HSTS' => 'curl/curl_d.stub', 'CURLOPT_HSTS_CTRL' => 'curl/curl_d.stub', 'CURLOPT_HTTP09_ALLOWED' => 'curl/curl_d.stub', 'CURLOPT_HTTP200ALIASES' => 'curl/curl_d.stub', 'CURLOPT_HTTPAUTH' => 'curl/curl_d.stub', 'CURLOPT_HTTPGET' => 'curl/curl_d.stub', 'CURLOPT_HTTPHEADER' => 'curl/curl_d.stub', 'CURLOPT_HTTPPROXYTUNNEL' => 'curl/curl_d.stub', 'CURLOPT_HTTP_CONTENT_DECODING' => 'curl/curl_d.stub', 'CURLOPT_HTTP_TRANSFER_DECODING' => 'curl/curl_d.stub', 'CURLOPT_HTTP_VERSION' => 'curl/curl_d.stub', 'CURLOPT_IGNORE_CONTENT_LENGTH' => 'curl/curl_d.stub', 'CURLOPT_INFILE' => 'curl/curl_d.stub', 'CURLOPT_INFILESIZE' => 'curl/curl_d.stub', 'CURLOPT_INTERFACE' => 'curl/curl_d.stub', 'CURLOPT_IPRESOLVE' => 'curl/curl_d.stub', 'CURLOPT_ISSUERCERT' => 'curl/curl_d.stub', 'CURLOPT_ISSUERCERT_BLOB' => 'curl/curl_d.stub', 'CURLOPT_KEEP_SENDING_ON_ERROR' => 'curl/curl_d.stub', 'CURLOPT_KEYPASSWD' => 'curl/curl_d.stub', 'CURLOPT_KRB4LEVEL' => 'curl/curl_d.stub', 'CURLOPT_KRBLEVEL' => 'curl/curl_d.stub', 'CURLOPT_LOCALPORT' => 'curl/curl_d.stub', 'CURLOPT_LOCALPORTRANGE' => 'curl/curl_d.stub', 'CURLOPT_LOGIN_OPTIONS' => 'curl/curl_d.stub', 'CURLOPT_LOW_SPEED_LIMIT' => 'curl/curl_d.stub', 'CURLOPT_LOW_SPEED_TIME' => 'curl/curl_d.stub', 'CURLOPT_MAIL_AUTH' => 'curl/curl_d.stub', 'CURLOPT_MAIL_FROM' => 'curl/curl_d.stub', 'CURLOPT_MAIL_RCPT' => 'curl/curl_d.stub', 'CURLOPT_MAIL_RCPT_ALLLOWFAILS' => 'curl/curl_d.stub', 'CURLOPT_MAXAGE_CONN' => 'curl/curl_d.stub', 'CURLOPT_MAXCONNECTS' => 'curl/curl_d.stub', 'CURLOPT_MAXFILESIZE' => 'curl/curl_d.stub', 'CURLOPT_MAXFILESIZE_LARGE' => 'curl/curl_d.stub', 'CURLOPT_MAXLIFETIME_CONN' => 'curl/curl_d.stub', 'CURLOPT_MAXREDIRS' => 'curl/curl_d.stub', 'CURLOPT_MAX_RECV_SPEED_LARGE' => 'curl/curl_d.stub', 'CURLOPT_MAX_SEND_SPEED_LARGE' => 'curl/curl_d.stub', 'CURLOPT_MIME_OPTIONS' => 'curl/curl_d.stub', 'CURLOPT_MUTE' => 'curl/curl_d.stub', 'CURLOPT_NETRC' => 'curl/curl_d.stub', 'CURLOPT_NETRC_FILE' => 'curl/curl_d.stub', 'CURLOPT_NEW_DIRECTORY_PERMS' => 'curl/curl_d.stub', 'CURLOPT_NEW_FILE_PERMS' => 'curl/curl_d.stub', 'CURLOPT_NOBODY' => 'curl/curl_d.stub', 'CURLOPT_NOPROGRESS' => 'curl/curl_d.stub', 'CURLOPT_NOPROXY' => 'curl/curl_d.stub', 'CURLOPT_NOSIGNAL' => 'curl/curl_d.stub', 'CURLOPT_PASSWDFUNCTION' => 'curl/curl_d.stub', 'CURLOPT_PASSWORD' => 'curl/curl_d.stub', 'CURLOPT_PATH_AS_IS' => 'curl/curl_d.stub', 'CURLOPT_PINNEDPUBLICKEY' => 'curl/curl_d.stub', 'CURLOPT_PIPEWAIT' => 'curl/curl_d.stub', 'CURLOPT_PORT' => 'curl/curl_d.stub', 'CURLOPT_POST' => 'curl/curl_d.stub', 'CURLOPT_POSTFIELDS' => 'curl/curl_d.stub', 'CURLOPT_POSTQUOTE' => 'curl/curl_d.stub', 'CURLOPT_POSTREDIR' => 'curl/curl_d.stub', 'CURLOPT_PREQUOTE' => 'curl/curl_d.stub', 'CURLOPT_PREREQFUNCTION' => 'curl/curl_d.stub', 'CURLOPT_PRE_PROXY' => 'curl/curl_d.stub', 'CURLOPT_PRIVATE' => 'curl/curl_d.stub', 'CURLOPT_PROGRESSFUNCTION' => 'curl/curl_d.stub', 'CURLOPT_PROTOCOLS' => 'curl/curl_d.stub', 'CURLOPT_PROTOCOLS_STR' => 'curl/curl_d.stub', 'CURLOPT_PROXY' => 'curl/curl_d.stub', 'CURLOPT_PROXYAUTH' => 'curl/curl_d.stub', 'CURLOPT_PROXYHEADER' => 'curl/curl_d.stub', 'CURLOPT_PROXYPASSWORD' => 'curl/curl_d.stub', 'CURLOPT_PROXYPORT' => 'curl/curl_d.stub', 'CURLOPT_PROXYTYPE' => 'curl/curl_d.stub', 'CURLOPT_PROXYUSERNAME' => 'curl/curl_d.stub', 'CURLOPT_PROXYUSERPWD' => 'curl/curl_d.stub', 'CURLOPT_PROXY_CAINFO' => 'curl/curl_d.stub', 'CURLOPT_PROXY_CAINFO_BLOB' => 'curl/curl_d.stub', 'CURLOPT_PROXY_CAPATH' => 'curl/curl_d.stub', 'CURLOPT_PROXY_CRLFILE' => 'curl/curl_d.stub', 'CURLOPT_PROXY_ISSUERCERT' => 'curl/curl_d.stub', 'CURLOPT_PROXY_ISSUERCERT_BLOB' => 'curl/curl_d.stub', 'CURLOPT_PROXY_KEYPASSWD' => 'curl/curl_d.stub', 'CURLOPT_PROXY_PINNEDPUBLICKEY' => 'curl/curl_d.stub', 'CURLOPT_PROXY_SERVICE_NAME' => 'curl/curl_d.stub', 'CURLOPT_PROXY_SSLCERT' => 'curl/curl_d.stub', 'CURLOPT_PROXY_SSLCERTTYPE' => 'curl/curl_d.stub', 'CURLOPT_PROXY_SSLCERT_BLOB' => 'curl/curl_d.stub', 'CURLOPT_PROXY_SSLKEY' => 'curl/curl_d.stub', 'CURLOPT_PROXY_SSLKEYTYPE' => 'curl/curl_d.stub', 'CURLOPT_PROXY_SSLKEY_BLOB' => 'curl/curl_d.stub', 'CURLOPT_PROXY_SSLVERSION' => 'curl/curl_d.stub', 'CURLOPT_PROXY_SSL_CIPHER_LIST' => 'curl/curl_d.stub', 'CURLOPT_PROXY_SSL_OPTIONS' => 'curl/curl_d.stub', 'CURLOPT_PROXY_SSL_VERIFYHOST' => 'curl/curl_d.stub', 'CURLOPT_PROXY_SSL_VERIFYPEER' => 'curl/curl_d.stub', 'CURLOPT_PROXY_TLS13_CIPHERS' => 'curl/curl_d.stub', 'CURLOPT_PROXY_TLSAUTH_PASSWORD' => 'curl/curl_d.stub', 'CURLOPT_PROXY_TLSAUTH_TYPE' => 'curl/curl_d.stub', 'CURLOPT_PROXY_TLSAUTH_USERNAME' => 'curl/curl_d.stub', 'CURLOPT_PROXY_TRANSFER_MODE' => 'curl/curl_d.stub', 'CURLOPT_PUT' => 'curl/curl_d.stub', 'CURLOPT_QUICK_EXIT' => 'curl/curl_d.stub', 'CURLOPT_QUOTE' => 'curl/curl_d.stub', 'CURLOPT_RANDOM_FILE' => 'curl/curl_d.stub', 'CURLOPT_RANGE' => 'curl/curl_d.stub', 'CURLOPT_READDATA' => 'curl/curl_d.stub', 'CURLOPT_READFUNCTION' => 'curl/curl_d.stub', 'CURLOPT_REDIR_PROTOCOLS' => 'curl/curl_d.stub', 'CURLOPT_REDIR_PROTOCOLS_STR' => 'curl/curl_d.stub', 'CURLOPT_REFERER' => 'curl/curl_d.stub', 'CURLOPT_REQUEST_TARGET' => 'curl/curl_d.stub', 'CURLOPT_RESOLVE' => 'curl/curl_d.stub', 'CURLOPT_RESUME_FROM' => 'curl/curl_d.stub', 'CURLOPT_RETURNTRANSFER' => 'curl/curl_d.stub', 'CURLOPT_RTSP_CLIENT_CSEQ' => 'curl/curl_d.stub', 'CURLOPT_RTSP_REQUEST' => 'curl/curl_d.stub', 'CURLOPT_RTSP_SERVER_CSEQ' => 'curl/curl_d.stub', 'CURLOPT_RTSP_SESSION_ID' => 'curl/curl_d.stub', 'CURLOPT_RTSP_STREAM_URI' => 'curl/curl_d.stub', 'CURLOPT_RTSP_TRANSPORT' => 'curl/curl_d.stub', 'CURLOPT_SAFE_UPLOAD' => 'curl/curl_d.stub', 'CURLOPT_SASL_AUTHZID' => 'curl/curl_d.stub', 'CURLOPT_SASL_IR' => 'curl/curl_d.stub', 'CURLOPT_SERVICE_NAME' => 'curl/curl_d.stub', 'CURLOPT_SHARE' => 'curl/curl_d.stub', 'CURLOPT_SOCKS5_AUTH' => 'curl/curl_d.stub', 'CURLOPT_SOCKS5_GSSAPI_NEC' => 'curl/curl_d.stub', 'CURLOPT_SOCKS5_GSSAPI_SERVICE' => 'curl/curl_d.stub', 'CURLOPT_SSH_AUTH_TYPES' => 'curl/curl_d.stub', 'CURLOPT_SSH_COMPRESSION' => 'curl/curl_d.stub', 'CURLOPT_SSH_HOSTKEYFUNCTION' => 'curl/curl_d.stub', 'CURLOPT_SSH_HOST_PUBLIC_KEY_MD5' => 'curl/curl_d.stub', 'CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256' => 'curl/curl_d.stub', 'CURLOPT_SSH_KNOWNHOSTS' => 'curl/curl_d.stub', 'CURLOPT_SSH_PRIVATE_KEYFILE' => 'curl/curl_d.stub', 'CURLOPT_SSH_PUBLIC_KEYFILE' => 'curl/curl_d.stub', 'CURLOPT_SSLCERT' => 'curl/curl_d.stub', 'CURLOPT_SSLCERTPASSWD' => 'curl/curl_d.stub', 'CURLOPT_SSLCERTTYPE' => 'curl/curl_d.stub', 'CURLOPT_SSLCERT_BLOB' => 'curl/curl_d.stub', 'CURLOPT_SSLENGINE' => 'curl/curl_d.stub', 'CURLOPT_SSLENGINE_DEFAULT' => 'curl/curl_d.stub', 'CURLOPT_SSLKEY' => 'curl/curl_d.stub', 'CURLOPT_SSLKEYPASSWD' => 'curl/curl_d.stub', 'CURLOPT_SSLKEYTYPE' => 'curl/curl_d.stub', 'CURLOPT_SSLKEY_BLOB' => 'curl/curl_d.stub', 'CURLOPT_SSLVERSION' => 'curl/curl_d.stub', 'CURLOPT_SSL_CIPHER_LIST' => 'curl/curl_d.stub', 'CURLOPT_SSL_EC_CURVES' => 'curl/curl_d.stub', 'CURLOPT_SSL_ENABLE_ALPN' => 'curl/curl_d.stub', 'CURLOPT_SSL_ENABLE_NPN' => 'curl/curl_d.stub', 'CURLOPT_SSL_FALSESTART' => 'curl/curl_d.stub', 'CURLOPT_SSL_OPTIONS' => 'curl/curl_d.stub', 'CURLOPT_SSL_SESSIONID_CACHE' => 'curl/curl_d.stub', 'CURLOPT_SSL_VERIFYHOST' => 'curl/curl_d.stub', 'CURLOPT_SSL_VERIFYPEER' => 'curl/curl_d.stub', 'CURLOPT_SSL_VERIFYSTATUS' => 'curl/curl_d.stub', 'CURLOPT_STDERR' => 'curl/curl_d.stub', 'CURLOPT_STREAM_WEIGHT' => 'curl/curl_d.stub', 'CURLOPT_SUPPRESS_CONNECT_HEADERS' => 'curl/curl_d.stub', 'CURLOPT_TCP_FASTOPEN' => 'curl/curl_d.stub', 'CURLOPT_TCP_KEEPALIVE' => 'curl/curl_d.stub', 'CURLOPT_TCP_KEEPCNT' => 'curl/curl_d.stub', 'CURLOPT_TCP_KEEPIDLE' => 'curl/curl_d.stub', 'CURLOPT_TCP_KEEPINTVL' => 'curl/curl_d.stub', 'CURLOPT_TCP_NODELAY' => 'curl/curl_d.stub', 'CURLOPT_TELNETOPTIONS' => 'curl/curl_d.stub', 'CURLOPT_TFTP_BLKSIZE' => 'curl/curl_d.stub', 'CURLOPT_TFTP_NO_OPTIONS' => 'curl/curl_d.stub', 'CURLOPT_TIMECONDITION' => 'curl/curl_d.stub', 'CURLOPT_TIMEOUT' => 'curl/curl_d.stub', 'CURLOPT_TIMEOUT_MS' => 'curl/curl_d.stub', 'CURLOPT_TIMEVALUE' => 'curl/curl_d.stub', 'CURLOPT_TIMEVALUE_LARGE' => 'curl/curl_d.stub', 'CURLOPT_TLS13_CIPHERS' => 'curl/curl_d.stub', 'CURLOPT_TLSAUTH_PASSWORD' => 'curl/curl_d.stub', 'CURLOPT_TLSAUTH_TYPE' => 'curl/curl_d.stub', 'CURLOPT_TLSAUTH_USERNAME' => 'curl/curl_d.stub', 'CURLOPT_TRANSFERTEXT' => 'curl/curl_d.stub', 'CURLOPT_TRANSFER_ENCODING' => 'curl/curl_d.stub', 'CURLOPT_UNIX_SOCKET_PATH' => 'curl/curl_d.stub', 'CURLOPT_UNRESTRICTED_AUTH' => 'curl/curl_d.stub', 'CURLOPT_UPKEEP_INTERVAL_MS' => 'curl/curl_d.stub', 'CURLOPT_UPLOAD' => 'curl/curl_d.stub', 'CURLOPT_UPLOAD_BUFFERSIZE' => 'curl/curl_d.stub', 'CURLOPT_URL' => 'curl/curl_d.stub', 'CURLOPT_USERAGENT' => 'curl/curl_d.stub', 'CURLOPT_USERNAME' => 'curl/curl_d.stub', 'CURLOPT_USERPWD' => 'curl/curl_d.stub', 'CURLOPT_USE_SSL' => 'curl/curl_d.stub', 'CURLOPT_VERBOSE' => 'curl/curl_d.stub', 'CURLOPT_WILDCARDMATCH' => 'curl/curl_d.stub', 'CURLOPT_WRITEFUNCTION' => 'curl/curl_d.stub', 'CURLOPT_WRITEHEADER' => 'curl/curl_d.stub', 'CURLOPT_WS_OPTIONS' => 'curl/curl_d.stub', 'CURLOPT_XFERINFOFUNCTION' => 'curl/curl_d.stub', 'CURLOPT_XOAUTH2_BEARER' => 'curl/curl_d.stub', 'CURLPAUSE_ALL' => 'curl/curl_d.stub', 'CURLPAUSE_CONT' => 'curl/curl_d.stub', 'CURLPAUSE_RECV' => 'curl/curl_d.stub', 'CURLPAUSE_RECV_CONT' => 'curl/curl_d.stub', 'CURLPAUSE_SEND' => 'curl/curl_d.stub', 'CURLPAUSE_SEND_CONT' => 'curl/curl_d.stub', 'CURLPIPE_HTTP1' => 'curl/curl_d.stub', 'CURLPIPE_MULTIPLEX' => 'curl/curl_d.stub', 'CURLPIPE_NOTHING' => 'curl/curl_d.stub', 'CURLPROTO_ALL' => 'curl/curl_d.stub', 'CURLPROTO_DICT' => 'curl/curl_d.stub', 'CURLPROTO_FILE' => 'curl/curl_d.stub', 'CURLPROTO_FTP' => 'curl/curl_d.stub', 'CURLPROTO_FTPS' => 'curl/curl_d.stub', 'CURLPROTO_GOPHER' => 'curl/curl_d.stub', 'CURLPROTO_HTTP' => 'curl/curl_d.stub', 'CURLPROTO_HTTPS' => 'curl/curl_d.stub', 'CURLPROTO_IMAP' => 'curl/curl_d.stub', 'CURLPROTO_IMAPS' => 'curl/curl_d.stub', 'CURLPROTO_LDAP' => 'curl/curl_d.stub', 'CURLPROTO_LDAPS' => 'curl/curl_d.stub', 'CURLPROTO_MQTT' => 'curl/curl_d.stub', 'CURLPROTO_POP3' => 'curl/curl_d.stub', 'CURLPROTO_POP3S' => 'curl/curl_d.stub', 'CURLPROTO_RTMP' => 'curl/curl_d.stub', 'CURLPROTO_RTMPE' => 'curl/curl_d.stub', 'CURLPROTO_RTMPS' => 'curl/curl_d.stub', 'CURLPROTO_RTMPT' => 'curl/curl_d.stub', 'CURLPROTO_RTMPTE' => 'curl/curl_d.stub', 'CURLPROTO_RTMPTS' => 'curl/curl_d.stub', 'CURLPROTO_RTSP' => 'curl/curl_d.stub', 'CURLPROTO_SCP' => 'curl/curl_d.stub', 'CURLPROTO_SFTP' => 'curl/curl_d.stub', 'CURLPROTO_SMB' => 'curl/curl_d.stub', 'CURLPROTO_SMBS' => 'curl/curl_d.stub', 'CURLPROTO_SMTP' => 'curl/curl_d.stub', 'CURLPROTO_SMTPS' => 'curl/curl_d.stub', 'CURLPROTO_TELNET' => 'curl/curl_d.stub', 'CURLPROTO_TFTP' => 'curl/curl_d.stub', 'CURLPROXY_HTTP' => 'curl/curl_d.stub', 'CURLPROXY_HTTPS' => 'curl/curl_d.stub', 'CURLPROXY_HTTP_1_0' => 'curl/curl_d.stub', 'CURLPROXY_SOCKS4' => 'curl/curl_d.stub', 'CURLPROXY_SOCKS4A' => 'curl/curl_d.stub', 'CURLPROXY_SOCKS5' => 'curl/curl_d.stub', 'CURLPROXY_SOCKS5_HOSTNAME' => 'curl/curl_d.stub', 'CURLPX_BAD_ADDRESS_TYPE' => 'curl/curl_d.stub', 'CURLPX_BAD_VERSION' => 'curl/curl_d.stub', 'CURLPX_CLOSED' => 'curl/curl_d.stub', 'CURLPX_GSSAPI' => 'curl/curl_d.stub', 'CURLPX_GSSAPI_PERMSG' => 'curl/curl_d.stub', 'CURLPX_GSSAPI_PROTECTION' => 'curl/curl_d.stub', 'CURLPX_IDENTD' => 'curl/curl_d.stub', 'CURLPX_IDENTD_DIFFER' => 'curl/curl_d.stub', 'CURLPX_LONG_HOSTNAME' => 'curl/curl_d.stub', 'CURLPX_LONG_PASSWD' => 'curl/curl_d.stub', 'CURLPX_LONG_USER' => 'curl/curl_d.stub', 'CURLPX_NO_AUTH' => 'curl/curl_d.stub', 'CURLPX_OK' => 'curl/curl_d.stub', 'CURLPX_RECV_ADDRESS' => 'curl/curl_d.stub', 'CURLPX_RECV_AUTH' => 'curl/curl_d.stub', 'CURLPX_RECV_CONNECT' => 'curl/curl_d.stub', 'CURLPX_RECV_REQACK' => 'curl/curl_d.stub', 'CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED' => 'curl/curl_d.stub', 'CURLPX_REPLY_COMMAND_NOT_SUPPORTED' => 'curl/curl_d.stub', 'CURLPX_REPLY_CONNECTION_REFUSED' => 'curl/curl_d.stub', 'CURLPX_REPLY_GENERAL_SERVER_FAILURE' => 'curl/curl_d.stub', 'CURLPX_REPLY_HOST_UNREACHABLE' => 'curl/curl_d.stub', 'CURLPX_REPLY_NETWORK_UNREACHABLE' => 'curl/curl_d.stub', 'CURLPX_REPLY_NOT_ALLOWED' => 'curl/curl_d.stub', 'CURLPX_REPLY_TTL_EXPIRED' => 'curl/curl_d.stub', 'CURLPX_REPLY_UNASSIGNED' => 'curl/curl_d.stub', 'CURLPX_REQUEST_FAILED' => 'curl/curl_d.stub', 'CURLPX_RESOLVE_HOST' => 'curl/curl_d.stub', 'CURLPX_SEND_AUTH' => 'curl/curl_d.stub', 'CURLPX_SEND_CONNECT' => 'curl/curl_d.stub', 'CURLPX_SEND_REQUEST' => 'curl/curl_d.stub', 'CURLPX_UNKNOWN_FAIL' => 'curl/curl_d.stub', 'CURLPX_UNKNOWN_MODE' => 'curl/curl_d.stub', 'CURLPX_USER_REJECTED' => 'curl/curl_d.stub', 'CURLSHOPT_NONE' => 'curl/curl_d.stub', 'CURLSHOPT_SHARE' => 'curl/curl_d.stub', 'CURLSHOPT_UNSHARE' => 'curl/curl_d.stub', 'CURLSSH_AUTH_AGENT' => 'curl/curl_d.stub', 'CURLSSH_AUTH_ANY' => 'curl/curl_d.stub', 'CURLSSH_AUTH_DEFAULT' => 'curl/curl_d.stub', 'CURLSSH_AUTH_GSSAPI' => 'curl/curl_d.stub', 'CURLSSH_AUTH_HOST' => 'curl/curl_d.stub', 'CURLSSH_AUTH_KEYBOARD' => 'curl/curl_d.stub', 'CURLSSH_AUTH_NONE' => 'curl/curl_d.stub', 'CURLSSH_AUTH_PASSWORD' => 'curl/curl_d.stub', 'CURLSSH_AUTH_PUBLICKEY' => 'curl/curl_d.stub', 'CURLSSLOPT_ALLOW_BEAST' => 'curl/curl_d.stub', 'CURLSSLOPT_AUTO_CLIENT_CERT' => 'curl/curl_d.stub', 'CURLSSLOPT_NATIVE_CA' => 'curl/curl_d.stub', 'CURLSSLOPT_NO_PARTIALCHAIN' => 'curl/curl_d.stub', 'CURLSSLOPT_NO_REVOKE' => 'curl/curl_d.stub', 'CURLSSLOPT_REVOKE_BEST_EFFORT' => 'curl/curl_d.stub', 'CURLUSESSL_ALL' => 'curl/curl_d.stub', 'CURLUSESSL_CONTROL' => 'curl/curl_d.stub', 'CURLUSESSL_NONE' => 'curl/curl_d.stub', 'CURLUSESSL_TRY' => 'curl/curl_d.stub', 'CURLVERSION_NOW' => 'curl/curl_d.stub', 'CURLWS_RAW_MODE' => 'curl/curl_d.stub', 'CURL_FNMATCHFUNC_FAIL' => 'curl/curl_d.stub', 'CURL_FNMATCHFUNC_MATCH' => 'curl/curl_d.stub', 'CURL_FNMATCHFUNC_NOMATCH' => 'curl/curl_d.stub', 'CURL_HTTP_VERSION_1_0' => 'curl/curl_d.stub', 'CURL_HTTP_VERSION_1_1' => 'curl/curl_d.stub', 'CURL_HTTP_VERSION_2' => 'curl/curl_d.stub', 'CURL_HTTP_VERSION_2TLS' => 'curl/curl_d.stub', 'CURL_HTTP_VERSION_2_0' => 'curl/curl_d.stub', 'CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE' => 'curl/curl_d.stub', 'CURL_HTTP_VERSION_3' => 'curl/curl_d.stub', 'CURL_HTTP_VERSION_3ONLY' => 'curl/curl_d.stub', 'CURL_HTTP_VERSION_NONE' => 'curl/curl_d.stub', 'CURL_IPRESOLVE_V4' => 'curl/curl_d.stub', 'CURL_IPRESOLVE_V6' => 'curl/curl_d.stub', 'CURL_IPRESOLVE_WHATEVER' => 'curl/curl_d.stub', 'CURL_LOCK_DATA_CONNECT' => 'curl/curl_d.stub', 'CURL_LOCK_DATA_COOKIE' => 'curl/curl_d.stub', 'CURL_LOCK_DATA_DNS' => 'curl/curl_d.stub', 'CURL_LOCK_DATA_PSL' => 'curl/curl_d.stub', 'CURL_LOCK_DATA_SSL_SESSION' => 'curl/curl_d.stub', 'CURL_MAX_READ_SIZE' => 'curl/curl_d.stub', 'CURL_NETRC_IGNORED' => 'curl/curl_d.stub', 'CURL_NETRC_OPTIONAL' => 'curl/curl_d.stub', 'CURL_NETRC_REQUIRED' => 'curl/curl_d.stub', 'CURL_PREREQFUNC_ABORT' => 'curl/curl_d.stub', 'CURL_PREREQFUNC_OK' => 'curl/curl_d.stub', 'CURL_PUSH_DENY' => 'curl/curl_d.stub', 'CURL_PUSH_OK' => 'curl/curl_d.stub', 'CURL_READFUNC_PAUSE' => 'curl/curl_d.stub', 'CURL_REDIR_POST_301' => 'curl/curl_d.stub', 'CURL_REDIR_POST_302' => 'curl/curl_d.stub', 'CURL_REDIR_POST_303' => 'curl/curl_d.stub', 'CURL_REDIR_POST_ALL' => 'curl/curl_d.stub', 'CURL_RTSPREQ_ANNOUNCE' => 'curl/curl_d.stub', 'CURL_RTSPREQ_DESCRIBE' => 'curl/curl_d.stub', 'CURL_RTSPREQ_GET_PARAMETER' => 'curl/curl_d.stub', 'CURL_RTSPREQ_OPTIONS' => 'curl/curl_d.stub', 'CURL_RTSPREQ_PAUSE' => 'curl/curl_d.stub', 'CURL_RTSPREQ_PLAY' => 'curl/curl_d.stub', 'CURL_RTSPREQ_RECEIVE' => 'curl/curl_d.stub', 'CURL_RTSPREQ_RECORD' => 'curl/curl_d.stub', 'CURL_RTSPREQ_SETUP' => 'curl/curl_d.stub', 'CURL_RTSPREQ_SET_PARAMETER' => 'curl/curl_d.stub', 'CURL_RTSPREQ_TEARDOWN' => 'curl/curl_d.stub', 'CURL_SSLVERSION_DEFAULT' => 'curl/curl_d.stub', 'CURL_SSLVERSION_MAX_DEFAULT' => 'curl/curl_d.stub', 'CURL_SSLVERSION_MAX_NONE' => 'curl/curl_d.stub', 'CURL_SSLVERSION_MAX_TLSv1_0' => 'curl/curl_d.stub', 'CURL_SSLVERSION_MAX_TLSv1_1' => 'curl/curl_d.stub', 'CURL_SSLVERSION_MAX_TLSv1_2' => 'curl/curl_d.stub', 'CURL_SSLVERSION_MAX_TLSv1_3' => 'curl/curl_d.stub', 'CURL_SSLVERSION_SSLv2' => 'curl/curl_d.stub', 'CURL_SSLVERSION_SSLv3' => 'curl/curl_d.stub', 'CURL_SSLVERSION_TLSv1' => 'curl/curl_d.stub', 'CURL_SSLVERSION_TLSv1_0' => 'curl/curl_d.stub', 'CURL_SSLVERSION_TLSv1_1' => 'curl/curl_d.stub', 'CURL_SSLVERSION_TLSv1_2' => 'curl/curl_d.stub', 'CURL_SSLVERSION_TLSv1_3' => 'curl/curl_d.stub', 'CURL_TIMECOND_IFMODSINCE' => 'curl/curl_d.stub', 'CURL_TIMECOND_IFUNMODSINCE' => 'curl/curl_d.stub', 'CURL_TIMECOND_LASTMOD' => 'curl/curl_d.stub', 'CURL_TIMECOND_NONE' => 'curl/curl_d.stub', 'CURL_TLSAUTH_SRP' => 'curl/curl_d.stub', 'CURL_VERSION_ALTSVC' => 'curl/curl_d.stub', 'CURL_VERSION_ASYNCHDNS' => 'curl/curl_d.stub', 'CURL_VERSION_BROTLI' => 'curl/curl_d.stub', 'CURL_VERSION_CONV' => 'curl/curl_d.stub', 'CURL_VERSION_CURLDEBUG' => 'curl/curl_d.stub', 'CURL_VERSION_DEBUG' => 'curl/curl_d.stub', 'CURL_VERSION_GSASL' => 'curl/curl_d.stub', 'CURL_VERSION_GSSAPI' => 'curl/curl_d.stub', 'CURL_VERSION_GSSNEGOTIATE' => 'curl/curl_d.stub', 'CURL_VERSION_HSTS' => 'curl/curl_d.stub', 'CURL_VERSION_HTTP2' => 'curl/curl_d.stub', 'CURL_VERSION_HTTP3' => 'curl/curl_d.stub', 'CURL_VERSION_HTTPS_PROXY' => 'curl/curl_d.stub', 'CURL_VERSION_IDN' => 'curl/curl_d.stub', 'CURL_VERSION_IPV6' => 'curl/curl_d.stub', 'CURL_VERSION_KERBEROS4' => 'curl/curl_d.stub', 'CURL_VERSION_KERBEROS5' => 'curl/curl_d.stub', 'CURL_VERSION_LARGEFILE' => 'curl/curl_d.stub', 'CURL_VERSION_LIBZ' => 'curl/curl_d.stub', 'CURL_VERSION_MULTI_SSL' => 'curl/curl_d.stub', 'CURL_VERSION_NTLM' => 'curl/curl_d.stub', 'CURL_VERSION_NTLM_WB' => 'curl/curl_d.stub', 'CURL_VERSION_PSL' => 'curl/curl_d.stub', 'CURL_VERSION_SPNEGO' => 'curl/curl_d.stub', 'CURL_VERSION_SSL' => 'curl/curl_d.stub', 'CURL_VERSION_SSPI' => 'curl/curl_d.stub', 'CURL_VERSION_TLSAUTH_SRP' => 'curl/curl_d.stub', 'CURL_VERSION_UNICODE' => 'curl/curl_d.stub', 'CURL_VERSION_UNIX_SOCKETS' => 'curl/curl_d.stub', 'CURL_VERSION_ZSTD' => 'curl/curl_d.stub', 'CURL_WRITEFUNC_PAUSE' => 'curl/curl_d.stub', 'CURRENCY_SYMBOL' => 'standard/standard_defines.stub', 'CYAN' => 'winbinder/winbinder.stub', 'Calendar' => 'winbinder/winbinder.stub', 'CheckBox' => 'winbinder/winbinder.stub', 'ComboBox' => 'winbinder/winbinder.stub', 'DARKBLUE' => 'winbinder/winbinder.stub', 'DARKCYAN' => 'winbinder/winbinder.stub', 'DARKGRAY' => 'winbinder/winbinder.stub', 'DARKGREEN' => 'winbinder/winbinder.stub', 'DARKMAGENTA' => 'winbinder/winbinder.stub', 'DARKRED' => 'winbinder/winbinder.stub', 'DARKYELLOW' => 'winbinder/winbinder.stub', 'DATE_ATOM' => 'date/date_d.stub', 'DATE_COOKIE' => 'date/date_d.stub', 'DATE_ISO8601' => 'date/date_d.stub', 'DATE_ISO8601_EXPANDED' => 'date/date_d.stub', 'DATE_RFC1036' => 'date/date_d.stub', 'DATE_RFC1123' => 'date/date_d.stub', 'DATE_RFC2822' => 'date/date_d.stub', 'DATE_RFC3339' => 'date/date_d.stub', 'DATE_RFC3339_EXTENDED' => 'date/date_d.stub', 'DATE_RFC7231' => 'date/date_d.stub', 'DATE_RFC822' => 'date/date_d.stub', 'DATE_RFC850' => 'date/date_d.stub', 'DATE_RSS' => 'date/date_d.stub', 'DATE_W3C' => 'date/date_d.stub', 'DAY_1' => 'standard/standard_defines.stub', 'DAY_2' => 'standard/standard_defines.stub', 'DAY_3' => 'standard/standard_defines.stub', 'DAY_4' => 'standard/standard_defines.stub', 'DAY_5' => 'standard/standard_defines.stub', 'DAY_6' => 'standard/standard_defines.stub', 'DAY_7' => 'standard/standard_defines.stub', 'DB2_AUTOCOMMIT_OFF' => 'ibm_db2/ibm_db2.stub', 'DB2_AUTOCOMMIT_ON' => 'ibm_db2/ibm_db2.stub', 'DB2_BINARY' => 'ibm_db2/ibm_db2.stub', 'DB2_CASE_LOWER' => 'ibm_db2/ibm_db2.stub', 'DB2_CASE_NATURAL' => 'ibm_db2/ibm_db2.stub', 'DB2_CASE_UPPER' => 'ibm_db2/ibm_db2.stub', 'DB2_CHAR' => 'ibm_db2/ibm_db2.stub', 'DB2_CONVERT' => 'ibm_db2/ibm_db2.stub', 'DB2_DEFERRED_PREPARE_OFF' => 'ibm_db2/ibm_db2.stub', 'DB2_DEFERRED_PREPARE_ON' => 'ibm_db2/ibm_db2.stub', 'DB2_DOUBLE' => 'ibm_db2/ibm_db2.stub', 'DB2_FORWARD_ONLY' => 'ibm_db2/ibm_db2.stub', 'DB2_LONG' => 'ibm_db2/ibm_db2.stub', 'DB2_PARAM_FILE' => 'ibm_db2/ibm_db2.stub', 'DB2_PARAM_IN' => 'ibm_db2/ibm_db2.stub', 'DB2_PARAM_INOUT' => 'ibm_db2/ibm_db2.stub', 'DB2_PARAM_OUT' => 'ibm_db2/ibm_db2.stub', 'DB2_PASSTHRU' => 'ibm_db2/ibm_db2.stub', 'DB2_SCROLLABLE' => 'ibm_db2/ibm_db2.stub', 'DB2_XML' => 'ibm_db2/ibm_db2.stub', 'DBA_LMDB_NO_SUB_DIR' => 'dba/dba.stub', 'DBA_LMDB_USE_SUB_DIR' => 'dba/dba.stub', 'DEBUG_BACKTRACE_IGNORE_ARGS' => 'Core/Core_d.stub', 'DEBUG_BACKTRACE_PROVIDE_OBJECT' => 'Core/Core_d.stub', 'DECIMAL_POINT' => 'standard/standard_defines.stub', 'DEFAULT_INCLUDE_PATH' => 'Core/Core_d.stub', 'DIRECTORY_SEPARATOR' => 'standard/standard_defines.stub', 'DISP_E_DIVBYZERO' => 'com_dotnet/com_dotnet.stub', 'DISP_E_OVERFLOW' => 'com_dotnet/com_dotnet.stub', 'DNS_A' => 'standard/standard_defines.stub', 'DNS_A6' => 'standard/standard_defines.stub', 'DNS_AAAA' => 'standard/standard_defines.stub', 'DNS_ALL' => 'standard/standard_defines.stub', 'DNS_ANY' => 'standard/standard_defines.stub', 'DNS_CAA' => 'standard/standard_defines.stub', 'DNS_CNAME' => 'standard/standard_defines.stub', 'DNS_HINFO' => 'standard/standard_defines.stub', 'DNS_MX' => 'standard/standard_defines.stub', 'DNS_NAPTR' => 'standard/standard_defines.stub', 'DNS_NS' => 'standard/standard_defines.stub', 'DNS_PTR' => 'standard/standard_defines.stub', 'DNS_SOA' => 'standard/standard_defines.stub', 'DNS_SRV' => 'standard/standard_defines.stub', 'DNS_TXT' => 'standard/standard_defines.stub', 'DOMSTRING_SIZE_ERR' => 'dom/dom.stub', 'DOM_HIERARCHY_REQUEST_ERR' => 'dom/dom.stub', 'DOM_INDEX_SIZE_ERR' => 'dom/dom.stub', 'DOM_INUSE_ATTRIBUTE_ERR' => 'dom/dom.stub', 'DOM_INVALID_ACCESS_ERR' => 'dom/dom.stub', 'DOM_INVALID_CHARACTER_ERR' => 'dom/dom.stub', 'DOM_INVALID_MODIFICATION_ERR' => 'dom/dom.stub', 'DOM_INVALID_STATE_ERR' => 'dom/dom.stub', 'DOM_NAMESPACE_ERR' => 'dom/dom.stub', 'DOM_NOT_FOUND_ERR' => 'dom/dom.stub', 'DOM_NOT_SUPPORTED_ERR' => 'dom/dom.stub', 'DOM_NO_DATA_ALLOWED_ERR' => 'dom/dom.stub', 'DOM_NO_MODIFICATION_ALLOWED_ERR' => 'dom/dom.stub', 'DOM_PHP_ERR' => 'dom/dom.stub', 'DOM_SYNTAX_ERR' => 'dom/dom.stub', 'DOM_VALIDATION_ERR' => 'dom/dom.stub', 'DOM_WRONG_DOCUMENT_ERR' => 'dom/dom.stub', 'D_FMT' => 'standard/standard_defines.stub', 'D_T_FMT' => 'standard/standard_defines.stub', 'Dom\\HIERARCHY_REQUEST_ERR' => 'dom/dom_n.stub', 'Dom\\HTML_NO_DEFAULT_NS' => 'dom/dom_n.stub', 'Dom\\INDEX_SIZE_ERR' => 'dom/dom_n.stub', 'Dom\\INUSE_ATTRIBUTE_ERR' => 'dom/dom_n.stub', 'Dom\\INVALID_CHARACTER_ERR' => 'dom/dom_n.stub', 'Dom\\INVALID_MODIFICATION_ERR' => 'dom/dom_n.stub', 'Dom\\INVALID_STATE_ERR' => 'dom/dom_n.stub', 'Dom\\NAMESPACE_ERR' => 'dom/dom_n.stub', 'Dom\\NOT_FOUND_ERR' => 'dom/dom_n.stub', 'Dom\\NOT_SUPPORTED_ERR' => 'dom/dom_n.stub', 'Dom\\NO_DATA_ALLOWED_ERR' => 'dom/dom_n.stub', 'Dom\\NO_MODIFICATION_ALLOWED_ERR' => 'dom/dom_n.stub', 'Dom\\STRING_SIZE_ERR' => 'dom/dom_n.stub', 'Dom\\SYNTAX_ERR' => 'dom/dom_n.stub', 'Dom\\VALIDATION_ERR' => 'dom/dom_n.stub', 'Dom\\WRONG_DOCUMENT_ERR' => 'dom/dom_n.stub', 'EIO_DEBUG' => 'eio/eio.stub', 'EIO_DT_BLK' => 'eio/eio.stub', 'EIO_DT_CHR' => 'eio/eio.stub', 'EIO_DT_CMP' => 'eio/eio.stub', 'EIO_DT_DIR' => 'eio/eio.stub', 'EIO_DT_DOOR' => 'eio/eio.stub', 'EIO_DT_FIFO' => 'eio/eio.stub', 'EIO_DT_LNK' => 'eio/eio.stub', 'EIO_DT_MAX' => 'eio/eio.stub', 'EIO_DT_MPB' => 'eio/eio.stub', 'EIO_DT_MPC' => 'eio/eio.stub', 'EIO_DT_NAM' => 'eio/eio.stub', 'EIO_DT_NWK' => 'eio/eio.stub', 'EIO_DT_REG' => 'eio/eio.stub', 'EIO_DT_SOCK' => 'eio/eio.stub', 'EIO_DT_UNKNOWN' => 'eio/eio.stub', 'EIO_DT_WHT' => 'eio/eio.stub', 'EIO_FALLOC_FL_KEEP_SIZE' => 'eio/eio.stub', 'EIO_O_APPEND' => 'eio/eio.stub', 'EIO_O_CREAT' => 'eio/eio.stub', 'EIO_O_EXCL' => 'eio/eio.stub', 'EIO_O_FSYNC' => 'eio/eio.stub', 'EIO_O_NONBLOCK' => 'eio/eio.stub', 'EIO_O_RDONLY' => 'eio/eio.stub', 'EIO_O_RDWR' => 'eio/eio.stub', 'EIO_O_TRUNC' => 'eio/eio.stub', 'EIO_O_WRONLY' => 'eio/eio.stub', 'EIO_PRI_DEFAULT' => 'eio/eio.stub', 'EIO_PRI_MAX' => 'eio/eio.stub', 'EIO_PRI_MIN' => 'eio/eio.stub', 'EIO_READDIR_DENTS' => 'eio/eio.stub', 'EIO_READDIR_DIRS_FIRST' => 'eio/eio.stub', 'EIO_READDIR_FOUND_UNKNOWN' => 'eio/eio.stub', 'EIO_READDIR_STAT_ORDER' => 'eio/eio.stub', 'EIO_SEEK_CUR' => 'eio/eio.stub', 'EIO_SEEK_END' => 'eio/eio.stub', 'EIO_SEEK_SET' => 'eio/eio.stub', 'EIO_SYNC_FILE_RANGE_WAIT_AFTER' => 'eio/eio.stub', 'EIO_SYNC_FILE_RANGE_WAIT_BEFORE' => 'eio/eio.stub', 'EIO_SYNC_FILE_RANGE_WRITE' => 'eio/eio.stub', 'EIO_S_IFBLK' => 'eio/eio.stub', 'EIO_S_IFCHR' => 'eio/eio.stub', 'EIO_S_IFIFO' => 'eio/eio.stub', 'EIO_S_IFREG' => 'eio/eio.stub', 'EIO_S_IFSOCK' => 'eio/eio.stub', 'EIO_S_IRGRP' => 'eio/eio.stub', 'EIO_S_IROTH' => 'eio/eio.stub', 'EIO_S_IRUSR' => 'eio/eio.stub', 'EIO_S_IWGRP' => 'eio/eio.stub', 'EIO_S_IWOTH' => 'eio/eio.stub', 'EIO_S_IWUSR' => 'eio/eio.stub', 'EIO_S_IXGRP' => 'eio/eio.stub', 'EIO_S_IXOTH' => 'eio/eio.stub', 'EIO_S_IXUSR' => 'eio/eio.stub', 'ENC7BIT' => 'imap/imap.stub', 'ENC8BIT' => 'imap/imap.stub', 'ENCBASE64' => 'imap/imap.stub', 'ENCBINARY' => 'imap/imap.stub', 'ENCHANT_ISPELL' => 'enchant/enchant.stub', 'ENCHANT_MYSPELL' => 'enchant/enchant.stub', 'ENCOTHER' => 'imap/imap.stub', 'ENCQUOTEDPRINTABLE' => 'imap/imap.stub', 'ENT_COMPAT' => 'standard/standard_defines.stub', 'ENT_DISALLOWED' => 'standard/standard_defines.stub', 'ENT_HTML401' => 'standard/standard_defines.stub', 'ENT_HTML5' => 'standard/standard_defines.stub', 'ENT_IGNORE' => 'standard/standard_defines.stub', 'ENT_NOQUOTES' => 'standard/standard_defines.stub', 'ENT_QUOTES' => 'standard/standard_defines.stub', 'ENT_SUBSTITUTE' => 'standard/standard_defines.stub', 'ENT_XHTML' => 'standard/standard_defines.stub', 'ENT_XML1' => 'standard/standard_defines.stub', 'ERA' => 'standard/standard_defines.stub', 'ERA_D_FMT' => 'standard/standard_defines.stub', 'ERA_D_T_FMT' => 'standard/standard_defines.stub', 'ERA_T_FMT' => 'standard/standard_defines.stub', 'ERA_YEAR' => 'standard/standard_defines.stub', 'EVBUFFER_EOF' => 'libevent/libevent.stub', 'EVBUFFER_ERROR' => 'libevent/libevent.stub', 'EVBUFFER_READ' => 'libevent/libevent.stub', 'EVBUFFER_TIMEOUT' => 'libevent/libevent.stub', 'EVBUFFER_WRITE' => 'libevent/libevent.stub', 'EVLOOP_NONBLOCK' => 'libevent/libevent.stub', 'EVLOOP_ONCE' => 'libevent/libevent.stub', 'EV_PERSIST' => 'libevent/libevent.stub', 'EV_READ' => 'libevent/libevent.stub', 'EV_SIGNAL' => 'libevent/libevent.stub', 'EV_TIMEOUT' => 'libevent/libevent.stub', 'EV_WRITE' => 'libevent/libevent.stub', 'EXIF_USE_MBSTRING' => 'exif/exif.stub', 'EXP_EOF' => 'expect/expect.stub', 'EXP_EXACT' => 'expect/expect.stub', 'EXP_FULLBUFFER' => 'expect/expect.stub', 'EXP_GLOB' => 'expect/expect.stub', 'EXP_REGEXP' => 'expect/expect.stub', 'EXP_TIMEOUT' => 'expect/expect.stub', 'EXTR_IF_EXISTS' => 'standard/standard_defines.stub', 'EXTR_OVERWRITE' => 'standard/standard_defines.stub', 'EXTR_PREFIX_ALL' => 'standard/standard_defines.stub', 'EXTR_PREFIX_IF_EXISTS' => 'standard/standard_defines.stub', 'EXTR_PREFIX_INVALID' => 'standard/standard_defines.stub', 'EXTR_PREFIX_SAME' => 'standard/standard_defines.stub', 'EXTR_REFS' => 'standard/standard_defines.stub', 'EXTR_SKIP' => 'standard/standard_defines.stub', 'E_ALL' => 'Core/Core_d.stub', 'E_COMPILE_ERROR' => 'Core/Core_d.stub', 'E_COMPILE_WARNING' => 'Core/Core_d.stub', 'E_CORE_ERROR' => 'Core/Core_d.stub', 'E_CORE_WARNING' => 'Core/Core_d.stub', 'E_DEPRECATED' => 'Core/Core_d.stub', 'E_ERROR' => 'Core/Core_d.stub', 'E_NOTICE' => 'Core/Core_d.stub', 'E_PARSE' => 'Core/Core_d.stub', 'E_RECOVERABLE_ERROR' => 'Core/Core_d.stub', 'E_STRICT' => 'Core/Core_d.stub', 'E_USER_DEPRECATED' => 'Core/Core_d.stub', 'E_USER_ERROR' => 'Core/Core_d.stub', 'E_USER_NOTICE' => 'Core/Core_d.stub', 'E_USER_WARNING' => 'Core/Core_d.stub', 'E_WARNING' => 'Core/Core_d.stub', 'EditBox' => 'winbinder/winbinder.stub', 'FANN_COS' => 'fann/fann.stub', 'FANN_COS_SYMMETRIC' => 'fann/fann.stub', 'FANN_ELLIOT' => 'fann/fann.stub', 'FANN_ELLIOT_SYMMETRIC' => 'fann/fann.stub', 'FANN_ERRORFUNC_LINEAR' => 'fann/fann.stub', 'FANN_ERRORFUNC_TANH' => 'fann/fann.stub', 'FANN_E_CANT_ALLOCATE_MEM' => 'fann/fann.stub', 'FANN_E_CANT_OPEN_CONFIG_R' => 'fann/fann.stub', 'FANN_E_CANT_OPEN_CONFIG_W' => 'fann/fann.stub', 'FANN_E_CANT_OPEN_TD_R' => 'fann/fann.stub', 'FANN_E_CANT_OPEN_TD_W' => 'fann/fann.stub', 'FANN_E_CANT_READ_CONFIG' => 'fann/fann.stub', 'FANN_E_CANT_READ_CONNECTIONS' => 'fann/fann.stub', 'FANN_E_CANT_READ_NEURON' => 'fann/fann.stub', 'FANN_E_CANT_READ_TD' => 'fann/fann.stub', 'FANN_E_CANT_TRAIN_ACTIVATION' => 'fann/fann.stub', 'FANN_E_CANT_USE_ACTIVATION' => 'fann/fann.stub', 'FANN_E_CANT_USE_TRAIN_ALG' => 'fann/fann.stub', 'FANN_E_INDEX_OUT_OF_BOUND' => 'fann/fann.stub', 'FANN_E_INPUT_NO_MATCH' => 'fann/fann.stub', 'FANN_E_NO_ERROR' => 'fann/fann.stub', 'FANN_E_OUTPUT_NO_MATCH' => 'fann/fann.stub', 'FANN_E_SCALE_NOT_PRESENT' => 'fann/fann.stub', 'FANN_E_TRAIN_DATA_MISMATCH' => 'fann/fann.stub', 'FANN_E_TRAIN_DATA_SUBSET' => 'fann/fann.stub', 'FANN_E_WRONG_CONFIG_VERSION' => 'fann/fann.stub', 'FANN_E_WRONG_NUM_CONNECTIONS' => 'fann/fann.stub', 'FANN_GAUSSIAN' => 'fann/fann.stub', 'FANN_GAUSSIAN_STEPWISE' => 'fann/fann.stub', 'FANN_GAUSSIAN_SYMMETRIC' => 'fann/fann.stub', 'FANN_LINEAR' => 'fann/fann.stub', 'FANN_LINEAR_PIECE' => 'fann/fann.stub', 'FANN_LINEAR_PIECE_SYMMETRIC' => 'fann/fann.stub', 'FANN_NETTYPE_LAYER' => 'fann/fann.stub', 'FANN_NETTYPE_SHORTCUT' => 'fann/fann.stub', 'FANN_SIGMOID' => 'fann/fann.stub', 'FANN_SIGMOID_STEPWISE' => 'fann/fann.stub', 'FANN_SIGMOID_SYMMETRIC' => 'fann/fann.stub', 'FANN_SIGMOID_SYMMETRIC_STEPWISE' => 'fann/fann.stub', 'FANN_SIN' => 'fann/fann.stub', 'FANN_SIN_SYMMETRIC' => 'fann/fann.stub', 'FANN_STOPFUNC_BIT' => 'fann/fann.stub', 'FANN_STOPFUNC_MSE' => 'fann/fann.stub', 'FANN_THRESHOLD' => 'fann/fann.stub', 'FANN_THRESHOLD_SYMMETRIC' => 'fann/fann.stub', 'FANN_TRAIN_BATCH' => 'fann/fann.stub', 'FANN_TRAIN_INCREMENTAL' => 'fann/fann.stub', 'FANN_TRAIN_QUICKPROP' => 'fann/fann.stub', 'FANN_TRAIN_RPROP' => 'fann/fann.stub', 'FANN_TRAIN_SARPROP' => 'fann/fann.stub', 'FANN_VERSION' => 'fann/fann.stub', 'FILEINFO_APPLE' => 'fileinfo/fileinfo.stub', 'FILEINFO_CONTINUE' => 'fileinfo/fileinfo.stub', 'FILEINFO_DEVICES' => 'fileinfo/fileinfo.stub', 'FILEINFO_EXTENSION' => 'fileinfo/fileinfo.stub', 'FILEINFO_MIME' => 'fileinfo/fileinfo.stub', 'FILEINFO_MIME_ENCODING' => 'fileinfo/fileinfo.stub', 'FILEINFO_MIME_TYPE' => 'fileinfo/fileinfo.stub', 'FILEINFO_NONE' => 'fileinfo/fileinfo.stub', 'FILEINFO_PRESERVE_ATIME' => 'fileinfo/fileinfo.stub', 'FILEINFO_RAW' => 'fileinfo/fileinfo.stub', 'FILEINFO_SYMLINK' => 'fileinfo/fileinfo.stub', 'FILE_APPEND' => 'standard/standard_defines.stub', 'FILE_BINARY' => 'standard/standard_defines.stub', 'FILE_IGNORE_NEW_LINES' => 'standard/standard_defines.stub', 'FILE_NO_DEFAULT_CONTEXT' => 'standard/standard_defines.stub', 'FILE_SKIP_EMPTY_LINES' => 'standard/standard_defines.stub', 'FILE_TEXT' => 'standard/standard_defines.stub', 'FILE_USE_INCLUDE_PATH' => 'standard/standard_defines.stub', 'FILTER_CALLBACK' => 'filter/filter.stub', 'FILTER_DEFAULT' => 'filter/filter.stub', 'FILTER_FLAG_ALLOW_FRACTION' => 'filter/filter.stub', 'FILTER_FLAG_ALLOW_HEX' => 'filter/filter.stub', 'FILTER_FLAG_ALLOW_OCTAL' => 'filter/filter.stub', 'FILTER_FLAG_ALLOW_SCIENTIFIC' => 'filter/filter.stub', 'FILTER_FLAG_ALLOW_THOUSAND' => 'filter/filter.stub', 'FILTER_FLAG_EMAIL_UNICODE' => 'filter/filter.stub', 'FILTER_FLAG_EMPTY_STRING_NULL' => 'filter/filter.stub', 'FILTER_FLAG_ENCODE_AMP' => 'filter/filter.stub', 'FILTER_FLAG_ENCODE_HIGH' => 'filter/filter.stub', 'FILTER_FLAG_ENCODE_LOW' => 'filter/filter.stub', 'FILTER_FLAG_GLOBAL_RANGE' => 'filter/filter.stub', 'FILTER_FLAG_HOSTNAME' => 'filter/filter.stub', 'FILTER_FLAG_HOST_REQUIRED' => 'filter/filter.stub', 'FILTER_FLAG_IPV4' => 'filter/filter.stub', 'FILTER_FLAG_IPV6' => 'filter/filter.stub', 'FILTER_FLAG_NONE' => 'filter/filter.stub', 'FILTER_FLAG_NO_ENCODE_QUOTES' => 'filter/filter.stub', 'FILTER_FLAG_NO_PRIV_RANGE' => 'filter/filter.stub', 'FILTER_FLAG_NO_RES_RANGE' => 'filter/filter.stub', 'FILTER_FLAG_PATH_REQUIRED' => 'filter/filter.stub', 'FILTER_FLAG_QUERY_REQUIRED' => 'filter/filter.stub', 'FILTER_FLAG_SCHEME_REQUIRED' => 'filter/filter.stub', 'FILTER_FLAG_STRIP_BACKTICK' => 'filter/filter.stub', 'FILTER_FLAG_STRIP_HIGH' => 'filter/filter.stub', 'FILTER_FLAG_STRIP_LOW' => 'filter/filter.stub', 'FILTER_FORCE_ARRAY' => 'filter/filter.stub', 'FILTER_NULL_ON_FAILURE' => 'filter/filter.stub', 'FILTER_REQUIRE_ARRAY' => 'filter/filter.stub', 'FILTER_REQUIRE_SCALAR' => 'filter/filter.stub', 'FILTER_SANITIZE_ADD_SLASHES' => 'filter/filter.stub', 'FILTER_SANITIZE_EMAIL' => 'filter/filter.stub', 'FILTER_SANITIZE_ENCODED' => 'filter/filter.stub', 'FILTER_SANITIZE_FULL_SPECIAL_CHARS' => 'filter/filter.stub', 'FILTER_SANITIZE_MAGIC_QUOTES' => 'filter/filter.stub', 'FILTER_SANITIZE_NUMBER_FLOAT' => 'filter/filter.stub', 'FILTER_SANITIZE_NUMBER_INT' => 'filter/filter.stub', 'FILTER_SANITIZE_SPECIAL_CHARS' => 'filter/filter.stub', 'FILTER_SANITIZE_STRING' => 'filter/filter.stub', 'FILTER_SANITIZE_STRIPPED' => 'filter/filter.stub', 'FILTER_SANITIZE_URL' => 'filter/filter.stub', 'FILTER_UNSAFE_RAW' => 'filter/filter.stub', 'FILTER_VALIDATE_BOOL' => 'filter/filter.stub', 'FILTER_VALIDATE_BOOLEAN' => 'filter/filter.stub', 'FILTER_VALIDATE_DOMAIN' => 'filter/filter.stub', 'FILTER_VALIDATE_EMAIL' => 'filter/filter.stub', 'FILTER_VALIDATE_FLOAT' => 'filter/filter.stub', 'FILTER_VALIDATE_INT' => 'filter/filter.stub', 'FILTER_VALIDATE_IP' => 'filter/filter.stub', 'FILTER_VALIDATE_MAC' => 'filter/filter.stub', 'FILTER_VALIDATE_REGEXP' => 'filter/filter.stub', 'FILTER_VALIDATE_URL' => 'filter/filter.stub', 'FNM_CASEFOLD' => 'standard/standard_defines.stub', 'FNM_NOESCAPE' => 'standard/standard_defines.stub', 'FNM_PATHNAME' => 'standard/standard_defines.stub', 'FNM_PERIOD' => 'standard/standard_defines.stub', 'FORCE_DEFLATE' => 'zlib/zlib.stub', 'FORCE_GZIP' => 'zlib/zlib.stub', 'FPE_FLTDIV' => 'pcntl/pcntl.stub', 'FPE_FLTINV' => 'pcntl/pcntl.stub', 'FPE_FLTOVF' => 'pcntl/pcntl.stub', 'FPE_FLTRES' => 'pcntl/pcntl.stub', 'FPE_FLTSUB' => 'pcntl/pcntl.stub', 'FPE_FLTUND' => 'pcntl/pcntl.stub', 'FPE_INTDIV' => 'pcntl/pcntl.stub', 'FPE_INTOVF' => 'pcntl/pcntl.stub', 'FRAC_DIGITS' => 'standard/standard_defines.stub', 'FTA_BOLD' => 'winbinder/winbinder.stub', 'FTA_ITALIC' => 'winbinder/winbinder.stub', 'FTA_NORMAL' => 'winbinder/winbinder.stub', 'FTA_REGULAR' => 'winbinder/winbinder.stub', 'FTA_STRIKEOUT' => 'winbinder/winbinder.stub', 'FTA_UNDERLINE' => 'winbinder/winbinder.stub', 'FTP_ASCII' => 'ftp/ftp.stub', 'FTP_AUTORESUME' => 'ftp/ftp.stub', 'FTP_AUTOSEEK' => 'ftp/ftp.stub', 'FTP_BINARY' => 'ftp/ftp.stub', 'FTP_FAILED' => 'ftp/ftp.stub', 'FTP_FINISHED' => 'ftp/ftp.stub', 'FTP_IMAGE' => 'ftp/ftp.stub', 'FTP_MOREDATA' => 'ftp/ftp.stub', 'FTP_TEXT' => 'ftp/ftp.stub', 'FTP_TIMEOUT_SEC' => 'ftp/ftp.stub', 'FTP_USEPASVADDRESS' => 'ftp/ftp.stub', 'FT_INTERNAL' => 'imap/imap.stub', 'FT_NOT' => 'imap/imap.stub', 'FT_PEEK' => 'imap/imap.stub', 'FT_PREFETCHTEXT' => 'imap/imap.stub', 'FT_UID' => 'imap/imap.stub', 'F_DUPFD' => 'dio/dio_d.stub', 'F_GETFD' => 'dio/dio_d.stub', 'F_GETFL' => 'dio/dio_d.stub', 'F_GETLK' => 'dio/dio_d.stub', 'F_GETOWN' => 'dio/dio_d.stub', 'F_RDLCK' => 'dio/dio_d.stub', 'F_SETFL' => 'dio/dio_d.stub', 'F_SETLK' => 'dio/dio_d.stub', 'F_SETLKW' => 'dio/dio_d.stub', 'F_SETOWN' => 'dio/dio_d.stub', 'F_UNLCK' => 'dio/dio_d.stub', 'F_WRLCK' => 'dio/dio_d.stub', 'Frame' => 'winbinder/winbinder.stub', 'GD_BUNDLED' => 'gd/gd.stub', 'GD_EXTRA_VERSION' => 'gd/gd.stub', 'GD_MAJOR_VERSION' => 'gd/gd.stub', 'GD_MINOR_VERSION' => 'gd/gd.stub', 'GD_RELEASE_VERSION' => 'gd/gd.stub', 'GD_VERSION' => 'gd/gd.stub', 'GEARMAN_ARGS_BUFFER_SIZE' => 'gearman/gearman.stub', 'GEARMAN_CLIENT_ALLOCATED' => 'gearman/gearman.stub', 'GEARMAN_CLIENT_FREE_TASKS' => 'gearman/gearman.stub', 'GEARMAN_CLIENT_NON_BLOCKING' => 'gearman/gearman.stub', 'GEARMAN_CLIENT_NO_NEW' => 'gearman/gearman.stub', 'GEARMAN_CLIENT_STATE_IDLE' => 'gearman/gearman.stub', 'GEARMAN_CLIENT_STATE_NEW' => 'gearman/gearman.stub', 'GEARMAN_CLIENT_STATE_PACKET' => 'gearman/gearman.stub', 'GEARMAN_CLIENT_STATE_SUBMIT' => 'gearman/gearman.stub', 'GEARMAN_CLIENT_TASK_IN_USE' => 'gearman/gearman.stub', 'GEARMAN_CLIENT_UNBUFFERED_RESULT' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_ALL_YOURS' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_CANT_DO' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_CAN_DO' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_CAN_DO_TIMEOUT' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_ECHO_REQ' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_ECHO_RES' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_ERROR' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_GET_STATUS' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_GRAB_JOB' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_GRAB_JOB_UNIQ' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_JOB_ASSIGN' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_JOB_ASSIGN_UNIQ' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_JOB_CREATED' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_MAX' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_NOOP' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_NO_JOB' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_OPTION_REQ' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_OPTION_RES' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_PRE_SLEEP' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_RESET_ABILITIES' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_SET_CLIENT_ID' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_STATUS_RES' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_SUBMIT_JOB' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_SUBMIT_JOB_BG' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_SUBMIT_JOB_EPOCH' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_SUBMIT_JOB_HIGH' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_SUBMIT_JOB_HIGH_BG' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_SUBMIT_JOB_LOW' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_SUBMIT_JOB_LOW_BG' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_SUBMIT_JOB_SCHED' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_TEXT' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_UNUSED' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_WORK_COMPLETE' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_WORK_DATA' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_WORK_EXCEPTION' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_WORK_FAIL' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_WORK_STATUS' => 'gearman/gearman.stub', 'GEARMAN_COMMAND_WORK_WARNING' => 'gearman/gearman.stub', 'GEARMAN_CON_CLOSE_AFTER_FLUSH' => 'gearman/gearman.stub', 'GEARMAN_CON_EXTERNAL_FD' => 'gearman/gearman.stub', 'GEARMAN_CON_IGNORE_LOST_CONNECTION' => 'gearman/gearman.stub', 'GEARMAN_CON_PACKET_IN_USE' => 'gearman/gearman.stub', 'GEARMAN_CON_READY' => 'gearman/gearman.stub', 'GEARMAN_CON_RECV_STATE_READ_DATA' => 'gearman/gearman.stub', 'GEARMAN_CON_SEND_STATE_NONE' => 'gearman/gearman.stub', 'GEARMAN_COULD_NOT_CONNECT' => 'gearman/gearman.stub', 'GEARMAN_DATA_TOO_LARGE' => 'gearman/gearman.stub', 'GEARMAN_DEFAULT_SOCKET_RECV_SIZE' => 'gearman/gearman.stub', 'GEARMAN_DEFAULT_SOCKET_SEND_SIZE' => 'gearman/gearman.stub', 'GEARMAN_DEFAULT_SOCKET_TIMEOUT' => 'gearman/gearman.stub', 'GEARMAN_DEFAULT_TCP_HOST' => 'gearman/gearman.stub', 'GEARMAN_DEFAULT_TCP_PORT' => 'gearman/gearman.stub', 'GEARMAN_DONT_TRACK_PACKETS' => 'gearman/gearman.stub', 'GEARMAN_ECHO_DATA_CORRUPTION' => 'gearman/gearman.stub', 'GEARMAN_ERRNO' => 'gearman/gearman.stub', 'GEARMAN_EVENT' => 'gearman/gearman.stub', 'GEARMAN_FLUSH_DATA' => 'gearman/gearman.stub', 'GEARMAN_GETADDRINFO' => 'gearman/gearman.stub', 'GEARMAN_IGNORE_PACKET' => 'gearman/gearman.stub', 'GEARMAN_INVALID_COMMAND' => 'gearman/gearman.stub', 'GEARMAN_INVALID_FUNCTION_NAME' => 'gearman/gearman.stub', 'GEARMAN_INVALID_MAGIC' => 'gearman/gearman.stub', 'GEARMAN_INVALID_PACKET' => 'gearman/gearman.stub', 'GEARMAN_INVALID_WORKER_FUNCTION' => 'gearman/gearman.stub', 'GEARMAN_IO_WAIT' => 'gearman/gearman.stub', 'GEARMAN_JOB_EXISTS' => 'gearman/gearman.stub', 'GEARMAN_JOB_HANDLE_SIZE' => 'gearman/gearman.stub', 'GEARMAN_JOB_PRIORITY_HIGH' => 'gearman/gearman.stub', 'GEARMAN_JOB_PRIORITY_LOW' => 'gearman/gearman.stub', 'GEARMAN_JOB_PRIORITY_MAX' => 'gearman/gearman.stub', 'GEARMAN_JOB_PRIORITY_NORMAL' => 'gearman/gearman.stub', 'GEARMAN_JOB_QUEUE_FULL' => 'gearman/gearman.stub', 'GEARMAN_LOST_CONNECTION' => 'gearman/gearman.stub', 'GEARMAN_MAGIC_REQUEST' => 'gearman/gearman.stub', 'GEARMAN_MAGIC_RESPONSE' => 'gearman/gearman.stub', 'GEARMAN_MAGIC_TEXT' => 'gearman/gearman.stub', 'GEARMAN_MAX_COMMAND_ARGS' => 'gearman/gearman.stub', 'GEARMAN_MAX_ERROR_SIZE' => 'gearman/gearman.stub', 'GEARMAN_MAX_RETURN' => 'gearman/gearman.stub', 'GEARMAN_MEMORY_ALLOCATION_FAILURE' => 'gearman/gearman.stub', 'GEARMAN_NEED_WORKLOAD_FN' => 'gearman/gearman.stub', 'GEARMAN_NON_BLOCKING' => 'gearman/gearman.stub', 'GEARMAN_NOT_CONNECTED' => 'gearman/gearman.stub', 'GEARMAN_NOT_FLUSHING' => 'gearman/gearman.stub', 'GEARMAN_NO_ACTIVE_FDS' => 'gearman/gearman.stub', 'GEARMAN_NO_JOBS' => 'gearman/gearman.stub', 'GEARMAN_NO_REGISTERED_FUNCTIONS' => 'gearman/gearman.stub', 'GEARMAN_NO_SERVERS' => 'gearman/gearman.stub', 'GEARMAN_OPTION_SIZE' => 'gearman/gearman.stub', 'GEARMAN_PACKET_HEADER_SIZE' => 'gearman/gearman.stub', 'GEARMAN_PAUSE' => 'gearman/gearman.stub', 'GEARMAN_PIPE_EOF' => 'gearman/gearman.stub', 'GEARMAN_PTHREAD' => 'gearman/gearman.stub', 'GEARMAN_QUEUE_ERROR' => 'gearman/gearman.stub', 'GEARMAN_RECV_BUFFER_SIZE' => 'gearman/gearman.stub', 'GEARMAN_RECV_IN_PROGRESS' => 'gearman/gearman.stub', 'GEARMAN_SEND_BUFFER_SIZE' => 'gearman/gearman.stub', 'GEARMAN_SEND_BUFFER_TOO_SMALL' => 'gearman/gearman.stub', 'GEARMAN_SEND_IN_PROGRESS' => 'gearman/gearman.stub', 'GEARMAN_SERVER_ERROR' => 'gearman/gearman.stub', 'GEARMAN_SHUTDOWN' => 'gearman/gearman.stub', 'GEARMAN_SHUTDOWN_GRACEFUL' => 'gearman/gearman.stub', 'GEARMAN_SUCCESS' => 'gearman/gearman.stub', 'GEARMAN_TASK_STATE_COMPLETE' => 'gearman/gearman.stub', 'GEARMAN_TASK_STATE_CREATED' => 'gearman/gearman.stub', 'GEARMAN_TASK_STATE_DATA' => 'gearman/gearman.stub', 'GEARMAN_TASK_STATE_EXCEPTION' => 'gearman/gearman.stub', 'GEARMAN_TASK_STATE_FAIL' => 'gearman/gearman.stub', 'GEARMAN_TASK_STATE_FINISHED' => 'gearman/gearman.stub', 'GEARMAN_TASK_STATE_NEW' => 'gearman/gearman.stub', 'GEARMAN_TASK_STATE_STATUS' => 'gearman/gearman.stub', 'GEARMAN_TASK_STATE_SUBMIT' => 'gearman/gearman.stub', 'GEARMAN_TASK_STATE_WARNING' => 'gearman/gearman.stub', 'GEARMAN_TASK_STATE_WORK' => 'gearman/gearman.stub', 'GEARMAN_TASK_STATE_WORKLOAD' => 'gearman/gearman.stub', 'GEARMAN_TIMEOUT' => 'gearman/gearman.stub', 'GEARMAN_TOO_MANY_ARGS' => 'gearman/gearman.stub', 'GEARMAN_UNEXPECTED_PACKET' => 'gearman/gearman.stub', 'GEARMAN_UNIQUE_SIZE' => 'gearman/gearman.stub', 'GEARMAN_UNKNOWN_OPTION' => 'gearman/gearman.stub', 'GEARMAN_UNKNOWN_STATE' => 'gearman/gearman.stub', 'GEARMAN_VERBOSE_CRAZY' => 'gearman/gearman.stub', 'GEARMAN_VERBOSE_DEBUG' => 'gearman/gearman.stub', 'GEARMAN_VERBOSE_ERROR' => 'gearman/gearman.stub', 'GEARMAN_VERBOSE_FATAL' => 'gearman/gearman.stub', 'GEARMAN_VERBOSE_INFO' => 'gearman/gearman.stub', 'GEARMAN_VERBOSE_MAX' => 'gearman/gearman.stub', 'GEARMAN_VERBOSE_NEVER' => 'gearman/gearman.stub', 'GEARMAN_WORKER_ALLOCATED' => 'gearman/gearman.stub', 'GEARMAN_WORKER_CHANGE' => 'gearman/gearman.stub', 'GEARMAN_WORKER_GRAB_JOB_IN_USE' => 'gearman/gearman.stub', 'GEARMAN_WORKER_GRAB_UNIQ' => 'gearman/gearman.stub', 'GEARMAN_WORKER_NON_BLOCKING' => 'gearman/gearman.stub', 'GEARMAN_WORKER_PACKET_INIT' => 'gearman/gearman.stub', 'GEARMAN_WORKER_PRE_SLEEP_IN_USE' => 'gearman/gearman.stub', 'GEARMAN_WORKER_STATE_CONNECT' => 'gearman/gearman.stub', 'GEARMAN_WORKER_STATE_FUNCTION_SEND' => 'gearman/gearman.stub', 'GEARMAN_WORKER_STATE_GRAB_JOB_RECV' => 'gearman/gearman.stub', 'GEARMAN_WORKER_STATE_GRAB_JOB_SEND' => 'gearman/gearman.stub', 'GEARMAN_WORKER_STATE_PRE_SLEEP' => 'gearman/gearman.stub', 'GEARMAN_WORKER_STATE_START' => 'gearman/gearman.stub', 'GEARMAN_WORKER_TIMEOUT_RETURN' => 'gearman/gearman.stub', 'GEARMAN_WORKER_WAIT_TIMEOUT' => 'gearman/gearman.stub', 'GEARMAN_WORKER_WORK_JOB_IN_USE' => 'gearman/gearman.stub', 'GEARMAN_WORK_DATA' => 'gearman/gearman.stub', 'GEARMAN_WORK_ERROR' => 'gearman/gearman.stub', 'GEARMAN_WORK_EXCEPTION' => 'gearman/gearman.stub', 'GEARMAN_WORK_FAIL' => 'gearman/gearman.stub', 'GEARMAN_WORK_STATUS' => 'gearman/gearman.stub', 'GEARMAN_WORK_WARNING' => 'gearman/gearman.stub', 'GEOIP_ASNUM_EDITION' => 'geoip/geoip.stub', 'GEOIP_CABLEDSL_SPEED' => 'geoip/geoip.stub', 'GEOIP_CITY_EDITION_REV0' => 'geoip/geoip.stub', 'GEOIP_CITY_EDITION_REV1' => 'geoip/geoip.stub', 'GEOIP_CORPORATE_SPEED' => 'geoip/geoip.stub', 'GEOIP_COUNTRY_EDITION' => 'geoip/geoip.stub', 'GEOIP_DIALUP_SPEED' => 'geoip/geoip.stub', 'GEOIP_DOMAIN_EDITION' => 'geoip/geoip.stub', 'GEOIP_ISP_EDITION' => 'geoip/geoip.stub', 'GEOIP_NETSPEED_EDITION' => 'geoip/geoip.stub', 'GEOIP_ORG_EDITION' => 'geoip/geoip.stub', 'GEOIP_PROXY_EDITION' => 'geoip/geoip.stub', 'GEOIP_REGION_EDITION_REV0' => 'geoip/geoip.stub', 'GEOIP_REGION_EDITION_REV1' => 'geoip/geoip.stub', 'GEOIP_UNKNOWN_SPEED' => 'geoip/geoip.stub', 'GEOSBUF_CAP_FLAT' => 'geos/geos.stub', 'GEOSBUF_CAP_ROUND' => 'geos/geos.stub', 'GEOSBUF_CAP_SQUARE' => 'geos/geos.stub', 'GEOSBUF_JOIN_BEVEL' => 'geos/geos.stub', 'GEOSBUF_JOIN_MITRE' => 'geos/geos.stub', 'GEOSBUF_JOIN_ROUND' => 'geos/geos.stub', 'GEOSRELATE_BNR_ENDPOINT' => 'geos/geos.stub', 'GEOSRELATE_BNR_MOD2' => 'geos/geos.stub', 'GEOSRELATE_BNR_MONOVALENT_ENDPOINT' => 'geos/geos.stub', 'GEOSRELATE_BNR_MULTIVALENT_ENDPOINT' => 'geos/geos.stub', 'GEOSRELATE_BNR_OGC' => 'geos/geos.stub', 'GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE' => 'geos/geos.stub', 'GEOS_GEOMETRYCOLLECTION' => 'geos/geos.stub', 'GEOS_LINEARRING' => 'geos/geos.stub', 'GEOS_LINESTRING' => 'geos/geos.stub', 'GEOS_MULTILINESTRING' => 'geos/geos.stub', 'GEOS_MULTIPOINT' => 'geos/geos.stub', 'GEOS_MULTIPOLYGON' => 'geos/geos.stub', 'GEOS_POINT' => 'geos/geos.stub', 'GEOS_POLYGON' => 'geos/geos.stub', 'GLOB_AVAILABLE_FLAGS' => 'standard/standard_defines.stub', 'GLOB_BRACE' => 'standard/standard_defines.stub', 'GLOB_ERR' => 'standard/standard_defines.stub', 'GLOB_MARK' => 'standard/standard_defines.stub', 'GLOB_NOCHECK' => 'standard/standard_defines.stub', 'GLOB_NOESCAPE' => 'standard/standard_defines.stub', 'GLOB_NOSORT' => 'standard/standard_defines.stub', 'GLOB_ONLYDIR' => 'standard/standard_defines.stub', 'GMP_BIG_ENDIAN' => 'gmp/gmp.stub', 'GMP_LITTLE_ENDIAN' => 'gmp/gmp.stub', 'GMP_LSW_FIRST' => 'gmp/gmp.stub', 'GMP_MPIR_VERSION' => 'gmp/gmp.stub', 'GMP_MSW_FIRST' => 'gmp/gmp.stub', 'GMP_NATIVE_ENDIAN' => 'gmp/gmp.stub', 'GMP_ROUND_MINUSINF' => 'gmp/gmp.stub', 'GMP_ROUND_PLUSINF' => 'gmp/gmp.stub', 'GMP_ROUND_ZERO' => 'gmp/gmp.stub', 'GMP_VERSION' => 'gmp/gmp.stub', 'GNUPG_ERROR_EXCEPTION' => 'gnupg/gnupg.stub', 'GNUPG_ERROR_SILENT' => 'gnupg/gnupg.stub', 'GNUPG_ERROR_WARNING' => 'gnupg/gnupg.stub', 'GNUPG_GPGME_VERSION' => 'gnupg/gnupg.stub', 'GNUPG_PK_DSA' => 'gnupg/gnupg.stub', 'GNUPG_PK_ECC' => 'gnupg/gnupg.stub', 'GNUPG_PK_ECDH' => 'gnupg/gnupg.stub', 'GNUPG_PK_ECDSA' => 'gnupg/gnupg.stub', 'GNUPG_PK_EDDSA' => 'gnupg/gnupg.stub', 'GNUPG_PK_ELG' => 'gnupg/gnupg.stub', 'GNUPG_PK_ELG_E' => 'gnupg/gnupg.stub', 'GNUPG_PK_RSA' => 'gnupg/gnupg.stub', 'GNUPG_PK_RSA_E' => 'gnupg/gnupg.stub', 'GNUPG_PK_RSA_S' => 'gnupg/gnupg.stub', 'GNUPG_PROTOCOL_CMS' => 'gnupg/gnupg.stub', 'GNUPG_PROTOCOL_OpenPGP' => 'gnupg/gnupg.stub', 'GNUPG_SIGSUM_BAD_POLICY' => 'gnupg/gnupg.stub', 'GNUPG_SIGSUM_CRL_MISSING' => 'gnupg/gnupg.stub', 'GNUPG_SIGSUM_CRL_TOO_OLD' => 'gnupg/gnupg.stub', 'GNUPG_SIGSUM_GREEN' => 'gnupg/gnupg.stub', 'GNUPG_SIGSUM_KEY_EXPIRED' => 'gnupg/gnupg.stub', 'GNUPG_SIGSUM_KEY_MISSING' => 'gnupg/gnupg.stub', 'GNUPG_SIGSUM_KEY_REVOKED' => 'gnupg/gnupg.stub', 'GNUPG_SIGSUM_RED' => 'gnupg/gnupg.stub', 'GNUPG_SIGSUM_SIG_EXPIRED' => 'gnupg/gnupg.stub', 'GNUPG_SIGSUM_SYS_ERROR' => 'gnupg/gnupg.stub', 'GNUPG_SIGSUM_VALID' => 'gnupg/gnupg.stub', 'GNUPG_SIG_MODE_CLEAR' => 'gnupg/gnupg.stub', 'GNUPG_SIG_MODE_DETACH' => 'gnupg/gnupg.stub', 'GNUPG_SIG_MODE_NORMAL' => 'gnupg/gnupg.stub', 'GNUPG_VALIDITY_FULL' => 'gnupg/gnupg.stub', 'GNUPG_VALIDITY_MARGINAL' => 'gnupg/gnupg.stub', 'GNUPG_VALIDITY_NEVER' => 'gnupg/gnupg.stub', 'GNUPG_VALIDITY_ULTIMATE' => 'gnupg/gnupg.stub', 'GNUPG_VALIDITY_UNDEFINED' => 'gnupg/gnupg.stub', 'GNUPG_VALIDITY_UNKNOWN' => 'gnupg/gnupg.stub', 'GRAPHEME_EXTR_COUNT' => 'intl/intl.stub', 'GRAPHEME_EXTR_MAXBYTES' => 'intl/intl.stub', 'GRAPHEME_EXTR_MAXCHARS' => 'intl/intl.stub', 'GREEN' => 'winbinder/winbinder.stub', 'GROUPING' => 'standard/standard_defines.stub', 'Gauge' => 'winbinder/winbinder.stub', 'Grpc\\CALL_ERROR' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_ALREADY_ACCEPTED' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_ALREADY_FINISHED' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_ALREADY_INVOKED' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_BATCH_TOO_BIG' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_INVALID_FLAGS' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_INVALID_MESSAGE' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_INVALID_METADATA' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_NOT_INVOKED' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_NOT_ON_CLIENT' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_NOT_ON_SERVER' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_PAYLOAD_TYPE_MISMATCH' => 'grpc/grpc.stub', 'Grpc\\CALL_ERROR_TOO_MANY_OPERATIONS' => 'grpc/grpc.stub', 'Grpc\\CALL_OK' => 'grpc/grpc.stub', 'Grpc\\CHANNEL_CONNECTING' => 'grpc/grpc.stub', 'Grpc\\CHANNEL_FATAL_FAILURE' => 'grpc/grpc.stub', 'Grpc\\CHANNEL_IDLE' => 'grpc/grpc.stub', 'Grpc\\CHANNEL_READY' => 'grpc/grpc.stub', 'Grpc\\CHANNEL_SHUTDOWN' => 'grpc/grpc.stub', 'Grpc\\CHANNEL_TRANSIENT_FAILURE' => 'grpc/grpc.stub', 'Grpc\\OP_RECV_CLOSE_ON_SERVER' => 'grpc/grpc.stub', 'Grpc\\OP_RECV_INITIAL_METADATA' => 'grpc/grpc.stub', 'Grpc\\OP_RECV_MESSAGE' => 'grpc/grpc.stub', 'Grpc\\OP_RECV_STATUS_ON_CLIENT' => 'grpc/grpc.stub', 'Grpc\\OP_SEND_CLOSE_FROM_CLIENT' => 'grpc/grpc.stub', 'Grpc\\OP_SEND_INITIAL_METADATA' => 'grpc/grpc.stub', 'Grpc\\OP_SEND_MESSAGE' => 'grpc/grpc.stub', 'Grpc\\OP_SEND_STATUS_FROM_SERVER' => 'grpc/grpc.stub', 'Grpc\\STATUS_ABORTED' => 'grpc/grpc.stub', 'Grpc\\STATUS_ALREADY_EXISTS' => 'grpc/grpc.stub', 'Grpc\\STATUS_CANCELLED' => 'grpc/grpc.stub', 'Grpc\\STATUS_DATA_LOSS' => 'grpc/grpc.stub', 'Grpc\\STATUS_DEADLINE_EXCEEDED' => 'grpc/grpc.stub', 'Grpc\\STATUS_FAILED_PRECONDITION' => 'grpc/grpc.stub', 'Grpc\\STATUS_INTERNAL' => 'grpc/grpc.stub', 'Grpc\\STATUS_INVALID_ARGUMENT' => 'grpc/grpc.stub', 'Grpc\\STATUS_NOT_FOUND' => 'grpc/grpc.stub', 'Grpc\\STATUS_OK' => 'grpc/grpc.stub', 'Grpc\\STATUS_OUT_OF_RANGE' => 'grpc/grpc.stub', 'Grpc\\STATUS_PERMISSION_DENIED' => 'grpc/grpc.stub', 'Grpc\\STATUS_RESOURCE_EXHAUSTED' => 'grpc/grpc.stub', 'Grpc\\STATUS_UNAUTHENTICATED' => 'grpc/grpc.stub', 'Grpc\\STATUS_UNAVAILABLE' => 'grpc/grpc.stub', 'Grpc\\STATUS_UNIMPLEMENTED' => 'grpc/grpc.stub', 'Grpc\\STATUS_UNKNOWN' => 'grpc/grpc.stub', 'Grpc\\WRITE_BUFFER_HINT' => 'grpc/grpc.stub', 'Grpc\\WRITE_NO_COMPRESS' => 'grpc/grpc.stub', 'HASH_HMAC' => 'hash/hash.stub', 'HTMLControl' => 'winbinder/winbinder.stub', 'HTML_ENTITIES' => 'standard/standard_defines.stub', 'HTML_SPECIALCHARS' => 'standard/standard_defines.stub', 'HTTP_AUTH_ANY' => 'http/http.stub', 'HTTP_AUTH_BASIC' => 'http/http.stub', 'HTTP_AUTH_DIGEST' => 'http/http.stub', 'HTTP_AUTH_GSSNEG' => 'http/http.stub', 'HTTP_AUTH_NTLM' => 'http/http.stub', 'HTTP_COOKIE_HTTPONLY' => 'http/http.stub', 'HTTP_COOKIE_PARSE_RAW' => 'http/http.stub', 'HTTP_COOKIE_SECURE' => 'http/http.stub', 'HTTP_DEFLATE_LEVEL_DEF' => 'http/http.stub', 'HTTP_DEFLATE_LEVEL_MAX' => 'http/http.stub', 'HTTP_DEFLATE_LEVEL_MIN' => 'http/http.stub', 'HTTP_DEFLATE_STRATEGY_DEF' => 'http/http.stub', 'HTTP_DEFLATE_STRATEGY_FILT' => 'http/http.stub', 'HTTP_DEFLATE_STRATEGY_FIXED' => 'http/http.stub', 'HTTP_DEFLATE_STRATEGY_HUFF' => 'http/http.stub', 'HTTP_DEFLATE_STRATEGY_RLE' => 'http/http.stub', 'HTTP_DEFLATE_TYPE_GZIP' => 'http/http.stub', 'HTTP_DEFLATE_TYPE_RAW' => 'http/http.stub', 'HTTP_DEFLATE_TYPE_ZLIB' => 'http/http.stub', 'HTTP_ENCODING_STREAM_FLUSH_FULL' => 'http/http.stub', 'HTTP_ENCODING_STREAM_FLUSH_NONE' => 'http/http.stub', 'HTTP_ENCODING_STREAM_FLUSH_SYNC' => 'http/http.stub', 'HTTP_E_ENCODING' => 'http/http.stub', 'HTTP_E_HEADER' => 'http/http.stub', 'HTTP_E_INVALID_PARAM' => 'http/http.stub', 'HTTP_E_MALFORMED_HEADERS' => 'http/http.stub', 'HTTP_E_MESSAGE_TYPE' => 'http/http.stub', 'HTTP_E_QUERYSTRING' => 'http/http.stub', 'HTTP_E_REQUEST' => 'http/http.stub', 'HTTP_E_REQUEST_METHOD' => 'http/http.stub', 'HTTP_E_REQUEST_POOL' => 'http/http.stub', 'HTTP_E_RESPONSE' => 'http/http.stub', 'HTTP_E_RUNTIME' => 'http/http.stub', 'HTTP_E_SOCKET' => 'http/http.stub', 'HTTP_E_URL' => 'http/http.stub', 'HTTP_IPRESOLVE_ANY' => 'http/http.stub', 'HTTP_IPRESOLVE_V4' => 'http/http.stub', 'HTTP_IPRESOLVE_V6' => 'http/http.stub', 'HTTP_METH_ACL' => 'http/http.stub', 'HTTP_METH_BASELINE_CONTROL' => 'http/http.stub', 'HTTP_METH_CHECKIN' => 'http/http.stub', 'HTTP_METH_CHECKOUT' => 'http/http.stub', 'HTTP_METH_CONNECT' => 'http/http.stub', 'HTTP_METH_COPY' => 'http/http.stub', 'HTTP_METH_DELETE' => 'http/http.stub', 'HTTP_METH_GET' => 'http/http.stub', 'HTTP_METH_HEAD' => 'http/http.stub', 'HTTP_METH_LABEL' => 'http/http.stub', 'HTTP_METH_LOCK' => 'http/http.stub', 'HTTP_METH_MERGE' => 'http/http.stub', 'HTTP_METH_MKACTIVITY' => 'http/http.stub', 'HTTP_METH_MKCOL' => 'http/http.stub', 'HTTP_METH_MKWORKSPACE' => 'http/http.stub', 'HTTP_METH_MOVE' => 'http/http.stub', 'HTTP_METH_OPTIONS' => 'http/http.stub', 'HTTP_METH_POST' => 'http/http.stub', 'HTTP_METH_PROPFIND' => 'http/http.stub', 'HTTP_METH_PROPPATCH' => 'http/http.stub', 'HTTP_METH_PUT' => 'http/http.stub', 'HTTP_METH_REPORT' => 'http/http.stub', 'HTTP_METH_TRACE' => 'http/http.stub', 'HTTP_METH_UNCHECKOUT' => 'http/http.stub', 'HTTP_METH_UNLOCK' => 'http/http.stub', 'HTTP_METH_UPDATE' => 'http/http.stub', 'HTTP_METH_VERSION_CONTROL' => 'http/http.stub', 'HTTP_MSG_NONE' => 'http/http.stub', 'HTTP_MSG_REQUEST' => 'http/http.stub', 'HTTP_MSG_RESPONSE' => 'http/http.stub', 'HTTP_PARAMS_ALLOW_COMMA' => 'http/http.stub', 'HTTP_PARAMS_ALLOW_FAILURE' => 'http/http.stub', 'HTTP_PARAMS_DEFAULT' => 'http/http.stub', 'HTTP_PARAMS_RAISE_ERROR' => 'http/http.stub', 'HTTP_PROXY_HTTP' => 'http/http.stub', 'HTTP_PROXY_SOCKS4' => 'http/http.stub', 'HTTP_PROXY_SOCKS5' => 'http/http.stub', 'HTTP_QUERYSTRING_TYPE_ARRAY' => 'http/http.stub', 'HTTP_QUERYSTRING_TYPE_BOOL' => 'http/http.stub', 'HTTP_QUERYSTRING_TYPE_FLOAT' => 'http/http.stub', 'HTTP_QUERYSTRING_TYPE_INT' => 'http/http.stub', 'HTTP_QUERYSTRING_TYPE_OBJECT' => 'http/http.stub', 'HTTP_QUERYSTRING_TYPE_STRING' => 'http/http.stub', 'HTTP_REDIRECT' => 'http/http.stub', 'HTTP_REDIRECT_FOUND' => 'http/http.stub', 'HTTP_REDIRECT_PERM' => 'http/http.stub', 'HTTP_REDIRECT_POST' => 'http/http.stub', 'HTTP_REDIRECT_PROXY' => 'http/http.stub', 'HTTP_REDIRECT_TEMP' => 'http/http.stub', 'HTTP_SSL_VERSION_ANY' => 'http/http.stub', 'HTTP_SSL_VERSION_SSLv2' => 'http/http.stub', 'HTTP_SSL_VERSION_SSLv3' => 'http/http.stub', 'HTTP_SSL_VERSION_TLSv1' => 'http/http.stub', 'HTTP_SUPPORT' => 'http/http.stub', 'HTTP_SUPPORT_ENCODINGS' => 'http/http.stub', 'HTTP_SUPPORT_EVENTS' => 'http/http.stub', 'HTTP_SUPPORT_MAGICMIME' => 'http/http.stub', 'HTTP_SUPPORT_REQUESTS' => 'http/http.stub', 'HTTP_SUPPORT_SSLREQUESTS' => 'http/http.stub', 'HTTP_URL_FROM_ENV' => 'http/http.stub', 'HTTP_URL_JOIN_PATH' => 'http/http.stub', 'HTTP_URL_JOIN_QUERY' => 'http/http.stub', 'HTTP_URL_REPLACE' => 'http/http.stub', 'HTTP_URL_STRIP_ALL' => 'http/http.stub', 'HTTP_URL_STRIP_AUTH' => 'http/http.stub', 'HTTP_URL_STRIP_FRAGMENT' => 'http/http.stub', 'HTTP_URL_STRIP_PASS' => 'http/http.stub', 'HTTP_URL_STRIP_PATH' => 'http/http.stub', 'HTTP_URL_STRIP_PORT' => 'http/http.stub', 'HTTP_URL_STRIP_QUERY' => 'http/http.stub', 'HTTP_URL_STRIP_USER' => 'http/http.stub', 'HTTP_VERSION_1_0' => 'http/http.stub', 'HTTP_VERSION_1_1' => 'http/http.stub', 'HTTP_VERSION_ANY' => 'http/http.stub', 'HTTP_VERSION_NONE' => 'http/http.stub', 'HyperLink' => 'winbinder/winbinder.stub', 'IBASE_BKP_CONVERT' => 'interbase/interbase.stub', 'IBASE_BKP_IGNORE_CHECKSUMS' => 'interbase/interbase.stub', 'IBASE_BKP_IGNORE_LIMBO' => 'interbase/interbase.stub', 'IBASE_BKP_METADATA_ONLY' => 'interbase/interbase.stub', 'IBASE_BKP_NON_TRANSPORTABLE' => 'interbase/interbase.stub', 'IBASE_BKP_NO_GARBAGE_COLLECT' => 'interbase/interbase.stub', 'IBASE_BKP_OLD_DESCRIPTIONS' => 'interbase/interbase.stub', 'IBASE_COMMITTED' => 'interbase/interbase.stub', 'IBASE_CONCURRENCY' => 'interbase/interbase.stub', 'IBASE_CONSISTENCY' => 'interbase/interbase.stub', 'IBASE_CREATE' => 'interbase/interbase.stub', 'IBASE_DEFAULT' => 'interbase/interbase.stub', 'IBASE_FETCH_ARRAYS' => 'interbase/interbase.stub', 'IBASE_FETCH_BLOBS' => 'interbase/interbase.stub', 'IBASE_NOWAIT' => 'interbase/interbase.stub', 'IBASE_PRP_ACCESS_MODE' => 'interbase/interbase.stub', 'IBASE_PRP_ACTIVATE' => 'interbase/interbase.stub', 'IBASE_PRP_AM_READONLY' => 'interbase/interbase.stub', 'IBASE_PRP_AM_READWRITE' => 'interbase/interbase.stub', 'IBASE_PRP_DB_ONLINE' => 'interbase/interbase.stub', 'IBASE_PRP_DENY_NEW_ATTACHMENTS' => 'interbase/interbase.stub', 'IBASE_PRP_DENY_NEW_TRANSACTIONS' => 'interbase/interbase.stub', 'IBASE_PRP_PAGE_BUFFERS' => 'interbase/interbase.stub', 'IBASE_PRP_RES' => 'interbase/interbase.stub', 'IBASE_PRP_RESERVE_SPACE' => 'interbase/interbase.stub', 'IBASE_PRP_RES_USE_FULL' => 'interbase/interbase.stub', 'IBASE_PRP_SET_SQL_DIALECT' => 'interbase/interbase.stub', 'IBASE_PRP_SHUTDOWN_DB' => 'interbase/interbase.stub', 'IBASE_PRP_SWEEP_INTERVAL' => 'interbase/interbase.stub', 'IBASE_PRP_WM_ASYNC' => 'interbase/interbase.stub', 'IBASE_PRP_WM_SYNC' => 'interbase/interbase.stub', 'IBASE_PRP_WRITE_MODE' => 'interbase/interbase.stub', 'IBASE_READ' => 'interbase/interbase.stub', 'IBASE_REC_NO_VERSION' => 'interbase/interbase.stub', 'IBASE_REC_VERSION' => 'interbase/interbase.stub', 'IBASE_RES_CREATE' => 'interbase/interbase.stub', 'IBASE_RES_DEACTIVATE_IDX' => 'interbase/interbase.stub', 'IBASE_RES_NO_SHADOW' => 'interbase/interbase.stub', 'IBASE_RES_NO_VALIDITY' => 'interbase/interbase.stub', 'IBASE_RES_ONE_AT_A_TIME' => 'interbase/interbase.stub', 'IBASE_RES_REPLACE' => 'interbase/interbase.stub', 'IBASE_RES_USE_ALL_SPACE' => 'interbase/interbase.stub', 'IBASE_RPR_CHECK_DB' => 'interbase/interbase.stub', 'IBASE_RPR_FULL' => 'interbase/interbase.stub', 'IBASE_RPR_IGNORE_CHECKSUM' => 'interbase/interbase.stub', 'IBASE_RPR_KILL_SHADOWS' => 'interbase/interbase.stub', 'IBASE_RPR_MEND_DB' => 'interbase/interbase.stub', 'IBASE_RPR_SWEEP_DB' => 'interbase/interbase.stub', 'IBASE_RPR_VALIDATE_DB' => 'interbase/interbase.stub', 'IBASE_STS_DATA_PAGES' => 'interbase/interbase.stub', 'IBASE_STS_DB_LOG' => 'interbase/interbase.stub', 'IBASE_STS_HDR_PAGES' => 'interbase/interbase.stub', 'IBASE_STS_IDX_PAGES' => 'interbase/interbase.stub', 'IBASE_STS_SYS_RELATIONS' => 'interbase/interbase.stub', 'IBASE_SVC_GET_ENV' => 'interbase/interbase.stub', 'IBASE_SVC_GET_ENV_LOCK' => 'interbase/interbase.stub', 'IBASE_SVC_GET_ENV_MSG' => 'interbase/interbase.stub', 'IBASE_SVC_GET_USERS' => 'interbase/interbase.stub', 'IBASE_SVC_IMPLEMENTATION' => 'interbase/interbase.stub', 'IBASE_SVC_SERVER_VERSION' => 'interbase/interbase.stub', 'IBASE_SVC_SVR_DB_INFO' => 'interbase/interbase.stub', 'IBASE_SVC_USER_DBPATH' => 'interbase/interbase.stub', 'IBASE_TEXT' => 'interbase/interbase.stub', 'IBASE_UNIXTIME' => 'interbase/interbase.stub', 'IBASE_WAIT' => 'interbase/interbase.stub', 'IBASE_WRITE' => 'interbase/interbase.stub', 'ICONV_IMPL' => 'iconv/iconv.stub', 'ICONV_MIME_DECODE_CONTINUE_ON_ERROR' => 'iconv/iconv.stub', 'ICONV_MIME_DECODE_STRICT' => 'iconv/iconv.stub', 'ICONV_VERSION' => 'iconv/iconv.stub', 'IDABORT' => 'winbinder/winbinder.stub', 'IDCANCEL' => 'winbinder/winbinder.stub', 'IDCLOSE' => 'winbinder/winbinder.stub', 'IDDEFAULT' => 'winbinder/winbinder.stub', 'IDHELP' => 'winbinder/winbinder.stub', 'IDIGNORE' => 'winbinder/winbinder.stub', 'IDNA_ALLOW_UNASSIGNED' => 'intl/intl.stub', 'IDNA_CHECK_BIDI' => 'intl/intl.stub', 'IDNA_CHECK_CONTEXTJ' => 'intl/intl.stub', 'IDNA_DEFAULT' => 'intl/intl.stub', 'IDNA_ERROR_BIDI' => 'intl/intl.stub', 'IDNA_ERROR_CONTEXTJ' => 'intl/intl.stub', 'IDNA_ERROR_DISALLOWED' => 'intl/intl.stub', 'IDNA_ERROR_DOMAIN_NAME_TOO_LONG' => 'intl/intl.stub', 'IDNA_ERROR_EMPTY_LABEL' => 'intl/intl.stub', 'IDNA_ERROR_HYPHEN_3_4' => 'intl/intl.stub', 'IDNA_ERROR_INVALID_ACE_LABEL' => 'intl/intl.stub', 'IDNA_ERROR_LABEL_HAS_DOT' => 'intl/intl.stub', 'IDNA_ERROR_LABEL_TOO_LONG' => 'intl/intl.stub', 'IDNA_ERROR_LEADING_COMBINING_MARK' => 'intl/intl.stub', 'IDNA_ERROR_LEADING_HYPHEN' => 'intl/intl.stub', 'IDNA_ERROR_PUNYCODE' => 'intl/intl.stub', 'IDNA_ERROR_TRAILING_HYPHEN' => 'intl/intl.stub', 'IDNA_NONTRANSITIONAL_TO_ASCII' => 'intl/intl.stub', 'IDNA_NONTRANSITIONAL_TO_UNICODE' => 'intl/intl.stub', 'IDNA_USE_STD3_RULES' => 'intl/intl.stub', 'IDNO' => 'winbinder/winbinder.stub', 'IDOK' => 'winbinder/winbinder.stub', 'IDRETRY' => 'winbinder/winbinder.stub', 'IDYES' => 'winbinder/winbinder.stub', 'ILL_BADSTK' => 'pcntl/pcntl.stub', 'ILL_COPROC' => 'pcntl/pcntl.stub', 'ILL_ILLADR' => 'pcntl/pcntl.stub', 'ILL_ILLOPC' => 'pcntl/pcntl.stub', 'ILL_ILLOPN' => 'pcntl/pcntl.stub', 'ILL_ILLTRP' => 'pcntl/pcntl.stub', 'ILL_PRVOPC' => 'pcntl/pcntl.stub', 'ILL_PRVREG' => 'pcntl/pcntl.stub', 'IMAGETYPE_AVIF' => 'standard/standard_defines.stub', 'IMAGETYPE_BMP' => 'standard/standard_defines.stub', 'IMAGETYPE_COUNT' => 'standard/standard_defines.stub', 'IMAGETYPE_GIF' => 'standard/standard_defines.stub', 'IMAGETYPE_ICO' => 'standard/standard_defines.stub', 'IMAGETYPE_IFF' => 'standard/standard_defines.stub', 'IMAGETYPE_JB2' => 'standard/standard_defines.stub', 'IMAGETYPE_JP2' => 'standard/standard_defines.stub', 'IMAGETYPE_JPC' => 'standard/standard_defines.stub', 'IMAGETYPE_JPEG' => 'standard/standard_defines.stub', 'IMAGETYPE_JPEG2000' => 'standard/standard_defines.stub', 'IMAGETYPE_JPX' => 'standard/standard_defines.stub', 'IMAGETYPE_PNG' => 'standard/standard_defines.stub', 'IMAGETYPE_PSD' => 'standard/standard_defines.stub', 'IMAGETYPE_SWC' => 'standard/standard_defines.stub', 'IMAGETYPE_SWF' => 'standard/standard_defines.stub', 'IMAGETYPE_TIFF_II' => 'standard/standard_defines.stub', 'IMAGETYPE_TIFF_MM' => 'standard/standard_defines.stub', 'IMAGETYPE_UNKNOWN' => 'standard/standard_defines.stub', 'IMAGETYPE_WBMP' => 'standard/standard_defines.stub', 'IMAGETYPE_WEBP' => 'standard/standard_defines.stub', 'IMAGETYPE_XBM' => 'standard/standard_defines.stub', 'IMAP_CLOSETIMEOUT' => 'imap/imap.stub', 'IMAP_GC_ELT' => 'imap/imap.stub', 'IMAP_GC_ENV' => 'imap/imap.stub', 'IMAP_GC_TEXTS' => 'imap/imap.stub', 'IMAP_OPENTIMEOUT' => 'imap/imap.stub', 'IMAP_READTIMEOUT' => 'imap/imap.stub', 'IMAP_WRITETIMEOUT' => 'imap/imap.stub', 'IMG_AFFINE_ROTATE' => 'gd/gd.stub', 'IMG_AFFINE_SCALE' => 'gd/gd.stub', 'IMG_AFFINE_SHEAR_HORIZONTAL' => 'gd/gd.stub', 'IMG_AFFINE_SHEAR_VERTICAL' => 'gd/gd.stub', 'IMG_AFFINE_TRANSLATE' => 'gd/gd.stub', 'IMG_ARC_CHORD' => 'gd/gd.stub', 'IMG_ARC_EDGED' => 'gd/gd.stub', 'IMG_ARC_NOFILL' => 'gd/gd.stub', 'IMG_ARC_PIE' => 'gd/gd.stub', 'IMG_ARC_ROUNDED' => 'gd/gd.stub', 'IMG_AVIF' => 'gd/gd.stub', 'IMG_BELL' => 'gd/gd.stub', 'IMG_BESSEL' => 'gd/gd.stub', 'IMG_BICUBIC' => 'gd/gd.stub', 'IMG_BICUBIC_FIXED' => 'gd/gd.stub', 'IMG_BILINEAR_FIXED' => 'gd/gd.stub', 'IMG_BLACKMAN' => 'gd/gd.stub', 'IMG_BMP' => 'gd/gd.stub', 'IMG_BOX' => 'gd/gd.stub', 'IMG_BSPLINE' => 'gd/gd.stub', 'IMG_CATMULLROM' => 'gd/gd.stub', 'IMG_COLOR_BRUSHED' => 'gd/gd.stub', 'IMG_COLOR_STYLED' => 'gd/gd.stub', 'IMG_COLOR_STYLEDBRUSHED' => 'gd/gd.stub', 'IMG_COLOR_TILED' => 'gd/gd.stub', 'IMG_COLOR_TRANSPARENT' => 'gd/gd.stub', 'IMG_CROP_BLACK' => 'gd/gd.stub', 'IMG_CROP_DEFAULT' => 'gd/gd.stub', 'IMG_CROP_SIDES' => 'gd/gd.stub', 'IMG_CROP_THRESHOLD' => 'gd/gd.stub', 'IMG_CROP_TRANSPARENT' => 'gd/gd.stub', 'IMG_CROP_WHITE' => 'gd/gd.stub', 'IMG_EFFECT_ALPHABLEND' => 'gd/gd.stub', 'IMG_EFFECT_MULTIPLY' => 'gd/gd.stub', 'IMG_EFFECT_NORMAL' => 'gd/gd.stub', 'IMG_EFFECT_OVERLAY' => 'gd/gd.stub', 'IMG_EFFECT_REPLACE' => 'gd/gd.stub', 'IMG_FILTER_BRIGHTNESS' => 'gd/gd.stub', 'IMG_FILTER_COLORIZE' => 'gd/gd.stub', 'IMG_FILTER_CONTRAST' => 'gd/gd.stub', 'IMG_FILTER_EDGEDETECT' => 'gd/gd.stub', 'IMG_FILTER_EMBOSS' => 'gd/gd.stub', 'IMG_FILTER_GAUSSIAN_BLUR' => 'gd/gd.stub', 'IMG_FILTER_GRAYSCALE' => 'gd/gd.stub', 'IMG_FILTER_MEAN_REMOVAL' => 'gd/gd.stub', 'IMG_FILTER_NEGATE' => 'gd/gd.stub', 'IMG_FILTER_PIXELATE' => 'gd/gd.stub', 'IMG_FILTER_SCATTER' => 'gd/gd.stub', 'IMG_FILTER_SELECTIVE_BLUR' => 'gd/gd.stub', 'IMG_FILTER_SMOOTH' => 'gd/gd.stub', 'IMG_FLIP_BOTH' => 'gd/gd.stub', 'IMG_FLIP_HORIZONTAL' => 'gd/gd.stub', 'IMG_FLIP_VERTICAL' => 'gd/gd.stub', 'IMG_GAUSSIAN' => 'gd/gd.stub', 'IMG_GD2_COMPRESSED' => 'gd/gd.stub', 'IMG_GD2_RAW' => 'gd/gd.stub', 'IMG_GENERALIZED_CUBIC' => 'gd/gd.stub', 'IMG_GIF' => 'gd/gd.stub', 'IMG_HAMMING' => 'gd/gd.stub', 'IMG_HANNING' => 'gd/gd.stub', 'IMG_HERMITE' => 'gd/gd.stub', 'IMG_JPEG' => 'gd/gd.stub', 'IMG_JPG' => 'gd/gd.stub', 'IMG_MITCHELL' => 'gd/gd.stub', 'IMG_NEAREST_NEIGHBOUR' => 'gd/gd.stub', 'IMG_PNG' => 'gd/gd.stub', 'IMG_POWER' => 'gd/gd.stub', 'IMG_QUADRATIC' => 'gd/gd.stub', 'IMG_SINC' => 'gd/gd.stub', 'IMG_TGA' => 'gd/gd.stub', 'IMG_TRIANGLE' => 'gd/gd.stub', 'IMG_WBMP' => 'gd/gd.stub', 'IMG_WEBP' => 'gd/gd.stub', 'IMG_WEBP_LOSSLESS' => 'gd/gd.stub', 'IMG_WEIGHTED4' => 'gd/gd.stub', 'IMG_XPM' => 'gd/gd.stub', 'INF' => 'standard/standard_defines.stub', 'INFO_ALL' => 'standard/standard_defines.stub', 'INFO_CONFIGURATION' => 'standard/standard_defines.stub', 'INFO_CREDITS' => 'standard/standard_defines.stub', 'INFO_ENVIRONMENT' => 'standard/standard_defines.stub', 'INFO_GENERAL' => 'standard/standard_defines.stub', 'INFO_LICENSE' => 'standard/standard_defines.stub', 'INFO_MODULES' => 'standard/standard_defines.stub', 'INFO_VARIABLES' => 'standard/standard_defines.stub', 'INI_ALL' => 'standard/standard_defines.stub', 'INI_PERDIR' => 'standard/standard_defines.stub', 'INI_SCANNER_NORMAL' => 'standard/standard_defines.stub', 'INI_SCANNER_RAW' => 'standard/standard_defines.stub', 'INI_SCANNER_TYPED' => 'standard/standard_defines.stub', 'INI_SYSTEM' => 'standard/standard_defines.stub', 'INI_USER' => 'standard/standard_defines.stub', 'INPUT_COOKIE' => 'filter/filter.stub', 'INPUT_ENV' => 'filter/filter.stub', 'INPUT_GET' => 'filter/filter.stub', 'INPUT_POST' => 'filter/filter.stub', 'INPUT_REQUEST' => 'filter/filter.stub', 'INPUT_SERVER' => 'filter/filter.stub', 'INPUT_SESSION' => 'filter/filter.stub', 'INTL_ICU_DATA_VERSION' => 'intl/intl.stub', 'INTL_ICU_VERSION' => 'intl/intl.stub', 'INTL_IDNA_VARIANT_2003' => 'intl/intl.stub', 'INTL_IDNA_VARIANT_UTS46' => 'intl/intl.stub', 'INTL_MAX_LOCALE_LEN' => 'intl/intl.stub', 'INT_CURR_SYMBOL' => 'standard/standard_defines.stub', 'INT_FRAC_DIGITS' => 'standard/standard_defines.stub', 'IN_ACCESS' => 'inotify/inotify.stub', 'IN_ALL_EVENTS' => 'inotify/inotify.stub', 'IN_ATTRIB' => 'inotify/inotify.stub', 'IN_CLOSE' => 'inotify/inotify.stub', 'IN_CLOSE_NOWRITE' => 'inotify/inotify.stub', 'IN_CLOSE_WRITE' => 'inotify/inotify.stub', 'IN_CREATE' => 'inotify/inotify.stub', 'IN_DELETE' => 'inotify/inotify.stub', 'IN_DELETE_SELF' => 'inotify/inotify.stub', 'IN_DONT_FOLLOW' => 'inotify/inotify.stub', 'IN_IGNORED' => 'inotify/inotify.stub', 'IN_ISDIR' => 'inotify/inotify.stub', 'IN_MASK_ADD' => 'inotify/inotify.stub', 'IN_MODIFY' => 'inotify/inotify.stub', 'IN_MOVE' => 'inotify/inotify.stub', 'IN_MOVED_FROM' => 'inotify/inotify.stub', 'IN_MOVED_TO' => 'inotify/inotify.stub', 'IN_MOVE_SELF' => 'inotify/inotify.stub', 'IN_ONESHOT' => 'inotify/inotify.stub', 'IN_ONLYDIR' => 'inotify/inotify.stub', 'IN_OPEN' => 'inotify/inotify.stub', 'IN_Q_OVERFLOW' => 'inotify/inotify.stub', 'IN_UNMOUNT' => 'inotify/inotify.stub', 'IPPROTO_IP' => 'sockets/sockets.stub', 'IPPROTO_IPV6' => 'sockets/sockets.stub', 'IPV6_HOPLIMIT' => 'sockets/sockets.stub', 'IPV6_MULTICAST_HOPS' => 'sockets/sockets.stub', 'IPV6_MULTICAST_IF' => 'sockets/sockets.stub', 'IPV6_MULTICAST_LOOP' => 'sockets/sockets.stub', 'IPV6_PKTINFO' => 'sockets/sockets.stub', 'IPV6_RECVHOPLIMIT' => 'sockets/sockets.stub', 'IPV6_RECVPKTINFO' => 'sockets/sockets.stub', 'IPV6_RECVTCLASS' => 'sockets/sockets.stub', 'IPV6_TCLASS' => 'sockets/sockets.stub', 'IPV6_UNICAST_HOPS' => 'sockets/sockets.stub', 'IPV6_V6ONLY' => 'sockets/sockets.stub', 'IP_BIND_ADDRESS_NO_PORT' => 'sockets/sockets.stub', 'IP_MTU_DISCOVER' => 'sockets/sockets.stub', 'IP_MULTICAST_IF' => 'sockets/sockets.stub', 'IP_MULTICAST_LOOP' => 'sockets/sockets.stub', 'IP_MULTICAST_TTL' => 'sockets/sockets.stub', 'IP_PMTUDISC_DO' => 'sockets/sockets.stub', 'IP_PMTUDISC_DONT' => 'sockets/sockets.stub', 'IP_PMTUDISC_INTERFACE' => 'sockets/sockets.stub', 'IP_PMTUDISC_OMIT' => 'sockets/sockets.stub', 'IP_PMTUDISC_PROBE' => 'sockets/sockets.stub', 'IP_PMTUDISC_WANT' => 'sockets/sockets.stub', 'ImageButton' => 'winbinder/winbinder.stub', 'InvisibleArea' => 'winbinder/winbinder.stub', 'JOB_QUEUE_PRIORITY_HIGH' => 'zend/zend_d.stub', 'JOB_QUEUE_PRIORITY_LOW' => 'zend/zend_d.stub', 'JOB_QUEUE_PRIORITY_NORMAL' => 'zend/zend_d.stub', 'JOB_QUEUE_PRIORITY_URGENT' => 'zend/zend_d.stub', 'JOB_QUEUE_SAVE_COOKIE' => 'zend/zend_d.stub', 'JOB_QUEUE_SAVE_ENV' => 'zend/zend_d.stub', 'JOB_QUEUE_SAVE_FILES' => 'zend/zend_d.stub', 'JOB_QUEUE_SAVE_GET' => 'zend/zend_d.stub', 'JOB_QUEUE_SAVE_POST' => 'zend/zend_d.stub', 'JOB_QUEUE_SAVE_RAW_POST' => 'zend/zend_d.stub', 'JOB_QUEUE_SAVE_SERVER' => 'zend/zend_d.stub', 'JOB_QUEUE_SAVE_SESSION' => 'zend/zend_d.stub', 'JOB_QUEUE_STATUS_EXECUTION_FAILED' => 'zend/zend_d.stub', 'JOB_QUEUE_STATUS_IN_PROCESS' => 'zend/zend_d.stub', 'JOB_QUEUE_STATUS_LOGICALLY_FAILED' => 'zend/zend_d.stub', 'JOB_QUEUE_STATUS_SCHEDULED' => 'zend/zend_d.stub', 'JOB_QUEUE_STATUS_SUCCESS' => 'zend/zend_d.stub', 'JOB_QUEUE_STATUS_SUSPENDED' => 'zend/zend_d.stub', 'JOB_QUEUE_STATUS_WAITING' => 'zend/zend_d.stub', 'JOB_QUEUE_STATUS_WAITING_PREDECESSOR' => 'zend/zend_d.stub', 'JSON_BIGINT_AS_STRING' => 'json/json.stub', 'JSON_ERROR_CTRL_CHAR' => 'json/json.stub', 'JSON_ERROR_DEPTH' => 'json/json.stub', 'JSON_ERROR_INF_OR_NAN' => 'json/json.stub', 'JSON_ERROR_INVALID_PROPERTY_NAME' => 'json/json.stub', 'JSON_ERROR_NONE' => 'json/json.stub', 'JSON_ERROR_NON_BACKED_ENUM' => 'json/json.stub', 'JSON_ERROR_RECURSION' => 'json/json.stub', 'JSON_ERROR_STATE_MISMATCH' => 'json/json.stub', 'JSON_ERROR_SYNTAX' => 'json/json.stub', 'JSON_ERROR_UNSUPPORTED_TYPE' => 'json/json.stub', 'JSON_ERROR_UTF16' => 'json/json.stub', 'JSON_ERROR_UTF8' => 'json/json.stub', 'JSON_FORCE_OBJECT' => 'json/json.stub', 'JSON_HEX_AMP' => 'json/json.stub', 'JSON_HEX_APOS' => 'json/json.stub', 'JSON_HEX_QUOT' => 'json/json.stub', 'JSON_HEX_TAG' => 'json/json.stub', 'JSON_INVALID_UTF8_IGNORE' => 'json/json.stub', 'JSON_INVALID_UTF8_SUBSTITUTE' => 'json/json.stub', 'JSON_NUMERIC_CHECK' => 'json/json.stub', 'JSON_OBJECT_AS_ARRAY' => 'json/json.stub', 'JSON_PARSER_NOTSTRICT' => 'json/json.stub', 'JSON_PARTIAL_OUTPUT_ON_ERROR' => 'json/json.stub', 'JSON_PRESERVE_ZERO_FRACTION' => 'json/json.stub', 'JSON_PRETTY_PRINT' => 'json/json.stub', 'JSON_THROW_ON_ERROR' => 'json/json.stub', 'JSON_UNESCAPED_LINE_TERMINATORS' => 'json/json.stub', 'JSON_UNESCAPED_SLASHES' => 'json/json.stub', 'JSON_UNESCAPED_UNICODE' => 'json/json.stub', 'LATT_HASCHILDREN' => 'imap/imap.stub', 'LATT_HASNOCHILDREN' => 'imap/imap.stub', 'LATT_MARKED' => 'imap/imap.stub', 'LATT_NOINFERIORS' => 'imap/imap.stub', 'LATT_NOSELECT' => 'imap/imap.stub', 'LATT_REFERRAL' => 'imap/imap.stub', 'LATT_UNMARKED' => 'imap/imap.stub', 'LC_ALL' => 'standard/standard_defines.stub', 'LC_COLLATE' => 'standard/standard_defines.stub', 'LC_CTYPE' => 'standard/standard_defines.stub', 'LC_MESSAGES' => 'standard/standard_defines.stub', 'LC_MONETARY' => 'standard/standard_defines.stub', 'LC_NUMERIC' => 'standard/standard_defines.stub', 'LC_TIME' => 'standard/standard_defines.stub', 'LDAP_CONTROL_ASSERT' => 'ldap/ldap.stub', 'LDAP_CONTROL_AUTHZID_REQUEST' => 'ldap/ldap.stub', 'LDAP_CONTROL_AUTHZID_RESPONSE' => 'ldap/ldap.stub', 'LDAP_CONTROL_DONTUSECOPY' => 'ldap/ldap.stub', 'LDAP_CONTROL_MANAGEDSAIT' => 'ldap/ldap.stub', 'LDAP_CONTROL_PAGEDRESULTS' => 'ldap/ldap.stub', 'LDAP_CONTROL_PASSWORDPOLICYREQUEST' => 'ldap/ldap.stub', 'LDAP_CONTROL_PASSWORDPOLICYRESPONSE' => 'ldap/ldap.stub', 'LDAP_CONTROL_POST_READ' => 'ldap/ldap.stub', 'LDAP_CONTROL_PRE_READ' => 'ldap/ldap.stub', 'LDAP_CONTROL_PROXY_AUTHZ' => 'ldap/ldap.stub', 'LDAP_CONTROL_SORTREQUEST' => 'ldap/ldap.stub', 'LDAP_CONTROL_SORTRESPONSE' => 'ldap/ldap.stub', 'LDAP_CONTROL_SUBENTRIES' => 'ldap/ldap.stub', 'LDAP_CONTROL_SYNC' => 'ldap/ldap.stub', 'LDAP_CONTROL_SYNC_DONE' => 'ldap/ldap.stub', 'LDAP_CONTROL_SYNC_STATE' => 'ldap/ldap.stub', 'LDAP_CONTROL_VALUESRETURNFILTER' => 'ldap/ldap.stub', 'LDAP_CONTROL_VLVREQUEST' => 'ldap/ldap.stub', 'LDAP_CONTROL_VLVRESPONSE' => 'ldap/ldap.stub', 'LDAP_CONTROL_X_DOMAIN_SCOPE' => 'ldap/ldap.stub', 'LDAP_CONTROL_X_EXTENDED_DN' => 'ldap/ldap.stub', 'LDAP_CONTROL_X_INCREMENTAL_VALUES' => 'ldap/ldap.stub', 'LDAP_CONTROL_X_PERMISSIVE_MODIFY' => 'ldap/ldap.stub', 'LDAP_CONTROL_X_SEARCH_OPTIONS' => 'ldap/ldap.stub', 'LDAP_CONTROL_X_TREE_DELETE' => 'ldap/ldap.stub', 'LDAP_DEREF_ALWAYS' => 'ldap/ldap.stub', 'LDAP_DEREF_FINDING' => 'ldap/ldap.stub', 'LDAP_DEREF_NEVER' => 'ldap/ldap.stub', 'LDAP_DEREF_SEARCHING' => 'ldap/ldap.stub', 'LDAP_ESCAPE_DN' => 'ldap/ldap.stub', 'LDAP_ESCAPE_FILTER' => 'ldap/ldap.stub', 'LDAP_EXOP_MODIFY_PASSWD' => 'ldap/ldap.stub', 'LDAP_EXOP_REFRESH' => 'ldap/ldap.stub', 'LDAP_EXOP_START_TLS' => 'ldap/ldap.stub', 'LDAP_EXOP_TURN' => 'ldap/ldap.stub', 'LDAP_EXOP_WHO_AM_I' => 'ldap/ldap.stub', 'LDAP_MODIFY_BATCH_ADD' => 'ldap/ldap.stub', 'LDAP_MODIFY_BATCH_ATTRIB' => 'ldap/ldap.stub', 'LDAP_MODIFY_BATCH_MODTYPE' => 'ldap/ldap.stub', 'LDAP_MODIFY_BATCH_REMOVE' => 'ldap/ldap.stub', 'LDAP_MODIFY_BATCH_REMOVE_ALL' => 'ldap/ldap.stub', 'LDAP_MODIFY_BATCH_REPLACE' => 'ldap/ldap.stub', 'LDAP_MODIFY_BATCH_VALUES' => 'ldap/ldap.stub', 'LDAP_OPT_CLIENT_CONTROLS' => 'ldap/ldap.stub', 'LDAP_OPT_DEBUG_LEVEL' => 'ldap/ldap.stub', 'LDAP_OPT_DEREF' => 'ldap/ldap.stub', 'LDAP_OPT_DIAGNOSTIC_MESSAGE' => 'ldap/ldap.stub', 'LDAP_OPT_ERROR_NUMBER' => 'ldap/ldap.stub', 'LDAP_OPT_ERROR_STRING' => 'ldap/ldap.stub', 'LDAP_OPT_HOST_NAME' => 'ldap/ldap.stub', 'LDAP_OPT_MATCHED_DN' => 'ldap/ldap.stub', 'LDAP_OPT_NETWORK_TIMEOUT' => 'ldap/ldap.stub', 'LDAP_OPT_PROTOCOL_VERSION' => 'ldap/ldap.stub', 'LDAP_OPT_REFERRALS' => 'ldap/ldap.stub', 'LDAP_OPT_RESTART' => 'ldap/ldap.stub', 'LDAP_OPT_SERVER_CONTROLS' => 'ldap/ldap.stub', 'LDAP_OPT_SIZELIMIT' => 'ldap/ldap.stub', 'LDAP_OPT_TIMELIMIT' => 'ldap/ldap.stub', 'LDAP_OPT_TIMEOUT' => 'ldap/ldap.stub', 'LDAP_OPT_X_KEEPALIVE_IDLE' => 'ldap/ldap.stub', 'LDAP_OPT_X_KEEPALIVE_INTERVAL' => 'ldap/ldap.stub', 'LDAP_OPT_X_KEEPALIVE_PROBES' => 'ldap/ldap.stub', 'LDAP_OPT_X_SASL_AUTHCID' => 'ldap/ldap.stub', 'LDAP_OPT_X_SASL_AUTHZID' => 'ldap/ldap.stub', 'LDAP_OPT_X_SASL_MECH' => 'ldap/ldap.stub', 'LDAP_OPT_X_SASL_NOCANON' => 'ldap/ldap.stub', 'LDAP_OPT_X_SASL_REALM' => 'ldap/ldap.stub', 'LDAP_OPT_X_SASL_USERNAME' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_ALLOW' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_CACERTDIR' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_CACERTFILE' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_CERTFILE' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_CIPHER_SUITE' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_CRLCHECK' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_CRLFILE' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_CRL_ALL' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_CRL_NONE' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_CRL_PEER' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_DEMAND' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_DHFILE' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_HARD' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_KEYFILE' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_NEVER' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_PACKAGE' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_PROTOCOL_MAX' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_PROTOCOL_MIN' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_PROTOCOL_SSL2' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_PROTOCOL_SSL3' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_PROTOCOL_TLS1_0' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_PROTOCOL_TLS1_1' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_PROTOCOL_TLS1_2' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_PROTOCOL_TLS1_3' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_RANDOM_FILE' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_REQUIRE_CERT' => 'ldap/ldap.stub', 'LDAP_OPT_X_TLS_TRY' => 'ldap/ldap.stub', 'LEVELDB_NO_COMPRESSION' => 'leveldb/LevelDB.stub', 'LEVELDB_SNAPPY_COMPRESSION' => 'leveldb/LevelDB.stub', 'LIBEXSLT_DOTTED_VERSION' => 'xsl/xsl.stub', 'LIBEXSLT_VERSION' => 'xsl/xsl.stub', 'LIBXML_BIGLINES' => 'libxml/libxml.stub', 'LIBXML_COMPACT' => 'libxml/libxml.stub', 'LIBXML_DOTTED_VERSION' => 'libxml/libxml.stub', 'LIBXML_DTDATTR' => 'libxml/libxml.stub', 'LIBXML_DTDLOAD' => 'libxml/libxml.stub', 'LIBXML_DTDVALID' => 'libxml/libxml.stub', 'LIBXML_ERR_ERROR' => 'libxml/libxml.stub', 'LIBXML_ERR_FATAL' => 'libxml/libxml.stub', 'LIBXML_ERR_NONE' => 'libxml/libxml.stub', 'LIBXML_ERR_WARNING' => 'libxml/libxml.stub', 'LIBXML_HTML_NODEFDTD' => 'libxml/libxml.stub', 'LIBXML_HTML_NOIMPLIED' => 'libxml/libxml.stub', 'LIBXML_LOADED_VERSION' => 'libxml/libxml.stub', 'LIBXML_NOBLANKS' => 'libxml/libxml.stub', 'LIBXML_NOCDATA' => 'libxml/libxml.stub', 'LIBXML_NOEMPTYTAG' => 'libxml/libxml.stub', 'LIBXML_NOENT' => 'libxml/libxml.stub', 'LIBXML_NOERROR' => 'libxml/libxml.stub', 'LIBXML_NONET' => 'libxml/libxml.stub', 'LIBXML_NOWARNING' => 'libxml/libxml.stub', 'LIBXML_NOXMLDECL' => 'libxml/libxml.stub', 'LIBXML_NSCLEAN' => 'libxml/libxml.stub', 'LIBXML_PARSEHUGE' => 'libxml/libxml.stub', 'LIBXML_PEDANTIC' => 'libxml/libxml.stub', 'LIBXML_RECOVER' => 'libxml/libxml.stub', 'LIBXML_SCHEMA_CREATE' => 'libxml/libxml.stub', 'LIBXML_VERSION' => 'libxml/libxml.stub', 'LIBXML_XINCLUDE' => 'libxml/libxml.stub', 'LIBXSLT_DOTTED_VERSION' => 'xsl/xsl.stub', 'LIBXSLT_VERSION' => 'xsl/xsl.stub', 'LIBZSTD_VERSION_NUMBER' => 'zstd/zstd.stub', 'LIBZSTD_VERSION_STRING' => 'zstd/zstd.stub', 'LIGHTGRAY' => 'winbinder/winbinder.stub', 'LOCK_EX' => 'standard/standard_defines.stub', 'LOCK_NB' => 'standard/standard_defines.stub', 'LOCK_SH' => 'standard/standard_defines.stub', 'LOCK_UN' => 'standard/standard_defines.stub', 'LOG_ALERT' => 'standard/standard_defines.stub', 'LOG_AUTH' => 'standard/standard_defines.stub', 'LOG_AUTHPRIV' => 'standard/standard_defines.stub', 'LOG_CONS' => 'standard/standard_defines.stub', 'LOG_CRIT' => 'standard/standard_defines.stub', 'LOG_CRON' => 'standard/standard_defines.stub', 'LOG_DAEMON' => 'standard/standard_defines.stub', 'LOG_DEBUG' => 'standard/standard_defines.stub', 'LOG_EMERG' => 'standard/standard_defines.stub', 'LOG_ERR' => 'standard/standard_defines.stub', 'LOG_INFO' => 'standard/standard_defines.stub', 'LOG_KERN' => 'standard/standard_defines.stub', 'LOG_LOCAL0' => 'standard/standard_defines.stub', 'LOG_LOCAL1' => 'standard/standard_defines.stub', 'LOG_LOCAL2' => 'standard/standard_defines.stub', 'LOG_LOCAL3' => 'standard/standard_defines.stub', 'LOG_LOCAL4' => 'standard/standard_defines.stub', 'LOG_LOCAL5' => 'standard/standard_defines.stub', 'LOG_LOCAL6' => 'standard/standard_defines.stub', 'LOG_LOCAL7' => 'standard/standard_defines.stub', 'LOG_LPR' => 'standard/standard_defines.stub', 'LOG_MAIL' => 'standard/standard_defines.stub', 'LOG_NDELAY' => 'standard/standard_defines.stub', 'LOG_NEWS' => 'standard/standard_defines.stub', 'LOG_NOTICE' => 'standard/standard_defines.stub', 'LOG_NOWAIT' => 'standard/standard_defines.stub', 'LOG_ODELAY' => 'standard/standard_defines.stub', 'LOG_PERROR' => 'standard/standard_defines.stub', 'LOG_PID' => 'standard/standard_defines.stub', 'LOG_SYSLOG' => 'standard/standard_defines.stub', 'LOG_USER' => 'standard/standard_defines.stub', 'LOG_UUCP' => 'standard/standard_defines.stub', 'LOG_WARNING' => 'standard/standard_defines.stub', 'Label' => 'winbinder/winbinder.stub', 'ListBox' => 'winbinder/winbinder.stub', 'ListView' => 'winbinder/winbinder.stub', 'MAGENTA' => 'winbinder/winbinder.stub', 'MAILPARSE_EXTRACT_OUTPUT' => 'mailparse/mailparse.stub', 'MAILPARSE_EXTRACT_RETURN' => 'mailparse/mailparse.stub', 'MAILPARSE_EXTRACT_STREAM' => 'mailparse/mailparse.stub', 'MB_CASE_FOLD' => 'mbstring/mbstring.stub', 'MB_CASE_FOLD_SIMPLE' => 'mbstring/mbstring.stub', 'MB_CASE_LOWER' => 'mbstring/mbstring.stub', 'MB_CASE_LOWER_SIMPLE' => 'mbstring/mbstring.stub', 'MB_CASE_TITLE' => 'mbstring/mbstring.stub', 'MB_CASE_TITLE_SIMPLE' => 'mbstring/mbstring.stub', 'MB_CASE_UPPER' => 'mbstring/mbstring.stub', 'MB_CASE_UPPER_SIMPLE' => 'mbstring/mbstring.stub', 'MB_ONIGURUMA_VERSION' => 'mbstring/mbstring.stub', 'MB_OVERLOAD_MAIL' => 'mbstring/mbstring.stub', 'MB_OVERLOAD_REGEX' => 'mbstring/mbstring.stub', 'MB_OVERLOAD_STRING' => 'mbstring/mbstring.stub', 'MCAST_BLOCK_SOURCE' => 'sockets/sockets.stub', 'MCAST_JOIN_GROUP' => 'sockets/sockets.stub', 'MCAST_JOIN_SOURCE_GROUP' => 'sockets/sockets.stub', 'MCAST_LEAVE_GROUP' => 'sockets/sockets.stub', 'MCAST_LEAVE_SOURCE_GROUP' => 'sockets/sockets.stub', 'MCAST_UNBLOCK_SOURCE' => 'sockets/sockets.stub', 'MCRYPT_3DES' => 'mcrypt/mcrypt.stub', 'MCRYPT_ARCFOUR' => 'mcrypt/mcrypt.stub', 'MCRYPT_ARCFOUR_IV' => 'mcrypt/mcrypt.stub', 'MCRYPT_BLOWFISH' => 'mcrypt/mcrypt.stub', 'MCRYPT_BLOWFISH_COMPAT' => 'mcrypt/mcrypt.stub', 'MCRYPT_CAST_128' => 'mcrypt/mcrypt.stub', 'MCRYPT_CAST_256' => 'mcrypt/mcrypt.stub', 'MCRYPT_CRYPT' => 'mcrypt/mcrypt.stub', 'MCRYPT_DECRYPT' => 'mcrypt/mcrypt.stub', 'MCRYPT_DES' => 'mcrypt/mcrypt.stub', 'MCRYPT_DES_COMPAT' => 'mcrypt/mcrypt.stub', 'MCRYPT_DEV_RANDOM' => 'mcrypt/mcrypt.stub', 'MCRYPT_DEV_URANDOM' => 'mcrypt/mcrypt.stub', 'MCRYPT_ENCRYPT' => 'mcrypt/mcrypt.stub', 'MCRYPT_ENIGNA' => 'mcrypt/mcrypt.stub', 'MCRYPT_GOST' => 'mcrypt/mcrypt.stub', 'MCRYPT_IDEA' => 'mcrypt/mcrypt.stub', 'MCRYPT_LOKI97' => 'mcrypt/mcrypt.stub', 'MCRYPT_MARS' => 'mcrypt/mcrypt.stub', 'MCRYPT_MODE_CBC' => 'mcrypt/mcrypt.stub', 'MCRYPT_MODE_CFB' => 'mcrypt/mcrypt.stub', 'MCRYPT_MODE_ECB' => 'mcrypt/mcrypt.stub', 'MCRYPT_MODE_NOFB' => 'mcrypt/mcrypt.stub', 'MCRYPT_MODE_OFB' => 'mcrypt/mcrypt.stub', 'MCRYPT_MODE_STREAM' => 'mcrypt/mcrypt.stub', 'MCRYPT_PANAMA' => 'mcrypt/mcrypt.stub', 'MCRYPT_RAND' => 'mcrypt/mcrypt.stub', 'MCRYPT_RC2' => 'mcrypt/mcrypt.stub', 'MCRYPT_RC4' => 'mcrypt/mcrypt.stub', 'MCRYPT_RC6' => 'mcrypt/mcrypt.stub', 'MCRYPT_RC6_128' => 'mcrypt/mcrypt.stub', 'MCRYPT_RC6_192' => 'mcrypt/mcrypt.stub', 'MCRYPT_RC6_256' => 'mcrypt/mcrypt.stub', 'MCRYPT_RIJNDAEL_128' => 'mcrypt/mcrypt.stub', 'MCRYPT_RIJNDAEL_192' => 'mcrypt/mcrypt.stub', 'MCRYPT_RIJNDAEL_256' => 'mcrypt/mcrypt.stub', 'MCRYPT_SAFER128' => 'mcrypt/mcrypt.stub', 'MCRYPT_SAFER64' => 'mcrypt/mcrypt.stub', 'MCRYPT_SAFERPLUS' => 'mcrypt/mcrypt.stub', 'MCRYPT_SERPENT' => 'mcrypt/mcrypt.stub', 'MCRYPT_SERPENT_128' => 'mcrypt/mcrypt.stub', 'MCRYPT_SERPENT_192' => 'mcrypt/mcrypt.stub', 'MCRYPT_SERPENT_256' => 'mcrypt/mcrypt.stub', 'MCRYPT_SKIPJACK' => 'mcrypt/mcrypt.stub', 'MCRYPT_THREEWAY' => 'mcrypt/mcrypt.stub', 'MCRYPT_TRIPLEDES' => 'mcrypt/mcrypt.stub', 'MCRYPT_TWOFISH' => 'mcrypt/mcrypt.stub', 'MCRYPT_WAKE' => 'mcrypt/mcrypt.stub', 'MCRYPT_XTEA' => 'mcrypt/mcrypt.stub', 'MEMCACHE_COMPRESSED' => 'memcache/memcache.stub', 'MEMCACHE_HAVE_SESSION' => 'memcache/memcache.stub', 'MEMCACHE_USER1' => 'memcache/memcache.stub', 'MEMCACHE_USER2' => 'memcache/memcache.stub', 'MEMCACHE_USER3' => 'memcache/memcache.stub', 'MEMCACHE_USER4' => 'memcache/memcache.stub', 'MESSAGEPACK_OPT_PHPONLY' => 'msgpack/msgpack.stub', 'MHASH_ADLER32' => 'hash/hash.stub', 'MHASH_CRC32' => 'hash/hash.stub', 'MHASH_CRC32B' => 'hash/hash.stub', 'MHASH_CRC32C' => 'hash/hash.stub', 'MHASH_FNV132' => 'hash/hash.stub', 'MHASH_FNV164' => 'hash/hash.stub', 'MHASH_FNV1A32' => 'hash/hash.stub', 'MHASH_FNV1A64' => 'hash/hash.stub', 'MHASH_GOST' => 'hash/hash.stub', 'MHASH_HAVAL128' => 'hash/hash.stub', 'MHASH_HAVAL160' => 'hash/hash.stub', 'MHASH_HAVAL192' => 'hash/hash.stub', 'MHASH_HAVAL224' => 'hash/hash.stub', 'MHASH_HAVAL256' => 'hash/hash.stub', 'MHASH_JOAAT' => 'hash/hash.stub', 'MHASH_MD2' => 'hash/hash.stub', 'MHASH_MD4' => 'hash/hash.stub', 'MHASH_MD5' => 'hash/hash.stub', 'MHASH_MURMUR3A' => 'hash/hash.stub', 'MHASH_MURMUR3C' => 'hash/hash.stub', 'MHASH_MURMUR3F' => 'hash/hash.stub', 'MHASH_RIPEMD128' => 'hash/hash.stub', 'MHASH_RIPEMD160' => 'hash/hash.stub', 'MHASH_RIPEMD256' => 'hash/hash.stub', 'MHASH_RIPEMD320' => 'hash/hash.stub', 'MHASH_SHA1' => 'hash/hash.stub', 'MHASH_SHA224' => 'hash/hash.stub', 'MHASH_SHA256' => 'hash/hash.stub', 'MHASH_SHA384' => 'hash/hash.stub', 'MHASH_SHA512' => 'hash/hash.stub', 'MHASH_SNEFRU256' => 'hash/hash.stub', 'MHASH_TIGER' => 'hash/hash.stub', 'MHASH_TIGER128' => 'hash/hash.stub', 'MHASH_TIGER160' => 'hash/hash.stub', 'MHASH_WHIRLPOOL' => 'hash/hash.stub', 'MHASH_XXH128' => 'hash/hash.stub', 'MHASH_XXH3' => 'hash/hash.stub', 'MHASH_XXH32' => 'hash/hash.stub', 'MHASH_XXH64' => 'hash/hash.stub', 'MING_NEW' => 'ming/ming.stub', 'MING_ZLIB' => 'ming/ming.stub', 'MK_E_UNAVAILABLE' => 'com_dotnet/com_dotnet.stub', 'MONGODB_STABILITY' => 'mongodb/mongodb.stub', 'MONGODB_VERSION' => 'mongodb/mongodb.stub', 'MON_1' => 'standard/standard_defines.stub', 'MON_10' => 'standard/standard_defines.stub', 'MON_11' => 'standard/standard_defines.stub', 'MON_12' => 'standard/standard_defines.stub', 'MON_2' => 'standard/standard_defines.stub', 'MON_3' => 'standard/standard_defines.stub', 'MON_4' => 'standard/standard_defines.stub', 'MON_5' => 'standard/standard_defines.stub', 'MON_6' => 'standard/standard_defines.stub', 'MON_7' => 'standard/standard_defines.stub', 'MON_8' => 'standard/standard_defines.stub', 'MON_9' => 'standard/standard_defines.stub', 'MON_DECIMAL_POINT' => 'standard/standard_defines.stub', 'MON_GROUPING' => 'standard/standard_defines.stub', 'MON_THOUSANDS_SEP' => 'standard/standard_defines.stub', 'MQSERIES_MQACT_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_AIX' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_BATCH' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_BROKER' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_CHANNEL_INITIATOR' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_CICS' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_CICS_BRIDGE' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_CICS_VSE' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_DEFAULT' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_DOS' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_DQM' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_GUARDIAN' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_IMS' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_IMS_BRIDGE' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_JAVA' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_MCAST_PUBLISH' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_MVS' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_NOTES_AGENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_NO_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_NSK' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_OPEN_TP1' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_OS2' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_OS390' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_OS400' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_QMGR' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_QMGR_PUBLISH' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_RRS_BATCH' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_SIB' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_SYSTEM_EXTENSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_TPF' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_UNIX' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_UNKNOWN' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_USER' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_USER_FIRST' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_USER_LAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_VM' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_VMS' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_VOS' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_WINDOWS' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_WINDOWS_NT' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_WLM' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_XCF' => 'mqseries/mqseries.stub', 'MQSERIES_MQAT_ZOS' => 'mqseries/mqseries.stub', 'MQSERIES_MQBO_CURRENT_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQBO_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQBO_VERSION_1' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_ADMIN_TOPIC_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_ALTERATION_DATE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_ALTERATION_TIME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_APPL_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_AUTH_INFO_CONN_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_AUTH_INFO_DESC' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_AUTH_INFO_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_AUTH_INFO_OCSP_URL' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_AUTO_REORG_CATALOG' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_AUTO_REORG_START_TIME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_BACKOUT_REQ_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_BASE_OBJECT_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_BASE_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_BATCH_INTERFACE_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CF_STRUC_DESC' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CF_STRUC_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CHANNEL_AUTO_DEF_EXIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CHILD' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CHINIT_SERVICE_PARM' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CHLAUTH_DESC' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CICS_FILE_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CLUSTER_DATE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CLUSTER_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CLUSTER_NAMELIST' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CLUSTER_Q_MGR_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CLUSTER_TIME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CLUSTER_WORKLOAD_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CLUSTER_WORKLOAD_EXIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CLUS_CHL_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_COMMAND_INPUT_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_COMMAND_REPLY_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_COMM_INFO_DESC' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_COMM_INFO_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CREATION_DATE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CREATION_TIME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_CUSTOM' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_DEAD_LETTER_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_DEF_XMIT_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_DNS_GROUP' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_ENV_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_FIRST' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_IGQ_USER_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_INITIATION_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_INSTALLATION_DESC' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_INSTALLATION_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_INSTALLATION_PATH' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_LAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_LAST_USED' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_LDAP_PASSWORD' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_LDAP_USER_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_LU62_ARM_SUFFIX' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_LU_GROUP_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_LU_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_MODEL_DURABLE_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_MODEL_NON_DURABLE_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_MONITOR_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_NAMELIST_DESC' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_NAMELIST_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_NAMES' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_PARENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_PASS_TICKET_APPL' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_POLICY_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_PROCESS_DESC' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_PROCESS_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_QSG_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_Q_DESC' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_Q_MGR_DESC' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_Q_MGR_IDENTIFIER' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_Q_MGR_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_RECIPIENT_DN' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_REMOTE_Q_MGR_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_REMOTE_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_REPOSITORY_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_REPOSITORY_NAMELIST' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_RESUME_DATE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_RESUME_TIME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SERVICE_DESC' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SERVICE_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SERVICE_START_ARGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SERVICE_START_COMMAND' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SERVICE_STOP_ARGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SERVICE_STOP_COMMAND' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SIGNER_DN' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SSL_CRL_NAMELIST' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SSL_CRYPTO_HARDWARE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SSL_KEY_LIBRARY' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SSL_KEY_MEMBER' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SSL_KEY_REPOSITORY' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_STDERR_DESTINATION' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_STDOUT_DESTINATION' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_STORAGE_CLASS' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_STORAGE_CLASS_DESC' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_SYSTEM_LOG_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_TCP_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_TOPIC_DESC' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_TOPIC_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_TOPIC_STRING' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_TOPIC_STRING_FILTER' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_TPIPE_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_TRIGGER_CHANNEL_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_TRIGGER_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_TRIGGER_PROGRAM_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_TRIGGER_TERM_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_TRIGGER_TRANS_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_USER_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_USER_LIST' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_XCF_GROUP_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_XCF_MEMBER_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_XMIT_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_XR_SSL_CIPHER_SUITES' => 'mqseries/mqseries.stub', 'MQSERIES_MQCA_XR_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQCCSI_APPL' => 'mqseries/mqseries.stub', 'MQSERIES_MQCCSI_AS_PUBLISHED' => 'mqseries/mqseries.stub', 'MQSERIES_MQCCSI_DEFAULT' => 'mqseries/mqseries.stub', 'MQSERIES_MQCCSI_EMBEDDED' => 'mqseries/mqseries.stub', 'MQSERIES_MQCCSI_INHERIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQCCSI_Q_MGR' => 'mqseries/mqseries.stub', 'MQSERIES_MQCCSI_UNDEFINED' => 'mqseries/mqseries.stub', 'MQSERIES_MQCC_FAILED' => 'mqseries/mqseries.stub', 'MQSERIES_MQCC_OK' => 'mqseries/mqseries.stub', 'MQSERIES_MQCC_UNKNOWN' => 'mqseries/mqseries.stub', 'MQSERIES_MQCC_WARNING' => 'mqseries/mqseries.stub', 'MQSERIES_MQCI_NEW_SESSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQCI_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_ACCOUNTING_MQI_DISABLED' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_ACCOUNTING_MQI_ENABLED' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_ACCOUNTING_Q_DISABLED' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_ACCOUNTING_Q_ENABLED' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_ACTIVITY_TRACE_DISABLED' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_ACTIVITY_TRACE_ENABLED' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_ALL_CONVS_SHARE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_CD_FOR_OUTPUT_ONLY' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_CLIENT_BINDING' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_CURRENT_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_FASTPATH_BINDING' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_HANDLE_SHARE_BLOCK' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_HANDLE_SHARE_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_HANDLE_SHARE_NO_BLOCK' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_ISOLATED_BINDING' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_LOCAL_BINDING' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_NO_CONV_SHARING' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_RECONNECT' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_RECONNECT_AS_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_RECONNECT_DISABLED' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_RECONNECT_Q_MGR' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_RESTRICT_CONN_TAG_QSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_RESTRICT_CONN_TAG_Q_MGR' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_SERIALIZE_CONN_TAG_QSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_SERIALIZE_CONN_TAG_Q_MGR' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_SHARED_BINDING' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_STANDARD_BINDING' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_USE_CD_SELECTION' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_VERSION_1' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_VERSION_2' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_VERSION_3' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_VERSION_4' => 'mqseries/mqseries.stub', 'MQSERIES_MQCNO_VERSION_5' => 'mqseries/mqseries.stub', 'MQSERIES_MQCO_DELETE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCO_DELETE_PURGE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCO_IMMEDIATE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCO_KEEP_SUB' => 'mqseries/mqseries.stub', 'MQSERIES_MQCO_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCO_QUIESCE' => 'mqseries/mqseries.stub', 'MQSERIES_MQCO_REMOVE_SUB' => 'mqseries/mqseries.stub', 'MQSERIES_MQEC_CONNECTION_QUIESCING' => 'mqseries/mqseries.stub', 'MQSERIES_MQEC_MSG_ARRIVED' => 'mqseries/mqseries.stub', 'MQSERIES_MQEC_Q_MGR_QUIESCING' => 'mqseries/mqseries.stub', 'MQSERIES_MQEC_WAIT_CANCELED' => 'mqseries/mqseries.stub', 'MQSERIES_MQEC_WAIT_INTERVAL_EXPIRED' => 'mqseries/mqseries.stub', 'MQSERIES_MQEI_UNLIMITED' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_AS_PUBLISHED' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_DECIMAL_MASK' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_DECIMAL_NORMAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_DECIMAL_REVERSED' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_DECIMAL_UNDEFINED' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_FLOAT_IEEE_NORMAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_FLOAT_IEEE_REVERSED' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_FLOAT_MASK' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_FLOAT_S390' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_FLOAT_TNS' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_FLOAT_UNDEFINED' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_INTEGER_MASK' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_INTEGER_NORMAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_INTEGER_REVERSED' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_INTEGER_UNDEFINED' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_NATIVE' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_NORMAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_RESERVED_MASK' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_REVERSED' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_S390' => 'mqseries/mqseries.stub', 'MQSERIES_MQENC_TNS' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_ACTIVITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_APPL_CANNOT_BE_STARTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_APPL_FIRST' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_APPL_LAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_APPL_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_BIND_OPEN_CLUSRCVR_DEL' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_BUFFER_OVERFLOW' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CHANNEL_COMPLETED' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CHANNEL_FAIL' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CHANNEL_FAIL_RETRY' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_APPL_ABENDED' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_APPL_NOT_STARTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_BRIDGE_FAILURE' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_CCSID_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_CIH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_COMMAREA_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_CORREL_ID_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_DLQ_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_ENCODING_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_INTERNAL_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_NOT_AUTHORIZED' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_UOW_BACKED_OUT' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_CICS_UOW_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_COA' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_COD' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_DATA_LENGTH_NEGATIVE' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_DATA_LENGTH_TOO_BIG' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_DATA_LENGTH_ZERO' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_EXPIRATION' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_IIH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_IMS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_IMS_FIRST' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_IMS_LAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_IMS_NACK_1A_REASON_FIRST' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_IMS_NACK_1A_REASON_LAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_LENGTH_OFF_BY_ONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_MAX_ACTIVITIES' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_MSG_SCOPE_MISMATCH' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_NAN' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_NOT_AUTHORIZED_FOR_IMS' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_NOT_A_GROUPUR_MSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_NOT_A_REPOSITORY_MSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_NOT_DELIVERED' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_NOT_FORWARDED' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_PAN' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_PUBLICATIONS_ON_REQUEST' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_QUIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_SELECTOR_MISMATCH' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_STOPPED_BY_CHAD_EXIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_STOPPED_BY_MSG_EXIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_STOPPED_BY_PUBSUB_EXIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_SUBSCRIBER_IS_PUBLISHER' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_SYSTEM_FIRST' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_SYSTEM_LAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_TM_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_UNSUPPORTED_DELIVERY' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_UNSUPPORTED_FORWARDING' => 'mqseries/mqseries.stub', 'MQSERIES_MQFB_XMIT_Q_MSG_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_ADMIN' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_CHANNEL_COMPLETED' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_CICS' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_COMMAND_1' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_COMMAND_2' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_DEAD_LETTER_HEADER' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_DIST_HEADER' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_EMBEDDED_PCF' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_IMS' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_IMS_VAR_STRING' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_MD_EXTENSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_PCF' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_REF_MSG_HEADER' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_RF_HEADER' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_RF_HEADER_1' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_RF_HEADER_2' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_STRING' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_TRIGGER' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_WORK_INFO_HEADER' => 'mqseries/mqseries.stub', 'MQSERIES_MQFMT_XMIT_Q_HEADER' => 'mqseries/mqseries.stub', 'MQSERIES_MQGI_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_ACCEPT_TRUNCATED_MSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_ALL_MSGS_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_ALL_SEGMENTS_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_BROWSE_CO_OP' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_BROWSE_FIRST' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_BROWSE_HANDLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_BROWSE_MSG_UNDER_CURSOR' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_BROWSE_NEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_COMPLETE_MSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_CONVERT' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_CURRENT_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_FAIL_IF_QUIESCING' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_LOCK' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_LOGICAL_ORDER' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_MARK_BROWSE_CO_OP' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_MARK_BROWSE_HANDLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_MARK_SKIP_BACKOUT' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_MSG_UNDER_CURSOR' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_NO_PROPERTIES' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_NO_SYNCPOINT' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_NO_WAIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_PROPERTIES_AS_Q_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_PROPERTIES_COMPATIBILITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_PROPERTIES_FORCE_MQRFH2' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_PROPERTIES_IN_HANDLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_SET_SIGNAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_SYNCPOINT' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_SYNCPOINT_IF_PERSISTENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_UNLOCK' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_UNMARKED_BROWSE_MSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_UNMARK_BROWSE_CO_OP' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_UNMARK_BROWSE_HANDLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_VERSION_1' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_VERSION_2' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_VERSION_3' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_VERSION_4' => 'mqseries/mqseries.stub', 'MQSERIES_MQGMO_WAIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ACCOUNTING_CONN_OVERRIDE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ACCOUNTING_INTERVAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ACCOUNTING_MQI' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ACCOUNTING_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ACTIVE_CHANNELS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ACTIVITY_CONN_OVERRIDE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ACTIVITY_RECORDING' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ACTIVITY_TRACE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ADOPTNEWMCA_CHECK' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ADOPTNEWMCA_INTERVAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ADOPTNEWMCA_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_APPL_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ARCHIVE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_AUTHORITY_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_AUTH_INFO_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_AUTO_REORGANIZATION' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_AUTO_REORG_INTERVAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_BACKOUT_THRESHOLD' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_BASE_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_BATCH_INTERFACE_AUTO' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_BRIDGE_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CERT_VAL_POLICY' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CF_CFCONLOS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CF_LEVEL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CF_OFFLDUSE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CF_OFFLOAD' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CF_OFFLOAD_THRESHOLD1' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CF_OFFLOAD_THRESHOLD2' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CF_OFFLOAD_THRESHOLD3' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CF_RECAUTO' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CF_RECOVER' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CF_SMDS_BUFFERS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CHANNEL_AUTO_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CHANNEL_AUTO_DEF_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CHANNEL_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CHINIT_ADAPTERS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CHINIT_CONTROL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CHINIT_DISPATCHERS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CHINIT_TRACE_AUTO_START' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CHINIT_TRACE_TABLE_SIZE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CHLAUTH_RECORDS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CLUSTER_Q_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CLUSTER_WORKLOAD_LENGTH' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CLWL_MRU_CHANNELS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CLWL_Q_PRIORITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CLWL_Q_RANK' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CLWL_USEQ' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CMD_SERVER_AUTO' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CMD_SERVER_CONTROL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CMD_SERVER_CONVERT_MSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CMD_SERVER_DLQ_MSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CODED_CHAR_SET_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_COMMAND_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_COMMAND_LEVEL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_COMM_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_COMM_INFO_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CONFIGURATION_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CPI_LEVEL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_CURRENT_Q_DEPTH' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_DEFINITION_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_DEF_BIND' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_DEF_CLUSTER_XMIT_Q_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_DEF_INPUT_OPEN_OPTION' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_DEF_PERSISTENCE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_DEF_PRIORITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_DEF_PUT_RESPONSE_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_DEF_READ_AHEAD' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_DIST_LISTS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_DNS_WLM' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_DURABLE_SUB' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_ENCRYPTION_ALGORITHM' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_EXPIRY_INTERVAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_FIRST' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_GROUP_UR' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_HARDEN_GET_BACKOUT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_HIGH_Q_DEPTH' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_IGQ_PUT_AUTHORITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_INDEX_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_INHIBIT_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_INHIBIT_GET' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_INHIBIT_PUB' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_INHIBIT_PUT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_INHIBIT_SUB' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_INTRA_GROUP_QUEUING' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_IP_ADDRESS_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_LAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_LISTENER_PORT_NUMBER' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_LISTENER_TIMER' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_LOCAL_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_LOGGER_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_LU62_CHANNELS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MASTER_ADMIN' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_CHANNELS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_CLIENTS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_GLOBAL_LOCKS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_HANDLES' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_LOCAL_LOCKS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_MSG_LENGTH' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_OPEN_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_PRIORITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_PROPERTIES_LENGTH' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_Q_DEPTH' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_Q_TRIGGERS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_RECOVERY_TASKS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_RESPONSES' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MAX_UNCOMMITTED_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MCAST_BRIDGE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MONITORING_AUTO_CLUSSDR' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MONITORING_CHANNEL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MONITORING_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MONITOR_INTERVAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MSG_DELIVERY_SEQUENCE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MSG_DEQ_COUNT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MSG_ENQ_COUNT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MSG_MARK_BROWSE_INTERVAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_MULTICAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_NAMELIST_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_NAME_COUNT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_NPM_CLASS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_NPM_DELIVERY' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_OPEN_INPUT_COUNT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_OPEN_OUTPUT_COUNT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_OUTBOUND_PORT_MAX' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_OUTBOUND_PORT_MIN' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PAGESET_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PERFORMANCE_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PLATFORM' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PM_DELIVERY' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_POLICY_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PROPERTY_CONTROL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PROT_POLICY_CAPABILITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PROXY_SUB' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PUBSUB_CLUSTER' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PUBSUB_MAXMSG_RETRY_COUNT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PUBSUB_MODE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PUBSUB_NP_MSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PUBSUB_NP_RESP' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PUBSUB_SYNC_PT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PUB_COUNT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_PUB_SCOPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMGR_CFCONLOS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_CONS_COMMS_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_CONS_CRITICAL_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_CONS_ERROR_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_CONS_INFO_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_CONS_REORG_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_CONS_SYSTEM_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_CONS_WARNING_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_CSMT_ON_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_INTERNAL_DUMP' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_LOG_COMMS_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_LOG_CRITICAL_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_LOG_ERROR_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_LOG_INFO_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_LOG_REORG_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_LOG_SYSTEM_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_LOG_WARNING_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_TRACE_COMMS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_TRACE_CONVERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_TRACE_MQI_CALLS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_TRACE_REORG' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QMOPT_TRACE_SYSTEM' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_QSG_DISP' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_Q_DEPTH_HIGH_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_Q_DEPTH_HIGH_LIMIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_Q_DEPTH_LOW_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_Q_DEPTH_LOW_LIMIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_Q_DEPTH_MAX_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_Q_SERVICE_INTERVAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_Q_SERVICE_INTERVAL_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_Q_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_Q_USERS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_READ_AHEAD' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_RECEIVE_TIMEOUT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_RECEIVE_TIMEOUT_MIN' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_RECEIVE_TIMEOUT_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_REMOTE_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_RESPONSE_RESTART_POINT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_RETENTION_INTERVAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SCOPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SECURITY_CASE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SERVICE_CONTROL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SERVICE_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SHAREABILITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SHARED_Q_Q_MGR_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SIGNATURE_ALGORITHM' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SSL_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SSL_FIPS_REQUIRED' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SSL_RESET_COUNT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SSL_TASKS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_START_STOP_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_STATISTICS_AUTO_CLUSSDR' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_STATISTICS_CHANNEL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_STATISTICS_INTERVAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_STATISTICS_MQI' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_STATISTICS_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SUB_CONFIGURATION_EVENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SUB_COUNT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SUB_SCOPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SUITE_B_STRENGTH' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_SYNCPOINT' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TCP_CHANNELS' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TCP_KEEP_ALIVE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TCP_STACK_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TIME_SINCE_RESET' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TOLERATE_UNPROTECTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TOPIC_DEF_PERSISTENCE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TOPIC_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TRACE_ROUTE_RECORDING' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TREE_LIFE_TIME' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TRIGGER_CONTROL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TRIGGER_DEPTH' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TRIGGER_INTERVAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TRIGGER_MSG_PRIORITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TRIGGER_RESTART' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_TRIGGER_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_UR_DISP' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_USAGE' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_USER_LIST' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_USE_DEAD_LETTER_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_WILDCARD_OPERATION' => 'mqseries/mqseries.stub', 'MQSERIES_MQIA_XR_CAPABILITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQMD_CURRENT_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQMD_VERSION_1' => 'mqseries/mqseries.stub', 'MQSERIES_MQMD_VERSION_2' => 'mqseries/mqseries.stub', 'MQSERIES_MQMF_ACCEPT_UNSUP_IF_XMIT_MASK' => 'mqseries/mqseries.stub', 'MQSERIES_MQMF_ACCEPT_UNSUP_MASK' => 'mqseries/mqseries.stub', 'MQSERIES_MQMF_LAST_MSG_IN_GROUP' => 'mqseries/mqseries.stub', 'MQSERIES_MQMF_LAST_SEGMENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQMF_MSG_IN_GROUP' => 'mqseries/mqseries.stub', 'MQSERIES_MQMF_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQMF_REJECT_UNSUP_MASK' => 'mqseries/mqseries.stub', 'MQSERIES_MQMF_SEGMENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQMF_SEGMENTATION_ALLOWED' => 'mqseries/mqseries.stub', 'MQSERIES_MQMF_SEGMENTATION_INHIBITED' => 'mqseries/mqseries.stub', 'MQSERIES_MQMI_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQMO_MATCH_CORREL_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQMO_MATCH_GROUP_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQMO_MATCH_MSG_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQMO_MATCH_MSG_SEQ_NUMBER' => 'mqseries/mqseries.stub', 'MQSERIES_MQMO_MATCH_MSG_TOKEN' => 'mqseries/mqseries.stub', 'MQSERIES_MQMO_MATCH_OFFSET' => 'mqseries/mqseries.stub', 'MQSERIES_MQMO_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQMTOK_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQMT_APPL_FIRST' => 'mqseries/mqseries.stub', 'MQSERIES_MQMT_APPL_LAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQMT_DATAGRAM' => 'mqseries/mqseries.stub', 'MQSERIES_MQMT_MQE_FIELDS' => 'mqseries/mqseries.stub', 'MQSERIES_MQMT_MQE_FIELDS_FROM_MQE' => 'mqseries/mqseries.stub', 'MQSERIES_MQMT_REPLY' => 'mqseries/mqseries.stub', 'MQSERIES_MQMT_REPORT' => 'mqseries/mqseries.stub', 'MQSERIES_MQMT_REQUEST' => 'mqseries/mqseries.stub', 'MQSERIES_MQMT_SYSTEM_FIRST' => 'mqseries/mqseries.stub', 'MQSERIES_MQMT_SYSTEM_LAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQOD_CURRENT_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQOD_VERSION_1' => 'mqseries/mqseries.stub', 'MQSERIES_MQOD_VERSION_2' => 'mqseries/mqseries.stub', 'MQSERIES_MQOD_VERSION_3' => 'mqseries/mqseries.stub', 'MQSERIES_MQOD_VERSION_4' => 'mqseries/mqseries.stub', 'MQSERIES_MQOL_UNDEFINED' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_ALTERNATE_USER_AUTHORITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_BIND_AS_Q_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_BIND_NOT_FIXED' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_BIND_ON_GROUP' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_BIND_ON_OPEN' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_BROWSE' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_CO_OP' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_FAIL_IF_QUIESCING' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_INPUT_AS_Q_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_INPUT_EXCLUSIVE' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_INPUT_SHARED' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_INQUIRE' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_NO_MULTICAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_NO_READ_AHEAD' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_OUTPUT' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_PASS_ALL_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_PASS_IDENTITY_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_READ_AHEAD' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_READ_AHEAD_AS_Q_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_RESOLVE_LOCAL_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_RESOLVE_LOCAL_TOPIC' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_SAVE_ALL_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_SET' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_SET_ALL_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQOO_SET_IDENTITY_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_AUTH_INFO' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_CF_STRUC' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_CHANNEL' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_COMM_INFO' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_LISTENER' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_NAMELIST' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_PROCESS' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_Q_MGR' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_RESERVED_1' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_SERVICE' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_STORAGE_CLASS' => 'mqseries/mqseries.stub', 'MQSERIES_MQOT_TOPIC' => 'mqseries/mqseries.stub', 'MQSERIES_MQPER_NOT_PERSISTENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPER_PERSISTENCE_AS_PARENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPER_PERSISTENCE_AS_Q_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQPER_PERSISTENCE_AS_TOPIC_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQPER_PERSISTENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_ALTERNATE_USER_AUTHORITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_ASYNC_RESPONSE' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_CURRENT_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_DEFAULT_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_FAIL_IF_QUIESCING' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_LOGICAL_ORDER' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_MD_FOR_OUTPUT_ONLY' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_NEW_CORREL_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_NEW_MSG_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_NOT_OWN_SUBS' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_NO_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_NO_SYNCPOINT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_PASS_ALL_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_PASS_IDENTITY_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_RESOLVE_LOCAL_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_RESPONSE_AS_Q_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_RESPONSE_AS_TOPIC_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_RETAIN' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_SCOPE_QMGR' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_SET_ALL_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_SET_IDENTITY_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_SUPPRESS_REPLYTO' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_SYNCPOINT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_SYNC_RESPONSE' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_VERSION_1' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_VERSION_2' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_VERSION_3' => 'mqseries/mqseries.stub', 'MQSERIES_MQPMO_WARN_IF_NO_SUBS_MATCHED' => 'mqseries/mqseries.stub', 'MQSERIES_MQPRI_PRIORITY_AS_PARENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPRI_PRIORITY_AS_PUBLISHED' => 'mqseries/mqseries.stub', 'MQSERIES_MQPRI_PRIORITY_AS_Q_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQPRI_PRIORITY_AS_TOPIC_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQPRT_ASYNC_RESPONSE' => 'mqseries/mqseries.stub', 'MQSERIES_MQPRT_RESPONSE_AS_PARENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQPRT_SYNC_RESPONSE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ACTION_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ADAPTER_CONN_LOAD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ADAPTER_CONV_LOAD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ADAPTER_DEFS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ADAPTER_DEFS_LOAD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ADAPTER_DISC_LOAD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ADAPTER_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ADAPTER_SERV_LOAD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ADAPTER_STORAGE_SHORTAGE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_AIR_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ALIAS_BASE_Q_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ALIAS_TARGTYPE_CHANGED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ALREADY_CONNECTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ALREADY_JOINED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ALTER_SUB_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ANOTHER_Q_MGR_CONNECTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_API_EXIT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_API_EXIT_INIT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_API_EXIT_LOAD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_API_EXIT_NOT_FOUND' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_API_EXIT_TERM_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_APPL_FIRST' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_APPL_LAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ASID_MISMATCH' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ASYNC_UOW_CONFLICT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ASYNC_XA_CONFLICT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ATTRIBUTE_LOCKED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_AUTH_INFO_CONN_NAME_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_AUTH_INFO_REC_COUNT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_AUTH_INFO_REC_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_AUTH_INFO_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_BACKED_OUT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_BACKOUT_THRESHOLD_REACHED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_BAG_CONVERSION_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_BAG_WRONG_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_BINARY_DATA_LENGTH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_BMHO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_BO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_BRIDGE_STARTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_BRIDGE_STOPPED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_BUFFER_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_BUFFER_LENGTH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_BUFFER_NOT_AUTOMATIC' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CALLBACK_LINK_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CALLBACK_NOT_REGISTERED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CALLBACK_ROUTINE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CALLBACK_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CALL_INTERRUPTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CALL_IN_PROGRESS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CBD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CBD_OPTIONS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CD_ARRAY_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CERT_VAL_POLICY_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CFBF_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CFBS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CFGR_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CFH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CFIF_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CFIL_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CFIN_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CFSF_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CFSL_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CFST_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CF_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CF_STRUC_AUTH_FAILED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CF_STRUC_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CF_STRUC_FAILED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CF_STRUC_IN_USE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CF_STRUC_LIST_HDR_IN_USE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_ACTIVATED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_AUTO_DEF_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_AUTO_DEF_OK' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_BLOCKED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_BLOCKED_WARNING' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_CONFIG_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_CONV_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_NOT_ACTIVATED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_SSL_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_SSL_WARNING' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_STARTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_STOPPED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHANNEL_STOPPED_BY_USER' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHAR_ATTRS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHAR_ATTRS_TOO_SHORT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHAR_ATTR_LENGTH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CHAR_CONVERSION_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CICS_BRIDGE_RESTRICTION' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CICS_WAIT_FAILED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CIPHER_SPEC_NOT_SUITE_B' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CLIENT_CHANNEL_CONFLICT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CLIENT_CONN_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CLIENT_EXIT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CLIENT_EXIT_LOAD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CLUSTER_EXIT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CLUSTER_EXIT_LOAD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CLUSTER_PUT_INHIBITED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CLUSTER_RESOLUTION_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CLUSTER_RESOURCE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CMD_SERVER_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CMHO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CNO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CODED_CHAR_SET_ID_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_COD_NOT_VALID_FOR_XCF_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_COMMAND_MQSC' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_COMMAND_PCF' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_COMMAND_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_COMMINFO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONFIG_CHANGE_OBJECT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONFIG_CREATE_OBJECT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONFIG_DELETE_OBJECT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONFIG_REFRESH_OBJECT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONNECTION_BROKEN' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONNECTION_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONNECTION_NOT_AUTHORIZED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONNECTION_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONNECTION_QUIESCING' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONNECTION_STOPPED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONNECTION_STOPPING' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONNECTION_SUSPENDED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONN_ID_IN_USE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONN_TAG_IN_USE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONN_TAG_NOT_RELEASED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONN_TAG_NOT_USABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONTENT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONTEXT_HANDLE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONTEXT_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONTEXT_OBJECT_NOT_VALID' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONTEXT_OPEN_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONVERTED_MSG_TOO_BIG' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CONVERTED_STRING_TOO_BIG' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CORREL_ID_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CRYPTO_HARDWARE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CTLO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CURRENT_RECORD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_CURSOR_NOT_VALID' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DATA_LENGTH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DATA_SET_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DATA_TRUNCATED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DB2_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DBCS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DEF_SYNCPOINT_INHIBITED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DEF_XMIT_Q_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DEF_XMIT_Q_USAGE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DEST_CLASS_NOT_ALTERABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DEST_ENV_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DEST_NAME_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DISTRIBUTION_LIST_EMPTY' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DLH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DMHO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DMPO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DUPLICATE_GROUP_SUB' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DUPLICATE_RECOV_COORD' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DURABILITY_NOT_ALLOWED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DURABILITY_NOT_ALTERABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_DYNAMIC_Q_NAME_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ENCODING_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ENCODING_NOT_SUPPORTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ENVIRONMENT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_EPH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_EXIT_PROPS_NOT_SUPPORTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_EXIT_REASON_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_EXPIRY_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_FASTPATH_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_FEEDBACK_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_FILE_NOT_AUDITED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_FILE_SYSTEM_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_FILTER_OPERATOR_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_FORMAT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_FORMAT_NOT_SUPPORTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_FUNCTION_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_FUNCTION_NOT_SUPPORTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_GET_ENABLED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_GET_INHIBITED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_GLOBAL_UOW_CONFLICT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_GMO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_GROUPING_NOT_ALLOWED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_GROUPING_NOT_ALTERABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_GROUP_ADDRESS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_GROUP_ID_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HANDLE_IN_USE_FOR_UOW' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HANDLE_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HBAG_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HCONFIG_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HCONN_ASYNC_ACTIVE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HCONN_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HEADER_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HMSG_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HMSG_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HOBJ_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HOBJ_QUIESCED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HOBJ_QUIESCED_NO_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_HOST_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_IDENTITY_MISMATCH' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_IIH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_IMPO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INCOMPLETE_GROUP' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INCOMPLETE_MSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INCONSISTENT_BROWSE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INCONSISTENT_CCSIDS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INCONSISTENT_ENCODINGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INCONSISTENT_FORMAT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INCONSISTENT_ITEM_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INCONSISTENT_OBJECT_STATE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INCONSISTENT_OPEN_OPTIONS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INCONSISTENT_PERSISTENCE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INCONSISTENT_UOW' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INDEX_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INDEX_NOT_PRESENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INHIBIT_VALUE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INITIALIZATION_FAILED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INQUIRY_COMMAND_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INSTALLATION_MISMATCH' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INSTALLATION_MISSING' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INSUFFICIENT_BUFFER' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INSUFFICIENT_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INT_ATTRS_ARRAY_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INT_ATTR_COUNT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INT_ATTR_COUNT_TOO_SMALL' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INVALID_DESTINATION' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INVALID_MSG_UNDER_CURSOR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_INVALID_SUBSCRIPTION' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ITEM_COUNT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ITEM_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ITEM_VALUE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_JMS_FORMAT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_JSSE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_KEY_REPOSITORY_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_LDAP_PASSWORD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_LDAP_USER_NAME_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_LDAP_USER_NAME_LENGTH_ERR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_LOCAL_UOW_CONFLICT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_LOGGER_STATUS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_LOOPING_PUBLICATION' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MATCH_OPTIONS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MAX_CONNS_LIMIT_REACHED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MAX_MSG_LENGTH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MCAST_PUB_STATUS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MCAST_SUB_STATUS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MDE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MHBO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MISSING_REPLY_TO_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MISSING_WIH' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MIXED_CONTENT_NOT_ALLOWED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MODULE_ENTRY_NOT_FOUND' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MODULE_INVALID' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MODULE_NOT_FOUND' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_FLAGS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_HANDLE_COPY_FAILURE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_HANDLE_IN_USE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_ID_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_MARKED_BROWSE_CO_OP' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_NOT_ALLOWED_IN_GROUP' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_NOT_MATCHED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_SEQ_NUMBER_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_TOKEN_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_TOO_BIG_FOR_CHANNEL' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_TOO_BIG_FOR_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_TOO_BIG_FOR_Q_MGR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MSG_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MULTICAST_CONFIG_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MULTICAST_INTERFACE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MULTICAST_INTERNAL_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MULTICAST_ONLY' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MULTICAST_SEND_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MULTIPLE_INSTANCE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_MULTIPLE_REASONS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NAME_IN_USE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NAME_NOT_VALID_FOR_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NEGATIVE_LENGTH' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NEGATIVE_OFFSET' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NESTED_BAG_NOT_SUPPORTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NESTED_SELECTOR_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NEXT_OFFSET_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NEXT_RECORD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_AUTHORIZED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_CONNECTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_CONVERTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_OPEN' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_OPEN_FOR_BROWSE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_OPEN_FOR_INPUT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_OPEN_FOR_INQUIRE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_OPEN_FOR_OUTPUT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_OPEN_FOR_PASS_ALL' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_OPEN_FOR_PASS_IDENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_OPEN_FOR_SET' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_OPEN_FOR_SET_ALL' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_OPEN_FOR_SET_IDENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NOT_PRIVILEGED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_BUFFER' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_CALLBACKS_ACTIVE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_CONNECTION_REFERENCE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_DATA_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_DESTINATIONS_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_EXTERNAL_PARTICIPANTS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_MSG_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_MSG_LOCKED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_MSG_UNDER_CURSOR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_RECORD_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_RETAINED_MSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_SUBSCRIPTION' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NO_SUBS_MATCHED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_NULL_POINTER' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OBJECT_ALREADY_EXISTS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OBJECT_CHANGED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OBJECT_DAMAGED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OBJECT_IN_USE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OBJECT_LEVEL_INCOMPATIBLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OBJECT_NAME_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OBJECT_NOT_UNIQUE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OBJECT_Q_MGR_NAME_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OBJECT_RECORDS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OBJECT_STRING_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OBJECT_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OCSP_URL_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OFFSET_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OPEN_FAILED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OPERATION_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OPERATION_NOT_ALLOWED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OPTIONS_CHANGED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OPTIONS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OPTION_ENVIRONMENT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OPTION_NOT_VALID_FOR_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ORIGINAL_LENGTH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OUTCOME_MIXED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OUTCOME_PENDING' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_OUT_SELECTOR_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PAGESET_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PAGESET_FULL' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PARAMETER_MISSING' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PARTIALLY_CONVERTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PARTICIPANT_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PARTICIPANT_NOT_DEFINED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PCF_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PERSISTENCE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PERSISTENT_NOT_ALLOWED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PMO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PMO_RECORD_FLAGS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PRECONN_EXIT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PRECONN_EXIT_LOAD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PRECONN_EXIT_NOT_FOUND' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PRIORITY_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PRIORITY_EXCEEDS_MAXIMUM' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROPERTIES_DISABLED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROPERTIES_TOO_BIG' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROPERTY_NAME_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROPERTY_NAME_LENGTH_ERR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROPERTY_NAME_TOO_BIG' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROPERTY_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROPERTY_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROPERTY_VALUE_TOO_BIG' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROP_CONV_NOT_SUPPORTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROP_NAME_NOT_CONVERTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROP_NUMBER_FORMAT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROP_TYPE_NOT_SUPPORTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PROP_VALUE_NOT_CONVERTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PUBLICATION_FAILURE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PUBLISH_EXIT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PUBSUB_INHIBITED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PUT_INHIBITED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PUT_MSG_RECORDS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_PUT_NOT_RETAINED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_ALREADY_EXISTS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_DELETED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_DEPTH_HIGH' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_DEPTH_LOW' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_FULL' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_INDEX_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_MGR_ACTIVE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_MGR_NAME_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_MGR_NOT_ACTIVE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_MGR_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_MGR_QUIESCING' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_MGR_STOPPING' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_NOT_EMPTY' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_SERVICE_INTERVAL_HIGH' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_SERVICE_INTERVAL_OK' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_SPACE_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_Q_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RAS_PROPERTY_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_READ_AHEAD_MSGS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RECONNECTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RECONNECTING' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RECONNECT_FAILED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RECONNECT_INCOMPATIBLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RECONNECT_QMID_MISMATCH' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RECONNECT_Q_MGR_REQD' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RECONNECT_TIMED_OUT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RECS_PRESENT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_REFERENCE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_REMOTE_Q_NAME_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_REOPEN_EXCL_INPUT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_REOPEN_INQUIRE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_REOPEN_SAVED_CONTEXT_ERR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_REOPEN_TEMPORARY_Q_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_REPORT_OPTIONS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RESERVED_VALUE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RESOURCE_PROBLEM' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RESPONSE_RECORDS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RES_OBJECT_STRING_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RETAINED_MSG_Q_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RETAINED_NOT_DELIVERED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RFH_COMMAND_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RFH_DUPLICATE_PARM' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RFH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RFH_FORMAT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RFH_HEADER_FIELD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RFH_PARM_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RFH_PARM_MISSING' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RFH_RESTRICTED_FORMAT_ERR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RFH_STRING_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_RMH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SCO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SD_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SECOND_MARK_NOT_ALLOWED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SECURITY_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SEGMENTATION_NOT_ALLOWED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SEGMENTS_NOT_SUPPORTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SEGMENT_LENGTH_ZERO' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTION_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTION_STRING_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_ALWAYS_FALSE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_COUNT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_INVALID_FOR_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_LIMIT_EXCEEDED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_NOT_ALTERABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_NOT_FOR_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_NOT_PRESENT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_NOT_SUPPORTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_NOT_UNIQUE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_OUT_OF_RANGE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_SYNTAX_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SELECTOR_WRONG_TYPE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SERVICE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SERVICE_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SIGNAL1_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SIGNAL_OUTSTANDING' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SIGNAL_REQUEST_ACCEPTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SMPO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SOAP_AXIS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SOAP_DOTNET_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SOAP_URL_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SOURCE_BUFFER_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SOURCE_CCSID_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SOURCE_DECIMAL_ENC_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SOURCE_FLOAT_ENC_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SOURCE_INTEGER_ENC_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SOURCE_LENGTH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SRC_ENV_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SRC_NAME_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SRO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SSL_ALREADY_INITIALIZED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SSL_ALT_PROVIDER_REQUIRED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SSL_CERTIFICATE_REVOKED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SSL_CERT_STORE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SSL_CONFIG_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SSL_INITIALIZATION_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SSL_KEY_RESET_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SSL_NOT_ALLOWED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SSL_PEER_NAME_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SSL_PEER_NAME_MISMATCH' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_STANDBY_Q_MGR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_STAT_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_STOPPED_BY_CLUSTER_EXIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_STORAGE_CLASS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_STORAGE_MEDIUM_FULL' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_STORAGE_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_STRING_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_STRING_LENGTH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_STRING_TRUNCATED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_STRUC_ID_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_STRUC_LENGTH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_STS_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SUBLEVEL_NOT_ALTERABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SUBSCRIPTION_CHANGE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SUBSCRIPTION_CREATE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SUBSCRIPTION_DELETE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SUBSCRIPTION_IN_USE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SUBSCRIPTION_REFRESH' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SUB_ALREADY_EXISTS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SUB_INHIBITED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SUB_NAME_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SUB_USER_DATA_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SUITE_B_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SUPPRESSED_BY_EXIT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SYNCPOINT_LIMIT_REACHED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SYNCPOINT_NOT_ALLOWED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SYNCPOINT_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SYSTEM_BAG_NOT_ALTERABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SYSTEM_BAG_NOT_DELETABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SYSTEM_ITEM_NOT_ALTERABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_SYSTEM_ITEM_NOT_DELETABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TARGET_BUFFER_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TARGET_CCSID_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TARGET_DECIMAL_ENC_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TARGET_FLOAT_ENC_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TARGET_INTEGER_ENC_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TARGET_LENGTH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TERMINATION_FAILED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TMC_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TM_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TOPIC_NOT_ALTERABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TOPIC_STRING_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TRIGGER_CONTROL_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TRIGGER_DEPTH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TRIGGER_MSG_PRIORITY_ERR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TRIGGER_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TRUNCATED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TRUNCATED_MSG_ACCEPTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_TRUNCATED_MSG_FAILED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UCS2_CONVERSION_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNEXPECTED_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNIT_OF_WORK_NOT_STARTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_ALIAS_BASE_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_AUTH_ENTITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_CHANNEL_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_COMPONENT_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_DEF_XMIT_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_ENTITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_OBJECT_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_OBJECT_Q_MGR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_Q_NAME' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_REF_OBJECT' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_REMOTE_Q_MGR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_REPORT_OPTION' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNKNOWN_XMIT_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNSUPPORTED_CIPHER_SUITE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UNSUPPORTED_PROPERTY' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UOW_CANCELED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UOW_COMMITTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UOW_ENLISTMENT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UOW_IN_PROGRESS' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UOW_MIX_NOT_SUPPORTED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_UOW_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_USER_ID_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_WAIT_INTERVAL_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_WIH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_WRONG_CF_LEVEL' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_WRONG_GMO_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_WRONG_MD_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_WRONG_VERSION' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_WXP_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_XEPO_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_XMIT_Q_TYPE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_XMIT_Q_USAGE_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_XQH_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_XR_NOT_AVAILABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_XWAIT_CANCELED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_XWAIT_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQRC_ZERO_LENGTH' => 'mqseries/mqseries.stub', 'MQSERIES_MQRL_UNDEFINED' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_ACCEPT_UNSUP_IF_XMIT_MASK' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_ACCEPT_UNSUP_MASK' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_ACTIVITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_COA' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_COA_WITH_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_COA_WITH_FULL_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_COD' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_COD_WITH_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_COD_WITH_FULL_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_COPY_MSG_ID_TO_CORREL_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_DEAD_LETTER_Q' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_DISCARD_MSG' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_EXCEPTION' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_EXCEPTION_WITH_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_EXCEPTION_WITH_FULL_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_EXPIRATION' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_EXPIRATION_WITH_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_EXPIRATION_WITH_FULL_DATA' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_NAN' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_NEW_MSG_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_PAN' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_PASS_CORREL_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_PASS_DISCARD_AND_EXPIRY' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_PASS_MSG_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQRO_REJECT_UNSUP_MASK' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_ALTER' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_ALTERNATE_USER_AUTHORITY' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_ANY_USERID' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_CREATE' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_DURABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_FAIL_IF_QUIESCING' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_FIXED_USERID' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_GROUP_SUB' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_MANAGED' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_NEW_PUBLICATIONS_ONLY' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_NONE' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_NON_DURABLE' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_NO_MULTICAST' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_NO_READ_AHEAD' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_PUBLICATIONS_ON_REQUEST' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_READ_AHEAD' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_READ_AHEAD_AS_Q_DEF' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_RESUME' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_SCOPE_QMGR' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_SET_CORREL_ID' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_SET_IDENTITY_CONTEXT' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_WILDCARD_CHAR' => 'mqseries/mqseries.stub', 'MQSERIES_MQSO_WILDCARD_TOPIC' => 'mqseries/mqseries.stub', 'MQSERIES_MQSTAT_TYPE_ASYNC_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQSTAT_TYPE_RECONNECTION' => 'mqseries/mqseries.stub', 'MQSERIES_MQSTAT_TYPE_RECONNECTION_ERROR' => 'mqseries/mqseries.stub', 'MQSERIES_MQWI_UNLIMITED' => 'mqseries/mqseries.stub', 'MQSERIES_MQXPT_ALL' => 'mqseries/mqseries.stub', 'MQSERIES_MQXPT_DECNET' => 'mqseries/mqseries.stub', 'MQSERIES_MQXPT_LOCAL' => 'mqseries/mqseries.stub', 'MQSERIES_MQXPT_LU62' => 'mqseries/mqseries.stub', 'MQSERIES_MQXPT_NETBIOS' => 'mqseries/mqseries.stub', 'MQSERIES_MQXPT_SPX' => 'mqseries/mqseries.stub', 'MQSERIES_MQXPT_TCP' => 'mqseries/mqseries.stub', 'MQSERIES_MQXPT_UDP' => 'mqseries/mqseries.stub', 'MSG_CMSG_CLOEXEC' => 'sockets/sockets.stub', 'MSG_CONFIRM' => 'sockets/sockets.stub', 'MSG_CTRUNC' => 'sockets/sockets.stub', 'MSG_DONTROUTE' => 'sockets/sockets.stub', 'MSG_DONTWAIT' => 'sockets/sockets.stub', 'MSG_EAGAIN' => 'sysvmsg/sysvmsg.stub', 'MSG_ENOMSG' => 'sysvmsg/sysvmsg.stub', 'MSG_EOF' => 'sockets/sockets.stub', 'MSG_EOR' => 'sockets/sockets.stub', 'MSG_ERRQUEUE' => 'sockets/sockets.stub', 'MSG_EXCEPT' => 'sysvmsg/sysvmsg.stub', 'MSG_IPC_NOWAIT' => 'sysvmsg/sysvmsg.stub', 'MSG_MORE' => 'sockets/sockets.stub', 'MSG_NOERROR' => 'sysvmsg/sysvmsg.stub', 'MSG_NOSIGNAL' => 'sockets/sockets.stub', 'MSG_OOB' => 'sockets/sockets.stub', 'MSG_PEEK' => 'sockets/sockets.stub', 'MSG_TRUNC' => 'sockets/sockets.stub', 'MSG_WAITALL' => 'sockets/sockets.stub', 'MSG_WAITFORONE' => 'sockets/sockets.stub', 'MSG_ZEROCOPY' => 'sockets/sockets.stub', 'MSSQL_ASSOC' => 'mssql/mssql.stub', 'MSSQL_BOTH' => 'mssql/mssql.stub', 'MSSQL_NUM' => 'mssql/mssql.stub', 'MS_ALIGN_CENTER' => 'mapscript/mapscript.stub', 'MS_ALIGN_LEFT' => 'mapscript/mapscript.stub', 'MS_ALIGN_RIGHT' => 'mapscript/mapscript.stub', 'MS_AUTO' => 'mapscript/mapscript.stub', 'MS_AUTO2' => 'mapscript/mapscript.stub', 'MS_CC' => 'mapscript/mapscript.stub', 'MS_CGIERR' => 'mapscript/mapscript.stub', 'MS_CL' => 'mapscript/mapscript.stub', 'MS_CR' => 'mapscript/mapscript.stub', 'MS_DBFERR' => 'mapscript/mapscript.stub', 'MS_DD' => 'mapscript/mapscript.stub', 'MS_DEFAULT' => 'mapscript/mapscript.stub', 'MS_DELETE' => 'mapscript/mapscript.stub', 'MS_EMBED' => 'mapscript/mapscript.stub', 'MS_EOFERR' => 'mapscript/mapscript.stub', 'MS_FALSE' => 'mapscript/mapscript.stub', 'MS_FEET' => 'mapscript/mapscript.stub', 'MS_FOLLOW' => 'mapscript/mapscript.stub', 'MS_GDERR' => 'mapscript/mapscript.stub', 'MS_GD_ALPHA' => 'mapscript/mapscript.stub', 'MS_GET_REQUEST' => 'mapscript/mapscript.stub', 'MS_GIANT' => 'mapscript/mapscript.stub', 'MS_GRATICULE' => 'mapscript/mapscript.stub', 'MS_HASHERR' => 'mapscript/mapscript.stub', 'MS_HILITE' => 'mapscript/mapscript.stub', 'MS_HTTPERR' => 'mapscript/mapscript.stub', 'MS_IDENTERR' => 'mapscript/mapscript.stub', 'MS_IMAGEMODE_BYTE' => 'mapscript/mapscript.stub', 'MS_IMAGEMODE_FEATURE' => 'mapscript/mapscript.stub', 'MS_IMAGEMODE_FLOAT32' => 'mapscript/mapscript.stub', 'MS_IMAGEMODE_INT16' => 'mapscript/mapscript.stub', 'MS_IMAGEMODE_NULL' => 'mapscript/mapscript.stub', 'MS_IMAGEMODE_PC256' => 'mapscript/mapscript.stub', 'MS_IMAGEMODE_RGB' => 'mapscript/mapscript.stub', 'MS_IMAGEMODE_RGBA' => 'mapscript/mapscript.stub', 'MS_IMGERR' => 'mapscript/mapscript.stub', 'MS_INCHES' => 'mapscript/mapscript.stub', 'MS_INLINE' => 'mapscript/mapscript.stub', 'MS_IOERR' => 'mapscript/mapscript.stub', 'MS_JOINERR' => 'mapscript/mapscript.stub', 'MS_KILOMETERS' => 'mapscript/mapscript.stub', 'MS_LABEL_BINDING_ANGLE' => 'mapscript/mapscript.stub', 'MS_LABEL_BINDING_COLOR' => 'mapscript/mapscript.stub', 'MS_LABEL_BINDING_FONT' => 'mapscript/mapscript.stub', 'MS_LABEL_BINDING_OUTLINECOLOR' => 'mapscript/mapscript.stub', 'MS_LABEL_BINDING_POSITION' => 'mapscript/mapscript.stub', 'MS_LABEL_BINDING_PRIORITY' => 'mapscript/mapscript.stub', 'MS_LABEL_BINDING_SHADOWSIZEX' => 'mapscript/mapscript.stub', 'MS_LABEL_BINDING_SHADOWSIZEY' => 'mapscript/mapscript.stub', 'MS_LABEL_BINDING_SIZE' => 'mapscript/mapscript.stub', 'MS_LARGE' => 'mapscript/mapscript.stub', 'MS_LAYER_ANNOTATION' => 'mapscript/mapscript.stub', 'MS_LAYER_CHART' => 'mapscript/mapscript.stub', 'MS_LAYER_CIRCLE' => 'mapscript/mapscript.stub', 'MS_LAYER_LINE' => 'mapscript/mapscript.stub', 'MS_LAYER_POINT' => 'mapscript/mapscript.stub', 'MS_LAYER_POLYGON' => 'mapscript/mapscript.stub', 'MS_LAYER_QUERY' => 'mapscript/mapscript.stub', 'MS_LAYER_RASTER' => 'mapscript/mapscript.stub', 'MS_LAYER_TILEINDEX' => 'mapscript/mapscript.stub', 'MS_LC' => 'mapscript/mapscript.stub', 'MS_LL' => 'mapscript/mapscript.stub', 'MS_LR' => 'mapscript/mapscript.stub', 'MS_MAPCONTEXTERR' => 'mapscript/mapscript.stub', 'MS_MEDIUM' => 'mapscript/mapscript.stub', 'MS_MEMERR' => 'mapscript/mapscript.stub', 'MS_METERS' => 'mapscript/mapscript.stub', 'MS_MILES' => 'mapscript/mapscript.stub', 'MS_MISCERR' => 'mapscript/mapscript.stub', 'MS_MULTIPLE' => 'mapscript/mapscript.stub', 'MS_NAUTICALMILES' => 'mapscript/mapscript.stub', 'MS_NO' => 'mapscript/mapscript.stub', 'MS_NOERR' => 'mapscript/mapscript.stub', 'MS_NONE' => 'mapscript/mapscript.stub', 'MS_NORMAL' => 'mapscript/mapscript.stub', 'MS_NOTFOUND' => 'mapscript/mapscript.stub', 'MS_OFF' => 'mapscript/mapscript.stub', 'MS_OGR' => 'mapscript/mapscript.stub', 'MS_OGRERR' => 'mapscript/mapscript.stub', 'MS_ON' => 'mapscript/mapscript.stub', 'MS_ORACLESPATIAL' => 'mapscript/mapscript.stub', 'MS_ORACLESPATIALERR' => 'mapscript/mapscript.stub', 'MS_PARSEERR' => 'mapscript/mapscript.stub', 'MS_PIXELS' => 'mapscript/mapscript.stub', 'MS_PLUGIN' => 'mapscript/mapscript.stub', 'MS_POSTGIS' => 'mapscript/mapscript.stub', 'MS_POST_REQUEST' => 'mapscript/mapscript.stub', 'MS_PROJERR' => 'mapscript/mapscript.stub', 'MS_QUERYERR' => 'mapscript/mapscript.stub', 'MS_RASTER' => 'mapscript/mapscript.stub', 'MS_REGEXERR' => 'mapscript/mapscript.stub', 'MS_SDE' => 'mapscript/mapscript.stub', 'MS_SDEERR' => 'mapscript/mapscript.stub', 'MS_SELECTED' => 'mapscript/mapscript.stub', 'MS_SHAPEFILE' => 'mapscript/mapscript.stub', 'MS_SHAPE_LINE' => 'mapscript/mapscript.stub', 'MS_SHAPE_NULL' => 'mapscript/mapscript.stub', 'MS_SHAPE_POINT' => 'mapscript/mapscript.stub', 'MS_SHAPE_POLYGON' => 'mapscript/mapscript.stub', 'MS_SHPERR' => 'mapscript/mapscript.stub', 'MS_SHP_ARC' => 'mapscript/mapscript.stub', 'MS_SHP_MULTIPOINT' => 'mapscript/mapscript.stub', 'MS_SHP_POINT' => 'mapscript/mapscript.stub', 'MS_SHP_POLYGON' => 'mapscript/mapscript.stub', 'MS_SINGLE' => 'mapscript/mapscript.stub', 'MS_SMALL' => 'mapscript/mapscript.stub', 'MS_STYLE_BINDING_ANGLE' => 'mapscript/mapscript.stub', 'MS_STYLE_BINDING_COLOR' => 'mapscript/mapscript.stub', 'MS_STYLE_BINDING_OUTLINECOLOR' => 'mapscript/mapscript.stub', 'MS_STYLE_BINDING_SIZE' => 'mapscript/mapscript.stub', 'MS_STYLE_BINDING_SYMBOL' => 'mapscript/mapscript.stub', 'MS_STYLE_BINDING_WIDTH' => 'mapscript/mapscript.stub', 'MS_SYMBOL_ELLIPSE' => 'mapscript/mapscript.stub', 'MS_SYMBOL_PIXMAP' => 'mapscript/mapscript.stub', 'MS_SYMBOL_SIMPLE' => 'mapscript/mapscript.stub', 'MS_SYMBOL_TRUETYPE' => 'mapscript/mapscript.stub', 'MS_SYMBOL_VECTOR' => 'mapscript/mapscript.stub', 'MS_SYMERR' => 'mapscript/mapscript.stub', 'MS_TILED_OGR' => 'mapscript/mapscript.stub', 'MS_TILED_SHAPEFILE' => 'mapscript/mapscript.stub', 'MS_TINY' => 'mapscript/mapscript.stub', 'MS_TRUE' => 'mapscript/mapscript.stub', 'MS_TTFERR' => 'mapscript/mapscript.stub', 'MS_TYPEERR' => 'mapscript/mapscript.stub', 'MS_UC' => 'mapscript/mapscript.stub', 'MS_UL' => 'mapscript/mapscript.stub', 'MS_UNION' => 'mapscript/mapscript.stub', 'MS_UR' => 'mapscript/mapscript.stub', 'MS_WCSERR' => 'mapscript/mapscript.stub', 'MS_WEBERR' => 'mapscript/mapscript.stub', 'MS_WFS' => 'mapscript/mapscript.stub', 'MS_WFSCONNERR' => 'mapscript/mapscript.stub', 'MS_WFSERR' => 'mapscript/mapscript.stub', 'MS_WMS' => 'mapscript/mapscript.stub', 'MS_WMSCONNERR' => 'mapscript/mapscript.stub', 'MS_WMSERR' => 'mapscript/mapscript.stub', 'MS_XY' => 'mapscript/mapscript.stub', 'MS_YES' => 'mapscript/mapscript.stub', 'MT_RAND_MT19937' => 'standard/standard_defines.stub', 'MT_RAND_PHP' => 'standard/standard_defines.stub', 'MYSQLI_ASSOC' => 'mysqli/mysqli.stub', 'MYSQLI_ASYNC' => 'mysqli/mysqli.stub', 'MYSQLI_AUTO_INCREMENT_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_BINARY_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_BLOB_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_BOTH' => 'mysqli/mysqli.stub', 'MYSQLI_CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS' => 'mysqli/mysqli.stub', 'MYSQLI_CLIENT_COMPRESS' => 'mysqli/mysqli.stub', 'MYSQLI_CLIENT_FOUND_ROWS' => 'mysqli/mysqli.stub', 'MYSQLI_CLIENT_IGNORE_SPACE' => 'mysqli/mysqli.stub', 'MYSQLI_CLIENT_INTERACTIVE' => 'mysqli/mysqli.stub', 'MYSQLI_CLIENT_NO_SCHEMA' => 'mysqli/mysqli.stub', 'MYSQLI_CLIENT_SSL' => 'mysqli/mysqli.stub', 'MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT' => 'mysqli/mysqli.stub', 'MYSQLI_CLIENT_SSL_VERIFY_SERVER_CERT' => 'mysqli/mysqli.stub', 'MYSQLI_CURSOR_TYPE_FOR_UPDATE' => 'mysqli/mysqli.stub', 'MYSQLI_CURSOR_TYPE_NO_CURSOR' => 'mysqli/mysqli.stub', 'MYSQLI_CURSOR_TYPE_READ_ONLY' => 'mysqli/mysqli.stub', 'MYSQLI_CURSOR_TYPE_SCROLLABLE' => 'mysqli/mysqli.stub', 'MYSQLI_DATA_TRUNCATED' => 'mysqli/mysqli.stub', 'MYSQLI_DEBUG_TRACE_ENABLED' => 'mysqli/mysqli.stub', 'MYSQLI_ENUM_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_GROUP_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_INIT_COMMAND' => 'mysqli/mysqli.stub', 'MYSQLI_IS_MARIADB' => 'mysqli/mysqli.stub', 'MYSQLI_MULTIPLE_KEY_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_NOT_NULL_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_NO_DATA' => 'mysqli/mysqli.stub', 'MYSQLI_NO_DEFAULT_VALUE_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_NUM' => 'mysqli/mysqli.stub', 'MYSQLI_NUM_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_ON_UPDATE_NOW_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS' => 'mysqli/mysqli.stub', 'MYSQLI_OPT_CONNECT_TIMEOUT' => 'mysqli/mysqli.stub', 'MYSQLI_OPT_INT_AND_FLOAT_NATIVE' => 'mysqli/mysqli.stub', 'MYSQLI_OPT_LOAD_DATA_LOCAL_DIR' => 'mysqli/mysqli.stub', 'MYSQLI_OPT_LOCAL_INFILE' => 'mysqli/mysqli.stub', 'MYSQLI_OPT_NET_CMD_BUFFER_SIZE' => 'mysqli/mysqli.stub', 'MYSQLI_OPT_NET_READ_BUFFER_SIZE' => 'mysqli/mysqli.stub', 'MYSQLI_OPT_READ_TIMEOUT' => 'mysqli/mysqli.stub', 'MYSQLI_OPT_SSL_VERIFY_SERVER_CERT' => 'mysqli/mysqli.stub', 'MYSQLI_PART_KEY_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_PRI_KEY_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_READ_DEFAULT_FILE' => 'mysqli/mysqli.stub', 'MYSQLI_READ_DEFAULT_GROUP' => 'mysqli/mysqli.stub', 'MYSQLI_REFRESH_BACKUP_LOG' => 'mysqli/mysqli.stub', 'MYSQLI_REFRESH_GRANT' => 'mysqli/mysqli.stub', 'MYSQLI_REFRESH_HOSTS' => 'mysqli/mysqli.stub', 'MYSQLI_REFRESH_LOG' => 'mysqli/mysqli.stub', 'MYSQLI_REFRESH_MASTER' => 'mysqli/mysqli.stub', 'MYSQLI_REFRESH_REPLICA' => 'mysqli/mysqli.stub', 'MYSQLI_REFRESH_SLAVE' => 'mysqli/mysqli.stub', 'MYSQLI_REFRESH_STATUS' => 'mysqli/mysqli.stub', 'MYSQLI_REFRESH_TABLES' => 'mysqli/mysqli.stub', 'MYSQLI_REFRESH_THREADS' => 'mysqli/mysqli.stub', 'MYSQLI_REPORT_ALL' => 'mysqli/mysqli.stub', 'MYSQLI_REPORT_ERROR' => 'mysqli/mysqli.stub', 'MYSQLI_REPORT_INDEX' => 'mysqli/mysqli.stub', 'MYSQLI_REPORT_OFF' => 'mysqli/mysqli.stub', 'MYSQLI_REPORT_STRICT' => 'mysqli/mysqli.stub', 'MYSQLI_SERVER_PS_OUT_PARAMS' => 'mysqli/mysqli.stub', 'MYSQLI_SERVER_PUBLIC_KEY' => 'mysqli/mysqli.stub', 'MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED' => 'mysqli/mysqli.stub', 'MYSQLI_SERVER_QUERY_NO_INDEX_USED' => 'mysqli/mysqli.stub', 'MYSQLI_SERVER_QUERY_WAS_SLOW' => 'mysqli/mysqli.stub', 'MYSQLI_SET_CHARSET_DIR' => 'mysqli/mysqli.stub', 'MYSQLI_SET_CHARSET_NAME' => 'mysqli/mysqli.stub', 'MYSQLI_SET_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_STMT_ATTR_CURSOR_TYPE' => 'mysqli/mysqli.stub', 'MYSQLI_STMT_ATTR_PREFETCH_ROWS' => 'mysqli/mysqli.stub', 'MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH' => 'mysqli/mysqli.stub', 'MYSQLI_STORE_RESULT' => 'mysqli/mysqli.stub', 'MYSQLI_STORE_RESULT_COPY_DATA' => 'mysqli/mysqli.stub', 'MYSQLI_TIMESTAMP_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_TRANS_COR_AND_CHAIN' => 'mysqli/mysqli.stub', 'MYSQLI_TRANS_COR_AND_NO_CHAIN' => 'mysqli/mysqli.stub', 'MYSQLI_TRANS_COR_NO_RELEASE' => 'mysqli/mysqli.stub', 'MYSQLI_TRANS_COR_RELEASE' => 'mysqli/mysqli.stub', 'MYSQLI_TRANS_START_READ_ONLY' => 'mysqli/mysqli.stub', 'MYSQLI_TRANS_START_READ_WRITE' => 'mysqli/mysqli.stub', 'MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_BIT' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_BLOB' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_CHAR' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_DATE' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_DATETIME' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_DECIMAL' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_DOUBLE' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_ENUM' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_FLOAT' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_GEOMETRY' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_INT24' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_INTERVAL' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_JSON' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_LONG' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_LONGLONG' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_LONG_BLOB' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_MEDIUM_BLOB' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_NEWDATE' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_NEWDECIMAL' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_NULL' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_SET' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_SHORT' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_STRING' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_TIME' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_TIMESTAMP' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_TINY' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_TINY_BLOB' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_VAR_STRING' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_VECTOR' => 'mysqli/mysqli.stub', 'MYSQLI_TYPE_YEAR' => 'mysqli/mysqli.stub', 'MYSQLI_UNIQUE_KEY_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_UNSIGNED_FLAG' => 'mysqli/mysqli.stub', 'MYSQLI_USE_RESULT' => 'mysqli/mysqli.stub', 'MYSQLI_ZEROFILL_FLAG' => 'mysqli/mysqli.stub', 'MYSQLX_LOCK_DEFAULT' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_LOCK_NOWAIT' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_LOCK_SKIP_LOCKED' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_BIGINT' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_BIT' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_BLOB' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_BYTES' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_CHAR' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_DATE' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_DATETIME' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_DECIMAL' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_DOUBLE' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_ENUM' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_FLOAT' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_GEOMETRY' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_INT' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_INT24' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_INTERVAL' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_JSON' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_LONG' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_LONGLONG' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_LONG_BLOB' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_MEDIUMINT' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_MEDIUM_BLOB' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_NEWDATE' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_NEWDECIMAL' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_NULL' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_SET' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_SHORT' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_SMALLINT' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_STRING' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_TIME' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_TIMESTAMP' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_TINY' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_TINY_BLOB' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_VAR_STRING' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQLX_TYPE_YEAR' => 'mysql_xdevapi/mysql_xdevapi.stub', 'MYSQL_ASSOC' => 'mysql/mysql.stub', 'MYSQL_BOTH' => 'mysql/mysql.stub', 'MYSQL_CLIENT_COMPRESS' => 'mysql/mysql.stub', 'MYSQL_CLIENT_IGNORE_SPACE' => 'mysql/mysql.stub', 'MYSQL_CLIENT_INTERACTIVE' => 'mysql/mysql.stub', 'MYSQL_CLIENT_SSL' => 'mysql/mysql.stub', 'MYSQL_NUM' => 'mysql/mysql.stub', 'M_1_PI' => 'standard/standard_defines.stub', 'M_2_PI' => 'standard/standard_defines.stub', 'M_2_SQRTPI' => 'standard/standard_defines.stub', 'M_E' => 'standard/standard_defines.stub', 'M_EULER' => 'standard/standard_defines.stub', 'M_LN10' => 'standard/standard_defines.stub', 'M_LN2' => 'standard/standard_defines.stub', 'M_LNPI' => 'standard/standard_defines.stub', 'M_LOG10E' => 'standard/standard_defines.stub', 'M_LOG2E' => 'standard/standard_defines.stub', 'M_PI' => 'standard/standard_defines.stub', 'M_PI_2' => 'standard/standard_defines.stub', 'M_PI_4' => 'standard/standard_defines.stub', 'M_SQRT1_2' => 'standard/standard_defines.stub', 'M_SQRT2' => 'standard/standard_defines.stub', 'M_SQRT3' => 'standard/standard_defines.stub', 'M_SQRTPI' => 'standard/standard_defines.stub', 'Menu' => 'winbinder/winbinder.stub', 'ModalDialog' => 'winbinder/winbinder.stub', 'ModelessDialog' => 'winbinder/winbinder.stub', 'NAN' => 'standard/standard_defines.stub', 'NCURSES_ALL_MOUSE_EVENTS' => 'ncurses/ncurses.stub', 'NCURSES_A_ALTCHARSET' => 'ncurses/ncurses.stub', 'NCURSES_A_BLINK' => 'ncurses/ncurses.stub', 'NCURSES_A_BOLD' => 'ncurses/ncurses.stub', 'NCURSES_A_CHARTEXT' => 'ncurses/ncurses.stub', 'NCURSES_A_DIM' => 'ncurses/ncurses.stub', 'NCURSES_A_INVIS' => 'ncurses/ncurses.stub', 'NCURSES_A_NORMAL' => 'ncurses/ncurses.stub', 'NCURSES_A_PROTECT' => 'ncurses/ncurses.stub', 'NCURSES_A_REVERSE' => 'ncurses/ncurses.stub', 'NCURSES_A_STANDOUT' => 'ncurses/ncurses.stub', 'NCURSES_A_UNDERLINE' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON1_CLICKED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON1_DOUBLE_CLICKED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON1_PRESSED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON1_RELEASED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON1_TRIPLE_CLICKED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON2_CLICKED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON2_DOUBLE_CLICKED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON2_PRESSED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON2_RELEASED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON2_TRIPLE_CLICKED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON3_CLICKED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON3_DOUBLE_CLICKED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON3_PRESSED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON3_RELEASED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON3_TRIPLE_CLICKED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON4_CLICKED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON4_DOUBLE_CLICKED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON4_PRESSED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON4_RELEASED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON4_TRIPLE_CLICKED' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON_ALT' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON_CTRL' => 'ncurses/ncurses.stub', 'NCURSES_BUTTON_SHIFT' => 'ncurses/ncurses.stub', 'NCURSES_COLOR_BLACK' => 'ncurses/ncurses.stub', 'NCURSES_COLOR_BLUE' => 'ncurses/ncurses.stub', 'NCURSES_COLOR_CYAN' => 'ncurses/ncurses.stub', 'NCURSES_COLOR_GREEN' => 'ncurses/ncurses.stub', 'NCURSES_COLOR_MAGENTA' => 'ncurses/ncurses.stub', 'NCURSES_COLOR_RED' => 'ncurses/ncurses.stub', 'NCURSES_COLOR_WHITE' => 'ncurses/ncurses.stub', 'NCURSES_COLOR_YELLOW' => 'ncurses/ncurses.stub', 'NCURSES_KEY_A1' => 'ncurses/ncurses.stub', 'NCURSES_KEY_A3' => 'ncurses/ncurses.stub', 'NCURSES_KEY_B2' => 'ncurses/ncurses.stub', 'NCURSES_KEY_BACKSPACE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_BEG' => 'ncurses/ncurses.stub', 'NCURSES_KEY_BTAB' => 'ncurses/ncurses.stub', 'NCURSES_KEY_C1' => 'ncurses/ncurses.stub', 'NCURSES_KEY_C3' => 'ncurses/ncurses.stub', 'NCURSES_KEY_CANCEL' => 'ncurses/ncurses.stub', 'NCURSES_KEY_CATAB' => 'ncurses/ncurses.stub', 'NCURSES_KEY_CLEAR' => 'ncurses/ncurses.stub', 'NCURSES_KEY_CLOSE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_COMMAND' => 'ncurses/ncurses.stub', 'NCURSES_KEY_COPY' => 'ncurses/ncurses.stub', 'NCURSES_KEY_CREATE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_CTAB' => 'ncurses/ncurses.stub', 'NCURSES_KEY_DC' => 'ncurses/ncurses.stub', 'NCURSES_KEY_DL' => 'ncurses/ncurses.stub', 'NCURSES_KEY_DOWN' => 'ncurses/ncurses.stub', 'NCURSES_KEY_EIC' => 'ncurses/ncurses.stub', 'NCURSES_KEY_END' => 'ncurses/ncurses.stub', 'NCURSES_KEY_ENTER' => 'ncurses/ncurses.stub', 'NCURSES_KEY_EOL' => 'ncurses/ncurses.stub', 'NCURSES_KEY_EOS' => 'ncurses/ncurses.stub', 'NCURSES_KEY_EXIT' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F0' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F1' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F10' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F11' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F12' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F2' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F3' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F4' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F5' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F6' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F7' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F8' => 'ncurses/ncurses.stub', 'NCURSES_KEY_F9' => 'ncurses/ncurses.stub', 'NCURSES_KEY_FIND' => 'ncurses/ncurses.stub', 'NCURSES_KEY_HELP' => 'ncurses/ncurses.stub', 'NCURSES_KEY_HOME' => 'ncurses/ncurses.stub', 'NCURSES_KEY_IC' => 'ncurses/ncurses.stub', 'NCURSES_KEY_IL' => 'ncurses/ncurses.stub', 'NCURSES_KEY_LEFT' => 'ncurses/ncurses.stub', 'NCURSES_KEY_LL' => 'ncurses/ncurses.stub', 'NCURSES_KEY_MARK' => 'ncurses/ncurses.stub', 'NCURSES_KEY_MESSAGE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_MOUSE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_MOVE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_NEXT' => 'ncurses/ncurses.stub', 'NCURSES_KEY_NPAGE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_OPEN' => 'ncurses/ncurses.stub', 'NCURSES_KEY_OPTIONS' => 'ncurses/ncurses.stub', 'NCURSES_KEY_PPAGE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_PREVIOUS' => 'ncurses/ncurses.stub', 'NCURSES_KEY_PRINT' => 'ncurses/ncurses.stub', 'NCURSES_KEY_REDO' => 'ncurses/ncurses.stub', 'NCURSES_KEY_REFERENCE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_REFRESH' => 'ncurses/ncurses.stub', 'NCURSES_KEY_REPLACE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_RESET' => 'ncurses/ncurses.stub', 'NCURSES_KEY_RESIZE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_RESTART' => 'ncurses/ncurses.stub', 'NCURSES_KEY_RESUME' => 'ncurses/ncurses.stub', 'NCURSES_KEY_RIGHT' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SAVE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SBEG' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SCANCEL' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SCOMMAND' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SCOPY' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SCREATE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SDC' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SDL' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SELECT' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SEND' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SEOL' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SEXIT' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SF' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SFIND' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SHELP' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SHOME' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SIC' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SLEFT' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SMESSAGE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SMOVE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SNEXT' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SOPTIONS' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SPREVIOUS' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SPRINT' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SR' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SREDO' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SREPLACE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SRESET' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SRIGHT' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SRSUME' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SSAVE' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SSUSPEND' => 'ncurses/ncurses.stub', 'NCURSES_KEY_STAB' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SUNDO' => 'ncurses/ncurses.stub', 'NCURSES_KEY_SUSPEND' => 'ncurses/ncurses.stub', 'NCURSES_KEY_UNDO' => 'ncurses/ncurses.stub', 'NCURSES_KEY_UP' => 'ncurses/ncurses.stub', 'NCURSES_REPORT_MOUSE_POSITION' => 'ncurses/ncurses.stub', 'NEGATIVE_SIGN' => 'standard/standard_defines.stub', 'NIL' => 'imap/imap.stub', 'NOCOLOR' => 'winbinder/winbinder.stub', 'NOEXPR' => 'standard/standard_defines.stub', 'NORM_IGNORECASE' => 'com_dotnet/com_dotnet.stub', 'NORM_IGNOREKANATYPE' => 'com_dotnet/com_dotnet.stub', 'NORM_IGNOREKASHIDA' => 'com_dotnet/com_dotnet.stub', 'NORM_IGNORENONSPACE' => 'com_dotnet/com_dotnet.stub', 'NORM_IGNORESYMBOLS' => 'com_dotnet/com_dotnet.stub', 'NORM_IGNOREWIDTH' => 'com_dotnet/com_dotnet.stub', 'NOSTR' => 'standard/standard_defines.stub', 'N_CS_PRECEDES' => 'standard/standard_defines.stub', 'N_SEP_BY_SPACE' => 'standard/standard_defines.stub', 'N_SIGN_POSN' => 'standard/standard_defines.stub', 'NakedWindow' => 'winbinder/winbinder.stub', 'OAUTH_AUTH_TYPE_AUTHORIZATION' => 'oauth/oauth.stub', 'OAUTH_AUTH_TYPE_FORM' => 'oauth/oauth.stub', 'OAUTH_AUTH_TYPE_NONE' => 'oauth/oauth.stub', 'OAUTH_AUTH_TYPE_URI' => 'oauth/oauth.stub', 'OAUTH_BAD_NONCE' => 'oauth/oauth.stub', 'OAUTH_BAD_TIMESTAMP' => 'oauth/oauth.stub', 'OAUTH_CONSUMER_KEY_REFUSED' => 'oauth/oauth.stub', 'OAUTH_CONSUMER_KEY_UNKNOWN' => 'oauth/oauth.stub', 'OAUTH_HTTP_METHOD_DELETE' => 'oauth/oauth.stub', 'OAUTH_HTTP_METHOD_GET' => 'oauth/oauth.stub', 'OAUTH_HTTP_METHOD_HEAD' => 'oauth/oauth.stub', 'OAUTH_HTTP_METHOD_POST' => 'oauth/oauth.stub', 'OAUTH_HTTP_METHOD_PUT' => 'oauth/oauth.stub', 'OAUTH_INVALID_SIGNATURE' => 'oauth/oauth.stub', 'OAUTH_OK' => 'oauth/oauth.stub', 'OAUTH_PARAMETER_ABSENT' => 'oauth/oauth.stub', 'OAUTH_REQENGINE_CURL' => 'oauth/oauth.stub', 'OAUTH_REQENGINE_STREAMS' => 'oauth/oauth.stub', 'OAUTH_SIGNATURE_METHOD_REJECTED' => 'oauth/oauth.stub', 'OAUTH_SIG_METHOD_HMACSHA1' => 'oauth/oauth.stub', 'OAUTH_SIG_METHOD_HMACSHA256' => 'oauth/oauth.stub', 'OAUTH_SIG_METHOD_RSASHA1' => 'oauth/oauth.stub', 'OAUTH_TOKEN_EXPIRED' => 'oauth/oauth.stub', 'OAUTH_TOKEN_REJECTED' => 'oauth/oauth.stub', 'OAUTH_TOKEN_USED' => 'oauth/oauth.stub', 'OAUTH_VERIFIER_INVALID' => 'oauth/oauth.stub', 'OCI_ASSOC' => 'oci8/oci8.stub', 'OCI_BOTH' => 'oci8/oci8.stub', 'OCI_B_BFILE' => 'oci8/oci8.stub', 'OCI_B_BIN' => 'oci8/oci8.stub', 'OCI_B_BLOB' => 'oci8/oci8.stub', 'OCI_B_BOL' => 'oci8/oci8.stub', 'OCI_B_CFILEE' => 'oci8/oci8.stub', 'OCI_B_CLOB' => 'oci8/oci8.stub', 'OCI_B_CURSOR' => 'oci8/oci8.stub', 'OCI_B_INT' => 'oci8/oci8.stub', 'OCI_B_NTY' => 'oci8/oci8.stub', 'OCI_B_NUM' => 'oci8/oci8.stub', 'OCI_B_ROWID' => 'oci8/oci8.stub', 'OCI_COMMIT_ON_SUCCESS' => 'oci8/oci8.stub', 'OCI_CRED_EXT' => 'oci8/oci8.stub', 'OCI_DEFAULT' => 'oci8/oci8.stub', 'OCI_DESCRIBE_ONLY' => 'oci8/oci8.stub', 'OCI_DTYPE_FILE' => 'oci8/oci8.stub', 'OCI_DTYPE_LOB' => 'oci8/oci8.stub', 'OCI_DTYPE_ROWID' => 'oci8/oci8.stub', 'OCI_D_FILE' => 'oci8/oci8.stub', 'OCI_D_LOB' => 'oci8/oci8.stub', 'OCI_D_ROWID' => 'oci8/oci8.stub', 'OCI_EXACT_FETCH' => 'oci8/oci8.stub', 'OCI_FETCHSTATEMENT_BY_COLUMN' => 'oci8/oci8.stub', 'OCI_FETCHSTATEMENT_BY_ROW' => 'oci8/oci8.stub', 'OCI_LOB_BUFFER_FREE' => 'oci8/oci8.stub', 'OCI_NO_AUTO_COMMIT' => 'oci8/oci8.stub', 'OCI_NUM' => 'oci8/oci8.stub', 'OCI_RETURN_LOBS' => 'oci8/oci8.stub', 'OCI_RETURN_NULLS' => 'oci8/oci8.stub', 'OCI_SEEK_CUR' => 'oci8/oci8.stub', 'OCI_SEEK_END' => 'oci8/oci8.stub', 'OCI_SEEK_SET' => 'oci8/oci8.stub', 'OCI_SYSDATE' => 'oci8/oci8.stub', 'OCI_SYSDBA' => 'oci8/oci8.stub', 'OCI_SYSOPER' => 'oci8/oci8.stub', 'OCI_TEMP_BLOB' => 'oci8/oci8.stub', 'OCI_TEMP_CLOB' => 'oci8/oci8.stub', 'ODBC_BINMODE_CONVERT' => 'odbc/odbc.stub', 'ODBC_BINMODE_PASSTHRU' => 'odbc/odbc.stub', 'ODBC_BINMODE_RETURN' => 'odbc/odbc.stub', 'ODBC_TYPE' => 'odbc/odbc.stub', 'OPENSSL_ALGO_DSS1' => 'openssl/openssl.stub', 'OPENSSL_ALGO_MD2' => 'openssl/openssl.stub', 'OPENSSL_ALGO_MD4' => 'openssl/openssl.stub', 'OPENSSL_ALGO_MD5' => 'openssl/openssl.stub', 'OPENSSL_ALGO_RMD160' => 'openssl/openssl.stub', 'OPENSSL_ALGO_SHA1' => 'openssl/openssl.stub', 'OPENSSL_ALGO_SHA224' => 'openssl/openssl.stub', 'OPENSSL_ALGO_SHA256' => 'openssl/openssl.stub', 'OPENSSL_ALGO_SHA384' => 'openssl/openssl.stub', 'OPENSSL_ALGO_SHA512' => 'openssl/openssl.stub', 'OPENSSL_CIPHER_3DES' => 'openssl/openssl.stub', 'OPENSSL_CIPHER_AES_128_CBC' => 'openssl/openssl.stub', 'OPENSSL_CIPHER_AES_192_CBC' => 'openssl/openssl.stub', 'OPENSSL_CIPHER_AES_256_CBC' => 'openssl/openssl.stub', 'OPENSSL_CIPHER_DES' => 'openssl/openssl.stub', 'OPENSSL_CIPHER_RC2_128' => 'openssl/openssl.stub', 'OPENSSL_CIPHER_RC2_40' => 'openssl/openssl.stub', 'OPENSSL_CIPHER_RC2_64' => 'openssl/openssl.stub', 'OPENSSL_CMS_BINARY' => 'openssl/openssl.stub', 'OPENSSL_CMS_DETACHED' => 'openssl/openssl.stub', 'OPENSSL_CMS_NOATTR' => 'openssl/openssl.stub', 'OPENSSL_CMS_NOCERTS' => 'openssl/openssl.stub', 'OPENSSL_CMS_NOINTERN' => 'openssl/openssl.stub', 'OPENSSL_CMS_NOSIGS' => 'openssl/openssl.stub', 'OPENSSL_CMS_NOVERIFY' => 'openssl/openssl.stub', 'OPENSSL_CMS_OLDMIMETYPE' => 'openssl/openssl.stub', 'OPENSSL_CMS_TEXT' => 'openssl/openssl.stub', 'OPENSSL_DEFAULT_STREAM_CIPHERS' => 'openssl/openssl.stub', 'OPENSSL_DONT_ZERO_PAD_KEY' => 'openssl/openssl.stub', 'OPENSSL_ENCODING_DER' => 'openssl/openssl.stub', 'OPENSSL_ENCODING_PEM' => 'openssl/openssl.stub', 'OPENSSL_ENCODING_SMIME' => 'openssl/openssl.stub', 'OPENSSL_KEYTYPE_DH' => 'openssl/openssl.stub', 'OPENSSL_KEYTYPE_DSA' => 'openssl/openssl.stub', 'OPENSSL_KEYTYPE_EC' => 'openssl/openssl.stub', 'OPENSSL_KEYTYPE_ED25519' => 'openssl/openssl.stub', 'OPENSSL_KEYTYPE_ED448' => 'openssl/openssl.stub', 'OPENSSL_KEYTYPE_RSA' => 'openssl/openssl.stub', 'OPENSSL_KEYTYPE_X25519' => 'openssl/openssl.stub', 'OPENSSL_KEYTYPE_X448' => 'openssl/openssl.stub', 'OPENSSL_NO_PADDING' => 'openssl/openssl.stub', 'OPENSSL_PKCS1_OAEP_PADDING' => 'openssl/openssl.stub', 'OPENSSL_PKCS1_PADDING' => 'openssl/openssl.stub', 'OPENSSL_RAW_DATA' => 'openssl/openssl.stub', 'OPENSSL_SSLV23_PADDING' => 'openssl/openssl.stub', 'OPENSSL_TLSEXT_SERVER_NAME' => 'openssl/openssl.stub', 'OPENSSL_VERSION_NUMBER' => 'openssl/openssl.stub', 'OPENSSL_VERSION_TEXT' => 'openssl/openssl.stub', 'OPENSSL_ZERO_PADDING' => 'openssl/openssl.stub', 'OP_ANONYMOUS' => 'imap/imap.stub', 'OP_DEBUG' => 'imap/imap.stub', 'OP_EXPUNGE' => 'imap/imap.stub', 'OP_HALFOPEN' => 'imap/imap.stub', 'OP_PROTOTYPE' => 'imap/imap.stub', 'OP_READONLY' => 'imap/imap.stub', 'OP_SECURE' => 'imap/imap.stub', 'OP_SHORTCACHE' => 'imap/imap.stub', 'OP_SILENT' => 'imap/imap.stub', 'O_APPEND' => 'dio/dio_d.stub', 'O_ASYNC' => 'dio/dio_d.stub', 'O_CREAT' => 'dio/dio_d.stub', 'O_EXCL' => 'dio/dio_d.stub', 'O_NDELAY' => 'dio/dio_d.stub', 'O_NOCTTY' => 'dio/dio_d.stub', 'O_NONBLOCK' => 'dio/dio_d.stub', 'O_RDONLY' => 'dio/dio_d.stub', 'O_RDWR' => 'dio/dio_d.stub', 'O_SYNC' => 'dio/dio_d.stub', 'O_TRUNC' => 'dio/dio_d.stub', 'O_WRONLY' => 'dio/dio_d.stub', 'PASSWORD_ARGON2I' => 'standard/password.stub', 'PASSWORD_ARGON2ID' => 'standard/password.stub', 'PASSWORD_ARGON2_DEFAULT_MEMORY_COST' => 'standard/password.stub', 'PASSWORD_ARGON2_DEFAULT_THREADS' => 'standard/password.stub', 'PASSWORD_ARGON2_DEFAULT_TIME_COST' => 'standard/password.stub', 'PASSWORD_ARGON2_PROVIDER' => 'standard/password.stub', 'PASSWORD_BCRYPT' => 'standard/password.stub', 'PASSWORD_BCRYPT_DEFAULT_COST' => 'standard/password.stub', 'PASSWORD_DEFAULT' => 'standard/password.stub', 'PATHINFO_ALL' => 'standard/standard_defines.stub', 'PATHINFO_BASENAME' => 'standard/standard_defines.stub', 'PATHINFO_DIRNAME' => 'standard/standard_defines.stub', 'PATHINFO_EXTENSION' => 'standard/standard_defines.stub', 'PATHINFO_FILENAME' => 'standard/standard_defines.stub', 'PATH_SEPARATOR' => 'standard/standard_defines.stub', 'PCNTL_E2BIG' => 'pcntl/pcntl.stub', 'PCNTL_EACCES' => 'pcntl/pcntl.stub', 'PCNTL_EAGAIN' => 'pcntl/pcntl.stub', 'PCNTL_ECHILD' => 'pcntl/pcntl.stub', 'PCNTL_EFAULT' => 'pcntl/pcntl.stub', 'PCNTL_EINTR' => 'pcntl/pcntl.stub', 'PCNTL_EINVAL' => 'pcntl/pcntl.stub', 'PCNTL_EIO' => 'pcntl/pcntl.stub', 'PCNTL_EISDIR' => 'pcntl/pcntl.stub', 'PCNTL_ELIBBAD' => 'pcntl/pcntl.stub', 'PCNTL_ELOOP' => 'pcntl/pcntl.stub', 'PCNTL_EMFILE' => 'pcntl/pcntl.stub', 'PCNTL_ENAMETOOLONG' => 'pcntl/pcntl.stub', 'PCNTL_ENFILE' => 'pcntl/pcntl.stub', 'PCNTL_ENOENT' => 'pcntl/pcntl.stub', 'PCNTL_ENOEXEC' => 'pcntl/pcntl.stub', 'PCNTL_ENOMEM' => 'pcntl/pcntl.stub', 'PCNTL_ENOSPC' => 'pcntl/pcntl.stub', 'PCNTL_ENOTDIR' => 'pcntl/pcntl.stub', 'PCNTL_EPERM' => 'pcntl/pcntl.stub', 'PCNTL_ESRCH' => 'pcntl/pcntl.stub', 'PCNTL_ETXTBSY' => 'pcntl/pcntl.stub', 'PCNTL_EUSERS' => 'pcntl/pcntl.stub', 'PCRE_JIT_SUPPORT' => 'pcre/pcre.stub', 'PCRE_VERSION' => 'pcre/pcre.stub', 'PCRE_VERSION_MAJOR' => 'pcre/pcre.stub', 'PCRE_VERSION_MINOR' => 'pcre/pcre.stub', 'PEAR_EXTENSION_DIR' => 'Core/Core_d.stub', 'PEAR_INSTALL_DIR' => 'Core/Core_d.stub', 'PGSQL_ASSOC' => 'pgsql/pgsql.stub', 'PGSQL_BAD_RESPONSE' => 'pgsql/pgsql.stub', 'PGSQL_BOTH' => 'pgsql/pgsql.stub', 'PGSQL_COMMAND_OK' => 'pgsql/pgsql.stub', 'PGSQL_CONNECTION_AUTH_OK' => 'pgsql/pgsql.stub', 'PGSQL_CONNECTION_AWAITING_RESPONSE' => 'pgsql/pgsql.stub', 'PGSQL_CONNECTION_BAD' => 'pgsql/pgsql.stub', 'PGSQL_CONNECTION_MADE' => 'pgsql/pgsql.stub', 'PGSQL_CONNECTION_OK' => 'pgsql/pgsql.stub', 'PGSQL_CONNECTION_SETENV' => 'pgsql/pgsql.stub', 'PGSQL_CONNECTION_STARTED' => 'pgsql/pgsql.stub', 'PGSQL_CONNECT_ASYNC' => 'pgsql/pgsql.stub', 'PGSQL_CONNECT_FORCE_NEW' => 'pgsql/pgsql.stub', 'PGSQL_CONV_FORCE_NULL' => 'pgsql/pgsql.stub', 'PGSQL_CONV_IGNORE_DEFAULT' => 'pgsql/pgsql.stub', 'PGSQL_CONV_IGNORE_NOT_NULL' => 'pgsql/pgsql.stub', 'PGSQL_COPY_IN' => 'pgsql/pgsql.stub', 'PGSQL_COPY_OUT' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_COLUMN_NAME' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_CONSTRAINT_NAME' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_CONTEXT' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_DATATYPE_NAME' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_INTERNAL_POSITION' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_INTERNAL_QUERY' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_MESSAGE_DETAIL' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_MESSAGE_HINT' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_MESSAGE_PRIMARY' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_SCHEMA_NAME' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_SEVERITY' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_SEVERITY_NONLOCALIZED' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_SOURCE_FILE' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_SOURCE_FUNCTION' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_SOURCE_LINE' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_SQLSTATE' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_STATEMENT_POSITION' => 'pgsql/pgsql.stub', 'PGSQL_DIAG_TABLE_NAME' => 'pgsql/pgsql.stub', 'PGSQL_DML_ASYNC' => 'pgsql/pgsql.stub', 'PGSQL_DML_ESCAPE' => 'pgsql/pgsql.stub', 'PGSQL_DML_EXEC' => 'pgsql/pgsql.stub', 'PGSQL_DML_NO_CONV' => 'pgsql/pgsql.stub', 'PGSQL_DML_STRING' => 'pgsql/pgsql.stub', 'PGSQL_EMPTY_QUERY' => 'pgsql/pgsql.stub', 'PGSQL_ERRORS_DEFAULT' => 'pgsql/pgsql.stub', 'PGSQL_ERRORS_SQLSTATE' => 'pgsql/pgsql.stub', 'PGSQL_ERRORS_TERSE' => 'pgsql/pgsql.stub', 'PGSQL_ERRORS_VERBOSE' => 'pgsql/pgsql.stub', 'PGSQL_FATAL_ERROR' => 'pgsql/pgsql.stub', 'PGSQL_LIBPQ_VERSION' => 'pgsql/pgsql.stub', 'PGSQL_LIBPQ_VERSION_STR' => 'pgsql/pgsql.stub', 'PGSQL_NONFATAL_ERROR' => 'pgsql/pgsql.stub', 'PGSQL_NOTICE_ALL' => 'pgsql/pgsql.stub', 'PGSQL_NOTICE_CLEAR' => 'pgsql/pgsql.stub', 'PGSQL_NOTICE_LAST' => 'pgsql/pgsql.stub', 'PGSQL_NUM' => 'pgsql/pgsql.stub', 'PGSQL_PIPELINE_ABORTED' => 'pgsql/pgsql.stub', 'PGSQL_PIPELINE_OFF' => 'pgsql/pgsql.stub', 'PGSQL_PIPELINE_ON' => 'pgsql/pgsql.stub', 'PGSQL_PIPELINE_SYNC' => 'pgsql/pgsql.stub', 'PGSQL_POLLING_ACTIVE' => 'pgsql/pgsql.stub', 'PGSQL_POLLING_FAILED' => 'pgsql/pgsql.stub', 'PGSQL_POLLING_OK' => 'pgsql/pgsql.stub', 'PGSQL_POLLING_READING' => 'pgsql/pgsql.stub', 'PGSQL_POLLING_WRITING' => 'pgsql/pgsql.stub', 'PGSQL_SEEK_CUR' => 'pgsql/pgsql.stub', 'PGSQL_SEEK_END' => 'pgsql/pgsql.stub', 'PGSQL_SEEK_SET' => 'pgsql/pgsql.stub', 'PGSQL_SHOW_CONTEXT_ALWAYS' => 'pgsql/pgsql.stub', 'PGSQL_SHOW_CONTEXT_ERRORS' => 'pgsql/pgsql.stub', 'PGSQL_SHOW_CONTEXT_NEVER' => 'pgsql/pgsql.stub', 'PGSQL_STATUS_LONG' => 'pgsql/pgsql.stub', 'PGSQL_STATUS_STRING' => 'pgsql/pgsql.stub', 'PGSQL_TRACE_REGRESS_MODE' => 'pgsql/pgsql.stub', 'PGSQL_TRANSACTION_ACTIVE' => 'pgsql/pgsql.stub', 'PGSQL_TRANSACTION_IDLE' => 'pgsql/pgsql.stub', 'PGSQL_TRANSACTION_INERROR' => 'pgsql/pgsql.stub', 'PGSQL_TRANSACTION_INTRANS' => 'pgsql/pgsql.stub', 'PGSQL_TRANSACTION_UNKNOWN' => 'pgsql/pgsql.stub', 'PGSQL_TUPLES_OK' => 'pgsql/pgsql.stub', 'PHP_AMQP_MAX_CHANNELS' => 'amqp/amqp.stub', 'PHP_BINARY' => 'Core/Core_d.stub', 'PHP_BINARY_READ' => 'sockets/sockets.stub', 'PHP_BINDIR' => 'Core/Core_d.stub', 'PHP_CLI_PROCESS_TITLE' => 'Core/Core_d.stub', 'PHP_CONFIG_FILE_PATH' => 'Core/Core_d.stub', 'PHP_CONFIG_FILE_SCAN_DIR' => 'Core/Core_d.stub', 'PHP_DATADIR' => 'Core/Core_d.stub', 'PHP_DEBUG' => 'Core/Core_d.stub', 'PHP_EOL' => 'Core/Core_d.stub', 'PHP_EXTENSION_DIR' => 'Core/Core_d.stub', 'PHP_EXTRA_VERSION' => 'Core/Core_d.stub', 'PHP_FD_SETSIZE' => 'Core/Core_d.stub', 'PHP_FLOAT_DIG' => 'Core/Core_d.stub', 'PHP_FLOAT_EPSILON' => 'Core/Core_d.stub', 'PHP_FLOAT_MAX' => 'Core/Core_d.stub', 'PHP_FLOAT_MIN' => 'Core/Core_d.stub', 'PHP_INT_MAX' => 'Core/Core_d.stub', 'PHP_INT_MIN' => 'Core/Core_d.stub', 'PHP_INT_SIZE' => 'Core/Core_d.stub', 'PHP_LIBDIR' => 'Core/Core_d.stub', 'PHP_LOCALSTATEDIR' => 'Core/Core_d.stub', 'PHP_MAJOR_VERSION' => 'Core/Core_d.stub', 'PHP_MANDIR' => 'Core/Core_d.stub', 'PHP_MAXPATHLEN' => 'Core/Core_d.stub', 'PHP_MINOR_VERSION' => 'Core/Core_d.stub', 'PHP_NORMAL_READ' => 'sockets/sockets.stub', 'PHP_OS' => 'Core/Core_d.stub', 'PHP_OS_FAMILY' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_CLEAN' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_CLEANABLE' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_CONT' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_DISABLED' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_END' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_FINAL' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_FLUSH' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_FLUSHABLE' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_PROCESSED' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_REMOVABLE' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_START' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_STARTED' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_STDFLAGS' => 'Core/Core_d.stub', 'PHP_OUTPUT_HANDLER_WRITE' => 'Core/Core_d.stub', 'PHP_PREFIX' => 'Core/Core_d.stub', 'PHP_QUERY_RFC1738' => 'standard/standard_defines.stub', 'PHP_QUERY_RFC3986' => 'standard/standard_defines.stub', 'PHP_RELEASE_VERSION' => 'Core/Core_d.stub', 'PHP_ROUND_HALF_DOWN' => 'standard/standard_defines.stub', 'PHP_ROUND_HALF_EVEN' => 'standard/standard_defines.stub', 'PHP_ROUND_HALF_ODD' => 'standard/standard_defines.stub', 'PHP_ROUND_HALF_UP' => 'standard/standard_defines.stub', 'PHP_SAPI' => 'Core/Core_d.stub', 'PHP_SBINDIR' => 'Core/Core_d.stub', 'PHP_SESSION_ACTIVE' => 'standard/standard_defines.stub', 'PHP_SESSION_DISABLED' => 'standard/standard_defines.stub', 'PHP_SESSION_NONE' => 'standard/standard_defines.stub', 'PHP_SHLIB_SUFFIX' => 'Core/Core_d.stub', 'PHP_SVN_AUTH_PARAM_IGNORE_SSL_VERIFY_ERRORS' => 'svn/svn.stub', 'PHP_SYSCONFDIR' => 'Core/Core_d.stub', 'PHP_URL_FRAGMENT' => 'standard/standard_defines.stub', 'PHP_URL_HOST' => 'standard/standard_defines.stub', 'PHP_URL_PASS' => 'standard/standard_defines.stub', 'PHP_URL_PATH' => 'standard/standard_defines.stub', 'PHP_URL_PORT' => 'standard/standard_defines.stub', 'PHP_URL_QUERY' => 'standard/standard_defines.stub', 'PHP_URL_SCHEME' => 'standard/standard_defines.stub', 'PHP_URL_USER' => 'standard/standard_defines.stub', 'PHP_VERSION' => 'Core/Core_d.stub', 'PHP_VERSION_ID' => 'Core/Core_d.stub', 'PHP_WINDOWS_EVENT_CTRL_BREAK' => 'Core/Core_d.stub', 'PHP_WINDOWS_EVENT_CTRL_C' => 'Core/Core_d.stub', 'PHP_WINDOWS_NT_DOMAIN_CONTROLLER' => 'Core/Core_d.stub', 'PHP_WINDOWS_NT_SERVER' => 'Core/Core_d.stub', 'PHP_WINDOWS_NT_WORKSTATION' => 'Core/Core_d.stub', 'PHP_WINDOWS_VERSION_BUILD' => 'Core/Core_d.stub', 'PHP_WINDOWS_VERSION_MAJOR' => 'Core/Core_d.stub', 'PHP_WINDOWS_VERSION_MINOR' => 'Core/Core_d.stub', 'PHP_WINDOWS_VERSION_PLATFORM' => 'Core/Core_d.stub', 'PHP_WINDOWS_VERSION_PRODUCTTYPE' => 'Core/Core_d.stub', 'PHP_WINDOWS_VERSION_SP_MAJOR' => 'Core/Core_d.stub', 'PHP_WINDOWS_VERSION_SP_MINOR' => 'Core/Core_d.stub', 'PHP_WINDOWS_VERSION_SUITEMASK' => 'Core/Core_d.stub', 'PHP_ZTS' => 'Core/Core_d.stub', 'PKCS7_BINARY' => 'openssl/openssl.stub', 'PKCS7_DETACHED' => 'openssl/openssl.stub', 'PKCS7_NOATTR' => 'openssl/openssl.stub', 'PKCS7_NOCERTS' => 'openssl/openssl.stub', 'PKCS7_NOCHAIN' => 'openssl/openssl.stub', 'PKCS7_NOINTERN' => 'openssl/openssl.stub', 'PKCS7_NOOLDMIMETYPE' => 'openssl/openssl.stub', 'PKCS7_NOSIGS' => 'openssl/openssl.stub', 'PKCS7_NOVERIFY' => 'openssl/openssl.stub', 'PKCS7_TEXT' => 'openssl/openssl.stub', 'PM_STR' => 'standard/standard_defines.stub', 'PNG_ALL_FILTERS' => 'gd/gd.stub', 'PNG_FILTER_AVG' => 'gd/gd.stub', 'PNG_FILTER_NONE' => 'gd/gd.stub', 'PNG_FILTER_PAETH' => 'gd/gd.stub', 'PNG_FILTER_SUB' => 'gd/gd.stub', 'PNG_FILTER_UP' => 'gd/gd.stub', 'PNG_NO_FILTER' => 'gd/gd.stub', 'POLL_ERR' => 'pcntl/pcntl.stub', 'POLL_HUP' => 'pcntl/pcntl.stub', 'POLL_IN' => 'pcntl/pcntl.stub', 'POLL_MSG' => 'pcntl/pcntl.stub', 'POLL_OUT' => 'pcntl/pcntl.stub', 'POLL_PRI' => 'pcntl/pcntl.stub', 'POSITIVE_SIGN' => 'standard/standard_defines.stub', 'POSIX_F_OK' => 'posix/posix.stub', 'POSIX_PC_ALLOC_SIZE_MIN' => 'posix/posix.stub', 'POSIX_PC_CHOWN_RESTRICTED' => 'posix/posix.stub', 'POSIX_PC_LINK_MAX' => 'posix/posix.stub', 'POSIX_PC_MAX_CANON' => 'posix/posix.stub', 'POSIX_PC_MAX_INPUT' => 'posix/posix.stub', 'POSIX_PC_NAME_MAX' => 'posix/posix.stub', 'POSIX_PC_NO_TRUNC' => 'posix/posix.stub', 'POSIX_PC_PATH_MAX' => 'posix/posix.stub', 'POSIX_PC_PIPE_BUF' => 'posix/posix.stub', 'POSIX_PC_SYMLINK_MAX' => 'posix/posix.stub', 'POSIX_RLIMIT_AS' => 'posix/posix.stub', 'POSIX_RLIMIT_CORE' => 'posix/posix.stub', 'POSIX_RLIMIT_CPU' => 'posix/posix.stub', 'POSIX_RLIMIT_DATA' => 'posix/posix.stub', 'POSIX_RLIMIT_FSIZE' => 'posix/posix.stub', 'POSIX_RLIMIT_INFINITY' => 'posix/posix.stub', 'POSIX_RLIMIT_LOCKS' => 'posix/posix.stub', 'POSIX_RLIMIT_MEMLOCK' => 'posix/posix.stub', 'POSIX_RLIMIT_MSGQUEUE' => 'posix/posix.stub', 'POSIX_RLIMIT_NICE' => 'posix/posix.stub', 'POSIX_RLIMIT_NOFILE' => 'posix/posix.stub', 'POSIX_RLIMIT_NPROC' => 'posix/posix.stub', 'POSIX_RLIMIT_RSS' => 'posix/posix.stub', 'POSIX_RLIMIT_RTPRIO' => 'posix/posix.stub', 'POSIX_RLIMIT_RTTIME' => 'posix/posix.stub', 'POSIX_RLIMIT_SIGPENDING' => 'posix/posix.stub', 'POSIX_RLIMIT_STACK' => 'posix/posix.stub', 'POSIX_R_OK' => 'posix/posix.stub', 'POSIX_SC_ARG_MAX' => 'posix/posix.stub', 'POSIX_SC_CHILD_MAX' => 'posix/posix.stub', 'POSIX_SC_CLK_TCK' => 'posix/posix.stub', 'POSIX_SC_NPROCESSORS_CONF' => 'posix/posix.stub', 'POSIX_SC_NPROCESSORS_ONLN' => 'posix/posix.stub', 'POSIX_SC_PAGESIZE' => 'posix/posix.stub', 'POSIX_S_IFBLK' => 'posix/posix.stub', 'POSIX_S_IFCHR' => 'posix/posix.stub', 'POSIX_S_IFIFO' => 'posix/posix.stub', 'POSIX_S_IFREG' => 'posix/posix.stub', 'POSIX_S_IFSOCK' => 'posix/posix.stub', 'POSIX_W_OK' => 'posix/posix.stub', 'POSIX_X_OK' => 'posix/posix.stub', 'PREG_BACKTRACK_LIMIT_ERROR' => 'pcre/pcre.stub', 'PREG_BAD_UTF8_ERROR' => 'pcre/pcre.stub', 'PREG_BAD_UTF8_OFFSET_ERROR' => 'pcre/pcre.stub', 'PREG_GREP_INVERT' => 'pcre/pcre.stub', 'PREG_INTERNAL_ERROR' => 'pcre/pcre.stub', 'PREG_JIT_STACKLIMIT_ERROR' => 'pcre/pcre.stub', 'PREG_NO_ERROR' => 'pcre/pcre.stub', 'PREG_OFFSET_CAPTURE' => 'pcre/pcre.stub', 'PREG_PATTERN_ORDER' => 'pcre/pcre.stub', 'PREG_RECURSION_LIMIT_ERROR' => 'pcre/pcre.stub', 'PREG_SET_ORDER' => 'pcre/pcre.stub', 'PREG_SPLIT_DELIM_CAPTURE' => 'pcre/pcre.stub', 'PREG_SPLIT_NO_EMPTY' => 'pcre/pcre.stub', 'PREG_SPLIT_OFFSET_CAPTURE' => 'pcre/pcre.stub', 'PREG_UNMATCHED_AS_NULL' => 'pcre/pcre.stub', 'PRIO_PGRP' => 'pcntl/pcntl.stub', 'PRIO_PROCESS' => 'pcntl/pcntl.stub', 'PRIO_USER' => 'pcntl/pcntl.stub', 'PSFS_ERR_FATAL' => 'standard/standard_defines.stub', 'PSFS_FEED_ME' => 'standard/standard_defines.stub', 'PSFS_FLAG_FLUSH_CLOSE' => 'standard/standard_defines.stub', 'PSFS_FLAG_FLUSH_INC' => 'standard/standard_defines.stub', 'PSFS_FLAG_NORMAL' => 'standard/standard_defines.stub', 'PSFS_PASS_ON' => 'standard/standard_defines.stub', 'PSPELL_BAD_SPELLERS' => 'pspell/pspell.stub', 'PSPELL_FAST' => 'pspell/pspell.stub', 'PSPELL_NORMAL' => 'pspell/pspell.stub', 'PSPELL_RUN_TOGETHER' => 'pspell/pspell.stub', 'PTHREADS_ALLOW_HEADERS' => 'pthreads/pthreads.stub', 'PTHREADS_INHERIT_ALL' => 'pthreads/pthreads.stub', 'PTHREADS_INHERIT_CLASSES' => 'pthreads/pthreads.stub', 'PTHREADS_INHERIT_COMMENTS' => 'pthreads/pthreads.stub', 'PTHREADS_INHERIT_CONSTANTS' => 'pthreads/pthreads.stub', 'PTHREADS_INHERIT_FUNCTIONS' => 'pthreads/pthreads.stub', 'PTHREADS_INHERIT_INCLUDES' => 'pthreads/pthreads.stub', 'PTHREADS_INHERIT_INI' => 'pthreads/pthreads.stub', 'PTHREADS_INHERIT_NONE' => 'pthreads/pthreads.stub', 'P_ALL' => 'pcntl/pcntl.stub', 'P_CS_PRECEDES' => 'standard/standard_defines.stub', 'P_PGID' => 'pcntl/pcntl.stub', 'P_PID' => 'pcntl/pcntl.stub', 'P_PIDFD' => 'pcntl/pcntl.stub', 'P_SEP_BY_SPACE' => 'standard/standard_defines.stub', 'P_SIGN_POSN' => 'standard/standard_defines.stub', 'PopupWindow' => 'winbinder/winbinder.stub', 'PushButton' => 'winbinder/winbinder.stub', 'RADIUS_ACCESS_ACCEPT' => 'radius/radius.stub', 'RADIUS_ACCESS_CHALLENGE' => 'radius/radius.stub', 'RADIUS_ACCESS_REJECT' => 'radius/radius.stub', 'RADIUS_ACCESS_REQUEST' => 'radius/radius.stub', 'RADIUS_ACCOUNTING_OFF' => 'radius/radius.stub', 'RADIUS_ACCOUNTING_ON' => 'radius/radius.stub', 'RADIUS_ACCOUNTING_REQUEST' => 'radius/radius.stub', 'RADIUS_ACCOUNTING_RESPONSE' => 'radius/radius.stub', 'RADIUS_ACCT_AUTHENTIC' => 'radius/radius.stub', 'RADIUS_ACCT_DELAY_TIME' => 'radius/radius.stub', 'RADIUS_ACCT_INPUT_OCTETS' => 'radius/radius.stub', 'RADIUS_ACCT_INPUT_PACKETS' => 'radius/radius.stub', 'RADIUS_ACCT_LINK_COUNT' => 'radius/radius.stub', 'RADIUS_ACCT_MULTI_SESSION_ID' => 'radius/radius.stub', 'RADIUS_ACCT_OUTPUT_OCTETS' => 'radius/radius.stub', 'RADIUS_ACCT_OUTPUT_PACKETS' => 'radius/radius.stub', 'RADIUS_ACCT_SESSION_ID' => 'radius/radius.stub', 'RADIUS_ACCT_SESSION_TIME' => 'radius/radius.stub', 'RADIUS_ACCT_STATUS_TYPE' => 'radius/radius.stub', 'RADIUS_ACCT_TERMINATE_CAUSE' => 'radius/radius.stub', 'RADIUS_ADMINISTRATIVE' => 'radius/radius.stub', 'RADIUS_ADSL_CAP' => 'radius/radius.stub', 'RADIUS_ADSL_DMT' => 'radius/radius.stub', 'RADIUS_ARAP' => 'radius/radius.stub', 'RADIUS_ASYNC' => 'radius/radius.stub', 'RADIUS_AUTHENTICATE_ONLY' => 'radius/radius.stub', 'RADIUS_AUTH_LOCAL' => 'radius/radius.stub', 'RADIUS_AUTH_RADIUS' => 'radius/radius.stub', 'RADIUS_AUTH_REMOTE' => 'radius/radius.stub', 'RADIUS_CABLE' => 'radius/radius.stub', 'RADIUS_CALLBACK_FRAMED' => 'radius/radius.stub', 'RADIUS_CALLBACK_ID' => 'radius/radius.stub', 'RADIUS_CALLBACK_LOGIN' => 'radius/radius.stub', 'RADIUS_CALLBACK_NAS_PROMPT' => 'radius/radius.stub', 'RADIUS_CALLBACK_NUMBER' => 'radius/radius.stub', 'RADIUS_CALLED_STATION_ID' => 'radius/radius.stub', 'RADIUS_CALLING_STATION_ID' => 'radius/radius.stub', 'RADIUS_CHAP_CHALLENGE' => 'radius/radius.stub', 'RADIUS_CHAP_PASSWORD' => 'radius/radius.stub', 'RADIUS_CLASS' => 'radius/radius.stub', 'RADIUS_COA_ACK' => 'radius/radius.stub', 'RADIUS_COA_NAK' => 'radius/radius.stub', 'RADIUS_COA_REQUEST' => 'radius/radius.stub', 'RADIUS_COMP_IPXHDR' => 'radius/radius.stub', 'RADIUS_COMP_NONE' => 'radius/radius.stub', 'RADIUS_COMP_VJ' => 'radius/radius.stub', 'RADIUS_CONNECT_INFO' => 'radius/radius.stub', 'RADIUS_DISCONNECT_ACK' => 'radius/radius.stub', 'RADIUS_DISCONNECT_NAK' => 'radius/radius.stub', 'RADIUS_DISCONNECT_REQUEST' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_ADMINISTRATIVELY_PROHIBITED' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_INVALID_EAP_PACKET' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_INVALID_REQUEST' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_MISSING_ATTRIBUTE' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_NAS_IDENTIFICATION_MISMATCH' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_OTHER_PROXY_PROCESSING_ERROR' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_REQUEST_INITIATED' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_REQUEST_NOT_ROUTABLE' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_RESIDUAL_SESSION_CONTEXT_REMOVED' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_RESOURCES_UNAVAILABLE' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_SESSION_CONTEXT_NOT_FOUND' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_SESSION_CONTEXT_NOT_REMOVABLE' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_UNSUPPORTED_ATTRIBUTE' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_UNSUPPORTED_EXCEPTION' => 'radius/radius.stub', 'RADIUS_ERROR_CAUSE_UNSUPPORTED_SERVICE' => 'radius/radius.stub', 'RADIUS_ETHERNET' => 'radius/radius.stub', 'RADIUS_FILTER_ID' => 'radius/radius.stub', 'RADIUS_FRAMED' => 'radius/radius.stub', 'RADIUS_FRAMED_APPLETALK_LINK' => 'radius/radius.stub', 'RADIUS_FRAMED_APPLETALK_NETWORK' => 'radius/radius.stub', 'RADIUS_FRAMED_APPLETALK_ZONE' => 'radius/radius.stub', 'RADIUS_FRAMED_COMPRESSION' => 'radius/radius.stub', 'RADIUS_FRAMED_INTERFACE_ID' => 'radius/radius.stub', 'RADIUS_FRAMED_IPV6_POOL' => 'radius/radius.stub', 'RADIUS_FRAMED_IPV6_PREFIX' => 'radius/radius.stub', 'RADIUS_FRAMED_IPV6_ROUTE' => 'radius/radius.stub', 'RADIUS_FRAMED_IPX_NETWORK' => 'radius/radius.stub', 'RADIUS_FRAMED_IP_ADDRESS' => 'radius/radius.stub', 'RADIUS_FRAMED_IP_NETMASK' => 'radius/radius.stub', 'RADIUS_FRAMED_MTU' => 'radius/radius.stub', 'RADIUS_FRAMED_PROTOCOL' => 'radius/radius.stub', 'RADIUS_FRAMED_ROUTE' => 'radius/radius.stub', 'RADIUS_FRAMED_ROUTING' => 'radius/radius.stub', 'RADIUS_GANDALF' => 'radius/radius.stub', 'RADIUS_G_3_FAX' => 'radius/radius.stub', 'RADIUS_HDLC_CLEAR_CHANNEL' => 'radius/radius.stub', 'RADIUS_IDLE_TIMEOUT' => 'radius/radius.stub', 'RADIUS_IDSL' => 'radius/radius.stub', 'RADIUS_ISDN_ASYNC_V110' => 'radius/radius.stub', 'RADIUS_ISDN_ASYNC_V120' => 'radius/radius.stub', 'RADIUS_ISDN_SYNC' => 'radius/radius.stub', 'RADIUS_LOGIN' => 'radius/radius.stub', 'RADIUS_LOGIN_IPV6_HOST' => 'radius/radius.stub', 'RADIUS_LOGIN_IP_HOST' => 'radius/radius.stub', 'RADIUS_LOGIN_LAT_GROUP' => 'radius/radius.stub', 'RADIUS_LOGIN_LAT_NODE' => 'radius/radius.stub', 'RADIUS_LOGIN_LAT_PORT' => 'radius/radius.stub', 'RADIUS_LOGIN_LAT_SERVICE' => 'radius/radius.stub', 'RADIUS_LOGIN_SERVICE' => 'radius/radius.stub', 'RADIUS_LOGIN_TCP_PORT' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_ACCT_AUTH_TYPE' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_ACCT_EAP_TYPE' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_ARAP_CHALLENGE' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_ARAP_PASSWORD_CHANGE_REASON' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_BAP_USAGE' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_CHAP2_PW' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_CHAP2_RESPONSE' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_CHAP2_SUCCESS' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_CHAP_CHALLENGE' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_CHAP_DOMAIN' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_CHAP_ERROR' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_CHAP_LM_ENC_PW' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_CHAP_MPPE_KEYS' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_CHAP_NT_ENC_PW' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_CHAP_PW_1' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_CHAP_PW_2' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_CHAP_RESPONSE' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_FILTER' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_LINK_DROP_TIME_LIMIT' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_LINK_UTILIZATION_THRESHOLD' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_MPPE_RECV_KEY' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_MPPE_SEND_KEY' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_NEW_ARAP_PASSWORD' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_OLD_ARAP_PASSWORD' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_PRIMARY_DNS_SERVER' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_PRIMARY_NBNS_SERVER' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_RAS_VENDOR' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_RAS_VERSION' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_SECONDARY_DNS_SERVER' => 'radius/radius.stub', 'RADIUS_MICROSOFT_MS_SECONDARY_NBNS_SERVER' => 'radius/radius.stub', 'RADIUS_MPPE_KEY_LEN' => 'radius/radius.stub', 'RADIUS_NAS_IDENTIFIER' => 'radius/radius.stub', 'RADIUS_NAS_IPV6_ADDRESS' => 'radius/radius.stub', 'RADIUS_NAS_IP_ADDRESS' => 'radius/radius.stub', 'RADIUS_NAS_PORT' => 'radius/radius.stub', 'RADIUS_NAS_PORT_TYPE' => 'radius/radius.stub', 'RADIUS_NAS_PROMPT' => 'radius/radius.stub', 'RADIUS_OPTION_NONE' => 'radius/radius.stub', 'RADIUS_OPTION_SALT' => 'radius/radius.stub', 'RADIUS_OPTION_TAGGED' => 'radius/radius.stub', 'RADIUS_OUTBOUND' => 'radius/radius.stub', 'RADIUS_PIAFS' => 'radius/radius.stub', 'RADIUS_PORT_LIMIT' => 'radius/radius.stub', 'RADIUS_PPP' => 'radius/radius.stub', 'RADIUS_PROXY_STATE' => 'radius/radius.stub', 'RADIUS_REPLY_MESSAGE' => 'radius/radius.stub', 'RADIUS_SDSL' => 'radius/radius.stub', 'RADIUS_SERVICE_TYPE' => 'radius/radius.stub', 'RADIUS_SESSION_TIMEOUT' => 'radius/radius.stub', 'RADIUS_SLIP' => 'radius/radius.stub', 'RADIUS_START' => 'radius/radius.stub', 'RADIUS_STATE' => 'radius/radius.stub', 'RADIUS_STOP' => 'radius/radius.stub', 'RADIUS_SYNC' => 'radius/radius.stub', 'RADIUS_TERMINATION_ACTION' => 'radius/radius.stub', 'RADIUS_TERM_ADMIN_REBOOT' => 'radius/radius.stub', 'RADIUS_TERM_ADMIN_RESET' => 'radius/radius.stub', 'RADIUS_TERM_CALLBACK' => 'radius/radius.stub', 'RADIUS_TERM_HOST_REQUEST' => 'radius/radius.stub', 'RADIUS_TERM_IDLE_TIMEOUT' => 'radius/radius.stub', 'RADIUS_TERM_LOST_CARRIER' => 'radius/radius.stub', 'RADIUS_TERM_LOST_SERVICE' => 'radius/radius.stub', 'RADIUS_TERM_NAS_ERROR' => 'radius/radius.stub', 'RADIUS_TERM_NAS_REBOOT' => 'radius/radius.stub', 'RADIUS_TERM_NAS_REQUEST' => 'radius/radius.stub', 'RADIUS_TERM_PORT_ERROR' => 'radius/radius.stub', 'RADIUS_TERM_PORT_PREEMPTED' => 'radius/radius.stub', 'RADIUS_TERM_PORT_SUSPENDED' => 'radius/radius.stub', 'RADIUS_TERM_PORT_UNNEEDED' => 'radius/radius.stub', 'RADIUS_TERM_SERVICE_UNAVAILABLE' => 'radius/radius.stub', 'RADIUS_TERM_SESSION_TIMEOUT' => 'radius/radius.stub', 'RADIUS_TERM_USER_ERROR' => 'radius/radius.stub', 'RADIUS_TERM_USER_REQUEST' => 'radius/radius.stub', 'RADIUS_USER_NAME' => 'radius/radius.stub', 'RADIUS_USER_PASSWORD' => 'radius/radius.stub', 'RADIUS_VENDOR_MICROSOFT' => 'radius/radius.stub', 'RADIUS_VENDOR_SPECIFIC' => 'radius/radius.stub', 'RADIUS_VIRTUAL' => 'radius/radius.stub', 'RADIUS_WIRELESS_IEEE_802_11' => 'radius/radius.stub', 'RADIUS_WIRELESS_OTHER' => 'radius/radius.stub', 'RADIUS_XDSL' => 'radius/radius.stub', 'RADIUS_XYLOGICS' => 'radius/radius.stub', 'RADIUS_X_25' => 'radius/radius.stub', 'RADIUS_X_75' => 'radius/radius.stub', 'RADIXCHAR' => 'standard/standard_defines.stub', 'RAD_OPTION_TAG' => 'radius/radius.stub', 'RD_KAFKA_BUILD_VERSION' => 'rdkafka/constants.stub', 'RD_KAFKA_CONF_INVALID' => 'rdkafka/constants.stub', 'RD_KAFKA_CONF_OK' => 'rdkafka/constants.stub', 'RD_KAFKA_CONF_UNKNOWN' => 'rdkafka/constants.stub', 'RD_KAFKA_CONSUMER' => 'rdkafka/constants.stub', 'RD_KAFKA_LOG_PRINT' => 'rdkafka/constants.stub', 'RD_KAFKA_LOG_SYSLOG' => 'rdkafka/constants.stub', 'RD_KAFKA_LOG_SYSLOG_PRINT' => 'rdkafka/constants.stub', 'RD_KAFKA_MSG_F_BLOCK' => 'rdkafka/constants.stub', 'RD_KAFKA_MSG_PARTITIONER_CONSISTENT' => 'rdkafka/constants.stub', 'RD_KAFKA_MSG_PARTITIONER_CONSISTENT_RANDOM' => 'rdkafka/constants.stub', 'RD_KAFKA_MSG_PARTITIONER_MURMUR2' => 'rdkafka/constants.stub', 'RD_KAFKA_MSG_PARTITIONER_MURMUR2_RANDOM' => 'rdkafka/constants.stub', 'RD_KAFKA_MSG_PARTITIONER_RANDOM' => 'rdkafka/constants.stub', 'RD_KAFKA_OFFSET_BEGINNING' => 'rdkafka/constants.stub', 'RD_KAFKA_OFFSET_END' => 'rdkafka/constants.stub', 'RD_KAFKA_OFFSET_INVALID' => 'rdkafka/constants.stub', 'RD_KAFKA_OFFSET_STORED' => 'rdkafka/constants.stub', 'RD_KAFKA_PARTITION_UA' => 'rdkafka/constants.stub', 'RD_KAFKA_PRODUCER' => 'rdkafka/constants.stub', 'RD_KAFKA_PURGE_F_INFLIGHT' => 'rdkafka/constants.stub', 'RD_KAFKA_PURGE_F_NON_BLOCKING' => 'rdkafka/constants.stub', 'RD_KAFKA_PURGE_F_QUEUE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_BROKER_NOT_AVAILABLE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_CLUSTER_AUTHORIZATION_FAILED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_CONCURRENT_TRANSACTIONS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_COORDINATOR_LOAD_IN_PROGRESS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_COORDINATOR_NOT_AVAILABLE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_DELEGATION_TOKEN_AUTHORIZATION_FAILED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_DELEGATION_TOKEN_AUTH_DISABLED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_DELEGATION_TOKEN_EXPIRED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_DELEGATION_TOKEN_NOT_FOUND' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_DELEGATION_TOKEN_OWNER_MISMATCH' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_DELEGATION_TOKEN_REQUEST_NOT_ALLOWED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_DUPLICATE_RESOURCE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_DUPLICATE_SEQUENCE_NUMBER' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_ELECTION_NOT_NEEDED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_ELIGIBLE_LEADERS_NOT_AVAILABLE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_FEATURE_UPDATE_FAILED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_FENCED_INSTANCE_ID' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_FENCED_LEADER_EPOCH' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_FETCH_SESSION_ID_NOT_FOUND' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_GROUP_AUTHORIZATION_FAILED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_GROUP_COORDINATOR_NOT_AVAILABLE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_GROUP_ID_NOT_FOUND' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_GROUP_LOAD_IN_PROGRESS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_GROUP_MAX_SIZE_REACHED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_GROUP_SUBSCRIBED_TO_TOPIC' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_ILLEGAL_GENERATION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_ILLEGAL_SASL_STATE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INCONSISTENT_GROUP_PROTOCOL' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INCONSISTENT_VOTER_SET' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_COMMIT_OFFSET_SIZE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_CONFIG' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_FETCH_SESSION_EPOCH' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_GROUP_ID' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_MSG' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_MSG_SIZE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_PARTITIONS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_PRINCIPAL_TYPE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_PRODUCER_EPOCH' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_PRODUCER_ID_MAPPING' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_RECORD' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_REPLICATION_FACTOR' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_REPLICA_ASSIGNMENT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_REQUEST' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_REQUIRED_ACKS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_SESSION_TIMEOUT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_TIMESTAMP' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_TRANSACTION_TIMEOUT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_TXN_STATE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_INVALID_UPDATE_VERSION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_KAFKA_STORAGE_ERROR' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_LEADER_NOT_AVAILABLE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_LISTENER_NOT_FOUND' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_LOG_DIR_NOT_FOUND' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_MEMBER_ID_REQUIRED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_MSG_SIZE_TOO_LARGE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_NETWORK_EXCEPTION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_NON_EMPTY_GROUP' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_NOT_CONTROLLER' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_NOT_COORDINATOR' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_NOT_COORDINATOR_FOR_GROUP' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_NOT_ENOUGH_REPLICAS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_NOT_ENOUGH_REPLICAS_AFTER_APPEND' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_NOT_LEADER_FOR_PARTITION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_NO_ERROR' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_NO_REASSIGNMENT_IN_PROGRESS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_OFFSET_METADATA_TOO_LARGE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_OFFSET_NOT_AVAILABLE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_OFFSET_OUT_OF_RANGE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_OPERATION_NOT_ATTEMPTED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_OUT_OF_ORDER_SEQUENCE_NUMBER' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_POLICY_VIOLATION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_PREFERRED_LEADER_NOT_AVAILABLE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_PRINCIPAL_DESERIALIZATION_FAILURE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_PRODUCER_FENCED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_REASSIGNMENT_IN_PROGRESS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_REBALANCE_IN_PROGRESS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_RECORD_LIST_TOO_LARGE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_REPLICA_NOT_AVAILABLE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_REQUEST_TIMED_OUT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_RESOURCE_NOT_FOUND' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_SASL_AUTHENTICATION_FAILED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_SECURITY_DISABLED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_STALE_BROKER_EPOCH' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_STALE_CTRL_EPOCH' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_THROTTLING_QUOTA_EXCEEDED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_TOPIC_ALREADY_EXISTS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_TOPIC_AUTHORIZATION_FAILED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_TOPIC_DELETION_DISABLED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_TOPIC_EXCEPTION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_TRANSACTIONAL_ID_AUTHORIZATION_FAILED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_TRANSACTION_COORDINATOR_FENCED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_UNACCEPTABLE_CREDENTIAL' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_UNKNOWN' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_UNKNOWN_LEADER_EPOCH' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_UNKNOWN_MEMBER_ID' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_UNKNOWN_PRODUCER_ID' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_UNSTABLE_OFFSET_COMMIT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_UNSUPPORTED_COMPRESSION_TYPE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_UNSUPPORTED_FOR_MESSAGE_FORMAT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_UNSUPPORTED_SASL_MECHANISM' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR_UNSUPPORTED_VERSION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__ALL_BROKERS_DOWN' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__APPLICATION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__ASSIGNMENT_LOST' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__AUTHENTICATION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__AUTO_OFFSET_RESET' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__BAD_COMPRESSION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__BAD_MSG' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__BEGIN' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__CONFLICT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__CRIT_SYS_RESOURCE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__DESTROY' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__END' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__EXISTING_SUBSCRIPTION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__FAIL' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__FATAL' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__FENCED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__FS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__GAPLESS_GUARANTEE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__INCONSISTENT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__INTR' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__INVALID_ARG' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__INVALID_TYPE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__IN_PROGRESS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__ISR_INSUFF' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__KEY_DESERIALIZATION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__KEY_SERIALIZATION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__MAX_POLL_EXCEEDED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__MSG_TIMED_OUT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__NODE_UPDATE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__NOENT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__NOOP' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__NOT_CONFIGURED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__NOT_IMPLEMENTED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__NO_OFFSET' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__OUTDATED' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__PARTIAL' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__PARTITION_EOF' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__PREV_IN_PROGRESS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__PURGE_INFLIGHT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__PURGE_QUEUE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__QUEUE_FULL' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__READ_ONLY' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__RESOLVE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__RETRY' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__SSL' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__STATE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__TIMED_OUT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__TIMED_OUT_QUEUE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__TRANSPORT' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__UNDERFLOW' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__UNKNOWN_BROKER' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__UNKNOWN_GROUP' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__UNKNOWN_PARTITION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__UNKNOWN_PROTOCOL' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__UNKNOWN_TOPIC' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__UNSUPPORTED_FEATURE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__VALUE_DESERIALIZATION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__VALUE_SERIALIZATION' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__WAIT_CACHE' => 'rdkafka/constants.stub', 'RD_KAFKA_RESP_ERR__WAIT_COORD' => 'rdkafka/constants.stub', 'RD_KAFKA_VERSION' => 'rdkafka/constants.stub', 'READLINE_LIB' => 'readline/readline.stub', 'RED' => 'winbinder/winbinder.stub', 'RPMMIRE_DEFAULT' => 'rpminfo/rpminfo.stub', 'RPMMIRE_GLOB' => 'rpminfo/rpminfo.stub', 'RPMMIRE_REGEX' => 'rpminfo/rpminfo.stub', 'RPMMIRE_STRCMP' => 'rpminfo/rpminfo.stub', 'RPMSENSE_ANY' => 'rpminfo/rpminfo.stub', 'RPMSENSE_CONFIG' => 'rpminfo/rpminfo.stub', 'RPMSENSE_EQUAL' => 'rpminfo/rpminfo.stub', 'RPMSENSE_FIND_PROVIDES' => 'rpminfo/rpminfo.stub', 'RPMSENSE_FIND_REQUIRES' => 'rpminfo/rpminfo.stub', 'RPMSENSE_GREATER' => 'rpminfo/rpminfo.stub', 'RPMSENSE_INTERP' => 'rpminfo/rpminfo.stub', 'RPMSENSE_KEYRING' => 'rpminfo/rpminfo.stub', 'RPMSENSE_LESS' => 'rpminfo/rpminfo.stub', 'RPMSENSE_MISSINGOK' => 'rpminfo/rpminfo.stub', 'RPMSENSE_POSTTRANS' => 'rpminfo/rpminfo.stub', 'RPMSENSE_PREREQ' => 'rpminfo/rpminfo.stub', 'RPMSENSE_PRETRANS' => 'rpminfo/rpminfo.stub', 'RPMSENSE_RPMLIB' => 'rpminfo/rpminfo.stub', 'RPMSENSE_SCRIPT_POST' => 'rpminfo/rpminfo.stub', 'RPMSENSE_SCRIPT_POSTUN' => 'rpminfo/rpminfo.stub', 'RPMSENSE_SCRIPT_PRE' => 'rpminfo/rpminfo.stub', 'RPMSENSE_SCRIPT_PREUN' => 'rpminfo/rpminfo.stub', 'RPMSENSE_SCRIPT_VERIFY' => 'rpminfo/rpminfo.stub', 'RPMSENSE_TRIGGERIN' => 'rpminfo/rpminfo.stub', 'RPMSENSE_TRIGGERPOSTUN' => 'rpminfo/rpminfo.stub', 'RPMSENSE_TRIGGERPREIN' => 'rpminfo/rpminfo.stub', 'RPMSENSE_TRIGGERUN' => 'rpminfo/rpminfo.stub', 'RPMTAG_ARCH' => 'rpminfo/rpminfo.stub', 'RPMTAG_ARCHIVESIZE' => 'rpminfo/rpminfo.stub', 'RPMTAG_BASENAMES' => 'rpminfo/rpminfo.stub', 'RPMTAG_BUGURL' => 'rpminfo/rpminfo.stub', 'RPMTAG_BUILDARCHS' => 'rpminfo/rpminfo.stub', 'RPMTAG_BUILDHOST' => 'rpminfo/rpminfo.stub', 'RPMTAG_BUILDTIME' => 'rpminfo/rpminfo.stub', 'RPMTAG_C' => 'rpminfo/rpminfo.stub', 'RPMTAG_CHANGELOGNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_CHANGELOGTEXT' => 'rpminfo/rpminfo.stub', 'RPMTAG_CHANGELOGTIME' => 'rpminfo/rpminfo.stub', 'RPMTAG_CLASSDICT' => 'rpminfo/rpminfo.stub', 'RPMTAG_CONFLICTFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_CONFLICTNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_CONFLICTNEVRS' => 'rpminfo/rpminfo.stub', 'RPMTAG_CONFLICTS' => 'rpminfo/rpminfo.stub', 'RPMTAG_CONFLICTVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_COOKIE' => 'rpminfo/rpminfo.stub', 'RPMTAG_DBINSTANCE' => 'rpminfo/rpminfo.stub', 'RPMTAG_DEPENDSDICT' => 'rpminfo/rpminfo.stub', 'RPMTAG_DESCRIPTION' => 'rpminfo/rpminfo.stub', 'RPMTAG_DIRINDEXES' => 'rpminfo/rpminfo.stub', 'RPMTAG_DIRNAMES' => 'rpminfo/rpminfo.stub', 'RPMTAG_DISTRIBUTION' => 'rpminfo/rpminfo.stub', 'RPMTAG_DISTTAG' => 'rpminfo/rpminfo.stub', 'RPMTAG_DISTURL' => 'rpminfo/rpminfo.stub', 'RPMTAG_DSAHEADER' => 'rpminfo/rpminfo.stub', 'RPMTAG_E' => 'rpminfo/rpminfo.stub', 'RPMTAG_ENCODING' => 'rpminfo/rpminfo.stub', 'RPMTAG_ENHANCEFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_ENHANCENAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_ENHANCENEVRS' => 'rpminfo/rpminfo.stub', 'RPMTAG_ENHANCES' => 'rpminfo/rpminfo.stub', 'RPMTAG_ENHANCEVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_EPOCH' => 'rpminfo/rpminfo.stub', 'RPMTAG_EPOCHNUM' => 'rpminfo/rpminfo.stub', 'RPMTAG_EVR' => 'rpminfo/rpminfo.stub', 'RPMTAG_EXCLUDEARCH' => 'rpminfo/rpminfo.stub', 'RPMTAG_EXCLUDEOS' => 'rpminfo/rpminfo.stub', 'RPMTAG_EXCLUSIVEARCH' => 'rpminfo/rpminfo.stub', 'RPMTAG_EXCLUSIVEOS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILECAPS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILECLASS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILECOLORS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILECONTEXTS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEDEPENDSN' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEDEPENDSX' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEDEVICES' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEDIGESTALGO' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEDIGESTS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEGROUPNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEINODES' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILELANGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILELINKTOS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEMD5S' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEMODES' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEMTIMES' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILENAMES' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILENLINKS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEPROVIDE' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILERDEVS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEREQUIRE' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILESIGNATURELENGTH' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILESIGNATURES' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILESIZES' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILESTATES' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILETRIGGERCONDS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILETRIGGERFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILETRIGGERINDEX' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILETRIGGERNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILETRIGGERPRIORITIES' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILETRIGGERSCRIPTFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILETRIGGERSCRIPTPROG' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILETRIGGERSCRIPTS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILETRIGGERTYPE' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILETRIGGERVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEUSERNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_FILEVERIFYFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_FSCONTEXTS' => 'rpminfo/rpminfo.stub', 'RPMTAG_GIF' => 'rpminfo/rpminfo.stub', 'RPMTAG_GROUP' => 'rpminfo/rpminfo.stub', 'RPMTAG_HDRID' => 'rpminfo/rpminfo.stub', 'RPMTAG_HEADERCOLOR' => 'rpminfo/rpminfo.stub', 'RPMTAG_HEADERI18NTABLE' => 'rpminfo/rpminfo.stub', 'RPMTAG_HEADERIMAGE' => 'rpminfo/rpminfo.stub', 'RPMTAG_HEADERIMMUTABLE' => 'rpminfo/rpminfo.stub', 'RPMTAG_HEADERREGIONS' => 'rpminfo/rpminfo.stub', 'RPMTAG_HEADERSIGNATURES' => 'rpminfo/rpminfo.stub', 'RPMTAG_ICON' => 'rpminfo/rpminfo.stub', 'RPMTAG_INSTALLCOLOR' => 'rpminfo/rpminfo.stub', 'RPMTAG_INSTALLTID' => 'rpminfo/rpminfo.stub', 'RPMTAG_INSTALLTIME' => 'rpminfo/rpminfo.stub', 'RPMTAG_INSTFILENAMES' => 'rpminfo/rpminfo.stub', 'RPMTAG_INSTPREFIXES' => 'rpminfo/rpminfo.stub', 'RPMTAG_LICENSE' => 'rpminfo/rpminfo.stub', 'RPMTAG_LONGARCHIVESIZE' => 'rpminfo/rpminfo.stub', 'RPMTAG_LONGFILESIZES' => 'rpminfo/rpminfo.stub', 'RPMTAG_LONGSIGSIZE' => 'rpminfo/rpminfo.stub', 'RPMTAG_LONGSIZE' => 'rpminfo/rpminfo.stub', 'RPMTAG_MODULARITYLABEL' => 'rpminfo/rpminfo.stub', 'RPMTAG_N' => 'rpminfo/rpminfo.stub', 'RPMTAG_NAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_NEVR' => 'rpminfo/rpminfo.stub', 'RPMTAG_NEVRA' => 'rpminfo/rpminfo.stub', 'RPMTAG_NOPATCH' => 'rpminfo/rpminfo.stub', 'RPMTAG_NOSOURCE' => 'rpminfo/rpminfo.stub', 'RPMTAG_NVR' => 'rpminfo/rpminfo.stub', 'RPMTAG_NVRA' => 'rpminfo/rpminfo.stub', 'RPMTAG_O' => 'rpminfo/rpminfo.stub', 'RPMTAG_OBSOLETEFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_OBSOLETENAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_OBSOLETENEVRS' => 'rpminfo/rpminfo.stub', 'RPMTAG_OBSOLETES' => 'rpminfo/rpminfo.stub', 'RPMTAG_OBSOLETEVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_OLDENHANCES' => 'rpminfo/rpminfo.stub', 'RPMTAG_OLDENHANCESFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_OLDENHANCESNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_OLDENHANCESVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_OLDFILENAMES' => 'rpminfo/rpminfo.stub', 'RPMTAG_OLDSUGGESTS' => 'rpminfo/rpminfo.stub', 'RPMTAG_OLDSUGGESTSFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_OLDSUGGESTSNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_OLDSUGGESTSVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_OPTFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_ORDERFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_ORDERNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_ORDERVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_ORIGBASENAMES' => 'rpminfo/rpminfo.stub', 'RPMTAG_ORIGDIRINDEXES' => 'rpminfo/rpminfo.stub', 'RPMTAG_ORIGDIRNAMES' => 'rpminfo/rpminfo.stub', 'RPMTAG_ORIGFILENAMES' => 'rpminfo/rpminfo.stub', 'RPMTAG_OS' => 'rpminfo/rpminfo.stub', 'RPMTAG_P' => 'rpminfo/rpminfo.stub', 'RPMTAG_PACKAGER' => 'rpminfo/rpminfo.stub', 'RPMTAG_PATCH' => 'rpminfo/rpminfo.stub', 'RPMTAG_PATCHESFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_PATCHESNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_PATCHESVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_PAYLOADCOMPRESSOR' => 'rpminfo/rpminfo.stub', 'RPMTAG_PAYLOADDIGEST' => 'rpminfo/rpminfo.stub', 'RPMTAG_PAYLOADDIGESTALGO' => 'rpminfo/rpminfo.stub', 'RPMTAG_PAYLOADFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_PAYLOADFORMAT' => 'rpminfo/rpminfo.stub', 'RPMTAG_PKGID' => 'rpminfo/rpminfo.stub', 'RPMTAG_PLATFORM' => 'rpminfo/rpminfo.stub', 'RPMTAG_POLICIES' => 'rpminfo/rpminfo.stub', 'RPMTAG_POLICYFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_POLICYNAMES' => 'rpminfo/rpminfo.stub', 'RPMTAG_POLICYTYPES' => 'rpminfo/rpminfo.stub', 'RPMTAG_POLICYTYPESINDEXES' => 'rpminfo/rpminfo.stub', 'RPMTAG_POSTIN' => 'rpminfo/rpminfo.stub', 'RPMTAG_POSTINFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_POSTINPROG' => 'rpminfo/rpminfo.stub', 'RPMTAG_POSTTRANS' => 'rpminfo/rpminfo.stub', 'RPMTAG_POSTTRANSFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_POSTTRANSPROG' => 'rpminfo/rpminfo.stub', 'RPMTAG_POSTUN' => 'rpminfo/rpminfo.stub', 'RPMTAG_POSTUNFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_POSTUNPROG' => 'rpminfo/rpminfo.stub', 'RPMTAG_PREFIXES' => 'rpminfo/rpminfo.stub', 'RPMTAG_PREIN' => 'rpminfo/rpminfo.stub', 'RPMTAG_PREINFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_PREINPROG' => 'rpminfo/rpminfo.stub', 'RPMTAG_PRETRANS' => 'rpminfo/rpminfo.stub', 'RPMTAG_PRETRANSFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_PRETRANSPROG' => 'rpminfo/rpminfo.stub', 'RPMTAG_PREUN' => 'rpminfo/rpminfo.stub', 'RPMTAG_PREUNFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_PREUNPROG' => 'rpminfo/rpminfo.stub', 'RPMTAG_PROVIDEFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_PROVIDENAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_PROVIDENEVRS' => 'rpminfo/rpminfo.stub', 'RPMTAG_PROVIDES' => 'rpminfo/rpminfo.stub', 'RPMTAG_PROVIDEVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_PUBKEYS' => 'rpminfo/rpminfo.stub', 'RPMTAG_R' => 'rpminfo/rpminfo.stub', 'RPMTAG_RECOMMENDFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_RECOMMENDNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_RECOMMENDNEVRS' => 'rpminfo/rpminfo.stub', 'RPMTAG_RECOMMENDS' => 'rpminfo/rpminfo.stub', 'RPMTAG_RECOMMENDVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_RECONTEXTS' => 'rpminfo/rpminfo.stub', 'RPMTAG_RELEASE' => 'rpminfo/rpminfo.stub', 'RPMTAG_REMOVETID' => 'rpminfo/rpminfo.stub', 'RPMTAG_REQUIREFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_REQUIRENAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_REQUIRENEVRS' => 'rpminfo/rpminfo.stub', 'RPMTAG_REQUIRES' => 'rpminfo/rpminfo.stub', 'RPMTAG_REQUIREVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_RPMVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_RSAHEADER' => 'rpminfo/rpminfo.stub', 'RPMTAG_SHA1HEADER' => 'rpminfo/rpminfo.stub', 'RPMTAG_SHA256HEADER' => 'rpminfo/rpminfo.stub', 'RPMTAG_SIGGPG' => 'rpminfo/rpminfo.stub', 'RPMTAG_SIGMD5' => 'rpminfo/rpminfo.stub', 'RPMTAG_SIGPGP' => 'rpminfo/rpminfo.stub', 'RPMTAG_SIGSIZE' => 'rpminfo/rpminfo.stub', 'RPMTAG_SIZE' => 'rpminfo/rpminfo.stub', 'RPMTAG_SOURCE' => 'rpminfo/rpminfo.stub', 'RPMTAG_SOURCEPACKAGE' => 'rpminfo/rpminfo.stub', 'RPMTAG_SOURCEPKGID' => 'rpminfo/rpminfo.stub', 'RPMTAG_SOURCERPM' => 'rpminfo/rpminfo.stub', 'RPMTAG_SUGGESTFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_SUGGESTNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_SUGGESTNEVRS' => 'rpminfo/rpminfo.stub', 'RPMTAG_SUGGESTS' => 'rpminfo/rpminfo.stub', 'RPMTAG_SUGGESTVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_SUMMARY' => 'rpminfo/rpminfo.stub', 'RPMTAG_SUPPLEMENTFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_SUPPLEMENTNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_SUPPLEMENTNEVRS' => 'rpminfo/rpminfo.stub', 'RPMTAG_SUPPLEMENTS' => 'rpminfo/rpminfo.stub', 'RPMTAG_SUPPLEMENTVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRANSFILETRIGGERCONDS' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRANSFILETRIGGERFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRANSFILETRIGGERINDEX' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRANSFILETRIGGERNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRANSFILETRIGGERPRIORITIES' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRANSFILETRIGGERSCRIPTFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRANSFILETRIGGERSCRIPTPROG' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRANSFILETRIGGERSCRIPTS' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRANSFILETRIGGERTYPE' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRANSFILETRIGGERVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRIGGERCONDS' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRIGGERFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRIGGERINDEX' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRIGGERNAME' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRIGGERSCRIPTFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRIGGERSCRIPTPROG' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRIGGERSCRIPTS' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRIGGERTYPE' => 'rpminfo/rpminfo.stub', 'RPMTAG_TRIGGERVERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_URL' => 'rpminfo/rpminfo.stub', 'RPMTAG_V' => 'rpminfo/rpminfo.stub', 'RPMTAG_VCS' => 'rpminfo/rpminfo.stub', 'RPMTAG_VENDOR' => 'rpminfo/rpminfo.stub', 'RPMTAG_VERBOSE' => 'rpminfo/rpminfo.stub', 'RPMTAG_VERIFYSCRIPT' => 'rpminfo/rpminfo.stub', 'RPMTAG_VERIFYSCRIPTFLAGS' => 'rpminfo/rpminfo.stub', 'RPMTAG_VERIFYSCRIPTPROG' => 'rpminfo/rpminfo.stub', 'RPMTAG_VERSION' => 'rpminfo/rpminfo.stub', 'RPMTAG_XPM' => 'rpminfo/rpminfo.stub', 'RPMVERSION' => 'rpminfo/rpminfo.stub', 'RTFEditBox' => 'winbinder/winbinder.stub', 'RadioButton' => 'winbinder/winbinder.stub', 'ResizableWindow' => 'winbinder/winbinder.stub', 'SA_ALL' => 'imap/imap.stub', 'SA_MESSAGES' => 'imap/imap.stub', 'SA_RECENT' => 'imap/imap.stub', 'SA_UIDNEXT' => 'imap/imap.stub', 'SA_UIDVALIDITY' => 'imap/imap.stub', 'SA_UNSEEN' => 'imap/imap.stub', 'SCANDIR_SORT_ASCENDING' => 'standard/standard_defines.stub', 'SCANDIR_SORT_DESCENDING' => 'standard/standard_defines.stub', 'SCANDIR_SORT_NONE' => 'standard/standard_defines.stub', 'SCM_CREDENTIALS' => 'sockets/sockets.stub', 'SCM_RIGHTS' => 'sockets/sockets.stub', 'SEEK_CUR' => 'standard/standard_defines.stub', 'SEEK_END' => 'standard/standard_defines.stub', 'SEEK_SET' => 'standard/standard_defines.stub', 'SEGV_ACCERR' => 'pcntl/pcntl.stub', 'SEGV_MAPERR' => 'pcntl/pcntl.stub', 'SE_FREE' => 'imap/imap.stub', 'SE_NOPREFETCH' => 'imap/imap.stub', 'SE_UID' => 'imap/imap.stub', 'SID' => 'standard/standard_defines.stub', 'SIGABRT' => 'pcntl/pcntl.stub', 'SIGALRM' => 'pcntl/pcntl.stub', 'SIGBABY' => 'pcntl/pcntl.stub', 'SIGBUS' => 'pcntl/pcntl.stub', 'SIGCHLD' => 'pcntl/pcntl.stub', 'SIGCLD' => 'pcntl/pcntl.stub', 'SIGCONT' => 'pcntl/pcntl.stub', 'SIGFPE' => 'pcntl/pcntl.stub', 'SIGHUP' => 'pcntl/pcntl.stub', 'SIGILL' => 'pcntl/pcntl.stub', 'SIGINT' => 'pcntl/pcntl.stub', 'SIGIO' => 'pcntl/pcntl.stub', 'SIGIOT' => 'pcntl/pcntl.stub', 'SIGKILL' => 'pcntl/pcntl.stub', 'SIGPIPE' => 'pcntl/pcntl.stub', 'SIGPOLL' => 'pcntl/pcntl.stub', 'SIGPROF' => 'pcntl/pcntl.stub', 'SIGPWR' => 'pcntl/pcntl.stub', 'SIGQUIT' => 'pcntl/pcntl.stub', 'SIGRTMAX' => 'pcntl/pcntl.stub', 'SIGRTMIN' => 'pcntl/pcntl.stub', 'SIGSEGV' => 'pcntl/pcntl.stub', 'SIGSTKFLT' => 'pcntl/pcntl.stub', 'SIGSTOP' => 'pcntl/pcntl.stub', 'SIGSYS' => 'pcntl/pcntl.stub', 'SIGTERM' => 'pcntl/pcntl.stub', 'SIGTRAP' => 'pcntl/pcntl.stub', 'SIGTSTP' => 'pcntl/pcntl.stub', 'SIGTTIN' => 'pcntl/pcntl.stub', 'SIGTTOU' => 'pcntl/pcntl.stub', 'SIGURG' => 'pcntl/pcntl.stub', 'SIGUSR1' => 'pcntl/pcntl.stub', 'SIGUSR2' => 'pcntl/pcntl.stub', 'SIGVTALRM' => 'pcntl/pcntl.stub', 'SIGWINCH' => 'pcntl/pcntl.stub', 'SIGXCPU' => 'pcntl/pcntl.stub', 'SIGXFSZ' => 'pcntl/pcntl.stub', 'SIG_BLOCK' => 'pcntl/pcntl.stub', 'SIG_DFL' => 'pcntl/pcntl.stub', 'SIG_ERR' => 'pcntl/pcntl.stub', 'SIG_IGN' => 'pcntl/pcntl.stub', 'SIG_SETMASK' => 'pcntl/pcntl.stub', 'SIG_UNBLOCK' => 'pcntl/pcntl.stub', 'SI_ASYNCIO' => 'pcntl/pcntl.stub', 'SI_KERNEL' => 'pcntl/pcntl.stub', 'SI_MESGQ' => 'pcntl/pcntl.stub', 'SI_QUEUE' => 'pcntl/pcntl.stub', 'SI_SIGIO' => 'pcntl/pcntl.stub', 'SI_TIMER' => 'pcntl/pcntl.stub', 'SI_TKILL' => 'pcntl/pcntl.stub', 'SI_USER' => 'pcntl/pcntl.stub', 'SKF_AD_ALU_XOR_X' => 'sockets/sockets.stub', 'SKF_AD_CPU' => 'sockets/sockets.stub', 'SKF_AD_HATYPE' => 'sockets/sockets.stub', 'SKF_AD_IFINDEX' => 'sockets/sockets.stub', 'SKF_AD_MARK' => 'sockets/sockets.stub', 'SKF_AD_MAX' => 'sockets/sockets.stub', 'SKF_AD_NLATTR' => 'sockets/sockets.stub', 'SKF_AD_NLATTR_NEST' => 'sockets/sockets.stub', 'SKF_AD_OFF' => 'sockets/sockets.stub', 'SKF_AD_PAY_OFFSET' => 'sockets/sockets.stub', 'SKF_AD_PKTTYPE' => 'sockets/sockets.stub', 'SKF_AD_PROTOCOL' => 'sockets/sockets.stub', 'SKF_AD_QUEUE' => 'sockets/sockets.stub', 'SKF_AD_RANDOM' => 'sockets/sockets.stub', 'SKF_AD_RXHASH' => 'sockets/sockets.stub', 'SKF_AD_VLAN_TAG' => 'sockets/sockets.stub', 'SKF_AD_VLAN_TAG_PRESENT' => 'sockets/sockets.stub', 'SKF_AD_VLAN_TPID' => 'sockets/sockets.stub', 'SNMP_BIT_STR' => 'snmp/snmp.stub', 'SNMP_COUNTER' => 'snmp/snmp.stub', 'SNMP_COUNTER64' => 'snmp/snmp.stub', 'SNMP_INTEGER' => 'snmp/snmp.stub', 'SNMP_IPADDRESS' => 'snmp/snmp.stub', 'SNMP_NULL' => 'snmp/snmp.stub', 'SNMP_OBJECT_ID' => 'snmp/snmp.stub', 'SNMP_OCTET_STR' => 'snmp/snmp.stub', 'SNMP_OID_OUTPUT_FULL' => 'snmp/snmp.stub', 'SNMP_OID_OUTPUT_MODULE' => 'snmp/snmp.stub', 'SNMP_OID_OUTPUT_NONE' => 'snmp/snmp.stub', 'SNMP_OID_OUTPUT_NUMERIC' => 'snmp/snmp.stub', 'SNMP_OID_OUTPUT_SUFFIX' => 'snmp/snmp.stub', 'SNMP_OID_OUTPUT_UCD' => 'snmp/snmp.stub', 'SNMP_OPAQUE' => 'snmp/snmp.stub', 'SNMP_TIMETICKS' => 'snmp/snmp.stub', 'SNMP_UINTEGER' => 'snmp/snmp.stub', 'SNMP_UNSIGNED' => 'snmp/snmp.stub', 'SNMP_VALUE_LIBRARY' => 'snmp/snmp.stub', 'SNMP_VALUE_OBJECT' => 'snmp/snmp.stub', 'SNMP_VALUE_PLAIN' => 'snmp/snmp.stub', 'SOAP_1_1' => 'soap/soap.stub', 'SOAP_1_2' => 'soap/soap.stub', 'SOAP_ACTOR_NEXT' => 'soap/soap.stub', 'SOAP_ACTOR_NONE' => 'soap/soap.stub', 'SOAP_ACTOR_UNLIMATERECEIVER' => 'soap/soap.stub', 'SOAP_AUTHENTICATION_BASIC' => 'soap/soap.stub', 'SOAP_AUTHENTICATION_DIGEST' => 'soap/soap.stub', 'SOAP_COMPRESSION_ACCEPT' => 'soap/soap.stub', 'SOAP_COMPRESSION_DEFLATE' => 'soap/soap.stub', 'SOAP_COMPRESSION_GZIP' => 'soap/soap.stub', 'SOAP_DOCUMENT' => 'soap/soap.stub', 'SOAP_ENCODED' => 'soap/soap.stub', 'SOAP_ENC_ARRAY' => 'soap/soap.stub', 'SOAP_ENC_OBJECT' => 'soap/soap.stub', 'SOAP_FUNCTIONS_ALL' => 'soap/soap.stub', 'SOAP_LITERAL' => 'soap/soap.stub', 'SOAP_PERSISTENCE_REQUEST' => 'soap/soap.stub', 'SOAP_PERSISTENCE_SESSION' => 'soap/soap.stub', 'SOAP_RPC' => 'soap/soap.stub', 'SOAP_SINGLE_ELEMENT_ARRAYS' => 'soap/soap.stub', 'SOAP_SSL_METHOD_SSLv2' => 'soap/soap.stub', 'SOAP_SSL_METHOD_SSLv23' => 'soap/soap.stub', 'SOAP_SSL_METHOD_SSLv3' => 'soap/soap.stub', 'SOAP_SSL_METHOD_TLS' => 'soap/soap.stub', 'SOAP_USE_XSI_ARRAY_TYPE' => 'soap/soap.stub', 'SOAP_WAIT_ONE_WAY_CALLS' => 'soap/soap.stub', 'SOCKET_E2BIG' => 'sockets/sockets.stub', 'SOCKET_EACCES' => 'sockets/sockets.stub', 'SOCKET_EADDRINUSE' => 'sockets/sockets.stub', 'SOCKET_EADDRNOTAVAIL' => 'sockets/sockets.stub', 'SOCKET_EADV' => 'sockets/sockets.stub', 'SOCKET_EAFNOSUPPORT' => 'sockets/sockets.stub', 'SOCKET_EAGAIN' => 'sockets/sockets.stub', 'SOCKET_EALREADY' => 'sockets/sockets.stub', 'SOCKET_EBADE' => 'sockets/sockets.stub', 'SOCKET_EBADF' => 'sockets/sockets.stub', 'SOCKET_EBADFD' => 'sockets/sockets.stub', 'SOCKET_EBADMSG' => 'sockets/sockets.stub', 'SOCKET_EBADR' => 'sockets/sockets.stub', 'SOCKET_EBADRQC' => 'sockets/sockets.stub', 'SOCKET_EBADSLT' => 'sockets/sockets.stub', 'SOCKET_EBUSY' => 'sockets/sockets.stub', 'SOCKET_ECANCELED' => 'swoole/constants.stub', 'SOCKET_ECHRNG' => 'sockets/sockets.stub', 'SOCKET_ECOMM' => 'sockets/sockets.stub', 'SOCKET_ECONNABORTED' => 'sockets/sockets.stub', 'SOCKET_ECONNREFUSED' => 'sockets/sockets.stub', 'SOCKET_ECONNRESET' => 'sockets/sockets.stub', 'SOCKET_EDESTADDRREQ' => 'sockets/sockets.stub', 'SOCKET_EDISCON' => 'sockets/sockets.stub', 'SOCKET_EDQUOT' => 'sockets/sockets.stub', 'SOCKET_EEXIST' => 'sockets/sockets.stub', 'SOCKET_EFAULT' => 'sockets/sockets.stub', 'SOCKET_EHOSTDOWN' => 'sockets/sockets.stub', 'SOCKET_EHOSTUNREACH' => 'sockets/sockets.stub', 'SOCKET_EIDRM' => 'sockets/sockets.stub', 'SOCKET_EINPROGRESS' => 'sockets/sockets.stub', 'SOCKET_EINTR' => 'sockets/sockets.stub', 'SOCKET_EINVAL' => 'sockets/sockets.stub', 'SOCKET_EIO' => 'sockets/sockets.stub', 'SOCKET_EISCONN' => 'sockets/sockets.stub', 'SOCKET_EISDIR' => 'sockets/sockets.stub', 'SOCKET_EISNAM' => 'sockets/sockets.stub', 'SOCKET_EL2HLT' => 'sockets/sockets.stub', 'SOCKET_EL2NSYNC' => 'sockets/sockets.stub', 'SOCKET_EL3HLT' => 'sockets/sockets.stub', 'SOCKET_EL3RST' => 'sockets/sockets.stub', 'SOCKET_ELNRNG' => 'sockets/sockets.stub', 'SOCKET_ELOOP' => 'sockets/sockets.stub', 'SOCKET_EMEDIUMTYPE' => 'sockets/sockets.stub', 'SOCKET_EMFILE' => 'sockets/sockets.stub', 'SOCKET_EMLINK' => 'sockets/sockets.stub', 'SOCKET_EMSGSIZE' => 'sockets/sockets.stub', 'SOCKET_EMULTIHOP' => 'sockets/sockets.stub', 'SOCKET_ENAMETOOLONG' => 'sockets/sockets.stub', 'SOCKET_ENETDOWN' => 'sockets/sockets.stub', 'SOCKET_ENETRESET' => 'sockets/sockets.stub', 'SOCKET_ENETUNREACH' => 'sockets/sockets.stub', 'SOCKET_ENFILE' => 'sockets/sockets.stub', 'SOCKET_ENOANO' => 'sockets/sockets.stub', 'SOCKET_ENOBUFS' => 'sockets/sockets.stub', 'SOCKET_ENOCSI' => 'sockets/sockets.stub', 'SOCKET_ENODATA' => 'sockets/sockets.stub', 'SOCKET_ENODEV' => 'sockets/sockets.stub', 'SOCKET_ENOENT' => 'sockets/sockets.stub', 'SOCKET_ENOLCK' => 'sockets/sockets.stub', 'SOCKET_ENOLINK' => 'sockets/sockets.stub', 'SOCKET_ENOMEDIUM' => 'sockets/sockets.stub', 'SOCKET_ENOMEM' => 'sockets/sockets.stub', 'SOCKET_ENOMSG' => 'sockets/sockets.stub', 'SOCKET_ENONET' => 'sockets/sockets.stub', 'SOCKET_ENOPROTOOPT' => 'sockets/sockets.stub', 'SOCKET_ENOSPC' => 'sockets/sockets.stub', 'SOCKET_ENOSR' => 'sockets/sockets.stub', 'SOCKET_ENOSTR' => 'sockets/sockets.stub', 'SOCKET_ENOSYS' => 'sockets/sockets.stub', 'SOCKET_ENOTBLK' => 'sockets/sockets.stub', 'SOCKET_ENOTCONN' => 'sockets/sockets.stub', 'SOCKET_ENOTDIR' => 'sockets/sockets.stub', 'SOCKET_ENOTEMPTY' => 'sockets/sockets.stub', 'SOCKET_ENOTSOCK' => 'sockets/sockets.stub', 'SOCKET_ENOTTY' => 'sockets/sockets.stub', 'SOCKET_ENOTUNIQ' => 'sockets/sockets.stub', 'SOCKET_ENXIO' => 'sockets/sockets.stub', 'SOCKET_EOPNOTSUPP' => 'sockets/sockets.stub', 'SOCKET_EPERM' => 'sockets/sockets.stub', 'SOCKET_EPFNOSUPPORT' => 'sockets/sockets.stub', 'SOCKET_EPIPE' => 'sockets/sockets.stub', 'SOCKET_EPROCLIM' => 'sockets/sockets.stub', 'SOCKET_EPROTO' => 'sockets/sockets.stub', 'SOCKET_EPROTONOSUPPORT' => 'sockets/sockets.stub', 'SOCKET_EPROTOTYPE' => 'sockets/sockets.stub', 'SOCKET_EREMCHG' => 'sockets/sockets.stub', 'SOCKET_EREMOTE' => 'sockets/sockets.stub', 'SOCKET_EREMOTEIO' => 'sockets/sockets.stub', 'SOCKET_ERESTART' => 'sockets/sockets.stub', 'SOCKET_EROFS' => 'sockets/sockets.stub', 'SOCKET_ESHUTDOWN' => 'sockets/sockets.stub', 'SOCKET_ESOCKTNOSUPPORT' => 'sockets/sockets.stub', 'SOCKET_ESPIPE' => 'sockets/sockets.stub', 'SOCKET_ESRMNT' => 'sockets/sockets.stub', 'SOCKET_ESTALE' => 'sockets/sockets.stub', 'SOCKET_ESTRPIPE' => 'sockets/sockets.stub', 'SOCKET_ETIME' => 'sockets/sockets.stub', 'SOCKET_ETIMEDOUT' => 'sockets/sockets.stub', 'SOCKET_ETOOMANYREFS' => 'sockets/sockets.stub', 'SOCKET_EUNATCH' => 'sockets/sockets.stub', 'SOCKET_EUSERS' => 'sockets/sockets.stub', 'SOCKET_EWOULDBLOCK' => 'sockets/sockets.stub', 'SOCKET_EXDEV' => 'sockets/sockets.stub', 'SOCKET_EXFULL' => 'sockets/sockets.stub', 'SOCKET_HOST_NOT_FOUND' => 'sockets/sockets.stub', 'SOCKET_NOTINITIALISED' => 'sockets/sockets.stub', 'SOCKET_NO_ADDRESS' => 'sockets/sockets.stub', 'SOCKET_NO_DATA' => 'sockets/sockets.stub', 'SOCKET_NO_RECOVERY' => 'sockets/sockets.stub', 'SOCKET_SYSNOTREADY' => 'sockets/sockets.stub', 'SOCKET_TRY_AGAIN' => 'sockets/sockets.stub', 'SOCKET_VERNOTSUPPORTED' => 'sockets/sockets.stub', 'SOCK_CLOEXEC' => 'sockets/sockets.stub', 'SOCK_DCCP' => 'sockets/sockets.stub', 'SOCK_DGRAM' => 'sockets/sockets.stub', 'SOCK_NONBLOCK' => 'sockets/sockets.stub', 'SOCK_RAW' => 'sockets/sockets.stub', 'SOCK_RDM' => 'sockets/sockets.stub', 'SOCK_SEQPACKET' => 'sockets/sockets.stub', 'SOCK_STREAM' => 'sockets/sockets.stub', 'SODIUM_BASE64_VARIANT_ORIGINAL' => 'sodium/sodium.stub', 'SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING' => 'sodium/sodium.stub', 'SODIUM_BASE64_VARIANT_URLSAFE' => 'sodium/sodium.stub', 'SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_AEGIS128L_ABYTES' => 'libsodium/libsodium_d.stub', 'SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES' => 'libsodium/libsodium_d.stub', 'SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES' => 'libsodium/libsodium_d.stub', 'SODIUM_CRYPTO_AEAD_AEGIS128L_NSECBYTES' => 'libsodium/libsodium_d.stub', 'SODIUM_CRYPTO_AEAD_AEGIS256_ABYTES' => 'libsodium/libsodium_d.stub', 'SODIUM_CRYPTO_AEAD_AEGIS256_KEYBYTES' => 'libsodium/libsodium_d.stub', 'SODIUM_CRYPTO_AEAD_AEGIS256_NPUBBYTES' => 'libsodium/libsodium_d.stub', 'SODIUM_CRYPTO_AEAD_AEGIS256_NSECBYTES' => 'libsodium/libsodium_d.stub', 'SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NSECBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AUTH_BYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_AUTH_KEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_BOX_KEYPAIRBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_BOX_MACBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_BOX_NONCEBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_BOX_PUBLICKEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_BOX_SEALBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_BOX_SECRETKEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_BOX_SEEDBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_GENERICHASH_BYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_GENERICHASH_BYTES_MAX' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_GENERICHASH_BYTES_MIN' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_GENERICHASH_KEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_KDF_BYTES_MAX' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_KDF_BYTES_MIN' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_KDF_CONTEXTBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_KDF_KEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_KX_BYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_KX_KEYPAIRBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_KX_PUBLICKEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_KX_SECRETKEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_KX_SEEDBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_KX_SESSIONKEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_ALG_DEFAULT' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_SALTBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_PWHASH_STRPREFIX' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SCALARMULT_BYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SCALARMULT_SCALARBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SECRETBOX_KEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SECRETBOX_MACBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SECRETBOX_NONCEBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_MESSAGE' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SHORTHASH_BYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SHORTHASH_KEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SIGN_BYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SIGN_KEYPAIRBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SIGN_SECRETKEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_SIGN_SEEDBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_STREAM_KEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_STREAM_NONCEBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES' => 'sodium/sodium.stub', 'SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES' => 'sodium/sodium.stub', 'SODIUM_LIBRARY_MAJOR_VERSION' => 'sodium/sodium.stub', 'SODIUM_LIBRARY_MINOR_VERSION' => 'sodium/sodium.stub', 'SODIUM_LIBRARY_VERSION' => 'sodium/sodium.stub', 'SOLR_EXTENSION_VERSION' => 'solr/constants.stub', 'SOLR_MAJOR_VERSION' => 'solr/constants.stub', 'SOLR_MINOR_VERSION' => 'solr/constants.stub', 'SOLR_PATCH_VERSION' => 'solr/constants.stub', 'SOL_SOCKET' => 'sockets/sockets.stub', 'SOL_TCP' => 'sockets/sockets.stub', 'SOL_UDP' => 'sockets/sockets.stub', 'SOL_UDPLITE' => 'sockets/sockets.stub', 'SOMAXCONN' => 'sockets/sockets.stub', 'SORTARRIVAL' => 'imap/imap.stub', 'SORTCC' => 'imap/imap.stub', 'SORTDATE' => 'imap/imap.stub', 'SORTFROM' => 'imap/imap.stub', 'SORTSIZE' => 'imap/imap.stub', 'SORTSUBJECT' => 'imap/imap.stub', 'SORTTO' => 'imap/imap.stub', 'SORT_ASC' => 'standard/standard_defines.stub', 'SORT_DESC' => 'standard/standard_defines.stub', 'SORT_FLAG_CASE' => 'standard/standard_defines.stub', 'SORT_LOCALE_STRING' => 'standard/standard_defines.stub', 'SORT_NATURAL' => 'standard/standard_defines.stub', 'SORT_NUMERIC' => 'standard/standard_defines.stub', 'SORT_REGULAR' => 'standard/standard_defines.stub', 'SORT_STRING' => 'standard/standard_defines.stub', 'SO_ATTACH_REUSEPORT_CBPF' => 'sockets/sockets.stub', 'SO_BINDTODEVICE' => 'sockets/sockets.stub', 'SO_BINDTOIFINDEX' => 'sockets/sockets.stub', 'SO_BPF_EXTENSIONS' => 'sockets/sockets.stub', 'SO_BROADCAST' => 'sockets/sockets.stub', 'SO_DEBUG' => 'sockets/sockets.stub', 'SO_DETACH_BPF' => 'sockets/sockets.stub', 'SO_DETACH_FILTER' => 'sockets/sockets.stub', 'SO_DONTROUTE' => 'sockets/sockets.stub', 'SO_ERROR' => 'sockets/sockets.stub', 'SO_FREE' => 'imap/imap.stub', 'SO_INCOMING_CPU' => 'sockets/sockets.stub', 'SO_KEEPALIVE' => 'sockets/sockets.stub', 'SO_LINGER' => 'sockets/sockets.stub', 'SO_MARK' => 'sockets/sockets.stub', 'SO_MEMINFO' => 'sockets/sockets.stub', 'SO_NOSERVER' => 'imap/imap.stub', 'SO_OOBINLINE' => 'sockets/sockets.stub', 'SO_PASSCRED' => 'sockets/sockets.stub', 'SO_RCVBUF' => 'sockets/sockets.stub', 'SO_RCVLOWAT' => 'sockets/sockets.stub', 'SO_RCVTIMEO' => 'sockets/sockets.stub', 'SO_REUSEADDR' => 'sockets/sockets.stub', 'SO_REUSEPORT' => 'sockets/sockets.stub', 'SO_SNDBUF' => 'sockets/sockets.stub', 'SO_SNDLOWAT' => 'sockets/sockets.stub', 'SO_SNDTIMEO' => 'sockets/sockets.stub', 'SO_TYPE' => 'sockets/sockets.stub', 'SO_ZEROCOPY' => 'sockets/sockets.stub', 'SQLBIT' => 'mssql/mssql.stub', 'SQLCHAR' => 'mssql/mssql.stub', 'SQLFLT4' => 'mssql/mssql.stub', 'SQLFLT8' => 'mssql/mssql.stub', 'SQLFLTN' => 'mssql/mssql.stub', 'SQLINT1' => 'mssql/mssql.stub', 'SQLINT2' => 'mssql/mssql.stub', 'SQLINT4' => 'mssql/mssql.stub', 'SQLITE3_ASSOC' => 'sqlite3/sqlite3.stub', 'SQLITE3_BLOB' => 'sqlite3/sqlite3.stub', 'SQLITE3_BOTH' => 'sqlite3/sqlite3.stub', 'SQLITE3_DETERMINISTIC' => 'sqlite3/sqlite3.stub', 'SQLITE3_FLOAT' => 'sqlite3/sqlite3.stub', 'SQLITE3_INTEGER' => 'sqlite3/sqlite3.stub', 'SQLITE3_NULL' => 'sqlite3/sqlite3.stub', 'SQLITE3_NUM' => 'sqlite3/sqlite3.stub', 'SQLITE3_OPEN_CREATE' => 'sqlite3/sqlite3.stub', 'SQLITE3_OPEN_READONLY' => 'sqlite3/sqlite3.stub', 'SQLITE3_OPEN_READWRITE' => 'sqlite3/sqlite3.stub', 'SQLITE3_TEXT' => 'sqlite3/sqlite3.stub', 'SQLITE_ABORT' => 'SQLite/SQLite.stub', 'SQLITE_ASSOC' => 'SQLite/SQLite.stub', 'SQLITE_AUTH' => 'SQLite/SQLite.stub', 'SQLITE_BOTH' => 'SQLite/SQLite.stub', 'SQLITE_BUSY' => 'SQLite/SQLite.stub', 'SQLITE_CANTOPEN' => 'SQLite/SQLite.stub', 'SQLITE_CONSTRAINT' => 'SQLite/SQLite.stub', 'SQLITE_CORRUPT' => 'SQLite/SQLite.stub', 'SQLITE_DONE' => 'SQLite/SQLite.stub', 'SQLITE_EMPTY' => 'SQLite/SQLite.stub', 'SQLITE_ERROR' => 'SQLite/SQLite.stub', 'SQLITE_FORMAT' => 'SQLite/SQLite.stub', 'SQLITE_FULL' => 'SQLite/SQLite.stub', 'SQLITE_INTERNAL' => 'SQLite/SQLite.stub', 'SQLITE_INTERRUPT' => 'SQLite/SQLite.stub', 'SQLITE_IOERR' => 'SQLite/SQLite.stub', 'SQLITE_LOCKED' => 'SQLite/SQLite.stub', 'SQLITE_MISMATCH' => 'SQLite/SQLite.stub', 'SQLITE_MISUSE' => 'SQLite/SQLite.stub', 'SQLITE_NOLFS' => 'SQLite/SQLite.stub', 'SQLITE_NOMEM' => 'SQLite/SQLite.stub', 'SQLITE_NOTADB' => 'SQLite/SQLite.stub', 'SQLITE_NOTFOUND' => 'SQLite/SQLite.stub', 'SQLITE_NUM' => 'SQLite/SQLite.stub', 'SQLITE_OK' => 'SQLite/SQLite.stub', 'SQLITE_PERM' => 'SQLite/SQLite.stub', 'SQLITE_PROTOCOL' => 'SQLite/SQLite.stub', 'SQLITE_READONLY' => 'SQLite/SQLite.stub', 'SQLITE_ROW' => 'SQLite/SQLite.stub', 'SQLITE_SCHEMA' => 'SQLite/SQLite.stub', 'SQLITE_TOOBIG' => 'SQLite/SQLite.stub', 'SQLSRV_CURSOR_CLIENT_BUFFERED' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_CURSOR_DYNAMIC' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_CURSOR_FORWARD' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_CURSOR_KEYSET' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_CURSOR_STATIC' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_ENC_BINARY' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_ENC_CHAR' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_ERR_ALL' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_ERR_ERRORS' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_ERR_WARNINGS' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_FETCH_ASSOC' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_FETCH_BOTH' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_FETCH_NUMERIC' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_LOG_SEVERITY_ALL' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_LOG_SEVERITY_ERROR' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_LOG_SEVERITY_NOTICE' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_LOG_SEVERITY_WARNING' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_LOG_SYSTEM_ALL' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_LOG_SYSTEM_CONN' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_LOG_SYSTEM_INIT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_LOG_SYSTEM_OFF' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_LOG_SYSTEM_STMT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_LOG_SYSTEM_UTIL' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_NULLABLE_NO' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_NULLABLE_UNKNOWN' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_NULLABLE_YES' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_PARAM_IN' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_PARAM_INOUT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_PARAM_OUT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_PHPTYPE_DATETIME' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_PHPTYPE_FLOAT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_PHPTYPE_INT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_PHPTYPE_NULL' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SCROLL_ABSOLUTE' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SCROLL_FIRST' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SCROLL_LAST' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SCROLL_NEXT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SCROLL_PRIOR' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SCROLL_RELATIVE' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_BIGINT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_BIT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_CHAR' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_DATE' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_DATETIME' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_DATETIME2' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_DATETIMEOFFSET' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_DECIMAL' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_FLOAT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_IMAGE' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_INT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_MONEY' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_NCHAR' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_NTEXT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_NUMERIC' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_NVARCHAR' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_REAL' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_SMALLDATETIME' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_SMALLINT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_SMALLMONEY' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_TEXT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_TIME' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_TIMESTAMP' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_TINYINT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_UDT' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_UNIQUEIDENTIFIER' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_VARBINARY' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_VARCHAR' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_SQLTYPE_XML' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_TXN_READ_COMMITTED' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_TXN_READ_UNCOMMITTED' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_TXN_REPEATABLE_READ' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_TXN_SERIALIZABLE' => 'sqlsrv/sqlsrv.stub', 'SQLSRV_TXN_SNAPSHOT' => 'sqlsrv/sqlsrv.stub', 'SQLTEXT' => 'mssql/mssql.stub', 'SQLT_AFC' => 'oci8/oci8.stub', 'SQLT_AVC' => 'oci8/oci8.stub', 'SQLT_BDOUBLE' => 'oci8/oci8.stub', 'SQLT_BFILEE' => 'oci8/oci8.stub', 'SQLT_BFLOAT' => 'oci8/oci8.stub', 'SQLT_BIN' => 'oci8/oci8.stub', 'SQLT_BLOB' => 'oci8/oci8.stub', 'SQLT_BOL' => 'oci8/oci8.stub', 'SQLT_CFILEE' => 'oci8/oci8.stub', 'SQLT_CHR' => 'oci8/oci8.stub', 'SQLT_CLOB' => 'oci8/oci8.stub', 'SQLT_FLT' => 'oci8/oci8.stub', 'SQLT_INT' => 'oci8/oci8.stub', 'SQLT_LBI' => 'oci8/oci8.stub', 'SQLT_LNG' => 'oci8/oci8.stub', 'SQLT_LVC' => 'oci8/oci8.stub', 'SQLT_NTY' => 'oci8/oci8.stub', 'SQLT_NUM' => 'oci8/oci8.stub', 'SQLT_ODT' => 'oci8/oci8.stub', 'SQLT_RDD' => 'oci8/oci8.stub', 'SQLT_RSET' => 'oci8/oci8.stub', 'SQLT_STR' => 'oci8/oci8.stub', 'SQLT_UIN' => 'oci8/oci8.stub', 'SQLT_VCS' => 'oci8/oci8.stub', 'SQLVARCHAR' => 'mssql/mssql.stub', 'SQL_BEST_ROWID' => 'odbc/odbc.stub', 'SQL_BIGINT' => 'odbc/odbc.stub', 'SQL_BINARY' => 'odbc/odbc.stub', 'SQL_BIT' => 'odbc/odbc.stub', 'SQL_CHAR' => 'odbc/odbc.stub', 'SQL_CONCURRENCY' => 'odbc/odbc.stub', 'SQL_CONCUR_LOCK' => 'odbc/odbc.stub', 'SQL_CONCUR_READ_ONLY' => 'odbc/odbc.stub', 'SQL_CONCUR_ROWVER' => 'odbc/odbc.stub', 'SQL_CONCUR_VALUES' => 'odbc/odbc.stub', 'SQL_CURSOR_DYNAMIC' => 'odbc/odbc.stub', 'SQL_CURSOR_FORWARD_ONLY' => 'odbc/odbc.stub', 'SQL_CURSOR_KEYSET_DRIVEN' => 'odbc/odbc.stub', 'SQL_CURSOR_STATIC' => 'odbc/odbc.stub', 'SQL_CURSOR_TYPE' => 'odbc/odbc.stub', 'SQL_CUR_USE_DRIVER' => 'odbc/odbc.stub', 'SQL_CUR_USE_IF_NEEDED' => 'odbc/odbc.stub', 'SQL_CUR_USE_ODBC' => 'odbc/odbc.stub', 'SQL_DATE' => 'odbc/odbc.stub', 'SQL_DECIMAL' => 'odbc/odbc.stub', 'SQL_DOUBLE' => 'odbc/odbc.stub', 'SQL_ENSURE' => 'odbc/odbc.stub', 'SQL_FETCH_FIRST' => 'odbc/odbc.stub', 'SQL_FETCH_NEXT' => 'odbc/odbc.stub', 'SQL_FLOAT' => 'odbc/odbc.stub', 'SQL_INDEX_ALL' => 'odbc/odbc.stub', 'SQL_INDEX_UNIQUE' => 'odbc/odbc.stub', 'SQL_INTEGER' => 'odbc/odbc.stub', 'SQL_KEYSET_SIZE' => 'odbc/odbc.stub', 'SQL_LONGVARBINARY' => 'odbc/odbc.stub', 'SQL_LONGVARCHAR' => 'odbc/odbc.stub', 'SQL_NO_NULLS' => 'odbc/odbc.stub', 'SQL_NULLABLE' => 'odbc/odbc.stub', 'SQL_NUMERIC' => 'odbc/odbc.stub', 'SQL_ODBC_CURSORS' => 'odbc/odbc.stub', 'SQL_QUICK' => 'odbc/odbc.stub', 'SQL_REAL' => 'odbc/odbc.stub', 'SQL_ROWVER' => 'odbc/odbc.stub', 'SQL_SCOPE_CURROW' => 'odbc/odbc.stub', 'SQL_SCOPE_SESSION' => 'odbc/odbc.stub', 'SQL_SCOPE_TRANSACTION' => 'odbc/odbc.stub', 'SQL_SMALLINT' => 'odbc/odbc.stub', 'SQL_TIME' => 'odbc/odbc.stub', 'SQL_TIMESTAMP' => 'odbc/odbc.stub', 'SQL_TINYINT' => 'odbc/odbc.stub', 'SQL_TYPE_DATE' => 'odbc/odbc.stub', 'SQL_TYPE_TIME' => 'odbc/odbc.stub', 'SQL_TYPE_TIMESTAMP' => 'odbc/odbc.stub', 'SQL_VARBINARY' => 'odbc/odbc.stub', 'SQL_VARCHAR' => 'odbc/odbc.stub', 'SQL_WCHAR' => 'odbc/odbc.stub', 'SQL_WLONGVARCHAR' => 'odbc/odbc.stub', 'SQL_WVARCHAR' => 'odbc/odbc.stub', 'SSH2_DEFAULT_TERMINAL' => 'ssh2/ssh2.stub', 'SSH2_DEFAULT_TERM_HEIGHT' => 'ssh2/ssh2.stub', 'SSH2_DEFAULT_TERM_UNIT' => 'ssh2/ssh2.stub', 'SSH2_DEFAULT_TERM_WIDTH' => 'ssh2/ssh2.stub', 'SSH2_FINGERPRINT_HEX' => 'ssh2/ssh2.stub', 'SSH2_FINGERPRINT_MD5' => 'ssh2/ssh2.stub', 'SSH2_FINGERPRINT_RAW' => 'ssh2/ssh2.stub', 'SSH2_FINGERPRINT_SHA1' => 'ssh2/ssh2.stub', 'SSH2_POLLERR' => 'ssh2/ssh2.stub', 'SSH2_POLLEXT' => 'ssh2/ssh2.stub', 'SSH2_POLLHUP' => 'ssh2/ssh2.stub', 'SSH2_POLLIN' => 'ssh2/ssh2.stub', 'SSH2_POLLNVAL' => 'ssh2/ssh2.stub', 'SSH2_POLLOUT' => 'ssh2/ssh2.stub', 'SSH2_POLL_CHANNEL_CLOSED' => 'ssh2/ssh2.stub', 'SSH2_POLL_LISTENER_CLOSED' => 'ssh2/ssh2.stub', 'SSH2_POLL_SESSION_CLOSED' => 'ssh2/ssh2.stub', 'SSH2_STREAM_STDERR' => 'ssh2/ssh2.stub', 'SSH2_STREAM_STDIO' => 'ssh2/ssh2.stub', 'SSH2_TERM_UNIT_CHARS' => 'ssh2/ssh2.stub', 'SSH2_TERM_UNIT_PIXELS' => 'ssh2/ssh2.stub', 'STDERR' => 'Core/Core_d.stub', 'STDIN' => 'Core/Core_d.stub', 'STDOUT' => 'Core/Core_d.stub', 'STREAM_BUFFER_FULL' => 'standard/standard_defines.stub', 'STREAM_BUFFER_LINE' => 'standard/standard_defines.stub', 'STREAM_BUFFER_NONE' => 'standard/standard_defines.stub', 'STREAM_CAST_AS_STREAM' => 'standard/standard_defines.stub', 'STREAM_CAST_FOR_SELECT' => 'standard/standard_defines.stub', 'STREAM_CLIENT_ASYNC_CONNECT' => 'standard/standard_defines.stub', 'STREAM_CLIENT_CONNECT' => 'standard/standard_defines.stub', 'STREAM_CLIENT_PERSISTENT' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_ANY_CLIENT' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_ANY_SERVER' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_SSLv23_CLIENT' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_SSLv23_SERVER' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_SSLv2_CLIENT' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_SSLv2_SERVER' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_SSLv3_CLIENT' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_SSLv3_SERVER' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_TLS_CLIENT' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_TLS_SERVER' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_TLSv1_0_SERVER' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_TLSv1_1_SERVER' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_TLSv1_2_SERVER' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_METHOD_TLSv1_3_SERVER' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_PROTO_SSLv3' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_PROTO_TLSv1_0' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_PROTO_TLSv1_1' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_PROTO_TLSv1_2' => 'standard/standard_defines.stub', 'STREAM_CRYPTO_PROTO_TLSv1_3' => 'standard/standard_defines.stub', 'STREAM_ENFORCE_SAFE_MODE' => 'standard/standard_defines.stub', 'STREAM_FILTER_ALL' => 'standard/standard_defines.stub', 'STREAM_FILTER_READ' => 'standard/standard_defines.stub', 'STREAM_FILTER_WRITE' => 'standard/standard_defines.stub', 'STREAM_IGNORE_URL' => 'standard/standard_defines.stub', 'STREAM_IPPROTO_ICMP' => 'standard/standard_defines.stub', 'STREAM_IPPROTO_IP' => 'standard/standard_defines.stub', 'STREAM_IPPROTO_RAW' => 'standard/standard_defines.stub', 'STREAM_IPPROTO_TCP' => 'standard/standard_defines.stub', 'STREAM_IPPROTO_UDP' => 'standard/standard_defines.stub', 'STREAM_IS_URL' => 'standard/standard_defines.stub', 'STREAM_META_ACCESS' => 'standard/standard_defines.stub', 'STREAM_META_GROUP' => 'standard/standard_defines.stub', 'STREAM_META_GROUP_NAME' => 'standard/standard_defines.stub', 'STREAM_META_OWNER' => 'standard/standard_defines.stub', 'STREAM_META_OWNER_NAME' => 'standard/standard_defines.stub', 'STREAM_META_TOUCH' => 'standard/standard_defines.stub', 'STREAM_MKDIR_RECURSIVE' => 'standard/standard_defines.stub', 'STREAM_MUST_SEEK' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_AUTH_REQUIRED' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_AUTH_RESULT' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_COMPLETED' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_CONNECT' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_FAILURE' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_FILE_SIZE_IS' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_MIME_TYPE_IS' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_PROGRESS' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_REDIRECTED' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_RESOLVE' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_SEVERITY_ERR' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_SEVERITY_INFO' => 'standard/standard_defines.stub', 'STREAM_NOTIFY_SEVERITY_WARN' => 'standard/standard_defines.stub', 'STREAM_OOB' => 'standard/standard_defines.stub', 'STREAM_OPTION_BLOCKING' => 'standard/standard_defines.stub', 'STREAM_OPTION_READ_BUFFER' => 'standard/standard_defines.stub', 'STREAM_OPTION_READ_TIMEOUT' => 'standard/standard_defines.stub', 'STREAM_OPTION_WRITE_BUFFER' => 'standard/standard_defines.stub', 'STREAM_PEEK' => 'standard/standard_defines.stub', 'STREAM_PF_INET' => 'standard/standard_defines.stub', 'STREAM_PF_INET6' => 'standard/standard_defines.stub', 'STREAM_PF_UNIX' => 'standard/standard_defines.stub', 'STREAM_REPORT_ERRORS' => 'standard/standard_defines.stub', 'STREAM_SERVER_BIND' => 'standard/standard_defines.stub', 'STREAM_SERVER_LISTEN' => 'standard/standard_defines.stub', 'STREAM_SHUT_RD' => 'standard/standard_defines.stub', 'STREAM_SHUT_RDWR' => 'standard/standard_defines.stub', 'STREAM_SHUT_WR' => 'standard/standard_defines.stub', 'STREAM_SOCK_DGRAM' => 'standard/standard_defines.stub', 'STREAM_SOCK_RAW' => 'standard/standard_defines.stub', 'STREAM_SOCK_RDM' => 'standard/standard_defines.stub', 'STREAM_SOCK_SEQPACKET' => 'standard/standard_defines.stub', 'STREAM_SOCK_STREAM' => 'standard/standard_defines.stub', 'STREAM_URL_STAT_LINK' => 'standard/standard_defines.stub', 'STREAM_URL_STAT_QUIET' => 'standard/standard_defines.stub', 'STREAM_USE_PATH' => 'standard/standard_defines.stub', 'STR_PAD_BOTH' => 'standard/standard_defines.stub', 'STR_PAD_LEFT' => 'standard/standard_defines.stub', 'STR_PAD_RIGHT' => 'standard/standard_defines.stub', 'ST_SET' => 'imap/imap.stub', 'ST_SILENT' => 'imap/imap.stub', 'ST_UID' => 'imap/imap.stub', 'SUHOSIN_PATCH' => 'Core/Core_d.stub', 'SUHOSIN_PATCH_VERSION' => 'Core/Core_d.stub', 'SUNFUNCS_RET_DOUBLE' => 'date/date_d.stub', 'SUNFUNCS_RET_STRING' => 'date/date_d.stub', 'SUNFUNCS_RET_TIMESTAMP' => 'date/date_d.stub', 'SVN_ALL' => 'svn/svn.stub', 'SVN_AUTH_PARAM_CONFIG' => 'svn/svn.stub', 'SVN_AUTH_PARAM_CONFIG_DIR' => 'svn/svn.stub', 'SVN_AUTH_PARAM_DEFAULT_PASSWORD' => 'svn/svn.stub', 'SVN_AUTH_PARAM_DEFAULT_USERNAME' => 'svn/svn.stub', 'SVN_AUTH_PARAM_DONT_STORE_PASSWORDS' => 'svn/svn.stub', 'SVN_AUTH_PARAM_NON_INTERACTIVE' => 'svn/svn.stub', 'SVN_AUTH_PARAM_NO_AUTH_CACHE' => 'svn/svn.stub', 'SVN_AUTH_PARAM_SERVER_GROUP' => 'svn/svn.stub', 'SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO' => 'svn/svn.stub', 'SVN_AUTH_PARAM_SSL_SERVER_FAILURES' => 'svn/svn.stub', 'SVN_DISCOVER_CHANGED_PATHS' => 'svn/svn.stub', 'SVN_FS_CONFIG_FS_TYPE' => 'svn/svn.stub', 'SVN_FS_TYPE_BDB' => 'svn/svn.stub', 'SVN_FS_TYPE_FSFS' => 'svn/svn.stub', 'SVN_NODE_DIR' => 'svn/svn.stub', 'SVN_NODE_FILE' => 'svn/svn.stub', 'SVN_NODE_NONE' => 'svn/svn.stub', 'SVN_NODE_UNKNOWN' => 'svn/svn.stub', 'SVN_NON_RECURSIVE' => 'svn/svn.stub', 'SVN_NO_IGNORE' => 'svn/svn.stub', 'SVN_OMIT_MESSAGES' => 'svn/svn.stub', 'SVN_PROP_REVISION_AUTHOR' => 'svn/svn.stub', 'SVN_PROP_REVISION_DATE' => 'svn/svn.stub', 'SVN_PROP_REVISION_LOG' => 'svn/svn.stub', 'SVN_PROP_REVISION_ORIG_DATE' => 'svn/svn.stub', 'SVN_REVISION_BASE' => 'svn/svn.stub', 'SVN_REVISION_COMMITTED' => 'svn/svn.stub', 'SVN_REVISION_HEAD' => 'svn/svn.stub', 'SVN_REVISION_INITIAL' => 'svn/svn.stub', 'SVN_REVISION_PREV' => 'svn/svn.stub', 'SVN_REVISION_UNSPECIFIED' => 'svn/svn.stub', 'SVN_SHOW_UPDATES' => 'svn/svn.stub', 'SVN_STOP_ON_COPY' => 'svn/svn.stub', 'SVN_WC_SCHEDULE_ADD' => 'svn/svn.stub', 'SVN_WC_SCHEDULE_DELETE' => 'svn/svn.stub', 'SVN_WC_SCHEDULE_NORMAL' => 'svn/svn.stub', 'SVN_WC_SCHEDULE_REPLACE' => 'svn/svn.stub', 'SVN_WC_STATUS_ADDED' => 'svn/svn.stub', 'SVN_WC_STATUS_CONFLICTED' => 'svn/svn.stub', 'SVN_WC_STATUS_DELETED' => 'svn/svn.stub', 'SVN_WC_STATUS_EXTERNAL' => 'svn/svn.stub', 'SVN_WC_STATUS_IGNORED' => 'svn/svn.stub', 'SVN_WC_STATUS_INCOMPLETE' => 'svn/svn.stub', 'SVN_WC_STATUS_MERGED' => 'svn/svn.stub', 'SVN_WC_STATUS_MISSING' => 'svn/svn.stub', 'SVN_WC_STATUS_MODIFIED' => 'svn/svn.stub', 'SVN_WC_STATUS_NONE' => 'svn/svn.stub', 'SVN_WC_STATUS_NORMAL' => 'svn/svn.stub', 'SVN_WC_STATUS_OBSTRUCTED' => 'svn/svn.stub', 'SVN_WC_STATUS_REPLACED' => 'svn/svn.stub', 'SVN_WC_STATUS_UNVERSIONED' => 'svn/svn.stub', 'SWFACTION_DATA' => 'ming/ming.stub', 'SWFACTION_ENTERFRAME' => 'ming/ming.stub', 'SWFACTION_KEYDOWN' => 'ming/ming.stub', 'SWFACTION_KEYUP' => 'ming/ming.stub', 'SWFACTION_MOUSEDOWN' => 'ming/ming.stub', 'SWFACTION_MOUSEMOVE' => 'ming/ming.stub', 'SWFACTION_MOUSEUP' => 'ming/ming.stub', 'SWFACTION_ONLOAD' => 'ming/ming.stub', 'SWFACTION_UNLOAD' => 'ming/ming.stub', 'SWFBUTTON_DOWN' => 'ming/ming.stub', 'SWFBUTTON_DRAGOUT' => 'ming/ming.stub', 'SWFBUTTON_DRAGOVER' => 'ming/ming.stub', 'SWFBUTTON_HIT' => 'ming/ming.stub', 'SWFBUTTON_MOUSEDOWN' => 'ming/ming.stub', 'SWFBUTTON_MOUSEOUT' => 'ming/ming.stub', 'SWFBUTTON_MOUSEOVER' => 'ming/ming.stub', 'SWFBUTTON_MOUSEUP' => 'ming/ming.stub', 'SWFBUTTON_MOUSEUPOUTSIDE' => 'ming/ming.stub', 'SWFBUTTON_OVER' => 'ming/ming.stub', 'SWFBUTTON_UP' => 'ming/ming.stub', 'SWFFILL_CLIPPED_BITMAP' => 'ming/ming.stub', 'SWFFILL_LINEAR_GRADIENT' => 'ming/ming.stub', 'SWFFILL_RADIAL_GRADIENT' => 'ming/ming.stub', 'SWFFILL_TILED_BITMAP' => 'ming/ming.stub', 'SWFTEXTFIELD_ALIGN_CENTER' => 'ming/ming.stub', 'SWFTEXTFIELD_ALIGN_JUSTIFY' => 'ming/ming.stub', 'SWFTEXTFIELD_ALIGN_LEFT' => 'ming/ming.stub', 'SWFTEXTFIELD_ALIGN_RIGHT' => 'ming/ming.stub', 'SWFTEXTFIELD_AUTOSIZE' => 'ming/ming.stub', 'SWFTEXTFIELD_DRAWBOX' => 'ming/ming.stub', 'SWFTEXTFIELD_HASLENGTH' => 'ming/ming.stub', 'SWFTEXTFIELD_HTML' => 'ming/ming.stub', 'SWFTEXTFIELD_MULTILINE' => 'ming/ming.stub', 'SWFTEXTFIELD_NOEDIT' => 'ming/ming.stub', 'SWFTEXTFIELD_NOSELECT' => 'ming/ming.stub', 'SWFTEXTFIELD_PASSWORD' => 'ming/ming.stub', 'SWFTEXTFIELD_USEFONT' => 'ming/ming.stub', 'SWFTEXTFIELD_WORDWRAP' => 'ming/ming.stub', 'SWF_SOUND_11KHZ' => 'ming/ming.stub', 'SWF_SOUND_16BITS' => 'ming/ming.stub', 'SWF_SOUND_22KHZ' => 'ming/ming.stub', 'SWF_SOUND_44KHZ' => 'ming/ming.stub', 'SWF_SOUND_5KHZ' => 'ming/ming.stub', 'SWF_SOUND_8BITS' => 'ming/ming.stub', 'SWF_SOUND_ADPCM_COMPRESSED' => 'ming/ming.stub', 'SWF_SOUND_MONO' => 'ming/ming.stub', 'SWF_SOUND_MP3_COMPRESSED' => 'ming/ming.stub', 'SWF_SOUND_NELLY_COMPRESSED' => 'ming/ming.stub', 'SWF_SOUND_NOT_COMPRESSED' => 'ming/ming.stub', 'SWF_SOUND_NOT_COMPRESSED_LE' => 'ming/ming.stub', 'SWF_SOUND_STEREO' => 'ming/ming.stub', 'SWOOLE_ASYNC' => 'swoole/constants.stub', 'SWOOLE_BASE' => 'swoole/constants.stub', 'SWOOLE_CHANNEL_CANCELED' => 'swoole/constants.stub', 'SWOOLE_CHANNEL_CLOSED' => 'swoole/constants.stub', 'SWOOLE_CHANNEL_OK' => 'swoole/constants.stub', 'SWOOLE_CHANNEL_TIMEOUT' => 'swoole/constants.stub', 'SWOOLE_CORO_END' => 'swoole/constants.stub', 'SWOOLE_CORO_INIT' => 'swoole/constants.stub', 'SWOOLE_CORO_MAX_NUM_LIMIT' => 'swoole/constants.stub', 'SWOOLE_CORO_RUNNING' => 'swoole/constants.stub', 'SWOOLE_CORO_WAITING' => 'swoole/constants.stub', 'SWOOLE_DEBUG' => 'swoole/constants.stub', 'SWOOLE_DEFAULT_MAX_CORO_NUM' => 'swoole/constants.stub', 'SWOOLE_DISPATCH_CO_CONN_LB' => 'swoole/constants.stub', 'SWOOLE_DISPATCH_CO_REQ_LB' => 'swoole/constants.stub', 'SWOOLE_DISPATCH_FDMOD' => 'swoole/constants.stub', 'SWOOLE_DISPATCH_IDLE_WORKER' => 'swoole/constants.stub', 'SWOOLE_DISPATCH_IPMOD' => 'swoole/constants.stub', 'SWOOLE_DISPATCH_RESULT_CLOSE_CONNECTION' => 'swoole/constants.stub', 'SWOOLE_DISPATCH_RESULT_DISCARD_PACKET' => 'swoole/constants.stub', 'SWOOLE_DISPATCH_RESULT_USERFUNC_FALLBACK' => 'swoole/constants.stub', 'SWOOLE_DISPATCH_ROUND' => 'swoole/constants.stub', 'SWOOLE_DISPATCH_STREAM' => 'swoole/constants.stub', 'SWOOLE_DISPATCH_UIDMOD' => 'swoole/constants.stub', 'SWOOLE_DISPATCH_USERFUNC' => 'swoole/constants.stub', 'SWOOLE_DTLS_CLIENT_METHOD' => 'swoole/constants.stub', 'SWOOLE_DTLS_SERVER_METHOD' => 'swoole/constants.stub', 'SWOOLE_ERROR_AIO_BAD_REQUEST' => 'swoole/constants.stub', 'SWOOLE_ERROR_AIO_CANCELED' => 'swoole/constants.stub', 'SWOOLE_ERROR_AIO_TIMEOUT' => 'swoole/constants.stub', 'SWOOLE_ERROR_BAD_IPV6_ADDRESS' => 'swoole/constants.stub', 'SWOOLE_ERROR_CLIENT_NO_CONNECTION' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_BLOCK_OBJECT_LOCKED' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_BLOCK_OBJECT_WAITING' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_CANCELED' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_CANNOT_CANCEL' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_DISABLED_MULTI_THREAD' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_GETCONTEXT_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_HAS_BEEN_BOUND' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_HAS_BEEN_DISCARDED' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_IOCPINIT_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_MAKECONTEXT_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_MUTEX_DOUBLE_UNLOCK' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_NOT_EXISTS' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_OUT_OF_COROUTINE' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_PROTECT_STACK_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_STD_THREAD_LINK_ERROR' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_SWAPCONTEXT_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_TIMEDOUT' => 'swoole/constants.stub', 'SWOOLE_ERROR_CO_YIELD_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_DATA_LENGTH_TOO_LARGE' => 'swoole/constants.stub', 'SWOOLE_ERROR_DNSLOOKUP_DUPLICATE_REQUEST' => 'swoole/constants.stub', 'SWOOLE_ERROR_DNSLOOKUP_NO_SERVER' => 'swoole/constants.stub', 'SWOOLE_ERROR_DNSLOOKUP_RESOLVE_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_DNSLOOKUP_RESOLVE_TIMEOUT' => 'swoole/constants.stub', 'SWOOLE_ERROR_DNSLOOKUP_UNSUPPORTED' => 'swoole/constants.stub', 'SWOOLE_ERROR_EVENT_SOCKET_REMOVED' => 'swoole/constants.stub', 'SWOOLE_ERROR_FILE_EMPTY' => 'swoole/constants.stub', 'SWOOLE_ERROR_FILE_NOT_EXIST' => 'swoole/constants.stub', 'SWOOLE_ERROR_FILE_TOO_LARGE' => 'swoole/constants.stub', 'SWOOLE_ERROR_HTTP2_STREAM_ID_TOO_BIG' => 'swoole/constants.stub', 'SWOOLE_ERROR_HTTP2_STREAM_IGNORE' => 'swoole/constants.stub', 'SWOOLE_ERROR_HTTP2_STREAM_NOT_FOUND' => 'swoole/constants.stub', 'SWOOLE_ERROR_HTTP2_STREAM_NO_HEADER' => 'swoole/constants.stub', 'SWOOLE_ERROR_HTTP_INVALID_PROTOCOL' => 'swoole/constants.stub', 'SWOOLE_ERROR_HTTP_PROXY_BAD_RESPONSE' => 'swoole/constants.stub', 'SWOOLE_ERROR_HTTP_PROXY_HANDSHAKE_ERROR' => 'swoole/constants.stub', 'SWOOLE_ERROR_HTTP_PROXY_HANDSHAKE_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_INVALID_PARAMS' => 'swoole/constants.stub', 'SWOOLE_ERROR_MALLOC_FAIL' => 'swoole/constants.stub', 'SWOOLE_ERROR_NAME_TOO_LONG' => 'swoole/constants.stub', 'SWOOLE_ERROR_OPERATION_NOT_SUPPORT' => 'swoole/constants.stub', 'SWOOLE_ERROR_OUTPUT_BUFFER_OVERFLOW' => 'swoole/constants.stub', 'SWOOLE_ERROR_OUTPUT_SEND_YIELD' => 'swoole/constants.stub', 'SWOOLE_ERROR_PACKAGE_LENGTH_NOT_FOUND' => 'swoole/constants.stub', 'SWOOLE_ERROR_PACKAGE_LENGTH_TOO_LARGE' => 'swoole/constants.stub', 'SWOOLE_ERROR_PACKAGE_MALFORMED_DATA' => 'swoole/constants.stub', 'SWOOLE_ERROR_PHP_FATAL_ERROR' => 'swoole/constants.stub', 'SWOOLE_ERROR_PROTOCOL_ERROR' => 'swoole/constants.stub', 'SWOOLE_ERROR_QUEUE_FULL' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_CONNECT_FAIL' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_INVALID_COMMAND' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_INVALID_LISTEN_PORT' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_INVALID_REQUEST' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_MUST_CREATED_BEFORE_CLIENT' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_NO_IDLE_WORKER' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_ONLY_START_ONE' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_PIPE_BUFFER_FULL' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_SEND_IN_MASTER' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_TOO_MANY_LISTEN_PORT' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_TOO_MANY_SOCKET' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_WORKER_ABNORMAL_PIPE_DATA' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_WORKER_EXIT_TIMEOUT' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_WORKER_TERMINATED' => 'swoole/constants.stub', 'SWOOLE_ERROR_SERVER_WORKER_UNPROCESSED_DATA' => 'swoole/constants.stub', 'SWOOLE_ERROR_SESSION_CLOSED' => 'swoole/constants.stub', 'SWOOLE_ERROR_SESSION_CLOSED_BY_CLIENT' => 'swoole/constants.stub', 'SWOOLE_ERROR_SESSION_CLOSED_BY_SERVER' => 'swoole/constants.stub', 'SWOOLE_ERROR_SESSION_CLOSING' => 'swoole/constants.stub', 'SWOOLE_ERROR_SESSION_DISCARD_DATA' => 'swoole/constants.stub', 'SWOOLE_ERROR_SESSION_DISCARD_TIMEOUT_DATA' => 'swoole/constants.stub', 'SWOOLE_ERROR_SESSION_INVALID_ID' => 'swoole/constants.stub', 'SWOOLE_ERROR_SESSION_NOT_EXIST' => 'swoole/constants.stub', 'SWOOLE_ERROR_SOCKET_CLOSED' => 'swoole/constants.stub', 'SWOOLE_ERROR_SOCKET_POLL_TIMEOUT' => 'swoole/constants.stub', 'SWOOLE_ERROR_SOCKS5_AUTH_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_SOCKS5_HANDSHAKE_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_SOCKS5_SERVER_ERROR' => 'swoole/constants.stub', 'SWOOLE_ERROR_SOCKS5_UNSUPPORT_METHOD' => 'swoole/constants.stub', 'SWOOLE_ERROR_SOCKS5_UNSUPPORT_VERSION' => 'swoole/constants.stub', 'SWOOLE_ERROR_SSL_BAD_CLIENT' => 'swoole/constants.stub', 'SWOOLE_ERROR_SSL_BAD_PROTOCOL' => 'swoole/constants.stub', 'SWOOLE_ERROR_SSL_CANNOT_USE_SENFILE' => 'swoole/constants.stub', 'SWOOLE_ERROR_SSL_EMPTY_PEER_CERTIFICATE' => 'swoole/constants.stub', 'SWOOLE_ERROR_SSL_HANDSHAKE_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_SSL_NOT_READY' => 'swoole/constants.stub', 'SWOOLE_ERROR_SSL_RESET' => 'swoole/constants.stub', 'SWOOLE_ERROR_SSL_VERIFY_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_SYSTEM_CALL_FAIL' => 'swoole/constants.stub', 'SWOOLE_ERROR_TASK_DISPATCH_FAIL' => 'swoole/constants.stub', 'SWOOLE_ERROR_TASK_PACKAGE_TOO_BIG' => 'swoole/constants.stub', 'SWOOLE_ERROR_TASK_TIMEOUT' => 'swoole/constants.stub', 'SWOOLE_ERROR_UNREGISTERED_SIGNAL' => 'swoole/constants.stub', 'SWOOLE_ERROR_WEBSOCKET_BAD_CLIENT' => 'swoole/constants.stub', 'SWOOLE_ERROR_WEBSOCKET_BAD_OPCODE' => 'swoole/constants.stub', 'SWOOLE_ERROR_WEBSOCKET_HANDSHAKE_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_WEBSOCKET_INCOMPLETE_PACKET' => 'swoole/constants.stub', 'SWOOLE_ERROR_WEBSOCKET_PACK_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_WEBSOCKET_UNCONNECTED' => 'swoole/constants.stub', 'SWOOLE_ERROR_WEBSOCKET_UNPACK_FAILED' => 'swoole/constants.stub', 'SWOOLE_ERROR_WRONG_OPERATION' => 'swoole/constants.stub', 'SWOOLE_EVENT_READ' => 'swoole/constants.stub', 'SWOOLE_EVENT_WRITE' => 'swoole/constants.stub', 'SWOOLE_EXIT_IN_COROUTINE' => 'swoole/constants.stub', 'SWOOLE_EXIT_IN_SERVER' => 'swoole/constants.stub', 'SWOOLE_EXTRA_VERSION' => 'swoole/constants.stub', 'SWOOLE_FILELOCK' => 'swoole/constants.stub', 'SWOOLE_HAVE_BROTLI' => 'swoole/constants.stub', 'SWOOLE_HAVE_COMPRESSION' => 'swoole/constants.stub', 'SWOOLE_HAVE_ZLIB' => 'swoole/constants.stub', 'SWOOLE_HOOK_ALL' => 'swoole/constants.stub', 'SWOOLE_HOOK_BLOCKING_FUNCTION' => 'swoole/constants.stub', 'SWOOLE_HOOK_CURL' => 'swoole/constants.stub', 'SWOOLE_HOOK_FILE' => 'swoole/constants.stub', 'SWOOLE_HOOK_NATIVE_CURL' => 'swoole/constants.stub', 'SWOOLE_HOOK_PROC' => 'swoole/constants.stub', 'SWOOLE_HOOK_SLEEP' => 'swoole/constants.stub', 'SWOOLE_HOOK_SOCKETS' => 'swoole/constants.stub', 'SWOOLE_HOOK_SSL' => 'swoole/constants.stub', 'SWOOLE_HOOK_STDIO' => 'swoole/constants.stub', 'SWOOLE_HOOK_STREAM_FUNCTION' => 'swoole/constants.stub', 'SWOOLE_HOOK_STREAM_SELECT' => 'swoole/constants.stub', 'SWOOLE_HOOK_TCP' => 'swoole/constants.stub', 'SWOOLE_HOOK_TLS' => 'swoole/constants.stub', 'SWOOLE_HOOK_UDG' => 'swoole/constants.stub', 'SWOOLE_HOOK_UDP' => 'swoole/constants.stub', 'SWOOLE_HOOK_UNIX' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_CANCEL' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_COMPRESSION_ERROR' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_CONNECT_ERROR' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_ENHANCE_YOUR_CALM' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_FLOW_CONTROL_ERROR' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_FRAME_SIZE_ERROR' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_INADEQUATE_SECURITY' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_INTERNAL_ERROR' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_NO_ERROR' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_PROTOCOL_ERROR' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_REFUSED_STREAM' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_SETTINGS_TIMEOUT' => 'swoole/constants.stub', 'SWOOLE_HTTP2_ERROR_STREAM_CLOSED' => 'swoole/constants.stub', 'SWOOLE_HTTP2_TYPE_CONTINUATION' => 'swoole/constants.stub', 'SWOOLE_HTTP2_TYPE_DATA' => 'swoole/constants.stub', 'SWOOLE_HTTP2_TYPE_GOAWAY' => 'swoole/constants.stub', 'SWOOLE_HTTP2_TYPE_HEADERS' => 'swoole/constants.stub', 'SWOOLE_HTTP2_TYPE_PING' => 'swoole/constants.stub', 'SWOOLE_HTTP2_TYPE_PRIORITY' => 'swoole/constants.stub', 'SWOOLE_HTTP2_TYPE_PUSH_PROMISE' => 'swoole/constants.stub', 'SWOOLE_HTTP2_TYPE_RST_STREAM' => 'swoole/constants.stub', 'SWOOLE_HTTP2_TYPE_SETTINGS' => 'swoole/constants.stub', 'SWOOLE_HTTP2_TYPE_WINDOW_UPDATE' => 'swoole/constants.stub', 'SWOOLE_HTTP_CLIENT_ESTATUS_CONNECT_FAILED' => 'swoole/constants.stub', 'SWOOLE_HTTP_CLIENT_ESTATUS_REQUEST_TIMEOUT' => 'swoole/constants.stub', 'SWOOLE_HTTP_CLIENT_ESTATUS_SEND_FAILED' => 'swoole/constants.stub', 'SWOOLE_HTTP_CLIENT_ESTATUS_SERVER_RESET' => 'swoole/constants.stub', 'SWOOLE_IOV_MAX' => 'swoole/constants.stub', 'SWOOLE_IPC_MSGQUEUE' => 'swoole/constants.stub', 'SWOOLE_IPC_NONE' => 'swoole/constants.stub', 'SWOOLE_IPC_PREEMPTIVE' => 'swoole/constants.stub', 'SWOOLE_IPC_SOCKET' => 'swoole/constants.stub', 'SWOOLE_IPC_UNIXSOCK' => 'swoole/constants.stub', 'SWOOLE_IPC_UNSOCK' => 'swoole/constants.stub', 'SWOOLE_KEEP' => 'swoole/constants.stub', 'SWOOLE_LOG_DEBUG' => 'swoole/constants.stub', 'SWOOLE_LOG_ERROR' => 'swoole/constants.stub', 'SWOOLE_LOG_INFO' => 'swoole/constants.stub', 'SWOOLE_LOG_NONE' => 'swoole/constants.stub', 'SWOOLE_LOG_NOTICE' => 'swoole/constants.stub', 'SWOOLE_LOG_ROTATION_DAILY' => 'swoole/constants.stub', 'SWOOLE_LOG_ROTATION_EVERY_MINUTE' => 'swoole/constants.stub', 'SWOOLE_LOG_ROTATION_HOURLY' => 'swoole/constants.stub', 'SWOOLE_LOG_ROTATION_MONTHLY' => 'swoole/constants.stub', 'SWOOLE_LOG_ROTATION_SINGLE' => 'swoole/constants.stub', 'SWOOLE_LOG_TRACE' => 'swoole/constants.stub', 'SWOOLE_LOG_WARNING' => 'swoole/constants.stub', 'SWOOLE_MAJOR_VERSION' => 'swoole/constants.stub', 'SWOOLE_MINOR_VERSION' => 'swoole/constants.stub', 'SWOOLE_MUTEX' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_CANT_FIND_CHARSET' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_COMMANDS_OUT_OF_SYNC' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_CONNECTION_ERROR' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_INVALID_BUFFER_USE' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_INVALID_PARAMETER_NO' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_MALFORMED_PACKET' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_NOT_IMPLEMENTED' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_NO_PREPARE_STMT' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_OUT_OF_MEMORY' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_PARAMS_NOT_BOUND' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_SERVER_GONE_ERROR' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_SERVER_LOST' => 'swoole/constants.stub', 'SWOOLE_MYSQLND_CR_UNKNOWN_ERROR' => 'swoole/constants.stub', 'SWOOLE_PROCESS' => 'swoole/constants.stub', 'SWOOLE_REDIS_ERR_ALLOC' => 'swoole/constants.stub', 'SWOOLE_REDIS_ERR_CLOSED' => 'swoole/constants.stub', 'SWOOLE_REDIS_ERR_EOF' => 'swoole/constants.stub', 'SWOOLE_REDIS_ERR_IO' => 'swoole/constants.stub', 'SWOOLE_REDIS_ERR_NOAUTH' => 'swoole/constants.stub', 'SWOOLE_REDIS_ERR_OOM' => 'swoole/constants.stub', 'SWOOLE_REDIS_ERR_OTHER' => 'swoole/constants.stub', 'SWOOLE_REDIS_ERR_PROTOCOL' => 'swoole/constants.stub', 'SWOOLE_REDIS_MODE_MULTI' => 'swoole/constants.stub', 'SWOOLE_REDIS_MODE_PIPELINE' => 'swoole/constants.stub', 'SWOOLE_REDIS_TYPE_HASH' => 'swoole/constants.stub', 'SWOOLE_REDIS_TYPE_LIST' => 'swoole/constants.stub', 'SWOOLE_REDIS_TYPE_NOT_FOUND' => 'swoole/constants.stub', 'SWOOLE_REDIS_TYPE_SET' => 'swoole/constants.stub', 'SWOOLE_REDIS_TYPE_STRING' => 'swoole/constants.stub', 'SWOOLE_REDIS_TYPE_ZSET' => 'swoole/constants.stub', 'SWOOLE_RELEASE_VERSION' => 'swoole/constants.stub', 'SWOOLE_RWLOCK' => 'swoole/constants.stub', 'SWOOLE_SEM' => 'swoole/constants.stub', 'SWOOLE_SERVER_COMMAND_EVENT_WORKER' => 'swoole/constants.stub', 'SWOOLE_SERVER_COMMAND_MANAGER' => 'swoole/constants.stub', 'SWOOLE_SERVER_COMMAND_MASTER' => 'swoole/constants.stub', 'SWOOLE_SERVER_COMMAND_REACTOR_THREAD' => 'swoole/constants.stub', 'SWOOLE_SERVER_COMMAND_TASK_WORKER' => 'swoole/constants.stub', 'SWOOLE_SERVER_COMMAND_WORKER' => 'swoole/constants.stub', 'SWOOLE_SOCK_ASYNC' => 'swoole/constants.stub', 'SWOOLE_SOCK_SYNC' => 'swoole/constants.stub', 'SWOOLE_SOCK_TCP' => 'swoole/constants.stub', 'SWOOLE_SOCK_TCP6' => 'swoole/constants.stub', 'SWOOLE_SOCK_UDP' => 'swoole/constants.stub', 'SWOOLE_SOCK_UDP6' => 'swoole/constants.stub', 'SWOOLE_SOCK_UNIX_DGRAM' => 'swoole/constants.stub', 'SWOOLE_SOCK_UNIX_STREAM' => 'swoole/constants.stub', 'SWOOLE_SPINLOCK' => 'swoole/constants.stub', 'SWOOLE_SSL' => 'swoole/constants.stub', 'SWOOLE_SSL_DTLS' => 'swoole/constants.stub', 'SWOOLE_SSL_SSLv2' => 'swoole/constants.stub', 'SWOOLE_SSL_TLSv1' => 'swoole/constants.stub', 'SWOOLE_SSL_TLSv1_1' => 'swoole/constants.stub', 'SWOOLE_SSL_TLSv1_2' => 'swoole/constants.stub', 'SWOOLE_SSL_TLSv1_3' => 'swoole/constants.stub', 'SWOOLE_SSLv23_CLIENT_METHOD' => 'swoole/constants.stub', 'SWOOLE_SSLv23_METHOD' => 'swoole/constants.stub', 'SWOOLE_SSLv23_SERVER_METHOD' => 'swoole/constants.stub', 'SWOOLE_SSLv3_CLIENT_METHOD' => 'swoole/constants.stub', 'SWOOLE_SSLv3_METHOD' => 'swoole/constants.stub', 'SWOOLE_SSLv3_SERVER_METHOD' => 'swoole/constants.stub', 'SWOOLE_STRERROR_DNS' => 'swoole/constants.stub', 'SWOOLE_STRERROR_GAI' => 'swoole/constants.stub', 'SWOOLE_STRERROR_SWOOLE' => 'swoole/constants.stub', 'SWOOLE_STRERROR_SYSTEM' => 'swoole/constants.stub', 'SWOOLE_SYNC' => 'swoole/constants.stub', 'SWOOLE_TASK_CALLBACK' => 'swoole/constants.stub', 'SWOOLE_TASK_COROUTINE' => 'swoole/constants.stub', 'SWOOLE_TASK_NONBLOCK' => 'swoole/constants.stub', 'SWOOLE_TASK_NOREPLY' => 'swoole/constants.stub', 'SWOOLE_TASK_PEEK' => 'swoole/constants.stub', 'SWOOLE_TASK_SERIALIZE' => 'swoole/constants.stub', 'SWOOLE_TASK_TMPFILE' => 'swoole/constants.stub', 'SWOOLE_TASK_WAITALL' => 'swoole/constants.stub', 'SWOOLE_TCP' => 'swoole/constants.stub', 'SWOOLE_TCP6' => 'swoole/constants.stub', 'SWOOLE_TIMER_MAX_MS' => 'swoole/constants.stub', 'SWOOLE_TIMER_MAX_SEC' => 'swoole/constants.stub', 'SWOOLE_TIMER_MIN_MS' => 'swoole/constants.stub', 'SWOOLE_TIMER_MIN_SEC' => 'swoole/constants.stub', 'SWOOLE_TLS_CLIENT_METHOD' => 'swoole/constants.stub', 'SWOOLE_TLS_METHOD' => 'swoole/constants.stub', 'SWOOLE_TLS_SERVER_METHOD' => 'swoole/constants.stub', 'SWOOLE_TLSv1_1_CLIENT_METHOD' => 'swoole/constants.stub', 'SWOOLE_TLSv1_1_METHOD' => 'swoole/constants.stub', 'SWOOLE_TLSv1_1_SERVER_METHOD' => 'swoole/constants.stub', 'SWOOLE_TLSv1_2_CLIENT_METHOD' => 'swoole/constants.stub', 'SWOOLE_TLSv1_2_METHOD' => 'swoole/constants.stub', 'SWOOLE_TLSv1_2_SERVER_METHOD' => 'swoole/constants.stub', 'SWOOLE_TLSv1_CLIENT_METHOD' => 'swoole/constants.stub', 'SWOOLE_TLSv1_METHOD' => 'swoole/constants.stub', 'SWOOLE_TLSv1_SERVER_METHOD' => 'swoole/constants.stub', 'SWOOLE_TRACE_AIO' => 'swoole/constants.stub', 'SWOOLE_TRACE_ALL' => 'swoole/constants.stub', 'SWOOLE_TRACE_BUFFER' => 'swoole/constants.stub', 'SWOOLE_TRACE_CARES' => 'swoole/constants.stub', 'SWOOLE_TRACE_CHANNEL' => 'swoole/constants.stub', 'SWOOLE_TRACE_CLIENT' => 'swoole/constants.stub', 'SWOOLE_TRACE_CLOSE' => 'swoole/constants.stub', 'SWOOLE_TRACE_CONN' => 'swoole/constants.stub', 'SWOOLE_TRACE_CONTEXT' => 'swoole/constants.stub', 'SWOOLE_TRACE_COROUTINE' => 'swoole/constants.stub', 'SWOOLE_TRACE_CO_CURL' => 'swoole/constants.stub', 'SWOOLE_TRACE_CO_HTTP_SERVER' => 'swoole/constants.stub', 'SWOOLE_TRACE_EOF_PROTOCOL' => 'swoole/constants.stub', 'SWOOLE_TRACE_EVENT' => 'swoole/constants.stub', 'SWOOLE_TRACE_HTTP' => 'swoole/constants.stub', 'SWOOLE_TRACE_HTTP2' => 'swoole/constants.stub', 'SWOOLE_TRACE_HTTP_CLIENT' => 'swoole/constants.stub', 'SWOOLE_TRACE_LENGTH_PROTOCOL' => 'swoole/constants.stub', 'SWOOLE_TRACE_MEMORY' => 'swoole/constants.stub', 'SWOOLE_TRACE_MYSQL_CLIENT' => 'swoole/constants.stub', 'SWOOLE_TRACE_NORMAL' => 'swoole/constants.stub', 'SWOOLE_TRACE_PHP' => 'swoole/constants.stub', 'SWOOLE_TRACE_REACTOR' => 'swoole/constants.stub', 'SWOOLE_TRACE_REDIS_CLIENT' => 'swoole/constants.stub', 'SWOOLE_TRACE_SERVER' => 'swoole/constants.stub', 'SWOOLE_TRACE_SOCKET' => 'swoole/constants.stub', 'SWOOLE_TRACE_SSL' => 'swoole/constants.stub', 'SWOOLE_TRACE_TABLE' => 'swoole/constants.stub', 'SWOOLE_TRACE_TIMER' => 'swoole/constants.stub', 'SWOOLE_TRACE_WEBSOCKET' => 'swoole/constants.stub', 'SWOOLE_TRACE_WORKER' => 'swoole/constants.stub', 'SWOOLE_UDP' => 'swoole/constants.stub', 'SWOOLE_UDP6' => 'swoole/constants.stub', 'SWOOLE_UNIX_DGRAM' => 'swoole/constants.stub', 'SWOOLE_UNIX_STREAM' => 'swoole/constants.stub', 'SWOOLE_USE_HTTP2' => 'swoole/constants.stub', 'SWOOLE_USE_SHORTNAME' => 'swoole/constants.stub', 'SWOOLE_VERSION' => 'swoole/constants.stub', 'SWOOLE_VERSION_ID' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_CLOSE_ABNORMAL' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_CLOSE_DATA_ERROR' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_CLOSE_EXTENSION_MISSING' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_CLOSE_GOING_AWAY' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_CLOSE_MESSAGE_ERROR' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_CLOSE_MESSAGE_TOO_BIG' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_CLOSE_NORMAL' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_CLOSE_POLICY_ERROR' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_CLOSE_PROTOCOL_ERROR' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_CLOSE_SERVER_ERROR' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_CLOSE_STATUS_ERROR' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_CLOSE_TLS' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_FLAG_COMPRESS' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_FLAG_FIN' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_FLAG_MASK' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_FLAG_RSV1' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_FLAG_RSV2' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_FLAG_RSV3' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_OPCODE_BINARY' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_OPCODE_CLOSE' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_OPCODE_CONTINUATION' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_OPCODE_PING' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_OPCODE_PONG' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_OPCODE_TEXT' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_STATUS_ACTIVE' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_STATUS_CLOSING' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_STATUS_CONNECTION' => 'swoole/constants.stub', 'SWOOLE_WEBSOCKET_STATUS_HANDSHAKE' => 'swoole/constants.stub', 'SWOOLE_WORKER_BUSY' => 'swoole/constants.stub', 'SWOOLE_WORKER_EXIT' => 'swoole/constants.stub', 'SWOOLE_WORKER_IDLE' => 'swoole/constants.stub', 'S_ALL' => 'Core/Core_d.stub', 'S_EXECUTOR' => 'Core/Core_d.stub', 'S_FILES' => 'Core/Core_d.stub', 'S_INCLUDE' => 'Core/Core_d.stub', 'S_INTERNAL' => 'Core/Core_d.stub', 'S_IRGRP' => 'dio/dio_d.stub', 'S_IROTH' => 'dio/dio_d.stub', 'S_IRUSR' => 'dio/dio_d.stub', 'S_IRWXG' => 'dio/dio_d.stub', 'S_IRWXO' => 'dio/dio_d.stub', 'S_IRWXU' => 'dio/dio_d.stub', 'S_IWGRP' => 'dio/dio_d.stub', 'S_IWOTH' => 'dio/dio_d.stub', 'S_IWUSR' => 'dio/dio_d.stub', 'S_IXGRP' => 'dio/dio_d.stub', 'S_IXOTH' => 'dio/dio_d.stub', 'S_IXUSR' => 'dio/dio_d.stub', 'S_MAIL' => 'Core/Core_d.stub', 'S_MEMORY' => 'Core/Core_d.stub', 'S_MISC' => 'Core/Core_d.stub', 'S_SESSION' => 'Core/Core_d.stub', 'S_SQL' => 'Core/Core_d.stub', 'S_VARS' => 'Core/Core_d.stub', 'ScrollBar' => 'winbinder/winbinder.stub', 'Slider' => 'winbinder/winbinder.stub', 'Sodium\\CRYPTO_AEAD_AES256GCM_ABYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_AEAD_AES256GCM_KEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_AEAD_AES256GCM_NPUBBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_AEAD_AES256GCM_NSECBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_AEAD_CHACHA20POLY1305_ABYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_AUTH_BYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_AUTH_KEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_BOX_KEYPAIRBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_BOX_MACBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_BOX_NONCEBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_BOX_PUBLICKEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_BOX_SEALBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_BOX_SECRETKEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_BOX_SEEDBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_GENERICHASH_BYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_GENERICHASH_BYTES_MAX' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_GENERICHASH_BYTES_MIN' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_GENERICHASH_KEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_GENERICHASH_KEYBYTES_MAX' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_GENERICHASH_KEYBYTES_MIN' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_KX_BYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_KX_PUBLICKEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_KX_SECRETKEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_PWHASH_MEMLIMIT_MODERATE' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_PWHASH_MEMLIMIT_SENSITIVE' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_PWHASH_OPSLIMIT_MODERATE' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_PWHASH_OPSLIMIT_SENSITIVE' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_SCALARMULT_BYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_SCALARMULT_SCALARBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_SECRETBOX_KEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_SECRETBOX_MACBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_SECRETBOX_NONCEBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_SHORTHASH_BYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_SHORTHASH_KEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_SIGN_BYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_SIGN_KEYPAIRBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_SIGN_PUBLICKEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_SIGN_SECRETKEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_SIGN_SEEDBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_STREAM_KEYBYTES' => 'libsodium/libsodium.stub', 'Sodium\\CRYPTO_STREAM_NONCEBYTES' => 'libsodium/libsodium.stub', 'Spinner' => 'winbinder/winbinder.stub', 'StatusBar' => 'winbinder/winbinder.stub', 'TCP_CONGESTION' => 'sockets/sockets.stub', 'TCP_DEFER_ACCEPT' => 'sockets/sockets.stub', 'TCP_KEEPCNT' => 'sockets/sockets.stub', 'TCP_KEEPIDLE' => 'sockets/sockets.stub', 'TCP_KEEPINTVL' => 'sockets/sockets.stub', 'TCP_NODELAY' => 'sockets/sockets.stub', 'TCP_NOTSENT_LOWAT' => 'sockets/sockets.stub', 'TCP_QUICKACK' => 'sockets/sockets.stub', 'TCP_REPAIR' => 'sockets/sockets.stub', 'TCP_SYNCNT' => 'sockets/sockets.stub', 'THOUSANDS_SEP' => 'standard/standard_defines.stub', 'THOUSEP' => 'standard/standard_defines.stub', 'TIDY_NODETYPE_ASP' => 'tidy/tidy.stub', 'TIDY_NODETYPE_CDATA' => 'tidy/tidy.stub', 'TIDY_NODETYPE_COMMENT' => 'tidy/tidy.stub', 'TIDY_NODETYPE_DOCTYPE' => 'tidy/tidy.stub', 'TIDY_NODETYPE_END' => 'tidy/tidy.stub', 'TIDY_NODETYPE_JSTE' => 'tidy/tidy.stub', 'TIDY_NODETYPE_PHP' => 'tidy/tidy.stub', 'TIDY_NODETYPE_PROCINS' => 'tidy/tidy.stub', 'TIDY_NODETYPE_ROOT' => 'tidy/tidy.stub', 'TIDY_NODETYPE_SECTION' => 'tidy/tidy.stub', 'TIDY_NODETYPE_START' => 'tidy/tidy.stub', 'TIDY_NODETYPE_STARTEND' => 'tidy/tidy.stub', 'TIDY_NODETYPE_TEXT' => 'tidy/tidy.stub', 'TIDY_NODETYPE_XMLDECL' => 'tidy/tidy.stub', 'TIDY_TAG_A' => 'tidy/tidy.stub', 'TIDY_TAG_ABBR' => 'tidy/tidy.stub', 'TIDY_TAG_ACRONYM' => 'tidy/tidy.stub', 'TIDY_TAG_ADDRESS' => 'tidy/tidy.stub', 'TIDY_TAG_ALIGN' => 'tidy/tidy.stub', 'TIDY_TAG_APPLET' => 'tidy/tidy.stub', 'TIDY_TAG_AREA' => 'tidy/tidy.stub', 'TIDY_TAG_ARTICLE' => 'tidy/tidy.stub', 'TIDY_TAG_ASIDE' => 'tidy/tidy.stub', 'TIDY_TAG_AUDIO' => 'tidy/tidy.stub', 'TIDY_TAG_B' => 'tidy/tidy.stub', 'TIDY_TAG_BASE' => 'tidy/tidy.stub', 'TIDY_TAG_BASEFONT' => 'tidy/tidy.stub', 'TIDY_TAG_BDI' => 'tidy/tidy.stub', 'TIDY_TAG_BDO' => 'tidy/tidy.stub', 'TIDY_TAG_BGSOUND' => 'tidy/tidy.stub', 'TIDY_TAG_BIG' => 'tidy/tidy.stub', 'TIDY_TAG_BLINK' => 'tidy/tidy.stub', 'TIDY_TAG_BLOCKQUOTE' => 'tidy/tidy.stub', 'TIDY_TAG_BODY' => 'tidy/tidy.stub', 'TIDY_TAG_BR' => 'tidy/tidy.stub', 'TIDY_TAG_BUTTON' => 'tidy/tidy.stub', 'TIDY_TAG_CANVAS' => 'tidy/tidy.stub', 'TIDY_TAG_CAPTION' => 'tidy/tidy.stub', 'TIDY_TAG_CENTER' => 'tidy/tidy.stub', 'TIDY_TAG_CITE' => 'tidy/tidy.stub', 'TIDY_TAG_CODE' => 'tidy/tidy.stub', 'TIDY_TAG_COL' => 'tidy/tidy.stub', 'TIDY_TAG_COLGROUP' => 'tidy/tidy.stub', 'TIDY_TAG_COMMAND' => 'tidy/tidy.stub', 'TIDY_TAG_COMMENT' => 'tidy/tidy.stub', 'TIDY_TAG_DATALIST' => 'tidy/tidy.stub', 'TIDY_TAG_DD' => 'tidy/tidy.stub', 'TIDY_TAG_DEL' => 'tidy/tidy.stub', 'TIDY_TAG_DETAILS' => 'tidy/tidy.stub', 'TIDY_TAG_DFN' => 'tidy/tidy.stub', 'TIDY_TAG_DIALOG' => 'tidy/tidy.stub', 'TIDY_TAG_DIR' => 'tidy/tidy.stub', 'TIDY_TAG_DIV' => 'tidy/tidy.stub', 'TIDY_TAG_DL' => 'tidy/tidy.stub', 'TIDY_TAG_DT' => 'tidy/tidy.stub', 'TIDY_TAG_EM' => 'tidy/tidy.stub', 'TIDY_TAG_EMBED' => 'tidy/tidy.stub', 'TIDY_TAG_FIELDSET' => 'tidy/tidy.stub', 'TIDY_TAG_FIGCAPTION' => 'tidy/tidy.stub', 'TIDY_TAG_FIGURE' => 'tidy/tidy.stub', 'TIDY_TAG_FONT' => 'tidy/tidy.stub', 'TIDY_TAG_FOOTER' => 'tidy/tidy.stub', 'TIDY_TAG_FORM' => 'tidy/tidy.stub', 'TIDY_TAG_FRAME' => 'tidy/tidy.stub', 'TIDY_TAG_FRAMESET' => 'tidy/tidy.stub', 'TIDY_TAG_H1' => 'tidy/tidy.stub', 'TIDY_TAG_H2' => 'tidy/tidy.stub', 'TIDY_TAG_H3' => 'tidy/tidy.stub', 'TIDY_TAG_H4' => 'tidy/tidy.stub', 'TIDY_TAG_H5' => 'tidy/tidy.stub', 'TIDY_TAG_H6' => 'tidy/tidy.stub', 'TIDY_TAG_HEAD' => 'tidy/tidy.stub', 'TIDY_TAG_HEADER' => 'tidy/tidy.stub', 'TIDY_TAG_HGROUP' => 'tidy/tidy.stub', 'TIDY_TAG_HR' => 'tidy/tidy.stub', 'TIDY_TAG_HTML' => 'tidy/tidy.stub', 'TIDY_TAG_I' => 'tidy/tidy.stub', 'TIDY_TAG_IFRAME' => 'tidy/tidy.stub', 'TIDY_TAG_ILAYER' => 'tidy/tidy.stub', 'TIDY_TAG_IMG' => 'tidy/tidy.stub', 'TIDY_TAG_INPUT' => 'tidy/tidy.stub', 'TIDY_TAG_INS' => 'tidy/tidy.stub', 'TIDY_TAG_ISINDEX' => 'tidy/tidy.stub', 'TIDY_TAG_KBD' => 'tidy/tidy.stub', 'TIDY_TAG_KEYGEN' => 'tidy/tidy.stub', 'TIDY_TAG_LABEL' => 'tidy/tidy.stub', 'TIDY_TAG_LAYER' => 'tidy/tidy.stub', 'TIDY_TAG_LEGEND' => 'tidy/tidy.stub', 'TIDY_TAG_LI' => 'tidy/tidy.stub', 'TIDY_TAG_LINK' => 'tidy/tidy.stub', 'TIDY_TAG_LISTING' => 'tidy/tidy.stub', 'TIDY_TAG_MAIN' => 'tidy/tidy.stub', 'TIDY_TAG_MAP' => 'tidy/tidy.stub', 'TIDY_TAG_MARK' => 'tidy/tidy.stub', 'TIDY_TAG_MARQUEE' => 'tidy/tidy.stub', 'TIDY_TAG_MENU' => 'tidy/tidy.stub', 'TIDY_TAG_MENUITEM' => 'tidy/tidy.stub', 'TIDY_TAG_META' => 'tidy/tidy.stub', 'TIDY_TAG_METER' => 'tidy/tidy.stub', 'TIDY_TAG_MULTICOL' => 'tidy/tidy.stub', 'TIDY_TAG_NAV' => 'tidy/tidy.stub', 'TIDY_TAG_NOBR' => 'tidy/tidy.stub', 'TIDY_TAG_NOEMBED' => 'tidy/tidy.stub', 'TIDY_TAG_NOFRAMES' => 'tidy/tidy.stub', 'TIDY_TAG_NOLAYER' => 'tidy/tidy.stub', 'TIDY_TAG_NOSAVE' => 'tidy/tidy.stub', 'TIDY_TAG_NOSCRIPT' => 'tidy/tidy.stub', 'TIDY_TAG_OBJECT' => 'tidy/tidy.stub', 'TIDY_TAG_OL' => 'tidy/tidy.stub', 'TIDY_TAG_OPTGROUP' => 'tidy/tidy.stub', 'TIDY_TAG_OPTION' => 'tidy/tidy.stub', 'TIDY_TAG_OUTPUT' => 'tidy/tidy.stub', 'TIDY_TAG_P' => 'tidy/tidy.stub', 'TIDY_TAG_PARAM' => 'tidy/tidy.stub', 'TIDY_TAG_PLAINTEXT' => 'tidy/tidy.stub', 'TIDY_TAG_PRE' => 'tidy/tidy.stub', 'TIDY_TAG_PROGRESS' => 'tidy/tidy.stub', 'TIDY_TAG_Q' => 'tidy/tidy.stub', 'TIDY_TAG_RB' => 'tidy/tidy.stub', 'TIDY_TAG_RBC' => 'tidy/tidy.stub', 'TIDY_TAG_RP' => 'tidy/tidy.stub', 'TIDY_TAG_RT' => 'tidy/tidy.stub', 'TIDY_TAG_RTC' => 'tidy/tidy.stub', 'TIDY_TAG_RUBY' => 'tidy/tidy.stub', 'TIDY_TAG_S' => 'tidy/tidy.stub', 'TIDY_TAG_SAMP' => 'tidy/tidy.stub', 'TIDY_TAG_SCRIPT' => 'tidy/tidy.stub', 'TIDY_TAG_SECTION' => 'tidy/tidy.stub', 'TIDY_TAG_SELECT' => 'tidy/tidy.stub', 'TIDY_TAG_SERVER' => 'tidy/tidy.stub', 'TIDY_TAG_SERVLET' => 'tidy/tidy.stub', 'TIDY_TAG_SMALL' => 'tidy/tidy.stub', 'TIDY_TAG_SOURCE' => 'tidy/tidy.stub', 'TIDY_TAG_SPACER' => 'tidy/tidy.stub', 'TIDY_TAG_SPAN' => 'tidy/tidy.stub', 'TIDY_TAG_STRIKE' => 'tidy/tidy.stub', 'TIDY_TAG_STRONG' => 'tidy/tidy.stub', 'TIDY_TAG_STYLE' => 'tidy/tidy.stub', 'TIDY_TAG_SUB' => 'tidy/tidy.stub', 'TIDY_TAG_SUMMARY' => 'tidy/tidy.stub', 'TIDY_TAG_SUP' => 'tidy/tidy.stub', 'TIDY_TAG_TABLE' => 'tidy/tidy.stub', 'TIDY_TAG_TBODY' => 'tidy/tidy.stub', 'TIDY_TAG_TD' => 'tidy/tidy.stub', 'TIDY_TAG_TEMPLATE' => 'tidy/tidy.stub', 'TIDY_TAG_TEXTAREA' => 'tidy/tidy.stub', 'TIDY_TAG_TFOOT' => 'tidy/tidy.stub', 'TIDY_TAG_TH' => 'tidy/tidy.stub', 'TIDY_TAG_THEAD' => 'tidy/tidy.stub', 'TIDY_TAG_TIME' => 'tidy/tidy.stub', 'TIDY_TAG_TITLE' => 'tidy/tidy.stub', 'TIDY_TAG_TR' => 'tidy/tidy.stub', 'TIDY_TAG_TRACK' => 'tidy/tidy.stub', 'TIDY_TAG_TT' => 'tidy/tidy.stub', 'TIDY_TAG_U' => 'tidy/tidy.stub', 'TIDY_TAG_UL' => 'tidy/tidy.stub', 'TIDY_TAG_UNKNOWN' => 'tidy/tidy.stub', 'TIDY_TAG_VAR' => 'tidy/tidy.stub', 'TIDY_TAG_VIDEO' => 'tidy/tidy.stub', 'TIDY_TAG_WBR' => 'tidy/tidy.stub', 'TIDY_TAG_XMP' => 'tidy/tidy.stub', 'TOKEN_PARSE' => 'tokenizer/tokenizer.stub', 'TRAP_BRKPT' => 'pcntl/pcntl.stub', 'TRAP_TRACE' => 'pcntl/pcntl.stub', 'TYPEAPPLICATION' => 'imap/imap.stub', 'TYPEAUDIO' => 'imap/imap.stub', 'TYPEIMAGE' => 'imap/imap.stub', 'TYPEMESSAGE' => 'imap/imap.stub', 'TYPEMODEL' => 'imap/imap.stub', 'TYPEMULTIPART' => 'imap/imap.stub', 'TYPEOTHER' => 'imap/imap.stub', 'TYPETEXT' => 'imap/imap.stub', 'TYPEVIDEO' => 'imap/imap.stub', 'T_ABSTRACT' => 'tokenizer/tokenizer.stub', 'T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG' => 'tokenizer/tokenizer.stub', 'T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG' => 'tokenizer/tokenizer.stub', 'T_AND_EQUAL' => 'tokenizer/tokenizer.stub', 'T_ARRAY' => 'tokenizer/tokenizer.stub', 'T_ARRAY_CAST' => 'tokenizer/tokenizer.stub', 'T_AS' => 'tokenizer/tokenizer.stub', 'T_ATTRIBUTE' => 'tokenizer/tokenizer.stub', 'T_BAD_CHARACTER' => 'tokenizer/tokenizer.stub', 'T_BOOLEAN_AND' => 'tokenizer/tokenizer.stub', 'T_BOOLEAN_OR' => 'tokenizer/tokenizer.stub', 'T_BOOL_CAST' => 'tokenizer/tokenizer.stub', 'T_BREAK' => 'tokenizer/tokenizer.stub', 'T_CALLABLE' => 'tokenizer/tokenizer.stub', 'T_CASE' => 'tokenizer/tokenizer.stub', 'T_CATCH' => 'tokenizer/tokenizer.stub', 'T_CHARACTER' => 'tokenizer/tokenizer.stub', 'T_CLASS' => 'tokenizer/tokenizer.stub', 'T_CLASS_C' => 'tokenizer/tokenizer.stub', 'T_CLONE' => 'tokenizer/tokenizer.stub', 'T_CLOSE_TAG' => 'tokenizer/tokenizer.stub', 'T_COALESCE' => 'tokenizer/tokenizer.stub', 'T_COALESCE_EQUAL' => 'tokenizer/tokenizer.stub', 'T_COMMENT' => 'tokenizer/tokenizer.stub', 'T_CONCAT_EQUAL' => 'tokenizer/tokenizer.stub', 'T_CONST' => 'tokenizer/tokenizer.stub', 'T_CONSTANT_ENCAPSED_STRING' => 'tokenizer/tokenizer.stub', 'T_CONTINUE' => 'tokenizer/tokenizer.stub', 'T_CURLY_OPEN' => 'tokenizer/tokenizer.stub', 'T_DEC' => 'tokenizer/tokenizer.stub', 'T_DECLARE' => 'tokenizer/tokenizer.stub', 'T_DEFAULT' => 'tokenizer/tokenizer.stub', 'T_DIR' => 'tokenizer/tokenizer.stub', 'T_DIV_EQUAL' => 'tokenizer/tokenizer.stub', 'T_DNUMBER' => 'tokenizer/tokenizer.stub', 'T_DO' => 'tokenizer/tokenizer.stub', 'T_DOC_COMMENT' => 'tokenizer/tokenizer.stub', 'T_DOLLAR_OPEN_CURLY_BRACES' => 'tokenizer/tokenizer.stub', 'T_DOUBLE_ARROW' => 'tokenizer/tokenizer.stub', 'T_DOUBLE_CAST' => 'tokenizer/tokenizer.stub', 'T_DOUBLE_COLON' => 'tokenizer/tokenizer.stub', 'T_ECHO' => 'tokenizer/tokenizer.stub', 'T_ELLIPSIS' => 'tokenizer/tokenizer.stub', 'T_ELSE' => 'tokenizer/tokenizer.stub', 'T_ELSEIF' => 'tokenizer/tokenizer.stub', 'T_EMPTY' => 'tokenizer/tokenizer.stub', 'T_ENCAPSED_AND_WHITESPACE' => 'tokenizer/tokenizer.stub', 'T_ENDDECLARE' => 'tokenizer/tokenizer.stub', 'T_ENDFOR' => 'tokenizer/tokenizer.stub', 'T_ENDFOREACH' => 'tokenizer/tokenizer.stub', 'T_ENDIF' => 'tokenizer/tokenizer.stub', 'T_ENDSWITCH' => 'tokenizer/tokenizer.stub', 'T_ENDWHILE' => 'tokenizer/tokenizer.stub', 'T_END_HEREDOC' => 'tokenizer/tokenizer.stub', 'T_ENUM' => 'tokenizer/tokenizer.stub', 'T_EVAL' => 'tokenizer/tokenizer.stub', 'T_EXIT' => 'tokenizer/tokenizer.stub', 'T_EXTENDS' => 'tokenizer/tokenizer.stub', 'T_FILE' => 'tokenizer/tokenizer.stub', 'T_FINAL' => 'tokenizer/tokenizer.stub', 'T_FINALLY' => 'tokenizer/tokenizer.stub', 'T_FMT' => 'standard/standard_defines.stub', 'T_FMT_AMPM' => 'standard/standard_defines.stub', 'T_FN' => 'tokenizer/tokenizer.stub', 'T_FOR' => 'tokenizer/tokenizer.stub', 'T_FOREACH' => 'tokenizer/tokenizer.stub', 'T_FUNCTION' => 'tokenizer/tokenizer.stub', 'T_FUNC_C' => 'tokenizer/tokenizer.stub', 'T_GLOBAL' => 'tokenizer/tokenizer.stub', 'T_GOTO' => 'tokenizer/tokenizer.stub', 'T_HALT_COMPILER' => 'tokenizer/tokenizer.stub', 'T_IF' => 'tokenizer/tokenizer.stub', 'T_IMPLEMENTS' => 'tokenizer/tokenizer.stub', 'T_INC' => 'tokenizer/tokenizer.stub', 'T_INCLUDE' => 'tokenizer/tokenizer.stub', 'T_INCLUDE_ONCE' => 'tokenizer/tokenizer.stub', 'T_INLINE_HTML' => 'tokenizer/tokenizer.stub', 'T_INSTANCEOF' => 'tokenizer/tokenizer.stub', 'T_INSTEADOF' => 'tokenizer/tokenizer.stub', 'T_INTERFACE' => 'tokenizer/tokenizer.stub', 'T_INT_CAST' => 'tokenizer/tokenizer.stub', 'T_ISSET' => 'tokenizer/tokenizer.stub', 'T_IS_EQUAL' => 'tokenizer/tokenizer.stub', 'T_IS_GREATER_OR_EQUAL' => 'tokenizer/tokenizer.stub', 'T_IS_IDENTICAL' => 'tokenizer/tokenizer.stub', 'T_IS_NOT_EQUAL' => 'tokenizer/tokenizer.stub', 'T_IS_NOT_IDENTICAL' => 'tokenizer/tokenizer.stub', 'T_IS_SMALLER_OR_EQUAL' => 'tokenizer/tokenizer.stub', 'T_LINE' => 'tokenizer/tokenizer.stub', 'T_LIST' => 'tokenizer/tokenizer.stub', 'T_LNUMBER' => 'tokenizer/tokenizer.stub', 'T_LOGICAL_AND' => 'tokenizer/tokenizer.stub', 'T_LOGICAL_OR' => 'tokenizer/tokenizer.stub', 'T_LOGICAL_XOR' => 'tokenizer/tokenizer.stub', 'T_MATCH' => 'tokenizer/tokenizer.stub', 'T_METHOD_C' => 'tokenizer/tokenizer.stub', 'T_MINUS_EQUAL' => 'tokenizer/tokenizer.stub', 'T_MOD_EQUAL' => 'tokenizer/tokenizer.stub', 'T_MUL_EQUAL' => 'tokenizer/tokenizer.stub', 'T_NAMESPACE' => 'tokenizer/tokenizer.stub', 'T_NAME_FULLY_QUALIFIED' => 'tokenizer/tokenizer.stub', 'T_NAME_QUALIFIED' => 'tokenizer/tokenizer.stub', 'T_NAME_RELATIVE' => 'tokenizer/tokenizer.stub', 'T_NEW' => 'tokenizer/tokenizer.stub', 'T_NS_C' => 'tokenizer/tokenizer.stub', 'T_NS_SEPARATOR' => 'tokenizer/tokenizer.stub', 'T_NULLSAFE_OBJECT_OPERATOR' => 'tokenizer/tokenizer.stub', 'T_NUM_STRING' => 'tokenizer/tokenizer.stub', 'T_OBJECT_CAST' => 'tokenizer/tokenizer.stub', 'T_OBJECT_OPERATOR' => 'tokenizer/tokenizer.stub', 'T_OPEN_TAG' => 'tokenizer/tokenizer.stub', 'T_OPEN_TAG_WITH_ECHO' => 'tokenizer/tokenizer.stub', 'T_OR_EQUAL' => 'tokenizer/tokenizer.stub', 'T_PAAMAYIM_NEKUDOTAYIM' => 'tokenizer/tokenizer.stub', 'T_PLUS_EQUAL' => 'tokenizer/tokenizer.stub', 'T_POW' => 'tokenizer/tokenizer.stub', 'T_POW_EQUAL' => 'tokenizer/tokenizer.stub', 'T_PRINT' => 'tokenizer/tokenizer.stub', 'T_PRIVATE' => 'tokenizer/tokenizer.stub', 'T_PRIVATE_SET' => 'tokenizer/tokenizer.stub', 'T_PROPERTY_C' => 'tokenizer/tokenizer.stub', 'T_PROTECTED' => 'tokenizer/tokenizer.stub', 'T_PROTECTED_SET' => 'tokenizer/tokenizer.stub', 'T_PUBLIC' => 'tokenizer/tokenizer.stub', 'T_PUBLIC_SET' => 'tokenizer/tokenizer.stub', 'T_READONLY' => 'tokenizer/tokenizer.stub', 'T_REQUIRE' => 'tokenizer/tokenizer.stub', 'T_REQUIRE_ONCE' => 'tokenizer/tokenizer.stub', 'T_RETURN' => 'tokenizer/tokenizer.stub', 'T_SL' => 'tokenizer/tokenizer.stub', 'T_SL_EQUAL' => 'tokenizer/tokenizer.stub', 'T_SPACESHIP' => 'tokenizer/tokenizer.stub', 'T_SR' => 'tokenizer/tokenizer.stub', 'T_SR_EQUAL' => 'tokenizer/tokenizer.stub', 'T_START_HEREDOC' => 'tokenizer/tokenizer.stub', 'T_STATIC' => 'tokenizer/tokenizer.stub', 'T_STRING' => 'tokenizer/tokenizer.stub', 'T_STRING_CAST' => 'tokenizer/tokenizer.stub', 'T_STRING_VARNAME' => 'tokenizer/tokenizer.stub', 'T_SWITCH' => 'tokenizer/tokenizer.stub', 'T_THROW' => 'tokenizer/tokenizer.stub', 'T_TRAIT' => 'tokenizer/tokenizer.stub', 'T_TRAIT_C' => 'tokenizer/tokenizer.stub', 'T_TRY' => 'tokenizer/tokenizer.stub', 'T_UNSET' => 'tokenizer/tokenizer.stub', 'T_UNSET_CAST' => 'tokenizer/tokenizer.stub', 'T_USE' => 'tokenizer/tokenizer.stub', 'T_VAR' => 'tokenizer/tokenizer.stub', 'T_VARIABLE' => 'tokenizer/tokenizer.stub', 'T_WHILE' => 'tokenizer/tokenizer.stub', 'T_WHITESPACE' => 'tokenizer/tokenizer.stub', 'T_XOR_EQUAL' => 'tokenizer/tokenizer.stub', 'T_YIELD' => 'tokenizer/tokenizer.stub', 'T_YIELD_FROM' => 'tokenizer/tokenizer.stub', 'TabControl' => 'winbinder/winbinder.stub', 'Timer' => 'winbinder/winbinder.stub', 'ToolBar' => 'winbinder/winbinder.stub', 'ToolDialog' => 'winbinder/winbinder.stub', 'TreeView' => 'winbinder/winbinder.stub', 'ULOC_ACTUAL_LOCALE' => 'intl/intl.stub', 'ULOC_VALID_LOCALE' => 'intl/intl.stub', 'UNKNOWN_TYPE' => 'soap/soap.stub', 'UPLOAD_ERR_CANT_WRITE' => 'Core/Core_d.stub', 'UPLOAD_ERR_EXTENSION' => 'Core/Core_d.stub', 'UPLOAD_ERR_FORM_SIZE' => 'Core/Core_d.stub', 'UPLOAD_ERR_INI_SIZE' => 'Core/Core_d.stub', 'UPLOAD_ERR_NO_FILE' => 'Core/Core_d.stub', 'UPLOAD_ERR_NO_TMP_DIR' => 'Core/Core_d.stub', 'UPLOAD_ERR_OK' => 'Core/Core_d.stub', 'UPLOAD_ERR_PARTIAL' => 'Core/Core_d.stub', 'UUID_TYPE_DCE' => 'uuid/uuid_c.stub', 'UUID_TYPE_DEFAULT' => 'uuid/uuid_c.stub', 'UUID_TYPE_INVALID' => 'uuid/uuid_c.stub', 'UUID_TYPE_MD5' => 'uuid/uuid_c.stub', 'UUID_TYPE_NAME' => 'uuid/uuid_c.stub', 'UUID_TYPE_NULL' => 'uuid/uuid_c.stub', 'UUID_TYPE_RANDOM' => 'uuid/uuid_c.stub', 'UUID_TYPE_SECURITY' => 'uuid/uuid_c.stub', 'UUID_TYPE_SHA1' => 'uuid/uuid_c.stub', 'UUID_TYPE_TIME' => 'uuid/uuid_c.stub', 'UUID_VARIANT_DCE' => 'uuid/uuid_c.stub', 'UUID_VARIANT_MICROSOFT' => 'uuid/uuid_c.stub', 'UUID_VARIANT_NCS' => 'uuid/uuid_c.stub', 'UUID_VARIANT_OTHER' => 'uuid/uuid_c.stub', 'U_AMBIGUOUS_ALIAS_WARNING' => 'intl/intl.stub', 'U_BAD_VARIABLE_DEFINITION' => 'intl/intl.stub', 'U_BRK_ASSIGN_ERROR' => 'intl/intl.stub', 'U_BRK_ERROR_LIMIT' => 'intl/intl.stub', 'U_BRK_ERROR_START' => 'intl/intl.stub', 'U_BRK_HEX_DIGITS_EXPECTED' => 'intl/intl.stub', 'U_BRK_INIT_ERROR' => 'intl/intl.stub', 'U_BRK_INTERNAL_ERROR' => 'intl/intl.stub', 'U_BRK_MALFORMED_RULE_TAG' => 'intl/intl.stub', 'U_BRK_MISMATCHED_PAREN' => 'intl/intl.stub', 'U_BRK_NEW_LINE_IN_QUOTED_STRING' => 'intl/intl.stub', 'U_BRK_RULE_EMPTY_SET' => 'intl/intl.stub', 'U_BRK_RULE_SYNTAX' => 'intl/intl.stub', 'U_BRK_SEMICOLON_EXPECTED' => 'intl/intl.stub', 'U_BRK_UNCLOSED_SET' => 'intl/intl.stub', 'U_BRK_UNDEFINED_VARIABLE' => 'intl/intl.stub', 'U_BRK_UNRECOGNIZED_OPTION' => 'intl/intl.stub', 'U_BRK_VARIABLE_REDFINITION' => 'intl/intl.stub', 'U_BUFFER_OVERFLOW_ERROR' => 'intl/intl.stub', 'U_CE_NOT_FOUND_ERROR' => 'intl/intl.stub', 'U_COLLATOR_VERSION_MISMATCH' => 'intl/intl.stub', 'U_DIFFERENT_UCA_VERSION' => 'intl/intl.stub', 'U_ENUM_OUT_OF_SYNC_ERROR' => 'intl/intl.stub', 'U_ERROR_LIMIT' => 'intl/intl.stub', 'U_ERROR_WARNING_LIMIT' => 'intl/intl.stub', 'U_ERROR_WARNING_START' => 'intl/intl.stub', 'U_FILE_ACCESS_ERROR' => 'intl/intl.stub', 'U_FMT_PARSE_ERROR_LIMIT' => 'intl/intl.stub', 'U_FMT_PARSE_ERROR_START' => 'intl/intl.stub', 'U_IDNA_ACE_PREFIX_ERROR' => 'intl/intl.stub', 'U_IDNA_CHECK_BIDI_ERROR' => 'intl/intl.stub', 'U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR' => 'intl/intl.stub', 'U_IDNA_ERROR_LIMIT' => 'intl/intl.stub', 'U_IDNA_ERROR_START' => 'intl/intl.stub', 'U_IDNA_LABEL_TOO_LONG_ERROR' => 'intl/intl.stub', 'U_IDNA_PROHIBITED_ERROR' => 'intl/intl.stub', 'U_IDNA_STD3_ASCII_RULES_ERROR' => 'intl/intl.stub', 'U_IDNA_UNASSIGNED_ERROR' => 'intl/intl.stub', 'U_IDNA_VERIFICATION_ERROR' => 'intl/intl.stub', 'U_IDNA_ZERO_LENGTH_LABEL_ERROR' => 'intl/intl.stub', 'U_ILLEGAL_ARGUMENT_ERROR' => 'intl/intl.stub', 'U_ILLEGAL_CHARACTER' => 'intl/intl.stub', 'U_ILLEGAL_CHAR_FOUND' => 'intl/intl.stub', 'U_ILLEGAL_CHAR_IN_SEGMENT' => 'intl/intl.stub', 'U_ILLEGAL_ESCAPE_SEQUENCE' => 'intl/intl.stub', 'U_ILLEGAL_PAD_POSITION' => 'intl/intl.stub', 'U_INDEX_OUTOFBOUNDS_ERROR' => 'intl/intl.stub', 'U_INTERNAL_PROGRAM_ERROR' => 'intl/intl.stub', 'U_INTERNAL_TRANSLITERATOR_ERROR' => 'intl/intl.stub', 'U_INVALID_CHAR_FOUND' => 'intl/intl.stub', 'U_INVALID_FORMAT_ERROR' => 'intl/intl.stub', 'U_INVALID_FUNCTION' => 'intl/intl.stub', 'U_INVALID_ID' => 'intl/intl.stub', 'U_INVALID_PROPERTY_PATTERN' => 'intl/intl.stub', 'U_INVALID_RBT_SYNTAX' => 'intl/intl.stub', 'U_INVALID_STATE_ERROR' => 'intl/intl.stub', 'U_INVALID_TABLE_FILE' => 'intl/intl.stub', 'U_INVALID_TABLE_FORMAT' => 'intl/intl.stub', 'U_INVARIANT_CONVERSION_ERROR' => 'intl/intl.stub', 'U_MALFORMED_EXPONENTIAL_PATTERN' => 'intl/intl.stub', 'U_MALFORMED_PRAGMA' => 'intl/intl.stub', 'U_MALFORMED_RULE' => 'intl/intl.stub', 'U_MALFORMED_SET' => 'intl/intl.stub', 'U_MALFORMED_SYMBOL_REFERENCE' => 'intl/intl.stub', 'U_MALFORMED_UNICODE_ESCAPE' => 'intl/intl.stub', 'U_MALFORMED_VARIABLE_DEFINITION' => 'intl/intl.stub', 'U_MALFORMED_VARIABLE_REFERENCE' => 'intl/intl.stub', 'U_MEMORY_ALLOCATION_ERROR' => 'intl/intl.stub', 'U_MESSAGE_PARSE_ERROR' => 'intl/intl.stub', 'U_MISMATCHED_SEGMENT_DELIMITERS' => 'intl/intl.stub', 'U_MISPLACED_ANCHOR_START' => 'intl/intl.stub', 'U_MISPLACED_COMPOUND_FILTER' => 'intl/intl.stub', 'U_MISPLACED_CURSOR_OFFSET' => 'intl/intl.stub', 'U_MISPLACED_QUANTIFIER' => 'intl/intl.stub', 'U_MISSING_OPERATOR' => 'intl/intl.stub', 'U_MISSING_RESOURCE_ERROR' => 'intl/intl.stub', 'U_MISSING_SEGMENT_CLOSE' => 'intl/intl.stub', 'U_MULTIPLE_ANTE_CONTEXTS' => 'intl/intl.stub', 'U_MULTIPLE_COMPOUND_FILTERS' => 'intl/intl.stub', 'U_MULTIPLE_CURSORS' => 'intl/intl.stub', 'U_MULTIPLE_DECIMAL_SEPARATORS' => 'intl/intl.stub', 'U_MULTIPLE_DECIMAL_SEPERATORS' => 'intl/intl.stub', 'U_MULTIPLE_EXPONENTIAL_SYMBOLS' => 'intl/intl.stub', 'U_MULTIPLE_PAD_SPECIFIERS' => 'intl/intl.stub', 'U_MULTIPLE_PERCENT_SYMBOLS' => 'intl/intl.stub', 'U_MULTIPLE_PERMILL_SYMBOLS' => 'intl/intl.stub', 'U_MULTIPLE_POST_CONTEXTS' => 'intl/intl.stub', 'U_NO_SPACE_AVAILABLE' => 'intl/intl.stub', 'U_NO_WRITE_PERMISSION' => 'intl/intl.stub', 'U_PARSE_ERROR' => 'intl/intl.stub', 'U_PARSE_ERROR_LIMIT' => 'intl/intl.stub', 'U_PARSE_ERROR_START' => 'intl/intl.stub', 'U_PATTERN_SYNTAX_ERROR' => 'intl/intl.stub', 'U_PRIMARY_TOO_LONG_ERROR' => 'intl/intl.stub', 'U_REGEX_BAD_ESCAPE_SEQUENCE' => 'intl/intl.stub', 'U_REGEX_BAD_INTERVAL' => 'intl/intl.stub', 'U_REGEX_ERROR_LIMIT' => 'intl/intl.stub', 'U_REGEX_ERROR_START' => 'intl/intl.stub', 'U_REGEX_INTERNAL_ERROR' => 'intl/intl.stub', 'U_REGEX_INVALID_BACK_REF' => 'intl/intl.stub', 'U_REGEX_INVALID_FLAG' => 'intl/intl.stub', 'U_REGEX_INVALID_STATE' => 'intl/intl.stub', 'U_REGEX_LOOK_BEHIND_LIMIT' => 'intl/intl.stub', 'U_REGEX_MAX_LT_MIN' => 'intl/intl.stub', 'U_REGEX_MISMATCHED_PAREN' => 'intl/intl.stub', 'U_REGEX_NUMBER_TOO_BIG' => 'intl/intl.stub', 'U_REGEX_PROPERTY_SYNTAX' => 'intl/intl.stub', 'U_REGEX_RULE_SYNTAX' => 'intl/intl.stub', 'U_REGEX_SET_CONTAINS_STRING' => 'intl/intl.stub', 'U_REGEX_UNIMPLEMENTED' => 'intl/intl.stub', 'U_RESOURCE_TYPE_MISMATCH' => 'intl/intl.stub', 'U_RULE_MASK_ERROR' => 'intl/intl.stub', 'U_SAFECLONE_ALLOCATED_WARNING' => 'intl/intl.stub', 'U_SORT_KEY_TOO_SHORT_WARNING' => 'intl/intl.stub', 'U_STANDARD_ERROR_LIMIT' => 'intl/intl.stub', 'U_STATE_OLD_WARNING' => 'intl/intl.stub', 'U_STATE_TOO_OLD_ERROR' => 'intl/intl.stub', 'U_STRINGPREP_CHECK_BIDI_ERROR' => 'intl/intl.stub', 'U_STRINGPREP_PROHIBITED_ERROR' => 'intl/intl.stub', 'U_STRINGPREP_UNASSIGNED_ERROR' => 'intl/intl.stub', 'U_STRING_NOT_TERMINATED_WARNING' => 'intl/intl.stub', 'U_TOO_MANY_ALIASES_ERROR' => 'intl/intl.stub', 'U_TRAILING_BACKSLASH' => 'intl/intl.stub', 'U_TRUNCATED_CHAR_FOUND' => 'intl/intl.stub', 'U_UNCLOSED_SEGMENT' => 'intl/intl.stub', 'U_UNDEFINED_SEGMENT_REFERENCE' => 'intl/intl.stub', 'U_UNDEFINED_VARIABLE' => 'intl/intl.stub', 'U_UNEXPECTED_TOKEN' => 'intl/intl.stub', 'U_UNMATCHED_BRACES' => 'intl/intl.stub', 'U_UNQUOTED_SPECIAL' => 'intl/intl.stub', 'U_UNSUPPORTED_ATTRIBUTE' => 'intl/intl.stub', 'U_UNSUPPORTED_ERROR' => 'intl/intl.stub', 'U_UNSUPPORTED_ESCAPE_SEQUENCE' => 'intl/intl.stub', 'U_UNSUPPORTED_PROPERTY' => 'intl/intl.stub', 'U_UNTERMINATED_QUOTE' => 'intl/intl.stub', 'U_USELESS_COLLATOR_ERROR' => 'intl/intl.stub', 'U_USING_DEFAULT_WARNING' => 'intl/intl.stub', 'U_USING_FALLBACK_WARNING' => 'intl/intl.stub', 'U_VARIABLE_RANGE_EXHAUSTED' => 'intl/intl.stub', 'U_VARIABLE_RANGE_OVERLAP' => 'intl/intl.stub', 'U_ZERO_ERROR' => 'intl/intl.stub', 'VARCMP_EQ' => 'com_dotnet/com_dotnet.stub', 'VARCMP_GT' => 'com_dotnet/com_dotnet.stub', 'VARCMP_LT' => 'com_dotnet/com_dotnet.stub', 'VARCMP_NULL' => 'com_dotnet/com_dotnet.stub', 'VIR_CONNECT_FLAG_SOUNDHW_GET_NAMES' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_LIST_NETWORKS_ACTIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_LIST_NETWORKS_AUTOSTART' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_LIST_NETWORKS_INACTIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_LIST_NETWORKS_NO_AUTOSTART' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_LIST_NETWORKS_PERSISTENT' => 'libvirt-php/libvirt-php.stub', 'VIR_CONNECT_LIST_NETWORKS_TRANSIENT' => 'libvirt-php/libvirt-php.stub', 'VIR_CRED_AUTHNAME' => 'libvirt-php/libvirt-php.stub', 'VIR_CRED_CNONCE' => 'libvirt-php/libvirt-php.stub', 'VIR_CRED_ECHOPROMPT' => 'libvirt-php/libvirt-php.stub', 'VIR_CRED_EXTERNAL' => 'libvirt-php/libvirt-php.stub', 'VIR_CRED_LANGUAGE' => 'libvirt-php/libvirt-php.stub', 'VIR_CRED_NOECHOPROMPT' => 'libvirt-php/libvirt-php.stub', 'VIR_CRED_PASSPHRASE' => 'libvirt-php/libvirt-php.stub', 'VIR_CRED_REALM' => 'libvirt-php/libvirt-php.stub', 'VIR_CRED_USERNAME' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_AFFECT_CONFIG' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_AFFECT_CURRENT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_AFFECT_LIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCKED' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_COMMIT_ACTIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_COMMIT_DELETE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_COMMIT_RELATIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_COMMIT_SHALLOW' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_COPY_REUSE_EXT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_COPY_SHALLOW' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_JOB_INFO_BANDWIDTH_BYTES' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_JOB_TYPE_COPY' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_JOB_TYPE_PULL' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_REBASE_COPY' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_REBASE_COPY_DEV' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_REBASE_COPY_RAW' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_REBASE_RELATIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_REBASE_SHALLOW' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_BLOCK_RESIZE_BYTES' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_CRASHED' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_DEVICE_MODIFY_CONFIG' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_DEVICE_MODIFY_CURRENT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_DEVICE_MODIFY_FORCE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_DEVICE_MODIFY_LIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_DISK_ACCESS_ALL' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_DISK_BLOCK' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_DISK_FILE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_FLAG_CLOCK_LOCALTIME' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_FLAG_FEATURE_ACPI' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_FLAG_FEATURE_APIC' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_FLAG_FEATURE_PAE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_FLAG_SOUND_AC97' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_FLAG_TEST_LOCAL_VNC' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_JOB_BOUNDED' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_JOB_CANCELLED' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_JOB_COMPLETED' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_JOB_FAILED' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_JOB_NONE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_JOB_UNBOUNDED' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEMORY_STAT_AVAILABLE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEMORY_STAT_MAJOR_FAULT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEMORY_STAT_MINOR_FAULT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEMORY_STAT_NR' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEMORY_STAT_RSS' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEMORY_STAT_SWAP_IN' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEMORY_STAT_SWAP_OUT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEMORY_STAT_UNUSED' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEM_CONFIG' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEM_CURRENT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEM_LIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_MEM_MAXIMUM' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_METADATA_DESCRIPTION' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_METADATA_ELEMENT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_METADATA_TITLE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_NONE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_NOSTATE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_PAUSED' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_PMSUSPENDED' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_RUNNING' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_SHUTDOWN' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_SHUTOFF' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_START_AUTODESTROY' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_START_BYPASS_CACHE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_START_FORCE_BOOT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_START_PAUSED' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_START_VALIDATE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_STATS_BALLOON' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_STATS_BLOCK' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_STATS_CPU_TOTAL' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_STATS_INTERFACE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_STATS_STATE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_STATS_VCPU' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_UNDEFINE_KEEP_NVRAM' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_UNDEFINE_MANAGED_SAVE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_UNDEFINE_NVRAM' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_VCPU_CONFIG' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_VCPU_CURRENT' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_VCPU_GUEST' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_VCPU_LIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_VCPU_MAXIMUM' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_XML_INACTIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_XML_MIGRATABLE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_XML_SECURE' => 'libvirt-php/libvirt-php.stub', 'VIR_DOMAIN_XML_UPDATE_CPU' => 'libvirt-php/libvirt-php.stub', 'VIR_KEYCODE_SET_ATSET1' => 'libvirt-php/libvirt-php.stub', 'VIR_KEYCODE_SET_ATSET2' => 'libvirt-php/libvirt-php.stub', 'VIR_KEYCODE_SET_ATSET3' => 'libvirt-php/libvirt-php.stub', 'VIR_KEYCODE_SET_LINUX' => 'libvirt-php/libvirt-php.stub', 'VIR_KEYCODE_SET_OSX' => 'libvirt-php/libvirt-php.stub', 'VIR_KEYCODE_SET_RFB' => 'libvirt-php/libvirt-php.stub', 'VIR_KEYCODE_SET_USB' => 'libvirt-php/libvirt-php.stub', 'VIR_KEYCODE_SET_WIN32' => 'libvirt-php/libvirt-php.stub', 'VIR_KEYCODE_SET_XT' => 'libvirt-php/libvirt-php.stub', 'VIR_KEYCODE_SET_XT_KBD' => 'libvirt-php/libvirt-php.stub', 'VIR_MEMORY_PHYSICAL' => 'libvirt-php/libvirt-php.stub', 'VIR_MEMORY_VIRTUAL' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_ABORT_ON_ERROR' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_AUTO_CONVERGE' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_CHANGE_PROTECTION' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_COMPRESSED' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_LIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_NON_SHARED_DISK' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_NON_SHARED_INC' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_OFFLINE' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_PAUSED' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_PEER2PEER' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_PERSIST_DEST' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_TUNNELLED' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_UNDEFINE_SOURCE' => 'libvirt-php/libvirt-php.stub', 'VIR_MIGRATE_UNSAFE' => 'libvirt-php/libvirt-php.stub', 'VIR_NETWORKS_ACTIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_NETWORKS_ALL' => 'libvirt-php/libvirt-php.stub', 'VIR_NETWORKS_INACTIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_NODE_CPU_STATS_ALL_CPUS' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_CREATE_ATOMIC' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_CREATE_CURRENT' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_CREATE_DISK_ONLY' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_CREATE_HALT' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_CREATE_LIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_CREATE_NO_METADATA' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_CREATE_QUIESCE' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_CREATE_REDEFINE' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_CREATE_REUSE_EXT' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_DELETE_CHILDREN' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_DELETE_CHILDREN_ONLY' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_DELETE_METADATA_ONLY' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_LIST_ACTIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_LIST_DESCENDANTS' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_LIST_DISK_ONLY' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_LIST_EXTERNAL' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_LIST_INACTIVE' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_LIST_INTERNAL' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_LIST_LEAVES' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_LIST_METADATA' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_LIST_NO_LEAVES' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_LIST_NO_METADATA' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_LIST_ROOTS' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_REVERT_FORCE' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_REVERT_PAUSED' => 'libvirt-php/libvirt-php.stub', 'VIR_SNAPSHOT_REVERT_RUNNING' => 'libvirt-php/libvirt-php.stub', 'VIR_STORAGE_POOL_BUILD_NEW' => 'libvirt-php/libvirt-php.stub', 'VIR_STORAGE_POOL_BUILD_REPAIR' => 'libvirt-php/libvirt-php.stub', 'VIR_STORAGE_POOL_BUILD_RESIZE' => 'libvirt-php/libvirt-php.stub', 'VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA' => 'libvirt-php/libvirt-php.stub', 'VIR_STORAGE_VOL_CREATE_REFLINK' => 'libvirt-php/libvirt-php.stub', 'VIR_STORAGE_VOL_RESIZE_ALLOCATE' => 'libvirt-php/libvirt-php.stub', 'VIR_STORAGE_VOL_RESIZE_DELTA' => 'libvirt-php/libvirt-php.stub', 'VIR_STORAGE_VOL_RESIZE_SHRINK' => 'libvirt-php/libvirt-php.stub', 'VIR_VERSION_BINDING' => 'libvirt-php/libvirt-php.stub', 'VIR_VERSION_LIBVIRT' => 'libvirt-php/libvirt-php.stub', 'VT_ARRAY' => 'com_dotnet/com_dotnet.stub', 'VT_BOOL' => 'com_dotnet/com_dotnet.stub', 'VT_BSTR' => 'com_dotnet/com_dotnet.stub', 'VT_BYREF' => 'com_dotnet/com_dotnet.stub', 'VT_CY' => 'com_dotnet/com_dotnet.stub', 'VT_DATE' => 'com_dotnet/com_dotnet.stub', 'VT_DECIMAL' => 'com_dotnet/com_dotnet.stub', 'VT_DISPATCH' => 'com_dotnet/com_dotnet.stub', 'VT_EMPTY' => 'com_dotnet/com_dotnet.stub', 'VT_ERROR' => 'com_dotnet/com_dotnet.stub', 'VT_I1' => 'com_dotnet/com_dotnet.stub', 'VT_I2' => 'com_dotnet/com_dotnet.stub', 'VT_I4' => 'com_dotnet/com_dotnet.stub', 'VT_INT' => 'com_dotnet/com_dotnet.stub', 'VT_NULL' => 'com_dotnet/com_dotnet.stub', 'VT_R4' => 'com_dotnet/com_dotnet.stub', 'VT_R8' => 'com_dotnet/com_dotnet.stub', 'VT_UI1' => 'com_dotnet/com_dotnet.stub', 'VT_UI2' => 'com_dotnet/com_dotnet.stub', 'VT_UI4' => 'com_dotnet/com_dotnet.stub', 'VT_UINT' => 'com_dotnet/com_dotnet.stub', 'VT_UNKNOWN' => 'com_dotnet/com_dotnet.stub', 'VT_VARIANT' => 'com_dotnet/com_dotnet.stub', 'WBC_ALT' => 'winbinder/winbinder.stub', 'WBC_AUTOREPEAT' => 'winbinder/winbinder.stub', 'WBC_BEEP' => 'winbinder/winbinder.stub', 'WBC_BORDER' => 'winbinder/winbinder.stub', 'WBC_BOTTOM' => 'winbinder/winbinder.stub', 'WBC_CENTER' => 'winbinder/winbinder.stub', 'WBC_CHECKBOXES' => 'winbinder/winbinder.stub', 'WBC_CONTROL' => 'winbinder/winbinder.stub', 'WBC_CUSTOMDRAW' => 'winbinder/winbinder.stub', 'WBC_DBLCLICK' => 'winbinder/winbinder.stub', 'WBC_DEFAULT' => 'winbinder/winbinder.stub', 'WBC_DEFAULTPOS' => 'winbinder/winbinder.stub', 'WBC_DISABLED' => 'winbinder/winbinder.stub', 'WBC_ELLIPSIS' => 'winbinder/winbinder.stub', 'WBC_ENABLED' => 'winbinder/winbinder.stub', 'WBC_GETFOCUS' => 'winbinder/winbinder.stub', 'WBC_GROUP' => 'winbinder/winbinder.stub', 'WBC_HEADERSEL' => 'winbinder/winbinder.stub', 'WBC_IMAGE' => 'winbinder/winbinder.stub', 'WBC_INFO' => 'winbinder/winbinder.stub', 'WBC_INVISIBLE' => 'winbinder/winbinder.stub', 'WBC_KEYDOWN' => 'winbinder/winbinder.stub', 'WBC_KEYUP' => 'winbinder/winbinder.stub', 'WBC_LBUTTON' => 'winbinder/winbinder.stub', 'WBC_LEFT' => 'winbinder/winbinder.stub', 'WBC_LINES' => 'winbinder/winbinder.stub', 'WBC_LV_BACK' => 'winbinder/winbinder.stub', 'WBC_LV_COLUMNS' => 'winbinder/winbinder.stub', 'WBC_LV_DEFAULT' => 'winbinder/winbinder.stub', 'WBC_LV_DRAW' => 'winbinder/winbinder.stub', 'WBC_LV_FORE' => 'winbinder/winbinder.stub', 'WBC_LV_NONE' => 'winbinder/winbinder.stub', 'WBC_MASKED' => 'winbinder/winbinder.stub', 'WBC_MAXIMIZED' => 'winbinder/winbinder.stub', 'WBC_MAXSIZE' => 'winbinder/winbinder.stub', 'WBC_MBUTTON' => 'winbinder/winbinder.stub', 'WBC_MIDDLE' => 'winbinder/winbinder.stub', 'WBC_MINIMIZED' => 'winbinder/winbinder.stub', 'WBC_MINSIZE' => 'winbinder/winbinder.stub', 'WBC_MOUSEDOWN' => 'winbinder/winbinder.stub', 'WBC_MOUSEMOVE' => 'winbinder/winbinder.stub', 'WBC_MOUSEUP' => 'winbinder/winbinder.stub', 'WBC_MULTILINE' => 'winbinder/winbinder.stub', 'WBC_MULTISELECT' => 'winbinder/winbinder.stub', 'WBC_NOHEADER' => 'winbinder/winbinder.stub', 'WBC_NORMAL' => 'winbinder/winbinder.stub', 'WBC_NOTIFY' => 'winbinder/winbinder.stub', 'WBC_NUMBER' => 'winbinder/winbinder.stub', 'WBC_OK' => 'winbinder/winbinder.stub', 'WBC_OKCANCEL' => 'winbinder/winbinder.stub', 'WBC_QUESTION' => 'winbinder/winbinder.stub', 'WBC_RBUTTON' => 'winbinder/winbinder.stub', 'WBC_READONLY' => 'winbinder/winbinder.stub', 'WBC_REDRAW' => 'winbinder/winbinder.stub', 'WBC_RESIZE' => 'winbinder/winbinder.stub', 'WBC_RIGHT' => 'winbinder/winbinder.stub', 'WBC_RTF_TEXT' => 'winbinder/winbinder.stub', 'WBC_SHIFT' => 'winbinder/winbinder.stub', 'WBC_SINGLE' => 'winbinder/winbinder.stub', 'WBC_SORT' => 'winbinder/winbinder.stub', 'WBC_STOP' => 'winbinder/winbinder.stub', 'WBC_TASKBAR' => 'winbinder/winbinder.stub', 'WBC_TITLE' => 'winbinder/winbinder.stub', 'WBC_TOP' => 'winbinder/winbinder.stub', 'WBC_TRANSPARENT' => 'winbinder/winbinder.stub', 'WBC_VERSION' => 'winbinder/winbinder.stub', 'WBC_VISIBLE' => 'winbinder/winbinder.stub', 'WBC_WARNING' => 'winbinder/winbinder.stub', 'WBC_YESNO' => 'winbinder/winbinder.stub', 'WBC_YESNOCANCEL' => 'winbinder/winbinder.stub', 'WCONTINUED' => 'pcntl/pcntl.stub', 'WEBSOCKET_CLOSE_ABNORMAL' => 'swoole/constants.stub', 'WEBSOCKET_CLOSE_DATA_ERROR' => 'swoole/constants.stub', 'WEBSOCKET_CLOSE_EXTENSION_MISSING' => 'swoole/constants.stub', 'WEBSOCKET_CLOSE_GOING_AWAY' => 'swoole/constants.stub', 'WEBSOCKET_CLOSE_MESSAGE_ERROR' => 'swoole/constants.stub', 'WEBSOCKET_CLOSE_MESSAGE_TOO_BIG' => 'swoole/constants.stub', 'WEBSOCKET_CLOSE_NORMAL' => 'swoole/constants.stub', 'WEBSOCKET_CLOSE_POLICY_ERROR' => 'swoole/constants.stub', 'WEBSOCKET_CLOSE_PROTOCOL_ERROR' => 'swoole/constants.stub', 'WEBSOCKET_CLOSE_SERVER_ERROR' => 'swoole/constants.stub', 'WEBSOCKET_CLOSE_STATUS_ERROR' => 'swoole/constants.stub', 'WEBSOCKET_CLOSE_TLS' => 'swoole/constants.stub', 'WEBSOCKET_OPCODE_BINARY' => 'swoole/constants.stub', 'WEBSOCKET_OPCODE_CLOSE' => 'swoole/constants.stub', 'WEBSOCKET_OPCODE_CONTINUATION' => 'swoole/constants.stub', 'WEBSOCKET_OPCODE_PING' => 'swoole/constants.stub', 'WEBSOCKET_OPCODE_PONG' => 'swoole/constants.stub', 'WEBSOCKET_OPCODE_TEXT' => 'swoole/constants.stub', 'WEBSOCKET_STATUS_ACTIVE' => 'swoole/constants.stub', 'WEBSOCKET_STATUS_CLOSING' => 'swoole/constants.stub', 'WEBSOCKET_STATUS_CONNECTION' => 'swoole/constants.stub', 'WEBSOCKET_STATUS_FRAME' => 'swoole/constants.stub', 'WEBSOCKET_STATUS_HANDSHAKE' => 'swoole/constants.stub', 'WEXITED' => 'pcntl/pcntl.stub', 'WHITE' => 'winbinder/winbinder.stub', 'WIN32_ABOVE_NORMAL_PRIORITY_CLASS' => 'win32service/win32service.stub', 'WIN32_BELOW_NORMAL_PRIORITY_CLASS' => 'win32service/win32service.stub', 'WIN32_ERROR_ACCESS_DENIED' => 'win32service/win32service.stub', 'WIN32_ERROR_CIRCULAR_DEPENDENCY' => 'win32service/win32service.stub', 'WIN32_ERROR_DATABASE_DOES_NOT_EXIST' => 'win32service/win32service.stub', 'WIN32_ERROR_DEPENDENT_SERVICES_RUNNING' => 'win32service/win32service.stub', 'WIN32_ERROR_DUPLICATE_SERVICE_NAME' => 'win32service/win32service.stub', 'WIN32_ERROR_FAILED_SERVICE_CONTROLLER_CONNECT' => 'win32service/win32service.stub', 'WIN32_ERROR_INSUFFICIENT_BUFFER' => 'win32service/win32service.stub', 'WIN32_ERROR_INVALID_DATA' => 'win32service/win32service.stub', 'WIN32_ERROR_INVALID_HANDLE' => 'win32service/win32service.stub', 'WIN32_ERROR_INVALID_LEVEL' => 'win32service/win32service.stub', 'WIN32_ERROR_INVALID_NAME' => 'win32service/win32service.stub', 'WIN32_ERROR_INVALID_PARAMETER' => 'win32service/win32service.stub', 'WIN32_ERROR_INVALID_SERVICE_ACCOUNT' => 'win32service/win32service.stub', 'WIN32_ERROR_INVALID_SERVICE_CONTROL' => 'win32service/win32service.stub', 'WIN32_ERROR_PATH_NOT_FOUND' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_ALREADY_RUNNING' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_CANNOT_ACCEPT_CTRL' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_DATABASE_LOCKED' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_DEPENDENCY_DELETED' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_DEPENDENCY_FAIL' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_DISABLED' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_DOES_NOT_EXIST' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_EXISTS' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_LOGON_FAILED' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_MARKED_FOR_DELETE' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_NOT_ACTIVE' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_NO_THREAD' => 'win32service/win32service.stub', 'WIN32_ERROR_SERVICE_REQUEST_TIMEOUT' => 'win32service/win32service.stub', 'WIN32_ERROR_SHUTDOWN_IN_PROGRESS' => 'win32service/win32service.stub', 'WIN32_HIGH_PRIORITY_CLASS' => 'win32service/win32service.stub', 'WIN32_IDLE_PRIORITY_CLASS' => 'win32service/win32service.stub', 'WIN32_NORMAL_PRIORITY_CLASS' => 'win32service/win32service.stub', 'WIN32_NO_ERROR' => 'win32service/win32service.stub', 'WIN32_REALTIME_PRIORITY_CLASS' => 'win32service/win32service.stub', 'WIN32_SERVICE_ACCEPT_PAUSE_CONTINUE' => 'win32service/win32service.stub', 'WIN32_SERVICE_ACCEPT_PRESHUTDOWN' => 'win32service/win32service.stub', 'WIN32_SERVICE_ACCEPT_SHUTDOWN' => 'win32service/win32service.stub', 'WIN32_SERVICE_ACCEPT_STOP' => 'win32service/win32service.stub', 'WIN32_SERVICE_AUTO_START' => 'win32service/win32service.stub', 'WIN32_SERVICE_CONTINUE_PENDING' => 'win32service/win32service.stub', 'WIN32_SERVICE_CONTROL_CONTINUE' => 'win32service/win32service.stub', 'WIN32_SERVICE_CONTROL_INTERROGATE' => 'win32service/win32service.stub', 'WIN32_SERVICE_CONTROL_PAUSE' => 'win32service/win32service.stub', 'WIN32_SERVICE_CONTROL_PRESHUTDOWN' => 'win32service/win32service.stub', 'WIN32_SERVICE_CONTROL_SHUTDOWN' => 'win32service/win32service.stub', 'WIN32_SERVICE_CONTROL_STOP' => 'win32service/win32service.stub', 'WIN32_SERVICE_DEMAND_START' => 'win32service/win32service.stub', 'WIN32_SERVICE_DISABLED' => 'win32service/win32service.stub', 'WIN32_SERVICE_ERROR_IGNORE' => 'win32service/win32service.stub', 'WIN32_SERVICE_ERROR_NORMAL' => 'win32service/win32service.stub', 'WIN32_SERVICE_INTERACTIVE_PROCESS' => 'win32service/win32service.stub', 'WIN32_SERVICE_PAUSED' => 'win32service/win32service.stub', 'WIN32_SERVICE_PAUSE_PENDING' => 'win32service/win32service.stub', 'WIN32_SERVICE_RUNNING' => 'win32service/win32service.stub', 'WIN32_SERVICE_RUNS_IN_SYSTEM_PROCESS' => 'win32service/win32service.stub', 'WIN32_SERVICE_START_PENDING' => 'win32service/win32service.stub', 'WIN32_SERVICE_STOPPED' => 'win32service/win32service.stub', 'WIN32_SERVICE_STOP_PENDING' => 'win32service/win32service.stub', 'WIN32_SERVICE_WIN32_OWN_PROCESS' => 'win32service/win32service.stub', 'WIN32_SERVICE_WIN32_OWN_PROCESS_INTERACTIVE' => 'win32service/win32service.stub', 'WNOHANG' => 'pcntl/pcntl.stub', 'WNOWAIT' => 'pcntl/pcntl.stub', 'WSDL_CACHE_BOTH' => 'soap/soap.stub', 'WSDL_CACHE_DISK' => 'soap/soap.stub', 'WSDL_CACHE_MEMORY' => 'soap/soap.stub', 'WSDL_CACHE_NONE' => 'soap/soap.stub', 'WSTOPPED' => 'pcntl/pcntl.stub', 'WUNTRACED' => 'pcntl/pcntl.stub', 'X509_PURPOSE_ANY' => 'openssl/openssl.stub', 'X509_PURPOSE_CRL_SIGN' => 'openssl/openssl.stub', 'X509_PURPOSE_NS_SSL_SERVER' => 'openssl/openssl.stub', 'X509_PURPOSE_OCSP_HELPER' => 'openssl/openssl.stub', 'X509_PURPOSE_SMIME_ENCRYPT' => 'openssl/openssl.stub', 'X509_PURPOSE_SMIME_SIGN' => 'openssl/openssl.stub', 'X509_PURPOSE_SSL_CLIENT' => 'openssl/openssl.stub', 'X509_PURPOSE_SSL_SERVER' => 'openssl/openssl.stub', 'X509_PURPOSE_TIMESTAMP_SIGN' => 'openssl/openssl.stub', 'XDEBUG_CC_BRANCH_CHECK' => 'xdebug/xdebug.stub', 'XDEBUG_CC_DEAD_CODE' => 'xdebug/xdebug.stub', 'XDEBUG_CC_UNUSED' => 'xdebug/xdebug.stub', 'XDEBUG_FILTER_CODE_COVERAGE' => 'xdebug/xdebug.stub', 'XDEBUG_FILTER_NONE' => 'xdebug/xdebug.stub', 'XDEBUG_FILTER_STACK' => 'xdebug/xdebug.stub', 'XDEBUG_FILTER_TRACING' => 'xdebug/xdebug.stub', 'XDEBUG_NAMESPACE_BLACKLIST' => 'xdebug/xdebug.stub', 'XDEBUG_NAMESPACE_EXCLUDE' => 'xdebug/xdebug.stub', 'XDEBUG_NAMESPACE_INCLUDE' => 'xdebug/xdebug.stub', 'XDEBUG_NAMESPACE_WHITELIST' => 'xdebug/xdebug.stub', 'XDEBUG_PATH_BLACKLIST' => 'xdebug/xdebug.stub', 'XDEBUG_PATH_EXCLUDE' => 'xdebug/xdebug.stub', 'XDEBUG_PATH_INCLUDE' => 'xdebug/xdebug.stub', 'XDEBUG_PATH_WHITELIST' => 'xdebug/xdebug.stub', 'XDEBUG_STACK_NO_DESC' => 'xdebug/xdebug.stub', 'XDEBUG_TRACE_APPEND' => 'xdebug/xdebug.stub', 'XDEBUG_TRACE_COMPUTERIZED' => 'xdebug/xdebug.stub', 'XDEBUG_TRACE_HTML' => 'xdebug/xdebug.stub', 'XDEBUG_TRACE_NAKED_FILENAME' => 'xdebug/xdebug.stub', 'XDIFF_PATCH_IGNORESPACE' => 'xdiff/xdiff.stub', 'XDIFF_PATCH_NORMAL' => 'xdiff/xdiff.stub', 'XDIFF_PATCH_REVERSE' => 'xdiff/xdiff.stub', 'XHPROF_FLAGS_CPU' => 'xhprof/xhprof.stub', 'XHPROF_FLAGS_MEMORY' => 'xhprof/xhprof.stub', 'XHPROF_FLAGS_NO_BUILTINS' => 'xhprof/xhprof.stub', 'XML_ATTRIBUTE_CDATA' => 'dom/dom.stub', 'XML_ATTRIBUTE_DECL_NODE' => 'dom/dom.stub', 'XML_ATTRIBUTE_ENTITY' => 'dom/dom.stub', 'XML_ATTRIBUTE_ENUMERATION' => 'dom/dom.stub', 'XML_ATTRIBUTE_ID' => 'dom/dom.stub', 'XML_ATTRIBUTE_IDREF' => 'dom/dom.stub', 'XML_ATTRIBUTE_IDREFS' => 'dom/dom.stub', 'XML_ATTRIBUTE_NMTOKEN' => 'dom/dom.stub', 'XML_ATTRIBUTE_NMTOKENS' => 'dom/dom.stub', 'XML_ATTRIBUTE_NODE' => 'dom/dom.stub', 'XML_ATTRIBUTE_NOTATION' => 'dom/dom.stub', 'XML_CDATA_SECTION_NODE' => 'dom/dom.stub', 'XML_COMMENT_NODE' => 'dom/dom.stub', 'XML_DOCUMENT_FRAG_NODE' => 'dom/dom.stub', 'XML_DOCUMENT_NODE' => 'dom/dom.stub', 'XML_DOCUMENT_TYPE_NODE' => 'dom/dom.stub', 'XML_DTD_NODE' => 'dom/dom.stub', 'XML_ELEMENT_DECL_NODE' => 'dom/dom.stub', 'XML_ELEMENT_NODE' => 'dom/dom.stub', 'XML_ENTITY_DECL_NODE' => 'dom/dom.stub', 'XML_ENTITY_NODE' => 'dom/dom.stub', 'XML_ENTITY_REF_NODE' => 'dom/dom.stub', 'XML_ERROR_ASYNC_ENTITY' => 'xml/xml.stub', 'XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF' => 'xml/xml.stub', 'XML_ERROR_BAD_CHAR_REF' => 'xml/xml.stub', 'XML_ERROR_BINARY_ENTITY_REF' => 'xml/xml.stub', 'XML_ERROR_DUPLICATE_ATTRIBUTE' => 'xml/xml.stub', 'XML_ERROR_EXTERNAL_ENTITY_HANDLING' => 'xml/xml.stub', 'XML_ERROR_INCORRECT_ENCODING' => 'xml/xml.stub', 'XML_ERROR_INVALID_TOKEN' => 'xml/xml.stub', 'XML_ERROR_JUNK_AFTER_DOC_ELEMENT' => 'xml/xml.stub', 'XML_ERROR_MISPLACED_XML_PI' => 'xml/xml.stub', 'XML_ERROR_NONE' => 'xml/xml.stub', 'XML_ERROR_NO_ELEMENTS' => 'xml/xml.stub', 'XML_ERROR_NO_MEMORY' => 'xml/xml.stub', 'XML_ERROR_PARAM_ENTITY_REF' => 'xml/xml.stub', 'XML_ERROR_PARTIAL_CHAR' => 'xml/xml.stub', 'XML_ERROR_RECURSIVE_ENTITY_REF' => 'xml/xml.stub', 'XML_ERROR_SYNTAX' => 'xml/xml.stub', 'XML_ERROR_TAG_MISMATCH' => 'xml/xml.stub', 'XML_ERROR_UNCLOSED_CDATA_SECTION' => 'xml/xml.stub', 'XML_ERROR_UNCLOSED_TOKEN' => 'xml/xml.stub', 'XML_ERROR_UNDEFINED_ENTITY' => 'xml/xml.stub', 'XML_ERROR_UNKNOWN_ENCODING' => 'xml/xml.stub', 'XML_HTML_DOCUMENT_NODE' => 'dom/dom.stub', 'XML_LOCAL_NAMESPACE' => 'dom/dom.stub', 'XML_NAMESPACE_DECL_NODE' => 'dom/dom.stub', 'XML_NOTATION_NODE' => 'dom/dom.stub', 'XML_OPTION_CASE_FOLDING' => 'xml/xml.stub', 'XML_OPTION_PARSE_HUGE' => 'xml/xml.stub', 'XML_OPTION_SKIP_TAGSTART' => 'xml/xml.stub', 'XML_OPTION_SKIP_WHITE' => 'xml/xml.stub', 'XML_OPTION_TARGET_ENCODING' => 'xml/xml.stub', 'XML_PI_NODE' => 'dom/dom.stub', 'XML_SAX_IMPL' => 'xml/xml.stub', 'XML_TEXT_NODE' => 'dom/dom.stub', 'XSD_1999_NAMESPACE' => 'soap/soap.stub', 'XSD_1999_TIMEINSTANT' => 'soap/soap.stub', 'XSD_ANYTYPE' => 'soap/soap.stub', 'XSD_ANYURI' => 'soap/soap.stub', 'XSD_ANYXML' => 'soap/soap.stub', 'XSD_BASE64BINARY' => 'soap/soap.stub', 'XSD_BOOLEAN' => 'soap/soap.stub', 'XSD_BYTE' => 'soap/soap.stub', 'XSD_DATE' => 'soap/soap.stub', 'XSD_DATETIME' => 'soap/soap.stub', 'XSD_DECIMAL' => 'soap/soap.stub', 'XSD_DOUBLE' => 'soap/soap.stub', 'XSD_DURATION' => 'soap/soap.stub', 'XSD_ENTITIES' => 'soap/soap.stub', 'XSD_ENTITY' => 'soap/soap.stub', 'XSD_FLOAT' => 'soap/soap.stub', 'XSD_GDAY' => 'soap/soap.stub', 'XSD_GMONTH' => 'soap/soap.stub', 'XSD_GMONTHDAY' => 'soap/soap.stub', 'XSD_GYEAR' => 'soap/soap.stub', 'XSD_GYEARMONTH' => 'soap/soap.stub', 'XSD_HEXBINARY' => 'soap/soap.stub', 'XSD_ID' => 'soap/soap.stub', 'XSD_IDREF' => 'soap/soap.stub', 'XSD_IDREFS' => 'soap/soap.stub', 'XSD_INT' => 'soap/soap.stub', 'XSD_INTEGER' => 'soap/soap.stub', 'XSD_LANGUAGE' => 'soap/soap.stub', 'XSD_LONG' => 'soap/soap.stub', 'XSD_NAME' => 'soap/soap.stub', 'XSD_NAMESPACE' => 'soap/soap.stub', 'XSD_NCNAME' => 'soap/soap.stub', 'XSD_NEGATIVEINTEGER' => 'soap/soap.stub', 'XSD_NMTOKEN' => 'soap/soap.stub', 'XSD_NMTOKENS' => 'soap/soap.stub', 'XSD_NONNEGATIVEINTEGER' => 'soap/soap.stub', 'XSD_NONPOSITIVEINTEGER' => 'soap/soap.stub', 'XSD_NORMALIZEDSTRING' => 'soap/soap.stub', 'XSD_NOTATION' => 'soap/soap.stub', 'XSD_POSITIVEINTEGER' => 'soap/soap.stub', 'XSD_QNAME' => 'soap/soap.stub', 'XSD_SHORT' => 'soap/soap.stub', 'XSD_STRING' => 'soap/soap.stub', 'XSD_TIME' => 'soap/soap.stub', 'XSD_TOKEN' => 'soap/soap.stub', 'XSD_UNSIGNEDBYTE' => 'soap/soap.stub', 'XSD_UNSIGNEDINT' => 'soap/soap.stub', 'XSD_UNSIGNEDLONG' => 'soap/soap.stub', 'XSD_UNSIGNEDSHORT' => 'soap/soap.stub', 'XSL_CLONE_ALWAYS' => 'xsl/xsl.stub', 'XSL_CLONE_AUTO' => 'xsl/xsl.stub', 'XSL_CLONE_NEVER' => 'xsl/xsl.stub', 'XSL_SECPREF_CREATE_DIRECTORY' => 'xsl/xsl.stub', 'XSL_SECPREF_DEFAULT' => 'xsl/xsl.stub', 'XSL_SECPREF_NONE' => 'xsl/xsl.stub', 'XSL_SECPREF_READ_FILE' => 'xsl/xsl.stub', 'XSL_SECPREF_READ_NETWORK' => 'xsl/xsl.stub', 'XSL_SECPREF_WRITE_FILE' => 'xsl/xsl.stub', 'XSL_SECPREF_WRITE_NETWORK' => 'xsl/xsl.stub', 'YAF\\ENVIRON' => 'yaf/yaf_namespace.stub', 'YAF\\ERR\\AUTOLOAD\\FAILED' => 'yaf/yaf_namespace.stub', 'YAF\\ERR\\CALL\\FAILED' => 'yaf/yaf_namespace.stub', 'YAF\\ERR\\DISPATCH\\FAILED' => 'yaf/yaf_namespace.stub', 'YAF\\ERR\\NOTFOUND\\ACTION' => 'yaf/yaf_namespace.stub', 'YAF\\ERR\\NOTFOUND\\CONTROLLER' => 'yaf/yaf_namespace.stub', 'YAF\\ERR\\NOTFOUND\\MODULE' => 'yaf/yaf_namespace.stub', 'YAF\\ERR\\NOTFOUND\\VIEW' => 'yaf/yaf_namespace.stub', 'YAF\\ERR\\ROUTE\\FAILED' => 'yaf/yaf_namespace.stub', 'YAF\\ERR\\STARTUP\\FAILED' => 'yaf/yaf_namespace.stub', 'YAF\\ERR\\TYPE\\ERROR' => 'yaf/yaf_namespace.stub', 'YAF\\VERSION' => 'yaf/yaf_namespace.stub', 'YAF_ENVIRON' => 'yaf/yaf.stub', 'YAF_ERR_ACCESS_ERROR' => 'yaf/yaf.stub', 'YAF_ERR_AUTOLOAD_FAILED' => 'yaf/yaf.stub', 'YAF_ERR_CALL_FAILED' => 'yaf/yaf.stub', 'YAF_ERR_DISPATCH_FAILED' => 'yaf/yaf.stub', 'YAF_ERR_NOTFOUND_ACTION' => 'yaf/yaf.stub', 'YAF_ERR_NOTFOUND_CONTROLLER' => 'yaf/yaf.stub', 'YAF_ERR_NOTFOUND_MODULE' => 'yaf/yaf.stub', 'YAF_ERR_NOTFOUND_VIEW' => 'yaf/yaf.stub', 'YAF_ERR_ROUTE_FAILED' => 'yaf/yaf.stub', 'YAF_ERR_STARTUP_FAILED' => 'yaf/yaf.stub', 'YAF_ERR_TYPE_ERROR' => 'yaf/yaf.stub', 'YAF_VERSION' => 'yaf/yaf.stub', 'YAML_ANY_BREAK' => 'yaml/yaml.stub', 'YAML_ANY_ENCODING' => 'yaml/yaml.stub', 'YAML_ANY_SCALAR_STYLE' => 'yaml/yaml.stub', 'YAML_BINARY_TAG' => 'yaml/yaml.stub', 'YAML_BOOL_TAG' => 'yaml/yaml.stub', 'YAML_CRLN_BREAK' => 'yaml/yaml.stub', 'YAML_CR_BREAK' => 'yaml/yaml.stub', 'YAML_DOUBLE_QUOTED_SCALAR_STYLE' => 'yaml/yaml.stub', 'YAML_FLOAT_TAG' => 'yaml/yaml.stub', 'YAML_FOLDED_SCALAR_STYLE' => 'yaml/yaml.stub', 'YAML_INT_TAG' => 'yaml/yaml.stub', 'YAML_LITERAL_SCALAR_STYLE' => 'yaml/yaml.stub', 'YAML_LN_BREAK' => 'yaml/yaml.stub', 'YAML_MAP_TAG' => 'yaml/yaml.stub', 'YAML_MERGE_TAG' => 'yaml/yaml.stub', 'YAML_NULL_TAG' => 'yaml/yaml.stub', 'YAML_PHP_TAG' => 'yaml/yaml.stub', 'YAML_PLAIN_SCALAR_STYLE' => 'yaml/yaml.stub', 'YAML_SEQ_TAG' => 'yaml/yaml.stub', 'YAML_SINGLE_QUOTED_SCALAR_STYLE' => 'yaml/yaml.stub', 'YAML_STR_TAG' => 'yaml/yaml.stub', 'YAML_TIMESTAMP_TAG' => 'yaml/yaml.stub', 'YAML_UTF16BE_ENCODING' => 'yaml/yaml.stub', 'YAML_UTF16LE_ENCODING' => 'yaml/yaml.stub', 'YAML_UTF8_ENCODING' => 'yaml/yaml.stub', 'YAR_CLIENT_PROTOCOL_HTTP' => 'yar/yar.stub', 'YAR_CLIENT_PROTOCOL_TCP' => 'yar/yar.stub', 'YAR_CLIENT_PROTOCOL_UNIX' => 'yar/yar.stub', 'YAR_ERR_EXCEPTION' => 'yar/yar.stub', 'YAR_ERR_OKEY' => 'yar/yar.stub', 'YAR_ERR_OUTPUT' => 'yar/yar.stub', 'YAR_ERR_PACKAGER' => 'yar/yar.stub', 'YAR_ERR_PROTOCOL' => 'yar/yar.stub', 'YAR_ERR_REQUEST' => 'yar/yar.stub', 'YAR_ERR_TRANSPORT' => 'yar/yar.stub', 'YAR_OPT_CONNECT_TIMEOUT' => 'yar/yar.stub', 'YAR_OPT_HEADER' => 'yar/yar.stub', 'YAR_OPT_PACKAGER' => 'yar/yar.stub', 'YAR_OPT_PERSISTENT' => 'yar/yar.stub', 'YAR_OPT_RESOLVE' => 'yar/yar.stub', 'YAR_OPT_TIMEOUT' => 'yar/yar.stub', 'YAR_PACKAGER_JSON' => 'yar/yar.stub', 'YAR_PACKAGER_PHP' => 'yar/yar.stub', 'YAR_VERSION' => 'yar/yar.stub', 'YELLOW' => 'winbinder/winbinder.stub', 'YESEXPR' => 'standard/standard_defines.stub', 'YESSTR' => 'standard/standard_defines.stub', 'ZEND_ACC_ABSTRACT' => 'uopz/uopz.stub', 'ZEND_ACC_FETCH' => 'uopz/uopz.stub', 'ZEND_ACC_FINAL' => 'uopz/uopz.stub', 'ZEND_ACC_PPP_MASK' => 'uopz/uopz.stub', 'ZEND_ACC_PRIVATE' => 'uopz/uopz.stub', 'ZEND_ACC_PROTECTED' => 'uopz/uopz.stub', 'ZEND_ACC_PUBLIC' => 'uopz/uopz.stub', 'ZEND_ACC_STATIC' => 'uopz/uopz.stub', 'ZEND_DEBUG_BUILD' => 'Core/Core_d.stub', 'ZEND_MULTIBYTE' => 'Core/Core_d.stub', 'ZEND_THREAD_SAFE' => 'Core/Core_d.stub', 'ZLIB_BLOCK' => 'zlib/zlib.stub', 'ZLIB_BUF_ERROR' => 'zlib/zlib.stub', 'ZLIB_DATA_ERROR' => 'zlib/zlib.stub', 'ZLIB_DEFAULT_STRATEGY' => 'zlib/zlib.stub', 'ZLIB_ENCODING_DEFLATE' => 'zlib/zlib.stub', 'ZLIB_ENCODING_GZIP' => 'zlib/zlib.stub', 'ZLIB_ENCODING_RAW' => 'zlib/zlib.stub', 'ZLIB_ERRNO' => 'zlib/zlib.stub', 'ZLIB_FILTERED' => 'zlib/zlib.stub', 'ZLIB_FINISH' => 'zlib/zlib.stub', 'ZLIB_FIXED' => 'zlib/zlib.stub', 'ZLIB_FULL_FLUSH' => 'zlib/zlib.stub', 'ZLIB_HUFFMAN_ONLY' => 'zlib/zlib.stub', 'ZLIB_MEM_ERROR' => 'zlib/zlib.stub', 'ZLIB_NEED_DICT' => 'zlib/zlib.stub', 'ZLIB_NO_FLUSH' => 'zlib/zlib.stub', 'ZLIB_OK' => 'zlib/zlib.stub', 'ZLIB_PARTIAL_FLUSH' => 'zlib/zlib.stub', 'ZLIB_RLE' => 'zlib/zlib.stub', 'ZLIB_STREAM_END' => 'zlib/zlib.stub', 'ZLIB_STREAM_ERROR' => 'zlib/zlib.stub', 'ZLIB_SYNC_FLUSH' => 'zlib/zlib.stub', 'ZLIB_VERNUM' => 'zlib/zlib.stub', 'ZLIB_VERSION' => 'zlib/zlib.stub', 'ZLIB_VERSION_ERROR' => 'zlib/zlib.stub', 'ZSTD_COMPRESS_LEVEL_DEFAULT' => 'zstd/zstd.stub', 'ZSTD_COMPRESS_LEVEL_MAX' => 'zstd/zstd.stub', 'ZSTD_COMPRESS_LEVEL_MIN' => 'zstd/zstd.stub', '__CLASS__' => 'standard/basic.stub', '__COMPILER_HALT_OFFSET__' => 'standard/_standard_manual.stub', '__DIR__' => 'standard/basic.stub', '__FILE__' => 'standard/basic.stub', '__FUNCTION__' => 'standard/basic.stub', '__LINE__' => 'standard/basic.stub', '__METHOD__' => 'standard/basic.stub', '__NAMESPACE__' => 'standard/basic.stub', '__TRAIT__' => 'standard/basic.stub', '__class__' => 'standard/basic.stub', '__dir__' => 'standard/basic.stub', '__file__' => 'standard/basic.stub', '__function__' => 'standard/basic.stub', '__line__' => 'standard/basic.stub', '__method__' => 'standard/basic.stub', '__namespace__' => 'standard/basic.stub', '__trait__' => 'standard/basic.stub', 'ast\\AST_ARG_LIST' => 'ast/ast.stub', 'ast\\AST_ARRAY' => 'ast/ast.stub', 'ast\\AST_ARRAY_ELEM' => 'ast/ast.stub', 'ast\\AST_ARROW_FUNC' => 'ast/ast.stub', 'ast\\AST_ASSIGN' => 'ast/ast.stub', 'ast\\AST_ASSIGN_OP' => 'ast/ast.stub', 'ast\\AST_ASSIGN_REF' => 'ast/ast.stub', 'ast\\AST_ATTRIBUTE' => 'ast/ast.stub', 'ast\\AST_ATTRIBUTE_GROUP' => 'ast/ast.stub', 'ast\\AST_ATTRIBUTE_LIST' => 'ast/ast.stub', 'ast\\AST_BINARY_OP' => 'ast/ast.stub', 'ast\\AST_BREAK' => 'ast/ast.stub', 'ast\\AST_CALL' => 'ast/ast.stub', 'ast\\AST_CAST' => 'ast/ast.stub', 'ast\\AST_CATCH' => 'ast/ast.stub', 'ast\\AST_CATCH_LIST' => 'ast/ast.stub', 'ast\\AST_CLASS' => 'ast/ast.stub', 'ast\\AST_CLASS_CONST' => 'ast/ast.stub', 'ast\\AST_CLASS_CONST_DECL' => 'ast/ast.stub', 'ast\\AST_CLASS_CONST_GROUP' => 'ast/ast.stub', 'ast\\AST_CLASS_NAME' => 'ast/ast.stub', 'ast\\AST_CLONE' => 'ast/ast.stub', 'ast\\AST_CLOSURE' => 'ast/ast.stub', 'ast\\AST_CLOSURE_USES' => 'ast/ast.stub', 'ast\\AST_CLOSURE_VAR' => 'ast/ast.stub', 'ast\\AST_CONDITIONAL' => 'ast/ast.stub', 'ast\\AST_CONST' => 'ast/ast.stub', 'ast\\AST_CONST_DECL' => 'ast/ast.stub', 'ast\\AST_CONST_ELEM' => 'ast/ast.stub', 'ast\\AST_CONTINUE' => 'ast/ast.stub', 'ast\\AST_DECLARE' => 'ast/ast.stub', 'ast\\AST_DIM' => 'ast/ast.stub', 'ast\\AST_DO_WHILE' => 'ast/ast.stub', 'ast\\AST_ECHO' => 'ast/ast.stub', 'ast\\AST_EMPTY' => 'ast/ast.stub', 'ast\\AST_ENCAPS_LIST' => 'ast/ast.stub', 'ast\\AST_EXIT' => 'ast/ast.stub', 'ast\\AST_EXPR_LIST' => 'ast/ast.stub', 'ast\\AST_FOR' => 'ast/ast.stub', 'ast\\AST_FOREACH' => 'ast/ast.stub', 'ast\\AST_FUNC_DECL' => 'ast/ast.stub', 'ast\\AST_GLOBAL' => 'ast/ast.stub', 'ast\\AST_GOTO' => 'ast/ast.stub', 'ast\\AST_GROUP_USE' => 'ast/ast.stub', 'ast\\AST_HALT_COMPILER' => 'ast/ast.stub', 'ast\\AST_IF' => 'ast/ast.stub', 'ast\\AST_IF_ELEM' => 'ast/ast.stub', 'ast\\AST_INCLUDE_OR_EVAL' => 'ast/ast.stub', 'ast\\AST_INSTANCEOF' => 'ast/ast.stub', 'ast\\AST_ISSET' => 'ast/ast.stub', 'ast\\AST_LABEL' => 'ast/ast.stub', 'ast\\AST_LIST' => 'ast/ast.stub', 'ast\\AST_MAGIC_CONST' => 'ast/ast.stub', 'ast\\AST_MATCH' => 'ast/ast.stub', 'ast\\AST_MATCH_ARM' => 'ast/ast.stub', 'ast\\AST_MATCH_ARM_LIST' => 'ast/ast.stub', 'ast\\AST_METHOD' => 'ast/ast.stub', 'ast\\AST_METHOD_CALL' => 'ast/ast.stub', 'ast\\AST_METHOD_REFERENCE' => 'ast/ast.stub', 'ast\\AST_NAME' => 'ast/ast.stub', 'ast\\AST_NAMED_ARG' => 'ast/ast.stub', 'ast\\AST_NAMESPACE' => 'ast/ast.stub', 'ast\\AST_NAME_LIST' => 'ast/ast.stub', 'ast\\AST_NEW' => 'ast/ast.stub', 'ast\\AST_NULLABLE_TYPE' => 'ast/ast.stub', 'ast\\AST_NULLSAFE_METHOD_CALL' => 'ast/ast.stub', 'ast\\AST_NULLSAFE_PROP' => 'ast/ast.stub', 'ast\\AST_PARAM' => 'ast/ast.stub', 'ast\\AST_PARAM_LIST' => 'ast/ast.stub', 'ast\\AST_POST_DEC' => 'ast/ast.stub', 'ast\\AST_POST_INC' => 'ast/ast.stub', 'ast\\AST_PRE_DEC' => 'ast/ast.stub', 'ast\\AST_PRE_INC' => 'ast/ast.stub', 'ast\\AST_PRINT' => 'ast/ast.stub', 'ast\\AST_PROP' => 'ast/ast.stub', 'ast\\AST_PROP_DECL' => 'ast/ast.stub', 'ast\\AST_PROP_ELEM' => 'ast/ast.stub', 'ast\\AST_PROP_GROUP' => 'ast/ast.stub', 'ast\\AST_REF' => 'ast/ast.stub', 'ast\\AST_RETURN' => 'ast/ast.stub', 'ast\\AST_SHELL_EXEC' => 'ast/ast.stub', 'ast\\AST_STATIC' => 'ast/ast.stub', 'ast\\AST_STATIC_CALL' => 'ast/ast.stub', 'ast\\AST_STATIC_PROP' => 'ast/ast.stub', 'ast\\AST_STMT_LIST' => 'ast/ast.stub', 'ast\\AST_SWITCH' => 'ast/ast.stub', 'ast\\AST_SWITCH_CASE' => 'ast/ast.stub', 'ast\\AST_SWITCH_LIST' => 'ast/ast.stub', 'ast\\AST_THROW' => 'ast/ast.stub', 'ast\\AST_TRAIT_ADAPTATIONS' => 'ast/ast.stub', 'ast\\AST_TRAIT_ALIAS' => 'ast/ast.stub', 'ast\\AST_TRAIT_PRECEDENCE' => 'ast/ast.stub', 'ast\\AST_TRY' => 'ast/ast.stub', 'ast\\AST_TYPE' => 'ast/ast.stub', 'ast\\AST_TYPE_UNION' => 'ast/ast.stub', 'ast\\AST_UNARY_OP' => 'ast/ast.stub', 'ast\\AST_UNPACK' => 'ast/ast.stub', 'ast\\AST_UNSET' => 'ast/ast.stub', 'ast\\AST_USE' => 'ast/ast.stub', 'ast\\AST_USE_ELEM' => 'ast/ast.stub', 'ast\\AST_USE_TRAIT' => 'ast/ast.stub', 'ast\\AST_VAR' => 'ast/ast.stub', 'ast\\AST_WHILE' => 'ast/ast.stub', 'ast\\AST_YIELD' => 'ast/ast.stub', 'ast\\AST_YIELD_FROM' => 'ast/ast.stub', 'ast\\flags\\ARRAY_ELEM_REF' => 'ast/ast.stub', 'ast\\flags\\ARRAY_SYNTAX_LIST' => 'ast/ast.stub', 'ast\\flags\\ARRAY_SYNTAX_LONG' => 'ast/ast.stub', 'ast\\flags\\ARRAY_SYNTAX_SHORT' => 'ast/ast.stub', 'ast\\flags\\BINARY_ADD' => 'ast/ast.stub', 'ast\\flags\\BINARY_BITWISE_AND' => 'ast/ast.stub', 'ast\\flags\\BINARY_BITWISE_OR' => 'ast/ast.stub', 'ast\\flags\\BINARY_BITWISE_XOR' => 'ast/ast.stub', 'ast\\flags\\BINARY_BOOL_AND' => 'ast/ast.stub', 'ast\\flags\\BINARY_BOOL_OR' => 'ast/ast.stub', 'ast\\flags\\BINARY_BOOL_XOR' => 'ast/ast.stub', 'ast\\flags\\BINARY_COALESCE' => 'ast/ast.stub', 'ast\\flags\\BINARY_CONCAT' => 'ast/ast.stub', 'ast\\flags\\BINARY_DIV' => 'ast/ast.stub', 'ast\\flags\\BINARY_IS_EQUAL' => 'ast/ast.stub', 'ast\\flags\\BINARY_IS_GREATER' => 'ast/ast.stub', 'ast\\flags\\BINARY_IS_GREATER_OR_EQUAL' => 'ast/ast.stub', 'ast\\flags\\BINARY_IS_IDENTICAL' => 'ast/ast.stub', 'ast\\flags\\BINARY_IS_NOT_EQUAL' => 'ast/ast.stub', 'ast\\flags\\BINARY_IS_NOT_IDENTICAL' => 'ast/ast.stub', 'ast\\flags\\BINARY_IS_SMALLER' => 'ast/ast.stub', 'ast\\flags\\BINARY_IS_SMALLER_OR_EQUAL' => 'ast/ast.stub', 'ast\\flags\\BINARY_MOD' => 'ast/ast.stub', 'ast\\flags\\BINARY_MUL' => 'ast/ast.stub', 'ast\\flags\\BINARY_POW' => 'ast/ast.stub', 'ast\\flags\\BINARY_SHIFT_LEFT' => 'ast/ast.stub', 'ast\\flags\\BINARY_SHIFT_RIGHT' => 'ast/ast.stub', 'ast\\flags\\BINARY_SPACESHIP' => 'ast/ast.stub', 'ast\\flags\\BINARY_SUB' => 'ast/ast.stub', 'ast\\flags\\CLASS_ABSTRACT' => 'ast/ast.stub', 'ast\\flags\\CLASS_ANONYMOUS' => 'ast/ast.stub', 'ast\\flags\\CLASS_FINAL' => 'ast/ast.stub', 'ast\\flags\\CLASS_INTERFACE' => 'ast/ast.stub', 'ast\\flags\\CLASS_TRAIT' => 'ast/ast.stub', 'ast\\flags\\CLOSURE_USE_REF' => 'ast/ast.stub', 'ast\\flags\\DIM_ALTERNATIVE_SYNTAX' => 'ast/ast.stub', 'ast\\flags\\EXEC_EVAL' => 'ast/ast.stub', 'ast\\flags\\EXEC_INCLUDE' => 'ast/ast.stub', 'ast\\flags\\EXEC_INCLUDE_ONCE' => 'ast/ast.stub', 'ast\\flags\\EXEC_REQUIRE' => 'ast/ast.stub', 'ast\\flags\\EXEC_REQUIRE_ONCE' => 'ast/ast.stub', 'ast\\flags\\FUNC_GENERATOR' => 'ast/ast.stub', 'ast\\flags\\FUNC_RETURNS_REF' => 'ast/ast.stub', 'ast\\flags\\MAGIC_CLASS' => 'ast/ast.stub', 'ast\\flags\\MAGIC_DIR' => 'ast/ast.stub', 'ast\\flags\\MAGIC_FILE' => 'ast/ast.stub', 'ast\\flags\\MAGIC_FUNCTION' => 'ast/ast.stub', 'ast\\flags\\MAGIC_LINE' => 'ast/ast.stub', 'ast\\flags\\MAGIC_METHOD' => 'ast/ast.stub', 'ast\\flags\\MAGIC_NAMESPACE' => 'ast/ast.stub', 'ast\\flags\\MAGIC_TRAIT' => 'ast/ast.stub', 'ast\\flags\\MODIFIER_ABSTRACT' => 'ast/ast.stub', 'ast\\flags\\MODIFIER_FINAL' => 'ast/ast.stub', 'ast\\flags\\MODIFIER_PRIVATE' => 'ast/ast.stub', 'ast\\flags\\MODIFIER_PROTECTED' => 'ast/ast.stub', 'ast\\flags\\MODIFIER_PUBLIC' => 'ast/ast.stub', 'ast\\flags\\MODIFIER_STATIC' => 'ast/ast.stub', 'ast\\flags\\NAME_FQ' => 'ast/ast.stub', 'ast\\flags\\NAME_NOT_FQ' => 'ast/ast.stub', 'ast\\flags\\NAME_RELATIVE' => 'ast/ast.stub', 'ast\\flags\\PARAM_MODIFIER_PRIVATE' => 'ast/ast.stub', 'ast\\flags\\PARAM_MODIFIER_PROTECTED' => 'ast/ast.stub', 'ast\\flags\\PARAM_MODIFIER_PUBLIC' => 'ast/ast.stub', 'ast\\flags\\PARAM_REF' => 'ast/ast.stub', 'ast\\flags\\PARAM_VARIADIC' => 'ast/ast.stub', 'ast\\flags\\PARENTHESIZED_CONDITIONAL' => 'ast/ast.stub', 'ast\\flags\\RETURNS_REF' => 'ast/ast.stub', 'ast\\flags\\TYPE_ARRAY' => 'ast/ast.stub', 'ast\\flags\\TYPE_BOOL' => 'ast/ast.stub', 'ast\\flags\\TYPE_CALLABLE' => 'ast/ast.stub', 'ast\\flags\\TYPE_DOUBLE' => 'ast/ast.stub', 'ast\\flags\\TYPE_FALSE' => 'ast/ast.stub', 'ast\\flags\\TYPE_ITERABLE' => 'ast/ast.stub', 'ast\\flags\\TYPE_LONG' => 'ast/ast.stub', 'ast\\flags\\TYPE_MIXED' => 'ast/ast.stub', 'ast\\flags\\TYPE_NULL' => 'ast/ast.stub', 'ast\\flags\\TYPE_OBJECT' => 'ast/ast.stub', 'ast\\flags\\TYPE_STATIC' => 'ast/ast.stub', 'ast\\flags\\TYPE_STRING' => 'ast/ast.stub', 'ast\\flags\\TYPE_VOID' => 'ast/ast.stub', 'ast\\flags\\UNARY_BITWISE_NOT' => 'ast/ast.stub', 'ast\\flags\\UNARY_BOOL_NOT' => 'ast/ast.stub', 'ast\\flags\\UNARY_MINUS' => 'ast/ast.stub', 'ast\\flags\\UNARY_PLUS' => 'ast/ast.stub', 'ast\\flags\\UNARY_SILENCE' => 'ast/ast.stub', 'ast\\flags\\USE_CONST' => 'ast/ast.stub', 'ast\\flags\\USE_FUNCTION' => 'ast/ast.stub', 'ast\\flags\\USE_NORMAL' => 'ast/ast.stub', 'bgrBLACK' => 'winbinder/winbinder.stub', 'bgrBLUE' => 'winbinder/winbinder.stub', 'bgrCYAN' => 'winbinder/winbinder.stub', 'bgrDARKBLUE' => 'winbinder/winbinder.stub', 'bgrDARKCYAN' => 'winbinder/winbinder.stub', 'bgrDARKGRAY' => 'winbinder/winbinder.stub', 'bgrDARKGREEN' => 'winbinder/winbinder.stub', 'bgrDARKMAGENTA' => 'winbinder/winbinder.stub', 'bgrDARKRED' => 'winbinder/winbinder.stub', 'bgrDARKYELLOW' => 'winbinder/winbinder.stub', 'bgrGREEN' => 'winbinder/winbinder.stub', 'bgrLIGHTGRAY' => 'winbinder/winbinder.stub', 'bgrMAGENTA' => 'winbinder/winbinder.stub', 'bgrNOCOLOR' => 'winbinder/winbinder.stub', 'bgrRED' => 'winbinder/winbinder.stub', 'bgrWHITE' => 'winbinder/winbinder.stub', 'bgrYELLOW' => 'winbinder/winbinder.stub', 'false' => 'Core/Core_d.stub', 'http\\Client\\Curl\\AUTH_ANY' => 'http/http3.stub', 'http\\Client\\Curl\\AUTH_BASIC' => 'http/http3.stub', 'http\\Client\\Curl\\AUTH_DIGEST' => 'http/http3.stub', 'http\\Client\\Curl\\AUTH_DIGEST_IE' => 'http/http3.stub', 'http\\Client\\Curl\\AUTH_GSSNEG' => 'http/http3.stub', 'http\\Client\\Curl\\AUTH_NTLM' => 'http/http3.stub', 'http\\Client\\Curl\\AUTH_SPNEGO' => 'http/http3.stub', 'http\\Client\\Curl\\FEATURES' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\ASYNCHDNS' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\GSSAPI' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\GSSNEGOTIATE' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\HTTP2' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\IDN' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\IPV6' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\KERBEROS4' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\KERBEROS5' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\LARGEFILE' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\LIBZ' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\NTLM' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\NTLM_WB' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\PSL' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\SPNEGO' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\SSL' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\SSPI' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\TLSAUTH_SRP' => 'http/http3.stub', 'http\\Client\\Curl\\Features\\UNIX_SOCKETS' => 'http/http3.stub', 'http\\Client\\Curl\\HTTP_VERSION_1_0' => 'http/http3.stub', 'http\\Client\\Curl\\HTTP_VERSION_1_1' => 'http/http3.stub', 'http\\Client\\Curl\\HTTP_VERSION_2TLS' => 'http/http3.stub', 'http\\Client\\Curl\\HTTP_VERSION_2_0' => 'http/http3.stub', 'http\\Client\\Curl\\HTTP_VERSION_ANY' => 'http/http3.stub', 'http\\Client\\Curl\\IPRESOLVE_ANY' => 'http/http3.stub', 'http\\Client\\Curl\\IPRESOLVE_V4' => 'http/http3.stub', 'http\\Client\\Curl\\IPRESOLVE_V6' => 'http/http3.stub', 'http\\Client\\Curl\\POSTREDIR_301' => 'http/http3.stub', 'http\\Client\\Curl\\POSTREDIR_302' => 'http/http3.stub', 'http\\Client\\Curl\\POSTREDIR_303' => 'http/http3.stub', 'http\\Client\\Curl\\POSTREDIR_ALL' => 'http/http3.stub', 'http\\Client\\Curl\\PROXY_HTTP' => 'http/http3.stub', 'http\\Client\\Curl\\PROXY_HTTP_1_0' => 'http/http3.stub', 'http\\Client\\Curl\\PROXY_SOCKS4' => 'http/http3.stub', 'http\\Client\\Curl\\PROXY_SOCKS4A' => 'http/http3.stub', 'http\\Client\\Curl\\PROXY_SOCKS5' => 'http/http3.stub', 'http\\Client\\Curl\\PROXY_SOCKS5_HOSTNAME' => 'http/http3.stub', 'http\\Client\\Curl\\SSL_VERSION_ANY' => 'http/http3.stub', 'http\\Client\\Curl\\SSL_VERSION_SSLv2' => 'http/http3.stub', 'http\\Client\\Curl\\SSL_VERSION_SSLv3' => 'http/http3.stub', 'http\\Client\\Curl\\SSL_VERSION_TLSv1' => 'http/http3.stub', 'http\\Client\\Curl\\SSL_VERSION_TLSv1_0' => 'http/http3.stub', 'http\\Client\\Curl\\SSL_VERSION_TLSv1_1' => 'http/http3.stub', 'http\\Client\\Curl\\SSL_VERSION_TLSv1_2' => 'http/http3.stub', 'http\\Client\\Curl\\TLSAUTH_SRP' => 'http/http3.stub', 'http\\Client\\Curl\\VERSIONS' => 'http/http3.stub', 'http\\Client\\Curl\\Versions\\ARES' => 'http/http3.stub', 'http\\Client\\Curl\\Versions\\CURL' => 'http/http3.stub', 'http\\Client\\Curl\\Versions\\IDN' => 'http/http3.stub', 'http\\Client\\Curl\\Versions\\LIBZ' => 'http/http3.stub', 'http\\Client\\Curl\\Versions\\SSL' => 'http/http3.stub', 'null' => 'Core/Core_d.stub', 'pcov\\all' => 'pcov/pcov.stub', 'pcov\\exclusive' => 'pcov/pcov.stub', 'pcov\\inclusive' => 'pcov/pcov.stub', 'pcov\\version' => 'pcov/pcov.stub', 'true' => 'Core/Core_d.stub', 'yaf\\environ' => 'yaf/yaf_namespace.stub', 'yaf\\err\\autoload\\failed' => 'yaf/yaf_namespace.stub', 'yaf\\err\\call\\failed' => 'yaf/yaf_namespace.stub', 'yaf\\err\\dispatch\\failed' => 'yaf/yaf_namespace.stub', 'yaf\\err\\notfound\\action' => 'yaf/yaf_namespace.stub', 'yaf\\err\\notfound\\controller' => 'yaf/yaf_namespace.stub', 'yaf\\err\\notfound\\module' => 'yaf/yaf_namespace.stub', 'yaf\\err\\notfound\\view' => 'yaf/yaf_namespace.stub', 'yaf\\err\\route\\failed' => 'yaf/yaf_namespace.stub', 'yaf\\err\\startup\\failed' => 'yaf/yaf_namespace.stub', 'yaf\\err\\type\\error' => 'yaf/yaf_namespace.stub', 'yaf\\version' => 'yaf/yaf_namespace.stub', 'yaf_environ' => 'yaf/yaf.stub', 'yaf_err_autoload_failed' => 'yaf/yaf.stub', 'yaf_err_call_failed' => 'yaf/yaf.stub', 'yaf_err_dispatch_failed' => 'yaf/yaf.stub', 'yaf_err_notfound_action' => 'yaf/yaf.stub', 'yaf_err_notfound_controller' => 'yaf/yaf.stub', 'yaf_err_notfound_module' => 'yaf/yaf.stub', 'yaf_err_notfound_view' => 'yaf/yaf.stub', 'yaf_err_route_failed' => 'yaf/yaf.stub', 'yaf_err_startup_failed' => 'yaf/yaf.stub', 'yaf_err_type_error' => 'yaf/yaf.stub', 'yaf_version' => 'yaf/yaf.stub'); } https://secure.php.net/manual/en/reserved.variables.php */ $GLOBALS = []; /** * @xglobal $_COOKIE array * Variables provided to the script via HTTP cookies. Analogous to the old $HTTP_COOKIE_VARS array * (which is still available, but deprecated). * *

    * https://secure.php.net/manual/en/reserved.variables.php */ $_COOKIE = []; /** * @xglobal $_ENV array * @xglobal $HTTP_ENV_VARS array * * Variables provided to the script via the environment. * Analogous to the old $HTTP_ENV_VARS array (which is still available, but deprecated). * *

    * https://secure.php.net/manual/en/reserved.variables.php */ $_ENV = []; /** * @deprecated 4.1 * @removed 5.4 */ $HTTP_ENV_VARS = []; /** * @xglobal $_FILES array * @xglobal $HTTP_POST_FILES array * * Variables provided to the script via HTTP post file uploads. Analogous to the old $HTTP_POST_FILES array * (which is still available, but deprecated). * See POST method uploads for more information. * *

    * https://secure.php.net/manual/en/reserved.variables.php */ $_FILES = []; /** * @deprecated 4.1 * @removed 5.4 */ $HTTP_POST_FILES = []; /** * @xglobal $_GET array * @xglobal $HTTP_GET_VARS array * * Variables provided to the script via URL query string. * Analogous to the old $HTTP_GET_VARS array (which is still available, but deprecated). * *

    * https://secure.php.net/manual/en/reserved.variables.php */ $_GET = []; /** * @deprecated 4.1 * @removed 5.4 */ $HTTP_GET_VARS = []; /** * @xglobal $_POST array * @xglobal $HTTP_POST_VARS array * * Variables provided to the script via HTTP POST. Analogous to the old $HTTP_POST_VARS array * (which is still available, but deprecated). * @link https://secure.php.net/manual/en/language.variables.predefined.php * *

    * https://secure.php.net/manual/en/reserved.variables.php */ $_POST = []; /** * @deprecated 4.1 * @removed 5.4 */ $HTTP_POST_VARS = []; /** * @xglobal $_REQUEST array * Variables provided to the script via the GET, POST, and COOKIE input mechanisms, * and which therefore cannot be trusted. * The presence and order of variable inclusion in this array is defined according to the * PHP variables_order configuration directive. * This array has no direct analogue in versions of PHP prior to 4.1.0. * See also import_request_variables(). *

    * Caution *

    Since PHP 4.3.0, FILE information from $_FILES does not exist in $_REQUEST. *

    * Note: When running on the command line , this will not include the argv and argc entries; these are present in the $_SERVER array. * * *

    * https://secure.php.net/manual/en/reserved.variables.php */ $_REQUEST = []; /** * @xglobal $_SERVER array * @xglobal $HTTP_SERVER_VARS array * * Variables set by the web server or otherwise directly related to the execution environment of the current script. * Analogous to the old $HTTP_SERVER_VARS array (which is still available, but deprecated). * *

    * https://secure.php.net/manual/en/reserved.variables.php */ $_SERVER = []; /** * @deprecated 4.1 * @removed 5.4 */ $HTTP_SERVER_VARS = []; $_SERVER['PHP_SELF'] = ''; $_SERVER['argv'] = ''; $_SERVER['argc'] = ''; $_SERVER['GATEWAY_INTERFACE'] = 'CGI/1.1'; $_SERVER['SERVER_ADDR'] = '127.0.0.1'; $_SERVER['SERVER_NAME'] = 'localhost'; $_SERVER['SERVER_SOFTWARE'] = ''; $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0'; $_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['REQUEST_TIME'] = 946713600; $_SERVER['REQUEST_TIME_FLOAT'] = 946713600.123456; $_SERVER['QUERY_STRING'] = ''; $_SERVER['DOCUMENT_ROOT'] = ''; $_SERVER['HTTP_ACCEPT'] = ''; $_SERVER['HTTP_ACCEPT_CHARSET'] = 'iso-8859-1,*,utf-8'; $_SERVER['HTTP_ACCEPT_ENCODING'] = 'gzip'; $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'en'; $_SERVER['HTTP_CONNECTION'] = 'Keep-Alive'; $_SERVER['HTTP_HOST'] = ''; $_SERVER['HTTP_REFERER'] = ''; $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586).'; $_SERVER['HTTPS'] = ''; $_SERVER['REMOTE_ADDR'] = ''; $_SERVER['REMOTE_HOST'] = ''; $_SERVER['REMOTE_PORT'] = ''; $_SERVER['REMOTE_USER'] = ''; $_SERVER['REDIRECT_REMOTE_USER'] = ''; $_SERVER['SCRIPT_FILENAME'] = ''; $_SERVER['SERVER_ADMIN'] = ''; $_SERVER['SERVER_PORT'] = '80'; $_SERVER['SERVER_SIGNATURE'] = ''; $_SERVER['PATH_TRANSLATED'] = ''; $_SERVER['SCRIPT_NAME'] = ''; $_SERVER['REQUEST_URI'] = '/index.html'; $_SERVER['PHP_AUTH_DIGEST'] = ''; $_SERVER['PHP_AUTH_USER'] = ''; $_SERVER['PHP_AUTH_PW'] = ''; $_SERVER['AUTH_TYPE'] = ''; $_SERVER['PATH_INFO'] = ''; $_SERVER['ORIG_PATH_INFO'] = ''; /** * @xglobal $_SESSION array * @xglobal $HTTP_SESSION_VARS array * * Variables which are currently registered to a script's session. * Analogous to the old $HTTP_SESSION_VARS array (which is still available, but deprecated). * See the Session handling functions section for more information. * *

    * https://secure.php.net/manual/en/reserved.variables.php */ $_SESSION = []; /** * @deprecated 4.1 * @removed 5.4 */ $HTTP_SESSION_VARS = []; /** * @xglobal $argc int * @type int<1, max> * * The number of arguments passed to script * *

    * https://secure.php.net/manual/en/reserved.variables.php */ $argc = 0; /** * @xglobal $argv array * * Array of arguments passed to script * *

    * https://secure.php.net/manual/en/reserved.variables.php */ $argv = [1 + 1 => "a" . "b"]; /** * @xglobal $HTTP_RAW_POST_DATA string * * Raw POST data * *

    * https://secure.php.net/manual/en/reserved.variables.php * * @deprecated 5.6 Deprecated as of PHP 5.6.0. Use the php://input stream instead. * @removed 7.0 */ $HTTP_RAW_POST_DATA = ''; /** * @xglobal $http_response_header array * * HTTP response headers * *

    * https://secure.php.net/manual/en/reserved.variables.php */ $http_response_header = []; /** * @xglobal $php_errormsg string * The previous error message * *

    * https://secure.php.net/manual/en/reserved.variables.php * @deprecated 7.2 */ $php_errormsg = ''; * swoole_coroutine_create(function () { // The surrounding function of a coroutine. * echo '1'; * swoole_coroutine_defer(function () { // The callback function to be deferred. * echo '3'; * }); * echo '2'; * }); *

     */
    function swoole_coroutine_defer(callable $callback) {}
    
    /**
     * @param $domain[required]
     * @param $type[required]
     * @param $protocol[required]
     * @return mixed
     */
    function swoole_coroutine_socketpair($domain, $type, $protocol) {}
    
    /**
     * @param $count[optional]
     * @param $sleep_time[optional]
     * @return mixed
     */
    function swoole_test_kernel_coroutine($count = null, $sleep_time = null) {}
    
    /**
     * @param $read_array[required]
     * @param $write_array[required]
     * @param $error_array[required]
     * @param $timeout[optional]
     * @return mixed
     */
    function swoole_client_select(&$read_array, &$write_array, &$error_array, $timeout = null) {}
    
    /**
     * @param $read_array[required]
     * @param $write_array[required]
     * @param $error_array[required]
     * @param $timeout[optional]
     * @return mixed
     */
    function swoole_select(&$read_array, &$write_array, &$error_array, $timeout = null) {}
    
    /**
     * @param $process_name[required]
     * @return mixed
     */
    function swoole_set_process_name($process_name) {}
    
    /**
     * @return mixed
     */
    function swoole_get_local_ip() {}
    
    /**
     * @return mixed
     */
    function swoole_get_local_mac() {}
    
    /**
     * @param $errno[required]
     * @param $error_type[optional]
     * @return mixed
     */
    function swoole_strerror($errno, $error_type = null) {}
    
    /**
     * @return mixed
     */
    function swoole_errno() {}
    
    /**
     * @return mixed
     */
    function swoole_clear_error() {}
    
    /**
     * @return void
     */
    function swoole_error_log(int $level, string $msg) {}
    
    /**
     * @return void
     * @since 4.8.1
     */
    function swoole_error_log_ex(int $level, int $error, string $msg) {}
    
    /**
     * @return void
     * @since 4.8.1
     */
    function swoole_ignore_error(int $error) {}
    
    /**
     * @param $data[required]
     * @param $type[optional]
     * @return mixed
     */
    function swoole_hashcode($data, $type = null) {}
    
    /**
     * @param $suffix[required]
     * @param $mime_type[required]
     * @return mixed
     */
    function swoole_mime_type_add($suffix, $mime_type) {}
    
    /**
     * @param $suffix[required]
     * @param $mime_type[required]
     * @return mixed
     */
    function swoole_mime_type_set($suffix, $mime_type) {}
    
    /**
     * @param $suffix[required]
     * @return mixed
     */
    function swoole_mime_type_delete($suffix) {}
    
    /**
     * @param $filename[required]
     * @return mixed
     */
    function swoole_mime_type_get($filename) {}
    
    /**
     * @param $filename[required]
     * @return mixed
     */
    function swoole_get_mime_type($filename) {}
    
    /**
     * @param $filename[required]
     * @return mixed
     */
    function swoole_mime_type_exists($filename) {}
    
    /**
     * @return mixed
     */
    function swoole_mime_type_list() {}
    
    /**
     * @return mixed
     */
    function swoole_clear_dns_cache() {}
    
    /**
     * @param $str[required]
     * @param $offset[required]
     * @param $length[optional]
     * @param $options[optional]
     * @return mixed
     */
    function swoole_substr_unserialize($str, $offset, $length = null, $options = null) {}
    
    /**
     * @param $json[required]
     * @param $offset[required]
     * @param $length[optional]
     * @param $associative[optional]
     * @param $depth[optional]
     * @param $flags[optional]
     * @return mixed
     */
    function swoole_substr_json_decode($json, $offset, $length = null, $associative = null, $depth = null, $flags = null) {}
    
    /**
     * @return mixed
     */
    function swoole_internal_call_user_shutdown_begin() {}
    
    /**
     * Get all PHP objects of current call stack.
     *
     * @return array|false Return an array of objects back; return FALSE when no objects exist or when error happens.
     * @since 4.8.1
     */
    function swoole_get_objects() {}
    
    /**
     * Get status information of current call stack.
     *
     * @return array The array contains two fields: "object_num" (# of objects) and "resource_num" (# of resources).
     * @since 4.8.1
     */
    function swoole_get_vm_status() {}
    
    /**
     * @return array|false Return the specified object back; return FALSE when no object found or when error happens.
     * @since 4.8.1
     */
    function swoole_get_object_by_handle(int $handle) {}
    
    /**
     * This function is an alias of function swoole_coroutine_create(); it's available only when directive
     * "swoole.use_shortname" is not explicitly turned off.
     *
     * @return int|false
     * @see swoole_coroutine_create()
     */
    function go(callable $func, ...$params) {}
    
    /**
     * Defers the execution of a callback function until the surrounding function of a coroutine returns.
     *
     * This function is an alias of function swoole_coroutine_defer(); it's available only when directive
     * "swoole.use_shortname" is not explicitly turned off.
     *
     * @return void
     * @see swoole_coroutine_defer()
     *
     * @example
     * 
     * go(function () {      // The surrounding function of a coroutine.
     *   echo '1';
     *   defer(function () { // The callback function to be deferred.
     *     echo '3';
     *   });
     *   echo '2';
     * });
     * 
     */
    function defer(callable $callback) {}
    
    /**
     * @param $fd[required]
     * @param $read_callback[required]
     * @param $write_callback[optional]
     * @param $events[optional]
     * @return mixed
     */
    function swoole_event_add($fd, $read_callback, $write_callback = null, $events = null) {}
    
    /**
     * @param $fd[required]
     * @return mixed
     */
    function swoole_event_del($fd) {}
    
    /**
     * @param $fd[required]
     * @param $read_callback[optional]
     * @param $write_callback[optional]
     * @param $events[optional]
     * @return mixed
     */
    function swoole_event_set($fd, $read_callback = null, $write_callback = null, $events = null) {}
    
    /**
     * @param $fd[required]
     * @param $events[optional]
     * @return mixed
     */
    function swoole_event_isset($fd, $events = null) {}
    
    /**
     * @return mixed
     */
    function swoole_event_dispatch() {}
    
    /**
     * This function is an alias of method \Swoole\Event::defer().
     *
     * @return true
     * @see \Swoole\Event::defer()
     */
    function swoole_event_defer(callable $callback) {}
    
    /**
     * @param $callback[required]
     * @param $before[optional]
     * @return mixed
     */
    function swoole_event_cycle($callback, $before = null) {}
    
    /**
     * @param $fd[required]
     * @param $data[required]
     * @return mixed
     */
    function swoole_event_write($fd, $data) {}
    
    /**
     * @return mixed
     */
    function swoole_event_wait() {}
    
    /**
     * @return mixed
     */
    function swoole_event_exit() {}
    
    /**
     * This function is an alias of method \Swoole\Timer::set().
     *
     * @return void
     * @see \Swoole\Timer::set()
     */
    function swoole_timer_set(array $settings) {}
    
    /**
     * This function is an alias of method \Swoole\Timer::after().
     *
     * @return int
     * @see \Swoole\Timer::after()
     */
    function swoole_timer_after(int $ms, callable $callback, ...$params) {}
    
    /**
     * This function is an alias of method \Swoole\Timer::tick().
     *
     * @return int
     * @see \Swoole\Timer::tick()
     */
    function swoole_timer_tick(int $ms, callable $callback, ...$params) {}
    
    /**
     * This function is an alias of method \Swoole\Timer::exists().
     *
     * @return bool
     * @see \Swoole\Timer::exists()
     */
    function swoole_timer_exists(int $timer_id) {}
    
    /**
     * This function is an alias of method \Swoole\Timer::info().
     *
     * @return array
     * @see \Swoole\Timer::info()
     */
    function swoole_timer_info(int $timer_id) {}
    
    /**
     * This function is an alias of method \Swoole\Timer::stats().
     *
     * @return array
     * @see \Swoole\Timer::stats()
     */
    function swoole_timer_stats() {}
    
    /**
     * This function is an alias of method \Swoole\Timer::list().
     *
     * @return \Swoole\timer\Iterator
     * @see \Swoole\Timer::list()
     */
    function swoole_timer_list() {}
    
    /**
     * This function is an alias of method \Swoole\Timer::clear().
     *
     * @return bool
     * @see \Swoole\Timer::clear()
     */
    function swoole_timer_clear(int $timer_id) {}
    
    /**
     * This function is an alias of method \Swoole\Timer::clearAll().
     *
     * @return bool
     * @see \Swoole\Timer::clearAll()
     */
    function swoole_timer_clear_all() {}
    
     * The tested string.
     * 

    * @return bool TRUE if every character in text is either * a letter or a digit, FALSE otherwise. */ #[Pure] function ctype_alnum(#[LanguageLevelTypeAware(['8.1' => 'string'], default: 'mixed')] mixed $text): bool {} /** * Check for alphabetic character(s) * @link https://php.net/manual/en/function.ctype-alpha.php * @param string $text

    * The tested string. *

    * @return bool TRUE if every character in text is * a letter from the current locale, FALSE otherwise. */ #[Pure] function ctype_alpha(#[LanguageLevelTypeAware(['8.1' => 'string'], default: 'mixed')] mixed $text): bool {} /** * Check for control character(s) * @link https://php.net/manual/en/function.ctype-cntrl.php * @param string $text

    * The tested string. *

    * @return bool TRUE if every character in text is * a control character from the current locale, FALSE otherwise. */ #[Pure] function ctype_cntrl(#[LanguageLevelTypeAware(['8.1' => 'string'], default: 'mixed')] mixed $text): bool {} /** * Check for numeric character(s) * @link https://php.net/manual/en/function.ctype-digit.php * @param string $text

    * The tested string. *

    * @return bool TRUE if every character in the string * text is a decimal digit, FALSE otherwise. */ #[Pure] function ctype_digit(#[LanguageLevelTypeAware(['8.1' => 'string'], default: 'mixed')] mixed $text): bool {} /** * Check for lowercase character(s) * @link https://php.net/manual/en/function.ctype-lower.php * @param string $text

    * The tested string. *

    * @return bool TRUE if every character in text is * a lowercase letter in the current locale. */ #[Pure] function ctype_lower(#[LanguageLevelTypeAware(['8.1' => 'string'], default: 'mixed')] mixed $text): bool {} /** * Check for any printable character(s) except space * @link https://php.net/manual/en/function.ctype-graph.php * @param string $text

    * The tested string. *

    * @return bool TRUE if every character in text is * printable and actually creates visible output (no white space), FALSE * otherwise. */ #[Pure] function ctype_graph(#[LanguageLevelTypeAware(['8.1' => 'string'], default: 'mixed')] mixed $text): bool {} /** * Check for printable character(s) * @link https://php.net/manual/en/function.ctype-print.php * @param string $text

    * The tested string. *

    * @return bool TRUE if every character in text * will actually create output (including blanks). Returns FALSE if * text contains control characters or characters * that do not have any output or control function at all. */ #[Pure] function ctype_print(#[LanguageLevelTypeAware(['8.1' => 'string'], default: 'mixed')] mixed $text): bool {} /** * Check for any printable character which is not whitespace or an * alphanumeric character * @link https://php.net/manual/en/function.ctype-punct.php * @param string $text

    * The tested string. *

    * @return bool TRUE if every character in text * is printable, but neither letter, digit or blank, FALSE otherwise. */ #[Pure] function ctype_punct(#[LanguageLevelTypeAware(['8.1' => 'string'], default: 'mixed')] mixed $text): bool {} /** * Check for whitespace character(s) * @link https://php.net/manual/en/function.ctype-space.php * @param string $text

    * The tested string. *

    * @return bool TRUE if every character in text * creates some sort of white space, FALSE otherwise. Besides the * blank character this also includes tab, vertical tab, line feed, * carriage return and form feed characters. */ #[Pure] function ctype_space(#[LanguageLevelTypeAware(['8.1' => 'string'], default: 'mixed')] mixed $text): bool {} /** * Check for uppercase character(s) * @link https://php.net/manual/en/function.ctype-upper.php * @param string $text

    * The tested string. *

    * @return bool TRUE if every character in text is * an uppercase letter in the current locale. */ #[Pure] function ctype_upper(#[LanguageLevelTypeAware(['8.1' => 'string'], default: 'mixed')] mixed $text): bool {} /** * Check for character(s) representing a hexadecimal digit * @link https://php.net/manual/en/function.ctype-xdigit.php * @param string $text

    * The tested string. *

    * @return bool TRUE if every character in text is * a hexadecimal 'digit', that is a decimal digit or a character from * [A-Fa-f] , FALSE otherwise. */ #[Pure] function ctype_xdigit(#[LanguageLevelTypeAware(['8.1' => 'string'], default: 'mixed')] mixed $text): bool {} Used to specify if {@link sqlsrv_errors() sqlsrv_errors} returns errors, warnings, or both.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_ERR_ERRORS', 0); /** * Warnings generated on the last sqlsrv function call are returned. * *
    Used to specify if {@link sqlsrv_errors() sqlsrv_errors} returns errors, warnings, or both.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_ERR_WARNINGS', 1); /** * Errors and warnings generated on the last sqlsrv function call are returned. * *
    This is the default value.
    * * Used to specify if {@link sqlsrv_errors() sqlsrv_errors} returns errors, warnings, or both.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_ERR_ALL', 2); /** * Turns on logging of all subsystems. * *
    Used as the value for the LogSubsystems setting with * {@link sqlsrv_configure() sqlsrv_configure}.
    * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_LOG_SYSTEM_ALL', -1); /** * Turns logging off. * *
    Used as the value for the LogSubsystems setting with {@link sqlsrv_configure() sqlsrv_configure}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_LOG_SYSTEM_OFF', 0); /** * Turns on logging of initialization activity. * *
    Used as the value for the LogSubsystems setting with {@link sqlsrv_configure() sqlsrv_configure}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_LOG_SYSTEM_INIT', 1); /** * Turns on logging of connection activity. * *
    Used as the value for the LogSubsystems setting with {@link sqlsrv_configure() sqlsrv_configure}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_LOG_SYSTEM_CONN', 2); /** * Turns on logging of statement activity. * *
    Used as the value for the LogSubsystems setting with {@link sqlsrv_configure() sqlsrv_configure}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_LOG_SYSTEM_STMT', 4); /** * Turns on logging of error functions activity (such as handle_error and handle_warning). * *
    Used as the value for the * LogSubsystems setting with {@link sqlsrv_configure() sqlsrv_configure}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_LOG_SYSTEM_UTIL', 8); /** * Specifies that errors, warnings, and notices will be logged. * *
    Used as the value for the LogSeverity setting with {@link sqlsrv_configure() sqlsrv_configure}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_LOG_SEVERITY_ALL', -1); /** * Specifies that errors will be logged. * *
    Used as the value for the LogSeverity setting with {@link sqlsrv_configure() sqlsrv_configure}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_LOG_SEVERITY_ERROR', 1); /** * Specifies that notices will be logged. * *
    Used as the value for the LogSeverity setting with {@link sqlsrv_configure() sqlsrv_configure}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_LOG_SEVERITY_NOTICE', 4); /** * Specifies that warnings will be logged. * *
    Used as the value for the LogSeverity setting with {@link sqlsrv_configure() sqlsrv_configure}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_LOG_SEVERITY_WARNING', 2); /** * Returns numerically indexed array. * *
    {@link sqlsrv_fetch_array() sqlsrv_fetch_array} returns the next row of data as a numerically indexed array.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_FETCH_NUMERIC', 1); /** * Returns an associative array. * *
    {@link sqlsrv_fetch_array() sqlsrv_fetch_array} returns the next row of data as an associative array.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_FETCH_ASSOC', 2); /** * Returns both a numeric and associative array. * *
    {@link sqlsrv_fetch_array() sqlsrv_fetch_array} returns the next row of data as an array with both numeric and * associative keys.
    * * This is the default value.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_FETCH_BOTH', 3); /** * Null * *
    Used with {@link sqlsrv_prepare() sqlsrv_prepare}, * {@link sqlsrv_query() sqlsrv_query} * and {@link sqlsrv_get_field() sqlsrv_get_field} to request a field be return as a specific PHP type.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_PHPTYPE_NULL', 1); /** * Integer * *
    Used with {@link sqlsrv_prepare() sqlsrv_prepare}, * {@link sqlsrv_query() sqlsrv_query} * and {@link sqlsrv_get_field() sqlsrv_get_field} to request a field be return as a specific PHP type.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_PHPTYPE_INT', 2); /** * Float * *
    Used with {@link sqlsrv_prepare() sqlsrv_prepare}, * {@link sqlsrv_query() sqlsrv_query} * and {@link sqlsrv_get_field() sqlsrv_get_field} to request a field be return as a specific PHP type.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_PHPTYPE_FLOAT', 3); /** * Datetime * *
    Used with {@link sqlsrv_prepare() sqlsrv_prepare}, * {@link sqlsrv_query() sqlsrv_query} * and {@link sqlsrv_get_field() sqlsrv_get_field} to request a field be return as a specific PHP type.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_PHPTYPE_DATETIME', 4); /** * Binary Encoding * *
    Data is returned as a raw byte stream from the server without performing encoding or translation.
    * * Used with {@link sqlsrv_prepare() sqlsrv_prepare}, * {@link sqlsrv_query() sqlsrv_query} * and {@link sqlsrv_get_field() sqlsrv_get_field} to request a field be return as a specific PHP type.
    * * This is used with {@link SQLSRV_PHPTYPE_STREAM() SQLSRV_PHPTYPE_STREAM} and * {@link SQLSRV_PHPTYPE_STRING() SQLSRV_PHPTYPE_STRING} to specify the encoding of those PHP types types.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_ENC_BINARY', 'binary'); /** * Character Encoding * *
    Data is returned in 8-bit characters as specified in the code page of the Windows locale that is set on the * system. Any multi-byte characters or characters that do not map into this code page are substituted with a single * byte question mark (?) character.
    * * This is the default encoding.
    * * Used with {@link sqlsrv_prepare() sqlsrv_prepare}, * {@link sqlsrv_query() sqlsrv_query} * and {@link sqlsrv_get_field() sqlsrv_get_field} to request a field be return as a specific PHP type.
    * * This is used with {@link SQLSRV_PHPTYPE_STREAM() SQLSRV_PHPTYPE_STREAM} and * {@link SQLSRV_PHPTYPE_STRING() SQLSRV_PHPTYPE_STRING} to specify the encoding of those PHP types types.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_ENC_CHAR', 'char'); /** * The column is not nullable. * *
    You can compare the value of the Nullable key that is returned by * {@link sqlsrv_field_metadata() sqlsrv_field_metadata} to determine the column's nullable status.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_NULLABLE_NO', 0); /** * The column is nullable. * *
    You can compare the value of the Nullable key that is returned by * {@link sqlsrv_field_metadata() sqlsrv_field_metadata} to determine the column's nullable status.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_NULLABLE_YES', 1); /** * It is not known if the column is nullable. * *
    You can compare the value of the Nullable key that is returned by * {@link sqlsrv_field_metadata() sqlsrv_field_metadata} to determine the column's nullable status.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_NULLABLE_UNKNOWN', 2); /** * bigint. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_BIGINT', -5); /** * bit. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_BIT', -7); /** * char. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_CHAR', 1); /** * datetime. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_DATETIME', 25177693); /** * decimal. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_DECIMAL', 3); /** * float. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_FLOAT', 6); /** * image. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_IMAGE', -4); /** * int. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_INT', 4); /** * money. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_MONEY', 33564163); /** * nchar. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_NCHAR', -8); /** * ntext. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_NTEXT', -10); /** * numeric. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_NUMERIC', 2); /** * nvarchar. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_NVARCHAR', -9); /** * text. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_TEXT', -1); /** * real. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_REAL', 7); /** * smalldatetime. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_SMALLDATETIME', 8285); /** * smallint. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_SMALLINT', 5); /** * smallmoney. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_SMALLMONEY', 33559555); /** * timestamp. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_TIMESTAMP', 4606); /** * tinyint. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_TINYINT', -6); /** * udt. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_UDT', -151); /** * uniqueidentifier. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_UNIQUEIDENTIFIER', -11); /** * varbinary. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_VARBINARY', -3); /** * varchar. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_VARCHAR', 12); /** * xml. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_XML', -152); /** * date. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_DATE', 5211); /** * time. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_TIME', 58728806); /** * datetimeoffset. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_DATETIMEOFFSET', 58738021); /** * datetime2. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the SQL Server data type of a parameter.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SQLTYPE_DATETIME2', 58734173); /** * Indicates an input parameter. * *
    Used for specifying parameter direction when you call {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_PARAM_IN', 1); /** * Indicates a bidirectional parameter. * *
    Used for specifying parameter direction when you call {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_PARAM_INOUT', 2); /** * Indicates an output parameter. * *
    Used for specifying parameter direction when you call {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_PARAM_OUT', 4); /** * Read Uncommitted. * *
    Specifies that statements can read rows that have been modified by other transactions but not yet committed.
    * * Transactions running at the READ UNCOMMITTED level do not issue shared locks to prevent other transactions from * modifying data read by the current transaction. READ UNCOMMITTED transactions are also not blocked by exclusive locks * that would prevent the current transaction from reading rows that have been modified but not committed by other * transactions. When this option is set, it is possible to read uncommitted modifications, which are called dirty reads. * Values in the data can be changed and rows can appear or disappear in the data set before the end of the transaction. * This option has the same effect as setting NOLOCK on all tables in all SELECT statements in a transaction. This is * the least restrictive of the isolation levels.
    * * Used with the TransactionIsolation key when calling {@link sqlsrv_connect() sqlsrv_connect}. For information on using * these constants, see {@link http://msdn.microsoft.com/en-us/library/ms173763(v=sql.110).aspx SET TRANSACTION ISOLATION LEVEL (Transact-SQL)}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_TXN_READ_UNCOMMITTED', 1); /** * Read Committed. * *
    Specifies that statements cannot read data that has been modified but not committed by other transactions. * This prevents dirty reads. Data can be changed by other transactions between individual statements within the current * transaction, resulting in nonrepeatable reads or phantom data. This option is the SQL Server default.
    * * The behavior of READ COMMITTED depends on the setting of the READ_COMMITTED_SNAPSHOT database option.
    * * Used with the TransactionIsolation key when calling {@link sqlsrv_connect() sqlsrv_connect}. For information on using * these constants, see {@link http://msdn.microsoft.com/en-us/library/ms173763(v=sql.110).aspx SET TRANSACTION ISOLATION LEVEL (Transact-SQL)}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_TXN_READ_COMMITTED', 2); /** * Repeatable Read. * *
    Specifies that statements cannot read data that has been modified but not yet committed by other transactions and * that no other transactions can modify data that has been read by the current transaction until the current transaction * completes.
    * * Shared locks are placed on all data read by each statement in the transaction and are held until the transaction * completes. This prevents other transactions from modifying any rows that have been read by the current transaction. * Other transactions can insert new rows that match the search conditions of statements issued by the current transaction. * If the current transaction then retries the statement it will retrieve the new rows, which results in phantom reads. * Because shared locks are held to the end of a transaction instead of being released at the end of each statement, * concurrency is lower than the default READ COMMITTED isolation level.
    * * Use this option only when necessary.
    * * Used with the TransactionIsolation key when calling {@link sqlsrv_connect() sqlsrv_connect}. For information on using * these constants, see {@link http://msdn.microsoft.com/en-us/library/ms173763(v=sql.110).aspx SET TRANSACTION ISOLATION LEVEL (Transact-SQL)}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_TXN_REPEATABLE_READ', 4); /** * Serializable. * *
    Specifies the following: *
    • Statements cannot read data that has been modified but not yet committed by other transactions.
    • *
    • No other transactions can modify data that has been read by the current transaction until the current * transaction completes.
    • *
    • Other transactions cannot insert new rows with key values that would fall in the range of keys read by any * statements in the current transaction until the current transaction completes.
    * * Range locks are placed in the range of key values that match the search conditions of each statement executed in a * transaction. This blocks other transactions from updating or inserting any rows that would qualify for any of the * statements executed by the current transaction. This means that if any of the statements in a transaction are * executed a second time, they will read the same set of rows. The range locks are held until the transaction completes. * This is the most restrictive of the isolation levels because it locks entire ranges of keys and holds the locks until * the transaction completes. Because concurrency is lower, use this option only when necessary. This option has the same * effect as setting HOLDLOCK on all tables in all SELECT statements in a transaction.
    * * Used with the TransactionIsolation key when calling {@link sqlsrv_connect() sqlsrv_connect}. For information on using * these constants, see {@link http://msdn.microsoft.com/en-us/library/ms173763(v=sql.110).aspx SET TRANSACTION ISOLATION LEVEL (Transact-SQL)}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_TXN_SERIALIZABLE', 8); /** * Snapshot. * *
    Specifies that data read by any statement in a transaction will be the transactionally consistent version of * the data that existed at the start of the transaction. The transaction can only recognize data modifications that * were committed before the start of the transaction. Data modifications made by other transactions after the start of * the current transaction are not visible to statements executing in the current transaction. The effect is as if the * statements in a transaction get a snapshot of the committed data as it existed at the start of the transaction.
    * * Except when a database is being recovered, SNAPSHOT transactions do not request locks when reading data. SNAPSHOT * transactions reading data do not block other transactions from writing data. Transactions writing data do not block * SNAPSHOT transactions from reading data.
    * * During the roll-back phase of a database recovery, SNAPSHOT transactions will request a lock if an attempt is made to * read data that is locked by another transaction that is being rolled back. The SNAPSHOT transaction is blocked until * that transaction has been rolled back. The lock is released immediately after it has been granted.
    * * The ALLOW_SNAPSHOT_ISOLATION database option must be set to ON before you can start a transaction that uses the * SNAPSHOT isolation level. If a transaction using the SNAPSHOT isolation level accesses data in multiple databases, * ALLOW_SNAPSHOT_ISOLATION must be set to ON in each database.
    * * A transaction cannot be set to SNAPSHOT isolation level that started with another isolation level; doing so will * cause the transaction to abort. If a transaction starts in the SNAPSHOT isolation level, you can change it to another * isolation level and then back to SNAPSHOT. A transaction starts the first time it accesses data.
    * * A transaction running under SNAPSHOT isolation level can view changes made by that transaction. For example, if the * transaction performs an UPDATE on a table and then issues a SELECT statement against the same table, the modified * data will be included in the result set.
    * * Used with the TransactionIsolation key when calling {@link sqlsrv_connect() sqlsrv_connect}. For information on using * these constants, see {@link http://msdn.microsoft.com/en-us/library/ms173763(v=sql.110).aspx SET TRANSACTION ISOLATION LEVEL (Transact-SQL)}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_TXN_SNAPSHOT', 32); /** * Specifies the next row. * *
    This is the default value, if you do not specify the row parameter for a scrollable result set.
    * * Used with {@link sqlsrv_fetch() sqlsrv_fetch}, * {@link sqlsrv_fetch_array() sqlsrv_fetch_array}, * or {@link sqlsrv_fetch_object() sqlsrv_fetch_object} to specify a row.
    * * Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify which row to select in the result set. For * information on using these constants, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SCROLL_NEXT', 1); /** * Specifies the row before the current row. * *
    Used with {@link sqlsrv_fetch() sqlsrv_fetch}, * {@link sqlsrv_fetch_array() sqlsrv_fetch_array}, * or {@link sqlsrv_fetch_object() sqlsrv_fetch_object} to specify a row.
    * * Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify which row to select in the result set. For * information on using these constants, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SCROLL_PRIOR', 4); /** * Specifies the first row in the result set. * *
    Used with {@link sqlsrv_fetch() sqlsrv_fetch}, * {@link sqlsrv_fetch_array() sqlsrv_fetch_array}, * or {@link sqlsrv_fetch_object() sqlsrv_fetch_object} to specify a row.
    * * Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify which row to select in the result set. For * information on using these constants, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SCROLL_FIRST', 2); /** * Specifies the last row in the result set. * *
    Used with {@link sqlsrv_fetch() sqlsrv_fetch}, * {@link sqlsrv_fetch_array() sqlsrv_fetch_array}, * or {@link sqlsrv_fetch_object() sqlsrv_fetch_object} to specify a row.
    * * Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify which row to select in the result set. For * information on using these constants, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SCROLL_LAST', 3); /** * Specifies the row specified with the offset parameter. * *
    Used with {@link sqlsrv_fetch() sqlsrv_fetch}, * {@link sqlsrv_fetch_array() sqlsrv_fetch_array}, * or {@link sqlsrv_fetch_object() sqlsrv_fetch_object} to specify a row.
    * * Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify which row to select in the result set. For * information on using these constants, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SCROLL_ABSOLUTE', 5); /** * Specifies the row specified with the offset parameter from the current row. * *
    Used with {@link sqlsrv_fetch() sqlsrv_fetch}, * {@link sqlsrv_fetch_array() sqlsrv_fetch_array}, * or {@link sqlsrv_fetch_object() sqlsrv_fetch_object} to specify a row.
    * * Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify which row to select in the result set. For * information on using these constants, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_SCROLL_RELATIVE', 6); /** * Lets you move one row at a time starting at the first row of the result set until you reach the end of * the result set. * *
    This is the default cursor type.
    * * {@link sqlsrv_num_rows() sqlsrv_num_rows} returns an error for result sets created with this cursor type.
    * * Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the kind of cursor that you can use in a result * set. For information on using these constants, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_CURSOR_FORWARD', 'forward'); /** * Lets you access rows in any order but will not reflect changes in the database. * *
    Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the kind of cursor that you can use in a result * set. For information on using these constants, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_CURSOR_STATIC', 'static'); /** * Lets you access rows in any order and will reflect changes in the database. * *
    {@link sqlsrv_num_rows() sqlsrv_num_rows} returns an error for result sets created with this cursor type.
    * * Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the kind of cursor that you can use in a result * set. For information on using these constants, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_CURSOR_DYNAMIC', 'dynamic'); /** * Lets you access rows in any order. * *
    However, a keyset cursor does not update the row count if a row is deleted from the table (a deleted row is * returned with no values).
    * * Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the kind of cursor that you can use in a result * set. For information on using these constants, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_CURSOR_KEYSET', 'keyset'); /** * Lets you access rows in any order. * *
    Creates a client-side cursor query.
    * * Used when calling {@link sqlsrv_query() sqlsrv_query} or *{@link sqlsrv_prepare() sqlsrv_prepare} to specify the kind of cursor that you can use in a result * set. For information on using these constants, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server */ define('SQLSRV_CURSOR_CLIENT_BUFFERED', 'buffered'); /** * Creates and opens a connection. * *
    Creates a connection resource and opens a connection. By default, the connection is attempted using Windows * Authentication.
    * * If values for the UID and PWD keys are not specified in the optional $connectionInfo parameter, the connection will * be attempted using Windows Authentication. For more information about connecting to the server, * see {@link http://msdn.microsoft.com/en-us/library/cc296205.aspx How to: Connect Using Windows Authentication} * and {@link http://msdn.microsoft.com/en-us/library/cc296182.aspx How to: Connect Using SQL Server Authentication.}
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-connect * @param string $server_name A string specifying the name of the server to which a connection is being established. * An instance name (for example, "myServer\instanceName") or port number (for example, "myServer, 1521") can be * included as part of this string. For a complete description of the options available for this parameter, see the * Server keyword in the ODBC Driver Connection String Keywords section * of {@link http://go.microsoft.com/fwlink/?LinkId=105504 Using Connection String Keywords with SQL Native Client}.
    * * Beginning in version 3.0 of the Microsoft Drivers for PHP for SQL Server, you can also specify a LocalDB instance * with "(localdb)\instancename". For more information, * see {@link http://msdn.microsoft.com/en-us/library/hh487161.aspx PHP Driver for SQL Server Support for LocalDB} .
    * * Also beginning in version 3.0 of the Microsoft Drivers for PHP for SQL Server, you can specify a virtual network name, * to connect to an AlwaysOn availability group. For more information about Microsoft Drivers for PHP for SQL Server * support for AlwaysOn Availability Groups, * see {@link http://msdn.microsoft.com/en-us/library/hh487159.aspx PHP Driver for SQL Server Support for High Availability, Disaster Recovery}. * @param array $connection_info [optional] An associative array that contains connection attributes (for example, array("Database" => "AdventureWorks")). * See {@link http://msdn.microsoft.com/en-us/library/ff628167.aspx Connection Options} for a list of the supported keys for the array. * @return resource|false A PHP connection resource. If a connection cannot be successfully created and opened, false is returned. */ function sqlsrv_connect($server_name, $connection_info = []) {} /** * Closes a connection. Frees all resources associated with the connection. * *
    Null is a valid parameter for this function. This allows the function to be called multiple times in a script. For * example, if you close a connection in an error condition and close it again at the end of the script, the second call * to sqlsrv_close will return true because the first call to sqlsrv_close (in the error condition) sets the connection * resource to null.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-close * @param resource|null $conn The connection to be closed. * @return bool The Boolean value true unless the function is called with an invalid parameter. If the function is called with an invalid parameter, false is returned. */ function sqlsrv_close($conn) {} /** * Commits a transaction that was begun with sqlsrv_begin_transaction. * *
    Commits the current transaction on the specified connection and returns the connection to the auto-commit mode. * The current transaction includes all statements on the specified connection that were executed after the call to * sqlsrv_begin_transaction and before any calls to sqlsrv_rollback or sqlsrv_commit.
    * * The Microsoft Drivers for PHP for SQL Server is in auto-commit mode by default. This means that all queries are * automatically committed upon success unless they have been designated as part of an explicit transaction by using * sqlsrv_begin_transaction.
    * * If sqlsrv_commit is called on a connection that is not in an active transaction and that was initiated with * sqlsrv_begin_transaction, the call returns false and a Not in Transaction error is added to the error collection.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-commit * @param resource $conn The connection on which the transaction is active. * @return bool A Boolean value: true if the transaction was successfully committed. Otherwise, false. */ function sqlsrv_commit($conn) {} /** * Begins a database transaction. * *
    Begins a transaction on a specified connection. The current transaction includes all statements on the specified * connection that were executed after the call to sqlsrv_begin_transaction and before any calls to sqlsrv_rollback or * sqlsrv_commit.
    * * The Microsoft Drivers for PHP for SQL Server is in auto-commit mode by default. This means that all queries are * automatically committed upon success unless they have been designated as part of an explicit transaction by using * sqlsrv_begin_transaction.
    * * If sqlsrv_begin_transaction is called after a transaction has already been initiated on the connection but not * completed by calling either sqlsrv_commit or sqlsrv_rollback, the call returns false and an Already in Transaction * error is added to the error collection.
    * * Do not use embedded Transact-SQL to perform transactions. For example, do not execute a statement with * "BEGIN TRANSACTION" as the Transact-SQL query to begin a transaction. The expected transactional behavior cannot be * guaranteed when using embedded Transact-SQL to perform transactions.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296206.aspx How to Perform Transactions} * and {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-begin-transaction * @param resource $conn The connection with which the transaction is associated. * @return bool A Boolean value: true if the transaction was successfully begun. Otherwise, false. */ function sqlsrv_begin_transaction($conn) {} /** * Rolls back a transaction that was begun with {@see sqlsrv_begin_transaction}. * *
    Rolls back the current transaction on the specified connection and returns the connection to the auto-commit mode. * The current transaction includes all statements on the specified connection that were executed after the call to * sqlsrv_begin_transaction and before any calls to {@link sqlsrv_rollback() sqlsrv_rollback} or * {@link sqlsrv_commit() sqlsrv_commit}.
    * * The Microsoft Drivers for PHP for SQL Server is in auto-commit mode by default. This means that all queries are * automatically committed upon success unless they have been designated as part of an explicit transaction by using * {@link sqlsrv_begin_transaction() sqlsrv_begin_transaction}.
    * * If sqlsrv_rollback is called on a connection that is not in an active transaction that was initiated with * {@link sqlsrv_begin_transaction() sqlsrv_begin_transaction}, the call returns false and a Not in Transaction error * is added to the error collection.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296206.aspx How to Perform Transactions} * and {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-rollback * @param resource $conn The connection on which the transaction is active. * @return bool A Boolean value: true if the transaction was successfully rolled back. Otherwise, false. */ function sqlsrv_rollback($conn) {} /** * Returns error and/or warning information about the last operation. * *
    Returns extended error and/or warning information about the last sqlsrv operation performed.
    * * The sqlsrv_errors function can return error and/or warning information by calling it with one of the parameter values * specified in the Parameters section below.
    * * By default, warnings generated on a call to any sqlsrv function are treated as errors; if a warning occurs on a call * to a sqlsrv function, the function returns false. However, warnings that correspond to SQLSTATE values 01000, 01001, * 01003, and 01S02 are never treated as errors.
    * * The following line of code turns off the behavior mentioned above; a warning generated by a call to a sqlsrv function * does not cause the function to return false:
    * * {@link sqlsrv_configure() sqlsrv_configure}("WarningsReturnAsErrors", 0); * * The following line of code reinstates the default behavior; warnings (with exceptions, noted above) are treated as * errors:
    * * {@link sqlsrv_configure() sqlsrv_configure}("WarningsReturnAsErrors", 1); * * Regardless of the setting, warnings can only be retrieved by calling sqlsrv_errors with either the SQLSRV_ERR_ALL or * SQLSRV_ERR_WARNINGS parameter value (see Parameters section below for details).
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-errors * @param int $errorsAndOrWarnings [optional] A predefined constant. This parameter can take one of the values in the * following list: SQLSRV_ERR_ALL, SQLSRV_ERR_ERRORS, SQLSRV_ERR_WARNINGS. If no parameter value is supplied, both * errors and warnings generated by the last sqlsrv function call are returned. * @return array|null An array of arrays, or null. Each array in the returned array contains three key-value pairs. The * following table lists each key and its description:
    * SQLSTATE: *
      *
    • For errors that originate from the ODBC driver, the SQLSTATE returned by ODBC.For information about SQLSTATE * values for ODBC, see {@link http://go.microsoft.com/fwlink/?linkid=119618 ODBC Error Codes}.
    • *
    • For errors that originate from the Microsoft Drivers for PHP for SQL Server, a SQLSTATE of IMSSP.
    • *
    • For warnings that originate from the Microsoft Drivers for PHP for SQL Server, a SQLSTATE of 01SSP.
    • *
    * code: *
      *
    • For errors that originate from SQL Server, the native SQL Server error code.
    • *
    • For errors that originate from the ODBC driver, the error code returned by ODBC.
    • *
    • For errors that originate from the Microsoft Drivers for PHP for SQL Server, the Microsoft Drivers for PHP for SQL Server error code. For more information, see {@link http://msdn.microsoft.com/en-us/library/cc626302.aspx Handling Errors and Warnings}.
    • *
    * message: A description of the error.
    * * The array values can also be accessed with numeric keys 0, 1, and 2.

    * * If no errors or warnings occur, null is returned.
    */ function sqlsrv_errors($errorsAndOrWarnings = SQLSRV_ERR_ALL) {} /** * Changes the driver error handling and logging configurations. * *
    Changes the settings for error handling and logging options.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-configure * @param string $setting The name of the setting to be configured. See table below for list of settings. * @param mixed $value The value to be applied to the setting specified in the $setting parameter. The possible values for this parameter depend on which setting is specified. The following table lists the possible combinations.
    * ClientBufferMaxKBSize (Default: 10240)
    * For more information about client-side queries, see {@link http://msdn.microsoft.com/en-us/library/hh487160.aspx Cursor Types (SQLSRV Driver)}. *
      *
    • A non negative number up to the PHP memory limit.
    • *
    • Zero (0) means no limit to the buffer size.
    • *
    * LogSeverity (Default: SQLSRV_LOG_SEVERITY_ERROR )
    * For more information about logging activity, see {@link http://msdn.microsoft.com/en-us/library/cc296188.aspx Logging Activity}. *
    • SQLSRV_LOG_SEVERITY_ALL (-1)
    • *
    • SQLSRV_LOG_SEVERITY_ERROR (1)
    • *
    • SQLSRV_LOG_SEVERITY_NOTICE (4)
    • *
    • SQLSRV_LOG_SEVERITY_WARNING (2)
    * WarningsReturnAsErrors (Default: true )
    * For more information about configuring error and warning handling, see {@link http://msdn.microsoft.com/en-us/library/cc626306.aspx How to: Configure Error and Warning Handling Using the SQLSRV Driver}. *
    • true (1)
    • *
    • false (0)
    * @return bool If sqlsrv_configure is called with an unsupported setting or value, the function returns false. Otherwise, the function returns true. */ function sqlsrv_configure($setting, $value) {} /** * Returns the current value of the specified configuration setting. * *
    If false is returned by sqlsrv_get_config, you must call {@link sqlsrv_errors() sqlsrv_errors} to determine if an error occurred or * if false is the value of the setting specified by the $setting parameter.
    * * For a list of configurable settings, see {@link sqlsrv_configure() sqlsrv_configure}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-get-config * @param string $setting The configuration setting for which the value is returned. * @return mixed|false The value of the setting specified by the $setting parameter. If an invalid setting is specified, false is returned and an error is added to the error collection. */ function sqlsrv_get_config($setting) {} /** * Prepares a Transact-SQL query without executing it. Implicitly binds parameters. * *
    Creates a statement resource associated with the specified connection. This function is useful for execution of * multiple queries.
    * * Variables passed as query parameters should be passed by reference instead of by value. For example, pass * &$myVariable instead of $myVariable. A PHP warning will be raised when a query with by-value parameters is * executed.
    * * When you prepare a statement that uses variables as parameters, the variables are bound to the statement. That means * that if you update the values of the variables, the next time you execute the statement it will run with updated * parameter values.
    * * The combination of sqlsrv_prepare and {@link sqlsrv_execute() sqlsrv_execute} separates statement preparation and * statement execution in to two function calls and can be used to execute parameterized queries. This function is ideal * to execute a statement multiple times with different parameter values for each execution.
    * * For alternative strategies for writing and reading large amounts of information, see * {@link http://go.microsoft.com/fwlink/?LinkId=104225 Batches of SQL Statements} and * {@link http://go.microsoft.com/fwlink/?LinkId=104226 BULK INSERT}.
    * * For more information, see * {@link http://msdn.microsoft.com/en-us/library/cc626303.aspx How to: Retrieve Output Parameters Using the SQLSRV Driver.}
    * * For additional Information see: *
    • {@link http://msdn.microsoft.com/en-us/library/cc644934.aspx Using Directional Parameters}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296202.aspx Updating Data (Microsoft Drivers for PHP for SQL Server)}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296201.aspx How to: Perform Parameterized Queries}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296191.aspx How to: Send Data as a Stream}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-prepare * @param resource $conn The connection resource associated with the created statement. * @param string $tsql The Transact-SQL expression that corresponds to the created statement. * @param array $params [optional]: An array of values that correspond to parameters in a parameterized query. Each * element of the array can be one of the following: a literal value, a reference to a PHP variable, or an array with * the following structure: * array(&$value [, $direction [, $phpType [, $sqlType]]]) * The following table describes these array elements: *
    • &$value - A literal value or a reference to a PHP variable.
    • *
    • $direction[optional] - One of the following SQLSRV_PARAM_* constants used to indicate the parameter direction: * SQLSRV_PARAM_IN, SQLSRV_PARAM_OUT, SQLSRV_PARAM_INOUT. The default value is SQLSRV_PARAM_IN. For more information * about PHP constants, see * {@link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server Constants (Microsoft Drivers for PHP for SQL Server)}.
    • *
    • $phpType[optional] - A SQLSRV_PHPTYPE_* constant that specifies PHP data type of the returned value.
    • *
    • $sqlType[optional] - A SQLSRV_SQLTYPE_* constant that specifies the SQL Server data type of the input value.
    * @param array $options [optional]: An associative array that sets query properties. The table below lists the * supported keys and corresponding values:
    * * QueryTimeout (int) - Sets the query timeout in seconds. By default, the driver will wait indefinitely for results. * Any positive integer value.
    * * SendStreamParamsAtExec (bool) - Configures the driver to send all stream data at execution (true), or to send stream * data in chunks (false). By default, the value is set to true. For more information, see * {@link sqlsrv_send_stream_data() sqlsrv_send_stream_data}.
    * * Scrollable - For more information about these values, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}. *
    • SQLSRV_CURSOR_FORWARD
    • *
    • SQLSRV_CURSOR_STATIC
    • *
    • SQLSRV_CURSOR_DYNAMIC
    • *
    • SQLSRV_CURSOR_KEYSET
    • *
    • SQLSRV_CURSOR_CLIENT_BUFFERED
    * @return resource|false A statement resource. If the statement resource cannot be created, false is returned. */ function sqlsrv_prepare($conn, $tsql, $params = [], $options = []) {} /** * Executes a statement prepared with {@see sqlsrv_prepare} * *
    Executes a previously prepared statement. See {@link sqlsrv_prepare() sqlsrv_prepare} for information on preparing a statement * for execution.
    * * This function is ideal for executing a prepared statement multiple times with different parameter values.
    * * For additional Information see: *
    • {@link sqlsrv_query() sqlsrv_query}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296201.aspx How to: Perform Parameterized Queries}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-execute * @param resource $stmt A resource specifying the statement to be executed. For more information about how to create a * statement resource, see {@link sqlsrv_prepare() sqlsrv_prepare}. * @return bool A Boolean value: true if the statement was successfully executed. Otherwise, false. */ function sqlsrv_execute($stmt) {} /** * Prepares and executes a Transact-SQL query. * *
    Prepares and executes a statement.
    * * The sqlsrv_query function is well-suited for one-time queries and should be the default choice to execute queries * unless special circumstances apply. This function provides a streamlined method to execute a query with a minimum * amount of code. The sqlsrv_query function does both statement preparation and statement execution, and can be used to * execute parameterized queries.
    * * For more information, see * {@link http://msdn.microsoft.com/en-us/library/cc626303.aspx How to: Retrieve Output Parameters Using the SQLSRV Driver.}
    * * For additional Information see: *
    • {@link http://msdn.microsoft.com/en-us/library/cc644934.aspx Using Directional Parameters}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296202.aspx Updating Data (Microsoft Drivers for PHP for SQL Server)}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296201.aspx How to: Perform Parameterized Queries}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296191.aspx How to: Send Data as a Stream}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-query * @param resource $conn The connection resource associated with the prepared statement. * @param string $tsql The Transact-SQL expression that corresponds to the prepared statement. * @param array $params [optional]: An array of values that correspond to parameters in a parameterized query. Each * element of the array can be one of the following: a literal value, a reference to a PHP variable, or an array with * the following structure: * array($value [, $direction [, $phpType [, $sqlType]]]) * The following table describes these array elements: *
    • &$value - A literal value, a PHP variable, or a PHP by-reference variable.
    • *
    • $direction[optional] - One of the following SQLSRV_PARAM_* constants used to indicate the parameter direction: * SQLSRV_PARAM_IN, SQLSRV_PARAM_OUT, SQLSRV_PARAM_INOUT. The default value is SQLSRV_PARAM_IN. For more information * about PHP constants, see * {@link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server Constants (Microsoft Drivers for PHP for SQL Server)}.
    • *
    • $phpType[optional] - A SQLSRV_PHPTYPE_* constant that specifies PHP data type of the returned value.
    • *
    • $sqlType[optional] - A SQLSRV_SQLTYPE_* constant that specifies the SQL Server data type of the input value.
    * @param array $options [optional]: An associative array that sets query properties. The table below lists the * supported keys and corresponding values:
    * * QueryTimeout (int) - Sets the query timeout in seconds. By default, the driver will wait indefinitely for results. * Any positive integer value.
    * * SendStreamParamsAtExec (bool) - Configures the driver to send all stream data at execution (true), or to send stream * data in chunks (false). By default, the value is set to true. For more information, see * {@link sqlsrv_send_stream_data() sqlsrv_send_stream_data}.
    * * Scrollable - For more information about these values, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}. *
    • SQLSRV_CURSOR_FORWARD
    • *
    • SQLSRV_CURSOR_STATIC
    • *
    • SQLSRV_CURSOR_DYNAMIC
    • *
    • SQLSRV_CURSOR_KEYSET
    • *
    • SQLSRV_CURSOR_CLIENT_BUFFERED
    * @return resource|false A statement resource. If the statement cannot be created and/or executed, false is returned. */ function sqlsrv_query($conn, $tsql, $params = [], $options = []) {} /** * Makes the next row in a result set available for reading. * *
    Makes the next row of a result set available for reading. Use {@link sqlsrv_get_field() sqlsrv_get_field} to read fields of * the row.
    * * A statement must be executed before results can be retrieved. For information on executing a statement, see {@link sqlsrv_query() sqlsrv_query} * and {@link sqlsrv_execute() sqlsrv_execute}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-fetch * @param resource|null $stmt A statement resource corresponding to an executed statement. * @param int|null $row [optional]: One of the following values, specifying the row to access in a result set that uses a * scrollable cursor: SQLSRV_SCROLL_NEXT, SQLSRV_SCROLL_PRIOR, SQLSRV_SCROLL_FIRST, SQLSRV_SCROLL_LAST, * SQLSRV_SCROLL_ABSOLUTE, SQLSRV_SCROLL_RELATIVE.
    * * For more information on these values, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}. * @param int|null $offset [optional] Used with SQLSRV_SCROLL_ABSOLUTE and SQLSRV_SCROLL_RELATIVE to specify the row to * retrieve. The first record in the result set is 0. * @return bool|null If the next row of the result set was successfully retrieved, true is returned. If there are * no more results in the result set, null is returned. If an error occurred, false is returned. */ function sqlsrv_fetch($stmt, $row = null, $offset = null) {} /** * Retrieves a field in the current row by index. The PHP return type can be specified. * *
    Retrieves data from the specified field of the current row. Field data must be accessed in order. For example, * data from the first field cannot be accessed after data from the second field has been accessed.
    * * The combination of {@link sqlsrv_fetch() sqlsrv_fetch} and * {@link sqlsrv_get_field() sqlsrv_get_field} provides forward-only access to data.
    * * The combination of {@link sqlsrv_fetch() sqlsrv_fetch} and * {@link sqlsrv_get_field() sqlsrv_get_field} loads only one * field of a result set row into script memory and allows PHP return type specification. (For information about how to * specify the PHP return type, see {@link http://msdn.microsoft.com/en-us/library/cc296208.aspx How to: Specify PHP Data Types}.) * This combination of functions also allows data to be retrieved as a stream. (For information about retrieving data * as a stream, see {@link http://msdn.microsoft.com/en-us/library/cc296155.aspx Retrieving Data as a Stream Using the SQLSRV Driver}.)
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-get-field * @param resource $stmt A statement resource corresponding to an executed statement. * @param int $field_index The index of the field to be retrieved. Indexes begin at zero. * @param int $get_as_type [optional] A SQLSRV constant (SQLSRV_PHPTYPE_*) that determines the PHP data type for the returned * data. For information about supported data types, see * {@link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server Constants (Microsoft Drivers for PHP for SQL Server)}. * If no return type is specified, a default PHP type will be returned. For information about default PHP types, see * {@link http://msdn.microsoft.com/en-us/library/cc296193.aspx Default PHP Data Types}. For information about * specifying PHP data types, see {@link http://msdn.microsoft.com/en-us/library/cc296208.aspx How to: Specify PHP Data Types}. * @return mixed The field data. You can specify the PHP data type of the returned data by using the $getAsType * parameter. If no return data type is specified, the default PHP data type will be returned. For information about * default PHP types, see {@link http://msdn.microsoft.com/en-us/library/cc296193.aspx Default PHP Data Types}. For * information about specifying PHP data types, * see {@link http://msdn.microsoft.com/en-us/library/cc296208.aspx How to: Specify PHP Data Types}. */ function sqlsrv_get_field($stmt, $field_index, $get_as_type = null) {} /** * Retrieves the next row of data as a numerically indexed array, an associative array, or both. * *
    If a column with no name is returned, the associative key for the array element will be an empty string (""). For * example, consider this Transact-SQL statement that inserts a value into a database table and retrieves the * server-generated primary key: * INSERT INTO Production.ProductPhoto (LargePhoto) VALUES (?); * SELECT SCOPE_IDENTITY() * If the result set returned by the SELECT SCOPE_IDENTITY() portion of this statement is retrieved as an associative * array, the key for the returned value will be an empty string ("") because the returned column has no name. To avoid * this, you can retrieve the result as a numeric array, or you can specify a name for the returned column in the * Transact-SQL statement. The following is one way to specify a column name in Transact-SQL: * SELECT SCOPE_IDENTITY() AS PictureID * If a result set contains multiple columns without names, the value of the last unnamed column will be assigned to the * empty string ("") key.
    * * The sqlsrv_fetch_array function always returns data according to the * {@link http://msdn.microsoft.com/en-us/library/cc296193.aspx Default PHP Data Types}. For information about * how to specify the PHP data type, * see {@link http://msdn.microsoft.com/en-us/library/cc296208.aspx How to: Specify PHP Data Types}.
    * * If a field with no name is retrieved, the associative key for the array element will be an empty string (""). For * more information, see {@link sqlsrv_fetch_array() sqlsrv_fetch_array}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296160.aspx Retrieving Data} and * {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-fetch-array * @param resource|null $stmt A statement resource corresponding to an executed statement. * @param int $fetch_type [optional] A predefined constant. This parameter can take on one of the values listed in the * following table: *
    • SQLSRV_FETCH_NUMERIC - The next row of data is returned as a numeric array.
    • *
    • SQLSRV_FETCH_ASSOC - The next row of data is returned as an associative array. The array keys are the column * names in the result set.
    • *
    • SQLSRV_FETCH_BOTH - The next row of data is returned as both a numeric array and an associative array. This is * the default value.
    * @param int|null $row [optional]: One of the following values, specifying the row to access in a result set that uses a * scrollable cursor: SQLSRV_SCROLL_NEXT, SQLSRV_SCROLL_PRIOR, SQLSRV_SCROLL_FIRST, SQLSRV_SCROLL_LAST, * SQLSRV_SCROLL_ABSOLUTE, SQLSRV_SCROLL_RELATIVE.
    * * For more information on these values, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}. * @param int|null $offset [optional] Used with SQLSRV_SCROLL_ABSOLUTE and SQLSRV_SCROLL_RELATIVE to specify the row to * retrieve. The first record in the result set is 0. * @return array|null|false If a row of data is retrieved, an array is returned. If there are no more rows to retrieve, null is returned. If an error occurs, false is returned. */ function sqlsrv_fetch_array($stmt, $fetch_type = null, $row = null, $offset = null) {} /** * Retrieves the next row of data as an object. * *
    Retrieves the next row of data as a PHP object.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296160.aspx Retrieving Data} and * {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-fetch-object * @param resource $stmt A statement resource corresponding to an executed statement. * @param string|null $class_name [optional] A string specifying the name of the class to instantiate. If a value for the * $className parameter is not specified, an instance of the PHP {@link stdClass} is instantiated. * @param array|null $ctor_params [optional] An array that contains values passed to the constructor of the class * specified with the $className parameter. If the constructor of the specified class accepts parameter values, the * $ctorParams parameter must be used when calling sqlsrv_fetch_object. * @param int|null $row [optional] One of the following values, specifying the row to access in a result set that uses a * scrollable cursor: SQLSRV_SCROLL_NEXT, SQLSRV_SCROLL_PRIOR, SQLSRV_SCROLL_FIRST, SQLSRV_SCROLL_LAST, * SQLSRV_SCROLL_ABSOLUTE, SQLSRV_SCROLL_RELATIVE.
    * * For more information on these values, see * {@link http://msdn.microsoft.com/en-us/library/ee376927.aspx Specifying a Cursor Type and Selecting Rows}. * @param int|null $offset [optional] Used with SQLSRV_SCROLL_ABSOLUTE and SQLSRV_SCROLL_RELATIVE to specify the row to * retrieve. The first record in the result set is 0. * @return object|false|null A PHP object with properties that correspond to result set field names. Property values are * populated with the corresponding result set field values. If the class specified with the optional $className * parameter does not exist or if there is no active result set associated with the specified statement, false is * returned. If there are no more rows to retrieve, null is returned.

    * * The data type of a value in the returned object will be the default PHP data type. For information on default PHP data * types, see {@link http://msdn.microsoft.com/en-us/library/cc296193.aspx Default PHP Data Types}.
    */ function sqlsrv_fetch_object($stmt, $class_name = null, $ctor_params = null, $row = null, $offset = null) {} /** * Detects if a result set has one or more rows. * *
    Indicates if the result set has one or more rows.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-has-rows * @param resource $stmt The executed statement. * @return bool If there are rows in the result set, the return value will be true. If there are no rows, or if the * function call fails, the return value will be false. */ function sqlsrv_has_rows($stmt) {} /** * Retrieves the number of fields (columns) on a statemen. * *
    Retrieves the number of fields in an active result set. Note that sqlsrv_num_fields can be called on any * prepared statement, before or after execution.
    * * Additional Information at {@link sqlsrv_field_metadata() sqlsrv_field_metadata} and * {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-num-fields * @param resource $stmt The statement on which the targeted result set is active. * @return int|false An integer value that represents the number of fields in the active result set. If an error occurs, * the Boolean value false is returned. */ function sqlsrv_num_fields($stmt) {} /** * Makes the next result of the specified statement active. * *
    Makes the next result (result set, row count, or output parameter) of the specified statement active.
    * * The first (or only) result returned by a batch query or stored procedure is active without a call to sqlsrv_next_result.
    * * Additional Information at * {@link http://msdn.microsoft.com/en-us/library/cc296202.aspx Updating Data (Microsoft Drivers for PHP for SQL Server)} and * {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-next-result * @param resource $stmt The executed statement on which the next result is made active. * @return bool|null If the next result was successfully made active, the Boolean value true is returned. If an error occurred in * making the next result active, false is returned. If no more results are available, null is returned. */ function sqlsrv_next_result($stmt) {} /** * Retrieves the number of rows in a result set. * *
    sqlsrv_num_rows requires a client-side, static, or keyset cursor, and will return false if you use a forward cursor * or a dynamic cursor. (A forward cursor is the default.) For more information about cursors, see * {@link sqlsrv_prepare() sqlsrv_prepare}, * {@link sqlsrv_query() sqlsrv_query} and * {@link http://msdn.microsoft.com/en-us/library/hh487160.aspx Cursor Types (SQLSRV Driver)}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-num-rows * @param resource $stmt The result set for which to count the rows. * @return int|false False if there was an error calculating the number of rows. Otherwise, returns the number of rows in the result set. */ function sqlsrv_num_rows($stmt) {} /** * Returns the number of modified rows. * *
    Returns the number of rows modified by the last statement executed. This function does not return the number of * rows returned by a SELECT statement.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-rows-affected * @param resource $stmt A statement resource corresponding to an executed statement. * @return int|false An integer indicating the number of rows modified by the last executed statement. If no rows were * modified, zero (0) is returned. If no information about the number of modified rows is available, negative one (-1) * is returned. If an error occurred in retrieving the number of modified rows, false is returned. */ function sqlsrv_rows_affected($stmt) {} /** * Provides information about the client. * *
    Returns information about the connection and client stack.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-client-info * @param resource $conn The connection resource by which the client is connected. * @return array|false An associative array with keys described in the table below, or false if the connection resource * is null.
    *
    • DriverDllName - SQLNCLI10.DLL (Microsoft Drivers for PHP for SQL Server version 2.0)
    • *
    • DriverODBCVer - ODBC version (xx.yy)
    • *
    • DriverVer - SQL Server Native Client DLL version: 10.50.xxx (Microsoft Drivers for PHP for SQL Server version 2.0)
    • *
    • ExtensionVer - php_sqlsrv.dll version: 2.0.xxxx.x(Microsoft Drivers for PHP for SQL Server version 2.0)
    */ function sqlsrv_client_info($conn) {} /** * Returns information about the server. * *
    Returns information about the server. A connection must be established before calling this function.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-server-info * @param resource $conn The connection resource by which the client and server are connected. * @return array An associative array with the following keys: *
    • CurrentDatabase - The database currently being targeted.
    • *
    • SQLServerVersion - The version of SQL Server.
    • *
    • SQLServerName - The name of the server.
    */ function sqlsrv_server_info($conn) {} /** * Cancels a statement; discards any pending results for the statement. * *
    Cancels a statement. This means that any pending results for the statement are discarded. After this function * is called, the statement can be re-executed if it was prepared with {@link sqlsrv_prepare() sqlsrv_prepare}. Calling * this function is not necessary if all the results associated with the statement have been consumed.
    * * A statement that is prepared and executed using the combination of {@link sqlsrv_prepare() sqlsrv_prepare} and * {@link sqlsrv_execute() sqlsrv_execute} can be re-executed * with {@link sqlsrv_execute() sqlsrv_execute} after calling sqlsrv_cancel. A statement that is executed with * {@link sqlsrv_query() sqlsrv_query} cannot be re-executed after calling sqlsrv_cancel.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-cancel * @param resource $stmt The statement to be canceled. * @return bool A Boolean value: true if the operation was successful. Otherwise, false. */ function sqlsrv_cancel($stmt) {} /** * Closes a statement. Frees all resources associated with the statement. * *
    Frees all resources associated with the specified statement. The statement cannot be used again after this function * has been called.
    * * Null is a valid parameter for this function. This allows the function to be called multiple times in a script. For * example, if you free a statement in an error condition and free it again at the end of the script, the second call to * sqlsrv_free_stmt will return true because the first call to sqlsrv_free_stmt (in the error condition) sets the * statement resource to null.
    * * Additional Information at {@link sqlsrv_cancel() sqlsrv_cancel} and * {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-free-stmt * @param resource|null $stmt The statement to be closed. * @return bool The Boolean value true unless the function is called with an invalid parameter. If the function is * called with an invalid parameter, false is returned. */ function sqlsrv_free_stmt($stmt) {} /** * Returns field metadata. * *
    Retrieves metadata for the fields of a prepared statement. For information about preparing a statement, * see {@link sqlsrv_query() sqlsrv_query} * or {@link sqlsrv_prepare() sqlsrv_prepare}. Note that sqlsrv_field_metadata can be called on any prepared statement, * pre- or post-execution.
    * * Additional Information at {@link sqlsrv_cancel() sqlsrv_cancel} and * {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-field-metadata * @param resource $stmt A statement resource for which field metadata is sought. * @return array|false An array of arrays or false. The array consists of one array for each field in the result set. * Each sub-array has keys as described in the table below. If there is an error in retrieving field metadata, false is * returned. *
    • Name - Name of the column to which the field corresponds.
    • *
    • Type - Numeric value that corresponds to a SQL type.
    • *
    • Size - Number of characters for fields of character type (char(n), varchar(n), nchar(n), nvarchar(n), XML). * Number of bytes for fields of binary type (binary(n), varbinary(n), UDT). NULL for other SQL Server data types.
    • *
    • Precision - The precision for types of variable precision (real, numeric, decimal, datetime2, datetimeoffset, and * time). NULL for other SQL Server data types.
    • *
    • Scale - The scale for types of variable scale (numeric, decimal, datetime2, datetimeoffset, and time). NULL for other * SQL Server data types.
    • *
    • Nullable - An enumerated value indicating whether the column is nullable (SQLSRV_NULLABLE_YES), the column is not * nullable (SQLSRV_NULLABLE_NO), or it is not known if the column is nullable (SQLSRV_NULLABLE_UNKNOWN).
    * See the {@link http://msdn.microsoft.com/en-us/library/cc296197.aspx function documentation} for more information on * the keys for each sub-array. */ function sqlsrv_field_metadata($stmt) {} /** * Sends up to eight kilobytes (8 KB) of data to the server with each call to the function. * *
    Sends data from parameter streams to the server. Up to eight kilobytes (8K) of data is sent with each call to * sqlsrv_send_stream_data.
    * * By default, all stream data is sent to the server when a query is executed. If this default behavior is not changed, * you do not have to use sqlsrv_send_stream_data to send stream data to the server. For information about changing the * default behavior, see the Parameters section of {@link sqlsrv_query() sqlsrv_query} * or {@link sqlsrv_prepare() sqlsrv_prepare}.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/sqlsrv-send-stream-data * @param resource $stmt A statement resource corresponding to an executed statement. * @return bool Boolean : true if there is more data to be sent. Otherwise, false. */ function sqlsrv_send_stream_data($stmt) {} /** * Specifies the encoding of a stream of data from the server. * *
    When specifying the PHP data type of a value being returned from the server, this allows you to specify the encoding * used to process the value if the value is a stream.
    * * In the documentation this is presented as a constant that accepts an arguement.
    * * When you use SQLSRV_PHPTYPE_STREAM, the encoding must be specified. If no parameter is supplied, an error will be * returned.
    * * Additional Information at: *
      *
    • {@link http://msdn.microsoft.com/en-us/library/cc296208.aspx How to: Specify PHP Data Types}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296163.aspx How to: Retrieve Character Data as a Stream Using the SQLSRV Driver.}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc626307.aspx How to: Send and Retrieve UTF-8 Data Using Built-In UTF-8 Support.}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    • *
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server * * @param string $encoding The encoding to use for the stream. The valid options are SQLSRV_ENC_BINARY, SQLSRV_ENC_CHAR * or "UTF-8". * * @return int Value to use in any place that accepts a SQLSRV_PHPTYPE_* constant to represent a PHP stream with the * given encoding. */ function SQLSRV_PHPTYPE_STREAM($encoding) {} /** * Specifies the encoding of a string being received form the server. * *
    When specifying the PHP data type of a value being returned from the server, this allows you to specify the * encoding used to process the value if the value is a string.
    * * In the documentation this is presented as a constant that accepts an arguement.
    * * When you use SQLSRV_PHPTYPE_STRING, the encoding must be specified. If no parameter is supplied, an error will be * returned.
    * * Additional Information at: *
      *
    • {@link http://msdn.microsoft.com/en-us/library/cc296208.aspx How to: Specify PHP Data Types}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296163.aspx How to: Retrieve Character Data as a Stream Using the SQLSRV Driver.}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc626307.aspx How to: Send and Retrieve UTF-8 Data Using Built-In UTF-8 Support.}
    • *
    • {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    • *
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server * * @param string $encoding The encoding to use for the stream. The valid options are SQLSRV_ENC_BINARY, SQLSRV_ENC_CHAR * or "UTF-8". * * @return int Value to use in any place that accepts a SQLSRV_PHPTYPE_* constant to represent a PHP string with the * given encoding. */ function SQLSRV_PHPTYPE_STRING($encoding) {} /** * Specifies a SQL Server binary field. * *
    In the documentation this is presented as a constant that accepts an arguement.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server * @param int $byteCount Must be between 1 and 8000. * @return int Value to use in any place that accepts a SQLSRV_SQLTYPE_* constant to represent the 'binary' data type. */ function SQLSRV_SQLTYPE_BINARY($byteCount) {} /** * Specifies a SQL Server varbinary field. * *
    In the documentation this is presented as a constant that accepts an arguement.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server * @param int|string $byteCount Must be between 1 and 8000 or 'max'. * @return int Value to use in any place that accepts a SQLSRV_SQLTYPE_* constant to represent the varbinary data type. */ function SQLSRV_SQLTYPE_VARBINARY($byteCount) {} /** * Specifies a SQL Server varchar filed. * *
    In the documentation this is presented as a constant that accepts an arguement.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server * * @param int|string $charCount Must be between 1 and 8000 or 'max'. * * @return int Value to use in any place that accepts a SQLSRV_SQLTYPE_* constant to represent the varchar data type. */ function SQLSRV_SQLTYPE_VARCHAR($charCount) {} /** * Specifies a SQL Server char field. * *
    In the documentation this is presented as a constant that accepts an arguement.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server * @param int $charCount Must be between 1 and 8000. * @return int Value to use in any place that accepts a SQLSRV_SQLTYPE_* constant to represent the char data type. */ function SQLSRV_SQLTYPE_CHAR($charCount) {} /** * Specifies a SQL Server nchar field. * *
    In the documentation this is presented as a constant that accepts an arguement.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server * @param int $charCount Must be between 1 and 4000. * @return int Value to use in any place that accepts a SQLSRV_SQLTYPE_* constant to represent the nchar data type. */ function SQLSRV_SQLTYPE_NCHAR($charCount) {} /** * Specifies a SQL Server nvarchar field. * *
    In the documentation this is presented as a constant that accepts an arguement.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server * @param int|string $charCount Must be between 1 and 4000 or 'max'. * @return int Value to use in any place that accepts a SQLSRV_SQLTYPE_* constant to represent the nvarchar data type. */ function SQLSRV_SQLTYPE_NVARCHAR($charCount) {} /** * Specifies a SQL Server decimal field. * *
    In the documentation this is presented as a constant that accepts an arguement.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server * @param int $precision Must be between 1 and 38. * @param int $scale Must be between 1 and $precision. * @return int Value to use in any place that accepts a SQLSRV_SQLTYPE_* constant to represent the decimal data type. */ function SQLSRV_SQLTYPE_DECIMAL($precision, $scale) {} /** * Specifies a SQL Server numeric field. * *
    In the documentation this is presented as a constant that accepts an arguement.
    * * Additional Information at {@link http://msdn.microsoft.com/en-us/library/cc296152.aspx SQLSRV Driver API Reference}
    * * @link https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server * @param int $precision Must be between 1 and 38. * @param int $scale Must be between 1 and $precision. * @return int Value to use in any place that accepts a SQLSRV_SQLTYPE_* constant to represent the numeric data type. */ function SQLSRV_SQLTYPE_NUMERIC($precision, $scale) {} * @link https://github.com/soulshockers/cassandra-phpdoc */ /** * Copyright 2019 DataStax, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace { /** * The main entry point to the PHP Driver for Apache Cassandra. * * Use Cassandra::cluster() to build a cluster instance. * Use Cassandra::ssl() to build SSL options instance. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/ */ final class Cassandra { /** * Consistency level ANY means the request is fulfilled as soon as the data * has been written on the Coordinator. Requests with this consistency level * are not guaranteed to make it to Replica nodes. * * @see \Cassandra\Session::execute() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-CONSISTENCY_ANY */ public const CONSISTENCY_ANY = 0; /** * Consistency level ONE guarantees that data has been written to at least * one Replica node. * * @see \Cassandra\Session::execute() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-CONSISTENCY_ONE */ public const CONSISTENCY_ONE = 1; /** * Consistency level TWO guarantees that data has been written to at least * two Replica nodes. * * @see \Cassandra\Session::execute() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-CONSISTENCY_TWO */ public const CONSISTENCY_TWO = 2; /** * Consistency level THREE guarantees that data has been written to at least * three Replica nodes. * * @see \Cassandra\Session::execute() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-CONSISTENCY_THREE */ public const CONSISTENCY_THREE = 3; /** * Consistency level QUORUM guarantees that data has been written to at least * the majority of Replica nodes. How many nodes exactly are a majority * depends on the replication factor of a given keyspace and is calculated * using the formula `ceil(RF / 2 + 1)`, where `ceil` is a mathematical * ceiling function and `RF` is the replication factor used. For example, * for a replication factor of `5`, the majority is `ceil(5 / 2 + 1) = 3`. * * @see \Cassandra\Session::execute() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-CONSISTENCY_QUORUM */ public const CONSISTENCY_QUORUM = 4; /** * Consistency level ALL guarantees that data has been written to all * Replica nodes. * * @see \Cassandra\Session::execute() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-CONSISTENCY_ALL */ public const CONSISTENCY_ALL = 5; /** * Same as `CONSISTENCY_QUORUM`, but confined to the local data center. This * consistency level works only with `NetworkTopologyStrategy` replication. * * @see \Cassandra\Session::execute() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-CONSISTENCY_LOCAL_QUORUM */ public const CONSISTENCY_LOCAL_QUORUM = 6; /** * Consistency level EACH_QUORUM guarantees that data has been written to at * least a majority Replica nodes in all datacenters. This consistency level * works only with `NetworkTopologyStrategy` replication. * * @see \Cassandra\Session::execute() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-CONSISTENCY_EACH_QUORUM */ public const CONSISTENCY_EACH_QUORUM = 7; /** * This is a serial consistency level, it is used in conditional updates, * e.g. (`CREATE|INSERT ... IF NOT EXISTS`), and should be specified as the * `serial_consistency` execution option when invoking `session.execute` * or `session.execute_async`. * * Consistency level SERIAL, when set, ensures that a Paxos commit fails if * any of the replicas is down. * * @see \Cassandra\Session::execute() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-CONSISTENCY_SERIAL */ public const CONSISTENCY_SERIAL = 8; /** * Same as `CONSISTENCY_SERIAL`, but confined to the local data center. This * consistency level works only with `NetworkTopologyStrategy` replication. * * @see \Cassandra\Session::execute() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-CONSISTENCY_LOCAL_SERIAL */ public const CONSISTENCY_LOCAL_SERIAL = 9; /** * Same as `CONSISTENCY_ONE`, but confined to the local data center. This * consistency level works only with `NetworkTopologyStrategy` replication. * * @see \Cassandra\Session::execute() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-CONSISTENCY_LOCAL_ONE */ public const CONSISTENCY_LOCAL_ONE = 10; /** * Perform no verification of nodes when using SSL encryption. * * @see \Cassandra\SSLOptions\Builder::withVerifyFlags() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-VERIFY_NONE */ public const VERIFY_NONE = 0; /** * Verify presence and validity of SSL certificates. * * @see \Cassandra\SSLOptions\Builder::withVerifyFlags() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-VERIFY_PEER_CERT */ public const VERIFY_PEER_CERT = 1; /** * Verify that the IP address matches the SSL certificate’s common name or * one of its subject alternative names. This implies the certificate is * also present. * * @see \Cassandra\SSLOptions\Builder::withVerifyFlags() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-VERIFY_PEER_IDENTITY */ public const VERIFY_PEER_IDENTITY = 2; /** * @see \Cassandra\BatchStatement::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-BATCH_LOGGED */ public const BATCH_LOGGED = 0; /** * @see \Cassandra\BatchStatement::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-BATCH_UNLOGGED */ public const BATCH_UNLOGGED = 1; /** * @see \Cassandra\BatchStatement::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-BATCH_COUNTER */ public const BATCH_COUNTER = 2; /** * Used to disable logging. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-LOG_DISABLED */ public const LOG_DISABLED = 0; /** * Allow critical level logging. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-LOG_CRITICAL */ public const LOG_CRITICAL = 1; /** * Allow error level logging. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-LOG_ERROR */ public const LOG_ERROR = 2; /** * Allow warning level logging. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-LOG_WARN */ public const LOG_WARN = 3; /** * Allow info level logging. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-LOG_INFO */ public const LOG_INFO = 4; /** * Allow debug level logging. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-LOG_DEBUG */ public const LOG_DEBUG = 5; /** * Allow trace level logging. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-LOG_TRACE */ public const LOG_TRACE = 6; /** * When using a map, collection or set of type text, all of its elements * must be strings. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_TEXT */ public const TYPE_TEXT = 'text'; /** * When using a map, collection or set of type ascii, all of its elements * must be strings. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_ASCII */ public const TYPE_ASCII = 'ascii'; /** * When using a map, collection or set of type varchar, all of its elements * must be strings. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_VARCHAR */ public const TYPE_VARCHAR = 'varchar'; /** * When using a map, collection or set of type bigint, all of its elements * must be instances of Bigint. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_BIGINT */ public const TYPE_BIGINT = 'bigint'; /** * When using a map, collection or set of type smallint, all of its elements * must be instances of Inet. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_SMALLINT */ public const TYPE_SMALLINT = 'smallint'; /** * When using a map, collection or set of type tinyint, all of its elements * must be instances of Inet. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_TINYINT */ public const TYPE_TINYINT = 'tinyint'; /** * When using a map, collection or set of type blob, all of its elements * must be instances of Blob. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_BLOB */ public const TYPE_BLOB = 'blob'; /** * When using a map, collection or set of type bool, all of its elements * must be boolean. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_BOOLEAN */ public const TYPE_BOOLEAN = 'boolean'; /** * When using a map, collection or set of type counter, all of its elements * must be instances of Bigint. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_COUNTER */ public const TYPE_COUNTER = 'counter'; /** * When using a map, collection or set of type decimal, all of its elements * must be instances of Decimal. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_DECIMAL */ public const TYPE_DECIMAL = 'decimal'; /** * When using a map, collection or set of type double, all of its elements * must be doubles. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_DOUBLE */ public const TYPE_DOUBLE = 'double'; /** * When using a map, collection or set of type float, all of its elements * must be instances of Float. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_FLOAT */ public const TYPE_FLOAT = 'float'; /** * When using a map, collection or set of type int, all of its elements * must be ints. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_INT */ public const TYPE_INT = 'int'; /** * When using a map, collection or set of type timestamp, all of its elements * must be instances of Timestamp. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_TIMESTAMP */ public const TYPE_TIMESTAMP = 'timestamp'; /** * When using a map, collection or set of type uuid, all of its elements * must be instances of Uuid. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_UUID */ public const TYPE_UUID = 'uuid'; /** * When using a map, collection or set of type varint, all of its elements * must be instances of Varint. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_VARINT */ public const TYPE_VARINT = 'varint'; /** * When using a map, collection or set of type timeuuid, all of its elements * must be instances of Timeuuid. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_TIMEUUID */ public const TYPE_TIMEUUID = 'timeuuid'; /** * When using a map, collection or set of type inet, all of its elements * must be instances of Inet. * * @see Set::__construct() * @see Collection::__construct() * @see Map::__construct() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-TYPE_INET */ public const TYPE_INET = 'inet'; /** * The current version of the extension. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-VERSION */ public const VERSION = '1.3.2'; /** * The version of the cpp-driver the extension is compiled against. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#constant-CPP_DRIVER_VERSION */ public const CPP_DRIVER_VERSION = '2.13.0'; /** * Creates a new cluster builder for constructing a Cluster object. * * @return \Cassandra\Cluster\Builder A cluster builder object with default settings * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#method-cluster */ public static function cluster() {} /** * Creates a new ssl builder for constructing a SSLOptions object. * * @return \Cassandra\SSLOptions\Builder A SSL options builder with default settings * @link https://docs.datastax.com/en/developer/php-driver/latest/api/class.Cassandra/#method-ssl */ public static function ssl() {} } } /** * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/ */ namespace Cassandra { use JetBrains\PhpStorm\Deprecated; /** * A PHP representation of a column * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Column/ */ interface Column { /** * Returns the name of the column. * * @return string Name of the column or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Column/#method-name */ public function name(); /** * Returns the type of the column. * * @return \Cassandra\Type Type of the column * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Column/#method-type */ public function type(); /** * Returns whether the column is in descending or ascending order. * * @return bool Whether the column is stored in descending order. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Column/#method-isReversed */ public function isReversed(); /** * Returns true for static columns. * * @return bool Whether the column is static * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Column/#method-isStatic */ public function isStatic(); /** * Returns true for frozen columns. * * @return bool Whether the column is frozen * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Column/#method-isFrozen */ public function isFrozen(); /** * Returns name of the index if defined. * * @return string Name of the index if defined or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Column/#method-indexName */ public function indexName(); /** * Returns index options if present. * * @return string Index options if present or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Column/#method-indexOptions */ public function indexOptions(); } /** * A session is used to prepare and execute statements. * * @see \Cassandra\Cluster::connect() * @see \Cassandra\Cluster::connectAsync() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Session/ */ interface Session { /** * Execute a query. * * Available execution options: * | Option Name | Option **Type** | Option Details | * |--------------------|-----------------|----------------------------------------------------------------------------------------------------------| * | arguments | array | An array or positional or named arguments | * | consistency | int | A consistency constant e.g Dse::CONSISTENCY_ONE, Dse::CONSISTENCY_QUORUM, etc. | * | timeout | int | A number of rows to include in result for paging | * | paging_state_token | string | A string token use to resume from the state of a previous result set | * | retry_policy | RetryPolicy | A retry policy that is used to handle server-side failures for this request | * | serial_consistency | int | Either Dse::CONSISTENCY_SERIAL or Dse::CONSISTENCY_LOCAL_SERIAL | * | timestamp | int\|string | Either an integer or integer string timestamp that represents the number of microseconds since the epoch | * | execute_as | string | User to execute statement as | * * @param string|\Cassandra\Statement $statement string or statement to be executed. * @param array|\Cassandra\ExecutionOptions|null $options Options to control execution of the query. * * @return \Cassandra\Rows A collection of rows. * @throws \Cassandra\Exception * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Session/#method-execute */ public function execute($statement, $options); /** * Execute a query asynchronously. This method returns immediately, but * the query continues execution in the background. * * @param string|\Cassandra\Statement $statement string or statement to be executed. * @param array|\Cassandra\ExecutionOptions|null $options Options to control execution of the query. * * @return \Cassandra\FutureRows A future that can be used to retrieve the result. * * @see \Cassandra\Session::execute() for valid execution options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Session/#method-executeAsync */ public function executeAsync($statement, $options); /** * Prepare a query for execution. * * @param string $cql The query to be prepared. * @param array|\Cassandra\ExecutionOptions|null $options Options to control preparing the query. * * @return \Cassandra\PreparedStatement A prepared statement that can be bound with parameters and executed. * * @throws \Cassandra\Exception * * @see \Cassandra\Session::execute() for valid execution options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Session/#method-prepare */ public function prepare($cql, $options); /** * Asynchronously prepare a query for execution. * * @param string $cql The query to be prepared. * @param array|\Cassandra\ExecutionOptions|null $options Options to control preparing the query. * * @return \Cassandra\FuturePreparedStatement A future that can be used to retrieve the prepared statement. * * @see \Cassandra\Session::execute() for valid execution options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Session/#method-prepareAsync */ public function prepareAsync($cql, $options); /** * Close the session and all its connections. * * @param float $timeout The amount of time in seconds to wait for the session to close. * * @return null Nothing. * @throws \Cassandra\Exception * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Session/#method-close */ public function close($timeout); /** * Asynchronously close the session and all its connections. * * @return \Cassandra\FutureClose A future that can be waited on. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Session/#method-closeAsync */ public function closeAsync(); /** * Get performance and diagnostic metrics. * * @return array Performance/Diagnostic metrics. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Session/#method-metrics */ public function metrics(); /** * Get a snapshot of the cluster's current schema. * * @return \Cassandra\Schema A snapshot of the cluster's schema. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Session/#method-schema */ public function schema(); } /** * A PHP representation of a table * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/ */ interface Table { /** * Returns the name of this table * * @return string Name of the table * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-name */ public function name(); /** * Return a table's option by name * * @param string $name The name of the option * * @return \Cassandra\Value Value of an option by name * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-option */ public function option($name); /** * Returns all the table's options * * @return array A dictionary of `string` and `Value` pairs of the table's options. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-options */ public function options(); /** * Description of the table, if any * * @return string Table description or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-comment */ public function comment(); /** * Returns read repair chance * * @return float Read repair chance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-readRepairChance */ public function readRepairChance(); /** * Returns local read repair chance * * @return float Local read repair chance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-localReadRepairChance */ public function localReadRepairChance(); /** * Returns GC grace seconds * * @return int GC grace seconds * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-gcGraceSeconds */ public function gcGraceSeconds(); /** * Returns caching options * * @return string Caching options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-caching */ public function caching(); /** * Returns bloom filter FP chance * * @return float Bloom filter FP chance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-bloomFilterFPChance */ public function bloomFilterFPChance(); /** * Returns memtable flush period in milliseconds * * @return int Memtable flush period in milliseconds * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-memtableFlushPeriodMs */ public function memtableFlushPeriodMs(); /** * Returns default TTL. * * @return int Default TTL. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-defaultTTL */ public function defaultTTL(); /** * Returns speculative retry. * * @return string Speculative retry. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-speculativeRetry */ public function speculativeRetry(); /** * Returns index interval * * @return int Index interval * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-indexInterval */ public function indexInterval(); /** * Returns compaction strategy class name * * @return string Compaction strategy class name * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-compactionStrategyClassName */ public function compactionStrategyClassName(); /** * Returns compaction strategy options * * @return \Cassandra\Map Compaction strategy options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-compactionStrategyOptions */ public function compactionStrategyOptions(); /** * Returns compression parameters * * @return \Cassandra\Map Compression parameters * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-compressionParameters */ public function compressionParameters(); /** * Returns whether or not the `populate_io_cache_on_flush` is true * * @return bool Value of `populate_io_cache_on_flush` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-populateIOCacheOnFlush */ public function populateIOCacheOnFlush(); /** * Returns whether or not the `replicate_on_write` is true * * @return bool Value of `replicate_on_write` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-replicateOnWrite */ public function replicateOnWrite(); /** * Returns the value of `max_index_interval` * * @return int Value of `max_index_interval` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-maxIndexInterval */ public function maxIndexInterval(); /** * Returns the value of `min_index_interval` * * @return int Value of `min_index_interval` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-minIndexInterval */ public function minIndexInterval(); /** * Returns column by name * * @param string $name Name of the column * * @return \Cassandra\Column Column instance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-column */ public function column($name); /** * Returns all columns in this table * * @return array A list of Column instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-columns */ public function columns(); /** * Returns the partition key columns of the table * * @return array A list of Column instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-partitionKey */ public function partitionKey(); /** * Returns both the partition and clustering key columns of the table * * @return array A list of Column instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-primaryKey */ public function primaryKey(); /** * Returns the clustering key columns of the table * * @return array A list of Column instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-clusteringKey */ public function clusteringKey(); /** * @return array A list of cluster column orders ('asc' and 'desc') * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Table/#method-clusteringOrder */ public function clusteringOrder(); } /** * Interface for retry policies. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.RetryPolicy/ */ interface RetryPolicy {} /** * Interface for timestamp generators. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.TimestampGenerator/ */ interface TimestampGenerator {} /** * An interface implemented by all exceptions thrown by the PHP Driver. * Makes it easy to catch all driver-related exceptions using * `catch (Exception $e)`. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Exception/ */ interface Exception {} /** * A PHP representation of a function * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Function/ */ interface Function_ { /** * Returns the full name of the function * * @return string Full name of the function including name and types * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Function/#method-name */ public function name(); /** * Returns the simple name of the function * * @return string Simple name of the function * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Function/#method-simpleName */ public function simpleName(); /** * Returns the arguments of the function * * @return array Arguments of the function * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Function/#method-arguments */ public function arguments(); /** * Returns the return type of the function * * @return \Cassandra\Type Return type of the function * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Function/#method-returnType */ public function returnType(); /** * Returns the signature of the function * * @return string Signature of the function (same as name()) * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Function/#method-signature */ public function signature(); /** * Returns the lanuage of the function * * @return string Language used by the function * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Function/#method-language */ public function language(); /** * Returns the body of the function * * @return string Body of the function * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Function/#method-body */ public function body(); /** * Determines if a function is called when the value is null. * * @return bool Returns whether the function is called when the input columns are null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Function/#method-isCalledOnNullInput */ public function isCalledOnNullInput(); } /** * A PHP representation of the CQL `uuid` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.UuidInterface/ */ interface UuidInterface { /** * Returns this uuid as string. * * @return string uuid as string * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.UuidInterface/#method-uuid */ public function uuid(); /** * Returns the version of this uuid. * * @return int version of this uuid * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.UuidInterface/#method-version */ public function version(); } /** * A PHP representation of an index * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Index/ */ interface Index { /** * Returns the name of the index * * @return string Name of the index * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Index/#method-name */ public function name(); /** * Returns the kind of index * * @return string Kind of the index * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Index/#method-kind */ public function kind(); /** * Returns the target column of the index * * @return string Target column name of the index * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Index/#method-target */ public function target(); /** * Return a column's option by name * * @param string $name The name of the option * * @return \Cassandra\Value Value of an option by name * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Index/#method-option */ public function option($name); /** * Returns all the index's options * * @return array A dictionary of `string` and `Value` pairs of the index's options. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Index/#method-options */ public function options(); /** * Returns the class name of the index * * @return string Class name of a custom index * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Index/#method-className */ public function className(); /** * Determines if the index is a custom index. * * @return bool true if a custom index * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Index/#method-isCustom */ public function isCustom(); } /** * Cluster object is used to create Sessions. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Cluster/ */ interface Cluster { /** * Creates a new Session instance. * * @param string $keyspace Optional keyspace name * * @return \Cassandra\Session Session instance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Cluster/#method-connect */ public function connect($keyspace); /** * Creates a new Session instance. * * @param string $keyspace Optional keyspace name * * @return \Cassandra\Future A Future Session instance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Cluster/#method-connectAsync */ public function connectAsync($keyspace); } /** * Common interface implemented by all numeric types, providing basic * arithmetic functions. * * @see \Cassandra\Bigint * @see \Cassandra\Decimal * @see \Cassandra\Float_ * @see \Cassandra\Varint * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Numeric/ */ interface Numeric { /** * @param \Cassandra\Numeric $num a number to add to this one * * @return \Cassandra\Numeric sum * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Numeric/#method-add */ public function add($num); /** * @param \Cassandra\Numeric $num a number to subtract from this one * * @return \Cassandra\Numeric difference * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Numeric/#method-sub */ public function sub($num); /** * @param \Cassandra\Numeric $num a number to multiply this one by * * @return \Cassandra\Numeric product * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Numeric/#method-mul */ public function mul($num); /** * @param \Cassandra\Numeric $num a number to divide this one by * * @return \Cassandra\Numeric quotient * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Numeric/#method-div */ public function div($num); /** * @param \Cassandra\Numeric $num a number to divide this one by * * @return \Cassandra\Numeric remainder * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Numeric/#method-mod */ public function mod($num); /** * @return \Cassandra\Numeric absolute value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Numeric/#method-abs */ public function abs(); /** * @return \Cassandra\Numeric negative value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Numeric/#method-neg */ public function neg(); /** * @return \Cassandra\Numeric square root * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Numeric/#method-sqrt */ public function sqrt(); /** * @return int this number as int * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Numeric/#method-toInt */ public function toInt(); /** * @return float this number as float * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Numeric/#method-toDouble */ public function toDouble(); } /** * Futures are returns from asynchronous methods. * * @see \Cassandra\Cluster::connectAsync() * @see \Cassandra\Session::executeAsync() * @see \Cassandra\Session::prepareAsync() * @see \Cassandra\Session::closeAsync() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Future/ */ interface Future { /** * Waits for a given future resource to resolve and throws errors if any. * * @param int|float|null $timeout A timeout in seconds * * @return mixed a value that the future has been resolved with * @throws \Cassandra\Exception\TimeoutException * * @throws \Cassandra\Exception\InvalidArgumentException * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Future/#method-get */ public function get($timeout); } /** * A PHP representation of a keyspace * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/ */ interface Keyspace { /** * Returns keyspace name * * @return string Name * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-name */ public function name(); /** * Returns replication class name * * @return string Replication class * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-replicationClassName */ public function replicationClassName(); /** * Returns replication options * * @return \Cassandra\Map Replication options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-replicationOptions */ public function replicationOptions(); /** * Returns whether the keyspace has durable writes enabled * * @return string Whether durable writes are enabled * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-hasDurableWrites */ public function hasDurableWrites(); /** * Returns a table by name * * @param string $name Table name * * @return \Cassandra\Table|null Table instance or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-table */ public function table($name); /** * Returns all tables defined in this keyspace * * @return array An array of `Table` instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-tables */ public function tables(); /** * Get user type by name * * @param string $name User type name * * @return \Cassandra\Type\UserType|null A user type or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-userType */ public function userType($name); /** * Get all user types * * @return array An array of user types * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-userTypes */ public function userTypes(); /** * Get materialized view by name * * @param string $name Materialized view name * * @return \Cassandra\MaterializedView|null A materialized view or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-materializedView */ public function materializedView($name); /** * Gets all materialized views * * @return array An array of materialized views * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-materializedViews */ public function materializedViews(); /** * Get a function by name and signature * * @param string $name Function name * @param string|\Cassandra\Type $params Function arguments * * @return \Cassandra\Function_|null A function or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-function */ public function function_($name, ...$params); /** * Get all functions * * @return array An array of functions * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-functions */ public function functions(); /** * Get an aggregate by name and signature * * @param string $name Aggregate name * @param string|\Cassandra\Type $params Aggregate arguments * * @return \Cassandra\Aggregate|null An aggregate or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-aggregate */ public function aggregate($name, ...$params); /** * Get all aggregates * * @return array An array of aggregates * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Keyspace/#method-aggregates */ public function aggregates(); } /** * Common interface implemented by all Cassandra value types. * * @see \Cassandra\Bigint * @see \Cassandra\Smallint * @see \Cassandra\Tinyint * @see \Cassandra\Blob * @see \Cassandra\Collection * @see \Cassandra\Float_ * @see \Cassandra\Inet * @see \Cassandra\Map * @see \Cassandra\Set * @see \Cassandra\Timestamp * @see \Cassandra\Timeuuid * @see \Cassandra\Uuid * @see \Cassandra\Varint * @see \Cassandra\Date * @see \Cassandra\Time * * @see \Cassandra\Numeric * @see \Cassandra\UuidInterface * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Value/ */ interface Value { /** * The type of represented by the value. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Value/#method-type */ public function type(); } /** * A PHP representation of an aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Aggregate/ */ interface Aggregate { /** * Returns the full name of the aggregate * * @return string Full name of the aggregate including name and types * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Aggregate/#method-name */ public function name(); /** * Returns the simple name of the aggregate * * @return string Simple name of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Aggregate/#method-simpleName */ public function simpleName(); /** * Returns the argument types of the aggregate * * @return array Argument types of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Aggregate/#method-argumentTypes */ public function argumentTypes(); /** * Returns the final function of the aggregate * * @return \Cassandra\Function_ Final function of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Aggregate/#method-finalFunction */ public function finalFunction(); /** * Returns the state function of the aggregate * * @return \Cassandra\Function_ State function of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Aggregate/#method-stateFunction */ public function stateFunction(); /** * Returns the initial condition of the aggregate * * @return \Cassandra\Value Initial condition of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Aggregate/#method-initialCondition */ public function initialCondition(); /** * Returns the return type of the aggregate * * @return \Cassandra\Type Return type of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Aggregate/#method-returnType */ public function returnType(); /** * Returns the state type of the aggregate * * @return \Cassandra\Type State type of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Aggregate/#method-stateType */ public function stateType(); /** * Returns the signature of the aggregate * * @return string Signature of the aggregate (same as name()) * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Aggregate/#method-signature */ public function signature(); } /** * All statements implement this common interface. * * @see \Cassandra\SimpleStatement * @see \Cassandra\PreparedStatement * @see \Cassandra\BatchStatement * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Statement/ */ interface Statement {} /** * A PHP representation of a schema * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Schema/ */ interface Schema { /** * Returns a Keyspace instance by name. * * @param string $name Name of the keyspace to get * * @return \Cassandra\Keyspace Keyspace instance or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Schema/#method-keyspace */ public function keyspace($name); /** * Returns all keyspaces defined in the schema. * * @return array An array of Keyspace instances. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/interface.Schema/#method-keyspaces */ public function keyspaces(); } /** * Rows represent a result of statement execution. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/ */ final class Rows implements \Iterator, \ArrayAccess { /** * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-__construct */ public function __construct() {} /** * Returns the number of rows. * * @return int number of rows * * @see \Countable::count() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-count */ public function count() {} /** * Resets the rows iterator. * * @return void * * @see \Iterator::rewind() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-rewind */ public function rewind() {} /** * Returns current row. * * @return array current row * * @see \Iterator::current() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-current */ public function current() {} /** * Returns current index. * * @return int index * * @see \Iterator::key() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-key */ public function key() {} /** * Advances the rows iterator by one. * * @return void * * @see \Iterator::next() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-next */ public function next() {} /** * Returns existence of more rows being available. * * @return bool whether there are more rows available for iteration * * @see \Iterator::valid() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-valid */ public function valid() {} /** * Returns existence of a given row. * * @param int $offset row index * * @return bool whether a row at a given index exists * * @see \ArrayAccess::offsetExists() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-offsetExists */ public function offsetExists($offset) {} /** * Returns a row at given index. * * @param int $offset row index * * @return array|null row at a given index * * @see \ArrayAccess::offsetGet() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-offsetGet */ public function offsetGet($offset) {} /** * Sets a row at given index. * * @param int $offset row index * @param array $value row value * * @return void * * @throws \Cassandra\Exception\DomainException * * @see \ArrayAccess::offsetSet() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-offsetSet */ public function offsetSet($offset, $value) {} /** * Removes a row at given index. * * @param int $offset row index * * @return void * * @throws \Cassandra\Exception\DomainException * * @see \ArrayAccess::offsetUnset() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-offsetUnset */ public function offsetUnset($offset) {} /** * Check for the last page when paging. * * @return bool whether this is the last page or not * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-isLastPage */ public function isLastPage() {} /** * Get the next page of results. * * @param float|null $timeout * * @return \Cassandra\Rows|null loads and returns next result page * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-nextPage */ public function nextPage($timeout) {} /** * Get the next page of results asynchronously. * * @return \Cassandra\Future returns future of the next result page * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-nextPageAsync */ public function nextPageAsync() {} /** * Returns the raw paging state token. * * @return string * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-pagingStateToken */ public function pagingStateToken() {} /** * Get the first row. * * @return array|null returns first row if any * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Rows/#method-first */ public function first() {} } /** * Default cluster implementation. * * @see \Cassandra\Cluster * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultCluster/ */ final class DefaultCluster implements Cluster { /** * Creates a new Session instance. * * @param string $keyspace Optional keyspace name * @param int $timeout Optional timeout * * @return \Cassandra\Session Session instance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultCluster/#method-connect */ public function connect($keyspace, $timeout) {} /** * Creates a new Session instance. * * @param string $keyspace Optional keyspace name * * @return \Cassandra\Future A Future Session instance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultCluster/#method-connectAsync */ public function connectAsync($keyspace) {} } /** * A PHP representation of a public function * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultFunction/ */ final class DefaultFunction implements Function_ { /** * Returns the full name of the function * * @return string Full name of the function including name and types * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultFunction/#method-name */ public function name() {} /** * Returns the simple name of the function * * @return string Simple name of the function * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultFunction/#method-simpleName */ public function simpleName() {} /** * Returns the arguments of the function * * @return array Arguments of the function * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultFunction/#method-arguments */ public function arguments() {} /** * Returns the return type of the function * * @return \Cassandra\Type Return type of the function * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultFunction/#method-returnType */ public function returnType() {} /** * Returns the signature of the function * * @return string Signature of the function (same as name()) * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultFunction/#method-signature */ public function signature() {} /** * Returns the lanuage of the function * * @return string Language used by the function * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultFunction/#method-language */ public function language() {} /** * Returns the body of the function * * @return string Body of the function * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultFunction/#method-body */ public function body() {} /** * Determines if a function is called when the value is null. * * @return bool Returns whether the function is called when the input columns are null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultFunction/#method-isCalledOnNullInput */ public function isCalledOnNullInput() {} } /** * Simple statements can be executed using a Session instance. * They are constructed with a CQL string that can contain positional * argument markers `?`. * * NOTE: Positional argument are only valid for native protocol v2+. * * @see \Cassandra\Session::execute() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.SimpleStatement/ */ final class SimpleStatement implements Statement { /** * Creates a new simple statement with the provided CQL. * * @param string $cql CQL string for this simple statement * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.SimpleStatement/#method-__construct */ public function __construct($cql) {} } /** * A PHP representation of the CQL `tuple` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tuple/ */ final class Tuple implements Value, \Countable, \Iterator { /** * Creates a new tuple with the given types. * * @param array $types Array of types * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tuple/#method-__construct */ public function __construct($types) {} /** * The type of this tuple. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tuple/#method-type */ public function type() {} /** * Array of values in this tuple. * * @return array values * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tuple/#method-values */ public function values() {} /** * Sets the value at index in this tuple . * * @param mixed $value A value or null * * @return void * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tuple/#method-set */ public function set($value) {} /** * Retrieves the value at a given index. * * @param int $index Index * * @return mixed A value or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tuple/#method-get */ public function get($index) {} /** * Total number of elements in this tuple * * @return int count * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tuple/#method-count */ public function count() {} /** * Current element for iteration * * @return mixed current element * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tuple/#method-current */ public function current() {} /** * Current key for iteration * * @return int current key * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tuple/#method-key */ public function key() {} /** * Move internal iterator forward * * @return void * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tuple/#method-next */ public function next() {} /** * Check whether a current value exists * * @return bool * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tuple/#method-valid */ public function valid() {} /** * Rewind internal iterator * * @return void * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tuple/#method-rewind */ public function rewind() {} } /** * A PHP representation of the CQL `smallint` datatype. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/ */ final class Smallint implements Value, Numeric { /** * Creates a new 16-bit signed integer. * * @param int|float|string $value The value as an integer, double or string * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-__construct */ public function __construct($value) {} /** * Minimum possible Smallint value * * @return \Cassandra\Smallint minimum value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-min */ public static function min() {} /** * Maximum possible Smallint value * * @return \Cassandra\Smallint maximum value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-max */ public static function max() {} /** * @return string * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-__toString */ public function __toString() {} /** * The type of this value (smallint). * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-type */ public function type() {} /** * Returns the integer value. * * @return int integer value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-value */ public function value() {} /** * @param \Cassandra\Numeric $num a number to add to this one * * @return \Cassandra\Numeric sum * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-add */ public function add($num) {} /** * @param \Cassandra\Numeric $num a number to subtract from this one * * @return \Cassandra\Numeric difference * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-sub */ public function sub($num) {} /** * @param \Cassandra\Numeric $num a number to multiply this one by * * @return \Cassandra\Numeric product * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-mul */ public function mul($num) {} /** * @param \Cassandra\Numeric $num a number to divide this one by * * @return \Cassandra\Numeric quotient * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-div */ public function div($num) {} /** * @param \Cassandra\Numeric $num a number to divide this one by * * @return \Cassandra\Numeric remainder * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-mod */ public function mod($num) {} /** * @return \Cassandra\Numeric absolute value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-abs */ public function abs() {} /** * @return \Cassandra\Numeric negative value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-neg */ public function neg() {} /** * @return \Cassandra\Numeric square root * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-sqrt */ public function sqrt() {} /** * @return int this number as int * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-toInt */ public function toInt() {} /** * @return float this number as float * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Smallint/#method-toDouble */ public function toDouble() {} } /** * A future returned from `Session::prepareAsync()` * This future will resolve with a PreparedStatement or an exception. * * @see \Cassandra\Session::prepareAsync() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.FuturePreparedStatement/ */ final class FuturePreparedStatement implements Future { /** * Waits for a given future resource to resolve and throws errors if any. * * @param int|float|null $timeout A timeout in seconds * * @return \Cassandra\PreparedStatement A prepared statement * @throws \Cassandra\Exception\TimeoutException * * @throws \Cassandra\Exception\InvalidArgumentException * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.FuturePreparedStatement/#method-get */ public function get($timeout) {} } /** * A PHP representation of a schema * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSchema/ */ final class DefaultSchema implements Schema { /** * Returns a Keyspace instance by name. * * @param string $name Name of the keyspace to get * * @return \Cassandra\Keyspace Keyspace instance or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSchema/#method-keyspace */ public function keyspace($name) {} /** * Returns all keyspaces defined in the schema. * * @return array An array of `Keyspace` instances. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSchema/#method-keyspaces */ public function keyspaces() {} /** * Get the version of the schema snapshot * * @return int Version of the schema. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSchema/#method-version */ public function version() {} } /** * Batch statements are used to execute a series of simple or prepared * statements. * * There are 3 types of batch statements: * * `Cassandra::BATCH_LOGGED` - this is the default batch type. This batch * guarantees that either all or none of its statements will be executed. * This behavior is achieved by writing a batch log on the coordinator, * which slows down the execution somewhat. * * `Cassandra::BATCH_UNLOGGED` - this batch will not be verified when * executed, which makes it faster than a `LOGGED` batch, but means that * some of its statements might fail, while others - succeed. * * `Cassandra::BATCH_COUNTER` - this batch is used for counter updates, * which are, unlike other writes, not idempotent. * * @see Cassandra::BATCH_LOGGED * @see Cassandra::BATCH_UNLOGGED * @see Cassandra::BATCH_COUNTER * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.BatchStatement/ */ final class BatchStatement implements Statement { /** * Creates a new batch statement. * * @param int $type must be one of Cassandra::BATCH_* (default: Cassandra::BATCH_LOGGED). * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.BatchStatement/#method-__construct */ public function __construct($type) {} /** * Adds a statement to this batch. * * @param string|\Cassandra\Statement $statement string or statement to add * @param array|null $arguments positional or named arguments (optional) * * @return \Cassandra\BatchStatement self * @throws \Cassandra\Exception\InvalidArgumentException * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.BatchStatement/#method-add */ public function add($statement, $arguments) {} } /** * A PHP representation of the CQL `list` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/ */ final class Collection implements Value, \Countable, \Iterator { /** * Creates a new collection of a given type. * * @param \Cassandra\Type $type * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-__construct */ public function __construct($type) {} /** * The type of this collection. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-type */ public function type() {} /** * Array of values in this collection. * * @return array values * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-values */ public function values() {} /** * Adds one or more values to this collection. * * @param mixed ...$value one or more values to add * * @return int total number of values in this collection * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-add */ public function add(...$value) {} /** * Retrieves the value at a given index. * * @param int $index Index * * @return mixed Value or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-get */ public function get($index) {} /** * Finds index of a value in this collection. * * @param mixed $value Value * * @return int Index or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-find */ public function find($value) {} /** * Total number of elements in this collection * * @return int count * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-count */ public function count() {} /** * Current element for iteration * * @return mixed current element * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-current */ public function current() {} /** * Current key for iteration * * @return int current key * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-key */ public function key() {} /** * Move internal iterator forward * * @return void * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-next */ public function next() {} /** * Check whether a current value exists * * @return bool * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-valid */ public function valid() {} /** * Rewind internal iterator * * @return void * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-rewind */ public function rewind() {} /** * Deletes the value at a given index * * @param int $index Index * * @return bool Whether the value at a given index is correctly removed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Collection/#method-remove */ public function remove($index) {} } /** * This future results is resolved with Rows. * * @see \Cassandra\Session::executeAsync() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.FutureRows/ */ final class FutureRows implements Future { /** * Waits for a given future resource to resolve and throws errors if any. * * @param int|float|null $timeout A timeout in seconds * * @return \Cassandra\Rows|null The result set * @throws \Cassandra\Exception\TimeoutException * * @throws \Cassandra\Exception\InvalidArgumentException * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.FutureRows/#method-get */ public function get($timeout) {} } /** * A PHP representation of a materialized view * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/ */ final class DefaultMaterializedView extends MaterializedView { /** * Returns the name of this view * * @return string Name of the view * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-name */ public function name() {} /** * Return a view's option by name * * @param string $name The name of the option * * @return \Cassandra\Value Value of an option by name * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-option */ public function option($name) {} /** * Returns all the view's options * * @return array A dictionary of string and Value pairs of the * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-options */ public function options() {} /** * Description of the view, if any * * @return string Table description or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-comment */ public function comment() {} /** * Returns read repair chance * * @return float Read repair chance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-readRepairChance */ public function readRepairChance() {} /** * Returns local read repair chance * * @return float Local read repair chance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-localReadRepairChance */ public function localReadRepairChance() {} /** * Returns GC grace seconds * * @return int GC grace seconds * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-gcGraceSeconds */ public function gcGraceSeconds() {} /** * Returns caching options * * @return string Caching options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-caching */ public function caching() {} /** * Returns bloom filter FP chance * * @return float Bloom filter FP chance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-bloomFilterFPChance */ public function bloomFilterFPChance() {} /** * Returns memtable flush period in milliseconds * * @return int Memtable flush period in milliseconds * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-memtableFlushPeriodMs */ public function memtableFlushPeriodMs() {} /** * Returns default TTL. * * @return int Default TTL. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-defaultTTL */ public function defaultTTL() {} /** * Returns speculative retry. * * @return string Speculative retry. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-speculativeRetry */ public function speculativeRetry() {} /** * Returns index interval * * @return int Index interval * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-indexInterval */ public function indexInterval() {} /** * Returns compaction strategy class name * * @return string Compaction strategy class name * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-compactionStrategyClassName */ public function compactionStrategyClassName() {} /** * Returns compaction strategy options * * @return \Cassandra\Map Compaction strategy options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-compactionStrategyOptions */ public function compactionStrategyOptions() {} /** * Returns compression parameters * * @return \Cassandra\Map Compression parameters * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-compressionParameters */ public function compressionParameters() {} /** * Returns whether or not the `populate_io_cache_on_flush` is true * * @return bool Value of `populate_io_cache_on_flush` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-populateIOCacheOnFlush */ public function populateIOCacheOnFlush() {} /** * Returns whether or not the `replicate_on_write` is true * * @return bool Value of `replicate_on_write` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-replicateOnWrite */ public function replicateOnWrite() {} /** * Returns the value of `max_index_interval` * * @return int Value of `max_index_interval` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-maxIndexInterval */ public function maxIndexInterval() {} /** * Returns the value of `min_index_interval` * * @return int Value of `min_index_interval` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-minIndexInterval */ public function minIndexInterval() {} /** * Returns column by name * * @param string $name Name of the column * * @return \Cassandra\Column Column instance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-column */ public function column($name) {} /** * Returns all columns in this view * * @return array A list of Column instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-columns */ public function columns() {} /** * Returns the partition key columns of the view * * @return array A list of Column instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-partitionKey */ public function partitionKey() {} /** * Returns both the partition and clustering key columns of the view * * @return array A list of Column instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-primaryKey */ public function primaryKey() {} /** * Returns the clustering key columns of the view * * @return array A list of Column instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-clusteringKey */ public function clusteringKey() {} /** * @return array A list of cluster column orders ('asc' and 'desc') * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-clusteringOrder */ public function clusteringOrder() {} /** * Returns the base table of the view * * @return \Cassandra\Table Base table of the view * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultMaterializedView/#method-baseTable */ public function baseTable() {} } /** * SSL options for Cluster. * * @see \Cassandra\SSLOptions\Builder * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.SSLOptions/ */ final class SSLOptions {} /** * A PHP representation of the CQL `bigint` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/ */ final class Bigint implements Value, Numeric { /** * Creates a new 64bit integer. * * @param string $value integer value as a string * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-__construct */ public function __construct($value) {} /** * Minimum possible Bigint value * * @return \Cassandra\Bigint minimum value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-min */ public static function min() {} /** * Maximum possible Bigint value * * @return \Cassandra\Bigint maximum value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-max */ public static function max() {} /** * Returns string representation of the integer value. * * @return string integer value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-__toString */ public function __toString() {} /** * The type of this bigint. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-type */ public function type() {} /** * Returns the integer value. * * @return string integer value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-value */ public function value() {} /** * @param \Cassandra\Numeric $num a number to add to this one * * @return \Cassandra\Numeric sum * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-add */ public function add($num) {} /** * @param \Cassandra\Numeric $num a number to subtract from this one * * @return \Cassandra\Numeric difference * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-sub */ public function sub($num) {} /** * @param \Cassandra\Numeric $num a number to multiply this one by * * @return \Cassandra\Numeric product * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-mul */ public function mul($num) {} /** * @param \Cassandra\Numeric $num a number to divide this one by * * @return \Cassandra\Numeric quotient * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-div */ public function div($num) {} /** * @param \Cassandra\Numeric $num a number to divide this one by * * @return \Cassandra\Numeric remainder * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-mod */ public function mod($num) {} /** * @return \Cassandra\Numeric absolute value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-abs */ public function abs() {} /** * @return \Cassandra\Numeric negative value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-neg */ public function neg() {} /** * @return \Cassandra\Numeric square root * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-sqrt */ public function sqrt() {} /** * @return int this number as int * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-toInt */ public function toInt() {} /** * @return float this number as float * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Bigint/#method-toDouble */ public function toDouble() {} } /** * A future that resolves with Session. * * @see \Cassandra\Cluster::connectAsync() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.FutureSession/ */ final class FutureSession implements Future { /** * Waits for a given future resource to resolve and throws errors if any. * * @param int|float|null $timeout A timeout in seconds * * @return \Cassandra\Session A connected session * @throws \Cassandra\Exception\TimeoutException * * @throws \Cassandra\Exception\InvalidArgumentException * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.FutureSession/#method-get */ public function get($timeout) {} } /** * A PHP representation of the CQL `set` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/ */ final class Set implements Value, \Countable, \Iterator { /** * Creates a new collection of a given type. * * @param \Cassandra\Type $type * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/#method-__construct */ public function __construct($type) {} /** * The type of this set. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/#method-type */ public function type() {} /** * Array of values in this set. * * @return array values * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/#method-values */ public function values() {} /** * Adds a value to this set. * * @param mixed $value Value * * @return bool whether the value has been added * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/#method-add */ public function add($value) {} /** * Returns whether a value is in this set. * * @param mixed $value Value * * @return bool whether the value is in the set * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/#method-has */ public function has($value) {} /** * Removes a value to this set. * * @param mixed $value Value * * @return bool whether the value has been removed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/#method-remove */ public function remove($value) {} /** * Total number of elements in this set * * @return int count * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/#method-count */ public function count() {} /** * Current element for iteration * * @return mixed current element * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/#method-current */ public function current() {} /** * Current key for iteration * * @return int current key * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/#method-key */ public function key() {} /** * Move internal iterator forward * * @return void * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/#method-next */ public function next() {} /** * Check whether a current value exists * * @return bool * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/#method-valid */ public function valid() {} /** * Rewind internal iterator * * @return void * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Set/#method-rewind */ public function rewind() {} } /** * A PHP representation of an index * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultIndex/ */ final class DefaultIndex implements Index { /** * Returns the name of the index * * @return string Name of the index * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultIndex/#method-name */ public function name() {} /** * Returns the kind of index * * @return string Kind of the index * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultIndex/#method-kind */ public function kind() {} /** * Returns the target column of the index * * @return string Target column name of the index * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultIndex/#method-target */ public function target() {} /** * Return a column's option by name * * @param string $name The name of the option * * @return \Cassandra\Value Value of an option by name * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultIndex/#method-option */ public function option($name) {} /** * Returns all the index's options * * @return array A dictionary of `string` and `Value` pairs of the index's options. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultIndex/#method-options */ public function options() {} /** * Returns the class name of the index * * @return string Class name of a custom index * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultIndex/#method-className */ public function className() {} /** * Determines if the index is a custom index. * * @return bool true if a custom index * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultIndex/#method-isCustom */ public function isCustom() {} } /** * A PHP representation of an aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultAggregate/ */ final class DefaultAggregate implements Aggregate { /** * Returns the full name of the aggregate * * @return string Full name of the aggregate including name and types * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultAggregate/#method-name */ public function name() {} /** * Returns the simple name of the aggregate * * @return string Simple name of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultAggregate/#method-simpleName */ public function simpleName() {} /** * Returns the argument types of the aggregate * * @return array Argument types of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultAggregate/#method-argumentTypes */ public function argumentTypes() {} /** * Returns the state function of the aggregate * * @return \Cassandra\Function_ State public function of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultAggregate/#method-stateFunction */ public function stateFunction() {} /** * Returns the final function of the aggregate * * @return \Cassandra\Function_ Final public function of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultAggregate/#method-finalFunction */ public function finalFunction() {} /** * Returns the initial condition of the aggregate * * @return \Cassandra\Value Initial condition of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultAggregate/#method-initialCondition */ public function initialCondition() {} /** * Returns the state type of the aggregate * * @return \Cassandra\Type State type of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultAggregate/#method-stateType */ public function stateType() {} /** * Returns the return type of the aggregate * * @return \Cassandra\Type Return type of the aggregate * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultAggregate/#method-returnType */ public function returnType() {} /** * Returns the signature of the aggregate * * @return string Signature of the aggregate (same as name()) * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultAggregate/#method-signature */ public function signature() {} } /** * A PHP representation of the CQL `timestamp` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timestamp/ */ final class Timestamp implements Value { /** * Creates a new timestamp from either unix timestamp and microseconds or * from the current time by default. * * @param int $seconds The number of seconds * @param int $microseconds The number of microseconds * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timestamp/#method-__construct */ public function __construct($seconds, $microseconds) {} /** * The type of this timestamp. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timestamp/#method-type */ public function type() {} /** * Unix timestamp. * * @return int seconds * * @see time * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timestamp/#method-time */ public function time() {} /** * Microtime from this timestamp * * @param bool $get_as_float Whether to get this value as float * * @return float|string Float or string representation * * @see microtime * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timestamp/#method-microtime */ public function microtime($get_as_float) {} /** * Converts current timestamp to PHP DateTime. * * @return \DateTime PHP representation * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timestamp/#method-toDateTime */ public function toDateTime() {} /** * Returns a string representation of this timestamp. * * @return string timestamp * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timestamp/#method-__toString */ public function __toString() {} } /** * A PHP representation of the CQL `tinyint` datatype. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/ */ final class Tinyint implements Value, Numeric { /** * Creates a new 8-bit signed integer. * * @param int|float|string $value The value as an integer, float or string * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-__construct */ public function __construct($value) {} /** * Minimum possible Tinyint value * * @return \Cassandra\Tinyint minimum value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-min */ public static function min() {} /** * Maximum possible Tinyint value * * @return \Cassandra\Tinyint maximum value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-max */ public static function max() {} /** * @return string * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-__toString */ public function __toString() {} /** * The type of this value (tinyint). * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-type */ public function type() {} /** * Returns the integer value. * * @return int integer value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-value */ public function value() {} /** * @param \Cassandra\Numeric $num a number to add to this one * * @return \Cassandra\Numeric sum * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-add */ public function add($num) {} /** * @param \Cassandra\Numeric $num a number to subtract from this one * * @return \Cassandra\Numeric difference * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-sub */ public function sub($num) {} /** * @param \Cassandra\Numeric $num a number to multiply this one by * * @return \Cassandra\Numeric product * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-mul */ public function mul($num) {} /** * @param \Cassandra\Numeric $num a number to divide this one by * * @return \Cassandra\Numeric quotient * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-div */ public function div($num) {} /** * @param \Cassandra\Numeric $num a number to divide this one by * * @return \Cassandra\Numeric remainder * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-mod */ public function mod($num) {} /** * @return \Cassandra\Numeric absolute value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-abs */ public function abs() {} /** * @return \Cassandra\Numeric negative value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-neg */ public function neg() {} /** * @return \Cassandra\Numeric square root * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-sqrt */ public function sqrt() {} /** * @return int this number as int * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-toInt */ public function toInt() {} /** * @return float this number as float * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Tinyint/#method-toDouble */ public function toDouble() {} } /** * A PHP representation of the CQL `timeuuid` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timeuuid/ */ final class Timeuuid implements Value, UuidInterface { /** * Creates a timeuuid from a given timestamp or current time. * * @param int $timestamp Unix timestamp * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timeuuid/#method-__construct */ public function __construct($timestamp) {} /** * Returns this timeuuid as string. * * @return string timeuuid * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timeuuid/#method-__toString */ public function __toString() {} /** * The type of this timeuuid. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timeuuid/#method-type */ public function type() {} /** * Returns this timeuuid as string. * * @return string timeuuid * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timeuuid/#method-uuid */ public function uuid() {} /** * Returns the version of this timeuuid. * * @return int version of this timeuuid * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timeuuid/#method-version */ public function version() {} /** * Unix timestamp. * * @return int seconds * * @see time * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timeuuid/#method-time */ public function time() {} /** * Converts current timeuuid to PHP DateTime. * * @return \DateTime PHP representation * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Timeuuid/#method-toDateTime */ public function toDateTime() {} } /** * A session is used to prepare and execute statements. * * @see \Cassandra\Cluster::connect() * @see \Cassandra\Cluster::connectAsync() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSession/ */ final class DefaultSession implements Session { /** * Execute a query. * * Available execution options: * | Option Name | Option **Type** | Option Details | * |--------------------|-----------------|----------------------------------------------------------------------------------------------------------| * | arguments | array | An array or positional or named arguments | * | consistency | int | A consistency constant e.g Dse::CONSISTENCY_ONE, Dse::CONSISTENCY_QUORUM, etc. | * | timeout | int | A number of rows to include in result for paging | * | paging_state_token | string | A string token use to resume from the state of a previous result set | * | retry_policy | RetryPolicy | A retry policy that is used to handle server-side failures for this request | * | serial_consistency | int | Either Dse::CONSISTENCY_SERIAL or Dse::CONSISTENCY_LOCAL_SERIAL | * | timestamp | int\|string | Either an integer or integer string timestamp that represents the number of microseconds since the epoch | * | execute_as | string | User to execute statement as | * * @param string|\Cassandra\Statement $statement string or statement to be executed. * @param array|\Cassandra\ExecutionOptions|null $options Options to control execution of the query. * * @return \Cassandra\Rows A collection of rows. * @throws \Cassandra\Exception * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSession/#method-execute */ public function execute($statement, $options) {} /** * Execute a query asynchronously. This method returns immediately, but * the query continues execution in the background. * * @param string|\Cassandra\Statement $statement string or statement to be executed. * @param array|\Cassandra\ExecutionOptions|null $options Options to control execution of the query. * * @return \Cassandra\FutureRows A future that can be used to retrieve the result. * * @see \Cassandra\Session::execute() for valid execution options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSession/#method-executeAsync */ public function executeAsync($statement, $options) {} /** * Prepare a query for execution. * * @param string $cql The query to be prepared. * @param array|\Cassandra\ExecutionOptions|null $options Options to control preparing the query. * * @return \Cassandra\PreparedStatement A prepared statement that can be bound with parameters and executed. * * @throws \Cassandra\Exception * * @see \Cassandra\Session::execute() for valid execution options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSession/#method-prepare */ public function prepare($cql, $options) {} /** * Asynchronously prepare a query for execution. * * @param string $cql The query to be prepared. * @param array|\Cassandra\ExecutionOptions|null $options Options to control preparing the query. * * @return \Cassandra\FuturePreparedStatement A future that can be used to retrieve the prepared statement. * * @see \Cassandra\Session::execute() for valid execution options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSession/#method-prepareAsync */ public function prepareAsync($cql, $options) {} /** * Close the session and all its connections. * * @param float $timeout The amount of time in seconds to wait for the session to close. * * @return null Nothing. * @throws \Cassandra\Exception * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSession/#method-close */ public function close($timeout) {} /** * Asynchronously close the session and all its connections. * * @return \Cassandra\FutureClose A future that can be waited on. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSession/#method-closeAsync */ public function closeAsync() {} /** * Get performance and diagnostic metrics. * * @return array Performance/Diagnostic metrics. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSession/#method-metrics */ public function metrics() {} /** * Get a snapshot of the cluster's current schema. * * @return \Cassandra\Schema A snapshot of the cluster's schema. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultSession/#method-schema */ public function schema() {} } /** * A class for representing custom values. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Custom/ */ abstract class Custom implements Value { /** * The type of this value. * * @return \Cassandra\Type\Custom * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Custom/#method-type */ abstract public function type(); } /** * A PHP representation of a materialized view * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/ */ abstract class MaterializedView implements Table { /** * Returns the base table of the view * * @return \Cassandra\Table Base table of the view * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-baseTable */ abstract public function baseTable(); /** * Returns the name of this view * * @return string Name of the view * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-name */ abstract public function name(); /** * Return a view's option by name * * @param string $name The name of the option * * @return \Cassandra\Value Value of an option by name * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-option */ abstract public function option($name); /** * Returns all the view's options * * @return array A dictionary of string and Value pairs of the * view's options. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-options */ abstract public function options(); /** * Description of the view, if any * * @return string View description or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-comment */ abstract public function comment(); /** * Returns read repair chance * * @return float Read repair chance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-readRepairChance */ abstract public function readRepairChance(); /** * Returns local read repair chance * * @return float Local read repair chance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-localReadRepairChance */ abstract public function localReadRepairChance(); /** * Returns GC grace seconds * * @return int GC grace seconds * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-gcGraceSeconds */ abstract public function gcGraceSeconds(); /** * Returns caching options * * @return string Caching options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-caching */ abstract public function caching(); /** * Returns bloom filter FP chance * * @return float Bloom filter FP chance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-bloomFilterFPChance */ abstract public function bloomFilterFPChance(); /** * Returns memtable flush period in milliseconds * * @return int Memtable flush period in milliseconds * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-memtableFlushPeriodMs */ abstract public function memtableFlushPeriodMs(); /** * Returns default TTL. * * @return int Default TTL. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-defaultTTL */ abstract public function defaultTTL(); /** * Returns speculative retry. * * @return string Speculative retry. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-speculativeRetry */ abstract public function speculativeRetry(); /** * Returns index interval * * @return int Index interval * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-indexInterval */ abstract public function indexInterval(); /** * Returns compaction strategy class name * * @return string Compaction strategy class name * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-compactionStrategyClassName */ abstract public function compactionStrategyClassName(); /** * Returns compaction strategy options * * @return \Cassandra\Map Compaction strategy options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-compactionStrategyOptions */ abstract public function compactionStrategyOptions(); /** * Returns compression parameters * * @return \Cassandra\Map Compression parameters * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-compressionParameters */ abstract public function compressionParameters(); /** * Returns whether or not the `populate_io_cache_on_flush` is true * * @return bool Value of `populate_io_cache_on_flush` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-populateIOCacheOnFlush */ abstract public function populateIOCacheOnFlush(); /** * Returns whether or not the `replicate_on_write` is true * * @return bool Value of `replicate_on_write` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-replicateOnWrite */ abstract public function replicateOnWrite(); /** * Returns the value of `max_index_interval` * * @return int Value of `max_index_interval` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-maxIndexInterval */ abstract public function maxIndexInterval(); /** * Returns the value of `min_index_interval` * * @return int Value of `min_index_interval` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-minIndexInterval */ abstract public function minIndexInterval(); /** * Returns column by name * * @param string $name Name of the column * * @return \Cassandra\Column Column instance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-column */ abstract public function column($name); /** * Returns all columns in this view * * @return array A list of `Column` instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-columns */ abstract public function columns(); /** * Returns the partition key columns of the view * * @return array A list of `Column` instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-partitionKey */ abstract public function partitionKey(); /** * Returns both the partition and clustering key columns of the view * * @return array A list of `Column` instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-primaryKey */ abstract public function primaryKey(); /** * Returns the clustering key columns of the view * * @return array A list of `Column` instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-clusteringKey */ abstract public function clusteringKey(); /** * @return array A list of cluster column orders ('asc' and 'desc') * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.MaterializedView/#method-clusteringOrder */ abstract public function clusteringOrder(); } /** * A PHP representation of the CQL `time` type. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Time/ */ final class Time implements Value { /** * Creates a new Time object * * @param int|string $nanoseconds Number of nanoseconds since last microsecond * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Time/#method-__construct */ public function __construct($nanoseconds) {} /** * @param \DateTime $datetime * * @return \Cassandra\Time * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Time/#method-fromDateTime */ public static function fromDateTime($datetime) {} /** * The type of this date. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Time/#method-type */ public function type() {} /** * @return int * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Time/#method-seconds */ public function seconds() {} /** * @return string this date in string format: Time(nanoseconds=$nanoseconds) * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Time/#method-__toString */ public function __toString() {} } /** * Cluster object is used to create Sessions. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/ */ abstract class Type { /** * Get representation of ascii type * * @return \Cassandra\Type ascii type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-ascii */ final public static function ascii() {} /** * Get representation of bigint type * * @return \Cassandra\Type bigint type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-bigint */ final public static function bigint() {} /** * Get representation of smallint type * * @return \Cassandra\Type smallint type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-smallint */ final public static function smallint() {} /** * Get representation of tinyint type * * @return \Cassandra\Type tinyint type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-tinyint */ final public static function tinyint() {} /** * Get representation of blob type * * @return \Cassandra\Type blob type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-blob */ final public static function blob() {} /** * Get representation of boolean type * * @return \Cassandra\Type boolean type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-boolean */ final public static function boolean() {} /** * Get representation of counter type * * @return \Cassandra\Type counter type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-counter */ final public static function counter() {} /** * Get representation of decimal type * * @return \Cassandra\Type decimal type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-decimal */ final public static function decimal() {} /** * Get representation of double type * * @return \Cassandra\Type double type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-double */ final public static function double() {} /** * Get representation of duration type * * @return \Cassandra\Type duration type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-duration */ final public static function duration() {} /** * Get representation of float type * * @return \Cassandra\Type float type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-float */ final public static function float() {} /** * Get representation of int type * * @return \Cassandra\Type int type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-int */ final public static function int() {} /** * Get representation of text type * * @return \Cassandra\Type text type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-text */ final public static function text() {} /** * Get representation of timestamp type * * @return \Cassandra\Type timestamp type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-timestamp */ final public static function timestamp() {} /** * Get representation of date type * * @return \Cassandra\Type date type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-date */ final public static function date() {} /** * Get representation of time type * * @return \Cassandra\Type time type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-time */ final public static function time() {} /** * Get representation of uuid type * * @return \Cassandra\Type uuid type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-uuid */ final public static function uuid() {} /** * Get representation of varchar type * * @return \Cassandra\Type varchar type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-varchar */ final public static function varchar() {} /** * Get representation of varint type * * @return \Cassandra\Type varint type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-varint */ final public static function varint() {} /** * Get representation of timeuuid type * * @return \Cassandra\Type timeuuid type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-timeuuid */ final public static function timeuuid() {} /** * Get representation of inet type * * @return \Cassandra\Type inet type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-inet */ final public static function inet() {} /** * Initialize a Collection type * ```php * create(1, 2, 3, 4, 5, 6, 7, 8, 9); * * var_dump($collection); * ``` * * @param \Cassandra\Type $type The type of values * * @return \Cassandra\Type The collection type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-collection */ final public static function collection($type) {} /** * Initialize a set type * ``` * create("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"); * * var_dump($set); * ``` * * @param \Cassandra\Type $type The types of values * * @return \Cassandra\Type The set type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-set */ final public static function set($type) {} /** * Initialize a map type * ```create(1, "a", 2, "b", 3, "c", 4, "d", 5, "e", 6, "f") * * var_dump($map);``` * * @param \Cassandra\Type $keyType The type of keys * @param \Cassandra\Type $valueType The type of values * * @return \Cassandra\Type The map type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-map */ final public static function map($keyType, $valueType) {} /** * Initialize a tuple type * ```create("a", 123); * * var_dump($tuple);``` * * @param \Cassandra\Type $types A variadic list of types * * @return \Cassandra\Type The tuple type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-tuple */ final public static function tuple($types) {} /** * Initialize a user type * ```create("a", "abc", "b", 123); * * var_dump($userType);``` * * @param \Cassandra\Type $types A variadic list of name/type pairs * * @return \Cassandra\Type The user type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-userType */ final public static function userType($types) {} /** * Returns the name of this type as string. * * @return string Name of this type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-name */ abstract public function name(); /** * Returns string representation of this type. * * @return string String representation of this type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Type/#method-__toString */ abstract public function __toString(); } /** * A PHP representation of the CQL `varint` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/ */ final class Varint implements Value, Numeric { /** * Creates a new variable length integer. * * @param string $value integer value as a string * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-__construct */ public function __construct($value) {} /** * Returns the integer value. * * @return string integer value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-__toString */ public function __toString() {} /** * The type of this varint. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-type */ public function type() {} /** * Returns the integer value. * * @return string integer value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-value */ public function value() {} /** * @param \Cassandra\Numeric $num a number to add to this one * * @return \Cassandra\Numeric sum * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-add */ public function add($num) {} /** * @param \Cassandra\Numeric $num a number to subtract from this one * * @return \Cassandra\Numeric difference * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-sub */ public function sub($num) {} /** * @param \Cassandra\Numeric $num a number to multiply this one by * * @return \Cassandra\Numeric product * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-mul */ public function mul($num) {} /** * @param \Cassandra\Numeric $num a number to divide this one by * * @return \Cassandra\Numeric quotient * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-div */ public function div($num) {} /** * @param \Cassandra\Numeric $num a number to divide this one by * * @return \Cassandra\Numeric remainder * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-mod */ public function mod($num) {} /** * @return \Cassandra\Numeric absolute value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-abs */ public function abs() {} /** * @return \Cassandra\Numeric negative value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-neg */ public function neg() {} /** * @return \Cassandra\Numeric square root * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-sqrt */ public function sqrt() {} /** * @return int this number as int * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-toInt */ public function toInt() {} /** * @return float this number as float * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Varint/#method-toDouble */ public function toDouble() {} } /** * A PHP representation of the CQL `map` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/ */ final class Map implements Value, \Countable, \Iterator, \ArrayAccess { /** * Creates a new map of a given key and value type. * * @param \Cassandra\Type $keyType * @param \Cassandra\Type $valueType * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-__construct */ public function __construct($keyType, $valueType) {} /** * The type of this map. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-type */ public function type() {} /** * Returns all keys in the map as an array. * * @return array keys * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-keys */ public function keys() {} /** * Returns all values in the map as an array. * * @return array values * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-values */ public function values() {} /** * Sets key/value in the map. * * @param mixed $key key * @param mixed $value value * * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-set */ public function set($key, $value) {} /** * Gets the value of the key in the map. * * @param mixed $key Key * * @return mixed Value or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-get */ public function get($key) {} /** * Removes the key from the map. * * @param mixed $key Key * * @return bool Whether the key was removed or not, e.g. didn't exist * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-remove */ public function remove($key) {} /** * Returns whether the key is in the map. * * @param mixed $key Key * * @return bool Whether the key is in the map or not * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-has */ public function has($key) {} /** * Total number of elements in this map * * @return int count * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-count */ public function count() {} /** * Current value for iteration * * @return mixed current value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-current */ public function current() {} /** * Current key for iteration * * @return int current key * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-key */ public function key() {} /** * Move internal iterator forward * * @return void * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-next */ public function next() {} /** * Check whether a current value exists * * @return bool * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-valid */ public function valid() {} /** * Rewind internal iterator * * @return void * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-rewind */ public function rewind() {} /** * Sets the value at a given key * * @param mixed $key Key to use. * @param mixed $value Value to set. * * @return void * @throws \Cassandra\Exception\InvalidArgumentException when the type of key or value is wrong * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-offsetSet */ public function offsetSet($key, $value) {} /** * Retrieves the value at a given key * * @param mixed $key Key to use. * * @return mixed Value or `null` * @throws \Cassandra\Exception\InvalidArgumentException when the type of key is wrong * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-offsetGet */ public function offsetGet($key) {} /** * Deletes the value at a given key * * @param mixed $key Key to use. * * @return void * @throws \Cassandra\Exception\InvalidArgumentException when the type of key is wrong * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-offsetUnset */ public function offsetUnset($key) {} /** * Returns whether the value a given key is present * * @param mixed $key Key to use. * * @return bool Whether the value at a given key is present * @throws \Cassandra\Exception\InvalidArgumentException when the type of key is wrong * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Map/#method-offsetExists */ public function offsetExists($key) {} } /** * A PHP representation of the CQL `uuid` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Uuid/ */ final class Uuid implements Value, UuidInterface { /** * Creates a uuid from a given uuid string or a random one. * * @param string $uuid A uuid string * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Uuid/#method-__construct */ public function __construct($uuid) {} /** * Returns this uuid as string. * * @return string uuid * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Uuid/#method-__toString */ public function __toString() {} /** * The type of this uuid. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Uuid/#method-type */ public function type() {} /** * Returns this uuid as string. * * @return string uuid * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Uuid/#method-uuid */ public function uuid() {} /** * Returns the version of this uuid. * * @return int version of this uuid * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Uuid/#method-version */ public function version() {} } /** * A PHP representation of the CQL `float` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/ */ final class Float_ implements Value, Numeric { /** * Creates a new float. * * @param float|int|string|\Cassandra\Float_ $value A float value as a string, number or Float * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-__construct */ public function __construct($value) {} /** * Minimum possible Float value * * @return \Cassandra\Float_ minimum value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-min */ public static function min() {} /** * Maximum possible Float value * * @return \Cassandra\Float_ maximum value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-max */ public static function max() {} /** * Returns string representation of the float value. * * @return string float value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-__toString */ public function __toString() {} /** * The type of this float. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-type */ public function type() {} /** * Returns the float value. * * @return float float value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-value */ public function value() {} /** * @return bool * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-isInfinite */ public function isInfinite() {} /** * @return bool * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-isFinite */ public function isFinite() {} /** * @return bool * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-isNaN */ public function isNaN() {} /** * @param \Cassandra\Numeric $num a number to add to this one * * @return \Cassandra\Numeric sum * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-add */ public function add($num) {} /** * @param \Cassandra\Numeric $num a number to subtract from this one * * @return \Cassandra\Numeric difference * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-sub */ public function sub($num) {} /** * @param \Cassandra\Numeric $num a number to multiply this one by * * @return \Cassandra\Numeric product * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-mul */ public function mul($num) {} /** * @param \Cassandra\Numeric $num a number to divide this one by * * @return \Cassandra\Numeric quotient * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-div */ public function div($num) {} /** * @param \Cassandra\Numeric $num a number to divide this one by * * @return \Cassandra\Numeric remainder * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-mod */ public function mod($num) {} /** * @return \Cassandra\Numeric absolute value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-abs */ public function abs() {} /** * @return \Cassandra\Numeric negative value * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-neg */ public function neg() {} /** * @return \Cassandra\Numeric square root * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-sqrt */ public function sqrt() {} /** * @return int this number as int * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-toInt */ public function toInt() {} /** * @return float this number as float * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Float/#method-toDouble */ public function toDouble() {} } /** * A PHP representation of the CQL `duration` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Duration/ */ final class Duration implements Value { /** * @param int|float|string|\Cassandra\Bigint $months Months attribute of the duration. * @param int|float|string|\Cassandra\Bigint $days Days attribute of the duration. * @param int|float|string|\Cassandra\Bigint $nanos Nanos attribute of the duration. * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Duration/#method-__construct */ public function __construct($months, $days, $nanos) {} /** * The type of represented by the value. * * @return \Cassandra\Type the Cassandra type for Duration * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Duration/#method-type */ public function type() {} /** * @return string the months attribute of this Duration * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Duration/#method-months */ public function months() {} /** * @return string the days attribute of this Duration * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Duration/#method-days */ public function days() {} /** * @return string the nanoseconds attribute of this Duration * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Duration/#method-nanos */ public function nanos() {} /** * @return string string representation of this Duration; may be used as a literal parameter in CQL queries. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Duration/#method-__toString */ public function __toString() {} } /** * A PHP representation of a keyspace * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/ */ final class DefaultKeyspace implements Keyspace { /** * Returns keyspace name * * @return string Name * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-name */ public function name() {} /** * Returns replication class name * * @return string Replication class * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-replicationClassName */ public function replicationClassName() {} /** * Returns replication options * * @return \Cassandra\Map Replication options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-replicationOptions */ public function replicationOptions() {} /** * Returns whether the keyspace has durable writes enabled * * @return string Whether durable writes are enabled * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-hasDurableWrites */ public function hasDurableWrites() {} /** * Returns a table by name * * @param string $name Table name * * @return \Cassandra\Table * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-table */ public function table($name) {} /** * Returns all tables defined in this keyspace * * @return array An array of `Table` instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-tables */ public function tables() {} /** * Get user type by name * * @param string $name User type name * * @return \Cassandra\Type\UserType|null A user type or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-userType */ public function userType($name) {} /** * Get all user types * * @return array An array of user types * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-userTypes */ public function userTypes() {} /** * Get materialized view by name * * @param string $name Materialized view name * * @return \Cassandra\MaterializedView|null A materialized view or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-materializedView */ public function materializedView($name) {} /** * Gets all materialized views * * @return array An array of materialized views * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-materializedViews */ public function materializedViews() {} /** * Get a function by name and signature * * @param string $name Function name * @param string|\Cassandra\Type $params Function arguments * * @return \Cassandra\Function_|null A function or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-function */ public function function_($name, ...$params) {} /** * Get all functions * * @return array An array of functions * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-functions */ public function functions() {} /** * Get an aggregate by name and signature * * @param string $name Aggregate name * @param string|\Cassandra\Type $params Aggregate arguments * * @return \Cassandra\Aggregate|null An aggregate or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-aggregate */ public function aggregate($name, ...$params) {} /** * Get all aggregates * * @return array An array of aggregates * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultKeyspace/#method-aggregates */ public function aggregates() {} } /** * A PHP representation of the CQL `inet` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Inet/ */ final class Inet implements Value { /** * Creates a new IPv4 or IPv6 inet address. * * @param string $address any IPv4 or IPv6 address * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Inet/#method-__construct */ public function __construct($address) {} /** * Returns the normalized string representation of the address. * * @return string address * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Inet/#method-__toString */ public function __toString() {} /** * The type of this inet. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Inet/#method-type */ public function type() {} /** * Returns the normalized string representation of the address. * * @return string address * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Inet/#method-address */ public function address() {} } /** * A PHP representation of the CQL `date` type. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Date/ */ final class Date implements Value { /** * Creates a new Date object * * @param int $seconds Absolute seconds from epoch (1970, 1, 1), can be negative, defaults to current time. * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Date/#method-__construct */ public function __construct($seconds) {} /** * Creates a new Date object from a \DateTime object. * * @param \DateTime $datetime A \DateTime object to convert. * * @return \DateTime PHP representation * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Date/#method-fromDateTime */ public static function fromDateTime($datetime) {} /** * The type of this date. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Date/#method-type */ public function type() {} /** * @return int Absolute seconds from epoch (1970, 1, 1), can be negative * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Date/#method-seconds */ public function seconds() {} /** * Converts current date to PHP DateTime. * * @param \Cassandra\Time $time An optional Time object that is added to the DateTime object. * * @return \DateTime PHP representation * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Date/#method-toDateTime */ public function toDateTime($time) {} /** * @return string this date in string format: Date(seconds=$seconds) * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Date/#method-__toString */ public function __toString() {} } /** * A PHP representation of a column * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultColumn/ */ final class DefaultColumn implements Column { /** * Returns the name of the column. * * @return string Name of the column or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultColumn/#method-name */ public function name() {} /** * Returns the type of the column. * * @return \Cassandra\Type Type of the column * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultColumn/#method-type */ public function type() {} /** * Returns whether the column is in descending or ascending order. * * @return bool Whether the column is stored in descending order. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultColumn/#method-isReversed */ public function isReversed() {} /** * Returns true for static columns. * * @return bool Whether the column is static * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultColumn/#method-isStatic */ public function isStatic() {} /** * Returns true for frozen columns. * * @return bool Whether the column is frozen * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultColumn/#method-isFrozen */ public function isFrozen() {} /** * Returns name of the index if defined. * * @return string Name of the index if defined or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultColumn/#method-indexName */ public function indexName() {} /** * Returns index options if present. * * @return string Index options if present or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultColumn/#method-indexOptions */ public function indexOptions() {} } /** * A PHP representation of the CQL `blob` datatype * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Blob/ */ final class Blob implements Value { /** * Creates a new bytes array. * * @param string $bytes any bytes * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Blob/#method-__construct */ public function __construct($bytes) {} /** * Returns bytes as a hex string. * * @return string bytes as hexadecimal string * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Blob/#method-__toString */ public function __toString() {} /** * The type of this blob. * * @return \Cassandra\Type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Blob/#method-type */ public function type() {} /** * Returns bytes as a hex string. * * @return string bytes as hexadecimal string * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Blob/#method-bytes */ public function bytes() {} /** * Returns bytes as a binary string. * * @return string bytes as binary string * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Blob/#method-toBinaryString */ public function toBinaryString() {} } /** * A PHP representation of a table * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/ */ final class DefaultTable implements Table { /** * Returns the name of this table * * @return string Name of the table * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-name */ public function name() {} /** * Return a table's option by name * * @param string $name The name of the option * * @return \Cassandra\Value Value of an option by name * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-option */ public function option($name) {} /** * Returns all the table's options * * @return array A dictionary of `string` and `Value` pairs of the table's options. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-options */ public function options() {} /** * Description of the table, if any * * @return string Table description or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-comment */ public function comment() {} /** * Returns read repair chance * * @return float Read repair chance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-readRepairChance */ public function readRepairChance() {} /** * Returns local read repair chance * * @return float Local read repair chance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-localReadRepairChance */ public function localReadRepairChance() {} /** * Returns GC grace seconds * * @return int GC grace seconds * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-gcGraceSeconds */ public function gcGraceSeconds() {} /** * Returns caching options * * @return string Caching options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-caching */ public function caching() {} /** * Returns bloom filter FP chance * * @return float Bloom filter FP chance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-bloomFilterFPChance */ public function bloomFilterFPChance() {} /** * Returns memtable flush period in milliseconds * * @return int Memtable flush period in milliseconds * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-memtableFlushPeriodMs */ public function memtableFlushPeriodMs() {} /** * Returns default TTL. * * @return int Default TTL. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-defaultTTL */ public function defaultTTL() {} /** * Returns speculative retry. * * @return string Speculative retry. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-speculativeRetry */ public function speculativeRetry() {} /** * Returns index interval * * @return int Index interval * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-indexInterval */ public function indexInterval() {} /** * Returns compaction strategy class name * * @return string Compaction strategy class name * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-compactionStrategyClassName */ public function compactionStrategyClassName() {} /** * Returns compaction strategy options * * @return \Cassandra\Map Compaction strategy options * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-compactionStrategyOptions */ public function compactionStrategyOptions() {} /** * Returns compression parameters * * @return \Cassandra\Map Compression parameters * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-compressionParameters */ public function compressionParameters() {} /** * Returns whether or not the `populate_io_cache_on_flush` is true * * @return bool Value of `populate_io_cache_on_flush` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-populateIOCacheOnFlush */ public function populateIOCacheOnFlush() {} /** * Returns whether or not the `replicate_on_write` is true * * @return bool Value of `replicate_on_write` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-replicateOnWrite */ public function replicateOnWrite() {} /** * Returns the value of `max_index_interval` * * @return int Value of `max_index_interval` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-maxIndexInterval */ public function maxIndexInterval() {} /** * Returns the value of `min_index_interval` * * @return int Value of `min_index_interval` or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-minIndexInterval */ public function minIndexInterval() {} /** * Returns column by name * * @param string $name Name of the column * * @return \Cassandra\Column Column instance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-column */ public function column($name) {} /** * Returns all columns in this table * * @return array A list of `Column` instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-columns */ public function columns() {} /** * Returns the partition key columns of the table * * @return array A list of `Column` instance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-partitionKey */ public function partitionKey() {} /** * Returns both the partition and clustering key columns of the table * * @return array A list of `Column` instance * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-primaryKey */ public function primaryKey() {} /** * Returns the clustering key columns of the table * * @return array A list of `Column` instances * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-clusteringKey */ public function clusteringKey() {} /** * @return array A list of cluster column orders ('asc' and 'desc') * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-clusteringOrder */ public function clusteringOrder() {} /** * Get an index by name * * @param string $name Index name * * @return \Cassandra\Index|null An index or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-index */ public function index($name) {} /** * Gets all indexes * * @return array An array of indexes * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-indexes */ public function indexes() {} /** * Get materialized view by name * * @param string $name Materialized view name * * @return \Cassandra\MaterializedView|null A materialized view or null * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-materializedView */ public function materializedView($name) {} /** * Gets all materialized views * * @return array An array of materialized views * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.DefaultTable/#method-materializedViews */ public function materializedViews() {} } /** * A future that always resolves in a value. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.FutureValue/ */ final class FutureValue implements Future { /** * Waits for a given future resource to resolve and throws errors if any. * * @param int|float|null $timeout A timeout in seconds * * @return mixed A value * @throws \Cassandra\Exception\TimeoutException * * @throws \Cassandra\Exception\InvalidArgumentException * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.FutureValue/#method-get */ public function get($timeout) {} } /** * A PHP representation of the CQL `decimal` datatype * * The actual value of a decimal is `$value * pow(10, $scale * -1)` * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/class.Decimal/ */ final class Decimal implements Value, Numeric { /** * Creates a decimal from a given decimal string: * * ~~~{.php} * schema() will always return an empty object. This * can be useful for reducing the startup overhead of short-lived sessions. * * @param bool $enabled whether the driver fetches and maintains schema metadata. * * @return \Cassandra\Cluster\Builder self * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Cluster/class.Builder/#method-withSchemaMetadata */ public function withSchemaMetadata($enabled) {} /** * Enables/disables Hostname Resolution. * * If enabled the driver will resolve hostnames for IP addresses using * reverse IP lookup. This is useful for authentication (Kerberos) or * encryption SSL services that require a valid hostname for verification. * * Important: It's possible that the underlying C/C++ driver does not * support hostname resolution. A PHP warning will be emitted if the driver * does not support hostname resolution. * * @param bool $enabled whether the driver uses hostname resolution. * * @return \Cassandra\Cluster\Builder self * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Cluster/class.Builder/#method-withHostnameResolution */ public function withHostnameResolution($enabled) {} /** * Enables/disables Randomized Contact Points. * * If enabled this allows the driver randomly use contact points in order * to evenly spread the load across the cluster and prevent * hotspots/load spikes during notifications (e.g. massive schema change). * * Note: This setting should only be disabled for debugging and testing. * * @param bool $enabled whether the driver uses randomized contact points. * * @return \Cassandra\Cluster\Builder self * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Cluster/class.Builder/#method-withRandomizedContactPoints */ public function withRandomizedContactPoints($enabled) {} /** * Specify interval in seconds that the driver should wait before attempting * to send heartbeat messages and control the amount of time the connection * must be idle before sending heartbeat messages. This is useful for * preventing intermediate network devices from dropping connections. * * @param float $interval interval in seconds (0 to disable heartbeat). * * @return \Cassandra\Cluster\Builder self * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Cluster/class.Builder/#method-withConnectionHeartbeatInterval */ public function withConnectionHeartbeatInterval($interval) {} } } /** * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/TimestampGenerator/ */ namespace Cassandra\TimestampGenerator { /** * A timestamp generator that allows the server-side to assign timestamps. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/TimestampGenerator/class.ServerSide/ */ final class ServerSide implements \Cassandra\TimestampGenerator {} /** * A timestamp generator that generates monotonically increasing timestamps * client-side. The timestamps generated have a microsecond granularity with * the sub-millisecond part generated using a counter. The implementation * guarantees that no more than 1000 timestamps will be generated for a given * clock tick even if shared by multiple session objects. If that rate is * exceeded then a warning is logged and timestamps stop incrementing until * the next clock tick. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/TimestampGenerator/class.Monotonic/ */ final class Monotonic implements \Cassandra\TimestampGenerator {} } /** * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/RetryPolicy/ */ namespace Cassandra\RetryPolicy { /** * The default retry policy. This policy retries a query, using the * request's original consistency level, in the following cases: * * * On a read timeout, if enough replicas replied but the data was not received. * * On a write timeout, if a timeout occurs while writing a distributed batch log. * * On unavailable, it will move to the next host. * * In all other cases the error will be returned. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/RetryPolicy/class.DefaultPolicy/ */ final class DefaultPolicy implements \Cassandra\RetryPolicy {} /** * A retry policy that will downgrade the consistency of a request in * an attempt to save a request in cases where there is any chance of success. A * write request will succeed if there is at least a single copy persisted and a * read request will succeed if there is some data available even if it increases * the risk of reading stale data. This policy will retry in the same scenarios as * the default policy, and it will also retry in the following case: * * * On a read timeout, if some replicas responded but is lower than * required by the current consistency level then retry with a lower * consistency level * * On a write timeout, Retry unlogged batches at a lower consistency level * if at least one replica responded. For single queries and batch if any * replicas responded then consider the request successful and swallow the * error. * * On unavailable, retry at a lower consistency if at lease one replica * responded. * * Important: This policy may attempt to retry requests with a lower * consistency level. Using this policy can break consistency guarantees. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/RetryPolicy/class.DowngradingConsistency/ */ final class DowngradingConsistency implements \Cassandra\RetryPolicy {} /** * A retry policy that never retries and allows all errors to fallthrough. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/RetryPolicy/class.Fallthrough/ */ final class Fallthrough implements \Cassandra\RetryPolicy {} /** * A retry policy that logs the decisions of its child policy. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/RetryPolicy/class.Logging/ */ final class Logging implements \Cassandra\RetryPolicy { /** * Creates a new Logging retry policy. * * @param \Cassandra\RetryPolicy $childPolicy Any retry policy other than Logging * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/RetryPolicy/class.Logging/#method-__construct */ public function __construct($childPolicy) {} } } /** * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/ */ namespace Cassandra\Type { /** * A class that represents the tuple type. The tuple type is able to represent * a composite type of one or more types accessed by index. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Tuple/ */ final class Tuple extends \Cassandra\Type { private function __construct() {} /** * Returns "tuple" * * @return string "tuple" * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Tuple/#method-name */ public function name() {} /** * Returns type representation in CQL, e.g. `tuple` * * @return string Type representation in CQL * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Tuple/#method-__toString */ public function __toString() {} /** * Returns types of values * * @return array An array of types * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Tuple/#method-types */ public function types() {} /** * Creates a new Tuple from the given values. When no values given, * creates a tuple with null for the values. * * @param mixed ...$values One or more values to be added to the tuple. * * @return \Cassandra\Tuple A tuple with given values. * @throws \Cassandra\Exception\InvalidArgumentException when values given are of a * different type than what the * tuple expects. * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Tuple/#method-create */ public function create(...$values) {} } /** * A class that represents the list type. The list type contains the type of the * elements contain in the list. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Collection/ */ final class Collection extends \Cassandra\Type { private function __construct() {} /** * Returns "list" * * @return string "list" * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Collection/#method-name */ public function name() {} /** * Returns type of values * * @return \Cassandra\Type Type of values * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Collection/#method-valueType */ public function valueType() {} /** * Returns type representation in CQL, e.g. `list` * * @return string Type representation in CQL * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Collection/#method-__toString */ public function __toString() {} /** * Creates a new Collection from the given values. When no values * given, creates an empty list. * * @param mixed ...$value One or more values to be added to the list. * * @return \Cassandra\Collection A list with given values. * @throws \Cassandra\Exception\InvalidArgumentException when values given are of a * different type than what this * list type expects. * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Collection/#method-create */ public function create(...$value) {} } /** * A class that represents the set type. The set type contains the type of the * elements contain in the set. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Set/ */ final class Set extends \Cassandra\Type { private function __construct() {} /** * Returns "set" * * @return string "set" * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Set/#method-name */ public function name() {} /** * Returns type of values * * @return \Cassandra\Type Type of values * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Set/#method-valueType */ public function valueType() {} /** * Returns type representation in CQL, e.g. `set` * * @return string Type representation in CQL * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Set/#method-__toString */ public function __toString() {} /** * Creates a new Set from the given values. * * @param mixed ...$value One or more values to be added to the set. When no values are given, creates an empty set. * * @return \Cassandra\Set A set with given values. * @throws \Cassandra\Exception\InvalidArgumentException when values given are of a * different type than what this * set type expects. * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Set/#method-create */ public function create(...$value) {} } /** * A class that represents a custom type. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Custom/ */ final class Custom extends \Cassandra\Type { private function __construct() {} /** * Returns the name of this type as string. * * @return string The name of this type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Custom/#method-name */ public function name() {} /** * Returns string representation of this type. * * @return string String representation of this type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Custom/#method-__toString */ public function __toString() {} /** * @param mixed $value * * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Custom/#method-create */ public function create($value) {} } /** * A class that represents a user type. The user type is able to represent a * composite type of one or more types accessed by name. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.UserType/ */ final class UserType extends \Cassandra\Type { private function __construct() {} /** * Associate the user type with a name. * * @param string $name Name of the user type. * * @return null Nothing. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.UserType/#method-withName */ public function withName($name) {} /** * Returns type name for the user type * * @return string Name of this type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.UserType/#method-name */ public function name() {} /** * Associate the user type with a keyspace. * * @param string $keyspace Keyspace that contains the user type. * * @return null Nothing. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.UserType/#method-withKeyspace */ public function withKeyspace($keyspace) {} /** * Returns keyspace for the user type * * @return string * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.UserType/#method-keyspace */ public function keyspace() {} /** * Returns type representation in CQL, e.g. keyspace1.type_name1 or * `userType`. * * @return string Type representation in CQL * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.UserType/#method-__toString */ public function __toString() {} /** * Returns types of values * * @return array An array of types * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.UserType/#method-types */ public function types() {} /** * Creates a new UserTypeValue from the given name/value pairs. When * no values given, creates an empty user type. * * @param mixed ...$value One or more name/value pairs to be added to the user type. * * @return \Cassandra\UserTypeValue A user type value with given name/value pairs. * @throws \Cassandra\Exception\InvalidArgumentException when values given are of a * different types than what the * user type expects. * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.UserType/#method-create */ public function create(...$value) {} } /** * A class that represents the map type. The map type contains two types that * represents the types of the key and value contained in the map. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Map/ */ final class Map extends \Cassandra\Type { private function __construct() {} /** * Returns "map" * * @return string "map" * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Map/#method-name */ public function name() {} /** * Returns type of keys * * @return \Cassandra\Type Type of keys * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Map/#method-keyType */ public function keyType() {} /** * Returns type of values * * @return \Cassandra\Type Type of values * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Map/#method-valueType */ public function valueType() {} /** * Returns type representation in CQL, e.g. `map` * * @return string Type representation in CQL * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Map/#method-__toString */ public function __toString() {} /** * Creates a new Map from the given values. * * ```create(new Uuid(), 'first uuid', * new Uuid(), 'second uuid', * new Uuid(), 'third uuid'); * * var_dump($map);``` * * * is a key and each even value is a value for the * map, e.g. `create(key, value, key, value)`. * When no values given, creates an empty map. * * @param mixed ...$value An even number of values, where each odd value * * @return \Cassandra\Map A set with given values. * @throws \Cassandra\Exception\InvalidArgumentException when keys or values given are * of a different type than what * this map type expects. * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Map/#method-create */ public function create(...$value) {} } /** * A class that represents a primitive type (e.g. `varchar` or `bigint`) * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Scalar/ */ final class Scalar extends \Cassandra\Type { private function __construct() {} /** * Returns the name of this type as string. * * @return string Name of this type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Scalar/#method-name */ public function name() {} /** * Returns string representation of this type. * * @return string String representation of this type * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Scalar/#method-__toString */ public function __toString() {} /** * @param mixed $value * * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Type/class.Scalar/#method-create */ public function create($value) {} } } /** * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/SSLOptions/ */ namespace Cassandra\SSLOptions { /** * SSLOptions builder allows fluent configuration of ssl options. * * @see \Cassandra::ssl() * @see \Cassandra\Cluster\Builder::withSSL() * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/SSLOptions/class.Builder/ */ final class Builder { /** * Builds SSL options. * * @return \Cassandra\SSLOptions ssl options configured accordingly. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/SSLOptions/class.Builder/#method-build */ public function build() {} /** * Adds a trusted certificate. This is used to verify node's identity. * * @param string ...$path one or more paths to files containing a PEM formatted certificate. * * @return \Cassandra\Cluster\Builder self * @throws \Cassandra\Exception\InvalidArgumentException * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/SSLOptions/class.Builder/#method-withTrustedCerts */ public function withTrustedCerts(...$path) {} /** * Disable certificate verification. * * @param int $flags * * @return \Cassandra\Cluster\Builder self * @throws \Cassandra\Exception\InvalidArgumentException * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/SSLOptions/class.Builder/#method-withVerifyFlags */ public function withVerifyFlags($flags) {} /** * Set client-side certificate chain. * * This is used to authenticate the client on the server-side. This should contain the entire Certificate * chain starting with the certificate itself. * * @param string $path path to a file containing a PEM formatted certificate. * * @return \Cassandra\Cluster\Builder self * @throws \Cassandra\Exception\InvalidArgumentException * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/SSLOptions/class.Builder/#method-withClientCert */ public function withClientCert($path) {} /** * Set client-side private key. This is used to authenticate the client on * the server-side. * * @param string $path Path to the private key file * @param string|null $passphrase Passphrase for the private key, if any * * @return \Cassandra\Cluster\Builder self * @throws \Cassandra\Exception\InvalidArgumentException * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/SSLOptions/class.Builder/#method-withPrivateKey */ public function withPrivateKey($path, $passphrase) {} } } /** * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/ */ namespace Cassandra\Exception { use JetBrains\PhpStorm\Pure; /** * ConfigurationException is raised when query is syntactically correct but * invalid because of some configuration issue. * For example when attempting to drop a non-existent keyspace. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ConfigurationException/ */ class ConfigurationException extends ValidationException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ConfigurationException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ConfigurationException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ConfigurationException/#method-__toString */ public function __toString() {} } /** * Cassandra domain exception. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.DomainException/ */ class DomainException extends \DomainException implements \Cassandra\Exception { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.DomainException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.DomainException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.DomainException/#method-__toString */ public function __toString() {} } /** * InvalidQueryException is raised when query is syntactically correct but invalid. * For example when attempting to create a table without specifying a keyspace. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.InvalidQueryException/ */ class InvalidQueryException extends ValidationException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.InvalidQueryException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.InvalidQueryException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.InvalidQueryException/#method-__toString */ public function __toString() {} } /** * UnpreparedException is raised when a given prepared statement id does not * exist on the server. The driver should be automatically re-preparing the * statement in this case. Seeing this error could be considered a bug. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.UnpreparedException/ */ class UnpreparedException extends ValidationException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.UnpreparedException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.UnpreparedException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.UnpreparedException/#method-__toString */ public function __toString() {} } /** * Cassandra invalid argument exception. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.InvalidArgumentException/ */ class InvalidArgumentException extends \InvalidArgumentException implements \Cassandra\Exception { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.InvalidArgumentException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.InvalidArgumentException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.InvalidArgumentException/#method-__toString */ public function __toString() {} } /** * ServerException is raised when something unexpected happened on the server. * This exception is most likely due to a server-side bug. * **NOTE** This exception and all its children are generated on the server. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ServerException/ */ class ServerException extends RuntimeException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ServerException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ServerException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ServerException/#method-__toString */ public function __toString() {} } /** * Cassandra domain exception. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.RangeException/ */ class RangeException extends \RangeException implements \Cassandra\Exception { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.RangeException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.RangeException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.RangeException/#method-__toString */ public function __toString() {} } /** * UnauthorizedException is raised when the current user doesn't have * sufficient permissions to access data. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.UnauthorizedException/ */ class UnauthorizedException extends ValidationException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.UnauthorizedException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.UnauthorizedException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.UnauthorizedException/#method-__toString */ public function __toString() {} } /** * Cassandra logic exception. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.LogicException/ */ class LogicException extends \LogicException implements \Cassandra\Exception { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.LogicException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.LogicException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.LogicException/#method-__toString */ public function __toString() {} } /** * UnavailableException is raised when a coordinator detected that there aren't * enough replica nodes available to fulfill the request. * * NOTE: Request has not even been forwarded to the replica nodes in this case. * @see https://github.com/apache/cassandra/blob/cassandra-2.1/doc/native_protocol_v1.spec#L667-L677 Description of the Unavailable error in the native protocol v1 spec. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.UnavailableException/ */ class UnavailableException extends ExecutionException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.UnavailableException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.UnavailableException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.UnavailableException/#method-__toString */ public function __toString() {} } /** * AuthenticationException is raised when client was not configured with valid * authentication credentials. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.AuthenticationException/ */ class AuthenticationException extends RuntimeException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.AuthenticationException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.AuthenticationException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.AuthenticationException/#method-__toString */ public function __toString() {} } /** * OverloadedException is raised when a node is overloaded. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.OverloadedException/ */ class OverloadedException extends ServerException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.OverloadedException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.OverloadedException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.OverloadedException/#method-__toString */ public function __toString() {} } /** * ReadTimeoutException is raised when a coordinator failed to receive acks * from the required number of replica nodes in time during a read. * @see https://github.com/apache/cassandra/blob/cassandra-2.1/doc/native_protocol_v1.spec#L709-L726 Description of ReadTimeout error in the native protocol spec * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ReadTimeoutException/ */ class ReadTimeoutException extends ExecutionException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ReadTimeoutException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ReadTimeoutException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ReadTimeoutException/#method-__toString */ public function __toString() {} } /** * IsBootstrappingException is raised when a node is bootstrapping. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.IsBootstrappingException/ */ class IsBootstrappingException extends ServerException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.IsBootstrappingException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.IsBootstrappingException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.IsBootstrappingException/#method-__toString */ public function __toString() {} } /** * ProtocolException is raised when a client did not follow server's protocol, * e.g. sending a QUERY message before STARTUP. Seeing this error can be * considered a bug. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ProtocolException/ */ class ProtocolException extends RuntimeException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ProtocolException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ProtocolException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ProtocolException/#method-__toString */ public function __toString() {} } /** * ExecutionException is raised when something went wrong during request execution. * @see \Cassandra\Exception\TruncateException * @see \Cassandra\Exception\UnavailableException * @see \Cassandra\Exception\ReadTimeoutException * @see \Cassandra\Exception\WriteTimeoutException * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ExecutionException/ */ class ExecutionException extends RuntimeException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ExecutionException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ExecutionException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ExecutionException/#method-__toString */ public function __toString() {} } /** * InvalidSyntaxException is raised when CQL in the request is syntactically incorrect. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.InvalidSyntaxException/ */ class InvalidSyntaxException extends ValidationException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.InvalidSyntaxException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.InvalidSyntaxException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.InvalidSyntaxException/#method-__toString */ public function __toString() {} } /** * Cassandra runtime exception. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.RuntimeException/ */ class RuntimeException extends \RuntimeException implements \Cassandra\Exception { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.RuntimeException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.RuntimeException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.RuntimeException/#method-__toString */ public function __toString() {} } /** * TimeoutException is generally raised when a future did not resolve * within a given time interval. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.TimeoutException/ */ class TimeoutException extends RuntimeException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.TimeoutException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.TimeoutException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.TimeoutException/#method-__toString */ public function __toString() {} } /** * ValidationException is raised on invalid request, before even attempting to * execute it. * @see \Cassandra\Exception\InvalidSyntaxException * @see \Cassandra\Exception\UnauthorizedException * @see \Cassandra\Exception\InvalidQueryException * @see \Cassandra\Exception\ConfigurationException * @see \Cassandra\Exception\AlreadyExistsException * @see \Cassandra\Exception\UnpreparedException * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ValidationException/ */ class ValidationException extends RuntimeException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ValidationException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ValidationException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.ValidationException/#method-__toString */ public function __toString() {} } /** * TruncateException is raised when something went wrong during table * truncation. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.TruncateException/ */ class TruncateException extends ExecutionException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.TruncateException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.TruncateException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.TruncateException/#method-__toString */ public function __toString() {} } /** * AlreadyExistsException is raised when attempting to re-create existing keyspace. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.AlreadyExistsException/ */ class AlreadyExistsException extends ConfigurationException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.AlreadyExistsException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.AlreadyExistsException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.AlreadyExistsException/#method-__toString */ public function __toString() {} } /** * Cassandra domain exception. * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.DivideByZeroException/ */ class DivideByZeroException extends RangeException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.DivideByZeroException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.DivideByZeroException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.DivideByZeroException/#method-__toString */ public function __toString() {} } /** * WriteTimeoutException is raised when a coordinator failed to receive acks * from the required number of replica nodes in time during a write. * @see https://github.com/apache/cassandra/blob/cassandra-2.1/doc/native_protocol_v1.spec#L683-L708 Description of WriteTimeout error in the native protocol spec * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.WriteTimeoutException/ */ class WriteTimeoutException extends ExecutionException { /** * @param mixed $message * @param mixed $code * @param mixed $previous * * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.WriteTimeoutException/#method-__construct */ #[Pure] public function __construct($message, $code, $previous) {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.WriteTimeoutException/#method-__wakeup */ public function __wakeup() {} /** * @return mixed * @link https://docs.datastax.com/en/developer/php-driver/latest/api/Cassandra/Exception/class.WriteTimeoutException/#method-__toString */ public function __toString() {} } } * Construct a Phar archive object * @link https://php.net/manual/en/phar.construct.php * @param string $filename

    * Path to an existing Phar archive or to-be-created archive. The file name's * extension must contain .phar. *

    * @param int $flags [optional]

    * Flags to pass to parent class RecursiveDirectoryIterator. *

    * @param string $alias [optional]

    * Alias with which this Phar archive should be referred to in calls to stream * functionality. *

    * @throws BadMethodCallException If called twice. * @throws UnexpectedValueException If the phar archive can't be opened. */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = FilesystemIterator::SKIP_DOTS|FilesystemIterator::UNIX_PATHS, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $alias = null, #[PhpStormStubsElementAvailable(from: '5.3', to: '5.6')] $fileformat = null ) {} public function __destruct() {} /** * (Unknown)
    * Add an empty directory to the phar archive * @link https://php.net/manual/en/phar.addemptydir.php * @param string $directory

    * The name of the empty directory to create in the phar archive *

    * @return void no return value, exception is thrown on failure. */ #[TentativeType] public function addEmptyDir( #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $directory = '', #[PhpStormStubsElementAvailable(from: '8.0')] string $directory ): void {} /** * (Unknown)
    * Add a file from the filesystem to the phar archive * @link https://php.net/manual/en/phar.addfile.php * @param string $filename

    * Full or relative path to a file on disk to be added * to the phar archive. *

    * @param string $localName [optional]

    * Path that the file will be stored in the archive. *

    * @return void no return value, exception is thrown on failure. */ #[TentativeType] public function addFile( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $localName = null ): void {} /** * (Unknown)
    * Add a file from the filesystem to the phar archive * @link https://php.net/manual/en/phar.addfromstring.php * @param string $localName

    * Path that the file will be stored in the archive. *

    * @param string $contents

    * The file contents to store *

    * @return void no return value, exception is thrown on failure. */ #[TentativeType] public function addFromString( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $localName, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $contents = '', #[PhpStormStubsElementAvailable(from: '8.0')] string $contents ): void {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Construct a phar archive from the files within a directory. * @link https://php.net/manual/en/phar.buildfromdirectory.php * @param string $directory

    * The full or relative path to the directory that contains all files * to add to the archive. *

    * @param $pattern $regex [optional]

    * An optional pcre regular expression that is used to filter the * list of files. Only file paths matching the regular expression * will be included in the archive. *

    * @return array Phar::buildFromDirectory returns an associative array * mapping internal path of file to the full path of the file on the * filesystem. */ #[TentativeType] public function buildFromDirectory( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $directory, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $pattern = '' ): array {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Construct a phar archive from an iterator. * @link https://php.net/manual/en/phar.buildfromiterator.php * @param Traversable $iterator

    * Any iterator that either associatively maps phar file to location or * returns SplFileInfo objects *

    * @param string $baseDirectory [optional]

    * For iterators that return SplFileInfo objects, the portion of each * file's full path to remove when adding to the phar archive *

    * @return array Phar::buildFromIterator returns an associative array * mapping internal path of file to the full path of the file on the * filesystem. */ #[TentativeType] public function buildFromIterator( Traversable $iterator, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $baseDirectory = null ): array {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Compresses all files in the current Phar archive * @link https://php.net/manual/en/phar.compressfiles.php * @param int $compression

    * Compression must be one of Phar::GZ, * Phar::BZ2 to add compression, or Phar::NONE * to remove compression. *

    * @return void No value is returned. */ #[TentativeType] public function compressFiles(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $compression): void {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Decompresses all files in the current Phar archive * @link https://php.net/manual/en/phar.decompressfiles.php * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function decompressFiles() {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Compresses the entire Phar archive using Gzip or Bzip2 compression * @link https://php.net/manual/en/phar.compress.php * @param int $compression

    * Compression must be one of Phar::GZ, * Phar::BZ2 to add compression, or Phar::NONE * to remove compression. *

    * @param string $extension [optional]

    * By default, the extension is .phar.gz * or .phar.bz2 for compressing phar archives, and * .phar.tar.gz or .phar.tar.bz2 for * compressing tar archives. For decompressing, the default file extensions * are .phar and .phar.tar. *

    * @return static|null a Phar object. */ #[TentativeType] public function compress( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $compression, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $extension = null ): ?Phar {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Decompresses the entire Phar archive * @link https://php.net/manual/en/phar.decompress.php * @param string $extension [optional]

    * For decompressing, the default file extensions * are .phar and .phar.tar. * Use this parameter to specify another file extension. Be aware * that all executable phar archives must contain .phar * in their filename. *

    * @return static|null A Phar object is returned. */ #[TentativeType] public function decompress(#[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $extension = null): ?Phar {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Convert a phar archive to another executable phar archive file format * @link https://php.net/manual/en/phar.converttoexecutable.php * @param int $format [optional]

    * This should be one of Phar::PHAR, Phar::TAR, * or Phar::ZIP. If set to NULL, the existing file format * will be preserved. *

    * @param int $compression [optional]

    * This should be one of Phar::NONE for no whole-archive * compression, Phar::GZ for zlib-based compression, and * Phar::BZ2 for bzip-based compression. *

    * @param string $extension [optional]

    * This parameter is used to override the default file extension for a * converted archive. Note that all zip- and tar-based phar archives must contain * .phar in their file extension in order to be processed as a * phar archive. *

    *

    * If converting to a phar-based archive, the default extensions are * .phar, .phar.gz, or .phar.bz2 * depending on the specified compression. For tar-based phar archives, the * default extensions are .phar.tar, .phar.tar.gz, * and .phar.tar.bz2. For zip-based phar archives, the * default extension is .phar.zip. *

    * @return Phar|null The method returns a Phar object on success and throws an * exception on failure. */ #[TentativeType] public function convertToExecutable( #[LanguageLevelTypeAware(['8.0' => 'int|null'], default: '')] $format = null, #[LanguageLevelTypeAware(['8.0' => 'int|null'], default: '')] $compression = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $extension = null ): ?Phar {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Convert a phar archive to a non-executable tar or zip file * @link https://php.net/manual/en/phar.converttodata.php * @param int $format [optional]

    * This should be one of Phar::TAR * or Phar::ZIP. If set to NULL, the existing file format * will be preserved. *

    * @param int $compression [optional]

    * This should be one of Phar::NONE for no whole-archive * compression, Phar::GZ for zlib-based compression, and * Phar::BZ2 for bzip-based compression. *

    * @param string $extension [optional]

    * This parameter is used to override the default file extension for a * converted archive. Note that .phar cannot be used * anywhere in the filename for a non-executable tar or zip archive. *

    *

    * If converting to a tar-based phar archive, the * default extensions are .tar, .tar.gz, * and .tar.bz2 depending on specified compression. * For zip-based archives, the * default extension is .zip. *

    * @return PharData|null The method returns a PharData object on success and throws an * exception on failure. */ #[TentativeType] public function convertToData( #[LanguageLevelTypeAware(['8.0' => 'int|null'], default: '')] $format = null, #[LanguageLevelTypeAware(['8.0' => 'int|null'], default: '')] $compression = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $extension = null ): ?PharData {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Copy a file internal to the phar archive to another new file within the phar * @link https://php.net/manual/en/phar.copy.php * @param string $to * @param string $from * @return bool returns TRUE on success, but it is safer to encase method call in a * try/catch block and assume success if no exception is thrown. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function copy( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $to, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $from ) {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Returns the number of entries (files) in the Phar archive * @link https://php.net/manual/en/phar.count.php * @param int $mode [optional] * @return int<0,max> The number of files contained within this phar, or 0 (the number zero) * if none. */ #[TentativeType] public function count(#[PhpStormStubsElementAvailable(from: '8.0')] int $mode = COUNT_NORMAL): int {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Delete a file within a phar archive * @link https://php.net/manual/en/phar.delete.php * @param string $localName

    * Path within an archive to the file to delete. *

    * @return bool returns TRUE on success, but it is better to check for thrown exception, * and assume success if none is thrown. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function delete(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $localName) {} /** * (PHP >= 5.3.0, PECL phar >= 1.2.0)
    * Deletes the global metadata of the phar * @link https://php.net/manual/en/phar.delmetadata.php * @return bool returns TRUE on success, but it is better to check for thrown exception, * and assume success if none is thrown. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function delMetadata() {} /** * (Unknown)
    * Extract the contents of a phar archive to a directory * @link https://php.net/manual/en/phar.extractto.php * @param string $directory

    * Path within an archive to the file to delete. *

    * @param string|array|null $files [optional]

    * The name of a file or directory to extract, or an array of files/directories to extract *

    * @param bool $overwrite [optional]

    * Set to TRUE to enable overwriting existing files *

    * @return bool returns TRUE on success, but it is better to check for thrown exception, * and assume success if none is thrown. */ #[TentativeType] public function extractTo( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $directory, #[LanguageLevelTypeAware(['8.0' => 'array|string|null'], default: '')] $files = null, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $overwrite = false ): bool {} /** * @return string|null * @see setAlias */ #[TentativeType] public function getAlias(): ?string {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Returns phar archive meta-data * @link https://php.net/manual/en/phar.getmetadata.php * @param array $unserializeOptions [optional] if is set to anything other than the default, * the resulting metadata won't be cached and this won't return the value from the cache * @return mixed any PHP variable that can be serialized and is stored as meta-data for the Phar archive, * or NULL if no meta-data is stored. */ #[TentativeType] public function getMetadata(#[PhpStormStubsElementAvailable(from: '8.0')] array $unserializeOptions = []): mixed {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Return whether phar was modified * @link https://php.net/manual/en/phar.getmodified.php * @return bool TRUE if the phar has been modified since opened, FALSE if not. */ #[TentativeType] public function getModified(): bool {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Return MD5/SHA1/SHA256/SHA512/OpenSSL signature of a Phar archive * @link https://php.net/manual/en/phar.getsignature.php * @return array Array with the opened archive's signature in hash key and MD5, * SHA-1, * SHA-256, SHA-512, or OpenSSL * in hash_type. This signature is a hash calculated on the * entire phar's contents, and may be used to verify the integrity of the archive. * A valid signature is absolutely required of all executable phar archives if the * phar.require_hash INI variable * is set to true. */ #[ArrayShape(["hash" => "string", "hash_type" => "string"])] #[TentativeType] public function getSignature(): array|false {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Return the PHP loader or bootstrap stub of a Phar archive * @link https://php.net/manual/en/phar.getstub.php * @return string a string containing the contents of the bootstrap loader (stub) of * the current Phar archive. */ #[TentativeType] public function getStub(): string {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Return version info of Phar archive * @link https://php.net/manual/en/phar.getversion.php * @return string The opened archive's API version. This is not to be confused with * the API version that the loaded phar extension will use to create * new phars. Each Phar archive has the API version hard-coded into * its manifest. See Phar file format * documentation for more information. */ #[TentativeType] public function getVersion(): string {} /** * (PHP >= 5.3.0, PECL phar >= 1.2.0)
    * Returns whether phar has global meta-data * @link https://php.net/manual/en/phar.hasmetadata.php * @return bool TRUE if meta-data has been set, and FALSE if not. */ #[TentativeType] public function hasMetadata(): bool {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Used to determine whether Phar write operations are being buffered, or are flushing directly to disk * @link https://php.net/manual/en/phar.isbuffering.php * @return bool TRUE if the write operations are being buffer, FALSE otherwise. */ #[TentativeType] public function isBuffering(): bool {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Returns Phar::GZ or PHAR::BZ2 if the entire phar archive is compressed (.tar.gz/tar.bz and so on) * @link https://php.net/manual/en/phar.iscompressed.php * @return mixed Phar::GZ, Phar::BZ2 or FALSE */ #[TentativeType] public function isCompressed(): int|false {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Returns true if the phar archive is based on the tar/phar/zip file format depending on the parameter * @link https://php.net/manual/en/phar.isfileformat.php * @param int $format

    * Either Phar::PHAR, Phar::TAR, or * Phar::ZIP to test for the format of the archive. *

    * @return bool TRUE if the phar archive matches the file format requested by the parameter */ #[TentativeType] public function isFileFormat(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $format): bool {} /** * (Unknown)
    * Returns true if the phar archive can be modified * @link https://php.net/manual/en/phar.iswritable.php * @return bool TRUE if the phar archive can be modified */ #[TentativeType] public function isWritable(): bool {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * determines whether a file exists in the phar * @link https://php.net/manual/en/phar.offsetexists.php * @param string $localName

    * The filename (relative path) to look for in a Phar. *

    * @return bool TRUE if the file exists within the phar, or FALSE if not. */ #[TentativeType] public function offsetExists($localName): bool {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Gets a PharFileInfo object for a specific file * @link https://php.net/manual/en/phar.offsetget.php * @param string $localName

    * The filename (relative path) to look for in a Phar. *

    * @return PharFileInfo A PharFileInfo object is returned that can be used to * iterate over a file's contents or to retrieve information about the current file. */ #[TentativeType] public function offsetGet($localName): SplFileInfo {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * set the contents of an internal file to those of an external file * @link https://php.net/manual/en/phar.offsetset.php * @param string $localName

    * The filename (relative path) to modify in a Phar. *

    * @param string $value

    * Content of the file. *

    * @return void No return values. */ #[TentativeType] public function offsetSet($localName, $value): void {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * remove a file from a phar * @link https://php.net/manual/en/phar.offsetunset.php * @param string $localName

    * The filename (relative path) to modify in a Phar. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function offsetUnset($localName): void {} /** * (PHP >= 5.3.0, PECL phar >= 1.2.1)
    * Set the alias for the Phar archive * @link https://php.net/manual/en/phar.setalias.php * @param string $alias

    * A shorthand string that this archive can be referred to in phar * stream wrapper access. *

    * @return bool */ #[TentativeType] #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] public function setAlias(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $alias) {} /** * (Unknown)
    * Used to set the PHP loader or bootstrap stub of a Phar archive to the default loader * @link https://php.net/manual/en/phar.setdefaultstub.php * @param string $index [optional]

    * Relative path within the phar archive to run if accessed on the command-line *

    * @param string $webIndex [optional]

    * Relative path within the phar archive to run if accessed through a web browser *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] public function setDefaultStub( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $index = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $webIndex = null ) {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Sets phar archive meta-data * @link https://php.net/manual/en/phar.setmetadata.php * @param mixed $metadata

    * Any PHP variable containing information to store that describes the phar archive *

    * @return void No value is returned. */ #[TentativeType] public function setMetadata(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $metadata): void {} /** * (PHP >= 5.3.0, PECL phar >= 1.1.0)
    * set the signature algorithm for a phar and apply it. * @link https://php.net/manual/en/phar.setsignaturealgorithm.php * @param int $algo

    * One of Phar::MD5, * Phar::SHA1, Phar::SHA256, * Phar::SHA512, or Phar::OPENSSL *

    * @param string $privateKey [optional]

    * The contents of an OpenSSL private key, as extracted from a certificate or * OpenSSL key file: * * $private = openssl_get_privatekey(file_get_contents('private.pem')); * $pkey = ''; * openssl_pkey_export($private, $pkey); * $p->setSignatureAlgorithm(Phar::OPENSSL, $pkey); * * See phar introduction for instructions on * naming and placement of the public key file. *

    * @return void No value is returned. */ #[TentativeType] public function setSignatureAlgorithm( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $algo, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $privateKey = null ): void {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Used to set the PHP loader or bootstrap stub of a Phar archive * @link https://php.net/manual/en/phar.setstub.php * @param string $stub

    * A string or an open stream handle to use as the executable stub for this * phar archive. *

    * @param int $length [optional]

    *

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function setStub( $stub, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $length ) {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Start buffering Phar write operations, do not modify the Phar object on disk * @link https://php.net/manual/en/phar.startbuffering.php * @return void No value is returned. */ #[TentativeType] public function startBuffering(): void {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Stop buffering write requests to the Phar archive, and save changes to disk * @link https://php.net/manual/en/phar.stopbuffering.php * @return void No value is returned. */ #[TentativeType] public function stopBuffering(): void {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Returns the api version * @link https://php.net/manual/en/phar.apiversion.php * @return string The API version string as in "1.0.0". */ final public static function apiVersion(): string {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Returns whether phar extension supports compression using either zlib or bzip2 * @link https://php.net/manual/en/phar.cancompress.php * @param int $compression [optional]

    * Either Phar::GZ or Phar::BZ2 can be * used to test whether compression is possible with a specific compression * algorithm (zlib or bzip2). *

    * @return bool TRUE if compression/decompression is available, FALSE if not. */ final public static function canCompress(int $compression = 0): bool {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Returns whether phar extension supports writing and creating phars * @link https://php.net/manual/en/phar.canwrite.php * @return bool TRUE if write access is enabled, FALSE if it is disabled. */ final public static function canWrite(): bool {} /** * (Unknown)
    * Create a phar-file format specific stub * @link https://php.net/manual/en/phar.createdefaultstub.php * @param string|null $index [optional] * @param string|null $webIndex [optional] * @return string a string containing the contents of a customized bootstrap loader (stub) * that allows the created Phar archive to work with or without the Phar extension * enabled. */ final public static function createDefaultStub(?string $index = null, ?string $webIndex = null): string {} /** * (PHP >= 5.3.0, PECL phar >= 1.2.0)
    * Return array of supported compression algorithms * @link https://php.net/manual/en/phar.getsupportedcompression.php * @return string[] an array containing any of "GZ" or * "BZ2", depending on the availability of * the zlib extension or the * bz2 extension. */ final public static function getSupportedCompression(): array {} /** * (PHP >= 5.3.0, PECL phar >= 1.1.0)
    * Return array of supported signature types * @link https://php.net/manual/en/phar.getsupportedsignatures.php * @return string[] an array containing any of "MD5", "SHA-1", * "SHA-256", "SHA-512", or "OpenSSL". */ final public static function getSupportedSignatures(): array {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * instructs phar to intercept fopen, file_get_contents, opendir, and all of the stat-related functions * @link https://php.net/manual/en/phar.interceptfilefuncs.php * @return void */ final public static function interceptFileFuncs(): void {} /** * (PHP >= 5.3.0, PECL phar >= 1.2.0)
    * Returns whether the given filename is a valid phar filename * @link https://php.net/manual/en/phar.isvalidpharfilename.php * @param string $filename

    * The name or full path to a phar archive not yet created *

    * @param bool $executable [optional]

    * This parameter determines whether the filename should be treated as * a phar executable archive, or a data non-executable archive *

    * @return bool TRUE if the filename is valid, FALSE if not. */ final public static function isValidPharFilename(string $filename, bool $executable = true): bool {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Loads any phar archive with an alias * @link https://php.net/manual/en/phar.loadphar.php * @param string $filename

    * the full or relative path to the phar archive to open *

    * @param string|null $alias [optional]

    * The alias that may be used to refer to the phar archive. Note * that many phar archives specify an explicit alias inside the * phar archive, and a PharException will be thrown if * a new alias is specified in this case. *

    * @return bool TRUE on success or FALSE on failure. */ final public static function loadPhar(string $filename, ?string $alias = null): bool {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Reads the currently executed file (a phar) and registers its manifest * @link https://php.net/manual/en/phar.mapphar.php * @param string|null $alias [optional]

    * The alias that can be used in phar:// URLs to * refer to this archive, rather than its full path. *

    * @param int $offset [optional]

    * Unused variable, here for compatibility with PEAR's PHP_Archive. *

    * @return bool TRUE on success or FALSE on failure. */ final public static function mapPhar(?string $alias = null, int $offset = 0): bool {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Returns the full path on disk or full phar URL to the currently executing Phar archive * @link https://php.net/manual/en/phar.running.php * @param bool $returnPhar

    * If FALSE, the full path on disk to the phar * archive is returned. If TRUE, a full phar URL is returned. *

    * @return string the filename if valid, empty string otherwise. */ final public static function running( #[PhpStormStubsElementAvailable(from: '5.3', to: '5.6')] $returnPhar, #[PhpStormStubsElementAvailable(from: '7.0')] bool $returnPhar = true ): string {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Mount an external path or file to a virtual location within the phar archive * @link https://php.net/manual/en/phar.mount.php * @param string $pharPath

    * The internal path within the phar archive to use as the mounted path location. * This must be a relative path within the phar archive, and must not already exist. *

    * @param string $externalPath

    * A path or URL to an external file or directory to mount within the phar archive *

    * @return void No return. PharException is thrown on failure. */ final public static function mount(string $pharPath, string $externalPath): void {} /** * (Unknown)
    * Defines a list of up to 4 $_SERVER variables that should be modified for execution * @link https://php.net/manual/en/phar.mungserver.php * @param array $variables

    * an array containing as string indices any of * REQUEST_URI, PHP_SELF, * SCRIPT_NAME and SCRIPT_FILENAME. * Other values trigger an exception, and Phar::mungServer * is case-sensitive. *

    * @return void No return. */ final public static function mungServer(array $variables): void {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Completely remove a phar archive from disk and from memory * @link https://php.net/manual/en/phar.unlinkarchive.php * @param string $filename

    * The path on disk to the phar archive. *

    * @throws PharException * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] final public static function unlinkArchive(string $filename) {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * mapPhar for web-based phars. front controller for web applications * @link https://php.net/manual/en/phar.webphar.php * @param null|string $alias [optional]

    * The alias that can be used in phar:// URLs to * refer to this archive, rather than its full path. *

    * @param string|null $index [optional]

    * The location within the phar of the directory index. *

    * @param null|string $fileNotFoundScript [optional]

    * The location of the script to run when a file is not found. This * script should output the proper HTTP 404 headers. *

    * @param null|array $mimeTypes [optional]

    * An array mapping additional file extensions to MIME type. * If the default mapping is sufficient, pass an empty array. * By default, these extensions are mapped to these MIME types: * * $mimes = array( * 'phps' => Phar::PHPS, // pass to highlight_file() * 'c' => 'text/plain', * 'cc' => 'text/plain', * 'cpp' => 'text/plain', * 'c++' => 'text/plain', * 'dtd' => 'text/plain', * 'h' => 'text/plain', * 'log' => 'text/plain', * 'rng' => 'text/plain', * 'txt' => 'text/plain', * 'xsd' => 'text/plain', * 'php' => Phar::PHP, // parse as PHP * 'inc' => Phar::PHP, // parse as PHP * 'avi' => 'video/avi', * 'bmp' => 'image/bmp', * 'css' => 'text/css', * 'gif' => 'image/gif', * 'htm' => 'text/html', * 'html' => 'text/html', * 'htmls' => 'text/html', * 'ico' => 'image/x-ico', * 'jpe' => 'image/jpeg', * 'jpg' => 'image/jpeg', * 'jpeg' => 'image/jpeg', * 'js' => 'application/x-javascript', * 'midi' => 'audio/midi', * 'mid' => 'audio/midi', * 'mod' => 'audio/mod', * 'mov' => 'movie/quicktime', * 'mp3' => 'audio/mp3', * 'mpg' => 'video/mpeg', * 'mpeg' => 'video/mpeg', * 'pdf' => 'application/pdf', * 'png' => 'image/png', * 'swf' => 'application/shockwave-flash', * 'tif' => 'image/tiff', * 'tiff' => 'image/tiff', * 'wav' => 'audio/wav', * 'xbm' => 'image/xbm', * 'xml' => 'text/xml', * ); * *

    * @param null|callable $rewrite [optional]

    * The rewrites function is passed a string as its only parameter and must return a string or FALSE. *

    *

    * If you are using fast-cgi or cgi then the parameter passed to the function is the value of the * $_SERVER['PATH_INFO'] variable. Otherwise, the parameter passed to the function is the value * of the $_SERVER['REQUEST_URI'] variable. *

    *

    * If a string is returned it is used as the internal file path. If FALSE is returned then webPhar() will * send a HTTP 403 Denied Code. *

    * @return void No value is returned. */ final public static function webPhar( ?string $alias = null, ?string $index = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $fileNotFoundScript = null, array $mimeTypes = [], ?callable $rewrite = null ): void {} /** * Returns whether current entry is a directory and not '.' or '..' * @link https://php.net/manual/en/recursivedirectoryiterator.haschildren.php * @param bool $allow_links [optional]

    *

    * @return bool whether the current entry is a directory, but not '.' or '..' */ public function hasChildren($allow_links = false) {} /** * Returns an iterator for the current entry if it is a directory * @link https://php.net/manual/en/recursivedirectoryiterator.getchildren.php * @return mixed The filename, file information, or $this depending on the set flags. * See the FilesystemIterator * constants. */ public function getChildren() {} /** * Rewinds back to the beginning * @link https://php.net/manual/en/filesystemiterator.rewind.php * @return void No value is returned. */ public function rewind() {} /** * Move to the next file * @link https://php.net/manual/en/filesystemiterator.next.php * @return void No value is returned. */ public function next() {} /** * Retrieve the key for the current file * @link https://php.net/manual/en/filesystemiterator.key.php * @return string the pathname or filename depending on the set flags. * See the FilesystemIterator constants. */ public function key() {} /** * The current file * @link https://php.net/manual/en/filesystemiterator.current.php * @return mixed The filename, file information, or $this depending on the set flags. * See the FilesystemIterator constants. */ public function current() {} /** * Check whether current DirectoryIterator position is a valid file * @link https://php.net/manual/en/directoryiterator.valid.php * @return bool TRUE if the position is valid, otherwise FALSE */ public function valid() {} /** * Seek to a DirectoryIterator item * @link https://php.net/manual/en/directoryiterator.seek.php * @param int $position

    * The zero-based numeric position to seek to. *

    * @return void No value is returned. */ public function seek($position) {} public function _bad_state_ex() {} } /** * The PharData class provides a high-level interface to accessing and creating * non-executable tar and zip archives. Because these archives do not contain * a stub and cannot be executed by the phar extension, it is possible to create * and manipulate regular zip and tar files using the PharData class even if * phar.readonly php.ini setting is 1. * @link https://php.net/manual/en/class.phardata.php */ class PharData extends Phar { /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Construct a non-executable tar or zip archive object * @link https://php.net/manual/en/phardata.construct.php * @param string $filename

    * Path to an existing tar/zip archive or to-be-created archive *

    * @param int $flags [optional]

    * Flags to pass to Phar parent class * RecursiveDirectoryIterator. *

    * @param string $alias [optional]

    * Alias with which this Phar archive should be referred to in calls to stream * functionality. *

    * @param int $format [optional]

    * One of the * file format constants * available within the Phar class. *

    */ public function __construct( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = FilesystemIterator::SKIP_DOTS|FilesystemIterator::UNIX_PATHS, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $alias = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $format = 0 ) {} /** * @param string $localName * @return bool */ #[TentativeType] public function offsetExists($localName): bool {} /** * @param string $localName * @return SplFileInfo */ #[TentativeType] public function offsetGet($localName): SplFileInfo {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * set the contents of a file within the tar/zip to those of an external file or string * @link https://php.net/manual/en/phardata.offsetset.php * @param string $localName

    * The filename (relative path) to modify in a tar or zip archive. *

    * @param string $value

    * Content of the file. *

    * @return void No return values. */ #[TentativeType] public function offsetSet($localName, $value): void {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * remove a file from a tar/zip archive * @link https://php.net/manual/en/phardata.offsetunset.php * @param string $localName

    * The filename (relative path) to modify in the tar/zip archive. *

    * @return void */ #[TentativeType] public function offsetUnset($localName): void {} /** * Returns whether current entry is a directory and not '.' or '..' * @link https://php.net/manual/en/recursivedirectoryiterator.haschildren.php * @param bool $allow_links [optional]

    *

    * @return bool whether the current entry is a directory, but not '.' or '..' */ public function hasChildren($allow_links = false) {} /** * Returns an iterator for the current entry if it is a directory * @link https://php.net/manual/en/recursivedirectoryiterator.getchildren.php * @return mixed The filename, file information, or $this depending on the set flags. * See the FilesystemIterator * constants. */ public function getChildren() {} /** * Rewinds back to the beginning * @link https://php.net/manual/en/filesystemiterator.rewind.php * @return void No value is returned. */ public function rewind() {} /** * Move to the next file * @link https://php.net/manual/en/filesystemiterator.next.php * @return void No value is returned. */ public function next() {} /** * Retrieve the key for the current file * @link https://php.net/manual/en/filesystemiterator.key.php * @return string the pathname or filename depending on the set flags. * See the FilesystemIterator constants. */ public function key() {} /** * The current file * @link https://php.net/manual/en/filesystemiterator.current.php * @return mixed The filename, file information, or $this depending on the set flags. * See the FilesystemIterator constants. */ public function current() {} /** * Check whether current DirectoryIterator position is a valid file * @link https://php.net/manual/en/directoryiterator.valid.php * @return bool TRUE if the position is valid, otherwise FALSE */ public function valid() {} /** * Seek to a DirectoryIterator item * @link https://php.net/manual/en/directoryiterator.seek.php * @param int $position

    * The zero-based numeric position to seek to. *

    * @return void No value is returned. */ public function seek($position) {} } /** * The PharFileInfo class provides a high-level interface to the contents * and attributes of a single file within a phar archive. * @link https://php.net/manual/en/class.pharfileinfo.php */ class PharFileInfo extends SplFileInfo { /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Construct a Phar entry object * @link https://php.net/manual/en/pharfileinfo.construct.php * @param string $filename

    * The full url to retrieve a file. If you wish to retrieve the information * for the file my/file.php from the phar boo.phar, * the entry should be phar://boo.phar/my/file.php. *

    */ public function __construct(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename) {} public function __destruct() {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Sets file-specific permission bits * @link https://php.net/manual/en/pharfileinfo.chmod.php * @param int $perms

    * permissions (see chmod) *

    * @return void No value is returned. */ #[TentativeType] public function chmod(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $perms): void {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Compresses the current Phar entry with either zlib or bzip2 compression * @link https://php.net/manual/en/pharfileinfo.compress.php * @param int $compression * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function compress(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $compression) {} /** * (PHP >= 5.3.0, PECL phar >= 2.0.0)
    * Decompresses the current Phar entry within the phar * @link https://php.net/manual/en/pharfileinfo.decompress.php * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function decompress() {} /** * (PHP >= 5.3.0, PECL phar >= 1.2.0)
    * Deletes the metadata of the entry * @link https://php.net/manual/en/pharfileinfo.delmetadata.php * @return bool TRUE if successful, FALSE if the entry had no metadata. * As with all functionality that modifies the contents of * a phar, the phar.readonly INI variable * must be off in order to succeed if the file is within a Phar * archive. Files within PharData archives do not have * this restriction. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function delMetadata() {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Returns the actual size of the file (with compression) inside the Phar archive * @link https://php.net/manual/en/pharfileinfo.getcompressedsize.php * @return int<0, max> The size in bytes of the file within the Phar archive on disk. */ #[TentativeType] public function getCompressedSize(): int {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Returns CRC32 code or throws an exception if CRC has not been verified * @link https://php.net/manual/en/pharfileinfo.getcrc32.php * @return int The crc32 checksum of the file within the Phar archive. */ #[TentativeType] public function getCRC32(): int {} #[TentativeType] public function getContent(): string {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Returns file-specific meta-data saved with a file * @link https://php.net/manual/en/pharfileinfo.getmetadata.php * @param array $unserializeOptions [optional] if is set to anything other than the default, * the resulting metadata won't be cached and this won't return the value from the cache * @return mixed any PHP variable that can be serialized and is stored as meta-data for the file, * or NULL if no meta-data is stored. */ #[TentativeType] public function getMetadata(#[PhpStormStubsElementAvailable(from: '8.0')] array $unserializeOptions = []): mixed {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Returns the Phar file entry flags * @link https://php.net/manual/en/pharfileinfo.getpharflags.php * @return int The Phar flags (always 0 in the current implementation) */ #[TentativeType] public function getPharFlags(): int {} /** * (PHP >= 5.3.0, PECL phar >= 1.2.0)
    * Returns the metadata of the entry * @link https://php.net/manual/en/pharfileinfo.hasmetadata.php * @return bool FALSE if no metadata is set or is NULL, TRUE if metadata is not NULL */ #[TentativeType] public function hasMetadata(): bool {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Returns whether the entry is compressed * @link https://php.net/manual/en/pharfileinfo.iscompressed.php * @param int $compression [optional]

    * One of Phar::GZ or Phar::BZ2, * defaults to any compression. *

    * @return bool TRUE if the file is compressed within the Phar archive, FALSE if not. */ #[TentativeType] public function isCompressed(#[LanguageLevelTypeAware(['8.0' => 'int|null'], default: '')] $compression = null): bool {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Returns whether file entry has had its CRC verified * @link https://php.net/manual/en/pharfileinfo.iscrcchecked.php * @return bool TRUE if the file has had its CRC verified, FALSE if not. */ #[TentativeType] public function isCRCChecked(): bool {} /** * (PHP >= 5.3.0, PECL phar >= 1.0.0)
    * Sets file-specific meta-data saved with a file * @link https://php.net/manual/en/pharfileinfo.setmetadata.php * @param mixed $metadata

    * Any PHP variable containing information to store alongside a file *

    * @return void No value is returned. */ #[TentativeType] public function setMetadata(#[LanguageLevelTypeAware(['8.0' => 'mixed'], default: '')] $metadata): void {} } // End of Phar v.2.0.1 'int'], default: '')] public $status; /** * System status of the Zip Archive * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $statusSys; /** * Number of files in archive * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $numFiles; /** * File name in the file system * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $filename; /** * Comment for the archive * @var string */ #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $comment; /** * @var int */ #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $lastId; /** * (PHP 5 >= 5.2.0, PECL zip >= 1.1.0)
    * Open a ZIP file archive * * @link https://php.net/manual/en/ziparchive.open.php * * @param string $filename

    * The file name of the ZIP archive to open. *

    * @param int $flags [optional]

    * The mode to use to open the archive. *

    *

    * ZipArchive::OVERWRITE *

    * * @return int|bool Error codes *

    * Returns TRUE on success, FALSE or the error code on error. *

    *

    * ZipArchive::ER_EXISTS *

    *

    * File already exists. *

    *

    * ZipArchive::ER_INCONS *

    *

    * Zip archive inconsistent. *

    *

    * ZipArchive::ER_INVAL *

    *

    * Invalid argument. *

    *

    * ZipArchive::ER_MEMORY *

    *

    * Malloc failure. *

    *

    * ZipArchive::ER_NOENT *

    *

    * No such file. *

    *

    * ZipArchive::ER_NOZIP *

    *

    * Not a zip archive. *

    *

    * ZipArchive::ER_OPEN *

    *

    * Can't open file. *

    *

    * ZipArchive::ER_READ *

    *

    * Read error. *

    *

    * ZipArchive::ER_SEEK *

    *

    * Seek error. *

    */ #[TentativeType] public function open( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): int|bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.1.0)
    * Close the active archive (opened or newly created) * @link https://php.net/manual/en/ziparchive.close.php * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function close(): bool {} /** * (PHP 7 >= 7.2.0, PECL zip >= 1.15.0)
    * Counts the number of files in the archive. * @link https://www.php.net/manual/en/ziparchive.count.php * @return int * @since 7.2 */ #[TentativeType] public function count(): int {} /** * Returns the status error message, system and/or zip messages * @link https://php.net/manual/en/ziparchive.getstatusstring.php * @return string|false a string with the status message on success or FALSE on failure. * @since 5.2.7 */ #[TentativeType] public function getStatusString(): string {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.8.0)
    * Add a new directory * @link https://php.net/manual/en/ziparchive.addemptydir.php * @param string $dirname

    * The directory to add. *

    * @param int $flags [optional] Set how to manage name encoding (ZipArchive::FL_ENC_*) and entry replacement (ZipArchive::FL_OVERWRITE) * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function addEmptyDir( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $dirname, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags ): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.1.0)
    * Add a file to a ZIP archive using its contents * @link https://php.net/manual/en/ziparchive.addfromstring.php * @param string $name

    * The name of the entry to create. *

    * @param string $content

    * The contents to use to create the entry. It is used in a binary * safe mode. *

    * @param int $flags [optional] Set how to manage name encoding (ZipArchive::FL_ENC_*) and entry replacement (ZipArchive::FL_OVERWRITE) * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function addFromString( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $content, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 8192 ): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.1.0)
    * Adds a file to a ZIP archive from the given path * @link https://php.net/manual/en/ziparchive.addfile.php * @param string $filepath

    * The path to the file to add. *

    * @param string $entryname [optional]

    * If supplied, this is the local name inside the ZIP archive that will override the filename. *

    * @param int $start [optional]

    * This parameter is not used but is required to extend ZipArchive. *

    * @param int $length [optional]

    * This parameter is not used but is required to extend ZipArchive. *

    * @param int $flags [optional] Set how to manage name encoding (ZipArchive::FL_ENC_*) and entry replacement (ZipArchive::FL_OVERWRITE) * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function addFile( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filepath, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $entryname = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $start = 0, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $length = 0, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 8192 ): bool {} /** * (PHP 5 >= 5.3.0, PECL zip >= 1.9.0)
    * Add files from a directory by glob pattern * @link https://php.net/manual/en/ziparchive.addglob.php * @param string $pattern

    * A glob pattern against which files will be matched. *

    * @param int $flags [optional]

    * A bit mask of glob() flags. *

    * @param array $options [optional]

    * An associative array of options. Available options are: *

    *

    * "add_path" *

    *

    * Prefix to prepend when translating to the local path of the file within * the archive. This is applied after any remove operations defined by the * "remove_path" or "remove_all_path" * options. *

    * @return array|false */ #[TentativeType] public function addGlob( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $pattern, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0, array $options = [] ): array|false {} /** * (PHP 5 >= 5.3.0, PECL zip >= 1.9.0)
    * Add files from a directory by PCRE pattern * @link https://php.net/manual/en/ziparchive.addpattern.php * @param string $pattern

    * A PCRE pattern against which files will be matched. *

    * @param string $path [optional]

    * The directory that will be scanned. Defaults to the current working directory. *

    * @param array $options [optional]

    * An associative array of options accepted by ZipArchive::addGlob. *

    * @return array|false */ #[TentativeType] public function addPattern( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $pattern, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $path = '.', array $options = [] ): array|false {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.5.0)
    * Renames an entry defined by its index * @link https://php.net/manual/en/ziparchive.renameindex.php * @param int $index

    * Index of the entry to rename. *

    * @param string $new_name

    * New name. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function renameIndex( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $new_name ):bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.5.0)
    * Renames an entry defined by its name * @link https://php.net/manual/en/ziparchive.renamename.php * @param string $name

    * Name of the entry to rename. *

    * @param string $new_name

    * New name. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function renameName( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $new_name ): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.4.0)
    * Set the comment of a ZIP archive * @link https://php.net/manual/en/ziparchive.setarchivecomment.php * @param string $comment

    * The contents of the comment. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function setArchiveComment(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $comment): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.1.0)
    * Returns the Zip archive comment * @link https://php.net/manual/en/ziparchive.getarchivecomment.php * @param int $flags [optional]

    * If flags is set to ZipArchive::FL_UNCHANGED, the original unchanged * comment is returned. *

    * @return string|false the Zip archive comment or FALSE on failure. */ #[TentativeType] public function getArchiveComment(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null): string|false {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.4.0)
    * Set the comment of an entry defined by its index * @link https://php.net/manual/en/ziparchive.setcommentindex.php * @param int $index

    * Index of the entry. *

    * @param string $comment

    * The contents of the comment. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function setCommentIndex( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $comment ): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.4.0)
    * Set the comment of an entry defined by its name * @link https://php.net/manual/en/ziparchive.setcommentname.php * @param string $name

    * Name of the entry. *

    * @param string $comment

    * The contents of the comment. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function setCommentName( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $comment ): bool {} /** * Set the compression method of an entry defined by its index * @link https://php.net/manual/en/ziparchive.setcompressionindex.php * @param int $index Index of the entry. * @param int $method The compression method. Either ZipArchive::CM_DEFAULT, ZipArchive::CM_STORE or ZipArchive::CM_DEFLATE. * @param int $compflags [optional] Compression flags. Currently unused. * @return bool Returns TRUE on success or FALSE on failure. * @since 7.0 */ #[TentativeType] public function setCompressionIndex(int $index, int $method, int $compflags = 0): bool {} /** * Set the compression method of an entry defined by its name * https://secure.php.net/manual/en/ziparchive.setcompressionname.php * @param string $name Name of the entry. * @param int $method The compression method. Either ZipArchive::CM_DEFAULT, ZipArchive::CM_STORE or ZipArchive::CM_DEFLATE. * @param int $compflags [optional] Compression flags. Currently unused. * @return bool Returns TRUE on success or FALSE on failure. * @since 7.0 */ #[TentativeType] public function setCompressionName(string $name, int $method, int $compflags = 0): bool {} /** * Set the encryption method of an entry defined by its index * @link https://php.net/manual/en/ziparchive.setencryptionindex.php * @param int $index Index of the entry. * @param int $method The encryption method defined by one of the ZipArchive::EM_ constants. * @param string|null $password [optional] Optional password, default used when missing. * @return bool Returns TRUE on success or FALSE on failure. * @since 7.2 */ #[TentativeType] public function setEncryptionIndex(int $index, int $method, ?string $password = null): bool {} /** * Set the encryption method of an entry defined by its name * @link https://php.net/manual/en/ziparchive.setencryptionname.php * @param string $name Name of the entry. * @param int $method The encryption method defined by one of the ZipArchive::EM_ constants. * @param string|null $password [optional] Optional password, default used when missing. * @return bool Returns TRUE on success or FALSE on failure. * @since 7.2 */ #[TentativeType] public function setEncryptionName(string $name, int $method, ?string $password = null): bool {} /** * (PHP 5 >= 5.6.0, PECL zip >= 1.12.0)
    * @param string $password * @return bool */ #[TentativeType] public function setPassword(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $password): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.4.0)
    * Returns the comment of an entry using the entry index * @link https://php.net/manual/en/ziparchive.getcommentindex.php * @param int $index

    * Index of the entry *

    * @param int $flags [optional]

    * If flags is set to ZipArchive::FL_UNCHANGED, the original unchanged * comment is returned. *

    * @return string|false the comment on success or FALSE on failure. */ #[TentativeType] public function getCommentIndex( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): string|false {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.4.0)
    * Returns the comment of an entry using the entry name * @link https://php.net/manual/en/ziparchive.getcommentname.php * @param string $name

    * Name of the entry *

    * @param int $flags [optional]

    * If flags is set to ZipArchive::FL_UNCHANGED, the original unchanged * comment is returned. *

    * @return string|false the comment on success or FALSE on failure. */ #[TentativeType] public function getCommentName( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): string|false {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.5.0)
    * delete an entry in the archive using its index * @link https://php.net/manual/en/ziparchive.deleteindex.php * @param int $index

    * Index of the entry to delete. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function deleteIndex(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.5.0)
    * delete an entry in the archive using its name * @link https://php.net/manual/en/ziparchive.deletename.php * @param string $name

    * Name of the entry to delete. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function deleteName(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.5.0)
    * Get the details of an entry defined by its name. * @link https://php.net/manual/en/ziparchive.statname.php * @param string $name

    * Name of the entry *

    * @param int $flags [optional]

    * The flags argument specifies how the name lookup should be done. * Also, ZipArchive::FL_UNCHANGED may be ORed to it to request * information about the original file in the archive, * ignoring any changes made. * ZipArchive::FL_NOCASE *

    * @return array{name: string, index: int, crc: int, size: int, mtime: int, comp_size: int, comp_method: int, encryption_method: int}|false an array containing the entry details or FALSE on failure. */ #[TentativeType] public function statName( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): array|false {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.1.0)
    * Get the details of an entry defined by its index. * @link https://php.net/manual/en/ziparchive.statindex.php * @param int $index

    * Index of the entry *

    * @param int $flags [optional]

    * ZipArchive::FL_UNCHANGED may be ORed to it to request * information about the original file in the archive, * ignoring any changes made. *

    * @return array{name: string, index: int, crc: int, size: int, mtime: int, comp_size: int, comp_method: int, encryption_method: int}|false an array containing the entry details or FALSE on failure. */ #[TentativeType] public function statIndex( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ):array|false {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.5.0)
    * Returns the index of the entry in the archive * @link https://php.net/manual/en/ziparchive.locatename.php * @param string $name

    * The name of the entry to look up *

    * @param int $flags [optional]

    * The flags are specified by ORing the following values, * or 0 for none of them. * ZipArchive::FL_NOCASE *

    * @return int|false the index of the entry on success or FALSE on failure. */ #[TentativeType] public function locateName( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): int|false {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.5.0)
    * Returns the name of an entry using its index * @link https://php.net/manual/en/ziparchive.getnameindex.php * @param int $index

    * Index of the entry. *

    * @param int $flags [optional]

    * If flags is set to ZipArchive::FL_UNCHANGED, the original unchanged * name is returned. *

    * @return string|false the name on success or FALSE on failure. */ #[TentativeType] public function getNameIndex( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ):string|false {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.1.0)
    * Revert all global changes done in the archive. * @link https://php.net/manual/en/ziparchive.unchangearchive.php * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function unchangeArchive(): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.1.0)
    * Undo all changes done in the archive * @link https://php.net/manual/en/ziparchive.unchangeall.php * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function unchangeAll(): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.1.0)
    * Revert all changes done to an entry at the given index * @link https://php.net/manual/en/ziparchive.unchangeindex.php * @param int $index

    * Index of the entry. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function unchangeIndex(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.5.0)
    * Revert all changes done to an entry with the given name. * @link https://php.net/manual/en/ziparchive.unchangename.php * @param string $name

    * Name of the entry. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function unchangeName(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.1.0)
    * Extract the archive contents * @link https://php.net/manual/en/ziparchive.extractto.php * @param string $pathto

    * Location where to extract the files. *

    * @param string[]|string|null $files [optional]

    * The entries to extract. It accepts either a single entry name or * an array of names. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function extractTo( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $pathto, #[LanguageLevelTypeAware(['8.0' => 'array|string|null'], default: '')] $files = null ): bool {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.1.0)
    * Returns the entry contents using its name * @link https://php.net/manual/en/ziparchive.getfromname.php * @param string $name

    * Name of the entry *

    * @param int $len [optional]

    * The length to be read from the entry. If 0, then the * entire entry is read. *

    * @param int $flags [optional]

    * The flags to use to open the archive. the following values may * be ORed to it. * ZipArchive::FL_UNCHANGED *

    * @return string|false the contents of the entry on success or FALSE on failure. */ #[TentativeType] public function getFromName( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $len = 0, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): string|false {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.3.0)
    * Returns the entry contents using its index * @link https://php.net/manual/en/ziparchive.getfromindex.php * @param int $index

    * Index of the entry *

    * @param int $len [optional]

    * The length to be read from the entry. If 0, then the * entire entry is read. *

    * @param int $flags [optional]

    * The flags to use to open the archive. the following values may * be ORed to it. *

    *

    * ZipArchive::FL_UNCHANGED *

    * @return string|false the contents of the entry on success or FALSE on failure. */ #[TentativeType] public function getFromIndex( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $len = 0, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): string|false {} /** * (PHP 5 >= 5.2.0, PECL zip >= 1.1.0)
    * Get a file handler to the entry defined by its name (read only). * @link https://php.net/manual/en/ziparchive.getstream.php * @param string $name

    * The name of the entry to use. *

    * @return resource|false a file pointer (resource) on success or FALSE on failure. */ public function getStream(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name) {} /** * (PHP 8 >= 8.2.0, PECL zip >= 1.20.0)
    * Get a file handler to the entry defined by its index (read only) * @link https://php.net/manual/en/ziparchive.getstreamindex.php * @param int $index

    * Index of the entry *

    * @param int $flags [optional]

    * If flags is set to ZipArchive::FL_UNCHANGED, the original unchanged stream is returned. *

    * @return resource|false a file pointer (resource) on success or FALSE on failure. */ public function getStreamIndex( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = 0 ) {} /** * Set the external attributes of an entry defined by its name * @link https://www.php.net/manual/en/ziparchive.setexternalattributesname.php * @param string $name Name of the entry * @param int $opsys The operating system code defined by one of the ZipArchive::OPSYS_ constants. * @param int $attr The external attributes. Value depends on operating system. * @param int $flags [optional] Optional flags. Currently unused. * @return bool Returns TRUE on success or FALSE on failure. */ #[TentativeType] public function setExternalAttributesName( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $opsys, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $attr, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): bool {} /** * Retrieve the external attributes of an entry defined by its name * @link https://www.php.net/manual/en/ziparchive.getexternalattributesname.php * @param string $name Name of the entry * @param int &$opsys On success, receive the operating system code defined by one of the ZipArchive::OPSYS_ constants. * @param int &$attr On success, receive the external attributes. Value depends on operating system. * @param int $flags [optional] If flags is set to ZipArchive::FL_UNCHANGED, the original unchanged attributes are returned. * @return bool Returns TRUE on success or FALSE on failure. */ #[TentativeType] public function getExternalAttributesName( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] &$opsys, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] &$attr, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): bool {} /** * Set the external attributes of an entry defined by its index * @link https://www.php.net/manual/en/ziparchive.setexternalattributesindex.php * @param int $index Index of the entry. * @param int $opsys The operating system code defined by one of the ZipArchive::OPSYS_ constants. * @param int $attr The external attributes. Value depends on operating system. * @param int $flags [optional] Optional flags. Currently unused. * @return bool Returns TRUE on success or FALSE on failure. */ #[TentativeType] public function setExternalAttributesIndex( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $opsys, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $attr, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): bool {} /** * Retrieve the external attributes of an entry defined by its index * @link https://www.php.net/manual/en/ziparchive.getexternalattributesindex.php * @param int $index Index of the entry. * @param int &$opsys On success, receive the operating system code defined by one of the ZipArchive::OPSYS_ constants. * @param int &$attr On success, receive the external attributes. Value depends on operating system. * @param int $flags [optional] If flags is set to ZipArchive::FL_UNCHANGED, the original unchanged attributes are returned. * @return bool Returns TRUE on success or FALSE on failure. */ #[TentativeType] public function getExternalAttributesIndex( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] &$opsys, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] &$attr, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): bool {} #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] public static function isEncryptionMethodSupported( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $method, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $enc = true ) {} #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] public static function isCompressionMethodSupported( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $method, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $enc = true ) {} #[TentativeType] public function registerCancelCallback(#[LanguageLevelTypeAware(['8.0' => 'callable'], default: '')] $callback): bool {} #[TentativeType] public function registerProgressCallback( #[LanguageLevelTypeAware(['8.0' => 'float'], default: '')] $rate, #[LanguageLevelTypeAware(['8.0' => 'callable'], default: '')] $callback ): bool {} #[TentativeType] public function setMtimeName( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $timestamp, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): bool {} #[TentativeType] public function setMtimeIndex( #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $timestamp, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): bool {} #[TentativeType] public function replaceFile( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filepath, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $index, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $start = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $length = null, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = null ): bool {} #[LanguageLevelTypeAware(['8.0' => 'void'], default: '')] public function clearError() {} /** * @param int $flag * @param int $value * @return bool */ #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] public function setArchiveFlag( #[LanguageLevelTypeAware(['8.3' => 'int'], default: '')] $flag, #[LanguageLevelTypeAware(['8.3' => 'int'], default: '')] $value ) {} /** * @param int $flag * @param int $flags * @return int */ #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] public function getArchiveFlag( #[LanguageLevelTypeAware(['8.3' => 'int'], default: '')] $flag, #[LanguageLevelTypeAware(['8.3' => 'int'], default: '')] $flags = 0 ) {} /** * @param string $name * @param int $flags * @return void */ public function getStreamName( #[LanguageLevelTypeAware(['8.2' => 'string'], default: '')] $name, #[LanguageLevelTypeAware(['8.2' => 'int'], default: '')] $flags = 0 ) {} } /** * (PHP 4 >= 4.1.0, PHP 5 >= 5.2.0, PECL zip >= 1.0.0)
    * Open a ZIP file archive * @link https://php.net/manual/en/function.zip-open.php * @param string $filename

    * The file name of the ZIP archive to open. *

    * @return resource|int|false a resource handle for later use with * zip_read and zip_close * or returns the number of error if filename does not * exist or in case of other error. * @deprecated 8.0 Use {@link ZipArchive} instead. */ function zip_open(string $filename) {} /** * (PHP 4 >= 4.1.0, PHP 5 >= 5.2.0, PECL zip >= 1.0.0)
    * Close a ZIP file archive * @link https://php.net/manual/en/function.zip-close.php * @param resource $zip

    * A ZIP file previously opened with zip_open. *

    * @return void No value is returned. * @deprecated 8.0 Use {@link ZipArchive} instead. */ function zip_close($zip): void {} /** * (PHP 4 >= 4.1.0, PHP 5 >= 5.2.0, PECL zip >= 1.0.0)
    * Read next entry in a ZIP file archive * @link https://php.net/manual/en/function.zip-read.php * @param resource $zip

    * A ZIP file previously opened with zip_open. *

    * @return resource|false a directory entry resource for later use with the * zip_entry_... functions, or FALSE if * there are no more entries to read, or an error code if an error * occurred. * @deprecated 8.0 Use {@link ZipArchive} instead. */ function zip_read($zip) {} /** * (PHP 4 >= 4.1.0, PHP 5 >= 5.2.0, PECL zip >= 1.0.0)
    * Open a directory entry for reading * @link https://php.net/manual/en/function.zip-entry-open.php * @param resource $zip_dp

    * A valid resource handle returned by zip_open. *

    * @param resource $zip_entry

    * A directory entry returned by zip_read. *

    * @param string $mode [optional]

    * Any of the modes specified in the documentation of * fopen. *

    *

    * Currently, mode is ignored and is always * "rb". This is due to the fact that zip support * in PHP is read only access. *

    * @return bool TRUE on success or FALSE on failure. *

    * Unlike fopen and other similar functions, * the return value of zip_entry_open only * indicates the result of the operation and is not needed for * reading or closing the directory entry. *

    */ #[Deprecated(reason: 'This function is deprecated in favor of the Object API', since: "8.0")] function zip_entry_open($zip_dp, $zip_entry, string $mode = 'rb'): bool {} /** * (PHP 4 >= 4.1.0, PHP 5 >= 5.2.0, PECL zip >= 1.0.0)
    * Close a directory entry * @link https://php.net/manual/en/function.zip-entry-close.php * @param resource $zip_entry

    * A directory entry previously opened zip_entry_open. *

    * @return bool TRUE on success or FALSE on failure. * @deprecated 8.0 Use {@link ZipArchive} instead. */ function zip_entry_close($zip_entry): bool {} /** * (PHP 4 >= 4.1.0, PHP 5 >= 5.2.0, PECL zip >= 1.0.0)
    * Read from an open directory entry * @link https://php.net/manual/en/function.zip-entry-read.php * @param resource $zip_entry

    * A directory entry returned by zip_read. *

    * @param int $len [optional]

    * The number of bytes to return. *

    *

    * This should be the uncompressed length you wish to read. *

    * @return string|false the data read, empty string on end of a file, or FALSE on error. * @deprecated 8.0 Use {@link ZipArchive} instead. */ function zip_entry_read($zip_entry, int $len = 1024): string|false {} /** * (PHP 4 >= 4.1.0, PHP 5 >= 5.2.0, PECL zip >= 1.0.0)
    * Retrieve the actual file size of a directory entry * @link https://php.net/manual/en/function.zip-entry-filesize.php * @param resource $zip_entry

    * A directory entry returned by zip_read. *

    * @return int|false The size of the directory entry. * @deprecated 8.0 Use {@link ZipArchive} instead. */ function zip_entry_filesize($zip_entry): int|false {} /** * (PHP 4 >= 4.1.0, PHP 5 >= 5.2.0, PECL zip >= 1.0.0)
    * Retrieve the name of a directory entry * @link https://php.net/manual/en/function.zip-entry-name.php * @param resource $zip_entry

    * A directory entry returned by zip_read. *

    * @return string|false The name of the directory entry. * @deprecated 8.0 Use {@link ZipArchive} instead. */ function zip_entry_name($zip_entry): string|false {} /** * (PHP 4 >= 4.1.0, PHP 5 >= 5.2.0, PECL zip >= 1.0.0)
    * Retrieve the compressed size of a directory entry * @link https://php.net/manual/en/function.zip-entry-compressedsize.php * @param resource $zip_entry

    * A directory entry returned by zip_read. *

    * @return int|false The compressed size. * @deprecated 8.0 Use {@link ZipArchive} instead. */ function zip_entry_compressedsize($zip_entry): int|false {} /** * (PHP 4 >= 4.1.0, PHP 5 >= 5.2.0, PECL zip >= 1.0.0)
    * Retrieve the compression method of a directory entry * @link https://php.net/manual/en/function.zip-entry-compressionmethod.php * @param resource $zip_entry

    * A directory entry returned by zip_read. *

    * @return string|false The compression method. * @deprecated 8.0 Use {@link ZipArchive} instead. */ function zip_entry_compressionmethod($zip_entry): string|false {} // End of zip v.1.11.0 * First epoch:version-release string *

    * @param string $evr2

    * Second epoch:version-release string *

    * @return int

    * < 0 if evr1 < evr2, > 0 if evr1 > evr2, 0 if equal. *

    * @since 0.1.0 */ function rpmvercmp(string $evr1, string $evr2) {} /** * Retrieve information from a RPM file, reading its metadata. * If given error will be used to store error message * instead of raising a warning. The return * value is a hash table, * or false if it fails. * * @param string $path

    * Path to the RPM file. *

    * @param bool $full [optional]

    * If TRUE all information headers for the file are retrieved, else only a minimal set. *

    * @param null|string &$error [optional]

    * If provided, will receive the possible error message, and will avoid a runtime warning. *

    * * @return array|null

    * An array of information or NULL on error. *

    * @since 0.1.0 */ function rpminfo(string $path, bool $full = false, ?string &$error = null) {} /** * Retrieve information about an installed package, from the system RPM database. * * @param string $nevr

    * Name with optional epoch, version and release. *

    * @param bool $full [optional]

    * If TRUE all information headers for the file are retrieved, else only a minimal set. *

    * * @return array|null

    * An array of arrays of information or NULL on error. *

    * @since 0.2.0 */ function rpmdbinfo(string $nevr, bool $full = false) {} /** * Retriev information from the local RPM database. * * @param string $pattern

    * Value to search for. *

    * @param int $rpmtag [optional]

    * Search criterion, one of RPMTAG_* constant. *

    * @param int $rpmmire [optional]

    * Pattern type, one of RPMMIRE_* constant. * When < 0 the criterion must equals the value, and database index is used if possible. *

    * @param bool $full [optional]

    * If TRUE all information headers for the file are retrieved, else only a minimal set. *

    * * @return array|null

    * An array of arrays of information or NULL on error. *

    * @since 0.3.0 */ function rpmdbsearch(string $pattern, int $rpmtag = RPMTAG_NAME, int $rpmmire = -1, bool $full = false) {} /** * Add an additional retrieved tag in subsequent queries. * * @param int $tag One of RPMTAG_* constant, see the rpminfo constants page. * * @return bool Returns true on success or false on failure. * @since 0.5.0 */ function rpmaddtag(int $tag): bool {} NULL on error. * @link https://secure.php.net/serialize PHP default serialize */ function igbinary_serialize($value) {} /** Creates a PHP value from a stored representation. * igbinary_unserialize() takes a single serialized variable and converts it back into a PHP value. * * If the variable being unserialized is an object, after successfully reconstructing the object * PHP will automatically attempt to call the __wakeup() member function (if it exists). * In case the passed string is not unserializeable, NULL is returned and E_WARNING is issued. * * @param string $str The serialized string. * @return mixed|false The converted value is returned, and can be a boolean, integer, float, string, array, object or false by empty string input. * @link https://secure.php.net/manual/en/function.unserialize.php PHP default unserialize * @link https://secure.php.net/~helly/php/ext/spl/interfaceSerializable.html Serializable */ function igbinary_unserialize($str) {} // End of igbinary v.1.0.0 * The MySQL server. It can also include a port number. e.g. * "hostname:port" or a path to a local socket e.g. ":/path/to/socket" for * the localhost. *

    *

    * If the PHP directive * mysql.default_host is undefined (default), then the default * value is 'localhost:3306'. In "ini.sql.safe-mode", this parameter is ignored * and value 'localhost:3306' is always used. *

    * @param string $username [optional]

    * The username. Default value is defined by mysql.default_user. In * "ini.sql.safe-mode", this parameter is ignored and the name of the user that * owns the server process is used. *

    * @param string $password [optional]

    * The password. Default value is defined by mysql.default_password. In * "ini.sql.safe-mode", this parameter is ignored and empty password is used. *

    * @param bool $new_link [optional]

    * If a second call is made to mysql_connect * with the same arguments, no new link will be established, but * instead, the link identifier of the already opened link will be * returned. The new_link parameter modifies this * behavior and makes mysql_connect always open * a new link, even if mysql_connect was called * before with the same parameters. * In "ini.sql.safe-mode", this parameter is ignored. *

    * @param int $client_flags [optional]

    * The client_flags parameter can be a combination * of the following constants: * 128 (enable LOAD DATA LOCAL handling), * MYSQL_CLIENT_SSL, * MYSQL_CLIENT_COMPRESS, * MYSQL_CLIENT_IGNORE_SPACE or * MYSQL_CLIENT_INTERACTIVE. * Read the section about for further information. * In "ini.sql.safe-mode", this parameter is ignored. *

    * @return resource|false a MySQL link identifier on success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_connect($server = 'ini_get("mysql.default_host")', $username = 'ini_get("mysql.default_user")', $password = 'ini_get("mysql.default_password")', $new_link = false, $client_flags = 0) {} /** * Open a persistent connection to a MySQL server * @link https://php.net/manual/en/function.mysql-pconnect.php * @param string $server [optional]

    * The MySQL server. It can also include a port number. e.g. * "hostname:port" or a path to a local socket e.g. ":/path/to/socket" for * the localhost. *

    *

    * If the PHP directive * mysql.default_host is undefined (default), then the default * value is 'localhost:3306' *

    * @param string $username [optional]

    * The username. Default value is the name of the user that owns the * server process. *

    * @param string $password [optional]

    * The password. Default value is an empty password. *

    * @param int $client_flags [optional]

    * The client_flags parameter can be a combination * of the following constants: * 128 (enable LOAD DATA LOCAL handling), * MYSQL_CLIENT_SSL, * MYSQL_CLIENT_COMPRESS, * MYSQL_CLIENT_IGNORE_SPACE or * MYSQL_CLIENT_INTERACTIVE. *

    * @return resource|false a MySQL persistent link identifier on success, or false on * failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_pconnect($server = 'ini_get("mysql.default_host")', $username = 'ini_get("mysql.default_user")', $password = 'ini_get("mysql.default_password")', $client_flags = null) {} /** * Close MySQL connection * @link https://php.net/manual/en/function.mysql-close.php * @param resource $link_identifier [optional] * @return bool true on success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_close($link_identifier = null) {} /** * Select a MySQL database * @link https://php.net/manual/en/function.mysql-select-db.php * @param string $database_name

    * The name of the database that is to be selected. *

    * @param resource $link_identifier [optional] * @return bool true on success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_select_db($database_name, $link_identifier = null) {} /** * Send a MySQL query * @link https://php.net/manual/en/function.mysql-query.php * @param string $query

    * An SQL query *

    *

    * The query string should not end with a semicolon. * Data inside the query should be properly escaped. *

    * @param resource $link_identifier [optional] * @return resource|bool For SELECT, SHOW, DESCRIBE, EXPLAIN and other statements returning resultset, * mysql_query * returns a resource on success, or false on * error. *

    *

    * For other type of SQL statements, INSERT, UPDATE, DELETE, DROP, etc, * mysql_query returns true on success * or false on error. *

    *

    * The returned result resource should be passed to * mysql_fetch_array, and other * functions for dealing with result tables, to access the returned data. *

    *

    * Use mysql_num_rows to find out how many rows * were returned for a SELECT statement or * mysql_affected_rows to find out how many * rows were affected by a DELETE, INSERT, REPLACE, or UPDATE * statement. *

    *

    * mysql_query will also fail and return false * if the user does not have permission to access the table(s) referenced by * the query. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_query($query, $link_identifier = null) {} /** * @deprecated 5.5 * Send an SQL query to MySQL without fetching and buffering the result rows. * @link https://php.net/manual/en/function.mysql-unbuffered-query.php * @param string $query

    * The SQL query to execute. *

    *

    * Data inside the query should be properly escaped. *

    * @param resource $link_identifier [optional] * @return resource|bool For SELECT, SHOW, DESCRIBE or EXPLAIN statements, * mysql_unbuffered_query * returns a resource on success, or false on * error. *

    *

    * For other type of SQL statements, UPDATE, DELETE, DROP, etc, * mysql_unbuffered_query returns true on success * or false on error. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_unbuffered_query($query, $link_identifier = null) {} /** * Selects a database and executes a query on it * @link https://php.net/manual/en/function.mysql-db-query.php * @param string $database

    * The name of the database that will be selected. *

    * @param string $query

    * The MySQL query. *

    *

    * Data inside the query should be properly escaped. *

    * @param resource $link_identifier [optional] * @return resource|bool a positive MySQL result resource to the query result, * or false on error. The function also returns true/false for * INSERT/UPDATE/DELETE * queries to indicate success/failure. * @removed 7.0 * @see mysql_select_db() * @see mysql_query() */ #[Deprecated('Use mysql_select_db() and mysql_query() instead', since: '5.3')] function mysql_db_query($database, $query, $link_identifier = null) {} /** * List databases available on a MySQL server * @link https://php.net/manual/en/function.mysql-list-dbs.php * @param resource $link_identifier [optional] * @return resource|false a result pointer resource on success, or false on * failure. Use the mysql_tablename function to traverse * this result pointer, or any function for result tables, such as * mysql_fetch_array. * @removed 7.0 */ #[Deprecated(since: '5.4')] function mysql_list_dbs($link_identifier = null) {} /** * List tables in a MySQL database * @link https://php.net/manual/en/function.mysql-list-tables.php * @param string $database

    * The name of the database *

    * @param resource $link_identifier [optional] * @return resource|false A result pointer resource on success or false on failure. *

    * Use the mysql_tablename function to * traverse this result pointer, or any function for result tables, * such as mysql_fetch_array. *

    * @removed 7.0 */ #[Deprecated(since: '5.3')] function mysql_list_tables($database, $link_identifier = null) {} /** * List MySQL table fields * @link https://php.net/manual/en/function.mysql-list-fields.php * @param string $database_name

    * The name of the database that's being queried. *

    * @param string $table_name

    * The name of the table that's being queried. *

    * @param resource $link_identifier [optional] * @return resource|false A result pointer resource on success, or false on * failure. *

    *

    * The returned result can be used with mysql_field_flags, * mysql_field_len, * mysql_field_name * mysql_field_type. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_list_fields($database_name, $table_name, $link_identifier = null) {} /** * List MySQL processes * @link https://php.net/manual/en/function.mysql-list-processes.php * @param resource $link_identifier [optional] * @return resource|false A result pointer resource on success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_list_processes($link_identifier = null) {} /** * Returns the text of the error message from previous MySQL operation * @link https://php.net/manual/en/function.mysql-error.php * @param resource $link_identifier [optional] * @return string the error text from the last MySQL function, or * '' (empty string) if no error occurred. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_error($link_identifier = null) {} /** * Returns the numerical value of the error message from previous MySQL operation * @link https://php.net/manual/en/function.mysql-errno.php * @param resource $link_identifier [optional] * @return int the error number from the last MySQL function, or * 0 (zero) if no error occurred. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_errno($link_identifier = null) {} /** * Get number of affected rows in previous MySQL operation * @link https://php.net/manual/en/function.mysql-affected-rows.php * @param resource $link_identifier [optional] * @return int the number of affected rows on success, and -1 if the last query * failed. *

    *

    * If the last query was a DELETE query with no WHERE clause, all * of the records will have been deleted from the table but this * function will return zero with MySQL versions prior to 4.1.2. *

    *

    * When using UPDATE, MySQL will not update columns where the new value is the * same as the old value. This creates the possibility that * mysql_affected_rows may not actually equal the number * of rows matched, only the number of rows that were literally affected by * the query. *

    *

    * The REPLACE statement first deletes the record with the same primary key * and then inserts the new record. This function returns the number of * deleted records plus the number of inserted records. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_affected_rows($link_identifier = null) {} /** * Get the ID generated in the last query * @link https://php.net/manual/en/function.mysql-insert-id.php * @param resource $link_identifier [optional] * @return int The ID generated for an AUTO_INCREMENT column by the previous * query on success, 0 if the previous * query does not generate an AUTO_INCREMENT value, or false if * no MySQL connection was established. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_insert_id($link_identifier = null) {} /** * Get result data * @link https://php.net/manual/en/function.mysql-result.php * @param resource $result * @param int $row

    * The row number from the result that's being retrieved. Row numbers * start at 0. *

    * @param mixed $field [optional]

    * The name or offset of the field being retrieved. *

    *

    * It can be the field's offset, the field's name, or the field's table * dot field name (tablename.fieldname). If the column name has been * aliased ('select foo as bar from...'), use the alias instead of the * column name. If undefined, the first field is retrieved. *

    * @return string The contents of one cell from a MySQL result set on success, or * false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_result($result, $row, $field = 0) {} /** * Get number of rows in result * @link https://php.net/manual/en/function.mysql-num-rows.php * @param resource $result

    The result resource that is being evaluated. This result comes from a call to mysql_query().

    * @return int|false

    The number of rows in the result set on success or FALSE on failure.

    * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_num_rows($result) {} /** * Get number of fields in result * @link https://php.net/manual/en/function.mysql-num-fields.php * @param resource $result * @return int the number of fields in the result set resource on * success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_num_fields($result) {} /** * Get a result row as an enumerated array * @link https://php.net/manual/en/function.mysql-fetch-row.php * @param resource $result * @return array an numerical array of strings that corresponds to the fetched row, or * false if there are no more rows. *

    *

    * mysql_fetch_row fetches one row of data from * the result associated with the specified result identifier. The * row is returned as an array. Each result column is stored in an * array offset, starting at offset 0. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_fetch_row($result) {} /** * Fetch a result row as an associative array, a numeric array, or both * @link https://php.net/manual/en/function.mysql-fetch-array.php * @param resource $result * @param int $result_type [optional]

    * The type of array that is to be fetched. It's a constant and can * take the following values: MYSQL_ASSOC, * MYSQL_NUM, and * MYSQL_BOTH. *

    * @return array|false an array of strings that corresponds to the fetched row, or false * if there are no more rows. The type of returned array depends on * how result_type is defined. By using * MYSQL_BOTH (default), you'll get an array with both * associative and number indices. Using MYSQL_ASSOC, you * only get associative indices (as mysql_fetch_assoc * works), using MYSQL_NUM, you only get number indices * (as mysql_fetch_row works). *

    *

    * If two or more columns of the result have the same field names, * the last column will take precedence. To access the other column(s) * of the same name, you must use the numeric index of the column or * make an alias for the column. For aliased columns, you cannot * access the contents with the original column name. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_fetch_array($result, $result_type = MYSQL_BOTH) {} /** * Fetch a result row as an associative array * @link https://php.net/manual/en/function.mysql-fetch-assoc.php * @param resource $result * @return array an associative array of strings that corresponds to the fetched row, or * false if there are no more rows. *

    *

    * If two or more columns of the result have the same field names, * the last column will take precedence. To access the other * column(s) of the same name, you either need to access the * result with numeric indices by using * mysql_fetch_row or add alias names. * See the example at the mysql_fetch_array * description about aliases. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_fetch_assoc($result) {} /** * @template T * * Fetch a result row as an object * @link https://php.net/manual/en/function.mysql-fetch-object.php * @param resource $result * @param class-string $class_name [optional]

    * The name of the class to instantiate, set the properties of and return. * If not specified, a stdClass object is returned. *

    * @param array $params [optional]

    * An optional array of parameters to pass to the constructor * for class_name objects. *

    * @return T|stdClass an object with string properties that correspond to the * fetched row, or false if there are no more rows. *

    *

    * mysql_fetch_row fetches one row of data from * the result associated with the specified result identifier. The * row is returned as an array. Each result column is stored in an * array offset, starting at offset 0. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_fetch_object($result, $class_name = 'stdClass', array $params = null) {} /** * Move internal result pointer * @link https://php.net/manual/en/function.mysql-data-seek.php * @param resource $result * @param int $row_number

    * The desired row number of the new result pointer. *

    * @return bool true on success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_data_seek($result, $row_number) {} /** * Get the length of each output in a result * @link https://php.net/manual/en/function.mysql-fetch-lengths.php * @param resource $result * @return array|false An array of lengths on success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_fetch_lengths($result) {} /** * Get column information from a result and return as an object * @link https://php.net/manual/en/function.mysql-fetch-field.php * @param resource $result * @param int $field_offset [optional]

    * The numerical field offset. If the field offset is not specified, the * next field that was not yet retrieved by this function is retrieved. * The field_offset starts at 0. *

    * @return object an object containing field information. The properties * of the object are: *

    *

    * name - column name * table - name of the table the column belongs to * def - default value of the column * max_length - maximum length of the column * not_null - 1 if the column cannot be null * primary_key - 1 if the column is a primary key * unique_key - 1 if the column is a unique key * multiple_key - 1 if the column is a non-unique key * numeric - 1 if the column is numeric * blob - 1 if the column is a BLOB * type - the type of the column * unsigned - 1 if the column is unsigned * zerofill - 1 if the column is zero-filled * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_fetch_field($result, $field_offset = 0) {} /** * Set result pointer to a specified field offset * @link https://php.net/manual/en/function.mysql-field-seek.php * @param resource $result * @param int $field_offset * @return bool true on success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_field_seek($result, $field_offset) {} /** * Free result memory * @link https://php.net/manual/en/function.mysql-free-result.php * @param resource $result * @return bool true on success or false on failure. *

    * If a non-resource is used for the result, an * error of level E_WARNING will be emitted. It's worth noting that * mysql_query only returns a resource * for SELECT, SHOW, EXPLAIN, and DESCRIBE queries. *

    * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_free_result($result) {} /** * Get the name of the specified field in a result * @link https://php.net/manual/en/function.mysql-field-name.php * @param resource $result * @param int $field_offset * @return string|false The name of the specified field index on success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_field_name($result, $field_offset) {} /** * Get name of the table the specified field is in * @link https://php.net/manual/en/function.mysql-field-table.php * @param resource $result * @param int $field_offset * @return string The name of the table on success. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_field_table($result, $field_offset) {} /** * Returns the length of the specified field * @link https://php.net/manual/en/function.mysql-field-len.php * @param resource $result * @param int $field_offset * @return int|false The length of the specified field index on success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_field_len($result, $field_offset) {} /** * Get the type of the specified field in a result * @link https://php.net/manual/en/function.mysql-field-type.php * @param resource $result * @param int $field_offset * @return string The returned field type * will be one of "int", "real", * "string", "blob", and others as * detailed in the MySQL * documentation. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_field_type($result, $field_offset) {} /** * Get the flags associated with the specified field in a result * @link https://php.net/manual/en/function.mysql-field-flags.php * @param resource $result * @param int $field_offset * @return string|false a string of flags associated with the result or false on failure. *

    * The following flags are reported, if your version of MySQL * is current enough to support them: "not_null", * "primary_key", "unique_key", * "multiple_key", "blob", * "unsigned", "zerofill", * "binary", "enum", * "auto_increment" and "timestamp". *

    * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_field_flags($result, $field_offset) {} /** * Escapes a string for use in a mysql_query * @link https://php.net/manual/en/function.mysql-escape-string.php * @param string $unescaped_string

    * The string that is to be escaped. *

    * @return string the escaped string. * @removed 7.0 */ #[Deprecated(replacement: 'mysql_real_escape_string(%parameter0%)', since: '5.3')] function mysql_escape_string($unescaped_string) {} /** * Escapes special characters in a string for use in an SQL statement * @link https://php.net/manual/en/function.mysql-real-escape-string.php * @param string $unescaped_string

    * The string that is to be escaped. *

    * @param resource $link_identifier [optional] * @return string|false the escaped string, or false on error. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_real_escape_string($unescaped_string, $link_identifier = null) {} /** * Get current system status * @link https://php.net/manual/en/function.mysql-stat.php * @param resource $link_identifier [optional] * @return string a string with the status for uptime, threads, queries, open tables, * flush tables and queries per second. For a complete list of other status * variables, you have to use the SHOW STATUS SQL command. * If link_identifier is invalid, null is returned. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_stat($link_identifier = null) {} /** * Return the current thread ID * @link https://php.net/manual/en/function.mysql-thread-id.php * @param resource $link_identifier [optional] * @return int|false The thread ID on success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_thread_id($link_identifier = null) {} /** * Returns the name of the character set * @link https://php.net/manual/en/function.mysql-client-encoding.php * @param resource $link_identifier [optional] * @return string the default character set name for the current connection. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_client_encoding($link_identifier = null) {} /** * Ping a server connection or reconnect if there is no connection * @link https://php.net/manual/en/function.mysql-ping.php * @param resource $link_identifier [optional] * @return bool true if the connection to the server MySQL server is working, * otherwise false. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_ping($link_identifier = null) {} /** * Get MySQL client info * @link https://php.net/manual/en/function.mysql-get-client-info.php * @return string The MySQL client version. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_get_client_info() {} /** * Get MySQL host info * @link https://php.net/manual/en/function.mysql-get-host-info.php * @param resource $link_identifier [optional] * @return string a string describing the type of MySQL connection in use for the * connection or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_get_host_info($link_identifier = null) {} /** * Get MySQL protocol info * @link https://php.net/manual/en/function.mysql-get-proto-info.php * @param resource $link_identifier [optional] * @return int|false the MySQL protocol on success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_get_proto_info($link_identifier = null) {} /** * Get MySQL server info * @link https://php.net/manual/en/function.mysql-get-server-info.php * @param resource $link_identifier [optional] * @return string|false the MySQL server version on success or false on failure. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_get_server_info($link_identifier = null) {} /** * Get information about the most recent query * @link https://php.net/manual/en/function.mysql-info.php * @param resource $link_identifier [optional] * @return string|false information about the statement on success, or false on * failure. See the example below for which statements provide information, * and what the returned value may look like. Statements that are not listed * will return false. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_info($link_identifier = null) {} /** * Sets the client character set * @link https://php.net/manual/en/function.mysql-set-charset.php * @param string $charset

    * A valid character set name. *

    * @param resource $link_identifier [optional] * @return bool true on success or false on failure. * @since 5.2.3 * @removed 7.0 * @see mysqli_set_charset() */ #[Deprecated(replacement: 'Use mysqli_set_charset instead', since: '5.5')] function mysql_set_charset($charset, $link_identifier = null) {} /** * @param $database_name * @param $query * @param $link_identifier [optional] * @removed 7.0 */ #[Deprecated(replacement: "mysql_db_query(%parametersList%)", since: '5.3')] function mysql($database_name, $query, $link_identifier) {} /** * @param $result * @param $field_index * @removed 7.0 */ #[Deprecated(replacement: 'mysql_field_name(%parametersList%)', since: '5.5')] function mysql_fieldname($result, $field_index) {} /** * @param $result * @param $field_offset * @removed 7.0 */ #[Deprecated(replacement: 'mysql_field_table(%parametersList%)', since: '5.5')] function mysql_fieldtable($result, $field_offset) {} /** * @param $result * @param $field_offset * @removed 7.0 */ #[Deprecated(replacement: 'mysql_field_len(%parametersList%)', since: '5.5')] function mysql_fieldlen($result, $field_offset) {} /** * @param $result * @param $field_offset * @removed 7.0 */ #[Deprecated(replacement: 'mysql_field_type(%parametersList%)', since: '5.5')] function mysql_fieldtype($result, $field_offset) {} /** * @param $result * @param $field_offset * @removed 7.0 */ #[Deprecated(replacement: 'mysql_field_flags(%parametersList%)', since: '5.5')] function mysql_fieldflags($result, $field_offset) {} /** * @param $database_name * @param $link_identifier [optional] * @removed 7.0 */ #[Deprecated(replacement: 'mysql_select_db(%parametersList%)', since: '5.5')] function mysql_selectdb($database_name, $link_identifier) {} /** * @param $result * @removed 7.0 */ #[Deprecated(replacement: 'mysql_free_result(%parametersList%)', since: '5.5')] function mysql_freeresult($result) {} /** * @param $result * @removed 7.0 */ #[Deprecated(replacement: 'mysql_num_fields(%parametersList%)', since: '5.5')] function mysql_numfields($result) {} /** * (PHP 4, PHP 5) * Alias of mysql_num_rows() * @link https://php.net/manual/en/function.mysql-num-rows.php * @param resource $result

    The result resource that is being evaluated. This result comes from a call to mysql_query().

    * @return int|false

    The number of rows in the result set on success or FALSE on failure.

    * @removed 7.0 */ #[Deprecated(replacement: 'mysql_num_rows(%parametersList%)', since: '5.5')] function mysql_numrows($result) {} /** * @param $link_identifier [optional] * @removed 7.0 */ #[Deprecated(replacement: 'mysql_list_dbs(%parametersList%)', since: '5.5')] function mysql_listdbs($link_identifier) {} /** * @param $database_name * @param $link_identifier [optional] * @removed 7.0 */ #[Deprecated(replacement: 'mysql_list_tables(%parametersList%)', since: '5.5')] function mysql_listtables($database_name, $link_identifier) {} /** * @param $database_name * @param $table_name * @param $link_identifier [optional] * @removed 7.0 */ #[Deprecated(replacement: 'mysql_list_fields(%parametersList%)', since: '5.5')] function mysql_listfields($database_name, $table_name, $link_identifier) {} /** * Retrieves database name from the call to {@see mysql_list_dbs} * @link https://php.net/manual/en/function.mysql-db-name.php * @param resource $result

    * The result pointer from a call to mysql_list_dbs. *

    * @param int $row

    * The index into the result set. *

    * @param mixed $field [optional]

    * The field name. *

    * @return string|false the database name on success, and false on failure. If false * is returned, use mysql_error to determine the nature * of the error. * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_db_name($result, $row, $field = null) {} /** * @param $result * @param $row * @param $field [optional] * @removed 7.0 */ #[Deprecated(replacement: 'mysql_db_name(%parametersList%)', since: '5.5')] function mysql_dbname($result, $row, $field) {} /** * Get table name of field * @link https://php.net/manual/en/function.mysql-tablename.php * @param resource $result

    * A result pointer resource that's returned from * mysql_list_tables. *

    * @param int $i

    * The integer index (row/table number) *

    * @return string|false The name of the table on success or false on failure. *

    * Use the mysql_tablename function to * traverse this result pointer, or any function for result tables, * such as mysql_fetch_array. *

    * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_tablename($result, $i) {} /** * @param $result * @param $row * @param $field [optional] * @removed 7.0 */ #[Deprecated(since: '5.5')] function mysql_table_name($result, $row, $field) {} /** * Columns are returned into the array having the fieldname as the array * index. * @link https://php.net/manual/en/mysql.constants.php * @deprecated 5.5 * @removed 7.0 */ define('MYSQL_ASSOC', 1); /** * Columns are returned into the array having a numerical index to the * fields. This index starts with 0, the first field in the result. * @link https://php.net/manual/en/mysql.constants.php * @deprecated 5.5 * @removed 7.0 */ define('MYSQL_NUM', 2); /** * Columns are returned into the array having both a numerical index * and the fieldname as the array index. * @link https://php.net/manual/en/mysql.constants.php * @deprecated 5.5 * @removed 7.0 */ define('MYSQL_BOTH', 3); /** * Use compression protocol * @link https://php.net/manual/en/mysql.constants.php * @deprecated 5.5 * @removed 7.0 */ define('MYSQL_CLIENT_COMPRESS', 32); /** * Use SSL encryption. This flag is only available with version 4.x * of the MySQL client library or newer. Version 3.23.x is bundled both * with PHP 4 and Windows binaries of PHP 5. * @link https://php.net/manual/en/mysql.constants.php * @deprecated 5.5 * @removed 7.0 */ define('MYSQL_CLIENT_SSL', 2048); /** * Allow interactive_timeout seconds (instead of wait_timeout) of * inactivity before closing the connection. * @link https://php.net/manual/en/mysql.constants.php * @deprecated 5.5 * @removed 7.0 */ define('MYSQL_CLIENT_INTERACTIVE', 1024); /** * Allow space after function names * @link https://php.net/manual/en/mysql.constants.php * @deprecated 5.5 * @removed 7.0 */ define('MYSQL_CLIENT_IGNORE_SPACE', 256); // End of mysql v.1.0 data pairs. A URL to a file containing a SVM Light formatted problem, with the each line being a new training example, the start of each line containing the class (1, -1) then a series of tab separated data values shows as key:value. A opened stream pointing to a data source formatted as in the file above. * @param array|null $weights Weights are an optional set of weighting parameters for the different classes, to help account for unbalanced training sets. For example, if the classes were 1 and -1, and -1 had significantly more example than one, the weight for -1 could be 0.5. Weights should be in the range 0-1. * @return SVMModel Returns an SVMModel that can be used to classify previously unseen data. Throws SVMException on error * @throws SMVException * @link https://www.php.net/manual/en/svm.train.php */ public function train(array $problem, array $weights = null): SVMModel {} } value pairs in increasing key order, but not necessarily continuous. * @return float the predicted value. This will be a class label in the case of classification, a real value in the case of regression. Throws SVMException on error * @throws SVMException Throws SVMException on error * @link https://www.php.net/manual/en/svmmodel.predict-probability.php */ public function predict_probability(array $data): float {} /** * Predict a value for previously unseen data * * This function accepts an array of data and attempts to predict the class or regression value based on the model extracted from previously trained data. * @param array $data The array to be classified. This should be a series of key => value pairs in increasing key order, but not necessarily continuous. * @return float the predicted value. This will be a class label in the case of classification, a real value in the case of regression. Throws SVMException on error * @throws SVMException Throws SVMException on error * @link https://www.php.net/manual/en/svmmodel.predict.php */ public function predict(array $data): float {} /** * Save a model to a file, for later use * @param string $filename The file to save the model to. * @return bool Throws SVMException on error. Returns true on success. * @throws SVMException Throws SVMException on error * @link https://www.php.net/manual/en/svmmodel.save.php */ public function save(string $filename): bool {} } 'string'], default: '')] $data, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $options = 0, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $dataIsURL = false, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $namespaceOrPrefix = "", #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $isPrefix = false ) {} /** * Provides access to element's children * private Method not callable directly, stub exists for typehint only * @param string $name child name * @return static */ private function __get($name) {} /** * Return a well-formed XML string based on SimpleXML element * @link https://php.net/manual/en/simplexmlelement.asxml.php * @param string $filename [optional]

    * If specified, the function writes the data to the file rather than * returning it. *

    * @return string|bool If the filename isn't specified, this function * returns a string on success and FALSE on error. If the * parameter is specified, it returns TRUE if the file was written * successfully and FALSE otherwise. * @since 5.0.1 */ #[TentativeType] public function asXML(#[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $filename = null): string|bool {} /** * Alias of SimpleXMLElement::asXML * Return a well-formed XML string based on SimpleXML element * @link https://php.net/manual/en/simplexmlelement.savexml.php * @param string $filename [optional]

    * If specified, the function writes the data to the file rather than * returning it. *

    * @return string|bool If the filename isn't specified, this function * returns a string on success and false on error. If the * parameter is specified, it returns true if the file was written * successfully and false otherwise. */ #[TentativeType] public function saveXML(#[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $filename = null): string|bool {} /** * Runs XPath query on XML data * @link https://php.net/manual/en/simplexmlelement.xpath.php * @param string $expression

    * An XPath path *

    * @return static[]|false|null an array of SimpleXMLElement objects or FALSE in * case of an error. */ #[TentativeType] public function xpath(#[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $expression): array|false|null {} /** * Creates a prefix/ns context for the next XPath query * @link https://php.net/manual/en/simplexmlelement.registerxpathnamespace.php * @param string $prefix

    * The namespace prefix to use in the XPath query for the namespace given in * ns. *

    * @param string $namespace

    * The namespace to use for the XPath query. This must match a namespace in * use by the XML document or the XPath query using * prefix will not return any results. *

    * @return bool TRUE on success or FALSE on failure. */ #[TentativeType] public function registerXPathNamespace( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $prefix, #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $namespace ): bool {} /** * Identifies an element's attributes * @link https://php.net/manual/en/simplexmlelement.attributes.php * @param string $namespaceOrPrefix [optional]

    * An optional namespace for the retrieved attributes *

    * @param bool $isPrefix [optional]

    * Default to FALSE *

    * @return static|null a SimpleXMLElement object that can be * iterated over to loop through the attributes on the tag. *

    *

    * Returns NULL if called on a SimpleXMLElement * object that already represents an attribute and not a tag. * @since 5.0.1 */ #[TentativeType] public function attributes( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespaceOrPrefix = null, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $isPrefix = false ): ?static {} /** * Finds children of given node * @link https://php.net/manual/en/simplexmlelement.children.php * @param string $namespaceOrPrefix [optional]

    * An XML namespace. *

    * @param bool $isPrefix [optional]

    * If is_prefix is TRUE, * ns will be regarded as a prefix. If FALSE, * ns will be regarded as a namespace * URL. *

    * @return static|null a SimpleXMLElement element, whether the node * has children or not. * @since 5.0.1 */ #[Pure] #[TentativeType] public function children( #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespaceOrPrefix = null, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $isPrefix = false ): ?static {} /** * Returns namespaces used in document * @link https://php.net/manual/en/simplexmlelement.getnamespaces.php * @param bool $recursive [optional]

    * If specified, returns all namespaces used in parent and child nodes. * Otherwise, returns only namespaces used in root node. *

    * @return array The getNamespaces method returns an array of * namespace names with their associated URIs. * @since 5.1.2 */ #[Pure] #[TentativeType] public function getNamespaces(#[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $recursive = false): array {} /** * Returns namespaces declared in document * @link https://php.net/manual/en/simplexmlelement.getdocnamespaces.php * @param bool $recursive [optional]

    * If specified, returns all namespaces declared in parent and child nodes. * Otherwise, returns only namespaces declared in root node. *

    * @param bool $fromRoot [optional]

    * Allows you to recursively check namespaces under a child node instead of * from the root of the XML doc. *

    * @return array The getDocNamespaces method returns an array * of namespace names with their associated URIs. * @since 5.1.2 */ #[Pure] #[TentativeType] public function getDocNamespaces( #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $recursive = false, #[LanguageLevelTypeAware(['8.0' => 'bool'], default: '')] $fromRoot = true ): array|false {} /** * Gets the name of the XML element * @link https://php.net/manual/en/simplexmlelement.getname.php * @return string The getName method returns as a string the * name of the XML tag referenced by the SimpleXMLElement object. * @since 5.1.3 */ #[Pure] #[TentativeType] public function getName(): string {} /** * Adds a child element to the XML node * @link https://php.net/manual/en/simplexmlelement.addchild.php * @param string $qualifiedName

    * The name of the child element to add. *

    * @param string $value [optional]

    * If specified, the value of the child element. *

    * @param string $namespace [optional]

    * If specified, the namespace to which the child element belongs. *

    * @return static|null The addChild method returns a SimpleXMLElement * object representing the child added to the XML node. * @since 5.1.3 */ #[TentativeType] public function addChild( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $value = null, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespace = null ): ?static {} /** * Adds an attribute to the SimpleXML element * @link https://php.net/manual/en/simplexmlelement.addattribute.php * @param string $qualifiedName

    * The name of the attribute to add. *

    * @param string $value

    * The value of the attribute. *

    * @param string $namespace [optional]

    * If specified, the namespace to which the attribute belongs. *

    * @return void No value is returned. * @since 5.1.3 */ #[TentativeType] public function addAttribute( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $qualifiedName, #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] $value = null, #[PhpStormStubsElementAvailable(from: '8.0')] string $value, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $namespace = null ): void {} /** * Returns the string content * @link https://php.net/manual/en/simplexmlelement.tostring.php * @return string the string content on success or an empty string on failure. * @since 5.3 */ #[TentativeType] public function __toString(): string {} /** * Counts the children of an element * @link https://php.net/manual/en/simplexmlelement.count.php * @return int<0,max> the number of elements of an element. */ #[Pure] #[TentativeType] public function count(): int {} /** * Class provides access to children by position, and attributes by name * private Method not callable directly, stub exists for typehint only * @param string|int $offset * @return bool true on success or false on failure. */ #[Pure] public function offsetExists($offset) {} /** * Class provides access to children by position, and attributes by name * private Method not callable directly, stub exists for typehint only * @param string|int $offset * @return static Either a named attribute or an element from a list of children */ #[Pure] public function offsetGet($offset) {} /** * Class provides access to children by position, and attributes by name * private Method not callable directly, stub exists for typehint only * @param string|int $offset * @param mixed $value * @return void */ public function offsetSet($offset, $value) {} /** * Class provides access to children by position, and attributes by name * private Method not callable directly, stub exists for typehint only * @param string|int $offset * @return void */ public function offsetUnset($offset) {} /** * Rewind to the first element * @link https://php.net/manual/en/simplexmliterator.rewind.php * @return void No value is returned. */ #[TentativeType] public function rewind(): void {} /** * Check whether the current element is valid * @link https://php.net/manual/en/simplexmliterator.valid.php * @return bool TRUE if the current element is valid, otherwise FALSE */ #[Pure] #[TentativeType] public function valid(): bool {} /** * Returns the current element * @link https://php.net/manual/en/simplexmliterator.current.php * @return static|null the current element as a SimpleXMLElement object or NULL on failure. */ #[Pure] #[TentativeType] public function current(): ?static {} /** * Return current key * @link https://php.net/manual/en/simplexmliterator.key.php * @return string|false the XML tag name of the element referenced by the current SimpleXMLIterator object */ #[TentativeType] #[LanguageLevelTypeAware(['8.0' => 'string'], default: 'string|false')] public function key() {} /** * Move to next element * @link https://php.net/manual/en/simplexmliterator.next.php * @return void No value is returned. */ #[TentativeType] public function next(): void {} /** * @return bool * @since 8.0 */ #[Pure] #[TentativeType] public function hasChildren(): bool {} /** * @since 8.0 */ #[Pure] #[TentativeType] public function getChildren(): ?SimpleXMLElement {} } /** * The SimpleXMLIterator provides recursive iteration over all nodes of a SimpleXMLElement object. * @link https://php.net/manual/en/class.simplexmliterator.php */ class SimpleXMLIterator extends SimpleXMLElement implements RecursiveIterator, Countable, Stringable { /** * Rewind to the first element * @link https://php.net/manual/en/simplexmliterator.rewind.php * @return void No value is returned. */ public function rewind() {} /** * Check whether the current element is valid * @link https://php.net/manual/en/simplexmliterator.valid.php * @return bool TRUE if the current element is valid, otherwise FALSE */ #[Pure] public function valid() {} /** * Returns the current element * @link https://php.net/manual/en/simplexmliterator.current.php * @return static|null the current element as a SimpleXMLIterator object or NULL on failure. */ #[Pure] public function current() {} /** * Return current key * @link https://php.net/manual/en/simplexmliterator.key.php * @return string|false the XML tag name of the element referenced by the current SimpleXMLIterator object or FALSE */ public function key() {} /** * Move to next element * @link https://php.net/manual/en/simplexmliterator.next.php * @return void No value is returned. */ public function next() {} /** * Checks whether the current element has sub elements. * @link https://php.net/manual/en/simplexmliterator.haschildren.php * @return bool TRUE if the current element has sub-elements, otherwise FALSE */ #[Pure] public function hasChildren() {} /** * Returns the sub-elements of the current element * @link https://php.net/manual/en/simplexmliterator.getchildren.php * @return SimpleXMLIterator a SimpleXMLIterator object containing * the sub-elements of the current element. */ #[Pure] public function getChildren() {} /** * Returns the string content * @link https://php.net/manual/en/simplexmlelement.tostring.php * @return string the string content on success or an empty string on failure. * @since 5.3 */ public function __toString() {} /** * Counts the children of an element * @link https://php.net/manual/en/simplexmlelement.count.php * @return int the number of elements of an element. */ #[Pure] public function count() {} } /** * Interprets an XML file into an object * @link https://php.net/manual/en/function.simplexml-load-file.php * @param string $filename

    * Path to the XML file *

    *

    * Libxml 2 unescapes the URI, so if you want to pass e.g. * b&c as the URI parameter a, * you have to call * simplexml_load_file(rawurlencode('https://example.com/?a=' . * urlencode('b&c'))). Since PHP 5.1.0 you don't need to do * this because PHP will do it for you. *

    * @param string|null $class_name [optional]

    * You may use this optional parameter so that * simplexml_load_file will return an object of * the specified class. That class should extend the * SimpleXMLElement class. *

    * @param int $options [optional]

    * Since PHP 5.1.0 and Libxml 2.6.0, you may also use the * options parameter to specify additional Libxml parameters. *

    * @param string $namespace_or_prefix [optional]

    * Namespace prefix or URI. *

    * @param bool $is_prefix [optional]

    * TRUE if ns is a prefix, FALSE if it's a URI; * defaults to FALSE. *

    * @return SimpleXMLElement|false an object of class SimpleXMLElement with * properties containing the data held within the XML document, or FALSE on failure. */ function simplexml_load_file(string $filename, ?string $class_name = "SimpleXMLElement", int $options = 0, string $namespace_or_prefix = "", bool $is_prefix = false): SimpleXMLElement|false {} /** * Interprets a string of XML into an object * @link https://php.net/manual/en/function.simplexml-load-string.php * @param string $data

    * A well-formed XML string *

    * @param string|null $class_name [optional]

    * You may use this optional parameter so that * simplexml_load_string will return an object of * the specified class. That class should extend the * SimpleXMLElement class. *

    * @param int $options [optional]

    * Since PHP 5.1.0 and Libxml 2.6.0, you may also use the * options parameter to specify additional Libxml parameters. *

    * @param string $namespace_or_prefix [optional]

    * Namespace prefix or URI. *

    * @param bool $is_prefix [optional]

    * TRUE if ns is a prefix, FALSE if it's a URI; * defaults to FALSE. *

    * @return SimpleXMLElement|false an object of class SimpleXMLElement with * properties containing the data held within the xml document, or FALSE on failure. */ function simplexml_load_string(string $data, ?string $class_name = "SimpleXMLElement", int $options = 0, string $namespace_or_prefix = "", bool $is_prefix = false): SimpleXMLElement|false {} /** * Get a SimpleXMLElement object from a DOM node. * @link https://php.net/manual/en/function.simplexml-import-dom.php * @param SimpleXMLElement|DOMNode $node

    * A DOM Element node *

    * @param string|null $class_name [optional]

    * You may use this optional parameter so that * simplexml_import_dom will return an object of * the specified class. That class should extend the * SimpleXMLElement class. *

    * @return SimpleXMLElement|null a SimpleXMLElement or FALSE on failure. */ function simplexml_import_dom(#[LanguageLevelTypeAware(['8.4' => 'object'], default: 'SimpleXMLElement|DOMNode')] $node, ?string $class_name = "SimpleXMLElement"): ?SimpleXMLElement {} // End of SimpleXML v.0.1 * create a new broker object capable of requesting * @link https://php.net/manual/en/function.enchant-broker-init.php * @return resource|false|EnchantBroker a broker resource on success or FALSE. */ function enchant_broker_init() {} /** * Free the broker resource and its dictionaries * @link https://php.net/manual/en/function.enchant-broker-free.php * @param resource|EnchantBroker $broker

    * Broker resource *

    * @return bool TRUE on success or FALSE on failure. * @since 5.3 */ #[Deprecated(reason: "Unset the object instead", since: '8.0')] function enchant_broker_free($broker) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * Returns the last error of the broker * @link https://php.net/manual/en/function.enchant-broker-get-error.php * @param resource|EnchantBroker $broker

    * Broker resource. *

    * @return string|false Return the msg string if an error was found or FALSE */ function enchant_broker_get_error($broker) {} /** * Set the directory path for a given backend * @link https://www.php.net/manual/en/function.enchant-broker-set-dict-path.php * @param resource|EnchantBroker $broker * @param int $dict_type * @param string $value * @return bool TRUE on success or FALSE on failure. */ #[Deprecated(since: '8.0', reason: 'Relying on this function is highly discouraged.')] function enchant_broker_set_dict_path($broker, int $dict_type, string $value) {} /** * Get the directory path for a given backend * @link https://www.php.net/manual/en/function.enchant-broker-get-dict-path.php * @param resource|EnchantBroker $broker * @param int $dict_type * @return string|false */ #[Deprecated(since: '8.0', reason: 'Relying on this function is highly discouraged.')] function enchant_broker_get_dict_path($broker, $dict_type) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 1.0.1)
    * Returns a list of available dictionaries * @link https://php.net/manual/en/function.enchant-broker-list-dicts.php * @param resource|EnchantBroker $broker

    * Broker resource *

    * @return array Returns an array of available dictionaries with their details. */ function enchant_broker_list_dicts($broker) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * create a new dictionary using a tag * @link https://php.net/manual/en/function.enchant-broker-request-dict.php * @param resource|EnchantBroker $broker

    * Broker resource *

    * @param string $tag

    * A tag describing the locale, for example en_US, de_DE *

    * @return resource|false|EnchantDictionary a dictionary resource on success or FALSE on failure. */ function enchant_broker_request_dict($broker, $tag) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * creates a dictionary using a PWL file * @link https://php.net/manual/en/function.enchant-broker-request-pwl-dict.php * @param resource|EnchantBroker $broker

    * Broker resource *

    * @param string $filename

    * Path to the PWL file. *

    * @return resource|false|EnchantDictionary a dictionary resource on success or FALSE on failure. */ function enchant_broker_request_pwl_dict($broker, $filename) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * Free a dictionary resource * @link https://php.net/manual/en/function.enchant-broker-free-dict.php * @param resource|EnchantDictionary $dict

    * Dictionary resource. *

    * @return bool TRUE on success or FALSE on failure. */ #[Deprecated("Unset the object instead", since: '8.0')] function enchant_broker_free_dict($dict) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * Whether a dictionary exists or not. Using non-empty tag * @link https://php.net/manual/en/function.enchant-broker-dict-exists.php * @param resource|EnchantBroker $broker

    * Broker resource *

    * @param string $tag

    * non-empty tag in the LOCALE format, ex: us_US, ch_DE, etc. *

    * @return bool TRUE when the tag exist or FALSE when not. */ function enchant_broker_dict_exists($broker, $tag) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * Declares a preference of dictionaries to use for the language * @link https://php.net/manual/en/function.enchant-broker-set-ordering.php * @param resource|EnchantBroker $broker

    * Broker resource *

    * @param string $tag

    * Language tag. The special "*" tag can be used as a language tag * to declare a default ordering for any language that does not * explicitly declare an ordering. *

    * @param string $ordering

    * Comma delimited list of provider names *

    * @return bool TRUE on success or FALSE on failure. */ function enchant_broker_set_ordering($broker, $tag, $ordering) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0)
    * Enumerates the Enchant providers * @link https://php.net/manual/en/function.enchant-broker-describe.php * @param resource|EnchantBroker $broker

    * Broker resource *

    * @return array|false */ function enchant_broker_describe($broker) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * Check whether a word is correctly spelled or not * @link https://php.net/manual/en/function.enchant-dict-check.php * @param resource|EnchantDictionary $dict

    * Dictionary resource *

    * @param string $word

    * The word to check *

    * @return bool TRUE if the word is spelled correctly, FALSE if not. */ function enchant_dict_check($dict, $word) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * Will return a list of values if any of those pre-conditions are not met * @link https://php.net/manual/en/function.enchant-dict-suggest.php * @param resource|EnchantDictionary $dict

    * Dictionary resource *

    * @param string $word

    * Word to use for the suggestions. *

    * @return array|false Will returns an array of suggestions if the word is bad spelled. */ function enchant_dict_suggest($dict, $word) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * add a word to personal word list * @link https://php.net/manual/en/function.enchant-dict-add-to-personal.php * @param resource $dict

    * Dictionary resource *

    * @param string $word

    * The word to add *

    * @return void * @see enchant_dict_add() */ #[Deprecated( reason: 'Use enchant_dict_add instead', replacement: 'enchant_dict_add(%parameter0%, %parameter1%)', since: '8.0' )] function enchant_dict_add_to_personal($dict, $word) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * add 'word' to this spell-checking session * @link https://php.net/manual/en/function.enchant-dict-add-to-session.php * @param resource|EnchantDictionary $dict

    * Dictionary resource *

    * @param string $word

    * The word to add *

    * @return void */ function enchant_dict_add_to_session($dict, $word) {} /** * (PHP 8)
    * Add a word to personal word list * @link https://php.net/manual/en/function.enchant-dict-add.php * @param EnchantDictionary $dictionary

    * An Enchant dictionary returned by enchant_broker_request_dict() or enchant_broker_request_pwl_dict(). *

    * @param string $word

    * The word to add *

    * @return void * @since 8.0 */ function enchant_dict_add($dictionary, $word) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * whether or not 'word' exists in this spelling-session * @link https://php.net/manual/en/function.enchant-dict-is-in-session.php * @param resource $dict

    * Dictionary resource *

    * @param string $word

    * The word to lookup *

    * @return bool TRUE if the word exists or FALSE * @see enchant_dict_is_added */ #[Deprecated( reason: 'Use enchant_dict_is_added instead', replacement: 'enchant_dict_is_added(%parameter0%, %parameter1%)', since: '8.0' )] function enchant_dict_is_in_session($dict, $word) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * Add a correction for a word * @link https://php.net/manual/en/function.enchant-dict-store-replacement.php * @param resource|EnchantDictionary $dict

    * Dictionary resource *

    * @param string $mis

    * The work to fix *

    * @param string $cor

    * The correct word *

    * @return void */ function enchant_dict_store_replacement($dict, $mis, $cor) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * Returns the last error of the current spelling-session * @link https://php.net/manual/en/function.enchant-dict-get-error.php * @param resource|EnchantDictionary $dict

    * Dictinaray resource *

    * @return string|false the error message as string or FALSE if no error occurred. */ function enchant_dict_get_error($dict) {} /** * (PHP 8)
    * Whether or not 'word' exists in this spelling-session * @link https://php.net/manual/en/function.enchant-dict-is-added.php * @param EnchantDictionary $dictionary

    * An Enchant dictionary returned by enchant_broker_request_dict() or enchant_broker_request_pwl_dict(). *

    * @param string $word

    * The word to lookup *

    * @return bool TRUE if the word exists or FALSE * @since 8.0 */ function enchant_dict_is_added($dictionary, $word) {} /** * (PHP 5 >= 5.3.0, PECL enchant >= 0.1.0 )
    * Describes an individual dictionary * @link https://php.net/manual/en/function.enchant-dict-describe.php * @param resource|EnchantDictionary $dict

    * Dictionary resource *

    * @return array Returns the details of the dictionary. */ function enchant_dict_describe($dict) {} /** * (PHP 5 >= 5.3.0, PECL enchant:0.2.0-1.0.1)
    * Check the word is correctly spelled and provide suggestions * @link https://php.net/manual/en/function.enchant-dict-quick-check.php * @param resource|EnchantDictionary $dict

    * Dictionary resource *

    * @param string $word

    * The word to check *

    * @param null|array &$suggestions [optional]

    * If the word is not correctly spelled, this variable will * contain an array of suggestions. *

    * @return bool TRUE if the word is correctly spelled or FALSE */ function enchant_dict_quick_check($dict, $word, ?array &$suggestions = null) {} /** * @deprecated 8.0 */ define('ENCHANT_MYSPELL', 1); /** * @deprecated 8.0 */ define('ENCHANT_ISPELL', 2); final class EnchantBroker {} final class EnchantDictionary {} // End of enchant v.1.1.0 * For a cataloged connection to a database, this parameter * represents the connection alias in the DB2 client catalog. *

    *

    * For an uncataloged connection to a database, * this parameter represents a complete DSN in the following format: * DRIVER=driver;DATABASE=database;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=username;PWD=password; *

    * @param string|null $username

    * The username with which you are connecting to the database, or null if * the $database parameter contains a DSN which already provides the username for * the connection. *

    * @param string|null $password

    * The password with which you are connecting to the database, or null if * the $database parameter contains a DSN which already provides the password for * the connection. *

    * @param array $options

    * An associative array of connection options that affect the behavior * of the connection, where valid array keys include: * autocommit *

    * Passing the DB2_AUTOCOMMIT_ON value turns * autocommit on for this connection handle. *

    *

    * Passing the DB2_AUTOCOMMIT_OFF value turns * autocommit off for this connection handle. *

    * @return resource|false A connection handle resource if the connection attempt is * successful. If the connection attempt fails, db2_connect * returns false. */ function db2_connect(#[\SensitiveParameter] string $database, ?string $username, #[\SensitiveParameter] ?string $password, array $options = []) {} /** * Commits a transaction * @link https://php.net/manual/en/function.db2-commit.php * @param resource $connection

    * A valid database connection resource variable as returned from * db2_connect or db2_pconnect. *

    * @return bool true on success or false on failure. */ function db2_commit($connection): bool {} /** * Returns a persistent connection to a database * @link https://php.net/manual/en/function.db2-pconnect.php * @param string $database

    * For a cataloged connection to a database, this parameter * represents the connection alias in the DB2 client catalog. *

    *

    * For an uncataloged connection to a database, * this parameter represents a complete DSN in the following format: * DRIVER=driver;DATABASE=database;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=username;PWD=password; *

    * @param string|null $username

    * The username with which you are connecting to the database, or null if * the $database parameter contains a DSN which already provides the username for * the connection. *

    * @param string|null $password

    * The password with which you are connecting to the database, or null if * the $database parameter contains a DSN which already provides the password for * the connection. *

    * @param array $options

    * An associative array of connection options that affect the behavior * of the connection, where valid array keys include: * autocommit *

    *

    * Passing the DB2_AUTOCOMMIT_ON value turns * autocommit on for this connection handle. *

    *

    * Passing the DB2_AUTOCOMMIT_OFF value turns * autocommit off for this connection handle. *

    * @return resource|false A connection handle resource if the connection attempt is * successful. db2_pconnect tries to reuse an existing * connection resource that exactly matches the * database, username, and * password parameters. If the connection attempt fails, * db2_pconnect returns false. */ function db2_pconnect(#[\SensitiveParameter] string $database, ?string $username, #[\SensitiveParameter] ?string $password, array $options = []) {} /** * Closes a persistent database connection * * This function closes a persistent DB2 client connection. * * @link https://php.net/manual/en/function.db2-pclose.php * * @param resource $connection Specifies a persistent DB2 client connection. * * @return bool Returns true on success or false on failure. */ function db2_pclose($connection): bool {} /** * Returns or sets the AUTOCOMMIT state for a database connection * @link https://php.net/manual/en/function.db2-autocommit.php * @param resource $connection

    * A valid database connection resource variable as returned from * db2_connect or db2_pconnect. *

    * @param int $value

    * One of the following constants:

    *

    * DB2_AUTOCOMMIT_OFF * Turns AUTOCOMMIT off. *

    *

    * DB2_AUTOCOMMIT_ON * Turns AUTOCOMMIT on. *

    * @return int|bool

    When db2_autocommit receives only the * connection parameter, it returns the current state * of AUTOCOMMIT for the requested connection as an integer value. A value of * 0 indicates that AUTOCOMMIT is off, while a value of 1 indicates that * AUTOCOMMIT is on. *

    *

    * When db2_autocommit receives both the * connection parameter and * autocommit parameter, it attempts to set the * AUTOCOMMIT state of the requested connection to the corresponding state. * true on success or false on failure.

    */ function db2_autocommit($connection, int $value = null): int|bool {} /** * Binds a PHP variable to an SQL statement parameter * @link https://php.net/manual/en/function.db2-bind-param.php * @param resource $stmt

    * A prepared statement returned from db2_prepare. *

    * @param int $parameter_number * @param string $variable_name * @param int $parameter_type * @param int $data_type * @param int $precision

    * Specifies the precision with which the variable should be bound to the * database. This parameter can also be used for retrieving XML output values * from stored procedures. A non-negative value specifies the maximum size of * the XML data that will be retrieved from the database. If this parameter * is not used, a default of 1MB will be assumed for retrieving the XML * output value from the stored procedure. *

    * @param int $scale

    * Specifies the scale with which the variable should be bound to the * database. *

    * @return bool true on success or false on failure. */ function db2_bind_param($stmt, int $parameter_number, string $variable_name, int $parameter_type = DB2_PARAM_IN, int $data_type = 0, int $precision = -1, int $scale = 0): bool {} /** * Closes a database connection * @link https://php.net/manual/en/function.db2-close.php * @param resource $connection

    * Specifies an active DB2 client connection. *

    * @return bool true on success or false on failure. */ function db2_close($connection): bool {} /** * Returns a result set listing the columns and associated privileges for a table * @link https://php.net/manual/en/function.db2-column-privileges.php * @param resource $connection

    * A valid connection to an IBM DB2, Cloudscape, or Apache Derby database. *

    * @param string|null $qualifier

    * A qualifier for DB2 databases running on OS/390 or z/OS servers. For * other databases, pass null or an empty string. *

    * @param string|null $schema

    * The schema which contains the tables. To match all schemas, pass null * or an empty string. *

    * @param string|null $table_name * @param string|null $column_name * @return resource|false a statement resource with a result set containing rows describing * the column privileges for columns matching the specified parameters. The * rows are composed of the following columns: * * Column name * Description * * * TABLE_CAT * Name of the catalog. The value is NULL if this table does not * have catalogs. * * * TABLE_SCHEM * Name of the schema. * * * TABLE_NAME * Name of the table or view. * * * COLUMN_NAME * Name of the column. * * * GRANTOR * Authorization ID of the user who granted the privilege. * * * GRANTEE * Authorization ID of the user to whom the privilege was * granted. * * * PRIVILEGE * The privilege for the column. * * * IS_GRANTABLE * Whether the GRANTEE is permitted to grant this privilege to * other users. * */ function db2_column_privileges($connection, ?string $qualifier = null, ?string $schema = null, ?string $table_name = null, ?string $column_name = null) {} function db2_columnprivileges() {} /** * Returns a result set listing the columns and associated metadata for a table * @link https://php.net/manual/en/function.db2-columns.php * @param resource $connection

    * A valid connection to an IBM DB2, Cloudscape, or Apache Derby database. *

    * @param string $qualifier

    * A qualifier for DB2 databases running on OS/390 or z/OS servers. For * other databases, pass null or an empty string. *

    * @param string $schema

    * The schema which contains the tables. To match all schemas, pass * '%'. *

    * @param string $table_name * @param string $column_name * @return resource|false A statement resource with a result set containing rows describing * the columns matching the specified parameters. The rows are composed of * the following columns: * * Column name * Description * * * TABLE_CAT * Name of the catalog. The value is NULL if this table does not * have catalogs. * * * TABLE_SCHEM * Name of the schema. * * * TABLE_NAME * Name of the table or view. * * * COLUMN_NAME * Name of the column. * * * DATA_TYPE * The SQL data type for the column represented as an integer value. * * * TYPE_NAME * A string representing the data type for the column. * * * COLUMN_SIZE * An integer value representing the size of the column. * * * BUFFER_LENGTH * * Maximum number of bytes necessary to store data from this column. * * * * DECIMAL_DIGITS * * The scale of the column, or null where scale is not applicable. * * * * NUM_PREC_RADIX * * An integer value of either 10 (representing * an exact numeric data type), 2 (representing an * approximate numeric data type), or null (representing a data type for * which radix is not applicable). * * * * NULLABLE * An integer value representing whether the column is nullable or * not. * * * REMARKS * Description of the column. * * * COLUMN_DEF * Default value for the column. * * * SQL_DATA_TYPE * An integer value representing the size of the column. * * * SQL_DATETIME_SUB * * Returns an integer value representing a datetime subtype code, * or null for SQL data types to which this does not apply. * * * * CHAR_OCTET_LENGTH * * Maximum length in octets for a character data type column, which * matches COLUMN_SIZE for single-byte character set data, or null for * non-character data types. * * * * ORDINAL_POSITION * The 1-indexed position of the column in the table. * * * IS_NULLABLE * * A string value where 'YES' means that the column is nullable and * 'NO' means that the column is not nullable. * * */ function db2_columns($connection, $qualifier = null, $schema = null, $table_name = null, $column_name = null) {} /** * Returns a result set listing the foreign keys for a table * @link https://php.net/manual/en/function.db2-foreign-keys.php * @param resource $connection

    * A valid connection to an IBM DB2, Cloudscape, or Apache Derby database. *

    * @param string|null $qualifier

    * A qualifier for DB2 databases running on OS/390 or z/OS servers. For * other databases, pass null or an empty string. *

    * @param string|null $schema

    * The schema which contains the tables. If schema * is null, db2_foreign_keys matches the schema for * the current connection. *

    * @param string $table_name * @return resource|false A statement resource with a result set containing rows describing * the foreign keys for the specified table. The result set is composed of the * following columns: * * Column name * Description * * * PKTABLE_CAT * * Name of the catalog for the table containing the primary key. The * value is NULL if this table does not have catalogs. * * * * PKTABLE_SCHEM * * Name of the schema for the table containing the primary key. * * * * PKTABLE_NAME * Name of the table containing the primary key. * * * PKCOLUMN_NAME * Name of the column containing the primary key. * * * FKTABLE_CAT * * Name of the catalog for the table containing the foreign key. The * value is NULL if this table does not have catalogs. * * * * FKTABLE_SCHEM * * Name of the schema for the table containing the foreign key. * * * * FKTABLE_NAME * Name of the table containing the foreign key. * * * FKCOLUMN_NAME * Name of the column containing the foreign key. * * * KEY_SEQ * 1-indexed position of the column in the key. * * * UPDATE_RULE * * Integer value representing the action applied to the foreign key * when the SQL operation is UPDATE. * * * * DELETE_RULE * * Integer value representing the action applied to the foreign key * when the SQL operation is DELETE. * * * * FK_NAME * The name of the foreign key. * * * PK_NAME * The name of the primary key. * * * DEFERRABILITY * * An integer value representing whether the foreign key deferrability is * SQL_INITIALLY_DEFERRED, SQL_INITIALLY_IMMEDIATE, or * SQL_NOT_DEFERRABLE. * * */ function db2_foreign_keys($connection, ?string $qualifier, ?string $schema, string $table_name) {} function db2_foreignkeys() {} /** * Returns a result set listing primary keys for a table * @link https://php.net/manual/en/function.db2-primary-keys.php * @param resource $connection

    * A valid connection to an IBM DB2, Cloudscape, or Apache Derby database. *

    * @param string|null $qualifier

    * A qualifier for DB2 databases running on OS/390 or z/OS servers. For * other databases, pass null or an empty string. *

    * @param string|null $schema

    * The schema which contains the tables. If schema * is null, db2_primary_keys matches the schema for * the current connection. *

    * @param string $table_name * @return resource|false A statement resource with a result set containing rows describing * the primary keys for the specified table. The result set is composed of the * following columns: * * Column name * Description * * * TABLE_CAT * * Name of the catalog for the table containing the primary key. The * value is NULL if this table does not have catalogs. * * * * TABLE_SCHEM * * Name of the schema for the table containing the primary key. * * * * TABLE_NAME * Name of the table containing the primary key. * * * COLUMN_NAME * Name of the column containing the primary key. * * * KEY_SEQ * 1-indexed position of the column in the key. * * * PK_NAME * The name of the primary key. * */ function db2_primary_keys($connection, ?string $qualifier, ?string $schema, string $table_name) {} function db2_primarykeys() {} /** * Returns a result set listing stored procedure parameters * @link https://php.net/manual/en/function.db2-procedure-columns.php * @param resource $connection

    * A valid connection to an IBM DB2, Cloudscape, or Apache Derby database. *

    * @param string|null $qualifier

    * A qualifier for DB2 databases running on OS/390 or z/OS servers. For * other databases, pass null or an empty string. *

    * @param string $schema

    * The schema which contains the procedures. This parameter accepts a * search pattern containing _ and % * as wildcards. *

    * @param string $procedure

    * The name of the procedure. This parameter accepts a * search pattern containing _ and % * as wildcards. *

    * @param string|null $parameter

    * The name of the parameter. This parameter accepts a search pattern * containing _ and % as wildcards. * If this parameter is null, all parameters for the specified stored * procedures are returned. *

    * @return resource|false A statement resource with a result set containing rows describing * the parameters for the stored procedures matching the specified parameters. * The rows are composed of the following columns: * * Column name * Description * * * PROCEDURE_CAT * The catalog that contains the procedure. The value is null if * this table does not have catalogs. * * * PROCEDURE_SCHEM * Name of the schema that contains the stored procedure. * * * PROCEDURE_NAME * Name of the procedure. * * * COLUMN_NAME * Name of the parameter. * * * COLUMN_TYPE * *

    * An integer value representing the type of the parameter: * * Return value * Parameter type * * * 1 (SQL_PARAM_INPUT) * Input (IN) parameter. * * * 2 (SQL_PARAM_INPUT_OUTPUT) * Input/output (INOUT) parameter. * * * 3 (SQL_PARAM_OUTPUT) * Output (OUT) parameter. * *

    * * * * DATA_TYPE * The SQL data type for the parameter represented as an integer * value. * * * TYPE_NAME * A string representing the data type for the parameter. * * * COLUMN_SIZE * An integer value representing the size of the parameter. * * * BUFFER_LENGTH * * Maximum number of bytes necessary to store data for this parameter. * * * * DECIMAL_DIGITS * * The scale of the parameter, or null where scale is not applicable. * * * * NUM_PREC_RADIX * * An integer value of either 10 (representing * an exact numeric data type), 2 (representing an * approximate numeric data type), or null (representing a data type for * which radix is not applicable). * * * * NULLABLE * An integer value representing whether the parameter is nullable * or not. * * * REMARKS * Description of the parameter. * * * COLUMN_DEF * Default value for the parameter. * * * SQL_DATA_TYPE * An integer value representing the size of the parameter. * * * SQL_DATETIME_SUB * * Returns an integer value representing a datetime subtype code, * or null for SQL data types to which this does not apply. * * * * CHAR_OCTET_LENGTH * * Maximum length in octets for a character data type parameter, which * matches COLUMN_SIZE for single-byte character set data, or null for * non-character data types. * * * * ORDINAL_POSITION * The 1-indexed position of the parameter in the CALL * statement. * * * IS_NULLABLE * * A string value where 'YES' means that the parameter accepts or * returns null values and 'NO' means that the parameter does not * accept or return null values. * * */ function db2_procedure_columns($connection, ?string $qualifier, string $schema, string $procedure, ?string $parameter) {} function db2_procedurecolumns() {} /** * Returns a result set listing the stored procedures registered in a database * @link https://php.net/manual/en/function.db2-procedures.php * @param resource $connection

    * A valid connection to an IBM DB2, Cloudscape, or Apache Derby database. *

    * @param string|null $qualifier

    * A qualifier for DB2 databases running on OS/390 or z/OS servers. For * other databases, pass null or an empty string. *

    * @param string $schema

    * The schema which contains the procedures. This parameter accepts a * search pattern containing _ and % * as wildcards. *

    * @param string $procedure

    * The name of the procedure. This parameter accepts a * search pattern containing _ and % * as wildcards. *

    * @return resource|false A statement resource with a result set containing rows describing * the stored procedures matching the specified parameters. The rows are * composed of the following columns: * * Column name * Description * * * PROCEDURE_CAT * The catalog that contains the procedure. The value is null if * this table does not have catalogs. * * * PROCEDURE_SCHEM * Name of the schema that contains the stored procedure. * * * PROCEDURE_NAME * Name of the procedure. * * * NUM_INPUT_PARAMS * Number of input (IN) parameters for the stored procedure. * * * NUM_OUTPUT_PARAMS * Number of output (OUT) parameters for the stored procedure. * * * NUM_RESULT_SETS * Number of result sets returned by the stored procedure. * * * REMARKS * Any comments about the stored procedure. * * * PROCEDURE_TYPE * Always returns 1, indicating that the stored * procedure does not return a return value. * */ function db2_procedures($connection, ?string $qualifier, string $schema, string $procedure) {} /** * Returns a result set listing the unique row identifier columns for a table * @link https://php.net/manual/en/function.db2-special-columns.php * @param resource $connection

    * A valid connection to an IBM DB2, Cloudscape, or Apache Derby database. *

    * @param string|null $qualifier

    * A qualifier for DB2 databases running on OS/390 or z/OS servers. For * other databases, pass null or an empty string. *

    * @param string $schema

    * The schema which contains the tables. *

    * @param string $table_name

    * The name of the table. *

    * @param int $scope

    * Integer value representing the minimum duration for which the * unique row identifier is valid. This can be one of the following * values: * * Integer value * SQL constant * Description * * * 0 * SQL_SCOPE_CURROW * Row identifier is valid only while the cursor is positioned * on the row. * * * 1 * SQL_SCOPE_TRANSACTION * Row identifier is valid for the duration of the * transaction. * * * 2 * SQL_SCOPE_SESSION * Row identifier is valid for the duration of the * connection. * *

    * @return resource|false A statement resource with a result set containing rows with unique * row identifier information for a table. The rows are composed of the * following columns: * * Column name * Description * * * SCOPE * *

    * * Integer value * SQL constant * Description * * * 0 * SQL_SCOPE_CURROW * Row identifier is valid only while the cursor is positioned * on the row. * * * 1 * SQL_SCOPE_TRANSACTION * Row identifier is valid for the duration of the * transaction. * * * 2 * SQL_SCOPE_SESSION * Row identifier is valid for the duration of the * connection. * *

    * * * * COLUMN_NAME * Name of the unique column. * * * DATA_TYPE * SQL data type for the column. * * * TYPE_NAME * Character string representation of the SQL data type for the * column. * * * COLUMN_SIZE * An integer value representing the size of the column. * * * BUFFER_LENGTH * * Maximum number of bytes necessary to store data from this column. * * * * DECIMAL_DIGITS * * The scale of the column, or null where scale is not applicable. * * * * NUM_PREC_RADIX * * An integer value of either 10 (representing * an exact numeric data type), 2 (representing an * approximate numeric data type), or null (representing a data type for * which radix is not applicable). * * * * PSEUDO_COLUMN * Always returns 1. * */ function db2_special_columns($connection, ?string $qualifier, string $schema, string $table_name, int $scope) {} function db2_specialcolumns() {} /** * Returns a result set listing the index and statistics for a table * @link https://php.net/manual/en/function.db2-statistics.php * @param resource $connection

    * A valid connection to an IBM DB2, Cloudscape, or Apache Derby database. *

    * @param string|null $qualifier

    * A qualifier for DB2 databases running on OS/390 or z/OS servers. For * other databases, pass null or an empty string. *

    * @param string|null $schema

    * The schema that contains the targeted table. If this parameter is * null, the statistics and indexes are returned for the schema of the * current user. *

    * @param string $table_name

    * The name of the table. *

    * @param bool $unique

    * Whether to return the only the unique indexes or all the indexes in the table. *

    *

    * Return only the information for unique indexes on the table. *

    * @return resource|false A statement resource with a result set containing rows describing * the statistics and indexes for the base tables matching the specified * parameters. The rows are composed of the following columns: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    Column nameDescription
    TABLE_CATThe catalog that contains the table. The value is null if * this table does not have catalogs.
    TABLE_SCHEMName of the schema that contains the table.
    TABLE_NAMEName of the table.
    NON_UNIQUE * *

    * An boolean value representing whether the index prohibits unique * values, or whether the row represents statistics on the table itself:

    * * * * * * * * * * * * * * * * *
    Return valueParameter type
    false (SQL_FALSE)The index allows duplicate values.
    true (SQL_TRUE)The index values must be unique.
    nullThis row is statistics information for the table itself.
    *
    INDEX_QUALIFIERA string value representing the qualifier that would have to be * prepended to INDEX_NAME to fully qualify the index.
    INDEX_NAMEA string representing the name of the index.
    TYPE *

    * An integer value representing the type of information contained in * this row of the result set:

    * * * * * * * * * * * * * * * * * * * * * *
    Return valueParameter type
    0 (SQL_TABLE_STAT)The row contains statistics about the table itself.
    1 (SQL_INDEX_CLUSTERED)The row contains information about a clustered index.
    2 (SQL_INDEX_HASH)The row contains information about a hashed index.
    3 (SQL_INDEX_OTHER)The row contains information about a type of index that * is neither clustered nor hashed.
    *
    ORDINAL_POSITIONThe 1-indexed position of the column in the index. null if * the row contains statistics information about the table itself.
    COLUMN_NAMEThe name of the column in the index. null if the row * contains statistics information about the table itself.
    ASC_OR_DESC * A if the column is sorted in ascending order, * D if the column is sorted in descending order, * null if the row contains statistics information about the table * itself. *
    CARDINALITY *

    * If the row contains information about an index, this column contains * an integer value representing the number of unique values in the * index. *

    *

    * If the row contains information about the table itself, this column * contains an integer value representing the number of rows in the * table. *

    *
    PAGES *

    * If the row contains information about an index, this column contains * an integer value representing the number of pages used to store the * index. *

    *

    * If the row contains information about the table itself, this column * contains an integer value representing the number of pages used to * store the table. *

    *
    FILTER_CONDITIONAlways returns null.
    */ function db2_statistics($connection, ?string $qualifier, ?string $schema, string $table_name, bool $unique) {} /** * Returns a result set listing the tables and associated privileges in a database * @link https://php.net/manual/en/function.db2-table-privileges.php * @param resource $connection

    * A valid connection to an IBM DB2, Cloudscape, or Apache Derby database. *

    * @param string|null $qualifier

    * A qualifier for DB2 databases running on OS/390 or z/OS servers. For * other databases, pass null or an empty string. *

    * @param string|null $schema

    * The schema which contains the tables. This parameter accepts a * search pattern containing _ and % * as wildcards. *

    * @param string|null $table_name

    * The name of the table. This parameter accepts a search pattern * containing _ and % as wildcards. *

    * @return resource|false A statement resource with a result set containing rows describing * the privileges for the tables that match the specified parameters. The rows * are composed of the following columns: * * Column name * Description * * * TABLE_CAT * The catalog that contains the table. The value is null if * this table does not have catalogs. * * * TABLE_SCHEM * Name of the schema that contains the table. * * * TABLE_NAME * Name of the table. * * * GRANTOR * Authorization ID of the user who granted the privilege. * * * GRANTEE * Authorization ID of the user to whom the privilege was * granted. * * * PRIVILEGE * * The privilege that has been granted. This can be one of ALTER, * CONTROL, DELETE, INDEX, INSERT, REFERENCES, SELECT, or UPDATE. * * * * IS_GRANTABLE * * A string value of "YES" or "NO" indicating whether the grantee * can grant the privilege to other users. * * */ function db2_table_privileges($connection, ?string $qualifier = null, ?string $schema = null, ?string $table_name = null) {} function db2_tableprivileges() {} /** * Returns a result set listing the tables and associated metadata in a database * @link https://php.net/manual/en/function.db2-tables.php * @param resource $connection

    * A valid connection to an IBM DB2, Cloudscape, or Apache Derby database. *

    * @param string|null $qualifier

    * A qualifier for DB2 databases running on OS/390 or z/OS servers. For * other databases, pass null or an empty string. *

    * @param string|null $schema

    * The schema which contains the tables. This parameter accepts a * search pattern containing _ and % * as wildcards. *

    * @param string|null $table_name * @param string|null $table_type * @return resource|false A statement resource with a result set containing rows describing * the tables that match the specified parameters. The rows are composed of * the following columns: * * Column name * Description * * * TABLE_CAT * The catalog that contains the table. The value is null if * this table does not have catalogs. * * * TABLE_SCHEM * Name of the schema that contains the table. * * * TABLE_NAME * Name of the table. * * * TABLE_TYPE * Table type identifier for the table. * * * REMARKS * Description of the table. * */ function db2_tables($connection, ?string $qualifier = null, ?string $schema = null, ?string $table_name = null, ?string $table_type = null) {} /** * Executes an SQL statement directly * @link https://php.net/manual/en/function.db2-exec.php * @param resource $connection

    * A valid database connection resource variable as returned from * db2_connect or db2_pconnect. *

    * @param string $statement

    * An SQL statement. The statement cannot contain any parameter markers. *

    * @param array $options

    * An associative array containing statement options. You can use this * parameter to request a scrollable cursor on database servers that * support this functionality. * cursor *

    *

    * Passing the DB2_FORWARD_ONLY value requests a * forward-only cursor for this SQL statement. This is the default * type of cursor, and it is supported by all database servers. It is * also much faster than a scrollable cursor. *

    *

    * Passing the DB2_SCROLLABLE value requests a * scrollable cursor for this SQL statement. This type of cursor * enables you to fetch rows non-sequentially from the database * server. However, it is only supported by DB2 servers, and is much * slower than forward-only cursors. *

    * @return resource|false A statement resource if the SQL statement was issued successfully, * or false if the database failed to execute the SQL statement. */ function db2_exec($connection, string $statement, array $options = []) {} /** * Prepares an SQL statement to be executed * @link https://php.net/manual/en/function.db2-prepare.php * @param resource $connection

    * A valid database connection resource variable as returned from * db2_connect or db2_pconnect. *

    * @param string $statement

    * An SQL statement, optionally containing one or more parameter markers.. *

    * @param array $options

    * An associative array containing statement options. You can use this * parameter to request a scrollable cursor on database servers that * support this functionality. * cursor *

    *

    * Passing the DB2_FORWARD_ONLY value requests a * forward-only cursor for this SQL statement. This is the default * type of cursor, and it is supported by all database servers. It is * also much faster than a scrollable cursor. *

    *

    * Passing the DB2_SCROLLABLE value requests a * scrollable cursor for this SQL statement. This type of cursor * enables you to fetch rows non-sequentially from the database * server. However, it is only supported by DB2 servers, and is much * slower than forward-only cursors. *

    * @return resource|false A statement resource if the SQL statement was successfully parsed and * prepared by the database server. Returns false if the database server * returned an error. You can determine which error was returned by calling * db2_stmt_error or db2_stmt_errormsg. */ function db2_prepare($connection, string $statement, array $options = []) {} /** * Executes a prepared SQL statement * @link https://php.net/manual/en/function.db2-execute.php * @param resource $stmt

    * A prepared statement returned from db2_prepare. *

    * @param array $parameters

    * An array of input parameters matching any parameter markers contained * in the prepared statement. *

    * @return bool true on success or false on failure. */ function db2_execute($stmt, array $parameters = []): bool {} /** * Returns a string containing the last SQL statement error message * @link https://php.net/manual/en/function.db2-stmt-errormsg.php * @param resource|null $stmt

    * A valid statement resource or NULL. *

    * @return string a string containing the error message and SQLCODE value for the * last error that occurred issuing an SQL statement. */ function db2_stmt_errormsg($stmt = null) {} /** * Returns the last connection error message and SQLCODE value * @link https://php.net/manual/en/function.db2-conn-errormsg.php * @param resource|null $connection

    * A connection resource associated with a connection that initially * succeeded, but which over time became invalid. *

    * @return string a string containing the error message and SQLCODE value resulting * from a failed connection attempt. If there is no error associated with the last * connection attempt, db2_conn_errormsg returns an empty * string. */ function db2_conn_errormsg($connection = null) {} /** * Returns a string containing the SQLSTATE returned by the last connection attempt * @link https://php.net/manual/en/function.db2-conn-error.php * @param resource|null $connection

    * A connection resource associated with a connection that initially * succeeded, but which over time became invalid. *

    * @return string the SQLSTATE value resulting from a failed connection attempt. * Returns an empty string if there is no error associated with the last * connection attempt. */ function db2_conn_error($connection = null) {} /** * Returns a string containing the SQLSTATE returned by an SQL statement * @link https://php.net/manual/en/function.db2-stmt-error.php * @param resource|null $stmt

    * A valid statement resource or NULL. *

    * @return string a string containing an SQLSTATE value. */ function db2_stmt_error($stmt = null) {} /** * Requests the next result set from a stored procedure * @link https://php.net/manual/en/function.db2-next-result.php * @param resource $stmt

    * A prepared statement returned from db2_exec or * db2_execute. *

    * @return resource|false A new statement resource containing the next result set if the * stored procedure returned another result set. Returns false if the stored * procedure did not return another result set. */ function db2_next_result($stmt) {} /** * Returns the number of fields contained in a result set * @link https://php.net/manual/en/function.db2-num-fields.php * @param resource $stmt

    * A valid statement resource containing a result set. *

    * @return int|false An integer value representing the number of fields in the result * set associated with the specified statement resource. Returns false if * the statement resource is not a valid input value. */ function db2_num_fields($stmt): int|false {} /** * Returns the number of rows affected by an SQL statement * @link https://php.net/manual/en/function.db2-num-rows.php * @param resource $stmt

    * A valid stmt resource containing a result set. *

    * @return int|false the number of rows affected by the last SQL statement issued by * the specified statement handle, or false in case of failure. */ function db2_num_rows($stmt): int|false {} /** * Returns the name of the column in the result set * @link https://php.net/manual/en/function.db2-field-name.php * @param resource $stmt

    * Specifies a statement resource containing a result set. *

    * @param int|string $column

    * Specifies the column in the result set. This can either be an integer * representing the 0-indexed position of the column, or a string * containing the name of the column. *

    * @return string|false A string containing the name of the specified column. If the * specified column does not exist in the result * set, db2_field_name returns false. */ function db2_field_name($stmt, int|string $column): string|false {} /** * Returns the maximum number of bytes required to display a column * @link https://php.net/manual/en/function.db2-field-display-size.php * @param resource $stmt

    * Specifies a statement resource containing a result set. *

    * @param int|string $column

    * Specifies the column in the result set. This can either be an integer * representing the 0-indexed position of the column, or a string * containing the name of the column. *

    * @return int|false An integer value with the maximum number of bytes required to * display the specified column. If the column does not exist in the result * set, db2_field_display_size returns false. */ function db2_field_display_size($stmt, int|string $column): int|false {} /** * Returns the position of the named column in a result set * @link https://php.net/manual/en/function.db2-field-num.php * @param resource $stmt

    * Specifies a statement resource containing a result set. *

    * @param int|string $column

    * Specifies the column in the result set. This can either be an integer * representing the 0-indexed position of the column, or a string * containing the name of the column. *

    * @return int|false An integer containing the 0-indexed position of the named column in * the result set. If the specified column does not exist in the result set, * db2_field_num returns false. */ function db2_field_num($stmt, int|string $column): int|false {} /** * Returns the precision of the indicated column in a result set * @link https://php.net/manual/en/function.db2-field-precision.php * @param resource $stmt

    * Specifies a statement resource containing a result set. *

    * @param int|string $column

    * Specifies the column in the result set. This can either be an integer * representing the 0-indexed position of the column, or a string * containing the name of the column. *

    * @return int|false An integer containing the precision of the specified column. If the * specified column does not exist in the result set, * db2_field_precision returns false. */ function db2_field_precision($stmt, int|string $column): int|false {} /** * Returns the scale of the indicated column in a result set * @link https://php.net/manual/en/function.db2-field-scale.php * @param resource $stmt

    * Specifies a statement resource containing a result set. *

    * @param int|string $column

    * Specifies the column in the result set. This can either be an integer * representing the 0-indexed position of the column, or a string * containing the name of the column. *

    * @return int|false An integer containing the scale of the specified column. If the * specified column does not exist in the result set, * db2_field_scale returns false. */ function db2_field_scale($stmt, int|string $column): int|false {} /** * Returns the data type of the indicated column in a result set * @link https://php.net/manual/en/function.db2-field-type.php * @param resource $stmt

    * Specifies a statement resource containing a result set. *

    * @param int|string $column

    * Specifies the column in the result set. This can either be an integer * representing the 0-indexed position of the column, or a string * containing the name of the column. *

    * @return string|false A string containing the defined data type of the specified column. * If the specified column does not exist in the result set, * db2_field_type returns false. */ function db2_field_type($stmt, int|string $column): string|false {} /** * Returns the width of the current value of the indicated column in a result set * @link https://php.net/manual/en/function.db2-field-width.php * @param resource $stmt

    * Specifies a statement resource containing a result set. *

    * @param int|string $column

    * Specifies the column in the result set. This can either be an integer * representing the 0-indexed position of the column, or a string * containing the name of the column. *

    * @return int|false An integer containing the width of the specified character or * binary data type column in a result set. If the specified column does not * exist in the result set, db2_field_width returns * false. */ function db2_field_width($stmt, int|string $column): int|false {} /** * Returns the cursor type used by a statement resource * @link https://php.net/manual/en/function.db2-cursor-type.php * @param resource $stmt

    * A valid statement resource. *

    * @return int either DB2_FORWARD_ONLY if the statement * resource uses a forward-only cursor or DB2_SCROLLABLE if * the statement resource uses a scrollable cursor. */ function db2_cursor_type($stmt): int {} /** * Rolls back a transaction * @link https://php.net/manual/en/function.db2-rollback.php * @param resource $connection

    * A valid database connection resource variable as returned from * db2_connect or db2_pconnect. *

    * @return bool true on success or false on failure. */ function db2_rollback($connection): bool {} /** * Frees resources associated with the indicated statement resource * @link https://php.net/manual/en/function.db2-free-stmt.php * @param resource $stmt

    * A valid statement resource. *

    * @return bool true on success or false on failure. */ function db2_free_stmt($stmt): bool {} /** * Returns a single column from a row in the result set * @link https://php.net/manual/en/function.db2-result.php * @param resource $stmt

    * A valid stmt resource. *

    * @param int|string $column

    * Either an integer mapping to the 0-indexed field in the result set, or * a string matching the name of the column. *

    * @return mixed the value of the requested field if the field exists in the result * set. Returns NULL if the field does not exist, and issues a warning. */ function db2_result($stmt, int|string $column): mixed {} /** * Sets the result set pointer to the next row or requested row * @link https://php.net/manual/en/function.db2-fetch-row.php * @param resource $stmt

    * A valid stmt resource. *

    * @param int $row_number

    * With scrollable cursors, you can request a specific row number in the * result set. Row numbering is 1-indexed. *

    * @return bool true if the requested row exists in the result set. Returns * false if the requested row does not exist in the result set. */ function db2_fetch_row($stmt, int $row_number = null) {} /** * Returns an array, indexed by column name, representing a row in a result set * @link https://php.net/manual/en/function.db2-fetch-assoc.php * @param resource $stmt

    * A valid stmt resource containing a result set. *

    * @param int $row_number

    * Requests a specific 1-indexed row from the result set. Passing this * parameter results in a PHP warning if the result set uses a * forward-only cursor. *

    * @return array|false An associative array with column values indexed by the column name * representing the next or requested row in the result set. Returns false if * there are no rows left in the result set, or if the row requested by * row_number does not exist in the result set. */ function db2_fetch_assoc($stmt, int $row_number = null): array|false {} /** * Returns an array, indexed by column position, representing a row in a result set * @link https://php.net/manual/en/function.db2-fetch-array.php * @param resource $stmt

    * A valid stmt resource containing a result set. *

    * @param int $row_number

    * Requests a specific 1-indexed row from the result set. Passing this * parameter results in a PHP warning if the result set uses a * forward-only cursor. *

    * @return array|false A 0-indexed array with column values indexed by the column position * representing the next or requested row in the result set. Returns false if * there are no rows left in the result set, or if the row requested by * row_number does not exist in the result set. */ function db2_fetch_array($stmt, int $row_number = null): array|false {} /** * Returns an array, indexed by both column name and position, representing a row in a result set * @link https://php.net/manual/en/function.db2-fetch-both.php * @param resource $stmt

    * A valid stmt resource containing a result set. *

    * @param int $row_number

    * Requests a specific 1-indexed row from the result set. Passing this * parameter results in a PHP warning if the result set uses a * forward-only cursor. *

    * @return array|false An associative array with column values indexed by both the column * name and 0-indexed column number. The array represents the next or * requested row in the result set. Returns false if there are no rows left * in the result set, or if the row requested by * row_number does not exist in the result set. */ function db2_fetch_both($stmt, int $row_number = null): array|false {} /** * Frees resources associated with a result set * @link https://php.net/manual/en/function.db2-free-result.php * @param resource $stmt

    * A valid statement resource. *

    * @return bool true on success or false on failure. */ function db2_free_result($stmt): bool {} /** * Set options for connection or statement resources * @link https://php.net/manual/en/function.db2-set-option.php * @param resource $resource

    * A valid statement resource as returned from * db2_prepare or a valid connection resource as * returned from db2_connect or * db2_pconnect. *

    * @param array $options

    * An associative array containing valid statement or connection * options. This parameter can be used to change autocommit values, * cursor types (scrollable or forward), and to specify the case of * the column names (lower, upper, or natural) that will appear in a * result set. * autocommit *

    * Passing DB2_AUTOCOMMIT_ON turns * autocommit on for the specified connection resource. *

    *

    * Passing DB2_AUTOCOMMIT_OFF turns * autocommit off for the specified connection resource. *

    * @param int $type

    * An integer value that specifies the type of resource that was * passed into the function. The type of resource and this value * must correspond. *

    * Passing 1 as the value specifies that * a connection resource has been passed into the function. *

    *

    * Passing any integer not equal to 1 as * the value specifies that a statement resource has been * passed into the function. *

    * @return bool true on success or false on failure. */ function db2_set_option($resource, array $options, int $type): bool {} function db2_setoption(): bool {} /** * Returns an object with properties representing columns in the fetched row * @link https://php.net/manual/en/function.db2-fetch-object.php * @param resource $stmt

    * A valid stmt resource containing a result set. *

    * @param int $row_number

    * Requests a specific 1-indexed row from the result set. Passing this * parameter results in a PHP warning if the result set uses a * forward-only cursor. *

    * @return stdClass|false An object representing a single row in the result set. The * properties of the object map to the names of the columns in the result set. *

    *

    * The IBM DB2, Cloudscape, and Apache Derby database servers typically fold * column names to upper-case, so the object properties will reflect that case. *

    *

    * If your SELECT statement calls a scalar function to modify the value * of a column, the database servers return the column number as the name of * the column in the result set. If you prefer a more descriptive column name * and object property, you can use the AS clause to assign a name to the * column in the result set. *

    *

    * Returns false if no row was retrieved. */ function db2_fetch_object($stmt, int $row_number = null): stdClass|false {} /** * Returns an object with properties that describe the DB2 database server * @link https://php.net/manual/en/function.db2-server-info.php * @param resource $connection

    * Specifies an active DB2 client connection. *

    * @return stdClass|false An object on a successful call. Returns false on failure. */ function db2_server_info($connection): stdClass|false {} /** * Returns an object with properties that describe the DB2 database client * @link https://php.net/manual/en/function.db2-client-info.php * @param resource $connection

    * Specifies an active DB2 client connection. *

    * @return stdClass|false An object on a successful call. Returns false on failure. */ function db2_client_info($connection): stdClass|false {} /** * Used to escape certain characters * @link https://php.net/manual/en/function.db2-escape-string.php * @param string $string_literal

    * The string that contains special characters that need to be modified. * Characters that are prepended with a backslash are \x00, * \n, \r, \, * ', " and \x1a. *

    * @return string string_literal with the special characters * noted above prepended with backslashes. */ function db2_escape_string(string $string_literal): string {} /** * Gets a user defined size of LOB files with each invocation * @link https://php.net/manual/en/function.db2-lob-read.php * @param resource $stmt

    * A valid stmt resource containing LOB data. *

    * @param int $colnum

    * A valid column number in the result set of the stmt resource. *

    * @param int $length

    * The size of the LOB data to be retrieved from the stmt resource. *

    * @return string|false The amount of data the user specifies. Returns * false if the data cannot be retrieved. */ function db2_lob_read($stmt, int $colnum, int $length): string|false {} /** * Retrieves an option value for a statement resource or a connection resource * @link https://php.net/manual/en/function.db2-get-option.php * @param resource $resource

    * A valid statement resource as returned from * db2_prepare or a valid connection resource as * returned from db2_connect or * db2_pconnect. *

    * @param string $option

    * A valid statement or connection options. The following new options are available * as of ibm_db2 version 1.6.0. They provide useful tracking information * that can be set during execution with db2_get_option. *

    *

    * Note: Prior versions of ibm_db2 do not support these new options. *

    *

    * When the value in each option is being set, some servers might not handle * the entire length provided and might truncate the value. *

    *

    * To ensure that the data specified in each option is converted correctly * when transmitted to a host system, use only the characters A through Z, * 0 through 9, and the underscore (_) or period (.). *

    *

    * SQL_ATTR_INFO_USERID - A pointer to a null-terminated * character string used to identify the client user ID sent to the host * database server when using DB2 Connect. *

    *

    * Note: DB2 for z/OS and OS/390 servers support up to a length of 16 characters. * This user-id is not to be confused with the authentication user-id, it is for * identification purposes only and is not used for any authorization. *

    * @return string|false The current setting of the connection attribute provided on success * or false on failure. */ function db2_get_option($resource, string $option): string|false {} /** * Returns the auto generated ID of the last insert query that successfully executed on this connection. * @link https://php.net/manual/en/function.db2-last-insert-id.php * The result of this function is not affected by any of the following: *
    • A single row INSERT statement with a VALUES clause for a table without an identity column. *
    • A multiple row INSERT statement with a VALUES clause. *
    • An INSERT statement with a fullselect. *
    • A ROLLBACK TO SAVEPOINT statement. *
    * @param resource $resource A valid connection resource as returned from db2_connect() or db2_pconnect(). * The value of this parameter cannot be a statement resource or result set resource. * @return string|null Returns the auto generated ID of last insert query that successfully executed on this connection * or NULL if no ID was found. */ function db2_last_insert_id($resource): ?string {} /** * Specifies that binary data shall be returned as is. This is the default * mode. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_BINARY', 1); /** * Specifies that binary data shall be converted to a hexadecimal encoding * and returned as an ASCII string. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_CONVERT', 2); /** * Specifies that binary data shall be converted to a null value. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_PASSTHRU', 3); /** * Specifies a scrollable cursor for a statement resource. This mode enables * random access to rows in a result set, but currently is supported only by * IBM DB2 Universal Database. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_SCROLLABLE', 1); /** * Specifies a forward-only cursor for a statement resource. This is the * default cursor type and is supported on all database servers. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_FORWARD_ONLY', 0); /** * Specifies the PHP variable should be bound as an IN parameter for a * stored procedure. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_PARAM_IN', 1); /** * Specifies the PHP variable should be bound as an OUT parameter for a * stored procedure. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_PARAM_OUT', 4); /** * Specifies the PHP variable should be bound as an INOUT parameter for a * stored procedure. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_PARAM_INOUT', 2); /** * Specifies that the column should be bound directly to a file for input. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_PARAM_FILE', 11); /** * Specifies that autocommit should be turned on. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_AUTOCOMMIT_ON', 1); /** * Specifies that autocommit should be turned off. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_AUTOCOMMIT_OFF', 0); /** * Specifies that deferred prepare should be turned on for the specified statement resource. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_DEFERRED_PREPARE_ON', 1); /** * Specifies that deferred prepare should be turned off for the specified statement resource. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_DEFERRED_PREPARE_OFF', 0); /** * Specifies that the variable should be bound as a DOUBLE, FLOAT, or REAL * data type. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_DOUBLE', 8); /** * Specifies that the variable should be bound as a SMALLINT, INTEGER, or * BIGINT data type. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_LONG', 4); /** * Specifies that the variable should be bound as a CHAR or VARCHAR data type. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_CHAR', 1); define('DB2_XML', -370); /** * Specifies that column names will be returned in their natural case. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_CASE_NATURAL', 0); /** * Specifies that column names will be returned in lower case. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_CASE_LOWER', 1); /** * Specifies that column names will be returned in upper case. * @link https://php.net/manual/en/ibm-db2.constants.php */ define('DB2_CASE_UPPER', 2); // End of ibm_db2 v.1.6.0 * The following error codes are used:
      *
    • -1 - error outside UnRAR library
    • *
    • 11 - insufficient memory
    • *
    • 12 - bad data
    • *
    • 13 - bad archive
    • *
    • 14 - unknown format
    • *
    • 15 - file open error
    • *
    • 16 - file create error
    • *
    • 17 - file close error
    • *
    • 18 - read error
    • *
    • 19 - write error
    • *
    • 20 - buffer too small
    • *
    • 21 - unkown RAR error
    • *
    • 22 - password required but not given
    • *
    * * @link https://php.net/manual/en/class.rarexception.php */ final class RarException extends Exception { /** * Check whether error handling with exceptions is in use * * @link https://php.net/manual/en/rarexception.isusingexceptions.php * * @return bool TRUE if exceptions are being used, FALSE otherwise */ public static function isUsingExceptions() {} /** * Activate and deactivate error handling with exceptions * * @link https://php.net/manual/en/rarexception.setusingexceptions.php * * @param bool $using_exceptions Should be TRUE to activate exception throwing, FALSE to deactivate (the default) */ public static function setUsingExceptions($using_exceptions) {} } *
  • %parametersList%: parameters of the function call. For example, for the "f(1,2)" call, %parametersList% will be "1,2"
  • *
  • %parameter0%,%parameter1%,%parameter2%,...: parameters of the function call. For example, for the "f(1,2)" call, %parameter1% will be "2"
  • *
  • %name%: For "\x\f(1,2)", %name% will be "\x\f", for "$this->ff()", %name% will be "ff"
  • *
  • %class%: If the attribute is provided for method "m", then for "$this->f()->m()", %class% will be "$this->f()"
  • * * The following example shows how to wrap a function call in another call and swap arguments:
    * "#[Deprecated(replacement: "wrappedCall(%name%(%parameter1%, %parameter0%))")] f($a, $b){}
    * f(1,2) will be replaced with wrappedCall(f(2,1)) * @param string $since Element is deprecated starting with the provided PHP language level, applicable only for PhpStorm stubs entries */ public function __construct( $reason = "", $replacement = "", #[ExpectedValues(self::PHP_VERSIONS)] $since = "5.6" ) {} } *
  • Code completion - expected arguments are displayed on the top of the suggestions list when used in comparison expressions
  • *
  • Inspections [when used in a comparison with a value/assignment to/return from method] - the element absent from the expected values list produces the inspection warning
  • *
  • Code generation - for example, when generating the 'switch' statement, all possible expected values are inserted automatically
  • * * * Expected values can be any of the following: *
      *
    • numbers
    • *
    • string literals
    • *
    • constant references
    • *
    • class constant references
    • *
    * * Expected arguments can be specified in any of the following ways: *
      *
    • #[ExpectedValues(values: [1,2,3])] means that one of the following is expected: `1`, `2`, or `3`
    • *
    • #[ExpectedValues(values: MY_CONST] - default value of MY_CONST is expected to be array creation expression, in this case value of MY_CONST will be inlined
    • *
    • #[ExpectedValues(flags: [1,2,3])] means that a bitmask of the following is expected: `1`, `2`, or `3`
    • *
    • #[ExpectedValues(valuesFromClass: MyClass::class)] means that one of the constants from the class `MyClass` is expected
    • *
    • #[ExpectedValues(flagsFromClass: ExpectedValues::class)] means that a bitmask of the constants from the class `MyClass` is expected
    • *
    * * The attribute with the number of provided constructor arguments different from 1 will result in undefined behavior. * @since 8.0 */ #[Attribute(Attribute::TARGET_FUNCTION|Attribute::TARGET_METHOD|Attribute::TARGET_PARAMETER|Attribute::TARGET_PROPERTY)] class ExpectedValues { public function __construct(array $values = [], array $flags = [], string $valuesFromClass = null, string $flagsFromClass = null) {} } *
  • {@link Immutable::CONSTRUCTOR_WRITE_SCOPE}: write is allowed only in containing class constructor (default choice)
  • *
  • {@link Immutable::PRIVATE_WRITE_SCOPE}: write is allowed only in places where the property would be accessible if it had 'private' visibility modifier
  • *
  • {@link Immutable::PROTECTED_WRITE_SCOPE}: write is allowed only in places where the property would be accessible if it had 'protected' visibility modifier
  • * * @since 8.0 */ #[Attribute(Attribute::TARGET_PROPERTY|Attribute::TARGET_CLASS)] class Immutable { public const CONSTRUCTOR_WRITE_SCOPE = "constructor"; public const PRIVATE_WRITE_SCOPE = "private"; public const PROTECTED_WRITE_SCOPE = "protected"; public function __construct(#[ExpectedValues(valuesFromClass: Immutable::class)] $allowedWriteScope = self::CONSTRUCTOR_WRITE_SCOPE) {} } * * Example:
    * #[ArrayShape(["f" => "int", "string", "x" => "float"])] * This usage applied on an element effectively means that the array has 3 elements, the keys are "f", 1, and "x", and the corresponding types are "int", "string", and "float". */ #[Attribute(Attribute::TARGET_FUNCTION|Attribute::TARGET_METHOD|Attribute::TARGET_PARAMETER|Attribute::TARGET_PROPERTY)] class ArrayShape { public function __construct(array $shape) {} } #[ObjectShape(["age" => "int", "name" => "string"])]
    * * This usage applied on an element effectively means that the object has 2 fields, the names are "age" and "name", and the corresponding types are "int" and "string". */ #[Attribute(Attribute::TARGET_FUNCTION|Attribute::TARGET_METHOD|Attribute::TARGET_PARAMETER|Attribute::TARGET_PROPERTY)] class ObjectShape { public function __construct(array $shape) {} } json_encode. * @link https://php.net/manual/en/class.jsonserializable.php * @since 5.4 */ interface JsonSerializable { /** * Specify data which should be serialized to JSON * @link https://php.net/manual/en/jsonserializable.jsonserialize.php * @return mixed data which can be serialized by json_encode, * which is a value of any type other than a resource. * @since 5.4 */ #[TentativeType] public function jsonSerialize(): mixed; } class JsonIncrementalParser { public const JSON_PARSER_SUCCESS = 0; public const JSON_PARSER_CONTINUE = 1; /** * @param int $depth [optional] * @param int $options [optional] */ #[Pure] public function __construct($depth, $options) {} #[Pure] public function getError() {} public function reset() {} /** * @param string $json */ public function parse($json) {} /** * @param string $filename */ public function parseFile($filename) {} /** * @param int $options [optional] */ #[Pure] public function get($options) {} } /** * (PHP 5 >= 5.2.0, PECL json >= 1.2.0)
    * Returns the JSON representation of a value * @link https://php.net/manual/en/function.json-encode.php * @param mixed $value

    * The value being encoded. Can be any type except * a resource. *

    *

    * All string data must be UTF-8 encoded. *

    *

    PHP implements a superset of * JSON - it will also encode and decode scalar types and NULL. The JSON standard * only supports these values when they are nested inside an array or an object. *

    * @param int $flags [optional]

    * Bitmask consisting of JSON_HEX_QUOT, * JSON_HEX_TAG, * JSON_HEX_AMP, * JSON_HEX_APOS, * JSON_NUMERIC_CHECK, * JSON_PRETTY_PRINT, * JSON_UNESCAPED_SLASHES, * JSON_FORCE_OBJECT, * JSON_UNESCAPED_UNICODE. * JSON_THROW_ON_ERROR The behaviour of these * constants is described on * the JSON constants page. *

    * @param int $depth [optional]

    * Set the maximum depth. Must be greater than zero. *

    * @return string|false a JSON encoded string on success or FALSE on failure. */ function json_encode(mixed $value, int $flags = 0, int $depth = 512): string|false {} /** * (PHP 5 >= 5.2.0, PECL json >= 1.2.0)
    * Decodes a JSON string * @link https://php.net/manual/en/function.json-decode.php * @param string $json

    * The json string being decoded. *

    *

    * This function only works with UTF-8 encoded strings. *

    *

    PHP implements a superset of * JSON - it will also encode and decode scalar types and NULL. The JSON standard * only supports these values when they are nested inside an array or an object. *

    * @param bool|null $associative

    * When TRUE, returned objects will be converted into * associative arrays. *

    * @param int $depth [optional]

    * User specified recursion depth. *

    * @param int $flags [optional]

    * Bitmask of JSON decode options:
    * {@see JSON_BIGINT_AS_STRING} decodes large integers as their original string value.
    * {@see JSON_INVALID_UTF8_IGNORE} ignores invalid UTF-8 characters,
    * {@see JSON_INVALID_UTF8_SUBSTITUTE} converts invalid UTF-8 characters to \0xfffd,
    * {@see JSON_OBJECT_AS_ARRAY} decodes JSON objects as PHP array, since 7.2.0 used by default if $assoc parameter is true,
    * {@see JSON_THROW_ON_ERROR} when passed this flag, the error behaviour of these functions is changed. The global error state is left untouched, and if an error occurs that would otherwise set it, these functions instead throw a JsonException
    *

    * @return mixed the value encoded in json in appropriate * PHP type. Values true, false and * null (case-insensitive) are returned as TRUE, FALSE * and NULL respectively. NULL is returned if the * json cannot be decoded or if the encoded * data is deeper than the recursion limit. */ function json_decode(string $json, ?bool $associative = null, int $depth = 512, int $flags = 0): mixed {} /** * Returns the last error occurred * @link https://php.net/manual/en/function.json-last-error.php * @return int an integer, the value can be one of the following * constants: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    ConstantMeaningAvailability
    JSON_ERROR_NONENo error has occurred 
    JSON_ERROR_DEPTHThe maximum stack depth has been exceeded 
    JSON_ERROR_STATE_MISMATCHInvalid or malformed JSON 
    JSON_ERROR_CTRL_CHARControl character error, possibly incorrectly encoded 
    JSON_ERROR_SYNTAXSyntax error 
    JSON_ERROR_UTF8Malformed UTF-8 characters, possibly incorrectly encodedPHP 5.3.3
    JSON_ERROR_RECURSIONOne or more recursive references in the value to be encodedPHP 5.5.0
    JSON_ERROR_INF_OR_NAN * One or more * NAN * or INF * values in the value to be encoded * PHP 5.5.0
    JSON_ERROR_UNSUPPORTED_TYPEA value of a type that cannot be encoded was givenPHP 5.5.0
    JSON_ERROR_INVALID_PROPERTY_NAMEA property name that cannot be encoded was givenPHP 7.0.0
    JSON_ERROR_UTF16Malformed UTF-16 characters, possibly incorrectly encodedPHP 7.0.0
    */ #[Pure(true)] function json_last_error(): int {} /** * Returns the error string of the last json_encode() or json_decode() call, which did not specify JSON_THROW_ON_ERROR. * @link https://php.net/manual/en/function.json-last-error-msg.php * @return string Returns the error message on success, "No error" if no error has occurred. * @since 5.5 */ #[Pure] function json_last_error_msg(): string {} /** * @since 8.3 */ function json_validate(string $json, int $depth = 512, int $flags = 0): bool {} /** * All < and > are converted to \u003C and \u003E. * @link https://php.net/manual/en/json.constants.php */ define('JSON_HEX_TAG', 1); /** * All &s are converted to \u0026. * @link https://php.net/manual/en/json.constants.php */ define('JSON_HEX_AMP', 2); /** * All ' are converted to \u0027. * @link https://php.net/manual/en/json.constants.php */ define('JSON_HEX_APOS', 4); /** * All " are converted to \u0022. * @link https://php.net/manual/en/json.constants.php */ define('JSON_HEX_QUOT', 8); /** * Outputs an object rather than an array when a non-associative array is * used. Especially useful when the recipient of the output is expecting * an object and the array is empty. * @link https://php.net/manual/en/json.constants.php */ define('JSON_FORCE_OBJECT', 16); /** * Encodes numeric strings as numbers. * @since 5.3.3 * @link https://php.net/manual/en/json.constants.php */ define('JSON_NUMERIC_CHECK', 32); /** * Don't escape /. * @since 5.4 * @link https://php.net/manual/en/json.constants.php */ define('JSON_UNESCAPED_SLASHES', 64); /** * Use whitespace in returned data to format it. * @since 5.4 * @link https://php.net/manual/en/json.constants.php */ define('JSON_PRETTY_PRINT', 128); /** * Encode multibyte Unicode characters literally (default is to escape as \uXXXX). * @since 5.4 * @link https://php.net/manual/en/json.constants.php */ define('JSON_UNESCAPED_UNICODE', 256); define('JSON_PARTIAL_OUTPUT_ON_ERROR', 512); /** * Occurs with underflow or with the modes mismatch. * @link https://php.net/manual/en/json.constants.php */ define('JSON_ERROR_STATE_MISMATCH', 2); /** * Control character error, possibly incorrectly encoded. * @link https://php.net/manual/en/json.constants.php */ define('JSON_ERROR_CTRL_CHAR', 3); /** * Malformed UTF-8 characters, possibly incorrectly encoded. This * constant is available as of PHP 5.3.3. * @link https://php.net/manual/en/json.constants.php */ define('JSON_ERROR_UTF8', 5); /** *

    * The object or array passed to json_encode include * recursive references and cannot be encoded. * If the JSON_PARTIAL_OUTPUT_ON_ERROR option was * given, NULL will be encoded in the place of the recursive reference. *

    *

    * This constant is available as of PHP 5.5.0. *

    * @link https://php.net/manual/en/json.constants.php */ define('JSON_ERROR_RECURSION', 6); /** *

    * The value passed to json_encode includes either * NAN * or INF. * If the JSON_PARTIAL_OUTPUT_ON_ERROR option was * given, 0 will be encoded in the place of these * special numbers. *

    *

    * This constant is available as of PHP 5.5.0. *

    * @link https://php.net/manual/en/json.constants.php */ define('JSON_ERROR_INF_OR_NAN', 7); /** *

    * A value of an unsupported type was given to * json_encode, such as a resource. * If the JSON_PARTIAL_OUTPUT_ON_ERROR option was * given, NULL will be encoded in the place of the unsupported value. *

    *

    * This constant is available as of PHP 5.5.0. *

    * @link https://php.net/manual/en/json.constants.php */ define('JSON_ERROR_UNSUPPORTED_TYPE', 8); /** * No error has occurred. * @link https://php.net/manual/en/json.constants.php */ define('JSON_ERROR_NONE', 0); /** * The maximum stack depth has been exceeded. * @link https://php.net/manual/en/json.constants.php */ define('JSON_ERROR_DEPTH', 1); /** * Syntax error. * @link https://php.net/manual/en/json.constants.php */ define('JSON_ERROR_SYNTAX', 4); /** * Decodes JSON objects as PHP array. * @since 5.4 * @link https://php.net/manual/en/json.constants.php */ define('JSON_OBJECT_AS_ARRAY', 1); define('JSON_PARSER_NOTSTRICT', 4); /** * Decodes large integers as their original string value. * @since 5.4 * @link https://php.net/manual/en/json.constants.php */ define('JSON_BIGINT_AS_STRING', 2); /** * Ensures that float values are always encoded as a float value. * @since 5.6.6 * @link https://php.net/manual/en/json.constants.php */ define('JSON_PRESERVE_ZERO_FRACTION', 1024); /** * The line terminators are kept unescaped when JSON_UNESCAPED_UNICODE is supplied. * It uses the same behaviour as it was before PHP 7.1 without this constant. Available since PHP 7.1.0. * @link https://php.net/manual/en/json.constants.php * @since 7.1 */ define('JSON_UNESCAPED_LINE_TERMINATORS', 2048); /** * Ignore invalid UTF-8 characters. * @since 7.2 */ define('JSON_INVALID_UTF8_IGNORE', 1048576); /** * Convert invalid UTF-8 characters to \0xfffd (Unicode Character 'REPLACEMENT CHARACTER'). * @since 7.2 */ define('JSON_INVALID_UTF8_SUBSTITUTE', 2097152); /** * A key starting with \u0000 character was in the string passed to json_decode() when decoding a JSON object into a PHP object. * Available since PHP 7.0.0. * @link https://php.net/manual/en/json.constants.php * @since 7.0 */ define('JSON_ERROR_INVALID_PROPERTY_NAME', 9); /** * Single unpaired UTF-16 surrogate in unicode escape contained in the JSON string passed to json_encode(). * Available since PHP 7.0.0. * @link https://php.net/manual/en/json.constants.php * @since 7.0 */ define('JSON_ERROR_UTF16', 10); /** * Throws JsonException if an error occurs instead of setting the global error state * that is retrieved with json_last_error() and json_last_error_msg(). * * {@see JSON_PARTIAL_OUTPUT_ON_ERROR} takes precedence over JSON_THROW_ON_ERROR. * @since 7.3 */ define('JSON_THROW_ON_ERROR', 4194304); /** * @since 8.1 */ define('JSON_ERROR_NON_BACKED_ENUM', 11); /** * Class JsonException * *

    A new flag has been added, JSON_THROW_ON_ERROR, which can be used with * json_decode() or json_encode() and causes these functions to throw a * JsonException upon an error, instead of setting the global error state that * is retrieved with json_last_error(). JSON_PARTIAL_OUTPUT_ON_ERROR takes * precedence over JSON_THROW_ON_ERROR. *

    * * @since 7.3 * @link https://wiki.php.net/rfc/json_throw_on_error */ class JsonException extends Exception {} // End of json v.1.3.1 'int'], default: '')] $flags = 0, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: '')] $magic_database ) {} /** * @param $options [optional] * @param $arg [optional] */ #[PhpStormStubsElementAvailable(from: '5.3', to: '7.4')] public function finfo($options, $arg) {} /** * (PHP >= 5.3.0, PECL fileinfo >= 0.1.0)
    * Set libmagic configuration options * @link https://php.net/manual/en/function.finfo-set-flags.php * @param int $flags

    * One or disjunction of more Fileinfo * constants. *

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] #[TentativeType] public function set_flags(#[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags) {} /** * (PHP >= 5.3.0, PECL fileinfo >= 0.1.0)
    * Return information about a file * @link https://php.net/manual/en/function.finfo-file.php * @param string $filename

    * Name of a file to be checked. *

    * @param int $flags [optional]

    * One or disjunction of more Fileinfo * constants. *

    * @param resource $context [optional]

    * For a description of contexts, refer to . *

    * @return string a textual description of the contents of the * filename argument, or FALSE if an error occurred. */ #[Pure] #[TentativeType] public function file( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $filename, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = FILEINFO_NONE, $context = null ): string|false {} /** * (PHP 5 >= 5.3.0, PECL fileinfo >= 0.1.0)
    * Return information about a string buffer * @link https://php.net/manual/en/function.finfo-buffer.php * @param string $string

    * Content of a file to be checked. *

    * @param int $flags [optional]

    * One or disjunction of more Fileinfo * constants. *

    * @param resource $context [optional] * @return string a textual description of the string * argument, or FALSE if an error occurred. */ #[Pure] #[TentativeType] public function buffer( #[LanguageLevelTypeAware(['8.0' => 'string'], default: '')] $string, #[LanguageLevelTypeAware(['8.0' => 'int'], default: '')] $flags = FILEINFO_NONE, $context = null ): string|false {} } /** * (PHP >= 5.3.0, PECL fileinfo >= 0.1.0)
    * Create a new fileinfo resource * @link https://php.net/manual/en/function.finfo-open.php * @param int $flags

    * One or disjunction of more Fileinfo * constants. *

    * @param string|null $magic_database [optional]

    * Name of a magic database file, usually something like * /path/to/magic.mime. If not specified, * the MAGIC environment variable is used. If this variable * is not set either, /usr/share/misc/magic is used by default. * A .mime and/or .mgc suffix is added if * needed. *

    * @return resource|false a magic database resource on success or FALSE on failure. */ #[LanguageLevelTypeAware(['8.1' => 'finfo|false'], default: 'resource|false')] function finfo_open(int $flags = 0, ?string $magic_database = null) {} /** * (PHP >= 5.3.0, PECL fileinfo >= 0.1.0)
    * Close fileinfo resource * @link https://php.net/manual/en/function.finfo-close.php * @param resource $finfo

    * Fileinfo resource returned by finfo_open. *

    * @return bool TRUE on success or FALSE on failure. */ function finfo_close(#[LanguageLevelTypeAware(['8.1' => 'finfo'], default: 'resource')] $finfo): bool {} /** * (PHP >= 5.3.0, PECL fileinfo >= 0.1.0)
    * Set libmagic configuration options * @link https://php.net/manual/en/function.finfo-set-flags.php * @param resource $finfo

    * Fileinfo resource returned by finfo_open. *

    * @param int $flags

    * One or disjunction of more Fileinfo * constants. *

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(['8.4' => 'true'], default: 'bool')] function finfo_set_flags(#[LanguageLevelTypeAware(['8.1' => 'finfo'], default: 'resource')] $finfo, int $flags) {} /** * (PHP >= 5.3.0, PECL fileinfo >= 0.1.0)
    * Return information about a file * @link https://php.net/manual/en/function.finfo-file.php * @param resource $finfo

    * Fileinfo resource returned by finfo_open. *

    * @param string $filename

    * Name of a file to be checked. *

    * @param int $flags

    * One or disjunction of more Fileinfo * constants. *

    * @param resource $context [optional]

    * For a description of contexts, refer to . *

    * @return string|false a textual description of the contents of the * filename argument, or FALSE if an error occurred. */ function finfo_file(#[LanguageLevelTypeAware(['8.1' => 'finfo'], default: 'resource')] $finfo, string $filename, int $flags = 0, $context): string|false {} /** * (PHP 5 >= 5.3.0, PECL fileinfo >= 0.1.0)
    * Return information about a string buffer * @link https://php.net/manual/en/function.finfo-buffer.php * @param resource $finfo

    * Fileinfo resource returned by finfo_open. *

    * @param string $string

    * Content of a file to be checked. *

    * @param int $flags [optional] One or disjunction of more * Fileinfo constants. * @param resource $context [optional] * @return string|false a textual description of the string * argument, or FALSE if an error occurred. */ function finfo_buffer(#[LanguageLevelTypeAware(['8.1' => 'finfo'], default: 'resource')] $finfo, string $string, int $flags = FILEINFO_NONE, $context): string|false {} /** * Detect MIME Content-type for a file * @link https://php.net/manual/en/function.mime-content-type.php * @param string $filename

    * Path to the tested file. *

    * @return string|false the content type in MIME format, like * text/plain or application/octet-stream. */ function mime_content_type($filename): string|false {} /** * No special handling. * @link https://php.net/manual/en/fileinfo.constants.php */ define('FILEINFO_NONE', 0); /** * Follow symlinks. * @link https://php.net/manual/en/fileinfo.constants.php */ define('FILEINFO_SYMLINK', 2); /** * Return the mime type and mime encoding as defined by RFC 2045. * @link https://php.net/manual/en/fileinfo.constants.php */ define('FILEINFO_MIME', 1040); /** * Return the mime type. * @link https://php.net/manual/en/fileinfo.constants.php */ define('FILEINFO_MIME_TYPE', 16); /** * Return the mime encoding of the file. * @link https://php.net/manual/en/fileinfo.constants.php */ define('FILEINFO_MIME_ENCODING', 1024); /** * Look at the contents of blocks or character special devices. * @link https://php.net/manual/en/fileinfo.constants.php */ define('FILEINFO_DEVICES', 8); /** * Return all matches, not just the first. * @link https://php.net/manual/en/fileinfo.constants.php */ define('FILEINFO_CONTINUE', 32); /** * If possible preserve the original access time. * @link https://php.net/manual/en/fileinfo.constants.php */ define('FILEINFO_PRESERVE_ATIME', 128); /** * Don't translate unprintable characters to a \ooo octal * representation. * @link https://php.net/manual/en/fileinfo.constants.php */ define('FILEINFO_RAW', 256); /** * Returns the file extension appropriate for a the MIME type detected in the file. * For types that commonly have multiple file extensions, such as JPEG images, then the return value is multiple extensions speparated by a forward slash e.g.: "jpeg/jpg/jpe/jfif". * For unknown types not available in the magic.mime database, then return value is "???". Available since PHP 7.2.0. * @since 7.2 */ define('FILEINFO_EXTENSION', 2097152); /** * @since 8.2 */ define('FILEINFO_APPLE', 2048); // End of fileinfo v.1.0.5 /dev/null && pwd )" cd "$SCRIPT_DIR" || exit echo "Building docker container for PHP_$i..." docker-compose -f docker-compose.yml build echo "Dumping reflection data to file $SCRIPT_DIR/ReflectionData.json for PHP_$i..." docker-compose -f docker-compose.yml run -e PHP_VERSION="$i" php_under_test /usr/local/bin/php tests/Tools/dump-reflection-to-file.php ReflectionData.json echo "Running tests agains PHP_$i..." docker-compose -f docker-compose.yml run -e PHP_VERSION="$i" test_runner vendor/bin/phpunit --testsuite PHP_"$i" echo "Removing file $SCRIPT_DIR/ReflectionData.json with reflection data for PHP_$i..." rm -f "$SCRIPT_DIR/ReflectionData.json" done Instead of embedding of a long C definition into PHP string, * and creating FFI through FFI::cdef(), it's possible to separate * it into a C header file. Note, that C preprocessor directives * (e.g. #define or #ifdef) are not supported. And only a couple of * special macros may be used especially for FFI.

    * * * #define FFI_LIB "libc.so.6" * * int printf(const char *format, ...); * * * Here, FFI_LIB specifies, that the given library should be loaded. * * * $ffi = FFI::load(__DIR__ . "/printf.h"); * $ffi->printf("Hello world!\n"); * * * @param string $filename * @return FFI|null */ public static function load(string $filename): ?FFI {} /** * FFI definition parsing and shared library loading may take * significant time. It's not useful to do it on each HTTP request in * WEB environment. However, it's possible to pre-load FFI definitions * and libraries at php startup, and instantiate FFI objects when * necessary. Header files may be extended with FFI_SCOPE define * (default pre-loading scope is "C"). This name is going to be * used as FFI::scope() argument. It's possible to pre-load few * files into a single scope. * * * #define FFI_LIB "libc.so.6" * #define FFI_SCOPE "libc" * * int printf(const char *format, ...); * * * These files are loaded through the same FFI::load() load function, * executed from file loaded by opcache.preload php.ini directive. * * * ffi.preload=/etc/php/ffi/printf.h * * * Finally, FFI::scope() instantiate an FFI object, that implements * all C definition from the given scope. * * * $ffi = FFI::scope("libc"); * $ffi->printf("Hello world!\n"); * * * @param string $name * @return FFI */ public static function scope(string $name): FFI {} /** * Method that creates an arbitrary C structure. * * @param string|CType $type * @param bool $owned * @param bool $persistent * @return CData|null * @throws ParserException */ public static function new($type, bool $owned = true, bool $persistent = false): ?CData {} /** * Manually removes previously created "not-owned" data structure. * * @param CData $ptr * @return void */ public static function free(CData $ptr): void {} /** * Casts given $pointer to another C type, specified by C declaration * string or FFI\CType object. * * This function may be called statically and use only predefined * types, or as a method of previously created FFI object. In last * case the first argument may reuse all type and tag names * defined in FFI::cdef(). * * @param CType|string $type * @param CData|int|float|bool|null $ptr * @return CData|null */ public static function cast($type, $ptr): ?CData {} /** * This function creates and returns a FFI\CType object, representng * type of the given C type declaration string. * * FFI::type() may be called statically and use only predefined types, * or as a method of previously created FFI object. In last case the * first argument may reuse all type and tag names defined in * FFI::cdef(). * * @param string $type * @return CType|null */ public static function type(string $type): ?CType {} /** * This function returns the FFI\CType object, representing the type of * the given FFI\CData object. * * @param CData $ptr * @return CType */ public static function typeof(CData $ptr): CType {} /** * Constructs a new C array type with elements of $type and * dimensions specified by $dimensions. * * @param CType $type * @param int[] $dimensions * @return CType */ public static function arrayType(CType $type, array $dimensions): CType {} /** * Returns C pointer to the given C data structure. The pointer is * not "owned" and won't be free. Anyway, this is a potentially * unsafe operation, because the life-time of the returned pointer * may be longer than life-time of the source object, and this may * cause dangling pointer dereference (like in regular C). * * @param CData $ptr * @return CData */ public static function addr(CData $ptr): CData {} /** * Returns size of C data type of the given FFI\CData or FFI\CType. * * @param CData|CType $ptr * @return int */ public static function sizeof($ptr): int {} /** * Returns size of C data type of the given FFI\CData or FFI\CType. * * @param CData|CType $ptr * @return int */ public static function alignof($ptr): int {} /** * Copies $size bytes from memory area $source to memory area $target. * $source may be any native data structure (FFI\CData) or PHP string. * * @param CData $to * @param CData|string $from * @param int $size */ public static function memcpy(CData $to, $from, int $size): void {} /** * Compares $size bytes from memory area $ptr1 and $ptr2. * * @param CData|string $ptr1 * @param CData|string $ptr2 * @param int $size * @return int */ public static function memcmp($ptr1, $ptr2, int $size): int {} /** * Fills the $size bytes of the memory area pointed to by $target with * the constant byte $byte. * * @param CData $ptr * @param int $value * @param int $size */ public static function memset(CData $ptr, int $value, int $size): void {} /** * Creates a PHP string from $size bytes of memory area pointed by * $source. If size is omitted, $source must be zero terminated * array of C chars. * * @param CData $ptr * @param int|null $size * @return string */ public static function string(CData $ptr, ?int $size = null): string {} /** * Checks whether the FFI\CData is a null pointer. * * @param CData $ptr * @return bool */ public static function isNull(CData $ptr): bool {} } } namespace FFI { /** * General FFI exception. * * @since 7.4 */ class Exception extends \Error {} /** * An exception that occurs when parsing invalid header files. * * @since 7.4 */ class ParserException extends Exception {} /** * Proxy object that provides access to compiled structures. * * In the case that CData is a wrapper over a scalar, it contains an * additional "cdata" property. * * @property int|float|bool|null|string|CData $cdata * * In the case that the CData is a wrapper over an arbitrary C structure, * then it allows reading and writing to the fields defined by * this structure. * * @method mixed __get(string $name) * @method mixed __set(string $name, mixed $value) * * In the case that CData is a wrapper over an array, it is an * implementation of the {@see \Traversable}, {@see \Countable}, * and {@see \ArrayAccess} * * @mixin \Traversable * @mixin \Countable * @mixin \ArrayAccess * * In the case when CData is a wrapper over a function pointer, it can * be called. * * @method mixed __invoke(mixed ...$args) * * @since 7.4 */ class CData { /** * Note that this method does not physically exist and is only required * for correct type inference. * * @param int $offset * @return bool */ private function offsetExists(int $offset) {} /** * Note that this method does not physically exist and is only required * for correct type inference. * * @param int $offset * @return CData|int|float|bool|null|string */ private function offsetGet(int $offset) {} /** * Note that this method does not physically exist and is only required * for correct type inference. * * @param int $offset * @param CData|int|float|bool|null|string $value */ private function offsetSet(int $offset, $value) {} /** * Note that this method does not physically exist and is only required * for correct type inference. * * @param int $offset */ private function offsetUnset(int $offset) {} /** * Note that this method does not physically exist and is only required * for correct type inference. * * @return int */ private function count(): int {} } /** * Class containing C type information. * * @since 7.4 */ class CType { /** * @since 8.1 */ public const TYPE_VOID = 0; /** * @since 8.1 */ public const TYPE_FLOAT = 1; /** * @since 8.1 */ public const TYPE_DOUBLE = 2; /** * Please note that this constant may NOT EXIST if there is * no long double support on the current platform. * * @since 8.1 */ public const TYPE_LONGDOUBLE = 3; /** * @since 8.1 */ public const TYPE_UINT8 = 4; /** * @since 8.1 */ public const TYPE_SINT8 = 5; /** * @since 8.1 */ public const TYPE_UINT16 = 6; /** * @since 8.1 */ public const TYPE_SINT16 = 7; /** * @since 8.1 */ public const TYPE_UINT32 = 8; /** * @since 8.1 */ public const TYPE_SINT32 = 9; /** * @since 8.1 */ public const TYPE_UINT64 = 10; /** * @since 8.1 */ public const TYPE_SINT64 = 11; /** * @since 8.1 */ public const TYPE_ENUM = 12; /** * @since 8.1 */ public const TYPE_BOOL = 13; /** * @since 8.1 */ public const TYPE_CHAR = 14; /** * @since 8.1 */ public const TYPE_POINTER = 15; /** * @since 8.1 */ public const TYPE_FUNC = 16; /** * @since 8.1 */ public const TYPE_ARRAY = 17; /** * @since 8.1 */ public const TYPE_STRUCT = 18; /** * @since 8.1 */ public const ATTR_CONST = 1; /** * @since 8.1 */ public const ATTR_INCOMPLETE_TAG = 2; /** * @since 8.1 */ public const ATTR_VARIADIC = 4; /** * @since 8.1 */ public const ATTR_INCOMPLETE_ARRAY = 8; /** * @since 8.1 */ public const ATTR_VLA = 16; /** * @since 8.1 */ public const ATTR_UNION = 32; /** * @since 8.1 */ public const ATTR_PACKED = 64; /** * @since 8.1 */ public const ATTR_MS_STRUCT = 128; /** * @since 8.1 */ public const ATTR_GCC_STRUCT = 256; /** * @since 8.1 */ public const ABI_DEFAULT = 0; /** * @since 8.1 */ public const ABI_CDECL = 1; /** * @since 8.1 */ public const ABI_FASTCALL = 2; /** * @since 8.1 */ public const ABI_THISCALL = 3; /** * @since 8.1 */ public const ABI_STDCALL = 4; /** * @since 8.1 */ public const ABI_PASCAL = 5; /** * @since 8.1 */ public const ABI_REGISTER = 6; /** * @since 8.1 */ public const ABI_MS = 7; /** * @since 8.1 */ public const ABI_SYSV = 8; /** * @since 8.1 */ public const ABI_VECTORCALL = 9; /** * Returns the name of the type. * * @since 8.0 * @return string */ public function getName(): string {} /** * Returns the identifier of the root type. * * Value may be one of: * - {@see CType::TYPE_VOID} * - {@see CType::TYPE_FLOAT} * - {@see CType::TYPE_DOUBLE} * - {@see CType::TYPE_LONGDOUBLE} * - {@see CType::TYPE_UINT8} * - {@see CType::TYPE_SINT8} * - {@see CType::TYPE_UINT16} * - {@see CType::TYPE_SINT16} * - {@see CType::TYPE_UINT32} * - {@see CType::TYPE_SINT32} * - {@see CType::TYPE_UINT64} * - {@see CType::TYPE_SINT64} * - {@see CType::TYPE_ENUM} * - {@see CType::TYPE_BOOL} * - {@see CType::TYPE_CHAR} * - {@see CType::TYPE_POINTER} * - {@see CType::TYPE_FUNC} * - {@see CType::TYPE_ARRAY} * - {@see CType::TYPE_STRUCT} * * @since 8.1 * @return int */ public function getKind(): int {} /** * Returns the size of the type in bytes. * * @since 8.1 * @return int */ public function getSize(): int {} /** * Returns the alignment of the type in bytes. * * @since 8.1 * @return int */ public function getAlignment(): int {} /** * Returns the bit-mask of type attributes. * * @since 8.1 * @return int */ public function getAttributes(): int {} /** * Returns the identifier of the enum value type. * * Value may be one of: * - {@see CType::TYPE_UINT32} * - {@see CType::TYPE_UINT64} * * @since 8.1 * @return int * @throws Exception In the case that the type is not an enumeration. */ public function getEnumKind(): int {} /** * Returns the type of array elements. * * @since 8.1 * @return CType * @throws Exception In the case that the type is not an array. */ public function getArrayElementType(): CType {} /** * Returns the size of an array. * * @since 8.1 * @return int * @throws Exception In the case that the type is not an array. */ public function getArrayLength(): int {} /** * Returns the original type of the pointer. * * @since 8.1 * @return CType * @throws Exception In the case that the type is not a pointer. */ public function getPointerType(): CType {} /** * Returns the field string names of a structure or union. * * @since 8.1 * @return array * @throws Exception In the case that the type is not a struct or union. */ public function getStructFieldNames(): array {} /** * Returns the offset of the structure by the name of this field. In * the case that the type is a union, then for each field of this type * the offset will be equal to 0. * * @since 8.1 * @param string $name * @return int * @throws Exception In the case that the type is not a struct or union. */ public function getStructFieldOffset(string $name): int {} /** * Returns the field type of a structure or union. * * @since 8.1 * @param string $name * @return CType * @throws Exception In the case that the type is not a struct or union. */ public function getStructFieldType(string $name): CType {} /** * Returns the application binary interface (ABI) identifier with which * you can call the function. * * Value may be one of: * - {@see CType::ABI_DEFAULT} * - {@see CType::ABI_CDECL} * - {@see CType::ABI_FASTCALL} * - {@see CType::ABI_THISCALL} * - {@see CType::ABI_STDCALL} * - {@see CType::ABI_PASCAL} * - {@see CType::ABI_REGISTER} * - {@see CType::ABI_MS} * - {@see CType::ABI_SYSV} * - {@see CType::ABI_VECTORCALL} * * @since 8.1 * @return int * @throws Exception In the case that the type is not a function. */ public function getFuncABI(): int {} /** * Returns the return type of the function. * * @since 8.1 * @return CType * @throws Exception In the case that the type is not a function. */ public function getFuncReturnType(): CType {} /** * Returns the number of arguments to the function. * * @since 8.1 * @return int * @throws Exception In the case that the type is not a function. */ public function getFuncParameterCount(): int {} /** * Returns the type of the function argument by its numeric index. * * @since 8.1 * @param int $index * @return CType * @throws Exception In the case that the type is not a function. */ public function getFuncParameterType(int $index): CType {} } } *

    * @return int */ function ncurses_addch($ch) {} /** * Set fore- and background color * @link https://php.net/manual/en/function.ncurses-color-set.php * @param int $pair

    *

    * @return int */ function ncurses_color_set($pair) {} /** * Delete a ncurses window * @link https://php.net/manual/en/function.ncurses-delwin.php * @param resource $window

    *

    * @return bool */ function ncurses_delwin($window) {} /** * Stop using ncurses, clean up the screen * @link https://php.net/manual/en/function.ncurses-end.php * @return int */ function ncurses_end() {} /** * Read a character from keyboard * @link https://php.net/manual/en/function.ncurses-getch.php * @return int */ function ncurses_getch() {} /** * Check if terminal has colors * @link https://php.net/manual/en/function.ncurses-has-colors.php * @return bool Return true if the terminal has color capacities, false otherwise. */ function ncurses_has_colors() {} /** * Initialize ncurses * @link https://php.net/manual/en/function.ncurses-init.php * @return void */ function ncurses_init() {} /** * Allocate a color pair * @link https://php.net/manual/en/function.ncurses-init-pair.php * @param int $pair

    *

    * @param int $fg

    *

    * @param int $bg

    *

    * @return int */ function ncurses_init_pair($pair, $fg, $bg) {} /** * Gets the RGB value for color * @link https://php.net/manual/en/function.ncurses-color-content.php * @param int $color

    *

    * @param int &$r

    *

    * @param int &$g

    *

    * @param int &$b

    *

    * @return int */ function ncurses_color_content($color, &$r, &$g, &$b) {} /** * Gets the RGB value for color * @link https://php.net/manual/en/function.ncurses-pair-content.php * @param int $pair

    *

    * @param int &$f

    *

    * @param int &$b

    *

    * @return int */ function ncurses_pair_content($pair, &$f, &$b) {} /** * Move output position * @link https://php.net/manual/en/function.ncurses-move.php * @param int $y

    *

    * @param int $x

    *

    * @return int */ function ncurses_move($y, $x) {} /** * Create a new window * @link https://php.net/manual/en/function.ncurses-newwin.php * @param int $rows

    * Number of rows *

    * @param int $cols

    * Number of columns *

    * @param int $y

    * y-ccordinate of the origin *

    * @param int $x

    * x-ccordinate of the origin *

    * @return resource a resource ID for the new window. */ function ncurses_newwin($rows, $cols, $y, $x) {} /** * Refresh screen * @link https://php.net/manual/en/function.ncurses-refresh.php * @param int $ch

    *

    * @return int */ function ncurses_refresh($ch) {} /** * Start using colors * @link https://php.net/manual/en/function.ncurses-start-color.php * @return int */ function ncurses_start_color() {} /** * Start using 'standout' attribute * @link https://php.net/manual/en/function.ncurses-standout.php * @return int */ function ncurses_standout() {} /** * Stop using 'standout' attribute * @link https://php.net/manual/en/function.ncurses-standend.php * @return int */ function ncurses_standend() {} /** * Returns baudrate of terminal * @link https://php.net/manual/en/function.ncurses-baudrate.php * @return int */ function ncurses_baudrate() {} /** * Let the terminal beep * @link https://php.net/manual/en/function.ncurses-beep.php * @return int */ function ncurses_beep() {} /** * Check if we can change terminals colors * @link https://php.net/manual/en/function.ncurses-can-change-color.php * @return bool Return true if the terminal has color capabilities and you can change * the colors, false otherwise. */ function ncurses_can_change_color() {} /** * Switch of input buffering * @link https://php.net/manual/en/function.ncurses-cbreak.php * @return bool true or NCURSES_ERR if any error occurred. */ function ncurses_cbreak() {} /** * Clear screen * @link https://php.net/manual/en/function.ncurses-clear.php * @return bool */ function ncurses_clear() {} /** * Clear screen from current position to bottom * @link https://php.net/manual/en/function.ncurses-clrtobot.php * @return bool */ function ncurses_clrtobot() {} /** * Clear screen from current position to end of line * @link https://php.net/manual/en/function.ncurses-clrtoeol.php * @return bool */ function ncurses_clrtoeol() {} /** * Saves terminals (program) mode * @link https://php.net/manual/en/function.ncurses-def-prog-mode.php * @return bool false on success, otherwise true. */ function ncurses_def_prog_mode() {} /** * Resets the prog mode saved by def_prog_mode * @link https://php.net/manual/en/function.ncurses-reset-prog-mode.php * @return int */ function ncurses_reset_prog_mode() {} /** * Saves terminals (shell) mode * @link https://php.net/manual/en/function.ncurses-def-shell-mode.php * @return bool false on success, true otherwise. */ function ncurses_def_shell_mode() {} /** * Resets the shell mode saved by def_shell_mode * @link https://php.net/manual/en/function.ncurses-reset-shell-mode.php * @return int */ function ncurses_reset_shell_mode() {} /** * Delete character at current position, move rest of line left * @link https://php.net/manual/en/function.ncurses-delch.php * @return bool false on success, true otherwise. */ function ncurses_delch() {} /** * Delete line at current position, move rest of screen up * @link https://php.net/manual/en/function.ncurses-deleteln.php * @return bool false on success, otherwise true. */ function ncurses_deleteln() {} /** * Write all prepared refreshes to terminal * @link https://php.net/manual/en/function.ncurses-doupdate.php * @return bool */ function ncurses_doupdate() {} /** * Activate keyboard input echo * @link https://php.net/manual/en/function.ncurses-echo.php * @return bool false on success, true if any error occurred. */ function ncurses_echo() {} /** * Erase terminal screen * @link https://php.net/manual/en/function.ncurses-erase.php * @return bool */ function ncurses_erase() {} /** * Erase window contents * @link https://php.net/manual/en/function.ncurses-werase.php * @param resource $window

    *

    * @return int */ function ncurses_werase($window) {} /** * Returns current erase character * @link https://php.net/manual/en/function.ncurses-erasechar.php * @return string The current erase char, as a string. */ function ncurses_erasechar() {} /** * Flash terminal screen (visual bell) * @link https://php.net/manual/en/function.ncurses-flash.php * @return bool false on success, otherwise true. */ function ncurses_flash() {} /** * Flush keyboard input buffer * @link https://php.net/manual/en/function.ncurses-flushinp.php * @return bool false on success, otherwise true. */ function ncurses_flushinp() {} /** * Check for insert- and delete-capabilities * @link https://php.net/manual/en/function.ncurses-has-ic.php * @return bool true if the terminal has insert/delete-capabilities, false * otherwise. */ function ncurses_has_ic() {} /** * Check for line insert- and delete-capabilities * @link https://php.net/manual/en/function.ncurses-has-il.php * @return bool true if the terminal has insert/delete-line capabilities, * false otherwise. */ function ncurses_has_il() {} /** * Get character and attribute at current position * @link https://php.net/manual/en/function.ncurses-inch.php * @return string the character, as a string. */ function ncurses_inch() {} /** * Insert a line, move rest of screen down * @link https://php.net/manual/en/function.ncurses-insertln.php * @return int */ function ncurses_insertln() {} /** * Ncurses is in endwin mode, normal screen output may be performed * @link https://php.net/manual/en/function.ncurses-isendwin.php * @return bool true, if ncurses_endwin has been called * without any subsequent calls to ncurses_wrefresh, * false otherwise. */ function ncurses_isendwin() {} /** * Returns current line kill character * @link https://php.net/manual/en/function.ncurses-killchar.php * @return string the kill character, as a string. */ function ncurses_killchar() {} /** * Translate newline and carriage return / line feed * @link https://php.net/manual/en/function.ncurses-nl.php * @return bool */ function ncurses_nl() {} /** * Switch terminal to cooked mode * @link https://php.net/manual/en/function.ncurses-nocbreak.php * @return bool true if any error occurred, otherwise false. */ function ncurses_nocbreak() {} /** * Switch off keyboard input echo * @link https://php.net/manual/en/function.ncurses-noecho.php * @return bool true if any error occurred, false otherwise. */ function ncurses_noecho() {} /** * Do not translate newline and carriage return / line feed * @link https://php.net/manual/en/function.ncurses-nonl.php * @return bool */ function ncurses_nonl() {} /** * Switch terminal out of raw mode * @link https://php.net/manual/en/function.ncurses-noraw.php * @return bool true if any error occurred, otherwise false. */ function ncurses_noraw() {} /** * Switch terminal into raw mode * @link https://php.net/manual/en/function.ncurses-raw.php * @return bool true if any error occurred, otherwise false. */ function ncurses_raw() {} /** * Enables/Disable 8-bit meta key information * @link https://php.net/manual/en/function.ncurses-meta.php * @param resource $window

    *

    * @param $bit8 bool

    *

    * @return int */ function ncurses_meta($window, $bit8) {} /** * Restores saved terminal state * @link https://php.net/manual/en/function.ncurses-resetty.php * @return bool Always returns false. */ function ncurses_resetty() {} /** * Saves terminal state * @link https://php.net/manual/en/function.ncurses-savetty.php * @return bool Always returns false. */ function ncurses_savetty() {} /** * Returns a logical OR of all attribute flags supported by terminal * @link https://php.net/manual/en/function.ncurses-termattrs.php * @return bool */ function ncurses_termattrs() {} /** * Assign terminal default colors to color id -1 * @link https://php.net/manual/en/function.ncurses-use-default-colors.php * @return bool */ function ncurses_use_default_colors() {} /** * Returns current soft label key attribute * @link https://php.net/manual/en/function.ncurses-slk-attr.php * @return int The attribute, as an integer. */ function ncurses_slk_attr() {} /** * Clears soft labels from screen * @link https://php.net/manual/en/function.ncurses-slk-clear.php * @return bool true on errors, false otherwise. */ function ncurses_slk_clear() {} /** * Copies soft label keys to virtual screen * @link https://php.net/manual/en/function.ncurses-slk-noutrefresh.php * @return bool */ function ncurses_slk_noutrefresh() {} /** * Copies soft label keys to screen * @link https://php.net/manual/en/function.ncurses-slk-refresh.php * @return int */ function ncurses_slk_refresh() {} /** * Restores soft label keys * @link https://php.net/manual/en/function.ncurses-slk-restore.php * @return int */ function ncurses_slk_restore() {} /** * Forces output when ncurses_slk_noutrefresh is performed * @link https://php.net/manual/en/function.ncurses-slk-touch.php * @return int */ function ncurses_slk_touch() {} /** * Turn off the given attributes * @link https://php.net/manual/en/function.ncurses-attroff.php * @param int $attributes

    *

    * @return int */ function ncurses_attroff($attributes) {} /** * Turn on the given attributes * @link https://php.net/manual/en/function.ncurses-attron.php * @param int $attributes

    *

    * @return int */ function ncurses_attron($attributes) {} /** * Set given attributes * @link https://php.net/manual/en/function.ncurses-attrset.php * @param int $attributes

    *

    * @return int */ function ncurses_attrset($attributes) {} /** * Set background property for terminal screen * @link https://php.net/manual/en/function.ncurses-bkgd.php * @param int $attrchar

    *

    * @return int */ function ncurses_bkgd($attrchar) {} /** * Set cursor state * @link https://php.net/manual/en/function.ncurses-curs-set.php * @param int $visibility

    *

    * @return int */ function ncurses_curs_set($visibility) {} /** * Delay output on terminal using padding characters * @link https://php.net/manual/en/function.ncurses-delay-output.php * @param int $milliseconds

    *

    * @return int */ function ncurses_delay_output($milliseconds) {} /** * Single character output including refresh * @link https://php.net/manual/en/function.ncurses-echochar.php * @param int $character

    *

    * @return int */ function ncurses_echochar($character) {} /** * Put terminal into halfdelay mode * @link https://php.net/manual/en/function.ncurses-halfdelay.php * @param int $tenth

    *

    * @return int */ function ncurses_halfdelay($tenth) {} /** * Check for presence of a function key on terminal keyboard * @link https://php.net/manual/en/function.ncurses-has-key.php * @param int $keycode

    *

    * @return int */ function ncurses_has_key($keycode) {} /** * Insert character moving rest of line including character at current position * @link https://php.net/manual/en/function.ncurses-insch.php * @param int $character

    *

    * @return int */ function ncurses_insch($character) {} /** * Insert lines before current line scrolling down (negative numbers delete and scroll up) * @link https://php.net/manual/en/function.ncurses-insdelln.php * @param int $count

    *

    * @return int */ function ncurses_insdelln($count) {} /** * Set timeout for mouse button clicks * @link https://php.net/manual/en/function.ncurses-mouseinterval.php * @param int $milliseconds

    *

    * @return int */ function ncurses_mouseinterval($milliseconds) {} /** * Sleep * @link https://php.net/manual/en/function.ncurses-napms.php * @param int $milliseconds

    *

    * @return int */ function ncurses_napms($milliseconds) {} /** * Scroll window content up or down without changing current position * @link https://php.net/manual/en/function.ncurses-scrl.php * @param int $count

    *

    * @return int */ function ncurses_scrl($count) {} /** * Turn off the given attributes for soft function-key labels * @link https://php.net/manual/en/function.ncurses-slk-attroff.php * @param int $intarg

    *

    * @return int */ function ncurses_slk_attroff($intarg) {} /** * Turn on the given attributes for soft function-key labels * @link https://php.net/manual/en/function.ncurses-slk-attron.php * @param int $intarg

    *

    * @return int */ function ncurses_slk_attron($intarg) {} /** * Set given attributes for soft function-key labels * @link https://php.net/manual/en/function.ncurses-slk-attrset.php * @param int $intarg

    *

    * @return int */ function ncurses_slk_attrset($intarg) {} /** * Sets color for soft label keys * @link https://php.net/manual/en/function.ncurses-slk-color.php * @param int $intarg

    *

    * @return int */ function ncurses_slk_color($intarg) {} /** * Initializes soft label key functions * @link https://php.net/manual/en/function.ncurses-slk-init.php * @param int $format

    * If ncurses_initscr eventually uses a line from * stdscr to emulate the soft labels, then this parameter determines how * the labels are arranged of the screen. *

    *

    * 0 indicates a 3-2-3 arrangement of the labels, 1 indicates a 4-4 * arrangement and 2 indicates the PC like 4-4-4 mode, but in addition an * index line will be created. *

    * @return bool */ function ncurses_slk_init($format) {} /** * Sets function key labels * @link https://php.net/manual/en/function.ncurses-slk-set.php * @param int $labelnr

    *

    * @param string $label

    *

    * @param int $format

    *

    * @return bool */ function ncurses_slk_set($labelnr, $label, $format) {} /** * Specify different filedescriptor for typeahead checking * @link https://php.net/manual/en/function.ncurses-typeahead.php * @param int $fd

    *

    * @return int */ function ncurses_typeahead($fd) {} /** * Put a character back into the input stream * @link https://php.net/manual/en/function.ncurses-ungetch.php * @param int $keycode

    *

    * @return int */ function ncurses_ungetch($keycode) {} /** * Display the string on the terminal in the video attribute mode * @link https://php.net/manual/en/function.ncurses-vidattr.php * @param int $intarg

    *

    * @return int */ function ncurses_vidattr($intarg) {} /** * Refresh window on terminal screen * @link https://php.net/manual/en/function.ncurses-wrefresh.php * @param resource $window

    *

    * @return int */ function ncurses_wrefresh($window) {} /** * Control use of extended names in terminfo descriptions * @link https://php.net/manual/en/function.ncurses-use-extended-names.php * @param bool $flag

    *

    * @return int */ function ncurses_use_extended_names($flag) {} /** * Control screen background * @link https://php.net/manual/en/function.ncurses-bkgdset.php * @param int $attrchar

    *

    * @return void */ function ncurses_bkgdset($attrchar) {} /** * Set LINES for iniscr() and newterm() to 1 * @link https://php.net/manual/en/function.ncurses-filter.php * @return void */ function ncurses_filter() {} /** * Do not flush on signal characters * @link https://php.net/manual/en/function.ncurses-noqiflush.php * @return void */ function ncurses_noqiflush() {} /** * Flush on signal characters * @link https://php.net/manual/en/function.ncurses-qiflush.php * @return void */ function ncurses_qiflush() {} /** * Set timeout for special key sequences * @link https://php.net/manual/en/function.ncurses-timeout.php * @param int $millisec

    *

    * @return void */ function ncurses_timeout($millisec) {} /** * Control use of environment information about terminal size * @link https://php.net/manual/en/function.ncurses-use-env.php * @param bool $flag

    *

    * @return void */ function ncurses_use_env($flag) {} /** * Output text at current position * @link https://php.net/manual/en/function.ncurses-addstr.php * @param string $text

    *

    * @return int */ function ncurses_addstr($text) {} /** * Apply padding information to the string and output it * @link https://php.net/manual/en/function.ncurses-putp.php * @param string $text

    *

    * @return int */ function ncurses_putp($text) {} /** * Dump screen content to file * @link https://php.net/manual/en/function.ncurses-scr-dump.php * @param string $filename

    *

    * @return int */ function ncurses_scr_dump($filename) {} /** * Initialize screen from file dump * @link https://php.net/manual/en/function.ncurses-scr-init.php * @param string $filename

    *

    * @return int */ function ncurses_scr_init($filename) {} /** * Restore screen from file dump * @link https://php.net/manual/en/function.ncurses-scr-restore.php * @param string $filename

    *

    * @return int */ function ncurses_scr_restore($filename) {} /** * Inherit screen from file dump * @link https://php.net/manual/en/function.ncurses-scr-set.php * @param string $filename

    *

    * @return int */ function ncurses_scr_set($filename) {} /** * Move current position and add character * @link https://php.net/manual/en/function.ncurses-mvaddch.php * @param int $y

    *

    * @param int $x

    *

    * @param int $c

    *

    * @return int */ function ncurses_mvaddch($y, $x, $c) {} /** * Move position and add attributed string with specified length * @link https://php.net/manual/en/function.ncurses-mvaddchnstr.php * @param int $y

    *

    * @param int $x

    *

    * @param string $s

    *

    * @param int $n

    *

    * @return int */ function ncurses_mvaddchnstr($y, $x, $s, $n) {} /** * Add attributed string with specified length at current position * @link https://php.net/manual/en/function.ncurses-addchnstr.php * @param string $s

    *

    * @param int $n

    *

    * @return int */ function ncurses_addchnstr($s, $n) {} /** * Move position and add attributed string * @link https://php.net/manual/en/function.ncurses-mvaddchstr.php * @param int $y

    *

    * @param int $x

    *

    * @param string $s

    *

    * @return int */ function ncurses_mvaddchstr($y, $x, $s) {} /** * Add attributed string at current position * @link https://php.net/manual/en/function.ncurses-addchstr.php * @param string $s

    *

    * @return int */ function ncurses_addchstr($s) {} /** * Move position and add string with specified length * @link https://php.net/manual/en/function.ncurses-mvaddnstr.php * @param int $y

    *

    * @param int $x

    *

    * @param string $s

    *

    * @param int $n

    *

    * @return int */ function ncurses_mvaddnstr($y, $x, $s, $n) {} /** * Add string with specified length at current position * @link https://php.net/manual/en/function.ncurses-addnstr.php * @param string $s

    *

    * @param int $n

    *

    * @return int */ function ncurses_addnstr($s, $n) {} /** * Move position and add string * @link https://php.net/manual/en/function.ncurses-mvaddstr.php * @param int $y

    *

    * @param int $x

    *

    * @param string $s

    *

    * @return int */ function ncurses_mvaddstr($y, $x, $s) {} /** * Move position and delete character, shift rest of line left * @link https://php.net/manual/en/function.ncurses-mvdelch.php * @param int $y

    *

    * @param int $x

    *

    * @return int */ function ncurses_mvdelch($y, $x) {} /** * Move position and get character at new position * @link https://php.net/manual/en/function.ncurses-mvgetch.php * @param int $y

    *

    * @param int $x

    *

    * @return int */ function ncurses_mvgetch($y, $x) {} /** * Move position and get attributed character at new position * @link https://php.net/manual/en/function.ncurses-mvinch.php * @param int $y

    *

    * @param int $x

    *

    * @return int */ function ncurses_mvinch($y, $x) {} /** * Add string at new position in window * @link https://php.net/manual/en/function.ncurses-mvwaddstr.php * @param resource $window

    *

    * @param int $y

    *

    * @param int $x

    *

    * @param string $text

    *

    * @return int */ function ncurses_mvwaddstr($window, $y, $x, $text) {} /** * Insert string at current position, moving rest of line right * @link https://php.net/manual/en/function.ncurses-insstr.php * @param string $text

    *

    * @return int */ function ncurses_insstr($text) {} /** * Reads string from terminal screen * @link https://php.net/manual/en/function.ncurses-instr.php * @param string &$buffer

    * The characters. Attributes will be stripped. *

    * @return int the number of characters. */ function ncurses_instr(&$buffer) {} /** * Set new position and draw a horizontal line using an attributed character and max. n characters long * @link https://php.net/manual/en/function.ncurses-mvhline.php * @param int $y

    *

    * @param int $x

    *

    * @param int $attrchar

    *

    * @param int $n

    *

    * @return int */ function ncurses_mvhline($y, $x, $attrchar, $n) {} /** * Move cursor immediately * @link https://php.net/manual/en/function.ncurses-mvcur.php * @param int $old_y

    *

    * @param int $old_x

    *

    * @param int $new_y

    *

    * @param int $new_x

    *

    * @return int */ function ncurses_mvcur($old_y, $old_x, $new_y, $new_x) {} /** * Set new RGB value for color * @link https://php.net/manual/en/function.ncurses-init-color.php * @param int $color

    *

    * @param int $r

    *

    * @param int $g

    *

    * @param int $b

    *

    * @return int */ function ncurses_init_color($color, $r, $g, $b) {} /** * Draw a border around the screen using attributed characters * @link https://php.net/manual/en/function.ncurses-border.php * @param int $left

    *

    * @param int $right

    *

    * @param int $top

    *

    * @param int $bottom

    *

    * @param int $tl_corner

    * Top left corner *

    * @param int $tr_corner

    * Top right corner *

    * @param int $bl_corner

    * Bottom left corner *

    * @param int $br_corner

    * Bottom right corner *

    * @return int */ function ncurses_border($left, $right, $top, $bottom, $tl_corner, $tr_corner, $bl_corner, $br_corner) {} /** * Define default colors for color 0 * @link https://php.net/manual/en/function.ncurses-assume-default-colors.php * @param int $fg

    *

    * @param int $bg

    *

    * @return int */ function ncurses_assume_default_colors($fg, $bg) {} /** * Define a keycode * @link https://php.net/manual/en/function.ncurses-define-key.php * @param string $definition

    *

    * @param int $keycode

    *

    * @return int */ function ncurses_define_key($definition, $keycode) {} /** * Draw a horizontal line at current position using an attributed character and max. n characters long * @link https://php.net/manual/en/function.ncurses-hline.php * @param int $charattr

    *

    * @param int $n

    *

    * @return int */ function ncurses_hline($charattr, $n) {} /** * Draw a vertical line at current position using an attributed character and max. n characters long * @link https://php.net/manual/en/function.ncurses-vline.php * @param int $charattr

    *

    * @param int $n

    *

    * @return int */ function ncurses_vline($charattr, $n) {} /** * Enable or disable a keycode * @link https://php.net/manual/en/function.ncurses-keyok.php * @param int $keycode

    *

    * @param bool $enable

    *

    * @return int */ function ncurses_keyok($keycode, $enable) {} /** * Returns terminals (short)-name * @link https://php.net/manual/en/function.ncurses-termname.php * @return string|null the shortname of the terminal, truncated to 14 characters. * On errors, returns null. */ function ncurses_termname() {} /** * Returns terminals description * @link https://php.net/manual/en/function.ncurses-longname.php * @return string|null the description, as a string truncated to 128 characters. * On errors, returns null. */ function ncurses_longname() {} /** * Sets mouse options * @link https://php.net/manual/en/function.ncurses-mousemask.php * @param int $newmask

    * Mouse mask options can be set with the following predefined constants: *

    NCURSES_BUTTON1_PRESSED

    * @param int &$oldmask

    * This will be set to the previous value of the mouse event mask. *

    * @return int a mask to indicated which of the in parameter * newmask specified mouse events can be reported. On * complete failure, it returns 0. *

    */ function ncurses_mousemask($newmask, &$oldmask) {} /** * Reads mouse event * @link https://php.net/manual/en/function.ncurses-getmouse.php * @param array &$mevent

    * Event options will be delivered in this parameter which has to be an * array, passed by reference (see example below). *

    *

    * On success an associative array with following keys will be delivered: *

    * "id" : Id to distinguish multiple devices *

    * @return bool false if a mouse event is actually visible in the given window, * otherwise returns true. *

    */ function ncurses_getmouse(array &$mevent) {} /** * Pushes mouse event to queue * @link https://php.net/manual/en/function.ncurses-ungetmouse.php * @param array $mevent

    * An associative array specifying the event options: * "id" : Id to distinguish multiple devices *

    * @return bool false on success, true otherwise. */ function ncurses_ungetmouse(array $mevent) {} /** * Transforms coordinates * @link https://php.net/manual/en/function.ncurses-mouse-trafo.php * @param int &$y

    *

    * @param int &$x

    *

    * @param bool $toscreen

    *

    * @return bool */ function ncurses_mouse_trafo(&$y, &$x, $toscreen) {} /** * Transforms window/stdscr coordinates * @link https://php.net/manual/en/function.ncurses-wmouse-trafo.php * @param resource $window

    *

    * @param int &$y

    *

    * @param int &$x

    *

    * @param bool $toscreen

    *

    * @return bool */ function ncurses_wmouse_trafo($window, &$y, &$x, $toscreen) {} /** * Outputs text at current position in window * @link https://php.net/manual/en/function.ncurses-waddstr.php * @param resource $window

    *

    * @param string $str

    *

    * @param int $n [optional]

    *

    * @return int */ function ncurses_waddstr($window, $str, $n = null) {} /** * Copies window to virtual screen * @link https://php.net/manual/en/function.ncurses-wnoutrefresh.php * @param resource $window

    *

    * @return int */ function ncurses_wnoutrefresh($window) {} /** * Clears window * @link https://php.net/manual/en/function.ncurses-wclear.php * @param resource $window

    *

    * @return int */ function ncurses_wclear($window) {} /** * Sets windows color pairings * @link https://php.net/manual/en/function.ncurses-wcolor-set.php * @param resource $window

    *

    * @param int $color_pair

    *

    * @return int */ function ncurses_wcolor_set($window, $color_pair) {} /** * Reads a character from keyboard (window) * @link https://php.net/manual/en/function.ncurses-wgetch.php * @param resource $window

    *

    * @return int */ function ncurses_wgetch($window) {} /** * Turns keypad on or off * @link https://php.net/manual/en/function.ncurses-keypad.php * @param resource $window

    *

    * @param bool $bf

    *

    * @return int */ function ncurses_keypad($window, $bf) {} /** * Moves windows output position * @link https://php.net/manual/en/function.ncurses-wmove.php * @param resource $window

    *

    * @param int $y

    *

    * @param int $x

    *

    * @return int */ function ncurses_wmove($window, $y, $x) {} /** * Creates a new pad (window) * @link https://php.net/manual/en/function.ncurses-newpad.php * @param int $rows

    *

    * @param int $cols

    *

    * @return resource */ function ncurses_newpad($rows, $cols) {} /** * Copies a region from a pad into the virtual screen * @link https://php.net/manual/en/function.ncurses-prefresh.php * @param resource $pad

    *

    * @param int $pminrow

    *

    * @param int $pmincol

    *

    * @param int $sminrow

    *

    * @param int $smincol

    *

    * @param int $smaxrow

    *

    * @param int $smaxcol

    *

    * @return int */ function ncurses_prefresh($pad, $pminrow, $pmincol, $sminrow, $smincol, $smaxrow, $smaxcol) {} /** * Copies a region from a pad into the virtual screen * @link https://php.net/manual/en/function.ncurses-pnoutrefresh.php * @param resource $pad

    *

    * @param int $pminrow

    *

    * @param int $pmincol

    *

    * @param int $sminrow

    *

    * @param int $smincol

    *

    * @param int $smaxrow

    *

    * @param int $smaxcol

    *

    * @return int */ function ncurses_pnoutrefresh($pad, $pminrow, $pmincol, $sminrow, $smincol, $smaxrow, $smaxcol) {} /** * Enter standout mode for a window * @link https://php.net/manual/en/function.ncurses-wstandout.php * @param resource $window

    *

    * @return int */ function ncurses_wstandout($window) {} /** * End standout mode for a window * @link https://php.net/manual/en/function.ncurses-wstandend.php * @param resource $window

    *

    * @return int */ function ncurses_wstandend($window) {} /** * Set the attributes for a window * @link https://php.net/manual/en/function.ncurses-wattrset.php * @param resource $window

    *

    * @param int $attrs

    *

    * @return int */ function ncurses_wattrset($window, $attrs) {} /** * Turns on attributes for a window * @link https://php.net/manual/en/function.ncurses-wattron.php * @param resource $window

    *

    * @param int $attrs

    *

    * @return int */ function ncurses_wattron($window, $attrs) {} /** * Turns off attributes for a window * @link https://php.net/manual/en/function.ncurses-wattroff.php * @param resource $window

    *

    * @param int $attrs

    *

    * @return int */ function ncurses_wattroff($window, $attrs) {} /** * Adds character at current position in a window and advance cursor * @link https://php.net/manual/en/function.ncurses-waddch.php * @param resource $window

    *

    * @param int $ch

    *

    * @return int */ function ncurses_waddch($window, $ch) {} /** * Draws a border around the window using attributed characters * @link https://php.net/manual/en/function.ncurses-wborder.php * @param resource $window

    * The window on which we operate *

    * @param int $left

    *

    * @param int $right

    *

    * @param int $top

    *

    * @param int $bottom

    *

    * @param int $tl_corner

    * Top left corner *

    * @param int $tr_corner

    * Top right corner *

    * @param int $bl_corner

    * Bottom left corner *

    * @param int $br_corner

    * Bottom right corner *

    * @return int */ function ncurses_wborder($window, $left, $right, $top, $bottom, $tl_corner, $tr_corner, $bl_corner, $br_corner) {} /** * Draws a horizontal line in a window at current position using an attributed character and max. n characters long * @link https://php.net/manual/en/function.ncurses-whline.php * @param resource $window

    *

    * @param int $charattr

    *

    * @param int $n

    *

    * @return int */ function ncurses_whline($window, $charattr, $n) {} /** * Draws a vertical line in a window at current position using an attributed character and max. n characters long * @link https://php.net/manual/en/function.ncurses-wvline.php * @param resource $window

    *

    * @param int $charattr

    *

    * @param int $n

    *

    * @return int */ function ncurses_wvline($window, $charattr, $n) {} /** * Returns the current cursor position for a window * @link https://php.net/manual/en/function.ncurses-getyx.php * @param resource $window

    *

    * @param int &$y

    *

    * @param int &$x

    *

    * @return void */ function ncurses_getyx($window, &$y, &$x) {} /** * Returns the size of a window * @link https://php.net/manual/en/function.ncurses-getmaxyx.php * @param resource $window

    * The measured window *

    * @param int &$y

    * This will be set to the window height *

    * @param int &$x

    * This will be set to the window width *

    * @return void */ function ncurses_getmaxyx($window, &$y, &$x) {} /** * Refreshes the virtual screen to reflect the relations between panels in the stack * @link https://php.net/manual/en/function.ncurses-update-panels.php * @return void */ function ncurses_update_panels() {} /** * Returns the window associated with panel * @link https://php.net/manual/en/function.ncurses-panel-window.php * @param resource $panel

    *

    * @return resource */ function ncurses_panel_window($panel) {} /** * Returns the panel below panel * @link https://php.net/manual/en/function.ncurses-panel-below.php * @param resource $panel

    *

    * @return resource */ function ncurses_panel_below($panel) {} /** * Returns the panel above panel * @link https://php.net/manual/en/function.ncurses-panel-above.php * @param resource $panel

    *

    * @return resource If panel is null, returns the bottom panel in the stack. */ function ncurses_panel_above($panel) {} /** * Replaces the window associated with panel * @link https://php.net/manual/en/function.ncurses-replace-panel.php * @param resource $panel

    *

    * @param resource $window

    *

    * @return int */ function ncurses_replace_panel($panel, $window) {} /** * Moves a panel so that its upper-left corner is at [startx, starty] * @link https://php.net/manual/en/function.ncurses-move-panel.php * @param resource $panel

    *

    * @param int $startx

    *

    * @param int $starty

    *

    * @return int */ function ncurses_move_panel($panel, $startx, $starty) {} /** * Moves a visible panel to the bottom of the stack * @link https://php.net/manual/en/function.ncurses-bottom-panel.php * @param resource $panel

    *

    * @return int */ function ncurses_bottom_panel($panel) {} /** * Moves a visible panel to the top of the stack * @link https://php.net/manual/en/function.ncurses-top-panel.php * @param resource $panel

    *

    * @return int */ function ncurses_top_panel($panel) {} /** * Places an invisible panel on top of the stack, making it visible * @link https://php.net/manual/en/function.ncurses-show-panel.php * @param resource $panel

    *

    * @return int */ function ncurses_show_panel($panel) {} /** * Remove panel from the stack, making it invisible * @link https://php.net/manual/en/function.ncurses-hide-panel.php * @param resource $panel

    *

    * @return int */ function ncurses_hide_panel($panel) {} /** * Remove panel from the stack and delete it (but not the associated window) * @link https://php.net/manual/en/function.ncurses-del-panel.php * @param resource $panel

    *

    * @return bool */ function ncurses_del_panel($panel) {} /** * Create a new panel and associate it with window * @link https://php.net/manual/en/function.ncurses-new-panel.php * @param resource $window

    *

    * @return resource */ function ncurses_new_panel($window) {} define('NCURSES_COLOR_BLACK', 0); define('NCURSES_COLOR_RED', 1); define('NCURSES_COLOR_GREEN', 2); define('NCURSES_COLOR_YELLOW', 3); define('NCURSES_COLOR_BLUE', 4); define('NCURSES_COLOR_MAGENTA', 5); define('NCURSES_COLOR_CYAN', 6); define('NCURSES_COLOR_WHITE', 7); define('NCURSES_KEY_DOWN', 258); define('NCURSES_KEY_UP', 259); define('NCURSES_KEY_LEFT', 260); define('NCURSES_KEY_RIGHT', 261); define('NCURSES_KEY_HOME', 262); define('NCURSES_KEY_END', 360); define('NCURSES_KEY_BACKSPACE', 263); define('NCURSES_KEY_MOUSE', 409); define('NCURSES_KEY_F0', 264); define('NCURSES_KEY_F1', 265); define('NCURSES_KEY_F2', 266); define('NCURSES_KEY_F3', 267); define('NCURSES_KEY_F4', 268); define('NCURSES_KEY_F5', 269); define('NCURSES_KEY_F6', 270); define('NCURSES_KEY_F7', 271); define('NCURSES_KEY_F8', 272); define('NCURSES_KEY_F9', 273); define('NCURSES_KEY_F10', 274); define('NCURSES_KEY_F11', 275); define('NCURSES_KEY_F12', 276); define('NCURSES_KEY_DL', 328); define('NCURSES_KEY_IL', 329); define('NCURSES_KEY_DC', 330); define('NCURSES_KEY_IC', 331); define('NCURSES_KEY_EIC', 332); define('NCURSES_KEY_CLEAR', 333); define('NCURSES_KEY_EOS', 334); define('NCURSES_KEY_EOL', 335); define('NCURSES_KEY_SF', 336); define('NCURSES_KEY_SR', 337); define('NCURSES_KEY_NPAGE', 338); define('NCURSES_KEY_PPAGE', 339); define('NCURSES_KEY_STAB', 340); define('NCURSES_KEY_CTAB', 341); define('NCURSES_KEY_CATAB', 342); define('NCURSES_KEY_ENTER', 343); define('NCURSES_KEY_SRESET', 344); define('NCURSES_KEY_RESET', 345); define('NCURSES_KEY_PRINT', 346); define('NCURSES_KEY_LL', 347); define('NCURSES_KEY_A1', 348); define('NCURSES_KEY_A3', 349); define('NCURSES_KEY_B2', 350); define('NCURSES_KEY_C1', 351); define('NCURSES_KEY_C3', 352); define('NCURSES_KEY_BTAB', 353); define('NCURSES_KEY_BEG', 354); define('NCURSES_KEY_CANCEL', 355); define('NCURSES_KEY_CLOSE', 356); define('NCURSES_KEY_COMMAND', 357); define('NCURSES_KEY_COPY', 358); define('NCURSES_KEY_CREATE', 359); define('NCURSES_KEY_EXIT', 361); define('NCURSES_KEY_FIND', 362); define('NCURSES_KEY_HELP', 363); define('NCURSES_KEY_MARK', 364); define('NCURSES_KEY_MESSAGE', 365); define('NCURSES_KEY_MOVE', 366); define('NCURSES_KEY_NEXT', 367); define('NCURSES_KEY_OPEN', 368); define('NCURSES_KEY_OPTIONS', 369); define('NCURSES_KEY_PREVIOUS', 370); define('NCURSES_KEY_REDO', 371); define('NCURSES_KEY_REFERENCE', 372); define('NCURSES_KEY_REFRESH', 373); define('NCURSES_KEY_REPLACE', 374); define('NCURSES_KEY_RESTART', 375); define('NCURSES_KEY_RESUME', 376); define('NCURSES_KEY_SAVE', 377); define('NCURSES_KEY_SBEG', 378); define('NCURSES_KEY_SCANCEL', 379); define('NCURSES_KEY_SCOMMAND', 380); define('NCURSES_KEY_SCOPY', 381); define('NCURSES_KEY_SCREATE', 382); define('NCURSES_KEY_SDC', 383); define('NCURSES_KEY_SDL', 384); define('NCURSES_KEY_SELECT', 385); define('NCURSES_KEY_SEND', 386); define('NCURSES_KEY_SEOL', 387); define('NCURSES_KEY_SEXIT', 388); define('NCURSES_KEY_SFIND', 389); define('NCURSES_KEY_SHELP', 390); define('NCURSES_KEY_SHOME', 391); define('NCURSES_KEY_SIC', 392); define('NCURSES_KEY_SLEFT', 393); define('NCURSES_KEY_SMESSAGE', 394); define('NCURSES_KEY_SMOVE', 395); define('NCURSES_KEY_SNEXT', 396); define('NCURSES_KEY_SOPTIONS', 397); define('NCURSES_KEY_SPREVIOUS', 398); define('NCURSES_KEY_SPRINT', 399); define('NCURSES_KEY_SREDO', 400); define('NCURSES_KEY_SREPLACE', 401); define('NCURSES_KEY_SRIGHT', 402); define('NCURSES_KEY_SRSUME', 403); define('NCURSES_KEY_SSAVE', 404); define('NCURSES_KEY_SSUSPEND', 405); define('NCURSES_KEY_SUNDO', 406); define('NCURSES_KEY_SUSPEND', 407); define('NCURSES_KEY_UNDO', 408); define('NCURSES_KEY_RESIZE', 410); define('NCURSES_A_NORMAL', 0); define('NCURSES_A_STANDOUT', 65536); define('NCURSES_A_UNDERLINE', 131072); define('NCURSES_A_REVERSE', 262144); define('NCURSES_A_BLINK', 524288); define('NCURSES_A_DIM', 1048576); define('NCURSES_A_BOLD', 2097152); define('NCURSES_A_PROTECT', 16777216); define('NCURSES_A_INVIS', 8388608); define('NCURSES_A_ALTCHARSET', 4194304); define('NCURSES_A_CHARTEXT', 255); define('NCURSES_BUTTON1_PRESSED', 2); define('NCURSES_BUTTON1_RELEASED', 1); define('NCURSES_BUTTON1_CLICKED', 4); define('NCURSES_BUTTON1_DOUBLE_CLICKED', 8); define('NCURSES_BUTTON1_TRIPLE_CLICKED', 16); define('NCURSES_BUTTON2_PRESSED', 128); define('NCURSES_BUTTON2_RELEASED', 64); define('NCURSES_BUTTON2_CLICKED', 256); define('NCURSES_BUTTON2_DOUBLE_CLICKED', 512); define('NCURSES_BUTTON2_TRIPLE_CLICKED', 1024); define('NCURSES_BUTTON3_PRESSED', 8192); define('NCURSES_BUTTON3_RELEASED', 4096); define('NCURSES_BUTTON3_CLICKED', 16384); define('NCURSES_BUTTON3_DOUBLE_CLICKED', 32768); define('NCURSES_BUTTON3_TRIPLE_CLICKED', 65536); define('NCURSES_BUTTON4_PRESSED', 524288); define('NCURSES_BUTTON4_RELEASED', 262144); define('NCURSES_BUTTON4_CLICKED', 1048576); define('NCURSES_BUTTON4_DOUBLE_CLICKED', 2097152); define('NCURSES_BUTTON4_TRIPLE_CLICKED', 4194304); define('NCURSES_BUTTON_SHIFT', 33554432); define('NCURSES_BUTTON_CTRL', 16777216); define('NCURSES_BUTTON_ALT', 67108864); define('NCURSES_ALL_MOUSE_EVENTS', 134217727); define('NCURSES_REPORT_MOUSE_POSITION', 134217728); // End of ncurses v. * @link https://github.com/i-ekho/zmq-phpdoc */ /** * Class ZMQ * @link https://secure.php.net/manual/en/class.zmq.php */ class ZMQ { /** * Exclusive pair pattern */ public const SOCKET_PAIR = 0; /** * Publisher socket */ public const SOCKET_PUB = 1; /** * Subscriber socket */ public const SOCKET_SUB = 2; /** * Request socket */ public const SOCKET_REQ = 3; /** * Reply socket */ public const SOCKET_REP = 4; /** * Alias for SOCKET_DEALER */ public const SOCKET_XREQ = 5; /** * Alias for SOCKET_ROUTER */ public const SOCKET_XREP = 6; /** * Pipeline upstream push socket */ public const SOCKET_PUSH = 8; /** * Pipeline downstream pull socket */ public const SOCKET_PULL = 7; /** * Extended REP socket that can route replies to requesters */ public const SOCKET_ROUTER = 6; /** * Extended REQ socket that load balances to all connected peers */ public const SOCKET_DEALER = 5; /** * Similar to SOCKET_PUB, except you can receive subscriptions as messages. * The subscription message is 0 (unsubscribe) or 1 (subscribe) followed by the topic. */ public const SOCKET_XPUB = 9; /** * Similar to SOCKET_SUB, except you can send subscriptions as messages. See SOCKET_XPUB for format. */ public const SOCKET_XSUB = 10; /** * Used to send and receive TCP data from a non-ØMQ peer. * Available if compiled against ZeroMQ 4.x or higher. */ public const SOCKET_STREAM = 11; /** * The high water mark for inbound and outbound messages is a hard * limit on the maximum number of outstanding messages ØMQ shall queue in memory * for any single peer that the specified socket is communicating with. * Setting this option on a socket will only affect connections made after the option has been set. * On ZeroMQ 3.x this is a wrapper for setting both SNDHWM and RCVHWM. */ public const SOCKOPT_HWM = 1; /** * The ZMQ_SNDHWM option shall set the high water mark for outbound messages on the specified socket. * Available if compiled against ZeroMQ 3.x or higher. */ public const SOCKOPT_SNDHWM = 23; /** * The ZMQ_SNDHWM option shall set the high water mark for inbound messages on the specified socket. * Available if compiled against ZeroMQ 3.x or higher. */ public const SOCKOPT_RCVHWM = 24; /** * Set I/O thread affinity */ public const SOCKOPT_AFFINITY = 4; /** * Set socket identity */ public const SOCKOPT_IDENTITY = 5; /** * Establish message filter. Valid for subscriber socket */ public const SOCKOPT_SUBSCRIBE = 6; /** * Remove message filter. Valid for subscriber socket */ public const SOCKOPT_UNSUBSCRIBE = 7; /** * Set rate for multicast sockets (pgm) (Value: int >= 0) */ public const SOCKOPT_RATE = 8; /** * Set multicast recovery interval (Value: int >= 0) */ public const SOCKOPT_RECOVERY_IVL = 9; /** * Set the initial reconnection interval (Value: int >= 0) */ public const SOCKOPT_RECONNECT_IVL = 18; /** * Set the max reconnection interval (Value: int >= 0) */ public const SOCKOPT_RECONNECT_IVL_MAX = 21; /** * Control multicast loopback (Value: int >= 0) */ public const SOCKOPT_MCAST_LOOP = 10; /** * Set kernel transmit buffer size (Value: int >= 0) */ public const SOCKOPT_SNDBUF = 11; /** * Set kernel receive buffer size (Value: int >= 0) */ public const SOCKOPT_RCVBUF = 12; /** * Receive multi-part messages */ public const SOCKOPT_RCVMORE = 13; /** * Get the socket type. Valid for getSockOpt */ public const SOCKOPT_TYPE = 16; /** * The linger value of the socket. * Specifies how long the socket blocks trying flush messages after it has been closed */ public const SOCKOPT_LINGER = 17; /** * The SOCKOPT_BACKLOG option shall set the maximum length of the queue of outstanding peer connections * for the specified socket; this only applies to connection-oriented transports. */ public const SOCKOPT_BACKLOG = 19; /** * Limits the maximum size of the inbound message. Value -1 means no limit. * Available if compiled against ZeroMQ 3.x or higher */ public const SOCKOPT_MAXMSGSIZE = 22; /** * Sets the timeout for send operation on the socket. Value -1 means no limit. * Available if compiled against ZeroMQ 3.x or higher */ public const SOCKOPT_SNDTIMEO = 28; /** * Sets the timeout for receive operation on the socket. Value -1 means no limit. * Available if compiled against ZeroMQ 3.x or higher */ public const SOCKOPT_RCVTIMEO = 27; /** * Disable IPV6 support if 1. * Available if compiled against ZeroMQ 3.x */ public const SOCKOPT_IPV4ONLY = 31; /** * Retrieve the last connected endpoint - for use with * wildcard ports. * Available if compiled against ZeroMQ 3.x or higher */ public const SOCKOPT_LAST_ENDPOINT = 32; /** * Idle time for TCP keepalive. * Available if compiled against ZeroMQ 3.x or higher */ public const SOCKOPT_TCP_KEEPALIVE_IDLE = 36; /** * Count time for TCP keepalive. * Available if compiled against ZeroMQ 3.x or higher */ public const SOCKOPT_TCP_KEEPALIVE_CNT = 35; /** * Interval for TCP keepalive. * Available if compiled against ZeroMQ 3.x or higher */ public const SOCKOPT_TCP_KEEPALIVE_INTVL = 37; /** * Set a CIDR string to match against incoming TCP connections. * Available if compiled against ZeroMQ 3.x or higher */ public const SOCKOPT_DELAY_ATTACH_ON_CONNECT = 39; /** * Set a CIDR string to match against incoming TCP connections. * Available if compiled against ZeroMQ 3.x or higher */ public const SOCKOPT_TCP_ACCEPT_FILTER = 38; /** * Set the XPUB to receive an application message on each instance of a subscription. * Available if compiled against ZeroMQ 3.x or higher */ public const SOCKOPT_XPUB_VERBOSE = 40; /** * Sets the raw mode on the ROUTER, when set to 1. * In raw mode when using tcp:// transport the socket will read and write without ZeroMQ framing. * Available if compiled against ZeroMQ 4.0 or higher */ public const SOCKOPT_ROUTER_RAW = 41; /** * Enable IPV6. * Available if compiled against ZeroMQ 4.0 or higher */ public const SOCKOPT_IPV6 = 42; /** * The socket limit for this context. * Available if compiled against ZeroMQ 3.x or higher */ public const CTXOPT_MAX_SOCKETS = 2; /** * Poll for incoming data */ public const POLL_IN = 1; /** * Poll for outgoing data */ public const POLL_OUT = 2; /** * Non-blocking operation. * @deprecated use ZMQ::MODE_DONTWAIT instead */ public const MODE_NOBLOCK = 1; /** * Non-blocking operation */ public const MODE_DONTWAIT = 1; /** * Send multi-part message */ public const MODE_SNDMORE = 2; /** * Forwarder device */ public const DEVICE_FORWARDER = 2; /** * Queue device */ public const DEVICE_QUEUE = 3; /** * Streamer device */ public const DEVICE_STREAMER = 1; /** * ZMQ extension internal error */ public const ERR_INTERNAL = -99; /** * Implies that the operation would block when ZMQ::MODE_DONTWAIT is used */ public const ERR_EAGAIN = 11; /** * The operation is not supported by the socket type */ public const ERR_ENOTSUP = 156384713; /** * The operation can not be executed because the socket is not in correct state */ public const ERR_EFSM = 156384763; /** * The context has been terminated */ public const ERR_ETERM = 156384765; /** * Private constructor to prevent direct initialization. This class holds the constants for ZMQ extension. * @link https://secure.php.net/manual/en/zmq.construct.php */ private function __construct() {} } /** * Class ZMQContext * @link https://secure.php.net/manual/en/class.zmqcontext.php */ class ZMQContext { /** * Constructs a new ZMQ context. The context is used to initialize sockets. * A persistent context is required to initialize persistent sockets. * * @link https://secure.php.net/manual/en/zmqcontext.construct.php * * @param int $io_threads Number of io-threads in the context * @param bool $is_persistent Whether the context is persistent. Persistent context is stored over multiple requests and is a requirement for persistent sockets. */ public function __construct($io_threads = 1, $is_persistent = true) {} /** * (PECL zmq >= 1.0.4) * Returns the value of a context option. * * @link https://secure.php.net/manual/en/zmqcontext.getopt.php * * @param string $key An int representing the option. See the ZMQ::CTXOPT_* constants. * @return string|int Returns either a string or an integer depending on key. Throws ZMQContextException on error. * @throws ZMQContextException */ public function getOpt($key) {} /** * (PECL zmq >= 0.5.0) * Shortcut for creating new sockets from the context. * If the context is not persistent the persistent_id parameter is ignored * and the socket falls back to being non-persistent. * The on_new_socket is called only when a new underlying socket structure is created. * * @link https://secure.php.net/manual/en/zmqcontext.getsocket.php * * @param int $type ZMQ::SOCKET_* constant to specify socket type. * @param string $persistent_id If persistent_id is specified the socket will be persisted over multiple requests. * @param callable $on_new_socket Callback function, which is executed when a new socket structure is created. This function does not get invoked if the underlying persistent connection is re-used. The callback takes ZMQSocket and persistent_id as two arguments. * @return ZMQSocket * @throws ZMQSocketException */ public function getSocket($type, $persistent_id = null, $on_new_socket = null) {} /** * (PECL zmq >= 0.5.0) * Whether the context is persistent. * Persistent context is needed for persistent connections as each socket is allocated from a context. * * @link https://secure.php.net/manual/en/zmqcontext.ispersistent.php * * @return bool Returns TRUE if the context is persistent and FALSE if the context is non-persistent. */ public function isPersistent() {} /** * (PECL zmq >= 1.0.4) * Sets a ZMQ context option. The type of the value depends on the key. * See ZMQ Constant Types for more information. * * @link https://secure.php.net/manual/en/zmqcontext.setopt.php * * @param int $key One of the ZMQ::CTXOPT_* constants. * @param mixed $value The value of the parameter. * @return ZMQContext * @throws ZMQContextException */ public function setOpt($key, $value) {} } /** * Class ZMQSocket * @link https://secure.php.net/manual/en/class.zmqsocket.php */ class ZMQSocket { /** * (PECL zmq >= 0.5.0) * Constructs a ZMQSocket object. * The persistent_id parameter can be used to allocated a persistent socket. * A persistent socket has to be allocated from a persistent context and it stays connected over multiple requests. * The persistent_id parameter can be used to recall the same socket over multiple requests. * The on_new_socket is called only when a new underlying socket structure is created. * * @link https://secure.php.net/manual/en/zmqsocket.construct.php * * @param ZMQContext $context

    ZMQContext to build this object

    * @param int $type

    The type of the socket. See ZMQ::SOCKET_* constants.

    * @param string $persistent_id [optional]

    If persistent_id is specified the socket will be persisted over multiple requests. If context is not persistent the socket falls back to non-persistent mode.

    * @param callable $on_new_socket [optional]

    Callback function, which is executed when a new socket structure is created. This function does not get invoked if the underlying persistent connection is re-used.

    * * @throws ZMQSocketException */ public function __construct(ZMQContext $context, $type, $persistent_id = null, $on_new_socket = null) {} /** * (PECL zmq >= 0.5.0) * Bind the socket to an endpoint. * The endpoint is defined in format transport://address * where transport is one of the following: inproc, ipc, tcp, pgm or epgm. * * @link https://secure.php.net/manual/en/zmqsocket.bind.php * * @param string $dsn The bind dsn, for example transport://address. * @param bool $force Tries to bind even if the socket has already been bound to the given endpoint. * * @return ZMQSocket * @throws ZMQSocketException if binding fails */ public function bind($dsn, $force = false) {} /** * (PECL zmq >= 0.5.0) * Connect the socket to a remote endpoint. * The endpoint is defined in format transport://address * where transport is one of the following: inproc, ipc, tcp, pgm or epgm. * * @link https://secure.php.net/manual/en/zmqsocket.connect.php * * @param string $dsn The bind dsn, for example transport://address. * @param bool $force Tries to bind even if the socket has already been bound to the given endpoint. * * @return ZMQSocket * @throws ZMQSocketException If connection fails */ public function connect($dsn, $force = false) {} /** * (PECL zmq >= 1.0.4) * Disconnect the socket from a previously connected remote endpoint. * The endpoint is defined in format transport://address * where transport is one of the following: inproc, ipc, tcp, pgm or epgm. * * @link https://secure.php.net/manual/en/zmqsocket.disconnect.php * * @param string $dsn The bind dsn, for example transport://address. * * @return ZMQSocket * @throws ZMQSocketException If connection fails */ public function disconnect($dsn) {} /** * Returns a list of endpoints where the socket is connected or bound to. * * @link https://secure.php.net/manual/en/zmqsocket.getendpoints.php * * @return array contains two sub-arrays: 'connect' and 'bind' * @throws ZMQSocketException */ public function getEndpoints() {} /** * Returns the persistent id string assigned of the object and NULL if socket is not persistent. * * @link https://secure.php.net/manual/en/zmqsocket.getpersistentid.php * * @return string|null

    * Returns the persistent id string assigned of the object and NULL if socket is not persistent. *

    */ public function getPersistentId() {} /** * Returns the value of a socket option. * This method is available if ZMQ extension has been compiled against ZMQ version 2.0.7 or higher * * @link https://secure.php.net/manual/en/zmqsocket.getsockopt.php * * @since 0MQ 2.0.7 * @param int $key An int representing the option. See the ZMQ::SOCKOPT_* constants. * * @return string|int

    * Returns either a string or an integer depending on key. Throws * ZMQSocketException on error. *

    * @throws ZMQSocketException */ public function getSockOpt($key) {} /** * Return the socket type. * The socket type can be compared against ZMQ::SOCKET_* constants. * * @link https://secure.php.net/manual/en/zmqsocket.getsockettype.php * * @return int

    * Returns an integer representing the socket type. The integer can be compared against * ZMQ::SOCKET_* constants. *

    */ public function getSocketType() {} /** * Check whether the socket is persistent. * * @link https://secure.php.net/manual/en/zmqsocket.ispersistent.php * * @return bool

    Returns a boolean based on whether the socket is persistent or not.

    */ public function isPersistent() {} /** * Receive a message from a socket. * By default receiving will block until a message is available unless ZMQ::MODE_NOBLOCK flag is used. * ZMQ::SOCKOPT_RCVMORE socket option can be used for receiving multi-part messages. * Returns the message. * If ZMQ::MODE_NOBLOCK is used and the operation would block bool false shall be returned. * * @link https://secure.php.net/manual/en/zmqsocket.recv.php * @see ZMQSocket::setSockOpt() * * @param int $mode Pass mode flags to receive multipart messages or non-blocking operation. See ZMQ::MODE_* constants. * * @return string|false

    Returns the message. Throws ZMQSocketException in error. If ZMQ::MODE_NOBLOCK is used and the operation would block boolean false shall be returned.

    * @throws ZMQSocketException if receiving fails. */ public function recv($mode = 0) {} /** * Receive an array multipart message from a socket. * By default receiving will block until a message is available unless ZMQ::MODE_NOBLOCK flag is used. * Returns the array of message parts. * If ZMQ::MODE_NOBLOCK is used and the operation would block bool false shall be returned. * * @link https://secure.php.net/manual/en/zmqsocket.recvmulti.php * * @param int $mode Pass mode flags to receive multipart messages or non-blocking operation. See ZMQ::MODE_* constants. * * @return string[] Returns the array of message parts. Throws ZMQSocketException in error. If ZMQ::MODE_NOBLOCK is used and the operation would block boolean false shall be returned. * @throws ZMQSocketException if receiving fails. */ public function recvMulti($mode = 0) {} /** * Send a message using the socket. The operation can block unless ZMQ::MODE_NOBLOCK is used. * If ZMQ::MODE_NOBLOCK is used and the operation would block bool false shall be returned. * * @link https://secure.php.net/manual/en/zmqsocket.send.php * * @param string $message The message to send * @param int $mode Pass mode flags to receive multipart messages or non-blocking operation. See ZMQ::MODE_* constants. * * * @return ZMQSocket * @throws ZMQSocketException if sending message fails */ public function send($message, $mode = 0) {} /** * Send a multipart message using the socket. The operation can block unless ZMQ::MODE_NOBLOCK is used. * If ZMQ::MODE_NOBLOCK is used and the operation would block bool false shall be returned. * * @link https://secure.php.net/manual/en/zmqsocket.sendmulti.php * * @param array $message The message to send - an array of strings * @param int $mode Pass mode flags to receive multipart messages or non-blocking operation. See ZMQ::MODE_* constants. * * * @return ZMQSocket * @throws ZMQSocketException if sending message fails */ public function sendmulti(array $message, $mode = 0) {} /** * Sets a ZMQ socket option. The type of the value depends on the key. * @see ZMQ Constant Types for more information. * * @link https://secure.php.net/manual/en/zmqsocket.setsockopt.php * * @param int $key One of the ZMQ::SOCKOPT_* constants. * @param mixed $value The value of the parameter. * * @return ZMQSocket * @throws ZMQSocketException */ public function setSockOpt($key, $value) {} /** * Unbind the socket from an endpoint. * The endpoint is defined in format transport://address * where transport is one of the following: inproc, ipc, tcp, pgm or epgm. * * @link https://secure.php.net/manual/en/zmqsocket.unbind.php * * @param string $dsn The previously bound dsn, for example transport://address. * * @return ZMQSocket * @throws ZMQSocketException if binding fails */ public function unbind($dsn) {} } /** * Class ZMQPoll * @link https://secure.php.net/manual/en/class.zmqpoll.php */ class ZMQPoll { /** * (PECL zmq >= 0.5.0) * Adds a new item to the poll set and returns the internal id of the added item. * The item can be removed from the poll set using the returned string id. * Returns a string id of the added item which can be later used to remove the item. * * @link https://secure.php.net/manual/en/zmqpoll.add.php * * @param ZMQSocket $entry ZMQSocket object or a PHP stream resource * @param int $type Defines what activity the socket is polled for. See ZMQ::POLL_IN and ZMQ::POLL_OUT constants. * * @return int Returns a string id of the added item which can be later used to remove the item. Throws ZMQPollException on error. * @throws ZMQPollException if the object has not been initialized with polling */ public function add(ZMQSocket $entry, $type) {} /** * (PECL zmq >= 1.0.4) * Clears all elements from the poll set. * * @link https://secure.php.net/manual/en/zmqpoll.clear.php * * @return ZMQPoll Returns the current object. */ public function clear() {} /** * (PECL zmq >= 0.5.0) * Count the items in the poll set. * * @link https://secure.php.net/manual/en/zmqpoll.count.php * * @return int Returns an integer representing the amount of items in the poll set. */ public function count() {} /** * (PECL zmq >= 0.5.0) * Returns the ids of the objects that had errors in the last poll. * Returns an array containing ids for the items that had errors in the last poll. * Empty array is returned if there were no errors. * * @link https://secure.php.net/manual/en/zmqpoll.getlasterrors.php * * @return int[] */ public function getLastErrors() {} /** * (PECL zmq >= 0.5.0) * Polls the items in the current poll set. * The readable and writable items are returned in the readable and writable parameters. * ZMQPoll::getLastErrors() can be used to check if there were errors. * Returns an int representing amount of items with activity. * * @link https://secure.php.net/manual/en/zmqpoll.poll.php * * @param array &$readable Array where readable ZMQSockets/PHP streams are returned. The array will be cleared at the beginning of the operation. * @param array &$writable Array where writable ZMQSockets/PHP streams are returned. The array will be cleared at the beginning of the operation. * @param int $timeout Timeout for the operation. -1 means that poll waits until at least one item has activity. Please note that starting from version 1.0.0 the poll timeout is defined in milliseconds, rather than microseconds. * * @throws ZMQPollException if polling fails * @return int */ public function poll(array &$readable, array &$writable, $timeout = -1) {} /** * (PECL zmq >= 0.5.0) * Remove item from the poll set. * The item parameter can be ZMQSocket object, a stream resource or the id returned from ZMQPoll::add() method. * Returns true if the item was removed and false if the object with given id does not exist in the poll set. * * @link https://secure.php.net/manual/en/zmqpoll.remove.php * * @param ZMQSocket|string|mixed $item The ZMQSocket object, PHP stream or string id of the item. * @return bool Returns true if the item was removed and false if the object with given id does not exist in the poll set. */ public function remove($item) {} } /** * Class ZMQDevice * @link https://secure.php.net/manual/en/class.zmqdevice.php */ class ZMQDevice { /** * (PECL zmq >= 1.0.4) * Construct a new device. * "ØMQ devices can do intermediation of addresses, services, queues, or any other abstraction you care * to define above the message and socket layers." -- zguide * Call to this method will prepare the device. Usually devices are very long running processes so running this method from interactive script is not recommended. This method throw ZMQDeviceException if the device cannot be started. * * @link https://secure.php.net/manual/en/zmqdevice.construct.php * * @param ZMQSocket $frontend Frontend parameter for the devices. Usually where there messages are coming. * @param ZMQSocket $backend Backend parameter for the devices. Usually where there messages going to. * @param null|ZMQSocket $listener Listener socket, which receives a copy of all messages going both directions. The type of this socket should be SUB, PULL or DEALER. */ public function __construct(ZMQSocket $frontend, ZMQSocket $backend, ZMQSocket $listener = null) {} /** * Gets the idle callback timeout value. * This method returns the idle callback timeout value. * Added in ZMQ extension version 1.1.0. * * @link https://secure.php.net/manual/en/zmqdevice.getidletimeout.php * * @return int This method returns the idle callback timeout value. */ public function getIdleTimeout() {} /** * Gets the timer callback timeout value. * Added in ZMQ extension version 1.1.0. * * @link https://secure.php.net/manual/en/zmqdevice.gettimertimeout.php * * @return int This method returns the timer timeout value. */ public function getTimerTimeout() {} /** * Runs the device. * Call to this method will block until the device is running. * It is not recommended that devices are used from interactive scripts. * * @link https://secure.php.net/manual/en/zmqdevice.run.php * * @throws ZMQDeviceException */ public function run() {} /** * Sets the idle callback function. * If idle timeout is defined the idle callback function shall be called if the internal poll loop times out * without events. If the callback function returns false or a value that evaluates to false the device is stopped. * The callback function signature is callback (mixed $user_data). * * @link https://secure.php.net/manual/en/zmqdevice.setidlecallback.php * * @param callable $cb_func Callback function to invoke when the device is idle. Returning false or a value that evaluates to false from this function will cause the device to stop. * @param int $timeout How often to invoke the idle callback in milliseconds. The idle callback is invoked periodically when there is no activity on the device. The timeout value guarantees that there is at least this amount of milliseconds between invocations of the callback function. * @param mixed $user_data Additional data to pass to the callback function. * * @return ZMQDevice On success this method returns the current object. */ public function setIdleCallback($cb_func, $timeout, $user_data) {} /** * Sets the idle callback timeout value. The idle callback is invoked periodically when the device is idle. * On success this method returns the current object. * * @link https://secure.php.net/manual/en/zmqdevice.setidletimeout.php * * @param int $timeout The idle callback timeout value in milliseconds * * @return ZMQDevice On success this method returns the current object. */ public function setIdleTimeout($timeout) {} /** * Sets the timer callback function. The timer callback will be invoked after timeout has passed. * The difference between idle and timer callbacks are that idle callback is invoked only when the device is idle. * The callback function signature is callback (mixed $user_data). * Added in ZMQ extension version 1.1.0. * * @link https://secure.php.net/manual/en/zmqdevice.settimercallback.php * * @param callable $cb_func Callback function to invoke when the device is idle. Returning false or a value that evaluates to false from this function will cause the device to stop. * @param int $timeout How often to invoke the idle callback in milliseconds. The idle callback is invoked periodically when there is no activity on the device. The timeout value guarantees that there is at least this amount of milliseconds between invocations of the callback function. * @param mixed $user_data Additional data to pass to the callback function. * * @return ZMQDevice */ public function setTimerCallback($cb_func, $timeout, $user_data) {} /** * Sets the timer callback timeout value. The timer callback is invoked periodically if it's set. * Added in ZMQ extension version 1.1.0. * * @link https://secure.php.net/manual/en/zmqdevice.settimertimeout.php * * @param int $timeout The timer callback timeout value. * * @return ZMQDevice */ public function setTimerTimeout($timeout) {} } class ZMQException extends Exception {} class ZMQContextException extends ZMQException {} class ZMQSocketException extends ZMQException {} class ZMQPollException extends ZMQException {} class ZMQDeviceException extends ZMQException {} * COM class constructor. * @param string $module_name * @param string $server_name [optional] * @param int $codepage [optional] * @param string $typelib [optional] */ public function __construct($module_name, $server_name = null, $codepage = CP_ACP, $typelib = null) {} public function __get($name) {} public function __set($name, $value) {} public function __call($name, $args) {} } /** * The DOTNET class allows you to instantiate a class from a .Net assembly and call its methods and access its properties. * @link https://php.net/manual/en/class.dotnet.php */ class DOTNET { /** * (PHP 4 >= 4.1.0, PHP 5, PHP 7)
    * COM class constructor. * @param string $assembly_name * @param string $class_name * @param int $codepage [optional] */ public function __construct($assembly_name, string $class_name, $codepage = CP_ACP) {} public function __get($name) {} public function __set($name, $value) {} public function __call($name, $args) {} } /** * The VARIANT is COM's equivalent of the PHP zval; it is a structure that can contain a value with a range of different possible types. The VARIANT class provided by the COM extension allows you to have more control over the way that PHP passes values to and from COM. * @link https://php.net/manual/en/class.variant.php */ class VARIANT { /** * (PHP 4 >= 4.1.0, PHP 5, PHP 7)
    * COM class constructor. * @param mixed $value [optional] * @param int $type [optional] * @param int $codepage [optional] */ public function __construct($value = null, int $type = VT_EMPTY, $codepage = CP_ACP) {} public function __get($name) {} public function __set($name, $value) {} public function __call($name, $args) {} } /** * This extension will throw instances of the class com_exception whenever there is a potentially fatal error reported by COM. All COM exceptions have a well-defined code property that corresponds to the HRESULT return value from the various COM operations. You may use this code to make programmatic decisions on how to handle the exception. * @link https://php.net/manual/en/com.error-handling.php */ class com_exception extends \Exception {} /** * (PHP 5, PHP 7)
    * Generate a globally unique identifier (GUID) * @link https://php.net/manual/en/function.com-create-guid.php * @return string */ function com_create_guid() {} /** * (PHP 4 >= 4.2.0, PHP 5, PHP 7)
    * Connect events from a COM object to a PHP object * @link https://php.net/manual/en/function.com-event-sink.php * @param \VARIANT $comobject * @param object $sinkobject * @param string $sinkinterface [optional] * @return bool */ function com_event_sink($comobject, $sinkobject, $sinkinterface = null) {} /** * (PHP 5, PHP 7)
    * Returns a handle to an already running instance of a COM object * @link https://php.net/manual/en/function.com-get-active-object.php * @param string $progid * @param int $code_page [optional] * @return \VARIANT */ function com_get_active_object($progid, $code_page = CP_ACP) {} /** * (PHP 4 >= 4.1.0, PHP 5, PHP 7)
    * Loads a Typelib * @link https://php.net/manual/en/function.com-get-active-object.php * @param string $typelib_name * @param bool $case_insensitive [optional] * @return bool */ function com_load_typelib($typelib_name, $case_insensitive = true) {} /** * (PHP 4 >= 4.2.0, PHP 5, PHP 7)
    * Process COM messages, sleeping for up to timeoutms milliseconds * @link https://php.net/manual/en/function.com-message-pump.php * @param int $timeoutms [optional] * @return bool */ function com_message_pump($timeoutms = 0) {} /** * (PHP 4 >= 4.2.0, PHP 5, PHP 7)
    * Print out a PHP class definition for a dispatchable interface * @link https://php.net/manual/en/function.com-print-typeinfo.php * @param object $comobject * @param string $dispinterface [optional] * @param bool $wantsink [optional] * @return bool */ function com_print_typeinfo($comobject, $dispinterface = null, $wantsink = false) {} /** * (PHP 5, PHP 7)
    * Returns the absolute value of a variant * @link https://php.net/manual/en/function.variant-abs.php * @param mixed $val * @return mixed */ function variant_abs($val) {} /** * (PHP 5, PHP 7)
    * "Adds" two variant values together and returns the result * @link https://php.net/manual/en/function.variant-abs.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_add($left, $right) {} /** * (PHP 5, PHP 7)
    * Performs a bitwise AND operation between two variants * @link https://php.net/manual/en/function.variant-and.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_and($left, $right) {} /** * (PHP 5, PHP 7)
    * Convert a variant into a new variant object of another type * @link https://php.net/manual/en/function.variant-cast.php * @param \VARIANT $variant * @param int $type * @return \VARIANT */ function variant_cast($variant, $type) {} /** * (PHP 5, PHP 7)
    * Concatenates two variant values together and returns the result * @link https://php.net/manual/en/function.variant-cat.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_cat($left, $right) {} /** * (PHP 5, PHP 7)
    * Compares two variants * @link https://php.net/manual/en/function.variant-cmp.php * @param mixed $left * @param mixed $right * @param int $lcid [optional] * @param int $flags [optional] * @return int */ function variant_cmp($left, $right, $lcid = null, $flags = null) {} /** * (PHP 5, PHP 7)
    * Returns a variant date representation of a Unix timestamp * @link https://php.net/manual/en/function.variant-date-from-timestamp.php * @param int $timestamp * @return \VARIANT */ function variant_date_from_timestamp($timestamp) {} /** * (PHP 5, PHP 7)
    * Converts a variant date/time value to Unix timestamp * @link https://php.net/manual/en/function.variant-date-to-timestamp.php * @param \VARIANT $variant * @return int */ function variant_date_to_timestamp($variant) {} /** * (PHP 5, PHP 7)
    * Returns the result from dividing two variants * @link https://php.net/manual/en/function.variant-div.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_div($left, $right) {} /** * (PHP 5, PHP 7)
    * Performs a bitwise equivalence on two variants * @link https://php.net/manual/en/function.variant-eqv.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_eqv($left, $right) {} /** * (PHP 5, PHP 7)
    * Returns the integer portion of a variant * @link https://php.net/manual/en/function.variant-fix.php * @param mixed $variant * @return mixed */ function variant_fix($variant) {} /** * (PHP 5, PHP 7)
    * Returns the type of a variant object * @link https://php.net/manual/en/function.variant-get-type.php * @param VARIANT $variant * @return int */ function variant_get_type($variant) {} /** * (PHP 5, PHP 7)
    * Converts variants to integers and then returns the result from dividing them * @link https://php.net/manual/en/function.variant-idiv.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_idiv($left, $right) {} /** * (PHP 5, PHP 7)
    * Performs a bitwise implication on two variants * @link https://php.net/manual/en/function.variant-imp.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_imp($left, $right) {} /** * (PHP 5, PHP 7)
    * Returns the integer portion of a variant * @link https://php.net/manual/en/function.variant-int.php * @param mixed $variant * @return mixed */ function variant_int($variant) {} /** * (PHP 5, PHP 7)
    * Divides two variants and returns only the remainder * @link https://php.net/manual/en/function.variant-mod.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_mod($left, $right) {} /** * (PHP 5, PHP 7)
    * Multiplies the values of the two variants * @link https://php.net/manual/en/function.variant-mul.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_mul($left, $right) {} /** * (PHP 5, PHP 7)
    * Performs logical negation on a variant * @link https://php.net/manual/en/function.variant-neg.php * @param mixed $variant * @return mixed */ function variant_neg($variant) {} /** * (PHP 5, PHP 7)
    * Performs bitwise not negation on a variant * @link https://php.net/manual/en/function.variant-not.php * @param mixed $variant * @return mixed */ function variant_not($variant) {} /** * (PHP 5, PHP 7)
    * Performs a logical disjunction on two variants * @link https://php.net/manual/en/function.variant-or.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_or($left, $right) {} /** * (PHP 5, PHP 7)
    * Returns the result of performing the power function with two variants * @link https://php.net/manual/en/function.variant-pow.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_pow($left, $right) {} /** * (PHP 5, PHP 7)
    * Rounds a variant to the specified number of decimal places * @link https://php.net/manual/en/function.variant-round.php * @param mixed $variant * @param int $decimals * @return mixed */ function variant_round($variant, $decimals) {} /** * (PHP 5, PHP 7)
    * Convert a variant into another type "in-place" * @link https://php.net/manual/en/function.variant-set-type.php * @param VARIANT $variant * @param int $type * @return void */ function variant_set_type($variant, $type) {} /** * (PHP 5, PHP 7)
    * Assigns a new value for a variant object * @link https://php.net/manual/en/function.variant-set.php * @param VARIANT $variant * @param mixed $value * @return void */ function variant_set($variant, $value) {} /** * (PHP 5, PHP 7)
    * Subtracts the value of the right variant from the left variant value * @link https://php.net/manual/en/function.variant-sub.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_sub($left, $right) {} /** * (PHP 5, PHP 7)
    * Performs a logical exclusion on two variants * @link https://php.net/manual/en/function.variant-xor.php * @param mixed $left * @param mixed $right * @return mixed */ function variant_xor($left, $right) {} define('CLSCTX_INPROC_SERVER', 1); define('CLSCTX_INPROC_HANDLER', 2); define('CLSCTX_LOCAL_SERVER', 4); define('CLSCTX_REMOTE_SERVER', 16); define('CLSCTX_SERVER', 21); define('CLSCTX_ALL', 23); define('VT_NULL', 1); define('VT_EMPTY', 0); define('VT_UI1', 17); define('VT_I2', 2); define('VT_I4', 3); define('VT_R4', 4); define('VT_R8', 5); define('VT_BOOL', 11); define('VT_ERROR', 10); define('VT_CY', 6); define('VT_DATE', 7); define('VT_BSTR', 8); define('VT_DECIMAL', 14); define('VT_UNKNOWN', 13); define('VT_DISPATCH', 9); define('VT_VARIANT', 12); define('VT_I1', 16); define('VT_UI2', 18); define('VT_UI4', 19); define('VT_INT', 22); define('VT_UINT', 23); define('VT_ARRAY', 8192); define('VT_BYREF', 16384); define('CP_ACP', 0); define('CP_MACCP', 2); define('CP_OEMCP', 1); define('CP_UTF7', 65000); define('CP_UTF8', 65001); define('CP_SYMBOL', 42); define('CP_THREAD_ACP', 3); define('VARCMP_LT', 0); define('VARCMP_EQ', 1); define('VARCMP_GT', 2); define('VARCMP_NULL', 3); define('NORM_IGNORECASE', 1); define('NORM_IGNORENONSPACE', 2); define('NORM_IGNORESYMBOLS', 4); define('NORM_IGNOREWIDTH', 131072); define('NORM_IGNOREKANATYPE', 65536); define('NORM_IGNOREKASHIDA', 262144); define('DISP_E_DIVBYZERO', -2147352558); define('DISP_E_OVERFLOW', -2147352566); define('MK_E_UNAVAILABLE', -2147221021); // End of com v. * The optional encoding specifies the character * encoding for the input/output in PHP 4. Starting from PHP 5, the input * encoding is automatically detected, so that the * encoding parameter specifies only the output * encoding. In PHP 4, the default output encoding is the same as the * input charset. If empty string is passed, the parser attempts to identify * which encoding the document is encoded in by looking at the heading 3 or * 4 bytes. In PHP 5.0.0 and 5.0.1, the default output charset is * ISO-8859-1, while in PHP 5.0.2 and upper is UTF-8. The supported * encodings are ISO-8859-1, UTF-8 and * US-ASCII. *

    * @return resource|false|XMLParser a resource handle for the new XML parser. */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] function xml_parser_create(?string $encoding) {} /** * Create an XML parser with namespace support * @link https://php.net/manual/en/function.xml-parser-create-ns.php * @param string|null $encoding [optional]

    * The optional encoding specifies the character * encoding for the input/output in PHP 4. Starting from PHP 5, the input * encoding is automatically detected, so that the * encoding parameter specifies only the output * encoding. In PHP 4, the default output encoding is the same as the * input charset. In PHP 5.0.0 and 5.0.1, the default output charset is * ISO-8859-1, while in PHP 5.0.2 and upper is UTF-8. The supported * encodings are ISO-8859-1, UTF-8 and * US-ASCII. *

    * @param string $separator [optional]

    * With a namespace aware parser tag parameters passed to the various * handler functions will consist of namespace and tag name separated by * the string specified in separator. *

    * @return resource|false|XMLParser a resource handle for the new XML parser. */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] function xml_parser_create_ns(?string $encoding, string $separator = ':') {} /** * Use XML Parser within an object * @link https://php.net/manual/en/function.xml-set-object.php * @param XMLParser|resource $parser

    * A reference to the XML parser to use inside the object. *

    * @param object $object

    * The object where to use the XML parser. *

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(["8.2" => "true"], default: "bool")] #[Deprecated("The function is deprecated", since: "8.4")] function xml_set_object(#[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, object $object) {} /** * Set up start and end element handlers * @link https://php.net/manual/en/function.xml-set-element-handler.php * @param XMLParser|resource $parser

    * A reference to the XML parser to set up start and end element handler functions. *

    * @param callable $start_handler

    * The function named by start_element_handler * must accept three parameters: * start_element_handler * resourceparser * stringname * arrayattribs * parser * The first parameter, parser, is a * reference to the XML parser calling the handler.

    * @param callable $end_handler

    * The function named by end_element_handler * must accept two parameters: * end_element_handler * resourceparser * stringname * parser * The first parameter, parser, is a * reference to the XML parser calling the handler.

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(["8.2" => "true"], default: "bool")] function xml_set_element_handler( #[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, #[LanguageLevelTypeAware(["8.4" => "callable|string|null"], default: "callable")] $start_handler, #[LanguageLevelTypeAware(["8.4" => "callable|string|null"], default: "callable")] $end_handler ) {} /** * Set up character data handler * @link https://php.net/manual/en/function.xml-set-character-data-handler.php * @param XMLParser|resource $parser

    * A reference to the XML parser to set up character data handler function. *

    * @param callable $handler

    * handler is a string containing the name of a * function that must exist when xml_parse is called * for parser. *

    *

    * The function named by handler must accept * two parameters: * handler * resourceparser * stringdata * parser * The first parameter, parser, is a * reference to the XML parser calling the handler.

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(["8.2" => "true"], default: "bool")] function xml_set_character_data_handler( #[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, #[LanguageLevelTypeAware(["8.4" => "callable|string|null"], default: "callable")] $handler ) {} /** * Set up processing instruction (PI) handler * @link https://php.net/manual/en/function.xml-set-processing-instruction-handler.php * @param XMLParser|resource $parser

    * A reference to the XML parser to set up processing instruction (PI) handler function. *

    * @param callable $handler

    * handler is a string containing the name of a * function that must exist when xml_parse is called * for parser. *

    *

    * The function named by handler must accept * three parameters: * handler * resourceparser * stringtarget * stringdata * parser * The first parameter, parser, is a * reference to the XML parser calling the handler.

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(["8.2" => "true"], default: "bool")] function xml_set_processing_instruction_handler( #[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, #[LanguageLevelTypeAware(["8.4" => "callable|string|null"], default: "callable")] $handler ) {} /** * Set up default handler * @link https://php.net/manual/en/function.xml-set-default-handler.php * @param XMLParser|resource $parser

    * A reference to the XML parser to set up default handler function. *

    * @param callable $handler

    * handler is a string containing the name of a * function that must exist when xml_parse is called * for parser. *

    *

    * The function named by handler must accept * two parameters: * handler * resourceparser * stringdata * parser * The first parameter, parser, is a * reference to the XML parser calling the handler.

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(["8.2" => "true"], default: "bool")] function xml_set_default_handler( #[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, #[LanguageLevelTypeAware(["8.4" => "callable|string|null"], default: "callable")] $handler ) {} /** * Set up unparsed entity declaration handler * @link https://php.net/manual/en/function.xml-set-unparsed-entity-decl-handler.php * @param XMLParser|resource $parser

    * A reference to the XML parser to set up unparsed entity declaration handler function. *

    * @param callable $handler

    * handler is a string containing the name of a * function that must exist when xml_parse is called * for parser. *

    *

    * The function named by handler must accept six * parameters: * handler * resourceparser * stringentity_name * stringbase * stringsystem_id * stringpublic_id * stringnotation_name * parser * The first parameter, parser, is a * reference to the XML parser calling the * handler.

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(["8.2" => "true"], default: "bool")] function xml_set_unparsed_entity_decl_handler( #[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, #[LanguageLevelTypeAware(["8.4" => "callable|string|null"], default: "callable")] $handler ) {} /** * Set up notation declaration handler * @link https://php.net/manual/en/function.xml-set-notation-decl-handler.php * @param XMLParser|resource $parser

    * A reference to the XML parser to set up notation declaration handler function. *

    * @param callable $handler

    * handler is a string containing the name of a * function that must exist when xml_parse is called * for parser. *

    *

    * The function named by handler must accept * five parameters: * handler * resourceparser * stringnotation_name * stringbase * stringsystem_id * stringpublic_id * parser * The first parameter, parser, is a * reference to the XML parser calling the handler.

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(["8.2" => "true"], default: "bool")] function xml_set_notation_decl_handler( #[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, #[LanguageLevelTypeAware(["8.4" => "callable|string|null"], default: "callable")] $handler ) {} /** * Set up external entity reference handler * @link https://php.net/manual/en/function.xml-set-external-entity-ref-handler.php * @param XMLParser|resource $parser

    * A reference to the XML parser to set up external entity reference handler function. *

    * @param callable $handler

    * handler is a string containing the name of a * function that must exist when xml_parse is called * for parser. *

    *

    * The function named by handler must accept * five parameters, and should return an integer value.If the * value returned from the handler is FALSE (which it will be if no * value is returned), the XML parser will stop parsing and * xml_get_error_code will return * XML_ERROR_EXTERNAL_ENTITY_HANDLING. * handler * resourceparser * stringopen_entity_names * stringbase * stringsystem_id * stringpublic_id * parser * The first parameter, parser, is a * reference to the XML parser calling the handler.

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(["8.2" => "true"], default: "bool")] function xml_set_external_entity_ref_handler( #[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, #[LanguageLevelTypeAware(["8.4" => "callable|string|null"], default: "callable")] $handler ) {} /** * Set up start namespace declaration handler * @link https://php.net/manual/en/function.xml-set-start-namespace-decl-handler.php * @param XMLParser|resource $parser

    * A reference to the XML parser. *

    * @param callable $handler

    * handler is a string containing the name of a * function that must exist when xml_parse is called * for parser. *

    *

    * The function named by handler must accept * three parameters, and should return an integer value. If the * value returned from the handler is FALSE (which it will be if no * value is returned), the XML parser will stop parsing and * xml_get_error_code will return * XML_ERROR_EXTERNAL_ENTITY_HANDLING. * handler * resourceparser * stringprefix * stringuri * parser * The first parameter, parser, is a * reference to the XML parser calling the handler.

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(["8.2" => "true"], default: "bool")] function xml_set_start_namespace_decl_handler( #[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, #[LanguageLevelTypeAware(["8.4" => "callable|string|null"], default: "callable")] $handler ) {} /** * Set up end namespace declaration handler * @link https://php.net/manual/en/function.xml-set-end-namespace-decl-handler.php * @param XMLParser|resource $parser

    * A reference to the XML parser. *

    * @param callable $handler

    * handler is a string containing the name of a * function that must exist when xml_parse is called * for parser. *

    *

    * The function named by handler must accept * two parameters, and should return an integer value. If the * value returned from the handler is FALSE (which it will be if no * value is returned), the XML parser will stop parsing and * xml_get_error_code will return * XML_ERROR_EXTERNAL_ENTITY_HANDLING. * handler * resourceparser * stringprefix * parser * The first parameter, parser, is a * reference to the XML parser calling the handler.

    * @return bool TRUE on success or FALSE on failure. */ #[LanguageLevelTypeAware(["8.2" => "true"], default: "bool")] function xml_set_end_namespace_decl_handler( #[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, #[LanguageLevelTypeAware(["8.4" => "callable|string|null"], default: "callable")] $handler ) {} /** * Start parsing an XML document * @link https://php.net/manual/en/function.xml-parse.php * @param XMLParser|resource $parser

    * A reference to the XML parser to use. *

    * @param string $data

    * Chunk of data to parse. A document may be parsed piece-wise by * calling xml_parse several times with new data, * as long as the is_final parameter is set and * TRUE when the last data is parsed. *

    * @param bool $is_final [optional]

    * If set and TRUE, data is the last piece of * data sent in this parse. *

    * @return int 1 on success or 0 on failure. *

    * For unsuccessful parses, error information can be retrieved with * xml_get_error_code, * xml_error_string, * xml_get_current_line_number, * xml_get_current_column_number and * xml_get_current_byte_index. *

    *

    * Entity errors are reported at the end of the data thus only if * is_final is set and TRUE. *

    */ function xml_parse(#[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, string $data, bool $is_final = false): int {} /** * Parse XML data into an array structure * @link https://php.net/manual/en/function.xml-parse-into-struct.php * @param XMLParser|resource $parser

    * A reference to the XML parser. *

    * @param string $data

    * A string containing the XML data. *

    * @param array &$values

    * An array containing the values of the XML data *

    * @param array &$index [optional]

    * An array containing pointers to the location of the appropriate values in the $values. *

    * @return int xml_parse_into_struct returns 0 for failure and 1 for * success. This is not the same as FALSE and TRUE, be careful with * operators such as ===. */ #[LanguageLevelTypeAware(['8.1' => 'int|false'], default: 'int')] function xml_parse_into_struct(#[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, string $data, &$values, &$index) {} /** * Get XML parser error code * @link https://php.net/manual/en/function.xml-get-error-code.php * @param XMLParser|resource $parser

    * A reference to the XML parser to get error code from. *

    * @return int|false Returns one of the error codes listed in the error codes * section. */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "int"], default: "int|false")] function xml_get_error_code(#[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser) {} /** * Get XML parser error string * @link https://php.net/manual/en/function.xml-error-string.php * @param int $error_code

    * An error code from xml_get_error_code. *

    * @return string|null a string with a textual description of the error * code, or FALSE if no description was found. */ #[Pure] function xml_error_string(int $error_code): ?string {} /** * Get current line number for an XML parser * @link https://php.net/manual/en/function.xml-get-current-line-number.php * @param XMLParser|resource $parser

    * A reference to the XML parser to get line number from. *

    * @return int|false This function returns FALSE if parser does * not refer to a valid parser, or else it returns which line the * parser is currently at in its data buffer. */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "int"], default: "int|false")] function xml_get_current_line_number(#[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser) {} /** * Get current column number for an XML parser * @link https://php.net/manual/en/function.xml-get-current-column-number.php * @param XMLParser|resource $parser

    * A reference to the XML parser to get column number from. *

    * @return int|false This function returns FALSE if parser does * not refer to a valid parser, or else it returns which column on * the current line (as given by * xml_get_current_line_number) the parser is * currently at. */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "int"], default: "int|false")] function xml_get_current_column_number(#[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser) {} /** * Get current byte index for an XML parser * @link https://php.net/manual/en/function.xml-get-current-byte-index.php * @param XMLParser|resource $parser

    * A reference to the XML parser to get byte index from. *

    * @return int|false This function returns FALSE if parser does * not refer to a valid parser, or else it returns which byte index * the parser is currently at in its data buffer (starting at 0). */ #[Pure] #[LanguageLevelTypeAware(["8.0" => "int"], default: "int|false")] function xml_get_current_byte_index(#[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser) {} /** * Free an XML parser * @link https://php.net/manual/en/function.xml-parser-free.php * @param XMLParser|resource $parser A reference to the XML parser to free. * @return bool This function returns FALSE if parser does not * refer to a valid parser, or else it frees the parser and returns TRUE. */ function xml_parser_free(#[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser): bool {} /** * Set options in an XML parser * @link https://php.net/manual/en/function.xml-parser-set-option.php * @param XMLParser|resource $parser

    * A reference to the XML parser to set an option in. *

    * @param int $option

    * Which option to set. See below. *

    *

    * The following options are available: *

    * XML parser options * * * * * * * * * * * * * * * * * * * * * * * * * *
    Option constantData typeDescription
    XML_OPTION_CASE_FOLDINGinteger * Controls whether case-folding is enabled for this * XML parser. Enabled by default. *
    XML_OPTION_SKIP_TAGSTARTinteger * Specify how many characters should be skipped in the beginning of a * tag name. *
    XML_OPTION_SKIP_WHITEinteger * Whether to skip values consisting of whitespace characters. *
    XML_OPTION_TARGET_ENCODINGstring * Sets which target encoding to * use in this XML parser.By default, it is set to the same as the * source encoding used by xml_parser_create. * Supported target encodings are ISO-8859-1, * US-ASCII and UTF-8. *
    *

    * @param mixed $value

    * The option's new value. *

    * @return bool This function returns FALSE if parser does not * refer to a valid parser, or if the option could not be set. Else the * option is set and TRUE is returned. */ function xml_parser_set_option(#[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, int $option, $value): bool {} /** * Get options from an XML parser * @link https://php.net/manual/en/function.xml-parser-get-option.php * @param XMLParser|resource $parser A reference to the XML parser to get an option from. * @param int $option Which option to fetch. XML_OPTION_CASE_FOLDING * and XML_OPTION_TARGET_ENCODING are available. * See xml_parser_set_option for their description. * @return string|int|bool This function returns FALSE if parser does * not refer to a valid parser or if option isn't * valid (generates also a E_WARNING). * Else the option's value is returned. */ #[Pure] #[LanguageLevelTypeAware(["8.3" => "string|int|bool"], default: "string|int")] function xml_parser_get_option(#[LanguageLevelTypeAware(["8.0" => "XMLParser"], default: "resource")] $parser, int $option) {} define('XML_ERROR_NONE', 0); define('XML_ERROR_NO_MEMORY', 1); define('XML_ERROR_SYNTAX', 2); define('XML_ERROR_NO_ELEMENTS', 3); define('XML_ERROR_INVALID_TOKEN', 4); define('XML_ERROR_UNCLOSED_TOKEN', 5); define('XML_ERROR_PARTIAL_CHAR', 6); define('XML_ERROR_TAG_MISMATCH', 7); define('XML_ERROR_DUPLICATE_ATTRIBUTE', 8); define('XML_ERROR_JUNK_AFTER_DOC_ELEMENT', 9); define('XML_ERROR_PARAM_ENTITY_REF', 10); define('XML_ERROR_UNDEFINED_ENTITY', 11); define('XML_ERROR_RECURSIVE_ENTITY_REF', 12); define('XML_ERROR_ASYNC_ENTITY', 13); define('XML_ERROR_BAD_CHAR_REF', 14); define('XML_ERROR_BINARY_ENTITY_REF', 15); define('XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF', 16); define('XML_ERROR_MISPLACED_XML_PI', 17); define('XML_ERROR_UNKNOWN_ENCODING', 18); define('XML_ERROR_INCORRECT_ENCODING', 19); define('XML_ERROR_UNCLOSED_CDATA_SECTION', 20); define('XML_ERROR_EXTERNAL_ENTITY_HANDLING', 21); define('XML_OPTION_CASE_FOLDING', 1); define('XML_OPTION_TARGET_ENCODING', 2); define('XML_OPTION_SKIP_TAGSTART', 3); define('XML_OPTION_SKIP_WHITE', 4); /** * @since 8.4 */ define('XML_OPTION_PARSE_HUGE', 5); /** * Holds the SAX implementation method. * Can be libxml or expat. * @link https://php.net/manual/en/xml.constants.php */ define('XML_SAX_IMPL', "libxml"); /** * @since 8.0 */ final class XMLParser {} // End of xml v. next() method. * * @return void */ function ms_ResetErrorList() {} /** * Class Objects can be returned by the `layerObj`_ class, or can be * created using: */ final class classObj { /** * @var string */ public $group; /** * @var string */ public $keyimage; /** * Removed (6.2) - use addLabel, getLabel, ... * * @var labelObj */ public $label; /** * @var float */ public $maxscaledenom; /** * @var hashTableObj */ public $metadata; /** * @var float */ public $minscaledenom; /** * @var string */ public $name; /** * read-only (since 6.2) * * @var int */ public $numlabels; /** * read-only * * @var int */ public $numstyles; /** * MS_ON, MS_OFF or MS_DELETE * * @var int */ public $status; /** * @var string */ public $template; /** * @var string */ public $title; /** * @var int */ public $type; /** * The second argument class is optional. If given, the new class * created will be a copy of this class. * * @param layerObj $layer * @param classObj $class */ final public function __construct(layerObj $layer, classObj $class) {} /** * Old style constructor * * @param layerObj $layer * @param classObj $class * @return classObj */ final public function ms_newClassObj(layerObj $layer, classObj $class) {} /** * Add a labelObj to the classObj and return its index in the labels * array. * .. versionadded:: 6.2 * * @param labelObj $label * @return int */ final public function addLabel(labelObj $label) {} /** * Saves the object to a string. Provides the inverse option for * updateFromString. * * @return string */ final public function convertToString() {} /** * Draw the legend icon and return a new imageObj. * * @param int $width * @param int $height * @return imageObj */ final public function createLegendIcon($width, $height) {} /** * Delete the style specified by the style index. If there are any * style that follow the deleted style, their index will decrease by 1. * * @param int $index * @return int */ final public function deletestyle($index) {} /** * Draw the legend icon on im object at dstX, dstY. * Returns MS_SUCCESS/MS_FAILURE. * * @param int $width * @param int $height * @param imageObj $im * @param int $dstX * @param int $dstY * @return int */ final public function drawLegendIcon($width, $height, imageObj $im, $dstX, $dstY) {} /** * Free the object properties and break the internal references. * Note that you have to unset the php variable to free totally the * resources. * * @return void */ final public function free() {} /** * Returns the :ref:`expression ` string for the class * object. * * @return string */ final public function getExpressionString() {} /** * Return a reference to the labelObj at *index* in the labels array. * See the labelObj_ section for more details on multiple class * labels. * .. versionadded:: 6.2 * * @param int $index * @return labelObj */ final public function getLabel($index) {} /** * Fetch class metadata entry by name. Returns "" if no entry * matches the name. Note that the search is case sensitive. * .. note:: * getMetaData's query is case sensitive. * * @param string $name * @return int */ final public function getMetaData($name) {} /** * Return the style object using an index. index >= 0 && * index < class->numstyles. * * @param int $index * @return styleObj */ final public function getStyle($index) {} /** * Returns the text string for the class object. * * @return string */ final public function getTextString() {} /** * The style specified by the style index will be moved down into * the array of classes. Returns MS_SUCCESS or MS_FAILURE. * ex class->movestyledown(0) will have the effect of moving style 0 * up to position 1, and the style at position 1 will be moved * to position 0. * * @param int $index * @return int */ final public function movestyledown($index) {} /** * The style specified by the style index will be moved up into * the array of classes. Returns MS_SUCCESS or MS_FAILURE. * ex class->movestyleup(1) will have the effect of moving style 1 * up to position 0, and the style at position 0 will be moved * to position 1. * * @param int $index * @return int */ final public function movestyleup($index) {} /** * Remove the labelObj at *index* from the labels array and return a * reference to the labelObj. numlabels is decremented, and the * array is updated. * .. versionadded:: 6.2 * * @param int $index * @return labelObj */ final public function removeLabel($index) {} /** * Remove a metadata entry for the class. Returns MS_SUCCESS/MS_FAILURE. * * @param string $name * @return int */ final public function removeMetaData($name) {} /** * Set object property to a new value. * * @param string $property_name * @param $new_value * @return int */ final public function set($property_name, $new_value) {} /** * Set the :ref:`expression ` string for the class * object. * * @param string $expression * @return int */ final public function setExpression($expression) {} /** * Set a metadata entry for the class. Returns MS_SUCCESS/MS_FAILURE. * * @param string $name * @param string $value * @return int */ final public function setMetaData($name, $value) {} /** * Set the text string for the class object. * * @param string $text * @return int */ final public function settext($text) {} /** * Update a class from a string snippet. Returns MS_SUCCESS/MS_FAILURE. * .. code-block:: php * set the color * $oClass->updateFromString('CLASS STYLE COLOR 255 0 255 END END'); * * @param string $snippet * @return int */ final public function updateFromString($snippet) {} } /** * Instance of clusterObj is always embedded inside the `layerObj`_. */ final class clusterObj { /** * @var float */ public $buffer; /** * @var float */ public $maxdistance; /** * @var string */ public $region; /** * Saves the object to a string. Provides the inverse option for * updateFromString. * * @return string */ final public function convertToString() {} /** * Returns the :ref:`expression ` for this cluster * filter or NULL on error. * * @return string */ final public function getFilterString() {} /** * Returns the :ref:`expression ` for this cluster group * or NULL on error. * * @return string */ final public function getGroupString() {} /** * Set layer filter :ref:`expression `. * * @param string $expression * @return int */ final public function setFilter($expression) {} /** * Set layer group :ref:`expression `. * * @param string $expression * @return int */ final public function setGroup($expression) {} } /** * Instances of colorObj are always embedded inside other classes. */ final class colorObj { /** * @var int */ public $red; /** * @var int */ public $green; /** * @var int */ public $blue; /** * @var int */ public $alpha; /** * Get the color as a hex string "#rrggbb" or (if alpha is not 255) * "#rrggbbaa". * * @return string */ final public function toHex() {} /** * Set red, green, blue and alpha values. The hex string should have the form * "#rrggbb" (alpha will be set to 255) or "#rrggbbaa". Returns MS_SUCCESS. * * @param string $hex * @return int */ final public function setHex($hex) {} } final class errorObj { /** * //See error code constants above * * @var int */ public $code; /** * @var string */ public $message; /** * @var string */ public $routine; } /** * The grid is always embedded inside a layer object defined as * a grid (layer->connectiontype = MS_GRATICULE) * (for more docs : https://github.com/mapserver/mapserver/wiki/MapServerGrid) * A layer can become a grid layer by adding a grid object to it using : * ms_newGridObj(layerObj layer) * $oLayer = ms_newlayerobj($oMap); * $oLayer->set("name", "GRID"); * ms_newgridobj($oLayer); * $oLayer->grid->set("labelformat", "DDMMSS"); */ final class gridObj { /** * @var string */ public $labelformat; /** * @var float */ public $maxacrs; /** * @var float */ public $maxinterval; /** * @var float */ public $maxsubdivide; /** * @var float */ public $minarcs; /** * @var float */ public $mininterval; /** * @var float */ public $minsubdivide; /** * Set object property to a new value. * * @param string $property_name * @param $new_value * @return int */ final public function set($property_name, $new_value) {} } /** * Instance of hashTableObj is always embedded inside the `classObj`_, * `layerObj`_, `mapObj`_ and `webObj`_. It is uses a read only. * $hashTable = $oLayer->metadata; * $key = null; * while ($key = $hashTable->nextkey($key)) * echo "Key: ".$key." value: ".$hashTable->get($key)."
    "; */ final class hashTableObj { /** * Clear all items in the hashTable (To NULL). * * @return void */ final public function clear() {} /** * Fetch class metadata entry by name. Returns "" if no entry * matches the name. Note that the search is case sensitive. * * @param string $key * @return string */ final public function get($key) {} /** * Return the next key or first key if previousKey = NULL. * Return NULL if no item is in the hashTable or end of hashTable is * reached * * @param string $previousKey * @return string */ final public function nextkey($previousKey) {} /** * Remove a metadata entry in the hashTable. Returns MS_SUCCESS/MS_FAILURE. * * @param string $key * @return int */ final public function remove($key) {} /** * Set a metadata entry in the hashTable. Returns MS_SUCCESS/MS_FAILURE. * * @param string $key * @param string $value * @return int */ final public function set($key, $value) {} } /** * Instances of imageObj are always created by the `mapObj`_ class methods. */ final class imageObj { /** * read-only * * @var int */ public $width; /** * read-only * * @var int */ public $height; /** * read-only * * @var int */ public $resolution; /** * read-only * * @var int */ public $resolutionfactor; /** * @var string */ public $imagepath; /** * @var string */ public $imageurl; /** * Copy srcImg on top of the current imageObj. * transparentColorHex is the color (in 0xrrggbb format) from srcImg * that should be considered transparent (i.e. those pixels won't * be copied). Pass -1 if you don't want any transparent color. * If optional dstx,dsty are provided then it defines the position * where the image should be copied (dstx,dsty = top-left corner * position). * The optional angle is a value between 0 and 360 degrees to rotate * the source image counterclockwise. Note that if an angle is specified * (even if its value is zero) then the dstx and dsty coordinates * specify the CENTER of the destination area. * Note: this function works only with 8 bits GD images (PNG or GIF). * * @param imageObj $srcImg * @param int $transparentColorHex * @param int $dstX * @param int $dstY * @param int $angle * @return void */ final public function pasteImage(imageObj $srcImg, $transparentColorHex, $dstX, $dstY, $angle) {} /** * Writes image object to specified filename. * Passing no filename or an empty filename sends output to stdout. In * this case, the PHP header() function should be used to set the * document's content-type prior to calling saveImage(). The output * format is the one that is currently selected in the map file. The * second argument oMap is not manadatory. It is usful when saving to * formats like GTIFF that needs georeference information contained in * the map file. On success, it returns either MS_SUCCESS if writing to an * external file, or the number of bytes written if output is sent to * stdout. * * @param string $filename * @param mapObj $oMap * @return int */ final public function saveImage($filename, mapObj $oMap) {} /** * Writes image to temp directory. Returns image URL. * The output format is the one that is currently selected in the * map file. * * @return string */ final public function saveWebImage() {} } final class labelcacheMemberObj { /** * read-only * * @var int */ public $classindex; /** * read-only * * @var int */ public $featuresize; /** * read-only * * @var int */ public $layerindex; /** * read-only * * @var int */ public $markerid; /** * read-only * * @var int */ public $numstyles; /** * read-only * * @var int */ public $shapeindex; /** * read-only * * @var int */ public $status; /** * read-only * * @var string */ public $text; /** * read-only * * @var int */ public $tileindex; } final class labelcacheObj { /** * Free the label cache. Always returns MS_SUCCESS. * Ex : map->labelcache->freeCache(); * * @return bool */ final public function freeCache() {} } /** * labelObj are always embedded inside other classes. */ final class labelObj { /** * @var int */ public $align; /** * @var float */ public $angle; /** * @var int */ public $anglemode; /** * @var int */ public $antialias; /** * @var int */ public $autominfeaturesize; /** * (deprecated since 6.0) * * @var colorObj */ public $backgroundcolor; /** * (deprecated since 6.0) * * @var colorObj */ public $backgroundshadowcolor; /** * (deprecated since 6.0) * * @var int */ public $backgroundshadowsizex; /** * (deprecated since 6.0) * * @var int */ public $backgroundshadowsizey; /** * @var int */ public $buffer; /** * @var colorObj */ public $color; /** * @var string */ public $encoding; /** * @var string */ public $font; /** * @var int */ public $force; /** * @var int */ public $maxlength; /** * @var int */ public $maxsize; /** * @var int */ public $mindistance; /** * @var int */ public $minfeaturesize; /** * @var int */ public $minlength; /** * @var int */ public $minsize; /** * @var int */ public $numstyles; /** * @var int */ public $offsetx; /** * @var int */ public $offsety; /** * @var colorObj */ public $outlinecolor; /** * @var int */ public $outlinewidth; /** * @var int */ public $partials; /** * @var int */ public $position; /** * @var int */ public $priority; /** * @var int */ public $repeatdistance; /** * @var colorObj */ public $shadowcolor; /** * @var int */ public $shadowsizex; /** * @var int */ public $shadowsizey; /** * @var int */ public $size; /** * @var int */ public $wrap; final public function __construct() {} /** * Saves the object to a string. Provides the inverse option for * updateFromString. * * @return string */ final public function convertToString() {} /** * Delete the style specified by the style index. If there are any * style that follow the deleted style, their index will decrease by 1. * * @param int $index * @return int */ final public function deleteStyle($index) {} /** * Free the object properties and break the internal references. * Note that you have to unset the php variable to free totally the * resources. * * @return void */ final public function free() {} /** * Get the attribute binding for a specified label property. Returns * NULL if there is no binding for this property. * Example: * .. code-block:: php * $oLabel->setbinding(MS_LABEL_BINDING_COLOR, "FIELD_NAME_COLOR"); * echo $oLabel->getbinding(MS_LABEL_BINDING_COLOR); // FIELD_NAME_COLOR * * @param mixed $labelbinding * @return string */ final public function getBinding($labelbinding) {} /** * Returns the label expression string. * * @return string */ final public function getExpressionString() {} /** * Return the style object using an index. index >= 0 && * index < label->numstyles. * * @param int $index * @return styleObj */ final public function getStyle($index) {} /** * Returns the label text string. * * @return string */ final public function getTextString() {} /** * The style specified by the style index will be moved down into * the array of classes. Returns MS_SUCCESS or MS_FAILURE. * ex label->movestyledown(0) will have the effect of moving style 0 * up to position 1, and the style at position 1 will be moved * to position 0. * * @param int $index * @return int */ final public function moveStyleDown($index) {} /** * The style specified by the style index will be moved up into * the array of classes. Returns MS_SUCCESS or MS_FAILURE. * ex label->movestyleup(1) will have the effect of moving style 1 * up to position 0, and the style at position 0 will be moved * to position 1. * * @param int $index * @return int */ final public function moveStyleUp($index) {} /** * Remove the attribute binding for a specfiled style property. * Example: * .. code-block:: php * $oStyle->removebinding(MS_LABEL_BINDING_COLOR); * * @param mixed $labelbinding * @return int */ final public function removeBinding($labelbinding) {} /** * Set object property to a new value. * * @param string $property_name * @param $new_value * @return int */ final public function set($property_name, $new_value) {} /** * Set the attribute binding for a specified label property. * Example: * .. code-block:: php * $oLabel->setbinding(MS_LABEL_BINDING_COLOR, "FIELD_NAME_COLOR"); * This would bind the color parameter with the data (ie will extract * the value of the color from the field called "FIELD_NAME_COLOR" * * @param mixed $labelbinding * @param string $value * @return int */ final public function setBinding($labelbinding, $value) {} /** * Set the label expression. * * @param string $expression * @return int */ final public function setExpression($expression) {} /** * Set the label text. * * @param string $text * @return int */ final public function setText($text) {} /** * Update a label from a string snippet. Returns MS_SUCCESS/MS_FAILURE. * * @param string $snippet * @return int */ final public function updateFromString($snippet) {} } /** * Layer Objects can be returned by the `mapObj`_ class, or can be * created using: * A second optional argument can be given to ms_newLayerObj() to create * the new layer as a copy of an existing layer. If a layer is given as * argument then all members of a this layer will be copied in the new * layer created. */ final class layerObj { /** * @var int */ public $annotate; /** * @var hashTableObj */ public $bindvals; /** * @var string */ public $classgroup; /** * @var string */ public $classitem; /** * @var clusterObj */ public $cluster; /** * @var string */ public $connection; /** * read-only, use setConnectionType() to set it * * @var int */ public $connectiontype; /** * @var string */ public $data; /** * @var int */ public $debug; /** * deprecated since 6.0 * * @var int */ public $dump; /** * @var string */ public $filteritem; /** * @var string */ public $footer; /** * only available on a layer defined as grid (MS_GRATICULE) * * @var gridObj */ public $grid; /** * @var string */ public $group; /** * @var string */ public $header; /** * read-only * * @var int */ public $index; /** * @var int */ public $labelcache; /** * @var string */ public $labelitem; /** * @var float */ public $labelmaxscaledenom; /** * @var float */ public $labelminscaledenom; /** * @var string */ public $labelrequires; /** * @var string */ public $mask; /** * @var int */ public $maxfeatures; /** * @var float */ public $maxscaledenom; /** * @var hashTableObj */ public $metadata; /** * @var float */ public $minscaledenom; /** * @var string */ public $name; /** * @var int */ public $num_processing; /** * read-only * * @var int */ public $numclasses; /** * @var colorObj */ public $offsite; /** * @var int */ public $opacity; /** * @var projectionObj */ public $projection; /** * @var int */ public $postlabelcache; /** * @var string */ public $requires; /** * @var int */ public $sizeunits; /** * @var int */ public $startindex; /** * MS_ON, MS_OFF, MS_DEFAULT or MS_DELETE * * @var int */ public $status; /** * @var string */ public $styleitem; /** * @var float */ public $symbolscaledenom; /** * @var string */ public $template; /** * @var string */ public $tileindex; /** * @var string */ public $tileitem; /** * @var float */ public $tolerance; /** * @var int */ public $toleranceunits; /** * @var int */ public $transform; /** * @var int */ public $type; /** * Old style constructor * * @param mapObj $map * @param layerObj $layer * @return layerObj */ final public function ms_newLayerObj(mapObj $map, layerObj $layer) {} /** * Add a new feature in a layer. Returns MS_SUCCESS or MS_FAILURE on * error. * * @param shapeObj $shape * @return int */ final public function addFeature(shapeObj $shape) {} /** * Apply the :ref:`SLD ` document to the layer object. * The matching between the sld document and the layer will be done * using the layer's name. * If a namedlayer argument is passed (argument is optional), * the NamedLayer in the sld that matchs it will be used to style * the layer. * See :ref:`SLD HowTo ` for more information on the SLD support. * * @param string $sldxml * @param string $namedlayer * @return int */ final public function applySLD($sldxml, $namedlayer) {} /** * Apply the :ref:`SLD ` document pointed by the URL to the * layer object. The matching between the sld document and the layer * will be done using the layer's name. If a namedlayer argument is * passed (argument is optional), the NamedLayer in the sld that * matchs it will be used to style the layer. See :ref:`SLD HowTo ` * for more information on the SLD support. * * @param string $sldurl * @param string $namedlayer * @return int */ final public function applySLDURL($sldurl, $namedlayer) {} /** * Clears all the processing strings. * * @return void */ final public function clearProcessing() {} /** * Close layer previously opened with open(). * * @return void */ final public function close() {} /** * Saves the object to a string. Provides the inverse option for * updateFromString. * * @return string */ final public function convertToString() {} /** * Draw a single layer, add labels to cache if required. * Returns MS_SUCCESS or MS_FAILURE on error. * * @param imageObj $image * @return int */ final public function draw(imageObj $image) {} /** * Draw query map for a single layer. * string executeWFSGetfeature() * Executes a GetFeature request on a WFS layer and returns the * name of the temporary GML file created. Returns an empty * string on error. * * @param imageObj $image * @return int */ final public function drawQuery(imageObj $image) {} /** * Free the object properties and break the internal references. * Note that you have to unset the php variable to free totally the * resources. * * @return void */ final public function free() {} /** * Returns an SLD XML string based on all the classes found in the * layer (the layer must have `STATUS` `on`). * * @return string */ final public function generateSLD() {} /** * Returns a classObj from the layer given an index value (0=first class) * * @param int $classIndex * @return classObj */ final public function getClass($classIndex) {} /** * Get the class index of a shape for a given scale. Returns -1 if no * class matches. classgroup is an array of class ids to check * (Optional). numclasses is the number of classes that the classgroup * array contains. By default, all the layer classes will be checked. * * @param $shape * @param $classgroup * @param $numclasses * @return int */ final public function getClassIndex($shape, $classgroup, $numclasses) {} /** * Returns the layer's data extents or NULL on error. * If the layer's EXTENT member is set then this value is used, * otherwise this call opens/closes the layer to read the * extents. This is quick on shapefiles, but can be * an expensive operation on some file formats or data sources. * This function is safe to use on both opened or closed layers: it * is not necessary to call open()/close() before/after calling it. * * @return rectObj */ final public function getExtent() {} /** * Returns the :ref:`expression ` for this layer or NULL * on error. * * @return string|null */ final public function getFilterString() {} /** * Returns an array containing the grid intersection coordinates. If * there are no coordinates, it returns an empty array. * * @return array */ final public function getGridIntersectionCoordinates() {} /** * Returns an array containing the items. Must call open function first. * If there are no items, it returns an empty array. * * @return array */ final public function getItems() {} /** * Fetch layer metadata entry by name. Returns "" if no entry * matches the name. Note that the search is case sensitive. * .. note:: * getMetaData's query is case sensitive. * * @param string $name * @return int */ final public function getMetaData($name) {} /** * Returns the number of results in the last query. * * @return int */ final public function getNumResults() {} /** * Returns an array containing the processing strings. * If there are no processing strings, it returns an empty array. * * @return array */ final public function getProcessing() {} /** * Returns a string representation of the :ref:`projection `. * Returns NULL on error or if no projection is set. * * @return string */ final public function getProjection() {} /** * Returns a resultObj by index from a layer object with * index in the range 0 to numresults-1. * Returns a valid object or FALSE(0) if index is invalid. * * @param int $index * @return resultObj */ final public function getResult($index) {} /** * Returns the bounding box of the latest result. * * @return rectObj */ final public function getResultsBounds() {} /** * If the resultObj passed has a valid resultindex, retrieve shapeObj from * a layer's resultset. (You get it from the resultObj returned by * getResult() for instance). Otherwise, it will do a single query on * the layer to fetch the shapeindex * .. code-block:: php * $map = new mapObj("gmap75.map"); * $l = $map->getLayerByName("popplace"); * $l->queryByRect($map->extent); * for ($i = 0; $i < $l->getNumResults(); $i++) { * $s = $l->getShape($l->getResult($i)); * echo $s->getValue($l,"Name"); * echo "\n"; * } * * @param resultObj $result * @return shapeObj */ final public function getShape(resultObj $result) {} /** * Returns a WMS GetFeatureInfo URL (works only for WMS layers) * clickX, clickY is the location of to query in pixel coordinates * with (0,0) at the top left of the image. * featureCount is the number of results to return. * infoFormat is the format the format in which the result should be * requested. Depends on remote server's capabilities. MapServer * WMS servers support only "MIME" (and should support "GML.1" soon). * Returns "" and outputs a warning if layer is not a WMS layer * or if it is not queriable. * * @param int $clickX * @param int $clickY * @param int $featureCount * @param string $infoFormat * @return string */ final public function getWMSFeatureInfoURL($clickX, $clickY, $featureCount, $infoFormat) {} /** * Returns MS_TRUE/MS_FALSE depending on whether the layer is * currently visible in the map (i.e. turned on, in scale, etc.). * * @return bool */ final public function isVisible() {} /** * The class specified by the class index will be moved down into * the array of layers. Returns MS_SUCCESS or MS_FAILURE. * ex layer->moveclassdown(0) will have the effect of moving class 0 * up to position 1, and the class at position 1 will be moved * to position 0. * * @param int $index * @return int */ final public function moveclassdown($index) {} /** * The class specified by the class index will be moved up into * the array of layers. Returns MS_SUCCESS or MS_FAILURE. * ex layer->moveclassup(1) will have the effect of moving class 1 * up to position 0, and the class at position 0 will be moved * to position 1. * * @param int $index * @return int */ final public function moveclassup($index) {} /** * Open the layer for use with getShape(). * Returns MS_SUCCESS/MS_FAILURE. * * @return int */ final public function open() {} /** * Called after msWhichShapes has been called to actually retrieve * shapes within a given area. Returns a shape object or NULL on * error. * .. code-block:: php * $map = ms_newmapobj("d:/msapps/gmap-ms40/htdocs/gmap75.map"); * $layer = $map->getLayerByName('road'); * $status = $layer->open(); * $status = $layer->whichShapes($map->extent); * while ($shape = $layer->nextShape()) * { * echo $shape->index ."
    \n"; * } * $layer->close(); * * @return shapeObj */ final public function nextShape() {} /** * Query layer for shapes that intersect current map extents. qitem * is the item (attribute) on which the query is performed, and * qstring is the expression to match. The query is performed on all * the shapes that are part of a :ref:`CLASS` that contains a * :ref:`TEMPLATE